/* ═══════════════════════════════════════════
   SheLoveShapeWear — Global Styles
   Brand: deep magenta + rich purple + warm black
   ═══════════════════════════════════════════ */

:root {
  --rose:        #b30039;
  --rose-light:  #e8557a;
  --rose-glow:   rgba(179,0,57,0.18);
  --purple:      #6d28d9;
  --purple-deep: #4c1d95;
  --purple-soft: rgba(109,40,217,0.12);
  --dark:        #0d0016;
  --dark2:       #140028;
  --cream:       #fff8f8;
  --gold:        #c9983a;
  --text-muted:  rgba(255,255,255,0.55);
  --card-bg:     rgba(255,255,255,0.04);
  --border:      rgba(255,255,255,0.08);
  --radius:      18px;
  --shadow:      0 8px 40px rgba(0,0,0,0.35);
  --glow-rose:   0 0 30px rgba(179,0,57,0.4), 0 0 60px rgba(179,0,57,0.15);
  --glow-purple: 0 0 30px rgba(109,40,217,0.5), 0 0 60px rgba(109,40,217,0.2);
}

/* ── Reset & Base ── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }

body {
  font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
  background: var(--dark);
  color: #f0e6ff;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  overflow-x: hidden;
}

main { flex: 1; }

a { color: var(--rose-light); text-decoration: none; transition: color .2s; }
a:hover { color: #fff; }

img { max-width: 100%; }

/* ── Scrollbar ── */
::-webkit-scrollbar { width: 6px; }
::-webkit-scrollbar-track { background: var(--dark2); }
::-webkit-scrollbar-thumb { background: var(--rose); border-radius: 3px; }

/* ══════════════════════════════
   NAVBAR
══════════════════════════════ */
.navbar {
  background: rgba(13,0,22,0.88) !important;
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-bottom: 1px solid var(--border);
  box-shadow: 0 4px 40px rgba(0,0,0,0.4) !important;
  z-index: 1050;
}

.brand-wrap {
  display: flex;
  align-items: center;
  font-weight: 900;
  font-size: 1.7rem;
  letter-spacing: 0.5px;
  white-space: nowrap;
  line-height: 1;
  text-decoration: none !important;
}

.brand-shelove  { color: #fff; position: relative; display: inline-block; }
.brand-shelove::after {
  content: "SheLove";
  position: absolute; left: 2px; top: 2px;
  color: var(--rose); z-index: -1;
}

.brand-shapewear { margin-left: 5px; color: #e0ccff; position: relative; display: inline-block; }
.brand-shapewear::after {
  content: "ShapeWear";
  position: absolute; left: 2px; top: 2px;
  color: var(--purple); z-index: -1;
}

.navbar-pill {
  background: rgba(25,8,50,0.5);
  color: #e0ccff !important;
  border-radius: 999px;
  padding: 7px 18px;
  font-weight: 600;
  font-size: .88rem;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1px solid rgba(124,58,237,0.3);
  transition: all .25s ease;
  text-decoration: none !important;
  white-space: nowrap;
  flex-shrink: 0;
  line-height: 1;
}

.navbar-pill:hover,
.navbar-pill.active-pill {
  background: linear-gradient(135deg, var(--purple), var(--purple-deep));
  color: #fff !important;
  box-shadow: var(--glow-purple);
  transform: translateY(-1px);
}

.btn-neon-small {
  background: linear-gradient(135deg, var(--rose), #8b1e5d);
  color: #fff !important;
  border-radius: 999px;
  padding: 7px 20px;
  font-weight: 700;
  font-size: .88rem;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: none;
  transition: all .25s ease;
  text-decoration: none !important;
  cursor: pointer;
  white-space: nowrap;
  flex-shrink: 0;
  line-height: 1;
}

.btn-neon-small:hover {
  box-shadow: var(--glow-rose);
  transform: translateY(-2px) scale(1.04);
  color: #fff !important;
}

/* ── Cart badge ── */
.cart-badge {
  background: #fff !important;
  color: var(--rose) !important;
  border: 2px solid var(--rose);
  font-size: .7rem !important;
  font-weight: 800 !important;
  min-width: 20px;
  height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* ── Dropdown ── */
.dropdown-menu {
  background: rgba(20,0,40,0.97);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  backdrop-filter: blur(20px);
  box-shadow: 0 20px 60px rgba(0,0,0,0.6);
  padding: 8px;
}
.dropdown-item {
  color: #e0ccff;
  border-radius: 10px;
  padding: 10px 16px;
  font-size: .9rem;
  transition: all .2s;
}
.dropdown-item:hover {
  background: var(--purple-soft);
  color: #fff;
}

/* ══════════════════════════════
   HERO SLIDER
══════════════════════════════ */
.hero-slider {
  position: relative;
  overflow: hidden;
}

.slider-container {
  width: 100%;
  overflow: hidden;
  position: relative;
}

.slider-wrapper {
  display: flex;
  transition: transform 0.7s cubic-bezier(0.25,0.46,0.45,0.94);
  will-change: transform;
}

/* Scoped to .slider-wrapper on purpose — do not loosen these back to a bare
   `.slide`.
   Bootstrap names its carousel `class="carousel slide"`, so a bare `.slide`
   selector matches EVERY Bootstrap carousel on the site, not just the hero.
   That leaked `brightness(0.55)` onto the home-page showcase image, where it
   compounded with .showcase-img's own filter — 0.55 x 0.9 = 0.495 — and
   rendered the product at roughly half brightness with a grey cast. The same
   class collision previously broke the hero slide COUNT in JS (a phantom 5th
   slide); this is the CSS half of the same bug.
   The 0.55 itself is correct and load-bearing: hero slides carry white text
   over the photo and need the contrast. Hero slides are always
   .slider-wrapper > .slide, so scoping keeps the hero identical while leaving
   carousels elsewhere untouched. */
.slider-wrapper > .slide {
  min-width: 100%;
  position: relative;
}

.slider-wrapper > .slide img {
  width: 100%;
  height: 65vh;
  object-fit: cover;
  display: block;
  /* 0.85, not the old 0.55.
     Text contrast here is handled by .glass-overlay, which lays a
     `linear-gradient(to top, rgba(13,0,22,.85), transparent)` scrim behind the
     copy, plus a text-shadow on the h3. That gradient is the load-bearing part
     and it is untouched. The flat 0.55 filter was a SECOND solution to the same
     problem, and unlike the gradient it dimmed the whole frame — including the
     top, where there is no text and where the garment actually is.
     On an apparel site the product photo is the sell; darkening it 45% to
     protect text that is already protected is a bad trade. A light 0.85 is kept
     so an over-exposed supplier shot still sits inside the dark palette. */
  filter: brightness(0.85);
}

.glass-overlay {
  position: absolute;
  bottom: 0; left: 0; right: 0;
  padding: 48px 64px;
  background: linear-gradient(to top, rgba(13,0,22,0.85) 0%, transparent 100%);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
}

.glass-overlay h3 {
  font-size: clamp(1.6rem, 4vw, 3rem);
  font-weight: 800;
  color: #fff;
  text-shadow: 0 2px 20px rgba(0,0,0,0.5);
  line-height: 1.1;
}

.glass-overlay p {
  font-size: clamp(.95rem, 2vw, 1.2rem);
  color: rgba(255,255,255,0.8);
  max-width: 500px;
}

.slider-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  background: rgba(255,255,255,0.1);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255,255,255,0.2);
  color: #fff;
  width: 36px; height: 36px;
  border-radius: 50%;
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: all .25s;
  z-index: 10;
}

.slider-nav.prev { left: 16px; }
.slider-nav.next { right: 16px; }
.slider-nav:hover {
  background: var(--rose);
  box-shadow: var(--glow-rose);
  border-color: transparent;
}

/* ══════════════════════════════
   TRUST STRIP
══════════════════════════════ */
.trust-strip {
  background: linear-gradient(90deg, #1a0030, #0d0016, #200040);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  padding: 15px 0;
  overflow: hidden;
  /* Fades the ends so items aren't clipped mid-word. Symmetric — no RTL variant. */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 70px, #000 calc(100% - 70px), transparent);
          mask-image: linear-gradient(90deg, transparent, #000 70px, #000 calc(100% - 70px), transparent);
}

.trust-marquee {
  display: flex;
  gap: 0;
  animation: marquee 28s linear infinite;
  white-space: nowrap;
  will-change: transform;       /* promote to its own GPU layer for smoother, jank-free scrolling */
  backface-visibility: hidden;
}
.trust-strip:hover .trust-marquee { animation-play-state: paused; }   /* pause so shoppers can read it */

.trust-item {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 0 34px;
  font-size: .84rem;
  font-weight: 600;
  /* Tight: wide tracking on small caps reads faint at any alpha. */
  letter-spacing: .07em;
  text-transform: uppercase;
  /* ~14:1. Scrolling text needs headroom over the 4.5:1 AA floor, but stays
     below the hero. */
  color: rgba(255,255,255,0.88);
  position: relative;
  flex-shrink: 0;
}

/* Short centred divider — a full-height rule reads as a table, not a series. */
.trust-item::after {
  content: '';
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 1px;
  height: 14px;
  background: rgba(255,255,255,0.16);
}

.trust-item .icon { font-size: 1.05rem; }

@keyframes marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* ── Accessibility: honour users who prefer reduced motion (WCAG 2.3.3) ── */
@media (prefers-reduced-motion: reduce) {
  .trust-marquee { animation: none !important; transform: none !important; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ══════════════════════════════
   SECTION HEADERS
══════════════════════════════ */
.section-eyebrow {
  font-size: .78rem;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--rose-light);
  font-weight: 600;
}

.section-title {
  font-size: clamp(2rem, 4vw, 3.2rem);
  font-weight: 800;
  line-height: 1.1;
  color: #fff;
}

.gradient-text {
  background: linear-gradient(135deg, #fff 0%, var(--rose-light) 50%, #c084fc 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

/* ══════════════════════════════
   CATEGORY GRID
══════════════════════════════ */
.category-grid {
  display: grid;
  grid-template-columns: 1.5fr 1fr 1fr;
  grid-template-rows: 240px 240px;
  /* The two rows above hold the tall tile plus four beside it. Tiles are data
     now, so switching one on in Admin can push the count past five; without
     this, the sixth lands in an implicit auto-height row and collapses. */
  grid-auto-rows: 240px;
  gap: 12px;
}

.category-card {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius);
  cursor: pointer;
  border: 1px solid var(--border);
  transition: opacity .6s ease;
}

/* A category waiting its turn. Hidden rather than left out of the page, so the
   rotation script can lift its content into a slot, and so a visitor with no
   JavaScript gets a full, square grid instead of a ragged extra row. */
.category-card--queued { display: none; }

/* The swap: fade out, change underneath, fade back in. Kept in step with the
   FADE constant in the rotation script on the home page. */
.category-card.is-swapping { opacity: 0; }

.category-card:first-child { grid-row: 1 / 3; }

.category-card img {
  width: 100%; height: 100%;
  object-fit: cover;
  /* Hover feedback, so it has to feel immediate. .6s read as lag. */
  transition: transform .25s ease;
  /* Same reasoning as the hero: .category-label already carries a 0.9 gradient
     scrim behind the text, so the tile label is safe. Raised 0.6 -> 0.85 so the
     category photography is actually visible. */
  filter: brightness(0.85);
}

/* Hover still darkens — that direction is the interaction cue and worth keeping
   — but from 0.85 to 0.7 rather than plunging to 0.45. */
.category-card:hover img { transform: scale(1.06); filter: brightness(0.7); }

.category-label {
  position: absolute;
  bottom: 0; left: 0; right: 0;
  padding: 28px 24px;
  background: linear-gradient(to top, rgba(13,0,22,0.9) 0%, transparent 100%);
}

.category-label h3 {
  font-size: 1.4rem;
  font-weight: 800;
  color: #fff;
  margin-bottom: 4px;
}

.category-card:first-child .category-label h3 { font-size: 2rem; }
/* Rendered as a filled pill, not bare text.
   These are badges — "BEST SELLER", "ALL-DAY COMFORT" — and they sit on
   supplier photography whose backdrop is unpredictable: the Shorts tile is
   near-white, Postpartum is dark. Coloured text on top of that is a losing
   game; it was washing out on the pale tiles at any rose we picked, and
   re-darkening the images to rescue it would undo the brightness fix.
   A filled chip removes the dependency entirely — white on a solid fill is
   legible over anything, reads as an intentional badge rather than a caption,
   and separates the eyebrow from the title so the hierarchy is clearer.
   The fill is PURPLE, not rose, on purpose: rose is the action colour on this
   site (Cart, Join Free, Shop Now, Add to Cart, prices). A descriptive label
   painted in the action colour competes with the buttons. Purple already means
   state/navigation here — the active nav pill — so it reads as information.
   Keep rose free for badges that ARE a call to action, e.g. stock or sale. */
.category-label span {
  display: inline-block;
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: #fff;
  /* Same treatment as the active nav pill (.navbar-pill.active-pill) so the
     badge reads as part of the same design language. */
  background: linear-gradient(135deg, var(--purple), var(--purple-deep));
  padding: 4px 10px;
  border-radius: 999px;
  margin-bottom: 8px;
  /* The purple glow is the Home-pill look; the second, tight dark shadow is
     added because this pill sits on photography rather than the dark navbar —
     without it the edge dissolves into a pale garment behind it. */
  box-shadow: var(--glow-purple), 0 2px 8px rgba(0,0,0,.35);
}

.category-hover-btn {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%,-50%) scale(0.8);
  opacity: 0;
  transition: all .3s ease;
  white-space: nowrap;
}

.category-card:hover .category-hover-btn {
  opacity: 1;
  transform: translate(-50%,-50%) scale(1);
}

/* ══════════════════════════════
   PRODUCT CARDS
══════════════════════════════ */
.product-card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  transition: all .3s ease;
  cursor: pointer;
  position: relative;
}

.product-card:hover {
  transform: translateY(-8px);
  border-color: rgba(179,0,57,0.4);
  box-shadow: 0 20px 60px rgba(0,0,0,0.5), 0 0 30px rgba(179,0,57,0.1);
}

.product-img-wrap {
  position: relative;
  overflow: hidden;
  aspect-ratio: 4/5;
  background: #1a0030;
}

.product-img-wrap img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform .55s ease;
  filter: brightness(0.92);
}

.product-card:hover .product-img-wrap img { transform: scale(1.07); filter: brightness(1); }

.product-badge {
  position: absolute;
  top: 12px; left: 12px;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  z-index: 2;
}

.badge-sale { background: var(--rose); color: #fff; }
.badge-new  { background: var(--purple); color: #fff; }
.badge-hot  { background: linear-gradient(135deg, #ff6b35, #f7c500); color: #000; }

.product-wishlist {
  position: absolute;
  top: 12px; right: 12px;
  width: 36px; height: 36px;
  border-radius: 50%;
  background: rgba(0,0,0,0.5);
  backdrop-filter: blur(8px);
  border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center;
  font-size: 1rem;
  cursor: pointer;
  opacity: 0;
  transition: all .25s;
  z-index: 2;
}

.product-card:hover .product-wishlist { opacity: 1; }
.product-wishlist:hover { background: var(--rose); border-color: var(--rose); }

.product-quick-add {
  position: absolute;
  bottom: 0; left: 0; right: 0;
  background: linear-gradient(135deg, var(--rose), #8b1e5d);
  color: #fff;
  border: none;
  padding: 14px;
  font-weight: 700;
  font-size: .85rem;
  letter-spacing: .08em;
  cursor: pointer;
  transform: translateY(100%);
  transition: transform .3s ease;
  text-transform: uppercase;
}

.product-card:hover .product-quick-add,
.product-card:focus-within .product-quick-add { transform: translateY(0); }

/* Touch devices have no hover, so a hover-only "Add to Cart" was permanently
   invisible on phones — where most of this store's traffic shops. Show it
   persistently wherever hover isn't available. */
@media (hover: none) {
  .product-quick-add { transform: translateY(0); }
  .product-wishlist  { opacity: 1; }
}

.product-info {
  padding: 18px 16px 20px;
}

.product-category {
  font-size: .72rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.4);
  margin-bottom: 6px;
}

.product-name {
  font-size: 1rem;
  font-weight: 700;
  color: #f0e6ff;
  margin-bottom: 10px;
  line-height: 1.3;
}

.product-stars {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 10px;
}

.stars { color: var(--gold); font-size: .85rem; letter-spacing: 1px; }
.review-count { font-size: .78rem; color: rgba(255,255,255,0.4); }

.product-colors { display: flex; gap: 5px; margin-bottom: 12px; }
.color-swatch {
  width: 14px; height: 14px;
  border-radius: 50%;
  border: 1.5px solid rgba(255,255,255,0.2);
  cursor: pointer;
  transition: transform .2s;
}
.color-swatch:hover { transform: scale(1.3); border-color: #fff; }

.product-price {
  display: flex;
  align-items: center;
  gap: 10px;
}

.price-now {
  font-size: 1.2rem;
  font-weight: 800;
  color: #fff;
}

.price-was {
  font-size: .9rem;
  text-decoration: line-through;
  color: rgba(255,255,255,0.35);
}

.price-save {
  font-size: .75rem;
  font-weight: 700;
  color: var(--rose-light);
  background: var(--rose-glow);
  padding: 2px 8px;
  border-radius: 999px;
}

/* ── Filter tabs ── */
.filter-tabs {
  display: flex;
  gap: 0;
  border: 1px solid var(--border);
  border-radius: 999px;
  overflow: hidden;
  padding: 4px;
  background: rgba(255,255,255,0.04);
}

.filter-tab {
  background: none;
  border: none;
  color: rgba(255,255,255,0.55);
  padding: 9px 22px;
  font-size: .82rem;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  cursor: pointer;
  border-radius: 999px;
  transition: all .2s;
  white-space: nowrap;
}

.filter-tab:hover { color: #fff; }

.filter-tab.active {
  background: linear-gradient(135deg, var(--rose), #8b1e5d);
  color: #fff;
  box-shadow: var(--glow-rose);
}

/* ══════════════════════════════
   SHOWCASE / FEATURE SECTION
══════════════════════════════ */
.showcase-section {
  background: linear-gradient(135deg, #1a0030, #0d0016, #200030);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

.showcase-img {
  width: 100%; height: 100%;
  min-height: 500px;
  object-fit: cover;
  border-radius: var(--radius);
  /* No brightness filter here.
     This used to carry `filter: brightness(0.9)`, which dimmed every showcase
     image to 90%. On a dark purple section that reads as murky rather than
     moody, and it fights the product photography — the whole point of the
     showcase is that the garment looks good. Supplier shots already vary in
     exposure; darkening all of them uniformly makes the dull ones worse.
     If a specific image is too bright, fix that image, not every image. */
}

.feature-list { list-style: none; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.feature-list li {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: .95rem;
  color: rgba(255,255,255,0.75);
}

.feature-list li::before {
  content: '';
  width: 22px; height: 2px;
  background: linear-gradient(to right, var(--rose), var(--purple));
  flex-shrink: 0;
  border-radius: 1px;
}

.price-display {
  font-size: 2.8rem;
  font-weight: 900;
  background: linear-gradient(135deg, #fff, var(--rose-light));
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.size-btn-group { display: flex; flex-wrap: wrap; gap: 8px; }

.size-btn {
  width: 44px; height: 44px;
  border-radius: 10px;
  border: 1.5px solid var(--border);
  background: rgba(255,255,255,0.05);
  color: rgba(255,255,255,0.6);
  font-size: .82rem;
  font-weight: 600;
  cursor: pointer;
  transition: all .2s;
  display: flex; align-items: center; justify-content: center;
}

.size-btn:hover, .size-btn.active {
  border-color: var(--rose);
  background: var(--rose-glow);
  color: #fff;
  box-shadow: 0 0 12px rgba(179,0,57,0.3);
}

/* ══════════════════════════════
   TESTIMONIALS
══════════════════════════════ */
.testimonial-card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 32px 28px;
  border-top: 3px solid var(--rose);
  transition: all .3s;
}

.testimonial-card:hover {
  transform: translateY(-4px);
  border-color: rgba(179,0,57,0.5);
  box-shadow: 0 12px 40px rgba(0,0,0,0.3);
}

.testimonial-stars { color: var(--gold); font-size: 1.1rem; letter-spacing: 2px; margin-bottom: 14px; }

.testimonial-text {
  font-size: 1rem;
  line-height: 1.7;
  color: rgba(255,255,255,0.8);
  font-style: italic;
  margin-bottom: 20px;
}

.testimonial-avatar {
  width: 44px; height: 44px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--rose), var(--purple));
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 1.1rem; color: #fff;
  flex-shrink: 0;
}

.testimonial-name { font-weight: 700; color: #fff; font-size: .95rem; }
.testimonial-location { font-size: .78rem; color: rgba(255,255,255,0.4); }

/* ══════════════════════════════
   NEWSLETTER
══════════════════════════════ */
.newsletter-section {
  background: linear-gradient(135deg, #1a003a, #0d0016, #300060);
  border-top: 1px solid var(--border);
  position: relative;
  overflow: hidden;
}

.newsletter-section::before {
  content: '';
  position: absolute;
  top: -50%; right: -10%;
  width: 500px; height: 500px;
  background: radial-gradient(circle, rgba(109,40,217,0.15) 0%, transparent 70%);
  border-radius: 50%;
  pointer-events: none;
}

.newsletter-input-wrap {
  display: flex;
  border-radius: 999px;
  overflow: hidden;
  border: 1.5px solid rgba(179,0,57,0.4);
  background: rgba(255,255,255,0.05);
  transition: border-color .2s;
}

.newsletter-input-wrap:focus-within {
  border-color: var(--rose);
  box-shadow: 0 0 0 3px var(--rose-glow);
}

.newsletter-input {
  flex: 1;
  background: none;
  border: none;
  padding: 16px 24px;
  color: #fff;
  font-size: .95rem;
  outline: none;
}

.newsletter-input::placeholder { color: rgba(255,255,255,0.3); }

.newsletter-btn {
  background: linear-gradient(135deg, var(--rose), #8b1e5d);
  color: #fff;
  border: none;
  padding: 16px 28px;
  font-weight: 700;
  font-size: .85rem;
  cursor: pointer;
  letter-spacing: .08em;
  text-transform: uppercase;
  transition: all .25s;
  border-radius: 0 999px 999px 0;
}

.newsletter-btn:hover {
  box-shadow: var(--glow-rose);
  filter: brightness(1.1);
}

/* ══════════════════════════════
   FEATURES ROW
══════════════════════════════ */
.features-row {
  background: rgba(255,255,255,0.02);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

.feature-item {
  padding: 40px 24px;
  text-align: center;
  border-right: 1px solid var(--border);
  transition: background .2s;
}

.feature-item:last-child { border-right: none; }
.feature-item:hover { background: rgba(179,0,57,0.04); }
.feature-icon { font-size: 2rem; margin-bottom: 14px; display: block; }
.feature-title { font-size: 1rem; font-weight: 700; color: #fff; margin-bottom: 6px; }
.feature-desc { font-size: .82rem; color: rgba(255,255,255,0.45); line-height: 1.6; }

/* ══════════════════════════════
   FOOTER
══════════════════════════════ */
footer {
  background: linear-gradient(135deg, #0a0018, #140028, #0f001f) !important;
  color: rgba(255,255,255,0.6) !important;
  padding: 64px 0 0 !important;
  border-top: 1px solid var(--border);
}

.footer-brand {
  font-size: 1.8rem;
  font-weight: 900;
  color: #fff;
}

.footer-tagline {
  font-size: .9rem;
  line-height: 1.7;
  color: rgba(255,255,255,0.4);
  max-width: 260px;
  margin-top: 12px;
}

.footer-heading {
  font-size: .78rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.35);
  margin-bottom: 18px;
  font-weight: 600;
}

.footer-links { list-style: none; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.footer-links a {
  color: rgba(255,255,255,0.55);
  font-size: .9rem;
  transition: color .2s;
  text-decoration: none;
}
.footer-links a:hover { color: var(--rose-light); }

.footer-bottom {
  margin-top: 48px;
  padding: 20px 0;
  border-top: 1px solid var(--border);
  font-size: .8rem;
  color: rgba(255,255,255,0.25);
}

.social-links { display: flex; gap: 12px; }
.social-link {
  width: 38px; height: 38px;
  border-radius: 10px;
  background: rgba(255,255,255,0.06);
  border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center;
  font-size: 1.1rem;
  transition: all .2s;
  text-decoration: none;
}
.social-link:hover {
  background: var(--rose);
  border-color: var(--rose);
  transform: translateY(-2px);
  box-shadow: var(--glow-rose);
}

/* ══════════════════════════════
   FORMS (Login, Register, etc.)
══════════════════════════════ */
.auth-card {
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--border);
  border-radius: 24px;
  padding: 48px 40px;
  max-width: 480px;
  margin: 0 auto;
  backdrop-filter: blur(12px);
  box-shadow: 0 24px 80px rgba(0,0,0,0.5);
}

.form-control, .form-select {
  background: rgba(255,255,255,0.06) !important;
  border: 1.5px solid var(--border) !important;
  color: #fff !important;
  border-radius: 12px !important;
  padding: 13px 18px !important;
  font-size: .95rem !important;
  transition: all .2s !important;
}

.form-control::placeholder { color: rgba(255,255,255,0.3) !important; }

.form-control:focus, .form-select:focus {
  border-color: var(--rose) !important;
  box-shadow: 0 0 0 3px var(--rose-glow) !important;
  background: rgba(255,255,255,0.09) !important;
}

.form-select option { background: #1a0030; color: #fff; }

.form-label {
  color: rgba(255,255,255,0.7);
  font-size: .85rem;
  font-weight: 600;
  margin-bottom: 6px;
}

.btn-primary-full {
  width: 100%;
  background: linear-gradient(135deg, var(--rose), #8b1e5d);
  border: none;
  border-radius: 999px;
  padding: 15px;
  font-weight: 800;
  font-size: 1rem;
  color: #fff;
  cursor: pointer;
  transition: all .25s;
  letter-spacing: .04em;
}

.btn-primary-full:hover {
  box-shadow: var(--glow-rose);
  transform: translateY(-2px);
  filter: brightness(1.1);
}

/* ══════════════════════════════
   CART & CHECKOUT
══════════════════════════════ */
.cart-item-card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  transition: all .3s;
}

.cart-item-card:hover {
  border-color: rgba(179,0,57,0.3);
  transform: translateY(-3px);
  box-shadow: 0 12px 40px rgba(0,0,0,0.3);
}

.cart-item-img {
  width: 140px;
  min-height: 160px;
  object-fit: cover;
  flex-shrink: 0;
}

.summary-card {
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 28px 24px;
  position: sticky;
  top: 100px;
}

.qty-selector {
  background: rgba(255,255,255,0.06) !important;
  border: 1px solid var(--border) !important;
  color: #fff !important;
  border-radius: 10px !important;
  padding: 8px 12px !important;
  width: auto !important;
  min-width: 80px;
}

/* ── Stripe card element ── */
#card-element {
  background: rgba(255,255,255,0.06) !important;
  border: 1.5px solid var(--border) !important;
  border-radius: 12px !important;
  padding: 18px !important;
  transition: border-color .2s;
}

#card-element.StripeElement--focus {
  border-color: var(--rose) !important;
  box-shadow: 0 0 0 3px var(--rose-glow) !important;
}

/* ══════════════════════════════
   ADMIN PANEL
══════════════════════════════ */
.admin-sidebar {
  width: 260px;
  background: rgba(255,255,255,0.03);
  border-right: 1px solid var(--border);
  min-height: calc(100vh - 72px);
  padding: 32px 16px;
  flex-shrink: 0;
}

.admin-nav-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border-radius: 12px;
  color: rgba(255,255,255,0.55);
  font-weight: 600;
  font-size: .9rem;
  text-decoration: none;
  transition: all .2s;
  margin-bottom: 4px;
}

.admin-nav-item:hover, .admin-nav-item.active {
  background: var(--rose-glow);
  color: #fff;
}

.admin-stat-card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 24px;
  transition: all .3s;
}

.admin-stat-card:hover {
  transform: translateY(-4px);
  border-color: rgba(179,0,57,0.3);
}

.admin-stat-val {
  font-size: 2.4rem;
  font-weight: 900;
  color: #fff;
  line-height: 1;
  margin-bottom: 6px;
}

.admin-stat-label {
  font-size: .8rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.4);
}

.data-table {
  width: 100%;
  border-collapse: collapse;
}

.data-table th {
  text-align: left;
  padding: 12px 16px;
  font-size: .78rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.4);
  border-bottom: 1px solid var(--border);
  font-weight: 600;
}

.data-table td {
  padding: 14px 16px;
  border-bottom: 1px solid rgba(255,255,255,0.04);
  font-size: .9rem;
  color: rgba(255,255,255,0.8);
  vertical-align: middle;
}

.data-table tr:hover td { background: rgba(255,255,255,0.02); }

.status-badge {
  padding: 4px 12px;
  border-radius: 999px;
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .08em;
}

.badge-pending   { background: rgba(249,168,37,0.15); color: #f9a825; }
.badge-shipped   { background: rgba(109,40,217,0.2);  color: #c084fc; }
.badge-delivered { background: rgba(22,163,74,0.15);  color: #4ade80; }
.badge-cancelled { background: rgba(179,0,57,0.15);   color: var(--rose-light); }

/* ══════════════════════════════
   PRODUCT DETAIL
══════════════════════════════ */
.breadcrumb-item a { color: var(--rose-light); }
.breadcrumb-item.active { color: rgba(255,255,255,0.5); }
.breadcrumb-separator { color: rgba(255,255,255,0.25); }

.product-detail-img {
  border-radius: var(--radius);
  width: 100%;
  object-fit: cover;
  cursor: zoom-in;
  transition: transform .3s;
}

.product-detail-img:hover { transform: scale(1.01); }

.thumbnail-strip {
  display: flex;
  gap: 10px;
  margin-top: 12px;
  /* A garment now carries up to six photos, which is wider than a phone. The
     strip scrolls on its own rather than making the whole page scroll sideways. */
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: thin;
  padding-bottom: 4px;
  -webkit-overflow-scrolling: touch;
}

.thumbnail {
  width: 80px; height: 80px;
  border-radius: 10px;
  object-fit: cover;
  border: 2px solid transparent;
  cursor: pointer;
  transition: all .2s;
  opacity: 0.65;
}

.thumbnail.active, .thumbnail:hover {
  border-color: var(--rose);
  opacity: 1;
  box-shadow: 0 0 12px var(--rose-glow);
}

/* ══════════════════════════════
   ALERTS & TOASTS
══════════════════════════════ */
.alert-success-custom {
  background: rgba(22,163,74,0.15);
  border: 1px solid rgba(74,222,128,0.3);
  border-radius: 12px;
  color: #4ade80;
  padding: 14px 20px;
}

.alert-error-custom {
  background: var(--rose-glow);
  border: 1px solid rgba(179,0,57,0.4);
  border-radius: 12px;
  color: var(--rose-light);
  padding: 14px 20px;
}

/* ══════════════════════════════
   PAGE OFFSET FOR FIXED NAV
══════════════════════════════ */
.page-offset { padding-top: 72px; }
.page-no-offset { padding-top: 0; }

/* ══════════════════════════════
   ANIMATIONS
══════════════════════════════ */
@keyframes fadeInUp {
  from { opacity: 0; transform: translateY(24px); }
  to   { opacity: 1; transform: translateY(0); }
}

.fade-in-up { animation: fadeInUp .5s ease both; }
.delay-1 { animation-delay: .1s; }
.delay-2 { animation-delay: .2s; }
.delay-3 { animation-delay: .3s; }

/* ══════════════════════════════
   RESPONSIVE
══════════════════════════════ */
@media (max-width: 991px) {
  .category-grid {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto;
    /* Explicit rows are auto here, so the implicit ones must be too, or the first
       tile sizes to its image while every tile below it sits at the desktop 240px. */
    grid-auto-rows: auto;
  }
  .category-card:first-child { grid-row: auto; grid-column: 1 / 3; }
  .glass-overlay { padding: 24px 32px; }
  .admin-sidebar { width: 220px; }
}

@media (max-width: 767px) {
  .category-grid { grid-template-columns: 1fr; }
  .category-card:first-child { grid-column: auto; }
  .filter-tabs { overflow-x: auto; padding-bottom: 4px; }
  .auth-card { padding: 32px 24px; }
  /* Scoped like the desktop rule — a bare `.slide img` also matches Bootstrap
     carousels (class="carousel slide"), which would force the showcase image
     to 45vh on mobile. .showcase-slide sets its own 320px height there. */
  .slider-wrapper > .slide img { height: 45vh; }
  .glass-overlay { padding: 20px 20px; }
  .admin-sidebar { display: none; }
  .newsletter-input-wrap { flex-direction: column; border-radius: 16px; }
  .newsletter-btn { border-radius: 0 0 16px 16px; }
}

@media (max-width: 480px) {
  .brand-wrap { font-size: 1.3rem; }
  .products-grid { grid-template-columns: repeat(2, 1fr) !important; gap: 12px; }
}

/* ══════════════════════════════
   ACCESSIBILITY (WCAG 2.1 AA)
══════════════════════════════ */

/* Skip-to-content link — hidden until keyboard-focused, then visible top-left */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100000;
  background: #b30039;
  color: #fff;
  padding: 12px 20px;
  font-weight: 700;
  text-decoration: none;
  border-radius: 0 0 10px 0;
}
.skip-link:focus { left: 0; }

/* SINGLE SOURCE OF TRUTH for keyboard focus.
   Purple (#7c3aed), matching the Home / Shop / Discover pills, replacing the
   previous yellow. Measured against the #0d0016 page background:
       #ffd166 -> 14.2:1   #c084fc -> 7.2:1   #e8557a (rose) -> 5.8:1
       #7c3aed -> 3.35:1 (passes)             #6d28d9 (--purple) -> 2.5:1 (FAILS)
   WCAG 1.4.11 requires 3:1 for focus indicators.

   #7c3aed rather than the exact nav-pill HOVER colour (--purple, #6d28d9): that
   shade measures 2.5:1 and fails outright — a focus ring nobody can see is not a
   focus ring, and keyboard users would lose track of where they are on the page.
   The two are ~5% apart in lightness and indistinguishable side by side, so this
   matches visually while staying above the floor. #7c3aed is already the pill's
   resting border colour, so it is the same purple, not an approximation.

   3.35:1 has little headroom. If this is ever changed again, re-measure before
   shipping — "looks visible on my monitor" is not the test.

   Rose was rejected for a different reason: it would compete visually with the
   rose hover borders on product cards, so focus and hover would be hard to tell
   apart.

   The !important that used to be here is GONE: it only existed to beat 13
   inline `outline:none` declarations in the markup, which have now been
   removed at source. Normal cascade is enough. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
/* BUGFIX: this was a bare [tabindex]:focus-visible, which also matched
   <main id="main-content" tabindex="-1"> in the layout. tabindex="-1" means
   "focusable by script, not by Tab" — it is a scroll/skip-link destination,
   not a control — but clicking anywhere inside it can still focus it, and the
   browser then drew the focus ring around the ENTIRE page content. What showed
   up was its top edge: a stray line across the top of the cart and checkout,
   right where the flash banner sits. Excluding -1 keeps the ring on real
   interactive controls only. */
[tabindex]:not([tabindex="-1"]):focus-visible,
.product-card:focus-visible,
.size-btn:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Belt and braces: the skip link still needs to move focus into <main>, and
   that must not paint an outline. */
#main-content:focus,
#main-content:focus-visible { outline: none; }

/* Screen-reader-only utility */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ── Pagination (shared _Pager partial: storefront + admin) ── */
.sls-pager {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  margin: 28px 0 6px;
}
.sls-page {
  min-width: 38px;
  height: 38px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 12px;
  border-radius: 10px;
  background: rgba(255,255,255,.05);
  border: 1px solid rgba(255,255,255,.12);
  color: #e0ccff;
  font-weight: 600;
  font-size: .85rem;
  text-decoration: none;
  transition: all .18s ease;
}
.sls-page:hover {
  border-color: rgba(232,85,122,.6);
  background: rgba(232,85,122,.1);
  color: #fff;
}
.sls-page-active {
  background: linear-gradient(135deg, #e8557a, #8b1e5d);
  border-color: transparent;
  color: #fff;
  cursor: default;
}
.sls-page-disabled {
  opacity: .35;
  cursor: default;
  pointer-events: none;
}
.sls-page-gap { color: rgba(255,255,255,.4); padding: 0 2px; }
.sls-pager-meta {
  text-align: center;
  color: rgba(255,255,255,.45);
  font-size: .78rem;
  margin-bottom: 10px;
}

/* ═══════════════════════════════════════════════════════════════
   DESIGN SYSTEM v2 — tokens, primitives & components
   Added in the premium redesign pass. Everything below is additive:
   no existing selector is redefined, so nothing above can regress.
   ═══════════════════════════════════════════════════════════════ */

:root {
  /* ── BUGFIX: --rose-l alias ────────────────────────────────────────
     30 places across 21 files write `var(--rose-l)`, but the variable is
     actually named `--rose-light`. An undefined custom property with no
     fallback is invalid at computed-value time, so `color: var(--rose-l)`
     silently INHERITED the parent colour instead of rendering brand pink —
     wishlist prices, admin "Edit →" links, coupon codes and delete buttons
     were all rendering in the wrong colour.
     Aliasing here fixes every occurrence at once and cannot regress
     anything: the only declarations it affects are ones that were broken.
     (The typo'd usages can be renamed later; this stops the bleeding now.) */
  --rose-l: #e8557a;

  /* Focus indicator — one token, used by every focusable element. */
  /* The nav-pill purple (#7c3aed — the same family as Home / Shop / Discover),
     NOT --purple (#6d28d9). The gradient shade measures 2.5:1 against the page
     background and fails the 3:1 WCAG minimum, so this is the brightest shade of
     that purple that still passes. See the contrast table above the focus rules. */
  --focus-ring: #7c3aed;

  /* ── Fluid type scale (clamp = no media queries, no layout jumps) ── */
  --fs-xs:    clamp(.72rem, .70rem + .10vw, .78rem);
  --fs-sm:    clamp(.82rem, .79rem + .15vw, .90rem);
  --fs-base:  clamp(.94rem, .90rem + .20vw, 1.02rem);
  --fs-md:    clamp(1.05rem, .99rem + .30vw, 1.20rem);
  --fs-lg:    clamp(1.30rem, 1.15rem + .70vw, 1.75rem);
  --fs-xl:    clamp(1.75rem, 1.40rem + 1.60vw, 2.75rem);
  --fs-2xl:   clamp(2.20rem, 1.60rem + 2.80vw, 4.00rem);

  /* ── Spacing scale ── */
  --sp-1: 4px;   --sp-2: 8px;   --sp-3: 12px;  --sp-4: 16px;
  --sp-5: 24px;  --sp-6: 32px;  --sp-7: 48px;  --sp-8: 64px;

  /* ── Radii ── */
  --radius-sm: 10px;
  --radius-md: 14px;
  --radius-lg: 18px;   /* mirrors legacy --radius */
  --radius-pill: 999px;

  /* ── Elevation tiers ── */
  --elev-1: 0 2px 10px rgba(0,0,0,.25);
  --elev-2: 0 8px 30px rgba(0,0,0,.35);
  --elev-3: 0 20px 60px rgba(0,0,0,.50);

  /* ── Glass tiers ── */
  --glass-1: rgba(255,255,255,.04);
  --glass-2: rgba(255,255,255,.07);
  --glass-brd: rgba(255,255,255,.12);

  /* ── Motion ── */
  --ease-out:  cubic-bezier(.22,.61,.36,1);
  --ease-soft: cubic-bezier(.4,0,.2,1);
  --dur-fast:  .18s;
  --dur-base:  .3s;
  --dur-slow:  .55s;

  /* ── Semantic text ── */
  --txt-hi:  #ffffff;
  --txt-mid: rgba(255,255,255,.72);
  --txt-lo:  rgba(255,255,255,.55);
  --txt-dim: rgba(255,255,255,.40);
  --ok:      #4ade80;
  --warn:    #fbbf24;
  --danger:  #f87171;
}

/* ── Text utilities (replace repeated inline colour/size styles) ── */
.t-hi   { color: var(--txt-hi); }
.t-mid  { color: var(--txt-mid); }
.t-lo   { color: var(--txt-lo); }
.t-dim  { color: var(--txt-dim); }
.t-ok   { color: var(--ok); }
.t-xs   { font-size: var(--fs-xs); }
.t-sm   { font-size: var(--fs-sm); }
.t-md   { font-size: var(--fs-md); }
.t-lg   { font-size: var(--fs-lg); }
.t-bold { font-weight: 700; }
.t-loose { line-height: 1.8; }

/* ── Surfaces ── */
.card-surface {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--sp-5);
}
.card-surface-lg { padding: var(--sp-6); }

.section-rule { border-top: 1px solid var(--border); }

/* ═══════════════════════════════
   PAGE TITLES — fixes the missing-h1 problem
   Visually identical to the old .glass-overlay h3 so the hero
   looks unchanged while the document outline becomes correct.
═══════════════════════════════ */
/* Product page title.
   Values match the inline style this replaced exactly (font-size:2rem,
   font-weight:800, color:#fff, line-height:1.2, margin-bottom:12px).
   Earlier this used the Syne display face and the --fs-xl scale, which made
   product names both a different typeface from the rest of the page AND up to
   37% larger — they swallowed the top of the product page. Restyling was never
   the goal here; the point was only to get the value out of a style attribute. */
.page-h1 {
  font-size: 2rem;
  font-weight: 800;
  color: #fff;
  line-height: 1.2;
  margin-bottom: 12px;
}
/* Hero headline.
   Scoped to .glass-overlay as well because slides 2+ render the title as a
   <p class="hero-h1"> (only slide 1 may be the <h1>), and the pre-existing
   `.glass-overlay p` rule has HIGHER specificity (0,1,1) than a bare
   `.hero-h1` (0,1,0) — without this it would shrink those titles to body
   size. Values below are copied from the old `.glass-overlay h3` so the hero
   renders pixel-identical to before. */
.hero-h1,
.glass-overlay .hero-h1 {
  font-size: clamp(1.6rem, 4vw, 3rem);
  font-weight: 800;
  color: #fff;
  text-shadow: 0 2px 20px rgba(0,0,0,0.5);
  line-height: 1.1;
  letter-spacing: -.01em;
  margin: 0;
  max-width: none;
  text-wrap: balance;
}

/* Fallback hero panel shown when no slider images exist in the DB. */
.hero-fallback {
  height: 65vh;
  min-height: 380px;
  background: linear-gradient(135deg, #1a003a, #0d0016, #300060);
}

/* ═══════════════════════════════
   ACCESSIBLE CARD LINK
   Replaces div[onclick] product cards. The <a> covers the whole card
   via ::after, so the card is clickable, focusable and announced as a
   single link — while nested forms stay clickable by sitting above it.
═══════════════════════════════ */
.card-link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
}
/* The nested wishlist/add-to-cart forms must sit ABOVE the .card-link::after
   overlay so they stay clickable.
   BUGFIX: this block used to also set `position: relative` on
   .product-quick-add and .product-wishlist. Both are `position: absolute` in
   their own rules, but `.product-card .product-quick-add` (specificity 0,2,0)
   beats `.product-quick-add` (0,1,0) — so it silently switched them back into
   normal flow. The quick-add button kept its `transform: translateY(100%)`,
   which then pushed it outside the overflow:hidden image wrapper: the
   "Add to Cart" button disappeared entirely and the heart moved off its corner.
   z-index alone is enough here, since both elements are already positioned. */
.product-card > .product-img-wrap form {
  position: relative;
  z-index: 2;
}
.product-card .product-quick-add,
.product-card .product-wishlist {
  z-index: 2;
}

/* Keyboard focus must be visible on the card, not just the link text. */
.product-card:focus-within {
  border-color: var(--focus-ring);
  box-shadow: 0 0 0 3px var(--focus-ring), var(--elev-3);
}

/* BUGFIX: a focus ring rendering as a stray bar across product images.
   Once the product NAME became a full-card link (.card-link), tapping a card left
   focus on that link — and because the <a> is display:block across the whole card,
   the a:focus-visible ring drew as a bar over the image edge, which is what showed
   up while scrolling on touch.
   The focus indicator is not lost: it moves to .product-card:focus-within, so
   WCAG 2.4.7 is still satisfied. */
.card-link:focus,
.card-link:focus-visible {
  /* The ring is drawn on the CARD (.product-card:focus-within) instead of on
     the link's own box, which spans the card and rendered as a stray bar over
     the image. No !important needed: .card-link:focus-visible (0,2,0) already
     outranks a:focus-visible (0,1,1). */
  outline: none;
}

/* Video parity with .product-img-wrap img (which already had these rules). */
.product-img-wrap video {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out);
  filter: brightness(.92);
}
.product-card:hover .product-img-wrap video { transform: scale(1.07); filter: brightness(1); }

/* ═══════════════════════════════
   MEDIA — kills layout shift
   aspect-ratio reserves the box before the file arrives, so CLS ≈ 0
   even when width/height attributes are unknown at render time.
═══════════════════════════════ */
.media-cover { width: 100%; height: 100%; object-fit: cover; display: block; }
.media-fill   { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.media-dim    { filter: brightness(.85); transition: transform .25s var(--ease-out); }

/* These two rules exist for SPECIFICITY, not for their values.
   .media-dim is (0,1,0) and `.category-card img` is (0,1,1), so without a
   matching-specificity rule here the tile's own selector wins and .media-dim is
   silently ignored — which is exactly the bug that produced two different
   category brightnesses in the first place.
   Keep these in step with `.category-card img` above. Both are now 0.85 rest /
   0.7 hover; if you change one, change the other or they diverge again. */
.category-card .media-dim { filter: brightness(.85); }
.category-card:hover .media-dim { transform: scale(1.06); filter: brightness(.7); }
.ratio-1-1 { aspect-ratio: 1 / 1; }
.ratio-4-5 { aspect-ratio: 4 / 5; }

/* ═══════════════════════════════
   PRODUCT DETAIL
═══════════════════════════════ */
.detail-media {
  width: 100%;
  aspect-ratio: 4 / 5;
  max-height: 620px;
  object-fit: cover;
  border-radius: var(--radius-lg);
  background: #1a0030;
  display: block;
}
.detail-price { font-size: var(--fs-xl); }
.detail-desc  { color: var(--txt-mid); line-height: 1.8; margin-bottom: var(--sp-6); }

.field-label {
  color: var(--txt-mid);
  font-size: var(--fs-sm);
  font-weight: 600;
  display: block;
  margin-bottom: var(--sp-2);
}

/* Colour swatch as a real <button> — keyboard operable (WCAG 2.1.1). */
.swatch-btn {
  width: 30px; height: 30px;
  border-radius: 50%;
  border: 2px solid rgba(255,255,255,.25);
  padding: 0;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease-out), border-color var(--dur-fast);
}
.swatch-btn:hover { transform: scale(1.12); }
.swatch-btn[aria-pressed="true"] {
  border-color: #fff;
  box-shadow: 0 0 0 3px rgba(232,85,122,.5);
}
.swatch-btn:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 3px;
}

/* Thumbnail as a real <button> wrapping the image. */
.thumb-btn {
  padding: 0; border: 2px solid transparent; background: none;
  border-radius: var(--radius-sm); cursor: pointer; line-height: 0;
  transition: border-color var(--dur-fast) var(--ease-out);
  /* Six thumbnails are 506px wide. Without this the flex row squashes them on a
     phone until every photo is an unreadable sliver — the strip scrolls instead.
     Never squash: the point of a thumbnail is that you can tell what it is. */
  flex: 0 0 auto;
}
.thumb-btn[aria-pressed="true"] { border-color: var(--rose-light); }
.thumb-btn:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 2px; }
.thumb-btn img { width: 76px; height: 95px; object-fit: cover; border-radius: 8px; display: block; }

/* Trust row under the buy box */
.trust-note { display: flex; flex-wrap: wrap; gap: var(--sp-5); padding-top: var(--sp-5); }
.trust-note span { color: var(--txt-lo); font-size: var(--fs-sm); }
.trust-note .tick { color: var(--ok); margin-right: 4px; }

/* ═══════════════════════════════
   REVIEWS
═══════════════════════════════ */
.review-card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--sp-4) 18px;
}
.review-head { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-3); }
.review-author { color: var(--txt-hi); font-weight: 600; }
.review-verified {
  color: var(--ok); font-size: .68rem;
  border: 1px solid rgba(74,222,128,.4);
  border-radius: 6px; padding: 1px 6px; white-space: nowrap;
}
.review-rating { color: #ffd166; font-size: .9rem; white-space: nowrap; }
.review-title { color: var(--txt-hi); font-weight: 600; margin-top: 6px; }
.review-body  { color: var(--txt-mid); font-size: .9rem; margin-top: 4px; }
.review-meta  { color: var(--txt-dim); font-size: var(--fs-xs); margin-top: var(--sp-2); }
.review-list  { max-width: 760px; }

.star-pick { font-size: 1.7rem; line-height: 1; color: #ffd166; display: inline-flex; }
.star-pick button {
  background: none; border: none; color: inherit; cursor: pointer;
  font-size: inherit; line-height: 1; padding: 0 2px;
}
.star-pick button:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 2px; border-radius: 4px; }

/* ═══════════════════════════════
   EMPTY / LOADING / ERROR STATES
═══════════════════════════════ */
.empty-state { text-align: center; padding: var(--sp-8) var(--sp-4); }
.empty-state-icon { font-size: 4rem; margin-bottom: var(--sp-4); line-height: 1; }
.empty-state h2, .empty-state h3 {
  color: var(--txt-mid); font-weight: 700;
  font-size: var(--fs-lg); margin-bottom: var(--sp-2);
}
.empty-state p { color: var(--txt-lo); margin-bottom: var(--sp-5); }

.is-loading { color: var(--txt-lo); }

/* Skeleton shimmer for async content (reviews, grids). */
.skeleton {
  background: linear-gradient(90deg, rgba(255,255,255,.04) 25%, rgba(255,255,255,.09) 37%, rgba(255,255,255,.04) 63%);
  background-size: 400% 100%;
  animation: sls-shimmer 1.4s ease infinite;
  border-radius: var(--radius-sm);
}
@keyframes sls-shimmer { from { background-position: 100% 50%; } to { background-position: 0 50%; } }

/* ═══════════════════════════════
   BREADCRUMB
═══════════════════════════════ */
.breadcrumb { background: none; padding: 0; }
.breadcrumb .active { color: var(--txt-lo); }

/* ═══════════════════════════════
   FOCUS — visible ring on every interactive element (WCAG 2.4.7)
═══════════════════════════════ */
/* (Focus styling lives in the single block further up — deliberately not
   duplicated here. A second focus rule in a different colour was the reason
   the site had two competing focus indicators.) */

/* ═══════════════════════════════
   TOUCH TARGETS — WCAG 2.5.8 (min 24px, 44px recommended)
═══════════════════════════════ */
@media (pointer: coarse) {
  .btn-neon-small, .navbar-pill, .size-btn, .filter-tab,
  .product-quick-add, .product-wishlist, .sls-page {
    min-height: 44px;
  }
  .swatch-btn { width: 36px; height: 36px; }
}

/* ═══════════════════════════════
   REDUCED MOTION — pause decorative autoplay video too
═══════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  .product-card:hover { transform: none; }
  .category-card:hover .media-dim { transform: none; }
  .skeleton { animation: none; }
}

/* ═══════════════════════════════
   PRINT — usable order/receipt printing
═══════════════════════════════ */
@media print {
  .navbar, .slider-nav, .trust-strip, .newsletter-section,
  footer, .product-quick-add, .product-wishlist, .skip-link { display: none !important; }
  body { background: #fff !important; color: #000 !important; }
  a { color: #000 !important; text-decoration: underline; }
}

/* ═══════════════════════════════
   CART & ORDER SUMMARY
═══════════════════════════════ */
.cart-empty-icon { filter: grayscale(1); opacity: .4; font-size: 5rem; }

.cart-item-title {
  color: var(--txt-hi);
  font-weight: 700;
  font-size: var(--fs-md);
  margin-bottom: 6px;
}
.cart-item-total {
  font-size: var(--fs-md);
  font-weight: 800;
  color: var(--txt-hi);
}

/* Text-only button (Remove, coupon Remove).
   Colour is rgba(255,255,255,.62) rather than the old .3/.55 mix: on the
   #0d0016 page background that clears the WCAG 1.4.3 4.5:1 threshold for
   small text, which .3 badly failed. */
.link-btn {
  background: none;
  border: none;
  padding: 0;
  font-size: var(--fs-sm);
  color: rgba(255,255,255,.62);
  cursor: pointer;
  text-decoration: underline;
  transition: color var(--dur-fast) var(--ease-out);
}
.link-btn:hover { color: var(--rose-light); }

.back-link {
  color: var(--rose-light);
  font-size: var(--fs-sm);
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
}

.summary-title {
  color: var(--txt-hi);
  font-weight: 700;
  font-size: var(--fs-md);
  margin-bottom: var(--sp-5);
}
.summary-block {
  border-top: 1px solid var(--border);
  padding-top: 20px;
  margin-top: var(--sp-2);
}
.summary-total-label { font-size: var(--fs-md); font-weight: 700; color: var(--txt-hi); }
.summary-total-value { font-size: var(--fs-lg); font-weight: 900; color: var(--txt-hi); }

/* Free-shipping nudge */
.ship-nudge {
  margin-top: var(--sp-2);
  background: rgba(179,0,57,.1);
  border-radius: var(--radius-sm);
  padding: var(--sp-2) var(--sp-3);
}
.ship-nudge-text { font-size: var(--fs-xs); color: var(--txt-lo); margin: 0; }
.ship-nudge-text strong { color: var(--rose-light); }
.ship-progress {
  height: 4px;
  background: rgba(255,255,255,.1);
  border-radius: 2px;
  margin-top: var(--sp-2);
  overflow: hidden;
}
.ship-progress-fill {
  height: 100%;
  background: linear-gradient(to right, var(--rose), var(--purple));
  border-radius: 2px;
  transition: width var(--dur-base) var(--ease-out);
}

/* Coupon */
.coupon-applied {
  background: rgba(74,222,128,.08);
  border: 1px solid rgba(74,222,128,.3);
  border-radius: var(--radius-sm);
  padding: var(--sp-3) 14px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--sp-3);
}
.coupon-code { color: var(--ok); font-weight: 700; font-size: var(--fs-sm); }
.coupon-input { flex: 1; text-transform: uppercase; }

/* Inline form feedback */
.form-msg { font-size: var(--fs-xs); margin-top: var(--sp-2); }
.form-msg-error { color: var(--danger); }
.form-msg-ok    { color: var(--ok); }

/* Full-width primary CTA (checkout button) */
.btn-block-lg {
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
  padding: var(--sp-3) var(--sp-5);
  border-radius: 12px;
}

/* ═══════════════════════════════
   CHECKOUT
═══════════════════════════════ */
.checkout-heading {
  color: var(--txt-hi);
  font-weight: 700;
  font-size: var(--fs-md);
  margin-bottom: 20px;
}
.checkout-heading-crypto { color: #c084fc; margin-bottom: 6px; }

.checkout-panel {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 28px;
  margin-bottom: 20px;
}

/* Payment method toggle */
.pay-toggle { display: flex; gap: 10px; margin-bottom: var(--sp-6); flex-wrap: wrap; }
.pay-option {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-5);
  border-radius: 12px;
  border: 2px solid rgba(255,255,255,.14);
  background: rgba(255,255,255,.03);
  /* .68 alpha clears 4.5:1 on the page background; the previous .5 did not. */
  color: rgba(255,255,255,.68);
  cursor: pointer;
  font-weight: 700;
  font-size: var(--fs-sm);
  transition: all var(--dur-fast) var(--ease-out);
}
.pay-option:hover { color: #fff; border-color: rgba(255,255,255,.3); }
.pay-option.is-active {
  border-color: var(--rose);
  background: rgba(179,0,57,.15);
  color: #fff;
}
#btnCrypto.is-active { border-color: #c084fc; background: rgba(192,132,252,.15); }

/* Crypto currency picker */
.js-crypto-pick {
  padding: 10px 18px;
  border-radius: var(--radius-sm);
  border: 2px solid rgba(255,255,255,.14);
  background: rgba(255,255,255,.03);
  color: rgba(255,255,255,.68);
  cursor: pointer;
  font-weight: 600;
  font-size: var(--fs-sm);
  transition: all var(--dur-fast) var(--ease-out);
  display: flex;
  align-items: center;
  gap: 6px;
}
.js-crypto-pick:hover { color: #fff; border-color: rgba(192,132,252,.5); }
.js-crypto-pick.is-active {
  border-color: #c084fc;
  background: rgba(192,132,252,.15);
  color: #fff;
}

/* Order-summary thumbnails */
.summary-thumb {
  width: 56px; height: 56px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  flex-shrink: 0;
}

.currency-select {
  background: rgba(255,255,255,.07);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: #fff;
  font-size: .8rem;
  padding: 6px 10px;
}

/* ── Native select dropdown lists ─────────────────────────────────────────
   The CLOSED control is styled by the rules above, but the OPEN option list is
   drawn by the operating system, which ignores CSS on the <select>. On Windows
   and Chrome that means a white panel with black text and a white scrollbar
   dropping out of a dark page.

   color-scheme is the actual fix: it tells the browser to draw its native
   widgets — the popup, the scrollbar inside it, the dropdown arrow — in dark
   mode. Styling `option` directly covers browsers that paint the list
   themselves.

   Applied to `select` generally rather than to each class, so the currency
   picker, the sort dropdown, the checkout country list, the quantity selectors
   and every admin dropdown are all covered and stay consistent.

   No effect on mobile, where the OS replaces the list with its own full-screen
   picker — that is expected and is why it looks right there already. */
select,
.currency-select,
.qty-selector,
.form-select {
  color-scheme: dark;
}

select option,
.currency-select option,
.qty-selector option,
.form-select option {
  background-color: #1a0a24;
  color: #fff;
}

/* NO colour on the selected row — deliberately.
   Both a purple and a rose version were tried and removed. The reason is that only
   HALF the highlight is stylable: `option:checked` takes a colour in Chrome, but the
   row under the cursor is drawn by the OS inside a native popup window and cannot be
   touched (it renders as Chrome's light blue). Firefox ignores option backgrounds
   altogether and draws its own grey either way.

   So colouring `:checked` produced a dropdown with a branded selected row and an
   unbrandable blue one moving next to it — two highlights in two unrelated colours,
   which looked more broken than leaving it alone. Consistent native highlighting is
   better than half-branded.

   The parts that ARE fully controllable stay branded: the closed control, its purple
   border, the dark panel and the option text above.

   The only way to brand the moving highlight is replacing <select> with a custom
   listbox — re-implementing keyboard navigation, type-ahead, Escape and ARIA by hand.
   That is real work and real bug surface in checkout, for something mobile shoppers
   never see, since phones substitute their own picker. Don't re-add a colour here
   without doing that first. */

.stripe-mark { opacity: .45; filter: invert(1); }

/* Utility completions referenced by the storefront markup. */
.t-base { font-size: var(--fs-base); }

/* Wrapper inside .product-img-wrap on the homepage featured grid. */
.product-img-inner { width: 100%; height: 100%; }
.product-img-inner img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out);
}

/* Showcase carousel media — fixed box so the carousel can't shift the page.
   (.showcase-img already sets object-fit further up; no need to repeat it.) */
.showcase-slide { height: 500px; object-fit: cover; }
@media (max-width: 767.98px) { .showcase-slide { height: 320px; } }

/* Showcase arrows — matched to the hero's .slider-nav.
   Bootstrap ships .carousel-control-* as a 15%-wide, FULL-HEIGHT invisible hit
   area holding a 2rem SVG chevron, at opacity .5. Next to the hero's 36px glass
   circle that reads as a different control on the same page. Every value below
   is copied from .slider-nav so the two stay identical.
   Done in CSS, not markup: the buttons keep their data-bs-target/data-bs-slide
   attributes, so Bootstrap's carousel JS is untouched. */
#showcaseSlider .carousel-control-prev,
#showcaseSlider .carousel-control-next {
  top: 50%;
  bottom: auto;                  /* Bootstrap stretches these top:0/bottom:0 */
  transform: translateY(-50%);
  width: 36px; height: 36px;
  padding: 0;
  border-radius: 50%;
  /* Same glass circle as .slider-nav, but filled DARK instead of light.
     .slider-nav uses rgba(255,255,255,.1) because hero photos sit at
     brightness(.85) and are mostly dark — a white glass disc reads fine there.
     Showcase shots are product photography on white backdrops, so the identical
     white-on-white disc all but disappears. Same size, same blur, same rose
     hover glow; only the fill is inverted so the control is actually visible. */
  background: rgba(13,0,22,0.45);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255,255,255,0.35);
  color: #fff;
  opacity: 1;                    /* Bootstrap dims to .5, then .9 on hover */
  transition: all .25s;
  z-index: 10;
}

#showcaseSlider .carousel-control-prev { left: 16px; }
#showcaseSlider .carousel-control-next { right: 16px; }

#showcaseSlider .carousel-control-prev:hover,
#showcaseSlider .carousel-control-next:hover,
#showcaseSlider .carousel-control-prev:focus-visible,
#showcaseSlider .carousel-control-next:focus-visible {
  background: var(--rose);
  box-shadow: var(--glow-rose);
  border-color: transparent;
  opacity: 1;
}

/* The chevron is a background-image SVG, 2rem by default — far too big for a
   36px circle. The disc already matches .slider-nav at 36px; what made the
   showcase arrow LOOK bigger was the glyph inside it. Bootstrap's SVG chevron
   is much heavier than the hero's thin ‹ › text characters, so it fills the
   circle and reads as a chunkier control even at identical dimensions.
   0.7rem brings the visual weight in line with the hero. */
#showcaseSlider .carousel-control-prev-icon,
#showcaseSlider .carousel-control-next-icon {
  width: .7rem; height: .7rem;
  background-size: 100% 100%;
}

/* ═══════════════════════════════
   WISHLIST
═══════════════════════════════ */
.page-section { background: var(--dark); min-height: 80vh; padding: 60px 0; }

.wish-img-wrap { aspect-ratio: 5 / 3; }
.wish-remove-form { position: absolute; top: 10px; right: 10px; margin: 0; z-index: 2; }
.wish-remove {
  width: 34px; height: 34px;
  border-radius: 50%;
  background: rgba(13,0,22,.8);
  border: 1px solid rgba(255,255,255,.18);
  color: var(--rose-light);
  cursor: pointer;
  font-size: 1rem;
  display: flex; align-items: center; justify-content: center;
  transition: all var(--dur-fast) var(--ease-out);
}
.wish-remove:hover { background: var(--rose); color: #fff; border-color: transparent; }
.wish-sale { top: 10px; left: 10px; right: auto; }

/* ═══════════════════════════════
   ORDER CONFIRMATION
═══════════════════════════════ */
.confirm-wrap { max-width: 640px; margin-inline: auto; }
.confirm-check {
  width: 100px; height: 100px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--rose), var(--purple));
  display: flex; align-items: center; justify-content: center;
  margin: 0 auto var(--sp-6);
  font-size: 2.8rem;
  color: #fff;
  box-shadow: var(--glow-rose);
}
.confirm-lede {
  color: var(--txt-mid);
  font-size: var(--fs-md);
  line-height: 1.8;
  margin: 20px 0 40px;
}
.confirm-step { padding: var(--sp-5); height: 100%; }
.confirm-step-icon  { font-size: 1.8rem; margin-bottom: var(--sp-2); line-height: 1; }
.confirm-step-title { font-weight: 700; color: var(--txt-hi); margin-bottom: 4px; }
.confirm-step-note  { font-size: var(--fs-sm); color: var(--txt-lo); }

/* Staggered reveal step 4 (delay-1..3 already existed). */
.delay-4 { animation-delay: .4s; }

/* ═══════════════════════════════
   AUTH PAGES (login / register / password reset)
═══════════════════════════════ */
.auth-shell {
  min-height: 70vh;
  display: flex;
  align-items: center;
}
.auth-emoji { font-size: 2.5rem; margin-bottom: var(--sp-3); line-height: 1; }
.auth-title {
  color: var(--txt-hi);
  font-weight: 800;
  font-size: var(--fs-lg);
  margin-bottom: 4px;
}
.auth-sub { color: var(--txt-lo); font-size: var(--fs-sm); }
.auth-highlight { color: #c084fc; }

/* One-time-passcode field: wide tracking makes 6 digits scannable. */
.otp-input {
  font-size: 1.5rem;
  letter-spacing: 8px;
  text-align: center;
  font-weight: 800;
}

.auth-link-btn {
  width: 100%;
  color: var(--txt-mid);
  font-size: var(--fs-sm);
  text-decoration: none;
}
.auth-link-btn:hover { color: var(--rose-light); }

.auth-badge {
  text-align: center;
  margin-top: var(--sp-4);
  color: var(--txt-lo);
  font-size: var(--fs-xs);
}

/* ═══════════════════════════════
   LAYOUT WIDGETS — replaces inline hover handlers
   Every rule here replaced an onmouseover/onmouseout pair that mutated
   element.style directly. CSS :hover also gives keyboard users :focus-visible
   parity and honours prefers-reduced-motion, which the JS version never did.
═══════════════════════════════ */

/* Language flag picker. The RESTING opacity differs per flag (the active
   language stays fully opaque), so it comes in as a --flag-rest custom
   property rather than needing a second class. */
.lang-flag {
  font-size: 1.3rem;
  text-decoration: none;
  opacity: var(--flag-rest, .4);
  transition: opacity var(--dur-fast) var(--ease-out);
}
.lang-flag:hover,
.lang-flag:focus-visible { opacity: 1; }

/* Floating action buttons (WhatsApp + chat toggle) */
.float-btn {
  position: fixed;
  right: 24px;
  border-radius: 50%;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}
.float-btn:hover,
.float-btn:focus-visible { transform: scale(1.1); }

.float-whatsapp {
  bottom: 100px;
  z-index: 9998;
  width: 52px; height: 52px;
  background: #25D366;
  box-shadow: 0 4px 20px rgba(37,211,102,.4);
  font-size: 1.4rem;
}

.chat-toggle {
  width: 60px; height: 60px;
  background: linear-gradient(135deg, #b30039, #6d28d9);
  box-shadow: 0 4px 20px rgba(179,0,57,.5);
  font-size: 1.6rem;
  position: relative;
}

/* Chat quick-reply chips */
.chat-chip {
  background: rgba(179,0,57,.15);
  border: 1px solid rgba(179,0,57,.4);
  color: var(--rose-light);
  padding: 5px 12px;
  border-radius: var(--radius-pill);
  font-size: .72rem;
  cursor: pointer;
  font-family: inherit;
  transition: all var(--dur-fast) var(--ease-out);
}
.chat-chip:hover,
.chat-chip:focus-visible {
  background: rgba(179,0,57,.35);
  box-shadow: 0 0 12px rgba(232,85,122,.5);
  color: #fff;
  transform: scale(1.05);
}

/* ═══════════════════════════════
   SEARCH SUGGESTIONS DROPDOWN
   (was inline styles inside an innerHTML template)
═══════════════════════════════ */
.sr-suggest {
  padding: 10px 14px;
  border-bottom: 1px solid rgba(255,255,255,.06);
  font-size: .75rem;
  color: var(--txt-lo);
}
.sr-item {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: 10px 14px;
  text-decoration: none;
  transition: background var(--dur-fast) var(--ease-out);
  border-bottom: 1px solid rgba(255,255,255,.04);
}
.sr-item:hover,
.sr-item:focus-visible { background: rgba(179,0,57,.1); }
.sr-thumb { width: 44px; height: 44px; object-fit: cover; border-radius: 8px; flex-shrink: 0; }
.sr-body { flex: 1; }
.sr-name { color: var(--txt-hi); font-size: var(--fs-sm); font-weight: 600; }
.sr-cat  { color: var(--txt-lo); font-size: .72rem; }
.sr-tag {
  font-size: .58rem; font-weight: 800;
  padding: 1px 6px; border-radius: 6px;
}
.sr-tag-sale { background: var(--rose); color: #fff; }
.sr-tag-new  { background: var(--ok);   color: var(--dark); }
.sr-price { text-align: right; white-space: nowrap; }
.sr-price-now { color: var(--rose-light); font-weight: 700; font-size: var(--fs-sm); }
.sr-price-was { color: var(--txt-dim); font-size: .72rem; }
.sr-all {
  display: block;
  padding: 10px 14px;
  text-align: center;
  color: var(--rose-light);
  font-size: .78rem;
  text-decoration: none;
  border-top: 1px solid rgba(255,255,255,.06);
}
.sr-all:hover { background: rgba(179,0,57,.1); }
.sr-empty { padding: var(--sp-4); color: var(--txt-lo); font-size: var(--fs-sm); }

/* ═══════════════════════════════
   GENERIC HOVER UTILITIES
   --hov-accent lets a Razor-computed colour drive the hover state without
   needing an inline event handler.
═══════════════════════════════ */
.hov-lift {
  transition: transform var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.hov-lift:hover {
  transform: translateY(-4px);
  border-color: var(--hov-accent, var(--rose-light));
}
.hov-lift-sm:hover { transform: translateY(-2px); border-color: var(--hov-accent, var(--rose-light)); }
.hov-tint { transition: background var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out); }
.hov-tint:hover {
  border-color: var(--hov-accent, var(--rose-light));
  background: rgba(255,255,255,.06);
}
.hov-row { transition: background var(--dur-fast) var(--ease-out); }
.hov-row:hover { background: rgba(255,255,255,.05); }

@media (prefers-reduced-motion: reduce) {
  .float-btn:hover, .chat-chip:hover, .hov-lift:hover, .hov-lift-sm:hover { transform: none; }
}

/* ═══════════════════════════════
   DATA-DRIVEN HOVER HOOKS
   Attribute selectors so a hover effect can be attached without inventing a
   class name per element. Each replaced an onmouseover/onmouseout pair.
═══════════════════════════════ */
[data-hov="scale"] { transition: transform var(--dur-base) var(--ease-out); }
[data-hov="scale"]:hover,
[data-hov="scale"]:focus-visible { transform: scale(1.1); }

[data-hov="row"] { transition: background var(--dur-fast) var(--ease-out); }
[data-hov="row"]:hover,
[data-hov="row"]:focus-visible { background: rgba(255,255,255,.05); }

@media (prefers-reduced-motion: reduce) {
  [data-hov="scale"]:hover { transform: none; }
}

/* ═══════════════════════════════
   VIP TIER CARDS
═══════════════════════════════ */
.vip-tier {
  background: var(--card-bg);
  border: 2px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 28px;
  text-align: center;
  position: relative;
  height: 100%;
}
.vip-tier.is-current {
  border-color: var(--tier-color, var(--rose-light));
  box-shadow: 0 0 30px color-mix(in srgb, var(--tier-color, #e8557a) 25%, transparent);
}

/* ═══════════════════════════════
   ADMIN TILES
═══════════════════════════════ */
.admin-quick {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: var(--sp-4);
  text-align: center;
  display: block;
  text-decoration: none;
}
.admin-agent {
  width: 100%;
  background: rgba(255,255,255,.03);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: var(--sp-4);
  text-align: center;
  cursor: pointer;
}
.tile-link {
  display: block;
  border-radius: 12px;
  padding: 14px;
  text-align: center;
  text-decoration: none;
  font-weight: 700;
  transition: background var(--dur-fast) var(--ease-out);
}
.tile-pink { background: rgba(244,114,182,.12); border: 1px solid rgba(244,114,182,.3); color: #f472b6; }
.tile-pink:hover { background: rgba(244,114,182,.22); color: #fff; }

.tile-btn {
  width: 100%;
  padding: 5px;
  border-radius: 8px;
  font-size: .72rem;
  cursor: pointer;
  font-family: inherit;
  transition: background var(--dur-fast) var(--ease-out);
}
.tile-purple { background: rgba(192,132,252,.15); border: 1px solid rgba(192,132,252,.3); color: #c084fc; }
.tile-purple:hover { background: rgba(192,132,252,.3); color: #fff; }

/* ═══════════════════════════════════════════════════════════════
   RIGHT-TO-LEFT (Arabic)
   The site offers Arabic but had no dir="rtl" handling at all, so the
   layout rendered mirrored-wrong for those readers. These rules flip the
   handful of places that are hard-coded to one side. Anything built with
   flexbox/grid + logical properties already flips automatically.
   ═══════════════════════════════════════════════════════════════ */
[dir="rtl"] {
  /* Physical left/right paddings that must swap. */
  --rtl: 1;
}

/* The divider is a ::after pinned right; in RTL it belongs on the other edge. */
[dir="rtl"] .trust-item::after { right: auto; left: 0; }

[dir="rtl"] .glass-overlay { align-items: flex-end; text-align: right; }

[dir="rtl"] .slider-nav.prev { left: auto; right: 16px; }
[dir="rtl"] .slider-nav.next { right: auto; left: 16px; }

[dir="rtl"] .product-wishlist  { right: auto; left: 12px; }
[dir="rtl"] .wish-remove-form  { right: auto; left: 10px; }
[dir="rtl"] .product-badge     { left: auto; right: 14px; }
[dir="rtl"] .wish-sale         { left: auto; right: 10px; }

[dir="rtl"] .float-btn { right: auto; left: 24px; }

[dir="rtl"] .category-label { text-align: right; }
[dir="rtl"] .summary-card,
[dir="rtl"] .card-surface   { text-align: right; }

[dir="rtl"] .skip-link { left: auto; right: 0; }

/* The marquee scrolls leftward; reverse it so it reads naturally in RTL. */
[dir="rtl"] .trust-marquee { animation-direction: reverse; }

/* Numbers, prices and codes stay LTR even inside RTL text. */
[dir="rtl"] .price-now,
[dir="rtl"] .price-was,
[dir="rtl"] .summary-total-value,
[dir="rtl"] .cart-item-total,
[dir="rtl"] .coupon-code,
[dir="rtl"] .otp-input { direction: ltr; unicode-bidi: embed; }

/* ═══════════════════════════════════════════════════════════════
   POLISH LAYER
   Everything below is ADDITIVE — new selectors and properties that
   nothing above already sets. That is deliberate: every regression in
   this refactor came from a new rule outranking an existing one.
   ═══════════════════════════════════════════════════════════════ */

/* ── Tell the browser this is a dark UI ───────────────────────────
   Without this, native widgets render in their LIGHT theme on a dark
   page: date pickers, select popups, spinners and — most visibly —
   Chrome's autofill, which paints a near-white background over your
   inputs the moment a saved address is offered. */
:root { color-scheme: dark; }

/* Chrome ignores background-color on autofilled inputs. The long inset
   shadow is the only reliable way to repaint them. */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
textarea:-webkit-autofill,
select:-webkit-autofill {
  -webkit-text-fill-color: #fff;
  -webkit-box-shadow: 0 0 0 1000px #1a0030 inset;
  caret-color: #fff;
  transition: background-color 9999s ease-out 0s;
}

/* ── Brand-coloured selection and form controls ───────────────── */
::selection { background: var(--rose); color: #fff; }

/* Checkboxes/radios were rendering in the browser default blue against
   a magenta/purple UI. One property fixes every one of them. */
input[type="checkbox"],
input[type="radio"],
progress,
input[type="range"] { accent-color: var(--rose-light); }

/* Firefox scrollbar (the existing rules are -webkit only, so Firefox
   users saw the default light scrollbar on a dark page). */
* { scrollbar-color: var(--rose) var(--dark2); scrollbar-width: thin; }

/* ── Anchor targets clear the fixed navbar ────────────────────────
   BUGFIX: .navbar is fixed-top and .page-offset reserves 72px, but any
   in-page anchor — including the "Skip to main content" link that
   targets #main-content — scrolled its target UNDERNEATH the header.
   The skip link appeared to work while hiding the very heading it was
   supposed to reveal, which defeats the purpose of WCAG 2.4.1.

   Scoped to :target and the known anchor destinations rather than a
   blanket [id] rule — scroll-margin-top also affects programmatic
   scrollIntoView(), and a site-wide value would silently change how
   every script-driven scroll lands. */
:target,
#main-content,
#reviewsSection,
#productGrid,
.section-title[id],
h1[id], h2[id], h3[id] { scroll-margin-top: 88px; }

/* ── Validation that waits its turn ───────────────────────────────
   :user-invalid (not :invalid) only matches AFTER the user has
   interacted and left the field. Plain :invalid would paint every
   empty required field red the instant checkout loads — which reads as
   "you did something wrong" before the shopper has typed anything. */
.form-control:user-invalid,
.form-select:user-invalid {
  border-color: var(--danger);
  box-shadow: 0 0 0 3px rgba(248,113,113,.18);
}
.form-control:user-valid,
.form-select:user-valid { border-color: rgba(74,222,128,.45); }

/* ── Typography niceties ──────────────────────────────────────────
   `pretty` prevents a single-word orphan on the last line of body copy;
   `balance` evens out multi-line headings. Both are ignored by browsers
   that don't support them, so there is no fallback to write. */
p, .detail-desc, .auth-sub, .confirm-lede { text-wrap: pretty; }
h1, h2, h3, .section-title, .page-h1 { text-wrap: balance; }

/* Prices and totals use tabular figures so digits occupy equal width —
   without this, columns of numbers visibly jitter as they change. */
.price-now, .price-was, .cart-item-total, .summary-total-value,
.detail-price, .admin-stat-val, .data-table td { font-variant-numeric: tabular-nums; }

/* ── Rendering performance on long catalogues ─────────────────────
   content-visibility lets the browser skip layout/paint for offscreen
   cards. contain-intrinsic-size supplies a placeholder height so the
   scrollbar stays stable instead of jumping as cards materialise. */
.product-grid-item,
.testimonial-card {
  content-visibility: auto;
  contain-intrinsic-size: auto 420px;
}

/* ── iOS safe areas ───────────────────────────────────────────────
   The floating chat/WhatsApp buttons sat under the home indicator on
   notched iPhones. */
@supports (padding: max(0px)) {
  .float-whatsapp { bottom: max(100px, calc(88px + env(safe-area-inset-bottom))); }
  .chat-toggle    { bottom: max(24px,  calc(12px + env(safe-area-inset-bottom))); }
  footer          { padding-bottom: max(0px, env(safe-area-inset-bottom)); }
}

/* ── Cross-document view transitions ──────────────────────────────
   Turns full page loads into a soft cross-fade in supporting browsers.
   Progressive: unsupported browsers simply navigate as before. */
@view-transition { navigation: auto; }

::view-transition-old(root) { animation: sls-fade-out .18s ease both; }
::view-transition-new(root) { animation: sls-fade-in  .22s ease both; }
@keyframes sls-fade-out { to   { opacity: 0; } }
@keyframes sls-fade-in  { from { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none; }
}

/* ── High-contrast preference ─────────────────────────────────────
   The glass aesthetic leans on very low-alpha borders. Users who ask
   for more contrast get solid ones. */
@media (prefers-contrast: more) {
  :root {
    --border:  rgba(255,255,255,.35);
    --txt-lo:  rgba(255,255,255,.8);
    --txt-dim: rgba(255,255,255,.7);
  }
  .product-card, .card-surface, .summary-card { border-width: 2px; }
}

/* ── Forced colours (Windows High Contrast) ───────────────────────
   Backgrounds are stripped in this mode, so glow/glass cues vanish;
   restore a real border so controls remain distinguishable. */
@media (forced-colors: active) {
  .btn-neon-small, .navbar-pill, .product-card, .filter-tab, .size-btn {
    border: 1px solid ButtonBorder;
  }
  .skip-link { border: 2px solid ButtonBorder; }
}

/* ── Product card: bottom-align the price row ─────────────────────
   OBSERVED IN BROWSER: cards in a row are equal height (.h-100), but the
   content inside was top-aligned, so a product whose name wraps to two
   lines pushed its price lower than its single-line neighbour — prices
   sat at three different heights across a row. Making the card a column
   and letting the price row take the leftover space pins every price to
   the same baseline.

   Additive: .product-card and .product-info previously set no display or
   margin, so nothing is overridden. */
.product-card { display: flex; flex-direction: column; }
.product-card .product-img-wrap { flex-shrink: 0; }
.product-info { display: flex; flex-direction: column; flex: 1 1 auto; }
.product-info .product-price { margin-top: auto; padding-top: 10px; }

/* Keep long names from pushing cards to wildly different content heights. */
.product-name {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Quick-add rendered as a link ("Choose Options") for products that have size
   or colour variants. .product-quick-add was written for a <button>, so an <a>
   needs the text centred and the underline removed to look identical. */
a.product-quick-add {
  display: block;
  text-align: center;
  text-decoration: none;
  color: #fff !important;
}

/* ═══════════════════════════════════════════════════════════════
   QUICK-ADD VARIANT PICKER
   Dialog shown when Add to Cart is pressed on a listing grid for a
   product with size or colour options. Built by site.js.
   ═══════════════════════════════════════════════════════════════ */
.vp-overlay {
  position: fixed;
  inset: 0;
  z-index: 10000;
  background: radial-gradient(120% 120% at 50% 0%, rgba(109,40,217,.28) 0%, rgba(5,0,12,.86) 60%);
  backdrop-filter: blur(10px) saturate(1.2);
  -webkit-backdrop-filter: blur(10px) saturate(1.2);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-4);
  animation: vp-fade .22s var(--ease-out) both;
}

.vp-panel {
  position: relative;
  width: min(440px, 100%);
  max-height: 90vh;
  overflow: auto;
  padding: var(--sp-6) var(--sp-6) var(--sp-5);
  border-radius: 22px;
  /* Layered fill: a soft rose/purple wash over deep glass. */
  background:
    radial-gradient(140% 90% at 0% 0%, rgba(179,0,57,.20) 0%, transparent 55%),
    radial-gradient(120% 90% at 100% 100%, rgba(109,40,217,.24) 0%, transparent 55%),
    rgba(20,0,38,.92);
  border: 1px solid rgba(255,255,255,.14);
  box-shadow:
    0 30px 80px rgba(0,0,0,.6),
    0 0 0 1px rgba(255,255,255,.04) inset,
    0 0 60px rgba(179,0,57,.18);
  animation: vp-rise .3s var(--ease-out) both;
}

/* Hairline gradient edge along the top of the panel. */
.vp-panel::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  border-radius: 22px 22px 0 0;
  background: linear-gradient(90deg, transparent, var(--rose-light), var(--purple), transparent);
  opacity: .9;
}

.vp-title {
  color: var(--txt-hi);
  font-size: var(--fs-md);
  font-weight: 800;
  line-height: 1.3;
  margin-bottom: 2px;
  letter-spacing: -.01em;
}
.vp-sub {
  color: var(--txt-lo);
  font-size: var(--fs-xs);
  letter-spacing: .18em;
  text-transform: uppercase;
  margin-bottom: var(--sp-5);
}

.vp-label {
  display: block;
  color: var(--txt-mid);
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  margin: var(--sp-5) 0 var(--sp-3);
}

.vp-row { display: flex; flex-wrap: wrap; gap: 10px; }

/* Size chips inside the picker — slightly larger tap targets than the
   inline ones on the product page. */
.vp-row .size-btn { min-width: 52px; padding: 10px 16px; border-radius: 12px; }
.vp-row .size-btn.active {
  box-shadow: 0 0 0 3px rgba(232,85,122,.35), 0 6px 20px rgba(179,0,57,.35);
}
.vp-row .swatch-btn { width: 34px; height: 34px; }

.vp-warn {
  color: var(--danger);
  font-size: var(--fs-sm);
  min-height: 1.25em;
  margin: var(--sp-4) 0 0;
}

.vp-actions {
  display: flex;
  gap: var(--sp-3);
  justify-content: flex-end;
  margin-top: var(--sp-5);
  padding-top: var(--sp-4);
  border-top: 1px solid rgba(255,255,255,.08);
}
.vp-actions .btn-neon-small { padding: 11px 26px; }
.vp-actions .navbar-pill    { padding: 11px 22px; }

@keyframes vp-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes vp-rise {
  from { opacity: 0; transform: translateY(14px) scale(.97); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .vp-overlay, .vp-panel { animation: none; }
  .vp-overlay { backdrop-filter: none; }
}

/* ═══════════════════════════════════════════════════════════════
   CART FLASH MESSAGE
   Confirmation / failure banner at the top of the cart. Success carries a
   Checkout shortcut so the shopper can act on it immediately instead of
   hunting for the button.
   ═══════════════════════════════════════════════════════════════ */
.cart-flash {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: 14px 18px;
  margin-bottom: var(--sp-5);
  border-radius: 14px;
  font-size: var(--fs-sm);
  font-weight: 600;
  border: 1px solid transparent;
  /* Slides down on arrival rather than snapping in. */
  animation: cart-flash-in .32s var(--ease-out) both;
}

.cart-flash-icon {
  flex: 0 0 auto;
  width: 24px; height: 24px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: .8rem;
  font-weight: 900;
}

.cart-flash-ok {
  color: #d7ffe9;
  background:
    linear-gradient(90deg, rgba(74,222,128,.16), rgba(74,222,128,.06));
  border-color: rgba(74,222,128,.34);
  box-shadow: 0 6px 26px rgba(74,222,128,.10);
}
.cart-flash-ok .cart-flash-icon { background: var(--ok); color: #06301a; }

.cart-flash-err {
  color: #ffdede;
  background:
    linear-gradient(90deg, rgba(248,113,113,.16), rgba(248,113,113,.06));
  border-color: rgba(248,113,113,.34);
  box-shadow: 0 6px 26px rgba(248,113,113,.10);
}
.cart-flash-err .cart-flash-icon { background: var(--danger); color: #3a0000; }

@keyframes cart-flash-in {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .cart-flash { animation: none; }
}

@media (max-width: 575.98px) {
  .cart-flash { flex-wrap: wrap; }
}


/* ══════════════════════════════════════════════════════════════════════════
   FIRST-VISIT REGION DIALOG
   Shown once, on the home page, before the shopper has chosen a country. Then
   never again — the flag in the header is the permanent control.

   A centred dialog rather than a bar: the question is asked at the entrance and
   answered once, and a strip pinned to every page repeats a question that has
   already been answered.
   ══════════════════════════════════════════════════════════════════════════ */
.region-modal {
    position: fixed;
    inset: 0;
    z-index: 3000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(6, 0, 14, .78);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    animation: region-modal-in .22s ease-out;
}

.region-modal-card {
    width: 100%;
    max-width: 440px;
    background: linear-gradient(160deg, #1a032e, #12001f);
    border: 1px solid rgba(192, 132, 252, .3);
    border-radius: 22px;
    padding: 34px 30px 30px;
    text-align: center;
    box-shadow: 0 30px 90px rgba(0, 0, 0, .65);
    font-family: 'DM Sans', system-ui, sans-serif;
    animation: region-card-in .26s cubic-bezier(.2, .9, .3, 1.1);
}

.region-modal-flagrow {
    display: flex;
    justify-content: center;
    gap: 10px;
    margin-bottom: 18px;
}

.region-modal-flagrow svg,
.region-modal-flagrow img { width: 34px; height: auto; border-radius: 4px; }

.region-modal-title {
    color: #fff;
    font-family: 'Cormorant Garamond', Georgia, serif;
    font-size: 1.72rem;
    font-weight: 400;
    margin: 0 0 10px;
}

.region-modal-text {
    color: rgba(255, 255, 255, .62);
    font-size: .9rem;
    line-height: 1.55;
    margin: 0 0 24px;
}

.region-modal-actions {
    display: flex;
    gap: 12px;
    justify-content: center;
    flex-wrap: wrap;
}

.region-modal-actions form { flex: 1 1 150px; }

.region-modal-btn {
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    background: rgba(255, 255, 255, .05);
    border: 1px solid rgba(255, 255, 255, .16);
    border-radius: 16px;
    padding: 18px 14px;
    color: #fff;
    font-family: inherit;
    font-size: .95rem;
    font-weight: 600;
    cursor: pointer;
    transition: background .16s ease, border-color .16s ease, transform .16s ease;
}

.region-modal-btn svg,
.region-modal-btn img { width: 30px; height: auto; border-radius: 3px; }

.region-modal-btn small {
    color: rgba(255, 255, 255, .5);
    font-size: .74rem;
    font-weight: 500;
    letter-spacing: .06em;
}

.region-modal-btn:hover,
.region-modal-btn:focus-visible {
    background: rgba(192, 132, 252, .18);
    border-color: rgba(192, 132, 252, .6);
    transform: translateY(-2px);
}

.region-modal-btn:focus-visible {
    outline: 3px solid var(--focus-ring);
    outline-offset: 2px;
}

@keyframes region-modal-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes region-card-in {
    from { opacity: 0; transform: translateY(14px) scale(.97); }
    to   { opacity: 1; transform: none; }
}

/* Respect a shopper who has asked the system for less movement. */
@media (prefers-reduced-motion: reduce) {
    .region-modal,
    .region-modal-card { animation: none; }
    .region-modal-btn:hover { transform: none; }
}

@media (max-width: 420px) {
    .region-modal-card    { padding: 28px 20px 24px; }
    .region-modal-title   { font-size: 1.45rem; }
    .region-modal-actions { flex-direction: column; }
}
}
