/* =========================================
   TOPBAR COMPONENT
========================================= */
.topbar {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: var(--topbar-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 14px;
  /* Solid black, the old site's header. White logo and icons on it. */
  background: var(--color-ink);
  color: #fff;
  z-index: 200;
}

/* Left side — hamburger */
.topbar-left {
  width: 64px;
  display: flex;
  align-items: center;
}

/* Center — brand name, set as words rather than a tracked-out wordmark */
.topbar .logo {
  font-size: 1.2rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-transform: none;
  color: #fff;
  flex: 1;
  text-align: center;
  white-space: nowrap;
}

@media (min-width: 1024px) {
  .topbar .logo {
    font-size: 1.75rem;
    font-weight: 600;
  }
}

/* Desktop collections menu: hidden on phones, where the side menu does this job */
.topbar-nav {
  display: none;
}

/* Centred while it fits; once the names run longer than the bar it starts at the left
   and scrolls sideways instead of being cut off at both ends. */
.topbar-nav ul {
  display: flex;
  align-items: center;
  justify-content: safe center;
  flex-wrap: nowrap;
  gap: 22px;
  list-style: none;
  overflow-x: auto;
  scrollbar-width: none;
  /* A soft fade at the right edge, so a cut-off name reads as "more this way" */
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
  mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
}

.topbar-nav ul::-webkit-scrollbar {
  display: none;
}

.topbar-nav a {
  display: block;
  color: #fff;
  font-size: 0.8rem;
  font-weight: 600;
  white-space: nowrap;
  padding: 4px 0;
  border-bottom: 1px solid transparent;
  transition: border-color 0.2s ease, opacity 0.2s ease;
}

.topbar-nav a:hover,
.topbar-nav a[aria-current="page"] {
  border-bottom-color: #fff;
}

@media (min-width: 1024px) {
  .topbar {
    padding: 0 32px;
    gap: 24px;
  }

  /* Logo left, menu in the middle, icons right — no hamburger when the menu is on show */
  .topbar-left {
    display: none;
  }

  .topbar .logo {
    flex: 0 0 auto;
    text-align: left;
  }

  .topbar-nav {
    display: block;
    flex: 1;
    min-width: 0;
  }

  .topbar-right {
    width: auto;
  }
}

/* ── Session offer tab ────────────────────────────────────────────────────────
   Pinned to the right edge, halfway down the screen — the place a floating cart or
   help button usually sits, so it is always in view without the brand having to take
   turns with it. Writing-mode turns the pill on its side so it costs almost no width. */
/* Two rows, read left-to-right: the clock on top, the offer under it. Sideways text saves
   width but is read as decoration, and this element exists to be understood at a glance. */
.so-tab {
  position: fixed;
  right: 0;
  top: 50%;
  transform: translateY(-50%) translateX(100%);
  z-index: 1350;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  width: 86px;
  padding: 0;
  overflow: hidden;
  border: 0;
  border-radius: 12px 0 0 12px;
  background: var(--text-color, #111);
  color: #fff;
  font: inherit;
  text-align: center;
  cursor: pointer;
  box-shadow: -2px 4px 18px rgba(0, 0, 0, .24);
  transition: transform .4s cubic-bezier(.2, .7, .2, 1), background .3s ease;
}

.so-tab.is-in {
  transform: translateY(-50%) translateX(0);
}

/* Row 1 — the countdown. Tabular figures keep every digit the same width, so the number
   does not jiggle once a second. */
.so-tab-clock {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 7px 6px 6px;
  background: rgba(255, 255, 255, .13);
  font-size: .74rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.so-tab-clock i {
  font-size: .78rem;
  line-height: 1;
  opacity: .85;
}

/* ── The promotion tab ──
   The sale red from the home hero, so the tab and the banner read as one campaign.
   Sampled from the image itself — its reds cluster at rgb(248,16,8) — then deepened a
   little, because white text on the raw value sits under the contrast threshold.
   The offer's NAME goes on top with the clock small underneath. The session offer's tab
   stays black: two different things in the same corner should not look like one, and
   the black one is personal where this is the shop-wide sale. */
.so-tab.pp-tab {
  width: 94px;
  /* Barely rounded. At 12px the corners read as a floating pill rather than a tab
     attached to the edge of the screen. */
  border-radius: 6px 0 0 6px;
  background: #d81e14;
  box-shadow: -2px 4px 18px rgba(216, 30, 20, .34);
}

.so-tab.pp-tab.is-urgent {
  background: #a3140c;
  box-shadow: -2px 4px 18px rgba(163, 20, 12, .36);
}

.so-tab.pp-tab.is-done {
  background: #6b7280;
  box-shadow: -2px 4px 18px rgba(0, 0, 0, .2);
}

.pp-tab-name {
  padding: 9px 7px 6px;
  font-size: .73rem;
  font-weight: 700;
  line-height: 1.22;
}

/* The clock sits on its own tint rather than a border, so the tab stays one shape. */
.pp-tab-clock {
  padding: 5px 6px 7px;
  background: rgba(0, 0, 0, .17);
  font-size: .68rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
  white-space: nowrap;
}

/* Row 2 — the offer, two words at most. session-offer.js shortens anything longer rather
   than letting it wrap into an unreadable stack. */
.so-tab-label {
  padding: 7px 6px 8px;
  font-size: .7rem;
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: .01em;
  word-break: break-word;
}

/* The last two minutes change the colour once. No pulsing: a thing that blinks for two
   minutes is read as an advert and stops being seen. */
.so-tab.is-urgent {
  background: #b45309;
}

.so-tab.is-done {
  background: #6b7280;
}

@media (prefers-reduced-motion: reduce) {
  .so-tab {
    transition: none;
  }
}

/* Right side â€” icons wrapper */
.topbar-right {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  width: 64px;
  /* Equal to topbar-left â€” keeps logo perfectly centered on mobile */
}

/* All topbar buttons */
.menu-btn,
.nav-search,
.nav-profile,
.nav-order {
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px;
  color: #fff;
  -webkit-appearance: none;
}

/* Bootstrap icon sizes & stroke for premium look */
.menu-btn i {
  font-size: 1.55rem;
  -webkit-text-stroke: 0.3px;
}

.nav-search i {
  font-size: 1.25rem;
  -webkit-text-stroke: 0.4px;
}

.nav-profile i {
  font-size: 1.3rem;
  -webkit-text-stroke: 0.3px;
}

/* bi-person needs to be slightly larger but thinner to visually match the others */
.nav-order i {
  font-size: 1.25rem;
  -webkit-text-stroke: 0.4px;
}

@media (max-width: 768px) {
  .desktop-only {
    display: none !important;
  }
}

@media (max-width: 768px) {
  body {
    padding-bottom: 0;
  }
}

/* =========================================
   SIDEMENU COMPONENT
========================================= */
.sidemenu-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  background: var(--overlay-medium);
  opacity: 0;
  visibility: hidden;
  transition: all 0.3s ease;
  z-index: 3000;
}

.sidemenu-overlay.active {
  opacity: 1;
  visibility: visible;
}

.sidemenu {
  position: fixed;
  top: 0;
  left: -400px;
  width: 320px;
  max-width: 85%;
  height: 100vh;
  background: var(--bg-color);
  z-index: 3001;
  transition: all 0.4s cubic-bezier(0.77, 0, 0.175, 1), visibility 0.4s;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  visibility: hidden;
}

.sidemenu.active {
  left: 0;
  visibility: visible;
}

/* Black like the header it opens from */
.sidemenu-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 20px;
  height: var(--topbar-h);
  flex-shrink: 0;
  background: var(--color-ink);
  color: #fff;
}

.sidemenu-logo {
  font-size: 1.2rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: #fff;
}

.sidemenu-close {
  color: #fff;
  background: none;
  border: none;
  cursor: pointer;
  display: flex;
}

/* Contact: quieter than the collections above them */
.sidemenu-secondary {
  margin-top: 12px;
  border-top: 6px solid var(--surface-muted);
}

.sidemenu-secondary a {
  font-weight: 400;
  color: var(--text-muted);
}

.sidemenu-nav {
  display: flex;
  flex-direction: column;
}

.sidemenu-nav li {
  border-bottom: 1px solid var(--border-light);
}

.sidemenu-nav a {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  font-size: 0.85rem;
  font-weight: 500;
  text-transform: none;
  color: var(--text-color);
  letter-spacing: 0.5px;
  transition: background 0.3s ease;
}

.sidemenu-nav a:hover {
  background: var(--surface-subtle);
}

.sidemenu-nav a span.plus {
  font-size: 1.2rem;
  font-weight: 300;
  color: var(--text-color);
}

/* Accordion sub-menu for parent collections with children */
.sidemenu-nav li.has-children {
  border-bottom: none;
}

/* Split row: name-link (left, navigates) + toggle-btn (right, expands) */
.sidemenu-nav .sidemenu-item-row {
  display: flex;
  align-items: stretch;
  border-bottom: 1px solid var(--border-light);
}

.sidemenu-nav .sidemenu-col-link {
  flex: 1;
  display: flex;
  align-items: center;
  padding: 16px 20px;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--text-color);
  letter-spacing: 0.5px;
  transition: background 0.2s ease;
}

.sidemenu-nav .sidemenu-col-link:hover {
  background: var(--surface-subtle);
}

/* + button — right side, expands/collapses */
.sidemenu-nav .accordion-toggle {
  width: 48px;
  flex-shrink: 0;
  background: none;
  border: none;
  border-left: 1px solid var(--border-light);
  font-size: 1.25rem;
  font-weight: 300;
  color: var(--gray-400);
  cursor: pointer;
  transition: color 0.15s ease, background 0.15s ease;
  display: flex;
  align-items: center;
  justify-content: center;
}

.sidemenu-nav .accordion-toggle:hover,
.sidemenu-nav .accordion-toggle.active {
  background: var(--surface-muted);
  color: var(--text-strong);
}

/* Sub-menu: hidden by default, shown via .open class */
.sidemenu-nav .sub-menu {
  list-style: none;
  padding: 0;
  margin: 0;
  background: var(--surface-subtle);
  border-bottom: 1px solid var(--border-light);
  /* Collapsed by default */
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.25s ease;
}

.sidemenu-nav .sub-menu.open {
  max-height: 400px;
  /* enough for any reasonable sub-list */
}

.sidemenu-nav .sub-item a {
  padding: 12px 20px 12px 34px;
  font-size: 0.82rem;
  font-weight: 400;
  color: var(--gray-700);
  display: block;
  border-bottom: 1px solid var(--border-light);
  transition: color 0.15s, background 0.15s;
}

.sidemenu-nav .sub-item:last-child a {
  border-bottom: none;
}

.sidemenu-nav .sub-item a:hover {
  color: var(--text-color);
  background: var(--surface-alt);
}

/* Hide the old .plus span on flat links (no children) */
.sidemenu-nav a span.plus {
  display: none;
}

.sidemenu-footer {
  margin-top: auto;
  padding: 30px 20px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
  box-sizing: border-box;
}

.btn-signin,
.btn-signup {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 14px;
  font-size: 0.85rem;
  font-weight: 600;
  text-transform: none;
  letter-spacing: 1px;
  transition: all 0.3s ease;
  cursor: pointer;
  border-radius: var(--radius-sm);
  flex: 1;
}

.btn-signin {
  border: 1px solid var(--text-color);
  color: var(--text-color);
  background: transparent;
}

.btn-signin:hover {
  background: var(--surface-muted);
}

.btn-signup {
  background: var(--text-color);
  color: var(--bg-color) !important;
  border: 1px solid var(--text-color);
}

.btn-signup:hover {
  background: var(--text-strong);
}

/* Sidemenu Action Button (Sign In / Sign Out) */
.btn-sidemenu-action {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  padding: 14px;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--text-color);
  background: var(--bg-color);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  transition: all 0.2s ease;
  text-decoration: none;
  cursor: pointer;
  box-sizing: border-box;
}

.btn-sidemenu-action:hover {
  background: var(--overlay-faint);
  border-color: var(--text-color);
  box-shadow: var(--shadow-xs);
}

/* =========================================
   CART DRAWER (Right Side)
========================================= */
.cart-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background-color: var(--overlay-scrim);
  z-index: 1999;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease, visibility 0.3s ease;
}

.cart-overlay.active {
  opacity: 1;
  visibility: visible;
}

.cart-drawer {
  position: fixed;
  top: 0;
  right: -100%;
  width: 90vw;
  max-width: 400px;
  height: 100vh;
  background-color: var(--bg-color);
  z-index: 2000;
  transition: right 0.4s cubic-bezier(0.77, 0, 0.175, 1), visibility 0.4s;
  display: flex;
  flex-direction: column;
  box-shadow: var(--shadow-drawer);
  visibility: hidden;
}

.cart-drawer.active {
  right: 0;
  visibility: visible;
}

.cart-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px 25px;
  border-bottom: 1px solid var(--border-light);
}

.cart-header h2 {
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 1px;
}

.cart-close {
  background: none;
  border: none;
  font-size: 1.5rem;
  cursor: pointer;
  color: var(--text-strong);
}

/* The scroll now belongs to the whole middle of the drawer — items, nudges and the
   bundle rail together — so the rail no longer holds space open above the footer. */
.cart-scroll {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

/* Tighter than it was. At 25px all round with 25px between rows, a single-item cart was
   mostly white space and the offer below it looked like a separate page. The last row
   drops its rule and its gap, so the nudge underneath sits against the cart rather than
   floating in the middle of the drawer. */
.cart-items-container {
  padding: 18px 20px 4px;
}

.cart-item {
  display: flex;
  gap: 14px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--surface-muted);
  padding-bottom: 16px;
}

.cart-item:last-child {
  margin-bottom: 0;
  padding-bottom: 4px;
  border-bottom: 0;
}

.cart-item:last-child {
  border-bottom: none;
  margin-bottom: 0;
  padding-bottom: 0;
}

/* The photo takes the height the row ACTUALLY needs rather than forcing 100px on it.
   Fixed at 100 it was taller than the text beside it — title, price and the size row come
   to about 72 — so every row carried ~28px of dead height, and .cart-item-actions parked
   all of it in one gap between the price and the size row. A short product name made that
   hole the most obvious thing in the cart. min-height keeps the photo portrait when a
   line of text is missing. */
.cart-item-image {
  width: 80px;
  height: auto;
  min-height: 92px;
  align-self: stretch;
  background: var(--surface-subtle);
  border: 1px solid var(--border-light);
  /* subtle frame — square, like the product grid */
  flex-shrink: 0;
}

.cart-item-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.cart-item-details {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  flex: 1;
}

/* Two lines at most, so a long name cannot make its row twice the height of the one
   above it — uneven rows are what reads as "gaps" when you scan a cart. */
.cart-item-title {
  font-size: 0.8rem;
  font-weight: 600;
  margin-bottom: 5px;
  text-transform: none;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.cart-item-price {
  font-size: 0.85rem;
  font-weight: 500;
  margin-bottom: 5px;
}

.cart-item-size {
  font-size: 0.75rem;
  color: var(--text-muted);
  margin-bottom: 15px;
}

.cart-item-actions {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: 10px;
  /* NOT `auto`. That pushed this row to the bottom of a block stretched to the photo's
     height, which turned the row's spare height into one visible hole above it. */
  margin-top: 6px;
}

.cart-item-size-left {
  font-size: 0.75rem;
  color: var(--text-muted);
  text-align: left;
}

.quantity-selector {
  display: flex;
  align-items: center;
  border: 1px solid var(--border-color);
  height: 32px;
  border-radius: 0;
  /* square — consistent with the checkout button */
}

.qty-btn {
  background: none;
  border: none;
  width: 30px;
  height: 100%;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
}

.qty-number {
  font-size: 0.85rem;
  font-weight: 500;
  min-width: 30px;
  text-align: center;
}

.cart-item-remove {
  background: none;
  /* minimal — just the icon, no grey circle */
  border: none;
  width: 32px;
  height: 32px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  transition: color 0.2s ease;
}

.cart-item-remove:hover {
  color: var(--color-danger);
}

/* Compacted: the footer is fixed to the bottom of the drawer, so every px it saves is
   a px of product list the customer can see. Tighter padding + row gaps, same content. */
.cart-footer {
  padding: 14px 20px 16px;
  background-color: var(--surface-subtle);
  border-top: 1px solid var(--surface-alt);
}

.cart-summary-row {
  display: flex;
  justify-content: space-between;
  margin-bottom: 7px;
  font-size: 0.85rem;
  color: var(--text-muted);
}

.cart-total-row {
  font-size: 1rem;
  font-weight: 600;
  color: var(--text-color);
  /* Divider separates the running summary from the final total. */
  margin-top: 2px;
  padding-top: 9px;
  border-top: 1px solid var(--border-light);
  margin-bottom: 12px;
}

.btn-checkout {
  width: 100%;
  background-color: var(--text-color);
  color: var(--bg-color);
  border: 1px solid var(--text-color);
  padding: 16px;
  font-size: 0.85rem;
  font-weight: 600;
  text-transform: none;
  letter-spacing: 1px;
  cursor: pointer;
  /* Square — matches the product page's Add-to-Cart / Buy-Now buttons (radius 0). */
  border-radius: 0;
  transition: background-color 0.3s ease;
}

.btn-checkout:hover {
  background-color: var(--text-strong);
}

/* ── Cart empty state ────────────────────────────────────────────────────────── */
/* The ordinary price, struck, beside what the offer makes it. Same treatment as the
   product page so the two screens read as one. */
.cart-item-was {
  text-decoration: line-through;
  color: var(--price-strike);
  font-size: 0.8rem;
  font-weight: 400;
  margin-right: 5px;
}

.cart-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  text-align: center;
  padding: 2rem 1.5rem;
}

.cart-empty-icon {
  font-size: 2.75rem;
  color: var(--gray-300, #cbcbcb);
  margin-bottom: 1rem;
}

.cart-empty-title {
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0.5px;
  color: var(--text-color);
  margin-bottom: 6px;
}

.cart-empty-sub {
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--text-muted);
  max-width: 26ch;
  margin-bottom: 1.75rem;
}

/* Auto width so it reads as a button, not a full bar, on an otherwise empty panel. */
.cart-empty-btn {
  width: auto;
  padding: 14px 34px;
}

/* =========================================
   CART DRAWER — BOGO PROMO BANNER
========================================= */
/* ── Announcement bar ─────────────────────────────────────────────────────────
   Above the topbar, in NORMAL FLOW — deliberately not fixed. The topbar is
   `position: fixed; top: 0`, so a fixed bar would force a top offset on every page
   and cost ~36px of permanent mobile height. Scrolling away costs nothing.
   Replaces the old home-only marquee. */
/* ── Session offer sheet ──────────────────────────────────────────────────────
   Slides up from the bottom and covers at most 60% of the screen. Deliberately not a
   full-screen modal: most of this traffic arrives from an ad and wants to see the
   product, and anything that blocks that view is answered with the back button. */
.so-sheet-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, .38);
  opacity: 0;
  pointer-events: none;
  transition: opacity .28s ease;
  z-index: 1400;
}

.so-sheet-backdrop.is-open {
  opacity: 1;
  pointer-events: auto;
}

.so-sheet {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  max-height: 78vh;
  overflow-y: auto;
  background: #fff;
  border-radius: 20px 20px 0 0;
  padding: 10px 20px calc(18px + env(safe-area-inset-bottom, 0px));
  transform: translateY(100%);
  transition: transform .32s cubic-bezier(.2, .7, .2, 1);
  z-index: 1401;
  box-shadow: 0 -8px 34px rgba(0, 0, 0, .18);
}

/* Desktop gets a card rather than a full-width bar: a 1400px-wide sheet reads as a site
   outage notice, not an offer. */
@media (min-width: 720px) {
  .so-sheet {
    left: auto;
    right: 26px;
    bottom: 26px;
    width: 400px;
    border-radius: 18px;
    padding: 10px 22px 20px;
  }

  .so-sheet.is-open {
    transform: none;
  }
}

.so-sheet.is-open {
  transform: none;
}

.so-sheet-grip {
  width: 38px;
  height: 4px;
  border-radius: 2px;
  background: #e2e2e8;
  margin: 0 auto 16px;
}

/* The corner X. Sits over the head rather than in it, so the heading stays centred. */
.so-sheet-x {
  position: absolute;
  top: 12px;
  right: 13px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: #f4f4f7;
  color: #6b6b74;
  font-size: .78rem;
  line-height: 1;
  cursor: pointer;
  transition: background .15s, color .15s;
}

.so-sheet-x:hover {
  background: #e8e8ee;
  color: var(--text-color, #111);
}

/* ── Head ── */
.so-sheet-head {
  text-align: center;
  /* Clear of the corner X, so a long heading never runs under it. */
  padding: 0 34px;
}

/* The one claim worth making before anything else: this is not a site-wide sale. */
.so-sheet-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 11px;
  border-radius: 999px;
  background: #f4f4f7;
  color: #555;
  font-size: .66rem;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
}

.so-sheet-badge i {
  font-size: .72rem;
}

.so-sheet h3 {
  margin: 11px 0 0;
  font-size: 1.14rem;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -.01em;
  color: var(--text-color);
}

.so-sheet-note {
  margin: 6px 0 0;
  font-size: .82rem;
  color: #767680;
  line-height: 1.5;
}

.so-sheet-sub {
  margin: 6px 0 0;
  font-size: .82rem;
  color: #767680;
}

/* ── Clock ──
   The number and a bar for how much of the window is gone. The bar is the part that is
   felt rather than read, which is why it is here and not only a digit. */
.so-clock {
  margin: 16px 0 4px;
  padding: 11px 13px 12px;
  border-radius: 12px;
  background: #f7f7f9;
}

.so-clock-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.so-clock-label {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: .76rem;
  font-weight: 600;
  color: #767680;
}

.so-sheet-time {
  font-size: 1.32rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
  line-height: 1;
  color: var(--text-color);
}

.so-clock-bar {
  height: 4px;
  margin-top: 9px;
  border-radius: 2px;
  background: #e4e4ea;
  overflow: hidden;
}

.so-clock-bar span {
  display: block;
  height: 100%;
  border-radius: 2px;
  background: var(--text-color, #111);
  transition: width 1s linear;
}

/* The last two minutes recolour the clock once. No pulsing — a thing that blinks for two
   minutes is read as an advert and stops being seen. */
.so-sheet.is-urgent .so-clock {
  background: #fff7ed;
}

.so-sheet.is-urgent .so-sheet-time {
  color: #b45309;
}

.so-sheet.is-urgent .so-clock-bar span {
  background: #b45309;
}

/* ── Perks ── */
.so-perks {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 12px;
}

.so-perk-card {
  padding: 12px 13px;
  border: 1px solid #ededf2;
  border-radius: 12px;
  background: #fff;
}

.so-perk-card.is-met {
  border-color: #bbf7d0;
  background: #f6fef9;
}

.so-perk-top {
  display: flex;
  align-items: center;
  gap: 11px;
}

/* How far the basket is from the minimum. Only drawn once the server has answered — the
   number it measures is the one the order is charged against, including for a perk
   limited to chosen products or collections, which the browser cannot work out. */
.so-progress {
  height: 5px;
  margin-top: 11px;
  border-radius: 3px;
  background: #eeeef3;
  overflow: hidden;
}

.so-progress span {
  display: block;
  height: 100%;
  min-width: 5px;
  border-radius: 3px;
  background: #b45309;
  transition: width .35s ease;
}

.so-progress.is-met span {
  background: #16a34a;
}

.so-perk-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 34px;
  height: 34px;
  border-radius: 9px;
  background: var(--text-color, #111);
  color: #fff;
  font-size: .92rem;
}

.so-perk-body {
  flex: 1;
  min-width: 0;
}

.so-perk-main {
  font-size: .9rem;
  font-weight: 700;
  line-height: 1.3;
  color: var(--text-color);
}

/* The minimum, always written out. A condition the visitor only meets at checkout is one
   they find out about at the worst possible moment. */
.so-perk-cond {
  font-size: .75rem;
  color: #8a8a94;
  margin-top: 3px;
  line-height: 1.4;
}

/* How far off the basket is, where the whole basket is what the server measures. */
.so-perk-gap {
  flex: 0 0 auto;
  padding: 4px 9px;
  border-radius: 6px;
  background: #fff7ed;
  color: #b45309;
  font-size: .72rem;
  font-weight: 700;
  white-space: nowrap;
}

.so-perk-ok {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  flex: 0 0 auto;
  padding: 4px 9px;
  border-radius: 6px;
  background: #ecfdf3;
  color: #15803d;
  font-size: .72rem;
  font-weight: 700;
  white-space: nowrap;
}

/* A random offer can hide behind this until it is tapped. */
.so-reveal {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  width: 100%;
  margin-top: 14px;
  padding: 20px 16px 18px;
  border: 1.5px dashed #d8d8de;
  border-radius: 14px;
  background: #fafafb;
  font: inherit;
  color: var(--text-color);
  cursor: pointer;
  transition: border-color .15s, background .15s;
}

.so-reveal:hover {
  border-color: var(--text-color, #111);
  background: #fff;
}

.so-reveal-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  margin-bottom: 5px;
  border-radius: 50%;
  background: var(--text-color, #111);
  color: #fff;
  font-size: 1.15rem;
}

.so-reveal-main {
  font-size: .92rem;
  font-weight: 700;
}

.so-reveal-sub {
  font-size: .73rem;
  color: #8a8a94;
}

/* ── A promotion's own panel ──
   Shares the session offer's tab and sheet; these are the two things it adds — the price
   ladder and the conditions.

   The sheet carries the tab's red so opening it feels like opening the thing you tapped.
   Scoped to #pp-sheet, because the session offer's panel is the black one and the two
   must stay telling apart. */
#pp-sheet .so-sheet-badge {
  background: #fdecea;
  color: #b3160f;
}

#pp-sheet .pp-tier b,
#pp-sheet .so-perk-icon,
#pp-sheet .so-sheet-close {
  background: #d81e14;
}

#pp-sheet .so-sheet-close:hover {
  background: #b3160f;
}

#pp-sheet .pp-clock {
  background: #fdecea;
}

#pp-sheet .pp-unit {
  border-color: #f8cfcb;
}

#pp-sheet .pp-unit strong {
  color: #b3160f;
}

#pp-sheet .pp-terms-btn:hover {
  border-color: #f0b7b2;
  background: #fffafa;
}

/* The last six hours deepen the red rather than switching to a different colour. */
#pp-sheet.is-urgent .pp-clock {
  background: #fde0dd;
}

#pp-sheet.is-urgent .pp-unit strong {
  color: #8f0f09;
}
/* ── One campaign, one card ───────────────────────────────────────────────────
   The sheet used to BE a single campaign — its title, its clock, its conditions,
   its button. With two running, each needs its own, so the campaign became a card
   and the sheet became the thing that holds them.

   With one campaign (`.is-only`) nothing is drawn around it, so the sheet looks
   exactly as it did before this existed. The separator appears only when there is
   genuinely a second campaign to separate. */
.pp-card + .pp-card {
  margin-top: 18px;
  padding-top: 18px;
  border-top: 1px solid #ECECEF;
}

/* The tab swapping from one campaign to the other. Both rows fade together — the
   name and the countdown describe the same offer, and sliding one without the
   other would put a campaign's name over another campaign's last day. */
.pp-tab.is-swapping .pp-tab-name,
.pp-tab.is-swapping .pp-tab-clock {
  opacity: 0;
  transform: translateY(-4px);
}

.pp-tab .pp-tab-name,
.pp-tab .pp-tab-clock {
  transition: opacity .2s ease, transform .2s ease;
}

@media (prefers-reduced-motion: reduce) {
  .pp-tab .pp-tab-name,
  .pp-tab .pp-tab-clock {
    transition: none;
  }
}

/* "Free delivery included" under an offer's prices. Quiet and green: it is a real
   part of the deal, but the prices are what the eye should land on first. */
.pp-block-ship {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
  font-size: 0.78rem;
  font-weight: 600;
  color: #047857;
}

.pp-block-ship i {
  font-size: 0.8rem;
}

.pp-blocks {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 14px;
}

.pp-block {
  padding: 12px 14px;
  border: 1px solid #ededf2;
  border-radius: 12px;
  background: #fff;
}

.pp-block-head {
  font-size: .82rem;
  font-weight: 700;
  color: var(--text-color);
  margin-bottom: 7px;
}

.pp-block ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.pp-block li {
  display: flex;
  align-items: baseline;
  gap: 7px;
  font-size: .85rem;
  color: #3f3f46;
  line-height: 1.75;
}

.pp-block li::before {
  content: "";
  flex: 0 0 4px;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: #c4c4cc;
}

/* An offer's "What they get" written by the admin (HTML, cleaned to a short tag list on save).
   Headings, bold, lists and small print — the same quiet look as the generated blocks. */
.pp-block-rich { font-size: .85rem; color: #3f3f46; line-height: 1.6; }
.pp-block-rich > :first-child { margin-top: 0; }
.pp-block-rich > :last-child { margin-bottom: 0; }
.pp-block-rich p { margin: 0 0 6px; }
.pp-block-rich h4 { margin: 0 0 7px; font-size: .82rem; font-weight: 700; color: var(--text-color); }
.pp-block-rich h5 { margin: 9px 0 4px; font-size: .74rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: #6b6b76; }
/* The generated blocks lay each list item out as a flex row (bullet, then text). Written text
   has bold and italic runs inside a line, and a flex row would space every run apart, so
   lists in a written block are ordinary lists. */
.pp-block-rich ul,
.pp-block-rich ol { margin: 0 0 6px; padding-left: 1.2em; }
.pp-block-rich ul { list-style: disc; }
.pp-block-rich li { display: list-item; line-height: 1.7; }
.pp-block-rich li::before { content: none; }
.pp-block-rich s { color: #9a9aa3; }

/* The whole ladder on one line. As a bulleted list each range ran four lines tall and the
   second range fell below the fold; as pills a range is two lines, heading included. */
.pp-tiers {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.pp-tier {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 10px 5px 6px;
  border-radius: 8px;
  background: #f5f5f8;
  font-size: .82rem;
  color: #3f3f46;
  white-space: nowrap;
}

/* The quantity reads as a chip of its own — "2" then the price, not "2৳1300". */
.pp-tier b {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  border-radius: 6px;
  background: var(--text-color, #111);
  color: #fff;
  font-size: .72rem;
  font-weight: 700;
}

.pp-tier>span {
  font-weight: 600;
}

/* ── The clock ──
   Four boxes that move every second. One static "9d 16h" stops reading as a countdown. */
.pp-clock {
  text-align: center;
}

.pp-clock-label {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  font-size: .74rem;
  font-weight: 600;
  color: #767680;
  margin-bottom: 9px;
}

.pp-clock-units {
  display: flex;
  justify-content: center;
  gap: 7px;
}

.pp-unit {
  flex: 1;
  max-width: 68px;
  padding: 7px 4px 6px;
  border-radius: 9px;
  background: #fff;
  border: 1px solid #e8e8ee;
}

.pp-unit strong {
  display: block;
  font-size: 1.18rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
  color: var(--text-color);
}

.pp-unit span {
  display: block;
  margin-top: 2px;
  font-size: .62rem;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: #9b9ba3;
}

.so-sheet.is-urgent .pp-unit strong {
  color: #b45309;
}

.so-sheet.is-urgent .pp-unit {
  border-color: #fed7aa;
}

/* The small print, opened on a tap. Always-visible terms are skipped; terms somebody
   chose to open are actually read — and the offer itself stays the thing on screen. */
.pp-terms-btn {
  display: flex;
  align-items: center;
  gap: 7px;
  width: 100%;
  margin-top: 12px;
  padding: 10px 13px;
  border: 1px solid #ededf2;
  border-radius: 10px;
  background: #fff;
  font: inherit;
  font-size: .8rem;
  font-weight: 600;
  color: #4b5563;
  cursor: pointer;
  transition: background .15s, border-color .15s;
}

.pp-terms-btn:hover {
  border-color: #d4d4db;
  background: #fafafb;
}

.pp-terms-btn span {
  flex: 1;
  text-align: left;
}

.pp-terms-caret {
  font-size: .75rem;
  color: #9ca3af;
  transition: transform .2s ease;
}

.pp-terms-btn.is-open .pp-terms-caret {
  transform: rotate(180deg);
}

.pp-terms {
  margin-top: 6px;
  padding: 11px 13px;
  border-radius: 10px;
  background: #f7f7f9;
}

/* Written in a rich editor, so the panel has to style whatever it allows: lists, a
   paragraph, bold and italic. Nothing else gets through the server's whitelist. */
.pp-terms ul,
.pp-terms ol {
  margin: 0;
  padding-left: 16px;
}

.pp-terms li,
.pp-terms p {
  font-size: .77rem;
  color: #6b6b74;
  line-height: 1.6;
  margin: 0;
}

.pp-terms li + li,
.pp-terms p + p,
.pp-terms ul + p,
.pp-terms p + ul {
  margin-top: 4px;
}

.pp-terms strong,
.pp-terms b {
  color: #4b4b54;
  font-weight: 700;
}

@media (prefers-reduced-motion: reduce) {
  .pp-terms-caret {
    transition: none;
  }
}

/* ── Ended ── */
.so-sheet-ended {
  text-align: center;
  padding: 8px 0 4px;
}

.so-ended-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin-bottom: 10px;
  border-radius: 50%;
  background: #f4f4f7;
  color: #8a8a94;
  font-size: 1.2rem;
}

/* The small print that keeps the offer honest: that it ends, and whether it can come
   round again. Quiet, but never absent. */
.so-sheet-fine {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  margin: 14px 0 0;
  font-size: .73rem;
  color: #9b9ba3;
  line-height: 1.5;
}

.so-sheet-fine i {
  font-size: .8rem;
  margin-top: 1px;
}

.so-sheet-close {
  display: block;
  text-align: center;
  text-decoration: none;
  width: 100%;
  margin-top: 14px;
  padding: 13px;
  border: 0;
  border-radius: 11px;
  background: var(--text-color, #111);
  color: #fff;
  font: inherit;
  font-size: .86rem;
  font-weight: 600;
  cursor: pointer;
}

.so-sheet-close:hover {
  background: var(--text-strong, #000);
}

@media (prefers-reduced-motion: reduce) {

  .so-sheet,
  .so-sheet-backdrop,
  .so-clock-bar span {
    transition: none;
  }
}

.announcement-bar {
  display: none;
  /* JS/SSR switches to flex when text exists */
  align-items: center;
  justify-content: center;
  gap: 0;
  width: 100%;
  /* Fixed height, border included: the offset below is a constant, so the bar must
     never grow. A long Bangla message that wrapped to two lines would push its own
     bottom edge past the topbar and cover the logo again. */
  box-sizing: border-box;
  height: 39px;
  padding: 0;
  /* arrows sit hard against the screen edges */
  /* White, not black: a black strip above a white header reads as a second toolbar
     and visually shortens the page. Light keeps it a whisper, not a shout.
     Metrics below are measured off goodybro.com — light weight, open tracking and
     a softened black are what make the strip read as a whisper rather than a banner. */
  /* Same glass treatment as .topbar — the two are stacked and touching, so a solid
     strip above a frosted one reads as two different toolbars. */
  /* Fallback matters here more than on .topbar: this bar overlays page content, so
     an undefined token would leave text sitting on the artwork. */
  /* Posh Palace: a plain white strip of small capitals UNDER the black header, as on the
     old site. Solid rather than frosted: under a black bar, glass reads as grey. */
  background: var(--bg-color, #fff);
  color: var(--text-muted, #545454);
  border-bottom: 1px solid var(--border-light, #ebebeb);
  font-family: var(--font-primary);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-align: center;
  /* Directly below the fixed header, but part of the page: it scrolls away with the
     content and only the header stays, as on the old site. Absolute against the document
     (body is not positioned), in the space body's padding-top keeps for it. */
  position: absolute;
  top: var(--topbar-h);
  left: 0;
  right: 0;
  z-index: 190;
  /* under the header (200), so the header covers it as it scrolls up */
}

/* One switch drives the whole offset. The attribute is only present once real
   messages exist (SSR bakes it; the client sets it after render), so an empty
   setting leaves every offset at zero and nothing shifts. */
body:has(#announcement-bar[data-messages]) {
  --announce-h: 39px;
  /* must equal the bar height including its 1px border */
}

/* Body padding moves in-flow content down; the fixed topbar is positioned
   explicitly because viewport-fixed elements ignore body padding. */
body {
  padding-top: var(--announce-h, 0px);
}

/* The header stays at the very top; the strip hangs under it. */
.topbar {
  top: 0;
}

.announce-track {
  flex: 1;
  min-width: 0;
  padding: 0 4px;
  overflow: hidden;
}

/* Only the active message is in the DOM at a time — no sliding strip to mis-measure.
   Up to TWO lines, never three: the bar height is a constant the whole page offset is
   built on (see .announcement-bar), so a long message has to fit rather than the strip
   grow. It used to be one line with an ellipsis, which silently ate the end of longer
   Bangla messages and forced the admin to count characters. */
.announce-msg {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  line-height: 1.25;
  animation: announce-in 0.35s ease both;
}

/* Set by initAnnouncementBar() only when the message actually wrapped. Shrinking the
   type is what keeps two lines inside a 38px strip; single-line messages are untouched
   and stay at full size, so the common case loses nothing. */
/* 0.78rem × 1.2 × 2 lines = 30px inside a 38px strip — about 4px of air top and
   bottom. Smaller was tried and reads as fine print rather than an announcement. */
.announcement-bar.is-two-line {
  font-size: 0.78rem;
  letter-spacing: 0.3px;
}

.announcement-bar.is-two-line .announce-msg {
  line-height: 1.2;
}

/* No underline — the arrow is the affordance, and underlining small tracked text
   at this size turns a quiet strip into noise. */
.announce-msg a {
  color: inherit;
  text-decoration: none;
}

/* The → glyph sits on the baseline, but its ink is shallower than the text's: at
   15.2px Montserrat the text ink centres 4.5px above the baseline and the arrow only
   3.5px, so it reads a pixel low. Corrected in em so it holds at both the 0.85rem
   and 0.95rem sizes. 1px / 15.2px = 0.066em. */
.announce-arrow {
  display: inline-block;
  margin-left: 2px;
  transform: translateY(-0.066em);
  transition: transform 0.15s ease;
}

/* Keeps the vertical correction while nudging sideways — a bare translateX here
   would drop the arrow back down. */
.announce-msg a:hover .announce-arrow {
  transform: translate(3px, -0.066em);
}

/* The chevrons are inline SVG rather than <i class="bi bi-chevron-left">: the site
   loads no icon font and ICONS in js/icons.js has no chevron-left/right, so the
   glyph never appeared — the buttons were live but invisible. Inline markup also
   means they paint with the SSR bar instead of waiting for replaceIcons(). */
.announce-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  color: inherit;
  opacity: 0.75;
  cursor: pointer;
  width: 44px;
  /* full thumb target, matching the bar height */
  height: 38px;
  padding: 0;
  line-height: 1;
  font-size: 12px;
  /* sizes the 1em SVG — navigation, not decoration */
  flex-shrink: 0;
  transition: opacity 0.15s;
}

.announce-nav:hover {
  opacity: 1;
}

@media (min-width: 768px) {
  .announcement-bar {
    font-size: 0.85rem;
  }

  /* Two lines need a step down: 0.78rem × 1.2 × 2 = 30px, inside the 38px strip. */
  .announcement-bar.is-two-line {
    font-size: 0.78rem;
  }
}

/* Continuous ticker (initAnnouncementBar). Hover pauses it so a link can be clicked. */
.announcement-bar.is-ticker .announce-track {
  padding: 0;
}

/* A running strip has nothing to step through. The server paints the arrows for a
   multi-message bar (inline display), hence the !important. */
.announcement-bar.is-ticker .announce-nav {
  display: none !important;
}

.announce-ticker {
  display: flex;
  width: max-content;
  animation: announce-scroll 30s linear infinite;
}

.announcement-bar.is-ticker:hover .announce-ticker {
  animation-play-state: paused;
}

.announce-run {
  display: flex;
  align-items: center;
  white-space: nowrap;
}

.announce-item {
  padding: 0 20px;
}

.announce-item a {
  color: inherit;
  text-decoration: none;
}

.announce-sep {
  opacity: 0.45;
}

@keyframes announce-scroll {
  from {
    transform: translateX(0);
  }

  to {
    transform: translateX(-50%);
  }
}

@keyframes announce-in {
  from {
    opacity: 0;
    transform: translateY(-3px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

/* Someone who asked for less motion should not get a strip that swaps under them */
@media (prefers-reduced-motion: reduce) {
  .announce-msg {
    animation: none;
  }
}

/* ── Bundle offer hint ────────────────────────────────────────────────────────
   One class for the product page, cart drawer and checkout so the offer reads as
   the same message everywhere. Monochrome on purpose: the site is black / white /
   cream, and a yellow "deal" strip made it look like a third-party coupon widget
   rather than part of the brand. The left rule carries the emphasis instead. */
.bundle-hint {
  display: none;
  /* JS switches to flex when a promo matches */
  align-items: center;
  flex-wrap: wrap;
  /* Posh Palace: the old site's cream offer box ("Shirts offer: Buy 2, save 10%") */
  background: var(--offer-bg, #fbf8f1);
  border: 1px solid var(--offer-border, #e2d8c3);
  border-radius: 0;
  padding: 12px 14px;
  /* No top margin: the hint sits directly under a summary row that already has its
     own spacing, and 12px on top left an obvious gap above it in checkout. */
  margin: 0 0 10px;
  font-family: var(--font-primary);
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--offer-text, #24201a);
}

.bundle-hint i {
  font-size: 0.95rem;
  flex-shrink: 0;
  opacity: 0.8;
}

.bundle-hint strong {
  font-weight: 700;
}

.bundle-hint a {
  color: var(--text-color);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.cart-bogo-hint {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 20px;
  font-family: var(--font-primary);
  border-top: 1px solid var(--border-light);
  border-bottom: 1px solid var(--border-light);
  animation: bogo-fadein 0.3s ease both;
}

@keyframes bogo-fadein {
  from {
    opacity: 0;
    transform: translateY(4px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Hint state — not yet eligible / info */
.cart-bogo-hint.hint {
  background: var(--surface-subtle);
  border-left: 3px solid var(--color-warning);
}

.cart-bogo-hint.hint .bogo-icon-wrap i {
  color: var(--color-warning);
}

/* Success state — BOGO unlocked */
.cart-bogo-hint.success {
  background: var(--bg-color);
  border-left: 3px solid var(--text-color);
}

.cart-bogo-hint.success .bogo-icon-wrap i {
  color: var(--text-color);
}

/* Icon column */
.bogo-icon-wrap {
  font-size: 1rem;
  flex-shrink: 0;
  margin-top: 2px;
}

/* Text column */
.bogo-text-wrap {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

/* Uppercase label line */
.bogo-label {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--text-strong);
}

/* Detail message line */
#cart-bogo-msg {
  font-size: 0.78rem;
  font-weight: 400;
  color: var(--color-ink-soft);
  line-height: 1.45;
}

/* Link inside banner */
.cart-bogo-hint a {
  color: var(--color-ink);
  text-decoration: underline;
  text-underline-offset: 2px;
  font-weight: 600;
}

/* =========================================
   FREE GIFT — UX COMPONENTS
========================================= */

/* Badge shown on free gift cart item */
.free-gift-badge {
  display: inline-block;
  background: transparent;
  color: var(--color-success);
  border: 1px solid var(--color-success);
  padding: 2px 7px;
  border-radius: var(--radius-sm);
  font-size: 10px;
  font-weight: 700;
  margin-top: 4px;
  letter-spacing: 0.3px;
}

/* Inline size row shown when free gift needs size selection */
.free-gift-size-row {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 8px;
}

.free-gift-size-label {
  font-size: 0.72rem;
  color: var(--text-muted);
  font-weight: 500;
  white-space: nowrap;
}

.free-gift-size-chip {
  background: var(--bg-color);
  border: 1.5px solid var(--border-color);
  border-radius: var(--radius-sm);
  padding: 3px 10px;
  font-size: 0.75rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
  font-family: var(--font-primary);
}

.free-gift-size-chip:hover {
  background: var(--color-ink);
  border-color: var(--color-ink);
  color: var(--bg-color);
}

/* Size selection reminder hint — appears below Proceed/Complete Order button */
.bogo-size-hint {
  display: none;
  margin: 8px 0 0;
  font-size: 0.75rem;
  color: var(--color-warning);
  text-align: center;
  font-weight: 500;
  font-family: var(--font-primary);
}

/* "Decline" link for free gift in checkout summary */
.gift-decline-btn {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 0.72rem;
  color: var(--text-muted);
  text-decoration: underline;
  text-underline-offset: 2px;
  padding: 0;
  font-family: var(--font-primary);
  transition: color 0.15s;
}

.gift-decline-btn:hover {
  color: var(--color-danger);
}

/* =========================================
   CART DRAWER — CUSTOM ALERT MODAL
========================================= */
#cart-alert-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: var(--overlay-scrim);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  z-index: 10000;
  align-items: center;
  justify-content: center;
}

#cart-alert-overlay.active {
  display: flex;
}

#cart-alert-box {
  background: var(--bg-color);
  border-radius: var(--radius-md);
  padding: 32px 28px 24px;
  width: min(340px, 88vw);
  box-shadow: var(--shadow-md);
  text-align: center;
  animation: c-alert-pop 0.2s cubic-bezier(.34, 1.56, .64, 1) both;
}

@keyframes c-alert-pop {
  from {
    transform: scale(0.88);
    opacity: 0;
  }

  to {
    transform: scale(1);
    opacity: 1;
  }
}

#cart-alert-icon {
  font-size: 2rem;
  margin-bottom: 10px;
  line-height: 1;
}

#cart-alert-icon .bi-exclamation-circle-fill {
  color: var(--color-warning);
}

#cart-alert-icon .bi-check-circle-fill {
  color: var(--color-success);
}

#cart-alert-icon .bi-x-circle-fill {
  color: var(--color-danger);
}

#cart-alert-title {
  font-family: var(--font-primary);
  font-size: 1rem;
  font-weight: 700;
  color: var(--color-ink);
  margin: 0 0 6px;
}

#cart-alert-msg {
  font-family: var(--font-primary);
  font-size: 0.85rem;
  color: var(--text-muted);
  line-height: 1.5;
  margin: 0 0 20px;
}

#cart-alert-actions {
  display: flex;
  gap: 10px;
  justify-content: center;
}

#cart-alert-actions button {
  font-family: var(--font-primary);
  font-size: 0.85rem;
  font-weight: 600;
  padding: 10px 28px;
  border-radius: var(--radius-sm);
  border: none;
  cursor: pointer;
  transition: opacity 0.15s;
  background: var(--color-ink);
  color: var(--bg-color);
}

#cart-alert-actions button:hover {
  opacity: 0.85;
}

/* =========================================
   FOOTER COMPONENT
========================================= */
/* Black, like the header: the PP mark and the name, the shop's contact lines with an icon
   each, social links in outlined circles; Help and Shop as columns on a computer and
   folded (+) rows on a phone; the copyright line under it all. Contact and social come
   from Admin → Settings (js/app.js). */
.footer {
  --footer-bg: #050505;
  --footer-text: rgba(255, 255, 255, 0.68);
  --footer-strong: #fff;
  --footer-line: rgba(255, 255, 255, 0.12);
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  padding: 40px 20px 8px;
  background: var(--footer-bg);
  color: var(--footer-text);
}

@media (min-width: 769px) {
  .footer {
    grid-template-columns: minmax(260px, 1.5fr) 2fr;
    gap: 48px;
    padding: 64px 5% 40px;
  }
}

/* ── Brand ─────────────────────────────────────────────────────────────────── */
.footer-brand {
  padding-bottom: 28px;
  border-bottom: 1px solid var(--footer-line);
}

@media (min-width: 769px) {
  .footer-brand {
    padding-bottom: 0;
    border-bottom: none;
  }
}

.footer-logo {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 22px;
  color: var(--footer-strong);
  text-decoration: none;
}

.footer-mark {
  display: block;
  width: 44px;
  height: 44px;
  border-radius: 10px;
  box-shadow: 0 0 0 1px var(--footer-line);
}

.footer-wordmark {
  font-size: 1.25rem;
  font-weight: 800;
  letter-spacing: -0.03em;
  color: var(--footer-strong);
}

/* ── Contact lines ─────────────────────────────────────────────────────────── */
.footer-contact {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin: 0;
  padding: 0;
  font-size: 0.875rem;
  line-height: 1.5;
}

.footer-contact li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}

.footer-contact li > svg {
  flex-shrink: 0;
  margin-top: 2px;
  color: var(--footer-strong);
  opacity: 0.8;
}

.footer-contact .footer-contact-value {
  color: var(--footer-text);
  text-decoration: none;
  word-break: break-word;
  transition: color 0.2s ease;
}

.footer-contact a.footer-contact-value:hover {
  color: var(--footer-strong);
}

.footer-direction {
  margin-top: 2px;
  padding-left: 26px;   /* under the values, past the icons */
}

.footer-direction a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding-bottom: 2px;
  border-bottom: 1px solid currentColor;
  color: var(--footer-strong);
  font-size: 0.8125rem;
  font-weight: 600;
  text-decoration: none;
}

/* ── Social ────────────────────────────────────────────────────────────────── */
.footer-social {
  display: flex;
  gap: 10px;
  margin-top: 22px;
}

.footer-social:empty {
  display: none;
}

.footer-social a {
  width: 38px;
  height: 38px;
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--footer-strong);
  font-size: 1rem;
  text-decoration: none;
  transition: background 0.2s, color 0.2s, border-color 0.2s;
}

.footer-social a svg {
  width: 16px;
  height: 16px;
}

.footer-social a:hover {
  background: #fff;
  border-color: #fff;
  color: #050505;
}

/* ── Help / Shop: always open — two columns side by side on a phone too ────── */
.footer-columns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  padding: 26px 0;
  border-bottom: 1px solid var(--footer-line);
}

@media (min-width: 769px) {
  .footer-columns {
    gap: 48px;
    padding: 0;
    border-bottom: none;
  }
}

/* No Help links: the Shop column takes the row */
.footer-columns > [hidden] {
  display: none;
}

.footer h3 {
  margin: 0 0 14px;
  font-family: var(--font-primary);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--footer-strong);
}

@media (min-width: 769px) {
  .footer h3 {
    margin-bottom: 20px;
    font-size: 0.8125rem;
  }
}

.footer-links {
  list-style: none;
  margin: 0;
}

.footer-links li {
  margin-bottom: 12px;
}

.footer-links li:last-child {
  margin-bottom: 0;
}

.footer-links a {
  font-size: 0.875rem;
  color: var(--footer-text);
  text-decoration: none;
  transition: color 0.2s ease;
}

.footer-links a:hover {
  color: var(--footer-strong);
}

/* ── Copyright line ────────────────────────────────────────────────────────── */
.footer-bottom {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 22px 20px;
  background: #050505;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  font-size: 0.78rem;
  color: rgba(255, 255, 255, 0.5);
  text-align: center;
}

@media (min-width: 769px) {
  .footer-bottom {
    flex-direction: row;
    justify-content: space-between;
    padding: 20px 5%;
  }
}

/* The bottom bar covers the last 67px on a phone */
@media (max-width: 768px) {
  .footer-bottom {
    padding-bottom: 87px;
  }
}

/* =========================================
   GLOBAL PRODUCT GRID & CARDS
========================================= */
/* Posh Palace cards: white tiles with a soft shadow and rounded corners, the photo
   rounded inside them, set in a grid with real gutters (not edge to edge). */
.product-grid {
  display: grid;
  /* Mobile-first: 2 columns always */
  grid-template-columns: repeat(2, 1fr);
  gap: 14px 12px;
  padding: 0 14px 6px;
  background: var(--bg-color);
}

/* Desktop: fixed 4 columns */
@media (min-width: 769px) {
  .product-grid {
    grid-template-columns: repeat(4, 1fr);
    gap: 28px 24px;
    padding: 0 32px 8px;
  }
}

.product-card {
  display: flex;
  flex-direction: column;
  cursor: pointer;
  background: var(--bg-color);
  text-decoration: none;
  color: inherit;
  /* The old site: a thin grey outline, 12px corners and a soft drop shadow */
  border: 1px solid rgba(0, 0, 0, 0.14);
  border-radius: 12px;
  box-shadow: 0 8px 18px rgba(0, 0, 0, 0.08);
  transition: box-shadow 0.25s ease, transform 0.25s ease;
}

@media (hover: hover) {
  .product-card:hover {
    box-shadow: 0 14px 32px rgba(0, 0, 0, 0.11);
    transform: translateY(-2px);
  }
}

/* 3:4 — the shape the CDN crops card photos to (img-url.js), so nothing is cropped twice */
.product-image-wrapper {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  /* The photo fills the top of the card, its corners following the card's */
  border-radius: 11px 11px 0 0;
  background-color: var(--surface-muted);
}

.product-badges {
  position: absolute;
  /* Top right, where the old site put its "-27%" */
  top: 12px;
  right: 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: flex-end;
  z-index: 5;
}

.badge-promo {
  background: var(--color-ink);
  color: var(--bg-color);
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 1.5px;
  padding: 3px 8px;
  text-transform: uppercase;
}

/* Discount — the old site's white pill with heavy black figures */
.badge-discount {
  background: var(--bg-color);
  color: var(--color-ink);
  font-size: 0.7rem;
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: 0;
  padding: 5px 9px 4px;
  border-radius: var(--radius-pill);
  white-space: nowrap;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12);
}

/* The product's first tag. The Posh look shows no tag on a card (the old site's tags are
   category slugs); tags still feed search. */
.product-card .badge-tag {
  display: none;
}

.badge-tag {
  background: var(--bg-color);
  color: var(--color-ink);
  font-size: 0.65rem;
  font-weight: 600;
  letter-spacing: 1px;
  padding: 3px 8px;
  text-transform: uppercase;
  box-shadow: var(--shadow-sm);
}

.product-image-wrapper img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity 0.4s ease;
}

.product-image-wrapper .img-hover {
  position: absolute;
  top: 0;
  left: 0;
  opacity: 0;
}

/* Sold out: a round grey disc in the middle of the photo, as on the old site */
.badge-soldout {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 76px;
  height: 76px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  background: rgba(255, 255, 255, 0.94);
  color: var(--color-ink);
  font-size: 0.8rem;
  font-weight: 700;
  line-height: 1.15;
  text-transform: none;
  z-index: 2;
}

.badge-flash {
  position: absolute;
  top: 10px;
  left: 10px;
  background: var(--bg-color);
  color: var(--color-ink);
  padding: 4px 8px;
  font-size: 9px;
  font-weight: 500;
  text-transform: none;
  z-index: 2;
  box-shadow: var(--shadow-xs);
}

.add-icon {
  position: absolute;
  background: var(--bg-color);
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow-raised);
  color: var(--text-color);
  z-index: 10;
  cursor: pointer;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.add-icon i {
  font-size: 0.9rem;
}

.add-icon:hover {
  transform: scale(1.05);
  box-shadow: var(--shadow-md);
}

.add-icon {
  bottom: 10px;
  right: 10px;
}

@media (hover: hover) {
  .product-card:hover .img-default {
    opacity: 0;
  }

  .product-card:hover .img-hover {
    opacity: 1;
  }
}

.product-card-info {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  padding: 12px 12px 14px;
}

.product-title {
  font-size: 0.86rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--color-ink);
  margin-bottom: 6px;
  line-height: 1.35;
  /* Allowing multiple lines */
}

.product-price {
  font-size: 0.86rem;
  font-weight: 700;
  color: var(--color-ink-soft);
  margin-bottom: 0;
}

@media (min-width: 769px) {
  .product-card-info {
    padding: 14px 14px 16px;
  }

  .product-title {
    font-size: 0.92rem;
  }

  .product-price {
    font-size: 0.92rem;
  }
}

/* "Free delivery" under a card's price. Its own line because the price row is already
   two numbers wide on a phone, and a third thing on that line pushes the struck price
   out of sight. Same green as the panel's delivery line, so the badge on the image, the
   tag here and the line inside the offer panel read as one promise. */
.card-ship {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: -10px;
  margin-bottom: 12px;
  font-size: 0.7rem;
  font-weight: 600;
  color: #047857;
  line-height: 1.2;
}

.card-ship i {
  font-size: 0.74rem;
}

.product-colors {
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--price-strike);
}

/* =========================================
   MOBILE BOTTOM BAR
========================================= */
/* The old site's phone bar: white, a soft shadow above instead of a rule, 18px black
   icons over 12px semi-bold labels, the cart count in sale red. */
.mobile-bottom-bar {
  display: none;
  position: fixed;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 67px;
  background: var(--bg-color);
  box-shadow: 0 -4px 10px rgba(0, 0, 0, 0.08);
  z-index: 1000;
  padding: 7px 5px;
  align-items: stretch;
  justify-content: space-around;
  transition: transform 0.3s ease;
  /* scroll-hide animation */
}

/* Scroll-hide: hide on scroll-down, reveal on scroll-up */
.mobile-bottom-bar.nav-hidden {
  transform: translateY(100%);
}

.bottom-bar-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 9px;
  color: #000;
  text-decoration: none;
  flex: 1;
  height: 100%;
  padding: 0;
  /* Search and Cart are <button>s: strip the browser's button look */
  background: none;
  border: none;
  font: inherit;
  cursor: pointer;
  -webkit-appearance: none;
}

.bb-icon {
  display: block;
  flex-shrink: 0;
}

/* The 18px icons and the 22px bag and house sit on one baseline */
.bottom-bar-item > .bb-icon[width="18"] {
  margin: 2px 0;
}

.bottom-bar-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  line-height: 1;
  font-family: var(--font-primary);
  color: #000;
}

/* Keeps the count badge positioned against the icon only */
.bottom-bar-icon-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

@media (max-width: 768px) {
  .mobile-bottom-bar {
    display: flex;
  }
}

.nav-order {
  position: relative;
}

.cart-count-badge {
  position: absolute;
  top: 0px;
  right: -4px;
  background: var(--text-color);
  color: var(--bg-color);
  font-size: 0.65rem;
  font-weight: 600;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* The bottom bar's cart count is red, as on the old site */
.mobile-bottom-bar .cart-count-badge {
  background: var(--color-sale);
  color: #fff;
}

/* On the black header the counts turn white so they still stand out */
.topbar .cart-count-badge {
  background: #fff;
  color: var(--color-ink);
}

/* =========================================
   QUICK ADD TO CART — BOTTOM SHEET
========================================= */
.qa-overlay {
  position: fixed;
  inset: 0;
  background: var(--overlay-scrim);
  z-index: 3000;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease, visibility 0.3s ease;
}

.qa-overlay.active {
  opacity: 1;
  visibility: visible;
}

.qa-sheet {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: var(--bg-color);
  border-radius: 20px 20px 0 0;
  z-index: 3001;
  transform: translateY(105%);
  transition: transform 0.35s cubic-bezier(0.32, 0.72, 0, 1);
  max-height: 90vh;
  overflow-y: auto;
  box-shadow: var(--shadow-sheet);
}

.qa-sheet.active {
  transform: translateY(0);
}

.qa-drag-handle {
  width: 36px;
  height: 4px;
  background: var(--border-color);
  border-radius: 2px;
  margin: 12px auto 0;
}

.qa-header {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 20px;
  border-bottom: 1px solid var(--surface-alt);
}

.qa-product-img-wrap {
  flex-shrink: 0;
  width: 60px;
  height: 72px;
  border-radius: 8px;
  overflow: hidden;
  background: var(--surface-muted);
}

.qa-product-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.qa-product-meta {
  flex: 1;
  min-width: 0;
}

.qa-product-title {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--color-ink);
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.qa-product-price {
  font-size: 0.88rem;
  color: var(--gray-700);
  margin-top: 4px;
}

.qa-close-btn {
  flex-shrink: 0;
  background: none;
  border: none;
  font-size: 1.1rem;
  cursor: pointer;
  color: var(--gray-700);
  padding: 4px;
  line-height: 1;
}

.qa-section {
  padding: 16px 20px 0;
}

.qa-section-label {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gray-500);
  margin-bottom: 10px;
}

.qa-selected-value {
  font-weight: 500;
  text-transform: none;
  color: var(--color-ink);
  letter-spacing: 0;
}

.qa-swatches {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.qa-swatch {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 2px solid transparent;
  cursor: pointer;
  transition: transform 0.15s ease;
  outline: 2px solid transparent;
  outline-offset: 3px;
  flex-shrink: 0;
}

.qa-swatch.active {
  outline-color: var(--color-ink);
}

.qa-swatch:hover {
  transform: scale(1.12);
}

/* Size Guide beside the SIZE label in the ordinary quick-add sheet. */
/* The combo size-guide panel lives in components/cart.html, which every page injects,
   so its styles belong here too. Left only in a page stylesheet, the panel rendered as
   plain in-flow markup wherever that sheet was absent — taking up space inside
   #cart-container and pushing the page below it down. */
/* ── Size guide panel for the combo card ────────────────────────────────────
   Its own ids/classes, so the product page's existing #size-guide-panel is
   neither duplicated nor touched. Values copied from product.css. */
.combo-sg-overlay {
  position: fixed; top: 0; left: 0; right: 0; bottom: 0;
  background: var(--overlay-scrim, rgba(0,0,0,.45));
  z-index: 3100; opacity: 0; pointer-events: none; transition: opacity .3s;
}
.combo-sg-overlay.active { opacity: 1; pointer-events: auto; }

.combo-sg-panel {
  position: fixed; top: 0; right: -100%;
  width: 90vw; max-width: 400px; height: 100vh;
  background: var(--bg-color, #fff);
  z-index: 3101;
  transition: right .4s cubic-bezier(.77, 0, .175, 1);
  display: flex; flex-direction: column;
  box-shadow: var(--shadow-drawer, 0 0 40px rgba(0,0,0,.18));
  overflow: hidden;
}
.combo-sg-panel.active { right: 0; }

.combo-sg-header {
  display: flex; justify-content: space-between; align-items: center;
  padding: 20px 25px;
  border-bottom: 1px solid var(--border-light, #eee);
  font-size: 1rem; font-weight: 600; letter-spacing: 1px;
}
.combo-sg-close {
  background: none; border: none; font-size: 1.5rem; cursor: pointer;
  color: var(--text-strong, #111);
}
.combo-sg-content { flex: 1; overflow-y: auto; padding: 25px; }
.combo-sg-content .size-chart-image { width: 100%; height: auto; display: block; }
.combo-sg-content .size-chart-table { width: 100%; border-collapse: collapse; font-size: .85rem; }
.combo-sg-content .size-chart-table th,
.combo-sg-content .size-chart-table td {
  border: 1px solid var(--border-light, #eee); padding: 10px; text-align: center;
}
.combo-sg-content .size-chart-table th { background: var(--surface-subtle, #f7f7f7); font-weight: 600; }

.qa-size-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin-bottom: 10px;
}
.qa-size-head .qa-section-label { margin-bottom: 0; }
.qa-size-guide-link {
  background: none; border: 1.5px solid var(--border-color, #e4e4e7);
  border-radius: 2px; padding: 4px 10px; cursor: pointer;
  font-size: 0.72rem; font-weight: 600; letter-spacing: 0.04em;
  color: var(--text-strong, #111);
}
.qa-size-guide-link:hover { border-color: var(--text-color, #111); }

.qa-size-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.qa-size-btn {
  min-width: 44px;
  height: 36px;
  padding: 0 12px;
  border: 1.5px solid var(--gray-300);
  border-radius: 6px;
  background: var(--bg-color);
  font-size: 0.8rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.15s ease;
  color: var(--color-ink-soft);
}

.qa-size-btn:hover:not(:disabled) {
  border-color: var(--color-ink);
}

.qa-size-btn.active {
  background: var(--color-ink);
  color: var(--bg-color);
  border-color: var(--color-ink);
}

.qa-size-btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
  text-decoration: line-through;
}

.qa-qty-row {
  display: inline-flex;
  align-items: center;
  border: 1.5px solid var(--gray-300);
  height: 36px;
  border-radius: 6px;
  background: var(--bg-color);
}

.qa-qty-btn {
  background: transparent;
  border: none;
  width: 40px;
  height: 100%;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.1rem;
  color: var(--color-ink-soft);
  transition: background 0.15s ease;
}

.qa-qty-btn:hover {
  background: var(--surface-muted);
}

#qa-qty-display {
  font-size: 0.9rem;
  font-weight: 600;
  min-width: 36px;
  text-align: center;
  color: var(--color-ink);
}

.qa-add-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: calc(100% - 40px);
  margin: 20px 20px 20px;
  height: 48px;
  background: var(--color-ink);
  color: var(--bg-color);
  border: none;
  border-radius: 10px;
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.2s ease, transform 0.15s ease;
}

.qa-add-btn:hover {
  background: var(--text-strong);
}

.qa-add-btn:active {
  transform: scale(0.98);
}

.qa-add-btn:disabled {
  background: var(--gray-300);
  cursor: not-allowed;
  transform: none;
}

/* ═══════════════════════════════════════
   SEARCH OVERLAY
═══════════════════════════════════════ */
.search-overlay {
  position: fixed;
  inset: 0;
  background: var(--bg-color);
  z-index: 4000;
  transform: translateY(-100%);
  transition: transform 0.35s cubic-bezier(0.77, 0, 0.175, 1), visibility 0.35s;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  visibility: hidden;
}

.search-overlay.is-open {
  transform: translateY(0);
  visibility: visible;
}

.search-overlay-header {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 20px;
  border-bottom: 1px solid var(--border-light);
  position: sticky;
  top: 0;
  background: var(--bg-color);
  z-index: 1;
}

.search-input-wrapper {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 10px;
}

.search-input-icon {
  color: var(--gray-500);
  font-size: 0.9rem;
}

.search-input {
  flex: 1;
  border: none;
  outline: none;
  font-size: 1rem;
  color: var(--text-color);
  background: transparent;
  font-family: var(--font-primary);
}

.search-input::placeholder {
  color: var(--gray-400);
}

.search-close-btn {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 1.1rem;
  color: var(--text-color);
  padding: 4px;
  display: flex;
  align-items: center;
}

/* Recent searches */
.search-recents {
  padding: 16px 20px;
}

.search-recents-label {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--gray-500);
  margin-bottom: 10px;
}

.search-recent-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 0;
  cursor: pointer;
  color: var(--text-strong);
  font-size: 0.88rem;
  border-bottom: 1px solid var(--surface-muted);
}

.search-recent-item i {
  color: var(--gray-400);
  font-size: 0.85rem;
}

.search-recent-item:hover {
  color: var(--text-color);
}

/* Results */
.search-results {
  padding: 8px 0;
  flex: 1;
}

.search-result-item {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 20px;
  text-decoration: none;
  color: var(--text-color);
  border-bottom: 1px solid var(--surface-muted);
  transition: background 0.15s ease;
}

.search-result-item:hover {
  background: var(--surface-subtle);
}

.search-result-item.is-focused {
  background: var(--surface-muted);
}

.search-result-img {
  width: 52px;
  height: 64px;
  object-fit: cover;
  object-position: top;
  flex-shrink: 0;
  background: var(--surface-alt);
}

.search-result-info {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.search-result-name {
  font-size: 0.88rem;
  font-weight: 500;
}

.search-result-name mark {
  background: none;
  color: var(--text-color);
  font-weight: 700;
}

.search-result-price {
  font-size: 0.8rem;
  color: var(--text-muted);
}

.search-status {
  padding: 24px 20px;
  color: var(--gray-500);
  font-size: 0.85rem;
}

/* ── Cart shipping zone + switch ───────────────────────────────────────────────
   The estimate comes from an IP guess, so the label names the zone it assumed and
   offers the other one on the same line. Kept visually quiet: it is a correction,
   not a call to action, and must not compete with Proceed to Checkout. */
.cart-ship-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-wrap: nowrap;
}

.cart-ship-switch {
  padding: 3px 9px;
  background: var(--surface-muted, #f5f5f5);
  border: 1px solid var(--border-color, #e5e5e5);
  border-radius: 999px;
  font-family: inherit;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--gray-500);
  cursor: pointer;
  line-height: 1.4;
  white-space: nowrap;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.cart-ship-switch:hover {
  background: var(--text-color);
  border-color: var(--text-color);
  color: var(--bg-color);
}

/* "Bundle offer" lead-in — without it the badge reads as a bare price list and
   nobody realises it is an offer at all. */
.bundle-hint-label {
  display: inline-block;
  background: var(--text-color);
  color: var(--bg-color);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 3px;
  margin-right: 6px;
  vertical-align: 1px;
}

/* Cart line items link to their product page — customers open the cart to re-check
   what they picked, and flat text gave them no way back to the details. */
.cart-item-image {
  display: block;
}

.cart-item-title a {
  color: inherit;
  text-decoration: none;
}

.cart-item-title a:hover {
  text-decoration: underline;
}
/* Combo line badge in the cart drawer */
.combo-cart-badge {
  display: inline-block; margin-top: 4px;
  font-size: .62rem; font-weight: 700; letter-spacing: .5px;
  background: #111; color: #fff; padding: 2px 7px; border-radius: 999px;
}

/* =========================================
   CART DRAWER — POSH PALACE
   "Shopping Cart", photos with soft corners, the price in sale red under a struck
   original, a grey rounded quantity pill with a "Remove" link, and SAVE beside the
   subtotal.
========================================= */
.cart-header h2 {
  font-size: 1.25rem;
  font-weight: 500;
  letter-spacing: -0.01em;
}

.cart-count-paren {
  display: none;
}

.cart-item-image {
  width: 82px;
  border: none;
  border-radius: 8px;
  overflow: hidden;
}

.cart-item-title {
  font-size: 0.92rem;
  font-weight: 500;
}

.cart-item-price {
  font-size: 0.9rem;
  font-weight: 600;
}

.cart-item-now {
  color: var(--color-sale);
}

.cart-item .quantity-selector {
  border: none;
  background: #f2f2f2;
  border-radius: 6px;
  height: 34px;
  /* As wide as its three cells. product.css sizes the product page's own selector
     (136px on a computer), and that width reached the cart's too: a blank strip after +. */
  width: max-content;
}

.cart-item-remove.cart-item-remove-text {
  width: auto;
  height: auto;
  padding: 0;
  font-family: var(--font-primary);
  font-size: 0.8rem;
  color: var(--color-ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.cart-footer {
  background-color: var(--bg-color);
  border-top: 1px solid var(--border-light);
}

.cart-subtotal-wrap {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.cart-save {
  border: 1px solid var(--color-sale);
  color: var(--color-sale);
  font-size: 0.66rem;
  font-weight: 700;
  padding: 2px 6px;
  line-height: 1.3;
}

.cart-save[hidden] {
  display: none;
}

.btn-checkout {
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0;
  background-color: var(--color-ink);
  border-color: var(--color-ink);
}

/* Size on its own line, then the quantity pill and Remove */
.cart-item .cart-item-actions {
  grid-template-columns: auto auto 1fr;
  row-gap: 8px;
}

.cart-item .cart-item-size-left {
  grid-column: 1 / -1;
}

.cart-item .cart-item-size-left:empty {
  display: none;
}

/* =========================================
   HEADER AND COUNTS — the old site's measurements
   64px black bar, the menu lines on the left, the name centred, search and the bag on
   the right; counts as 18px discs (white on the header, red on the phone bar).
========================================= */
.topbar {
  background: #050505;
  padding: 0 22px;
}

.topbar-left {
  width: 66px;
}

.menu-btn {
  padding: 4px 0;
}

.topbar .logo {
  font-size: 1.15rem;
  font-weight: 700;
}

.topbar-right {
  width: 66px;
  gap: 18px;
}

.menu-btn,
.nav-search,
.nav-order,
.nav-profile {
  padding: 0;
}

.tb-icon {
  display: block;
}

.cart-count-badge {
  width: 18px;
  height: 18px;
  border-radius: 999px;
}

.topbar .cart-count-badge {
  top: -9px;
  right: -9px;
  font-size: 11px;
  font-weight: 800;
}

.mobile-bottom-bar .cart-count-badge {
  top: -7px;
  right: -10px;
  font-size: 10px;
  font-weight: 500;
}

@media (min-width: 1024px) {
  .topbar {
    padding: 0 32px;
  }

  .topbar .logo {
    font-size: 1.75rem;
    font-weight: 600;
  }

  .topbar-right {
    width: auto;
  }
}

/* Side menu account buttons: Account in black, Google sign-in outlined under it */
.btn-sidemenu-action.btn-sidemenu-account {
  background: var(--color-ink);
  border-color: var(--color-ink);
  color: #fff;
  border-radius: 0;
}

.btn-sidemenu-action.btn-sidemenu-account:hover {
  background: #2b2b2b;
  color: #fff;
}

.btn-sidemenu-action.btn-sidemenu-secondary {
  border-radius: 0;
  font-family: var(--font-primary);
}

/* Desktop header at the old site's sizes: 66px bar, a heavy tight wordmark and a small
   bold capitals menu (measured on poshpalacebd.com at 1440px) */
@media (min-width: 1024px) {
  :root {
    --topbar-h: 66px;
  }

  .topbar .logo {
    font-size: 1.375rem;
    font-weight: 800;
    letter-spacing: -0.045em;
  }

  .topbar-nav a {
    font-size: 0.59375rem;
    font-weight: 800;
    letter-spacing: 0.065em;
    text-transform: uppercase;
  }
}

/* Card name and prices at the old site's sizes: 11.5px names and 10.8px prices on
   phones, 13px and 12px on desktop; the struck price grey 600, the price black 900 */
.product-card .product-title {
  font-size: 0.71875rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: #111;
}

.product-price-was {
  margin-right: 4px;
  font-size: 0.675rem;
  font-weight: 600;
  color: #a0a0a0;
  text-decoration: line-through;
}

.product-card .product-price {
  font-size: 0.675rem;
  font-weight: 900;
  color: #000;
}

.product-card .badge-discount {
  font-size: 0.75rem;
}

@media (min-width: 769px) {
  .product-card .product-title {
    font-size: 0.8125rem;
  }

  .product-price-was,
  .product-card .product-price {
    font-size: 0.75rem;
  }

  .product-card .badge-discount {
    font-size: 0.875rem;
  }
}

/* The card corner: the product's own Badge Label (Admin → Product → Promotion Badge,
   e.g. NEW, HOT) and any offer ("2 FOR ৳1500"), both in the old site's white pill
   where its "-27%" used to sit. The Free Delivery pill keeps its own colours. */
.product-card .badge-promo {
  background: var(--bg-color);
  color: var(--color-ink);
  font-size: 0.75rem;
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: 0;
  padding: 5px 9px 4px;
  border-radius: var(--radius-pill);
  white-space: nowrap;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12);
}

@media (min-width: 769px) {
  .product-card .badge-promo {
    font-size: 0.875rem;
  }
}

/* ── Posh Palace look for the offer tab and panel ─────────────────────────────
   The panel came over from Cloco with Cloco's soft shapes: pills, rounded cards, a
   red button. Posh is square and black — Add to Cart, Buy Now and the size boxes have
   no rounding — so the panel follows the product page. Red stays where it carries
   meaning: the tab that says there is a sale, and the clock that says it is ending. */
.so-tab,
.so-tab.pp-tab {
  border-radius: 0;
}

.so-sheet {
  border-radius: 0;
}

@media (min-width: 720px) {
  .so-sheet {
    border-radius: 0;
  }
}

.so-sheet-grip {
  border-radius: 0;
}

.so-sheet-x {
  border-radius: 0;
  background: transparent;
  border: 1px solid rgba(5, 5, 5, 0.14);
}

#pp-sheet .so-sheet-badge {
  border-radius: 0;
  background: var(--color-ink, #111);
  color: #fff;
  letter-spacing: 0.1em;
}

#pp-sheet .so-sheet-head h3 {
  font-family: var(--font-heading, inherit);
  font-weight: 600;
  letter-spacing: 0;
}

#pp-sheet .pp-clock {
  border-radius: 0;
  background: #f7f6f2;
  border: 1px solid rgba(5, 5, 5, 0.08);
}

#pp-sheet .pp-unit {
  border-radius: 0;
  border-color: rgba(5, 5, 5, 0.12);
}

#pp-sheet .pp-unit strong {
  color: var(--color-sale, #d81e14);
}

.pp-block,
.pp-terms-btn,
.pp-terms {
  border-radius: 0;
}

.pp-block {
  border-color: rgba(5, 5, 5, 0.12);
}

.pp-tier,
.pp-tier b {
  border-radius: 0;
}

#pp-sheet .pp-tier b {
  background: var(--color-ink, #111);
}

/* The price list the shop writes into the offer. It is rich text, and the server's
   clean-up keeps bare tags only (no class), so rows are styled by tag:
     <li><b>3 shirts</b> <em>pay for 2, 1 FREE</em> <strong>৳2,180</strong></li>
   <i> is a quiet note ("৳895 each"); <em> picks the row out. */
#pp-sheet .pp-block-rich h4 {
  margin-bottom: 8px;
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

#pp-sheet .pp-block-rich ul {
  padding: 0;
  list-style: none;
}

#pp-sheet .pp-block-rich li {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 7px 0;
  border-top: 1px solid rgba(5, 5, 5, 0.08);
  line-height: 1.35;
}

#pp-sheet .pp-block-rich li:first-child {
  border-top: 0;
}

#pp-sheet .pp-block-rich li i,
#pp-sheet .pp-block-rich li em {
  flex: 1;
  font-size: 0.74rem;
  color: var(--text-muted, #767680);
}

#pp-sheet .pp-block-rich li em {
  font-style: normal;
  font-weight: 700;
  color: var(--color-sale, #d81e14);
}

#pp-sheet .pp-block-rich li strong {
  margin-left: auto;
  white-space: nowrap;
  color: var(--color-ink, #111);
}

#pp-sheet .pp-block-rich li:has(> em) {
  margin: 0 -14px;
  padding: 9px 14px;
  background: #fdf1ef;
  border-top-color: transparent;
}

#pp-sheet .pp-block-rich li:has(> em) + li {
  border-top-color: transparent;
}

#pp-sheet .pp-block-rich li:has(> em) strong {
  color: var(--color-sale, #d81e14);
}

/* The way out of the panel: black and square, like Add to Cart. */
#pp-sheet .so-sheet-close {
  border-radius: 0;
  background: var(--color-ink, #111);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.82rem;
}

#pp-sheet .so-sheet-close:hover {
  background: #333;
}
