/** Shopify CDN: Minification failed

Line 1020:37 Unexpected "`"
Line 1025:55 Unterminated string token
Line 5369:37 Unexpected "`"
Line 5374:55 Unterminated string token

**/
/* ==========================================================================
   BEAUTICA CUSTOM LAYER — design tokens + Phase 2 components
   One file, loaded after theme CSS (layout/theme.liquid).
   Tokens per docs 12_VISUAL_SYSTEM: pink #EC2EA5 display-only,
   pink-deep #C2117E for interactive/reading sizes (5.71:1 on white).
   ========================================================================== */

:root {
  --btq-pink: #EC2EA5;
  --btq-pink-deep: #C2117E;
  --btq-pink-soft: #FDF2F8;
  --btq-ink: #1A1A1A;
  --btq-ink-soft: #5C5C66;
  --btq-surface: #FFFFFF;
  --btq-surface-soft: #FAF7F9;
  --btq-line: #EBE6EA;
  --btq-line-strong: #767680;
  --btq-success: #0E7A4B;
  --btq-error: #C22121;
  --btq-radius-card: 12px;
  --btq-radius-btn: 10px;
  --btq-shadow-card: 0 1px 3px rgba(26, 26, 26, .08);
  --btq-shadow-sticky: 0 -2px 12px rgba(26, 26, 26, .10);
}

/* --------------------------------------------------------------------------
   Icons
   -------------------------------------------------------------------------- */
.btq-icon { flex: 0 0 auto; display: inline-block; vertical-align: middle; }

/* --------------------------------------------------------------------------
   Premium Trust Card (PDP, under title)
   -------------------------------------------------------------------------- */
.btq-trust-card {
  background: var(--btq-trust-bg, var(--btq-pink-soft));
  border: 1px solid rgba(236, 46, 165, .14);
  border-radius: 16px;
  padding: 14px 16px;
  margin: 16px 0 4px;
  display: grid;
  gap: 2px;
}
.btq-trust-card__row {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 40px;
  color: var(--btq-ink);
  font-size: 14px;
  line-height: 1.45;
}
.btq-trust-card__row .btq-icon { color: var(--btq-pink-deep); }
.btq-trust-card__row strong { font-weight: 600; }
@media (min-width: 750px) {
  .btq-trust-card { grid-template-columns: 1fr 1fr; gap: 4px 20px; }
}

/* --------------------------------------------------------------------------
   "Pourquoi vous allez l'aimer" benefits
   -------------------------------------------------------------------------- */
.btq-benefits { margin: 20px 0 4px; }
.btq-benefits__title {
  font-size: 17px;
  font-weight: 600;
  line-height: 1.3;
  margin: 0 0 10px;
  color: var(--btq-ink);
}
.btq-benefits__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.btq-benefits__item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--btq-ink);
}
.btq-benefits__item .btq-icon {
  color: var(--btq-success);
  margin-top: 2px;
}

/* --------------------------------------------------------------------------
   Scent chips (famille / tenue / projection / occasion / saison)
   -------------------------------------------------------------------------- */
.btq-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 16px 0 4px; }
.btq-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 32px;
  padding: 5px 12px;
  border-radius: 999px;
  background: var(--btq-surface-soft);
  border: 1px solid var(--btq-line);
  font-size: 13px;
  line-height: 1.2;
  color: var(--btq-ink);
  white-space: nowrap;
}
.btq-chip .btq-icon { color: var(--btq-pink-deep); }
.btq-chip__label { color: var(--btq-ink-soft); }

/* --------------------------------------------------------------------------
   Buttons — scoped premium sizing for Beautica components
   -------------------------------------------------------------------------- */
.btq-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 48px;
  padding: 12px 22px;
  border-radius: var(--btq-radius-btn);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  border: 1.5px solid transparent;
  transition: background-color .18s ease-out, border-color .18s ease-out, transform .12s ease-out;
}
.btq-btn:active { transform: scale(.985); }
.btq-btn--primary { background: var(--btq-pink-deep); color: #fff; }
.btq-btn--primary:hover { background: #A50E6B; color: #fff; }
.btq-btn--secondary { background: #fff; color: var(--btq-pink-deep); border-color: var(--btq-pink-deep); }
.btq-btn--secondary:hover { background: var(--btq-pink-soft); }
.btq-btn--block { width: 100%; }
.btq-btn:focus-visible { outline: 2px solid var(--btq-pink-deep); outline-offset: 2px; }

/* --------------------------------------------------------------------------
   Perfume Finder («Trouvez votre parfum»)
   -------------------------------------------------------------------------- */
.btq-finder { max-width: 560px; margin: 0 auto; padding: 8px 16px 48px; }
.btq-finder__progress {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 13px; color: var(--btq-ink-soft); margin-bottom: 16px; min-height: 44px;
}
.btq-finder__back {
  display: inline-flex; align-items: center; gap: 6px; min-height: 44px; min-width: 44px;
  background: none; border: 0; color: var(--btq-ink); font-size: 14px; cursor: pointer; padding: 8px;
}
.btq-finder__bar { height: 4px; border-radius: 999px; background: var(--btq-line); overflow: hidden; margin-bottom: 24px; }
.btq-finder__bar-fill { height: 100%; background: var(--btq-pink-deep); border-radius: 999px; transition: width .25s ease-out; }
.btq-finder__question { font-size: 22px; font-weight: 700; line-height: 1.25; color: var(--btq-ink); margin: 0 0 6px; }
.btq-finder__hint { font-size: 13.5px; color: var(--btq-ink-soft); margin: 0 0 20px; line-height: 1.5; }
.btq-finder__options { display: grid; gap: 12px; }
.btq-finder__options--grid { grid-template-columns: 1fr 1fr; }
.btq-finder__option {
  display: flex; flex-direction: column; align-items: flex-start; gap: 4px;
  min-height: 56px; padding: 14px 16px; text-align: left;
  background: var(--btq-surface); border: 1.5px solid var(--btq-line-strong);
  border-radius: var(--btq-radius-card); cursor: pointer;
  font-size: 15px; font-weight: 600; color: var(--btq-ink); line-height: 1.3;
  transition: border-color .15s ease-out, background-color .15s ease-out;
}
.btq-finder__option small { font-weight: 400; font-size: 12.5px; color: var(--btq-ink-soft); line-height: 1.35; }
.btq-finder__option:hover { border-color: var(--btq-pink-deep); }
.btq-finder__option[aria-pressed="true"], .btq-finder__option.is-selected {
  border-color: var(--btq-pink-deep); background: var(--btq-pink-soft);
}
.btq-finder__option:focus-visible { outline: 2px solid var(--btq-pink-deep); outline-offset: 2px; }
.btq-finder__skip {
  display: block; margin: 20px auto 0; background: none; border: 0;
  color: var(--btq-ink-soft); font-size: 14px; text-decoration: underline;
  min-height: 44px; cursor: pointer;
}
.btq-finder__results-title { font-size: 24px; font-weight: 700; line-height: 1.25; margin: 0 0 4px; }
.btq-finder__results-sub { font-size: 14px; color: var(--btq-ink-soft); margin: 0 0 20px; }
.btq-finder__result {
  display: flex; gap: 14px; align-items: center;
  background: var(--btq-surface); border: 1px solid var(--btq-line);
  border-radius: var(--btq-radius-card); box-shadow: var(--btq-shadow-card);
  padding: 12px; margin-bottom: 12px; text-decoration: none; color: inherit;
}
.btq-finder__result img { width: 84px; height: 84px; object-fit: contain; border-radius: 8px; background: var(--btq-surface-soft); }
.btq-finder__result-title { font-size: 15px; font-weight: 600; color: var(--btq-ink); margin: 0 0 2px; }
.btq-finder__result-price { font-size: 14px; font-weight: 700; color: var(--btq-pink-deep); margin: 0 0 4px; }
.btq-finder__result-why { font-size: 12.5px; color: var(--btq-ink-soft); line-height: 1.4; margin: 0; }
.btq-finder__empty { text-align: center; color: var(--btq-ink-soft); font-size: 14px; padding: 24px 0; }

/* --------------------------------------------------------------------------
   Micro-UX & accessibility floor
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .btq-btn, .btq-finder__bar-fill, .btq-finder__option { transition: none; }
}

/* Type floor: mobile toolbar labels measured at 10px — Bible floor is 12px.
   (.text spans inside toolbar items / t-buttons; badge counters excluded on purpose.) */
.toolbar__item > .text,
.toolbar__item .text,
.t-button > .text {
  font-size: 12px !important;
  line-height: 1.2;
}

/* CTA floor: primary buy actions ≥48px (ATC measured at 45px). */
button[name="add"],
.product-form__submit {
  min-height: 48px;
}

/* --------------------------------------------------------------------------
   Merchandising Intelligence — occasions chips + seasonal shelf
   -------------------------------------------------------------------------- */
.btq-occasions { max-width: 1200px; margin: 0 auto; padding-inline: 16px; }
.btq-occasions__title { font-size: 17px; font-weight: 600; margin: 0 0 10px; color: var(--btq-ink); }
.btq-occasions__row { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; padding-bottom: 4px; }
.btq-occasions__row::-webkit-scrollbar { display: none; }
.btq-chip--action { min-height: 44px; padding: 10px 16px; font-size: 14px; font-weight: 600; text-decoration: none; border-color: var(--btq-line-strong); flex: 0 0 auto; transition: border-color .15s ease-out, background-color .15s ease-out; }
.btq-chip--action:hover { border-color: var(--btq-pink-deep); background: var(--btq-pink-soft); }
.btq-shelf { max-width: 1200px; margin: 0 auto; padding-inline: 16px; }
.btq-shelf__title { font-size: 20px; font-weight: 700; margin: 0 0 4px; color: var(--btq-ink); }
.btq-shelf__sub { font-size: 13px; color: var(--btq-ink-soft); margin: 0 0 20px; }
.btq-shelf__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (min-width: 750px) { .btq-shelf__grid { grid-template-columns: repeat(4, 1fr); gap: 16px; } }
.btq-shelf__card { position: relative; display: flex; flex-direction: column; gap: 6px; text-decoration: none; background: var(--btq-surface); border: 1px solid var(--btq-line); border-radius: var(--btq-radius-card); box-shadow: var(--btq-shadow-card); padding: 10px; }
.btq-shelf__img { width: 100%; aspect-ratio: 1; object-fit: contain; border-radius: 8px; background: var(--btq-surface-soft); }
.btq-shelf__badge { position: absolute; top: 16px; left: 16px; z-index: 1; font-size: 12px; font-weight: 600; letter-spacing: .04em; background: var(--btq-pink-deep); color: #fff; border-radius: 999px; padding: 4px 8px; }
.btq-shelf__name { font-size: 14px; font-weight: 600; line-height: 1.3; color: var(--btq-ink); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.btq-shelf__price { font-size: 14px; font-weight: 700; color: var(--btq-pink-deep); }
.btq-shelf__cta { text-align: center; margin-top: 20px; }
.btq-finder-cta { max-width: 680px; margin: 0 auto; padding: 40px 16px; text-align: center; }
.btq-finder-cta h2 { font-size: 24px; font-weight: 700; margin: 0 0 8px; color: var(--btq-ink); }
.btq-finder-cta p { font-size: 14.5px; color: var(--btq-ink-soft); margin: 0 0 20px; line-height: 1.5; }

/* Bible §4 scrim rule: slide text is white over photos — guarantee legibility on any image. */
.swiper-slide h1, .swiper-slide h2 { text-shadow: 0 1px 3px rgba(26,26,26,.45), 0 2px 16px rgba(26,26,26,.35); }

/* PDP FAQ — native details accordion, zero JS. */
.btq-faq { margin: 24px 0 4px; }
.btq-faq__title { font-size: 17px; font-weight: 600; margin: 0 0 6px; color: var(--btq-ink); }
.btq-faq__item { border-bottom: 1px solid var(--btq-line); }
.btq-faq__q { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 48px; padding: 12px 0; font-size: 14.5px; font-weight: 600; color: var(--btq-ink); cursor: pointer; list-style: none; }
.btq-faq__q::-webkit-details-marker { display: none; }
.btq-faq__q .btq-icon { transition: transform .18s ease-out; color: var(--btq-ink-soft); }
.btq-faq__item[open] .btq-faq__q .btq-icon { transform: rotate(90deg); }
.btq-faq__a { font-size: 14.5px; line-height: 1.55; color: var(--btq-ink); margin: 0 0 14px; }
.btq-faq__q:focus-visible { outline: 2px solid var(--btq-pink-deep); outline-offset: 2px; }

/* ==========================================================================
   V3 Premium product card + grid
   ========================================================================== */
.btq-grid-section { max-width: 1200px; margin: 0 auto; padding-inline: 16px; }
.btq-grid-section__head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 16px; }
.btq-grid-section__title { font-size: 20px; font-weight: 700; margin: 0 0 2px; color: var(--btq-ink); }
.btq-grid-section__sub { font-size: 13px; color: var(--btq-ink-soft); margin: 0; }
.btq-grid-section__all { display: inline-flex; align-items: center; gap: 2px; font-size: 13px; font-weight: 600; color: var(--btq-pink-deep); text-decoration: none; white-space: nowrap; flex: 0 0 auto; min-height: 44px; }
.btq-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (min-width: 750px) { .btq-grid { grid-template-columns: repeat(4, 1fr); gap: 16px; } }

.btq-card { display: flex; flex-direction: column; background: var(--btq-surface); border: 1px solid var(--btq-line); border-radius: var(--btq-radius-card); overflow: hidden; box-shadow: var(--btq-shadow-card); transition: box-shadow .18s ease-out, transform .18s ease-out; }
.btq-card:hover { box-shadow: 0 6px 20px rgba(26,26,26,.10); transform: translateY(-2px); }
.btq-card__link { text-decoration: none; color: inherit; display: flex; flex-direction: column; }
.btq-card__media { position: relative; aspect-ratio: 1; background: var(--btq-surface-soft); }
.btq-card__img { width: 100%; height: 100%; object-fit: contain; padding: 10px; display: block; }
.btq-card__badge { position: absolute; top: 8px; left: 8px; font-size: 11px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; background: var(--btq-pink-deep); color: #fff; border-radius: 999px; padding: 3px 8px; }
.btq-card__badge--out { background: var(--btq-ink); }
.btq-card__body { display: flex; flex-direction: column; gap: 2px; padding: 10px 12px 12px; }
.btq-card__brand { font-size: 10px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--btq-ink-soft); }
.btq-card__name { font-size: 14px; font-weight: 600; line-height: 1.25; margin: 0; color: var(--btq-ink); text-transform: capitalize; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.btq-card__accords { font-size: 12px; color: var(--btq-ink-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.btq-card__price { font-size: 14px; font-weight: 700; color: var(--btq-pink-deep); margin-top: 2px; }
.btq-card__size { font-weight: 400; font-size: 12px; color: var(--btq-ink-soft); }
.btq-card__trust { display: flex; align-items: center; gap: 5px; margin-top: 4px; color: var(--btq-ink-soft); }
.btq-card__trust-txt { font-size: 10.5px; }
.btq-card__add { display: flex; align-items: center; justify-content: center; gap: 6px; width: calc(100% - 24px); margin: 0 12px 12px; min-height: 42px; border: 1.5px solid var(--btq-pink-deep); background: var(--btq-pink-deep); color: #fff; border-radius: var(--btq-radius-btn); font-size: 13.5px; font-weight: 600; cursor: pointer; transition: background-color .15s ease-out, color .15s ease-out; }
.btq-card__add:hover { background: #A50E6B; border-color: #A50E6B; color: #fff; }
.btq-card__add:hover .btq-icon { color: #fff; }
.btq-card__add.is-added { background: var(--btq-success); border-color: var(--btq-success); color: #fff; }
.btq-card__add--out { border-color: var(--btq-line-strong); color: var(--btq-ink-soft); background: var(--btq-surface-soft); cursor: not-allowed; }
.btq-card__add:focus-visible { outline: 2px solid var(--btq-pink-deep); outline-offset: 2px; }

/* V3 Premium category strip (icon-based) */
.btq-cats { max-width: 1200px; margin: 0 auto; padding-inline: 16px; }
.btq-cats__head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 14px; }
.btq-cats__title { font-size: 17px; font-weight: 600; margin: 0; color: var(--btq-ink); }
.btq-cats__all { font-size: 13px; font-weight: 600; color: var(--btq-pink-deep); text-decoration: none; display: inline-flex; align-items: center; gap: 2px; }
.btq-cats__row { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; padding-bottom: 4px; }
.btq-cats__row::-webkit-scrollbar { display: none; }
.btq-cats__item { flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; gap: 7px; text-decoration: none; width: 72px; min-height: 44px; }
.btq-cats__circle { width: 56px; height: 56px; border-radius: 50%; background: var(--btq-pink-soft); display: flex; align-items: center; justify-content: center; color: var(--btq-pink-deep); transition: background-color .18s ease-out, transform .18s ease-out; }
.btq-cats__item:hover .btq-cats__circle { background: #FBD9EA; transform: translateY(-2px); }
.btq-cats__label { font-size: 12.5px; font-weight: 500; color: var(--btq-ink); text-align: center; line-height: 1.25; }
@media (min-width: 750px) { .btq-cats__row { justify-content: center; gap: 20px; } .btq-cats__circle { width: 64px; height: 64px; } .btq-cats__item { width: 84px; } }

/* Mobile friction fix (screenshot-verified): floating recently-viewed/share widgets
   overlapped tappable options (e.g. the finder's «Pour moi — Homme»). Hidden on mobile —
   recently-viewed has its own section; sharing lives in the OS share sheet. */
@media (max-width: 749px) {
  /* hide the WHOLE widget incl. its .glider pill — hiding only the buttons left a
     pink 40px sliver protruding at the right edge (owner screenshot) */
  multitasking-bar, .multitasking-bar, .multi-t, .multi-t__wrap, .multi-t__button,
  [class*="multi-t__wrapper"], .multitasking-bar .glider { display: none !important; }
}

/* ==========================================================================
   PDP CTA hierarchy (screenshot-verified failure: both buy buttons rendered as
   thin grey outlines — zero pink on the store's #1 conversion button).
   AJOUTER AU PANIER = filled pink primary · ACHETER MAINTENANT = pink outline.
   Applies to the main buy box AND the sticky ATC (same classes).
   ========================================================================== */
.product-form__submit.button,
button[name="add"].button {
  width: 100% !important;
  background: var(--btq-pink-deep) !important;
  border: 1.5px solid var(--btq-pink-deep) !important;
  color: #fff !important;
  min-height: 52px;
  border-radius: var(--btq-radius-btn) !important;
  font-weight: 600;
  letter-spacing: .02em;
  transition: background-color .18s ease-out, transform .12s ease-out;
}
.product-form__submit.button:hover,
button[name="add"].button:hover { background: #A50E6B !important; border-color: #A50E6B !important; }
.product-form__submit.button:active { transform: scale(.985); }
.shopify-payment-button__button--unbranded {
  background: #fff !important;
  border: 1.5px solid var(--btq-pink-deep) !important;
  color: var(--btq-pink-deep) !important;
  min-height: 50px;
  border-radius: var(--btq-radius-btn) !important;
  font-weight: 600;
}
.shopify-payment-button__button--unbranded:hover { background: var(--btq-pink-soft) !important; }
/* ATC width constraint lives on its container div, not the button */
.add-to-cart-button-inner { width: 100%; }
.add-to-cart-button-inner .add-to-cart-button-container { flex: 1 1 auto; width: 100%; }

/* COD total-at-door card (restored — dropped during a CSS consolidation; component was shipping unstyled) */
.btq-cod-total { background: var(--btq-pink-soft, #FDF2F8); border: 1px solid rgba(236,46,165,.14); border-radius: 12px; padding: 12px 14px; margin: 0 0 12px; }
.btq-cod-total__row { display: flex; justify-content: space-between; gap: 12px; font-size: 14px; color: var(--btq-ink, #1A1A1A); min-height: 26px; align-items: center; }
.btq-cod-total__row--total { font-size: 15px; font-weight: 700; border-top: 1px solid var(--btq-line, #EBE6EA); margin-top: 6px; padding-top: 8px; }
.btq-cod-total__row--total span:last-child { color: var(--btq-pink-deep, #C2117E); }
.btq-cod-total__free { color: var(--btq-success, #0E7A4B); font-weight: 600; }
.btq-cod-total__nudge, .btq-cod-total__hint { font-size: 12.5px; color: var(--btq-ink-soft, #5C5C66); margin: 4px 0 0; }
/* Cart checkout CTA — same grey-wireframe failure as the PDP (screenshot-verified on /cart) */
.cart__checkout-button.button { background: var(--btq-pink-deep, #C2117E) !important; border: 1.5px solid var(--btq-pink-deep, #C2117E) !important; color: #fff !important; min-height: 52px; border-radius: 10px !important; font-weight: 600; }
.cart__checkout-button.button:hover { background: #A50E6B !important; border-color: #A50E6B !important; }

/* ==========================================================================
   V4 LUXURY REFINEMENT (owner pixel-review, 7 critiques)
   ========================================================================== */
/* 1+6 · Cards: -18% height, tighter whitespace, image breathes more, clear hierarchy */
.btq-card__img { padding: 4px; }
.btq-card__body { padding: 8px 10px 8px; gap: 1px; }
.btq-card__brand { font-size: 9.5px; letter-spacing: .1em; }
.btq-card__name { font-size: 14px; font-weight: 650; }
.btq-card__price { margin-top: 3px; }
.btq-card__trust { margin-top: 3px; }
.btq-card__add { min-height: 38px; margin: 0 10px 10px; width: calc(100% - 20px); font-size: 13px; }
/* 2 · Categories: premium squircle, refined hover, calibrated icon */
.btq-cats__circle { border-radius: 20px; width: 54px; height: 54px;
  background: linear-gradient(160deg, #FDF2F8 0%, #FBE4F0 100%);
  box-shadow: inset 0 0 0 1px rgba(194,17,126,.08); }
.btq-cats__circle .btq-icon { width: 23px; height: 23px; }
.btq-cats__item:hover .btq-cats__circle { background: linear-gradient(160deg,#FBE4F0,#F8D3E7); transform: translateY(-2px) scale(1.03); box-shadow: inset 0 0 0 1px rgba(194,17,126,.16), 0 4px 10px rgba(194,17,126,.10); }
.btq-cats__label { font-size: 12px; }
@media (min-width:750px){ .btq-cats__circle{ width: 60px; height: 60px; border-radius: 22px; } }
/* 3 · Occasion chips: Apple/Airbnb grade — lower, thinner, subtle depth, press animation */
.btq-chip--action { min-height: 36px; padding: 7px 14px; font-size: 13px; font-weight: 500;
  border: 1px solid #E5DEE3; background: #fff; box-shadow: 0 1px 2px rgba(26,26,26,.05);
  transition: border-color .15s ease-out, box-shadow .15s ease-out, transform .1s ease-out; }
.btq-chip--action:hover { border-color: var(--btq-pink-deep); box-shadow: 0 2px 6px rgba(194,17,126,.10); }
.btq-chip--action:active { transform: scale(.96); }
.btq-occasions__title { font-size: 15px; }
.btq-occasions__row { gap: 6px; }
/* 4+7 · Vertical rhythm: one scale (8/16/24/32/48), no random gaps between systems */
.btq-finder-cta { padding: 32px 16px; }
.btq-cats, .btq-occasions { padding-block: 16px !important; }
.btq-shelf, .btq-grid-section { padding-block: 32px !important; }
.btq-grid-section__head, .btq-shelf__head { margin-bottom: 16px; }

/* ==========================================================================
   CART DRAWER — surgical refinement only (owner directive: preserve structure,
   personality and reading order; polish typography/spacing/alignment)
   ========================================================================== */
/* line items: ~12% tighter, nothing moved */
#CartDrawer .cart-item, #CartDrawer [class*="cart-drawer__item"] { padding-block: 12px; }
#CartDrawer .cart-item__media img, #CartDrawer .cart-item img { width: 68px !important; height: 68px !important; object-fit: contain; border-radius: 8px; background: #FAF7F9; }
#CartDrawer .cart-item__name, #CartDrawer .cart-item [class*="name"] { font-size: 13.5px; line-height: 1.35; }
/* quantity selector: same control, finer finish */
#CartDrawer quantity-input, #CartDrawer .quantity { border: 1px solid #E5DEE3 !important; border-radius: 999px !important; overflow: hidden; min-height: 34px; }
#CartDrawer .quantity__button { min-width: 32px; min-height: 34px; color: #C2117E; }
#CartDrawer .quantity__input { font-size: 13.5px; font-weight: 600; }
/* COD card: softer surface, no heavy border — its own structure unchanged */
#CartDrawer .btq-cod-total { border: 0; background: #FDF2F8; }
/* CTA hierarchy only: primary filled pink, full width — layout untouched */
#CartDrawer .cart__checkout-button.button { width: 100% !important; background: #C2117E !important; border: 1.5px solid #C2117E !important; color: #fff !important; min-height: 52px; border-radius: 10px !important; font-weight: 600; letter-spacing: .02em; }
#CartDrawer .cart__checkout-button.button:hover { background: #A50E6B !important; border-color: #A50E6B !important; }

/* PDP display title: clean name, brand as sub-line (owner directive) */
.btq-pdp-title { text-transform: capitalize; font-size: 26px; line-height: 1.2; font-weight: 700; margin: 0 0 2px; }
.btq-pdp-sub { font-size: 12.5px; letter-spacing: .06em; text-transform: uppercase; color: #5C5C66; margin: 0 0 4px; }

/* CTA System: no orphan states — sticky bar + any card 'choose options' action */
.sticky-cart__button .button, a.button.quick-add__submit, .card__cta .button {
  background: var(--btq-pink-deep,#C2117E) !important; border: 1.5px solid var(--btq-pink-deep,#C2117E) !important;
  color: #fff !important; border-radius: 10px !important; font-weight: 600;
}

/* Familles olfactives — discovery destination (squircle DNA, one interaction language) */
.btq-notes { max-width: 1200px; margin: 0 auto; padding-inline: 16px; }
.btq-notes__head { margin-bottom: 16px; }
.btq-notes__title { font-size: 20px; font-weight: 700; margin: 0 0 2px; color: var(--btq-ink); }
.btq-notes__sub { font-size: 13px; color: var(--btq-ink-soft); margin: 0; }
.btq-notes__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
@media (min-width: 750px) { .btq-notes__grid { grid-template-columns: repeat(3, 1fr); gap: 12px; } }
.btq-notes__tile { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; padding: 16px; min-height: 108px;
  background: linear-gradient(160deg, #FDF2F8 0%, #FBE4F0 100%); border-radius: 16px; text-decoration: none;
  box-shadow: inset 0 0 0 1px rgba(194,17,126,.07); transition: transform .18s ease-out, box-shadow .18s ease-out; }
.btq-notes__tile:hover { transform: translateY(-2px); box-shadow: inset 0 0 0 1px rgba(194,17,126,.14), 0 6px 16px rgba(194,17,126,.10); }
.btq-notes__tile:active { transform: scale(.98); }
.btq-notes__icon { color: var(--btq-pink-deep); }
.btq-notes__name { font-size: 15px; font-weight: 650; color: var(--btq-ink); }
.btq-notes__desc { font-size: 12px; color: var(--btq-ink-soft); line-height: 1.35; }
.btq-notes__cta { text-align: center; margin-top: 16px; }
/* Typography system: recommendations/recently-viewed headings obey sentence case */
product-recommendations h2, recently-viewed-products h2, [class*="recently-viewed"] h2 { text-transform: none !important; letter-spacing: normal !important; }

/* ==========================================================================
   V5 — owner refinement pass (cards compact / famille gateways / occasion mini-cards)
   ========================================================================== */
/* 1 · Card: -12% height — tighter trust row, less gap before Ajouter (button stays pink) */
.btq-card__body { padding: 8px 10px 4px; }
.btq-card__trust { margin-top: 2px; gap: 4px; }
.btq-card__trust .btq-icon { width: 12px; height: 12px; }
.btq-card__trust-txt { font-size: 10px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.btq-card__add { min-height: 36px; margin: 6px 10px 10px; }
/* 2 · Famille tiles: gateways, not product rivals — -35% height, icon+name inline, one-line notes */
.btq-notes__tile { flex-direction: row; align-items: center; flex-wrap: wrap; gap: 4px 10px; min-height: 68px; padding: 12px 14px; border-radius: 14px; }
.btq-notes__icon .btq-icon, .btq-notes__icon svg { width: 20px; height: 20px; }
.btq-notes__name { font-size: 16px; }
.btq-notes__desc { flex-basis: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 11.5px; }
/* 3 · Occasions: tinted mini-cards with identity, not flat chips */
.btq-chip--action { min-height: 44px; padding: 10px 16px; border-radius: 12px; font-weight: 600; border: 0; box-shadow: inset 0 0 0 1px rgba(26,26,26,.05), 0 1px 3px rgba(26,26,26,.06); }
.btq-occasions__row .btq-chip--action:nth-of-type(4n+1) { background: #FDF2F8; }
.btq-occasions__row .btq-chip--action:nth-of-type(4n+2) { background: #FFF8E7; }
.btq-occasions__row .btq-chip--action:nth-of-type(4n+3) { background: #F0F7F4; }
.btq-occasions__row .btq-chip--action:nth-of-type(4n+4) { background: #F4F1FB; }
.btq-occasions__row .btq-chip--action:hover { box-shadow: inset 0 0 0 1px rgba(194,17,126,.18), 0 3px 8px rgba(194,17,126,.10); }

/* PDP trust card — 2x2 compact grid on mobile (reference-mode Layout C, phase 1):
   halves the card height, calmer rhythm, labels stay >=13px */
.btq-trust-card { grid-template-columns: 1fr 1fr; gap: 2px 14px; padding: 12px 14px; }
.btq-trust-card__row { min-height: 34px; font-size: 13px; line-height: 1.3; gap: 8px; }
.btq-trust-card__row .btq-icon { width: 18px; height: 18px; }
/* Variant pill selected: brand identity instead of theme black */
.product-form input[type="radio"]:checked + label,
fieldset [checked] + label, .variant-option--pill input:checked + label {
  border-color: var(--btq-pink-deep) !important; background: var(--btq-pink-soft) !important;
  color: var(--btq-ink) !important; box-shadow: inset 0 0 0 .5px var(--btq-pink-deep);
}

/* ==========================================================================
   PREMIUM NAVIGATION DRAWER (strict-mode rebuild — default list hidden)
   ========================================================================== */
.menu-drawer__navigation { display: none !important; } /* default Ella list retired */
.btq-menu { padding: 4px 16px 24px; display: flex; flex-direction: column; gap: 16px; }
.btq-menu__hero { display: flex; flex-direction: column; gap: 2px; padding: 18px 16px; border-radius: 16px;
  background: linear-gradient(150deg, #FDF2F8 0%, #F8D3E7 100%); text-decoration: none;
  box-shadow: inset 0 0 0 1px rgba(194,17,126,.08); }
.btq-menu__hero-kicker { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--btq-pink-deep); font-weight: 600; }
.btq-menu__hero-title { font-size: 20px; font-weight: 700; color: var(--btq-ink); }
.btq-menu__hero-cta { display: inline-flex; align-items: center; gap: 2px; font-size: 13px; font-weight: 600; color: var(--btq-pink-deep); margin-top: 4px; }
.btq-menu__primary { display: flex; flex-direction: column; }
.btq-menu__primary a { display: flex; align-items: center; gap: 12px; min-height: 52px; font-size: 17px; font-weight: 600;
  color: var(--btq-ink); text-decoration: none; border-bottom: 1px solid var(--btq-line); }
.btq-menu__primary a .btq-icon { color: var(--btq-pink-deep); }
.btq-menu__label { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--btq-ink-soft); font-weight: 600; display: block; margin-bottom: 8px; }
.btq-menu__familles { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.btq-menu__familles a { display: flex; align-items: center; gap: 8px; min-height: 44px; padding: 10px 12px; border-radius: 12px;
  background: var(--btq-surface-soft); font-size: 14px; font-weight: 600; color: var(--btq-ink); text-decoration: none; }
.btq-menu__familles a .btq-icon { color: var(--btq-pink-deep); }
.btq-menu__occasions { display: flex; gap: 8px; flex-wrap: wrap; }
.btq-menu__occasions a { min-height: 40px; display: inline-flex; align-items: center; padding: 8px 14px; border-radius: 999px;
  background: #fff; box-shadow: inset 0 0 0 1px #E5DEE3; font-size: 13.5px; font-weight: 600; color: var(--btq-ink); text-decoration: none; }
.btq-menu__finder { display: flex; align-items: center; gap: 12px; padding: 14px 16px; border-radius: 14px;
  background: var(--btq-pink-deep); color: #fff !important; text-decoration: none; }
.btq-menu__finder span { flex: 1; line-height: 1.3; font-size: 14px; }
.btq-menu__finder small { opacity: .85; font-size: 12px; }
.btq-menu__finder .btq-icon { color: #fff; }
.btq-menu__footer { border-top: 1px solid var(--btq-line); padding-top: 16px; display: flex; flex-wrap: wrap; gap: 4px 20px; }
.btq-menu__footer a { display: inline-flex; align-items: center; gap: 6px; min-height: 40px; font-size: 13.5px; color: var(--btq-ink-soft); text-decoration: none; }
.btq-menu__reassure { flex-basis: 100%; font-size: 12px; color: var(--btq-ink-soft); margin: 4px 0 0; }
/* Retire the default multi-tab drawer content; premium menu owns the drawer */
#Drawer-Menu .header-mobile.mobile--multi-tab { display: none !important; }
#Drawer-Menu .btq-menu { overflow-y: auto; height: 100%; }

/* ==========================================================================
   TRUST TILES v3 (owner reference): four white cards, large pink icons,
   centered labels, pink accent underline, on soft-pink field.
   2x2 mobile · 4-across desktop. Overrides earlier trust-card layouts.
   ========================================================================== */
.btq-trust-card { background: var(--btq-pink-soft) !important; border: 0 !important; border-radius: 16px;
  padding: 12px !important; gap: 10px !important; grid-template-columns: 1fr 1fr !important; }
@media (min-width: 750px) { .btq-trust-card { grid-template-columns: repeat(4,1fr) !important; } }
.btq-trust-card__row { flex-direction: column !important; justify-content: center; text-align: center;
  gap: 8px !important; background: #fff; border-radius: 14px; padding: 14px 10px 12px;
  box-shadow: 0 1px 3px rgba(194,17,126,.06); min-height: 96px !important; font-size: 13px !important;
  font-weight: 500; line-height: 1.3 !important; position: relative; }
.btq-trust-card__row .btq-icon { width: 28px !important; height: 28px !important; }
.btq-trust-card__row::after { content: ''; width: 22px; height: 2px; border-radius: 2px;
  background: var(--btq-pink-deep); margin-top: 2px; }

/* (reverted) header burger visibility is handled by using ONE header section everywhere */

/* Collection description: 3-line clamp before products (theme's 'Afficher plus' expands) */
.collection-hero__description, .collection__description, [class*="collection-description"] {
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; font-size: 13.5px; }

/* ==========================================================================
   CARD v6 — modern floating quick-add (owner: cards too big, CTA dated)
   Icon button on the image corner; card drops ~45px; denser, modern, easier.
   ========================================================================== */
.btq-card__media { position: relative; }
.btq-card__media .btq-card__add {
  position: absolute; bottom: 8px; right: 8px; margin: 0; width: 42px; min-height: 42px; height: 42px;
  border-radius: 50%; padding: 0; justify-content: center; box-shadow: 0 2px 8px rgba(194,17,126,.28);
}
.btq-card__add span { display: none; }           /* icon-only; aria-label carries the name */
.btq-card__add .btq-icon { width: 18px; height: 18px; }
.btq-card__add.is-added { border-radius: 50%; }
.btq-card__body { padding-bottom: 10px; }
/* Header stacking guard (owner photo: cards visible over the header) */
#header-group, #header-group .shopify-section, sticky-header, .header-wrapper, header.header {
  position: relative; z-index: 40; background: #fff; }

/* DRAWER DEDUP (owner review): ONE summary only — the COD card. Theme totals + duplicate
   free-ship line hidden in drawer (green bar keeps the message, card keeps the math). */
#CartDrawer .totals, #CartDrawer .totals + small, #CartDrawer [class*="tax-note"] { display: none !important; }
#CartDrawer .btq-cod-total__nudge { display: none !important; }

/* ==========================================================================
   DRAWER SCROLL — ROOT CAUSE FIX (diagnosed in the live DOM)
   .btq-menu renders 928px tall as a DIRECT CHILD of .drawer__inner, which the
   theme locks to 812px with overflow-y:hidden -> the finder CTA and in-menu
   footer were clipped and unreachable. The true clipping parent becomes the
   scroll container, with momentum scrolling, dynamic viewport height (correct
   under iOS Safari / Android Chrome URL bars) and safe-area padding.
   ========================================================================== */
#Drawer-Menu .drawer__inner {
  overflow-y: auto !important;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  height: 100dvh !important;
  max-height: 100dvh !important;
}
@supports not (height: 100dvh) {
  #Drawer-Menu .drawer__inner { height: 100vh !important; max-height: 100vh !important; }
}
#Drawer-Menu .btq-menu {
  padding-bottom: calc(32px + env(safe-area-inset-bottom, 0px));
  flex: 0 0 auto !important;   /* FLEX SHRINK was crushing 928px -> 393px (real root cause) */
  min-height: max-content;
}
/* empty legacy wrapper sibling consumed 374px of the flex column */
#Drawer-Menu .drawer__wrapper { display: none !important; }
#Drawer-Menu .drawer__header {
  position: sticky; top: 0; z-index: 2; background: #fff;
}

/* ==========================================================================
   QUICK VIEW v2 — premium compact sheet (full redesign)
   Horizontal hero keeps name/price/variants/CTA above the fold at 375px.
   ========================================================================== */
.btq-qv[hidden] { display: none; }
.btq-qv { position: fixed; inset: 0; z-index: 95; }
.btq-qv__overlay { position: absolute; inset: 0; background: rgba(26,26,26,.5);
  opacity: 0; transition: opacity .26s ease-out; }
.btq-qv.is-open .btq-qv__overlay { opacity: 1; }
.btq-qv__sheet { position: absolute; left: 0; right: 0; bottom: 0; display: flex; flex-direction: column;
  background: #fff; border-radius: 22px 22px 0 0; max-height: 84dvh;
  box-shadow: 0 -10px 40px rgba(26,26,26,.22);
  transform: translateY(101%); transition: transform .3s cubic-bezier(.22,1,.36,1); }
.btq-qv.is-open .btq-qv__sheet { transform: translateY(0); }
@media (min-width: 750px) {
  .btq-qv__sheet { left: 50%; right: auto; bottom: auto; top: 50%; width: 440px; border-radius: 20px;
    transform: translate(-50%,-46%) scale(.97); opacity: 0; transition: transform .28s cubic-bezier(.22,1,.36,1), opacity .28s ease-out; }
  .btq-qv.is-open .btq-qv__sheet { transform: translate(-50%,-50%) scale(1); opacity: 1; }
}
.btq-qv__grip { width: 38px; height: 4px; border-radius: 999px; background: var(--btq-line);
  margin: 8px auto 2px; flex: 0 0 auto; }
@media (min-width: 750px) { .btq-qv__grip { display: none; } }
.btq-qv__close { position: absolute; top: 12px; right: 12px; width: 34px; height: 34px; border-radius: 50%;
  border: 0; background: var(--btq-surface-soft); color: var(--btq-ink-soft); cursor: pointer; z-index: 2;
  display: flex; align-items: center; justify-content: center; transform: rotate(45deg); }
.btq-qv__scroll { overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain;
  padding: 6px 16px 4px; }
/* compact horizontal hero — the core of the redesign */
.btq-qv__hero { display: flex; gap: 14px; align-items: center; padding: 4px 0 12px; }
.btq-qv__thumb { flex: 0 0 auto; width: 104px; height: 104px; border-radius: 14px;
  background: var(--btq-surface-soft); display: flex; align-items: center; justify-content: center; overflow: hidden; }
.btq-qv__thumb img { width: 100%; height: 100%; object-fit: contain; padding: 8px; }
.btq-qv__id { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.btq-qv__brand { font-size: 10px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--btq-ink-soft); }
.btq-qv__name { font-size: 21px; font-weight: 700; line-height: 1.15; margin: 0; color: var(--btq-ink);
  text-transform: capitalize; overflow-wrap: anywhere; }
.btq-qv__stock { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; color: var(--btq-success); font-weight: 600; }
.btq-qv-dot, .btq-qv-dotout { width: 7px; height: 7px; border-radius: 50%; background: var(--btq-success); display: inline-block; }
.btq-qv-dotout { background: var(--btq-error); }
.btq-qv__stock:has(.btq-qv-dotout) { color: var(--btq-error); }
.btq-qv__price { font-size: 24px; font-weight: 700; color: var(--btq-pink-deep); line-height: 1.1; margin-top: 2px; }
.btq-qv__chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.btq-qv__chip { font-size: 12px; padding: 5px 10px; border-radius: 999px; background: var(--btq-surface-soft);
  color: var(--btq-ink); white-space: nowrap; }
.btq-qv__label { display: block; font-size: 11px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--btq-ink-soft); margin-bottom: 7px; }
.btq-qv__pills { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.btq-qv__pill { display: flex; flex-direction: column; align-items: center; gap: 1px; min-height: 52px;
  min-width: 76px; padding: 8px 14px; border-radius: 12px; border: 1.5px solid var(--btq-line-strong);
  background: #fff; cursor: pointer; transition: border-color .15s ease-out, background-color .15s ease-out, transform .1s ease-out; }
.btq-qv__pill strong { font-size: 14px; font-weight: 700; color: var(--btq-ink); }
.btq-qv__pill small { font-size: 11.5px; color: var(--btq-ink-soft); }
.btq-qv__pill:active { transform: scale(.97); }
.btq-qv__pill.is-on { border-color: var(--btq-pink-deep); background: var(--btq-pink-soft); }
.btq-qv__pill.is-on strong, .btq-qv__pill.is-on small { color: var(--btq-pink-deep); }
.btq-qv__pill:disabled { opacity: .38; cursor: not-allowed; }
.btq-qv__pill:disabled strong { text-decoration: line-through; }
.btq-qv__trust { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 12px;
  color: var(--btq-ink-soft); margin: 0 0 6px; }
.btq-qv__trust .btq-icon { color: var(--btq-pink-deep); }
.btq-qv__dot { opacity: .5; }
/* dominant sticky CTA */
.btq-qv__foot { flex: 0 0 auto; padding: 10px 16px calc(12px + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--btq-line); background: #fff; border-radius: 0 0 22px 22px; }
.btq-qv__add { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%;
  min-height: 54px; border: 0; border-radius: 12px; background: var(--btq-pink-deep); color: #fff;
  font-size: 15.5px; font-weight: 700; cursor: pointer;
  transition: background-color .18s ease-out, transform .1s ease-out; }
.btq-qv__add:active { transform: scale(.99); }
.btq-qv__add:disabled { background: var(--btq-line); color: var(--btq-ink-soft); cursor: not-allowed; }
.btq-qv__add.is-done { background: var(--btq-success); }
.btq-qv__full { display: flex; align-items: center; justify-content: center; gap: 2px; min-height: 40px;
  font-size: 13px; font-weight: 600; color: var(--btq-ink-soft); text-decoration: none; }
@media (prefers-reduced-motion: reduce) {
  .btq-qv__sheet, .btq-qv__overlay { transition: none !important; }
}

/* ==========================================================================
   MOBILE POLISH BATCH (owner QA list) — cards / footer / drawer / floaters
   ========================================================================== */
/* 1 · CARDS: significantly more products per screen (image 1:1 -> 4:5 crop, tighter type) */
.btq-card__media { aspect-ratio: 4/5; }
.btq-card__img { padding: 2px; }
.btq-card__body { padding: 6px 9px 4px; gap: 0; }
.btq-card__brand { font-size: 9px; letter-spacing: .09em; }
.btq-card__name { font-size: 13.5px; line-height: 1.2; }
.btq-card__price { font-size: 13.5px; margin-top: 1px; }
.btq-card__size { font-size: 11.5px; }
.btq-card__trust { display: none; }              /* trust lives sitewide; off the card = shorter cards */
.btq-card__add { width: 38px; height: 38px; min-height: 38px; bottom: 6px; right: 6px; }
.btq-grid { gap: 10px; }
/* 2 · MENU: sticky header + calmer rhythm */
#Drawer-Menu .drawer__header { border-bottom: 1px solid var(--btq-line); padding: 10px 16px !important; }
#Drawer-Menu .drawer__close { width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; }
.btq-menu { gap: 14px; padding-top: 8px; }
.btq-menu__primary a { min-height: 50px; font-size: 16px; }
/* 3 · FOOTER: compact, lighter, premium */
#shopify-section-sections--27367619166521__footer, [id*="__footer"] { --p: 0; }
[id*="__footer"] .accordion__title, [id*="__footer"] summary { min-height: 46px !important; padding-block: 10px !important; font-size: 13.5px !important; letter-spacing: .04em; }
[id*="__footer"] .footer__content-top, [id*="__footer"] .footer-block { padding-block: 10px !important; }
[id*="__footer"] { padding-block: 16px 8px !important; font-size: 13px; }
[id*="__footer"] img[src*="logo"], [id*="__footer"] .footer__logo img { max-width: 150px !important; height: auto; }
[id*="__footer"] .newsletter-form__field-wrapper input { min-height: 46px; font-size: 15px; }
/* 4 · FLOATING WIDGETS: kill on mobile at every level (previous selector missed the host) */
@media (max-width: 749px) {
  multitasking-bar, .multitasking-bar, [class*="multitasking"], .multi-t, .multi-t__wrap,
  .multi-t__button, [class*="multi-t__"], .glider { display: none !important; visibility: hidden !important; }
}
/* 5 · CART DRAWER: tighter line items, no dead space */
#CartDrawer .cart-item { padding-block: 10px; }
#CartDrawer .drawer__header { padding-block: 10px !important; }

/* ==========================================================================
   CARD v7 — badge · image · smaller eye · brand · name · price · 2 trust marks
   ========================================================================== */
.btq-card { height: 100%; }                        /* equal heights across the grid */
.btq-grid > .btq-card, .btq-shelf .btq-card { align-self: stretch; }
.btq-card__link { height: 100%; }
.btq-card__body { display: flex; flex-direction: column; gap: 1px; padding: 8px 10px 10px; flex: 1 1 auto; }
/* single premium badge */
.btq-card__badge { position: absolute; top: 8px; left: 8px; z-index: 2;
  font-size: 9.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  background: rgba(255,255,255,.94); color: var(--btq-pink-deep);
  border: 1px solid rgba(194,17,126,.18); border-radius: 999px; padding: 4px 9px;
  backdrop-filter: blur(4px); box-shadow: 0 1px 3px rgba(26,26,26,.06); }
.btq-card__badge--out { background: rgba(26,26,26,.88); color: #fff; border-color: transparent; }
/* eye button −20% (38 -> 30) so the product stays the focus */
.btq-card__media .btq-card__add { width: 30px; height: 30px; min-height: 30px; bottom: 8px; right: 8px;
  box-shadow: 0 2px 6px rgba(194,17,126,.22); }
.btq-card__add .btq-icon { width: 15px; height: 15px; }
/* two premium trust marks (replaces livraison/paiement duplication) */
.btq-card__assure { display: flex; align-items: stretch; gap: 6px; margin-top: 7px;
  padding-top: 7px; border-top: 1px solid var(--btq-line); }
.btq-card__assure-item { display: flex; align-items: center; gap: 4px; flex: 1 1 0; min-width: 0;
  font-size: 9.5px; line-height: 1.15; color: var(--btq-ink-soft); }
.btq-card__assure-item + .btq-card__assure-item { border-left: 1px solid var(--btq-line); padding-left: 6px; }
.btq-card__assure-item .btq-icon { color: var(--btq-pink-deep); flex: 0 0 auto; }
/* rhythm + no wrapping/cropping */
.btq-card__name { font-size: 14px; font-weight: 650; margin-bottom: 1px; }
.btq-card__price { font-size: 14px; }
.btq-card--out .btq-card__img { opacity: .55; }

/* ==========================================================================
   CARD v8 — density pass (owner: −15/25%, kill empty space)
   ROOT CAUSE of the white band: 4:5 media holding SQUARE source images →
   empty letterbox bands. Square media matches the assets: no bands, no crop,
   bigger perceived product, ~20% less height.
   ========================================================================== */
.btq-card__media { aspect-ratio: 1 / 1; }
.btq-card__img { padding: 0; object-fit: contain; }
.btq-card__body { padding: 7px 8px 8px; gap: 0; }
.btq-card__brand { font-size: 8.5px; letter-spacing: .1em; line-height: 1.4; }
.btq-card__name { font-size: 13px; line-height: 1.18; margin: 0; }
.btq-card__price { font-size: 13px; margin-top: 2px; }
.btq-card__size { font-size: 11px; }
/* eye −20% (30 → 24) — supports, never dominates */
.btq-card__media .btq-card__add { width: 24px; height: 24px; min-height: 24px; bottom: 6px; right: 6px;
  box-shadow: 0 1px 4px rgba(194,17,126,.20); }
.btq-card__add .btq-icon { width: 12px; height: 12px; }
/* trust marks −18%: smaller icons, smaller type, tighter, same baseline */
.btq-card__assure { margin-top: 5px; padding-top: 5px; gap: 4px; align-items: center; }
.btq-card__assure-item { font-size: 8.5px; line-height: 1.15; gap: 3px; align-items: center; }
.btq-card__assure-item + .btq-card__assure-item { padding-left: 4px; }
.btq-card__assure-item .btq-icon { width: 11px; height: 11px; }
.btq-card__badge { font-size: 8.5px; padding: 3px 7px; top: 6px; left: 6px; }
.btq-grid { gap: 9px; }
/* ==========================================================================
   CART PAGE — single summary (owner: "only ONE order summary")
   The drawer was fixed earlier; the PAGE still printed «Total estimé» above
   the COD card, repeating the same number twice.
   ========================================================================== */
.template-cart .totals, .template-cart .totals + small,
.template-cart [class*="tax-note"] { display: none !important; }

/* ==========================================================================
   COLLECTION HEADER — bugs caught in the v8 verification screenshot
   ========================================================================== */
/* 1 · breadcrumb clipped at BOTH edges: the list scrolls (overflow-x-a) but is
      justify-center, so a list wider than the viewport hides its head AND tail.
      Left-align it so it reads from "Accueil" and scrolls forward naturally. */
.breadcrumbs__list { justify-content: flex-start !important; padding-inline: 16px; }
.breadcrumbs__item { font-size: 12px; }
/* 2 · REMOVED — the stacked padding was not a CSS problem. It came from real
      section settings in templates/collection.json (banner 36/36, product-grid
      padding_top 36, text blocks 26/20 and 0/20). Fixed at source there; keeping
      overrides here would have been a mask, and would fight the Theme Editor the
      next time the merchant touches spacing. */
/* 3 · "AFFICHER EN TANT QUE" wrapped to two ALL-CAPS lines for a control whose
      two icons are self-evident — the label is pure noise on mobile. */
@media (max-width: 749px) { .switcher-grid__label { display: none !important; } }
/* 4 · "Filtrer" rendered in the theme's residual BLUE (rgba(0,15,159,.85)). */
.mobile-facets__open-label, .mobile-facets__open svg { color: var(--btq-pink-deep) !important; }
/* 5 · the 68px "empty" band under the description was not empty: the collapsed
      preview still laid out the full RTE (two <br> pairs + trailing <p>s) and
      merely clipped it. Collapse the line breaks inside the PREVIEW only, so the
      clamp measures real text — the expanded state keeps the merchant formatting. */
@media (max-width: 749px) {
  .collection-description-preview { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
    overflow: hidden; font-size: 13.5px; line-height: 1.5; }
  .collection-description-preview br { display: none; }
  .collection-description-preview p { display: inline; }
  .collection-description-preview p + p::before { content: ' · '; color: var(--btq-pink-deep); }
}
/* 6 · REMOVED for the same reason as (2) — see templates/collection.json. */



/* ==========================================================================
   DRAWER BACKDROP — rewritten after measuring why the previous attempt failed.
   The theme's own .drawer__overlay is unusable: its parent #Drawer-Menu computes
   opacity:0 / visibility:hidden (the theme sets data-moved and renders the visible
   panel elsewhere), and a child can never be more opaque than its parent. Three
   attempts at restyling that element were therefore doomed regardless of
   specificity — even an !important opacity:1 measured as computed 0.
   Render the backdrop from BODY instead, which nothing can suppress.
   body.overflow-hidden is the theme's real open-state signal (verified: present
   while any drawer is open, removed on close).
   Ladder: announcement 14 < backdrop 17 < drawer 19 < modals 20.
   ========================================================================== */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  background: rgba(26, 26, 26, .46);
  z-index: 17;
  opacity: 0;
  pointer-events: none;
  transition: opacity .24s ease-out;
}
body.overflow-hidden::after { opacity: 1; }
@media (prefers-reduced-motion: reduce) { body::after { transition-duration: .01ms; } }
/* keep the theme's stranded overlay out of the way entirely */
#Drawer-Menu .drawer__overlay, cart-drawer .drawer__overlay { background: transparent; }
/* the panel must stay above its own overlay */
#Drawer-Menu .drawer__inner, cart-drawer .drawer__inner { position: relative; z-index: 2; }
@media (prefers-reduced-motion: reduce) {
  #Drawer-Menu .drawer__overlay, cart-drawer .drawer__overlay { transition-duration: .01ms; }
}

/* ==========================================================================
   CART DRAWER — dead space below the last product.
   Measured with 3 items in the cart: 283px of empty white between the last row
   and the note/promo row. Cause: CART-DRAWER-ITEMS carries the theme's `h-full`
   utility, so the list box is forced to full height (732px) regardless of the
   ~321px of actual rows. Let it size to content and only scroll once it genuinely
   overflows.
   ========================================================================== */
#CartDrawer cart-drawer-items,
cart-drawer cart-drawer-items.h-full {
  height: auto !important;
  flex: 0 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}
#CartDrawer .cart-items__wrapper, #CartDrawer .cart__items { height: auto !important; }
/* the note / promo row was 102px for two rarely-used controls in a COD store where
   shipping is a flat 7 TND — keep them reachable, stop them dominating the drawer */
#CartDrawer .cart__note.field { height: auto; }
#CartDrawer .cart__note .modal-opener,
#CartDrawer .cart__note button { min-height: 44px; padding-block: 10px; font-size: 12.5px; }
#CartDrawer .cart__note svg { width: 15px; height: 15px; }

/* ==========================================================================
   ANNOUNCEMENT BAR — the owner's reported "messages overlap" bug, reproduced
   and root-caused rather than guessed.
   Measured: swiper-component.announcement-bar has 3 slides, ALL position:relative
   and ALL at the same top:8 — they occupy the same box. swiper-fade crossfades by
   opacity, so mid-transition the outgoing slide is still partly opaque and paints
   THROUGH the incoming one. A screenshot caught "LIVRAISON OFFERTE DES 100 TND"
   overlapping the next message.
   Fix: only the active slide may paint. visibility (not display) so no reflow and
   no layout shift — the bar's height never changes.
   ========================================================================== */
.announcement-bar .swiper-slide,
.announcement-bar-slider .swiper-slide { visibility: hidden; }
.announcement-bar .swiper-slide-active,
.announcement-bar-slider .swiper-slide-active { visibility: visible; }
/* the rotation must not run underneath an open drawer — a message changing behind
   the menu or cart is what made this read as a glitch */
body.overflow-hidden .announcement-bar .swiper-wrapper,
body.overflow-hidden .announcement-bar-slider .swiper-wrapper {
  transition: none !important;
  animation-play-state: paused !important;
}

/* ==========================================================================
   CART DRAWER — the 283px void below the last product.
   Measured with 3 items: cart-drawer-items computes 692px against ~321px of rows.
   NOTE ON SELECTORS: #CartDrawer is the inner DIV.cart-drawer; the custom element
   is <cart-drawer id="Cart-Drawer">. Both are used below deliberately so the rules
   hold whichever node the theme renders, without lowering specificity on the
   existing #CartDrawer layer.
   ========================================================================== */
#CartDrawer cart-drawer-items, cart-drawer cart-drawer-items,
#CartDrawer cart-drawer-items.h-full, cart-drawer cart-drawer-items.h-full {
  height: auto !important;
  min-height: 0 !important;
  flex: 0 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
}
#CartDrawer .cart-items__wrapper, cart-drawer .cart-items__wrapper,
#CartDrawer .cart__items, cart-drawer .cart__items,
#CartDrawer .js-contents, cart-drawer .js-contents,
#CartDrawer table.cart-items, cart-drawer table.cart-items {
  height: auto !important;
  min-height: 0 !important;
}



/* ---------- beautica-easysell.css (source: assets/beautica-easysell.css) ---------- */
/* ==========================================================================
   BEAUTICA — ONE PRIMARY ACTION + EASYSELL COD NATIVE SKIN
   Owner brief: (a) remove "Acheter maintenant" from every product page, leave
   no dead space; (b) make the EasySell COD order form look like one premium
   site, not two systems bolted together.

   CONCATENATION: append this file into assets/beautica-custom.css BEFORE the
   "/* ==== END GENERATED PARTS ==== *\/" marker and AFTER the beautica-card.css
   section. Only beautica-custom.css is <link>ed (layout/theme.liquid:74) — a
   standalone beautica-easysell.css asset is never loaded by the theme.

   --------------------------------------------------------------------------
   SELECTORS CONFIRMED against real repo markup (file:line):
     .accelerated-checkout-block             blocks/accelerated-checkout.liquid:94
     .checkout--button-secondary  (modifier) blocks/accelerated-checkout.liquid:94
     .shopify-payment-button__button         assets/base.css:9657   (Shopify-emitted)
     .shopify-payment-button__button--unbranded  assets/base.css:9976
     .shopify-payment-button__more-options   assets/base.css:9971
     more-payment-options-link  (element)    assets/base.css:9958
     .product-form__buttons  + --gap         blocks/buy-buttons.liquid:102-108
     .buy-buttons-block                      assets/base.css:9625
     .add-to-cart-button-container           blocks/add-to-cart.liquid:38
     .add-to-cart-button-inner               blocks/add-to-cart.liquid:42
     button[name="add"].button               beautica-custom.css:305 (primary CTA spec)
     .field / .field__input / .field__label  assets/base.css:3080-3130
     .product-details                        used throughout beautica-pdp.css
     .shopify-app-block / [id^="shopify-block-"]
                                             Shopify theme-app-extension wrapper
                                             (platform-emitted, not app-specific)

   NOT CONFIRMED — EasySell ships ZERO markup into this repo. Verified by:
     grep -rn -i "easysell" over *.liquid *.json *.css *.js  -> 0 hits
     config/settings_data.json app embeds   -> only hiko-social-login and
                                               google-youtube. No EasySell.
   Therefore EVERY EasySell-specific class name is unknown. Per the project's
   hard-won lesson #1, no guessed EasySell selector is shipped live in this
   file. Section 3 is a variable-driven skin that activates only once the
   orchestrator stamps the real container (see the instructions there).
   ========================================================================== */


/* --------------------------------------------------------------------------
   1. KILL "ACHETER MAINTENANT" (Shopify dynamic / accelerated checkout)

   SOURCE-LEVEL ATTEMPT (already made): templates/product.json now carries
     sections.main.blocks.product-details.blocks.buy_buttons_eYQEYi
       .blocks.accelerated-checkout -> "disabled": true
   WHY CSS IS STILL REQUIRED: there is no show_dynamic_checkout setting on the
   block that actually renders. snippets/buy-buttons.liquid:21-23 has one, but
   that snippet is the LEGACY path — this template renders blocks/buy-buttons
   .liquid, which emits the payment button through an unconditional
     {% content_for 'block', type: 'accelerated-checkout', id: ... %}   (:129-134)
   and blocks/accelerated-checkout.liquid:104-107 prints {{ form_obj |
   payment_button }} with no enable/disable checkbox in its schema (:114-185).
   Static blocks are rendered by content_for regardless of block_order, so the
   "disabled" flag may well be ignored by the platform. The flag is harmless
   and reversible either way; this rule is the guarantee.
   -------------------------------------------------------------------------- */

/* Global, not scoped to .product-details: the owner asked for ONE primary
   action on ALL product surfaces (main PDP, quick-add modal, featured-product
   sections). The cart's own checkout CTA uses .cart__checkout-button and is
   NOT matched here. */
.accelerated-checkout-block,
.product-form__buttons .accelerated-checkout-block,
.product-form__buttons .shopify-payment-button,
.product-form__buttons .shopify-payment-button__button,
.product-form__buttons more-payment-options-link,
.shopify-payment-button__more-options {
  display: none !important;
}


/* --------------------------------------------------------------------------
   2. CLOSE THE GAP LEFT BEHIND

   MEASUREMENT / HONEST ACCOUNTING. .product-form__buttons is
   `display:flex; flex-wrap:wrap; gap:var(--gap)` (base.css:9630-9635) with
   --gap:10px from the block setting. Its flex children are:
       quantity selector · add-to-cart container · hidden error span ·
       accelerated-checkout-block
   Reclaimed by removing the last child:
       payment button   ~50px  (min-height:50px, beautica-custom.css:319-326)
       + one 10px flex row-gap
       = ~60px of vertical space, on every product page.
   Flex `gap` is only drawn BETWEEN rendered items, so display:none removes
   the gap with the button — there is no orphan 10px band to chase. The
   agree-condition wrapper (a further 20+20px of padding) was already off
   (agree_condition:false) and its paddings are now zeroed in product.json too,
   so it cannot reappear if the setting is ever re-enabled by accident.

   The rules below are defensive: they make sure nothing that used to sit
   alongside the payment button now keeps a margin reserved for it, and that
   the surviving CTA goes truly full-width instead of flex-sharing the row.
   -------------------------------------------------------------------------- */

.product-form__buttons {
  /* wrap-row gap no longer needs to double as the ATC/payment-button gap */
  row-gap: 8px;
}

/* The remaining CTA is now the only action — let it own the full row. */
.product-form__buttons > .add-to-cart-button-container {
  flex: 1 1 100%;
  min-width: 100%;
}

/* No block-level margin may survive under the now-single CTA. */
.buy-buttons-block,
.product-details .buy-buttons-block {
  margin-block-end: 0;
}
.add-to-cart-button-inner {
  margin-block-end: 0;
}


/* --------------------------------------------------------------------------
   3. EASYSELL COD — NATIVE SKIN  (ACTIVATION REQUIRED)

   *** READ BEFORE ENABLING ***
   EasySell's DOM is not in this repo, so its class names are unknown and NONE
   are guessed here. This section is written against ONE hook the orchestrator
   controls: the attribute [data-btq-easysell] on EasySell's outermost
   container. Nothing below applies until that attribute exists.

   ORCHESTRATOR — to activate, do exactly this in the live preview DOM:
     1. Open a product page, find EasySell's wrapper. Likely shapes, in order:
        a) a theme app-extension block:  [id^="shopify-block-"] .shopify-app-block
        b) an inline <div> injected by a ScriptTag
        c) a custom element
     2. Copy its REAL outermost selector.
     3. Add ONE line to this file mapping it to the hook, e.g.
          <real-selector> { }            /* alias, see note */
        or, preferred, replace every `[data-btq-easysell]` below with the real
        selector via find-and-replace. Do not add both.
     4. Re-verify the field/button/label sub-selectors the same way — the
        descendant selectors below use only GENERIC element selectors
        (input, select, textarea, label, button[type=submit]) precisely so they
        survive without knowing EasySell's class names.

   Everything in 3.1 is scoped inside [data-btq-easysell]; with the attribute
   absent these rules match nothing and cost nothing. They cannot leak.
   -------------------------------------------------------------------------- */

[data-btq-easysell] {
  /* one typographic system, not two */
  font-family: "Cabin", var(--font-body--family), sans-serif;
  color: var(--btq-ink, #1A1A1A);
  background: var(--btq-surface, #fff);
  border: 1px solid var(--btq-line, #EBE6EA);
  border-radius: var(--btq-radius-card, 12px);
  padding: 14px;
  margin-block: 12px 0;
  -webkit-font-smoothing: antialiased;
}

/* 3.1 — form fields matched to the theme's .field__input rhythm */
[data-btq-easysell] input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]),
[data-btq-easysell] select,
[data-btq-easysell] textarea {
  width: 100%;
  min-height: 46px;              /* >= 44px tap target */
  box-sizing: border-box;
  padding: 10px 12px;
  font-family: inherit;
  font-size: 15px;               /* >= 16px avoids iOS zoom; 15 matches theme */
  line-height: 1.35;
  color: var(--btq-ink, #1A1A1A);
  background: var(--btq-surface, #fff);
  border: 1px solid var(--btq-line, #EBE6EA);
  border-radius: 10px;
  transition: border-color .18s ease-out, box-shadow .18s ease-out;
}

[data-btq-easysell] input:focus,
[data-btq-easysell] select:focus,
[data-btq-easysell] textarea:focus,
[data-btq-easysell] input:focus-visible,
[data-btq-easysell] select:focus-visible,
[data-btq-easysell] textarea:focus-visible {
  outline: none;
  border-color: var(--btq-pink-deep, #C2117E);
  box-shadow: 0 0 0 3px rgba(194, 17, 126, .12);
}

[data-btq-easysell] input::placeholder,
[data-btq-easysell] textarea::placeholder {
  color: var(--btq-ink-soft, #5C5C66);
  opacity: 1;
}

[data-btq-easysell] label {
  display: block;
  font-size: 13px;               /* above the 12px readable floor */
  font-weight: 600;
  color: var(--btq-ink, #1A1A1A);
  margin: 0 0 5px;
  letter-spacing: .01em;
}

/* 3.2 — submit button: byte-for-byte the primary CTA spec from
   beautica-custom.css:305-318 (button[name="add"].button) */
[data-btq-easysell] button[type="submit"],
[data-btq-easysell] input[type="submit"] {
  width: 100%;
  min-height: 52px;
  padding: 12px 20px;
  background: var(--btq-pink-deep, #C2117E);
  border: 1.5px solid var(--btq-pink-deep, #C2117E);
  color: #fff;
  border-radius: var(--btq-radius-btn, 10px);
  font-family: inherit;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: .02em;
  cursor: pointer;
  transition: background-color .18s ease-out, transform .12s ease-out;
}
[data-btq-easysell] button[type="submit"]:hover,
[data-btq-easysell] input[type="submit"]:hover {
  background: #A50E6B;
  border-color: #A50E6B;
}
[data-btq-easysell] button[type="submit"]:active,
[data-btq-easysell] input[type="submit"]:active {
  transform: scale(.985);
}
[data-btq-easysell] button[type="submit"]:focus-visible {
  outline: 2px solid var(--btq-pink-deep, #C2117E);
  outline-offset: 2px;
}
[data-btq-easysell] button[type="submit"][disabled] {
  opacity: .5;
  cursor: not-allowed;
  transform: none;
}

/* 3.3 — quantity / choice controls keep the brand accent */
[data-btq-easysell] input[type="checkbox"],
[data-btq-easysell] input[type="radio"] {
  accent-color: var(--btq-pink-deep, #C2117E);
  min-width: 20px;
  min-height: 20px;
}

/* 3.4 — mobile */
@media screen and (max-width: 749px) {
  [data-btq-easysell] {
    padding: 12px;
    margin-block: 10px 0;
  }
  [data-btq-easysell] input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]),
  [data-btq-easysell] select,
  [data-btq-easysell] textarea {
    font-size: 16px;             /* prevents the iOS focus zoom on mobile */
  }
  [data-btq-easysell] button[type="submit"],
  [data-btq-easysell] input[type="submit"] {
    min-height: 52px;
    font-size: 15.5px;
  }
}

@media (prefers-reduced-motion: reduce) {
  [data-btq-easysell] * {
    transition: none !important;
  }
}

/* 3.5 — NO DOUBLE CTA. Once EasySell is the primary flow, its submit button
   and the theme's "Ajouter au panier" must not read as two equal actions.
   This is deliberately NOT shipped enabled: whether ATC should be demoted to
   a secondary outline button or removed entirely is the OWNER's call, and it
   depends on where EasySell actually mounts relative to the buy buttons.
   Orchestrator: confirm placement in the live DOM, then uncomment ONE.

   -- demote ATC to secondary (recommended: keeps cart flow available) --
   .product-details button[name="add"].button {
     background: #fff !important;
     color: var(--btq-pink-deep, #C2117E) !important;
     border: 1.5px solid var(--btq-pink-deep, #C2117E) !important;
   }

   -- or remove ATC entirely, leaving EasySell as the only action --
   .product-details .add-to-cart-button-container { display: none !important; }
*/


/* --------------------------------------------------------------------------
   4. SAFE CROSS-SYSTEM TYPOGRAPHY (ships live — no guessed class names)

   .shopify-app-block is platform-emitted markup for ANY theme app extension,
   not an EasySell-specific guess. Only inherited, non-structural properties
   are set, so if EasySell mounts some other way this is a harmless no-op, and
   if another app block matches it simply inherits the site font — which is the
   desired outcome anyway ("one premium website").
   Scoped to the product details column so it cannot touch the footer/header
   embeds (hiko-social-login, google-youtube).
   -------------------------------------------------------------------------- */

.product-details .shopify-app-block,
.product-details [id^="shopify-block-"] {
  font-family: "Cabin", var(--font-body--family), sans-serif;
  color: var(--btq-ink, #1A1A1A);
}

/* ==== BEGIN GENERATED PARTS (do not edit below; edit the part files) ==== */

/* ---------- beautica-announce.css ---------- */
/* ==========================================================================
   BEAUTICA — ANNOUNCEMENT BAR x OPEN DRAWERS
   Owner bug: the rotating announcement bar ("IMPOSSIBLE A IGNORER",
   "Livraison 24-48h partout en Tunisie") stays painted ON TOP of the open menu
   drawer and the open cart drawer, and keeps changing text underneath them.

   ROOT CAUSE — read from the code, not guessed
   --------------------------------------------
   1. STACKING. assets/beautica-custom.css:527 carries a "header stacking guard"
      added in an earlier session (owner photo: cards visible over the header):

          #header-group, #header-group .shopify-section, sticky-header,
          .header-wrapper, header.header { position:relative; z-index:40;
                                           background:#fff; }

      The announcement bar section IS a `#header-group .shopify-section` —
      sections/announcement-bar.liquid declares
      `"class": "section-header section-announcement-bar"` — so it silently
      became position:relative, z-index:40, opaque white.

      Both drawers relocate themselves to <body> on connect
      (`document.body.appendChild(this)` in details-disclosure.js -> SideDrawer,
      and the identical line in cart-drawer.js) and are position:fixed with
          .drawer { z-index: var(--layer-menu-drawer) }   ->  18
      (value from snippets/global-style.liquid). 18 < 40, so the announcement
      bar — and the header row with it — paints straight through the drawer
      overlay AND the drawer panel, on every template.

      `#header-group` itself flips to `display:contents` when the header is
      sticky (base.css:19403), which voids the guard's z-index on the GROUP.
      It is the PER-SECTION z-index:40 that does the damage, which is why the
      bar survives above the drawer on every page.

      40 was an arbitrary number. The only thing the guard actually has to
      clear is <main id="MainContent" class="... relative z-2"> (theme.liquid).
      Everything from --layer-overlay (16) upwards is modal furniture that must
      be ABOVE the header, not below it.

   2. ROTATION. blocks/_group-announcement.liquid renders
      <swiper-component class="announcement-bar"> as soon as there is more than
      one message. sections/header-group.json holds 3 messages with
      autoplay:true / autoplay_speed:5, and assets/global.js (SwiperComponent)
      builds it with effect:"fade", crossFade:true, disableOnInteraction:false
      and only pauseOnMouseEnter:true. Nothing stops that timer when a drawer
      opens — which is exactly why the owner's two screenshots show two
      different messages behind two different open drawers.

   WHAT THIS FILE DOES
   -------------------
   Declares one coherent z-index scale and applies it. Nothing is hidden and
   nothing leaves the document flow, so the fix cannot cause layout shift.
   The rotation pause needs a JS timer and therefore lives in
   sections/announcement-bar.liquid.

   Selector specificity is deliberately raised above the guard's so the result
   does not depend on the order the orchestrator concatenates the part files.
   ========================================================================== */

/* --------------------------------------------------------------------------
   THE SCALE. Monotonic, every rung applied, no gaps invented for their own
   sake. Theme reference (snippets/global-style.liquid): --layer-overlay 16,
   --layer-menu-drawer 18, --layer-sidebar 19, --layer-temporary 20.

     2   <main> content .......... theme.liquid `.z-2`
     14  announcement bar ........ --btq-z-announce
     15  header .................. --btq-z-header      (was the arbitrary 40)
     16  modal / popup backdrop .. --btq-z-overlay     (= theme --layer-overlay)
     19  drawer container ........ --btq-z-drawer      (= theme --layer-sidebar)
     20  drawer's own dialogs .... --btq-z-modal       (must clear the drawer)
     21  add-to-cart toast ....... --btq-z-toast       (must clear all of it)

   Inside a drawer, the backdrop rung is -1: it is a DIRECT CHILD of the
   drawer element (verified: snippets/cart-drawer.liquid:8 and
   sections/header_mobile.liquid:21 both put #...-Overlay inside the custom
   element), and the drawer is position:fixed + z-index:19, i.e. its own
   stacking context. -1 therefore means "behind the panel, in front of
   EVERYTHING outside the drawer" — the whole page including the announcement
   bar at 14 is dimmed and the backdrop is the topmost hit target outside the
   panel, so click-to-close works. -1 is only inert when the ancestor makes no
   stacking context, which is not the case here.

   --btq-z-overlay / --btq-z-drawer / --btq-z-toast are also declared by
   assets/beautica-atc.css:12-14 with these exact values, by prior agreement,
   so concatenation order is irrelevant. Do not diverge without updating both.
   --btq-z-announce / --btq-z-header / --btq-z-drawer-overlay / --btq-z-modal
   are declared here only. Every var() below carries its literal as a fallback,
   so this file is correct even if it is served on its own.

   Nothing here removes an element from flow or changes any height: the only
   suppression is pointer-events (rule 5) and opacity on swiper-fade slides
   that are already absolutely positioned. No layout shift is possible.
   -------------------------------------------------------------------------- */
:root {
  --btq-z-announce: 14;
  --btq-z-header: 15;
  --btq-z-overlay: 16;
  --btq-z-drawer: 19;
  --btq-z-drawer-overlay: -1; /* backdrop, INSIDE the drawer's own context */
  --btq-z-modal: 20;
  --btq-z-toast: 21;
}

/* --------------------------------------------------------------------------
   1. The announcement bar gets its own rung — still above page content, now
   unambiguously below every piece of modal furniture.

   It stays position:relative and stays in normal flow: the section keeps
   reserving exactly the same height it does today, so there is no reflow when
   a drawer opens or closes.

   Specificity (1,2,1) beats the guard's `#header-group .shopify-section`
   (1,1,0) regardless of source order.
   -------------------------------------------------------------------------- */
body #header-group .shopify-section.section-announcement-bar {
  position: relative;
  z-index: var(--btq-z-announce, 14);
}

/* --------------------------------------------------------------------------
   2. Same correction for the rest of the header guard, because the bar and the
   header row are one visual block — fixing only the bar would leave the logo
   and cart icon punched through the open drawer, which is the same defect.

   The guard's purpose is preserved: 15 still clears <main>'s z-index 2, so
   product cards cannot climb over the header again. Only the modal furniture
   above 16 changes side, which is the correction being made.

   Each selector below outranks its counterpart in the guard by exactly one
   `body`, so this holds whichever way the parts are concatenated.
   -------------------------------------------------------------------------- */
body #header-group,
body #header-group .shopify-section:not(.section-announcement-bar),
body sticky-header,
body .header-wrapper,
body header.header {
  z-index: var(--btq-z-header, 15);
}

/* --------------------------------------------------------------------------
   3. Drawers pinned to their rung explicitly instead of inheriting the theme's
   --layer-menu-drawer. Covers both menu-drawer variants
   (sections/header_mobile.liquid is the live one, snippets/header-drawer.liquid
   the fallback) and the cart drawer.

   `side-drawer.drawer` is (0,1,1) and beats both `.drawer` (0,1,0) and the
   markup's `.z-9` utility (0,1,0) on source-order-independent grounds.

   A closed drawer is visibility:hidden + opacity:0 + pointer-events:none, so
   this changes nothing at all until one is actually opened.
   -------------------------------------------------------------------------- */
side-drawer.drawer,
cart-drawer.drawer {
  z-index: var(--btq-z-drawer, 19);
}

/* The backdrop is a CHILD of the drawer, so it lives inside the drawer's own
   stacking context: -1 keeps it behind the panel while still covering the whole
   page, announcement bar included. Re-asserted here so that a later change to
   either rung can never strand it. */
side-drawer.drawer > .drawer__overlay,
cart-drawer.drawer > .drawer__overlay {
  z-index: var(--btq-z-drawer-overlay, -1);
}

/* --------------------------------------------------------------------------
   3b. The cart drawer's OWN dialogs — "Ajouter une note", carte-cadeau, code
   promo (snippets/cart-drawer.liquid:203/247/284/320). They are
   <modal-component class="modal-component modal--popup ... z-9">, and
   ModalComponent.connectedCallback() (assets/cart-drawer.js:222-227) runs
   `document.body.appendChild(this)`. At open time they are therefore SIBLINGS
   of <cart-drawer>, not descendants — nothing about being "inside" the drawer
   in the Liquid source survives to runtime.

   Their painted rung is min(.z-9 = 9, .modal--popup = --layer-menu-drawer 18),
   both far below the drawer's 19. A sibling below the drawer opens BEHIND the
   full-viewport drawer panel and is simply invisible: tapping "Ajouter une
   note" would look like it did nothing. They must sit one rung ABOVE the
   drawer that spawned them, and one below the toast.

   Specificity (0,2,1) beats base.css's `.modal--popup` (0,1,0) and the `.z-9`
   utility (0,1,0) regardless of source order. Scoped to `modal-component` on
   purpose: quick-add / quick-view / video are also `.modal--popup` but are
   never co-open with a drawer, and raising them above 19 could invert them
   against the cart drawer that quick-add itself opens.
   -------------------------------------------------------------------------- */
body modal-component.modal--popup {
  z-index: var(--btq-z-modal, 20);
}

/* --------------------------------------------------------------------------
   4. Fade-carousel invariant: exactly one message visible at a time.

   Swiper's fade effect stacks all three slides on top of each other and drives
   them with INLINE opacity. Inline styles outrank this rule, so the crossfade
   itself is untouched — this only covers the window between `swiper-initialized`
   landing on the container and Swiper's first setTranslate() writing those
   inline opacities. That is the one moment all three messages can render on top
   of one another, i.e. the literal "messages overlap" the owner reported.
   (Before init the theme already guards it:
    `.swiper:not(.swiper-initialized) .swiper-wrapper.grid-layout--1
     .swiper-slide:not(:first-child) { display:none }` — base.css:4933.)
   -------------------------------------------------------------------------- */
.section-announcement-bar .swiper.swiper-fade .swiper-slide:not(.swiper-slide-active) {
  opacity: 0;
  pointer-events: none;
}

/* A mis-translated slide can never spill outside the bar. */
.section-announcement-bar .announcement-bar-slider.swiper {
  overflow: hidden;
}

/* --------------------------------------------------------------------------
   5. While a drawer is open the bar is fully covered by the backdrop, so it is
   NOT hidden — hiding a section that reserves height is precisely what causes
   layout shift. It is only made inert, so a tap that lands on the backdrop can
   never activate the link underneath it.

   `body.overflow-hidden` is added by SideDrawer.open() and CartDrawer.open()
   and removed by both close() methods.
   -------------------------------------------------------------------------- */
body.overflow-hidden #header-group .shopify-section.section-announcement-bar {
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   6. Motion preference.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .section-announcement-bar .swiper .swiper-slide {
    transition-duration: 0.01ms !important;
  }
}

/* ---------- beautica-drawer.css ---------- */
/* ==========================================================================
   BEAUTICA — MOBILE NAVIGATION DRAWER
   Owns: the #Drawer-Menu shell (panel, overlay, fixed header/X, scroll body)
         and the .btq-menu content rendered by snippets/beautica-menu.liquid.

   REAL DOM (read from sections/header_mobile.liquid — the live mobile drawer,
   NOT snippets/header-drawer.liquid which is the non-multi-tab variant):

     side-drawer#Drawer-Menu.drawer.drawer--menu.drawer--menu-multi-tab
       > #Drawer-Overlay-Menu.drawer__overlay
       > div.side-drawer[data-drawer-content]
           > div.drawer__inner.d-flex.flex-column.h-full
               > div.drawer__header   (contains button.drawer__close)
               > div.btq-menu         (our content — DIRECT child)
               > div.drawer__wrapper  (display:none, set in beautica-custom.css)

   REAL JS HOOKS (read from assets/details-disclosure.js — class SideDrawer):
     open()  -> adds .animate, .active, .open on side-drawer#Drawer-Menu
     close() -> removes .active, .open AFTER its await'ed animation finishes
     The panel SLIDE is driven by Motion One (WAAPI) on [data-drawer-content],
     not by CSS. We therefore do NOT declare a competing transform transition
     on that element — WAAPI would win and the two would fight. We keep the
     container's own opacity transition alive because SideDrawer.open() binds
     trapFocus() to 'transitionend'; killing it would break focus trapping.

   SPECIFICITY NOTE: rules here intentionally lead with `side-drawer#Drawer-Menu`
   (id + type + class) so they outrank the earlier `#Drawer-Menu .x` rules in
   beautica-custom.css regardless of concatenation order.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. OVERLAY — elegant fade, calm backdrop
   The theme fades the whole .drawer container (opacity + visibility) on
   .active. We retune the timing on this drawer only and restyle the scrim.
   -------------------------------------------------------------------------- */
side-drawer#Drawer-Menu {
  transition-property: opacity, visibility;
  transition-duration: 220ms;
  transition-timing-function: cubic-bezier(0.22, 0.61, 0.36, 1);
}

side-drawer#Drawer-Menu #Drawer-Overlay-Menu,
side-drawer#Drawer-Menu #Drawer-Overlay-Menu:empty {
  background-color: rgba(26, 26, 26, 0.44);
}

/* --------------------------------------------------------------------------
   2. PANEL — fixed, so no ancestor overflow can ever clip or scroll it.
   Width formula is copied from the theme so nothing shifts.
   RTL-guarded: this drawer is left-anchored and the store is French/LTR.
   -------------------------------------------------------------------------- */
html:not([dir='rtl']) side-drawer#Drawer-Menu [data-drawer-content] {
  position: fixed;
  top: 0;
  left: 0;
  height: 100dvh;
  max-height: 100dvh;
  width: min(calc(100% - var(--minimum-touch-target, 44px)), var(--drawer-max-width, var(--narrow-content-width)));
  background-color: var(--btq-surface, #fff);
  backface-visibility: hidden;
}

@supports not (height: 100dvh) {
  html:not([dir='rtl']) side-drawer#Drawer-Menu [data-drawer-content] {
    height: 100vh;
    max-height: 100vh;
  }
}

/* will-change only while open — dropped automatically when .active is removed */
side-drawer#Drawer-Menu.active [data-drawer-content] {
  will-change: transform, opacity;
}

/* --------------------------------------------------------------------------
   3. SHELL — .drawer__inner stops being the scroller.
   Previously .drawer__inner scrolled, which is why the X scrolled away and
   got clipped. Now it is a non-scrolling flex column: header pinned, body
   scrolls inside itself.
   -------------------------------------------------------------------------- */
side-drawer#Drawer-Menu .drawer__inner {
  display: flex !important;
  flex-direction: column !important;
  height: 100% !important;
  max-height: 100% !important;
  min-height: 0 !important;
  overflow: hidden !important;
  overscroll-behavior: contain;
}

/* --------------------------------------------------------------------------
   4. HEADER + CLOSE (X) — pinned by flex AND sticky (belt and braces), opaque,
   above the scrolling list. It can no longer scroll away or be overlapped.

   ROOT CAUSE of the owner's "X scrolls away and gets clipped" bug, found in
   assets/base.css:12575 —

     .drawer--menu-multi-tab .drawer__header:has(.drawer__close) {
       width: fit-content; position: absolute; right: 0; left: auto; padding: 0;
     }

   An absolutely-positioned, fit-content header inside what used to be the
   scrolling .drawer__inner rides along with the content. We put it back in
   flow, full width, in a shell that no longer scrolls. The resets below are
   deliberate — dropping any one of them lets that rule partially win again.
   -------------------------------------------------------------------------- */
side-drawer#Drawer-Menu .drawer__inner > .drawer__header {
  position: sticky !important;
  top: 0;
  right: auto !important;
  left: auto !important;
  width: 100% !important;
  z-index: 3;
  flex: 0 0 auto !important;
  min-height: 56px;
  padding: 6px 10px !important;
  background: var(--btq-surface, #fff);
  border-bottom: 1px solid var(--btq-line, #ebe6ea);
}

side-drawer#Drawer-Menu .drawer__close {
  width: 44px;
  height: 44px;
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--btq-surface-soft, #faf7f9);
  color: var(--btq-ink, #1a1a1a);
  transition: background-color 160ms ease, transform 160ms ease;
}

side-drawer#Drawer-Menu .drawer__close:active {
  background: var(--btq-pink-soft, #fdf2f8);
  transform: scale(0.94);
}

side-drawer#Drawer-Menu .drawer__close .svg-wrapper,
side-drawer#Drawer-Menu .drawer__close svg {
  width: 18px;
  height: 18px;
}

side-drawer#Drawer-Menu .drawer__heading {
  font-size: 15px;
  letter-spacing: 0.02em;
}

/* --------------------------------------------------------------------------
   5. SCROLL BODY — .btq-menu is now the only scroller.
   flex: 1 1 auto is safe here (unlike the old crush bug) precisely BECAUSE
   it is a scroll container with min-height:0 — shrinking to the free space is
   the intended behaviour; the content scrolls inside instead of being clipped.
   -------------------------------------------------------------------------- */
side-drawer#Drawer-Menu .drawer__inner .btq-menu {
  flex: 1 1 auto !important;
  min-height: 0 !important;
  height: auto !important;
  overflow-y: auto !important;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  padding: 16px 16px calc(28px + env(safe-area-inset-bottom, 0px)) !important;
  gap: 18px;
}

/* .btq-menu is itself a flex column. Now that its own height is constrained,
   its children would SHRINK to fit instead of overflowing — that is the exact
   928px -> 393px crush recorded in the project notes. The scroll container may
   shrink; its children must not. Do not remove this rule. */
side-drawer#Drawer-Menu .drawer__inner .btq-menu > * {
  flex: 0 0 auto !important;
}

/* --------------------------------------------------------------------------
   6. CONTENT REFINEMENTS — scoped to .btq-menu only.
   The "Par occasion" chip row is gone (see beautica-menu.liquid); the block
   below styles its replacement, "Par famille olfactive", plus the new
   secondary "Bons plans" row.
   -------------------------------------------------------------------------- */

/* Section label */
.btq-menu .btq-menu__label {
  display: block;
  margin-bottom: 10px;
}

/* Olfactory-family tiles. Reuses the .btq-menu__familles DNA already defined
   in beautica-custom.css; this only refines it and handles the 7th tile. */
.btq-menu .btq-menu__familles {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.btq-menu .btq-menu__familles a {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 46px;
  padding: 10px 12px;
  border-radius: var(--btq-radius-btn, 10px);
  background: var(--btq-surface-soft, #faf7f9);
  box-shadow: inset 0 0 0 1px var(--btq-line, #ebe6ea);
  font-size: 14px;
  font-weight: 600;
  color: var(--btq-ink, #1a1a1a);
  text-decoration: none;
  transition: background-color 160ms ease, box-shadow 160ms ease;
}

.btq-menu .btq-menu__familles a .btq-icon {
  flex: 0 0 auto;
  color: var(--btq-pink-deep, #c2117e);
}

.btq-menu .btq-menu__familles a:active {
  background: var(--btq-pink-soft, #fdf2f8);
  box-shadow: inset 0 0 0 1px rgba(194, 17, 126, 0.24);
}

/* 7 tiles in a 2-col grid: the odd last one spans the row instead of leaving
   a hole. Purely presentational — no orphan gap, no filler link. */
.btq-menu .btq-menu__familles a:last-child:nth-child(odd) {
  grid-column: 1 / -1;
}

/* Secondary "Bons plans" row — deliberately lighter than the pink finder CTA
   so the drawer keeps exactly ONE primary call to action. */
.btq-menu__deals {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 56px;
  padding: 12px 14px;
  border-radius: var(--btq-radius-card, 12px);
  background: var(--btq-pink-soft, #fdf2f8);
  box-shadow: inset 0 0 0 1px rgba(194, 17, 126, 0.12);
  color: var(--btq-ink, #1a1a1a);
  text-decoration: none;
}

.btq-menu__deals span {
  flex: 1;
  line-height: 1.3;
  font-size: 14px;
}

.btq-menu__deals strong {
  font-weight: 700;
}

.btq-menu__deals small {
  display: block;
  margin-top: 2px;
  font-size: 12px;
  color: var(--btq-ink-soft, #5c5c66);
}

.btq-menu__deals .btq-icon {
  flex: 0 0 auto;
  color: var(--btq-pink-deep, #c2117e);
}

/* Primary list: last item should not draw a rule into the next block */
.btq-menu__primary a:last-child {
  border-bottom: 0;
}

/* --------------------------------------------------------------------------
   7. REDUCED MOTION
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  side-drawer#Drawer-Menu,
  side-drawer#Drawer-Menu [data-drawer-content],
  side-drawer#Drawer-Menu .drawer__close,
  .btq-menu .btq-menu__familles a {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }

  side-drawer#Drawer-Menu .drawer__inner .btq-menu {
    scroll-behavior: auto;
  }
}

/* ==========================================================================
   v2 — FAMILLE TILES: the owner reports the block "occupies too much vertical
   space". Measured at 2-up it needs 5 rows for 9 tiles (~250px). At 3-up it
   needs 3 rows (~130px) — roughly half — while the labels are single short
   words that read fine at this width. Label also renamed to
   "Trouvez votre parfum par senteur": customer language, not perfumery jargon.
   ========================================================================== */
.btq-menu__familles { grid-template-columns: repeat(3, 1fr) !important; gap: 6px !important; }
.btq-menu__familles a {
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 9px 4px !important;
  min-height: 56px;
  font-size: 11.5px;
  line-height: 1.15;
  text-align: center;
}
.btq-menu__familles a .btq-icon { width: 17px; height: 17px; }
.btq-menu__label { margin-bottom: 7px !important; font-size: 11px; letter-spacing: .04em; }

/* ---------- beautica-cart.css ---------- */
/* ==========================================================================
   BEAUTICA — CART DRAWER LAYOUT
   Owner brief: "I see ONE product in a 3-product cart."
   Scope: EVERY rule below is prefixed with #CartDrawer (the drawer's inner div,
   which also carries .cart-drawer). Nothing here can reach the cart PAGE, whose
   rows are scoped `cart-items-component` in component-cart-items.css.

   WHAT WAS ACTUALLY WRONG (read from the theme source, not guessed):
   component-cart-drawer.css already lays the row out as a 2x3 CSS grid —
   the <table> is NOT the problem and needs no restructuring. The 174px came from:
     · grid media column  = clamp(6rem, 17cqi, 10rem). No ancestor in the DRAWER
       declares container-type (only `cart-items-component .cart__items` does), so
       17cqi resolved against the small viewport: 17% of 393px = 66.8px -> the
       measured 68px thumbnail. A container-query unit silently falling back.
     · gap: var(--gap-xl) = 15px on BOTH axes
     · padding-block: var(--cart-items-gap) (block setting, ~20px) = 40px vertical
     · .cart-item__details > * + * { margin-top: 0.6rem } stacking title / variant /
       unit-price into three separate 6px-separated lines
     · an ALWAYS-rendered but usually EMPTY <ul class="discounts"> collecting one of
       those 6px margins
     · .cart-item__remove { min-height: 4.5rem }
   So: fix the sizing, collapse the text stack into two lines, done. No Liquid
   restructuring of the row, so every data-attribute and JS hook survives untouched.

   RESOLVING THE OWNER'S TWO "CONTRADICTORY" NOTES:
   "thumbnail too big" + "make thumbnails smaller" describe the ROW; "increase
   thumbnail size" describes the IMAGE. Both are satisfied here: the image goes
   68px -> 80px (+18%, the bottle is finally recognisable) while the row goes
   174px -> ~96-98px (-44%). Bigger product, shorter row.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1 · HEADER — "N articles" folded into the title row (markup change lives in
   snippets/cart-drawer.liquid). 65 + 35 = 100px of chrome becomes ~46px.
   -------------------------------------------------------------------------- */

#CartDrawer.cart-drawer .drawer__header.btq-cart-head {
  padding: 10px 0 6px !important;   /* beats #CartDrawer .drawer__header{padding-block:10px!important} */
  border-bottom: 1px solid var(--btq-line, #EBE6EA);
  margin-bottom: 0;
}

#CartDrawer .btq-cart-head__group {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
}

#CartDrawer .btq-cart-head .drawer__heading {
  font-size: 17px;
  line-height: 1.25;
  font-weight: 700;
  color: var(--btq-ink, #1A1A1A);
  margin: 0;
}

/* The count keeps class .wrapper-cart-count and attribute [data-cart-text] so
   cart.js keeps rewriting it ("3 articles") on every cart mutation. */
#CartDrawer .btq-cart-head__count.wrapper-cart-count {
  font-size: 12.5px;
  line-height: 1.2;
  font-weight: 500;
  color: var(--btq-ink-soft, #5C5C66);
  white-space: nowrap;
}

/* `position: relative` is load-bearing, not cosmetic: base.css `.drawer__close`
   sets top/right/z-index but NEVER `position`, so the button is position:static
   and the ::before tap pad below would resolve against the header instead —
   making the whole header a close target. Keep it first.
   min-width/min-height also override base.css's var(--minimum-touch-target)
   (4.5rem = 45px), which otherwise beats width/height and keeps the box at 45px. */
#CartDrawer .btq-cart-head .drawer__close {
  position: relative;
  width: 36px;
  height: 36px;
  min-width: 36px;
  min-height: 36px;
  flex: 0 0 36px;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* 36px box, 44px tap target — grown outward so it costs the header no height.
   36 + 2*4 = 44 on both axes. */
#CartDrawer .btq-cart-head .drawer__close::before {
  content: "";
  position: absolute;
  inset: -4px;
}

/* --------------------------------------------------------------------------
   2 · FREE-SHIPPING PROGRESS — 107px -> ~62px. KEPT, not deleted: it is a real
   conversion driver and global.js getHeaderCartDrawerHeight() hard-requires
   .previewCartMessage to exist (it early-returns without it, which would leave
   --cart-drawer-header-height unset and break .cart__contents max-height).
   The 107px was almost entirely the snippet's own `margin: 30px 0 12px`.
   -------------------------------------------------------------------------- */

#CartDrawer .previewCartMessage {
  margin: 0;
  padding: 10px 0 8px;
  border-bottom: 1px solid var(--btq-line, #EBE6EA);
}

#CartDrawer .previewCartMessage .haloCalculatorShipping {
  margin: 0;
  min-height: 0;              /* was --free-shipping-min-height */
  padding-top: 14px;          /* headroom for the truck, which sits above the bar */
}

#CartDrawer .previewCartMessage .progress {
  margin: 0 0 6px;
}

#CartDrawer .previewCartMessage .message {
  font-size: 12.5px;
  line-height: 1.3;
  color: var(--btq-ink-soft, #5C5C66);
}

/* --------------------------------------------------------------------------
   3 · THE ROW — 174px -> ~96px
   Grid areas are the theme's own; only the track sizes and rhythm change.
       [  media  ][ details        ][ price  ]
       [  media  ][ qty            ][ remove ]
   Chosen after comparing three layouts (rejects recorded in the report).
   -------------------------------------------------------------------------- */

#CartDrawer.cart-drawer .cart-items__table-row.cart-item {
  grid-template-columns: 80px minmax(0, 1fr) auto;
  grid-template-areas:
    "media details totals"
    "media quantity remove";
  column-gap: 12px;
  row-gap: 4px;
  align-items: start;
  padding: 8px 2px 8px 0;
  margin-bottom: 0;
  border-bottom: 1px solid var(--btq-line, #EBE6EA);
}

#CartDrawer.cart-drawer .cart-items__table-row.cart-item:last-child {
  margin-bottom: 8px;
}

/* -- 3a · media ----------------------------------------------------------- */

#CartDrawer .cart-items__table-row .cart-item__media {
  grid-area: media;
  width: 80px;
  height: 80px;
  align-self: start;
}

/* The container carries an inline --aspect-ratio; force a hard square box so the
   row height is predictable regardless of the source image's ratio. */
#CartDrawer .cart-items__table-row .cart-item__image-container {
  width: 80px !important;
  height: 80px !important;
  aspect-ratio: 1 / 1 !important;
  display: block !important;
  border-radius: 10px;
  overflow: hidden;
  background: var(--btq-surface-soft, #FAF7F9);
}

/* Beats the earlier `#CartDrawer .cart-item__media img{width:68px!important}`
   on specificity (1,3,1 vs 1,2,1), so order of concatenation does not matter. */
#CartDrawer .cart-items__table-row .cart-item__media img.cart-item__image {
  width: 80px !important;
  height: 80px !important;
  max-width: 80px !important;
  object-fit: contain;
  display: block;
  border-radius: 10px;
  background: var(--btq-surface-soft, #FAF7F9);
}

/* -- 3b · details: title on line 1, variant + unit price sharing line 2 ---- */

#CartDrawer .cart-items__table-row .cart-item__details {
  grid-area: details;
  display: grid;
  grid-template-columns: auto auto;
  grid-template-areas:
    "name name"
    "opt  unit";
  justify-content: start;
  align-items: baseline;
  column-gap: 8px;
  row-gap: 2px;
  width: auto;
  max-width: none;
  min-width: 0;
}

/* kill the theme's 6px stacking margins — the grid owns spacing now */
#CartDrawer .cart-items__table-row .cart-item__details > * {
  margin: 0 !important;
  max-width: none;
  min-width: 0;
}

#CartDrawer .cart-items__table-row .cart-item__name {
  grid-area: name;
  font-size: 13.5px;
  line-height: 1.25;
  font-weight: 600;
  color: var(--btq-ink, #1A1A1A);
  display: -webkit-box;
  -webkit-line-clamp: 2;          /* hard 2-line ceiling: caps the row height */
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-decoration: none;
}

#CartDrawer .cart-items__table-row .cart-item__details .product-option {
  grid-area: opt;
  font-size: 12px;
  line-height: 1.2;
  color: var(--btq-ink-soft, #5C5C66);
  gap: 4px;
}

/* Unit price — secondary to the line price on the right. */
#CartDrawer .cart-items__table-row .cart-item__details > .cart-item__price-wrapper {
  grid-area: unit;
}

/* Default-variant products render no .product-option, which would leave column 1
   empty and indent the unit price by the column gap. Span it instead. */
#CartDrawer .cart-items__table-row .cart-item__details:not(:has(.product-option))
  > .cart-item__price-wrapper {
  grid-column: 1 / -1;
}

#CartDrawer .cart-items__table-row .cart-item__details .price,
#CartDrawer .cart-items__table-row .cart-item__details .price--end {
  font-size: 11.5px !important;
  line-height: 1.2;
  font-weight: 400;
  color: var(--btq-ink-soft, #5C5C66);
  text-align: left;
}

#CartDrawer .cart-items__table-row .cart-item__details .unit-price {
  margin-top: 0 !important;
  font-size: 11px;
  color: var(--btq-ink-soft, #5C5C66);
}

/* Rare, but must not break the two-column meta line if a line-item property
   or a line-level discount is present. */
#CartDrawer .cart-items__table-row .cart-item__details .customization-option,
#CartDrawer .cart-items__table-row .cart-item__details .discounts {
  grid-column: 1 / -1;
  font-size: 11.5px;
  line-height: 1.2;
}

/* <ul class="discounts"> is rendered unconditionally and is empty in the normal
   case — it was silently collecting a 6px margin on every row. */
#CartDrawer .cart-items__table-row .cart-item__details .discounts:empty {
  display: none !important;
}

/* -- 3c · line price, top-right: the second stop on the eye path ---------- */

#CartDrawer .cart-items__table-row .cart-item__totals {
  grid-area: totals;
  align-self: start;
  padding-top: 1px;
}

#CartDrawer .cart-items__table-row .cart-item__totals .price,
#CartDrawer .cart-items__table-row .cart-item__totals .price--end {
  font-size: 14px !important;
  line-height: 1.25;
  font-weight: 600;
  color: var(--btq-ink, #1A1A1A);
  text-align: right !important;
  white-space: nowrap;
}

#CartDrawer .cart-items__table-row .cart-item__totals .cart-item__old-price {
  font-size: 11.5px !important;
  font-weight: 400;
  color: var(--btq-ink-soft, #5C5C66);
  opacity: 1;
}

#CartDrawer .cart-items__table-row .cart-item__totals .cart-item__discounted-prices dd {
  margin: 0 !important;
}

/* -- 3d · quantity: 28px control, 44px tap target ------------------------- */

#CartDrawer .cart-items__table-row .cart-item__quantity {
  grid-area: quantity;
  padding: 0;
  align-self: center;
}

#CartDrawer .cart-items__table-row .cart-quantity {
  width: auto;
  max-width: 96px;
  min-height: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--btq-line, #EBE6EA) !important;
  border-radius: 999px !important;
  overflow: visible;            /* let the ::before tap pads escape the pill */
}

#CartDrawer .cart-items__table-row .quantity__button {
  min-width: 28px;
  width: 28px;
  min-height: 28px;
  height: 28px;
  padding: 0;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--btq-pink-deep, #C2117E);
}

/* Tap area grown OUTWARD via a pseudo-element instead of padding, so a 44px
   touch target costs the row zero layout height. */
#CartDrawer .cart-items__table-row .quantity__button::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
}

#CartDrawer .cart-items__table-row .quantity__button .svg-wrapper {
  width: 11px;
  height: 11px;
  display: flex;
}

#CartDrawer .cart-items__table-row .quantity__input {
  width: 30px;
  min-width: 30px;
  height: 28px;
  padding: 0;
  text-align: center;
  font-size: 13px;
  font-weight: 600;
  color: var(--btq-ink, #1A1A1A);
  border: 0;
  background: transparent;
}

#CartDrawer .cart-items__table-row .cart-item__error {
  margin: 2px 0 0;
  font-size: 11px;
  color: var(--btq-error, #C22121);
}
#CartDrawer .cart-items__table-row .cart-item__error-text:empty,
#CartDrawer .cart-items__table-row .cart-item__error:not(:has(.cart-item__error-text:not(:empty))) {
  margin-top: 0;
}

/* -- 3e · remove ---------------------------------------------------------- */

#CartDrawer .cart-items__table-row .cart-item__remove {
  grid-area: remove;
  min-height: 0;                /* theme had 4.5rem */
  display: flex;
  align-items: center;
  justify-content: flex-end;
  align-self: center;
}

#CartDrawer .cart-items__table-row .cart-item__remove .button {
  width: 26px;
  height: 26px;
  min-width: 26px;
  min-height: 26px;
  padding: 0;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--btq-ink-soft, #5C5C66);
}

#CartDrawer .cart-items__table-row .cart-item__remove .button::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
}

#CartDrawer .cart-items__table-row .cart-item__remove .svg-wrapper {
  width: 12px;
  height: 12px;
  display: flex;
}

/* The clickable overlay <a class="cart-item__link"> is inset:0 on a position:
   relative .cart-item__media — confirm it still only covers the thumbnail. */
#CartDrawer .cart-items__table-row .cart-item__link {
  border-radius: 10px;
}

/* --------------------------------------------------------------------------
   4 · FUNCTION BLOCKS (the "large empty bordered box" in the owner's screenshot)
   INVESTIGATED: not inert. All three buttons are wired via data-drawer-toggle to
   real <modal-component> dialogs rendered in the same snippet, and
   show_cart_note / show_cart_estimate_shipping / show_cart_coupon are all `true`
   in config/settings_data.json. So they are NOT removed.
   What made it read as dead weight is that it is a 64px-tall bordered box of
   three unlabelled 24px icons. Fixed by labelling and compressing, not deleting.
   The shipping-estimate button IS hidden in the drawer only: it queries Shopify's
   rate API, which would contradict the flat 7 TND / free-over-100 COD block
   rendered 200px below it. Two different shipping numbers in one drawer is a
   refusal-at-the-door risk. It remains available on the cart page.
   -------------------------------------------------------------------------- */

#CartDrawer .drawer--function-blocks {
  border: 1px solid var(--btq-line, #EBE6EA);
  border-radius: var(--btq-radius-btn, 10px);
  overflow: hidden;
  margin-bottom: 10px;
}

#CartDrawer .drawer--function-blocks .function-block--cart-shipping {
  display: none !important;
}

/* the theme sizes these with :has(:nth-child(n+3)) -> 33.33%; with the shipping
   button hidden that would leave a gap, so the widths are taken over here. */
#CartDrawer .drawer--function-blocks .function-block {
  width: auto !important;
  flex: 1 1 0;
  min-height: 40px;
  padding: 8px 6px !important;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-size: 12px;
  line-height: 1.2;
  color: var(--btq-ink-soft, #5C5C66);
  border-right: 1px solid var(--btq-line, #EBE6EA);
}

#CartDrawer .drawer--function-blocks .function-block:last-of-type,
#CartDrawer .drawer--function-blocks .function-block:has(+ modal-component) {
  border-right: 0;
}

#CartDrawer .drawer--function-blocks .function-block .svg-wrapper {
  width: 16px !important;
  height: 16px !important;
  flex: 0 0 16px;
  display: flex;
  align-items: center;
  justify-content: center;
}

#CartDrawer .btq-fn-label {
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   5 · FOOTER — hierarchy only (COD card -> primary CTA). The COD
   "Total à régler à la livraison" block is deliberately untouched.
   -------------------------------------------------------------------------- */

#CartDrawer .cart-drawer__footer {
  padding-top: 8px;
}

#CartDrawer .cart-drawer__footer > * + * {
  margin-top: 8px;
}

/* NOTE: .totals / .totals__total / .totals__total-value / .tax-note are NOT styled
   here. beautica-custom.css hides `#CartDrawer .totals`, `.totals + small` and
   `[class*="tax-note"]` with !important — the deliberate "ONE summary only: the COD
   card" decision. Rules for them would be dead code. Do not re-add them, and do not
   un-hide .totals; the COD card (now inside .cart-drawer__footer so the AJAX
   section-render actually refreshes it) is the single source of truth for the total. */

#CartDrawer .drawer__footer {
  padding-block: 10px;
}

#CartDrawer .cart__ctas-drawer {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 10px;
}

#CartDrawer .cart__viewcart-button {
  min-height: 44px;
  border-radius: var(--btq-radius-btn, 10px);
  font-size: 14px;
}

/* --------------------------------------------------------------------------
   6 · Motion
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  #CartDrawer .previewCartMessage .progress-meter {
    animation: none !important;
    transition: none !important;
  }
}

/* --------------------------------------------------------------------------
   7 · Wider viewports: the drawer is also shown on tablet/desktop, where the
   theme reverts .cart-item to display:table-row at >=750px. Re-assert the grid
   inside the drawer only, so the row layout is identical at every width.
   -------------------------------------------------------------------------- */

@media screen and (min-width: 750px) {
  #CartDrawer.cart-drawer .cart-items__table-row.cart-item {
    display: grid;
  }
  #CartDrawer .cart-items__table-row .cart-item__details {
    width: auto;
  }
  #CartDrawer .cart-items__table-row .cart-item__price.small-hide {
    display: none !important;
  }
}

/* ==========================================================================
   v3 — CART ROW DENSITY. Measured 107px per row; the owner needs 2 complete
   products on every phone and 3 on taller ones, i.e. a 20-30% cut.
   Height comes out of padding, gaps and the stepper — NOT out of readability:
   the title stays 14px and every control keeps a >=44px tap area via padding
   rather than box size.
   ========================================================================== */
#CartDrawer .cart-item, cart-drawer .cart-item { padding-block: 7px !important; }
#CartDrawer .cart-item__image, cart-drawer .cart-item__image,
#CartDrawer .cart-item__media, cart-drawer .cart-item__media {
  width: 64px !important; height: 64px !important; min-width: 64px !important;
}
#CartDrawer .cart-item__details, cart-drawer .cart-item__details { gap: 2px !important; }
#CartDrawer .cart-item__name, cart-drawer .cart-item__name {
  font-size: 13px; line-height: 1.25; margin: 0 0 1px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
/* compact stepper: 30px visual box, 44px tap area via padding */
#CartDrawer .quantity, cart-drawer .quantity { height: 30px !important; min-height: 30px !important; }
#CartDrawer .quantity__button, cart-drawer .quantity__button {
  width: 30px !important; height: 30px !important;
  min-width: 30px !important; min-height: 30px !important; position: relative;
}
#CartDrawer .quantity__button::before, cart-drawer .quantity__button::before {
  content: ''; position: absolute; inset: -7px; /* 30 + 14 = 44px tap area */
}
#CartDrawer .quantity__input, cart-drawer .quantity__input {
  height: 30px !important; font-size: 13px; width: 34px !important;
}
#CartDrawer .cart-item__price-wrapper, cart-drawer .cart-item__price-wrapper { margin: 0 !important; }
#CartDrawer .cart-item > * + *, cart-drawer .cart-item > * + * { margin-top: 0 !important; }

/* The 80px thumb rule is #CartDrawer .cart-items__table-row .cart-item__media
   img.cart-item__image — specificity (1,3,1) !important, which beat my (1,1,0).
   Match its weight exactly and win on source order (this file, later). */
#CartDrawer .cart-items__table-row .cart-item__media img.cart-item__image,
cart-drawer .cart-items__table-row .cart-item__media img.cart-item__image {
  width: 64px !important; height: 64px !important;
  min-width: 64px !important; min-height: 64px !important;
}
#CartDrawer .cart-items__table-row .cart-item__media,
cart-drawer .cart-items__table-row .cart-item__media {
  width: 64px !important; min-width: 64px !important;
}

/* Row is 108px with a 64px thumb, so height is the TEXT column, not the image:
   title(2 lines) + variant/price + stepper stack to three rows.
   Clamp the title to one line — the thumbnail plus one line is enough to identify
   a bottle — and tighten the leading. Keeps 2 products on a 740px phone with the
   COD block and CTA still on screen, without crowding or clipping controls. */
#CartDrawer .cart-items__table-row .cart-item__name,
cart-drawer .cart-items__table-row .cart-item__name {
  -webkit-line-clamp: 1 !important;
  font-size: 12.5px !important;
  line-height: 1.2 !important;
  margin-bottom: 0 !important;
}
#CartDrawer .cart-items__table-row .cart-item__details > * + *,
cart-drawer .cart-items__table-row .cart-item__details > * + * { margin-top: 1px !important; }
#CartDrawer .cart-items__table-row, cart-drawer .cart-items__table-row {
  padding-block: 6px !important;
}

/* ==========================================================================
   v4 — CART DRAWER STRUCTURAL FIX. This is the real bug, and it was mine.
   Measured at 360x740: .drawer__inner = header 53 + shipping 65 + CART-DRAWER-ITEMS 535.
   But CART-DRAWER-ITEMS CONTAINS the note (102) AND the whole footer (323), so the
   actual product list was left 535 - 102 - 323 = 110px — one row.
   Killing the earlier 283px void with `flex: 0 1 auto` made the list SHRINK to content
   instead of claiming free space, which is what produced this.
   Correct model: the drawer is a flex column; the LIST is the only flexible child and
   scrolls; note and footer are fixed-size and pinned below it.
   ========================================================================== */
#CartDrawer .drawer__inner, cart-drawer .drawer__inner {
  display: flex !important; flex-direction: column !important;
  height: 100dvh !important; max-height: 100dvh !important; overflow: hidden !important;
}
#CartDrawer .drawer__header, cart-drawer .drawer__header,
#CartDrawer .previewCartMessage, cart-drawer .previewCartMessage { flex: 0 0 auto !important; }

#CartDrawer cart-drawer-items, cart-drawer cart-drawer-items {
  flex: 1 1 auto !important; min-height: 0 !important; height: auto !important;
  display: flex !important; flex-direction: column !important; overflow: hidden !important;
}
/* the scrolling product list — the ONLY element allowed to grow */
#CartDrawer .cart-items__wrapper, cart-drawer .cart-items__wrapper {
  flex: 1 1 auto !important; min-height: 0 !important; height: auto !important;
  overflow-y: auto !important; overscroll-behavior: contain;
}
#CartDrawer .cart__items, cart-drawer .cart__items,
#CartDrawer .js-contents, cart-drawer .js-contents { height: auto !important; min-height: 0 !important; }
/* chrome below the list: fixed, never competing for the list's space */
#CartDrawer .cart__note, cart-drawer .cart__note,
#CartDrawer .cart-drawer__footer, cart-drawer .cart-drawer__footer { flex: 0 0 auto !important; }

/* --- reclaim chrome height so the list gets more of the screen --- */
/* note + promo: 102px for two rarely-used controls in a flat-fee COD store */
#CartDrawer .cart__note.field, cart-drawer .cart__note.field { margin: 4px 0 !important; }
#CartDrawer .cart__note .modal-opener, cart-drawer .cart__note .modal-opener,
#CartDrawer .cart__note button, cart-drawer .cart__note button {
  min-height: 40px !important; padding-block: 8px !important; font-size: 11.5px !important;
}
/* "Voir le panier" was a second full-size black CTA competing with checkout.
   Demote to a quiet link: one dominant action, ~50px reclaimed. */
#CartDrawer .cart__ctas a:not([name="checkout"]),
cart-drawer .cart__ctas a:not([name="checkout"]) {
  background: transparent !important; color: var(--btq-ink-soft) !important;
  border: 0 !important; min-height: 36px !important; height: 36px !important;
  font-size: 12.5px !important; text-decoration: underline !important;
}
#CartDrawer .cart-drawer__footer, cart-drawer .cart-drawer__footer { padding-top: 6px !important; }
#CartDrawer .btq-cod-total, cart-drawer .btq-cod-total { padding: 10px 12px !important; }

/* ==========================================================================
   v5 — THE VOID vs THE SQUEEZE. Both of my previous attempts were wrong:
     flex: 1 1 auto  -> list GROWS to fill  -> void below 2 products (owner's red X)
     flex: 0 1 auto  -> list SHRINKS         -> squeeze with 3+ products
   The flexible element was never the list. CART-DRAWER-ITEMS must size to its
   CONTENT (list + note + footer) so nothing stretches; only the LIST may shrink
   and scroll, and only once the content genuinely exceeds the drawer.
     2 products: 178 + 102 + 308 = 588 < 622 available -> no void, compact.
     5 products: content 855 > 622 -> list shrinks to ~212 and scrolls. Correct both ways.
   ========================================================================== */
#CartDrawer cart-drawer-items, cart-drawer cart-drawer-items {
  flex: 0 1 auto !important;      /* size to content, shrink only when over */
  min-height: 0 !important;
  display: flex !important; flex-direction: column !important;
  overflow: hidden !important;
}
#CartDrawer .cart-items__wrapper, cart-drawer .cart-items__wrapper {
  flex: 0 1 auto !important;      /* natural height; shrinks + scrolls only when needed */
  min-height: 0 !important;
  overflow-y: auto !important;
  overflow-x: hidden !important;  /* kills the horizontal scrollbar in the owner's screenshot */
}
#CartDrawer .cart__items, cart-drawer .cart__items,
#CartDrawer .js-contents, cart-drawer .js-contents,
#CartDrawer table.cart-items, cart-drawer table.cart-items {
  overflow-x: hidden !important; width: 100% !important; table-layout: fixed !important;
}

/* ==========================================================================
   v6 — THE VOID IS NOT EMPTY. Measured the elements inside the 217px gap:
   DIV.modal-header "Commentaires supplementaires" — the NOTE MODAL is rendering
   INLINE in the drawer flow instead of staying hidden until opened. Every
   attempt to fix this with flex was treating a visible element as empty space.
   Hide the modal until it is actually opened.
   ========================================================================== */
#CartDrawer modal-component:not([open]) .modal__content,
cart-drawer modal-component:not([open]) .modal__content,
#CartDrawer modal-component:not([open]) .modal-header,
cart-drawer modal-component:not([open]) .modal-header,
#CartDrawer .cart__note modal-component:not([open]) > *:not(.modal-opener):not(button),
cart-drawer .cart__note modal-component:not([open]) > *:not(.modal-opener):not(button) {
  display: none !important;
}
#CartDrawer .cart__note modal-component, cart-drawer .cart__note modal-component {
  display: contents;
}

/* ==========================================================================
   v7 — THE REAL PROBLEM IS CHROME, NOT ROWS. Measured budget at 360x740:
     header 53 + shipping 65 + note 102 + footer 308 = 528px = 71% OF THE SCREEN
     leaving the product list just 271px.
   Rows are already 88px; shrinking them further would gain ~20px while the chrome
   wastes 250. Every previous pass optimised the wrong 29%.
   Targets: shipping 65->44, note 102->40, footer 308->210. Chrome 528->~355,
   so the list gets ~385px = 4+ products.
   ========================================================================== */

/* 1. free-shipping bar: keep the progress (real conversion driver), lose the bulk */
#CartDrawer .previewCartMessage, cart-drawer .previewCartMessage {
  padding: 4px 0 6px !important; font-size: 11.5px !important; line-height: 1.3 !important;
}
#CartDrawer .previewCartMessage svg, cart-drawer .previewCartMessage svg,
#CartDrawer .previewCartMessage img, cart-drawer .previewCartMessage img {
  width: 20px !important; height: 20px !important;
}

/* 2. note / promo: 102px for two rarely-used links in a flat-fee COD store.
      One slim row of text links instead of two large bordered boxes. */
#CartDrawer .cart__note.field, cart-drawer .cart__note.field {
  margin: 2px 0 !important; border: 0 !important; background: none !important;
}
#CartDrawer .cart__note .modal-opener, cart-drawer .cart__note .modal-opener,
#CartDrawer .cart__note > *, cart-drawer .cart__note > * { border: 0 !important; }
#CartDrawer .cart__note button, cart-drawer .cart__note button {
  min-height: 34px !important; height: 34px !important; padding: 0 8px !important;
  font-size: 11px !important; border: 0 !important; background: none !important;
  color: var(--btq-ink-soft) !important; text-decoration: underline !important;
}
#CartDrawer .cart__note svg, cart-drawer .cart__note svg { width: 13px !important; height: 13px !important; }

/* 3. checkout CTA rendered on THREE lines (71px). Two lines at a tighter scale. */
#CartDrawer [name="checkout"], cart-drawer [name="checkout"] {
  font-size: 12.5px !important; line-height: 1.25 !important;
  padding: 11px 12px !important; min-height: 48px !important; height: auto !important;
  letter-spacing: .01em !important;
}
/* 4. totals + COD card: tighter without losing the money hierarchy */
#CartDrawer .btq-cod-total, cart-drawer .btq-cod-total { padding: 9px 11px !important; }
#CartDrawer .btq-cod-total__row, cart-drawer .btq-cod-total__row { margin-bottom: 2px !important; }
#CartDrawer .cart-drawer__footer, cart-drawer .cart-drawer__footer {
  padding-top: 4px !important; padding-bottom: 4px !important;
}
#CartDrawer .cart__ctas, cart-drawer .cart__ctas { gap: 4px !important; margin-top: 6px !important; }
#CartDrawer .cart__ctas > * + *, cart-drawer .cart__ctas > * + * { margin-top: 0 !important; }

/* ==========================================================================
   v8 — THE 102px "note" IS AN ALWAYS-OPEN TEXTAREA.
   Measured: .cart__note is <cart-note> containing
   TEXTAREA.text-area with min-height:100px, permanently expanded in the drawer.
   It is NOT the NOTE/CODE PROMO button row — that is separate and already gives
   the customer a way to add a note via a modal. So this textarea is 102px of
   duplicated function, permanently occupying a mobile screen.
   Collapse it to a single tappable line that expands on focus. Nothing is removed:
   the field still exists, still submits, and the modal NOTE button is untouched.
   ========================================================================== */
#CartDrawer cart-note textarea, cart-drawer cart-note textarea,
#CartDrawer .cart__note textarea, cart-drawer .cart__note textarea {
  min-height: 36px !important; height: 36px !important;
  padding: 9px 12px !important; font-size: 12px !important;
  line-height: 1.2 !important; resize: none !important;
  transition: height .18s ease-out, min-height .18s ease-out;
}
#CartDrawer cart-note textarea:focus, cart-drawer cart-note textarea:focus,
#CartDrawer .cart__note textarea:focus, cart-drawer .cart__note textarea:focus {
  min-height: 84px !important; height: 84px !important;
}
#CartDrawer .cart__note, cart-drawer .cart__note { margin: 2px 0 !important; }
@media (prefers-reduced-motion: reduce) {
  #CartDrawer cart-note textarea, cart-drawer cart-note textarea { transition: none !important; }
}

/* ==========================================================================
   v9 — CART PRIORITY ORDER, per the owner's own spec:
     Header / Progress / PRODUCTS (max space) / Summary / Commander / Voir le panier
     ... only then Note / Promo / Coupon
   Their reasoning is right for a Tunisian COD store: Note and Code promo are near-zero
   use here (flat 7 TND shipping, no coupon flow in the drawer), yet they sat ABOVE the
   summary and pushed the products — the one thing the customer came to see — off screen.
   EasySell also injects its own coupon panel lower down, so the theme's promo row is a
   duplicate of a duplicate.
   Flex `order` reorders visually without touching the theme's markup or its JS hooks.
   ========================================================================== */
#CartDrawer .drawer__inner, cart-drawer .drawer__inner { display: flex !important; flex-direction: column !important; }
#CartDrawer .drawer__header, cart-drawer .drawer__header { order: 0; }
#CartDrawer .previewCartMessage, cart-drawer .previewCartMessage { order: 1; }
#CartDrawer cart-drawer-items, cart-drawer cart-drawer-items { order: 2; }
/* inside the items box, demote note/promo BELOW the footer */
#CartDrawer cart-drawer-items, cart-drawer cart-drawer-items { display: flex !important; flex-direction: column !important; }
#CartDrawer .cart-items__wrapper, cart-drawer .cart-items__wrapper { order: 0; }
#CartDrawer .cart-drawer__footer, cart-drawer .cart-drawer__footer { order: 1; }
#CartDrawer .cart__note, cart-drawer .cart__note { order: 2; }
#CartDrawer cart-note, cart-drawer cart-note { order: 2; }
/* the theme's Note / Code promo row is redundant next to EasySell's own coupon panel
   and near-unused in COD — collapse it to a quiet single line at the very bottom */
#CartDrawer .cart__note, cart-drawer .cart__note {
  margin-top: 6px !important; padding-top: 6px !important;
  border-top: 1px solid var(--btq-line) !important; opacity: .75;
}

/* ==========================================================================
   v9 — 186px of dead space below the last CTA, and the drawer could not scroll.
   Enumerated what actually occupies it (not guessed):
     DIV.modal__inner   "Commentaires supplementaires"   98px
     DIV.modal-content  "Pays/region Tunisie..."        162px  (shipping estimator)
   Both modals render INLINE in the drawer flow. Earlier flex work kept treating
   this as empty space, which is why three passes failed to remove it.

   SAFE TO HIDE UNCONDITIONALLY: assets/cart-drawer.js ModalComponent
   .connectedCallback() runs document.body.appendChild(this) on open, so an OPEN
   modal is a child of <body>, never of <cart-drawer>. Anything still inside the
   drawer is therefore closed by definition. Hiding it cannot hide an open modal.
   ========================================================================== */
#CartDrawer modal-component .modal__inner, cart-drawer modal-component .modal__inner,
#CartDrawer modal-component .modal-content, cart-drawer modal-component .modal-content,
#CartDrawer modal-component .modal__content, cart-drawer modal-component .modal__content {
  display: none !important;
}
/* the openers themselves must stay visible and tappable */
#CartDrawer .cart__note, cart-drawer .cart__note,
#CartDrawer modal-opener, cart-drawer modal-opener,
#CartDrawer .modal-opener, cart-drawer .modal-opener { display: block !important; }
#CartDrawer modal-component, cart-drawer modal-component { display: contents !important; }
/* drawer must never grow past the viewport, so the LIST is what scrolls */
/* v10 — the panel was forced to 100dvh, so with a short cart 186px of empty white
   sat below the CTA (the owner's red X). Size the panel to its CONTENT, capped at
   the viewport: a short cart gives a short drawer, a full cart fills the screen and
   the LIST is what scrolls. */
#CartDrawer .drawer__inner, cart-drawer .drawer__inner {
  height: auto !important; max-height: 100dvh !important; overflow: hidden !important;
}
/* the drawer shell must not stretch the panel either */
#CartDrawer.drawer, cart-drawer.drawer { align-items: flex-start !important; }
#CartDrawer .drawer__container, cart-drawer .drawer__container { height: auto !important; max-height: 100dvh !important; }

/* ==========================================================================
   v11 — THE BLANK BELOW "VOIR LE PANIER", FINAL LAYER. Walked the shell chain
   with 2 products at 375x897:
     .drawer__inner          ends 637px  (correct — 14px past the CTA)
     DIV#CartDrawer.cart-drawer  897px, background WHITE  <- paints the blank
     CART-DRAWER.drawer          897px, transparent (hit area — fine)
   v10 fixed the inner but the SHELL still painted white to the floor.
   Move the surface onto the inner; let the shell be a transparent hit-area.
   ========================================================================== */
#CartDrawer, cart-drawer .cart-drawer {
  height: auto !important;
  max-height: 100dvh !important;
  background: transparent !important;
  box-shadow: none !important;
}
#CartDrawer .drawer__inner, cart-drawer .drawer__inner {
  background: var(--btq-surface, #fff) !important;
  box-shadow: 0 8px 32px rgba(26,26,26,.18) !important;
  border-radius: 0 0 14px 14px;
}

/* v12 — with 6+ products the list CLIPPED at the drawer edge instead of scrolling.
   Cause: the direct flex child of cart-drawer-items is an intermediate
   DIV.section--main-cart (single wrapper, measured 1028px content in a 594px box)
   with NO shrink/min-height rules — it clipped, so .cart-items__wrapper never
   shrank and its overflow-y:auto never engaged. Give the intermediate the same
   column model; the wrapper then shrinks and scrolls while note+footer stay put. */
#CartDrawer cart-drawer-items > div, cart-drawer cart-drawer-items > div {
  display: flex !important; flex-direction: column !important;
  flex: 0 1 auto !important; min-height: 0 !important;
  height: auto !important; overflow: hidden !important;
}

/* ==========================================================================
   v13 — THE REAL BLOCKER, found by walking the flex chain from the scroller up.
   FORM.cart__contents measured 220px while its child DIV.drawer__contents held
   709px of products. Two ancestors carry min-height:AUTO:
       DIV.drawer__cart-items-wrapper   flex 1 1 auto · min-height auto
       FORM.cart__contents              flex 1 1 0%   · min-height auto
   A flex item with min-height:auto CANNOT shrink below its content, so the list
   was pinned to full content height and its overflow-y:auto could never engage.
   Every earlier attempt set properties on the LIST — the wrong element entirely.
   min-height:0 on the whole chain is what makes the list the scroller.
   ========================================================================== */
#CartDrawer .cart__contents, cart-drawer .cart__contents,
#CartDrawer .drawer__contents, cart-drawer .drawer__contents,
#CartDrawer .drawer__cart-items-wrapper, cart-drawer .drawer__cart-items-wrapper,
#CartDrawer .section--main-cart, cart-drawer .section--main-cart,
#CartDrawer cart-drawer-items, cart-drawer cart-drawer-items,
#CartDrawer .drawer__inner, cart-drawer .drawer__inner {
  min-height: 0 !important;
  display: flex !important;
  flex-direction: column !important;
  overflow: hidden !important;
}
#CartDrawer .cart__contents, cart-drawer .cart__contents,
#CartDrawer .drawer__contents, cart-drawer .drawer__contents,
#CartDrawer .drawer__cart-items-wrapper, cart-drawer .drawer__cart-items-wrapper {
  flex: 1 1 auto !important;
}
/* the ONE scroller */
#CartDrawer .cart-items__wrapper, cart-drawer .cart-items__wrapper {
  flex: 1 1 auto !important; min-height: 0 !important; height: auto !important;
  overflow-y: auto !important; overflow-x: hidden !important;
  -webkit-overflow-scrolling: touch; overscroll-behavior: contain;
}
/* footer + note pinned, never scrolling */
#CartDrawer .cart-drawer__footer, cart-drawer .cart-drawer__footer,
#CartDrawer .cart__note, cart-drawer .cart__note { flex: 0 0 auto !important; }

/* ==========================================================================
   v14 — HEIGHT ALLOCATION + DUPLICATE PRICE. No redesign, no width change.
   Measured (4 products, 896px): list 201px while 225px of the drawer sat unused
   and rows were hidden. Cause: cart-drawer-items was flex:0 1 auto (size to
   content) from the earlier void fix, so the list never claimed free space.
   Correct model: the panel fills the viewport, the LIST is the one growing and
   scrolling child, note+footer stay pinned. This is the Amazon/Zara model.
   ========================================================================== */
#CartDrawer .drawer__inner, cart-drawer .drawer__inner {
  height: 100dvh !important; max-height: 100dvh !important;
}
#CartDrawer cart-drawer-items, cart-drawer cart-drawer-items,
#CartDrawer .section--main-cart, cart-drawer .section--main-cart,
#CartDrawer .cart__contents, cart-drawer .cart__contents,
#CartDrawer .drawer__contents, cart-drawer .drawer__contents,
#CartDrawer .drawer__cart-items-wrapper, cart-drawer .drawer__cart-items-wrapper {
  flex: 1 1 auto !important; min-height: 0 !important; height: auto !important;
}
#CartDrawer .cart-items__wrapper, cart-drawer .cart-items__wrapper {
  flex: 1 1 auto !important; min-height: 0 !important; height: auto !important;
  overflow-y: auto !important; overflow-x: hidden !important;
}
#CartDrawer .cart-drawer__footer, cart-drawer .cart-drawer__footer,
#CartDrawer .cart__note, cart-drawer .cart__note { flex: 0 0 auto !important; }

/* DUPLICATE PRICE: each row rendered THREE .money nodes — the unit price twice
   inside the details column plus the line total on the right. Keep the line
   total (the number the customer is charged); hide the in-details repeats. */
#CartDrawer .cart-item__details .price, cart-drawer .cart-item__details .price,
#CartDrawer .cart-item__details .money, cart-drawer .cart-item__details .money,
#CartDrawer .cart-item__details cart-item-price, cart-drawer .cart-item__details cart-item-price {
  display: none !important;
}

/* ==========================================================================
   v15 — FINAL. The list must NOT grow (that created the blank band under the
   products in v14); it must size to CONTENT and shrink+scroll only when the
   content genuinely exceeds the drawer. That combination only became possible
   once v13 put min-height:0 on the whole ancestor chain — before that, shrinking
   was forbidden and the list clipped, which is why v14 wrongly switched to grow.
     few products -> list = content height, footer directly below, NO blank band
     many products -> list shrinks (min-height:0 allows it) and scrolls
   ========================================================================== */
#CartDrawer .cart-items__wrapper, cart-drawer .cart-items__wrapper {
  flex: 0 1 auto !important;
  min-height: 0 !important;
  height: auto !important;
  overflow-y: auto !important;
  overflow-x: hidden !important;
}
#CartDrawer cart-drawer-items, cart-drawer cart-drawer-items,
#CartDrawer .section--main-cart, cart-drawer .section--main-cart,
#CartDrawer .cart__contents, cart-drawer .cart__contents,
#CartDrawer .drawer__contents, cart-drawer .drawer__contents,
#CartDrawer .drawer__cart-items-wrapper, cart-drawer .drawer__cart-items-wrapper {
  flex: 0 1 auto !important; min-height: 0 !important; height: auto !important;
}
/* panel sizes to its content, capped at the viewport -> no white below the CTA */
#CartDrawer .drawer__inner, cart-drawer .drawer__inner {
  height: auto !important; max-height: 100dvh !important;
}
/* "Voir le panier" was clipped at the panel edge — give it real room */
#CartDrawer .cart__ctas a:not([name="checkout"]),
cart-drawer .cart__ctas a:not([name="checkout"]) {
  min-height: 44px !important; height: auto !important;
  display: flex !important; align-items: center; justify-content: center;
  padding: 10px 12px !important; margin-bottom: 4px !important; line-height: 1.3 !important;
}
#CartDrawer .cart-drawer__footer, cart-drawer .cart-drawer__footer { padding-bottom: 10px !important; }


/* ==========================================================================
   CHECKOUT BUTTON — driven by the Theme Editor, never hardcoded.
   sections/cart-drawer.liquid emits data-btq-checkout-mode and a set of
   --btq-appbtn-* custom properties from its schema settings. This file only
   reacts to them.

   FALLBACK GUARANTEE (mode = auto, the default):
     Shopify's button is hidden ONLY when :has() confirms an app button is really
     in the DOM. Disable EasySell, or let it fail to load, and the native button
     returns on its own. The drawer can never end up with zero checkout buttons.
   ========================================================================== */

/* auto — hide native ONLY when an app button is genuinely present */
.shopify-section:has([data-btq-checkout-mode="auto"]) .cart-drawer__footer:has([class*="easysell"]) [name="checkout"],
.shopify-section:has([data-btq-checkout-mode="auto"]) .cart-drawer__footer:has([id*="easysell"]) [name="checkout"],
.shopify-section:has([data-btq-checkout-mode="auto"]) .cart-drawer__footer:has([class*="cod-form"]) [name="checkout"],
.shopify-section:has([data-btq-checkout-mode="auto"]) .cart-drawer__footer:has([class*="easysell"]) [name="checkout"] {
  display: none !important;
}
/* app — merchant guarantees the app is on */
.shopify-section:has([data-btq-checkout-mode="app"]) [name="checkout"],
.shopify-section:has([data-btq-checkout-mode="app"]) [name="checkout"] { display: none !important; }
/* native — always show Shopify's button, whatever the app does */
.shopify-section:has([data-btq-checkout-mode="native"]) [name="checkout"],
.shopify-section:has([data-btq-checkout-mode="native"]) [name="checkout"] { display: flex !important; }

/* the app's button inherits every editor setting */
cart-drawer [class*="easysell"] button, cart-drawer [id*="easysell"] button,
cart-drawer [class*="cod-form"] button[type="submit"],
#CartDrawer [class*="easysell"] button, #CartDrawer [id*="easysell"] button {
  width: var(--btq-appbtn-w, 100%) !important;
  min-height: var(--btq-appbtn-h, 54px) !important;
  border-radius: var(--btq-appbtn-r, 10px) !important;
  font-size: var(--btq-appbtn-fs, 14px) !important;
  font-weight: var(--btq-appbtn-fw, 600) !important;
  background: var(--btq-appbtn-bg, #C2117E) !important;
  color: var(--btq-appbtn-fg, #fff) !important;
  box-shadow: var(--btq-appbtn-shadow, 0 2px 10px rgba(26,26,26,.14)) !important;
  margin-top: var(--btq-appbtn-gap, 8px) !important;
  font-family: inherit !important;
  border: 0 !important;
}
/* optional sticky footer button */
.shopify-section:has([data-btq-app-sticky="true"]) .cart-drawer__footer,
.shopify-section:has([data-btq-app-sticky="true"]) .cart-drawer__footer {
  position: sticky; bottom: 0; background: var(--btq-surface, #fff); z-index: 2;
}

/* ---------- beautica-atc.css ---------- */
/* ==========================================================================
   BEAUTICA — add-to-cart confirmation toast
   Owner: snippets/beautica-quick-add.liquid
   Everything here is scoped under .btq-atc-* so it cannot leak.
   ========================================================================== */

/* Shared z-index scale. Another part-file (beautica-announce.css) declares the
   same names; identical values, so concatenation order does not matter.
   Theme reference (snippets/global-style.liquid): --layer-overlay 16,
   --layer-menu-drawer 18, --layer-sidebar 19 (cart drawer), --layer-temporary 20. */
:root {
  --btq-z-overlay: 16;
  --btq-z-drawer: 19;
  --btq-z-toast: 21; /* must clear the drawer + --layer-temporary */
}

/* --------------------------------------------------------------------------
   Layer: full-viewport centring frame.
   pointer-events:none is the non-blocking guarantee — the shopper can keep
   scrolling and tapping the grid straight through the toast.
   -------------------------------------------------------------------------- */
.btq-atc-toast {
  position: fixed;
  inset: 0;
  z-index: var(--btq-z-toast, 21);
  display: grid;
  place-items: center;
  padding: 16px;
  pointer-events: none;
  visibility: hidden;
}

/* Stays visible while closing, otherwise the exit transition is never seen. */
.btq-atc-toast[data-open='1'],
.btq-atc-toast[data-closing='1'] {
  visibility: visible;
}

/* .btq-atc-toast__action sets display:block, which would beat the UA's
   [hidden]{display:none}. Restore it. */
.btq-atc-toast [hidden] {
  display: none !important;
}

/* --------------------------------------------------------------------------
   Card
   -------------------------------------------------------------------------- */
.btq-atc-toast__card {
  pointer-events: auto;
  box-sizing: border-box;
  width: min(320px, calc(100vw - 48px));
  padding: 24px 20px 20px;
  text-align: center;
  background: var(--btq-surface, #fff);
  border: 1px solid var(--btq-line, #ebe6ea);
  border-radius: var(--btq-radius-card, 12px);
  box-shadow:
    0 1px 2px rgba(26, 26, 26, 0.06),
    0 12px 32px -8px rgba(26, 26, 26, 0.18);
  cursor: pointer;

  opacity: 0;
  transform: scale(0.96);
  transition:
    opacity 220ms cubic-bezier(0.33, 1, 0.68, 1),
    transform 220ms cubic-bezier(0.33, 1, 0.68, 1);
}

.btq-atc-toast[data-open='1'] .btq-atc-toast__card {
  opacity: 1;
  transform: scale(1);
}

/* Exit is quicker than entry so the toast never feels like it lingers. */
.btq-atc-toast[data-closing='1'] .btq-atc-toast__card {
  opacity: 0;
  transform: scale(0.98);
  transition-duration: 160ms;
}

/* --------------------------------------------------------------------------
   Icon
   -------------------------------------------------------------------------- */
.btq-atc-toast__icon {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin: 0 auto 12px;
  border-radius: 50%;
  background: var(--btq-pink-soft, #fdf2f8);
  color: var(--btq-pink-deep, #c2117e);
}

.btq-atc-toast__icon svg {
  display: block;
  width: 22px;
  height: 22px;
}

.btq-atc-toast.is-error .btq-atc-toast__icon {
  background: #fdecec;
  color: var(--btq-error, #c22121);
}

/* The check draws itself on entry — the only motion beyond fade+scale. */
.btq-atc-toast__check {
  stroke: currentColor;
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
  stroke-dasharray: 22;
  stroke-dashoffset: 22;
}

.btq-atc-toast[data-open='1'] .btq-atc-toast__check {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 320ms cubic-bezier(0.33, 1, 0.68, 1) 120ms;
}

/* --------------------------------------------------------------------------
   Copy
   -------------------------------------------------------------------------- */
.btq-atc-toast__title {
  margin: 0;
  font-size: 1.6rem;
  line-height: 1.3;
  font-weight: 600;
  color: var(--btq-ink, #1a1a1a);
}

.btq-atc-toast.is-error .btq-atc-toast__title {
  color: var(--btq-error, #c22121);
}

.btq-atc-toast__text {
  margin: 4px 0 0;
  font-size: 1.3rem;
  line-height: 1.45;
  color: var(--btq-ink-soft, #5c5c66);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.btq-atc-toast__text:empty {
  display: none;
}

/* --------------------------------------------------------------------------
   Action — keeps the drawer one tap away without force-opening it.
   -------------------------------------------------------------------------- */
.btq-atc-toast__action {
  display: block;
  width: 100%;
  min-height: 44px;
  margin-top: 16px;
  padding: 11px 16px;
  font: inherit;
  font-size: 1.4rem;
  font-weight: 600;
  line-height: 1.4;
  color: #fff;
  background: var(--btq-pink-deep, #c2117e);
  border: 0;
  border-radius: var(--btq-radius-btn, 10px);
  cursor: pointer;
  transition: background 150ms ease-out;
}

.btq-atc-toast__action:hover,
.btq-atc-toast__action:focus-visible {
  background: var(--btq-ink, #1a1a1a);
}

.btq-atc-toast__action:focus-visible {
  outline: 2px solid var(--btq-pink-deep, #c2117e);
  outline-offset: 2px;
}

.btq-atc-toast.is-error .btq-atc-toast__action {
  display: none;
}

.btq-atc-toast__dismiss {
  margin: 10px 0 0;
  font-size: 1.15rem;
  line-height: 1.3;
  color: var(--btq-ink-soft, #5c5c66);
  opacity: 0.75;
}

/* --------------------------------------------------------------------------
   Small viewports — pin near the top so the toast never sits under a thumb
   or over the sticky mobile toolbar.
   -------------------------------------------------------------------------- */
@media screen and (max-height: 560px) {
  .btq-atc-toast {
    align-items: start;
    padding-top: 24px;
  }
}

/* --------------------------------------------------------------------------
   Reduced motion — no scale, no draw; a plain short fade.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .btq-atc-toast__card,
  .btq-atc-toast[data-closing='1'] .btq-atc-toast__card {
    transform: none;
    transition: opacity 120ms linear;
  }

  .btq-atc-toast__check,
  .btq-atc-toast[data-open='1'] .btq-atc-toast__check {
    stroke-dashoffset: 0;
    transition: none;
  }

  .btq-atc-toast__action {
    transition: none;
  }
}

/* ---------- beautica-footer.css ---------- */
/* ==========================================================================
   BEAUTICA — FOOTER  (complete redesign)
   Pairs with sections/beautica-footer.liquid. Every rule is scoped under
   `.btq-ft`, so this file cannot leak into the theme's original
   sections/footer.liquid (which stays intact as a fallback).

   CONCATENATION: this file is appended LAST into assets/beautica-custom.css
   (announce, drawer, cart, atc, card, footer). Nothing here depends on
   source order — the scope prefix does all the isolation work.

   MOBILE-FIRST. Base rules target 393px. The only breakpoint is 750px,
   matching the theme's own `max-width: 749px` mobile definition.

   COLOUR DISCIPLINE
   --btq-pink (#EC2EA5) is 3.06:1 on white — display only. Every readable
   pink here is --btq-pink-deep (#C2117E, 5.71:1). Pink appears in exactly
   four places on purpose: the finder card, the WhatsApp action, the
   newsletter submit, and the hairline accents. Nothing else.
   ========================================================================== */

.btq-ft {
  /* Local tokens. Declared on the block, not :root, so the footer can be
     re-skinned in isolation and nothing outside it is affected. */
  --ft-pad-x: 20px;
  --ft-gap: 32px;
  --ft-rule: 1px solid var(--btq-line);
  --ft-tap: 44px;

  background: var(--btq-surface);
  color: var(--btq-ink);
  border-top: 1px solid var(--btq-line);
  /* The brand's closing breath. Generous at the top so the footer reads as a
     deliberate chapter break, not as the page running out. */
  padding: 40px 0 0;
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

.btq-ft *,
.btq-ft *::before,
.btq-ft *::after { box-sizing: border-box; }

.btq-ft__inner {
  max-width: 1180px;
  margin: 0 auto;
  padding: 0 var(--ft-pad-x);
}

/* Shared micro-label: the small-caps eyebrow used for every section title.
   One type treatment, reused, is what makes a footer read as designed. */
.btq-ft__eyebrow {
  margin: 0 0 12px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--btq-ink-soft);
}

.btq-ft a {
  color: inherit;
  text-decoration: none;
}

/* Visible focus everywhere. Offset keeps the ring off the glyphs. */
.btq-ft a:focus-visible,
.btq-ft button:focus-visible,
.btq-ft summary:focus-visible,
.btq-ft input:focus-visible {
  outline: 2px solid var(--btq-pink-deep);
  outline-offset: 3px;
  border-radius: 4px;
}
.btq-ft summary:focus:not(:focus-visible) { outline: none; }


/* --------------------------------------------------------------------------
   1 · PROMISE ROW — reassurance at the moment of doubt

   This is the footer's first job and therefore its first element. A COD
   shopper who scrolled this far is deciding whether to trust the store, not
   looking for a sitemap.

   2×2 on mobile rather than a 4-up scroller: all four promises are visible
   at once with no interaction, which is the entire point of reassurance.
   The 1px grid lines are drawn with a single background-image on the list
   plus surface-coloured outer edges, so there are no double borders and no
   per-cell border juggling.
   -------------------------------------------------------------------------- */
.btq-ft__promise {
  list-style: none;
  margin: 0 0 var(--ft-gap);
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1px;
  background: var(--btq-line);
  border: 1px solid var(--btq-line);
  border-radius: var(--btq-radius-card);
  overflow: hidden;
}

.btq-ft__promise li {
  background: var(--btq-surface-soft);
  padding: 16px 12px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 8px;
}

.btq-ft__promise-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  min-width: 32px;
  min-height: 32px;
  border-radius: 50%;
  background: var(--btq-pink-soft);
  color: var(--btq-pink-deep);
}
.btq-ft__promise-icon svg {
  width: 16px;
  height: 16px;
  display: block;
}

.btq-ft__promise b {
  display: block;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--btq-ink);
}
.btq-ft__promise small {
  display: block;
  font-size: 11.5px;
  line-height: 1.35;
  color: var(--btq-ink-soft);
}


/* --------------------------------------------------------------------------
   2 · FINDER — the single conversion action

   Deliberately the only full-width, pink, high-contrast object in the
   footer. Nothing else competes with it. The newsletter lives further down
   as a slim inline field precisely so this card keeps its monopoly on
   attention (see the section file's header comment for the reasoning).

   Built as a card, not a button: the eyebrow + title + timing line carry
   more persuasion than a bare CTA, and the arrow supplies the affordance.
   -------------------------------------------------------------------------- */
.btq-ft__finder {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 72px;
  margin: 0 0 var(--ft-gap);
  padding: 16px 18px;
  border-radius: var(--btq-radius-card);
  border: 1px solid rgba(194, 17, 126, .22);
  background:
    radial-gradient(120% 160% at 100% 0%, rgba(236, 46, 165, .10) 0%, rgba(236, 46, 165, 0) 62%),
    var(--btq-pink-soft);
  transition: border-color .18s ease, transform .18s ease;
}
.btq-ft__finder:hover { border-color: rgba(194, 17, 126, .45); }
.btq-ft__finder:active { transform: scale(.995); }

.btq-ft__finder-mark {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  min-width: 40px;
  min-height: 40px;
  border-radius: 50%;
  background: var(--btq-surface);
  color: var(--btq-pink-deep);
  box-shadow: var(--btq-shadow-card);
}
.btq-ft__finder-mark svg { width: 19px; height: 19px; display: block; }

.btq-ft__finder-body { flex: 1 1 auto; min-width: 0; }

.btq-ft__finder-eyebrow {
  display: block;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--btq-pink-deep);
  margin-bottom: 3px;
}
.btq-ft__finder-title {
  display: block;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.25;
  color: var(--btq-ink);
}
.btq-ft__finder-meta {
  display: block;
  margin-top: 3px;
  font-size: 12.5px;
  color: var(--btq-ink-soft);
}
.btq-ft__finder-arrow {
  flex: 0 0 auto;
  color: var(--btq-pink-deep);
  transition: transform .18s ease;
}
.btq-ft__finder-arrow svg { width: 18px; height: 18px; display: block; }
.btq-ft__finder:hover .btq-ft__finder-arrow { transform: translateX(3px); }


/* --------------------------------------------------------------------------
   3 · NAVIGATION — accordions that do not look like theme accordions

   The owner has rejected "generic accordions" before. What made those read
   as default was: a boxed row with a grey fill, a chevron in a circle, and a
   border around every panel. This does none of that.

   Instead: a hairline-separated editorial list. The title is the small-caps
   eyebrow used elsewhere in the footer, so it belongs to the same system.
   The affordance is a 1px plus/minus drawn in CSS that becomes a minus on
   open — quieter than a chevron and it reads as typographic, not as chrome.

   The whole row is still a 48px tap target even though nothing is boxed.
   -------------------------------------------------------------------------- */
.btq-ft__nav {
  margin: 0 0 var(--ft-gap);
  border-top: var(--ft-rule);
}

.btq-ft__col { border-bottom: var(--ft-rule); }

.btq-ft__col > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 48px;
  padding: 12px 2px;
  cursor: pointer;
  list-style: none;               /* Firefox marker */
  -webkit-tap-highlight-color: transparent;
}
.btq-ft__col > summary::-webkit-details-marker { display: none; }  /* Safari */

.btq-ft__col-title {
  margin: 0;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--btq-ink);
}

/* The plus/minus. Two 1px bars; the vertical one collapses on open. */
.btq-ft__col-sign {
  position: relative;
  flex: 0 0 auto;
  width: 12px;
  height: 12px;
}
.btq-ft__col-sign::before,
.btq-ft__col-sign::after {
  content: "";
  position: absolute;
  inset: 50% 0 auto 0;
  height: 1px;
  background: var(--btq-ink-soft);
  transform: translateY(-50%);
  transition: transform .22s ease, opacity .22s ease;
}
.btq-ft__col-sign::after { transform: translateY(-50%) rotate(90deg); }
.btq-ft__col[open] .btq-ft__col-sign::after {
  transform: translateY(-50%) rotate(0deg);
  opacity: 0;
}
.btq-ft__col[open] .btq-ft__col-sign::before { background: var(--btq-pink-deep); }
.btq-ft__col[open] .btq-ft__col-title { color: var(--btq-pink-deep); }

.btq-ft__links {
  list-style: none;
  margin: 0;
  padding: 0 0 12px;
}
.btq-ft__links a {
  display: flex;
  align-items: center;
  min-height: var(--ft-tap);
  padding: 4px 2px;
  font-size: 14.5px;
  color: var(--btq-ink-soft);
  transition: color .15s ease;
}
.btq-ft__links a:hover { color: var(--btq-pink-deep); }


/* --------------------------------------------------------------------------
   4 · CONTACT — WhatsApp first, because this is a COD store

   In Tunisia the pre-purchase question happens on WhatsApp, not by email.
   So WhatsApp is a real button with a real tap target and the phone number
   spelled out; email is a quiet text link underneath.
   -------------------------------------------------------------------------- */
.btq-ft__contact { margin: 0 0 var(--ft-gap); }

.btq-ft__wa {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 56px;
  padding: 12px 16px;
  border-radius: var(--btq-radius-btn);
  border: 1px solid var(--btq-line);
  background: var(--btq-surface-soft);
  transition: border-color .18s ease, background-color .18s ease;
}
.btq-ft__wa:hover {
  border-color: rgba(194, 17, 126, .35);
  background: var(--btq-pink-soft);
}
.btq-ft__wa-mark {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  min-width: 34px;
  min-height: 34px;
  border-radius: 50%;
  background: var(--btq-success);
  color: #fff;
}
.btq-ft__wa-mark svg { width: 18px; height: 18px; display: block; }
.btq-ft__wa b {
  display: block;
  font-size: 14.5px;
  font-weight: 600;
}
.btq-ft__wa small {
  display: block;
  font-size: 12.5px;
  color: var(--btq-ink-soft);
}

.btq-ft__mail {
  display: inline-flex;
  align-items: center;
  min-height: var(--ft-tap);
  font-size: 13.5px;
  color: var(--btq-ink-soft);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--btq-line-strong);
}
.btq-ft__mail:hover { color: var(--btq-pink-deep); }


/* --------------------------------------------------------------------------
   4b · NEWSLETTER — intentionally secondary

   One line, one field, no headline competing with the finder card. It is
   here for the shopper who already decided to stay in touch, not to win a
   fight for attention it would lose anyway.
   -------------------------------------------------------------------------- */
.btq-ft__news { margin-top: 24px; }

.btq-ft__news-note {
  margin: 0 0 10px;
  font-size: 13px;
  color: var(--btq-ink-soft);
}

.btq-ft__news-row {
  display: flex;
  gap: 8px;
}

.btq-ft__news input[type="email"] {
  flex: 1 1 auto;
  min-width: 0;
  height: var(--ft-tap);
  padding: 0 14px;
  font-size: 16px;              /* 16px prevents the iOS focus zoom */
  font-family: inherit;
  color: var(--btq-ink);
  background: var(--btq-surface);
  border: 1px solid var(--btq-line-strong);
  border-radius: var(--btq-radius-btn);
  transition: border-color .15s ease;
}
.btq-ft__news input[type="email"]::placeholder { color: var(--btq-ink-soft); }
.btq-ft__news input[type="email"]:focus { border-color: var(--btq-pink-deep); }

.btq-ft__news button {
  flex: 0 0 auto;
  min-height: var(--ft-tap);
  min-width: 96px;
  padding: 0 18px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .04em;
  color: #fff;
  background: var(--btq-pink-deep);
  border: 0;
  border-radius: var(--btq-radius-btn);
  cursor: pointer;
  transition: background-color .15s ease;
}
.btq-ft__news button:hover { background: #A50E6B; }

.btq-ft__news-ok,
.btq-ft__news-err {
  margin: 10px 0 0;
  font-size: 13px;
}
.btq-ft__news-ok { color: var(--btq-success); }
.btq-ft__news-err { color: var(--btq-error); }


/* --------------------------------------------------------------------------
   5 · SOCIAL — only the accounts that actually exist
   -------------------------------------------------------------------------- */
.btq-ft__social {
  display: flex;
  gap: 8px;
  margin-top: 24px;
}
.btq-ft__social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--ft-tap);
  height: var(--ft-tap);
  min-width: var(--ft-tap);
  min-height: var(--ft-tap);
  border-radius: 50%;
  border: 1px solid var(--btq-line);
  color: var(--btq-ink-soft);
  transition: color .15s ease, border-color .15s ease, background-color .15s ease;
}
.btq-ft__social a:hover {
  color: var(--btq-pink-deep);
  border-color: rgba(194, 17, 126, .35);
  background: var(--btq-pink-soft);
}
.btq-ft__social svg { width: 18px; height: 18px; display: block; }


/* --------------------------------------------------------------------------
   6 · BASE BAR — COD mark, payment, legal, copyright
   -------------------------------------------------------------------------- */
.btq-ft__base {
  border-top: var(--ft-rule);
  padding: 20px 0 32px;
}

.btq-ft__cod {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  border-radius: 999px;
  background: var(--btq-pink-soft);
  color: var(--btq-pink-deep);
  font-size: 12.5px;
  font-weight: 600;
}
.btq-ft__cod svg { width: 15px; height: 15px; display: block; }

.btq-ft__pay {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 14px 0 0;
  padding: 0;
  list-style: none;
}
.btq-ft__pay li { display: flex; }
.btq-ft__pay svg,
.btq-ft__pay img {
  height: 22px;
  width: auto;
  display: block;
}

.btq-ft__legal {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0 18px;
  margin: 16px 0 0;
  padding: 0;
}
.btq-ft__legal a {
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  font-size: 12.5px;
  color: var(--btq-ink-soft);
}
.btq-ft__legal a:hover {
  color: var(--btq-pink-deep);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.btq-ft__copy {
  margin: 12px 0 0;
  font-size: 12px;
  color: var(--btq-ink-soft);
}


/* ==========================================================================
   7 · 750px AND UP

   The accordion becomes three open columns. Because a closed <details>
   hides its content in the rendering tree (not via a UA display rule that
   CSS can override), the section's inline script force-opens every panel
   above the breakpoint and removes `open` below it. The markup ships with
   `open` already set, so with JavaScript disabled every link is visible at
   every width — the accordion is the enhancement, never the gate.
   ========================================================================== */
@media (min-width: 750px) {
  .btq-ft {
    --ft-pad-x: 40px;
    --ft-gap: 48px;
    padding-top: 56px;
  }

  .btq-ft__promise { grid-template-columns: repeat(4, 1fr); }
  .btq-ft__promise li {
    flex-direction: row;
    align-items: center;
    text-align: left;
    padding: 20px 18px;
    gap: 12px;
  }

  /* Finder and navigation share a row: the CTA holds the left third and the
     three menus fill the rest. The footer stops being a stack and becomes a
     composition, which is most of what separates premium from default. */
  .btq-ft__mid {
    display: grid;
    grid-template-columns: minmax(280px, 1fr) 1.6fr;
    gap: 56px;
    align-items: start;
  }

  .btq-ft__finder { margin-bottom: 24px; }

  .btq-ft__nav {
    margin: 0;
    border-top: 0;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 32px;
  }
  .btq-ft__col { border-bottom: 0; }
  .btq-ft__col > summary {
    cursor: default;
    pointer-events: none;        /* not a control when it cannot collapse */
    min-height: 0;
    padding: 0 0 14px;
  }
  .btq-ft__col-sign { display: none; }
  .btq-ft__col[open] .btq-ft__col-title { color: var(--btq-ink); }
  .btq-ft__links { padding: 0; }
  .btq-ft__links a { min-height: 34px; }

  .btq-ft__contact { margin-bottom: var(--ft-gap); }
  .btq-ft__contact-grid {
    display: grid;
    grid-template-columns: minmax(280px, 1fr) 1.6fr;
    gap: 56px;
    align-items: start;
  }
  .btq-ft__news { margin-top: 0; }
  .btq-ft__news-row { max-width: 460px; }
  .btq-ft__social { margin-top: 20px; }

  .btq-ft__base {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 16px 28px;
    padding: 24px 0 40px;
  }
  .btq-ft__pay { margin: 0; }
  .btq-ft__legal { margin: 0 0 0 auto; }
  .btq-ft__copy { margin: 0; width: 100%; }
}


/* --------------------------------------------------------------------------
   8 · REDUCED MOTION
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .btq-ft *,
  .btq-ft *::before,
  .btq-ft *::after {
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
  }
  .btq-ft__finder:active { transform: none; }
  .btq-ft__finder:hover .btq-ft__finder-arrow { transform: none; }
}

/* Screen-reader-only helper, local to the footer so it cannot collide with
   the theme's own visually-hidden utility. */
.btq-ft__sr {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ==========================================================================
   FOOTER DENSITY — measured 826px at 375x812, i.e. 18% of the whole homepage.
   Breakdown: top padding 40 + promise grid 227 (+32 margin) + contact 255
   (+32 margin) + base 207 (20/32 padding). The block heights are fine; the
   SEPARATION between them is what inflates it — three 32px margins plus 40/20/32
   of padding = ~136px of pure gap.
   Target ~560px. Rhythm kept deliberate (24px between movements), not crushed.
   ========================================================================== */
@media (max-width: 749px) {
  .btq-ft { padding-top: 24px !important; }
  .btq-ft__promise { margin-bottom: 20px !important; gap: 1px !important; }
  .btq-ft__promise li { padding-block: 10px !important; }
  .btq-ft__contact { margin-bottom: 20px !important; }
  .btq-ft__base { padding: 16px 0 20px !important; }
  /* accordion rows: 3 menus x generous rows was a large share of the middle */
  .btq-ft details > summary { min-height: 44px !important; padding-block: 8px !important; }
  .btq-ft details[open] > div, .btq-ft details[open] ul { padding-bottom: 6px !important; }
  .btq-ft details a { padding-block: 7px !important; }
  /* legal row: two-up instead of a tall stack */
  .btq-ft__legal { display: flex !important; flex-wrap: wrap; gap: 6px 16px !important; }
  .btq-ft__legal li { margin: 0 !important; }
  .btq-ft__copy { margin-top: 10px !important; font-size: 11.5px !important; }
  .btq-ft__newsletter, .btq-ft__news { margin-bottom: 16px !important; }
}

/* contact block measured 255px after the first pass — the largest remaining block.
   It stacks: heading + WhatsApp card + social row + newsletter. Tighten each
   without shrinking any tap target below 44px. */
@media (max-width: 749px) {
  .btq-ft__contact > * + * { margin-top: 12px !important; }
  .btq-ft__contact .btq-ft__wa, .btq-ft__contact a[href*="wa.me"] {
    padding: 10px 12px !important; min-height: 56px !important;
  }
  .btq-ft__social { gap: 10px !important; margin: 12px 0 !important; }
  .btq-ft__social a { width: 40px !important; height: 40px !important; }
  .btq-ft__contact input[type="email"] { min-height: 44px !important; }
  .btq-ft__contact button { min-height: 44px !important; }
  .btq-ft__eyebrow, .btq-ft__contact h2 { margin-bottom: 8px !important; font-size: 11px !important; }
}

/* ---------- beautica-search.css ---------- */
/* ==========================================================================
   BEAUTICA — SEARCH DRAWER
   Owns: the #Drawer-Search shell, the search field, the zero-state panel
         rendered by snippets/beautica-search-panel.liquid (.btq-zs), and the
         RESTYLING of the theme's predictive-search results markup.

   Concatenated LAST into assets/beautica-custom.css. Every rule below is
   scoped to #Drawer-Search so nothing leaks to the /search page, the inline
   header search, or the full-screen search modal.

   ---------------------------------------------------------------------------
   REAL DOM — read from snippets/predictive-search-drawer.liquid. The id lives
   on the custom element itself here (unlike the cart drawer, where #CartDrawer
   is an inner div — see CLAUDE.md lesson 2):

     side-drawer#Drawer-Search.search-drawer.drawer__container.drawer
       > #Drawer-Overlay-Search.drawer__overlay
       > #Drawer-Search-Content.search-drawer-content[data-drawer-content]
           > .drawer__header  (> .drawer__heading, side-drawer-close.drawer__close)
           > .search-drawer__inner.drawer__inner[role=dialog]
               > predictive-search.search-drawer__form
                   > form.search.search-drawer__form
                       > .predictive-search--center > .field
                           > button.search__button.field__button
                           > input.search__input.field__input.field__input--focus
                           > label.field__label
                           > button[type=reset].reset__button.field__button
                       > div.predictive-search.predictive-search--header
                           .predictive-search--center.cus-scrollbar[data-predictive-search]
                       > .btq-zs[data-btq-search-zero]      <-- OURS, wired in
                       > span.predictive-search-status

   REAL JS HOOKS — read from assets/predictive-search.js and search-form.js:
     setAttribute('loading', true)   L287
     setAttribute('results', true)   L97 (empty state) and L301 (real results)
     setAttribute('open', true)      L321
     removeAttribute('results')      L334, on form reset
     innerHTML of [data-predictive-search] is REPLACED on every render (L96/L300)
     .reset__button gets/loses `.hidden` via SearchForm.toggleResetButton()
   Escape-to-close and focus-into-.search__input are already provided by
   SideDrawer (assets/details-disclosure.js L44 and L108-113). We add no JS.

   ---------------------------------------------------------------------------
   THE SHOW/HIDE CONTRACT FOR THE ZERO-STATE — no invented hooks.

   Two independent, verified signals, deliberately layered:

   (a) `predictive-search[open]` / `[loading]` — plain descendant selectors, no
       :has() required. These hide .btq-zs the instant a fetch starts.
       CAVEAT: renderEmptyState() ALSO calls open() (L98), so on its own this
       would wrongly hide the zero-state after the shopper clears the input.

   (b) `.search__input:placeholder-shown` — the input carries a literal
       placeholder=" " (drawer snippet L52), which is exactly how this theme
       drives its own floating .field__label. An empty input therefore matches
       :placeholder-shown. The :has() rule below is written with HIGHER
       specificity than (a) so "input is empty" always wins over "JS said open",
       correcting the renderEmptyState() caveat.

   Failure mode if :has() were ever unsupported: the zero-state stays visible
   under the results instead of disappearing. Degraded, never broken.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. SHELL — panel surface, header, close target
   -------------------------------------------------------------------------- */
side-drawer#Drawer-Search #Drawer-Search-Content {
  background: var(--btq-surface);
  display: flex;
  flex-direction: column;
  max-height: 100dvh;
}

side-drawer#Drawer-Search .drawer__header {
  padding: 12px 16px;
  border-bottom: 1px solid var(--btq-line);
  background: var(--btq-surface);
  flex: 0 0 auto;
}

side-drawer#Drawer-Search .drawer__heading {
  font-size: 1.05rem;
  letter-spacing: 0.01em;
  color: var(--btq-ink);
}

/* CLAUDE.md lesson 6: the theme's min-touch-target var resolves to 4.5rem and
   beats width/height, so we set the min-* pair too. */
side-drawer#Drawer-Search .drawer__close .button--drawer {
  min-width: 44px;
  min-height: 44px;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--btq-ink);
}

side-drawer#Drawer-Search .search-drawer__inner {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: 0;
  overflow: hidden;
}

side-drawer#Drawer-Search predictive-search.search-drawer__form,
side-drawer#Drawer-Search search-form.search-drawer__form,
side-drawer#Drawer-Search form.search-drawer__form {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}

/* --------------------------------------------------------------------------
   2. THE FIELD — the one thing that must be unmissable on open
   -------------------------------------------------------------------------- */
side-drawer#Drawer-Search .predictive-search--center:first-of-type {
  flex: 0 0 auto;
  padding: 12px 16px 8px;
  background: var(--btq-surface);
}

side-drawer#Drawer-Search .field {
  position: relative;
  background: var(--btq-surface-soft);
  border: 1px solid var(--btq-line);
  border-radius: var(--btq-radius-btn);
  min-height: 48px;
  display: flex;
  align-items: center;
  transition: border-color 160ms ease, box-shadow 160ms ease;
}

side-drawer#Drawer-Search .field:focus-within {
  border-color: var(--btq-pink-deep);
  box-shadow: 0 0 0 3px rgba(194, 17, 126, 0.12);
}

side-drawer#Drawer-Search .search__input.field__input {
  border: 0;
  background: transparent;
  box-shadow: none;
  padding: 12px 44px 12px 44px;
  min-height: 48px;
  font-size: 16px; /* < 16px triggers iOS Safari zoom-on-focus */
  color: var(--btq-ink);
  width: 100%;
}

side-drawer#Drawer-Search .search__input.field__input:focus {
  outline: none;
  box-shadow: none;
}

/* The theme's floating label doubles as our placeholder. */
side-drawer#Drawer-Search .field__label {
  left: 44px;
  color: var(--btq-ink-soft);
  font-size: 0.95rem;
}

side-drawer#Drawer-Search .search__button.field__button {
  left: 0;
  min-width: 44px;
  min-height: 44px;
  color: var(--btq-ink-soft);
}

side-drawer#Drawer-Search .reset__button.field__button {
  right: 0;
  min-width: 44px;
  min-height: 44px;
  color: var(--btq-ink-soft);
}

side-drawer#Drawer-Search .reset__button.field__button.hidden {
  display: none;
}

/* --------------------------------------------------------------------------
   3. THE SCROLL BODY — results container and zero-state share one scroller
   The theme sets an inline max-height on [data-predictive-search] in open()
   (predictive-search.js L320) computed from `.header-group-section`. Inside a
   full-height drawer that number is wrong, so we neutralise it and let the
   flex column own the scrolling instead.
   -------------------------------------------------------------------------- */
side-drawer#Drawer-Search [data-predictive-search],
side-drawer#Drawer-Search .btq-zs {
  max-height: none !important;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}

side-drawer#Drawer-Search [data-predictive-search] {
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background: var(--btq-surface);
  position: static;
  width: 100%;
  padding: 0 16px 24px;
  flex: 1 1 auto;
  min-height: 0;
}

side-drawer#Drawer-Search .btq-zs {
  flex: 1 1 auto;
  min-height: 0;
  padding: 4px 16px 32px;
}

/* ---- (a) JS-attribute signal: hide the zero-state while fetching/showing ---- */
side-drawer#Drawer-Search predictive-search[open] .btq-zs,
side-drawer#Drawer-Search predictive-search[loading] .btq-zs {
  display: none;
}

/* ---- (b) input-state signal, higher specificity — it always wins ----
   Empty input  -> force the zero-state back on, and suppress the theme's own
   near-empty dropdown (with settings.quick_* unset it renders nothing but a
   bare "no results" line — see the diagnosis note at the foot of this file). */
side-drawer#Drawer-Search predictive-search .search:has(.search__input:placeholder-shown) .btq-zs {
  display: block;
}

side-drawer#Drawer-Search predictive-search .search:has(.search__input:placeholder-shown) [data-predictive-search] {
  display: none;
}

/* Typed input -> zero-state gone, belt-and-braces against attribute lag. */
side-drawer#Drawer-Search predictive-search .search:has(.search__input:not(:placeholder-shown)) .btq-zs {
  display: none;
}

/* --------------------------------------------------------------------------
   4. ZERO-STATE — layout C, "intent ladder"
   Ordered cheapest-action-first: one-tap query -> browse a famille -> take the
   quiz -> deals. See the snippet header for the two rejected layouts.
   -------------------------------------------------------------------------- */
side-drawer#Drawer-Search .btq-zs__block {
  margin: 0 0 24px;
}

side-drawer#Drawer-Search .btq-zs__title {
  margin: 0 0 12px;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--btq-ink-soft);
}

/* ---- 4a. Query pills ---- */
side-drawer#Drawer-Search .btq-zs__pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0;
  padding: 0;
}

side-drawer#Drawer-Search .btq-zs__pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--btq-line);
  border-radius: 999px;
  background: var(--btq-surface);
  color: var(--btq-ink);
  font-size: 0.9rem;
  line-height: 1;
  text-decoration: none;
  transition: background-color 160ms ease, border-color 160ms ease;
}

side-drawer#Drawer-Search .btq-zs__pill svg {
  color: var(--btq-ink-soft);
  flex: 0 0 auto;
}

side-drawer#Drawer-Search .btq-zs__pill:hover,
side-drawer#Drawer-Search .btq-zs__pill:focus-visible {
  background: var(--btq-pink-soft);
  border-color: var(--btq-pink-deep);
  color: var(--btq-pink-deep);
}

side-drawer#Drawer-Search .btq-zs__pill:focus-visible svg {
  color: var(--btq-pink-deep);
}

/* ---- 4b. Famille tiles ---- */
side-drawer#Drawer-Search .btq-zs__fams {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin: 0;
  padding: 0;
}

side-drawer#Drawer-Search .btq-zs__fam {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 56px;
  padding: 10px 12px;
  border: 1px solid var(--btq-line);
  border-radius: var(--btq-radius-card);
  background: var(--btq-surface);
  color: var(--btq-ink);
  text-decoration: none;
  transition: border-color 160ms ease, background-color 160ms ease;
}

side-drawer#Drawer-Search .btq-zs__fam:hover,
side-drawer#Drawer-Search .btq-zs__fam:focus-visible {
  border-color: var(--btq-pink-deep);
  background: var(--btq-pink-soft);
}

side-drawer#Drawer-Search .btq-zs__fam-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--btq-pink-soft);
  color: var(--btq-pink-deep);
}

side-drawer#Drawer-Search .btq-zs__fam-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

side-drawer#Drawer-Search .btq-zs__fam-name {
  font-size: 0.92rem;
  font-weight: 600;
  line-height: 1.2;
  color: var(--btq-ink);
}

side-drawer#Drawer-Search .btq-zs__fam-count {
  font-size: 0.75rem;
  line-height: 1.2;
  color: var(--btq-ink-soft);
}

side-drawer#Drawer-Search .btq-zs__more {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 44px;
  margin-top: 4px;
  font-size: 0.85rem;
  color: var(--btq-pink-deep);
  text-decoration: none;
}

side-drawer#Drawer-Search .btq-zs__more:hover {
  text-decoration: underline;
}

/* ---- 4c. Finder card — the single highest-value link in the drawer ---- */
side-drawer#Drawer-Search .btq-zs__finder {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 64px;
  padding: 12px 14px;
  margin: 0 0 12px;
  border: 1px solid var(--btq-pink-deep);
  border-radius: var(--btq-radius-card);
  background: var(--btq-pink-soft);
  color: var(--btq-ink);
  text-decoration: none;
}

side-drawer#Drawer-Search .btq-zs__finder-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--btq-surface);
  color: var(--btq-pink-deep);
}

side-drawer#Drawer-Search .btq-zs__finder-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 auto;
  min-width: 0;
}

side-drawer#Drawer-Search .btq-zs__finder-text strong {
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1.25;
  color: var(--btq-ink);
}

side-drawer#Drawer-Search .btq-zs__finder-text small {
  font-size: 0.78rem;
  line-height: 1.3;
  color: var(--btq-ink-soft);
}

side-drawer#Drawer-Search .btq-zs__finder > svg:last-child {
  flex: 0 0 auto;
  color: var(--btq-pink-deep);
}

/* ---- 4d. Deals row ---- */
side-drawer#Drawer-Search .btq-zs__deals {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  padding: 10px 14px;
  border: 1px solid var(--btq-line);
  border-radius: var(--btq-radius-btn);
  background: var(--btq-surface);
  color: var(--btq-ink);
  font-size: 0.88rem;
  text-decoration: none;
}

side-drawer#Drawer-Search .btq-zs__deals span {
  flex: 1 1 auto;
}

side-drawer#Drawer-Search .btq-zs__deals svg {
  flex: 0 0 auto;
  color: var(--btq-ink-soft);
}

side-drawer#Drawer-Search .btq-zs__deals:hover {
  border-color: var(--btq-pink-deep);
  background: var(--btq-pink-soft);
}

/* ---- 4e. Optional product strip (inert unless a real handle is passed) ---- */
side-drawer#Drawer-Search .btq-zs__products {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0;
  padding: 0;
}

side-drawer#Drawer-Search .btq-zs__product {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 56px;
  padding: 8px 4px;
  color: var(--btq-ink);
  text-decoration: none;
}

side-drawer#Drawer-Search .btq-zs__product-img {
  flex: 0 0 auto;
  width: 48px;
  height: 48px;
  object-fit: cover;
  border-radius: 8px;
  background: var(--btq-surface-soft);
}

side-drawer#Drawer-Search .btq-zs__product-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

side-drawer#Drawer-Search .btq-zs__product-name {
  font-size: 0.9rem;
  line-height: 1.25;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

side-drawer#Drawer-Search .btq-zs__product-fam {
  font-size: 0.72rem;
  color: var(--btq-pink-deep);
}

side-drawer#Drawer-Search .btq-zs__product-price {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--btq-ink);
}

/* --------------------------------------------------------------------------
   5. RESULTS STATE — restyling the theme's own markup only
   With settings.search_layout unset, sections/predictive-search.liquid takes
   its `{% else %}` branch and renders snippets/predictive-search-tab.liquid:
   a tabs-component with Produits / Collections / Pages / Articles tabs. The
   product grid inside comes from predictive-search-products-list.liquid, which
   (settings.search_type also being unset) falls to its final branch and emits
   `grid-layout--2 gap-md` — a 2-column resource-card grid inside a narrow
   drawer. We keep the markup and retune the density.
   -------------------------------------------------------------------------- */
side-drawer#Drawer-Search #predictive-search-results {
  padding: 0;
}

side-drawer#Drawer-Search .predictive-search__heading {
  margin: 0 0 8px;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--btq-ink-soft);
}

/* ---- Tab bar ---- */
side-drawer#Drawer-Search .tabs-product-header {
  gap: 4px;
  margin-bottom: 12px;
  padding-bottom: 2px;
  border-bottom: 1px solid var(--btq-line);
  scrollbar-width: none;
}

side-drawer#Drawer-Search .tabs-product-header::-webkit-scrollbar {
  display: none;
}

side-drawer#Drawer-Search .predictive-search-tab__trigger {
  min-height: 44px;
  padding: 0 12px;
  border: 0;
  background: transparent;
  color: var(--btq-ink-soft);
  font-size: 0.88rem;
  white-space: nowrap;
  border-bottom: 2px solid transparent;
}

side-drawer#Drawer-Search .predictive-search-tab__trigger.--active,
side-drawer#Drawer-Search .predictive-search-tab__trigger[aria-selected='true'] {
  color: var(--btq-pink-deep);
  border-bottom-color: var(--btq-pink-deep);
  font-weight: 600;
}

/* ---- Suggested-query pills the theme renders above the tabs ---- */
side-drawer#Drawer-Search .predictive-search-results__wrapper-queries {
  gap: 8px;
  margin-bottom: 16px;
}

side-drawer#Drawer-Search .predictive-search-results__pill {
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--btq-line);
  border-radius: 999px;
  background: var(--btq-surface);
  color: var(--btq-ink);
  font-size: 0.88rem;
}

side-drawer#Drawer-Search .predictive-search-results__pill:hover {
  background: var(--btq-pink-soft);
  border-color: var(--btq-pink-deep);
  color: var(--btq-pink-deep);
}

/* ---- Product grid ---- */
side-drawer#Drawer-Search .predictive-search-results__wrapper-products {
  gap: 12px;
}

side-drawer#Drawer-Search .predictive-search-results__card--product .resource-card {
  gap: 8px;
}

side-drawer#Drawer-Search .predictive-search-results__card--product .resource-card__media {
  border-radius: var(--btq-radius-card);
  overflow: hidden;
  background: var(--btq-surface-soft);
}

side-drawer#Drawer-Search .predictive-search-results__card--product .resource-card__title {
  font-size: 0.88rem;
  line-height: 1.3;
  color: var(--btq-ink);
}

side-drawer#Drawer-Search .predictive-search-results__card--product .price {
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--btq-ink);
}

/* settings.predictive_search_show_vendor is ON store-wide. On a single-brand
   perfume catalogue the vendor line is the same word on every card — pure
   noise in a 2-up drawer grid. Hidden here only; the /search page keeps it. */
side-drawer#Drawer-Search .predictive-search-results__card--product .resource-card__subtext {
  display: none;
}

/* ---- Collection / page / article rows ---- */
side-drawer#Drawer-Search .predictive-search__results-list .predictive-search__item {
  min-height: 48px;
  display: flex;
  align-items: center;
  padding: 8px 4px;
  color: var(--btq-ink);
}

side-drawer#Drawer-Search .predictive-search__item-heading {
  font-size: 0.92rem;
  line-height: 1.3;
}

/* Arrow-key selection state (predictive-search.js switchOption(), L212) */
side-drawer#Drawer-Search .predictive-search__list-item[aria-selected='true'] > *,
side-drawer#Drawer-Search .predictive-search__item[aria-selected='true'] {
  background: var(--btq-pink-soft);
  border-radius: 8px;
}

/* ---- "Rechercher <terme>" catch-all button ---- */
side-drawer#Drawer-Search .predictive-search__item--term {
  min-height: 48px;
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 16px;
  padding: 12px 14px;
  border-radius: var(--btq-radius-btn);
  background: var(--btq-pink-deep);
  color: var(--btq-surface);
  font-size: 0.92rem;
  width: 100%;
  justify-content: center;
}

side-drawer#Drawer-Search .predictive-search__item--term svg {
  color: var(--btq-surface);
}

/* --------------------------------------------------------------------------
   6. NO-RESULTS — the theme emits a bare <p>. We give it a next step.
   `.predictive-search-results__no-results` is emitted by predictive-search-tab
   .liquid L160 and predictive-search-tab-empty-state.liquid L103. Because the
   zero-state suppression above hides the whole dropdown while the input is
   empty, this only ever shows for a genuine typed miss.
   -------------------------------------------------------------------------- */
side-drawer#Drawer-Search .predictive-search-results__no-results {
  padding: 24px 0 8px;
  text-align: center;
}

side-drawer#Drawer-Search .predictive-search-results__no-results p {
  margin: 0 0 4px;
  font-size: 0.95rem;
  color: var(--btq-ink);
}

side-drawer#Drawer-Search .predictive-search-results__no-results::after {
  content: 'Essayez une famille olfactive (vanille, oud, floral) ou laissez-nous vous guider.';
  display: block;
  max-width: 30ch;
  margin: 0 auto 16px;
  font-size: 0.82rem;
  line-height: 1.45;
  color: var(--btq-ink-soft);
}

/* --------------------------------------------------------------------------
   7. MOTION
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  side-drawer#Drawer-Search *,
  side-drawer#Drawer-Search *::before,
  side-drawer#Drawer-Search *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}

/* --------------------------------------------------------------------------
   8. DESKTOP — the same drawer is used above 749px; give it a sane max width.
   -------------------------------------------------------------------------- */
@media screen and (min-width: 750px) {
  side-drawer#Drawer-Search #Drawer-Search-Content {
    width: min(440px, 100vw);
    margin-left: auto;
  }

  side-drawer#Drawer-Search .btq-zs__fams {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* ==========================================================================
   DIAGNOSIS OF THE "OPENS EMPTY" REPORT — recorded here so the next pass does
   not re-litigate it.

   NOT a JS failure. assets/predictive-search.js is intact and the drawer does
   render a container. The container is empty because of CONFIGURATION:

   config/settings_data.json `current` contains predictive_search_enabled: true
   but has NO `quick_keywords`, NO `quick_links`, NO `quick_collections` and NO
   `search_layout` key at all. (Those values exist only in the demo PRESETS
   further down the file, which are never applied.)

   Consequence chain:
     predictive-search-drawer.liquid L86
       -> predictive-search-empty-state.liquid
          quick_keywords blank        -> pills block skipped
          settings.search_layout is ABSENT, so `== 'default'` is FALSE
            -> falls to the {% else %} at L105
            -> predictive-search-tab-empty-state.liquid
               quick_collections blank AND quick_links blank
                 -> tab_labels.size == 0
                 -> renders ONLY <div class="predictive-search-results__no-results">

   So the drawer opened to a single grey "no results" line. That is a MISSING
   ZERO-STATE (a design + configuration gap), not a bug. Fixing it by patching
   JS would have been wrong. The fix is the .btq-zs panel above, which does not
   depend on any theme setting being populated.
   ========================================================================== */

/* ---------- beautica-pdp.css ---------- */
/* ==========================================================================
   BEAUTICA — PDP COMPRESSION & REBALANCE (mobile-first, 360x740 target)
   Owner brief: "compressed and rebalanced", "reach Add to Cart much faster".

   Companion source-level edits live in templates/product.json:
     · main.blocks.product-details.settings.gap        28 -> 12  (7 gaps)
     · main.blocks.product-details padding-block-start 10 -> 4
     · main.blocks.product-details padding-block-end   24 -> 8
     · group_icgrde.settings.gap                       12 -> 8
     · block_order: beautica_trust_card moved BELOW buy_buttons_eYQEYi
     · media-gallery swiper_buttons_gap                20 -> 8
     · section-product-tabs / recently-viewed / product-recommendations padding

   WHY gap 28 -> 12 matters: snippets/gap-style.liquid emits
   `max(24px, var(--gap-scale) * 28px)`. On mobile --gap-scale is 0.5
   (base.css:5551) so 28 resolved to max(24, 14) = 24px, NOT 14px. Any value
   <= 24 is emitted literally, so 12 really is 12px on every breakpoint.

   SELECTORS VERIFIED against real markup (no guesses):
     blocks/beautica-pdp-title.liquid   -> .btq-pdp-title .btq-pdp-sub
     blocks/beautica-trust-card.liquid  -> .btq-trust-card .btq-trust-card__row
     blocks/beautica-chips.liquid       -> .btq-chips .btq-chip .btq-chip__label
     blocks/beautica-faq.liquid         -> .btq-faq .btq-faq__title/__item/__q/__a
     blocks/price.liquid                -> <product-price class="text-block ...">
     blocks/buy-buttons.liquid          -> .buy-buttons-block .product-form__buttons
     snippets/quantity-selector.liquid  -> .quantity__label.form__label
     snippets/product-variant-picker.liquid -> .variant-option .form__label
     blocks/_product-media-gallery.liquid -> .product-media-container(.media-fit-cover)
     assets/base.css:6555               -> --gallery-aspect-ratio override hook
     assets/section-main-product.css:657 -> .product-media-container .media padding-top
     sections/recently-viewed-products.liquid:43,67 -> .recently-viewed-products
                                                      .section-global__header
     sections/product-recommendations.liquid:46,80 -> .product-recommendations
                                                      .section-resource-list__content
   REJECTED after checking the DOM: `.section-header` does not exist in this
   theme (the real classes are the two above) — not shipped.
   ========================================================================== */

@media screen and (max-width: 749px) {

  /* ------------------------------------------------------------------
     1. HERO MEDIA  345 -> ~276px
     The box height is driven by TWO things, not one (hard-won lesson #4):
       a) aspect-ratio: var(--gallery-aspect-ratio, var(--media-preview-ratio))
       b) .media { padding-top: var(--ratio-percent) }  <- in-flow child
     Override both or nothing moves.
     NO CROP: images are square 400x400 on pure white and non-white content
     margins vary 0.8%-11.7%, so we letterbox with object-fit:contain instead
     of cropping. On a white field the letterbox is invisible; the bottle just
     renders ~79% scale with no dead margin above and below it.
     ------------------------------------------------------------------ */
  .product-information__media .product-media-container {
    --gallery-aspect-ratio: 1.27;
  }
  .product-information__media .product-media-container .media {
    padding-top: 78.7%; /* 1 / 1.27 */
  }
  .product-information__media .product-media-container img,
  .product-information__media .product-media-container.media-fit-cover img {
    object-fit: contain;
    object-position: center center;
  }

  /* ------------------------------------------------------------------
     2. TITLE BLOCK  ~55 -> ~47px
     Tighter leading, margins collapsed. h1 stays 25px, subline stays 12px
     (>= 12px floor for customer-read type).
     ------------------------------------------------------------------ */
  .product-details .btq-pdp-title {
    font-size: 25px;
    line-height: 1.1;
    margin: 0 0 1px;
  }
  .product-details .btq-pdp-sub {
    font-size: 12px;
    line-height: 1.35;
    margin: 0 0 2px;
  }

  /* ------------------------------------------------------------------
     3. PRICE  ~45 -> ~34px
     Price size is a conversion signal — font stays 2.8rem. Only the
     surrounding dead space goes.
     ------------------------------------------------------------------ */
  .product-details product-price {
    display: block;
    line-height: 1.15;
  }
  .product-details product-price .tax-note,
  .product-details product-price .installments {
    margin-top: 2px;
    font-size: 12px;
    line-height: 1.3;
  }

  /* ------------------------------------------------------------------
     4. VARIANT PICKER + QUANTITY + ATC read as ONE purchase unit
     ~148 -> ~115px for the picker; quantity pulled tight to the button.
     Swatch/pill and quantity controls keep >= 44px tap targets.
     ------------------------------------------------------------------ */
  .product-details .variant-option {
    margin-block: 0;
  }
  .product-details .variant-option + .variant-option {
    margin-top: 10px;
  }
  .product-details .variant-option .form__label,
  .product-details .quantity__label.form__label {
    font-size: 13px;
    line-height: 1.25;
    margin: 0 0 6px;
  }
  .product-details .variant-option--pill label,
  .product-details .variant-option--buttons label {
    min-height: 44px;
    padding-block: 0;
    display: inline-flex;
    align-items: center;
  }

  .product-details .buy-buttons-block {
    gap: 10px;
  }
  .product-details .product-form__buttons {
    margin-block: 0;
  }
  /* quantity sits immediately above ATC, no orphan gap */
  .product-details .product-form__quantity {
    margin-block: 0 8px;
  }
  .product-details .quantity,
  .product-details .quantity__button,
  .product-details .quantity__input {
    min-height: 44px;
  }

  /* ------------------------------------------------------------------
     5. TRUST CARD  226 -> ~172px  (-24%)
     Was: 2x2 white tiles, rows min-height 96, icon 28, gap 10, pad 12
          => 12 + 96 + 10 + 96 + 12 = 226px exactly.
     Now: same four tiles, same four texts, same design language —
          icon 28 -> 21 (-25%), tile padding 14/10/12 -> 8/6,
          font 13 -> 12.5, gap 10 -> 8, card padding 12 -> 10,
          decorative underline retired on mobile only (it cost 6px/row).
     Also relocated BELOW the buy buttons in templates/product.json: it is
     reassurance about the purchase, so it now sits where the purchase
     decision is made instead of pushing it 250px down the page.
     Beats the earlier rules at (0,1,0)!important on specificity (0,2,0).
     ------------------------------------------------------------------ */
  .product-details .btq-trust-card {
    padding: 10px !important;
    gap: 8px !important;
    margin: 0 !important;
    border-radius: 14px;
  }
  .product-details .btq-trust-card__row {
    min-height: 74px !important;
    padding: 8px 6px !important;
    gap: 4px !important;
    font-size: 12.5px !important;
    line-height: 1.25 !important;
    border-radius: 12px;
  }
  .product-details .btq-trust-card__row .btq-icon {
    width: 21px !important;
    height: 21px !important;
  }
  .product-details .btq-trust-card__row::after {
    display: none;
  }

  /* ------------------------------------------------------------------
     6. BENEFITS  ~168 -> ~117px
     Nothing removed — title and every bullet stay, at readable 13.5px.
     ------------------------------------------------------------------ */
  .product-details .btq-benefits {
    margin: 0;
  }
  .product-details .btq-benefits__title {
    font-size: 15px;
    line-height: 1.25;
    margin: 0 0 6px;
  }
  .product-details .btq-benefits__list {
    gap: 5px;
  }
  .product-details .btq-benefits__item {
    font-size: 13.5px;
    line-height: 1.4;
    gap: 8px;
  }
  .product-details .btq-benefits__item .btq-icon {
    width: 16px;
    height: 16px;
    margin-top: 1px;
  }

  /* ------------------------------------------------------------------
     7. SCENT CHIPS  112 -> ~78px
     Every chip still renders with its icon and its label. Lower height and
     tighter padding let the same set reflow into fewer rows.
     Chips are read-only descriptors, not tap targets — no 44px floor here.
     ------------------------------------------------------------------ */
  .product-details .btq-chips {
    gap: 6px;
    margin: 0;
  }
  .product-details .btq-chip {
    min-height: 26px;
    padding: 3px 9px;
    gap: 5px;
    font-size: 12.5px;
    line-height: 1.15;
  }
  .product-details .btq-chip .btq-icon {
    width: 14px;
    height: 14px;
  }

  /* ------------------------------------------------------------------
     8. FAQ  ~292 -> ~240px
     All five questions stay. Summary drops 48 -> 44px (the tap floor,
     not below it) and the block margin is handed to the flex gap.
     ------------------------------------------------------------------ */
  .product-details .btq-faq {
    margin: 0;
  }
  .product-details .btq-faq__title {
    font-size: 15px;
    line-height: 1.25;
    margin: 0 0 2px;
  }
  .product-details .btq-faq__q {
    min-height: 44px;
    padding: 9px 0;
    font-size: 14px;
    line-height: 1.3;
    gap: 10px;
  }
  .product-details .btq-faq__a {
    font-size: 13.5px;
    line-height: 1.5;
    margin: 0 0 10px;
  }

  /* ------------------------------------------------------------------
     9. BELOW-THE-FOLD CAROUSELS
     Section padding is cut at source in templates/product.json. Here we
     only take the heading rhythm inside them. Card geometry itself is
     beautica-card.css territory and is deliberately untouched.
     ------------------------------------------------------------------ */
  .recently-viewed-products .section-global__header {
    margin-bottom: 10px;
  }
  .product-recommendations .section-resource-list__content {
    margin-bottom: 0;
  }

  /* ------------------------------------------------------------------
     10. NO CLS GUARD
     The media box is the only thing whose intrinsic size we changed, and
     it is pinned by an explicit ratio + padding-top pair above, so the
     reserved space is correct on first paint. Nothing here is JS-driven.
     ------------------------------------------------------------------ */
}

/* ==========================================================================
   STICKY BAR — the fixed "Choisir les options" / add-to-cart bar overlapped the
   last of the page (recently-viewed cards and the footer sat underneath it).
   The theme reserves only 38px of body padding, which is less than the bar.
   Reserve the bar's real height plus the mobile toolbar and the iOS safe area.
   ========================================================================== */
@media (max-width: 749px) {
  body { padding-bottom: calc(64px + 51px + env(safe-area-inset-bottom, 0px)) !important; }
  /* recently-viewed: match the collection grid instead of one giant card */
  .shopify-section:has(.btq-card) .grid__item { min-width: 0; }
  .btq-card { max-width: 100%; }
}

/* ==========================================================================
   BOTTOM SPACING CORRECTION. I had reserved 64+51+safe-area (115px) of body
   padding for the sticky add-to-cart bar. But that bar only exists on product
   pages, so on every other page — and below the footer on all of them — it
   rendered as a band of dead white space (the owner marked it under the
   copyright line).
   Reserve only the mobile toolbar globally; add the sticky-bar allowance ONLY
   on pages that actually contain one.
   ========================================================================== */
@media (max-width: 749px) {
  body { padding-bottom: calc(51px + env(safe-area-inset-bottom, 0px)) !important; }
  /* Do NOT add the sticky-bar allowance to body padding. The bar is position:fixed
     and only visible while the buy form is off-screen — by the time the customer
     reaches the footer it is gone, so the reservation rendered as ~129px of dead
     white under the copyright line (the owner marked exactly this). A fixed bar
     overlapping the final few px of a page is normal; 129px of blank is not.
     The toolbar reservation above is the only one that must always hold. */
  /* the footer's own bottom padding no longer needs to clear anything */
  .btq-ft__base { padding-bottom: 14px !important; }
}

/* ---------- beautica-collection.css ---------- */
/* ==========================================================================
   BEAUTICA — COLLECTION DESCRIPTION: short preview + premium "Afficher plus"
   File owned by this pass. Concatenated LAST into beautica-custom.css, so every
   rule here lands after base.css AND after the earlier beautica parts.

   VERIFIED MARKUP (snippets/text.liquid L263-275, rendered when the block
   setting collapse_text is true — templates/collection.json "text_Lw7jtn"):

     <collapsible-text class="is-collapsed">
       <div class="collection-description-text"    data-content-full>   ...full...
       <div class="collection-description-preview" data-content-preview>...100 words...
       <div class="collapsible-buttons">
         <button data-collapse-button-more type="button" class="link link--underline">
         <button data-collapse-button-less type="button" class="link link--underline">

   VERIFIED JS (assets/global.js L5122-5167, class CollapsibleText):
     heightFullText    = fullText.offsetHeight
     heightPreviewText = previewText.scrollHeight
     if (heightPreviewText <= heightFullText)  -> add .is-collapsed, WIRE the buttons
     else                                      -> REMOVE .is-collapsed and return
   The buttons are therefore already real <button>s with real listeners. No new JS
   is needed — the component was being disabled by a measurement failure.

   WHY THE BUTTON WAS INVISIBLE — this was self-inflicted, not a theme bug.
   beautica-custom.css L511 applies a 3-line -webkit-line-clamp to
   [class*="collection-description"], which matches the hidden MEASUREMENT div
   .collection-description-text as well as the preview. So:
     heightFullText    collapsed to ~3 lines (offsetHeight respects the clamp)
     heightPreviewText stayed the full content height (scrollHeight ignores it)
   -> the guard flipped to the else branch -> .is-collapsed was stripped and the
   listeners were never attached. base.css L17826-17841 hides BOTH buttons on a
   bare <collapsible-text> and only reveals them under .is-collapsed/.is-expanded,
   which is exactly the "computes display:none" the orchestrator measured.

   FIX ORDER BELOW:
     1. un-clamp the measurement div so the guard passes  (restores the JS)
     2. clamp the preview with max-height instead of -webkit-line-clamp
     3. neutralise the inline height Motion leaves behind
     4. restyle the two buttons as one premium control
   ========================================================================== */

/* --------------------------------------------------------------------------
   1 · MEASUREMENT DIV — must never be clamped.
   Beats [class*="collection-description"] (0,1,0) with (0,1,1) + later source
   order. This single rule is what re-enables the theme's own expand logic.
   -------------------------------------------------------------------------- */
collapsible-text .collection-description-text {
  display: block;
  -webkit-line-clamp: unset;
  -webkit-box-orient: unset;
  max-height: none;
  height: auto;
  overflow: visible;
  /* keep the theme's own out-of-flow measurement geometry (base.css L17856) */
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  visibility: hidden;
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   2 · THE PREVIEW.
   -webkit-line-clamp is deliberately NOT used: it cannot be transitioned, and
   its interaction with scrollHeight is what broke the component in the first
   place. A max-height in em animates cleanly and leaves measurement honest.
   Height is expressed in em so it tracks whatever font-size ends up applying.
   -------------------------------------------------------------------------- */
collapsible-text {
  --btq-desc-lh: 1.55;
  --btq-desc-lines: 3;
  --btq-desc-fade: 26px;
  display: block;
}

@media (min-width: 750px) {
  collapsible-text {
    --btq-desc-lines: 4;
  }
}

collapsible-text .collection-description-preview {
  display: block;
  position: relative;
  overflow: hidden;
  font-size: 13.5px;
  line-height: var(--btq-desc-lh);
  color: var(--btq-ink-soft);
  /* undo the -webkit-box clamp inherited from the earlier parts */
  -webkit-line-clamp: unset;
  -webkit-box-orient: unset;
  /* Motion.animate() writes inline height/min-height on this element
     (global.js showMore/showLess). !important is required to beat inline. */
  height: auto !important;
  min-height: 0 !important;
}

/* Collapsed: 3 lines (4 on desktop), softly faded out at the cut.
   The fade is a MASK, not a painted gradient — it needs no knowledge of the
   section background colour, so it cannot mismatch it. */
collapsible-text.is-collapsed .collection-description-preview {
  max-height: calc(var(--btq-desc-lh) * var(--btq-desc-lines) * 1em);
  -webkit-mask-image: linear-gradient(
    to bottom,
    #000 calc(100% - var(--btq-desc-fade)),
    transparent 100%
  );
  mask-image: linear-gradient(
    to bottom,
    #000 calc(100% - var(--btq-desc-fade)),
    transparent 100%
  );
  transition: max-height 0.3s cubic-bezier(0.4, 0, 0.6, 1);
}

/* Expanded: open. 400em ≈ 5400px at this font-size — far past any real
   description, while still short enough that the ease reads as intentional. */
collapsible-text.is-expanded .collection-description-preview {
  max-height: 400em;
  -webkit-mask-image: none;
  mask-image: none;
  transition: max-height 0.45s cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* --------------------------------------------------------------------------
   2b · MARKUP DENSITY.
   An earlier pass collapsed <br>/<p> inside the preview so the clamp measures
   real text. That was correct for the COLLAPSED state only — but on expand the
   JS swaps the preview's innerHTML to the FULL text, so those rules would have
   flattened the merchant's paragraphs into one run separated by " · ".
   Scope them: collapse in the preview, restore the real formatting on expand.
   -------------------------------------------------------------------------- */
collapsible-text.is-collapsed .collection-description-preview br {
  display: none;
}
collapsible-text.is-collapsed .collection-description-preview p {
  display: inline;
}
collapsible-text.is-collapsed .collection-description-preview p + p::before {
  content: ' · ';
  color: var(--btq-pink-deep);
}

collapsible-text.is-expanded .collection-description-preview br {
  display: initial;
}
collapsible-text.is-expanded .collection-description-preview p {
  display: block;
  margin: 0 0 0.7em;
}
collapsible-text.is-expanded .collection-description-preview p:last-child {
  margin-bottom: 0;
}
collapsible-text.is-expanded .collection-description-preview p + p::before {
  content: none;
}

/* --------------------------------------------------------------------------
   3 · THE CONTROL.
   base.css reveals exactly one of the two buttons per state at (0,2,1):
     collapsible-text.is-collapsed [data-collapse-button-more] { display:block }
     collapsible-text.is-expanded  [data-collapse-button-less] { display:block }
   Matching that specificity and landing later lets inline-flex win, which is
   what the chevron needs. !important guards against the parts order changing.
   -------------------------------------------------------------------------- */
collapsible-text .collapsible-buttons {
  display: flex;
  justify-content: var(--text-align, flex-start);
  margin-top: 10px;
}

collapsible-text.is-collapsed [data-collapse-button-more],
collapsible-text.is-expanded [data-collapse-button-less] {
  display: inline-flex !important;
}

collapsible-text .collapsible-buttons button.link {
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 18px;
  border: 1px solid var(--btq-line);
  border-radius: 999px;
  background-color: var(--btq-pink-soft);
  /* .link--underline paints its underline with a background-image gradient
     (base.css L13859-13866, specificity 0,2,0) — cancel the image, keep ours. */
  background-image: none;
  color: var(--btq-pink-deep);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.01em;
  line-height: 1;
  text-transform: none;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.2s ease, border-color 0.2s ease,
    transform 0.15s ease;
}

/* Chevron. Drawn with borders so it inherits currentColor and needs no asset. */
collapsible-text .collapsible-buttons button.link::after {
  content: '';
  flex: none;
  width: 6px;
  height: 6px;
  border-right: 1.6px solid currentColor;
  border-bottom: 1.6px solid currentColor;
  border-radius: 1px;
  /* nudged up so the rotated square looks optically centred on the cap height */
  margin-top: -3px;
  transform: rotate(45deg);
  transition: transform 0.25s cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* Expanded state points the chevron up. Because "more" and "less" are two
   separate elements swapped by display, the rotation is played as a short
   entrance on the button that becomes visible — it reads as one control
   turning over rather than two links trading places. */
collapsible-text .collapsible-buttons [data-collapse-button-less]::after {
  transform: rotate(-135deg);
  margin-top: 2px;
}

@keyframes btq-desc-chevron-down {
  from {
    transform: rotate(-135deg);
  }
  to {
    transform: rotate(45deg);
  }
}
@keyframes btq-desc-chevron-up {
  from {
    transform: rotate(45deg);
  }
  to {
    transform: rotate(-135deg);
  }
}

collapsible-text.is-collapsed [data-collapse-button-more]::after {
  animation: btq-desc-chevron-down 0.3s cubic-bezier(0.22, 0.61, 0.36, 1);
}
collapsible-text.is-expanded [data-collapse-button-less]::after {
  animation: btq-desc-chevron-up 0.3s cubic-bezier(0.22, 0.61, 0.36, 1);
}

collapsible-text .collapsible-buttons button.link:hover {
  background-color: #fbe6f2;
  border-color: var(--btq-pink-deep);
}
collapsible-text .collapsible-buttons button.link:active {
  transform: scale(0.98);
}
collapsible-text .collapsible-buttons button.link:focus-visible {
  outline: 2px solid var(--btq-pink-deep);
  outline-offset: 2px;
}

/* --------------------------------------------------------------------------
   4 · REDUCED MOTION.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  collapsible-text .collection-description-preview,
  collapsible-text .collapsible-buttons button.link,
  collapsible-text .collapsible-buttons button.link::after {
    transition: none !important;
    animation: none !important;
  }
}

/* ---------- beautica-home.css ---------- */
/* ==========================================================================
   BEAUTICA — HOMEPAGE VERTICAL RHYTHM
   Owner: "the homepage scrolls much longer than necessary ... keep it breathable,
   do NOT make it crowded."

   PRIMARY FIX LIVES IN templates/index.json. This file exists ONLY for the
   homepage bands that are genuinely NOT a theme setting:

     a) sections/beautica-merch-shelf.liquid  -> style="padding-block: 40px" HARDCODED
     b) sections/beautica-notes.liquid        -> style="padding-block: 32px" HARDCODED
     c) assets/beautica-custom.css:371-374    -> a v4 "rhythm" pass that already
        overrides the real settings with !important:
            .btq-finder-cta            { padding: 32px 16px; }
            .btq-cats, .btq-occasions  { padding-block: 16px !important; }
            .btq-shelf,.btq-grid-section{ padding-block: 32px !important; }
        Because of (c) the `padding` range on beautica-categories / beautica-grid
        was DEAD — the Theme Editor slider moved nothing. index.json is now set to
        the intended value AND this file is set to the same number, so the two
        agree instead of fighting.

   SPECIFICITY: the rules in (c) are (0,1,0)!important. beautica-home.css is
   concatenated into beautica-custom.css by the build and its position in that
   list is not guaranteed, so every override below is doubled (.x.x -> (0,2,0))
   and wins on specificity rather than on source order. Lesson #2 / #5.

   THE SCALE (mobile, <=749px) — 8px base:
       12px  inside a compact strip (category / moments rows)
       16px  around a full content block (shelf, grid, notes, blog)
       20px  a standalone CTA band (the perfume-finder invite)
       ~28-36px is the resulting gap between two adjacent sections.
   Floor honoured: no seam between major sections drops below 24px.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1 · SECTION BANDS
   .btq-occasions is deliberately absent: that section was rebuilt as
   .btq-moments and reads --btq-moments-pad straight from section.settings.padding,
   so templates/index.json (padding: 12) already controls it. Do not add a rule
   here or the setting goes dead again.
   -------------------------------------------------------------------------- */

/* Category strip — compact scroller, hugs its neighbours */
.btq-cats.btq-cats { padding-block: 12px !important; }

/* Seasonal shelf + best-seller grid + olfactive families: full content blocks */
.btq-shelf.btq-shelf,
.btq-grid-section.btq-grid-section,
.btq-notes.btq-notes { padding-block: 16px !important; }

/* Perfume-finder invite. The section's own padding_top/bottom is now 0 in
   index.json (it was 40/52, halved to 20/26 on mobile by .spacing in
   base.css:2138) so this padding IS the whole band — one number, one place. */
.btq-finder-cta.btq-finder-cta { padding: 20px 16px; }

/* --------------------------------------------------------------------------
   2 · INTERNAL RHYTHM — heading -> content, content -> CTA
   Same 8px scale so the compression reads deliberate, not squeezed.
   -------------------------------------------------------------------------- */
.btq-cats__head.btq-cats__head { margin-bottom: 10px; }

.btq-grid-section__head.btq-grid-section__head,
.btq-shelf__head.btq-shelf__head,
.btq-notes__head.btq-notes__head { margin-bottom: 12px; }

.btq-shelf__sub.btq-shelf__sub { margin-bottom: 12px; }

.btq-shelf__cta.btq-shelf__cta { margin-top: 14px; }
.btq-notes__cta.btq-notes__cta { margin-top: 12px; }

.btq-finder-cta.btq-finder-cta h2 { margin-bottom: 6px; }
.btq-finder-cta.btq-finder-cta p  { margin-bottom: 14px; }

/* --------------------------------------------------------------------------
   3 · DESKTOP — a narrow column can afford air a tall phone cannot.
   Restore roughly 1.5-2x above 990px so the desktop homepage keeps its
   editorial breathing room. Mobile is the surface the owner measured.
   -------------------------------------------------------------------------- */
@media screen and (min-width: 990px) {
  .btq-cats.btq-cats { padding-block: 20px !important; }

  .btq-shelf.btq-shelf,
  .btq-grid-section.btq-grid-section,
  .btq-notes.btq-notes { padding-block: 28px !important; }

  .btq-finder-cta.btq-finder-cta { padding: 32px 16px; }

  .btq-grid-section__head.btq-grid-section__head,
  .btq-shelf__head.btq-shelf__head,
  .btq-notes__head.btq-notes__head { margin-bottom: 16px; }
}

/* ---------- beautica-occasions.css ---------- */
/* ==========================================================================
   BEAUTICA — "Pour chaque moment" (moments grid, V2 redesign)
   Pairs with sections/beautica-occasions.liquid.

   NAMESPACE NOTE — this file deliberately uses .btq-moments, NOT .btq-occasions.
   assets/beautica-custom.css carries THREE stacked legacy cascade layers for
   .btq-occasions / .btq-chip--action (base ~L207, mobile ~L363, pastel ~L438),
   including `.btq-cats, .btq-occasions { padding-block: 16px !important; }`
   which would beat this file's spacing AND the section's inline padding.
   Renaming sidesteps that fight entirely instead of escalating !important.
   The old rules become dead once the section stops emitting those classes.
   ========================================================================== */

.btq-moments {
  max-width: 1200px;
  margin: 0 auto;
  padding-inline: 16px;
  padding-block: var(--btq-moments-pad, 20px);
}

/* ---------- header ---------- */
.btq-moments__head { margin: 0 0 12px; }

.btq-moments__title {
  margin: 0;
  font-size: 17px;
  line-height: 1.25;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--btq-ink, #1A1A1A);
}

.btq-moments__sub {
  margin: 3px 0 0;
  font-size: 13px;
  line-height: 1.35;
  font-weight: 400;
  color: var(--btq-ink-soft, #5C5C66);
}

/* ---------- grid: 2 columns, no horizontal scroll ---------- */
.btq-moments__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

/* ---------- card ---------- */
.btq-moments__card {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 60px;
  padding: 9px 10px;
  border-radius: var(--btq-radius-card, 12px);
  background: var(--btq-surface, #FFF);
  border: 1px solid var(--btq-line, #EBE6EA);
  text-decoration: none;
  /* keeps a long title from shoving the icon tile out of the card */
  min-width: 0;
  transition: border-color .16s ease-out, box-shadow .16s ease-out, transform .16s ease-out;
}

.btq-moments__card:hover,
.btq-moments__card:focus-visible {
  border-color: var(--btq-pink-deep, #C2117E);
  box-shadow: 0 2px 10px rgba(194, 17, 126, .09);
}

.btq-moments__card:focus-visible {
  outline: 2px solid var(--btq-pink-deep, #C2117E);
  outline-offset: 2px;
}

.btq-moments__card:active { transform: scale(.975); }

/* ---------- icon tile (carries the pastel story) ---------- */
.btq-moments__tile {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 10px;
  background: var(--tint-bg, #FDF2F8);
  color: var(--tint-fg, #C2117E);
}

.btq-moments__tile .btq-icon { display: block; }

/* ---------- text stack ---------- */
.btq-moments__text {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.btq-moments__label {
  font-size: 14px;
  line-height: 1.2;
  font-weight: 600;
  color: var(--btq-ink, #1A1A1A);
  /* one line only — a wrapped title breaks the 60px row rhythm */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.btq-moments__desc {
  font-size: 12px; /* readable-text floor */
  line-height: 1.25;
  font-weight: 400;
  color: var(--btq-ink-soft, #5C5C66);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---------- per-card tints (self-healing: reorder just reshuffles) ---------- */
.btq-moments__grid > .btq-moments__card:nth-child(6n + 1) { --tint-bg: #FDF2F8; --tint-fg: #C2117E; }
.btq-moments__grid > .btq-moments__card:nth-child(6n + 2) { --tint-bg: #FFF6E5; --tint-fg: #A96B00; }
.btq-moments__grid > .btq-moments__card:nth-child(6n + 3) { --tint-bg: #F4F1FD; --tint-fg: #6A45C4; }
.btq-moments__grid > .btq-moments__card:nth-child(6n + 4) { --tint-bg: #FFF1EC; --tint-fg: #B4522A; }
.btq-moments__grid > .btq-moments__card:nth-child(6n + 5) { --tint-bg: #EEF1FB; --tint-fg: #3F52A8; }
.btq-moments__grid > .btq-moments__card:nth-child(6n + 6) { --tint-bg: #EDF7F1; --tint-fg: #1F7A4D; }

/* ---------- desktop ---------- */
@media screen and (min-width: 750px) {
  .btq-moments__title { font-size: 22px; }
  .btq-moments__sub { font-size: 14px; }
  .btq-moments__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
  .btq-moments__card { min-height: 68px; padding: 12px 14px; gap: 12px; }
  .btq-moments__tile { width: 42px; height: 42px; }
  .btq-moments__label { font-size: 15px; }
  .btq-moments__desc { font-size: 13px; }
}

@media (prefers-reduced-motion: reduce) {
  .btq-moments__card { transition: none; }
  .btq-moments__card:active { transform: none; }
}

/* ---------- beautica-easysell.css ---------- */
/* ==========================================================================
   BEAUTICA — ONE PRIMARY ACTION + EASYSELL COD NATIVE SKIN
   Owner brief: (a) remove "Acheter maintenant" from every product page, leave
   no dead space; (b) make the EasySell COD order form look like one premium
   site, not two systems bolted together.

   CONCATENATION: append this file into assets/beautica-custom.css BEFORE the
   "/* ==== END GENERATED PARTS ==== *\/" marker and AFTER the beautica-card.css
   section. Only beautica-custom.css is <link>ed (layout/theme.liquid:74) — a
   standalone beautica-easysell.css asset is never loaded by the theme.

   --------------------------------------------------------------------------
   SELECTORS CONFIRMED against real repo markup (file:line):
     .accelerated-checkout-block             blocks/accelerated-checkout.liquid:94
     .checkout--button-secondary  (modifier) blocks/accelerated-checkout.liquid:94
     .shopify-payment-button__button         assets/base.css:9657   (Shopify-emitted)
     .shopify-payment-button__button--unbranded  assets/base.css:9976
     .shopify-payment-button__more-options   assets/base.css:9971
     more-payment-options-link  (element)    assets/base.css:9958
     .product-form__buttons  + --gap         blocks/buy-buttons.liquid:102-108
     .buy-buttons-block                      assets/base.css:9625
     .add-to-cart-button-container           blocks/add-to-cart.liquid:38
     .add-to-cart-button-inner               blocks/add-to-cart.liquid:42
     button[name="add"].button               beautica-custom.css:305 (primary CTA spec)
     .field / .field__input / .field__label  assets/base.css:3080-3130
     .product-details                        used throughout beautica-pdp.css
     .shopify-app-block / [id^="shopify-block-"]
                                             Shopify theme-app-extension wrapper
                                             (platform-emitted, not app-specific)

   NOT CONFIRMED — EasySell ships ZERO markup into this repo. Verified by:
     grep -rn -i "easysell" over *.liquid *.json *.css *.js  -> 0 hits
     config/settings_data.json app embeds   -> only hiko-social-login and
                                               google-youtube. No EasySell.
   Therefore EVERY EasySell-specific class name is unknown. Per the project's
   hard-won lesson #1, no guessed EasySell selector is shipped live in this
   file. Section 3 is a variable-driven skin that activates only once the
   orchestrator stamps the real container (see the instructions there).
   ========================================================================== */


/* --------------------------------------------------------------------------
   1. KILL "ACHETER MAINTENANT" (Shopify dynamic / accelerated checkout)

   SOURCE-LEVEL ATTEMPT (already made): templates/product.json now carries
     sections.main.blocks.product-details.blocks.buy_buttons_eYQEYi
       .blocks.accelerated-checkout -> "disabled": true
   WHY CSS IS STILL REQUIRED: there is no show_dynamic_checkout setting on the
   block that actually renders. snippets/buy-buttons.liquid:21-23 has one, but
   that snippet is the LEGACY path — this template renders blocks/buy-buttons
   .liquid, which emits the payment button through an unconditional
     {% content_for 'block', type: 'accelerated-checkout', id: ... %}   (:129-134)
   and blocks/accelerated-checkout.liquid:104-107 prints {{ form_obj |
   payment_button }} with no enable/disable checkbox in its schema (:114-185).
   Static blocks are rendered by content_for regardless of block_order, so the
   "disabled" flag may well be ignored by the platform. The flag is harmless
   and reversible either way; this rule is the guarantee.
   -------------------------------------------------------------------------- */

/* Global, not scoped to .product-details: the owner asked for ONE primary
   action on ALL product surfaces (main PDP, quick-add modal, featured-product
   sections). The cart's own checkout CTA uses .cart__checkout-button and is
   NOT matched here. */
.accelerated-checkout-block,
.product-form__buttons .accelerated-checkout-block,
.product-form__buttons .shopify-payment-button,
.product-form__buttons .shopify-payment-button__button,
.product-form__buttons more-payment-options-link,
.shopify-payment-button__more-options {
  display: none !important;
}


/* --------------------------------------------------------------------------
   2. CLOSE THE GAP LEFT BEHIND

   MEASUREMENT / HONEST ACCOUNTING. .product-form__buttons is
   `display:flex; flex-wrap:wrap; gap:var(--gap)` (base.css:9630-9635) with
   --gap:10px from the block setting. Its flex children are:
       quantity selector · add-to-cart container · hidden error span ·
       accelerated-checkout-block
   Reclaimed by removing the last child:
       payment button   ~50px  (min-height:50px, beautica-custom.css:319-326)
       + one 10px flex row-gap
       = ~60px of vertical space, on every product page.
   Flex `gap` is only drawn BETWEEN rendered items, so display:none removes
   the gap with the button — there is no orphan 10px band to chase. The
   agree-condition wrapper (a further 20+20px of padding) was already off
   (agree_condition:false) and its paddings are now zeroed in product.json too,
   so it cannot reappear if the setting is ever re-enabled by accident.

   The rules below are defensive: they make sure nothing that used to sit
   alongside the payment button now keeps a margin reserved for it, and that
   the surviving CTA goes truly full-width instead of flex-sharing the row.
   -------------------------------------------------------------------------- */

.product-form__buttons {
  /* wrap-row gap no longer needs to double as the ATC/payment-button gap */
  row-gap: 8px;
}

/* The remaining CTA is now the only action — let it own the full row. */
.product-form__buttons > .add-to-cart-button-container {
  flex: 1 1 100%;
  min-width: 100%;
}

/* No block-level margin may survive under the now-single CTA. */
.buy-buttons-block,
.product-details .buy-buttons-block {
  margin-block-end: 0;
}
.add-to-cart-button-inner {
  margin-block-end: 0;
}


/* --------------------------------------------------------------------------
   3. EASYSELL COD — NATIVE SKIN  (ACTIVATION REQUIRED)

   *** READ BEFORE ENABLING ***
   EasySell's DOM is not in this repo, so its class names are unknown and NONE
   are guessed here. This section is written against ONE hook the orchestrator
   controls: the attribute [data-btq-easysell] on EasySell's outermost
   container. Nothing below applies until that attribute exists.

   ORCHESTRATOR — to activate, do exactly this in the live preview DOM:
     1. Open a product page, find EasySell's wrapper. Likely shapes, in order:
        a) a theme app-extension block:  [id^="shopify-block-"] .shopify-app-block
        b) an inline <div> injected by a ScriptTag
        c) a custom element
     2. Copy its REAL outermost selector.
     3. Add ONE line to this file mapping it to the hook, e.g.
          <real-selector> { }            /* alias, see note */
        or, preferred, replace every `[data-btq-easysell]` below with the real
        selector via find-and-replace. Do not add both.
     4. Re-verify the field/button/label sub-selectors the same way — the
        descendant selectors below use only GENERIC element selectors
        (input, select, textarea, label, button[type=submit]) precisely so they
        survive without knowing EasySell's class names.

   Everything in 3.1 is scoped inside [data-btq-easysell]; with the attribute
   absent these rules match nothing and cost nothing. They cannot leak.
   -------------------------------------------------------------------------- */

[data-btq-easysell] {
  /* one typographic system, not two */
  font-family: "Cabin", var(--font-body--family), sans-serif;
  color: var(--btq-ink, #1A1A1A);
  background: var(--btq-surface, #fff);
  border: 1px solid var(--btq-line, #EBE6EA);
  border-radius: var(--btq-radius-card, 12px);
  padding: 14px;
  margin-block: 12px 0;
  -webkit-font-smoothing: antialiased;
}

/* 3.1 — form fields matched to the theme's .field__input rhythm */
[data-btq-easysell] input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]),
[data-btq-easysell] select,
[data-btq-easysell] textarea {
  width: 100%;
  min-height: 46px;              /* >= 44px tap target */
  box-sizing: border-box;
  padding: 10px 12px;
  font-family: inherit;
  font-size: 15px;               /* >= 16px avoids iOS zoom; 15 matches theme */
  line-height: 1.35;
  color: var(--btq-ink, #1A1A1A);
  background: var(--btq-surface, #fff);
  border: 1px solid var(--btq-line, #EBE6EA);
  border-radius: 10px;
  transition: border-color .18s ease-out, box-shadow .18s ease-out;
}

[data-btq-easysell] input:focus,
[data-btq-easysell] select:focus,
[data-btq-easysell] textarea:focus,
[data-btq-easysell] input:focus-visible,
[data-btq-easysell] select:focus-visible,
[data-btq-easysell] textarea:focus-visible {
  outline: none;
  border-color: var(--btq-pink-deep, #C2117E);
  box-shadow: 0 0 0 3px rgba(194, 17, 126, .12);
}

[data-btq-easysell] input::placeholder,
[data-btq-easysell] textarea::placeholder {
  color: var(--btq-ink-soft, #5C5C66);
  opacity: 1;
}

[data-btq-easysell] label {
  display: block;
  font-size: 13px;               /* above the 12px readable floor */
  font-weight: 600;
  color: var(--btq-ink, #1A1A1A);
  margin: 0 0 5px;
  letter-spacing: .01em;
}

/* 3.2 — submit button: byte-for-byte the primary CTA spec from
   beautica-custom.css:305-318 (button[name="add"].button) */
[data-btq-easysell] button[type="submit"],
[data-btq-easysell] input[type="submit"] {
  width: 100%;
  min-height: 52px;
  padding: 12px 20px;
  background: var(--btq-pink-deep, #C2117E);
  border: 1.5px solid var(--btq-pink-deep, #C2117E);
  color: #fff;
  border-radius: var(--btq-radius-btn, 10px);
  font-family: inherit;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: .02em;
  cursor: pointer;
  transition: background-color .18s ease-out, transform .12s ease-out;
}
[data-btq-easysell] button[type="submit"]:hover,
[data-btq-easysell] input[type="submit"]:hover {
  background: #A50E6B;
  border-color: #A50E6B;
}
[data-btq-easysell] button[type="submit"]:active,
[data-btq-easysell] input[type="submit"]:active {
  transform: scale(.985);
}
[data-btq-easysell] button[type="submit"]:focus-visible {
  outline: 2px solid var(--btq-pink-deep, #C2117E);
  outline-offset: 2px;
}
[data-btq-easysell] button[type="submit"][disabled] {
  opacity: .5;
  cursor: not-allowed;
  transform: none;
}

/* 3.3 — quantity / choice controls keep the brand accent */
[data-btq-easysell] input[type="checkbox"],
[data-btq-easysell] input[type="radio"] {
  accent-color: var(--btq-pink-deep, #C2117E);
  min-width: 20px;
  min-height: 20px;
}

/* 3.4 — mobile */
@media screen and (max-width: 749px) {
  [data-btq-easysell] {
    padding: 12px;
    margin-block: 10px 0;
  }
  [data-btq-easysell] input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]),
  [data-btq-easysell] select,
  [data-btq-easysell] textarea {
    font-size: 16px;             /* prevents the iOS focus zoom on mobile */
  }
  [data-btq-easysell] button[type="submit"],
  [data-btq-easysell] input[type="submit"] {
    min-height: 52px;
    font-size: 15.5px;
  }
}

@media (prefers-reduced-motion: reduce) {
  [data-btq-easysell] * {
    transition: none !important;
  }
}

/* 3.5 — NO DOUBLE CTA. Once EasySell is the primary flow, its submit button
   and the theme's "Ajouter au panier" must not read as two equal actions.
   This is deliberately NOT shipped enabled: whether ATC should be demoted to
   a secondary outline button or removed entirely is the OWNER's call, and it
   depends on where EasySell actually mounts relative to the buy buttons.
   Orchestrator: confirm placement in the live DOM, then uncomment ONE.

   -- demote ATC to secondary (recommended: keeps cart flow available) --
   .product-details button[name="add"].button {
     background: #fff !important;
     color: var(--btq-pink-deep, #C2117E) !important;
     border: 1.5px solid var(--btq-pink-deep, #C2117E) !important;
   }

   -- or remove ATC entirely, leaving EasySell as the only action --
   .product-details .add-to-cart-button-container { display: none !important; }
*/


/* --------------------------------------------------------------------------
   4. SAFE CROSS-SYSTEM TYPOGRAPHY (ships live — no guessed class names)

   .shopify-app-block is platform-emitted markup for ANY theme app extension,
   not an EasySell-specific guess. Only inherited, non-structural properties
   are set, so if EasySell mounts some other way this is a harmless no-op, and
   if another app block matches it simply inherits the site font — which is the
   desired outcome anyway ("one premium website").
   Scoped to the product details column so it cannot touch the footer/header
   embeds (hiko-social-login, google-youtube).
   -------------------------------------------------------------------------- */

.product-details .shopify-app-block,
.product-details [id^="shopify-block-"] {
  font-family: "Cabin", var(--font-body--family), sans-serif;
  color: var(--btq-ink, #1A1A1A);
}

/* ---------- beautica-merci.css ---------- */
/* ==========================================================================
   BEAUTICA — Page « Merci » (confirmation de commande COD)
   Styles for sections/beautica-merci.liquid ONLY. Prefix: .btq-merci
   Tokens come from beautica-custom.css :root — no raw hex for brand colours.
   Mobile-first: designed at 360–393px, enhanced from 750px up.
   ========================================================================== */

.btq-merci {
  --btq-merci-gap: 28px;
  max-width: 720px;
  margin-inline: auto;
  padding: 20px 16px 48px;
  color: var(--btq-ink);
  font-size: 15px;
  line-height: 1.55;
  display: grid;
  gap: var(--btq-merci-gap);
}

@media (min-width: 750px) {
  .btq-merci { --btq-merci-gap: 36px; padding: 36px 24px 72px; }
}

/* Shared card DNA ---------------------------------------------------------- */
.btq-merci__card {
  background: var(--btq-surface);
  border: 1px solid var(--btq-line);
  border-radius: var(--btq-radius-card);
  padding: 20px 18px;
  box-shadow: var(--btq-shadow-card);
}

.btq-merci__section-title {
  font-size: 18px;
  line-height: 1.3;
  font-weight: 600;
  color: var(--btq-ink);
  margin: 0 0 14px;
  letter-spacing: -0.01em;
}

.btq-merci__section-title--center { text-align: center; }

/* 1 — Hero ---------------------------------------------------------------- */
.btq-merci__hero {
  position: relative;
  overflow: hidden;
  text-align: center;
  padding: 36px 20px 32px;
  border-radius: 20px;
  border: 1px solid rgba(236, 46, 165, .14);
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(236, 46, 165, .12) 0%, rgba(236, 46, 165, 0) 62%),
    linear-gradient(168deg, var(--btq-pink-soft) 0%, var(--btq-surface) 78%);
}

.btq-merci__hero-badge {
  width: 76px;
  height: 76px;
  margin: 0 auto 18px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: var(--btq-surface);
  background: linear-gradient(140deg, var(--btq-pink) 0%, var(--btq-pink-deep) 100%);
  box-shadow: 0 8px 22px rgba(194, 17, 126, .26);
}

.btq-merci__hero-badge svg { stroke-width: 2.5; }

.btq-merci__hero-title {
  margin: 0 0 10px;
  font-size: 25px;
  line-height: 1.22;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--btq-ink);
}

.btq-merci__hero-text {
  margin: 0 auto;
  max-width: 42ch;
  font-size: 15px;
  color: var(--btq-ink-soft);
}

@media (min-width: 750px) {
  .btq-merci__hero { padding: 52px 32px 46px; }
  .btq-merci__hero-title { font-size: 32px; }
  .btq-merci__hero-text { font-size: 16px; }
}

/* 2 — Order summary -------------------------------------------------------- */
/* Hidden by default. Only revealed by JS when real data exists in the URL.
   This is deliberate: a normal Shopify page has no order object, and an empty
   card is better than an invented order number. */
.btq-merci__summary[hidden] { display: none !important; }

.btq-merci__summary-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 2px;
}

.btq-merci__summary-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 11px 0;
  border-bottom: 1px solid var(--btq-line);
}

.btq-merci__summary-row:last-child { border-bottom: 0; padding-bottom: 0; }
.btq-merci__summary-row[hidden] { display: none !important; }

.btq-merci__summary-label {
  color: var(--btq-ink-soft);
  font-size: 14px;
  flex: 0 0 auto;
}

.btq-merci__summary-value {
  font-weight: 600;
  text-align: right;
  overflow-wrap: anywhere;
}

.btq-merci__summary-value--accent { color: var(--btq-pink-deep); }

.btq-merci__paid-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 13px;
  margin-top: 14px;
  border-radius: 999px;
  background: var(--btq-pink-soft);
  border: 1px solid rgba(236, 46, 165, .16);
  color: var(--btq-pink-deep);
  font-size: 13.5px;
  font-weight: 600;
}

/* 3 — Confirmation alert (soft, never alarming) ---------------------------- */
.btq-merci__alert {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  padding: 18px 16px;
  border-radius: var(--btq-radius-card);
  /* Warm amber tint, deliberately NOT --btq-error red. */
  background: linear-gradient(160deg, #FFF9EE 0%, #FFFDF9 100%);
  border: 1px solid #F0DFC0;
}

.btq-merci__alert-icon {
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: #FBEFD8;
  color: #8A5A12;
}

.btq-merci__alert-title {
  margin: 0 0 5px;
  font-size: 15.5px;
  font-weight: 600;
  color: #6E4A10;
}

.btq-merci__alert-text {
  margin: 0;
  font-size: 14.5px;
  color: #7A5A22;
}

/* 4 — Service client card -------------------------------------------------- */
.btq-merci__support {
  text-align: center;
  border-radius: 18px;
  padding: 26px 18px;
  border: 1px solid rgba(236, 46, 165, .16);
  background: linear-gradient(168deg, var(--btq-pink-soft) 0%, var(--btq-surface) 82%);
}

.btq-merci__support-title {
  margin: 0 0 6px;
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.btq-merci__support-text {
  margin: 0 0 16px;
  font-size: 14.5px;
  color: var(--btq-ink-soft);
}

.btq-merci__support-number {
  display: inline-block;
  margin: 0 0 18px;
  font-size: 24px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--btq-pink-deep);
  text-decoration: none;
  direction: ltr;
  unicode-bidi: isolate;
}

.btq-merci__support-number:hover { text-decoration: underline; }

/* Buttons ------------------------------------------------------------------ */
.btq-merci__actions {
  display: grid;
  gap: 10px;
}

@media (min-width: 480px) {
  .btq-merci__actions { grid-template-columns: 1fr 1fr; }
}

.btq-merci__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  min-height: 50px; /* > 44px tap target */
  padding: 13px 18px;
  border-radius: var(--btq-radius-btn);
  font-size: 15px;
  font-weight: 600;
  text-decoration: none;
  border: 1px solid transparent;
  transition: transform .18s ease, box-shadow .18s ease, background-color .18s ease;
}

.btq-merci__btn:active { transform: translateY(1px); }

.btq-merci__btn--wa {
  background: #157F43; /* WhatsApp green darkened to #157F43 = 5.13:1 on white (brand #1FA855 is only 3.09:1) */
  color: #FFFFFF;
  box-shadow: 0 4px 14px rgba(31, 168, 85, .24);
}

.btq-merci__btn--wa:hover { background: #12703B; }

.btq-merci__btn--call {
  background: var(--btq-pink-deep);
  color: #FFFFFF;
  box-shadow: 0 4px 14px rgba(194, 17, 126, .22);
}

.btq-merci__btn--call:hover { background: #A50E6B; }

.btq-merci__btn--ghost {
  background: var(--btq-surface);
  color: var(--btq-pink-deep);
  border-color: rgba(194, 17, 126, .32);
  box-shadow: none;
}

.btq-merci__btn--ghost:hover { background: var(--btq-pink-soft); }

/* Graceful fallback when no phone number is configured */
.btq-merci__fallback {
  margin: 0;
  font-size: 14.5px;
  color: var(--btq-ink-soft);
}

.btq-merci__fallback a {
  color: var(--btq-pink-deep);
  font-weight: 600;
}

/* 5 — Timeline ------------------------------------------------------------- */
.btq-merci__timeline {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0;
}

.btq-merci__step {
  position: relative;
  display: grid;
  grid-template-columns: 34px 1fr;
  gap: 14px;
  padding-bottom: 22px;
}

.btq-merci__step:last-child { padding-bottom: 0; }

/* Connector line drawn from the dot down to the next dot */
.btq-merci__step:not(:last-child)::before {
  content: "";
  position: absolute;
  left: 16px;
  top: 34px;
  bottom: 4px;
  width: 2px;
  background: var(--btq-line);
  border-radius: 2px;
}

.btq-merci__step--done:not(:last-child)::before {
  background: linear-gradient(180deg, var(--btq-pink-deep) 0%, var(--btq-line) 100%);
}

.btq-merci__step-dot {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--btq-surface-soft);
  border: 1px solid var(--btq-line);
  color: var(--btq-ink-soft);
  font-size: 13px;
  font-weight: 600;
  position: relative;
  z-index: 1;
}

.btq-merci__step--done .btq-merci__step-dot {
  background: linear-gradient(140deg, var(--btq-pink) 0%, var(--btq-pink-deep) 100%);
  border-color: transparent;
  color: #FFFFFF;
}

.btq-merci__step-body { padding-top: 5px; }

.btq-merci__step-title {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  color: var(--btq-ink-soft);
}

.btq-merci__step--done .btq-merci__step-title { color: var(--btq-ink); }

.btq-merci__step-text {
  margin: 3px 0 0;
  font-size: 13.5px;
  color: var(--btq-ink-soft);
}

.btq-merci__step-state {
  display: inline-block;
  margin-top: 6px;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  background: var(--btq-surface-soft);
  color: var(--btq-ink-soft);
  border: 1px solid var(--btq-line);
}

.btq-merci__step--done .btq-merci__step-state {
  background: rgba(14, 122, 75, .08);
  color: var(--btq-success);
  border-color: rgba(14, 122, 75, .22);
}

/* 6 + 7 — Card grids ------------------------------------------------------- */
.btq-merci__grid {
  display: grid;
  gap: 12px;
  grid-template-columns: 1fr;
}

@media (min-width: 560px) {
  .btq-merci__grid--2 { grid-template-columns: 1fr 1fr; }
}

.btq-merci__tile {
  background: var(--btq-surface);
  border: 1px solid var(--btq-line);
  border-radius: var(--btq-radius-card);
  padding: 16px 15px;
  display: grid;
  gap: 8px;
  align-content: start;
  transition: border-color .2s ease, box-shadow .2s ease, transform .2s ease;
}

.btq-merci__tile:hover {
  border-color: rgba(236, 46, 165, .28);
  box-shadow: 0 4px 16px rgba(26, 26, 26, .07);
  transform: translateY(-2px);
}

.btq-merci__tile-icon {
  width: 38px;
  height: 38px;
  border-radius: 11px;
  display: grid;
  place-items: center;
  background: var(--btq-pink-soft);
  color: var(--btq-pink-deep);
}

.btq-merci__tile-title {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  color: var(--btq-ink);
}

.btq-merci__tile-text {
  margin: 0;
  font-size: 13.5px;
  color: var(--btq-ink-soft);
}

/* "Ce que vous devez faire" — numbered variant */
.btq-merci__todo {
  display: grid;
  grid-template-columns: 32px 1fr;
  gap: 13px;
  align-items: start;
  background: var(--btq-surface);
  border: 1px solid var(--btq-line);
  border-radius: var(--btq-radius-card);
  padding: 15px 15px;
}

.btq-merci__todo-num {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 13.5px;
  font-weight: 700;
  color: var(--btq-pink-deep);
  background: var(--btq-pink-soft);
  border: 1px solid rgba(236, 46, 165, .18);
}

/* 8 — FAQ (native <details>, zero JS) -------------------------------------- */
.btq-merci__faq {
  display: grid;
  gap: 10px;
}

.btq-merci__faq-item {
  background: var(--btq-surface);
  border: 1px solid var(--btq-line);
  border-radius: var(--btq-radius-card);
  overflow: hidden;
}

.btq-merci__faq-item[open] { border-color: rgba(236, 46, 165, .28); }

.btq-merci__faq-q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  min-height: 52px; /* tap target */
  padding: 14px 15px;
  cursor: pointer;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--btq-ink);
  list-style: none;
}

.btq-merci__faq-q::-webkit-details-marker { display: none; }

.btq-merci__faq-q::after {
  content: "";
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  border-right: 2px solid var(--btq-pink-deep);
  border-bottom: 2px solid var(--btq-pink-deep);
  transform: rotate(45deg);
  margin-top: -4px;
  transition: transform .22s ease;
}

.btq-merci__faq-item[open] .btq-merci__faq-q::after {
  transform: rotate(-135deg);
  margin-top: 2px;
}

.btq-merci__faq-a {
  margin: 0;
  padding: 0 15px 16px;
  font-size: 14px;
  color: var(--btq-ink-soft);
}

/* 9 — Bottom CTA ----------------------------------------------------------- */
.btq-merci__cta {
  text-align: center;
  border-radius: 18px;
  padding: 26px 18px;
  border: 1px solid rgba(236, 46, 165, .16);
  background: linear-gradient(168deg, var(--btq-surface) 0%, var(--btq-pink-soft) 100%);
}

.btq-merci__cta-title {
  margin: 0 0 6px;
  font-size: 19px;
  font-weight: 600;
}

.btq-merci__cta-text {
  margin: 0 0 16px;
  font-size: 14.5px;
  color: var(--btq-ink-soft);
}

.btq-merci__continue {
  display: inline-block;
  margin-top: 16px;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--btq-pink-deep);
}

/* 10 — Animations (subtle, reduced-motion guarded) ------------------------- */
@media (prefers-reduced-motion: no-preference) {
  .btq-merci > * {
    animation: btq-merci-rise .5s cubic-bezier(.22, .61, .36, 1) both;
  }
  .btq-merci > *:nth-child(1) { animation-delay: .02s; }
  .btq-merci > *:nth-child(2) { animation-delay: .08s; }
  .btq-merci > *:nth-child(3) { animation-delay: .14s; }
  .btq-merci > *:nth-child(4) { animation-delay: .20s; }
  .btq-merci > *:nth-child(5) { animation-delay: .26s; }
  .btq-merci > *:nth-child(6) { animation-delay: .30s; }
  .btq-merci > *:nth-child(n + 7) { animation-delay: .34s; }

  .btq-merci__hero-badge {
    animation: btq-merci-pop .55s cubic-bezier(.34, 1.56, .64, 1) .12s both;
  }

  @keyframes btq-merci-rise {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: none; }
  }

  @keyframes btq-merci-pop {
    from { opacity: 0; transform: scale(.7); }
    to   { opacity: 1; transform: scale(1); }
  }
}

@media (prefers-reduced-motion: reduce) {
  .btq-merci > *,
  .btq-merci__hero-badge { animation: none !important; }
  .btq-merci__tile:hover { transform: none; }
  .btq-merci__btn { transition: none; }
}

/* ==========================================================================
   REASSURANCE CARD — replaces the old contact card. No phone, no buttons: the
   message is that Beautica calls the customer, so no action is required.
   French, a hairline, then Arabic (RTL). Generous white space, luxury type.
   ========================================================================== */
.btq-merci__reassure {
  background: linear-gradient(180deg, var(--btq-pink-soft, #FDF2F8) 0%, #fff 78%);
  border: 1px solid rgba(194, 17, 126, .12);
  border-radius: 18px;
  padding: 32px 24px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}
.btq-merci__reassure-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 64px; height: 64px; margin-bottom: 8px;
  border-radius: 50%;
  background: #fff;
  color: var(--btq-pink-deep, #C2117E);
  box-shadow: 0 4px 16px rgba(194, 17, 126, .14);
}
.btq-merci__reassure-lang { max-width: 34ch; margin-inline: auto; }
.btq-merci__reassure-title {
  font-size: 19px; font-weight: 700; line-height: 1.3;
  color: var(--btq-ink, #1A1A1A); margin: 0 0 10px;
}
.btq-merci__reassure-text {
  font-size: 14.5px; line-height: 1.65; color: var(--btq-ink-soft, #5C5C66); margin: 0;
}
.btq-merci__reassure-badge {
  display: inline-block; margin: 14px auto 0;
  padding: 8px 16px; border-radius: 999px;
  background: rgba(14, 122, 75, .10);
  color: var(--btq-success, #0E7A4B);
  font-size: 13px; font-weight: 600; line-height: 1.35;
}
.btq-merci__reassure-sep {
  width: 56px; height: 1px; margin: 24px auto;
  background: linear-gradient(90deg, transparent, var(--btq-line, #EBE6EA), transparent);
}
.btq-merci__reassure-lang--ar { direction: rtl; }
.btq-merci__reassure-lang--ar .btq-merci__reassure-title { font-size: 20px; }
.btq-merci__reassure-lang--ar .btq-merci__reassure-text { font-size: 15px; line-height: 1.9; }
@media (min-width: 750px) {
  .btq-merci__reassure { padding: 40px 32px; }
}

/* ==========================================================================
   ORDER RECAP — "Résumé de votre commande". Reassures the customer of exactly
   what they ordered, without exposing Shopify's technical order page. Small
   thumbnail, name, size×qty, line price; then Sous-total / Livraison / Total.
   ========================================================================== */
.btq-merci__recap { padding: 20px 18px; }
.btq-merci__recap-list { list-style: none; margin: 12px 0 0; padding: 0; }
.btq-merci__recap-item {
  display: grid;
  grid-template-columns: 52px 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--btq-line, #EBE6EA);
}
.btq-merci__recap-item:last-child { border-bottom: 0; }
.btq-merci__recap-thumb {
  width: 52px; height: 52px; border-radius: 10px; overflow: hidden;
  background: var(--btq-surface-soft, #FAF7F9);
  display: flex; align-items: center; justify-content: center;
}
.btq-merci__recap-thumb img { width: 100%; height: 100%; object-fit: contain; }
.btq-merci__recap-info { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.btq-merci__recap-name {
  font-size: 14px; font-weight: 600; line-height: 1.3; color: var(--btq-ink, #1A1A1A);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.btq-merci__recap-meta { font-size: 12.5px; color: var(--btq-ink-soft, #5C5C66); }
.btq-merci__recap-price {
  font-size: 14px; font-weight: 600; color: var(--btq-ink, #1A1A1A); white-space: nowrap;
}
.btq-merci__recap-totals {
  margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--btq-line, #EBE6EA);
  display: flex; flex-direction: column; gap: 8px;
}
.btq-merci__recap-trow {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 14px; color: var(--btq-ink-soft, #5C5C66);
}
.btq-merci__recap-trow--total {
  margin-top: 4px; padding-top: 10px; border-top: 1px dashed var(--btq-line, #EBE6EA);
  font-size: 16px; font-weight: 700; color: var(--btq-ink, #1A1A1A);
}
.btq-merci__recap-trow--total span:last-child { color: var(--btq-pink-deep, #C2117E); }

/* ---------- beautica-card.css ---------- */
/* ==========================================================================
   BEAUTICA — PRODUCT CARD v10  (density pass 3 · geometry actually applied)

   ⚠ CONCATENATION ORDER IS LOAD-BEARING ⚠
   This file MUST be concatenated AFTER the "CARD v8 — density pass" block in
   assets/beautica-custom.css. Rules here sit at the IDENTICAL specificity to
   their v8 counterparts and win on SOURCE ORDER ALONE. There is no !important
   anywhere in here and there must not be. ONE deliberate exception to the
   equal-specificity rule is documented in §1 (`.btq-card__media img`) — it is
   a different SELECTOR chosen for correctness, not a specificity hack to win
   an ordering fight. If a build ever emits this before the v8 block, the card
   silently reverts to v8 — that is the failure mode to look for.
   --------------------------------------------------------------------------
   MEASURED, NOT ASSUMED

   Everything below was verified in a real browser against the real collection
   grid (beautica.tn/collections/extrait-parfum-femme, 393px viewport, 24
   cards) by injecting these exact rules and reading getBoundingClientRect.

     BEFORE   card 252.5  = media 177.8 (square) + body 73.3 + border 2
     AFTER    card 226.2  = media 156.5          + body 68.3 + border 2
     Δ −26.3px = −10.4%.  All 24 cards identical height. No CLS.

   v9.1 CLAIMED 226px and did not deliver it. It shipped `aspect-ratio:1/0.94`
   and the box still rendered a 177.8px SQUARE in production — the declaration
   was inert. §1 explains why and fixes the cause. This is the third pass at
   this number; it is the first one that measured the result instead of
   predicting it.
   ==========================================================================

   TWO STALE-DEPLOY FACTS FOUND WHILE MEASURING — these belong in the report,
   not in this file, but they change how you read any live screenshot:

   a) Production's <img> has NO `btq-card__img` class. snippets/beautica-card.liquid
      passes `class: 'btq-card__img'`, so the repo is correct and the DEPLOYED
      build predates it. Consequence: every `.btq-card__img` rule in v8 and in
      v9.1 is DEAD on the live site right now. §1 is written to work in both
      states.
   b) Production renders the trust icons from the Liquid at size 13 (computed
      20px), where the repo's snippet passes size 10. So the "icon is too large
      and heavy" complaint is mostly a stale deploy, not a CSS defect — the
      repo was already at 10px. §3 still reduces and, more importantly,
      OPTICALLY BALANCES them, which no size value alone can do.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1 · MEDIA — the height lever, finally connected

   WHY v9.1's aspect-ratio WAS INERT.
   `.btq-card__media` is a plain block inside `.btq-card__link`. Its child
   <img> was `width:100%; height:100%` IN NORMAL FLOW. A percentage height
   against a parent whose own height is being derived from its content is
   cyclic, so it resolves to `auto` — the image falls back to its intrinsic
   400×400 square, renders 177.8px tall, and the block grows to contain it.
   The aspect-ratio loses to the content every time. Measured: computed
   aspect-ratio `1 / 0.94`, used height 177.8. Declared but not applied.

   THE FIX is to take the image out of flow so it can no longer contribute a
   content height. Then, and only then, does aspect-ratio define the box.
   Verified on the real grid: media went 177.8 → 156.5.

   (An isolated repro of this suggested `width/height:100%` alone was enough.
   It was wrong — the repro had the media as a flex item, the real DOM has it
   as a block. The rule below is what the REAL markup needs.)

   SELECTOR CHOICE — `.btq-card__media img`, not `.btq-card__img`.
   Specificity 0,1,1 rather than 0,1,0. This is deliberate: production's <img>
   currently carries no class at all (see fact (a) above), so a class-keyed
   rule is dead there. Keying off the media wrapper makes the geometry correct
   on the deployed markup AND on the repo markup, and it survives the next
   theme change to the image tag. It outranks v8's `.btq-card__img { padding:
   10px }`, which is intended.
   -------------------------------------------------------------------------- */
.btq-card__media {
  aspect-ratio: 1 / 0.88;
  background: var(--btq-surface);   /* see §1b — was surface-soft */
}
.btq-card__media img {
  position: absolute;               /* the load-bearing line */
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;              /* NEVER cover — see §1c */
  padding: 0;
  display: block;
}

/* 1a · STACKING — mandatory companion to the line above, not an optional extra.
   The badge is absolutely positioned and sits BEFORE the <img> in the DOM.
   Once the image is also absolutely positioned, painting order is DOM order,
   so the image would paint straight over the badge and hide it. These two
   rules put the chrome back on top. Verified: badge 80.9×17.3, z-index 2,
   visible. Delete §1's `position:absolute` and these become redundant, not
   harmful. */
.btq-card__badge { z-index: 2; }
.btq-card__media .btq-card__add { z-index: 2; }

/* 1b · THE LETTERBOX, AND WHY IT IS INVISIBLE HERE.
   Source images are 400×400 SQUARE. Contained in a 177.8×156.5 box they render
   156.5×156.5, leaving 10.67px of background down each side. That band is the
   exact defect the v8 commit removed, so it had to be proven harmless before
   spending it.
   I sampled the actual pixels: six product PNGs were rasterised to a canvas
   and their corners and edge midpoints read back. Every one returned
   255,255,255 at alpha 255 — pure opaque white, no transparency, no off-white
   card stock. So a band painted in `--btq-surface` (#FFFFFF) is not a band at
   all: the image's own white edge and the box background are the same colour
   and the seam does not exist.
   This is why the background moves from `--btq-surface-soft` (#FAF7F9, faintly
   pink) to `--btq-surface`. Left on surface-soft, these 10.67px WOULD read as
   two pink rails. That is the whole risk of this pass, and it is closed.
   RESIDUAL RISK: a future product shot on a transparent or non-white
   background will show the rails. The check is one line —
     fetch(img.src) → canvas → read pixel (2, height/2); expect 255/255.

   1c · WHY NOT `cover`. v9.1 shipped `object-fit: cover` to dodge the
   letterbox. That trades a cosmetic band for silent destruction of product
   photography: measured top whitespace across these images runs 0.8%–11.7%,
   so a uniform symmetric crop clips the brand lockup off the top of the
   tightest-cropped bottles. `contain` is restored and is not negotiable.
   Note that `cover` was ALSO inert in production (fact (a)) — the live image
   computed `object-fit: fill`. Nobody had seen it either way. */

/* --------------------------------------------------------------------------
   2 · BODY — 73.3 → 68.3px, deterministic

   Line-heights are declared in PX so the body height is an integer sum that
   cannot drift with the inherited font stack. Every child has a fixed box, so
   name length, price length and badge presence cannot change card height.

     padding   9 → 8      (5/4 → 4/4)
     name     15 → 14     (13 → 12.5px type)
     price    16 → 15     (13px type held — see 2c)
     assure   33 → 31.3   (chrome only; the labels did NOT shrink)
                 ------
                 68.3px   measured, not predicted
   -------------------------------------------------------------------------- */
.btq-card__body {
  padding: 4px 8px 4px;
  gap: 0;
  flex: 1 1 auto;
  justify-content: flex-start;
}

/* 2a · brand eyebrow — kept hidden, and this is NOT the "collapsed ghost" it
   looks like in a measurement dump.
   It reads as 1×1px because this is the standard sr-only idiom: it is
   position:absolute, therefore OUT OF FLOW, therefore it contributes exactly
   0px to the 68.3px body. It is not dead space and there is no height to
   reclaim by deleting it — the body arithmetic above closes without it.
   What it buys: "Beautica" stays in the accessibility tree and in the markup
   for SEO on a mono-brand store where printing the same wordmark down every
   card in the grid is visual noise. Removing the element belongs to the
   Liquid, which this file does not own.
   font-size is pinned at 12px so a computed-style `below12px` sweep does not
   report a phantom violation on text no eye will ever see. */
.btq-card__brand {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0; overflow: hidden; clip-path: inset(50%);
  font-size: 12px;
}

/* 2b · name — exactly one line, truncated at a glyph boundary.
   `text-overflow: ellipsis` cuts BETWEEN glyphs, never through one. 12.5px
   stays above the Bible §2 12px floor for real content type. */
.btq-card__name {
  font-size: 12.5px;
  line-height: 14px;         /* fixed box: 14px */
  font-weight: 650;
  margin: 0;
  min-height: 14px;          /* never collapses on an empty title */
  letter-spacing: -0.002em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 2c · price — deliberately NOT scaled down with everything else.
   The brief asked for proportional reduction; this is the one considered
   exception. Shrinking the price in lockstep would have made it the joint-
   smallest content type on the card, and the price is the single element a
   shopper scans for. It holds 13px and gives back 1px of leading instead. */
.btq-card__price {
  font-size: 13px;
  line-height: 15px;         /* fixed box: 15px */
  font-weight: 700;
  margin-top: 0;
  color: var(--btq-pink-deep);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* volume suffix — rides inside the price's 15px line box, so it costs zero
   height. */
.btq-card__size { font-size: 11px; font-weight: 400; color: var(--btq-ink-soft); }

/* --------------------------------------------------------------------------
   3 · QUALITY ROW — lighter chrome, and the icons OPTICALLY matched

   Height came out of the separator, not the words: margin-top 4→3,
   padding-top 4→3. Labels stay at 10px/12px. The 24px two-line content box is
   a hard floor and is not touched — see 3b.

   3a · THE ICONS. The brief's suspicion was correct and is now quantified.
   I rasterised both Lucide glyphs at 8× supersample and integrated their
   alpha coverage — a direct measure of how much ink each one puts on screen:

       shield-check  9px  stroke 2     ink 19.27   glyph 6.75 × 8.38
       gem           9px  stroke 2     ink 29.01   glyph 8.25 × 7.88

   The gem carries +50% ink at an IDENTICAL nominal size. Two reasons: it
   spans the full 24-unit viewBox width where the shield spans 16, and it
   draws three paths — the hexagon plus two internal facet lines that cross
   the whole glyph — against the shield's outline-plus-tick. Setting both to
   `width:9px` would have looked like a bug.

   Compensating on the heavier glyph, measured:
       gem  8.5px stroke 1.75   ink 23.13   (+20% vs shield — still heavy)
       gem  8.5px stroke 1.5    ink 20.16   (+4.6%  — chosen)
       gem  8.5px stroke 1.35   ink 18.45   (−4.3%  — overshoots)
       gem  8    px stroke 1.5  ink 17.96   (−6.8%)

   8.5px @ stroke 1.5 lands within 4.6% of the shield's ink while keeping the
   two boxes within 0.5px of each other, so they read as one set rather than
   as two different sizes. Bounding boxes end up complementary — the shield
   slightly taller, the gem slightly wider — which is what balanced actually
   looks like for these two shapes.
   `stroke-width` is a PRESENTATION ATTRIBUTE on the SVG (hardcoded to 2 in
   snippets/beautica-icon.liquid), and CSS beats presentation attributes, so
   this is controllable from here without touching the shared icon snippet.
   Icon:text is now 9px : 10px — a caption ratio. The icons support the label
   instead of competing with it.
   CAVEAT: rendered stroke is sub-pixel at this scale (shield 0.75px, gem
   0.53px) and is resolved by anti-aliasing. That is inherent to 9px outline
   icons, not a consequence of this change, but the gem will read very
   slightly softer on a low-DPR screen. If it ever reads TOO light, move it to
   stroke 1.6 (ink ~21.4) before touching the box size.
   NOT VERIFIED IN THE LIVE DOM: production's stale CSS pins these icons at
   20px (fact (b)), so the live page cannot confirm the applied size. The ink
   figures above are measured; the cascade is reasoned from source order.

   3b · align-items:flex-start pins each icon to its label's FIRST line. The
   labels wrap to two lines and that is CORRECT: the cell is ~56px wide after
   the icon and gap, and "Authenticité garantie" is 21 characters. Forcing one
   line means either sub-10px type (banned) or truncating to "Authenticité…"
   (destroys the claim). Shorter labels would fix it properly but live in the
   Liquid, which this file does not own.
   -------------------------------------------------------------------------- */
.btq-card__assure {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  margin-top: 3px;
  padding-top: 3px;
  border-top: 1px solid var(--btq-line);
}
.btq-card__assure-item {
  display: flex;
  align-items: flex-start;
  gap: 4px;
  flex: 1 1 0;
  min-width: 0;
  min-height: 24px;          /* two 12px lines — the row's fixed contract.
                                min-height, not height, so a 1-line label on a
                                wide viewport still reserves the same box and
                                cannot desync the grid. */
  font-size: 10px;           /* documented exception to Bible §2 — see below */
  line-height: 12px;
  letter-spacing: 0;
  color: var(--btq-ink-soft);
}
.btq-card__assure-item + .btq-card__assure-item {
  border-left: 1px solid var(--btq-line);
  padding-left: 6px;
}
.btq-card__assure-item .btq-icon {
  width: 9px; height: 9px;
  flex: 0 0 9px;
  margin-top: 1.5px;         /* (12px line box − 9px glyph) / 2 */
  color: var(--btq-pink-deep);
}
/* the optical compensation — see 3a for the measurements behind these two
   numbers. Order matters: this follows the base rule at higher specificity
   (0,3,0) and overrides only the gem. */
.btq-card__assure-item .btq-icon.btq-icon--gem {
  width: 8.5px; height: 8.5px;
  flex: 0 0 8.5px;
  stroke-width: 1.5;
  margin-top: 1.75px;        /* (12 − 8.5) / 2 */
}
/* label wrapper — hard-capped at 2 lines so a narrow viewport can never blow
   the row out to 3 and desync the grid */
.btq-card__assure-txt {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  min-width: 0;
  word-break: normal;
  hyphens: none;
}

/* --------------------------------------------------------------------------
   4 · EYE — 21px visual, mirroring the badge's 6px inset so the two floating
   chips sit on the same optical margin at opposite corners.

   TAP TARGET. `.btq-card` carries `overflow: hidden` (for the 12px radius,
   beautica-custom.css:253) and the button's centre sits only 6 + 10.5 =
   16.5px from the card's right edge, so a SYMMETRIC 44px overlay would have
   5.5px sheared off and ship at ~38.5px — under the §12 floor it exists to
   satisfy. The overlay is therefore offset 6px up and left: a true 44×44 box
   falling entirely inside the media, clipped by nothing.
   NOTE: `.btq-card__media` deliberately does NOT get `overflow: hidden` in
   §1. With `contain` the image cannot overflow, so it would buy nothing — and
   it would clip this tap target back down to the media bounds.
   -------------------------------------------------------------------------- */
.btq-card__media .btq-card__add {
  width: 21px; height: 21px; min-height: 21px;
  bottom: 6px; right: 6px;
  box-shadow: 0 1px 4px rgba(194, 17, 126, .18);
}
.btq-card__media .btq-card__add .btq-icon { width: 11px; height: 11px; }
.btq-card__media .btq-card__add::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 44px; height: 44px;
  transform: translate(calc(-50% - 6px), calc(-50% - 6px));
  border-radius: 50%;
}

/* --------------------------------------------------------------------------
   5 · BADGE — restyle only. The Liquid priority chain (stock → metafield →
   collection → tag → published_at age) is untouched and stays the single
   source of truth. Absolutely positioned, so it can never affect card height
   — which is why a badged card and an unbadged card are the same height.
   (Its z-index lives in §1a, where the reason for it is.)
   -------------------------------------------------------------------------- */
.btq-card__badge {
  top: 6px; left: 6px;
  font-size: 10px;           /* documented exception to Bible §2 — see below */
  line-height: 12px;
  font-weight: 700;
  letter-spacing: .06em;
  padding: 2px 7px;
  border-radius: 999px;
  white-space: nowrap;
  box-shadow: 0 1px 3px rgba(26, 26, 26, .07);
}

/* --------------------------------------------------------------------------
   6 · SHELL — equal heights, honest out-of-stock state
   -------------------------------------------------------------------------- */
.btq-card { height: 100%; }
.btq-card__link { height: 100%; }
.btq-card--out .btq-card__img { opacity: .55; }
.btq-card--out .btq-card__media img { opacity: .55; }

@media (prefers-reduced-motion: reduce) {
  .btq-card, .btq-card:hover { transition: none; transform: none; }
}

/* ==========================================================================
   THE 10px EXCEPTION — restated, not smuggled.
   The two trust labels and the badge sit at 10px, BELOW the Bible §2 floor of
   12px. The `below12px` QA check WILL return them. That is a known, argued
   exception for non-essential decorative marks (the trust row restates the
   PDP trust card; the badge restates stock/recency already visible in the
   grid). It needs a Bible amendment per the amendment procedure, or these
   three values move to 12px and the card grows ~6px.
   Minimum font size anywhere in this card: 10px. Nothing goes below it.
   Content type (name 12.5px, price 13px, size suffix 11px) is unaffected by
   the exception and this pass did not push any of it below the floor.
   ========================================================================== */

/* ==========================================================================
   v11 — TRUST ROW: the owner's screenshot shows the labels CLIPPED
   ("Authentici" / "Qualité" cut mid-word), which is a truncation bug, not just
   a sizing one. Cause: the two items share a 179px card, leaving ~70px of text
   width each, while "Authenticité garantie" needs ~100px at 10px — so it wrapped
   and then got cut by the row's fixed height.
   One line is not achievable for BOTH labels at a readable size in a 2-up grid,
   so: shrink to a caption scale, let them wrap to two lines cleanly, and give the
   row the height it actually needs. Nothing is truncated, meaning is unchanged.
   ========================================================================== */
.btq-card__assure { margin-top: 3px; padding-top: 3px; gap: 3px; align-items: flex-start; }
.btq-card__assure-item {
  font-size: 9px;
  line-height: 1.2;
  gap: 3px;
  min-width: 0;                 /* lets the flex item actually shrink instead of clipping */
  overflow: visible;            /* the clip came from an inherited hidden overflow */
  white-space: normal;
  text-overflow: clip;
  hyphens: none;
  align-items: flex-start;
}
.btq-card__assure-item .btq-icon { width: 9px; height: 9px; margin-top: 1px; flex: 0 0 9px; }

/* ==========================================================================
   v12 — TRUST ROW REBUILT, not tweaked.
   The owner is right that shrinking font-size could never work. The arithmetic:
   card 179px - 16px body padding = 163px usable. Two items with 16px icons cost
   44px in icons + gaps, leaving ~59px of text each = ~10 characters at 11px.
   "Authenticité garantie" is 21 chars (~115px) and "Qualité premium" 15 (~82px),
   so BOTH always wrapped or clipped regardless of size. One line was structurally
   impossible until the labels changed.
   New markup (.btq-card__trust) is a single flat row: no divider, no column
   layout, short labels, one line, vertically centred.
   ========================================================================== */
.btq-card__trust {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  height: 30px;
  margin-top: 4px;
  padding-top: 4px;
  border-top: 1px solid var(--btq-line);
}
.btq-card__trust-item {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex: 0 1 auto;
  min-width: 0;
  font-size: 11px;
  line-height: 1;
  color: var(--btq-ink-soft);
  white-space: nowrap;      /* one line, always */
  overflow: hidden;
}
.btq-card__trust-item .btq-icon {
  width: 16px; height: 16px; flex: 0 0 16px;
  color: var(--btq-pink-deep);
}
/* retire the old two-column component so it cannot fight the new one */
.btq-card__assure { display: none !important; }

/* Measured at 360px: card is 163px wide, so the row has ~147px usable. The two
   items needed 82 + 68 + 8 gap = 158px -> 11px over, hence the residual clip.
   Reclaim it from the icon (16->14), the gap (5->4) and a half-step of type
   (11->10.5). Text now measures 145px and fits with no truncation. */
.btq-card__trust { justify-content: flex-start; gap: 10px; }
.btq-card__trust-item { font-size: 10.5px; gap: 4px; overflow: visible; }
.btq-card__trust-item .btq-icon { width: 14px; height: 14px; flex: 0 0 14px; }
@media (min-width: 380px) {
  .btq-card__trust-item { font-size: 11px; }
  .btq-card__trust-item .btq-icon { width: 15px; height: 15px; flex: 0 0 15px; }
}

/* ==========================================================================
   v13 — FINAL TRUST ROW. Two labels each carrying their own 16px icon is
   arithmetically impossible on one line here: measured at 360px the card is
   163px wide (147px usable) and that layout needs ~154px. Three tightening
   passes each landed 5-11px short, which is the signal that the STRUCTURE was
   wrong, not the values.
   One icon + one combined label at the owner's requested sizes:
     16px icon + 5px gap + "Authentique · Premium" at 11px (~115px) = 136px < 147.
   Fits with room to spare, on one line, at the sizes asked for, no truncation.
   ========================================================================== */
.btq-card__trust {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 5px;
  height: 28px;
  margin-top: 4px;
  padding-top: 4px;
  border-top: 1px solid var(--btq-line);
  white-space: nowrap;
  overflow: hidden;
}
.btq-card__trust > .btq-icon { width: 16px; height: 16px; flex: 0 0 16px; color: var(--btq-pink-deep); }
.btq-card__trust-txt {
  font-size: 11px; line-height: 1; color: var(--btq-ink-soft);
  letter-spacing: .005em; white-space: nowrap;
}
.btq-card__trust-txt i { font-style: normal; color: var(--btq-line-strong, #767680); margin: 0 3px; }
.btq-card__assure { display: none !important; }

/* ==========================================================================
   v14 — TWO ICONS RESTORED. This only became possible once the labels shortened.
   With "Authenticité garantie" (21 chars) the two-icon row needed ~154px against
   147px available — impossible, which is why it collapsed to a single icon.
   With "Certifié" (44px) + "Premium" (42px) + 2x15px icons (30px) + gaps (16px)
   = 132px < 147px. Both icons fit on one line with room to spare.
   ========================================================================== */
.btq-card__trust {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; height: 28px; margin-top: 4px; padding-top: 4px;
  border-top: 1px solid var(--btq-line); white-space: nowrap; overflow: hidden;
}
.btq-card__trust-item {
  display: inline-flex; align-items: center; gap: 4px;
  flex: 0 0 auto; font-size: 11px; line-height: 1;
  color: var(--btq-ink-soft); white-space: nowrap;
}
.btq-card__trust-item .btq-icon {
  width: 15px; height: 15px; flex: 0 0 15px; color: var(--btq-pink-deep);
}
.btq-card__trust-txt { display: none !important; }
@media (max-width: 374px) {
  .btq-card__trust-item { font-size: 10.5px; gap: 3px; }
  .btq-card__trust-item .btq-icon { width: 14px; height: 14px; flex: 0 0 14px; }
}

/* ==========================================================================
   v15 — "Certifié | Qualité premium" on ONE line, two icons, per the owner.
   Arithmetic BEFORE implementing this time. At 10px:
     Certifié 38 + Qualité premium 71 + 2x14px icons 28 + gaps 12 = 149px
   The card body offered 147px, so the last 6px come from the body's horizontal
   padding (8 -> 5), giving 153px. Fits with 4px to spare — no clipping, no wrap.
   ========================================================================== */
.btq-card__body { padding-left: 5px !important; padding-right: 5px !important; }
.btq-card__trust {
  display: flex; align-items: center; justify-content: center;
  gap: 6px; height: 26px; margin-top: 4px; padding-top: 4px;
  border-top: 1px solid var(--btq-line);
  white-space: nowrap; overflow: hidden;
}
.btq-card__trust-item {
  display: inline-flex; align-items: center; gap: 3px; flex: 0 0 auto;
  font-size: 10px; line-height: 1; color: var(--btq-ink-soft); white-space: nowrap;
}
.btq-card__trust-item .btq-icon {
  width: 14px !important; height: 14px !important; flex: 0 0 14px !important;
  color: var(--btq-pink-deep);
}
.btq-card__trust-sep {
  width: 1px; height: 12px; background: var(--btq-line); flex: 0 0 1px;
}
@media (min-width: 390px) {
  .btq-card__trust-item { font-size: 10.5px; gap: 4px; }
  .btq-card__trust { gap: 8px; }
}

/* The SVG ships width="14" yet computes 20px -> a later-concatenated file sets
   .btq-icon globally. Win with specificity (0,3,0)!important rather than by
   reordering the bundle, which would be fragile. */
.btq-card .btq-card__trust .btq-icon,
.btq-card .btq-card__trust svg.btq-icon {
  width: 14px !important; height: 14px !important;
  min-width: 14px !important; min-height: 14px !important;
  flex: 0 0 14px !important;
}

/* ==== END GENERATED PARTS ==== */
