/*
Theme Name: LUQUA (Blocksy Child)
Theme URI: https://luqua.life
Description: LUQUA brand child theme. Tokens per clients/LUQUA/brand-tokens.md. Built by INONEXT Web Design Studio.
Author: INONEXT
Template: blocksy
Version: 1.0.0
Text Domain: luqua
*/

/* LUQUA FULL-BLEED: designed pages manage their own layout */
.page #main-container,.page main,.page article,.page [class*="ct-container"]{max-width:100%!important;width:100%!important;padding-left:0!important;padding-right:0!important;margin-left:0!important;margin-right:0!important}
.page .entry-content{max-width:100%!important;margin:0!important;padding:0!important}
.page .entry-header,.page .ct-page-title,.page .hero-section{display:none!important}

/* === Verification overrides (see DEVIATIONS.md) === */
/* Blocksy sets width:var(--theme-block-width) (~90vw) + margin-block-start on every
   .entry-content child, boxing sections and adding gaps. Force true full-width and
   remove block-gap so the designed sections stack edge-to-edge and flush. */
.page .entry-content > *{max-width:none!important;width:100%!important;margin:0!important}
/* Page's blanket `.entry-content h1,h2,h3{color:#2C2C34}` clobbers the design's
   warm-white card titles. Restore them. */
.page .entry-content [class*="range-card"] h3{color:#FFFDFB!important}
/* The design's range cards are <article> elements, so the container-neutralizing
   `article{padding:0!important}` (page zero-config + full-bleed block) wipes their
   clamp() padding — collapsing the card's text/image grid. Restore the card padding. */
.page .entry-content .range-card{padding:clamp(1.8rem,3vw,2.8rem)!important}
/* Range cards vertically-center their text against the product image (align-items:center), so a
   description that is one line longer (MenoLuv 5 lines vs FemeLuv 4) shifts that card's price + CTA
   ~12px off its neighbour's. The shop `.price{margin-top:auto}` trick can't apply — these cards are
   centered, not bottom-pinned, by design. Instead equalize the only variable element: reserve 5 lines
   (5 x 1.65 line-height = 8.25em) for the description so both text blocks are the same height and
   center identically -> price + button rows line up. Above ~1296px the wrap is fixed at 1200px so both
   descriptions are 4-5 lines and this equalizes exactly; only the shorter card gains a little trailing
   space. Backport: give `.range-card p` a min-height (or set the two descriptions to equal length). */
.page .range-card p{min-height:8.25em}
/* Same root cause as the range-card title fix above, generalized. The page's
   WP-integration shim `.entry-content h1,h2,h3{color:#2C2C34}` is declared LAST at equal
   (0,1,1) specificity, so it overrides every design section title that is warm-white on a
   dark band, forcing it to charcoal (dark-on-dark, near-invisible). Restore the design color.
   Verified live vs approved mockups: these render charcoal on live, warm-white in the mockup. */
.page .entry-content .house-band h2,    /* home  (id 72) "Plant-powered support..." */
.page .entry-content .formula-band h2,  /* pdp   (id 74) "Fifteen ingredients..."   */
.page .entry-content .facility h2{      /* about (id 75) "A certified facility..."  */
  color:#FFFDFB!important
}
/* `.product h2` is warm-white on the landing page (violet band) but charcoal on home,
   so scope this one to the landing page (page-id-77) to leave home's product title alone. */
.page-id-77 .entry-content .product h2{color:#FFFDFB!important}
/* Blocksy/WP give <ul> a default margin-block-end (~22.8px). The header nav's
   `.nav{align-items:center}` centers the ul's MARGIN box, so that bottom margin
   pushed the visible menu items up ~11.4px — misaligned vs the logo and CTA (which
   the design intends all centered). Reset the nav ul margin so it centers on content. */
/* …and the UA default padding-inline-start (38px) with it. Margin alone was not enough:
   the canvas header lives inside .entry-content, so the browser's list indent still applied
   and pushed the centred menu 19px right of true centre. The Woo chrome pages (cart /
   checkout / account) zero it in luqua-woo.css and were therefore correctly centred, which
   is why the two looked misaligned against each other (owner 2026-07-27). */
.luqua-header .nav ul{margin:0!important;padding:0!important}

/* True-centre the main menu (owner 2026-07-27).
   The nav was flex + space-between, so the menu's position depended on how wide the two
   side items happened to be. That is why /menoluv/ sat 14px off the others: its header CTA
   reads "Add to cart" (189px) where the rest read "Shop MenoLuv" (217px), and half of that
   28px difference moved the centre. A 3-column grid with equal 1fr flanks pins the menu to
   the real centre of the header no matter what the CTA says.

   - Above the 920px breakpoint ONLY. Below it the menu is display:none and opens as an
     absolutely-positioned dropdown, which the grid must not touch.
   - The minimal checkout header is excluded: it has two children (logo + "Secure checkout"),
     so a 3-column grid would centre the second one instead of pushing it right.
   - !important because luqua-woo.css sets `body.luqua-chrome .luqua-header .nav` (0,3,1),
     which outranks this selector (0,3,0) on the Woo chrome pages. Same reason as the reset above.
   - Page 77 (ads/offer) has no .luqua-header at all, so it is unaffected by construction. */
@media (min-width:921px){
  .luqua-header:not(.luqua-header--min) .nav{
    display:grid!important;
    grid-template-columns:1fr auto 1fr!important;
    align-items:center}
  .luqua-header:not(.luqua-header--min) .nav>:first-child{justify-self:start}
  .luqua-header:not(.luqua-header--min) .nav>ul{justify-self:center}
  .luqua-header:not(.luqua-header--min) .nav>.nav-cta{justify-self:end}
}

/* === UI refinements (requested by owner 2026-07-12; see DEVIATIONS.md) === */
/* Hero accent dots read as slider indicators; with a single static hero banner there are no
   slides to page, so hide them. z-index keeps them above the photo if a real multi-banner
   hero slider is added later (separate build). */
.hero-visual .dots{display:none!important;z-index:3}

/* FemeLuv coming soon (Aug 2026): obscure the unreleased pack as a real pixel MOSAIC, everywhere it
   appears (home range card + shop card), not just home. A plain CSS blur read as "just blurry", and
   only home had it. functions.php swaps the img src to a 30px low-res source; image-rendering:pixelated
   upscales it into crisp mosaic blocks so the pack reads as "there, but hidden". The `img[src*=feme]`
   selector catches every FemeLuv image regardless of container. Undo at launch (see DEVIATIONS.md). */
.page img[src*="femeluv"]{image-rendering:pixelated!important}
/* Mosaic filled the frame on home but rendered tiny on shop. Home's `.range-card img` sets
   `width:100%`, so the 30px mosaic scales UP to fill; shop's `.card .ph img` only sets
   `max-height:100%` (+ global `max-width:100%`), which cannot enlarge a source smaller than the
   box, so the mosaic stayed at its natural 30x24 and read as a "tiny product image". Force the
   shop FemeLuv card image to fill its frame like home. Scoped to the `mosaic` filename so the real
   femeluv.webp (returned at launch) is untouched — remove with the rest of the mosaic block then. */
.page .card.feme .ph img[src*="mosaic"]{width:100%!important;height:100%!important;object-fit:contain}

/* Announcement bar tracking was inconsistent between pages (owner 2026-07-13): home + PDP shipped
   `.announce` with `letter-spacing:.04em`, but shop/about/faq omitted it, so the same text read as a
   "different font". Font family/size/weight are already identical (Montserrat). Standardise every page
   to the home/PDP look (the .04em tracking). */
.page .announce{letter-spacing:.04em!important}

/* Shop product-card price + CTA must line up across cards (owner: buttons parallel but prices not).
   The card is a flex column with `.txt{flex:1}`. Putting `margin-top:auto` on the *button* alone only
   bottom-pinned the button — the price still trailed each description, so a card with a shorter blurb
   (the 90-day box is one line shorter) floated its price higher. Moving the auto margin to the *price*
   pushes price+CTA down as one block to the card floor, so BOTH the price row and the button row align
   across all three cards, with the slack absorbed above the price. (Two auto margins would split the
   slack and re-break the price, so it lives on the price only.) Standard bottom-cluster card pattern.
   Backport: give `.card .price` `margin-top:auto` upstream. */
.page .card .txt .price{margin-top:auto!important}

/* Advisory callouts shipped as a flat card with a coral left bar (reads as a generic UI-kit /
   shadcn "alert" default). Two owner directives apply: (1) drop the red left-border accent
   site-wide; (2) the box must stay clearly VISIBLE, not blend into the cream page.
   An earlier frosted-glass pass satisfied (1) but failed (2): a translucent panel on a warm-white
   page nearly vanished. Fix: use the brand's OWN purpose-named advisory tokens (--advisory-bg
   #FBEBDD warm peach fill, --advisory #B25E2A terracotta) that ship in every page's :root but were
   left unwired. Calm, legible "notice" surface with an EVEN hairline border (no left accent):
   visible AND on-brand, not a generic red alert. Icon + the "Contains soy." lead-in take the
   terracotta so the safety signal reads at a glance; the full advisory sentence stays dark ink for
   max legibility. var() fallbacks guard any page that lacks the token. Applies to pdp/landing/home/faq. */
.page .entry-content .callout{
  background:var(--advisory-bg,#FBEBDD)!important;
  border:1px solid rgba(178,94,42,.20)!important;
  border-radius:18px!important;
  box-shadow:0 6px 18px rgba(178,94,42,.10)!important;
  gap:.95rem!important;
  align-items:center!important;
  padding:1.15rem 1.35rem!important;
}
/* Modernise pass (owner: "contains soy" box looked old-fashioned). Keep the owner-chosen advisory
   palette; change the FORM. The dated feel came from a bare inline icon sitting on a flat fill.
   Lift the icon into a soft white round chip with its own shadow, soften the card radius/shadow,
   and vertically centre the chip against the text. Icon markup is unchanged, so this applies
   gracefully to every callout site-wide (page 76 has no icon and simply shows the softened card). */
.page .entry-content .callout svg{
  color:var(--advisory,#B25E2A)!important;
  width:38px!important;height:38px!important;padding:9px!important;
  box-sizing:border-box!important;border-radius:50%!important;
  background:rgba(255,255,255,.72)!important;
  box-shadow:0 2px 7px rgba(178,94,42,.16)!important;
  margin-top:0!important;
}
.page .entry-content .callout b{color:var(--advisory,#B25E2A)!important}

/* PDP trust strip (page 74 only): shipped as three flat blush blocks with a bold label and a line
   of small text, no iconography, so the row read as filler rather than as trust signals next to
   Add-to-cart. Rebuild each as a white card with a soft violet icon chip (shield-check / truck /
   award), a hairline border and a lift on hover. Icons are stroke SVGs added to the page markup;
   the 3-col grid + responsive base stay in the page's own CSS. Violet-only palette keeps MenoLuv's
   calm, dignified register (no multi-colour badge noise). */
/* 2026-07-25: was a stacked, centred card (display:flex + flex-direction:column +
   align-items:center). Now ONE COMPACT ROW per item: block flow with left padding for the
   absolutely-positioned icon, so <b> and the following <span> reflow as a single sentence.
   Do NOT reintroduce flex here — it would make them sibling flex items that cannot wrap
   together on mobile. */
.page .entry-content .trust-strip div{
  position:relative!important;
  background:#fff!important;
  border:1px solid var(--line,#E7E1E6)!important;
  border-radius:var(--r-md,16px)!important;
  padding:.72rem 1rem .72rem 3.05rem!important;
  display:block!important;
  text-align:left!important;
  box-shadow:var(--shadow-sm,0 2px 8px rgba(44,44,52,.06))!important;
  transition:transform .16s ease,box-shadow .16s ease,border-color .16s ease!important;
}
.page .entry-content .trust-strip div:hover{
  transform:translateY(-3px)!important;
  border-color:var(--violet-300,#ABA5E4)!important;
  box-shadow:var(--shadow-md,0 8px 24px rgba(83,71,192,.12))!important;
}
/* Compact single-row trust items from 2026-07-25 (was a 2x2 card grid): the icon is a small
   circle pinned to the left of each row and vertically centred, so the row is one line of text
   instead of a stacked card. Keep in step with the page-level `.trust-strip` rules. */
.page .entry-content .trust-strip .ts-ico{
  position:absolute;left:.95rem;top:50%;transform:translateY(-50%);
  width:30px;height:30px;border-radius:50%;flex:none;
  background:var(--violet-050,#F3F1FC);color:var(--violet,#5347C0);
  display:flex;align-items:center;justify-content:center;
}
.page .entry-content .trust-strip .ts-ico svg{width:17px;height:17px;display:block}
.page .entry-content .trust-strip b{margin-bottom:0!important;display:inline!important}

/* Payment logos (page 74): actual owner-confirmed brand marks (FPX, Visa, Mastercard, GrabPay)
   in a row under the trust strip, giving the "Secure checkout" card real proof. Official SVGs are
   copied into the child theme (assets/pay/) so they deploy with the theme; the source plugin
   (woo-stripe-payment) is deploy-excluded and its asset paths can't be relied on. Uniform white
   chips normalise the mixed logo aspect ratios (Visa/MC are card tiles, FPX/GrabPay are logos)
   into one tidy row. Negative top margin tucks the row under the trust cards' 1.4rem bottom gap. */
.page .entry-content .pay-strip{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:.35rem;margin:-.5rem 0 1.4rem;
}
.page .entry-content .pay-chip{
  width:56px;height:36px;background:#fff;
  border:1px solid var(--line,#E7E1E6);border-radius:8px;
  display:flex;align-items:center;justify-content:center;padding:0 7px;
  box-shadow:0 1px 3px rgba(44,44,52,.06);
}
.page .entry-content .pay-chip img{max-height:22px;max-width:100%;width:auto;display:block}
/* PDP pay-strip carries the full 8-mark set in a ~496px column, so its chips are a touch smaller
   than the footer's (which has room to keep 56px) to hold one clean row down to ~440px. */
.page .entry-content .pay-strip .pay-chip{width:50px;height:32px;padding:0 6px}
.page .entry-content .pay-strip .pay-chip img{max-height:19px}

/* Footer payment row (all pages): owner preference is marks, not a text method list. Reuse the same
   white .pay-chip so the site reads as one system. The footer is a dark purple gradient, so the white
   chips are also what keep FPX (dark logo) and GrabPay (green logo) legible; a bare logo row on that
   background would be low-contrast. Small "Secure payment" lead keeps the reassurance context. */
.page .entry-content .foot-pay{display:flex!important;flex-wrap:wrap;align-items:center;gap:.5rem}
/* Lead label uses the readable muted colour, not the old #A9A3D6 lavender: the footer background
   is LIGHT here (child-theme override `.page footer.site{background:#F3EBF0}` supersedes the page's
   old dark gradient), so lavender-on-light was near-invisible (the original text had this too). */
.page .entry-content .foot-pay-lead{color:var(--muted,#54525E);letter-spacing:.03em;margin-right:.25rem}

/* Same "no red left-border" directive: the product spec columns used coral left bars as dividers.
   Remove them so the stats separate on whitespace alone (no colored left-border accent anywhere). */
.page .entry-content .spec div{border-left:0!important;padding-left:0!important}

/* Testimonials shipped as sample/placeholder reviews (invented names + a "Verified buyer" badge).
   Publishing fabricated reviews as genuine is deceptive, so hide the review sections until real,
   consented customer reviews exist (then unhide + populate). Applies to home/pdp (.reviews) and
   landing (.proof). See DEVIATIONS.md. */
.page .entry-content .reviews,
.page .entry-content .proof{display:none!important}

/* Empty video-reel carousels (dashed "VIDEO SLOT 9:16" cards) read as unfinished and kill trust.
   Hide the whole section until real 9:16 UGC/education clips are embedded. Home packs its video
   row inside .reviews (already hidden above). PDP + landing use a separate .vids section.
   Unhide when real videos ship (see CONVERSION-REDESIGN-V10.md + DEVIATIONS.md). */
.page .entry-content section.vids{display:none!important}

/* === Conversion pass 2026-07-16: offer simplicity on PDP (see DEVIATIONS.md) ===
   SUPERSEDED 2026-07-21. This hid the 4-box and 5-box rows by position. The 1/3/6 decision
   removed the 2/4/5 tiers from the markup on pages 74 and 77 outright, so only three .pick
   elements remain and these nth-child selectors match nothing. Removed rather than left as
   dead code: with a positional selector, anyone re-adding a tier later would silently hide
   the wrong row. The tiers now live in checkout upsell, not in the picker. */

/* Sticky bar: show per-day cost under the main price (supplement buyers think in daily ritual). */
.luqua-stickybar__price{display:flex;flex-direction:column;align-items:flex-end;line-height:1.15}
.luqua-stickybar__price small{font-family:var(--body,'Montserrat',sans-serif);font-size:.72rem;font-weight:500;color:var(--muted,#8a8391);margin-top:.15rem}

/* === LUQUA footer redesign — premium light treatment (owner 2026-07-12; see DEVIATIONS.md) ===
   Brand context stands: the store read as MenoLuv because Pack Violet (#5347C0, from the MenoLuv
   box art) did ~15 jobs/page while LUQUA House Purple (#782B90, kit role "store-level chrome,
   cross-product moments") was a defined-but-unused token. First fix retinted the footer to a
   House-Purple gradient; that corrected the color but created a NEW problem: on home the purple
   "Start with MenoLuv" CTA band flows straight into a purple footer -> one flat, heavy, monotone
   purple slab (owner: "too ugly").
   Redesign grounded in the owner's own north-star refs: im8health (their #1 ref) + Womaness use a
   LIGHT warm footer with the brand color as ACCENT ONLY (headings/links/logo), never a full color
   wash; the bold color lives in the CTA band ABOVE, and the light footer gives crisp separation and
   a calmer, premium close. So: warm blush-white surface, dark legible text, House Purple #782B90 as
   the accent (column headings + link hover), dark logo (shipped as a white PNG via invert), and
   cert chips + rules re-tinted for a light bg. LUQUA identity is preserved by the purple announcement
   bar + house-band CTA; the footer just stops being a slab. !important is required because the footer
   ships hardcoded dark-bg colors and inline color styles on the logo/social/halal lines. */
.page footer.site{
  background:#F3EBF0!important;
  color:#4A4A55!important;
  border-top:1px solid #E4DAE4!important;
}
.page footer.site .foot-grid img{filter:brightness(0)!important;opacity:.9}
.page footer.site .foot-grid h4{color:#782B90!important}
/* Footer <ul> keeps the UA default padding-inline-start (~40px), so the links sat indented from
   their SHOP/LEARN headings (footer is outside .entry-content, so the page-level list resets miss
   it). Zero it so each column's heading + links share one left edge. */
.page footer.site .foot-grid ul{margin:0!important;padding:0!important;list-style:none!important}
.page footer.site .foot-grid a{color:#3E3E48!important}
.page footer.site .foot-grid a:hover{color:#782B90!important}
/* Contrast bump: on the light blush the grey meta/description text read faint (~3:1). Darken so
   every line is clearly legible (owner: "footer content is not visible"). */
.page footer.site .foot-grid p{color:#514C5A!important}
.page footer.site .certs span{border-color:#DCD1DE!important;color:#4A4A55!important}
/* Footer + contact social icons (2026-07-25): the plain "Facebook · Instagram" text links were
   replaced with monochrome brand glyphs (Instagram / TikTok / Facebook), linking the official
   luqua.life accounts. In the footer the icons inherit the foot-grid link colour (#3E3E48, hover
   House Purple) via currentColor; on the light contact card they wear House Purple directly. */
.page footer.site .foot-social{display:flex!important;align-items:center;gap:.95rem;margin-top:1rem!important}
.page footer.site .foot-social a{display:inline-flex!important;line-height:0}
.page footer.site .foot-social svg{width:20px;height:20px;transition:transform .15s ease}
.page footer.site .foot-social a:hover svg{transform:translateY(-1px)}
.con-card .chan .chan-social{display:flex;align-items:center;gap:.8rem;margin-top:.45rem}
.con-card .chan .chan-social a{display:inline-flex;line-height:0;color:#782B90}
.con-card .chan .chan-social a:hover{color:#5347C0}
.con-card .chan .chan-social svg{width:20px;height:20px;transition:transform .15s ease}
.con-card .chan .chan-social a:hover svg{transform:translateY(-1px)}
/* Footer newsletter signup + KKM/MOH-style disclaimer box (owner 2026-07-25). The 4th footer
   column (was the FDA/GMP/HACCP/ISO/Halal certs chips) is now a Klaviyo signup form; the bare
   pregnancy line grew into a full food-product disclaimer in a bordered box (Seed / AG1 / IM8
   pattern), retuned for the light footer. Certs still live on the homepage research-house section. */
.page footer.site .foot-news h4{margin-bottom:.7rem!important}
.page footer.site .foot-news .news-sub{color:#514C5A!important;font-size:.86rem!important;line-height:1.5;margin:0 0 .95rem!important;max-width:34ch}
.page footer.site .foot-news .news-field{display:flex;align-items:center;gap:.4rem;background:#fff;border:1px solid #DCD1DE;border-radius:999px;padding:.16rem .16rem .16rem 1rem;max-width:330px;transition:border-color .15s ease,box-shadow .15s ease}
.page footer.site .foot-news .news-field:focus-within{border-color:#782B90;box-shadow:0 0 0 3px rgba(120,43,144,.12)}
.page footer.site .foot-news .news-field.invalid{border-color:#C0392B;box-shadow:0 0 0 3px rgba(192,57,43,.12)}
.page footer.site .foot-news .news-field input{flex:1;min-width:0;border:0;outline:0;background:transparent;font:inherit;font-size:.9rem;color:#3E3E48;padding:.55rem 0}
.page footer.site .foot-news .news-field input::placeholder{color:#9A94A6}
.page footer.site .foot-news .news-field button{flex:none;width:40px;height:40px;padding:0;border:0;border-radius:50%;background:#782B90;color:#fff;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;transition:background .15s ease}
.page footer.site .foot-news .news-field button:hover{background:#5B2070}
.page footer.site .foot-news .news-field button svg{width:18px;height:18px}
.page footer.site .foot-news .news-consent{color:#7A7684!important;font-size:11.5px!important;line-height:1.5;margin:.65rem 0 0!important;max-width:34ch}
.page footer.site .foot-news .news-ok{color:#782B90!important;font-weight:600;font-size:.85rem!important;margin:.65rem 0 0!important}
/* The signup posts server-side now, so it can genuinely fail (Klaviyo down, rate limited). The
   status line doubles as the error surface rather than lying with a confirmation. */
.page footer.site .foot-news .news-ok.err{color:#C0392B!important}
.page footer.site .foot-news .news-field button[disabled]{opacity:.6;cursor:progress}
.page footer.site .foot-disclaimer{border:1px solid #E0D4E2!important;border-radius:12px!important;background:transparent!important;padding:.95rem 1.15rem!important;margin:0 0 1.1rem!important}
.page footer.site .foot-disclaimer p{color:#6E6E7A!important;font-size:12.5px!important;line-height:1.65!important;margin:0!important;max-width:none!important}
/* Copyright strip wears House Purple (owner 2026-07-13): the bottom "legal" line becomes a solid
   #782B90 band with light text, closing the light-blush footer on a branded note. The pregnancy
   disclaimer was moved out of this strip into .foot-disclaimer (light footer body) just above it. */
.page footer.site .foot-disclaimer{font-size:13px!important;color:#6E6E7A!important;margin:0 0 .2rem!important;line-height:1.5}
.page footer.site .legal{
  background:#782B90!important;
  color:#EFE7F2!important;
  border-top:0!important;
  border-radius:0!important;
  /* Full-bleed band: break out of .wrap to the viewport edges (html,body already clip overflow-x),
     and cancel footer's 2.5rem bottom padding so it seats flush on the page bottom. */
  width:100vw!important;
  margin-left:calc(50% - 50vw)!important;
  margin-right:calc(50% - 50vw)!important;
  margin-top:1.6rem!important;
  margin-bottom:-2.5rem!important;
  padding:1.1rem var(--gut)!important;
  justify-content:center!important;
  text-align:center!important;
}
.page footer.site .legal span{color:#EFE7F2!important}
.page footer.site .foot-pay{color:#6E6E7A!important}

/* === LUQUA pages wear House Purple, not MenoLuv Pack Violet (owner 2026-07-12; see DEVIATIONS.md) ===
   Owner directive: "use LUQUA colour instead of MenoLuv, unless it is the MenoLuv single-product
   landing page." Every page ships the same blue-violet accent scale pulled from the MenoLuv box art
   (--violet #5347C0 + deep/700/300/100/050), used ~15x/page. Remap that WHOLE scale to a magenta
   House-Purple scale (anchored on --house #782B90) so all accents on the LUQUA-brand pages -- hero
   italics, buttons, links, section washes, the "LUQUA" comparison column, range cards, ribbons --
   read as the parent brand. Scoped by body id to the LUQUA pages only: 72 home, 73 shop, 75 about,
   76 faq. MenoLuv product pages KEEP pack violet: 74 PDP, 77 offer/landing. Remapping the custom
   props on <body> re-defines them for the whole page subtree (they inherit), so one block retints
   everything downstream; the whole family is remapped together so gradients stay purple->purple
   (not purple->blue) and tints/borders stay in-family. Dark end #5A1F6E matches the house-band CTA. */
.page-id-72,.page-id-73,.page-id-75,.page-id-76,.page-id-96{
  --violet:#782B90!important;
  --violet-deep:#5A1F6E!important;
  --violet-700:#6A2680!important;
  --violet-300:#B98FC9!important;
  --violet-100:#E9DCEE!important;
  --violet-050:#F6EFF7!important;
}

/* === Button hover: kill the theme-blue label + brand peach hover (owner 2026-07-13) ===
   Blocksy sets a link-hover color of #1559ed (blue). Its `a:hover` (specificity 0,1,1) outranks the
   buttons' own single-class color (`.btn-primary` = 0,1,0), and the buttons' :hover rules only swap the
   background — so every button LABEL flipped to theme-blue on hover (near-illegible on the purple fill,
   e.g. the home hero "Shop the range"). Fix per owner: make the primary hover the brand peach with
   readable dark text (mirrors the existing range-card white->peach hover), and re-assert the other
   button families' label colors so the theme blue can never show. --violet-700 resolves to House Purple
   on LUQUA pages / Pack Violet on product pages, so the dark text stays on-palette per page. */
.page a.btn-primary:hover{background:var(--peach)!important;color:var(--violet-700)!important}
/* landing(77)/about(75)/faq(76) style the bare .btn as the primary CTA (violet fill, white label, no
   .btn-primary class) — same peach hover. Excludes .btn-coral; the WhatsApp/tel links on these pages
   are plain <a>, not .btn, so they're untouched. */
.page-id-77 .entry-content a.btn:not(.btn-coral):hover,
.page-id-75 .entry-content a.btn:hover,
.page-id-96 .entry-content a.btn:hover,
.page-id-76 .entry-content a.btn:hover{background:var(--peach)!important;color:var(--violet-700)!important}
/* ghost + coral only needed their label colors pinned so hover isn't theme-blue (their backgrounds
   already change correctly): ghost keeps the brand accent, coral keeps white on its coral fill. */
.page a.btn-ghost:hover{color:var(--violet)!important}
.page a.btn-coral:hover{color:var(--warm-white)!important}

/* === MenoLuv PDP (id 74): breadcrumb alignment + gallery interactions (owner 2026-07-13; see DEVIATIONS.md) ===
   (2) The breadcrumb sat flush to the viewport edge instead of aligning with the product grid. `.crumbs`
   is a DIRECT child of `.entry-content.is-layout-constrained`, so WordPress's constrained-layout rule
   (`.is-layout-constrained > *`) overrides the page's own `.wrap` max-width with an unset content-size
   token and the bar stretches full width. (`.pdp-grid` escapes it because it's nested inside
   <section class="pdp">, not a direct child.) Re-assert the page wrap so the breadcrumb text lines up
   with the gallery/info columns. !important because the WP/Blocksy layout rule outranks a plain `.wrap`. */
.page-id-74 .entry-content.is-layout-constrained > .crumbs.wrap{
  max-width:var(--max)!important;
  margin-inline:auto!important;
  padding-inline:var(--gut)!important;
}

/* (3) Product gallery chrome for the behaviour wired in functions.php (thumbnail switch, prev/next,
   click-to-zoom). The approved markup is a static mockup with no gallery JS. Arrows are injected into
   `.main`; zoom scales the image toward the click point, clipped to the rounded card. */
.page-id-74 .gallery .main{position:relative;overflow:hidden;cursor:zoom-in}
.page-id-74 .gallery .main.zoomed{cursor:zoom-out}
.page-id-74 .gallery .main img{transition:transform .28s ease}
.page-id-74 .gallery .main.zoomed img{transform:scale(1.9)}
.page-id-74 .gallery .main .gal-nav{position:absolute;top:50%;transform:translateY(-50%);width:42px;height:42px;border-radius:999px;border:1px solid var(--line);background:rgba(255,253,251,.86);color:var(--charcoal);font-family:var(--body);font-size:1.6rem;line-height:1;display:flex;align-items:center;justify-content:center;cursor:pointer;z-index:2;padding:0;transition:background .15s ease,box-shadow .15s ease}
.page-id-74 .gallery .main .gal-nav:hover{background:var(--warm-white);box-shadow:var(--shadow-sm)}
.page-id-74 .gallery .main .gal-prev{left:14px}
.page-id-74 .gallery .main .gal-next{right:14px}

/* (4) Cart/checkout totals: luqua-woo.css rounds .wc-block-components-totals-wrapper (var(--r-lg)),
   but that class is the INNER row wrapper, not the outer card. Its 24px radius curls the ends of
   the 1px WooCommerce row dividers (Cart totals/Add coupons, Free shipping/Estimated total).
   Reset to 0 so dividers stay straight; the outer card rounding lives on .wc-block-checkout__sidebar
   / order-summary, which is untouched. Backport: drop .wc-block-components-totals-wrapper from the
   border-radius selector at luqua-woo.css:168. */
body.luqua-chrome .wc-block-components-totals-wrapper{border-radius:0!important}

/* (5) Smart sticky header (owner 2026-07-13): JS "headroom". The approved position:sticky can't engage
   (Blocksy's #main-container/body establish nested scroll boxes), so luqua-cart.js instead switches the
   header to position:fixed once it scrolls past, hides it on scroll-down and reveals it on scroll-up, and
   drops back to normal flow at the very top. A spacer (set by JS) holds the layout while fixed. Skipped on
   checkout. Do NOT set position here — only the fixed/hidden states, so the top-of-page look is untouched. */
.luqua-header{transition:transform .32s cubic-bezier(.4,0,.2,1)}
.luqua-header.luqua-header--fixed{position:fixed;top:0;left:0;right:0;z-index:200}
body.admin-bar .luqua-header.luqua-header--fixed{top:32px} /* clear the desktop admin bar (logged-in preview only) */
.luqua-header.luqua-header--hidden{transform:translateY(-100%)}
.luqua-header-spacer{height:0}

/* (6) PDP sticky add-to-cart bar (owner 2026-07-13): injected + shown by luqua-cart.js once #atc-btn
   scrolls above the viewport. Content mirrors the selected bundle; the button reuses the ?add-to-cart
   deep-link so the cart-drawer interceptor handles the AJAX add. Tokens use fallbacks in case the
   page's own CSS vars aren't all defined. */
.luqua-stickybar{position:fixed;left:0;right:0;bottom:0;z-index:900;display:flex;align-items:center;
  gap:.85rem;padding:.65rem clamp(1rem,4vw,2rem);background:rgba(255,253,251,.97);backdrop-filter:blur(8px);
  border-top:1px solid var(--line,#ece6e1);box-shadow:0 -6px 24px rgba(44,44,52,.10);
  transform:translateY(110%);transition:transform .3s cubic-bezier(.4,0,.2,1);will-change:transform}
.luqua-stickybar.is-visible{transform:translateY(0)}
.luqua-stickybar__thumb{width:46px;height:46px;flex:0 0 46px;border-radius:var(--r-sm,10px);object-fit:cover;background:var(--blush,#f7efe9)}
.luqua-stickybar__meta{display:flex;flex-direction:column;min-width:0;line-height:1.25}
.luqua-stickybar__name{font-family:var(--display,'Playfair Display',serif);font-size:1rem;color:var(--charcoal,#2c2c34);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.luqua-stickybar__label{font-size:.76rem;color:var(--muted,#8a8391);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.luqua-stickybar__price{margin-left:auto;font-family:var(--display,'Playfair Display',serif);font-size:1.05rem;color:var(--charcoal,#2c2c34);white-space:nowrap}
.luqua-stickybar__btn{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;min-height:46px;
  padding:0 1.4rem;border:0;border-radius:999px;background:#E2545F;color:#fff;font-family:var(--body,'Montserrat',sans-serif);
  font-size:.95rem;font-weight:600;text-decoration:none;cursor:pointer;transition:background .18s ease}
.luqua-stickybar__btn:hover{background:#C7434D;color:#fff}
@media (max-width:560px){
  /* Two-row bar (owner 2026-07-24): the CTA now carries "Add N boxes · RM…" and is wide, so a single
     row crushed the plan label to "3 bo…". Stack plan + Change on row 1 (full width) and give the Add
     button its own full-width row 2. The in-bar stepper stays hidden (it lives in the hero). */
  .luqua-stickybar{flex-wrap:wrap;gap:.45rem .6rem;padding:.6rem .8rem}
  .luqua-stickybar__price{display:none}
  .luqua-stickybar.has-qty .luqua-stickybar__qty{display:none}
  .luqua-stickybar__name{font-size:.92rem}
  .luqua-stickybar__meta{flex:1 1 auto;min-width:0}
  .luqua-stickybar__btn{order:3;flex:1 1 100%;min-height:46px;padding:0 1.1rem;font-size:.95rem}
}

/* (7) Readability floor (owner 2026-07-13): the audience skews 45-60+, so lift the smallest label styles
   to a ~13px minimum. Body copy is already >=16px and untouched; this only raises sub-13px eyebrows /
   badges / chips / cert labels, so the hierarchy (labels < body) is preserved. !important beats the
   approved pages' own inline CSS. See DEVIATIONS.md. */
.eyebrow{font-size:13.5px!important}
.tag,.st{font-size:13px!important}
.hero-chip,.foot-pay{font-size:13px!important}
.certs span{font-size:13px!important}
.certs + p{font-size:13px!important}      /* "Halal certification in progress" note */
.legal,.legal span{font-size:13px!important} /* footer copyright + language switcher */
/* PDP-specific small labels (scoped to page 74 so generic class names can't affect other pages). */
.page-id-74 .flag{font-size:12.5px!important}                                   /* "Most chosen" badge */
.page-id-74 .small,.page-id-74 .tax,.page-id-74 .s,
.page-id-74 .foot,.page-id-74 .who{font-size:13px!important}

/* === MenoLuv landing (id 77): owner design revisions 2026-07-13 (see DEVIATIONS.md) ===
   Five owner-requested tweaks to the ads landing page. Style-only items live here, scoped to
   page-id-77 so the shared class names (.strip/.moment/.product-grid/.bundles/.faq) cannot leak
   to other pages. The offer's 4th bundle card is a markup change in the page source. */

/* (1) Announce strip wears MenoLuv Pack Violet instead of charcoal (the landing is a product
   surface, which by the brand hierarchy keeps pack violet). */
.page-id-77 .entry-content .strip{background:var(--violet)!important;color:#FFFDFB!important}

/* (2) The three "moments" lifestyle photos cut faces in half: the 3:2 landscape frame + centred
   cover crop sliced subjects mid-face. A taller 4:5 frame with a top-biased focal point keeps the
   face whole so it reads intentional. */
.page-id-77 .entry-content .moment .ph{aspect-ratio:4/5!important}
.page-id-77 .entry-content .moment .ph img{object-position:center 22%!important}

/* (3) Product shot read tiny next to the ingredient list (image column .85fr, img 82% wide), leaving
   dead space. Even the columns and let the box fill its frame so it anchors the section.
   The square 1600x1600 box (~459px tall) is much shorter than the 5-row ingredient column (~1000px),
   so any alignment leaves blank space: centre splits it above+below, top-align dumps the whole ~540px
   below. Sticky (the ideal pin-the-box pattern) is dead here: .product has overflow:hidden and a
   page-wide overflow:clip ancestor (horizontal-scroll guard), and any non-visible overflow on an
   ancestor disables position:sticky. Compromise that needs no page-wide overflow surgery: centre the
   box and enlarge it (slight bleed left into the section's full-bleed margin) so the box reads bigger
   and the leftover gap is smaller and balanced top/bottom instead of one large block. */
.page-id-77 .entry-content .product-grid{grid-template-columns:1fr 1.05fr!important;align-items:center!important}
.page-id-77 .entry-content .product-grid img.pack{width:130%!important;max-width:none!important;margin-left:-30%!important}

/* (4) Offer: the 4-card price grid read cramped/ragged at 4-up (owner feedback 2026-07-13). Replaced
   with the PDP's proven vertical bundle SELECTOR (Gruns pattern the owner referenced): one radio group
   of stacked .pick rows + a single #atc-btn "Add to cart". Benefits: one decision + one CTA (higher
   converting than 4 competing buttons), it stacks cleanly instead of cramming, and the site-wide
   luqua-cart.js auto-shows the sticky add-to-cart bar off #atc-btn with no JS change. CSS is ported
   verbatim from the PDP's .pick (page 74) so the two pages match, scoped to page 77 and given token
   fallbacks. Markup carries the landing's own approved bundle copy (no wording change). Tiers 1/2/3/6.
   The former .bundles/.bundle grid overrides are gone with that markup. */
.page-id-77 .entry-content .bundle-select{display:flex;flex-direction:column;gap:.85rem;max-width:520px;margin:2.4rem auto 0}
.page-id-77 .entry-content .bundle-select .pick{position:relative;display:grid;grid-template-columns:auto 1fr auto;gap:1rem;align-items:center;background:#fff;border:1.5px solid var(--line,#ece6e1);border-radius:var(--r-md,14px);padding:1rem 1.2rem;cursor:pointer;text-align:left;transition:border-color .15s ease,box-shadow .15s ease}
.page-id-77 .entry-content .bundle-select .pick:hover{border-color:var(--violet-300,#b7a9e8)}
.page-id-77 .entry-content .bundle-select .pick.on{border-color:var(--violet,#5347C0);box-shadow:var(--shadow-md,0 10px 24px rgba(44,44,52,.10))}
.page-id-77 .entry-content .bundle-select .pick input{accent-color:var(--violet,#5347C0);width:20px;height:20px;margin:0}
.page-id-77 .entry-content .bundle-select .pick b{display:block;font-size:.98rem;font-weight:700;color:var(--charcoal,#2c2c34)}
.page-id-77 .entry-content .bundle-select .pick span{font-size:.82rem;color:var(--muted,#8a8391)}
.page-id-77 .entry-content .bundle-select .pick .p{font-family:var(--display,'Playfair Display',serif);font-size:1.15rem;color:var(--charcoal,#2c2c34);text-align:right;white-space:nowrap}
.page-id-77 .entry-content .bundle-select .pick .p s{display:block;font-family:var(--body,'Montserrat',sans-serif);font-size:.78rem;color:var(--muted,#8a8391)}
.page-id-77 .entry-content .bundle-select .pick .flag{position:absolute;top:-11px;left:1rem;background:var(--pack-coral,#E2545F);color:#fff;font-size:12.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;border-radius:999px;padding:.28em .9em;line-height:1.3}
.page-id-77 .entry-content #atc-btn{display:flex;width:100%;max-width:520px;margin:1.15rem auto 0}
.page-id-77 .entry-content .offer-shot{max-width:190px;margin:0 auto 2.2rem}
.page-id-77 .entry-content .offer-shot img{width:100%;filter:drop-shadow(0 18px 34px rgba(20,16,60,.22))}

/* (4b) The offer read as three different widths stacked in one section (owner feedback 2026-07-26):
   the .founding launch band, the .fine reassurance line and the soy .callout all ran at the full
   1104px .wrap width while the buy box itself (.bundle-select / .qty-row / #atc-btn) is 520px. So
   copy that belongs TO the buy box was 2.1x the width of the buy box, and the eye read them as
   section banners rather than as part of the purchase. Pinned all three to the same 520px column so
   the whole buy cluster shares one edge.
   ⚠️ Related latent bug, deliberately NOT fixed site-wide here: the callout's own
   <div class="wrap narrow"> does not narrow. `.wrap{max-width:var(--max)}` is declared AFTER
   `.narrow{max-width:var(--narrow)}` at equal specificity, so .wrap wins and every `wrap narrow`
   combo renders at 1200px instead of 760px. Page 77 has exactly one such element (this callout),
   which is why the local max-width below is enough. Fixing the combo properly means adding
   `.wrap.narrow{max-width:var(--narrow)}`, which would resize elements on other pages too. */
.page-id-77 .entry-content .offer .founding{max-width:520px;margin-left:auto;margin-right:auto}
.page-id-77 .entry-content .offer .fine{max-width:520px;margin-left:auto;margin-right:auto}
.page-id-77 .entry-content .wrap.narrow>.callout{max-width:520px;margin-left:auto;margin-right:auto}

/* (5) FAQ collided with the community strip above it (FAQ ships inline padding-top:0). Add a top
   gap so the two sections breathe. */
.page-id-77 .entry-content .faq{margin-top:clamp(2.5rem,5vw,4.5rem)!important}

/* ============================================================================
   AIDA landing rebuild, page 77 (2026-07-21). Source: docs/AIDA-LANDING-COPY.md
   Two structural needs the page's inline CSS does not cover.
   ========================================================================= */

/* (6) The Interest section now carries FOUR moments (night/morning/afternoon/evening)
   instead of three. Inline CSS ships .moments as repeat(3,1fr), which would leave a
   lone orphan card on row 2. Two-up reads better for Madam Lim anyway: wider cards,
   larger type, fewer things per row. Mobile 1-col is inherited unchanged. */
.page-id-77 .entry-content .moments{grid-template-columns:repeat(2,1fr)}
@media (max-width:860px){.page-id-77 .entry-content .moments{grid-template-columns:1fr}}

/* (6b) Consequence of 2-up: override (2) pins .ph to 4:5, which at a 3-up card width
   (~320px) gave a sensible ~400px frame. At 2-up the card is ~490px, so 4:5 balloons to
   ~612px and four of them turn the Interest section into a scroll marathon, which is the
   opposite of what this rebuild is for. Drop to 4:3 (~490x367) and KEEP override (2)'s
   `object-position:center 22%`, which is what actually stops faces being sliced. The
   original 3:2 problem was the centred crop, not the landscape ratio itself.
   Mobile returns to 4:5, where the card is narrow and the tall frame reads well. */
.page-id-77 .entry-content .moment .ph{aspect-ratio:4/3!important}
@media (max-width:860px){.page-id-77 .entry-content .moment .ph{aspect-ratio:4/5!important}}

/* (7) New .ritual section (Desire stage bridge) has no inline background. Generic
   `section{padding:var(--sy) 0}` already gives it vertical rhythm; it only needs a
   surface that separates it from .product above and .compare (warm-white) below. */
.page-id-77 .entry-content .ritual{background:var(--blush,#faf5f2)}
.page-id-77 .entry-content .ritual p{color:var(--muted,#8a8391)}
.page-id-77 .entry-content .ritual p+p{margin-top:.9rem}

/* (8) About page: the facility photo slot renders its own art-direction brief as visible
   body text ("FACILITY / PRODUCTION PHOTO ... 1200x900 [SHOT NEEDED]"). No facility photo
   exists yet, so hide the slot the way .reviews/.vids are hidden rather than shipping a
   brief to customers. Page 75 has exactly one .ph element, so this cannot over-reach.
   UNHIDE when the shot lands. */
.page-id-75 .entry-content .ph{display:none}

/* ============================================================================
   (9) Ingredients section readability, page 77 (owner 2026-07-21)
   Owner: "ingredient image is too small, and the section is very long on desktop
   because all ingredients stack vertically."
   Root cause was structural, not cosmetic: .formula lived inside the 1.15fr right
   column of .product-grid (~600px at a 1200 wrap), so five cards could only stack,
   while the pack shot sat beside them in dead space. Markup now moves .formula and
   .note out into a full-width .formula-wrap below the pack/heading row, which is
   what makes the rest of this block possible.
   ========================================================================= */

/* Two-up across the full wrap: five cards become three rows instead of five, and each
   card gets ~2x the horizontal room so the descriptions stop wrapping so hard. */
.page-id-77 .entry-content .formula{grid-template-columns:repeat(2,1fr);gap:1.1rem}
/* Odd count: the fifth card spans the full width rather than orphaning half-empty.
   "Daily basics" is the natural closer, so this reads deliberate. */
.page-id-77 .entry-content .formula .f-row:last-child{grid-column:1 / -1}

/* Bigger ingredient art. CEILING IS THE ASSET, not the CSS: the source PNGs are 86x89
   native, and .f-row img carries 6px padding, so a 78px box renders ~66px of artwork,
   just under native. Going beyond this upscales and softens them. Anything larger needs
   new ingredient renders at 2x (>=180px) from the content team. */
.page-id-77 .entry-content .f-row img{width:78px;height:78px;border-radius:14px;padding:8px}
.page-id-77 .entry-content .f-row{gap:1.3rem;padding:1.25rem 1.4rem}
.page-id-77 .entry-content .f-row b{font-size:1.05rem;margin-bottom:.25rem}
.page-id-77 .entry-content .f-row span{font-size:.9rem;line-height:1.55}

/* The heading column is short now that the list moved out, so give the pack shot room
   and stop the grid stretching. */
.page-id-77 .entry-content .product-grid{align-items:center;margin-bottom:clamp(2rem,4vw,3.2rem)}
.page-id-77 .entry-content .product .lede{margin-top:1rem;font-size:1rem;line-height:1.65;color:var(--violet-100,#ded9f7)}
.page-id-77 .entry-content .formula-wrap .note{margin-top:1.4rem;text-align:center}

/* Below the 2-up breakpoint everything returns to a single column, including the
   spanned last card, so nothing is left mid-width on phones. */
@media (max-width:900px){
  .page-id-77 .entry-content .formula{grid-template-columns:1fr}
  .page-id-77 .entry-content .formula .f-row:last-child{grid-column:auto}
  .page-id-77 .entry-content .f-row img{width:64px;height:64px}
}

/* (9b) The "ingredient images" are not icons. Each 86x89 PNG is a rasterised mini info-card:
   product photo on top, then the ingredient name, then a claim line ("Traditionally used to
   support women's...", "Supports gut health and nutrient..."). Three problems, all of which
   got MORE visible once (9) enlarged them:
     1. The baked caption is illegible at any size the layout can afford, and it duplicates
        the card title and description sitting right next to it.
     2. The claim text is inside a raster. PlantBio cannot review, translate or grep it, and
        a claim is a claim regardless of medium. That is exactly what the brain's compliance
        rule is meant to catch.
     3. The photo is the only part carrying information here.
   The workaround was: crop to the photograph and drop the caption, via cover + top
   alignment on a 92x54 window showing the top ~57% of the source.

   ✅ RESOLVED 2026-07-21 — the asset request above was fulfilled, so the workaround is GONE.
   The five `ingredients/*.png` are now clean 240x240 photographs with **no baked text**,
   sourced from PlantBio's own MenoLuv e-flyer (`docs/MenoLUV_e-flyer_EN_Msia_FA_220426.pdf`,
   pages 6-7) and matched to each group's heading:
     soy -> soybeans · chasteberry -> vitex flowers · mulberry -> mulberries
     inulin -> Chinese yam (that file is "The roots" group, the name is historical)
     vitamins -> chicory root (the inulin source, "The daily basics" group)
   Old baked-text versions kept in `docs/image-originals/ingredients/`.

   With square sources, override (9) above (78px square, 64px under 900px, contain + padding)
   is correct again and this block no longer needs to override anything. Deleting the rules
   rather than the comment, so the history stays readable. Compliance win too: the claim text
   that used to be baked into a raster, where PlantBio could not review or translate it, is
   simply gone. */

/* ============================================================================
   (10) Page 74 AIDA pass (2026-07-21) — styles for the three new blocks and the
   block that replaced the fabricated star rating. Source: docs/AIDA-LANDING-COPY.md
   Part 2. Scoped page-id-74 because page 74 carries its own inline CSS and none of
   these class names exist there. Sections inherit the page's generic
   `section{padding:var(--sy) 0}` rhythm, so only the div blocks set their own spacing.
   ============================================================================ */

/* (10a) Replaces `.stars` — five gold stars + "Launch reviews coming" on a product with
   zero reviews was a fabricated rating. This states the two things that are true. */
.page-id-74 .entry-content .launch-note{
  font-size:.82rem;color:var(--muted,#6E6E7A);font-weight:500;margin:.1rem 0 1.1rem
}
.page-id-74 .entry-content .launch-note b{
  color:var(--pack-coral,#F86F5B);font-weight:700;letter-spacing:.12em;
  text-transform:uppercase;font-size:.72rem;margin-right:.45rem
}

/* (10b) INTEREST stage. The PDP had no Interest section at all, which was Dr. Ooi's
   "doesn't feel the menopause women's pains" note. 2-up not 4-up: same reasoning as
   override (6) on page 77 — wider cards, larger type, elder-friendly brief. */
.page-id-74 .entry-content .moments-pdp{background:var(--sand,#F3EEF0)}
.page-id-74 .entry-content .m-grid{
  display:grid;grid-template-columns:repeat(2,1fr);gap:1rem;margin-top:2.4rem
}
.page-id-74 .entry-content .m-grid .m{
  background:var(--warm-white,#FFFDFB);border:1px solid var(--line,#E7E1E6);
  border-radius:var(--r-md,16px);padding:1.4rem 1.5rem
}
.page-id-74 .entry-content .m-grid .m b{
  display:block;font-family:var(--display,Georgia,serif);font-weight:600;
  font-size:1.05rem;color:var(--charcoal,#2C2C34);margin-bottom:.4rem
}
.page-id-74 .entry-content .m-grid .m span{
  display:block;font-size:.95rem;line-height:1.65;color:var(--ink,#4A4A55)
}
.page-id-74 .entry-content .m-bridge{
  max-width:44em;margin:2rem auto 0;text-align:center;
  font-size:1rem;line-height:1.7;color:var(--muted,#6E6E7A)
}

/* (10c) Provenance strip. `.reviews` and `.vids` are still CSS-hidden pending real
   assets (B1/B2), which left a visible jump. This fills it with something true rather
   than simulated social proof. Remove when real reviews ship. */
.page-id-74 .entry-content .provenance{
  /* margin-bottom: .reviews and .vids below are display:none, so without it the strip
     butts straight against the FemeLuv cross-sell band with no breathing room. */
  max-width:var(--max,1200px);margin:0 auto 3rem;padding:1.5rem var(--gut,1.5rem);
  text-align:center;background:var(--blush,#F8F5F7);
  border-radius:var(--r-md,16px);border:1px solid var(--line,#E7E1E6)
}
.page-id-74 .entry-content .provenance b{
  display:block;font-family:var(--display,Georgia,serif);font-size:1.1rem;
  color:var(--charcoal,#2C2C34);margin-bottom:.3rem
}
.page-id-74 .entry-content .provenance span{font-size:.92rem;color:var(--muted,#6E6E7A)}

/* (10d) ACTION stage. The page previously ended on a CSS-hidden video carousel, so the
   last thing a visitor saw was nothing. Makes no outcome promise — it contrasts acting
   with not acting, which is unfalsifiable and therefore compliance-safe. */
.page-id-74 .entry-content .final-close{background:var(--blush,#F8F5F7);text-align:center}
.page-id-74 .entry-content .final-close p{
  max-width:40em;margin:1rem auto 1.8rem;font-size:1.05rem;line-height:1.7;
  color:var(--ink,#4A4A55)
}

/* ============================================================================
   (15) Quantity stepper + running total (owner 2026-07-21)
   The bundle radios chose which set; nothing let a shopper buy two of the same set.
   onecare.store's pattern, which the owner referenced: radios -> TOTAL -> [- n +] [Add].
   Sits directly above #atc-btn on pages 74 and 77. Behaviour is in luqua-cart.js.
   ============================================================================ */
.page .entry-content .qty-row{
  display:flex;align-items:center;justify-content:space-between;gap:1rem;margin:0 0 .9rem
}
.page .entry-content .qty{
  display:inline-flex;align-items:center;border:1px solid var(--line,#E7E1E6);
  border-radius:999px;background:var(--warm-white,#FFFDFB);overflow:hidden
}
.page .entry-content .qty-btn{
  width:42px;height:44px;border:0;background:transparent;cursor:pointer;
  font-size:1.15rem;line-height:1;color:var(--charcoal,#2C2C34);
  display:flex;align-items:center;justify-content:center;transition:background .15s ease
}
.page .entry-content .qty-btn:hover{background:var(--blush,#F8F5F7)}
.page .entry-content .qty-in{
  width:46px;height:44px;border:0;background:transparent;text-align:center;
  font-family:var(--body,inherit);font-size:1rem;font-weight:600;
  color:var(--charcoal,#2C2C34);-moz-appearance:textfield
}
.page .entry-content .qty-in:focus{outline:none}
.page .entry-content .qty-total{text-align:right;line-height:1.25}
.page .entry-content .qty-total span{
  display:block;font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--muted,#6E6E7A)
}
.page .entry-content .qty-total .qty-sum{
  font-family:var(--display,Georgia,serif);font-size:1.5rem;color:var(--charcoal,#2C2C34)
}
/* Stepper unit label (owner 2026-07-24): the stepper multiplies PLANS, not boxes. Labelling it
   "sets" (plus the box total on the CTA) stops it being read as a box count. margin-right:auto
   keeps it grouped with the stepper on the left while the total stays right. */
.page .entry-content .qty-unit{margin-right:auto;font-family:var(--body,'Montserrat',sans-serif);
  font-size:.82rem;color:var(--muted,#6E6E7A)}
/* Overpay nudge. Shown only when the chosen sets cost more than the cheapest tier
   combination for the same number of boxes. Peach/advisory rather than alarm red: it is
   an offer of a better deal, not an error. */
.page .entry-content .qty-nudge{
  margin:0 0 .9rem;padding:.75rem .95rem;border-radius:var(--r-sm,10px);
  background:var(--advisory-bg,#FBEBDD);border:1px solid rgba(178,94,42,.22);
  font-size:.86rem;line-height:1.55;color:var(--advisory,#B25E2A)
}
.page .entry-content .qty-nudge b{color:var(--advisory,#B25E2A);font-weight:700}
.page .entry-content .qty-nudge[hidden]{display:none}

/* page 77's buy column is narrower and sits on a light card; same component, tighter.
   Cap the qty-row to the picker/CTA width (520px, centred) so on the wide .offer container the
   stepper and total sit in one aligned column instead of stretching apart (owner 2026-07-25). */
.page-id-77 .entry-content .qty-row{max-width:520px;margin:1.5rem auto .8rem}
/* Transplanted PDP moments section (2026-07-25): it followed a padded buy-box on the PDP, but on
   the ads landing it sits right under the full-bleed USP marquee, so add its own top gap (padding,
   since .entry-content>* zeroes margins). Verify the rendered gap. */
.page-id-77 .entry-content .moments2{padding-top:clamp(2.75rem,6vw,4.5rem)!important}
@media (max-width:420px){
  .page .entry-content .qty-total .qty-sum{font-size:1.25rem}
}

/* ============================================================================
   (14) B18 "How MenoLuv works": mechanism cards + evidence table (owner 2026-07-21)
   The flyer's mechanism and research content was on no page at all. It is the strongest
   material available and it is PlantBio's own, so it goes between the formula band (what
   is in it) and the compare table (why it beats alternatives) — AIDA Desire, mechanism
   layer. Whole section is claim-bearing and wrapped in CLAIM markers in the markup.
   Sits on the light band, so cards are blush on warm-white rather than the violet
   treatment used inside the formula band.
   ============================================================================ */
.page .entry-content .science{background:linear-gradient(180deg,var(--warm-white,#FFFDFB) 0%,var(--violet-050,#F3F1FC) 100%)}
.page .entry-content .sci-lead{
  margin-top:.9rem;font-size:1.02rem;line-height:1.7;color:var(--muted,#6E6E7A)
}
.page .entry-content .sci-split{
  display:grid;grid-template-columns:0.82fr 1.18fr;gap:1.9rem;
  margin-top:2.6rem;align-items:stretch
}
.page .entry-content .sci-photo{
  border-radius:var(--r-lg,18px);overflow:hidden;background:var(--blush,#F8F5F7);
  box-shadow:0 20px 46px rgba(83,71,192,.14)
}
.page .entry-content .sci-photo img{width:100%;height:100%;min-height:440px;object-fit:cover;display:block}
.page .entry-content .sci-grid{text-align:left}
.page .entry-content .sci-grid .sci{
  display:grid;grid-template-columns:44px minmax(0,1fr);column-gap:1.15rem;
  padding:1.4rem 0;border-top:1px solid var(--line,#E7E1E6)
}
.page .entry-content .sci-grid .sci:first-child{border-top:0;padding-top:0}
.page .entry-content .sci-grid .sci-ic{
  grid-column:1;grid-row:1/-1;align-self:start;display:flex;align-items:center;justify-content:center;
  width:44px;height:44px;border-radius:12px;background:var(--violet-050,#F3F1FC);
  color:var(--violet,#5347C0);margin:0
}
.page .entry-content .sci-grid .sci-ic svg{width:22px;height:22px}
.page .entry-content .sci-grid .sci-n{display:none}
.page .entry-content .sci-grid .sci-for{
  grid-column:2;grid-row:1;color:#A6385A;font-weight:600;
  font-size:.9rem;line-height:1.4;margin:0 0 .35rem
}
.page .entry-content .sci-grid .sci b{
  grid-column:2;grid-row:2;display:block;font-family:var(--display,Georgia,serif);
  font-size:1.18rem;line-height:1.15;color:var(--charcoal,#2C2C34);margin:0 0 .2rem
}
.page .entry-content .sci-grid .sci-ing{
  grid-column:2;grid-row:3;display:block;font-size:.8rem;letter-spacing:.01em;
  color:var(--muted,#6E6E7A);margin:0 0 .55rem
}
.page .entry-content .sci-grid .sci p{
  grid-column:2;grid-row:4;font-size:.92rem;line-height:1.6;color:var(--ink,#4A4A55);margin:0
}
.page .entry-content .sci-h3{
  margin:3rem 0 1.2rem;text-align:center;font-family:var(--display,Georgia,serif);
  font-size:1.4rem;color:var(--charcoal,#2C2C34)
}
/* the table must scroll inside its own box, never the page */
.page .entry-content .sci-tw{overflow-x:auto;-webkit-overflow-scrolling:touch}
.page .entry-content .sci-table{
  width:100%;border-collapse:separate;border-spacing:0;min-width:640px;
  background:#fff;border-radius:var(--r-lg,18px);overflow:hidden;box-shadow:0 14px 34px rgba(83,71,192,.09)
}
.page .entry-content .sci-table th{
  text-align:left;font-size:.74rem;letter-spacing:.1em;text-transform:uppercase;
  background:var(--violet,#5347C0);color:var(--warm-white,#FFFDFB);padding:.9rem 1.1rem;font-weight:600
}
.page .entry-content .sci-table td{
  padding:.9rem 1.1rem;font-size:.9rem;line-height:1.55;color:var(--ink,#4A4A55);
  border-bottom:1px solid var(--line,#E7E1E6);vertical-align:top
}
.page .entry-content .sci-table tbody tr:nth-child(odd){background:var(--violet-050,#F3F1FC)}
.page .entry-content .sci-table tbody tr:last-child td{border-bottom:0}
.page .entry-content .sci-table td:first-child{font-weight:600;color:var(--charcoal,#2C2C34)}
.page .entry-content .sci-note{
  margin-top:1.1rem;text-align:center;font-size:.8rem;line-height:1.6;color:var(--muted,#6E6E7A)
}
@media (max-width:820px){
  .page .entry-content .sci-split{grid-template-columns:1fr;gap:1.3rem}
  .page .entry-content .sci-photo img{min-height:0;aspect-ratio:3/2}
  .page .entry-content .sci-grid .sci{padding:1.3rem 0}
}

/* ============================================================================
   (13) Per-ingredient photo grid (owner request 2026-07-21)
   Sits under the five role cards inside the formula band on pages 74 and 77. The role
   cards carry the narrative ("fifteen ingredients, five roles"); this grid carries the
   proof, which is the thing LUQUA actually competes on. Competitors shout claims; the
   counter is showing the label (see swipe cards 001 and 002).
   Ten botanicals have a photograph in PlantBio's e-flyer. The four that do not (bupleurum,
   B6, E, stevia) are named in `.ing-rest` rather than given an empty tile or a stand-in
   photo. Captions are neutral factual descriptors only, so nothing here carries a claim.
   Sits on the violet band, hence the translucent white tiles matching `.group` / `.f-row`.
   ============================================================================ */
.page .entry-content .ing-grid{
  display:grid;grid-template-columns:repeat(5,1fr);gap:.9rem;margin-top:1.6rem
}
.page .entry-content .ing-grid .ing{
  margin:0;padding:.9rem .6rem;text-align:center;
  background:rgba(255,253,251,.08);border:1px solid rgba(255,253,251,.18);
  border-radius:var(--r-md,16px)
}
.page .entry-content .ing-grid .ing img{
  width:64px;height:64px;margin:0 auto .6rem;display:block;
  object-fit:contain;background:var(--warm-white,#FFFDFB);
  border-radius:14px;padding:6px
}
.page .entry-content .ing-grid .ing figcaption b{
  display:block;font-size:.82rem;line-height:1.35;color:var(--warm-white,#FFFDFB);font-weight:600
}
.page .entry-content .ing-grid .ing figcaption span{
  display:block;margin-top:.2rem;font-size:.72rem;line-height:1.4;
  color:var(--violet-100,#DFD5FA);opacity:.85
}
.page .entry-content .ing-rest{
  margin-top:1rem;text-align:center;font-size:.84rem;
  color:var(--violet-100,#DFD5FA);opacity:.9
}
@media (max-width:1100px){
  .page .entry-content .ing-grid{grid-template-columns:repeat(4,1fr)}
}
@media (max-width:820px){
  .page .entry-content .ing-grid{grid-template-columns:repeat(3,1fr);gap:.7rem}
}
@media (max-width:520px){
  .page .entry-content .ing-grid{grid-template-columns:repeat(2,1fr)}
  .page .entry-content .ing-grid .ing img{width:56px;height:56px}
}

/* ============================================================================
   (12) Scroll reversal lag at the top/bottom of the page (owner reported 2026-07-21)
   Page CSS ships `html,body{overflow-x:hidden}` as a horizontal-scroll guard (needed:
   full-bleed sections, the max-content ticker, and .product-grid img at width:130% with a
   negative margin all overflow horizontally).

   The problem is `hidden`, not the guard. `overflow-x:hidden` makes an element a SCROLL
   CONTAINER. Applying it to html AND body creates two nested scrollers, so reaching the end
   of one chains the scroll to the other, and reversing direction has to unwind that chain.
   That is the dead spot the owner felt when scrolling back from the very top or bottom.

   `overflow-x:clip` clips identically but does NOT create a scroll container, so the guard
   survives and the nesting disappears. It also stops suppressing `position:sticky`, which
   this file already documents as collateral damage at block (3) above.

   Supported Chrome 90+, Firefox 81+, Safari 16+.

   !important is required, not lazy: the page's own `<style>` block lives inside the wp:html
   content in <body>, so it comes AFTER this linked stylesheet in document order. At equal
   specificity the later rule wins, so a plain `html,body{overflow-x:clip}` here would be
   silently overridden and do nothing.
   ============================================================================ */
html, body { overflow-x: clip !important }

/* ============================================================================
   (11) Scroll smoothness: sticky-header backdrop cost (owner reported 2026-07-21)
   The page CSS ships `header{position:sticky; backdrop-filter:blur(16px) saturate(1.5)}`.
   A full-width sticky element with a backdrop-filter forces the compositor to re-sample
   and blur everything behind it on EVERY frame of scrolling, and `saturate()` adds a
   second pass on top of the blur. It is the most expensive thing on these pages and the
   likeliest cause of the reported jank.
   Halving the blur radius and dropping saturate cuts that per-frame work substantially
   while keeping the frosted look, which is a deliberate design decision elsewhere on the
   site. Background opacity goes .92 -> .94 so less blur still reads as glass.
   TO REVERT: delete this block. TO GO FURTHER: drop backdrop-filter entirely and set the
   background to rgba(255,253,251,.98), which removes the per-frame cost completely at the
   price of the glass effect on the header only.
   ============================================================================ */
.page .entry-content header{
  background:rgba(255,253,251,.94);
  backdrop-filter:blur(8px);
  -webkit-backdrop-filter:blur(8px)
}

/* (10e) B16 90-day journey (swipe card 002). Answers "how long until I know?", the
   strongest unhandled objection in supplements, and makes the 3-box read as the honest
   unit of trial rather than the expensive option. Three columns deliberately mirror the
   three boxes.
   Scoped `.page` not `page-id-74`: the section ships on BOTH 74 and 77 and the class
   names exist nowhere else, so one rule serves both. */
/* The band BELOW the journey resolves to warm-white on both pages (74: unclassed section
   inheriting body; 77: .compare sets it explicitly), and the journey is warm-white too.
   With no colour boundary between them, `section{padding:var(--sy) 0}` on each stacks into
   ~200px of dead space, which is what the owner spotted on 77. The band ABOVE the journey
   is a different colour on both pages, so its top padding still does real work. Hence the
   asymmetry: keep padding-top, collapse padding-bottom and let the next section's own top
   padding carry the rhythm. */
.page .entry-content .journey{
  background:var(--warm-white,#FFFDFB);
  padding-bottom:0
}
.page .entry-content .j-lead{
  margin-top:.9rem;font-size:1rem;line-height:1.7;color:var(--muted,#6E6E7A)
}
.page .entry-content .j-grid{
  display:grid;grid-template-columns:repeat(3,1fr);gap:1rem;margin-top:2.4rem
}
.page .entry-content .j-grid .j{
  background:var(--blush,#F8F5F7);border:1px solid var(--line,#E7E1E6);
  border-radius:var(--r-md,16px);padding:1.5rem 1.4rem
}
.page .entry-content .j-grid .j-step{
  display:block;font-size:.7rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--pack-coral,#F86F5B);margin-bottom:.6rem
}
.page .entry-content .j-grid .j b{
  display:block;font-family:var(--display,Georgia,serif);font-weight:600;font-size:1.05rem;
  color:var(--charcoal,#2C2C34);margin-bottom:.45rem
}
.page .entry-content .j-grid .j span:not(.j-step){
  display:block;font-size:.93rem;line-height:1.65;color:var(--ink,#4A4A55)
}
.page .entry-content .j-foot{
  margin-top:1.8rem;text-align:center;font-family:var(--display,Georgia,serif);
  font-size:1.1rem;color:var(--charcoal,#2C2C34)
}

@media (max-width:860px){
  .page-id-74 .entry-content .m-grid{grid-template-columns:1fr;gap:.85rem}
  .page-id-74 .entry-content .m-grid .m{padding:1.15rem 1.25rem}
  .page .entry-content .j-grid{grid-template-columns:1fr;gap:.85rem}
  .page .entry-content .j-grid .j{padding:1.25rem 1.25rem}
}

/* (9) Duplicate sticky add-to-cart bar (owner 2026-07-22): pages 74 and 77 ship their own
   .sticky-cta from the approved mockup, and luqua-cart.js separately injects .luqua-stickybar.
   Both are position:fixed at the bottom, so two bars stacked. Owner chose to keep the injected
   one: it carries the product thumbnail, shows the live selected-bundle price, and its button
   actually adds to cart, where .sticky-cta only links to #buy. Hidden at the theme layer rather
   than cut from the page markup, matching how the PDP behaviours were wired in (5) and (6).
   #atc-btn sits outside .sticky-cta, so the injected bar's scroll trigger is unaffected. */
.page-id-74 .entry-content .sticky-cta,
.page-id-77 .entry-content .sticky-cta{display:none}

/* (10) Sticky buy box upgrade + change-package bottom sheet (owner 2026-07-22, backlog B20).
   Modelled on onecare.store/buy/lolvita: the bar carries the selected package with a "Change"
   affordance opening a bottom sheet, an optional in-bar quantity stepper, and a direct Add anchor.
   See luqua-cart.js and DEVIATIONS.md. */
/* "Change" is now a clear pill + chevron (owner 2026-07-24): the underlined text link read as
   optional and was easy to miss, so switching the plan was not discoverable. The whole plan label
   becomes a tappable selector control. */
.luqua-stickybar__change{display:inline-flex;align-items:center;gap:.35rem;max-width:100%;
  padding:.18rem .55rem;border:1px solid var(--line,#E7E1E6);border-radius:999px;background:#fff;
  cursor:pointer;text-align:left;font:inherit;transition:border-color .15s ease}
.luqua-stickybar__change:hover{border-color:#E2545F}
.luqua-stickybar__change .luqua-stickybar__label{margin:0}
.luqua-stickybar__changehint{flex:0 0 auto;font-family:var(--body,'Montserrat',sans-serif);
  font-size:.68rem;font-weight:600;color:#E2545F}
.luqua-stickybar__caret{flex:0 0 auto;width:.4em;height:.4em;margin-left:-.06rem;
  border-right:2px solid #E2545F;border-bottom:2px solid #E2545F;transform:translateY(-1px) rotate(45deg)}
.luqua-stickybar__qty{display:none;align-items:center;gap:.4rem;flex:0 0 auto}
.luqua-stickybar.has-qty .luqua-stickybar__qty{display:inline-flex}
.luqua-stickybar__qtybtn{width:30px;height:30px;flex:0 0 30px;border:1px solid var(--line,#E7E1E6);
  background:#fff;border-radius:8px;font-size:1.05rem;line-height:1;cursor:pointer;color:var(--charcoal,#2C2C34)}
.luqua-stickybar__qtyn{min-width:1.1rem;text-align:center;font-family:var(--body,'Montserrat',sans-serif);
  font-weight:600;font-size:.9rem;color:var(--charcoal,#2C2C34)}

.luqua-pkgsheet-overlay{position:fixed;inset:0;z-index:1000;background:rgba(28,24,34,.45);
  opacity:0;visibility:hidden;transition:opacity .25s ease}
.luqua-pkgsheet-overlay.is-open{opacity:1;visibility:visible}
.luqua-pkgsheet{position:fixed;left:0;right:0;bottom:0;z-index:1001;max-height:85vh;overflow:auto;
  background:var(--warm-white,#FFFDFB);border-radius:20px 20px 0 0;
  padding:.75rem clamp(1rem,4vw,1.75rem) calc(1.25rem + env(safe-area-inset-bottom,0px));
  box-shadow:0 -12px 40px rgba(44,44,52,.22);transform:translateY(110%);
  transition:transform .3s cubic-bezier(.4,0,.2,1)}
.luqua-pkgsheet.is-open{transform:translateY(0)}
.luqua-pkgsheet__handle{display:block;width:40px;height:4px;border-radius:999px;
  background:var(--line,#E7E1E6);margin:.25rem auto .9rem}
.luqua-pkgsheet__title{font-family:var(--display,'Playfair Display',serif);font-size:1.15rem;
  color:var(--charcoal,#2C2C34);margin-bottom:.85rem}
.luqua-pkgsheet__list{display:flex;flex-direction:column;gap:.6rem;margin-bottom:1rem}
.luqua-pkgsheet__opt{display:flex;align-items:center;gap:.85rem;width:100%;text-align:left;cursor:pointer;
  padding:.85rem 1rem;border:1.5px solid var(--line,#E7E1E6);border-radius:14px;background:#fff;font:inherit}
.luqua-pkgsheet__opt.is-selected{border-color:#5347C0;box-shadow:0 0 0 1px #5347C0 inset}
.luqua-pkgsheet__radio{flex:0 0 auto;width:20px;height:20px;border-radius:50%;
  border:2px solid var(--line,#CFC7CE);position:relative}
.luqua-pkgsheet__opt.is-selected .luqua-pkgsheet__radio{border-color:#5347C0}
.luqua-pkgsheet__opt.is-selected .luqua-pkgsheet__radio::after{content:"";position:absolute;inset:3px;
  border-radius:50%;background:#5347C0}
.luqua-pkgsheet__optbody{display:flex;flex-direction:column;gap:.15rem;min-width:0;flex:1 1 auto}
.luqua-pkgsheet__opttitle{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;
  font-family:var(--body,'Montserrat',sans-serif);font-weight:600;font-size:.95rem;color:var(--charcoal,#2C2C34)}
.luqua-pkgsheet__optsub{font-size:.78rem;color:var(--muted,#6E6E7A);line-height:1.3}
.luqua-pkgsheet__optprice{flex:0 0 auto;text-align:right;font-family:var(--display,'Playfair Display',serif);
  font-size:1.05rem;color:var(--charcoal,#2C2C34);white-space:nowrap}
.luqua-pkgsheet__optprice s{display:block;font-family:var(--body,'Montserrat',sans-serif);
  font-size:.7rem;font-weight:500;color:var(--muted,#6E6E7A)}
/* The sheet copies .p's innerHTML, so it inherits the savings <i> but NOT the page-scoped
   CSS that styles it. Without this it rendered as default italic. Keep in step with
   `.pick .p i` on pages 74 and 77. */
.luqua-pkgsheet__optprice i{display:block;width:-moz-fit-content;width:fit-content;margin:.3rem 0 0 auto;
  padding:.2em .55em;border-radius:999px;background:#C8102E;color:#fff;
  font-family:var(--body,'Montserrat',sans-serif);font-style:normal;
  font-size:.68rem;font-weight:800;letter-spacing:.01em;white-space:nowrap}
.luqua-pkgsheet__flag{flex:0 0 auto;font-family:var(--body,'Montserrat',sans-serif);font-size:.62rem;
  font-weight:700;letter-spacing:.03em;text-transform:uppercase;color:#fff;border-radius:999px;padding:.12rem .5rem}
.luqua-pkgsheet__confirm{display:block;width:100%;min-height:50px;border:0;border-radius:999px;
  background:#E2545F;color:#fff;font-family:var(--body,'Montserrat',sans-serif);font-size:1rem;
  font-weight:600;cursor:pointer;transition:background .18s ease}
.luqua-pkgsheet__confirm:hover{background:#C7434D}
body.luqua-pkgsheet-open{overflow:hidden}
@media (max-width:560px){ .luqua-stickybar.has-qty .luqua-stickybar__qty{display:none} }

/* (11) PDP hero: H1 is now the product name (was a keyword sentence); the "menopause supplement"
   head term moved to this <h2> descriptor so SEO holds while the name leads (owner 2026-07-22).
   See DEVIATIONS.md. Modelled on onecare / befree / the Purest / Moom, which all lead with the name. */
.page-id-74 .entry-content .buy .descriptor,
.page-id-77 .entry-content .buy .descriptor{
  font-family:var(--body,'Montserrat',sans-serif);font-size:1.05rem;font-weight:600;
  color:var(--muted,#6E6E7A);line-height:1.35;letter-spacing:0;margin:.1rem 0 .7rem
}
/* ™ was inheriting the full text size. Make it a small superscript site-wide
   (owner 2026-07-22; generalised from the PDP H1 rule to every .tm on the site). */
.entry-content .tm{font-size:inherit;vertical-align:baseline;font-weight:inherit;letter-spacing:normal}
/* The .usp checklist inherited the default <ul> padding, pushing it ~30px right of the
   description. Zero it so the checkmarks line up with the paragraph left edge (owner 2026-07-22). */
.page-id-74 .entry-content .buy .usp{padding-left:0;margin-left:0}

/* (12) Readability pass for the 40+ ICP (owner 2026-07-22). Body text read too thin and
   low-contrast next to onecare / befree; this is also the brand's own elder-friendly mandate
   (DESIGN-SYSTEM §3: 16-18px, line-height 1.6+). Two levers: darken the muted reading colour
   for all page CONTENT (header/footer keep their own), and give the PDP hero reading text real
   weight. See DEVIATIONS. Scoped to `.entry-content` so dark-band sections that set their own
   text colour are unaffected. */
.page .entry-content{--muted:#54525E;font-weight:500}   /* darker muted + body copy 400->500 Medium
   (Montserrat 500 is loaded). Headings set their own 600 and are unaffected; only default-weight
   body copy inherits this. Owner: make all body copy heavier site-wide, 2026-07-22. */
.page-id-74 .entry-content .buy .sub{color:var(--ink,#413E4A);font-weight:500;font-size:1.06rem;line-height:1.62}
.page-id-74 .entry-content .buy .usp{font-weight:500;font-size:.98rem}
.page-id-74 .entry-content .buy .usp li{color:#2F2D38}

/* ── Canonical Q&A accordion (owner 2026-07-25) ────────────────────────────────
   The FAQ item was implemented three separate times and had drifted into three
   looks: the PDP (74) hairline rows, the FAQ page (76) white cards via BARE
   `details`/`summary` element selectors, and the ads landing (77) which carried
   TWO `.faq details` rules at equal specificity (its own card rule plus the
   hairline rule transplanted with the PDP rebuild) so both applied at once and
   the rows rendered as over-padded cards.
   Owner picked the hairline treatment as the standard. It lives here once, as a
   CLASS (never a bare element selector, which is what leaked on 76), so the item
   is identical everywhere while each page keeps its own section layout: the FAQ
   page keeps its sticky category nav and h3 groups, the product pages stay a
   plain single column.
   Deliberately NOT applied to `.acc` on 74/77 — that is the buy-box product
   details accordion (Benefits etc.), a different component with a different job.
   Answers are `p.faq-a` on 74/77 and a plain `p` on 76; both are covered. */
.luqua-acc details{border-top:1px solid rgba(120,43,144,.16);padding:1.1rem .2rem;background:none;border-left:0;border-right:0;border-bottom:0;border-radius:0;box-shadow:none;margin:0}
.luqua-acc details:last-of-type{border-bottom:1px solid rgba(120,43,144,.16)}
.luqua-acc summary{font-family:var(--body,'Montserrat',sans-serif);font-weight:600;font-size:1rem;color:#2a2140;cursor:pointer;list-style:none;display:flex;justify-content:space-between;align-items:center;gap:1rem;padding:0;background:none;min-height:0}
.luqua-acc summary::-webkit-details-marker{display:none}
.luqua-acc summary::after{content:"+";font-family:var(--body,'Montserrat',sans-serif);font-size:1.35rem;line-height:1;color:#782B90;font-weight:400;flex:0 0 auto}
.luqua-acc details[open] summary::after{content:"\2212"}
.luqua-acc details > p,.luqua-acc .faq-a{margin:.9rem 0 .2rem;padding:0;color:#5a5470;font-size:1rem;line-height:1.65}

/* ── Reduced motion (added 2026-07-25) ─────────────────────────────────────────────────────
   Quality floor that was missing entirely: none of the three stylesheets honoured
   prefers-reduced-motion, while the site runs hover lifts on every button and card, a sticky
   header that animates in and out, and an auto-scrolling marquee. For a 45+ audience, some of
   whom will have motion sensitivity, that is a real accessibility gap rather than a nicety.
   Transitions are neutralised rather than removed so state changes (colour on hover, open on
   accordion) still READ, they just do not travel. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .page .entry-content .trust-strip div:hover,
  .page a.btn-primary:hover,
  body.luqua-chrome .btn-primary:hover,
  .luqua-cart-btn--primary:hover,
  .pick:hover { transform: none !important; }
}

/* ---------------------------------------------------------------------------
   THE STRUCK PRICE (2026-07-27)
   ---------------------------------------------------------------------------
   No styles needed, and that is the decision, not an omission. The MY anchor stopped being
   an RRP and became the Shopee/Lazada price for the same bundle (RM269xN -> RM179xN), which
   shrank the displayed discount from 48-55% to 22-33%. Captioning the strike to say so was
   built and then removed on the owner's call: the strike stands as a bare figure, with no
   label beside it and no disclosure line under the picker. Do not reintroduce either without
   asking. Existing .rrp / .pick .p s rules in the page <style> blocks still style it. */
