/* ==========================================================================
   Hizjaab — Homepage-only layout
   Shared pieces (nav, buttons, chips, cards, footer) live in components.css.
   ========================================================================== */

/* ---------- hero ---------- */
.hero{
  background:var(--surface-base);
  transition:background-color .25s ease;
  padding:64px 56px 96px;
  display:grid;
  grid-template-columns:1.1fr .9fr;
  gap:40px;
  align-items:center;
}
@media (max-width:1000px){
  .hero{grid-template-columns:1fr;padding:40px 24px 64px}
}
.hero-copy{position:relative}
.hero-title-outline{
  font-family:var(--font-display);
  font-weight:700;
  font-size:clamp(52px,8vw,104px);
  line-height:.92;
  color:transparent;
  -webkit-text-stroke:2px var(--taupe-400);
  margin:0;
}
.hero-title-italic{
  font-family:var(--font-display);
  font-style:italic;
  font-weight:600;
  font-size:clamp(32px,5vw,64px);
  color:var(--taupe-600);
  margin:-6px 0 0;
}
.hero-social{
  display:inline-flex;
  align-items:center;
  gap:14px;
  background:var(--pill-bg);
  border:1px solid var(--pill-border);
  border-radius:var(--radius-pill);
  padding:8px 18px 8px 8px;
  margin-top:36px;
}
.avatar-stack{display:flex}
.avatar-stack .img-slot{
  width:30px;height:30px;border-radius:50%;
  border:2px solid var(--surface-base);
}
.avatar-stack .img-slot + .img-slot{margin-left:-10px}
.hero-social-text{font-size:12px;color:var(--text-on-base-muted)}
.hero-social-text strong{color:var(--text-on-base-heading)}

.hero-desc{
  display:flex;
  align-items:center;
  gap:16px;
  margin-top:36px;
  max-width:320px;
}
.hero-desc p{
  font-size:14px;color:var(--text-on-base-muted);line-height:1.5;margin:0;
}

.hero-visual{position:relative}
.hero-model{
  border-radius:24px;
  width:100%;
  aspect-ratio:3/4;
}
.hero-product-card{
  position:absolute;
  left:-28px;
  bottom:-40px;
  width:230px;
  background:rgba(255,255,255,.35);
  backdrop-filter:blur(6px);
  border-radius:25px;
  box-shadow:var(--shadow-lg);
  padding:18px;
}
@media (max-width:1000px){
  .hero-product-card{position:static;margin-top:20px;width:100%}
}
.hero-product-card__head{
  display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:10px;
}
.hero-product-card__name{font-family:var(--font-display);font-size:15px;color:var(--text-primary)}
.hero-product-card__price{font-size:13px;color:var(--text-muted);margin-top:2px}
.hero-product-card .img-slot{width:100%;height:200px;border-radius:16px}
.hero-preview{
  position:absolute;
  right:0;
  top:0;
  width:150px;
  text-decoration:none;
  display:block;
}
@media (max-width:1000px){
  .hero-preview{display:none}
}
.hero-preview .img-slot{width:100%;height:110px;border-radius:16px}
.hero-preview-play{
  position:absolute;top:38px;left:58px;width:34px;height:34px;border-radius:50%;
  background:rgba(255,255,255,.9);border:none;
  display:flex;align-items:center;justify-content:center;cursor:pointer;
}
.hero-preview-play svg{width:14px;height:14px;color:var(--plum-900)}
.hero-preview-label{font-size:12px;color:var(--text-on-base-muted);text-align:center;margin-top:10px}

/* ---------- best categories ---------- */
.best-categories{padding:96px 56px;background:var(--cream-050)}
@media (max-width:900px){.best-categories{padding:56px 24px}}

/* Shared by .cat-shelf__auto-track (the desktop category-shelf loop) below -
   the earlier "Explore Our Best Categories" marquee that also used this
   keyframe was replaced with the manual-drag .cat-strip, but the keyframe
   itself is still live. */
@keyframes cat-marquee-scroll{
  from{transform:translateX(0)}
  to{transform:translateX(calc(-100% / var(--cat-marquee-copies)))}
}

/* ---------- category strip: full-bleed, infinite auto-scroll, drag/swipe-able ---------- */
/* Driven by JS (initCatStripAutoScroll in shared.js) advancing real
   scrollLeft on a loop rather than a CSS transform animation, specifically
   so touch/mouse drag on the SAME element works natively for free (a
   transform-based marquee can't be dragged without fighting the animation)
   and so the loop can never show a gap - it wraps scrollLeft by exactly one
   copy's width the instant it reaches it, and enough copies are rendered
   server-side that there's always more track to scroll into. */
.cat-strip{
  width:100vw;
  margin-left:calc(50% - 50vw);
  margin-right:calc(50% - 50vw);
  margin-top:40px;
  overflow-x:auto;
  overflow-y:hidden;
  cursor:grab;
  scrollbar-width:none;
  -webkit-overflow-scrolling:touch;
  mask-image:linear-gradient(90deg,transparent,#000 48px,#000 calc(100% - 48px),transparent);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 48px,#000 calc(100% - 48px),transparent);
}
.cat-strip::-webkit-scrollbar{display:none}
.cat-strip.is-dragging{cursor:grabbing}
.cat-strip.is-dragging .cat-strip__item{pointer-events:none}
.cat-strip__track{
  display:flex;gap:14px;width:max-content;padding:0 24px;
}
.cat-strip__item{
  position:relative;display:block;text-decoration:none;overflow:hidden;
  flex:0 0 128px;
  height:170px;
  border-radius:18px;
  background:var(--cream-100);
  box-shadow:0 8px 20px rgba(34,26,29,.10);
  transition:transform .25s ease,box-shadow .25s ease;
}
.cat-strip__item:hover,
.cat-strip__item:focus-visible{transform:translateY(-5px);box-shadow:0 14px 28px rgba(34,26,29,.16)}
.cat-strip__item .img-slot{width:100%;height:100%}
.cat-strip__item .img-slot img{width:100%;height:100%;object-fit:cover;padding:0}
/* Small pill label, always visible (a continuously-moving row can't rely on
   hover to be read in time) - modern "story rail" treatment rather than the
   old full-width gradient band. */
.cat-strip__caption{
  position:absolute;left:8px;right:8px;bottom:8px;
  padding:6px 10px;
  border-radius:var(--radius-pill);
  background:rgba(20,15,17,.55);
  backdrop-filter:blur(3px);
  color:#fff;font-family:var(--font-sans);font-size:10px;font-weight:600;
  letter-spacing:var(--tracking-wide);text-transform:uppercase;
  text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
@media (max-width:640px){
  .cat-strip__item{flex-basis:100px;height:134px;border-radius:14px}
  .cat-strip__track{padding:0 20px;gap:10px}
  .cat-strip__caption{font-size:9px;padding:5px 8px}
}
@media (prefers-reduced-motion: reduce){
  .cat-strip{overflow-x:auto;mask-image:none;-webkit-mask-image:none}
  .cat-strip__track{animation:none}
}
/* ---------- dark collections + new arrivals ---------- */
.dark-section{background:var(--surface-inverse);transition:background-color .25s ease;padding:88px 56px 0}
@media (max-width:900px){.dark-section{padding:56px 24px 0}}
.new-arrivals{padding-bottom:88px}

/* ---------- category shelves (one horizontal product strip per category) ---------- */
.cat-shelves{padding:24px 0 72px}
/* Unlike .best-categories/.why-section (deliberately fixed pale bands, see
   theme.css's comment), .cat-shelves sets no background of its own - it
   inherits the page's own theme-swapping surface. .section-head__title/
   __lede are styled for those fixed pale bands (a constant dark ink), so on
   this section they read correctly in light mode but turn dark-on-dark and
   vanish in dark mode. Overriding to the theme-aware --text-on-base-* tokens
   here (which flip together with --surface-page in theme.css) fixes both
   directions instead of just re-fixing one color for one theme. */
.cat-shelves .section-head__title{color:var(--text-on-base-heading)}
.cat-shelves .section-head__lede{color:var(--text-on-base-muted)}
.cat-shelf ~ .cat-shelf{margin-top:48px}
.cat-shelf__head{display:flex;align-items:baseline;justify-content:space-between;gap:16px;margin-bottom:18px}
.cat-shelf__head h2{font-family:var(--font-display);font-size:24px;color:var(--text-primary);margin:0}
.cat-shelf__track{
  display:flex;gap:16px;overflow-x:auto;scroll-snap-type:x proximity;
  -webkit-overflow-scrolling:touch;scrollbar-width:none;margin:0 -20px;padding:2px 20px 10px;
}
.cat-shelf__track::-webkit-scrollbar{display:none}
.cat-shelf__item{flex:0 0 220px;scroll-snap-align:start}
@media (max-width:640px){
  .cat-shelf__item{flex-basis:62vw}
  .cat-shelf__head h2{font-size:19px}
}

/* Desktop: an always-running loop instead of a manual-scroll track, so the
   shelf never sits at its scrolled-to-the-end state showing empty space.
   .cat-shelf__track (the mobile swipe version above) and .cat-shelf__auto
   are two separate renders of the same products - only one is ever visible,
   swapped at the breakpoint - so neither markup has to serve both a
   swipe-snap and an animated layout at once. */
.cat-shelf__auto{display:none}
@media (min-width:900px){
  .cat-shelf__track{display:none}
  .cat-shelf__auto{
    display:block;position:relative;overflow:hidden;
    mask-image:linear-gradient(90deg,transparent,#000 28px,#000 calc(100% - 28px),transparent);
    -webkit-mask-image:linear-gradient(90deg,transparent,#000 28px,#000 calc(100% - 28px),transparent);
  }
  .cat-shelf__auto-track{
    display:flex;gap:16px;width:max-content;
    --cat-marquee-copies:2;
    animation-name:cat-marquee-scroll;
    animation-duration:calc(var(--cat-marquee-copies) * 7s);
    animation-timing-function:linear;
    animation-iteration-count:infinite;
  }
  .cat-shelf__auto:hover .cat-shelf__auto-track,
  .cat-shelf__auto:focus-within .cat-shelf__auto-track{animation-play-state:paused}
  .cat-shelf__auto-track .cat-shelf__item{flex:0 0 220px}
  .cat-shelf__auto-track .cat-shelf__item[aria-hidden="true"]{pointer-events:none}
}
@media (prefers-reduced-motion: reduce){
  .cat-shelf__auto-track{animation:none}
  .cat-shelf__auto{overflow-x:auto}
}
.new-arrivals-head{margin:72px 0 44px}

/* ---------- why hizjaab ---------- */
.why-section{background:var(--cream-100);padding:80px 56px}
@media (max-width:900px){.why-section{padding:56px 24px}}
.why-eyebrow{
  font-size:11px;letter-spacing:var(--tracking-wider);text-transform:uppercase;color:var(--text-muted);
  margin-bottom:14px;
}
.why-head{display:flex;justify-content:space-between;align-items:flex-start}
.why-head h2{font-family:var(--font-display);font-weight:700;font-size:48px;color:var(--text-primary);margin:0}
.why-head .num{font-family:var(--font-display);font-size:52px;color:var(--umber-600)}
.why-hr{border-top:1px solid var(--border-hairline);margin:28px 0 0}
.why-grid{display:grid;grid-template-columns:1.6fr 1fr 1fr}
@media (max-width:900px){.why-grid{grid-template-columns:1fr;gap:40px}}
.why-col{padding:28px 32px 48px 0;position:relative}
.why-col + .why-col{border-left:1px solid var(--border-hairline);padding-left:32px}
@media (max-width:900px){.why-col + .why-col{border-left:none;padding-left:0}}
.why-col h3{font-family:var(--font-display);font-size:22px;color:var(--text-primary);margin:0 0 10px}
.why-col p{font-size:14px;color:var(--text-muted);line-height:1.5;margin:0 0 24px}
.why-col .num{
  font-family:var(--font-display);font-size:32px;color:var(--umber-600);
  position:absolute;right:0;bottom:16px;
}
.why-col--fabric{display:grid;grid-template-columns:1fr 1fr;gap:24px;align-items:start}
.why-col--fabric .num{right:32px}
@media (max-width:900px){
  /* At 900px .why-grid already stacks the three columns full-width, but
     .why-col--fabric kept its own internal 2-column split - on a phone that
     squeezed the fabric photo into a narrow strip and forced its fixed
     180px height into a tall, distorted sliver. Stack text above image
     here instead. */
  .why-col--fabric{grid-template-columns:1fr}
  .fabric-swatch{height:220px}
}
.fabric-icons{display:flex;gap:20px}
.fabric-icons > div{text-align:center}
.fabric-icons .ring{
  width:52px;height:52px;border:1px solid var(--border-subtle);border-radius:50%;
  display:flex;align-items:center;justify-content:center;margin:0 auto 8px;
}
.fabric-icons .ring svg{width:20px;height:20px;color:var(--umber-600)}
.fabric-icons span{font-size:11px;color:var(--text-muted)}
.fabric-swatch{width:100%;height:180px;border-radius:var(--radius-sm)}

.stress-test{position:relative;width:150px;height:100px;margin:0 auto}
.stress-test svg{position:absolute;width:18px;height:18px;color:var(--umber-600)}
.stress-test .label{
  position:absolute;top:38px;left:0;right:0;text-align:center;font-size:12px;font-weight:700;
  letter-spacing:var(--tracking-wider);color:var(--text-primary);
}

/* ---------- loyalty club ---------- */
.loyalty{
  background:var(--surface-inverse);transition:background-color .25s ease;
  padding:88px 56px;position:relative;overflow:hidden;
}
@media (max-width:900px){.loyalty{padding:56px 24px}}
.loyalty::before, .loyalty::after{
  content:"";position:absolute;border:1px solid var(--hairline-on-base-soft);border-radius:50%;
}
.loyalty::before{left:-120px;top:-80px;width:340px;height:340px}
.loyalty::after{left:-40px;top:20px;width:220px;height:220px}
.loyalty-grid{
  display:grid;grid-template-columns:1fr 1.4fr;gap:48px;align-items:center;position:relative;z-index:1;
}
@media (max-width:800px){.loyalty-grid{grid-template-columns:1fr}}
.loyalty-eyebrow{
  font-size:11px;letter-spacing:var(--tracking-wider);text-transform:uppercase;color:var(--taupe-400);
  margin-bottom:20px;
}
.loyalty-title{display:flex;align-items:center;gap:14px}
.loyalty-title svg{width:34px;height:34px;color:var(--text-on-base-heading)}
.loyalty-title span{font-family:var(--font-display);font-size:56px;color:var(--text-on-base-heading)}
.loyalty-lede{
  font-size:14px;line-height:1.7;color:var(--text-on-base-muted);
  margin:18px 0 0;max-width:320px;
}
.loyalty-members{display:flex;align-items:center;gap:14px;margin-top:26px}
.loyalty-members span{font-size:12px;color:var(--text-on-base-muted)}
.loyalty-members strong{color:var(--text-on-base-heading)}

/* Four even benefit cards instead of a ragged list — two of the old items had
   descriptions and two did not, which read as unfinished. */
.loyalty-benefits{
  display:grid;grid-template-columns:1fr 1fr;gap:22px 28px;margin-bottom:32px;
}
@media (max-width:620px){.loyalty-benefits{grid-template-columns:1fr;gap:18px}}
.loyalty-benefit{display:flex;gap:13px;align-items:flex-start}
.loyalty-benefit .ic{
  width:36px;height:36px;border-radius:50%;flex-shrink:0;
  background:var(--pill-bg);border:1px solid var(--hairline-on-base);
  display:flex;align-items:center;justify-content:center;
}
.loyalty-benefit .ic svg{width:16px;height:16px;color:var(--taupe-400)}
.loyalty-benefit h4{font-family:var(--font-display);font-size:18px;color:var(--text-on-base-heading);margin:0}
.loyalty-benefit p{font-size:12px;line-height:1.55;color:var(--text-on-base-muted);margin:5px 0 0}

.btn-club{
  font-family:var(--font-sans);font-size:12px;font-weight:600;
  letter-spacing:var(--tracking-wide);text-transform:uppercase;
  padding:15px 32px;border-radius:var(--radius-pill);background:var(--taupe-400);color:var(--plum-950);
  border:none;cursor:pointer;white-space:nowrap;
  display:inline-flex;align-items:center;justify-content:center;gap:8px;text-decoration:none;
  transition:background-color .2s ease,color .2s ease;
}
.btn-club:hover{background:var(--taupe-600);color:#fff}

/* ---------- club signup ---------- */
.club-form__row{
  display:flex;align-items:stretch;gap:0;
  background:var(--pill-bg);border:1px solid var(--hairline-on-base);
  border-radius:var(--radius-pill);padding:5px 5px 5px 20px;
  max-width:460px;
}
@media (max-width:520px){
  .club-form__row{
    flex-wrap:wrap;border-radius:22px;padding:14px;gap:12px;
  }
  .club-form__row .btn-club{width:100%}
}
.club-form__prefix{
  display:flex;align-items:center;font-size:14px;color:var(--text-on-base-muted);flex-shrink:0;
}
.club-form__row input{
  flex:1;min-width:0;background:none;border:none;outline:none;
  font-family:var(--font-sans);font-size:14px;color:var(--text-on-base);padding:0 12px;
}
.club-form__row input::placeholder{color:var(--text-on-base-muted);opacity:.65}
.club-form.has-error .club-form__row{border-color:var(--state-error)}
.club-form__error{
  display:none;align-items:center;gap:7px;
  font-size:12px;color:var(--state-error);margin:12px 0 0;
}
.club-form__error svg{width:13px;height:13px;flex-shrink:0}
.club-form.has-error .club-form__error{display:flex}
.club-form__note{
  font-size:11px;line-height:1.6;color:var(--text-on-base-muted);
  margin:14px 0 0;max-width:420px;opacity:.85;
}

.club-success{max-width:460px}
.club-success__tick{
  width:52px;height:52px;border-radius:50%;margin-bottom:18px;
  background:var(--state-success);display:flex;align-items:center;justify-content:center;
  animation:club-pop .4s cubic-bezier(.2,.9,.3,1.3);
}
.club-success__tick svg{width:24px;height:24px;color:#fff}
@keyframes club-pop{from{transform:scale(.5);opacity:0}to{transform:scale(1);opacity:1}}
@media (prefers-reduced-motion:reduce){.club-success__tick{animation:none}}
.club-success h3{
  font-family:var(--font-display);font-size:26px;color:var(--text-on-base-heading);margin:0 0 10px;
}
.club-success p{font-size:14px;line-height:1.65;color:var(--text-on-base-muted);margin:0 0 20px}

.club-code{
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  border:1px dashed var(--taupe-600);border-radius:16px;
  padding:16px 20px;margin-bottom:22px;background:var(--pill-bg);
}
.club-code code{
  font-family:var(--font-sans);font-size:20px;font-weight:600;
  letter-spacing:.14em;color:var(--text-on-base-heading);
}
.club-code__copy{
  margin-left:auto;display:inline-flex;align-items:center;gap:7px;
  font-family:var(--font-sans);font-size:11px;letter-spacing:var(--tracking-wide);text-transform:uppercase;
  background:none;border:1px solid var(--hairline-on-base);border-radius:var(--radius-pill);
  padding:9px 16px;color:var(--text-on-base);cursor:pointer;
  transition:border-color .18s ease,color .18s ease;
}
.club-code__copy:hover{border-color:var(--taupe-400);color:var(--taupe-400)}
.club-code__copy svg{width:13px;height:13px}
.club-code__copy.is-copied{border-color:var(--state-success);color:var(--state-success)}

/* ---------- customer reviews ---------- */
/* Round 10. One card shape, taken from the client's reference layout:
   a warm taupe panel with the customer's photo standing on the left and
   the words on the right. The reference's orange is not in this brand's
   palette; Taupe-400 is the on-palette equivalent of the same move (a warm
   block of colour lifted off the plum ground), and because the card ground
   is a fixed colour, its ink is fixed too - the card reads identically in
   the site's light and dark themes instead of having to restate every
   colour twice.

   The card NEVER reflows to a stack. Photo-left/words-right is the design,
   so on a phone the whole card scales down as one unit and stays
   horizontal; only the number of visible cards changes with width. */
.reviews-section{padding:24px 0 96px;position:relative}
@media (max-width:900px){.reviews-section{padding:16px 0 64px}}
.reviews-section .section-head{position:relative}
.reviews-section .section-head__lede{color:var(--text-on-base-muted)}
.reviews-nav{flex-shrink:0}
/* Manual controls only make sense on the manual (sub-900px) track - the
   auto-scroll loop above 900px has no buttons, matching "Shop by Category"
   directly above it, which has none either. */
@media (min-width:900px){.reviews-nav{display:none}}
@media (max-width:760px){.reviews-nav{display:none}}

/* Script word tucked over the display word, as in the reference. Parisienne
   is the site's own --font-script token (the logo uses it), not a foreign
   face brought in for one section. */
.rv-title{color:var(--text-on-base-heading);line-height:1.05}
.rv-title__script{
  display:block;font-family:var(--font-script);font-weight:400;
  font-size:clamp(26px,5.2vw,40px);line-height:1.1;
  color:var(--taupe-400);margin:0 0 -4px 3px;
}
/* Taupe reads beautifully on the plum ground and all but vanishes on the
   light theme's paper, so the light theme takes the palette's mauve
   instead. Same role, same family, enough contrast to be read. */
:root[data-theme="light"] .rv-title__script{color:var(--mauve-600)}
.rv-title__main{display:block;letter-spacing:.01em}

/* Native scroll-snap carousel; the prev/next buttons only nudge scrollLeft
   (initReviewsCarousel in shared.js). Touch swipe, trackpad and scrollbar
   all work with zero JS. Nothing auto-advances - a shopper needs to be
   able to stop and actually read a review. */
.reviews-strip{
  display:flex;gap:24px;overflow-x:auto;-webkit-overflow-scrolling:touch;
  scroll-snap-type:x proximity;scroll-behavior:smooth;
  scrollbar-width:none;margin:40px -56px 0;padding:10px 56px 18px;
}
@media (min-width:900px){.reviews-strip{display:none}}

/* ---------- reviews: desktop auto-scroll ----------
   Same mechanism as "Shop by Category" directly above (.cat-shelf__auto):
   a continuous CSS loop, the cat-marquee-scroll keyframe and
   --cat-marquee-copies variable reused rather than redefined, an edge
   fade only while it's the thing running, and a pause on hover/focus so a
   shopper who stops to read - or tap a badge - isn't fighting the motion.
   Below 900px this stays display:none and .reviews-strip (above) is what
   shows instead; only one of the two is ever visible at once. */
.reviews-auto{display:none}
@media (min-width:900px){
  .reviews-auto{
    display:block;position:relative;overflow:hidden;margin-top:40px;
    mask-image:linear-gradient(90deg,transparent,#000 40px,#000 calc(100% - 40px),transparent);
    -webkit-mask-image:linear-gradient(90deg,transparent,#000 40px,#000 calc(100% - 40px),transparent);
  }
  .reviews-auto-track{
    display:flex;gap:24px;width:max-content;
    animation-name:cat-marquee-scroll;
    /* Tuned for THIS track's own card width, not copied from the shelf's
       7s-per-copy constant - a review card is roughly double a product
       card's width and carries a sentence to read, so the same constant
       here would feel rushed. 32s/copy stays calm (this brand's motion
       dial is deliberately low) while still visibly alive. */
    animation-duration:calc(var(--cat-marquee-copies) * 32s);
    animation-timing-function:linear;
    animation-iteration-count:infinite;
  }
  .reviews-auto:hover .reviews-auto-track,
  .reviews-auto:focus-within .reviews-auto-track{animation-play-state:paused}
  /* A fixed width independent of .rv-card's own container-relative
     flex-basis rules (calc((100% - Npx)/2 or /3), tuned for the manual
     strip's own width). Those percentages would resolve against this
     track's width:max-content and produce an undefined size; a plain
     px value sidesteps that, and wins on specificity regardless of which
     breakpoint the percentage rule lives in. */
  .reviews-auto-track .rv-card{flex:0 0 380px;height:300px}
  /* Duplicate passes are already invisible to assistive tech via
     aria-hidden (set in PHP) and their badge is already unreachable by
     Tab (tabindex="-1", same file) - this only stops an idle mouse cursor
     resting over a duplicate card from showing a pointer/hover state for
     a control that a screen reader was never told exists. */
  .reviews-auto-track .rv-card[aria-hidden="true"]{pointer-events:none}
}
@media (prefers-reduced-motion:reduce){
  .reviews-auto-track{animation:none}
  .reviews-auto{overflow-x:auto}
}
.reviews-strip::-webkit-scrollbar{display:none}
@media (max-width:900px){
  .reviews-strip{margin:28px -24px 0;padding:8px 24px 16px}
}
@media (prefers-reduced-motion:reduce){
  .reviews-strip{scroll-behavior:auto}
}

.rv-card{
  --rv-pad:14px;
  --rv-badge:42px;
  position:relative;
  flex:0 0 86vw;max-width:420px;height:274px;
  scroll-snap-align:center;
  display:flex;gap:14px;
  padding:var(--rv-pad);
  background:var(--taupe-400);
  /* Hairline rather than a shadow, per the design's elevation rule. It is
     near-invisible against the plum ground and does the real work on the
     light theme, where a taupe card on paper needs a defined edge. */
  border:1px solid rgba(36,26,31,.10);
  border-radius:25px;
  color:var(--plum-950);
}
@media (min-width:560px){
  .rv-card{--rv-pad:18px;--rv-badge:48px;flex-basis:420px;height:304px;gap:20px}
}
@media (min-width:820px){
  .rv-card{flex-basis:calc((100% - 24px) / 2);max-width:none;scroll-snap-align:start}
}
@media (min-width:1400px){
  .rv-card{flex-basis:calc((100% - 48px) / 3)}
}

/* The one quote mark. The reference frames the card with two, which only
   reads as framing around a single centred card - in a row of three it
   would be visual litter, so it is kept as one editorial mark inside the
   card instead. */
.rv-card__mark{
  position:absolute;top:2px;right:18px;
  font-family:var(--font-display);font-weight:700;
  font-size:clamp(46px,9vw,68px);line-height:1;
  color:var(--cream-050);opacity:.55;pointer-events:none;
}

/* Photo panel: a framed slab standing the full height of the card, the
   cream frame lifted straight from the reference. */
.rv-card__photo{
  position:relative;flex:0 0 31%;align-self:stretch;
  border:3px solid var(--cream-050);border-radius:20px;
  background:var(--plum-900);
  display:flex;align-items:center;justify-content:center;
}
.rv-card__photo-img{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:center top;border-radius:17px;display:block;
}
/* Declared local placeholder while a real photo is still missing - an
   on-palette monogram, never an empty slot or a borrowed stock face. */
.rv-card__monogram{
  font-family:var(--font-display);font-size:clamp(22px,5vw,30px);
  color:var(--mauve-300);letter-spacing:.04em;
}

/* Source badge + its label, stacked so the label always sits directly
   above the badge without hard-coded offsets. */
.rv-card__source{
  position:absolute;left:50%;bottom:12px;transform:translateX(-50%);
  display:flex;flex-direction:column;align-items:center;gap:6px;z-index:2;
}
.rv-card__badge{
  position:relative;
  width:var(--rv-badge);height:var(--rv-badge);border-radius:50%;
  border:2px solid var(--taupe-400);background:var(--plum-950);color:var(--cream-100);
  display:flex;align-items:center;justify-content:center;padding:0;
}
.rv-card__badge svg{width:52%;height:52%;display:block}
.rv-card__badge-logo{width:60%;height:60%;object-fit:contain;display:block;border-radius:50%}
.rv-card__badge--live{cursor:pointer;transition:transform .18s ease,border-color .18s ease}
.rv-card__badge--live:hover,
.rv-card__badge--live:focus-visible{transform:scale(1.08);border-color:var(--cream-050)}
.rv-card__badge--live:focus-visible{outline:2px solid var(--plum-950);outline-offset:3px}

/* The affordance. A badge that opens a screenshot has to say so, and a
   caption alone is too quiet at this size - so the live badge breathes a
   single expanding ring. Motivated, not decorative: it appears only where
   there is something to open, and it is the only motion in the section. */
.rv-card__badge-pulse{
  position:absolute;inset:-3px;border-radius:50%;
  border:2px solid var(--taupe-400);
  animation:rv-pulse 2.6s cubic-bezier(.2,.7,.3,1) infinite;
  pointer-events:none;
}
@keyframes rv-pulse{
  0%{transform:scale(1);opacity:.75}
  70%{transform:scale(1.7);opacity:0}
  100%{transform:scale(1.7);opacity:0}
}
.rv-card__hint{
  font-family:var(--font-sans);font-size:9.5px;font-weight:500;
  letter-spacing:.1em;text-transform:uppercase;white-space:nowrap;
  color:var(--plum-950);background:var(--cream-050);
  padding:4px 8px;border-radius:999px;
  transition:opacity .18s ease,transform .18s ease;
}
/* On a mouse the label is a hover reveal; on touch there is no hover, so
   it stays visible and does the explaining the pulse only hints at.
   min-width is part of the condition on purpose: this site takes Facebook
   and Instagram in-app-browser traffic, and those WebViews are exactly the
   ones that report (hover:hover) while having no pointer to hover with. At
   phone widths the label is therefore always shown, whatever the browser
   claims about itself. */
@media (hover:hover) and (pointer:fine) and (min-width:561px){
  .rv-card__hint{opacity:0;transform:translateY(5px)}
  .rv-card__source:hover .rv-card__hint,
  .rv-card__source:focus-within .rv-card__hint{opacity:1;transform:none}
}
@media (prefers-reduced-motion:reduce){
  .rv-card__badge-pulse{animation:none;opacity:.5}
  .rv-card__hint{opacity:1;transform:none;transition:none}
  .rv-card__badge--live{transition:none}
}

.rv-card__body{
  flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center;
  padding:4px 2px 4px 0;overflow:hidden;
}
.rv-card__name{
  font-family:var(--font-display);font-weight:600;
  font-size:18px;line-height:1.15;letter-spacing:-.01em;
  color:var(--plum-950);margin:0;
  /* A long name must never push the quote out of a fixed-height card. */
  overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
}
.rv-card__role{
  font-family:var(--font-sans);font-size:10px;font-weight:500;
  letter-spacing:.14em;text-transform:uppercase;
  color:var(--plum-700);margin:5px 0 0;
}
.rv-card__stars{display:flex;gap:3px;margin:10px 0 0}
.rv-card__stars span{display:block;width:13px;height:13px;color:var(--plum-950);opacity:.22}
.rv-card__stars span.is-filled{opacity:1}
.rv-card__stars svg{width:100%;height:100%;fill:currentColor;display:block}
/* The quote is set to its own length (hizjaab_review_text_size in
   inc/customer-reviews-render.php picks the class). Real reviews are far
   shorter than marketing copy expects - "onek sundor, I'm satisfied" is a
   whole review - and the card height is deliberately fixed, so a short
   quote at body size would float in a half-empty card while a long one
   would be cut off. Short quotes are therefore set large like a pull
   quote, long ones step down until they fit. The card never changes
   shape; only the type inside it does. */
.rv-card__text{
  font-family:var(--font-serif);
  color:var(--plum-900);margin:11px 0 0;overflow:hidden;
  display:-webkit-box;-webkit-box-orient:vertical;
}
.rv-card__text--xl{font-size:19px;line-height:1.35;-webkit-line-clamp:4}
.rv-card__text--lg{font-size:16.5px;line-height:1.45;-webkit-line-clamp:5}
.rv-card__text--md{font-size:14.5px;line-height:1.55;-webkit-line-clamp:6}
.rv-card__text--sm{font-size:13.5px;line-height:1.5;-webkit-line-clamp:7}

@media (min-width:560px){
  .rv-card__name{font-size:22px}
  .rv-card__role{font-size:11px;margin-top:6px}
  .rv-card__stars{gap:4px;margin-top:12px}
  .rv-card__stars span{width:15px;height:15px}
  .rv-card__text{margin-top:13px}
  .rv-card__text--xl{font-size:24px;line-height:1.3;-webkit-line-clamp:5}
  .rv-card__text--lg{font-size:19px;line-height:1.45;-webkit-line-clamp:6}
  .rv-card__text--md{font-size:16px;line-height:1.6;-webkit-line-clamp:7}
  .rv-card__text--sm{font-size:15px;line-height:1.55;-webkit-line-clamp:7}
}

/* ---------- screenshot lightbox ----------
   Same shape as the product gallery's #gallery-lightbox: tap to open,
   swipe in any direction to dismiss, Escape and backdrop also close.
   initReviewsLightbox (shared.js) positions .rv-lightbox__frame over the
   card the badge belongs to, so the screenshot grows out of the badge and
   opens in the same place rather than jumping to the middle of nowhere. */
.rv-lightbox{position:fixed;inset:0;z-index:1200;display:none}
.rv-lightbox.is-open{display:block}
body.rv-lightbox-locked{overflow:hidden}
.rv-lightbox__backdrop{position:absolute;inset:0;background:rgba(36,26,31,.88)}
.rv-lightbox__frame{
  position:fixed;margin:0;display:flex;flex-direction:column;align-items:center;gap:12px;
  touch-action:none;-webkit-user-select:none;user-select:none;
}
.rv-lightbox__frame.is-animated{transition:transform .3s cubic-bezier(.2,.8,.25,1),opacity .22s ease}
.rv-lightbox__img{
  display:block;max-width:100%;max-height:76vh;width:auto;height:auto;object-fit:contain;
  border-radius:20px;border:1px solid rgba(255,255,255,.16);
  background:var(--plum-900);-webkit-user-drag:none;
}
.rv-lightbox__cap{
  font-family:var(--font-sans);font-size:11px;font-weight:500;
  letter-spacing:.14em;text-transform:uppercase;color:var(--mauve-300);text-align:center;
}
.rv-lightbox__close{
  position:absolute;top:18px;right:18px;width:42px;height:42px;border-radius:50%;
  border:1px solid rgba(255,255,255,.24);background:rgba(36,26,31,.55);color:var(--cream-100);
  display:flex;align-items:center;justify-content:center;cursor:pointer;
}
.rv-lightbox__close svg{width:18px;height:18px}
@media (prefers-reduced-motion:reduce){
  .rv-lightbox__frame.is-animated{transition:none}
}
