/* Generated by scripts/build-css.sh - do not edit directly. */
/* Edit the partials under assets/css/ and re-run the script.  */

/* ---- 00-fonts.css ---- */
/* Poppins, self-hosted.
   The Shopify theme sets Poppins 400/500/600/700. inc/assets.php was already
   preloading two weights, but the files had never been added and no @font-face
   rule existed — so the whole store had been rendering in the system sans the
   entire time, with two 404s on every page for the preloads.

   Latin subset only: this store is English and PKR, and the full Google set is
   eight files per weight for scripts nothing here uses. Four weights, 32KB.

   font-display: swap — text must be readable immediately on a slow Pakistani
   mobile connection; a flash of fallback beats a flash of nothing. */

@font-face {
  font-family: "Poppins";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/poppins-400.woff2") format("woff2");
}

@font-face {
  font-family: "Poppins";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/poppins-500.woff2") format("woff2");
}

@font-face {
  font-family: "Poppins";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/poppins-600.woff2") format("woff2");
}

@font-face {
  font-family: "Poppins";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/poppins-700.woff2") format("woff2");
}

/* Inter, variable, for interface typography only.
   Ali, 2026-09-17: "shopify's checkout UI design, fonts etc look more
   professional." They are right, and the reason is mostly this — Shopify's
   checkout and admin are set in Inter, a face cut for screen UI, while ours
   put Poppins at weight 600-700 on every label and field. Poppins is a
   geometric display face; at 14px on a form it reads chunky and a bit shouty.

   One variable file covers 400-700, which is why it replaced four static
   weights: Google serves Inter as a variable font and all four URLs were
   byte-identical. 48KB for the whole range.

   Scope is deliberate. Headings, the logo and marketing copy stay Poppins, so
   the store still looks like Glowvé. Only the working surfaces — form labels,
   inputs, totals, buttons — move to Inter. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/inter-var.woff2") format("woff2-variations");
}

/* Cabinet Grotesk, variable, for the checkout funnel only.
   From the design system in Mockups/glowve.css, which Ali supplied 2026-09-18.

   That file's own header notes Fontshare's hosted build has no 600 weight and
   works around it by setting display type at 500 with tight tracking. The
   variable build does exist and covers 100-900, so the workaround is not
   needed and headings get the real 600 the system specifies. 41KB.

   Loaded on every page but *applied* only under .gv-funnel, because rolling a
   new display face across the store is a separate job: 154 rules depend on
   weight 600 and 23 ported Shopify stylesheets were measured against Poppins. */
@font-face {
  font-family: "Cabinet Grotesk";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/cabinet-grotesk-var.woff2") format("woff2");
}

/* ---- 00-tokens.css ---- */
/* ==========================================================================
   Design tokens — the one token file (DS-01).

   The look is Mockups/glowve.css (Ali, 2026-09-18; "whole store on the mockup
   look", 2026-09-26). Every raw value lives here once; parts and pages use the
   names. Contract: .planning/phases/03-design-foundation-and-parts-sheet/
   03-UI-SPEC.md; colour meanings in docs/design.md §3.

   Two blocks:
   1. Canonical tokens (below) — the only names new CSS may use.
   2. Legacy tokens (further down) — today's storefront names, kept at their
      values so pages not yet rebuilt don't move. Retiring: each page phase
      (4–8) moves its CSS to the canonical names and deletes what it no longer
      uses. Two legacy names clashed with the mockup's and were renamed:
      --brand-pink (#FF4D8D) -> --legacy-pink, --font-sans (Poppins) ->
      --legacy-font-sans.

   Breakpoints (custom properties can't be used in @media; mobile first,
   min-width only): sm 640px, md 900px, lg 1200px.
   ========================================================================== */

:root {
  /* ---- Surfaces ------------------------------------------------------ */
  --surface-page:    #faf8f7;  /* page ground (60%) */
  --surface-card:    #ffffff;  /* panels, cards, header, drawer, inputs */
  --surface-sunken:  #f7f3f1;  /* image wells, input prefix, quiet bands, skeletons */
  --surface-tint:    #fff0f6;  /* your choice; one brand band per page */
  --surface-success: #e7f3ec;  /* saved, included, done */
  --surface-sun:     #fff6f0;  /* heads-up, time-limited */
  --surface-danger:  #fdf4f3;  /* error notice ground */
  --surface-track:   #f0e9e5;  /* progress track */

  /* ---- Ink ----------------------------------------------------------- */
  --ink:             #171310;  /* text; dark ground for footer and announcement bar */
  --ink-muted:       #4a423d;
  --ink-subtle:      #6b625c;  /* hints, meta, was-price, placeholders in new parts */
  --ink-success:     #1f5f41;
  --ink-sun:         #8a3a10;
  --ink-danger:      #b3261e;
  --ink-danger-deep: #7a1c15;
  --ink-on-dark:     #e0dad5;
  --ink-on-brand:    var(--surface-card);
  --ink-disabled:    #b8afa8;  /* turned-off controls only, always with a reason in words */
  --ink-placeholder: #9a918b;  /* the signed-off funnel's placeholder only (3.09:1): new parts use --ink-subtle */

  /* ---- Lines --------------------------------------------------------- */
  --line-hair:       #ede7e3;
  --line:            #e8e2de;
  --line-strong:     #dcd4cf;  /* decorative only (1.46:1) */
  --line-control:    #8f857f;  /* borders that identify a control (3.60:1) */
  --line-danger:     #f0c8c4;
  --surface-scrim:   rgba(23, 19, 16, 0.4);  /* behind the bag drawer and the phone menu */
  --surface-on-dark-hover: rgba(255, 255, 255, 0.12);  /* hover behind a control on the ink ground */
  --line-on-dark:    rgba(224, 218, 213, 0.2);  /* hairline on the ink ground */

  /* ---- Brand --------------------------------------------------------- */
  --brand-pink:      #e0006b;  /* accent (10%): five uses only, never text */
  --brand-pink-deep: #a30052;  /* links, primary hover, pink text */
  --brand-pink-soft: #f6d9e7;
  --focus-ring:      var(--brand-pink-deep);
  --whatsapp:        #075E54;  /* WhatsApp's dark teal, WhatsApp button only: white words on it 7.7:1 (#128C7E is 4.1:1, too low for words) */
  --whatsapp-mark:   #25D366;  /* the funnel confirmation's small icon, beside its label */

  /* ---- Type ---------------------------------------------------------- */
  --font-sans:    "Inter", "Helvetica Neue", Helvetica, sans-serif;
  --font-display: "Cabinet Grotesk", "Archivo", "Helvetica Neue", Helvetica, sans-serif;
  --text-caption: 12px;
  --text-ui:      14px;
  --text-body:    16px;
  --display-sm:   18px;  /* card titles, accordion titles (Ali, 2026-09-27: ingredient titles "oversized, disproportionate" at display-md) */
  --display-md:   24px;
  --display-xl:   34px;
  --weight-display:   700;  /* every heading in the display face (Ali, 2026-09-27: the name "should be bolder", the price "more bold") */
  --leading-text:     1.5;
  --leading-display:  1.1;
  --tracking-display: -0.03em;
  --tracking-eyebrow: 0.08em;

  /* ---- Space (4 px grid) --------------------------------------------- */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 56px;
  --space-9: 64px;

  /* Section rhythm: used only by the layout objects in 01-base.css. */
  --section-gap:    48px;
  --section-pad:    32px;
  --section-gap-lg: 64px;
  --block-gap:      24px;
  --stack-gap:      16px;

  /* ---- Shape, size, depth, motion ------------------------------------ */
  --radius-sm:   6px;
  --radius-md:   10px;
  --radius-lg:   14px;
  --radius-pill: 999px;
  --tap-min:      44px;
  --control-h:    48px;
  --control-h-lg: 54px;
  --header-h:     60px;
  --pill-nav-h:   60px;  /* the product page's sticky section menu: a 44 px pill + 8 + 8 */
  --sticky-offset: calc(var(--header-h) + var(--pill-nav-h) + var(--space-4));  /* where a jumped-to section's top lands */
  --container:        1280px;
  --container-narrow: 880px;
  --measure:          62ch;
  --gutter:           16px;
  --shadow-bar:     0 -8px 24px rgba(23, 19, 16, 0.07);
  --shadow-overlay: 0 12px 32px rgba(23, 19, 16, 0.16);
  --shadow-pressed: inset 0 2px 4px rgba(23, 19, 16, 0.24);
  --duration-fast: 180ms;
  --duration:      250ms;
  --ease:          ease;
}

@media (min-width: 900px) {
  :root {
    --display-sm:  20px;
    --display-md:  27px;
    --display-xl:  42px;
    --header-h:    72px;
    --gutter:      48px;
    --section-gap: 64px;
    --section-pad: 48px;
    --block-gap:   32px;
  }
}

/* ==========================================================================
   Legacy — retiring, do not use in new CSS (stylelint enforces this in
   new-look CSS). Today's storefront names at today's values.
   ========================================================================== */

:root {
  /* ---- Brand ---------------------------------------------------------- */
  /* Hot pink is the brand. Everything else is neutral. */
  --legacy-pink:      #FF4D8D;

  /* Same hue, dark enough to carry white text.
     White on #FF4D8D measures 3.14:1, under the 4.5:1 WCAG 2.2 AA floor this
     project sets as a hard rule -- and it was on every Add to cart, the
     announcement bar and the cart drawer, which is the worst place to have it.
     Used ONLY where white text or a white icon sits on pink. Everything
     decorative -- stars, outlines, links, pulse dots -- stays --legacy-pink,
     because 1.4.11 only asks 3:1 of non-text and the brighter pink is the
     brand. Ali's decision, 2026-09-16. Revert by pointing this at
     --legacy-pink. */
  --brand-pink-ink:  #D6285F;
  --brand-pink-dark: #E63974;
  --coral-pulse:     #FF4D8D;   /* sections may re-tint this per product family */
  --coral-dark:      #E63974;

  --berry-dark:      #1A1A1A;
  --warm-espresso:   #1A1A1A;
  --mid-gray:        #666666;
  --warm-gray:       #ECECEC;
  --off-white:       #FFFFFF;
  --cream-glow:      #FFFFFF;

  /* Accent fills used behind content blocks */
  --accent-mint:     #E2F5EE;
  --accent-yellow:   #FFF8D6;
  --accent-peach:    #FFF0E6;
  --accent-sky:      #E1EDF5;   /* the science section ground */

  /* ---- UI greys (from the PDP section styles) ------------------------- */
  --gv-line:         #ECECEC;
  --gv-line-strong:  #D7DADE;
  --gv-line-soft:    #F0F1F3;
  --gv-surface:      #FAFBFC;
  --gv-surface-2:    #F3F4F6;
  --gv-text:         #1A1A1A;
  --gv-text-2:       #444444;
  --gv-text-3:       #555555;
  /* Both darkened to clear 4.5:1 on white. They carry real text -- review
     counts, dates, field hints -- not decoration, and at #7C8089 / #9AA0A8 they
     measured 3.96 and 2.64. The second was the worst contrast on the site. */
  --gv-muted:        #73767F;
  --gv-muted-2:      #707782;

  /* Ratings are green on this store, not yellow. */
  --gv-star:         #7CC04A;

  /* Urgency / promo tints */
  --gv-pink-tint:    #FFF4F8;
  --gv-pink-border:  #FFD0E0;

  /* ---- Type ----------------------------------------------------------- */
  /* Poppins throughout. Headings are 600, letter-spacing 0 — NOT tightened. */
  --legacy-font-sans:  "Poppins", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-serif: var(--legacy-font-sans);

  /* Aliases the ported Shopify page stylesheets ask for by their own names.
     They all carry fallbacks, so this is about keeping one source of truth for
     the value rather than about making them work. */
  --font-main: var(--legacy-font-sans);

  /* Interface typography. Poppins is a display face and reads chunky on form
     labels and totals; Inter is cut for exactly that job, and is what Shopify
     sets its own checkout and admin in. Used on working surfaces only —
     headings and marketing copy stay on --legacy-font-sans. */
  --font-ui: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --base-bg:   #FFFFFF;

  --gv-heading-weight:     600;
  --gv-hero-headline-size: 52px;
  --gv-section-title-size: 48px;

  /* ---- Vertical rhythm ------------------------------------------------
     One scale for the whole site. Section spacing is NOT set per section;
     sections use these tokens so the page keeps a single predictable beat. */
  --gv-sec-gap:    40px;   /* between two distinct sections */
  --gv-sec-pad:    32px;   /* inside a section that has its own background */
  --gv-blk-gap:    24px;   /* between blocks within one section */
  --gv-stk-gap:    14px;   /* between stacked siblings: accordions, cards, rows */
  --gv-sec-gap-lg: 72px;   /* editorial pages that want more air than a PDP */

  /* ---- Radius --------------------------------------------------------- */
  /* Four radii, not eleven. The authored stylesheets had grown three separate
     pill values (999px, 99px, 30px) and two card values (12px, 14px) in mixed
     units, which is most of why boxed things on a page did not look related.
     --gv-r-media and --gv-r-pack are kept as aliases so the ported Shopify
     sections keep working without being edited. */
  --gv-r-xs:     8px;    /* inputs, small chips */
  --gv-r-sm:     12px;   /* buttons, thumbnails */
  --gv-r-card:   16px;   /* panels and cards */
  --gv-r-pill:   999px;  /* pills, avatars, progress tracks */

  --gv-r-input:  var(--gv-r-xs);
  --gv-r-media:  var(--gv-r-card);
  --gv-r-pack:   var(--gv-r-card);

  /* ---- Spacing scale --------------------------------------------------
     One 4px-based ramp. Before this the authored CSS carried 63 distinct
     hard-coded spacing values, so nothing lined up between sections.
     The clamp()-based --gv-sec-* tokens above stay: those are deliberately
     responsive. This replaces the ad-hoc numbers, not the considered ones. */
  --gv-s1:   4px;
  --gv-s2:   8px;
  --gv-s3:  12px;
  --gv-s4:  16px;
  --gv-s5:  20px;
  --gv-s6:  24px;
  --gv-s7:  32px;
  --gv-s8:  40px;
  --gv-s9:  56px;
  --gv-s10: 80px;

  /* ---- Layout --------------------------------------------------------- */
  --gv-container:  1280px;
  --gv-container-narrow: 1140px;   /* the PDP column */
  --gv-gutter:     40px;

  /* ---- Elevation ------------------------------------------------------ */
  --gv-shadow-card: 0 4px 16px rgba(0, 0, 0, .06);
  --gv-shadow-pop:  0 6px 20px rgba(0, 0, 0, .25);
  --gv-shadow-nav:  0 4px 10px rgba(0, 0, 0, .06);

  /* ---- Motion --------------------------------------------------------- */
  --gv-ease:     cubic-bezier(0.4, 0, 0.2, 1);
  --gv-duration: 200ms;

  /* ---- Stacking -------------------------------------------------------
     The sticky header is z-index 8 and forms its own stacking context, so
     persistent page furniture must stay strictly below it or it covers the
     open mobile menu. (Same constraint as the Shopify theme.) */
  --layer-raised:     2;
  --layer-heightened: 4;
  --layer-header:     8;
  --layer-drawer:     18;
  --layer-modal:      30;
}

@media (min-width: 1000px) {
  :root {
    --gv-sec-gap: 64px;
    --gv-sec-pad: 48px;
    --gv-blk-gap: 28px;
    --gv-sec-gap-lg: 120px;
  }
}

@media (max-width: 768px) {
  :root {
    --gv-gutter: 20px;
    --gv-section-title-size: 32px;
    --gv-hero-headline-size: 34px;
  }
}

@media (prefers-reduced-motion: reduce) {
  :root { --gv-duration: 0ms; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---- 01-base.css ---- */
/* ==========================================================================
   Base — element defaults and layout objects only.
   ========================================================================== */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--off-white);
  color: var(--berry-dark);
  font-family: var(--legacy-font-sans);
  font-size: 15px;
  font-weight: 400;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* Headings: Poppins 600, letter-spacing 0. The live store is explicit about
   this — no tightening, no italics. */
h1, h2, h3, h4, h5, h6 {
  margin: 0 0 12px;
  font-family: var(--legacy-font-sans);
  font-weight: var(--gv-heading-weight);
  letter-spacing: 0;
  line-height: 1.15;
  color: var(--berry-dark);
}

h1 { font-size: var(--gv-hero-headline-size); }
h2 { font-size: var(--gv-section-title-size); }
h3 { font-size: 23px; line-height: 1.18; }
h4 { font-size: 18px; }
h5 { font-size: 15px; }
h6 { font-size: 13px; }

p { margin: 0 0 12px; }

/* em is a pink highlight on this store, never italic. */
em { font-style: normal; color: var(--legacy-pink); }

a { color: inherit; text-underline-offset: 0.2em; }

img, picture, video, svg { max-width: 100%; height: auto; display: block; }

button, input, select, textarea { font: inherit; color: inherit; }

:focus-visible {
  outline: 2px solid var(--legacy-pink);
  outline-offset: 2px;
  border-radius: 2px;
}

/* --- Layout objects ------------------------------------------------------ */

.gv-container {
  max-width: var(--gv-container);
  margin-inline: auto;
  padding-inline: var(--gv-gutter);
}

.gv-container--narrow { max-width: var(--gv-container-narrow); }

.gv-section { padding-block: var(--gv-sec-gap); }
.gv-section--pad   { padding-block: var(--gv-sec-pad); }
.gv-section--tint  { background: var(--gv-surface); }
.gv-section--sky   { background: var(--accent-sky); }
.gv-section--mint  { background: var(--accent-mint); }
.gv-section--peach { background: var(--accent-peach); }

/* --- Utilities ----------------------------------------------------------- */

.gv-visually-hidden,
.screen-reader-text {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.gv-skip-link {
  position: absolute;
  left: 16px; top: -100%;
  z-index: var(--layer-modal);
  padding: 8px 16px;
  background: #fff;
  border-radius: var(--gv-r-sm);
  transition: top var(--gv-duration) var(--gv-ease);
}
.gv-skip-link:focus { top: 16px; }

/* Horizontal scrollers (carousels, pill nav, thumbnails) hide their bar. */
.gv-scroller {
  display: flex;
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
  -webkit-overflow-scrolling: touch;
}
.gv-scroller::-webkit-scrollbar { width: 0; height: 0; display: none; }

/* ---- 01-look.css ---- */
/* ==========================================================================
   The new look (Phase 3; docs/design.md §1–§2). Pages opt in with the body
   class gv-look (glowve_new_look()); until a page is rebuilt it keeps the
   legacy rules above. Layout objects are the only way to space a page: a
   section never types its own padding, margin between bands, or background.
   ========================================================================== */

body.gv-look {
  margin: 0;
  background: var(--surface-page);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--text-body);
  line-height: var(--leading-text);
  -webkit-font-smoothing: antialiased;
}

/* One class of weight (0,1,0): beats the legacy element rules (h3 {…}),
   and a part's own heading class, loaded later, still wins. */
.gv-look :where(h1, h2, h3, h4, h5, h6) {
  margin: 0;
  font: inherit;
  font-weight: 600;
}

:where(.gv-look) :focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* A page band. Grounds need --pad so text never touches the colour's edge. */
.gv-band         { padding-block: var(--section-gap); }
.gv-band--pad    { padding-block: var(--section-pad); }
.gv-band--lg     { padding-block: var(--section-gap-lg); }
.gv-band--first  { padding-block-start: var(--space-5); } /* the first band under a page's own menu: the page starts close to it */
.gv-band--card   { background: var(--surface-card); }
.gv-band--sunken { background: var(--surface-sunken); }
.gv-band--brand  { background: var(--surface-tint); }
.gv-band--ink    { background: var(--ink); color: var(--ink-on-dark); --focus-ring: var(--ink-on-dark); }

/* Page width and gutters. */
.gv-wrap {
  box-sizing: border-box;
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.gv-wrap--narrow { max-width: var(--container-narrow); }

/* Running text line length. */
.gv-prose { max-width: var(--measure); }

/* Stack: siblings in a column, spaced by the gap, never by their own margins. */
.gv-stack    { display: flex; flex-direction: column; gap: var(--stack-gap); }
.gv-stack--1 { gap: var(--space-1); }
.gv-stack--2 { gap: var(--space-2); }
.gv-stack--3 { gap: var(--space-3); }
.gv-stack--4 { gap: var(--space-4); }
.gv-stack--5 { gap: var(--space-5); }
.gv-stack--6 { gap: var(--space-6); }
.gv-stack--7 { gap: var(--space-7); }

/* Inline: a wrapping row. */
.gv-inline           { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.gv-inline--3        { gap: var(--space-3); }
.gv-inline--4        { gap: var(--space-4); }
.gv-inline--5        { gap: var(--space-5); }
.gv-inline--between  { justify-content: space-between; }
.gv-inline--nowrap   { flex-wrap: nowrap; }
.gv-inline--baseline { align-items: baseline; }

/* Grid of cards: 2 columns, 3 from 640, 4 from 1200 (--2 stays at 2). */
.gv-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
}
@media (min-width: 640px) {
  .gv-grid:not(.gv-grid--2) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 900px) {
  .gv-grid { gap: var(--space-5); }
}
@media (min-width: 1200px) {
  .gv-grid:not(.gv-grid--2) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* Grid of articles (--3): one column on phones, three from 900. */
.gv-grid--3 { grid-template-columns: minmax(0, 1fr); row-gap: var(--space-6); }
@media (min-width: 640px) {
  .gv-grid.gv-grid--3 { grid-template-columns: minmax(0, 1fr); }
}
@media (min-width: 900px) {
  .gv-grid.gv-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 1200px) {
  .gv-grid.gv-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* A band's gap to the band before it is --section-gap, not two paddings: two
   bands on the page ground in a row don't double their space (Phase 4). */
.gv-band:not(.gv-band--card, .gv-band--sunken, .gv-band--brand, .gv-band--ink) + .gv-band:not(.gv-band--card, .gv-band--sunken, .gv-band--brand, .gv-band--ink) { padding-block-start: 0; }

/* Split: one column on phones; two from 900 (7/5, or --even), for a photo
   beside its text. Spacing and measure only. */
.gv-split { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--block-gap); }
.gv-split--start { align-items: start; }
@media (min-width: 900px) {
  .gv-split { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); column-gap: var(--space-7); }
  .gv-split--even { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

/* Anything a link jumps to lands below the sticky header and section menu. */
.gv-look :where([id]) { scroll-margin-top: var(--sticky-offset); }

/* ---- shopify/_glowve-base.css ---- */
/* ============================================================
   GLOWVE DESIGN SYSTEM — BASE TOKENS & SHARED UTILITIES
   V2 — Dot & Key style: Poppins, hot pink, clean white
   Loaded globally via snippets/glowve-head.liquid
============================================================ */

/* Scroll-snap is armed by JS ~1.6s after window load (glowve-head.liquid).
   A snap container that re-snaps while the page is still loading counts as a
   scroll, and Chrome stops measuring LCP at the first scroll — the page then
   reports NO_LCP and PageSpeed cannot compute a performance score at all.
   Bisected on the live homepage (2026-07-13): with snap off, LCP records
   normally (hero banner, ~1.5s); with it on, zero LCP candidates ever emit.
   Universal on purpose: Horizon's own galleries and slideshows snap too. */
body:not(.gv-snap-ready) * { scroll-snap-type: none !important; }

:root {
  /* ---- V2 Color Palette ---- */
  --cream-glow:      #FFFFFF;
  --coral-pulse:     #FF4D8D;
  --coral-dark:      #E63974;
  /* Brand pink, immune to per-section overrides. Sections may reassign
     --coral-pulse / --gv-pink for a family tint; these two never change. */
  --legacy-pink:      #FF4D8D;
  --brand-pink-dark: #E63974;
  --mango-zest:      #FF4D8D;   /* used for em highlights — same as brand pink */
  --berry-dark:      #1A1A1A;
  --warm-espresso:   #1A1A1A;
  --mid-gray:        #666666;
  --warm-gray:       #ECECEC;
  --off-white:       #FFFFFF;

  /* Accent fills */
  --accent-mint:     #E2F5EE;
  --accent-yellow:   #FFF8D6;
  --accent-peach:    #FFF0E6;

  /* Legacy palette aliases (keep for any unported components) */
  --citrus-burst:    #FFC85C;
  --watermelon-blush:#FF8FA3;
  --pearl-glow:      #FFF0E8;
  --golden-hour:     #FFD580;
  --sage-calm:       #A8C5A0;
  --plum-dusk:       #9B72AA;

  /* ---- V2 Typography ---- */
  /* All fonts default to Poppins; merchant can override via Theme Settings */
  --font-serif: 'Poppins', system-ui, sans-serif;
  --legacy-font-sans:  'Poppins', system-ui, sans-serif;
  --font-mono:  'Poppins', system-ui, sans-serif;

  /* Heading scale */
  --gv-heading-weight:       600;
  --gv-hero-headline-size:   52px;
  --gv-section-title-size:   48px;

  /* ---- Vertical rhythm ----
     One scale for the whole site. Section spacing is NOT set per section --
     sections use these tokens so the page keeps a single, predictable beat. */
  --gv-sec-gap:  40px;   /* between two distinct sections */
  --gv-sec-pad:  32px;   /* inside a section that has its own background */
  --gv-blk-gap:  24px;   /* between blocks within one section */
  --gv-stk-gap:  14px;   /* between stacked siblings: accordions, cards, list rows */
  --gv-sec-gap-lg: 72px; /* editorial pages (Our Story) that want more air than a PDP */
}

@media (min-width: 1000px) {
  :root { --gv-sec-gap: 64px; --gv-sec-pad: 48px; --gv-blk-gap: 28px; --gv-sec-gap-lg: 120px; }
}

/* ============================================================
   SECTION RHYTHM
   Every top-level PDP section sits exactly one --gv-sec-gap below the one
   before it. Do not add ad-hoc margin-top/padding to a section: change the
   token, or the page drifts out of beat the way it did before this existed.
============================================================ */
.gv-v3-pdp-details-wrap,
.gv-v3-pdp-science-wrap,
.gv-v3-pdp-trending-wrap,
.gv-v3-pdp-cab-wrap,
.gv-v3-pdp-founder-wrap,
.gv-v3-pdp-reviews-wrap { margin-top: var(--gv-sec-gap); }

/* Product Details / Hero Ingredients / What To Expect / How To Use / FAQ are
   separate sections but read as one accordion list, so they close ranks. The
   14px between them comes from .gv-v3-acc's own margin. */
.gv-v3-pdp-ing-wrap,
.gv-v3-pdp-acc-wrap { margin-top: 0; }

/* Last section on the page needs a floor under it. */
.gv-v3-pdp-reviews-wrap { padding-bottom: var(--gv-sec-gap); }

/* ============================================================
   V2 GLOBAL TYPOGRAPHY OVERRIDES
============================================================ */

/* All headings: Poppins 600, no letter-spacing, no italic.
   Legacy pages only: :where() keeps each selector's specificity exactly as it
   was, and pages in the new look (body.gv-look) are left alone (L57). */
:where(body:not(.gv-look)) h1, :where(body:not(.gv-look)) h2, :where(body:not(.gv-look)) h3,
:where(body:not(.gv-look)) h4, :where(body:not(.gv-look)) h5, :where(body:not(.gv-look)) h6,
.gv-section-title,
.gv-hero-headline,
.gv-product-name,
.gv-promise-title,
.gv-ingredient-title,
.gv-routine-title {
  font-family: var(--legacy-font-sans) !important;
  font-weight: 600 !important;
  letter-spacing: 0 !important;
  font-style: normal !important;
}

/* em = pink highlight, not italic (legacy pages only, as above) */
:where(body:not(.gv-look)) em {
  font-style: normal !important;
  color: var(--coral-pulse) !important;
}

/* ============================================================
   SHARED BUTTON STYLES
============================================================ */
.gv-btn-primary {
  background: var(--coral-pulse);
  color: #fff;
  font-family: var(--legacy-font-sans);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 14px 26px;
  border-radius: 100px;
  border: none;
  cursor: pointer;
  transition: background 0.2s, transform 0.2s;
  display: inline-block;
  text-decoration: none;
  width: fit-content;
}
.gv-btn-primary:hover { background: var(--coral-dark); transform: scale(1.02); }

.gv-btn-secondary {
  font-family: var(--legacy-font-sans);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--warm-espresso);
  border-bottom: 1px solid var(--warm-espresso);
  padding-bottom: 2px;
  transition: color 0.2s, border-color 0.2s;
  text-decoration: none;
}
.gv-btn-secondary:hover { color: var(--coral-pulse); border-color: var(--coral-pulse); }

.gv-btn-ghost {
  background: transparent;
  border: 1.5px solid rgba(255,255,255,0.4);
  color: #fff;
  font-family: var(--legacy-font-sans);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 14px 26px;
  border-radius: 100px;
  cursor: pointer;
  transition: all 0.2s;
  display: inline-block;
  text-decoration: none;
  width: fit-content;
}
.gv-btn-ghost:hover { background: #fff; color: var(--berry-dark); }

/* ============================================================
   SHARED SECTION TYPOGRAPHY
============================================================ */
.gv-section-label {
  font-family: var(--legacy-font-sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--coral-pulse);
  margin-bottom: 12px;
  display: flex;
  align-items: center;
  gap: 10px;
}
.gv-section-label::before {
  content: '';
  display: block;
  width: 24px;
  height: 1px;
  background: var(--coral-pulse);
}

.gv-section-title {
  font-family: var(--legacy-font-sans);
  font-size: var(--gv-section-title-size);
  font-weight: 600;
  line-height: 1.15;
  color: var(--berry-dark);
  letter-spacing: 0;
}

.gv-legacy-section-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  margin-bottom: 48px;
}

.gv-view-all {
  font-family: var(--legacy-font-sans);
  font-size: 13px;
  font-weight: 500;
  color: var(--warm-espresso);
  border-bottom: 1px solid var(--warm-espresso);
  padding-bottom: 2px;
  white-space: nowrap;
  transition: color 0.2s, border-color 0.2s;
  text-decoration: none;
}
.gv-view-all:hover { color: var(--coral-pulse); border-color: var(--coral-pulse); }

/* ============================================================
   SHARED LAYOUT
============================================================ */
.gv-container {
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 40px;
}

@media (max-width: 768px) {
  .gv-container { padding: 0 20px; }
  .gv-section-title { font-size: 32px; }
  .gv-legacy-section-header { flex-direction: column; align-items: flex-start; gap: 16px; }
}

/* ---- shopify/gv-reel-tile.css ---- */
/* Ported verbatim from snippets/gv-reel-tile.liquid. */
/* ---------- Tile ---------- */
  .gv-reel {
    position: relative;
    display: grid;
    place-items: center;
    aspect-ratio: 9 / 16;
    border-radius: 14px;
    overflow: hidden;
    background: #e2e2e2;
    border: none;
    padding: 0;
    width: 100%;
    cursor: pointer;
  }
  .gv-reel:not(button) { cursor: default; }
  .gv-reel-vid,
  .gv-reel img,
  .gv-reel-ph { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
  /* The video stacks over the lazy poster and is transparent until it plays,
     so the poster shows through until the tile scrolls into view. */
  .gv-reel-poster { z-index: 0; }
  .gv-reel-vid { z-index: 1; }

  .gv-reel-play {
    position: relative;
    z-index: 2;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.88);
    display: grid;
    place-items: center;
    color: var(--text-dark, #1a1a1a);
    box-shadow: 0 3px 10px rgba(0, 0, 0, 0.2);
    transition: transform 0.2s;
  }
  .gv-reel-play svg { margin-left: 2px; }
  .gv-reel:hover .gv-reel-play { transform: scale(1.08); }
  .gv-reel:focus-visible { outline: 3px solid var(--coral-pulse, #ff4d8d); outline-offset: 2px; }

  .gv-reel-cap {
    position: absolute;
    z-index: 2;
    inset: auto 12px 12px;
    color: #fff;
    font-family: var(--legacy-font-sans);
    font-size: 12px;
    text-align: left;
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.55);
  }

  /* ---------- Fullscreen viewer ---------- */
  .gv-rv {
    position: fixed;
    inset: 0;
    z-index: 9999;
    background: #000;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .gv-rv[hidden] { display: none; }

  .gv-rv-track {
    display: flex;
    width: 100%;
    height: 100%;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    overscroll-behavior: contain;
  }
  .gv-rv-track::-webkit-scrollbar { display: none; }

  .gv-rv-slide {
    flex: 0 0 100%;
    box-sizing: border-box;   /* keep a slide exactly one viewport wide */
    scroll-snap-align: center;
    scroll-snap-stop: always;
    display: grid;
    place-items: center;
    padding: 16px;
  }

  .gv-rv-stage {
    position: relative;
    width: min(480px, 100%);
    max-height: 100%;
    aspect-ratio: 9 / 16;
    background: #111;
    border-radius: 14px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
  }
  .gv-rv-media { position: relative; flex: 1; min-height: 0; background: #111; }
  .gv-rv-media video,
  .gv-rv-media iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
    object-fit: cover;
  }

  .gv-rv-cap {
    position: absolute;
    z-index: 2;
    left: 14px;
    right: 14px;
    bottom: 12px;
    margin: 0;
    color: #fff;
    font-family: var(--legacy-font-sans);
    font-size: 13.5px;
    line-height: 1.5;
    text-shadow: 0 1px 6px rgba(0, 0, 0, 0.7);
    pointer-events: none;
  }
  .gv-rv-stage.has-shop .gv-rv-cap { bottom: 84px; }

  /* Shop bar — the reason the viewer exists */
  .gv-rv-shop {
    position: absolute;
    z-index: 3;
    left: 10px;
    right: 10px;
    bottom: 10px;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px;
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.94);
    backdrop-filter: blur(8px);
  }
  .gv-rv-shop img { width: 46px; height: 46px; border-radius: 8px; object-fit: cover; flex: 0 0 auto; background: #f7efe3; }
  .gv-rv-shop-txt { flex: 1; min-width: 0; font-family: var(--legacy-font-sans); }
  .gv-rv-shop-title {
    margin: 0;
    font-size: 13px;
    font-weight: 700;
    color: #1a1a20;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .gv-rv-shop-price { margin: 2px 0 0; font-size: 12.5px; color: #5c5c68; }
  .gv-rv-add {
    flex: 0 0 auto;
    border: none;
    border-radius: 999px;
    padding: 10px 16px;
    font-family: var(--legacy-font-sans);
    font-size: 13px;
    font-weight: 700;
    color: #fff;
    background: var(--coral-pulse, #ff2e88);
    cursor: pointer;
  }
  .gv-rv-add[disabled] { opacity: 0.6; cursor: default; }

  /* Tap-to-pause: no native controls, because they render along the bottom edge
     of the video — exactly where the shop bar sits. */
  .gv-rv-media { cursor: pointer; }
  .gv-rv-media::after {
    content: "";
    position: absolute;
    z-index: 2;
    top: 50%;
    left: 50%;
    width: 68px;
    height: 68px;
    margin: -34px 0 0 -34px;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.45) no-repeat center /24px 24px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23fff'%3E%3Cpath d='M8 5v14l11-7z'/%3E%3C/svg%3E");
    opacity: 0;
    transition: opacity 0.15s;
    pointer-events: none;
  }
  .gv-rv.is-paused .gv-rv-slide.is-active .gv-rv-media::after { opacity: 1; }

  /* Chrome */
  .gv-rv-close,
  .gv-rv-mute,
  .gv-rv-nav {
    position: absolute;
    z-index: 5;
    border: none;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.16);
    color: #fff;
    cursor: pointer;
    display: grid;
    place-items: center;
  }
  .gv-rv-close:hover,
  .gv-rv-mute:hover,
  .gv-rv-nav:hover { background: rgba(255, 255, 255, 0.3); }
  .gv-rv-close:focus-visible,
  .gv-rv-mute:focus-visible,
  .gv-rv-nav:focus-visible,
  .gv-rv-add:focus-visible { outline: 3px solid #fff; outline-offset: 2px; }

  .gv-rv-close { top: 16px; right: 18px; width: 42px; height: 42px; font-size: 26px; line-height: 1; }
  .gv-rv-mute { top: 16px; left: 18px; width: 42px; height: 42px; }
  .gv-rv-nav { top: 50%; transform: translateY(-50%); width: 46px; height: 46px; font-size: 30px; line-height: 1; }
  .gv-rv-prev { left: 18px; }
  .gv-rv-next { right: 18px; }
  .gv-rv-nav[hidden] { display: none; }

  .gv-rv-count {
    position: absolute;
    z-index: 5;
    top: 22px;
    left: 50%;
    transform: translateX(-50%);
    padding: 4px 10px;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.45);   /* video behind it can be any colour */
    font-family: var(--legacy-font-sans);
    font-size: 12.5px;
    color: rgba(255, 255, 255, 0.9);
  }

  /* Touch devices swipe; the arrows are for mouse users. */
  @media (pointer: coarse) {
    .gv-rv-nav { display: none; }
  }

/* ---- shopify/gv-v3-bestsellers.css ---- */
/* Ported verbatim from sections/gv-v3-bestsellers.liquid (stylesheet). */
.gv-v3-best { padding: 56px 0; background: #fff; }
  .gv-v3-wrap { max-width: 1240px; margin: 0 auto; padding: 0 20px; }

  .gv-v3-best-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 18px;
  }
  .gv-v3-best-label {
    font-family: var(--legacy-font-sans);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--coral-pulse, #ff4d8d);
    margin: 0 0 6px;
  }
  .gv-v3-best-title {
    font-family: var(--legacy-font-sans);
    font-size: 30px;
    font-weight: 700;
    letter-spacing: -0.5px;
    color: var(--text-dark, #1a1a1a);
    margin: 0;
  }
  .gv-v3-best-viewall {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-family: var(--legacy-font-sans);
    font-size: 13px;
    font-weight: 600;
    color: var(--coral-pulse, #ff4d8d);
    text-decoration: none;
    white-space: nowrap;
  }
  .gv-v3-best-viewall:hover { color: var(--coral-dark, #e63974); }

  /* Tabs */
  .gv-v3-tabs { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 22px; }
  .gv-v3-tab {
    font-family: var(--legacy-font-sans);
    border: 1.5px solid var(--gray-light, #ececec);
    border-radius: 100px;
    padding: 9px 22px;
    font-weight: 600;
    font-size: 13px;
    color: var(--text-dark, #1a1a1a);
    background: transparent;
    cursor: pointer;
    transition: all 0.15s;
  }
  .gv-v3-tab--active { background: var(--coral-pulse, #ff4d8d); color: #fff; border-color: var(--coral-pulse, #ff4d8d); }

  /* Carousel */
  .gv-v3-car-shell { position: relative; }
  .gv-v3-car {
    display: flex;
    gap: 18px;
    overflow-x: auto;
    scroll-behavior: smooth;
    scroll-snap-type: x proximity;
    padding: 6px 2px 14px;
    scrollbar-width: none;
  }
  .gv-v3-car::-webkit-scrollbar { display: none; }

  /* Grid — used on collection pages. A category holds only a handful of
     products, so hiding them behind a horizontal scroll makes the page feel
     emptier than it is. Cards must not stretch to fill the row when there are
     only one or two, or a single product balloons across the viewport. */
  .gv-v3-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 18px;
    padding: 6px 2px 14px;
    justify-content: start;
  }
  .gv-v3-best--grid .gv-v3-grid .gv-v3-card {
    flex: none;
    width: auto;
    min-width: 0;
    scroll-snap-align: none;
  }
  @media (max-width: 640px) {
    .gv-v3-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  }

  .gv-v3-car-btn {
    position: absolute;
    top: 38%;
    transform: translateY(-50%);
    z-index: 4;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: #fff;
    border: 1px solid var(--gray-light, #ececec);
    box-shadow: 0 3px 10px rgba(0,0,0,0.12);
    display: grid;
    place-items: center;
    color: var(--text-dark, #1a1a1a);
    cursor: pointer;
  }
  .gv-v3-car-prev { left: -8px; }
  .gv-v3-car-prev svg { transform: rotate(180deg); }
  .gv-v3-car-next { right: -8px; }

  /* Card */
  .gv-v3-card {
    flex: 0 0 272px;
    scroll-snap-align: start;
    display: flex;
    flex-direction: column;
    border: 1px solid var(--gray-light, #ececec);
    border-radius: 14px;
    overflow: hidden;
    background: #fff;
    position: relative;
    transition: transform 0.25s, box-shadow 0.25s;
  }
  .gv-v3-card:hover { transform: translateY(-4px); box-shadow: 0 14px 30px rgba(0,0,0,0.09); }

  .gv-v3-card-badge {
    position: absolute;
    top: 10px;
    left: 10px;
    z-index: 2;
    background: #fff;
    border: 1px solid #ffd9a0;
    color: #e07b00;
    font-family: var(--legacy-font-sans);
    font-size: 10px;
    font-weight: 800;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    border-radius: 5px;
    padding: 3px 7px;
  }
  /* Sale badge: campaign ink on white, so a live discount reads differently from
     the evergreen pink badge. Scoped to the badge so no global token moves and
     it reverts on its own once compare-at prices are cleared.
     (Was Azadi flag green through Aug 2026; now the 9.9 dark ground.) */
  .gv-v3-card-badge--sale {
    background: #1A1A1A;
    border-color: #1A1A1A;
    color: #FFFFFF;
  }

  .gv-v3-card-media { display: block; aspect-ratio: 1; background: linear-gradient(135deg, #ffe7d6, #ffd6e6); }
  .gv-v3-card-media img,
  .gv-v3-card-ph { width: 100%; height: 100%; object-fit: cover; display: block; }

  .gv-v3-card-body { padding: 14px; display: flex; flex-direction: column; gap: 9px; flex: 1; }

  .gv-v3-card-skintag {
    align-self: flex-start;
    font-family: var(--legacy-font-sans);
    font-size: 11px;
    color: var(--text-gray, #666);
    background: #f4f5f7;
    border-radius: 5px;
    padding: 3px 8px;
  }
  .gv-v3-card-title { margin: 0; font-family: var(--legacy-font-sans); font-size: 15px; font-weight: 700; line-height: 1.25; }
  .gv-v3-card-title a { color: var(--text-dark, #1a1a1a); text-decoration: none; }
  .gv-v3-card-title a:hover { color: var(--coral-pulse, #ff4d8d); }
  .gv-v3-card-desc { margin: -2px 0 0; font-family: var(--legacy-font-sans); font-size: 12px; color: var(--text-gray, #666); line-height: 1.4; }

  .gv-v3-card-rating { display: flex; align-items: center; gap: 6px; font-family: var(--legacy-font-sans); font-size: 12px; color: var(--text-gray, #666); }
  .gv-v3-stars { display: inline-flex; color: #7cc70a; }
  .gv-v3-stars svg { display: block; }

  .gv-v3-card-foot { margin-top: auto; display: flex; flex-direction: column; gap: 10px; }
  .gv-v3-card-price { font-family: var(--legacy-font-sans); }
  .gv-v3-price-now { font-size: 19px; font-weight: 800; color: var(--text-dark, #1a1a1a); }
  .gv-v3-price-old { font-size: 13px; color: #9aa3ad; margin-left: 6px; }

  .gv-v3-card-atc {
    width: 100%;
    background: var(--coral-pulse, #ff4d8d);
    color: #fff;
    font-family: var(--legacy-font-sans);
    font-weight: 800;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    font-size: 12px;
    border: none;
    border-radius: 9px;
    padding: 12px;
    cursor: pointer;
    transition: background 0.2s;
  }
  .gv-v3-card-atc:hover { background: var(--coral-dark, #e63974); }
  .gv-v3-card-atc--out { background: var(--gray-light, #ececec); color: var(--text-gray, #666); cursor: default; }
  .gv-v3-card-atc.gv-v3-loading { opacity: 0.75; cursor: wait; }

  .gv-v3-best-empty { font-family: var(--legacy-font-sans); color: var(--text-gray, #666); text-align: center; padding: 40px 0; }

  @media (max-width: 640px) {
    .gv-v3-best { padding: 40px 0; }
    .gv-v3-best-title { font-size: 24px; }
    .gv-v3-card { flex-basis: 46vw; }
    .gv-v3-car-btn { display: none; }
  }

/* ---- shopify/gv-v3-concern.css ---- */
/* Ported verbatim from sections/gv-v3-concern.liquid (stylesheet). */
.gv-v3-concern { padding: 16px 0 40px; background: #fff; }
  .gv-v3-concern .gv-v3-wrap { max-width: 1240px; margin: 0 auto; padding: 0 20px; }
  .gv-v3-concern-title {
    text-align: center;
    font-family: var(--legacy-font-sans);
    font-size: 30px;
    font-weight: 800;
    letter-spacing: -0.5px;
    color: var(--text-dark, #1a1a1a);
    margin: 30px 0 22px;
  }

  /* Horizontal scroller — 4 tiles visible on desktop */
  .gv-v3-concern .gv-v3-car-shell { position: relative; }
  .gv-v3-concern-track {
    display: flex;
    gap: 16px;
    overflow-x: auto;
    scroll-behavior: smooth;
    scroll-snap-type: x proximity;
    padding: 4px 2px 8px;
    scrollbar-width: none;
  }
  .gv-v3-concern-track::-webkit-scrollbar { display: none; }

  .gv-v3-concern .gv-v3-car-btn {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 4;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: #fff;
    border: 1px solid var(--gray-light, #ececec);
    box-shadow: 0 3px 10px rgba(0,0,0,0.12);
    display: grid;
    place-items: center;
    color: var(--text-dark, #1a1a1a);
    cursor: pointer;
  }
  .gv-v3-concern .gv-v3-car-prev { left: -8px; }
  .gv-v3-concern .gv-v3-car-prev svg { transform: rotate(180deg); }
  .gv-v3-concern .gv-v3-car-next { right: -8px; }

  .gv-v3-ctile {
    position: relative;
    display: block;
    flex: 0 0 calc((100% - 48px) / 4);
    scroll-snap-align: start;
    aspect-ratio: 3 / 4;
    border-radius: 16px;
    overflow: hidden;
    background: #f0e3e9;
    text-decoration: none;
  }
  .gv-v3-ctile img,
  .gv-v3-ctile-ph { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
  .gv-v3-ctile::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(20,8,14,0) 38%, rgba(20,8,14,0.78) 100%);
  }
  .gv-v3-ctile-label {
    position: absolute;
    left: 18px;
    bottom: 20px;
    right: 60px;
    z-index: 2;
    color: #fff;
    font-family: var(--legacy-font-sans);
    font-size: 20px;
    font-weight: 800;
    line-height: 1.15;
    text-shadow: 0 1px 4px rgba(0,0,0,0.35);
  }
  .gv-v3-ctile-go {
    position: absolute;
    right: 14px;
    bottom: 16px;
    z-index: 2;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: #fff;
    display: grid;
    place-items: center;
    color: var(--coral-pulse, #ff4d8d);
    box-shadow: 0 3px 10px rgba(0,0,0,0.18);
  }

  /* Mobile: 2-row grid that scrolls sideways by columns (D&K style).
     2 tiles visible per column → 2 above, 2 below; swipe right for more. */
  @media (max-width: 640px) {
    .gv-v3-concern-title { font-size: 24px; }
    .gv-v3-concern-track {
      display: grid;
      grid-auto-flow: column;
      grid-template-rows: repeat(2, auto);
      grid-auto-columns: 47%;
      gap: 12px;
      overflow-x: auto;
      scroll-snap-type: x proximity;
      padding-bottom: 6px;
    }
    .gv-v3-ctile { flex: none; }
    .gv-v3-ctile-label { font-size: 17px; left: 14px; bottom: 16px; right: 48px; }
    .gv-v3-ctile-go { width: 34px; height: 34px; right: 12px; bottom: 12px; }
    .gv-v3-ctile-go svg { width: 16px; height: 16px; }
    .gv-v3-concern .gv-v3-car-btn { display: none; }
  }

/* ---- shopify/gv-v3-footer.css ---- */
/* Ported verbatim from sections/gv-v3-footer.liquid (stylesheet). */
.gv-v3-footer {
    border-top: 1px solid var(--gray-light, #ececec);
    background: #fff;
    padding: 50px 0 30px;
  }
  .gv-v3-footer-grid {
    max-width: 1240px;
    margin: 0 auto;
    padding: 0 20px;
    display: grid;
    grid-template-columns: 1.4fr 1fr 1fr 1fr 1.4fr;
    gap: 30px;
  }

  .gv-v3-footer-word {
    font-family: var(--legacy-font-sans);
    font-size: 26px;
    font-weight: 800;
    letter-spacing: 0.5px;
    color: var(--text-dark, #1a1a1a);
    text-decoration: none;
  }
  .gv-v3-footer-logo { display: block; max-height: 36px; width: auto; }
  .gv-v3-footer-tagline { font-family: var(--legacy-font-sans); font-size: 14px; color: var(--text-gray, #666); line-height: 1.5; margin: 12px 0 0; max-width: 240px; }

  .gv-v3-footer-contact { list-style: none; margin: 18px 0 0; padding: 0; display: flex; flex-direction: column; gap: 10px; max-width: 260px; }
  .gv-v3-footer-contact-item { display: flex; align-items: flex-start; gap: 9px; font-family: var(--legacy-font-sans); font-size: 13.5px; line-height: 1.45; color: var(--text-gray, #666); }
  .gv-v3-footer-contact-item svg { flex: 0 0 auto; margin-top: 2px; color: var(--coral-pulse, #ff4d8d); }
  .gv-v3-footer-contact-item a { color: var(--text-gray, #666); text-decoration: none; }
  .gv-v3-footer-contact-item a:hover { color: var(--coral-pulse, #ff4d8d); }

  .gv-v3-footer-legal {
    max-width: 1240px;
    margin: 34px auto 0;
    padding: 0 20px;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 10px 22px;
  }
  .gv-v3-footer-legal-link { font-family: var(--legacy-font-sans); font-size: 13px; color: #3a424e; text-decoration: none; }
  .gv-v3-footer-legal-link:hover { color: var(--coral-pulse, #ff4d8d); text-decoration: underline; }

  .gv-v3-footer-coltitle { font-family: var(--legacy-font-sans); font-size: 16px; font-weight: 800; color: var(--text-dark, #1a1a1a); margin: 0 0 16px; }
  .gv-v3-footer-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
  .gv-v3-footer-link { font-family: var(--legacy-font-sans); font-size: 14px; color: #3a424e; text-decoration: none; }
  .gv-v3-footer-link:hover { color: var(--coral-pulse, #ff4d8d); }

  .gv-v3-sub { display: flex; border: 1px solid var(--gray-light, #ececec); border-radius: 9px; overflow: hidden; width: 100%; max-width: 340px; }
  /* min-width:0 is load-bearing. A flex item defaults to min-width:auto, and an
     <input> with no size attribute has an intrinsic min-content width of ~180px,
     so the field refused to shrink and pushed the button past the wrapper, where
     overflow:hidden clipped it. Broke below ~300px of available width. */
  .gv-v3-sub input { flex: 1 1 0; min-width: 0; border: none; outline: none; padding: 13px 16px; font-family: var(--legacy-font-sans); font-size: 14px; }
  .gv-v3-sub button {
    flex: 0 0 auto;
    white-space: nowrap;
    background: var(--coral-pulse, #ff4d8d);
    color: #fff;
    font-family: var(--legacy-font-sans);
    font-weight: 800;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    padding: 0 22px;
    font-size: 13px;
    border: none;
    cursor: pointer;
  }
  .gv-v3-sub button:hover { background: var(--coral-dark, #e63974); }
  .gv-v3-sub-ok { font-family: var(--legacy-font-sans); font-size: 14px; color: var(--coral-dark, #e63974); font-weight: 600; margin: 0; }

  .gv-v3-footer-follow { margin-top: 24px; }
  .gv-v3-footer-social { display: flex; gap: 12px; }
  .gv-v3-footer-social a {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: #f2f3f5;
    display: grid;
    place-items: center;
    color: #5b6573;
    text-decoration: none;
    transition: background 0.2s, color 0.2s;
  }
  .gv-v3-footer-social a:hover { background: var(--coral-pulse, #ff4d8d); color: #fff; }

  .gv-v3-footer-copy {
    text-align: center;
    font-family: var(--legacy-font-sans);
    color: var(--text-gray, #666);
    font-size: 14px;
    margin-top: 16px;
  }

  @media (max-width: 980px) {
    .gv-v3-footer-grid { grid-template-columns: 1fr 1fr; }
    .gv-v3-footer-brand { grid-column: 1 / -1; }
    .gv-v3-footer-news { grid-column: 1 / -1; }
  }
  @media (max-width: 640px) {
    .gv-v3-footer-grid { gap: 28px; }
    .gv-v3-sub { max-width: none; }
    .gv-v3-sub input { padding: 13px 14px; }
    .gv-v3-sub button { padding: 0 18px; }
  }

/* ---- shopify/gv-v3-hero.css ---- */
/* Ported verbatim from sections/gv-v3-hero.liquid (stylesheet).
   Behaviour (swipe / dots / arrows / autoplay) is already in assets/js/gv-v3.js
   as bindSlideshows(), bound by [data-gv-slideshow]. */
.gv-v3-hero {
  position: relative;
  width: 100%;
  overflow: hidden;
  background: var(--warm-gray, #ececec);
}

.gv-v3-hero-track {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.gv-v3-hero-track::-webkit-scrollbar { display: none; }

.gv-v3-hero-slide {
  flex: 0 0 100%;
  width: 100%;
  scroll-snap-align: start;
}
.gv-v3-hero-link { display: block; }

.gv-v3-hero-slide img,
.gv-v3-hero-slide picture {
  display: block;
  width: 100%;
  height: auto;
}
/* The headline, the products and the button are all painted into the banner
   file, so cropping it cuts the message. Every breakpoint shows the whole file
   at the real ratio of the artwork it is showing — the section emits those per
   slide as --gv-d-ar and --gv-m-ar, read from the actual image dimensions — and
   the height simply follows the width.

   This used to force `height: var(--gv-hero-h, 420px)` above 750px with
   object-fit: cover. The desktop artwork is 3:1, so on a 1728px screen the
   banner's natural height is 576px and 420px of it survived: a quarter of the
   picture, taken off the top and the bottom, which is where the headline and
   the button live.

   object-fit is contain, not cover, so that if a ratio is ever missing the
   banner letterboxes against the section background instead of eating words. */
.gv-v3-hero-slide img {
  aspect-ratio: var(--gv-d-ar, auto);
  object-fit: contain;
}

@media (max-width: 749px) {
  .gv-v3-hero-slide img { aspect-ratio: var(--gv-m-ar, auto); }
}

.gv-v3-hero-placeholder,
.gv-v3-hero-slide--empty { width: 100%; }
.gv-v3-hero-svg { width: 100%; height: auto; display: block; background: var(--warm-gray, #ececec); }

/* Arrows — desktop only */
.gv-v3-hero-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 3;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: rgba(255,255,255,0.92);
  box-shadow: 0 3px 12px rgba(0,0,0,0.16);
  display: grid;
  place-items: center;
  color: var(--text-dark, #1a1a1a);
  border: none;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.2s, background 0.2s;
}
.gv-v3-hero:hover .gv-v3-hero-arrow { opacity: 1; }
.gv-v3-hero-arrow:hover { background: #fff; }
.gv-v3-hero-arrow--prev { left: 18px; }
.gv-v3-hero-arrow--prev svg { transform: rotate(180deg); }
.gv-v3-hero-arrow--next { right: 18px; }

/* Dots */
.gv-v3-hero-dots {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 16px;
  z-index: 3;
  display: flex;
  justify-content: center;
  gap: 8px;
}
.gv-v3-dot {
  width: 9px;
  height: 9px;
  padding: 0;
  border-radius: 50%;
  border: none;
  background: rgba(255,255,255,0.55);
  box-shadow: 0 1px 3px rgba(0,0,0,0.25);
  cursor: pointer;
  transition: background 0.2s, transform 0.2s;
}
.gv-v3-dot--active { background: #fff; transform: scale(1.25); }

@media (max-width: 749px) {
  .gv-v3-hero-arrow { display: none; }
  .gv-v3-hero-dots { bottom: 10px; }
}

/* ---- shopify/gv-v3-pdp-accordions.css ---- */
/* Ported verbatim from sections/gv-v3-pdp-accordions.liquid (stylesheet). */
.gv-v3-rte ul { margin: 0; padding-left: 18px; }
  .gv-v3-rte li { margin-bottom: 6px; }
  .gv-v3-rte li:last-child { margin-bottom: 0; }
  .gv-v3-rte p { margin: 0 0 8px; }
  .gv-v3-rte p:last-child { margin-bottom: 0; }
  .gv-v3-rte strong { color: var(--text-dark, #1a1a1a); }

  /* ---- What To Expect timeline ---- */
  .gv-v3-tl-intro { max-width: 680px; font-size: 15px; line-height: 1.65; color: #555; margin: 0 0 18px; }

  .gv-v3-tl { list-style: none; margin: 0; padding: 0; max-width: 680px; }
  .gv-v3-tl-step {
    position: relative; display: grid; gap: 2px;
    padding: 0 0 20px 26px; margin: 0;
  }
  /* The rail is drawn by the step itself so it stops cleanly at the last one. */
  .gv-v3-tl-step::before {
    content: ""; position: absolute; left: 5px; top: 6px; bottom: -6px;
    width: 2px; background: #ECECEC;
  }
  .gv-v3-tl-step:last-child { padding-bottom: 0; }
  .gv-v3-tl-step:last-child::before { display: none; }
  .gv-v3-tl-marker {
    position: absolute; left: 0; top: 5px; width: 12px; height: 12px; border-radius: 50%;
    background: #fff; border: 2px solid #ECECEC; box-sizing: border-box;
  }
  .gv-v3-tl-step:first-child .gv-v3-tl-marker { border-color: var(--coral-pulse, #FF4D8D); background: var(--coral-pulse, #FF4D8D); }

  .gv-v3-tl-when {
    font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .09em;
    color: var(--coral-pulse, #FF4D8D); line-height: 1.5;
  }
  .gv-v3-tl-what { font-size: 15px; font-weight: 600; color: var(--text-dark, #1a1a1a); line-height: 1.4; }
  .gv-v3-tl-body { font-size: 14px; line-height: 1.65; color: #555; margin-top: 3px; }

  .gv-v3-tl-note {
    max-width: 680px; margin: 20px 0 0; padding: 14px 16px; background: #fff;
    border: 1px solid #ECECEC; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,.06);
    font-size: 13.5px; line-height: 1.6; color: #555;
  }

/* ---- shopify/gv-v3-pdp-buy.css ---- */
/* Ported verbatim from sections/gv-v3-pdp-buy.liquid (stylesheet). */
.gv-v3-pdp { background: #fff; --gv-pink: var(--coral-pulse, #ff4d8d); }
  .gv-v3-pdp * { box-sizing: border-box; }

  /* Pill nav — must stay BELOW the mobile menu drawer, or the pills render on
     top of the open menu.

     The number that matters is 8, not --layer-menu-drawer (18). The drawer is
     nested inside <header>, which is `position: sticky; z-index: 8` and so
     forms a stacking context the drawer can never escape: everything in the
     drawer is clamped to an effective 8 against the rest of the page. Anything
     here at >= 8 wins the tie on DOM order (main comes after header) and covers
     the menu. Keep persistent page furniture strictly under 8. */
  .gv-v3-pillnav { position: relative; z-index: var(--layer-raised, 2); background: #fff; border-bottom: 1px solid #f0f1f3; }
  .gv-v3-pillnav--fixed { position: fixed; left: 0; right: 0; z-index: var(--layer-heightened, 4); box-shadow: 0 4px 10px rgba(0,0,0,.06); }
  .gv-v3-pillnav-inner { display: flex; gap: 10px; padding: 12px 16px; overflow-x: auto; scrollbar-width: none; max-width: 1140px; margin: 0 auto; }
  .gv-v3-pillnav-inner::-webkit-scrollbar { display: none; }
  .gv-v3-pill { flex: 0 0 auto; padding: 8px 18px; border-radius: 30px; border: 1.5px solid var(--text-dark, #1a1a1a); color: var(--text-dark, #1a1a1a); font-family: var(--legacy-font-sans); font-size: 14px; font-weight: 600; text-decoration: none; }
  .gv-v3-pill--active { border-color: var(--gv-pink); color: var(--gv-pink); }

  .gv-v3-pdp-wrap { max-width: 1140px; margin: 0 auto; padding: 16px; }

  /* Gallery */
  .gv-v3-gallery-main { position: relative; border-radius: 20px; overflow: hidden; aspect-ratio: 1; background: linear-gradient(135deg,#bfe4f5,#cdbdf0 50%,#f3c6e2); }
  .gv-v3-gallery-track { display: flex; height: 100%; overflow-x: auto; overflow-y: hidden; scroll-behavior: smooth; overscroll-behavior-x: contain; scrollbar-width: none; -ms-overflow-style: none; -webkit-overflow-scrolling: touch; }
  .gv-v3-gallery-track::-webkit-scrollbar { width: 0; height: 0; display: none; }
  /* Snap rides the site-wide gate: glowve-head.liquid puts .gv-snap-ready on
     <body> 1600ms after load, and glowve-base.css force-disables snap until then.
     A snap container re-snapping during load registers as a scroll, and Chrome
     stops measuring LCP at the first scroll -- the page reports NO_LCP and gets
     no performance score at all. Bisected on the live homepage 2026-07-13. */
  .gv-snap-ready .gv-v3-gallery-track { scroll-snap-type: x mandatory; }
  .gv-v3-slide { position: relative; flex: 0 0 100%; width: 100%; height: 100%; scroll-snap-align: center; scroll-snap-stop: always; }
  .gv-v3-gallery-img, .gv-v3-gallery-video { width: 100%; height: 100%; object-fit: cover; display: block; }
  .gv-v3-dots { position: absolute; left: 0; right: 0; bottom: 12px; z-index: 3; display: flex; justify-content: center; gap: 6px; pointer-events: none; }
  .gv-v3-dot { width: 6px; height: 6px; border-radius: 50%; background: rgba(255,255,255,.6); box-shadow: 0 1px 3px rgba(0,0,0,.3); transition: width .22s ease, background .22s ease; }
  .gv-v3-dot.is-on { width: 18px; border-radius: 99px; background: #fff; }
  @media (prefers-reduced-motion: reduce) { .gv-v3-gallery-track { scroll-behavior: auto; } }
  .gv-v3-gallery-play { position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); z-index: 3; width: 64px; height: 64px; border-radius: 50%; border: none; cursor: pointer; background: rgba(255,255,255,.9); color: var(--gv-pink); display: grid; place-items: center; box-shadow: 0 6px 20px rgba(0,0,0,.25); }
  .gv-v3-gallery-play[hidden] { display: none; }
  .gv-v3-skin-badge { position: absolute; top: 14px; left: 14px; z-index: 2; background: rgba(26,26,26,.78); color: #fff; font-family: var(--legacy-font-sans); font-size: 11px; font-weight: 700; border-radius: 8px; padding: 6px 10px; line-height: 1.2; white-space: pre-line; }
  .gv-v3-boost-tag { position: absolute; bottom: 16px; right: 14px; z-index: 2; background: rgba(255,255,255,.6); backdrop-filter: blur(4px); color: var(--gv-pink); font-family: var(--legacy-font-sans); font-weight: 700; font-size: 12px; padding: 6px 12px; border-radius: 20px; }

  /* Gallery prev/next arrows */
  .gv-v3-gallery-nav { position: absolute; top: 50%; transform: translateY(-50%); z-index: 3; width: 40px; height: 40px; border-radius: 50%; border: none; cursor: pointer; background: rgba(255,255,255,.88); color: var(--text-dark, #1a1a1a); display: grid; place-items: center; box-shadow: 0 2px 10px rgba(0,0,0,.18); transition: background .15s, transform .15s; padding: 0; }
  .gv-v3-gallery-nav:hover { background: #fff; }
  .gv-v3-gallery-nav:active { transform: translateY(-50%) scale(.92); }
  .gv-v3-gallery-nav--prev { left: 12px; }
  .gv-v3-gallery-nav--next { right: 12px; }
  @media (hover: none) { .gv-v3-gallery-nav { display: none; } }
  @media (min-width: 1000px) { .gv-v3-dots { display: none; } }
  @media (max-width: 749px) { .gv-v3-gallery-nav { width: 34px; height: 34px; } }

  .gv-v3-thumbs { display: flex; gap: 8px; margin-top: 12px; overflow-x: auto; scrollbar-width: none; }
  .gv-v3-thumbs::-webkit-scrollbar { display: none; }
  .gv-v3-thumb { position: relative; flex: 0 0 auto; width: 56px; height: 56px; border-radius: 10px; border: 2px solid transparent; overflow: hidden; padding: 0; cursor: pointer; background: #f3f4f6; }
  .gv-v3-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .gv-v3-thumb--active { border-color: var(--gv-pink); }
  .gv-v3-thumb-play { position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); width: 22px; height: 22px; border-radius: 50%; background: rgba(0,0,0,.55); color: #fff; display: grid; place-items: center; }

  /* Buy info */
  .gv-v3-buyinfo { font-family: var(--legacy-font-sans); }
  .gv-v3-pdp-titlerow { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 16px 0 0; }
  .gv-v3-pdp-titlerow .gv-v3-pdp-title { margin: 0; }
  .gv-v3-size-pill { flex: 0 0 auto; display: inline-block; padding: 4px 11px; border: 1.5px solid var(--gv-pink); border-radius: 30px; background: #fff; color: var(--gv-pink); font-family: var(--legacy-font-sans); font-size: 13px; font-weight: 700; line-height: 1.2; white-space: nowrap; text-transform: uppercase; letter-spacing: .3px; }
  .gv-v3-pdp-title { font-size: 23px; font-weight: 800; letter-spacing: -0.3px; line-height: 1.18; margin: 16px 0 0; color: var(--text-dark, #1a1a1a); }
  .gv-v3-pdp-sub { color: #444; font-size: 15px; margin: 8px 0 0; }
  .gv-v3-pdp-promise { font-size: 16px; font-weight: 600; color: #1A1A20; margin: 10px 0 0; }
  .gv-v3-rating-row { display: flex; align-items: center; gap: 8px; margin: 12px 0; flex-wrap: wrap; }
  .gv-v3-stars { display: inline-flex; color: #7cc04a; }
  .gv-v3-rating-text { font-size: 14px; color: #444; display: inline-flex; align-items: center; gap: 5px; }
  .gv-v3-rating-text strong { color: var(--text-dark, #1a1a1a); }

  .gv-v3-urgency { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 4px; padding: 10px 14px; background: #fff4f8; border: 1px solid #ffd0e0; border-radius: 10px; }
  .gv-v3-urgency-live { display: flex; align-items: center; gap: 6px; color: var(--gv-pink); font-weight: 700; font-size: 13px; }
  .gv-v3-pulse { width: 8px; height: 8px; border-radius: 50%; background: var(--gv-pink); box-shadow: 0 0 0 0 rgba(255,77,141,.6); animation: gvpulse 1.6s infinite; }
  @keyframes gvpulse { 0%{box-shadow:0 0 0 0 rgba(255,77,141,.55);} 70%{box-shadow:0 0 0 8px rgba(255,77,141,0);} 100%{box-shadow:0 0 0 0 rgba(255,77,141,0);} }
  .gv-v3-urgency-text { font-size: 13px; color: #555; }

  /* Packs */
  .gv-v3-packs { display: flex; flex-direction: column; gap: 10px; margin-top: 16px; }
  .gv-v3-pack { position: relative; display: flex; align-items: center; gap: 12px; border: 1.5px solid #d7dade; border-radius: 14px; padding: 14px; cursor: pointer; background: #fafbfc; }
  .gv-v3-pack input { position: absolute; opacity: 0; width: 0; height: 0; }
  .gv-v3-pack--sel { border-color: var(--gv-pink); background: #fff; }
  .gv-v3-pack-radio { position: relative; flex: 0 0 auto; width: 20px; height: 20px; border-radius: 50%; border: 2px solid #c5cad0; }
  .gv-v3-pack--sel .gv-v3-pack-radio { border-color: var(--gv-pink); }
  .gv-v3-pack--sel .gv-v3-pack-radio::after { content: ""; position: absolute; inset: 3px; border-radius: 50%; background: var(--gv-pink); }
  .gv-v3-pack-main { flex: 1; display: flex; flex-direction: column; gap: 3px; }
  .gv-v3-pack-name { font-size: 15px; font-weight: 700; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
  .gv-v3-pack-note { font-size: 12px; color: #7c8089; }
  .gv-v3-pack-price { font-size: 15px; font-weight: 800; text-align: right; white-space: nowrap; }
  .gv-v3-pack-price s { display: block; font-size: 12px; color: #9aa0a8; font-weight: 600; }
  .gv-v3-pack-badge { font-size: 10px; font-weight: 700; color: #fff; background: var(--gv-pink); border-radius: 20px; padding: 2px 8px; }
  .gv-v3-pack-badge--alt { background: #2fc6e8; }

  /* Buy bar */
  .gv-v3-buybar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 16px; }
  .gv-v3-buy-price { font-size: 22px; font-weight: 800; }
  .gv-v3-buy-price s { font-size: 15px; color: #9aa0a8; font-weight: 600; margin-left: 6px; }
  .gv-v3-qty { display: flex; align-items: center; border: 1.5px solid #d7dade; border-radius: 10px; overflow: hidden; }
  .gv-v3-qty button { width: 38px; height: 40px; border: none; background: #f3f4f6; font-size: 20px; cursor: pointer; }
  .gv-v3-qty span { width: 44px; text-align: center; font-weight: 600; }
  .gv-v3-atc { flex: 1; min-width: 150px; height: 48px; border: none; cursor: pointer; background: var(--gv-pink); color: #fff; font-weight: 700; font-size: 16px; letter-spacing: .5px; border-radius: 12px; }
  .gv-v3-atc:hover { background: var(--coral-dark, #e63974); }

  /* Buy Now (Cash on Delivery) — secondary action under ATC */
  .gv-v3-buynow { display: flex; align-items: center; justify-content: center; gap: 9px; width: 100%; min-height: 50px; margin-top: 10px; padding: 12px 16px; border: none; cursor: pointer; background: var(--text-dark, #1a1a1a); color: #fff; font-family: var(--legacy-font-sans); font-weight: 700; font-size: 16px; letter-spacing: .3px; border-radius: 12px; line-height: 1.2; }
  .gv-v3-buynow:hover { background: #000; }
  .gv-v3-buynow svg { flex: 0 0 auto; }
  .gv-v3-buynow[data-gv-busy] { opacity: .75; cursor: default; }

  .gv-v3-mrp { color: #7c8089; font-size: 14px; margin: 8px 0 0; }

  /* Helps / Targets */
  /* Brand guidelines card surface: white, 1px #ECECEC, radius 16, shadow 0 4px 16px /.06.
     This had drifted to a 20px radius, a heavier shadow and no border at all. */
  .gv-v3-helps-card { margin-top: 18px; background: #fff; border: 1px solid #ececec; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,.06); padding: 20px; }
  /* Label sits ABOVE its list, not beside it. The old 56px side column stole
     width from the grid, pushed the checklist off-centre and left the label
     floating in space next to a two-row list. Stacked, the card reads as a
     titled block and the list gets the full width. (Ali, 21 Aug 2026.) */
  .gv-v3-helps-row, .gv-v3-targets-row { display: block; }
  /* Only pays for a divider when there is a Helps row above to divide from. */
  .gv-v3-helps-row + .gv-v3-targets-row { margin-top: 22px; padding-top: 20px; border-top: 1px solid #ECECEC; }
  .gv-v3-row-label {
    display: block; margin: 0 0 14px;
    font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .12em;
    color: var(--gv-pink);
  }
  .gv-v3-helps-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
  .gv-v3-help { border: 1.5px solid var(--gv-pink); border-radius: 12px; padding: 12px; font-family: var(--legacy-font-sans); font-size: 14px; font-weight: 500; color: var(--text-dark, #1a1a1a); background: #fff; cursor: pointer; display: flex; align-items: center; gap: 8px; text-align: left; line-height: 1.25; }
  .gv-v3-help-ico { display: flex; color: var(--gv-pink); }
  .gv-v3-help::after { content: "\24D8"; margin-left: auto; color: var(--gv-pink); font-size: 14px; }
  /* Targets read as a checklist, not as tags. Six solid pink blocks competed with
     ADD TO CART for attention, and a list of *problems* rendered like a list of
     prizes. Pink is now just the tick; the words are the message. Two fixed
     columns so uneven label lengths still line up. (Ali, 21 Aug 2026.) */
  .gv-v3-targets { display: grid; grid-template-columns: 1fr 1fr; gap: 15px 20px; }
  .gv-v3-target-pill {
    display: flex; align-items: center; gap: 10px;
    font-size: 15px; font-weight: 600; line-height: 1.3;
    color: var(--text-dark, #1A1A1A);
  }
  .gv-v3-target-pill::before {
    content: ""; flex: 0 0 auto; width: 18px; height: 18px; border-radius: 50%;
    background: var(--gv-pink) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E") center/11px 11px no-repeat;
  }

  @media (max-width: 749px) {
    .gv-v3-helps-card { padding: 18px 16px; }
    .gv-v3-row-label { margin-bottom: 12px; letter-spacing: .11em; }
    .gv-v3-helps-grid { gap: 8px; }
    .gv-v3-help { padding: 10px; font-size: 13px; gap: 6px; border-radius: 10px; }
    .gv-v3-help::after { font-size: 12px; }
    .gv-v3-targets { gap: 14px 14px; }
    .gv-v3-target-pill { font-size: 14px; gap: 9px; }
    .gv-v3-target-pill::before { width: 17px; height: 17px; background-size: 10px 10px; }
  }

  /* Trust strip */
  /* Five badges. Grid with auto-fit stranded the fifth on a row of its own at
     common phone widths; centred flex-wrap fits five across where there is room
     and centres the remainder where there isn't, so an odd row reads deliberate. */
  .gv-v3-atc-trust { display: flex; flex-wrap: wrap; justify-content: center; gap: 14px 4px; margin-top: 16px; padding: 14px 10px; background: #f5f6f8; border-radius: 14px; }
  .gv-v3-atc-trust-item { flex: 0 1 82px; min-width: 0; text-align: center; font-size: 10.5px; font-weight: 600; color: #444; line-height: 1.3; display: flex; flex-direction: column; align-items: center; gap: 5px; }
  .gv-v3-atc-trust-item svg { color: var(--gv-pink); }


  /* Guarantee */
  .gv-v3-guarantee { display: flex; align-items: center; gap: 14px; margin-top: 16px; padding: 16px; background: linear-gradient(160deg,#f1fbf4,#e6f7ec); border: 1px solid #bfe6cb; border-radius: 16px; }
  .gv-v3-guarantee-badge { flex: 0 0 auto; width: 56px; height: 56px; border-radius: 50%; background: #1fbf5b; color: #fff; font-weight: 800; font-size: 22px; line-height: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; box-shadow: 0 6px 16px rgba(31,191,91,.35); }
  .gv-v3-guarantee-badge small { font-size: 9px; font-weight: 700; letter-spacing: .5px; margin-top: 2px; }
  .gv-v3-guarantee-title { font-size: 15px; font-weight: 700; margin: 0; }
  .gv-v3-guarantee-sub { font-size: 12.5px; color: #41614c; line-height: 1.35; margin: 3px 0 0; }
  /* Prominent variant: sits directly under the buy buttons, so it carries more weight. */
  .gv-v3-guarantee--lg { margin-top: 14px; padding: 18px 18px 18px 16px; border-width: 2px; box-shadow: 0 6px 18px rgba(31,191,91,.14); }
  .gv-v3-guarantee--lg .gv-v3-guarantee-badge { width: 64px; height: 64px; font-size: 24px; }
  .gv-v3-guarantee--lg .gv-v3-guarantee-title { font-size: 16.5px; }
  .gv-v3-guarantee--lg .gv-v3-guarantee-sub { font-size: 13px; margin-top: 5px; }

  /* Sticky buy bar (mobile only) */
  /* Under 8 — see the pill nav note above: the menu drawer is trapped in the
     sticky header's z-index:8 stacking context, so anything >= 8 covers it. */
  .gv-v3-sticky-buy { position: fixed; bottom: 0; left: 0; right: 0; z-index: var(--layer-heightened, 4); display: flex; align-items: center; gap: 12px; padding: 10px 14px calc(10px + env(safe-area-inset-bottom)); background: #fff; border-top: 1px solid #eceef1; box-shadow: 0 -6px 24px rgba(0,0,0,.12); }
  .gv-v3-sticky-info { display: flex; flex-direction: column; line-height: 1.2; }
  .gv-v3-sticky-price { font-size: 19px; font-weight: 800; }
  .gv-v3-sticky-price s { font-size: 14px; color: #9aa0a8; font-weight: 600; margin-left: 4px; }
  .gv-v3-sticky-sub { font-size: 12px; color: var(--gv-pink); font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 45vw; }
  .gv-v3-sticky-sub:empty { display: none; }
  .gv-v3-sticky-atc { flex: 1; height: 48px; border: none; cursor: pointer; background: var(--gv-pink); color: #fff; font-weight: 700; font-size: 16px; letter-spacing: .5px; border-radius: 12px; }

  /* Gallery zoom overlay */
  .gv-v3-zoom { position: fixed; inset: 0; z-index: 9999; background: rgba(0,0,0,.9); display: flex; align-items: center; justify-content: center; overflow: auto; padding: 16px; }
  .gv-v3-zoom[hidden] { display: none; }
  .gv-v3-zoom img { max-width: 100%; max-height: 100%; object-fit: contain; cursor: zoom-in; }
  .gv-v3-zoom.gv-zoomed { align-items: flex-start; justify-content: flex-start; }
  .gv-v3-zoom.gv-zoomed img { max-width: none; max-height: none; width: 170%; cursor: zoom-out; }
  .gv-v3-zoom-close { position: fixed; top: 16px; right: 18px; z-index: 1; width: 42px; height: 42px; border-radius: 50%; border: none; background: rgba(255,255,255,.15); color: #fff; font-size: 24px; line-height: 1; cursor: pointer; }

  /* Modal */
  .gv-v3-pdp-modal { position: fixed; inset: 0; z-index: 100; background: rgba(20,22,28,.55); display: flex; align-items: center; justify-content: center; padding: 24px; }
  .gv-v3-pdp-modal[hidden] { display: none; }
  .gv-v3-pdp-modal-card { background: #fff; border-radius: 18px; padding: 22px 20px; max-width: 340px; width: 100%; position: relative; box-shadow: 0 20px 60px rgba(0,0,0,.3); font-family: var(--legacy-font-sans); }
  .gv-v3-pdp-modal-close { position: absolute; top: 12px; right: 14px; border: none; background: none; font-size: 22px; cursor: pointer; color: #999; line-height: 1; }
  .gv-v3-pdp-modal-title { font-size: 18px; font-weight: 700; margin: 0 24px 10px 0; }
  .gv-v3-pdp-modal-text { font-size: 14px; color: #555; line-height: 1.5; margin: 0; }

  /* ============ Desktop (>=1000px): two columns ============ */
  @media (min-width: 1000px) {
    .gv-v3-pdp-wrap { display: grid; grid-template-columns: minmax(0,1.05fr) minmax(0,0.95fr); column-gap: 48px; align-items: start; padding: 30px 34px; }
    .gv-v3-gallery { grid-column: 1; grid-row: 1 / span 50; position: sticky; top: calc(var(--header-height, 56px) + 70px); }
    .gv-v3-pdp-head, .gv-v3-helpswrap, .gv-v3-buyinfo { grid-column: 2; }
    .gv-v3-pdp-head { margin-top: 0; }
    .gv-v3-pdp-titlerow { margin-top: 0; }
    .gv-v3-pdp-title { font-size: 30px; margin-top: 0; }
    .gv-v3-thumb { width: 66px; height: 66px; }
    .gv-v3-sticky-buy { display: none; }
  }

  .gv-v3-save {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    margin: 14px 0 0; font-family: var(--legacy-font-sans);
  }
  .gv-v3-save-amt { font-size: 15px; font-weight: 700; color: var(--coral-pulse, #FF4D8D); }
  .gv-v3-save-pct {
    font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
    color: var(--coral-pulse, #FF4D8D); background: #ffe3ee;
    border-radius: 20px; padding: 3px 9px;
  }

  /* ---- Brand pink, belt and braces ----
     The family accent no longer feeds --gv-pink at all (see the note above the
     section tag), so these already resolve to #FF4D8D. Kept as a guard: if a
     per-product tint is ever reintroduced, the solid fills must not follow it.
     Guidelines: "Primary CTA: bg #FF4D8D". */
  .gv-v3-atc,
  .gv-v3-sticky-atc,
  .gv-v3-pack-badge { background: var(--legacy-pink, #FF4D8D); }
  .gv-v3-target-pill::before { background-color: var(--legacy-pink, #FF4D8D); }
  .gv-v3-atc:hover,
  .gv-v3-sticky-atc:hover { background: var(--brand-pink-dark, #E63974); }
  /* cyan "Best Value" badge keeps its own colour -- restated after the pin above */
  .gv-v3-pack-badge--alt { background: #2fc6e8; }

/* ---- shopify/gv-v3-pdp-details.css ---- */
/* Ported verbatim from sections/gv-v3-pdp-details.liquid (stylesheet). */
.gv-v3-pdp-sec { background: #fff; scroll-margin-top: 120px; }
  .gv-v3-pdp-inner { max-width: 980px; margin: 0 auto; padding: 0 16px; }

  .gv-v3-acc { background: #fff; border: 1px solid #ECECEC; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,.06); margin-top: var(--gv-stk-gap, 14px); transition: border-color .15s, box-shadow .15s; }
  .gv-v3-acc:hover { border-color: #dcdcdc; box-shadow: 0 6px 20px rgba(0,0,0,.08); }
  .gv-v3-acc[open] { border-color: var(--coral-pulse, #FF4D8D); }
  .gv-v3-acc summary {
    list-style: none; cursor: pointer; padding: 18px;
    font-family: var(--legacy-font-sans); font-size: 18px; font-weight: 700; color: var(--text-dark, #1a1a1a);
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
  }
  .gv-v3-acc summary::-webkit-details-marker { display: none; }
  .gv-v3-chev { flex: 0 0 auto; width: 28px; height: 28px; border-radius: 50%; background: #f1f2f4; display: grid; place-items: center; color: var(--text-dark, #1a1a1a); transition: transform .2s, background .15s, color .15s; transform: rotate(90deg); }
  .gv-v3-acc[open] .gv-v3-chev { transform: rotate(-90deg); background: #ffe3ee; color: var(--coral-pulse, #FF4D8D); }
  .gv-v3-acc-body { padding: 0 18px 18px; color: #555; font-family: var(--legacy-font-sans); font-size: 14px; }

  .gv-v3-detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px 14px; }
  .gv-v3-detail-item { display: flex; align-items: center; gap: 10px; font-family: var(--legacy-font-sans); font-size: 13px; font-weight: 500; color: var(--text-dark, #1a1a1a); line-height: 1.2; }
  .gv-v3-detail-item svg { color: var(--coral-pulse, #FF4D8D); flex: 0 0 auto; }

  /* ---- Story ---- */
  /* Built to scan in five seconds and read in thirty: one lead line, one short
     chapter per Targets pill, one honest note. Copy is capped at 640px because
     the accordion runs 980px wide on desktop and prose that long is unreadable.
     Keep the bodies to a sentence or two — the point of this panel is that it
     can be skimmed on the headings alone. */
  .gv-v3-story { max-width: 640px; }
  /* story.heading is the hook line; story.lead is ordinary body under it. */
  .gv-v3-story-lead-h {
    margin: 0 0 7px; font-size: 17px; line-height: 1.3; font-weight: 700;
    color: var(--text-dark, #1a1a1a); letter-spacing: -.01em;
  }
  .gv-v3-story-lead p { margin: 0 0 8px; font-size: 14.5px; line-height: 1.65; color: #555; }
  .gv-v3-story-lead p:last-child { margin-bottom: 0; }

  .gv-v3-story-ch { margin-top: 14px; padding-top: 14px; border-top: 1px solid #ECECEC; }
  .gv-v3-story-eyebrow {
    display: inline-block; font-size: 10.5px; font-weight: 700; text-transform: uppercase;
    letter-spacing: .10em; color: var(--coral-pulse, #FF4D8D); margin-bottom: 4px;
  }
  .gv-v3-story-h {
    margin: 0 0 5px; font-size: 16px; line-height: 1.35; font-weight: 700;
    color: var(--text-dark, #1a1a1a); letter-spacing: -.01em;
  }
  .gv-v3-story-p { margin: 0 0 7px; font-size: 14.5px; line-height: 1.6; color: #555; }
  .gv-v3-story-p:last-child { margin-bottom: 0; }
  .gv-v3-story-p strong { color: var(--text-dark, #1a1a1a); font-weight: 600; }

  .gv-v3-story-note {
    margin-top: 18px; padding: 14px 16px; background: #fff;
    border: 1px solid #ECECEC; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,.06);
  }
  .gv-v3-story-note-h {
    margin: 0 0 5px; font-size: 11px; font-weight: 700; text-transform: uppercase;
    letter-spacing: .08em; color: var(--text-dark, #1a1a1a);
  }
  .gv-v3-story-note p { margin: 0 0 7px; font-size: 13.5px; line-height: 1.6; color: #555; }
  .gv-v3-story-note p:last-child { margin-bottom: 0; }

  @media (max-width: 700px) {
    .gv-v3-detail-grid { grid-template-columns: 1fr; gap: 12px; }
  }

/* ---- shopify/gv-v3-pdp-science.css ---- */
/* Ported verbatim from sections/gv-v3-pdp-science.liquid (stylesheet). */
/* Band and padding come from the .gv-section layout component (01-base.css):
   gv-section--pad for a tinted band's inset, gv-section--sky for the ground.
   This used to hard-code #e8f4fb and its own padding, which is why the page
   ran at four different section rhythms. --accent-sky is the token that was
   already named "the science section ground". */
  .gv-v3-science-inner { max-width: 940px; margin: 0 auto; padding: 0 18px; font-family: var(--legacy-font-sans); }
  .gv-v3-science-title { color: var(--text-dark, #1a1a1a); font-size: 24px; font-weight: 800; margin: 0 0 18px; }

  /* One column. The ported layout kept a second 1.1fr column for an image that
     this section never renders, so the words were squeezed into 47% of the band
     and the other half sat empty. The prose keeps a readable measure; the
     pathway list runs the full width, in line with the comparison rows above. */
  .gv-v3-science-body { display: flex; flex-direction: column; gap: var(--gv-stk-gap); }
  .gv-v3-stat-text { max-width: 62ch; }

  .gv-v3-derm-check { display: inline-grid; place-items: center; width: 48px; height: 48px; border-radius: 50%; background: #1fbf5b; color: #fff; margin-bottom: 12px; }
  .gv-v3-stat-text { font-size: 16px; color: var(--text-dark, #1a1a1a); margin: 0; }
  .gv-v3-stat-text strong { font-weight: 800; }
  .gv-v3-derm-points { list-style: none; margin: 14px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
  .gv-v3-derm-points li { position: relative; padding-left: 24px; font-size: 13.5px; color: #1b4d59; font-weight: 600; }
  .gv-v3-derm-points li::before { content: "✓"; position: absolute; left: 0; color: #1b9fd1; font-weight: 800; }

  /* Head-to-head bar */
  .gv-v3-sci-cmp { display: flex; flex-direction: column; gap: 8px; margin: 0 0 20px; }
  .gv-v3-sci-cmp-row { display: grid; grid-template-columns: minmax(140px, 1.1fr) auto minmax(120px, 1fr); align-items: center; gap: 14px; background: rgba(255,255,255,.55); border: 1px solid #cbe3f1; border-radius: 12px; padding: 11px 14px; }
  .gv-v3-sci-cmp-row.is-ours { background: #fff; border-color: #1b9fd1; box-shadow: 0 3px 12px rgba(27,159,209,.16); }
  .gv-v3-sci-cmp-label { font-size: 13.5px; font-weight: 700; color: #2b4a55; }
  .gv-v3-sci-cmp-row.is-ours .gv-v3-sci-cmp-label { color: var(--text-dark, #1a1a1a); }
  .gv-v3-sci-cmp-dots { display: inline-flex; gap: 5px; }
  .gv-v3-sci-dot { width: 15px; height: 15px; border-radius: 4px; background: #fff; border: 1.5px solid #a9cfe3; }
  .gv-v3-sci-dot.is-on { background: #9db7c4; border-color: #9db7c4; }
  .gv-v3-sci-cmp-row.is-ours .gv-v3-sci-dot.is-on { background: #1b9fd1; border-color: #1b9fd1; }
  .gv-v3-sci-cmp-note { font-size: 12.5px; font-weight: 600; color: #2b4a55; text-align: right; }
  .gv-v3-sci-cmp-row.is-ours .gv-v3-sci-cmp-note { color: #1b9fd1; }

  /* Numbered pathway rail */
  .gv-v3-sci-rail { list-style: none; margin: 14px 0 0; padding: 0; counter-reset: none; }
  .gv-v3-sci-path { display: grid; grid-template-columns: 34px 1fr; gap: 12px; align-items: start; padding: 10px 0; border-top: 1px solid rgba(27,159,209,.22); }
  .gv-v3-sci-path:first-child { border-top: 0; padding-top: 0; }
  .gv-v3-sci-n { font-size: 13px; font-weight: 800; color: #1b9fd1; letter-spacing: .5px; line-height: 1.5; font-variant-numeric: tabular-nums; }
  .gv-v3-sci-txt { display: flex; flex-direction: column; gap: 2px; }
  .gv-v3-sci-proc { font-size: 14px; font-weight: 700; color: var(--text-dark, #1a1a1a); line-height: 1.35; }
  .gv-v3-sci-act { font-size: 12.5px; font-weight: 600; color: #1b4d59; }
  .gv-v3-sci-act::before { content: "\2192  "; color: #1b9fd1; }

  @media (max-width: 700px) {
    .gv-v3-sci-cmp-row { grid-template-columns: 1fr; gap: 7px; }
    .gv-v3-sci-cmp-note { text-align: left; }
  }

  .gv-v3-science-note { font-size: 11px; color: #2b4a55; margin-top: 18px; border-bottom: 1px solid rgba(0,0,0,.2); padding-bottom: 16px; }
  .gv-v3-science-result { font-size: 18px; margin-top: 16px; color: var(--text-dark, #1a1a1a); }
  .gv-v3-science-result-big { color: #1b9fd1; font-size: 22px; font-weight: 800; margin-top: 4px; }

/* ---- shopify/gv-v3-pdp-trending.css ---- */
/* Ported verbatim from sections/gv-v3-pdp-trending.liquid (stylesheet). */
.gv-v3-trending { padding: 0; background: #fff; }
  .gv-v3-trending-title {
    text-align: center;
    font-family: var(--legacy-font-sans);
    font-size: 24px;
    font-weight: 700;
    color: var(--text-dark, #1a1a1a);
    margin: 0 0 18px;
  }
  .gv-v3-trending-row { display: flex; gap: 12px; overflow-x: auto; scrollbar-width: none; }
  .gv-v3-trending-row::-webkit-scrollbar { display: none; }
  .gv-v3-trending-row .gv-reel { flex: 0 0 58%; }

  @media (min-width: 1000px) {
    .gv-v3-trending-row { justify-content: center; }
    .gv-v3-trending-row .gv-reel { flex: 0 1 240px; max-width: 240px; }
  }

/* ---- shopify/gv-v3-promise.css ---- */
/* Ported verbatim from sections/gv-v3-promise.liquid (stylesheet). */
.gv-v3-promise { background: linear-gradient(90deg, #ffe2e9, #ffc2d3, #ffb0c6); padding: 48px 0 54px; }
  .gv-v3-promise .gv-v3-wrap { max-width: 1240px; margin: 0 auto; padding: 0 20px; }
  .gv-v3-promise-title {
    text-align: center;
    font-family: var(--legacy-font-sans);
    font-size: 30px;
    font-weight: 800;
    letter-spacing: -0.5px;
    color: var(--text-dark, #1a1a1a);
    margin: 0 0 26px;
  }
  .gv-v3-promise-row { display: flex; justify-content: center; gap: 14px; max-width: 1040px; margin: 0 auto; }
  .gv-v3-promise-item {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 13px;
    padding: 0 6px;
  }
  .gv-v3-promise-ic {
    width: 66px;
    height: 66px;
    border-radius: 50%;
    background: #fff;
    display: grid;
    place-items: center;
    color: var(--coral-pulse, #ff4d8d);
    box-shadow: 0 8px 18px rgba(214,30,98,0.16);
  }
  .gv-v3-promise-ic svg { display: block; }
  .gv-v3-promise-label { font-family: var(--legacy-font-sans); font-size: 13.5px; font-weight: 700; color: #3a2230; line-height: 1.3; }

  @media (max-width: 640px) {
    .gv-v3-promise-title { font-size: 24px; }
    .gv-v3-promise-row { flex-wrap: wrap; gap: 22px 10px; }
    .gv-v3-promise-item { flex: 0 0 30%; }
    .gv-v3-promise-ic { width: 58px; height: 58px; }
  }

/* ---- shopify/gv-v3-promo-banner.css ---- */
/* Ported verbatim from sections/gv-v3-promo-banner.liquid (stylesheet). */
.gv-v3-promo-wrap { padding: 24px 0; background: #fff; }
  .gv-v3-promo-wrap .gv-v3-wrap { max-width: 1240px; margin: 0 auto; padding: 0 20px; }

  .gv-v3-promo {
    position: relative;
    border-radius: 18px;
    overflow: hidden;
    isolation: isolate;
  }

  /* Gradient fallback when no image is set */
  .gv-v3-promo--gradient {
    background: linear-gradient(90deg, #ffd9e6, #ff9cc4 55%, var(--coral-pulse, #ff4d8d) 110%);
    min-height: var(--gv-promo-h, 450px);
  }

  /* Background image — fixed height on desktop so the box is a known canvas */
  .gv-v3-promo-pic { display: block; }
  .gv-v3-promo-img {
    display: block;
    width: 100%;
    height: var(--gv-promo-h, 450px);   /* desktop canvas ~2400x900 */
    object-fit: cover;
  }

  /* Legibility scrim behind the text */
  .gv-v3-promo-scrim { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
  .gv-v3-promo-scrim--dark  { background: linear-gradient(105deg, rgba(0,0,0,0.48) 0%, rgba(0,0,0,0.16) 46%, rgba(0,0,0,0) 72%); }
  .gv-v3-promo-scrim--light { background: linear-gradient(105deg, rgba(255,255,255,0.6) 0%, rgba(255,255,255,0.2) 46%, rgba(255,255,255,0) 72%); }

  /* Text overlay */
  .gv-v3-promo--img .gv-v3-promo-text {
    position: absolute;
    inset: 0;
    z-index: 2;
    display: flex;
    flex-direction: column;
    padding: 26px 44px;
  }
  .gv-v3-promo--gradient .gv-v3-promo-text { padding: 26px 44px; }

  /* Position presets (desktop) */
  .gv-v3-promo--pos-top-left      .gv-v3-promo-text { justify-content: flex-start; align-items: flex-start; }
  .gv-v3-promo--pos-top-center    .gv-v3-promo-text { justify-content: flex-start; align-items: center; text-align: center; }
  .gv-v3-promo--pos-middle-left   .gv-v3-promo-text { justify-content: center;     align-items: flex-start; }
  .gv-v3-promo--pos-middle-center .gv-v3-promo-text { justify-content: center;     align-items: center; text-align: center; }
  .gv-v3-promo--pos-bottom-left   .gv-v3-promo-text { justify-content: flex-end;   align-items: flex-start; }
  .gv-v3-promo--pos-bottom-center .gv-v3-promo-text { justify-content: flex-end;   align-items: center; text-align: center; }

  .gv-v3-promo-inner { max-width: 460px; }

  .gv-v3-promo-text--light { color: #fff; }
  .gv-v3-promo-text--dark  { color: var(--berry-dark, #3a0d22); }

  .gv-v3-promo-a {
    font-family: var(--legacy-font-sans);
    font-size: 30px;
    font-weight: 900;
    line-height: 1.05;
    margin: 0;
  }
  .gv-v3-promo-text--light .gv-v3-promo-a { text-shadow: 0 2px 6px rgba(90,10,45,0.35); }
  .gv-v3-promo-b {
    font-family: var(--legacy-font-sans);
    font-size: 15px;
    font-weight: 600;
    margin: 8px 0 16px;
    line-height: 1.5;
  }
  .gv-v3-promo-text--light .gv-v3-promo-b { text-shadow: 0 1px 4px rgba(90,10,45,0.3); }

  .gv-v3-promo-ctas { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; }
  .gv-v3-promo--pos-top-center .gv-v3-promo-ctas,
  .gv-v3-promo--pos-middle-center .gv-v3-promo-ctas,
  .gv-v3-promo--pos-bottom-center .gv-v3-promo-ctas { justify-content: center; }

  .gv-v3-promo-cta {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-family: var(--legacy-font-sans);
    font-weight: 800;
    font-size: 14px;
    border-radius: 100px;
    padding: 11px 24px;
    text-decoration: none;
    transition: transform 0.2s;
  }
  .gv-v3-promo-cta:hover { transform: scale(1.03); }
  .gv-v3-promo-cta--primary { background: #fff; color: var(--coral-dark, #e63974); }
  .gv-v3-promo-cta--secondary {
    background: var(--coral-pulse, #ff4d8d);
    color: #fff;
    box-shadow: inset 0 0 0 1px rgba(255,255,255,0.35);
  }

  /* Mobile — square image, text pinned to the top-center over the calm zone */
  @media (max-width: 640px) {
    .gv-v3-promo-img { height: auto; aspect-ratio: 4 / 5; }   /* mobile canvas 1080x1350 */
    .gv-v3-promo--gradient { min-height: 180px; }
    .gv-v3-promo--img .gv-v3-promo-text {
      justify-content: flex-start;
      align-items: center;
      text-align: center;
      padding: 22px 20px;
    }
    .gv-v3-promo--gradient .gv-v3-promo-text { text-align: center; padding: 24px 22px; }
    .gv-v3-promo-inner { max-width: 100%; }
    .gv-v3-promo-a { font-size: 24px; }
    .gv-v3-promo-scrim--dark  { background: linear-gradient(180deg, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0.15) 42%, rgba(0,0,0,0) 62%); }
    .gv-v3-promo-scrim--light { background: linear-gradient(180deg, rgba(255,255,255,0.65) 0%, rgba(255,255,255,0.2) 42%, rgba(255,255,255,0) 62%); }
    .gv-v3-promo-ctas { justify-content: center; }
  }

/* ---- shopify/gv-v3-quiz-band.css ---- */
/* Ported verbatim from sections/gv-v3-quiz-band.liquid (stylesheet). */
.gv-v3-quiz {
    position: relative;
    background: var(--coral-pulse, #ff4d8d);
    padding: 36px 20px 42px;
    margin: 40px 0;
    text-align: center;
  }
  /* scalloped bottom edge (D&K style) */
  .gv-v3-quiz::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -14px;
    height: 16px;
    background: radial-gradient(circle at 12px -4px, var(--coral-pulse, #ff4d8d) 12px, transparent 13px);
    background-size: 28px 16px;
  }
  .gv-v3-quiz-inner {
    max-width: 1100px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 30px;
    flex-wrap: wrap;
    color: #fff;
  }
  .gv-v3-quiz-h {
    font-family: var(--legacy-font-sans);
    font-size: 28px;
    font-weight: 900;
    letter-spacing: 0.2px;
    margin: 0;
  }
  .gv-v3-quiz-p {
    font-family: var(--legacy-font-sans);
    font-size: 14px;
    font-weight: 500;
    opacity: 0.95;
    margin: 5px 0 0;
  }
  .gv-v3-quiz-btn {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    background: #fff;
    color: var(--coral-dark, #e63974);
    font-family: var(--legacy-font-sans);
    font-weight: 800;
    font-size: 15px;
    border-radius: 100px;
    padding: 14px 30px;
    text-decoration: none;
    transition: transform 0.2s;
  }
  .gv-v3-quiz-btn:hover { transform: scale(1.03); }

  @media (max-width: 640px) {
    .gv-v3-quiz-inner { flex-direction: column; gap: 16px; }
    .gv-v3-quiz-h { font-size: 23px; }
  }

/* ---- shopify/gv-v3-reels.css ---- */
/* Ported verbatim from sections/gv-v3-reels.liquid (stylesheet). */
.gv-v3-reels { padding: 16px 0 36px; background: #fff; }
  .gv-v3-reels .gv-v3-wrap { max-width: 1240px; margin: 0 auto; padding: 0 20px; }
  .gv-v3-reels-title {
    text-align: center;
    font-family: var(--legacy-font-sans);
    font-size: 30px;
    font-weight: 800;
    letter-spacing: -0.5px;
    color: var(--text-dark, #1a1a1a);
    margin: 30px 0 22px;
  }

  .gv-v3-reels-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 18px; }

  .gv-v3-reels-caption { text-align: center; margin: 22px 0 4px; display: flex; flex-direction: column; align-items: center; gap: 3px; }
  .gv-v3-reels-cap-a {
    font-family: var(--legacy-font-sans);
    font-size: 18px;
    font-weight: 800;
    color: var(--text-dark, #1a1a1a);
    margin: 0;
    display: inline-flex;
    align-items: center;
    gap: 8px;
  }
  .gv-v3-reels-cap-a::before,
  .gv-v3-reels-cap-a::after { content: "\25C7"; color: var(--coral-pulse, #ff4d8d); font-size: 12px; }
  .gv-v3-reels-cap-b { font-family: var(--legacy-font-sans); font-size: 13.5px; color: var(--text-gray, #666); margin: 0; }

  /* Desktop shows a fixed 5-across grid, which doesn't scroll — so it has nothing
     to loop, and the infinite-scroll clones would just spill into extra rows. */
  @media (min-width: 981px) {
    .gv-v3-reels-grid .gv-reel--clone { display: none; }
  }

  @media (max-width: 980px) {
    .gv-v3-reels-grid { display: flex; overflow-x: auto; gap: 12px; scrollbar-width: none; }
    .gv-v3-reels-grid::-webkit-scrollbar { display: none; }
    .gv-v3-reels-grid .gv-reel { flex: 0 0 60%; }
  }
  @media (max-width: 640px) {
    .gv-v3-reels-title { font-size: 24px; }
  }

/* ---- shopify/gv-v3-routine.css ---- */
/* Ported verbatim from sections/gv-v3-routine.liquid (stylesheet). */
.gv-v3-routine { padding: 24px 0 48px; background: #fff; }
  .gv-v3-routine .gv-v3-wrap { max-width: 1240px; margin: 0 auto; padding: 0 20px; }
  .gv-v3-routine-title {
    text-align: center;
    font-family: var(--legacy-font-sans);
    font-size: 30px;
    font-weight: 800;
    letter-spacing: -0.5px;
    color: var(--text-dark, #1a1a1a);
    margin: 30px 0 22px;
  }

  /* Carousel shell (self-contained — used by several V3 sections) */
  .gv-v3-routine .gv-v3-car-shell { position: relative; }
  .gv-v3-routine .gv-v3-car {
    display: flex;
    gap: 18px;
    overflow-x: auto;
    scroll-behavior: smooth;
    scroll-snap-type: x proximity;
    padding: 6px 2px 14px;
    scrollbar-width: none;
  }
  .gv-v3-routine .gv-v3-car::-webkit-scrollbar { display: none; }
  .gv-v3-routine .gv-v3-car-btn {
    position: absolute;
    top: 40%;
    transform: translateY(-50%);
    z-index: 4;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: #fff;
    border: 1px solid var(--gray-light, #ececec);
    box-shadow: 0 3px 10px rgba(0,0,0,0.12);
    display: grid;
    place-items: center;
    color: var(--text-dark, #1a1a1a);
    cursor: pointer;
  }
  .gv-v3-routine .gv-v3-car-prev { left: -8px; }
  .gv-v3-routine .gv-v3-car-prev svg { transform: rotate(180deg); }
  .gv-v3-routine .gv-v3-car-next { right: -8px; }

  /* Bundle card */
  .gv-v3-bcard {
    flex: 0 0 272px;
    scroll-snap-align: start;
    display: flex;
    flex-direction: column;
    border: 1px solid var(--gray-light, #ececec);
    border-radius: 14px;
    overflow: hidden;
    background: #fff;
    position: relative;
    transition: transform 0.25s, box-shadow 0.25s;
  }
  .gv-v3-bcard:hover { transform: translateY(-4px); box-shadow: 0 14px 30px rgba(0,0,0,0.09); }

  .gv-v3-bcard-badge {
    position: absolute;
    top: 10px;
    left: 10px;
    z-index: 2;
    background: var(--coral-pulse, #ff4d8d);
    color: #fff;
    font-family: var(--legacy-font-sans);
    font-size: 10px;
    font-weight: 800;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    border-radius: 5px;
    padding: 3px 8px;
  }
  /* Sale badge: campaign ink, so a live discount reads differently from the
     evergreen pink badge. Reverts by itself when compare-at is cleared.
     (Was Azadi flag green through Aug 2026; now the 9.9 dark ground.) */
  .gv-v3-bcard-badge--sale { background: #1A1A1A; }

  .gv-v3-bcard-media {
    height: 220px;
    background: linear-gradient(135deg, #fff0f6, #ffe2ec);
    display: flex;
    gap: 0;
    align-items: stretch;
    justify-content: center;
    padding: 0;
    overflow: hidden;
  }
  /* Images fill the square edge-to-edge; multiple images split it evenly */
  .gv-v3-bcard-media img { flex: 1 1 0; min-width: 0; height: 100%; width: 100%; object-fit: cover; display: block; }
  .gv-v3-bcard-ph { height: 100%; width: 100%; object-fit: cover; }

  .gv-v3-bcard-body { padding: 14px; display: flex; flex-direction: column; gap: 9px; flex: 1; }
  .gv-v3-bcard-skintype { align-self: flex-start; font-family: var(--legacy-font-sans); font-size: 11px; font-weight: 600; color: var(--text-dark, #1a1a1a); background: #f4f5f7; border-radius: 5px; padding: 4px 9px; }
  .gv-v3-bcard-contents { align-self: flex-start; font-family: var(--legacy-font-sans); font-size: 11px; color: var(--text-gray, #666); }
  .gv-v3-bcard-title { margin: 0; font-family: var(--legacy-font-sans); font-size: 15px; font-weight: 700; line-height: 1.25; }
  .gv-v3-bcard-title a { color: var(--text-dark, #1a1a1a); text-decoration: none; }
  .gv-v3-bcard-title a:hover { color: var(--coral-pulse, #ff4d8d); }
  .gv-v3-bcard-desc { margin: -2px 0 0; font-family: var(--legacy-font-sans); font-size: 12px; color: var(--text-gray, #666); line-height: 1.4; }
  .gv-v3-bcard-offer { align-self: flex-start; font-family: var(--legacy-font-sans); font-size: 11.5px; font-weight: 600; color: var(--coral-pulse, #ff4d8d); background: #ffeef5; border-radius: 6px; padding: 5px 9px; }

  .gv-v3-bcard-foot { margin-top: auto; display: flex; flex-direction: column; gap: 10px; }
  .gv-v3-bcard-price { font-family: var(--legacy-font-sans); }
  .gv-v3-bcard-price .gv-v3-price-now { font-size: 19px; font-weight: 800; color: var(--text-dark, #1a1a1a); }
  .gv-v3-bcard-price .gv-v3-price-old { font-size: 13px; color: #9aa3ad; margin-left: 6px; }
  .gv-v3-bcard-price .gv-v3-price-save { font-size: 11px; color: #7cc70a; font-weight: 700; margin-left: 6px; }
  .gv-v3-bcard-pick { font-family: var(--legacy-font-sans); font-size: 12px; color: var(--text-gray, #666); margin: 0; }

  .gv-v3-routine .gv-v3-card-atc {
    width: 100%;
    background: var(--coral-pulse, #ff4d8d);
    color: #fff;
    font-family: var(--legacy-font-sans);
    font-weight: 800;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    font-size: 12px;
    border: none;
    border-radius: 9px;
    padding: 12px;
    cursor: pointer;
    transition: background 0.2s;
  }
  .gv-v3-routine .gv-v3-card-atc:hover { background: var(--coral-dark, #e63974); }
  .gv-v3-routine .gv-v3-card-atc--out { background: var(--gray-light, #ececec); color: var(--text-gray, #666); cursor: default; }
  .gv-v3-routine .gv-v3-card-atc.gv-v3-loading { opacity: 0.75; cursor: wait; }

  @media (max-width: 640px) {
    .gv-v3-routine-title { font-size: 24px; }
    .gv-v3-bcard { flex-basis: 60vw; }
    .gv-v3-routine .gv-v3-car-btn { display: none; }
  }

/* ---- shopify/gv-v3-testimonials.css ---- */
/* Ported verbatim from sections/gv-v3-testimonials.liquid (stylesheet). */
.gv-v3-tst { padding: 16px 0 48px; background: #fff; }
  .gv-v3-tst .gv-v3-wrap { max-width: 1240px; margin: 0 auto; padding: 0 20px; }
  .gv-v3-tst-title {
    text-align: center;
    font-family: var(--legacy-font-sans);
    font-size: 30px;
    font-weight: 800;
    letter-spacing: -0.5px;
    color: var(--text-dark, #1a1a1a);
    margin: 30px 0 22px;
  }

  /* Carousel shell (self-contained) */
  .gv-v3-tst .gv-v3-car-shell { position: relative; }
  .gv-v3-tst .gv-v3-car {
    display: flex;
    gap: 18px;
    overflow-x: auto;
    scroll-behavior: smooth;
    scroll-snap-type: x proximity;
    padding: 6px 2px 14px;
    scrollbar-width: none;
  }
  .gv-v3-tst .gv-v3-car::-webkit-scrollbar { display: none; }
  .gv-v3-tst .gv-v3-car-btn {
    position: absolute;
    top: 42%;
    transform: translateY(-50%);
    z-index: 4;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: #fff;
    border: 1px solid var(--gray-light, #ececec);
    box-shadow: 0 3px 10px rgba(0,0,0,0.12);
    display: grid;
    place-items: center;
    color: var(--text-dark, #1a1a1a);
    cursor: pointer;
  }
  .gv-v3-tst .gv-v3-car-prev { left: -8px; }
  .gv-v3-tst .gv-v3-car-prev svg { transform: rotate(180deg); }
  .gv-v3-tst .gv-v3-car-next { right: -8px; }

  .gv-v3-tcard {
    flex: 0 0 330px;
    scroll-snap-align: start;
    border: 1px solid var(--gray-light, #ececec);
    border-radius: 14px;
    padding: 20px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    background: #fff;
  }
  .gv-v3-tcard-head { display: flex; align-items: center; gap: 12px; }
  .gv-v3-tcard-avatar {
    width: 50px;
    height: 50px;
    flex: 0 0 50px;
    border-radius: 50%;
    overflow: hidden;
    background: linear-gradient(135deg, #ffd6e6, #ffe7d6);
    display: grid;
    place-items: center;
    font-family: var(--legacy-font-sans);
    font-weight: 800;
    color: var(--coral-pulse, #ff4d8d);
    font-size: 18px;
  }
  .gv-v3-tcard-avatar img { width: 100%; height: 100%; object-fit: cover; }
  .gv-v3-tcard-who { display: flex; flex-direction: column; }
  .gv-v3-tcard-name { font-family: var(--legacy-font-sans); font-weight: 800; font-size: 14px; display: flex; align-items: center; gap: 6px; color: var(--text-dark, #1a1a1a); }
  .gv-v3-tcard-verif { color: #2ea7ff; display: inline-flex; }
  .gv-v3-tcard-meta { font-family: var(--legacy-font-sans); font-size: 11px; color: var(--text-gray, #666); }
  .gv-v3-tcard-stars { display: inline-flex; color: #7cc70a; }
  .gv-v3-tcard-stars svg { display: block; }
  .gv-v3-tcard-ttl { font-family: var(--legacy-font-sans); font-weight: 700; font-size: 15px; color: var(--text-dark, #1a1a1a); }
  .gv-v3-tcard-text { font-family: var(--legacy-font-sans); font-size: 13px; color: var(--text-gray, #666); line-height: 1.5; margin: 0; }
  .gv-v3-tcard-rec { font-family: var(--legacy-font-sans); font-size: 12px; color: var(--text-dark, #1a1a1a); font-weight: 600; margin-top: auto; }
  .gv-v3-tcard-shop { font-family: var(--legacy-font-sans); color: var(--coral-pulse, #ff4d8d); font-weight: 800; font-size: 13px; text-decoration: none; display: inline-flex; align-items: center; gap: 3px; }
  .gv-v3-tcard-shop:hover { color: var(--coral-dark, #e63974); }

  @media (max-width: 640px) {
    .gv-v3-tst-title { font-size: 24px; }
    .gv-v3-tcard { flex-basis: 82vw; }
    .gv-v3-tst .gv-v3-car-btn { display: none; }
  }

/* ---- components/badge.css ---- */
/* Pills and badges. */

.gv-legacy-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 20px;
  background: var(--brand-pink-ink);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  line-height: 1.6;
}

.gv-legacy-badge--alt     { background: #2FC6E8; }
.gv-legacy-badge--dark    { background: rgba(26,26,26,.78); font-size: 11px; border-radius: var(--gv-r-xs); padding: 6px 10px; }
.gv-legacy-badge--neutral { background: var(--warm-gray); color: var(--mid-gray); }

/* Outlined pink pill — the size marker beside a product title. */
.gv-legacy-badge--size {
  padding: 4px 11px;
  border: 1.5px solid var(--legacy-pink);
  border-radius: 30px;
  background: #fff;
  color: var(--legacy-pink);
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .3px;
}

/* Save/discount flag on a product card. */
.gv-legacy-badge--save {
  background: var(--berry-dark);
  font-size: 11px;
  padding: 4px 10px;
  border-radius: 6px;
  letter-spacing: .02em;
}

/* ---- components/button.css ---- */
/* Buttons — ported from glowve-base.css .gv-btn-primary / -secondary / -ghost.
   Primary is a pill: uppercase, 13px, 600, .04em tracking. */

.gv-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 14px 26px;
  border: none;
  border-radius: var(--gv-r-pill);
  /* --brand-pink-ink, not --coral-pulse: this variant carries white text.
     The outline variant below keeps the brighter pink, because there it is
     pink-on-white and the text colour is what has to pass. */
  background: var(--brand-pink-ink);
  color: #fff;
  font-family: var(--legacy-font-sans);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  width: fit-content;
  min-height: 46px;
  transition: background var(--gv-duration), transform var(--gv-duration);
}
.gv-btn:hover { background: #BE1F52; transform: scale(1.02); }
.gv-btn:active { transform: scale(0.99); }

/* Secondary is an underlined text link, not a filled button. */
.gv-btn--secondary {
  padding: 0 0 2px;
  min-height: 0;
  border-radius: 0;
  background: none;
  color: var(--warm-espresso);
  border-bottom: 1px solid var(--warm-espresso);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.02em;
  text-transform: none;
}
.gv-btn--secondary:hover {
  background: none;
  transform: none;
  /* Pink text on white is the same 3.14:1 as white on pink -- the ratio
     does not care which way round it is. The border can stay bright: 1.4.11
     asks only 3:1 of a non-text boundary. */
  color: var(--brand-pink-ink);
  border-color: var(--coral-pulse);
}

.gv-btn--ghost {
  background: transparent;
  border: 1.5px solid rgba(255, 255, 255, 0.4);
  color: #fff;
}
.gv-btn--ghost:hover { background: #fff; color: var(--berry-dark); }

/* Dark secondary action — "Buy Now (Cash on Delivery)" on the PDP. */
.gv-btn--dark { background: var(--berry-dark); }
.gv-btn--dark:hover { background: #000; }

/* Square-cornered block button used inside cards and the buy bar. */
.gv-btn--block {
  width: 100%;
  border-radius: var(--gv-r-input);
  min-height: 48px;
  font-size: 14px;
}

.gv-btn--sm { padding: 10px 18px; min-height: 40px; font-size: 12px; }
.gv-btn--lg { padding: 16px 32px; min-height: 52px; font-size: 14px; }
.gv-btn--full { width: 100%; }

.gv-btn[disabled], .gv-btn.loading { opacity: 0.55; pointer-events: none; }

/* ---- components/cart-drawer.css ---- */
/* Cart drawer — add-to-cart confirmation, slides in from the right. */

.gv-drawer {
  position: fixed;
  inset: 0;
  z-index: 120; /* above the sticky header and the WhatsApp button */
}

.gv-drawer[hidden] { display: none; }

.gv-drawer__scrim {
  position: absolute;
  inset: 0;
  background: rgba(26, 26, 26, 0.45);
  opacity: 0;
  transition: opacity 0.25s ease;
}

.gv-drawer.is-open .gv-drawer__scrim { opacity: 1; }

.gv-drawer__panel {
  position: absolute;
  top: 0;
  right: 0;
  display: flex;
  flex-direction: column;
  width: min(26rem, 100%);
  height: 100%;
  background: #fff;
  box-shadow: -12px 0 40px rgba(0, 0, 0, 0.14);
  transform: translateX(100%);
  transition: transform 0.28s cubic-bezier(0.32, 0.72, 0, 1);
}

.gv-drawer.is-open .gv-drawer__panel { transform: translateX(0); }

@media (prefers-reduced-motion: reduce) {
  .gv-drawer__scrim,
  .gv-drawer__panel { transition: none; }
}

/* ---- Head --------------------------------------------------------------- */

.gv-drawer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.125rem 1.25rem;
  border-bottom: 1px solid var(--gv-line);
}

.gv-drawer__title {
  margin: 0;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.gv-drawer__close {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-right: -0.5rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--gv-text);
  cursor: pointer;
}

.gv-drawer__close:hover { background: var(--gv-surface-2); }

/* ---- Body --------------------------------------------------------------- */

/* The fragment wrapper is the flex child; the scroller and the totals live
   inside it so WooCommerce can replace both in one swap. */
.gv-drawer__contents {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-height: 0;
}

.gv-drawer__body {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0.25rem 1.25rem;
}

.gv-drawer__items {
  margin: 0;
  padding: 0;
  list-style: none;
}

.gv-drawer-line {
  display: grid;
  grid-template-columns: 4.5rem minmax(0, 1fr);
  gap: 0.875rem;
  padding: 1.125rem 0;
  border-bottom: 1px solid var(--gv-line-soft);
}

.gv-drawer-line__media img {
  width: 100%;
  height: auto;
  border-radius: 12px;
  background: var(--gv-surface-2);
}

.gv-drawer-line__name {
  margin: 0;
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.35;
}

.gv-drawer-line__name a { color: var(--gv-text); text-decoration: none; }
.gv-drawer-line__name a:hover { color: var(--legacy-pink); }

.gv-drawer-line__meta {
  margin: 0.2rem 0 0;
  color: var(--gv-muted);
  font-size: 0.8125rem;
}

.gv-drawer-line__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-top: 0.625rem;
}

.gv-drawer-line__price {
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 700;
  white-space: nowrap;
}

.gv-drawer-line__remove {
  min-height: 24px;
  margin-top: 0.375rem;
  padding: 0;
  border: 0;
  background: none;
  color: var(--gv-muted);
  font: inherit;
  font-size: 0.8125rem;
  text-decoration: underline;
  text-underline-offset: 0.2em;
  cursor: pointer;
}

.gv-drawer-line__remove:hover { color: var(--legacy-pink); }

/* Plus/minus rather than a text field — a typed quantity is error-prone and
   slow, and it is the most-failed checkout guideline in Baymard's benchmark. */
.gv-qty {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--gv-line-strong);
  border-radius: var(--gv-r-pill);
}

.gv-qty__btn {
  width: 36px;
  height: 36px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--gv-text);
  font: inherit;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}

.gv-qty__btn:hover { color: var(--legacy-pink); }
.gv-qty__btn:disabled { opacity: 0.4; cursor: default; }

.gv-qty__value {
  min-width: 1.5rem;
  font-size: 0.9375rem;
  font-weight: 600;
  text-align: center;
}

/* ---- Empty -------------------------------------------------------------- */

.gv-drawer__empty {
  padding: 3rem 0;
  text-align: center;
}

.gv-drawer__empty-title {
  margin: 0 0 1.25rem;
  color: var(--gv-text-3);
  font-size: 1rem;
}

/* ---- Foot --------------------------------------------------------------- */

.gv-drawer__foot {
  flex: 0 0 auto;
  padding: 1.125rem 1.25rem calc(1.125rem + env(safe-area-inset-bottom));
  border-top: 1px solid var(--gv-line);
  background: var(--gv-surface);
}

.gv-drawer__totals { margin: 0 0 1rem; }

.gv-drawer__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin: 0 0 0.375rem;
  font-size: 0.9375rem;
}

.gv-drawer__row dt,
.gv-drawer__row dd { margin: 0; }

.gv-drawer__row dt { color: var(--gv-text-3); }

.gv-drawer__row--fee dd { color: var(--gv-star); font-weight: 600; }

.gv-drawer__row--total {
  margin: 0.625rem 0 0;
  padding-top: 0.625rem;
  border-top: 1px solid var(--gv-line);
  font-size: 1.0625rem;
  font-weight: 700;
}

.gv-drawer__row--total dt { color: var(--gv-text); }

.gv-drawer__checkout {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 52px;
  border-radius: var(--gv-r-pill);
  background: var(--brand-pink-ink);
  color: #fff;
  font-size: 0.875rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-decoration: none;
}

.gv-drawer__checkout:hover { background: var(--brand-pink-dark); }

.gv-drawer__viewbag {
  display: block;
  min-height: 44px;
  padding-top: 0.75rem;
  color: var(--gv-text-3);
  font-size: 0.875rem;
  text-align: center;
  text-underline-offset: 0.2em;
}

.gv-drawer__viewbag:hover { color: var(--legacy-pink); }

/* On a phone the panel is nearly full width, but never edge-to-edge — the
   sliver of scrim is what tells you the page is still behind it. */
@media (max-width: 480px) {
  .gv-drawer__panel { width: calc(100% - 2.5rem); }
}

/* ---- components/panel.css ---- */
/* Panel — the one boxed-thing primitive.
   docs/18-ui-spec-checkout.md §2.3.

   Checkout was stacking four different container treatments in its first
   screen: a pink-bordered notice, a bare text line, a pink tinted box and a
   grey card. Each was individually fine and together they read as four
   unrelated widgets. This is the single component they all become, so boxes on
   a page look like the same kind of object. */

.gv-legacy-panel {
  padding: var(--gv-s5);
  border: 1px solid var(--gv-line);
  border-radius: var(--gv-r-card);
  background: #fff;
}

/* Filled rather than outlined — for secondary information that should recede,
   like the order summary beside a form the customer is working in. */
.gv-legacy-panel--quiet {
  border-color: transparent;
  background: var(--gv-surface);
}

/* Carries brand tint. Reserved for one thing at a time on a page; two accent
   panels in view is two things claiming to be the most important. */
.gv-legacy-panel--accent {
  border-color: transparent;
  background: var(--gv-pink-tint);
}

/* For a panel whose contents bring their own padding — a table, a list of rows
   with their own dividers. */
.gv-legacy-panel--flush { padding: 0; }

.gv-legacy-panel + .gv-legacy-panel { margin-top: var(--gv-s4); }

/* A panel inside a panel reads as a mistake: two borders, two radii, and no
   way to tell which box you are in. Flatten the inner one rather than ban it,
   because WooCommerce nests markup we do not control. */
.gv-legacy-panel .gv-legacy-panel {
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
}

@media (min-width: 900px) {
  .gv-legacy-panel { padding: var(--gv-s6); }
  .gv-legacy-panel--flush { padding: 0; }
}

/* ---- Panel headings ------------------------------------------------------ */

.gv-legacy-panel__title {
  margin: 0 0 var(--gv-s4);
  font-size: 1.125rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

/* ---- components/product-card.css ---- */
/* Product card — the single definition used in every grid and carousel.
   Media sits on a soft gradient, as on the live store. */

.gv-card { display: flex; flex-direction: column; background: #fff; }

.gv-card__media {
  position: relative;
  display: block;
  aspect-ratio: 1;
  border-radius: var(--gv-r-media);
  overflow: hidden;
  background: linear-gradient(135deg, #BFE4F5, #CDBDF0 50%, #F3C6E2);
}
.gv-card__img { width: 100%; height: 100%; object-fit: cover; transition: transform 400ms var(--gv-ease); }
.gv-card:hover .gv-card__img { transform: scale(1.03); }

.gv-card__flag { position: absolute; top: 12px; left: 12px; z-index: 2; }

.gv-card__body { display: flex; flex-direction: column; gap: 8px; padding: 14px 2px 0; flex: 1; }

.gv-card__title {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.35;
}
.gv-card__title a { text-decoration: none; }
.gv-card__title a:hover { color: var(--coral-pulse); }

.gv-card__tags { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; list-style: none; }
.gv-card__tag {
  font-size: 11px; font-weight: 500; color: var(--mid-gray);
  border: 1px solid var(--warm-gray); border-radius: 20px; padding: 3px 9px;
}

.gv-card__price { margin: auto 0 0; padding-top: 4px; font-size: 16px; font-weight: 700; }
.gv-card__price del { margin-left: 6px; color: var(--gv-muted-2); font-size: 13px; font-weight: 600; }
.gv-card__price ins { text-decoration: none; }
.gv-card__save { display: block; margin-top: 2px; font-size: 12px; font-weight: 600; color: #1a8f4a; }

.gv-card__cta { margin-top: 12px; }

/* ---- components/rating.css ---- */
/* Stars are GREEN on this store (#7CC04A), not yellow. */

.gv-legacy-rating { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }

.gv-legacy-rating__stars { position: relative; display: inline-block; line-height: 1; font-size: 15px; }
.gv-legacy-rating__track { color: var(--warm-gray); letter-spacing: 0.06em; }
.gv-legacy-rating__fill {
  position: absolute; inset: 0;
  width: var(--gv-rating-pct, 0%);
  overflow: hidden; white-space: nowrap;
  color: var(--gv-star);
  letter-spacing: 0.06em;
}

.gv-legacy-rating__count { color: var(--gv-text-2); font-size: 14px; }
.gv-legacy-rating__count strong { color: var(--berry-dark); }

/* ---- components/whatsapp.css ---- */
/* Ported verbatim from snippets/whatsapp-button.liquid. */
.whatsapp-sticky-button {
  position: fixed;
  bottom: 20px;
  right: 20px;
  /* Must stay under 8: the header is `position: sticky; z-index: 8`, a stacking
     context the mobile menu cannot escape, so anything at 8+ floats over the
     open menu. */
  z-index: var(--layer-heightened, 4);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 60px;
  height: 60px;
  background-color: #25D366;
  border-radius: 50%;
  box-shadow: 0 4px 10px rgba(0,0,0,0.15);
  transition: transform 0.3s ease, bottom 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
  text-decoration: none;
}
.whatsapp-sticky-button:hover { transform: scale(1.1); }
.whatsapp-sticky-button svg { width: 35px; height: 35px; fill: #ffffff; }
@media screen and (max-width: 767px) {
  .whatsapp-sticky-button { bottom: 20px; right: 16px; width: 50px; height: 50px; }
  .whatsapp-sticky-button svg { width: 30px; height: 30px; }
}

.gv-v3-sub-err { flex-basis: 100%; margin: 0 0 8px; color: #c0254f; font-size: 13px; font-weight: 500; }

/* ---- sections/account.css ---- */
/* My account.
   WooCommerce's stylesheets are dequeued, so the login and tracking forms have
   no styling of their own at all — labels sat inline beside undersized inputs
   and the submit button rendered as a black browser default. */

/* Scoped to the account page, NOT to .gv-page--wide.
   .gv-page--wide is also on cart and checkout, so this measure -- written for a
   login form -- was squeezing the entire checkout to 544px. At 1440 that left
   the address column 112px wide and truncating input values. A measure meant
   for one screen has to be scoped to that screen. */
.woocommerce-account .woocommerce {
  max-width: 34rem;
  margin-inline: auto;
  padding-bottom: clamp(3rem, 7vw, 4.5rem);
}

.gv-track { margin-bottom: clamp(2rem, 5vw, 3rem); }

.gv-track__title {
  margin: 0 0 0.5rem;
  font-size: clamp(1.75rem, 4vw, 2.25rem);
  font-weight: 700;
  letter-spacing: -0.01em;
}

.gv-track__intro {
  margin: 0 0 1.5rem;
  color: var(--gv-text-3);
  line-height: 1.6;
}

.gv-track__staff {
  margin: 2.5rem 0 0.75rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--gv-line);
  color: var(--gv-muted);
  font-size: 0.8125rem;
}

/* ---- Forms --------------------------------------------------------------- */

.woocommerce-account form.login,
.woocommerce-account form.track_order,
.woocommerce-account form.woocommerce-form-login {
  display: grid;
  gap: 1rem;
  margin: 0;
  padding: clamp(1.25rem, 3vw, 1.75rem);
  border: 1px solid var(--gv-line);
  border-radius: var(--gv-r-card);
  background: var(--gv-surface);
}

.woocommerce-account .form-row,
.woocommerce-account .woocommerce-form-row {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  margin: 0;
  padding: 0;
  width: auto;
  float: none;
}

.woocommerce-account label {
  font-size: 0.875rem;
  font-weight: 600;
}

.woocommerce-account .required { color: var(--legacy-pink); text-decoration: none; }

.woocommerce-account input[type="text"],
.woocommerce-account input[type="email"],
.woocommerce-account input[type="password"] {
  width: 100%;
  min-height: 48px;
  padding: 0 0.875rem;
  border: 1px solid var(--gv-line-strong);
  border-radius: var(--gv-r-input, 12px);
  background: #fff;
  font: inherit;
  font-size: 1rem;
}

.woocommerce-account input:focus-visible {
  outline: 2px solid var(--legacy-pink);
  outline-offset: 1px;
}

/* WooCommerce wraps the password in a div and drops a show/hide button into
   it; unstyled it renders as a small grey box overlapping the field. */
.woocommerce-account .woocommerce-password-input,
.woocommerce-account .password-input { position: relative; display: block; }

.woocommerce-account .show-password-input {
  position: absolute;
  top: 50%;
  right: 0.75rem;
  width: 22px;
  height: 22px;
  transform: translateY(-50%);
  border: 0;
  background: transparent;
  cursor: pointer;
}

.woocommerce-account .show-password-input::before {
  content: "";
  display: block;
  width: 20px;
  height: 20px;
  background: currentColor;
  opacity: 0.45;
  -webkit-mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2'%3E%3Cpath d='M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z'/%3E%3Ccircle cx='12' cy='12' r='3'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2'%3E%3Cpath d='M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z'/%3E%3Ccircle cx='12' cy='12' r='3'/%3E%3C/svg%3E") center / contain no-repeat;
}

.woocommerce-account .show-password-input.display-password::before { opacity: 0.9; }

.woocommerce-account input[type="password"] { padding-right: 2.75rem; }

.woocommerce-account button[type="submit"],
.woocommerce-account .woocommerce-form-login__submit,
.woocommerce-account .button {
  justify-self: start;
  min-height: 48px;
  padding: 0 1.75rem;
  border: 0;
  border-radius: var(--gv-r-pill);
  background: var(--berry-dark);
  color: #fff;
  font: inherit;
  font-size: 0.875rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
}

.woocommerce-account button[type="submit"]:hover { background: var(--gv-text); }

.woocommerce-account .woocommerce-form-login__rememberme {
  flex-direction: row;
  align-items: center;
  gap: 0.5rem;
  font-weight: 500;
}

.woocommerce-account .woocommerce-LostPassword {
  margin: 0;
  font-size: 0.875rem;
}

/* ---- Logged in ----------------------------------------------------------- */

.woocommerce-account .woocommerce-MyAccount-navigation ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0 0 1.75rem;
  padding: 0;
  list-style: none;
}

.woocommerce-account .woocommerce-MyAccount-navigation a {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 0 1rem;
  border: 1px solid var(--gv-line-strong);
  border-radius: var(--gv-r-pill);
  color: var(--gv-text);
  font-size: 0.875rem;
  text-decoration: none;
}

.woocommerce-account .woocommerce-MyAccount-navigation li.is-active a {
  background: var(--berry-dark);
  border-color: var(--berry-dark);
  color: #fff;
}

/* WooCommerce's "Login" heading inherits the global h2 size, which renders it
   larger than the h1 above it. Correct markup, inverted hierarchy on screen. */
.woocommerce-account h2 {
  margin: 0 0 1rem;
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

/* ---- sections/blog.css ---- */
/* ==========================================================================
   Blog, pages, search and 404.

   Ported from screens/shopify/{desktop,mobile}/{blog,article}.png.

   Sizes here are in rem, deliberately. The rest of the theme still uses px
   (impact 19 in docs/13-platform-rules.md); this file is the pattern the
   conversion should follow, so a customer who raises their browser's default
   text size actually gets larger text.
   ========================================================================== */

/* ---- Shared prose measure ------------------------------------------------ */

.gv-legacy-prose {
  max-width: 44rem;                /* ~700px: the article column on the live store */
  margin-inline: auto;
  color: var(--gv-text-2);
  font-size: 1rem;
  line-height: 1.75;
}

.gv-legacy-prose > * + * { margin-top: 1.15em; }

.gv-legacy-prose h2,
.gv-legacy-prose h3 {
  margin-top: 2.25em;
  color: var(--gv-text);
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: 0;
}

/* The live articles mark each section with a short vertical rule. */
.gv-legacy-prose h2 {
  font-size: 1.375rem;
}

.gv-legacy-prose h3 { font-size: 1.125rem; }

.gv-legacy-prose a {
  color: var(--legacy-pink);
  text-underline-offset: 0.18em;
}

.gv-legacy-prose ul,
.gv-legacy-prose ol { padding-left: 1.25rem; }
.gv-legacy-prose li + li { margin-top: 0.4em; }

.gv-legacy-prose blockquote {
  margin-inline: 0;
  padding: 1.1rem 1.25rem;
  border-radius: 12px;
  background: var(--accent-peach);
  color: var(--gv-text);
  font-style: normal;
}

.gv-legacy-prose img { height: auto; border-radius: 12px; }

/* ---- Blog index / archives ---------------------------------------------- */

.gv-blog {
  max-width: var(--gv-container);
  margin-inline: auto;
  padding: 2.5rem 1.25rem 4rem;
}

.gv-blog__head { margin-bottom: 2rem; }

.gv-blog__title {
  margin: 0;
  color: var(--gv-text);
  font-size: clamp(1.75rem, 1.2rem + 2vw, 2.5rem);
  font-weight: 600;
  letter-spacing: 0;
}

.gv-blog__intro {
  max-width: 44rem;
  margin-top: 0.75rem;
  color: var(--gv-muted);
}

.gv-blog__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2.25rem 1.75rem;
}

.gv-blog__empty { color: var(--gv-muted); }

/* ---- Post card ----------------------------------------------------------- */

.gv-legacy-post-card { display: flex; flex-direction: column; gap: 0.85rem; }

.gv-legacy-post-card__media {
  display: block;
  overflow: hidden;
  border-radius: 12px;
  background: var(--gv-surface-2);
  aspect-ratio: 3 / 2;
}

.gv-legacy-post-card__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.gv-legacy-post-card__title {
  margin: 0;
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: 0;
}

/* Card titles are plain on the live store; only "Read more…" is underlined. */
.gv-legacy-post-card__title a { color: var(--gv-text); text-decoration: none; }
.gv-legacy-post-card__title a:hover { color: var(--legacy-pink); }

.gv-legacy-post-card__date {
  margin: 0;
  color: var(--gv-muted);
  font-size: 0.8125rem;
}

.gv-legacy-post-card__excerpt {
  margin: 0;
  color: var(--gv-text-3);
  font-size: 0.9375rem;
  line-height: 1.6;
}

.gv-legacy-post-card__more { margin: 0; }

.gv-legacy-post-card__more a {
  color: var(--gv-text);
  font-size: 0.875rem;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.gv-legacy-post-card__more a:hover { color: var(--legacy-pink); }

/* The lead article runs full width with the image beside the text. */
.gv-legacy-post-card--featured {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: 1.6fr 1fr;
  gap: 2rem;
  align-items: start;
}

.gv-legacy-post-card--featured .gv-legacy-post-card__media { aspect-ratio: 16 / 9; }
.gv-legacy-post-card--featured .gv-legacy-post-card__title { font-size: 1.375rem; }

/* ---- Article ------------------------------------------------------------- */

.gv-article { padding: 2rem 1.25rem 4rem; }

.gv-article__inner {
  max-width: var(--gv-container-narrow);
  margin-inline: auto;
}

.gv-article__back { margin: 0 0 1.5rem; }

.gv-article__back a {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  color: var(--gv-muted);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;

  /* This is the only way back out of an article on a phone, and at 12px it was
     a 19px-tall target. WCAG 2.2 AA (2.5.8) wants 24px, and it is not an inline
     link in a sentence, so the exception does not apply. */
  min-height: 24px;
  padding-block: 0.25rem;
}

.gv-article__back a:hover { color: var(--legacy-pink); }

.gv-article__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  justify-content: center;
  margin: 0 0 1.5rem;
  padding: 0;
  list-style: none;
}

.gv-article__tag {
  display: inline-block;
  padding: 0.35rem 0.75rem;
  border: 1px solid var(--legacy-pink);
  border-radius: 999px;
  color: var(--legacy-pink);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.gv-article__tag:hover { background: var(--brand-pink-ink); color: #fff; }

.gv-article__head { text-align: center; }

.gv-article__title {
  max-width: 36rem;
  margin: 0 auto;
  color: var(--gv-text);
  font-size: clamp(1.625rem, 1.1rem + 2.2vw, 2.375rem);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: 0;
}

.gv-article__meta {
  margin: 1rem 0 0;
  color: var(--gv-text-3);
  font-size: 0.875rem;
}

.gv-article__read {
  margin: 0.35rem 0 0;
  color: var(--gv-muted-2);
  font-size: 0.75rem;
}

.gv-article__hero {
  margin: 2rem 0 2.5rem;
}

.gv-article__hero-img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 14px;
}

.gv-article__hero figcaption {
  margin-top: 0.6rem;
  color: var(--gv-muted);
  font-size: 0.8125rem;
  text-align: center;
}

/* the_content() output gets the shared prose rules. */
.gv-article__body {
  max-width: 44rem;
  margin-inline: auto;
  color: var(--gv-text-2);
  font-size: 1rem;
  line-height: 1.75;
}

.gv-article__body > * + * { margin-top: 1.15em; }

.gv-article__body h2,
.gv-article__body h3 {
  margin-top: 2.25em;
  color: var(--gv-text);
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: 0;
}

.gv-article__body h2 {
  font-size: 1.375rem;
}

.gv-article__body h3 { font-size: 1.125rem; }
.gv-article__body a { color: var(--legacy-pink); text-underline-offset: 0.18em; }
.gv-article__body ul, .gv-article__body ol { padding-left: 1.25rem; }
.gv-article__body li + li { margin-top: 0.4em; }
.gv-article__body img { height: auto; border-radius: 12px; }

/* "The product this is about" */
.gv-article__product {
  max-width: 44rem;
  margin: 3rem auto 0;
  padding: 1.25rem;
  border: 1px solid var(--gv-line);
  border-radius: 14px;
  background: var(--gv-surface);
}

.gv-article__product-eyebrow {
  margin: 0 0 0.85rem;
  color: var(--gv-muted-2);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.gv-article__product-row {
  display: grid;
  grid-template-columns: 4.5rem 1fr;
  gap: 1rem;
  align-items: center;
}

.gv-article__product-media {
  display: block;
  overflow: hidden;
  border-radius: 10px;
  background: #fff;
}

.gv-article__product-img { width: 100%; height: auto; }

.gv-article__product-title {
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0;
}

.gv-article__product-title a { color: var(--gv-text); text-decoration: none; }
.gv-article__product-title a:hover { color: var(--legacy-pink); }

.gv-article__product-desc {
  margin: 0.3rem 0 0;
  color: var(--gv-text-3);
  font-size: 0.875rem;
  line-height: 1.55;
}

.gv-article__product-cta { margin: 0.6rem 0 0; }

.gv-article__product-cta a {
  color: var(--legacy-pink);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
}

/* ---- Plain page (policies) ---------------------------------------------- */

.gv-page { padding: 2.5rem 1.25rem 4rem; }

.gv-page__inner {
  max-width: var(--gv-container-narrow);
  margin-inline: auto;
}

.gv-page__head {
  max-width: 44rem;
  margin: 0 auto 2rem;
}

.gv-page__title {
  margin: 0;
  color: var(--gv-text);
  font-size: clamp(1.625rem, 1.1rem + 2vw, 2.25rem);
  font-weight: 600;
  letter-spacing: 0;
}

.gv-page__pages { margin-top: 2rem; font-size: 0.875rem; }

/* ---- Search -------------------------------------------------------------- */

.gv-search {
  max-width: var(--gv-container);
  margin-inline: auto;
  padding: 2.5rem 1.25rem 4rem;
}

.gv-search__head { margin-bottom: 2rem; }

.gv-search__title {
  margin: 0;
  color: var(--gv-text);
  font-size: clamp(1.5rem, 1.1rem + 1.6vw, 2rem);
  font-weight: 600;
  letter-spacing: 0;
}

.gv-search__count { margin: 0.4rem 0 1.25rem; color: var(--gv-muted); font-size: 0.875rem; }

.gv-search__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 2rem 1.5rem;
}

.gv-search__empty { color: var(--gv-muted); }
.gv-search__empty .gv-btn { margin-top: 1rem; }

.gv-search-form {
  display: flex;
  gap: 0.5rem;
  max-width: 28rem;
}

.gv-search-form__input {
  flex: 1;
  min-height: 46px;
  padding: 0 0.9rem;
  border: 1px solid var(--gv-line-strong);
  border-radius: 999px;
  background: #fff;
  color: var(--gv-text);
  font: inherit;
  font-size: 0.9375rem;
}

.gv-search-form__input:focus-visible {
  outline: 2px solid var(--legacy-pink);
  outline-offset: 1px;
}

.gv-search-form__submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  min-height: 46px;
  border: 0;
  border-radius: 999px;
  background: var(--brand-pink-ink);
  color: #fff;
  cursor: pointer;
}

.gv-search-form__submit:hover { background: var(--coral-dark); }

/* ---- 404 ----------------------------------------------------------------- */

.gv-404 { padding: 4rem 1.25rem 5rem; }

.gv-404__inner {
  max-width: 34rem;
  margin-inline: auto;
  text-align: center;
}

.gv-404__eyebrow {
  margin: 0 0 0.75rem;
  color: var(--legacy-pink);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.14em;
}

.gv-404__title {
  margin: 0;
  color: var(--gv-text);
  font-size: clamp(1.625rem, 1.1rem + 2vw, 2.25rem);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: 0;
}

.gv-404__text { margin: 0.85rem 0 1.75rem; color: var(--gv-text-3); }

.gv-404__search { display: flex; justify-content: center; margin-bottom: 1.75rem; }
.gv-404__search .gv-search-form { width: 100%; }

.gv-404__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  justify-content: center;
  margin: 0;
}

/* ---- Responsive ---------------------------------------------------------- */

@media (max-width: 1024px) {
  .gv-blog__grid { grid-template-columns: repeat(2, 1fr); }
  .gv-search__grid { grid-template-columns: repeat(3, 1fr); }
}

@media (max-width: 768px) {
  .gv-blog { padding: 1.5rem 1rem 3rem; }
  .gv-blog__grid { grid-template-columns: 1fr; gap: 2rem; }
  .gv-search__grid { grid-template-columns: repeat(2, 1fr); }

  .gv-legacy-post-card--featured {
    grid-template-columns: 1fr;
    gap: 0.85rem;
  }

  .gv-legacy-post-card--featured .gv-legacy-post-card__title { font-size: 1.1875rem; }

  .gv-article { padding: 1.25rem 1rem 3rem; }
  .gv-article__hero { margin: 1.5rem 0 2rem; }
  .gv-article__hero-img { border-radius: 10px; }

  .gv-page { padding: 1.5rem 1rem 3rem; }
  .gv-404 { padding: 3rem 1rem 4rem; }
}

@media (prefers-reduced-motion: reduce) {
  .gv-legacy-post-card__title a,
  .gv-article__tag { transition: none; }
}

/* Pages ported whole from the Shopify storefront lay out edge to edge and
   bring their own inner containers, so the page wrapper must add no padding of
   its own — otherwise every hero is inset by a gutter it was not designed for. */
.gv-page--ported .gv-page__inner {
  max-width: none;
  padding: 0;
}

/* ---- sections/cart.css ---- */
/* Cart.
   Woo's stylesheets are dequeued, so everything its templates emit — the
   totals table, the quantity input, the notices — is styled here. */

.gv-page--wide .gv-page__inner { max-width: none; }

/* ---- Empty ------------------------------------------------------------- */

.gv-cart-empty {
  padding: clamp(3rem, 9vw, 6.5rem) 1.25rem clamp(2.5rem, 6vw, 4rem);
  text-align: center;
}

.gv-cart-empty__title {
  margin: 0;
  font-size: clamp(1.75rem, 4vw, 2.25rem);
  font-weight: 700;
  letter-spacing: -0.01em;
}

.gv-cart-empty__login {
  margin: 1rem 0 0;
  color: var(--gv-text-3);
  font-size: 1rem;
}

.gv-cart-empty__login a { color: inherit; text-underline-offset: 0.2em; }
.gv-cart-empty__login a:hover { color: var(--legacy-pink); }

.gv-cart-empty__action { margin: 2rem 0 0; }

/* The live store sets this one button in sentence case on a softer radius,
   unlike the uppercase pills everywhere else. */
.gv-cart-empty__action .gv-btn {
  padding: 16px 32px;
  border-radius: 14px;
  font-size: 1rem;
  letter-spacing: 0;
  text-transform: none;
}

/* ---- Suggestions -------------------------------------------------------- */

.gv-cart-suggest {
  max-width: var(--gv-container, 1280px);
  margin-inline: auto;
  padding: clamp(2rem, 5vw, 3.5rem) 0 clamp(2.5rem, 6vw, 4rem);
}

.gv-cart-suggest__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.5rem;
}

.gv-cart-suggest__title {
  margin: 0;
  font-size: clamp(1.375rem, 3vw, 1.875rem);
  font-weight: 700;
}

.gv-cart-suggest__all {
  color: var(--gv-text-3);
  font-size: 0.9375rem;
  text-underline-offset: 0.2em;
}

.gv-cart-suggest__all:hover { color: var(--legacy-pink); }

.gv-cart-suggest__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
  gap: clamp(1.25rem, 2.5vw, 2rem) clamp(1rem, 2vw, 1.5rem);
}

/* ---- Filled ------------------------------------------------------------- */

.gv-cart {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 22rem;
  align-items: start;
  gap: clamp(1.5rem, 4vw, 3rem);
  padding-block: clamp(1.5rem, 4vw, 2.5rem) clamp(3rem, 7vw, 4.5rem);
}

.gv-cart__title {
  grid-column: 1 / -1;
  margin: 0;
  font-size: clamp(1.75rem, 4vw, 2.25rem);
  font-weight: 700;
  letter-spacing: -0.01em;
}

.gv-cart-line {
  display: grid;
  grid-template-columns: 6.5rem minmax(0, 1fr) auto;
  gap: 1rem;
  padding: 1.25rem 0;
  border-bottom: 1px solid var(--gv-line-soft);
}

.gv-cart__items > .gv-cart-line:first-of-type { border-top: 1px solid var(--gv-line-soft); }

.gv-cart-line__media img {
  width: 100%;
  height: auto;
  border-radius: var(--gv-r-card);
  background: var(--gv-surface-2);
}

.gv-cart-line__name {
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.4;
}

.gv-cart-line__name a { color: var(--gv-text); text-decoration: none; }
.gv-cart-line__name a:hover { color: var(--legacy-pink); }

.gv-cart-line__unit {
  margin: 0.35rem 0 0;
  color: var(--gv-text-3);
  font-size: 0.875rem;
}

.gv-cart-line__qty { margin-top: 0.75rem; }

.gv-cart-line__end {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.5rem;
}

.gv-cart-line__total {
  margin: 0;
  font-size: 1rem;
  font-weight: 700;
  white-space: nowrap;
}

.gv-cart-line__remove {
  min-height: 24px;
  color: var(--gv-muted);
  font-size: 0.8125rem;
  text-underline-offset: 0.2em;
}

.gv-cart-line__remove:hover { color: var(--legacy-pink); }

/* Woo's quantity input. */
.gv-cart .quantity {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--gv-line-strong);
  border-radius: var(--gv-r-pill);
  overflow: hidden;
}

.gv-cart .quantity input[type="number"] {
  width: 4.5rem;
  min-height: 44px;
  padding: 0 0.5rem;
  border: 0;
  background: none;
  font: inherit;
  font-size: 0.9375rem;
  text-align: center;
}

.gv-cart__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.75rem 1rem;
  padding-top: 1.5rem;
}

.gv-cart__coupon {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.gv-cart__coupon-label {
  flex: 1 0 100%;
  color: var(--gv-text-3);
  font-size: 0.8125rem;
  font-weight: 600;
}

.gv-cart__coupon-input {
  min-height: 44px;
  padding: 0 1rem;
  border: 1px solid var(--gv-line-strong);
  border-radius: var(--gv-r-pill);
  font: inherit;
  font-size: 0.9375rem;
}

.gv-cart__update {
  min-height: 44px;
  margin-left: auto;
  padding: 0;
  border: 0;
  background: none;
  color: var(--gv-muted);
  font: inherit;
  font-size: 0.8125rem;
  text-decoration: underline;
  text-underline-offset: 0.2em;
  cursor: pointer;
}

.gv-cart__update:hover { color: var(--gv-text); }

/* ---- Summary ------------------------------------------------------------ */

.gv-cart__summary {
  position: sticky;
  top: 6rem;
  padding: clamp(1.25rem, 2.5vw, 1.75rem);
  border: 1px solid var(--gv-line);
  border-radius: var(--gv-r-card);
  background: var(--gv-surface);
}

.gv-cart__summary h2 {
  margin: 0 0 1rem;
  font-size: 1.0625rem;
  font-weight: 700;
}

.gv-cart__summary table { width: 100%; border-collapse: collapse; }

.gv-cart__summary th,
.gv-cart__summary td {
  padding: 0.5rem 0;
  font-size: 0.9375rem;
  font-weight: 400;
  text-align: left;
  vertical-align: top;
}

.gv-cart__summary td { text-align: right; }

.gv-cart__summary .order-total th,
.gv-cart__summary .order-total td {
  padding-top: 0.875rem;
  border-top: 1px solid var(--gv-line);
  font-size: 1.0625rem;
  font-weight: 700;
}

.gv-cart__summary .wc-proceed-to-checkout { margin-top: 1.25rem; }

.gv-cart__summary .checkout-button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 52px;
  border: 0;
  border-radius: var(--gv-r-pill);
  background: var(--brand-pink-ink);
  color: #fff;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
}

.gv-cart__summary .checkout-button:hover { background: var(--brand-pink-dark); }

.gv-cart__summary .shipping-calculator-button { color: var(--gv-text-3); font-size: 0.875rem; }

@media (max-width: 900px) {
  .gv-cart { grid-template-columns: minmax(0, 1fr); }
  .gv-cart__summary { position: static; }
}

@media (max-width: 560px) {
  .gv-cart-line { grid-template-columns: 4.5rem minmax(0, 1fr); }
  .gv-cart-line__end { grid-column: 2; flex-direction: row; align-items: center; justify-content: space-between; }
  .gv-cart-suggest__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---- Shipping methods --------------------------------------------------- */

/* Woo emits these as a <ul>; with its stylesheet dequeued they arrive as a
   bulleted list indented into the middle of the totals table. */
.gv-cart__summary .woocommerce-shipping-methods,
.woocommerce-shipping-methods {
  margin: 0;
  padding: 0;
  list-style: none;
  text-align: left;
}

.woocommerce-shipping-methods li {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin: 0 0 0.375rem;
}

.woocommerce-shipping-methods label { cursor: pointer; }

.gv-cart__summary .woocommerce-shipping-destination,
.gv-cart__summary .shipping-calculator-button {
  display: block;
  margin-top: 0.5rem;
  color: var(--gv-text-3);
  font-size: 0.8125rem;
  text-align: left;
}

/* ---- Notices ------------------------------------------------------------ */

/* "… has been added to your cart", coupon errors, stock warnings. */
.woocommerce-message,
.woocommerce-info,
.woocommerce-error {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1rem;
  margin: 0 0 1rem;
  padding: 0.875rem 1.125rem;
  border: 1px solid var(--gv-pink-border);
  border-radius: var(--gv-r-card);
  background: var(--gv-pink-tint);
  color: var(--gv-text);
  font-size: 0.9375rem;
  list-style: none;
}

.woocommerce-error {
  border-color: #F5C2C7;
  background: #FDF2F3;
}

.woocommerce-message a,
.woocommerce-info a,
.woocommerce-error a {
  margin-left: auto;
  color: var(--legacy-pink);
  font-weight: 600;
  text-underline-offset: 0.2em;
}

.woocommerce-message li,
.woocommerce-error li { width: 100%; }

/* ---- Target sizes ------------------------------------------------------- */

/* WCAG 2.2 AA (2.5.8) wants 24px minimum, and none of these are inline links
   in a sentence. Measured on a 390px viewport: Apply was 19px, the shipping
   radios 13px, "Change address" 21px. */

.gv-cart__coupon .gv-btn--secondary,
.gv-cart__summary .shipping-calculator-button {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  padding-block: 0.25rem;
}

.woocommerce-shipping-methods li {
  align-items: center;
  min-height: 44px;
}

.woocommerce-shipping-methods input[type="radio"] {
  width: 20px;
  height: 20px;
  margin: 0;
  accent-color: var(--legacy-pink);
  flex: 0 0 auto;
}

/* The label carries the rest of the 44px row, so the whole line is tappable. */
.woocommerce-shipping-methods label {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding-block: 0.25rem;
}

/* ---- Cart rebuild, docs/18 §3.5 ------------------------------------------ */

.gv-cart { font-family: var(--font-ui); }
.gv-cart__title { font-family: var(--legacy-font-sans); letter-spacing: -0.02em; }


.gv-cart .gv-cart-line {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr) auto;
  align-items: start;
  gap: var(--gv-s4);
  padding: var(--gv-s5) 0;
  border-bottom: 1px solid var(--gv-line-soft);
}

.gv-cart .gv-cart-line__media img {
  width: 72px;
  height: 72px;
  border-radius: var(--gv-r-sm);
  object-fit: cover;
  background: var(--gv-surface);
}

.gv-cart .gv-cart-line__info {
  display: flex;
  flex-direction: column;
  gap: var(--gv-s2);
  min-width: 0;
}

.gv-cart .gv-cart-line__name {
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.35;
}

.gv-cart .gv-cart-line__name a { color: var(--gv-text); text-decoration: none; }
.gv-cart .gv-cart-line__name a:hover { text-decoration: underline; }

/* Unit price is secondary and says so. Two unlabelled prices per row was the
   main reason a glance at this page did not tell you anything. */
.gv-cart .gv-cart-line__unit {
  margin: 0;
  color: var(--gv-muted);
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
}

.gv-cart .gv-cart-line__end {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--gv-s2);
  text-align: right;
}

.gv-cart .gv-cart-line__total {
  margin: 0;
  font-size: 1rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.gv-cart .gv-cart-line__remove {
  color: var(--gv-muted);
  font-size: 0.8125rem;
  text-decoration: underline;
}

.gv-cart .gv-cart-line__remove:hover { color: #C2255C; }

/* ---- Quantity stepper ---------------------------------------------------- */

.gv-qty {
  display: inline-flex;
  align-items: stretch;
  align-self: flex-start;
  border: 1px solid var(--gv-line-strong);
  border-radius: var(--gv-r-pill);
  overflow: hidden;
}

.gv-qty__btn {
  display: grid;
  place-items: center;
  width: 44px;
  min-height: 44px;
  border: 0;
  background: none;
  color: var(--gv-text);
  font-family: var(--font-ui);
  font-size: 1.125rem;
  line-height: 1;
  cursor: pointer;
}

.gv-qty__btn:hover:not(:disabled) { background: var(--gv-surface-2); }
.gv-qty__btn:disabled { opacity: 0.4; cursor: default; }
.gv-qty__btn:focus-visible { outline: 2px solid var(--brand-pink-ink); outline-offset: -2px; }

.gv-qty .quantity { border: 0; border-radius: 0; }

.gv-qty input.qty {
  width: 3rem;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  font-family: var(--font-ui);
  font-size: 1rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-align: center;
  -moz-appearance: textfield;
}

/* The native spinners duplicate the buttons either side of them. */
.gv-qty input.qty::-webkit-outer-spin-button,
.gv-qty input.qty::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.gv-qty.is-busy { opacity: 0.55; }

/* ---- Totals -------------------------------------------------------------- */

.gv-cart .cart_totals th {
  width: auto;
  padding-right: var(--gv-s4);
  font-weight: 500;
  white-space: nowrap;
}

.gv-cart .cart_totals td { font-variant-numeric: tabular-nums; }

/* ---- Phone layout -------------------------------------------------------- */

/* At 390 the three-column grid leaves the price column nothing to sit in, so
   the total and Remove drop below the stepper and the row loses its shape.
   Two columns instead: image, then everything else, with the total pinned to
   the same line as the name where the eye expects it. */
@media (max-width: 640px) {
  .gv-cart .gv-cart-line {
    grid-template-columns: 64px minmax(0, 1fr);
    gap: var(--gv-s3) var(--gv-s4);
  }

  .gv-cart .gv-cart-line__media img { width: 64px; height: 64px; }

  .gv-cart .gv-cart-line__info { grid-column: 2; }

  .gv-cart .gv-cart-line__end {
    grid-column: 2;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    width: 100%;
  }

  .gv-cart .gv-cart-line__total { font-size: 0.9375rem; }
}

/* ---- Discount field ------------------------------------------------------ */

/* Collapsed behind a link, the same as checkout. An open discount box tells a
   customer who has no code that someone else is paying less — docs/17 §1.5 —
   and having it open here while it is closed two clicks later was us
   disagreeing with ourselves. */
.gv-cart .coupon.is-collapsed > * { display: none; }

.gv-cart__coupon-toggle {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--gv-muted);
  font-family: var(--font-ui);
  font-size: 0.8125rem;
  font-weight: 500;
  text-align: left;
  text-decoration: underline;
  cursor: pointer;
}

.gv-cart__coupon-toggle:hover { color: var(--brand-pink-ink); }

/* ---- Totals -------------------------------------------------------------- */

.gv-cart .cart_totals table tr {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--gv-s4);
  padding: var(--gv-s3) 0;
}

.gv-cart .cart_totals table th,
.gv-cart .cart_totals table td {
  padding: 0;
  border: 0;
  text-align: left;
}

.gv-cart .cart_totals table td { text-align: right; }

/* The address line under Delivery is context, not a total; it gets its own
   line at a smaller size instead of wrapping four deep inside the value cell. */
.gv-cart .cart_totals .woocommerce-shipping-destination {
  display: block;
  margin-top: var(--gv-s2);
  color: var(--gv-muted);
  font-size: 0.75rem;
  font-weight: 400;
  line-height: 1.4;
}

.gv-cart .cart_totals .order-total {
  margin-top: var(--gv-s2);
  padding-top: var(--gv-s4);
  border-top: 1px solid var(--gv-line);
}

.gv-cart .cart_totals .order-total th,
.gv-cart .cart_totals .order-total td { font-size: 1.25rem; font-weight: 700; }

/* ---- Checkout button ----------------------------------------------------- */

/* Sentence case and the UI face, matching the Place order button. All-caps at
   700 with wide tracking is the most dated thing on either page. */
.gv-cart .checkout-button,
.gv-cart .wc-proceed-to-checkout a.button {
  font-family: var(--font-ui);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-transform: none;
}

/* ---- sections/checkout.css ---- */
/* Checkout.
   The shortcode checkout, styled from nothing — Woo's stylesheet is dequeued,
   so every label, input, notice and the order-review table is ours to draw.
   Layout is form on the left, sticky order summary on the right, collapsing to
   one column on a phone, which is where nearly all of this store's traffic is. */

/* Layout moved to the ported design system (assets/css/funnel/).
   form-checkout.php now emits .checkout-grid > .checkout-grid__main + __aside,
   so the form is no longer the grid and #order_review is no longer a card in
   its own right — it sits inside one. The rules that used to do those jobs are
   gone rather than overridden: left in place they fought the new markup, which
   is what squeezed the desktop form column to 284px. */

.gv-checkout__title {
  margin: 0 0 var(--gv-s7);
  font-size: clamp(1.75rem, 4vw, 2.25rem);
  font-weight: 700;
  letter-spacing: -0.01em;
}

.woocommerce-checkout h3 {
  margin: 0 0 var(--gv-s5);
  font-size: 1.125rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

#customer_details { min-width: 0; }

/* ---- Fields ------------------------------------------------------------- */

.woocommerce-checkout .form-row {
  display: flex;
  flex-direction: column;
  gap: var(--gv-s2);
  margin: 0 0 var(--gv-s4);
  padding: 0;
}

.woocommerce-checkout .form-row label {
  color: var(--gv-text-2);
  font-size: 0.875rem;
  font-weight: 600;
}

.woocommerce-checkout .form-row .required {
  color: var(--legacy-pink);
  text-decoration: none;
}

.woocommerce-checkout .form-row .optional { color: var(--gv-muted); font-weight: 400; }

.woocommerce-checkout input[type="text"],
.woocommerce-checkout input[type="email"],
.woocommerce-checkout input[type="tel"],
.woocommerce-checkout input[type="password"],
.woocommerce-checkout textarea,
.woocommerce-checkout select,
.woocommerce-checkout .select2-container .select2-selection--single {
  width: 100%;
  min-height: 48px;
  padding: var(--gv-s3) var(--gv-s4);
  border: 1px solid var(--gv-line-strong);
  border-radius: var(--gv-r-xs);
  background: #fff;
  color: var(--gv-text);
  font: inherit;
  font-size: 1rem; /* 16px — anything smaller makes iOS zoom on focus. */
}

.woocommerce-checkout textarea { min-height: 6rem; resize: vertical; }

.woocommerce-checkout input:focus-visible,
.woocommerce-checkout textarea:focus-visible,
.woocommerce-checkout select:focus-visible {
  outline: 2px solid var(--legacy-pink);
  outline-offset: 1px;
  border-color: transparent;
}

.woocommerce-checkout .form-row .description {
  margin: 0;
  color: var(--gv-muted);
  font-size: 0.8125rem;
}

/* Woo's inline validation states. */
.woocommerce-checkout .woocommerce-invalid input,
.woocommerce-checkout .woocommerce-invalid select { border-color: #D6336C; }
.woocommerce-checkout .woocommerce-validated input { border-color: #7CC04A; }

/* Deliberately NOT two-up on wider screens. The only pair this used to serve
   was first/last name, which is now a single field, and Baymard's checkout
   research is consistent that a single column reads faster than a split row. */

/* select2, which Woo loads for the province picker. */
.woocommerce-checkout .select2-container--default .select2-selection--single {
  display: flex;
  align-items: center;
  border-radius: 12px;
}

.woocommerce-checkout .select2-container--default .select2-selection--single .select2-selection__rendered {
  padding: 0;
  line-height: inherit;
  color: var(--gv-text);
}

.woocommerce-checkout .select2-container--default .select2-selection--single .select2-selection__arrow { top: 50%; transform: translateY(-50%); }

/* ---- Login / coupon prompts --------------------------------------------- */

.woocommerce-form-login-toggle,
.woocommerce-form-coupon-toggle { margin-bottom: 1rem; }

.woocommerce-form-coupon,
.woocommerce-form-login {
  display: grid;
  gap: 0.75rem;
  margin: 0 0 1.5rem;
  padding: 1.25rem;
  border: 1px solid var(--gv-line);
  border-radius: var(--gv-r-card);
  background: var(--gv-surface);
}

.woocommerce-form-coupon .button,
.woocommerce-form-login .button {
  justify-self: start;
  min-height: 44px;
  padding: 0 1.5rem;
  border: 0;
  border-radius: var(--gv-r-pill);
  background: var(--berry-dark);
  color: #fff;
  font: inherit;
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
}

/* ---- Order summary ------------------------------------------------------ */

/* Plain container now: .checkout-grid__aside does the sticking and
   #gv-summary-card is the card. Padding and background here produced a card
   inside a card. */
.woocommerce-checkout #order_review {
  padding: 0;
  border: 0;
  background: none;
}

#order_review table.shop_table {
  width: 100%;
  border-collapse: collapse;
}

#order_review th,
#order_review td {
  padding: 0.625rem 0;
  font-size: 0.9375rem;
  font-weight: 400;
  text-align: left;
  vertical-align: top;
}

#order_review td { text-align: right; }

#order_review thead th { color: var(--gv-muted); font-size: 0.75rem; letter-spacing: 0.06em; text-transform: uppercase; }

#order_review table.shop_table tr.cart_item td { border-bottom: 1px solid var(--gv-line-soft); }

/* td is right-aligned for the money column; the product name is not money. */
#order_review .product-name,
#order_review th.product-name {
  font-weight: 600;
  line-height: 1.4;
  text-align: left;
}

#order_review .order-total th,
#order_review .order-total td {
  padding-top: 0.875rem;
  border-top: 1px solid var(--gv-line);
  font-size: 1.0625rem;
  font-weight: 700;
}

/* ---- Payment ------------------------------------------------------------ */

/* Payment rows are drawn by the design's .option card (funnel/glowve.css) and
   mapped in funnel/woo-bridge.css. The rules that used to live here gave each
   <li> its own bordered, pink-when-selected box — so the option card sat inside
   a second card — and `#payment ul.payment_methods li label` at (1,2,3)
   outranked `.gv-funnel .option` at (0,2,0), taking over the card's layout.
   Removed rather than overridden; see docs/LEARNINGS.md L31 and L33. */

.woocommerce-privacy-policy-text {
  color: var(--gv-muted);
  font-size: 0.8125rem;
  line-height: 1.6;
}

/* The one button the whole funnel exists to reach. */
.woocommerce-checkout #place_order {
  display: block;
  width: 100%;
  min-height: 56px;
  margin-top: 1rem;
  padding: 0 1.5rem;
  border: 0;
  border-radius: var(--gv-r-pill);
  background: var(--brand-pink-ink);
  color: #fff;
  font: inherit;
  font-size: 0.9375rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.15s;
}

.woocommerce-checkout #place_order:hover { background: var(--brand-pink-dark); }
.woocommerce-checkout #place_order:disabled { opacity: 0.6; cursor: not-allowed; }

/* Woo's AJAX overlay while totals refresh. */
.blockUI.blockOverlay { background: #fff !important; opacity: 0.6 !important; }

/* ---- Order received ----------------------------------------------------- */

/* The last page of the funnel, and on cash on delivery the one that has to
   reassure: the customer has committed money to a courier, not to a card. */

.woocommerce-order { padding-bottom: clamp(3rem, 7vw, 4.5rem); }

.woocommerce-thankyou-order-details {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 2.5rem;
  margin: 0 0 2rem;
  padding: 1.25rem 1.5rem;
  border: 1px solid var(--gv-line);
  border-radius: var(--gv-r-card);
  background: var(--gv-surface);
  list-style: none;
}

.woocommerce-thankyou-order-details li {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  color: var(--gv-muted);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.woocommerce-thankyou-order-details li strong {
  color: var(--gv-text);
  font-size: 1rem;
  letter-spacing: 0;
  text-transform: none;
}

.woocommerce-order h2,
.woocommerce-order h3 {
  margin: 2rem 0 1rem;
  font-size: 1.125rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.woocommerce-order table.shop_table {
  width: 100%;
  max-width: 34rem;
  border-collapse: collapse;
}

.woocommerce-order table.shop_table th,
.woocommerce-order table.shop_table td {
  padding: 0.625rem 0;
  border-bottom: 1px solid var(--gv-line-soft);
  font-size: 0.9375rem;
  font-weight: 400;
  text-align: left;
}

.woocommerce-order table.shop_table td { text-align: right; }
.woocommerce-order table.shop_table thead th { color: var(--gv-muted); font-size: 0.75rem; letter-spacing: 0.06em; text-transform: uppercase; }
.woocommerce-order table.shop_table tfoot th { font-weight: 600; }
.woocommerce-order table.shop_table .product-name { text-align: left; }
.woocommerce-order table.shop_table .product-name a { color: var(--gv-text); text-decoration: none; }
.woocommerce-order table.shop_table .product-name a:hover { color: var(--legacy-pink); }

.woocommerce-customer-details address {
  max-width: 34rem;
  padding: 1.25rem;
  border: 1px solid var(--gv-line);
  border-radius: var(--gv-r-card);
  font-size: 0.9375rem;
  font-style: normal;
  line-height: 1.7;
}

.woocommerce-columns--addresses {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* ---- Free delivery goal -------------------------------------------------- */

/* Both of these are injected by glowve-core into form.checkout, which is a
   grid with explicitly placed children, so they have to be placed too or the
   browser auto-flows them into the summary column. */
.woocommerce-checkout form.checkout > .gv-ship-goal-slot,
.woocommerce-checkout form.checkout > .gv-checkout-peek {
  grid-column: 1;
  min-width: 0;
}

.gv-ship-goal {
  margin: 0 0 1.25rem;
  padding: 0.875rem 1.125rem;
  border-radius: var(--gv-r-card);
  background: var(--gv-pink-tint, #FFF2F7);
}

.gv-ship-goal__text {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.4;
}

.gv-ship-goal__track {
  height: 6px;
  margin-top: 0.625rem;
  border-radius: 999px;
  background: #fff;
  overflow: hidden;
}

.gv-ship-goal__bar {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--brand-pink-ink);
  transition: width 0.3s ease;
}

.gv-ship-goal.is-met {
  background: var(--accent-mint, #E9F7F0);
}

.gv-ship-goal.is-met .gv-ship-goal__text {
  font-weight: 600;
}

@media (prefers-reduced-motion: reduce) {
  .gv-ship-goal__bar { transition: none; }
}

/* ---- Collapsed summary above the form ------------------------------------ */

/* The right-hand summary column already does this job on a wide screen, so the
   peek is phone-only. On desktop it would be the same figures twice. */
.gv-checkout-peek { display: none; }

.gv-peek {
  margin: 0 0 1.5rem;
  border: 1px solid var(--gv-line);
  border-radius: var(--gv-r-card);
  background: var(--gv-surface);
}

.gv-peek__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 52px;
  padding: 0 1.125rem;
  font-size: 0.9375rem;
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}

/* Safari still paints its own triangle without this. */
.gv-peek__bar::-webkit-details-marker { display: none; }

.gv-peek__label {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  color: var(--gv-text-3);
  font-weight: 500;
}

.gv-peek__label::after {
  content: "";
  width: 8px;
  height: 8px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform 0.15s;
}

.gv-peek[open] .gv-peek__label::after { transform: rotate(-135deg) translate(-1px, -1px); }

.gv-peek__total { font-size: 1.0625rem; }

.gv-peek__items {
  margin: 0;
  padding: 0.25rem 1.125rem 0;
  border-top: 1px solid var(--gv-line);
  list-style: none;
}

.gv-peek__item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem 0;
}

.gv-peek__item + .gv-peek__item { border-top: 1px solid var(--gv-line-soft); }

.gv-peek__thumb {
  position: relative;
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
}

.gv-peek__thumb img {
  width: 100%;
  height: 100%;
  border-radius: 8px;
  object-fit: cover;
}

.gv-peek__qty,
.gv-corev-qty {
  position: absolute;
  top: -6px;
  right: -6px;
  display: grid;
  place-items: center;
  min-width: 19px;
  height: 19px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--gv-text);
  color: #fff;
  font-size: 0.6875rem;
  font-weight: 700;
  line-height: 1;
}

.gv-peek__name {
  flex: 1;
  min-width: 0;
  font-size: 0.875rem;
  line-height: 1.35;
}

.gv-peek__price {
  flex: 0 0 auto;
  font-size: 0.875rem;
  font-weight: 600;
}

.gv-peek__edit {
  margin: 0;
  padding: 0.25rem 1.125rem 1rem;
  font-size: 0.875rem;
}

/* ---- Order review lines -------------------------------------------------- */

.gv-corev-line {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.gv-corev-thumb {
  position: relative;
  flex: 0 0 auto;
  width: 46px;
  height: 46px;
}

.gv-corev-thumb img {
  width: 100%;
  height: 100%;
  border-radius: 8px;
  object-fit: cover;
}

.gv-corev-text { min-width: 0; }

/* The name already carries the quantity as a badge on the thumbnail. */
.gv-corev-line .product-quantity {
  color: var(--gv-muted);
  font-weight: 600;
}

/* ---- Cash line and reassurance ------------------------------------------- */

.gv-cod-cash th {
  padding-top: 0.25rem;
  border: 0;
  color: var(--gv-text-3);
  font-size: 0.8125rem;
  font-weight: 400;
  text-align: left;
}

.gv-checkout-trust {
  display: grid;
  gap: 0.5rem;
  margin: 1rem 0 0;
  padding: 0;
  list-style: none;
}

.gv-checkout-trust li {
  position: relative;
  padding-left: 1.375rem;
  color: var(--gv-text-3);
  font-size: 0.8125rem;
  line-height: 1.45;
}

/* A tick rather than a padlock badge: Norton/McAfee/BBB carry no recognition
   equity in Pakistan, so the review said to encapsulate rather than badge. */
.gv-checkout-trust li::before {
  content: "";
  position: absolute;
  top: 0.3em;
  left: 0;
  width: 10px;
  height: 5px;
  border-left: 2px solid var(--legacy-pink);
  border-bottom: 2px solid var(--legacy-pink);
  transform: rotate(-45deg);
}

/* ---- Inline validation --------------------------------------------------- */

.gv-field-msg {
  margin: 0.375rem 0 0;
  color: #C2255C;
  font-size: 0.8125rem;
  line-height: 1.4;
}

.gv-field-msg:empty { display: none; }

.form-row.gv-bad input,
.form-row.gv-bad select,
.form-row.gv-bad textarea { border-color: #C2255C; }

/* Positive confirmation, which Woo's own validation never gives. Colour is not
   the only signal -- the border weight changes too -- so this still reads for
   anyone who cannot separate the two hues. */
.form-row.gv-ok input,
.form-row.gv-ok select,
.form-row.gv-ok textarea {
  border-color: #2F9E6B;
  border-width: 1.5px;
}

@media (max-width: 900px) {
  .gv-checkout-peek { display: block; }
}

/* ---- Field visibility ---------------------------------------------------- */

/* Kept in the DOM so the value still posts and WooCommerce still validates
   against it; only removed from view.

   !important is load-bearing here and not laziness: WooCommerce's own
   address-i18n script writes `style="display:block"` directly onto address
   rows as it reshapes the form per country, and an inline style beats any
   selector we can write. There is no filter for that behaviour, so the
   declaration has to outrank it. Scoped to this one class. */
.woocommerce-checkout .form-row.gv-field-hidden { display: none !important; }

/* ---- Coupon, de-emphasised ----------------------------------------------- */

/* Now sits beside the totals rather than above the form. Styled as a quiet
   line of text: still findable by anyone holding a code, no longer the first
   and loudest thing a customer without one reads. */
.woocommerce-checkout .woocommerce-form-coupon-toggle {
  margin: 0 0 0.75rem;
}

.woocommerce-checkout .woocommerce-form-coupon-toggle .woocommerce-info {
  display: block;
  padding: 0;
  border: 0;
  background: none;
  color: var(--gv-text-3);
  font-size: 0.8125rem;
}

.woocommerce-checkout .woocommerce-form-coupon-toggle .showcoupon {
  color: var(--gv-text-3);
  font-weight: 500;
  text-decoration: underline;
}

.woocommerce-checkout .woocommerce-form-coupon-toggle .showcoupon:hover { color: var(--legacy-pink); }

.woocommerce-checkout .woocommerce-form-coupon {
  margin: 0 0 1rem;
  padding: 1rem;
}

/* ---- Field flow ---------------------------------------------------------- */

/* One column, deliberately. There is a single "Full name" field now, so the
   two-column row that used to hold first and last has nothing to hold — and
   multi-column checkout forms make users scan in a Z-pattern, which costs more
   than the vertical space it saves.

   It was also actively breaking things: the landmark disclosure button is not a
   .form-row, so the grid auto-placed it into the first free cell and it
   surfaced above the name field instead of beside the address. */
.woocommerce-checkout .woocommerce-billing-fields__field-wrapper,
.woocommerce-checkout .woocommerce-shipping-fields__field-wrapper {
  display: flex;
  flex-direction: column;
}

.woocommerce-checkout .form-row-first,
.woocommerce-checkout .form-row-last,
.woocommerce-checkout .form-row-wide {
  float: none;
  width: auto;
}

/* ---- Single name field --------------------------------------------------- */

/* The last-name input stays in the form for WooCommerce, the order emails and
   the courier label, but the customer only ever sees one box. */
.woocommerce-checkout .form-row.gv-field-hidden { display: none !important; }

/* ---- Optional field disclosure ------------------------------------------- */

/* [hidden] needs restating because .form-row sets display on its children. */
.woocommerce-checkout .form-row [hidden] { display: none !important; }

.gv-field-optional__toggle {
  align-self: start;
  margin: -0.25rem 0 1rem;
  padding: 0;
  border: 0;
  background: none;
  color: var(--brand-pink-ink);
  font: inherit;
  font-size: 0.875rem;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

.gv-field-optional__toggle:hover { text-decoration: underline; }

/* ---- Field descriptions -------------------------------------------------- */

/* WooCommerce prints field descriptions with no styling of their own. This is
   where "why do you want my email" lives, so it has to be legible rather than
   fine print. */
.woocommerce-checkout .form-row .description {
  order: 3;
  margin: 0.25rem 0 0;
  color: var(--gv-muted);
  font-size: 0.8125rem;
  line-height: 1.45;
}

/* ---- Order summary rows, rebuilt ----------------------------------------- */
/* docs/18 §3.3. The table was giving the product name a narrow column so a
   68-character title wrapped to four lines beside a cramped price, and shipping
   rendered the method name stacked above its amount. Both rows are laid out as
   flex now; the table element stays because WooCommerce and its extensions
   hook it. */

#order_review table.shop_table thead { display: none; }

/* Specificity matters here and cost a round: `#order_review table.shop_table tr`
   is (1,1,1), which outranks `#order_review tfoot tr` at (1,0,2) — so a later
   `display:flex` on the totals rows lost to this `display:block` and every
   label ran into its value ("SubtotalRs.1,800.00"). The row rules below are
   written at matching specificity rather than relying on source order. */
#order_review table.shop_table,
#order_review table.shop_table tbody,
#order_review table.shop_table tfoot {
  display: block;
  width: 100%;
}

#order_review table.shop_table tr.cart_item {
  display: flex;
  align-items: flex-start;
  gap: var(--gv-s3);
  padding: var(--gv-s3) 0;
  border-bottom: 1px solid var(--gv-line-soft);
}

#order_review table.shop_table tr.cart_item td {
  padding: 0;
  border: 0;
}

#order_review table.shop_table tr.cart_item .product-name {
  flex: 1;
  min-width: 0;
  text-align: left;
}

/* The money column never wraps and never shrinks — a price broken across two
   lines reads as two prices. */
#order_review table.shop_table tr.cart_item .product-total {
  flex: 0 0 auto;
  padding-left: var(--gv-s3);
  font-weight: 600;
  white-space: nowrap;
  text-align: right;
}

#order_review .gv-corev-thumb {
  width: 56px;
  height: 56px;
  border-radius: var(--gv-r-sm);
}

/* Two lines, then ellipsis. The full name is a tap away on the product page and
   the customer already chose it; four lines of title is not information, it is
   a wall. */
#order_review .gv-corev-text {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.35;
}

#order_review .gv-corev-line .product-quantity {
  display: block;
  margin-top: var(--gv-s1);
  color: var(--gv-muted);
  font-size: 0.8125rem;
  font-weight: 500;
}

/* ---- Totals rows --------------------------------------------------------- */

#order_review table.shop_table tfoot tr {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--gv-s4);
  padding: var(--gv-s3) 0;
}

#order_review table.shop_table tfoot th,
#order_review table.shop_table tfoot td {
  padding: 0;
  border: 0;
  font-size: 0.9375rem;
}

#order_review table.shop_table tfoot th { font-weight: 500; color: var(--gv-text-2); text-align: left; }
#order_review table.shop_table tfoot td { font-weight: 600; text-align: right; white-space: nowrap; }

#order_review table.shop_table tfoot tr.order-total {
  margin-top: var(--gv-s2);
  padding-top: var(--gv-s4);
  border-top: 1px solid var(--gv-line);
}

#order_review table.shop_table tfoot tr.order-total th,
#order_review table.shop_table tfoot tr.order-total td {
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--gv-text);
}

/* Shipping shows one value. WooCommerce renders a <ul> of methods with the
   label inside; with a single method that became "Standard delivery:" stacked
   above "Rs.199.00" — one fact printed as two. */
#order_review .woocommerce-shipping-totals ul#shipping_method {
  margin: 0;
  padding: 0;
  list-style: none;
  text-align: right;
}

#order_review .woocommerce-shipping-totals ul#shipping_method li {
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: var(--gv-s2);
}

/* The method name is stripped in PHP, not here: it is a bare text node inside
   the label, so no selector can reach it. See Checkout_UX::shipping_label(). */

#order_review .woocommerce-shipping-totals ul#shipping_method label {
  margin: 0;
  font-weight: 600;
}

/* ---- Payment and actions, on the scale ----------------------------------- */

.woocommerce-checkout #place_order {
  min-height: 52px;
  margin-top: var(--gv-s4);
  border-radius: var(--gv-r-pill);
  font-size: 1rem;
}

/* ---- ux-walkthrough fixes, 2026-09-17 ------------------------------------ */

/* The required asterisk was brand pink on white: 3.14:1. It is the only thing
   marking a field as mandatory, so it has to be readable. */
.woocommerce-checkout .form-row .required { color: var(--brand-pink-ink); }

/* --gv-muted is tuned to clear 4.5:1 on white, and the summary panel is not
   white — on its tint the same grey lands at 4.38. Everything muted *inside*
   the panel gets the slightly darker value rather than lightening the panel. */
#order_review .gv-corev-line .product-quantity,
#order_review .woocommerce-privacy-policy-text,
#order_review .woocommerce-privacy-policy-text p,
#order_review table.shop_table tr.gv-review-edit a { color: #5F6670; }

/* WooCommerce's coupon [Remove] is a 19px inline link doing a destructive job,
   which is the one kind of inline link that should not be hard to hit. */
#order_review .woocommerce-remove-coupon,
.gv-cart .woocommerce-remove-coupon {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: #5F6670;
}

/* Tap targets. Both of these were text-sized: the coupon link 19px tall and
   the landmark toggle 22px, against a 44px floor. Padding rather than a fixed
   height, so the hit area grows without the text moving. */
.woocommerce-checkout .showcoupon,
.gv-field-optional__toggle {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

/* WooCommerce's "ship to a different address" checkbox renders at 13px, which
   is under half the floor and sits next to a label people do want to hit. */
.woocommerce-checkout #ship-to-different-address label {
  display: inline-flex;
  align-items: center;
  gap: var(--gv-s3);
  min-height: 44px;
  cursor: pointer;
}

.woocommerce-checkout #ship-to-different-address input[type="checkbox"] {
  width: 20px;
  height: 20px;
  margin: 0;
  flex: 0 0 auto;
  accent-color: var(--brand-pink-ink);
}

/* ---- Interface typography ------------------------------------------------ */

/* Everything the customer works *in* rather than reads: labels, fields, totals,
   payment rows, buttons. Headings stay on Poppins so the page still belongs to
   this store. Weights come down too — the labels were 600 and the totals 700,
   which is a lot of emphasis competing for the same eye. */
/* The input selectors carry an attribute, so they are (0,2,1) — a bare
   `.woocommerce-checkout input` at (0,1,1) loses to the `font: inherit` set
   further up regardless of source order. Matched shape deliberately; this is
   the third time this project that an override lost silently to specificity
   rather than to ordering (L25). */
.woocommerce-checkout .form-row label,
.woocommerce-checkout .form-row .description,
.woocommerce-checkout input[type="text"],
.woocommerce-checkout input[type="email"],
.woocommerce-checkout input[type="tel"],
.woocommerce-checkout input[type="password"],
.woocommerce-checkout input[type="number"],
.woocommerce-checkout select,
.woocommerce-checkout textarea,
.woocommerce-checkout .select2-container,
.woocommerce-checkout #order_review,
.woocommerce-checkout #payment,
.woocommerce-checkout #place_order,
.woocommerce-checkout .gv-peek,
.woocommerce-checkout .gv-ship-goal,
.woocommerce-checkout .gv-checkout-trust,
.gv-cart .gv-cart-line,
.gv-cart .cart_totals,
.gv-cart .gv-cart__actions {
  font-family: var(--font-ui);
  font-feature-settings: "tnum" 1, "cv05" 1;
  letter-spacing: 0;
}

/* Figures line up in columns when they are tabular. Prices sitting in a totals
   column with proportional digits never quite align, which is a large part of
   why a summary can look amateur without anyone being able to say why. */
.woocommerce-checkout .woocommerce-Price-amount,
.gv-cart .woocommerce-Price-amount {
  font-family: var(--font-ui);
  font-variant-numeric: tabular-nums;
}

.woocommerce-checkout .form-row label {
  color: var(--gv-text-2);
  font-size: 0.8125rem;
  font-weight: 500;
}

/* The asterisk was brand pink and bold beside every label — eight pink marks
   down the form, all shouting, none of them the thing to act on. */
.woocommerce-checkout .form-row .required {
  color: var(--gv-muted);
  font-weight: 400;
}

.woocommerce-checkout #order_review table.shop_table tfoot th { font-weight: 500; }
.woocommerce-checkout #order_review table.shop_table tfoot td { font-weight: 600; }

.woocommerce-checkout #order_review table.shop_table tfoot tr.order-total th,
.woocommerce-checkout #order_review table.shop_table tfoot tr.order-total td {
  font-weight: 700;
  letter-spacing: -0.01em;
}

/* Section headings keep Poppins but lose a step of weight and gain the tighter
   tracking a display face wants at this size. */
.woocommerce-checkout h3,
.gv-cart__title {
  font-family: var(--legacy-font-sans);
  letter-spacing: -0.02em;
}

/* All-caps at 700 with wide tracking is the single most dated thing on the
   page. Sentence case, one weight down. */
.woocommerce-checkout #place_order {
  font-family: var(--font-ui);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-transform: none;
}

/* Route back to the cart, under the summary lines at every width. */
#order_review table.shop_table tr.gv-review-edit {
  display: block;
  padding: var(--gv-s3) 0 0;
}

#order_review table.shop_table tr.gv-review-edit td {
  padding: 0;
  border: 0;
  text-align: left;
}

#order_review table.shop_table tr.gv-review-edit a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--gv-muted);
  font-size: 0.8125rem;
  font-weight: 500;
  text-decoration: underline;
}

#order_review table.shop_table tr.gv-review-edit a:hover { color: var(--brand-pink-ink); }

/* ---- Discount code, beside the totals ------------------------------------ */

.gv-coupon {
  margin: 0 0 var(--gv-s4);
  padding-bottom: var(--gv-s4);
  border-bottom: 1px solid var(--gv-line);
  font-family: var(--font-ui);
}

.gv-coupon__toggle {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: #5F6670;
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 500;
  text-align: left;
  text-decoration: underline;
  cursor: pointer;
}

.gv-coupon__toggle:hover { color: var(--brand-pink-ink); }

/* :not([hidden]) is doing real work. `display: flex` beats the hidden
   attribute's built-in `display: none`, so without this the field is open the
   moment it renders — which is the exact pattern docs/17 §1.5 says to avoid,
   arrived at by accident. */
.gv-coupon__fields:not([hidden]) {
  display: flex;
  gap: var(--gv-s2);
  margin-top: var(--gv-s2);
}

.gv-coupon__input {
  flex: 1;
  min-width: 0;
  min-height: 44px;
  padding: 0 var(--gv-s3);
  border: 1px solid var(--gv-line-strong);
  border-radius: var(--gv-r-xs);
  background: #fff;
  font-family: var(--font-ui);
  font-size: 1rem;
  text-transform: uppercase;
}

.gv-coupon__input:focus-visible {
  outline: 2px solid var(--brand-pink-ink);
  outline-offset: 1px;
}

.gv-coupon__apply {
  flex: 0 0 auto;
  min-height: 44px;
  padding: 0 var(--gv-s4);
  border: 1px solid var(--gv-text);
  border-radius: var(--gv-r-xs);
  background: none;
  color: var(--gv-text);
  font-family: var(--font-ui);
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
}

.gv-coupon__apply:hover:not(:disabled) { background: var(--gv-text); color: #fff; }
.gv-coupon__apply:disabled { opacity: 0.5; cursor: default; }

/* On the cart the proxy sits inside the totals panel, above the checkout
   button, so it needs the panel's rhythm rather than the summary's. */
.gv-cart .cart_totals .gv-coupon {
  margin-top: var(--gv-s4);
  padding-bottom: var(--gv-s4);
}

/* ---- sections/collection.css ---- */
/* Collection / shop archive.
   Woo's own stylesheets are dequeued in inc/woocommerce.php, which also takes
   the grid with them: ul.products is what positions every card, so without a
   replacement the archive stacks one full-width product per row. */

.gv-coll-hero {
  padding: clamp(2.5rem, 6vw, 4.5rem) 0 clamp(1.75rem, 4vw, 2.75rem);
  text-align: center;
  border-bottom: 1px solid var(--gv-line-soft);
}

.gv-coll-hero__eyebrow {
  margin: 0 0 0.75rem;
  color: var(--legacy-pink);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.gv-coll-hero__title {
  margin: 0;
  font-size: clamp(2.25rem, 6vw, 4.25rem);
  font-weight: 700;
  line-height: 1.04;
  letter-spacing: -0.02em;

  /* The live store sets this headline in lowercase. Done with a transform so
     the accessible name and the page title keep their real capitalisation. */
  text-transform: lowercase;
}

.gv-coll-hero__title span { color: var(--legacy-pink); }

.gv-coll-hero__intro {
  max-width: 34rem;
  margin: 1rem auto 0;
  color: var(--gv-text-3);
  font-size: 1.0625rem;
  line-height: 1.6;
}

.gv-coll-hero__intro p { margin: 0; }

.gv-coll-hero__pills {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.625rem;
  margin-top: clamp(1.5rem, 3vw, 2.25rem);
}

.gv-coll-pill {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 1.375rem;
  border: 1px solid var(--gv-line-strong);
  border-radius: var(--gv-r-pill);
  color: var(--gv-text);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}

.gv-coll-pill:hover { border-color: var(--gv-text); }

.gv-coll-pill.is-active {
  background: var(--berry-dark);
  border-color: var(--berry-dark);
  color: #fff;
}

/* ---- Toolbar ------------------------------------------------------------ */

.gv-coll-bar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 1rem;
  padding: 1.125rem 0;
  border-bottom: 1px solid var(--gv-line-soft);
}

.gv-coll-bar__count {
  margin: 0;
  color: var(--gv-text-3);
  font-size: 0.875rem;
}

.gv-coll-bar form { margin: 0; }

.gv-coll-bar select {
  min-height: 44px;
  padding: 0 2rem 0 0.875rem;
  border: 1px solid var(--gv-line-strong);
  border-radius: var(--gv-r-pill);
  background: #fff;
  color: var(--gv-text);
  font: inherit;
  font-size: 0.875rem;
  cursor: pointer;

  /* Native arrow sits badly inside a pill; draw our own. */
  appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%231A1A1A' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.875rem center;
}

/* ---- The grid ----------------------------------------------------------- */

/* .gv-legacy-grid is the same thing for sections that build their own product list —
   "Customers also bought", curated grids. It had no rules at all, so those
   sections stacked one full-width card per row. */
.gv-legacy-grid,
.woocommerce ul.products,
ul.products {
  display: grid;
  /* 13rem lands five across at 1440, which is what the live collection does;
     it degrades to four and then two as the viewport narrows. */
  grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
  gap: clamp(1.25rem, 2.5vw, 2rem) clamp(1rem, 2vw, 1.5rem);
  margin: clamp(1.75rem, 4vw, 2.5rem) 0 0;
  padding: 0;
  list-style: none;
}

.woocommerce ul.products::before,
.woocommerce ul.products::after { content: none; }

.woocommerce ul.products li.product,
ul.products li.product {
  width: auto;
  margin: 0;
  float: none;
  clear: none;
}

/* Woo prints its own "no products" notice and result count; neither matches. */
.woocommerce-no-products-found .woocommerce-info {
  padding: 2.5rem 0;
  border: 0;
  background: none;
  color: var(--gv-text-3);
  text-align: center;
}

/* ---- Quiz band ---------------------------------------------------------- */

.gv-coll-quiz {
  margin-top: clamp(3rem, 7vw, 5rem);
  padding: clamp(3rem, 7vw, 5rem) 1.25rem;
  background: var(--accent-mint);
  text-align: center;
}

.gv-coll-quiz__h {
  margin: 0;
  font-size: clamp(1.625rem, 4vw, 2.75rem);
  font-weight: 700;
  letter-spacing: -0.01em;
}

.gv-coll-quiz__p {
  margin: 0.75rem 0 0;
  color: var(--gv-text-3);
  font-size: 1rem;
}

.gv-coll-quiz__btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 48px;
  margin-top: 1.75rem;
  padding: 0 1.75rem;
  border: 1.5px solid var(--legacy-pink);
  border-radius: var(--gv-r-pill);
  color: var(--legacy-pink);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  transition: background 0.15s, color 0.15s;
}

.gv-coll-quiz__btn:hover { background: var(--brand-pink-ink); color: #fff; }

@media (max-width: 640px) {
  .gv-coll-bar { justify-content: space-between; }

  .gv-legacy-grid,
  ul.products { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---- sections/header.css ---- */
/* ==========================================================================
   Header — matched to the live store's Horizon header (screens/shopify).
   Announcement bar rotates one message; header is logo / nav / icons.
   ========================================================================== */

/* ---- Announcement bar --------------------------------------------------- */
.gv-annc {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 36px;
  padding: 0 44px;
  background: var(--brand-pink-ink);
  color: #fff;
}
.gv-annc__viewport { flex: 1; text-align: center; overflow: hidden; }
.gv-annc__item {
  margin: 0;
  font-family: var(--legacy-font-sans);
  font-size: 13px;
  font-weight: 500;
  line-height: 1.3;
  padding-block: 9px;
  animation: gv-annc-in .35s var(--gv-ease);
}
.gv-annc__item[hidden] { display: none; }
@keyframes gv-annc-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

.gv-annc__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 0;
  background: none;
  color: #fff;
  cursor: pointer;
}
.gv-annc__nav--prev { left: 8px; }
.gv-annc__nav--next { right: 8px; }
.gv-annc__nav:hover { opacity: .8; }

@media (max-width: 749px) {
  .gv-annc { min-height: 52px; }
  .gv-annc__item { font-size: 15px; padding-block: 14px; }
}

/* ---- Header -------------------------------------------------------------
   z-index 8 on purpose: persistent page furniture (pill nav, WhatsApp,
   sticky buy bar) stays strictly below it, so none of it covers the menu. */
.gv-hdr {
  position: sticky;
  top: 0;
  z-index: var(--layer-header);
  background: #fff;
  border-bottom: 1px solid var(--gv-line-soft);
}

.gv-hdr__inner {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 24px;
  max-width: var(--gv-container);
  min-height: 64px;
  margin-inline: auto;
  padding-inline: var(--gv-gutter);
}

.gv-hdr__logo { display: inline-flex; align-items: center; grid-column: 1; grid-row: 1; }
.gv-hdr__logo img { width: 107px; height: auto; display: block; }

.gv-hdr__left { display: none; }

.gv-hdr__nav { grid-column: 2; display: flex; justify-content: center; }
.gv-hdr__menu { display: flex; align-items: center; gap: 30px; margin: 0; padding: 0; list-style: none; }
.gv-hdr__menu a {
  display: inline-block;
  padding: 8px 0;
  font-size: 14px;
  font-weight: 500;
  color: var(--berry-dark);
  text-decoration: none;
  white-space: nowrap;
}
.gv-hdr__menu a:hover,
.gv-hdr__menu .current-menu-item > a { color: var(--legacy-pink); }

.gv-hdr__right { grid-column: 3; display: flex; align-items: center; justify-content: flex-end; gap: 6px; }

.gv-hdr__icon {
  position: relative;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--berry-dark);
  cursor: pointer;
  text-decoration: none;
}
.gv-hdr__icon:hover { color: var(--legacy-pink); }

.gv-hdr__count {
  position: absolute;
  top: 5px;
  right: 3px;
  display: grid;
  place-items: center;
  min-width: 18px;
  height: 18px;
  padding-inline: 5px;
  border-radius: 99px;
  background: var(--brand-pink-ink);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
}
.gv-hdr__count[hidden] { display: none; }

/* ---- Mobile ------------------------------------------------------------- */
@media (max-width: 999px) {
  .gv-hdr__inner {
    grid-template-columns: 1fr auto 1fr;
    gap: 0;
    min-height: 60px;
    padding-inline: 8px;
  }

  .gv-hdr__left { display: flex; align-items: center; grid-column: 1; }
  .gv-hdr__logo { grid-column: 2; justify-self: center; }
  .gv-hdr__logo img { width: 80px; }
  .gv-hdr__right { grid-column: 3; gap: 0; }
  .gv-hdr__search-d { display: none; }

  .gv-hdr__nav {
    position: absolute;
    inset: 100% 0 auto;
    grid-column: auto;
    display: block;
    max-height: 0;
    overflow: hidden;
    background: #fff;
    box-shadow: var(--gv-shadow-nav);
    transition: max-height .28s var(--gv-ease);
  }
  .gv-hdr__nav.is-open { max-height: 80vh; overflow-y: auto; border-bottom: 1px solid var(--gv-line-soft); }

  .gv-hdr__menu { flex-direction: column; align-items: stretch; gap: 0; padding: 6px 20px 14px; }
  .gv-hdr__menu a { display: block; padding: 14px 0; font-size: 16px; border-bottom: 1px solid var(--gv-line-soft); }
  .gv-hdr__menu li:last-child a { border-bottom: 0; }
}

/* ---- sections/pdp-woo.css ---- */
/* Bridging between WooCommerce's output and the ported Shopify PDP styles.
   Kept separate so the files under assets/css/shopify/ stay verbatim copies of
   the Shopify theme and can be re-extracted without losing local edits. */

/* Price markup.
   The Shopify CSS expects a plain price with an <s> after it. WooCommerce
   prints <del>old</del><ins>new</ins> — old first, and <ins> underlined by the
   browser default. Reorder and restyle rather than fight get_price_html(),
   which extensions filter. */
.gv-v3-buy-price,
.gv-v3-sticky-price {
  display: inline-flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px;
}

.gv-v3-buy-price .woocommerce-Price-amount,
.gv-v3-sticky-price .woocommerce-Price-amount { white-space: nowrap; }

.gv-v3-buy-price ins,
.gv-v3-sticky-price ins {
  order: 1;
  background: none;
  text-decoration: none;
}

.gv-v3-buy-price del,
.gv-v3-sticky-price del {
  order: 2;
  color: #9aa0a8;
  font-weight: 600;
  text-decoration: line-through;
}

.gv-v3-buy-price del { font-size: 15px; }
.gv-v3-sticky-price del { font-size: 14px; }

/* The size pill sits after the price, so it must not be dragged in front of
   the struck-through original by the ordering above. */
.gv-v3-buy-price .gv-v3-size-pill { order: 3; }

/* Quantity input.
   woocommerce_quantity_input wraps the field in <div class="quantity">; the
   ported bar expects a pill sitting next to the button. */
.gv-v3-buybar .quantity {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--gv-line-strong);
  border-radius: var(--gv-r-pill);
  overflow: hidden;
}

.gv-v3-buybar .quantity input[type="number"] {
  width: 3.5rem;
  min-height: 48px;
  padding: 0 0.25rem;
  border: 0;
  background: none;
  font: inherit;
  font-size: 1rem;
  font-weight: 600;
  text-align: center;
}

/* Stock notice, which Woo prints above the form. */
.gv-v3-buyinfo .stock {
  margin: 0 0 0.5rem;
  font-size: 0.875rem;
}

.gv-v3-buyinfo .stock.out-of-stock { color: #D6336C; }

/* The floating WhatsApp button sits bottom-right, which is exactly where the
   sticky buy bar puts "Add to bag" — it was covering the primary action.
   Lift it while the bar is on screen. */


/* The sticky bar is present from load so the observer can measure it, but it
   stays off-screen until the real add-to-cart has scrolled away — otherwise it
   competes with the button it is meant to replace. */
.gv-v3-sticky-buy {
  transform: translateY(110%);
  transition: transform 0.2s ease;
}

.gv-v3-sticky-buy.is-on { transform: none; }

@media (prefers-reduced-motion: reduce) {
  .gv-v3-sticky-buy { transition: none; }
}

/* Only lift the WhatsApp button while the bar is actually on screen. */
body:has(.gv-v3-sticky-buy.is-on) .whatsapp-sticky-button { bottom: calc(20px + 68px); }

/* Icons.
   The live store paints every gv-icon SVG brand pink; .gv-v3-stars sets green
   but has no text children, so the icon rule is what actually shows. Scoped to
   the rating rather than applied globally, because the header and footer icons
   are deliberately dark. */
.gv-v3-stars .gv-icon,
.gv-v3-rating-text .gv-icon { color: var(--legacy-pink); }

.gv-v3-stars { gap: 1px; align-items: center; }
.gv-v3-rating-text { gap: 5px; }

/* The ingredient scroller is designed to bleed past the panel padding, so it
   reads as a row you can push rather than a boxed list. */
.gv-v3-acc-body .gv-v3-ing-scroll { margin-inline: -18px; }
.gv-v3-acc-body .gv-v3-ing-inci-label,
.gv-v3-acc-body .gv-v3-ing-inci { margin-inline: 0; }

/* ---- Review list -------------------------------------------------------- */

/* On Shopify the list inside this section is Judge.me's widget. Ours are
   WooCommerce comments, so the list is ours to draw; the head above it keeps
   the store's shape and comes from the ported stylesheet. */

.gv-v3-reviews-summary {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin: 0 0 1.5rem;
  padding-bottom: 1.25rem;
  border-bottom: 1px solid var(--gv-line);
}

.gv-v3-reviews-avg {
  font-size: 1.75rem;
  font-weight: 700;
  line-height: 1;
}

.gv-v3-reviews-count { color: var(--gv-muted); font-size: 0.875rem; }

.gv-v3-review-list { display: grid; gap: 1.25rem; }

.gv-v3-review {
  padding: 1.125rem 1.25rem;
  border: 1px solid var(--gv-line);
  border-radius: var(--gv-r-card);
  background: #fff;
}

.gv-v3-review-head {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.gv-v3-review-avatar {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: var(--gv-pink-tint);
  color: var(--legacy-pink);
  font-size: 0.9375rem;
  font-weight: 700;
}

.gv-v3-review-who { flex: 1; min-width: 0; }

.gv-v3-review-name {
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 700;
  line-height: 1.3;
}

.gv-v3-review-loc {
  margin: 0.1rem 0 0;
  color: var(--gv-muted);
  font-size: 0.8125rem;
}

.gv-v3-review-date {
  flex: 0 0 auto;
  color: var(--gv-muted-2);
  font-size: 0.75rem;
}

.gv-v3-review-stars { margin: 0.75rem 0 0.5rem; }
.gv-v3-review-stars .gv-icon { width: 15px; height: 15px; }

.gv-v3-review-body {
  margin: 0;
  color: var(--gv-text-2);
  font-size: 0.9375rem;
  line-height: 1.65;
}

/* ---- Contrast on pink surfaces ------------------------------------------- */

/* The ported Shopify stylesheets paint every primary action with --gv-pink
   (#FF4D8D) and set white text on it, which measures 3.14:1 against the 4.5:1
   WCAG 2.2 AA floor this project treats as a hard rule.

   Overridden here rather than in assets/css/shopify/, which stays a verbatim
   copy of the Shopify theme so it can be re-extracted without losing this.
   Only surfaces carrying white text are changed; --gv-pink itself is untouched
   so every border, star and accent keeps the brand hue. */
.gv-v3-atc,
.gv-v3-sticky-buy .gv-v3-atc,
.gv-btn-primary,
.gv-btn-quiz,
.gv-step-num,
.gv-bundle-upsell {
  background: var(--brand-pink-ink);
}

.gv-v3-atc:hover,
.gv-v3-sticky-buy .gv-v3-atc:hover,
.gv-btn-primary:hover { background: #BE1F52; }

/* Text set in the ported science/ingredient blue (#1B9FD1) measures 3.03:1 on
   white and 2.71:1 on its own tint — both under the floor. Only the *text*
   uses are darkened; the dots, borders and shadows keep the brighter blue,
   which is what makes the "ours" row read as highlighted, and 1.4.11 asks only
   3:1 of a non-text boundary. */
.gv-v3-ingcard-name,
.gv-v3-ing-foot,
.gv-v3-derm-points li::before,
.gv-v3-sci-cmp-row.is-ours .gv-v3-sci-cmp-note,
.gv-v3-sci-cmp-row.is-ours .gv-v3-sci-cmp-label,
.gv-v3-sci-n { color: #14779D; }

/* Pink used as *text* has the same 3.14:1 problem as pink used as a surface —
   the ratio is symmetric. The section eyebrow, the nav pills and the review
   initial all sit on white or a near-white tint. */
.gv-v3-pill,
.gv-legacy-section-header__eyebrow,
.gv-v3-review-avatar,
.gv-v3-speech-name,
.gv-v3-row-label,
.gv-v3-speech-sign { color: var(--brand-pink-ink); }

/* The sticky bar's button is .gv-v3-sticky-atc, not .gv-v3-atc -- a separate
   class for the same action, which is why the first pass fixed the in-page
   button and left the one that covers it on scroll. */
.gv-v3-sticky-atc { background: var(--brand-pink-ink); }
.gv-v3-sticky-atc:hover { background: #BE1F52; }

/* Large text needs only 3:1, and this headline missed even that at 2.71:1
   against its own tinted panel. */
.gv-v3-science-result-big { color: #14779D; }

/* Last two: the net-size pill beside the price, and the footer newsletter
   button, which is an unclassed <button> inside .gv-v3-sub. */
.gv-v3-size-pill { color: var(--brand-pink-ink); }

.gv-v3-sub button { background: var(--brand-pink-ink); }
.gv-v3-sub button:hover { background: #BE1F52; }

/* ---- Home and card surfaces ---------------------------------------------- */

/* Product-card add-to-cart, the breadcrumb link, and the promo CTA all set
   white-on-pink or pink-on-white at 3.14:1. */
/* Specificity matched deliberately: the ported rules are
   `.gv-v3-routine .gv-v3-card-atc` and `.gv-v3-bcard-price .gv-v3-price-save`,
   so a single-class override loses regardless of order. */
.gv-v3-card-atc,
.gv-v3-routine .gv-v3-card-atc { background: var(--brand-pink-ink); }

.gv-v3-card-atc:hover,
.gv-v3-routine .gv-v3-card-atc:hover { background: #BE1F52; }

.gv-v3-promo-cta--primary,
.woocommerce-breadcrumb a { color: var(--brand-pink-ink); }

/* The offer line sits on a pink tint, which needs a touch more than the
   on-white value to clear the floor. */
.gv-v3-bcard-offer { color: #DC004F; }

/* Struck-through original prices are still prices — a customer reads them to
   work out the saving, so they are content, not decoration. #9AA3AD gave
   2.56:1, the worst text ratio on the home page. */
.gv-v3-price-was,
.price del,
.price del .woocommerce-Price-amount { color: #6C7885; }

/* The saving figure was a bright lime at 2.09:1. Same hue, dark enough to read. */
.gv-v3-price-save,
.gv-v3-bcard-price .gv-v3-price-save { color: #528407; }

/* The quiz band button and the struck price. */
.gv-v3-quiz-btn { color: var(--brand-pink-ink); }

.woocommerce-Price-amount.amount del,
del .woocommerce-Price-amount,
.gv-v3-card-price del,
.gv-v3-bcard-price del { color: #6C7885; }

/* Header nav links, the struck "was" price inside a product card, and the
   quiz band, which paints white copy straight onto #FF4D8D. */
.gv-v3-price-old,
.gv-v3-price-old .woocommerce-Price-amount { color: #6C7885; }

/* The quiz band keeps the brand pink. Darkening it was the wrong move: the
   band's heading is already near-black, and near-black on #FF4D8D measures
   5.55:1 — better than white on either pink. So the fix is to bring the
   paragraph into line with the heading rather than to repaint the band.

     #1A1A1A on #FF4D8D  5.55  ✓
     #1A1A1A on #D6285F  3.59  ✗
     #FFFFFF on #FF4D8D  3.14  ✗ */
.gv-v3-quiz-p,
.gv-v3-quiz-copy p,
.gv-v3-quiz-sub { color: #1A1A1A; }

/* Nav links: the ported header rule is more specific than a bare
   `.gv-hdr__menu a`. */
.gv-hdr__menu li a,
.gv-hdr__menu .menu-item a { color: var(--brand-pink-ink); }

/* Section eyebrows across the home page. */
.gv-v3-best-label,
.gv-v3-sec-label,
.gv-v3-eyebrow { color: var(--brand-pink-ink); }

/* Story chapter eyebrows on the product page. */
.gv-v3-story-eyebrow { color: var(--brand-pink-ink); }

/* ---- sections/pdp.css ---- */
/* ==========================================================================
   PDP — values ported from gv-v3-pdp-buy's {% stylesheet %} block.
   ========================================================================== */

/* ---- Pill nav -----------------------------------------------------------
   Stays strictly below the header's stacking context (z-index 8), or it
   renders on top of the open mobile menu. */
.gv-pillnav { position: relative; z-index: var(--layer-raised); background: #fff; border-bottom: 1px solid var(--gv-line-soft); }
.gv-pillnav--fixed { position: fixed; left: 0; right: 0; top: 0; z-index: var(--layer-heightened); box-shadow: var(--gv-shadow-nav); }
.gv-pillnav__inner { gap: 10px; padding: 12px 16px; max-width: var(--gv-container-narrow); margin-inline: auto; }

.gv-pill {
  flex: 0 0 auto;
  padding: 8px 18px;
  border: 1.5px solid var(--berry-dark);
  border-radius: 30px;
  color: var(--berry-dark);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
}
.gv-pill.is-active { border-color: var(--legacy-pink); color: var(--legacy-pink); }

/* ---- Layout ------------------------------------------------------------- */
.gv-pdp-buy { padding: 16px 0 var(--gv-sec-gap); }
.gv-pdp-buy__inner { display: grid; gap: 24px; align-items: start; }

@media (min-width: 1000px) {
  .gv-pdp-buy__inner { grid-template-columns: 1fr 1fr; gap: 48px; }
  .gv-buyinfo { position: sticky; top: 92px; }
}

/* ---- Gallery ------------------------------------------------------------ */
.gv-gallery__main {
  position: relative;
  aspect-ratio: 1;
  border-radius: var(--gv-r-media);
  overflow: hidden;
  background: linear-gradient(135deg, #BFE4F5, #CDBDF0 50%, #F3C6E2);
}
.gv-gallery__track { height: 100%; scroll-behavior: smooth; overscroll-behavior-x: contain; }
/* Snap is armed by JS after load. A snap container re-snapping during load
   counts as a scroll, and Chrome stops measuring LCP at the first scroll —
   the page then reports no LCP at all. Same fix as the Shopify theme. */
.gv-snap-ready .gv-gallery__track { scroll-snap-type: x mandatory; }
.gv-gallery__slide { position: relative; flex: 0 0 100%; width: 100%; height: 100%; scroll-snap-align: center; scroll-snap-stop: always; }
.gv-gallery__img { width: 100%; height: 100%; object-fit: cover; }

.gv-gallery__badge {
  position: absolute; top: 14px; left: 14px; z-index: 2;
  background: rgba(26,26,26,.78); color: #fff;
  font-size: 11px; font-weight: 700; line-height: 1.2;
  border-radius: var(--gv-r-xs); padding: 6px 10px; white-space: pre-line;
}

.gv-gallery__nav {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 3;
  width: 40px; height: 40px; padding: 0;
  border: none; border-radius: 50%; cursor: pointer;
  background: rgba(255,255,255,.88); color: var(--berry-dark);
  display: grid; place-items: center; font-size: 20px; line-height: 1;
  box-shadow: 0 2px 10px rgba(0,0,0,.18);
  transition: background .15s, transform .15s;
}
.gv-gallery__nav:hover { background: #fff; }
.gv-gallery__nav--prev { left: 12px; }
.gv-gallery__nav--next { right: 12px; }
@media (hover: none) { .gv-gallery__nav { display: none; } }

.gv-gallery__dots { position: absolute; left: 0; right: 0; bottom: 12px; z-index: 3; display: flex; justify-content: center; gap: 6px; pointer-events: none; }
.gv-gallery__dot { width: 6px; height: 6px; border-radius: 50%; background: rgba(255,255,255,.6); box-shadow: 0 1px 3px rgba(0,0,0,.3); transition: width .22s ease, background .22s ease; }
.gv-gallery__dot.is-on { width: 18px; border-radius: 99px; background: #fff; }
@media (min-width: 1000px) { .gv-gallery__dots { display: none; } }

.gv-gallery__thumbs { gap: 8px; margin-top: 12px; }
.gv-gallery__thumb {
  position: relative; flex: 0 0 auto;
  width: 56px; height: 56px; padding: 0;
  border: 2px solid transparent; border-radius: var(--gv-r-sm);
  overflow: hidden; cursor: pointer; background: var(--gv-surface-2);
}
.gv-gallery__thumb img { width: 100%; height: 100%; object-fit: cover; }
.gv-gallery__thumb.is-active { border-color: var(--legacy-pink); }

/* ---- Buy info ----------------------------------------------------------- */
.gv-buyinfo__titlerow { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 16px; }
.gv-buyinfo__title { margin: 0; font-size: 23px; font-weight: 800; letter-spacing: -0.3px; line-height: 1.18; }
.gv-buyinfo__sub { margin: 8px 0 0; color: var(--gv-text-2); font-size: 15px; }
.gv-buyinfo__rating { margin: 12px 0; }

.gv-buyinfo__saveline { margin: 12px 0 0; color: var(--legacy-pink); font-size: 14px; font-weight: 700; }

/* ---- Targets card -------------------------------------------------------
   Brand card surface: white, 1px #ECECEC, radius 16, shadow 0 4px 16px/.06.
   The label sits ABOVE its list, not beside it — a side column steals width
   and leaves the label floating next to a two-row list. */
.gv-targets-card {
  margin-top: 18px; padding: 20px;
  background: #fff; border: 1px solid var(--gv-line);
  border-radius: var(--gv-r-card); box-shadow: var(--gv-shadow-card);
}
.gv-row-label {
  display: block; margin: 0 0 14px;
  font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: var(--legacy-pink);
}
/* Targets read as a checklist, not as tags. Solid pink blocks competed with
   ADD TO CART, and a list of problems rendered like a list of prizes. Pink is
   the tick only; the words carry the message. */
.gv-targets { display: grid; grid-template-columns: 1fr 1fr; gap: 15px 20px; margin: 0; padding: 0; list-style: none; }
.gv-target { display: flex; align-items: center; gap: 10px; font-size: 15px; font-weight: 600; line-height: 1.3; }
.gv-target::before {
  content: ""; flex: 0 0 auto; width: 18px; height: 18px; border-radius: 50%;
  background: var(--brand-pink-ink) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E") center/11px 11px no-repeat;
}

/* ---- Packs -------------------------------------------------------------- */
.gv-packs { display: flex; flex-direction: column; gap: 10px; margin: 16px 0 0; padding: 0; list-style: none; }
.gv-pack__link {
  display: flex; align-items: center; gap: 12px;
  padding: 14px; text-decoration: none;
  border: 1.5px solid var(--gv-line-strong); border-radius: var(--gv-r-pack);
  background: var(--gv-surface);
  transition: border-color var(--gv-duration), background var(--gv-duration);
}
.gv-pack.is-selected .gv-pack__link { border-color: var(--legacy-pink); background: #fff; }
.gv-pack__link:hover { border-color: var(--legacy-pink); }

.gv-pack__radio { position: relative; flex: 0 0 auto; width: 20px; height: 20px; border-radius: 50%; border: 2px solid #C5CAD0; }
.gv-pack.is-selected .gv-pack__radio { border-color: var(--legacy-pink); }
.gv-pack.is-selected .gv-pack__radio::after { content: ""; position: absolute; inset: 3px; border-radius: 50%; background: var(--legacy-pink); }

.gv-pack__main { flex: 1; display: flex; flex-direction: column; gap: 3px; }
.gv-pack__name { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 15px; font-weight: 700; }
.gv-pack__note { font-size: 12px; color: var(--gv-muted); }
.gv-pack__price { font-size: 15px; font-weight: 800; text-align: right; white-space: nowrap; }
.gv-pack__price del { display: block; font-size: 12px; color: var(--gv-muted-2); font-weight: 600; }

/* ---- Urgency ------------------------------------------------------------ */
.gv-urgency {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 14px; padding: 10px 14px;
  background: var(--gv-pink-tint); border: 1px solid var(--gv-pink-border); border-radius: var(--gv-r-sm);
}
.gv-urgency__pulse {
  display: block; width: 8px; height: 8px; border-radius: 50%;
  background: var(--legacy-pink); animation: gv-pulse 1.6s infinite;
}
@keyframes gv-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(255,77,141,.55); }
  70%  { box-shadow: 0 0 0 8px rgba(255,77,141,0); }
  100% { box-shadow: 0 0 0 0 rgba(255,77,141,0); }
}
.gv-urgency__text { font-size: 13px; color: var(--gv-text-3); }

/* ---- Buy bar ------------------------------------------------------------ */
.gv-buybar { margin-top: 16px; }
.gv-buybar__price { margin: 0 0 12px; font-size: 22px; font-weight: 800; }
.gv-buybar__price del { margin-left: 6px; font-size: 15px; color: var(--gv-muted-2); font-weight: 600; }

.gv-buybar form.cart { display: flex; align-items: stretch; gap: 12px; flex-wrap: wrap; margin: 0; }
.gv-buybar form.cart .quantity { display: flex; align-items: center; border: 1.5px solid var(--gv-line-strong); border-radius: var(--gv-r-sm); overflow: hidden; }
.gv-buybar form.cart .quantity input {
  width: 64px; height: 48px; padding: 0 6px; border: none; background: #fff;
  text-align: center; font-weight: 600;
}
.gv-buybar form.cart button[type="submit"] {
  flex: 1; min-width: 150px; height: 48px; padding-inline: 20px;
  border: none; border-radius: var(--gv-r-input);
  background: var(--brand-pink-ink); color: #fff;
  font-weight: 700; font-size: 16px; letter-spacing: .5px;
  text-transform: uppercase; cursor: pointer;
  transition: background var(--gv-duration);
}
.gv-buybar form.cart button[type="submit"]:hover { background: var(--coral-dark); }

/* Black secondary action — Buy Now (Cash on Delivery). */
.gv-buynow {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  width: 100%; min-height: 50px; margin-top: 10px; padding: 12px 16px;
  border: none; border-radius: var(--gv-r-input); cursor: pointer;
  background: var(--berry-dark); color: #fff;
  font-weight: 700; font-size: 16px; letter-spacing: .3px; line-height: 1.2;
  text-decoration: none;
}
.gv-buynow:hover { background: #000; }

/* ---- Trust row ---------------------------------------------------------- */
.gv-trustrow {
  display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px;
  margin: 16px 0 0; padding: 14px 0 0; list-style: none;
  border-top: 1px solid var(--gv-line);
}
.gv-trustrow__item { font-size: 10px; font-weight: 600; line-height: 1.3; text-align: center; color: var(--mid-gray); }
@media (max-width: 480px) { .gv-trustrow { grid-template-columns: repeat(3, 1fr); gap: 12px 8px; } }

/* ---- Sticky mobile buy bar ---------------------------------------------
   Appears only after the real add-to-cart scrolls out of view, so it never
   competes with it. Sits in the thumb zone. */
.gv-stickybuy {
  position: fixed; left: 0; right: 0; bottom: 0;
  z-index: var(--layer-heightened);
  padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
  background: rgba(255,255,255,.97);
  backdrop-filter: blur(8px);
  border-top: 1px solid var(--gv-line);
  box-shadow: 0 -4px 16px rgba(0,0,0,.08);
  transform: translateY(100%);
  transition: transform .24s var(--gv-ease);
}
.gv-stickybuy.is-on { transform: translateY(0); }
.gv-stickybuy__inner { display: flex; align-items: center; gap: 12px; max-width: var(--gv-container-narrow); margin-inline: auto; }
.gv-stickybuy__price { font-size: 17px; font-weight: 800; white-space: nowrap; }
.gv-stickybuy__price del { display: none; }
.gv-stickybuy__btn { flex: 1; text-transform: uppercase; }
@media (min-width: 1000px) { .gv-stickybuy { display: none; } }

/* ---- sections/promo-bar.css ---- */
/* Sale promo bar — sits above the announcement bar while a campaign runs.
   Darker than the announcement bar so the two read as a hierarchy rather than
   one double-height pink block. */

.gv-promo {
  background: var(--berry-dark, #7A1436);
  color: #fff;
  text-align: center;
}

.gv-promo__text {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.25rem 0.75rem;
  margin: 0;
  padding: 0.5rem 1rem;
  font-size: 0.8125rem;
  line-height: 1.3;
}

.gv-promo__label {
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.gv-promo__ends { opacity: 0.85; }

/* ---- funnel/glowve.css ---- */
/* Glowvé checkout funnel — verbatim port of Mockups/glowve.css.

   Scoped under .gv-funnel by scripts/scope-funnel-css.py (2026-09-18); edited by
   hand since Phase 3 moved its tokens into 00-tokens.css. WooCommerce-specific
   mapping lives beside this in woo-bridge.css. */

/* The funnel's tokens now live once, in 00-tokens.css :root (identical values).
   The shared header and footer on these pages still use legacy names; point the
   two renamed ones at the mockup values here, as the funnel's own token block
   did, so the signed-off screens don't move. */
.gv-funnel {
  --legacy-pink: var(--brand-pink);
  --legacy-font-sans: var(--font-sans);
}

/* Dark mode is a straight token swap — the pairs are contrast-checked in the
   design system. Delete this block if the storefront is light-only. */
/* --------------------------------------------------------------- base --- */
.gv-funnel *,
.gv-funnel *::before,
.gv-funnel *::after {
 box-sizing: border-box;
}
.gv-funnel {
 -webkit-text-size-adjust: 100%;
}
.gv-funnel {
  margin: 0;
  background: var(--surface-page);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
.gv-funnel h1,
.gv-funnel h2,
.gv-funnel h3,
.gv-funnel p {
 margin: 0;
}
.gv-funnel a {
 color: var(--brand-pink-deep);
}
.gv-funnel a:hover {
 color: var(--ink);
}
.gv-funnel img {
 max-width: 100%; display: block;
}
.gv-funnel :where(a,
.gv-funnel button,
.gv-funnel input,
.gv-funnel select,
.gv-funnel textarea):focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
.gv-funnel .visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ------------------------------------------------------------ typography - */
.gv-funnel .display {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1.05;
}
.gv-funnel .display-xl {
 font-size: 34px;
}
.gv-funnel .display-lg {
 font-size: 28px;
}
.gv-funnel .display-md {
 font-size: 24px;
}
@media (min-width: 900px) {
.gv-funnel .display-xl {
 font-size: 42px;
}
.gv-funnel .display-lg {
 font-size: 34px;
}
.gv-funnel .display-md {
 font-size: 27px;
}

}
.gv-funnel .eyebrow {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 1.1px;
  text-transform: uppercase;
  color: var(--ink-subtle);
}
.gv-funnel .price {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.gv-funnel .price-lg {
 font-size: 26px;
}
.gv-funnel .price-xl {
 font-size: 30px;
}
.gv-funnel .muted {
 color: var(--ink-subtle);
}
.gv-funnel .dim {
 color: var(--ink-muted);
}
.gv-funnel .small {
 font-size: 12.5px;
}
.gv-funnel .tiny {
 font-size: 11.5px; line-height: 1.5;
}
.gv-funnel .strike {
 text-decoration: line-through; color: var(--ink-subtle);
}
.gv-funnel .tabular {
 font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------- shell -- */
.gv-funnel .wrap {
  max-width: 1280px;
  margin: 0 auto;
  padding-inline: var(--gutter);
}
.gv-funnel .site-header {
  background: var(--surface-card);
  border-bottom: 1px solid var(--line);
}
.gv-funnel .site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 60px;
}
.gv-funnel .site-header__side {
  width: 72px;
  display: flex;
  align-items: center;
}
.gv-funnel .site-header__side--end {
 justify-content: flex-end;
}
.gv-funnel .wordmark {
  flex: 1;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 24px;
  letter-spacing: -0.04em;
  color: var(--ink);
  text-decoration: none;
}
.gv-funnel .icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--tap-min);
  height: var(--tap-min);
  border: 0;
  background: none;
  color: var(--ink);
  border-radius: var(--radius-pill);
  text-decoration: none;
  cursor: pointer;
}
.gv-funnel .secure-flag {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: 11.5px;
  font-weight: 600;
  color: var(--ink-muted);
}
@media (min-width: 900px) {
.gv-funnel .site-header__inner {
 min-height: 72px;
}
.gv-funnel .site-header__side {
 width: 220px;
}
.gv-funnel .wordmark {
 text-align: left; font-size: 27px;
}
.gv-funnel .site-header__side--start {
 order: -1;
}

}

/* Desktop checkout header puts the wordmark left and help right. */
.gv-funnel .checkout-header .site-header__inner {
 justify-content: space-between;
}
@media (min-width: 900px) {
.gv-funnel .checkout-header .wordmark {
 flex: 0 0 auto;
}
.gv-funnel .checkout-header .site-header__side {
 width: auto; flex: 1;
}
.gv-funnel .checkout-header .site-header__side--end {
 justify-content: flex-end; gap: var(--space-5);
}

}

/* -------------------------------------------------------------- layout --- */
.gv-funnel .page {
  padding-block: var(--space-5) 160px;
}
@media (min-width: 900px) {
.gv-funnel .page {
 padding-block: var(--space-6) var(--space-8);
}

}
.gv-funnel .stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.gv-funnel .checkout-grid {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
@media (min-width: 900px) {
.gv-funnel .checkout-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 416px;
    gap: var(--space-7);
    align-items: start;
}
.gv-funnel .checkout-grid__main {
 display: flex; flex-direction: column; gap: var(--space-5);
}
.gv-funnel .checkout-grid__aside {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    position: sticky;
    top: var(--space-5);
}

}

/* ---------------------------------------------------------------- card --- */
.gv-funnel .card {
  background: var(--surface-card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
}
@media (min-width: 900px) {
.gv-funnel .card {
 padding: var(--space-5);
}

}
.gv-funnel .card__head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.gv-funnel .step-no {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  flex: 0 0 22px;
  border-radius: var(--radius-pill);
  background: var(--ink);
  color: var(--surface-card);
  font-size: 12px;
  font-weight: 700;
}
.gv-funnel .card__title {
  font-size: 15.5px;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.gv-funnel .divider {
  height: 1px;
  background: var(--line-hair);
  border: 0;
  margin: var(--space-3) 0;
}

/* --------------------------------------------------------------- forms --- */
.gv-funnel .fields {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}
@media (min-width: 640px) {
.gv-funnel .fields--two {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-5);
}

}
.gv-funnel .field__label {
  display: block;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-muted);
  margin-bottom: var(--space-2);
}
.gv-funnel .field__hint {
  margin-top: var(--space-2);
  font-size: 11.5px;
  color: var(--ink-subtle);
}
.gv-funnel .field__error {
  margin-top: var(--space-2);
  font-size: 11.5px;
  font-weight: 600;
  color: #b3261e;
  display: none;
}
.gv-funnel .field.is-invalid .field__error {
 display: block;
}
.gv-funnel .field.is-invalid .input,
.gv-funnel .field.is-invalid .input-group {
 border-color: #b3261e;
}
.gv-funnel .input,
.gv-funnel .select {
  width: 100%;
  height: var(--control-h);
  padding: 0 14px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: var(--surface-card);
  color: var(--ink);
  font-family: inherit;
  font-size: 15px;
}
.gv-funnel .select {
 padding-inline: 12px; appearance: auto;
}
.gv-funnel .input::placeholder {
 color: #9a918b;
}
.gv-funnel .input[readonly] {
  background: var(--surface-sunken);
  color: var(--ink-muted);
  border-color: var(--line);
}
.gv-funnel .input-group {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: var(--surface-card);
  overflow: hidden;
}
.gv-funnel .input-group__prefix {
  display: flex;
  align-items: center;
  padding: 0 12px;
  background: var(--surface-sunken);
  border-right: 1px solid var(--line-strong);
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-muted);
}
.gv-funnel .input-group .input {
  border: 0;
  border-radius: 0;
  background: transparent;
}
.gv-funnel .link-btn {
  align-self: flex-start;
  min-height: var(--tap-min);
  padding: 0;
  border: 0;
  background: none;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--brand-pink-deep);
  text-align: left;
  cursor: pointer;
}
.gv-funnel .note-box {
  padding: var(--space-3) var(--space-4);
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-md);
  background: var(--surface-page);
  font-size: 12.5px;
  color: var(--ink-muted);
}

/* ------------------------------------------------------------- buttons --- */
.gv-funnel .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--control-h);
  padding: 0 20px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-decoration: none;
  cursor: pointer;
}
.gv-funnel .btn--primary {
  height: var(--control-h-lg);
  background: var(--brand-pink);
  color: #ffffff;
  font-size: 16px;
}
.gv-funnel .btn--primary:hover {
 background: var(--brand-pink-deep); color: #ffffff;
}
.gv-funnel .btn--secondary {
  background: var(--surface-card);
  border-color: var(--ink);
  color: var(--ink);
}
.gv-funnel .btn--secondary:hover {
 background: var(--ink); color: var(--surface-card);
}
.gv-funnel .btn--block {
 width: 100%;
}
.gv-funnel .btn--quiet {
  background: transparent;
  border-color: var(--line-strong);
  color: var(--ink);
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 14px;
}

/* ------------------------------------------------------------- stepper --- */
.gv-funnel .stepper {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  background: var(--surface-card);
}
.gv-funnel .stepper__btn {
  width: var(--tap-min);
  height: var(--control-h);
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: none;
  color: var(--ink);
  cursor: pointer;
}
.gv-funnel .stepper__btn[disabled] {
 color: #b8afa8; cursor: default;
}
.gv-funnel .stepper__value {
  min-width: 26px;
  text-align: center;
  font-size: 15px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------ progress --- */
.gv-funnel .progress {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.gv-funnel .progress__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  font-size: 13px;
  font-weight: 600;
}
.gv-funnel .progress__track {
  height: 6px;
  border-radius: var(--radius-pill);
  background: #f0e9e5;
  overflow: hidden;
}
.gv-funnel .progress__fill {
  height: 100%;
  border-radius: var(--radius-pill);
  background: var(--brand-pink);
  transition: width 0.25s ease;
}
@media (prefers-reduced-motion: reduce) {
.gv-funnel .progress__fill {
 transition: none;
}

}

/* --------------------------------------------------------------- badge --- */
.gv-funnel .badge {
  display: inline-flex;
  align-items: center;
  border-radius: var(--radius-sm);
  padding: 3px 7px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.3px;
  text-transform: uppercase;
}
.gv-funnel .badge--save {
  background: var(--surface-success);
  color: var(--ink-success);
  border-radius: var(--radius-pill);
}
.gv-funnel .chip {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  padding: 5px 11px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-muted);
}

/* -------------------------------------------------------- pay options --- */
.gv-funnel .options {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.gv-funnel .option {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4);
  border: 1.5px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface-card);
  cursor: pointer;
}
.gv-funnel .option:has(input:checked) {
  border-color: var(--brand-pink);
  background: color-mix(in srgb, var(--brand-pink) 4%, var(--surface-card));
}
.gv-funnel .option input[type="radio"],
.gv-funnel .option input[type="checkbox"] {
  width: 20px;
  height: 20px;
  margin: 1px 0 0;
  flex: 0 0 20px;
  accent-color: var(--brand-pink);
}
.gv-funnel .option__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.gv-funnel .option__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  font-size: 14.5px;
  font-weight: 700;
}
.gv-funnel .option__note {
  font-size: 12.5px;
  color: var(--ink-muted);
}
.gv-funnel .option__meta {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: 11px;
  color: var(--ink-subtle);
}

/* ------------------------------------------------------------- summary --- */
.gv-funnel .summary-row {
  display: flex;
  justify-content: space-between;
  gap: var(--space-2);
  font-size: 13.5px;
  color: var(--ink-muted);
}
.gv-funnel .summary-row > span:last-child {
 color: var(--ink);
}
.gv-funnel .summary-row--save {
 color: var(--ink-success); font-weight: 600;
}
.gv-funnel .summary-row--save > span:last-child {
 color: var(--ink-success);
}
.gv-funnel .summary-rows {
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.gv-funnel .summary-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
}
.gv-funnel .summary-total__label {
 font-size: 15px; font-weight: 700;
}
.gv-funnel .line-item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
}
.gv-funnel .thumb {
  width: 48px;
  height: 48px;
  flex: 0 0 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-md);
  background: var(--surface-tint);
  border: 1px solid var(--brand-pink-soft);
  color: var(--brand-pink-deep);
}
.gv-funnel .thumb--lg {
 width: 72px; height: 88px; flex-basis: 72px;
}
.gv-funnel .disclosure {
  width: 100%;
  min-height: var(--tap-min);
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 0;
  border: 0;
  background: none;
  font-family: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.gv-funnel .disclosure__caret {
  display: flex;
  color: var(--ink-subtle);
  transition: transform 0.18s ease;
}
.gv-funnel .disclosure[aria-expanded="true"] .disclosure__caret {
 transform: rotate(180deg);
}
@media (prefers-reduced-motion: reduce) {
.gv-funnel .disclosure__caret {
 transition: none;
}

}
.gv-funnel [hidden] {
 display: none !important;
}

/* --------------------------------------------------------- reassurance --- */
.gv-funnel .reassure {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.gv-funnel .reassure__item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  font-size: 12.5px;
  color: var(--ink-muted);
}
.gv-funnel .reassure__tick {
 display: flex; color: var(--ink-success); margin-top: 1px; flex: 0 0 auto;
}
.gv-funnel .delivery {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
}
.gv-funnel .delivery__icon {
  width: 38px;
  height: 38px;
  flex: 0 0 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-md);
  background: var(--surface-sunken);
  color: var(--ink-muted);
}

/* -------------------------------------------------------------- paybar --- */
.gv-funnel .paybar {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 20;
  background: var(--surface-card);
  border-top: 1px solid var(--line);
  box-shadow: var(--shadow-bar);
  padding: var(--space-3) var(--gutter) var(--space-4);
  padding-bottom: calc(var(--space-4) + env(safe-area-inset-bottom, 0px));
}
.gv-funnel .paybar__inner {
  max-width: 1280px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.gv-funnel .paybar__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
}
.gv-funnel .paybar__label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--ink-subtle);
}
.gv-funnel .paybar__total {
 font-size: 19px;
}
@media (min-width: 900px) {
.gv-funnel .paybar {
 display: none;
}
.gv-funnel .desktop-submit {
 display: flex; flex-direction: column; gap: var(--space-3);
}

}
.gv-funnel .desktop-submit {
 display: none;
}

/* --------------------------------------------------------- confirmation - */
.gv-funnel .confirm-hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  text-align: center;
  padding-block: var(--space-2) var(--space-4);
}
@media (min-width: 900px) {
.gv-funnel .confirm-hero {
    flex-direction: row;
    align-items: flex-start;
    text-align: left;
    gap: var(--space-5);
}

}
.gv-funnel .tick-circle {
  width: 56px;
  height: 56px;
  flex: 0 0 56px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-pill);
  background: var(--surface-success);
  color: var(--ink-success);
}
.gv-funnel .timeline {
  display: flex;
  flex-direction: column;
}
.gv-funnel .timeline__step {
  display: flex;
  gap: var(--space-3);
}
.gv-funnel .timeline__rail {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 18px;
  flex: 0 0 18px;
}
.gv-funnel .timeline__dot {
  width: 12px;
  height: 12px;
  border-radius: var(--radius-pill);
  background: var(--surface-card);
  border: 2px solid var(--line-strong);
}
.gv-funnel .timeline__step--done .timeline__dot {
  background: var(--ink-success);
  border-color: var(--ink-success);
}
.gv-funnel .timeline__line {
  flex: 1;
  width: 2px;
  background: var(--line-strong);
}
.gv-funnel .timeline__body {
  padding-bottom: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.gv-funnel .timeline__step:last-child .timeline__body {
 padding-bottom: 0;
}
@media (min-width: 900px) {
.gv-funnel .timeline {
 flex-direction: row;
}
.gv-funnel .timeline__step {
 flex: 1; flex-direction: column; gap: var(--space-3);
}
.gv-funnel .timeline__rail {
 flex-direction: row; width: auto;
}
.gv-funnel .timeline__line {
 width: auto; height: 2px; flex: 1;
}
.gv-funnel .timeline__body {
 padding-bottom: 0; padding-right: var(--space-5);
}

}
.gv-funnel .confirm-grid {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
@media (min-width: 900px) {
.gv-funnel .confirm-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-5);
    align-items: start;
}

}
.gv-funnel .address-block {
  font-size: 13.5px;
  line-height: 1.6;
}

/* ----------------------------------------------------------------- cart - */
.gv-funnel .cart-item {
  display: flex;
  gap: var(--space-4);
}
.gv-funnel .cart-item__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.gv-funnel .cart-item__top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
}
.gv-funnel .cart-item__controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}
.gv-funnel .remove-btn {
  min-height: var(--tap-min);
  padding: 0 4px;
  border: 0;
  background: none;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-subtle);
  text-decoration: underline;
  cursor: pointer;
}
.gv-funnel .empty-state {
  display: none;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  text-align: center;
  padding: var(--space-8) var(--space-4);
}

/* ---- funnel/woo-bridge.css ---- */
/* WooCommerce → the funnel design system.
   funnel/glowve.css is a verbatim port of the supplied mockup and stays that
   way. Everything here maps markup WooCommerce generates, and that we cannot
   change, onto the classes that port defines. */

/* ---- Headings ------------------------------------------------------------ */

/* assets/css/shopify/_glowve-base.css pins every heading to Poppins with
   !important under a "V2 GLOBAL TYPOGRAPHY OVERRIDES" block. That file is a
   verbatim Shopify port and must stay re-extractable, so the override belongs
   here — scoped, so it cannot reach a heading anywhere else on the store. */
/* The design splits the two faces by role, not by tag: Cabinet Grotesk is for
   .display, .price and the wordmark only. Card titles, buttons and every
   heading that is not a .display are Inter at 700. An earlier version of this
   rule put every heading on the display face and made card titles read as
   headlines — measured against the mockup, which has them in Inter. */
.gv-funnel,
.gv-funnel h1,
.gv-funnel h2,
.gv-funnel h3,
.gv-funnel h4,
.gv-funnel .card__title,
.gv-funnel .btn,
.gv-funnel .eyebrow,
.gv-funnel input,
.gv-funnel select,
.gv-funnel textarea,
.gv-funnel .field__label,
.gv-funnel .small,
.gv-funnel .tiny { font-family: var(--font-sans) !important; }

/* After the block above, so a .display heading wins. */
.gv-funnel .display,
.gv-funnel .price,
.gv-funnel .wordmark { font-family: var(--font-display) !important; }

/* Same Shopify block also pins every heading to weight 600 and kills letter
   spacing, both with !important, so the design's 500 display face and its 700
   card titles were both landing on 600. Re-asserted here with the values from
   Mockups/glowve.css — scoped, so no heading outside the funnel is touched. */
.gv-funnel h1,
.gv-funnel h2,
.gv-funnel h3,
.gv-funnel h4 {
  font-weight: 700 !important;
  letter-spacing: -0.01em !important;
}

.gv-funnel .display {
  font-weight: 500 !important;
  letter-spacing: -0.03em !important;
}

.gv-funnel .eyebrow {
  font-weight: 600 !important;
  letter-spacing: 1.1px !important;
}

/* ---- Fields -------------------------------------------------------------- */

/* WooCommerce wraps each field in <p class="form-row">; the design expects
   .field. Mapped rather than renamed, because form-row is what checkout.js,
   the validation states and every extension look for. */
.gv-funnel .form-row {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
}

.gv-funnel .form-row label {
  display: block;
  margin-bottom: var(--space-2);
  color: var(--ink-muted);
  font-size: 12.5px;
  font-weight: 600;
}

.gv-funnel .form-row .required { color: var(--ink-subtle); text-decoration: none; }
.gv-funnel .form-row .optional { color: var(--ink-subtle); font-weight: 400; }

.gv-funnel .form-row input[type="text"],
.gv-funnel .form-row input[type="email"],
.gv-funnel .form-row input[type="tel"],
.gv-funnel .form-row input[type="password"],
.gv-funnel .form-row textarea,
.gv-funnel .form-row select,
.gv-funnel .select2-container .select2-selection--single {
  width: 100%;
  height: var(--control-h);
  padding: 0 14px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: var(--surface-card);
  color: var(--ink);
  font-size: 15px;
}

.gv-funnel .form-row textarea { height: auto; min-height: 88px; padding: 12px 14px; resize: vertical; }

.gv-funnel .form-row .description {
  margin: var(--space-2) 0 0;
  color: var(--ink-subtle);
  font-size: 11.5px;
}

.gv-funnel .woocommerce-invalid input,
.gv-funnel .woocommerce-invalid select,
.gv-funnel .form-row.gv-bad input { border-color: #b3261e; }

.gv-funnel .form-row.gv-ok input { border-color: var(--ink-success); }

.gv-funnel .gv-field-msg {
  margin: var(--space-2) 0 0;
  color: #b3261e;
  font-size: 11.5px;
  font-weight: 600;
}

.gv-funnel .gv-field-msg:empty { display: none; }
.gv-funnel .form-row.gv-field-hidden { display: none !important; }

/* select2, which Woo loads for the province picker. */
.gv-funnel .select2-container--default .select2-selection--single {
  display: flex;
  align-items: center;
}

.gv-funnel .select2-container--default .select2-selection--single .select2-selection__rendered {
  padding: 0;
  color: var(--ink);
  line-height: inherit;
}

.gv-funnel .select2-container--default .select2-selection--single .select2-selection__arrow {
  top: 50%;
  transform: translateY(-50%);
}

/* ---- The optional-field disclosure --------------------------------------- */

.gv-funnel .gv-field-optional__toggle {
  align-self: flex-start;
  min-height: var(--tap-min);
  padding: 0;
  border: 0;
  background: none;
  color: var(--brand-pink-deep);
  font-family: var(--font-sans);
  font-size: 12.5px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

/* ---- Notices ------------------------------------------------------------- */

.gv-funnel .woocommerce-message,
.gv-funnel .woocommerce-error,
.gv-funnel .woocommerce-info {
  margin: 0 0 var(--space-4);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface-card);
  font-size: 13px;
  list-style: none;
}

.gv-funnel .woocommerce-error {
  border-color: #f0c8c4;
  background: #fdf4f3;
  color: #7a1c15;
}

/* ---- Bits WooCommerce prints that the design has no place for ------------ */

.gv-funnel .woocommerce-form-coupon-toggle,
.gv-funnel form.checkout_coupon,
.gv-funnel #order_review_heading:not(.card__title) { display: none; }

/* The billing wrapper deliberately drops WooCommerce's own class so
   wc-address-i18n.js cannot re-parent the fields and flatten the step cards;
   see the note in checkout/form-billing.php. */
.gv-funnel .gv-billing-fields {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* ---- Place order: one button visible at a time --------------------------- */

/* The design submits from the pay bar on phones and from inside the payment
   card on desktop. Both exist in the form so either can submit; only one is
   ever on screen. Mirrors the mockup's .desktop-submit.
   Only on the checkout form: the pay-again page (form#order_review) has no pay
   bar, and hiding its button there left phones with no way to pay (BE-10, L50). */
.gv-funnel form.checkout #place_order { display: none; }

.gv-funnel #place_order,
.gv-funnel .paybar .btn--primary {
  width: 100%;
  min-height: var(--control-h-lg);
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--brand-pink);
  color: #fff;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-transform: none;
  cursor: pointer;
}

.gv-funnel #place_order:hover,
.gv-funnel .paybar .btn--primary:hover { background: var(--brand-pink-deep); }

.gv-funnel #order_review #place_order { display: block; margin-top: var(--space-4); }

@media (min-width: 900px) {
  .gv-funnel form.checkout #place_order { display: block; margin-top: var(--space-4); }
}

/* Terms and the privacy note sit under the gateways, before the button. */
.gv-funnel .woocommerce-terms-and-conditions-wrapper,
.gv-funnel .woocommerce-privacy-policy-text {
  margin-top: var(--space-4);
  color: var(--ink-subtle);
  font-size: 11.5px;
  line-height: 1.55;
}

/* ---- Trust list ---------------------------------------------------------- */

.gv-funnel .gv-checkout-trust {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin: var(--space-4) 0 0;
  padding: 0;
  list-style: none;
}

.gv-funnel .gv-checkout-trust li {
  position: relative;
  padding-left: 22px;
  color: var(--ink-muted);
  font-size: 12.5px;
  line-height: 1.5;
}

.gv-funnel .gv-checkout-trust li::before {
  content: "";
  position: absolute;
  top: 0.35em;
  left: 0;
  width: 10px;
  height: 5px;
  border-left: 2px solid var(--ink-success);
  border-bottom: 2px solid var(--ink-success);
  transform: rotate(-45deg);
}

/* ---- Cart lines ---------------------------------------------------------- */

/* .thumb in the design is a tinted placeholder holding a line icon. With a real
   product photo in it the tint and pink border read as a frame around the
   image, so when it contains an <img> it becomes the image. */
.gv-funnel .thumb:has(img) {
  background: var(--surface-sunken);
  border-color: var(--line);
  overflow: hidden;
  padding: 0;
}

.gv-funnel .thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.gv-funnel .cart-item__id {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

/* The product name is a link, but it is the line's title first. Underlined pink
   made every bag look like a page of links. */
.gv-funnel .cart-item__name,
.gv-funnel .cart-item__name a {
  color: var(--ink);
  font-size: 14.5px;
  font-weight: 700;
  line-height: 1.3;
  text-decoration: none;
}

.gv-funnel .cart-item__name a:hover { text-decoration: underline; }

.gv-funnel .cart-item__total { font-size: 16px; white-space: nowrap; }

/* WooCommerce's number input sits between the two stepper buttons. */
.gv-funnel .stepper .quantity { border: 0; background: none; }

.gv-funnel .stepper input.qty {
  width: 40px;
  min-width: 26px;
  height: var(--control-h);
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 15px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: center;
  -moz-appearance: textfield;
}

.gv-funnel .stepper input.qty::-webkit-outer-spin-button,
.gv-funnel .stepper input.qty::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.gv-funnel .stepper.is-busy { opacity: 0.55; }

/* ---- Page shell ---------------------------------------------------------- */

/* page.php wraps these in .gv-page__inner with a prose measure; the funnel
   brings its own .wrap and its own rhythm. */
.gv-funnel .gv-page__inner,
.gv-funnel .gv-page__body,
.gv-funnel .woocommerce {
  max-width: none;
  margin: 0;
  padding: 0;
}

.gv-funnel .site-main {
  max-width: 1280px;
  margin-inline: auto;
  padding: var(--space-5) var(--gutter) 160px;
}

@media (min-width: 900px) {
  .gv-funnel .site-main { padding-block: var(--space-6) var(--space-8); }
}

.gv-funnel .gv-cart { display: flex; flex-direction: column; gap: var(--space-5); }
.gv-funnel .gv-cart__items { gap: var(--space-4); }

/* ---------------------------------------------------------- confirmation --- */

/* The mockup's confirmation page is a centred column of cards at a narrower
   measure than the two-column checkout. Mockups/confirmation.html carries this
   as inline style on a wrapper div; it lives here instead so the template stays
   markup. */
.gv-funnel .gv-confirm {
  max-width: 1000px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.gv-funnel .gv-confirm__number {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.gv-funnel .gv-confirm__no {
  font-size: 17px;
  font-weight: 700;
  letter-spacing: 0.3px;
}

.gv-funnel .gv-confirm__number .btn.is-copied {
  color: var(--ink-success);
  border-color: var(--ink-success);
}

/* WhatsApp's own green, and only here. It is a third-party brand mark, so it
   does not take a Glowvé token — those are ours to change and this one is not. */
.gv-funnel .gv-confirm__wa svg { color: #25D366; }

.gv-funnel .gv-confirm__line + .gv-confirm__line { margin-top: var(--space-4); }

.gv-funnel .gv-confirm__line .thumb {
  width: 48px;
  height: 48px;
  flex: 0 0 48px;
}

.gv-funnel .gv-confirm__line img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.gv-funnel .gv-confirm__totals {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
}

.gv-funnel .gv-confirm__paid {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--line);
}

.gv-funnel .gv-confirm__foot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  text-align: center;
  padding-top: var(--space-2);
}

/* Matches the mockup, including its tap-target floor — at 23px tall this was
   under the WCAG 2.2 AA target size and a thin thing to hit on a phone. */
.gv-funnel .gv-confirm__more {
  min-height: var(--tap-min);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 13.5px;
  font-weight: 700;
  text-decoration: none;
}

/* ---- The desktop submit, which the mockup accidentally disables ----------- */

/* Mockups/glowve.css sets `.desktop-submit { display: none }` *after* the
   @media (min-width: 900px) block that sets it to flex. Equal specificity, so
   the later rule wins at every width and .desktop-submit never appears — while
   the same media query hides .paybar. On the cart that combination leaves a
   desktop visitor with no way to reach checkout at all.

   Re-stated here in the intended order rather than corrected in Mockups/: that
   file is the supplied design source and the porter copies it verbatim. */
.gv-funnel .desktop-submit { display: none; }

@media (min-width: 900px) {
  .gv-funnel .desktop-submit {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
  }
}

/* ---- Cart measure -------------------------------------------------------- */

/* Mockups/cart.html centres the bag in a 720px column inside the 1280px wrap,
   and matches the pay bar to it. Carried as inline style there; it belongs in
   CSS here. Without it the cart sits hard against the left of a wide screen. */
.gv-funnel .gv-cart {
  max-width: 720px;
  margin-inline: auto;
}

/* .gv-cart is a flex column, so the heading's bottom margin does not collapse
   into the container's gap — it adds to it, which is how 24px became 49px.
   Let the gap own the spacing and the heading contribute nothing. */
.gv-funnel .gv-cart {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.gv-funnel .gv-cart > .display { margin-bottom: 0; }

.woocommerce-cart.gv-funnel .paybar__inner { max-width: 720px; }

/* The confirmation page sets its own foot padding — there is no pay bar under
   it to clear, so the 160px the other two reserve would be a dead screenful. */
.woocommerce-order-received.gv-funnel .page { padding-bottom: var(--space-8); }

/* ---- Payment option badge ------------------------------------------------ */

/* .option__body is a column flex container, so a badge stretches the full card
   width and reads as a green bar rather than a pill. Mockups/checkout.html
   carries `style="align-self: flex-start"` on this badge for the same reason. */
.gv-funnel .option__body > .badge { align-self: flex-start; }

/* ---- Delivery card ------------------------------------------------------- */

/* .delivery is a flex row from the design; the body has to be the column that
   separates the method from the arrival window, or they run together as
   "Standard deliveryArrives Mon 21". */
.gv-funnel .gv-delivery__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.gv-funnel .gv-delivery__name,
.gv-funnel .gv-delivery__cost {
  font-size: 14px;
  font-weight: 700;
}

/* ---- Floating chat widget ------------------------------------------------ */

/* The site-wide WhatsApp bubble sits over the confirmation page's address card
   and over the pay bar on cart and checkout. The funnel already offers WhatsApp
   in the header and, on the confirmation page, as a full-width button — so the
   bubble adds nothing here and costs a covered control. */
.gv-funnel .whatsapp-sticky-button { display: none; }

/* ---- Gateway instructions ------------------------------------------------ */

.gv-funnel .gv-confirm__note p { margin: 0; }
.gv-funnel .gv-confirm__note p + p { margin-top: var(--space-2); }

/* ---- Cart spacing and notice measure ------------------------------------- */

/* A leftover 24px top margin on the items list collapsed through the form and
   doubled the gap under "Your bag" to 48px. The design's spacing comes from the
   heading's own margin. */
.gv-funnel .gv-cart__items { margin-top: 0; }

/* Notices are printed outside .gv-cart, so on a wide screen they ran the full
   1280px while the bag sat in its 720px column — two different left edges on
   one page. */
.woocommerce-cart.gv-funnel .woocommerce-message,
.woocommerce-cart.gv-funnel .woocommerce-info,
.woocommerce-cart.gv-funnel .woocommerce-error {
  max-width: 720px;
  margin-inline: auto;
}

/* ---- Free-delivery strip ------------------------------------------------- */

/* The only control in the strip, and at 20px tall it was under the WCAG 2.2 AA
   target-size floor of 24px. Grown vertically only, so the strip's height and
   the progress bar beneath it are unchanged. */
.gv-funnel .progress__more {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
}

/* ---- Standalone link tap targets ----------------------------------------- */

/* Links that stand on their own line rather than sitting inside a sentence are
   targets in their own right, so WCAG 2.2 AA's 24px floor applies to them.
   Height only — the text keeps its own width. */
.gv-funnel .gv-peek__edit a,
.gv-funnel .gv-review-edit a,
.gv-funnel .gv-checkout-trust a {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
}

/* ---- Empty bag ----------------------------------------------------------- */

/* The design defaults .empty-state to display:none because the mockup toggles
   it with JavaScript. Here the template only renders it when the cart is
   actually empty, so it has to be visible when present. */
.gv-funnel .empty-state { display: flex; }

/* The bestseller row under it is storefront merchandising, not funnel
   furniture — give it back the page's full measure. */
.woocommerce-cart.gv-funnel .gv-cart-suggest { max-width: none; }

/* ---- Invalid fields ------------------------------------------------------ */

/* The design marks a bad field with a red border and a red message
   (.field.is-invalid / .field__error). WooCommerce uses .woocommerce-invalid on
   the row and prints its own <p class="checkout-inline-error-message">, so the
   error was rendering in body colour against a normal border — a field that had
   failed validation looked exactly like one that had not. #b3261e is the
   design's error colour. */
.gv-funnel .form-row.woocommerce-invalid input.input-text,
.gv-funnel .form-row.woocommerce-invalid textarea,
.gv-funnel .form-row.woocommerce-invalid select,
.gv-funnel .form-row.woocommerce-invalid .select2-selection {
  border-color: #b3261e;
}

.gv-funnel .checkout-inline-error-message,
.gv-funnel .form-row.gv-bad .gv-field-msg {
  margin-top: var(--space-2);
  font-size: 11.5px;
  font-weight: 600;
  color: #b3261e;
}

/* ---- Header logo --------------------------------------------------------- */

/* The real logo, at the storefront header's own sizes (sections/header.css:
   80px wide on a phone, 107px from 900px), so it does not jump in size between
   the shop and the bag. .wordmark still does the layout — centred between the
   two header sides on a phone, left-aligned on the confirmation page's desktop
   header — line-height 0 stops the text box adding space under the image. */
.gv-funnel .gv-funnel-logo { line-height: 0; }

.gv-funnel .gv-funnel-logo img {
  display: inline-block;
  width: 80px;
  height: auto;
}

@media (min-width: 900px) {
  .gv-funnel .gv-funnel-logo img { width: 107px; }
}

/* ---- Free-delivery strip, as the mockup draws it -------------------------- */

/* Mockups/checkout.html puts the progress bar on a white band with a hairline
   under it and 12px/14px of padding. Unstyled, ours sat on the page colour
   with no edge, pressed against the header border. */
/* Only when there is a bar to show: an empty cart has none, and a bare band
   would draw a second hairline under the header's own. */
.gv-funnel .gv-funnel-strip:has(.progress) {
  background: var(--surface-card);
  border-bottom: 1px solid var(--line);
}

.gv-funnel .gv-funnel-strip > .wrap:has(.progress) { padding-block: 12px 14px; }

.gv-funnel .progress__more {
  font-size: 12px;
  font-weight: 600;
  text-decoration: none;
}

/* ---- Payment list -------------------------------------------------------- */

/* WooCommerce prints ul.payment_methods > li around each .option card. The
   design's equivalent is .options, a column with one gap; the <li> is only a
   wrapper and must draw nothing, or it becomes a second card around the first. */
.gv-funnel #payment ul.payment_methods {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin: 0 0 var(--space-4);
  padding: 0;
  list-style: none;
  border: 0;
}

.gv-funnel #payment ul.payment_methods > li {
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  list-style: none;
}

/* Payment brands, one row under the note at one height. */
.gv-funnel .gv-pay-marks {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.gv-funnel .gv-pay-marks img {
  display: block;
  width: 34px;
  height: 20px;
  border-radius: 3px;
}

/* ---- Bag peek ------------------------------------------------------------ */

/* The phone-only "Your items" disclosure is drawn by the old checkout's .gv-peek
   component: the storefront's grey-blue surface and a 24px bottom margin that
   added to the stack's own gap, so it sat 40px above the Contact card while
   every other card is 16px apart. Re-drawn as the design's card; the stack owns
   the spacing. */
.gv-funnel .gv-peek {
  margin: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface-card);
}

.gv-funnel .gv-peek__bar {
  min-height: var(--tap-min);
  padding: var(--space-3) var(--space-4);
  font-size: 14.5px;
  font-weight: 700;
}

/* ---- Email gate on order-received ---------------------------------------- */

/* A narrow centred column for the "confirm it's you" screen only. Scoped with
   :has() to the page that actually contains the gate — the same .woocommerce
   wrapper holds the full confirmation, and a measure written for one screen
   must not reach the other (docs/LEARNINGS.md L24). */
.gv-funnel .woocommerce:has(> .gv-verify) {
  max-width: 560px;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.gv-funnel .gv-verify__error {
  font-size: 12.5px;
  font-weight: 600;
  color: #b3261e;
}

/* ---- parts/accordion.css ---- */
/* Accordion (part 21): native details; the caret turns, not under reduced motion.
   card: each item a white box, the title in the display face with an icon disc.
   list: hairline rows, the title in bold body type (questions; inside a card). */
.gv-accordion__summary {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--control-h);
  list-style: none;
  cursor: pointer;
}
.gv-accordion__summary::-webkit-details-marker { display: none; }
.gv-accordion__title { flex: 1; min-width: 0; }
.gv-accordion__summary:hover .gv-accordion__title { text-decoration: underline; text-underline-offset: 3px; }
.gv-accordion__caret { display: flex; flex: none; color: var(--ink-muted); transform: rotate(90deg); transition: transform var(--duration-fast) var(--ease); }
.gv-accordion__item[open] > .gv-accordion__summary .gv-accordion__caret { transform: rotate(-90deg); }
.gv-accordion__body { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; color: var(--ink-muted); line-height: var(--leading-text); }
.gv-accordion__body > p { max-width: var(--measure); }
.gv-accordion__body > * { margin: 0; }
.gv-accordion__body ul:not([class]) { padding-inline-start: var(--space-5); } /* content's own lists; a part's list (the carousel's track) keeps its own */

/* Card */
.gv-accordion--card { display: flex; flex-direction: column; gap: var(--space-3); }
.gv-accordion--card > .gv-accordion__item { border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--surface-card); }
.gv-accordion--card > .gv-accordion__item > .gv-accordion__summary {
  min-height: var(--control-h-lg);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-lg);
  color: var(--ink);
  font-family: var(--font-display);
  font-size: var(--display-sm);
  font-weight: var(--weight-display);
  letter-spacing: var(--tracking-display);
  line-height: var(--leading-display);
}
.gv-accordion--card > .gv-accordion__item[open] > .gv-accordion__summary { border-end-start-radius: 0; border-end-end-radius: 0; border-bottom: 1px solid var(--line-hair); }
.gv-accordion--card > .gv-accordion__item > .gv-accordion__body { padding: var(--space-4); }
@media (min-width: 900px) {
  .gv-accordion--card > .gv-accordion__item > .gv-accordion__summary { padding-inline: var(--space-5); }
  .gv-accordion--card > .gv-accordion__item > .gv-accordion__body { padding: var(--space-5); }
}

/* List */
.gv-accordion--list { border-top: 1px solid var(--line-hair); }
.gv-accordion--list > .gv-accordion__item { border-bottom: 1px solid var(--line-hair); }
.gv-accordion--list > .gv-accordion__item > .gv-accordion__summary { padding-block: var(--space-3); color: var(--ink); font-size: var(--text-body); font-weight: 600; line-height: var(--leading-text); }
.gv-accordion--list > .gv-accordion__item > .gv-accordion__body { padding-bottom: var(--space-4); }
.gv-accordion__body > .gv-accordion--list:first-child { border-top: 0; } /* the card's own line is above it */
.gv-accordion__body > .gv-accordion--list:first-child > .gv-accordion__item:first-child > .gv-accordion__summary { padding-block-start: 0; }
.gv-accordion__body > .gv-accordion--list:last-child > .gv-accordion__item:last-child { border-bottom: 0; }

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

/* ---- parts/action-bar.css ---- */
/* Action bar (Phase 4): price and Add to bag at the bottom of phones and
   tablets once the buy row has scrolled away. */
.gv-action-bar { position: fixed; inset-inline: 0; inset-block-end: 0; z-index: 850; padding-block: var(--space-3) max(var(--space-3), env(safe-area-inset-bottom)); background: var(--surface-card); box-shadow: var(--shadow-bar); }
.gv-action-bar--inline { position: relative; inset: auto; z-index: auto; border: 1px solid var(--line); border-radius: var(--radius-lg); }
.gv-action-bar__inner { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.gv-action-bar__info { display: flex; flex-direction: column; min-width: 0; }
.gv-action-bar__info .gv-price { flex-wrap: nowrap; }
.gv-action-bar__size { color: var(--ink-subtle); font-size: var(--text-caption); }
.gv-action-bar .gv-button { flex: none; }
@media (prefers-reduced-motion: no-preference) {
  .gv-action-bar:not([hidden]) { animation: gv-fade-in var(--duration) var(--ease); }
}
@keyframes gv-fade-in { from { opacity: 0; } to { opacity: 1; } }
@media (min-width: 900px) {
  .gv-action-bar:not(.gv-action-bar--inline) { display: none; }
}

/* ---- parts/badge.css ---- */
/* Badge (part 3). The tone is also in the words. */
.gv-badge {
  display: inline-flex;
  align-items: center;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-pill);
  font-family: var(--font-sans);
  font-size: var(--text-caption);
  font-weight: 600;
  line-height: 1.4;
  white-space: nowrap;
}
.gv-badge--saving    { background: var(--surface-success); color: var(--ink-success); }
.gv-badge--sale-ends { background: var(--surface-sun); color: var(--ink-sun); }
.gv-badge--sold-out,
.gv-badge--neutral   { background: var(--surface-sunken); color: var(--ink-muted); }
.gv-badge--new       { background: var(--surface-tint); color: var(--brand-pink-deep); }

/* ---- parts/bag-drawer.css ---- */
/* Bag drawer (part 17): from the right on every width; the list scrolls, the
   total and the button to checkout stay pinned. Open/close, focus and scroll
   lock: assets/js/cart-drawer.js (.is-open, [hidden]). */
.gv-bag-drawer { position: fixed; inset: 0; z-index: 1000; }
.gv-bag-drawer__scrim { position: absolute; inset: 0; background: var(--surface-scrim); opacity: 0; transition: opacity var(--duration) var(--ease); }
.gv-bag-drawer__panel {
  position: absolute;
  inset-block: 0;
  inset-inline-end: 0;
  display: flex;
  flex-direction: column;
  width: min(420px, 100%);
  background: var(--surface-card);
  box-shadow: var(--shadow-overlay);
  transform: translateX(100%);
  transition: transform var(--duration) var(--ease);
}
.gv-bag-drawer.is-open .gv-bag-drawer__scrim { opacity: 1; }
.gv-bag-drawer.is-open .gv-bag-drawer__panel { transform: none; }

/* The parts sheet shows it open, in the page. */
.gv-bag-drawer--inline { position: relative; inset: auto; z-index: auto; height: 640px; }
.gv-bag-drawer--inline .gv-bag-drawer__panel { position: relative; width: 100%; max-width: 420px; height: 100%; overflow: hidden; border: 1px solid var(--line); border-radius: var(--radius-lg); }

.gv-bag-drawer__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-2) var(--space-2) var(--space-2) var(--space-5); border-bottom: 1px solid var(--line-hair); }
.gv-bag-drawer__title { font-family: var(--font-display); font-size: var(--display-md); font-weight: var(--weight-display); letter-spacing: var(--tracking-display); line-height: var(--leading-display); }

.gv-bag-drawer__contents { display: flex; flex: 1; flex-direction: column; min-height: 0; }
.gv-bag-drawer__scroll { display: flex; flex: 1; flex-direction: column; gap: var(--space-4); min-height: 0; padding: var(--space-4) var(--space-5); overflow-y: auto; overscroll-behavior: contain; }
.gv-bag-drawer__lines { margin: 0; padding: 0; list-style: none; }
.gv-bag-drawer__contents.is-updating .gv-bag-drawer__lines { opacity: 0.6; }

.gv-bag-drawer__foot { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-4) var(--space-5) var(--space-5); border-top: 1px solid var(--line-hair); background: var(--surface-card); box-shadow: var(--shadow-bar); }
.gv-bag-drawer__totals { display: flex; flex-direction: column; gap: var(--space-2); margin: 0; }
.gv-bag-drawer__row { display: flex; justify-content: space-between; gap: var(--space-3); color: var(--ink-muted); font-size: var(--text-ui); }
.gv-bag-drawer__row dd { margin: 0; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
.gv-bag-drawer__row--saving, .gv-bag-drawer__row--saving dd { color: var(--ink-success); }
.gv-bag-drawer__row--total { padding-top: var(--space-2); border-top: 1px solid var(--line-hair); color: var(--ink); font-size: var(--text-body); font-weight: 600; }
.gv-bag-drawer__view { display: inline-flex; align-items: center; align-self: center; min-height: var(--tap-min); color: var(--brand-pink-deep); font-size: var(--text-ui); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }
.gv-bag-drawer__view:hover { color: var(--ink); }

@media (prefers-reduced-motion: reduce) {
  .gv-bag-drawer__scrim, .gv-bag-drawer__panel { transition: none; }
}

/* ---- parts/button.css ---- */
/* Button (design.md §5 part 1). One button: primary, secondary, quiet, link. */
.gv-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--control-h);
  padding: var(--space-3) var(--space-5);
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font-family: var(--font-display);
  font-size: var(--text-body);
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease), color var(--duration-fast) var(--ease), border-color var(--duration-fast) var(--ease);
}
.gv-button--lg { min-height: var(--control-h-lg); }
.gv-button--block { display: flex; width: 100%; }

.gv-button--primary { background: var(--brand-pink); color: var(--ink-on-brand); }
.gv-button--primary:hover, .gv-button--primary.is-hover { background: var(--brand-pink-deep); }
.gv-button--primary:active, .gv-button--primary.is-pressed { background: var(--brand-pink-deep); box-shadow: var(--shadow-pressed); }

.gv-button--secondary { background: var(--surface-card); color: var(--ink); border-color: var(--ink); }
.gv-button--secondary:hover, .gv-button--secondary.is-hover { background: var(--ink); color: var(--surface-card); }

.gv-button--quiet { background: var(--surface-card); color: var(--ink); border-color: var(--line-control); font-family: var(--font-sans); font-size: var(--text-ui); font-weight: 600; letter-spacing: 0; }
.gv-button--quiet:hover, .gv-button--quiet.is-hover { background: var(--surface-sunken); }

.gv-button--link { min-height: var(--tap-min); padding-inline: 0; background: none; color: var(--brand-pink-deep); font-family: var(--font-sans); font-size: var(--text-ui); font-weight: 600; letter-spacing: 0; text-decoration: underline; text-underline-offset: 3px; }
.gv-button--link:hover, .gv-button--link.is-hover { color: var(--ink); }

.gv-button:focus-visible, .gv-button.is-focus { outline: 2px solid var(--focus-ring); outline-offset: 2px; }

.gv-button:disabled { background: var(--surface-sunken); color: var(--ink-disabled); border-color: var(--line); cursor: not-allowed; }
.gv-button.is-done { background: var(--surface-success); color: var(--ink-success); border-color: transparent; }
.gv-button.is-working { cursor: progress; }

.gv-button__spinner { flex: none; animation: gv-spin 0.8s linear infinite; } /* Lucide's loader-circle, turning */
@keyframes gv-spin { to { transform: rotate(360deg); } }

.gv-button__reason { margin: var(--space-1) 0 0; color: var(--ink-subtle); font-size: var(--text-caption); }
/* Live buttons (add to bag) carry both marks, shown by state. */
.gv-button[data-gv-live] .gv-button__spinner, .gv-button[data-gv-live] .gv-button__done { display: none; }
.gv-button[data-gv-live].is-working .gv-button__spinner { display: inline; }
.gv-button[data-gv-live].is-done .gv-button__done { display: inline; }

/* ---- parts/carousel.css ---- */
/* Carousel (part 24): the one engine. Native horizontal scroll with snap;
   arrows, thumbnails, keys and autoplay in parts.js. */
.gv-carousel { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; }
.gv-carousel__viewport { overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory; scrollbar-width: none; }
.gv-carousel__viewport::-webkit-scrollbar { display: none; }
.gv-carousel__viewport:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.gv-carousel__track { position: relative; display: flex; gap: var(--space-4); margin: 0; padding: 0; list-style: none; }
.gv-carousel__slide { flex: 0 0 100%; min-width: 0; scroll-snap-align: start; }
.gv-carousel__stage { position: relative; min-width: 0; }
.gv-carousel__controls { display: flex; align-items: center; justify-content: flex-end; gap: var(--space-1); }

/* Row: cards with the next one peeking, so it reads as "there's more". */
.gv-carousel--row .gv-carousel__slide { flex-basis: calc((100% - var(--space-4)) / 1.6); }
@media (min-width: 640px) {
  .gv-carousel--row .gv-carousel__slide { flex-basis: calc((100% - var(--space-4) * 2) / 2.5); }
}
@media (min-width: 900px) {
  .gv-carousel--row .gv-carousel__slide { flex-basis: calc((100% - var(--space-4) * 3) / 3.4); }
}
@media (min-width: 1200px) {
  .gv-carousel--row .gv-carousel__slide { flex-basis: calc((100% - var(--space-4) * 4) / 4.4); }
}

/* Gallery: one photo at a time, thumbnails under it. */
.gv-carousel--gallery .gv-carousel__slide { aspect-ratio: 1; overflow: hidden; border-radius: var(--radius-lg); background: var(--surface-sunken); }
.gv-carousel__img { display: block; width: 100%; height: 100%; object-fit: cover; }
.gv-carousel__no-photo { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-2); width: 100%; height: 100%; color: var(--ink-subtle); font-size: var(--text-ui); }
/* Two classes: icon-button.css loads later and sets its own position. */
.gv-carousel__stage > .gv-carousel__edge { position: absolute; inset-block-start: 50%; background: var(--surface-card); box-shadow: var(--shadow-overlay); transform: translateY(-50%); }
.gv-carousel__stage > .gv-carousel__edge--prev { inset-inline-start: var(--space-2); }
.gv-carousel__stage > .gv-carousel__edge--next { inset-inline-end: var(--space-2); }
.gv-carousel__stage > .gv-carousel__edge:hover { background: var(--surface-sunken); }
.gv-carousel__stage > .gv-carousel__edge:disabled { opacity: 0; pointer-events: none; }
.gv-carousel__thumbs { position: relative; display: flex; gap: var(--space-2); overflow-x: auto; scrollbar-width: none; }
.gv-carousel__thumbs::-webkit-scrollbar { display: none; }
.gv-carousel__thumb { display: grid; flex: none; place-items: center; width: var(--space-9); height: var(--space-9); padding: 0; overflow: hidden; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--surface-sunken); color: var(--ink-subtle); cursor: pointer; }
.gv-carousel__thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
.gv-carousel__thumb[aria-current="true"] { border-color: var(--brand-pink); box-shadow: inset 0 0 0 1px var(--brand-pink); }
.gv-carousel__thumb:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: -2px; } /* inside: the strip scrolls, so it would clip a ring outside */

/* From 900 the thumbnails stand in a column beside the photo, so the photo can
   be as tall as the screen allows (Ali, 2026-09-27: "completely visible on
   desktop without scroll"). The strip is as tall as the photo and scrolls. */
@media (min-width: 900px) {
  .gv-carousel--thumbs { display: grid; grid-template-columns: var(--space-9) minmax(0, 1fr); gap: var(--space-3); }
  .gv-carousel--thumbs .gv-carousel__stage { grid-area: 1 / 2; }
  .gv-carousel--thumbs .gv-carousel__thumbs { grid-area: 1 / 1; flex-direction: column; height: 0; min-height: 100%; overflow: hidden auto; }
}

/* Banner: one line of text between its controls (the announcement bar). */
.gv-carousel--banner { flex-direction: row; align-items: center; gap: var(--space-2); }
.gv-carousel--banner .gv-carousel__stage { flex: 1; order: 2; }
.gv-carousel--banner .gv-carousel__slide { display: flex; align-items: center; justify-content: center; text-align: center; }
.gv-carousel--banner .gv-carousel__controls { display: contents; }
.gv-carousel--banner [data-gv-carousel-prev] { order: 1; }
.gv-carousel--banner [data-gv-carousel-next] { order: 3; }
.gv-carousel--banner .gv-carousel__toggle { order: 4; }

@media (prefers-reduced-motion: no-preference) {
  .gv-carousel__viewport { scroll-behavior: smooth; }
}

/* ---- parts/chip.css ---- */
/* Chip (part 4). Selected: tint, a full pink border and a tick - never colour alone. */
.gv-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-height: var(--tap-min);
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--line-control);
  border-radius: var(--radius-pill);
  background: var(--surface-card);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--text-ui);
  line-height: var(--leading-text);
  text-align: start;
  cursor: pointer;
}
.gv-chip:hover, .gv-chip.is-hover { background: var(--surface-sunken); }
.gv-chip.is-selected { border-color: var(--brand-pink); background: var(--surface-tint); color: var(--brand-pink-deep); font-weight: 600; box-shadow: inset 0 0 0 1px var(--brand-pink); }
.gv-chip:focus-visible, .gv-chip.is-focus { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.gv-chip:disabled { color: var(--ink-disabled); border-color: var(--line); cursor: not-allowed; }

/* ---- parts/choice.css ---- */
/* Choice (part 9): a radio or checkbox card. Chosen = the input's own tick
   plus a full pink border and the tint - never a bar down one side. */
.gv-choice {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--line-control);
  border-radius: var(--radius-lg);
  background: var(--surface-card);
  color: var(--ink);
  cursor: pointer;
}
.gv-choice:hover, .gv-choice.is-hover { background: var(--surface-sunken); }
.gv-choice:has(.gv-choice__input:checked) { border-color: var(--brand-pink); background: var(--surface-tint); box-shadow: inset 0 0 0 1px var(--brand-pink); }
.gv-choice:has(.gv-choice__input:focus-visible), .gv-choice.is-focus { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.gv-choice__input { flex: none; width: 20px; height: 20px; margin: var(--space-1) 0 0; accent-color: var(--brand-pink); cursor: inherit; }
.gv-choice__input:focus-visible { outline: none; }

.gv-choice__body { display: flex; flex: 1; flex-direction: column; gap: var(--space-1); min-width: 0; }
.gv-choice__row { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--space-1) var(--space-3); }
.gv-choice__title { font-size: var(--text-body); font-weight: 600; }
.gv-choice__aside { font-size: var(--text-body); font-weight: 600; white-space: nowrap; }
.gv-choice__note { color: var(--ink-muted); font-size: var(--text-ui); line-height: var(--leading-text); }
.gv-choice__meta { display: flex; align-items: center; gap: var(--space-1); color: var(--ink-subtle); font-size: var(--text-caption); }
.gv-choice__meta .gv-icon { flex: none; }

.gv-choice:has(.gv-choice__input:disabled) { border-color: var(--line); background: var(--surface-sunken); cursor: not-allowed; }
.gv-choice:has(.gv-choice__input:disabled) .gv-choice__title,
.gv-choice:has(.gv-choice__input:disabled) .gv-choice__aside { color: var(--ink-disabled); }

/* ---- parts/compare.css ---- */
/* Compare: before and after in one circle, split at --gv-compare-x (0-100,
   set by parts.js). The split is a box from the left edge to the line, so the
   line and the handle sit on its right edge. The handle's box is outside the
   circle, so it is never clipped at the ends. */
.gv-compare { --gv-compare-x: 50; position: relative; width: 100%; aspect-ratio: 1; user-select: none; } /* the page still scrolls and pinch-zooms over the photos; only the handle takes a finger */
.gv-compare.is-ready { cursor: col-resize; }
.gv-compare__frame { position: absolute; inset: 0; overflow: hidden; border-radius: 50%; background: var(--surface-sunken); isolation: isolate; }
.gv-compare__photo { position: absolute; inset: 0; }
.gv-compare__photo--before { z-index: 1; clip-path: inset(0 calc((100 - var(--gv-compare-x)) * 1%) 0 0); }
.gv-compare__img { display: block; width: 100%; height: 100%; object-fit: cover; }
.gv-compare__tag { position: absolute; bottom: var(--space-8); padding: var(--space-1) var(--space-2); border-radius: var(--radius-pill); background: var(--ink); color: var(--ink-on-dark); font-size: var(--text-caption); font-weight: 600; letter-spacing: var(--tracking-eyebrow); line-height: var(--leading-text); text-transform: uppercase; pointer-events: none; transition: opacity var(--duration-fast) var(--ease); }
.gv-compare__tag--before { left: var(--space-7); }
.gv-compare__tag--after { right: var(--space-7); }
.gv-compare.is-before-thin .gv-compare__tag--before,
.gv-compare.is-after-thin .gv-compare__tag--after { opacity: 0; }

.gv-compare__split { position: absolute; z-index: 2; inset: 0 auto 0 0; width: calc(var(--gv-compare-x) * 1%); pointer-events: none; }
.gv-compare__split[hidden] { display: none; }
.gv-compare__line { position: absolute; inset-block: 0; right: 0; width: 2px; transform: translateX(50%); background: var(--surface-card); box-shadow: var(--shadow-overlay); }
.gv-compare__handle { position: absolute; top: 50%; right: 0; display: grid; place-items: center; width: var(--tap-min); height: var(--tap-min); border-radius: 50%; background: var(--brand-pink); color: var(--ink-on-brand); box-shadow: 0 0 0 3px var(--surface-card), var(--shadow-overlay); transform: translate(50%, -50%); pointer-events: auto; touch-action: none; }

/* The slider: over the circle for screen readers and the keyboard, never in
   the pointer's way (the page handles pointers). Its focus shows on the handle. */
.gv-compare__range { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; pointer-events: none; }
.gv-compare__range:focus-visible ~ .gv-compare__split .gv-compare__handle { outline: 2px solid var(--focus-ring); outline-offset: 2px; }

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

/* ---- parts/count.css ---- */
/* Bag count bubble (part 5). */
.gv-count {
  display: inline-grid;
  place-items: center;
  min-width: 18px;
  height: 18px;
  padding-inline: var(--space-1);
  border-radius: var(--radius-pill);
  background: var(--brand-pink);
  color: var(--ink-on-brand);
  font-family: var(--font-sans);
  font-size: var(--text-caption);
  font-weight: 600;
  line-height: 1;
}
.gv-count[hidden] { display: none; }

/* ---- parts/empty.css ---- */
/* Empty state (part 13): what is empty, one line that helps, one next step. */
.gv-empty { display: flex; flex-direction: column; align-items: center; gap: var(--space-3); padding: var(--space-6) var(--space-4); text-align: center; }
.gv-empty__icon { display: grid; place-items: center; width: var(--space-9); height: var(--space-9); margin-bottom: var(--space-1); border-radius: 50%; background: var(--surface-sunken); color: var(--ink-muted); }
.gv-empty__heading { font-family: var(--font-display); font-size: var(--display-md); font-weight: var(--weight-display); letter-spacing: var(--tracking-display); line-height: var(--leading-display); overflow-wrap: anywhere; }
.gv-empty__body { max-width: var(--measure); margin: 0; color: var(--ink-muted); }
.gv-empty .gv-button { margin-top: var(--space-2); }

/* ---- parts/feature-list.css ---- */
/* Feature list: short points, each an icon disc, a bold title and a line of
   text. start = the icon beside the words; center = the icon above, centred;
   wide-center = beside on phones and tablets, centred from 900 px. */
.gv-features { display: flex; flex-direction: column; gap: var(--space-4); margin: 0; padding: 0; list-style: none; }
.gv-features__item { display: flex; align-items: flex-start; gap: var(--space-3); }
.gv-features__words { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.gv-features__title { color: var(--ink); font-size: var(--text-body); font-weight: 600; line-height: var(--leading-text); }
.gv-features__text { margin: 0; color: var(--ink-muted); font-size: var(--text-ui); line-height: var(--leading-text); }

.gv-features--center .gv-features__item { flex-direction: column; align-items: center; text-align: center; }
@media (min-width: 900px) {
  .gv-features--wide-center { gap: var(--space-6); }
  .gv-features--wide-center .gv-features__item { flex-direction: column; align-items: center; text-align: center; }
}

/* ---- parts/field.css ---- */
/* Field (part 8). Label always visible; the control carries the focus ring;
   an error is words + icon + red border (design.md §3: red stops you). Input
   text is 16 px so phone browsers don't zoom into it. */
.gv-field { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.gv-field__label { font-size: var(--text-ui); font-weight: 600; color: var(--ink); }
.gv-field__optional { font-weight: 400; color: var(--ink-subtle); }

.gv-field__control {
  position: relative;
  display: flex;
  align-items: stretch;
  min-height: var(--control-h);
  border: 1px solid var(--line-control);
  border-radius: var(--radius-md);
  background: var(--surface-card);
  overflow: hidden;
}
.gv-field__control:focus-within, .gv-field.is-focus .gv-field__control { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.gv-field__control:hover, .gv-field.is-hover .gv-field__control { border-color: var(--ink-muted); }

.gv-field__input {
  flex: 1;
  min-width: 0;
  margin: 0;
  padding: 0 var(--space-4);
  border: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--text-body);
  line-height: var(--leading-text);
  appearance: none;
}
.gv-field__input:focus-visible { outline: none; }
.gv-field__input::placeholder { color: var(--ink-subtle); opacity: 1; }
.gv-field__control--textarea .gv-field__input { min-height: 96px; padding-block: var(--space-3); resize: vertical; }

.gv-field__prefix {
  display: flex;
  align-items: center;
  padding: 0 var(--space-3);
  border-inline-end: 1px solid var(--line-control);
  background: var(--surface-sunken);
  color: var(--ink-muted);
  font-size: var(--text-body);
  font-weight: 600;
}
.gv-field__icon { display: flex; align-items: center; padding-inline-start: var(--space-3); color: var(--ink-subtle); }
.gv-field__icon + .gv-field__input { padding-inline-start: var(--space-2); }

/* Select: the native list, Lucide's chevron-down over it. */
.gv-field__control--select .gv-field__input { padding-inline-end: var(--space-7); cursor: pointer; }
.gv-field__chevron { position: absolute; inset-block: 0; inset-inline-end: var(--space-3); display: flex; align-items: center; color: var(--ink-muted); pointer-events: none; }

.gv-field__hint { margin: 0; color: var(--ink-subtle); font-size: var(--text-caption); line-height: var(--leading-text); }
.gv-field__error { display: flex; align-items: flex-start; gap: var(--space-1); margin: 0; color: var(--ink-danger); font-size: var(--text-ui); font-weight: 600; line-height: var(--leading-text); }
.gv-field__error .gv-icon { flex: none; margin-top: var(--space-1); }

.gv-field.is-invalid .gv-field__control { border-color: var(--ink-danger); box-shadow: inset 0 0 0 1px var(--ink-danger); }

.gv-field.is-readonly .gv-field__control { border-color: var(--line); background: var(--surface-sunken); }
.gv-field.is-readonly .gv-field__input { color: var(--ink-muted); }
.gv-field.is-off .gv-field__control { border-color: var(--line); background: var(--surface-sunken); }
.gv-field.is-off .gv-field__input, .gv-field.is-off .gv-field__label { color: var(--ink-disabled); cursor: not-allowed; }

/* ---- parts/icon-button.css ---- */
/* Icon button (part 2): 44 × 44 always, a name always. */
.gv-icon-button {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: var(--tap-min);
  height: var(--tap-min);
  padding: 0;
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease);
}
.gv-icon-button:hover, .gv-icon-button.is-hover { background: var(--surface-sunken); }
.gv-icon-button--on-ink { color: var(--ink-on-dark); }
.gv-icon-button--on-ink:hover, .gv-icon-button--on-ink.is-hover { background: var(--surface-on-dark-hover); }
.gv-icon-button:focus-visible, .gv-icon-button.is-focus { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.gv-icon-button:disabled { color: var(--ink-disabled); cursor: not-allowed; background: transparent; }
.gv-icon-button .gv-count { position: absolute; top: var(--space-1); right: 0; }
.gv-icon-button__alt, .gv-icon-button.is-toggled .gv-icon-button__main { display: none; }
.gv-icon-button.is-toggled .gv-icon-button__alt { display: inline; }
.gv-icon-button--on-ink:disabled { color: var(--ink-subtle); }

/* ---- parts/icon-disc.css ---- */
/* Icon disc: a library icon on a round pink ground. tint = the details boxes'
   topics and the "See it fade." points; solid sm = the targets' ticks. */
.gv-icon-disc { display: grid; flex: none; place-items: center; width: var(--space-7); height: var(--space-7); border-radius: 50%; background: var(--surface-tint); color: var(--brand-pink-deep); }
.gv-icon-disc--solid { background: var(--brand-pink); color: var(--ink-on-brand); }
.gv-icon-disc--sm { width: calc(var(--space-1) * 4.5); height: calc(var(--space-1) * 4.5); }
.gv-icon-disc--sm .gv-icon { stroke-width: 3.5; } /* Lucide's own stroke setting: a 12 px tick at the default 2 is too faint to read */

/* ---- parts/line-item.css ---- */
/* Line item (part 16): one line in the bag. */
.gv-line-item { display: flex; gap: var(--space-3); padding-block: var(--space-4); border-bottom: 1px solid var(--line-hair); list-style: none; }
.gv-line-item:first-child { padding-top: 0; }
.gv-line-item__media { flex: none; width: 72px; height: 72px; overflow: hidden; border-radius: var(--radius-md); background: var(--surface-sunken); }
.gv-line-item__media img { display: block; width: 100%; height: 100%; object-fit: cover; }
.gv-line-item__no-photo { display: grid; place-items: center; width: 100%; height: 100%; color: var(--ink-subtle); }
.gv-line-item__info { display: flex; flex: 1; flex-direction: column; gap: var(--space-1); min-width: 0; }
.gv-line-item__name { margin: 0; font-size: var(--text-ui); font-weight: 600; line-height: var(--leading-text); overflow-wrap: break-word; }
.gv-line-item__name a { color: inherit; text-decoration: none; }
.gv-line-item__name a:hover { text-decoration: underline; text-underline-offset: 3px; }
.gv-line-item__variant { margin: 0; color: var(--ink-subtle); font-size: var(--text-caption); }
.gv-line-item__row { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--space-2); margin-top: var(--space-1); }
.gv-line-item__remove, .gv-line-item__undo {
  align-self: flex-start;
  min-height: var(--tap-min);
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink-muted);
  font-family: var(--font-sans);
  font-size: var(--text-caption);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.gv-line-item__remove:hover, .gv-line-item__undo:hover { color: var(--ink); }
.gv-line-item__undo { color: var(--brand-pink-deep); font-size: var(--text-ui); }
.gv-line-item.is-removed { padding-block: var(--space-2); }
.gv-line-item__removed { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--space-2); margin: 0; color: var(--ink-muted); font-size: var(--text-ui); }
/* The line's price sits beside the stepper: on sale, now above was, so both fit at 390. */
.gv-line-item__row .gv-price { flex-direction: column; align-items: flex-end; text-align: end; }
/* A 44 px place to tap, without making the line taller. */
.gv-line-item__undo { position: relative; }
.gv-line-item__undo::after { content: ""; position: absolute; inset: calc(var(--space-3) * -1) calc(var(--space-1) * -1); }

/* ---- parts/notice.css ---- */
/* Notice (part 11). Ground, a full hairline and the icon carry the tone;
   the words say it too. Text stays ink for reading; the icon and title take
   the tone's ink. */
.gv-notice {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface-sunken);
  color: var(--ink);
  font-size: var(--text-ui);
  line-height: var(--leading-text);
}
.gv-notice__icon { display: flex; flex: none; color: var(--ink-muted); }
.gv-notice__body { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.gv-notice__title, .gv-notice__message { margin: 0; }
.gv-notice__title { font-weight: 600; }
.gv-notice__action { align-self: flex-start; color: var(--brand-pink-deep); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }
.gv-notice__action:hover { color: var(--ink); }

.gv-notice--success { border-color: var(--surface-success); background: var(--surface-success); }
.gv-notice--success .gv-notice__icon, .gv-notice--success .gv-notice__title { color: var(--ink-success); }
.gv-notice--heads-up { border-color: var(--surface-sun); background: var(--surface-sun); }
.gv-notice--heads-up .gv-notice__icon, .gv-notice--heads-up .gv-notice__title { color: var(--ink-sun); }
.gv-notice--error { border-color: var(--line-danger); background: var(--surface-danger); }
.gv-notice--error .gv-notice__icon, .gv-notice--error .gv-notice__title { color: var(--ink-danger); }
/* A 44 px place to tap, without making the line taller. */
.gv-notice__action { position: relative; }
.gv-notice__action::after { content: ""; position: absolute; inset: calc(var(--space-3) * -1) calc(var(--space-1) * -1); }

/* ---- parts/panel.css ---- */
/* Panel (part 22): a white card with a full hairline; never a stripe. */
.gv-panel { display: flex; flex-direction: column; gap: var(--space-4); padding: var(--space-4); border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--surface-card); }
.gv-panel--sunken { border-color: transparent; background: var(--surface-sunken); }
.gv-panel__head { display: flex; align-items: center; gap: var(--space-3); font-size: var(--text-body); font-weight: 600; }
.gv-panel__step { display: grid; flex: none; place-items: center; width: var(--space-5); height: var(--space-5); border-radius: 50%; background: var(--ink); color: var(--ink-on-brand); font-size: var(--text-caption); font-weight: 600; }
.gv-panel__body { min-width: 0; }
@media (min-width: 900px) {
  .gv-panel { padding: var(--space-5); }
}

/* ---- parts/pill-nav.css ---- */
/* Pill nav (Phase 4): sticky "On this page" under the header. The current pill
   wears the "you are here" accent: a pink ring on a tint (design.md §3, accent 5). */
.gv-pill-nav { position: sticky; inset-block-start: var(--header-h); z-index: 700; min-height: var(--pill-nav-h); border-block: 1px solid var(--line-hair); background: var(--surface-card); } /* its top line lands on the header's own */
.gv-pill-nav--inline { position: relative; inset-block-start: auto; z-index: auto; }
.gv-pill-nav__list { display: flex; gap: var(--space-2); min-height: var(--pill-nav-h); align-items: center; margin: 0; padding: 0; overflow-x: auto; list-style: none; scroll-padding-inline: var(--gutter); scrollbar-width: none; }
.gv-pill-nav__list::-webkit-scrollbar { display: none; }
.gv-pill-nav__link {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
  padding-inline: var(--space-4);
  border: 1px solid var(--line-control);
  border-radius: var(--radius-pill);
  background: var(--surface-card);
  color: var(--ink);
  font-size: var(--text-ui);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.gv-pill-nav__link:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: -2px; } /* inside: the strip scrolls */
.gv-pill-nav__link[aria-current="true"] { border-color: var(--brand-pink); background: var(--surface-tint); color: var(--brand-pink-deep); box-shadow: inset 0 0 0 1px var(--brand-pink); }
@media (hover: hover) {
  .gv-pill-nav__link:hover { background: var(--surface-sunken); }
  .gv-pill-nav__link[aria-current="true"]:hover { background: var(--surface-tint); }
}
.gv-pill-nav__link.is-hover { background: var(--surface-sunken); }

/* ---- parts/post-card.css ---- */
/* Post card (part 23): a journal article in a grid. */
.gv-post-card { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; }
.gv-post-card__media { display: block; aspect-ratio: 3 / 2; overflow: hidden; border-radius: var(--radius-lg); background: var(--surface-sunken); }
.gv-post-card__media img { display: block; width: 100%; height: 100%; object-fit: cover; }
.gv-post-card__no-photo { display: grid; place-items: center; width: 100%; height: 100%; color: var(--ink-subtle); }
.gv-post-card__body { display: flex; flex-direction: column; gap: var(--space-2); }
.gv-post-card__eyebrow { margin: 0; color: var(--brand-pink-deep); font-size: var(--text-caption); font-weight: 600; letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; }
.gv-post-card__title { font-family: var(--font-display); font-size: var(--display-sm); font-weight: var(--weight-display); letter-spacing: var(--tracking-display); line-height: var(--leading-display); overflow-wrap: break-word; }
.gv-post-card__title a { color: inherit; text-decoration: none; }
.gv-post-card__title a:hover { text-decoration: underline; text-underline-offset: 3px; }
.gv-post-card__excerpt { display: -webkit-box; margin: 0; overflow: hidden; color: var(--ink-muted); line-height: var(--leading-text); -webkit-box-orient: vertical; -webkit-line-clamp: 3; }
.gv-post-card__date { margin: 0; color: var(--ink-subtle); font-size: var(--text-caption); }
/* Small: cards in a narrow row inside a box (the ingredient cards; Ali, 2026-09-27: "oversized, and disproportinate"). */
.gv-post-card--sm .gv-post-card__title { font-size: var(--text-body); letter-spacing: 0; line-height: var(--leading-text); }
.gv-post-card--sm .gv-post-card__excerpt { font-size: var(--text-ui); }

/* ---- parts/price.css ---- */
/* Price (part 6). Amounts never wrap mid-number. */
.gv-price { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 var(--space-2); margin: 0; }
.gv-price__now,
.gv-price__was { white-space: nowrap; font-variant-numeric: tabular-nums; }
.gv-price__now { font-family: var(--font-display); font-weight: var(--weight-display); letter-spacing: var(--tracking-display); color: var(--ink); }
.gv-price__was { color: var(--ink-subtle); font-size: var(--text-ui); }
.gv-price__from { color: var(--ink-subtle); font-size: var(--text-ui); }
.gv-price--card .gv-price__now { font-size: var(--text-body); }
.gv-price--buy .gv-price__now { font-size: var(--display-md); }
.gv-price--summary .gv-price__now { font-family: var(--font-sans); font-size: var(--text-ui); font-weight: 600; letter-spacing: 0; }

/* ---- parts/product-card.css ---- */
/* Product card (part 15): one card for every grid and rail. Every card in a row
   is the same height whatever the name's length (Ali, 2026-09-27): each line
   keeps a fixed space, the name shows two lines at most, the button sits at the
   foot. The name's link covers the whole card, so the card is one target. */
.gv-product-card { position: relative; display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; height: 100%; border-radius: var(--radius-lg); }
.gv-product-card__media { position: relative; aspect-ratio: 1; overflow: hidden; border-radius: var(--radius-lg); background: var(--surface-sunken); }
.gv-product-card__img { display: block; width: 100%; height: 100%; object-fit: cover; }
.gv-product-card__no-photo { display: grid; place-items: center; width: 100%; height: 100%; color: var(--ink-subtle); }
.gv-product-card__badge { position: absolute; inset-block-start: var(--space-2); inset-inline-start: var(--space-2); max-width: calc(100% - var(--space-4)); }
.gv-product-card.is-sold-out .gv-product-card__img { opacity: 0.55; }

.gv-product-card__body { display: flex; flex: 1; flex-direction: column; gap: var(--space-2); min-width: 0; }
.gv-product-card__eyebrow { min-height: calc(var(--text-caption) * var(--leading-text)); margin: 0; overflow: hidden; color: var(--ink-subtle); font-size: var(--text-caption); font-weight: 600; letter-spacing: var(--tracking-eyebrow); line-height: var(--leading-text); text-overflow: ellipsis; text-transform: uppercase; white-space: nowrap; }
.gv-product-card__name {
  display: -webkit-box;
  min-height: calc(var(--text-body) * var(--leading-text) * 2);
  overflow: hidden;
  font-size: var(--text-body);
  font-weight: 600;
  line-height: var(--leading-text);
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}
.gv-product-card__name a { color: inherit; text-decoration: none; }
.gv-product-card__name a::after { content: ""; position: absolute; inset: 0; border-radius: var(--radius-lg); } /* the whole card */
.gv-product-card__name a:focus-visible { outline: none; }
.gv-product-card:has(.gv-product-card__name a:focus-visible) { outline: 2px solid var(--focus-ring); outline-offset: var(--space-1); }
.gv-product-card:hover .gv-product-card__name a { text-decoration: underline; text-underline-offset: 3px; }

/* The price keeps two lines on phones (a sale price and the old one stack in a
   narrow card), one line from 640. */
.gv-product-card .gv-price { min-height: calc(var(--text-body) * var(--leading-text) * 2); align-content: flex-start; }
@media (min-width: 640px) {
  .gv-product-card .gv-price { min-height: calc(var(--text-body) * var(--leading-text)); }
}

.gv-product-card__action { position: relative; z-index: 1; display: flex; flex-direction: column; gap: var(--space-2); margin-top: auto; padding-top: var(--space-1); }
.gv-product-card__error { display: flex; align-items: flex-start; gap: var(--space-1); margin: 0; color: var(--ink-danger); font-size: var(--text-caption); font-weight: 600; line-height: var(--leading-text); }
.gv-product-card__error .gv-icon { flex: none; }

/* ---- parts/progress.css ---- */
/* Progress (part 12): the free-delivery meter. Pink fill (design.md §3: pink
   is the next step); done says so in green words with a tick. */
.gv-progress { --gv-progress: 0%; display: flex; flex-direction: column; gap: var(--space-2); }
.gv-progress__head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--space-1) var(--space-3); }
.gv-progress__label { display: flex; align-items: center; gap: var(--space-1); margin: 0; font-size: var(--text-ui); font-weight: 600; line-height: var(--leading-text); }
.gv-progress__action { color: var(--brand-pink-deep); font-size: var(--text-ui); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; white-space: nowrap; }
.gv-progress__action:hover { color: var(--ink); }
.gv-progress__track { height: 6px; border-radius: var(--radius-pill); background: var(--surface-track); overflow: hidden; }
.gv-progress__fill { display: block; width: var(--gv-progress); height: 100%; border-radius: var(--radius-pill); background: var(--brand-pink); transition: width var(--duration) var(--ease); }
.gv-progress.is-done .gv-progress__label { color: var(--ink-success); }
@media (prefers-reduced-motion: reduce) {
  .gv-progress__fill { transition: none; }
}
/* A 44 px place to tap, without making the line taller. */
.gv-progress__action { position: relative; }
.gv-progress__action::after { content: ""; position: absolute; inset: calc(var(--space-3) * -1) calc(var(--space-1) * -1); }

/* ---- parts/rating.css ---- */
/* Rating (part 7): Lucide stars. An empty row, and a filled row on top clipped
   to the exact fraction. Filled stars in the brand pink (Ali, 2026-09-27: "Make the
   review stars pink"; 4.5:1 on the page ground, over the 3:1 for icons); the
   empty row stays a quiet line, and the number beside them carries the value. */
.gv-rating { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-2); margin: 0; font-size: var(--text-ui); color: var(--ink-muted); }
.gv-rating__stars { position: relative; display: inline-flex; flex: none; }
.gv-rating__row { display: inline-flex; color: var(--line-strong); }
.gv-rating__row--filled { --gv-rating: 0%; /* set inline by the part */ position: absolute; inset-block-start: 0; inset-inline-start: 0; width: var(--gv-rating); overflow: hidden; color: var(--brand-pink); }
.gv-rating__row .gv-icon { flex: none; }
.gv-rating__text { white-space: nowrap; } /* moves under the stars as one, never breaks mid-phrase */
.gv-rating--empty { color: var(--ink-subtle); }
.gv-rating--compact { flex-wrap: nowrap; gap: var(--space-1); font-size: var(--text-caption); }
.gv-rating--none { min-height: calc(var(--text-caption) * var(--leading-text)); }

/* ---- parts/reels.css ---- */
/* Reel strip (part 25): 9:16 tiles on the carousel engine. */
.gv-reels { display: flex; flex-direction: column; gap: var(--space-2); }
.gv-reels__bar { display: flex; justify-content: flex-end; }
.gv-carousel--reels .gv-carousel__slide { flex-basis: calc((100% - var(--space-4)) / 2.3); }
@media (min-width: 640px) {
  .gv-carousel--reels .gv-carousel__slide { flex-basis: calc((100% - var(--space-4) * 3) / 3.5); }
}
@media (min-width: 1200px) {
  .gv-carousel--reels .gv-carousel__slide { flex-basis: calc((100% - var(--space-4) * 5) / 5.4); }
}
.gv-reels__tile { position: relative; display: block; width: 100%; aspect-ratio: 9 / 16; padding: 0; overflow: hidden; border: 0; border-radius: var(--radius-lg); background: var(--surface-sunken); color: var(--ink-on-brand); cursor: pointer; }
.gv-reels__tile:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.gv-reels__poster, .gv-reels__video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.gv-reels__no-poster { position: absolute; inset: 0; display: grid; place-items: center; color: var(--ink-subtle); }
.gv-reels__play { position: absolute; inset-block-start: var(--space-2); inset-inline-end: var(--space-2); display: grid; place-items: center; width: var(--space-6); height: var(--space-6); border-radius: 50%; background: var(--surface-scrim); }
.gv-reels__caption { position: absolute; inset-inline: 0; inset-block-end: 0; padding: var(--space-6) var(--space-3) var(--space-3); background: linear-gradient(to top, var(--ink), transparent); font-size: var(--text-caption); font-weight: 600; line-height: var(--leading-text); text-align: start; }
.gv-reels__tile--still { cursor: default; }
/* The viewer: the browser's own modal dialog over a dark scrim. */
.gv-reels__dialog { width: min(420px, 92vw); max-height: 92vh; padding: 0; border: 0; border-radius: var(--radius-lg); background: var(--ink); color: var(--ink-on-dark); --focus-ring: var(--ink-on-dark); }
.gv-reels__dialog::backdrop { background: var(--surface-scrim); }
.gv-reels__dialog-bar { display: flex; justify-content: flex-end; padding: var(--space-1); }
.gv-reels__player { display: block; width: 100%; max-height: calc(92vh - var(--tap-min) - var(--space-2)); aspect-ratio: 9 / 16; background: var(--ink); }

/* ---- parts/review-card.css ---- */
/* Review card (Phase 4): a customer review in full. */
.gv-review-card { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-4); border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--surface-card); }
.gv-review-card__head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--space-1) var(--space-3); }
.gv-review-card__who { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 var(--space-2); margin: 0; min-width: 0; }
.gv-review-card__name { color: var(--ink); font-size: var(--text-ui); font-weight: 600; overflow-wrap: anywhere; }
.gv-review-card__meta { color: var(--ink-subtle); font-size: var(--text-caption); }
.gv-review-card__verified { display: flex; align-items: center; gap: var(--space-1); margin: 0; color: var(--ink-muted); font-size: var(--text-caption); }
.gv-review-card__text { display: flex; flex-direction: column; gap: var(--space-2); color: var(--ink); line-height: var(--leading-text); }
.gv-review-card__text p { margin: 0; overflow-wrap: break-word; }
.gv-review-card__text.is-clamped { display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 6; }
.gv-review-card__more { align-self: flex-start; min-height: var(--tap-min); padding: 0; border: 0; background: none; color: var(--brand-pink-deep); font-family: var(--font-sans); font-size: var(--text-ui); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.gv-review-card__more:hover { color: var(--ink); }
@media (min-width: 900px) {
  .gv-review-card { padding: var(--space-5); }
}

/* ---- parts/section-header.css ---- */
/* Section header (part 20): eyebrow, heading, intro; the link sits at the end
   of the row on wide screens and under the text on phones. */
.gv-section-header { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--space-3) var(--space-5); }
.gv-section-header__text { display: flex; flex-direction: column; gap: var(--space-2); max-width: var(--measure); }
.gv-section-header__eyebrow { margin: 0; color: var(--brand-pink-deep); font-size: var(--text-caption); font-weight: 600; letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; }
.gv-section-header__heading { font-family: var(--font-display); font-size: var(--display-md); font-weight: var(--weight-display); letter-spacing: var(--tracking-display); line-height: var(--leading-display); text-wrap: balance; }
.gv-section-header__intro { margin: 0; color: var(--ink-muted); line-height: var(--leading-text); }
.gv-section-header__link { display: inline-flex; align-items: center; gap: var(--space-1); min-height: var(--tap-min); color: var(--ink); font-size: var(--text-ui); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; white-space: nowrap; }
.gv-section-header__link:hover { color: var(--brand-pink-deep); }
.gv-section-header--center { flex-direction: column; align-items: center; text-align: center; }
.gv-section-header--center .gv-section-header__text { align-items: center; }

/* ---- parts/site-footer.css ---- */
/* Site footer (part 27) on the ink ground: brand and contact, link columns,
   newsletter, legal row. Stacked on phones; side by side from 900. */
.gv-site-footer { padding-block: var(--section-gap) var(--space-5); background: var(--ink); color: var(--ink-on-dark); --focus-ring: var(--ink-on-dark); }
.gv-site-footer a { color: inherit; }
.gv-site-footer__grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-6); }
.gv-site-footer__brand, .gv-site-footer__news, .gv-site-footer__column { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; }
.gv-site-footer__logo img { display: block; width: auto; height: var(--space-7); }
.gv-site-footer__tagline { max-width: var(--measure); margin: 0; font-size: var(--text-ui); line-height: var(--leading-text); }
.gv-site-footer__contact, .gv-site-footer__links, .gv-site-footer__legal-links { margin: 0; padding: 0; list-style: none; }
.gv-site-footer__contact a, .gv-site-footer__links a, .gv-site-footer__social { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--tap-min); font-size: var(--text-ui); text-decoration: none; }
.gv-site-footer__contact a:hover, .gv-site-footer__links a:hover, .gv-site-footer__social:hover, .gv-site-footer__legal-links a:hover { text-decoration: underline; text-underline-offset: 3px; }
.gv-site-footer__title { color: var(--ink-on-brand); font-size: var(--text-ui); font-weight: 600; }
.gv-site-footer__form { display: flex; flex-direction: column; gap: var(--space-3); }
.gv-site-footer .gv-field__label { color: var(--ink-on-dark); }
.gv-site-footer .gv-field.is-invalid .gv-field__control { border-color: var(--line-danger); box-shadow: inset 0 0 0 1px var(--line-danger); }
.gv-site-footer .gv-field__error { color: var(--line-danger); }
.gv-site-footer .gv-button--secondary { border-color: var(--ink-on-dark); background: transparent; color: var(--ink-on-brand); }
.gv-site-footer .gv-button--secondary:hover { background: var(--ink-on-brand); color: var(--ink); }
.gv-site-footer__done { display: flex; align-items: flex-start; gap: var(--space-2); margin: 0; font-size: var(--text-ui); line-height: var(--leading-text); }
.gv-site-footer__legal { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2) var(--space-5); margin-top: var(--space-7); padding-top: var(--space-4); border-top: 1px solid var(--line-on-dark); font-size: var(--text-caption); }
.gv-site-footer__copy { margin: 0; }
.gv-site-footer__legal-links { display: flex; flex-wrap: wrap; gap: 0 var(--space-4); }
.gv-site-footer__legal-links a { display: inline-flex; align-items: center; min-height: var(--tap-min); text-decoration: none; }
@media (min-width: 900px) {
  .gv-site-footer__grid { grid-template-columns: 1.4fr repeat(3, minmax(0, 1fr)) 1.4fr; gap: var(--space-5); }
}

/* ---- parts/site-header.css ---- */
/* Site header (part 26): the ink announcement bar, then a sticky white bar.
   Phones: menu + search | logo | account + bag. From 900: logo | nav | icons. */
/* Only the white bar sticks; the announcement bar scrolls away (Phase 4). The
   wrapper steps aside (display: contents) so the bar sticks to the page. */
.gv-site-header { display: contents; }
.gv-site-header__announce { padding-inline: var(--space-2); background: var(--ink); color: var(--ink-on-dark); --focus-ring: var(--ink-on-dark); }
.gv-site-header__announce .gv-carousel { max-width: var(--container-narrow); margin-inline: auto; gap: 0; }
.gv-site-header__line { margin: 0; padding-block: var(--space-2); font-size: var(--text-caption); font-weight: 600; line-height: var(--leading-text); }

.gv-site-header__bar { position: sticky; inset-block-start: 0; z-index: 800; border-bottom: 1px solid var(--line-hair); background: var(--surface-card); }
.gv-site-header__inner { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: var(--space-2); min-height: var(--header-h); }
.gv-site-header__start, .gv-site-header__end { display: flex; align-items: center; }
.gv-site-header__end { justify-content: flex-end; }
.gv-site-header__logo { display: inline-flex; align-items: center; justify-self: center; min-height: var(--tap-min); }
.gv-site-header__logo img { display: block; width: auto; height: var(--space-6); }
.gv-site-header__nav, .gv-site-header__search-wide { display: none; }
.gv-site-header__links, .gv-site-header__menu-links { margin: 0; padding: 0; list-style: none; }

@media (min-width: 900px) {
  .gv-site-header__inner { grid-template-columns: auto 1fr auto; gap: var(--space-5); }
  .gv-site-header__start { display: none; }
  .gv-site-header__logo { justify-self: start; }
  .gv-site-header__nav { display: block; justify-self: center; }
  .gv-site-header__links { display: flex; gap: var(--space-5); }
  .gv-site-header__search-wide { display: inline-grid; }
  .gv-site-header__link { display: inline-flex; align-items: center; min-height: var(--tap-min); color: var(--ink); font-size: var(--text-ui); font-weight: 600; text-decoration: none; }
  .gv-site-header__link:hover { text-decoration: underline; text-underline-offset: 6px; }
  .gv-site-header__link[aria-current="page"] { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 6px; }
}

/* The phone menu: a panel from the left over a scrim; parts.js keeps focus inside. */
.gv-site-header__menu { position: fixed; inset: 0; z-index: 1000; }
.gv-site-header__scrim { position: absolute; inset: 0; background: var(--surface-scrim); }
.gv-site-header__panel { position: absolute; inset-block: 0; inset-inline-start: 0; display: flex; flex-direction: column; gap: var(--space-4); width: min(340px, 88%); padding: var(--space-2) var(--space-4) var(--space-5); overflow-y: auto; background: var(--surface-card); box-shadow: var(--shadow-overlay); }
.gv-site-header__panel-head { display: flex; align-items: center; justify-content: space-between; min-height: var(--header-h); }
.gv-site-header__panel-head .gv-site-header__logo img { height: var(--space-5); }
.gv-site-header__menu-links { border-top: 1px solid var(--line-hair); }
.gv-site-header__menu-link { display: flex; align-items: center; min-height: var(--control-h-lg); border-bottom: 1px solid var(--line-hair); color: var(--ink); font-family: var(--font-display); font-size: var(--display-md); font-weight: var(--weight-display); letter-spacing: var(--tracking-display); text-decoration: none; }
.gv-site-header__menu-link[aria-current="page"] { color: var(--brand-pink-deep); }

/* The parts sheet shows the menu open, in the page. */
.gv-site-header__menu--inline { position: relative; inset: auto; z-index: auto; height: 560px; }
.gv-site-header__menu--inline .gv-site-header__panel { position: relative; width: 100%; max-width: 340px; height: 100%; border: 1px solid var(--line); border-radius: var(--radius-lg); }

/* ---- parts/skeleton.css ---- */
/* Skeleton (part 14): grey shapes at the final size. A slow fade shows it's
   working; none at all under reduced motion. */
.gv-skeleton { display: flex; flex-direction: column; gap: var(--space-2); }
.gv-skeleton__block { display: block; height: var(--space-4); border-radius: var(--radius-sm); background: var(--surface-track); animation: gv-skeleton 1.4s var(--ease) infinite alternate; }
.gv-skeleton__block--image { height: auto; aspect-ratio: 1; border-radius: var(--radius-lg); }
.gv-skeleton__block--short { width: 60%; }
.gv-skeleton__block--price { width: 40%; height: var(--space-5); }
.gv-skeleton__block--button { height: var(--control-h); margin-top: var(--space-1); border-radius: var(--radius-pill); }
.gv-skeleton--card { gap: var(--space-3); }
@keyframes gv-skeleton { to { opacity: 0.5; } }
@media (prefers-reduced-motion: reduce) {
  .gv-skeleton__block { animation: none; }
}

/* ---- parts/step-list.css ---- */
/* Step list (Phase 4): numbered circles or labels; rows split by a hairline. */
.gv-steps { margin: 0; padding: 0; list-style: none; }
.gv-steps__item { display: flex; align-items: flex-start; gap: var(--space-3); padding-block: var(--space-3); border-bottom: 1px solid var(--line-hair); }
.gv-steps__item:first-child { padding-block-start: 0; }
.gv-steps__item:last-child { border-bottom: 0; padding-block-end: 0; }
.gv-steps__marker { display: grid; flex: none; place-items: center; width: var(--space-5); height: var(--space-5); border-radius: 50%; background: var(--surface-sunken); color: var(--ink); font-size: var(--text-ui); font-variant-numeric: tabular-nums; font-weight: 600; }
.gv-steps__body { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.gv-steps__label { margin: 0; color: var(--ink-subtle); font-size: var(--text-caption); font-weight: 600; letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; }
.gv-steps__title { margin: 0; color: var(--ink); font-size: var(--text-body); font-weight: 600; line-height: var(--leading-text); }
.gv-steps__text { margin: 0; color: var(--ink-muted); font-size: var(--text-body); line-height: var(--leading-text); }
.gv-steps--compact .gv-steps__text { font-size: var(--text-ui); }

/* ---- parts/stepper.css ---- */
/* Stepper (part 10): 44 x 44 buttons; at the ends a button turns off and the
   reason is said in words. */
.gv-stepper { display: inline-flex; flex-direction: column; align-items: flex-start; gap: var(--space-1); }
.gv-stepper__control {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--line-control);
  border-radius: var(--radius-pill);
  background: var(--surface-card);
}
.gv-stepper__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--tap-min);
  height: var(--tap-min);
  padding: 0;
  border: 0;
  border-radius: var(--radius-pill);
  background: none;
  color: var(--ink);
  cursor: pointer;
}
.gv-stepper__btn:hover, .gv-stepper__btn.is-hover { background: var(--surface-sunken); }
.gv-stepper__btn:focus-visible, .gv-stepper__btn.is-focus { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.gv-stepper__btn:disabled { color: var(--ink-disabled); background: none; cursor: not-allowed; }
.gv-stepper__value { min-width: var(--space-6); font-size: var(--text-body); font-weight: 600; font-variant-numeric: tabular-nums; text-align: center; }
.gv-stepper.is-working .gv-stepper__value { color: var(--ink-subtle); }
.gv-stepper__reason { margin: 0; color: var(--ink-subtle); font-size: var(--text-caption); }

/* ---- parts/trust.css ---- */
/* Trust row (part 18): short promises, each with a green tick. Tone brand: a
   product's targets, each a white tick in a pink disc, in bold words at the
   UI size so "Post-Acne Marks" holds one line two to a row at 390 and 1024. */
.gv-trust { display: flex; flex-direction: column; gap: var(--space-2); margin: 0; padding: 0; list-style: none; }
.gv-trust__item { display: flex; align-items: center; gap: var(--space-2); color: var(--ink); font-size: var(--text-ui); }
.gv-trust__item > .gv-icon { flex: none; color: var(--ink-success); }
.gv-trust--2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3) var(--space-4); }
.gv-trust--brand .gv-trust__item { align-items: flex-start; font-weight: 600; line-height: var(--leading-text); }
.gv-trust--brand .gv-icon-disc { margin-top: calc(var(--space-1) * 0.25); } /* centred on the first line of words (14 px x 1.5 = 21 px; the disc is 18) */

/* ---- parts/whatsapp.css ---- */
/* WhatsApp button (part 19): floats bottom right, always on screen, round with
   WhatsApp's mark at every width, as on the live store (the words stay for
   screen readers). parts.js lifts it above the phone buy bar and above a
   keep-clear control under its corner; it slides there. */
.gv-whatsapp {
  position: fixed;
  inset-block-end: var(--space-4);
  inset-inline-end: var(--space-4);
  z-index: 900;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-width: var(--space-8);
  min-height: var(--space-8);
  padding: var(--space-4);
  border-radius: var(--radius-pill);
  background: var(--whatsapp);
  color: var(--ink-on-brand);
  box-shadow: var(--shadow-overlay);
  font-size: var(--text-body);
  font-weight: 600;
  text-decoration: none;
  transition: bottom var(--duration) var(--ease);
}
.gv-whatsapp:hover { background: var(--ink); }
.gv-whatsapp__glyph { flex: none; }
.gv-whatsapp__label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.gv-whatsapp--inline { position: static; }
.gv-whatsapp.is-focus { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.gv-whatsapp[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) {
  .gv-whatsapp { transition: none; }
}

/* ---- pages/product.css ---- */
/* The product page in the new look (Phase 4). Composition only: the parts and
   layout objects do the rest. The science dots are the page's one drawing. */

/* The product band: on phones head, photos, then the rest (the DOM order);
   from 900 the photos take the left column. */
@media (min-width: 900px) {
  .gv-product__grid { grid-template-areas: "photos head" "photos buy"; grid-template-rows: auto 1fr; row-gap: var(--space-5); }
  /* The whole photo is on screen when the page opens (Ali, 2026-09-27): the
     column is at most the height left under the announcement bar, header,
     section menu (and their lines) and the band's top, plus the thumbnail
     column; never under 384 px. On a tall screen it is the usual 7/12. */
  .gv-product__grid {
    --gv-photo: max(calc(var(--space-9) * 6), calc(100svh - var(--tap-min) - var(--header-h) - var(--pill-nav-h) - var(--space-1) - var(--space-5) - var(--space-4)));
    grid-template-columns: min(calc((100% - var(--space-7)) * 7 / 12), calc(var(--gv-photo) + var(--space-9) + var(--space-3))) minmax(0, 1fr);
  }
  .gv-product__head { grid-area: head; }
  .gv-product__photos { grid-area: photos; }
  .gv-product__buy { grid-area: buy; }
}
.gv-product__photos, .gv-product__buy, .gv-product__head { min-width: 0; }
.gv-product__name { font-family: var(--font-display); font-size: var(--display-xl); font-weight: var(--weight-display); letter-spacing: var(--tracking-display); line-height: var(--leading-display); overflow-wrap: break-word; }
.gv-product__rating { display: inline-flex; align-items: center; align-self: flex-start; min-height: var(--tap-min); color: inherit; text-decoration: none; }
.gv-product__rating:hover .gv-rating__text { text-decoration: underline; text-underline-offset: 3px; }
.gv-product__subtitle, .gv-product__urgency { margin: 0; color: var(--ink-muted); }
.gv-product__eyebrow { margin: 0; color: var(--brand-pink-deep); font-size: var(--text-caption); font-weight: 600; letter-spacing: var(--tracking-eyebrow); line-height: var(--leading-text); text-transform: uppercase; }
.gv-product__small { margin: 0; color: var(--ink-subtle); font-size: var(--text-caption); line-height: var(--leading-text); }
.gv-product__small a { color: var(--brand-pink-deep); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }
.gv-product__text { max-width: var(--measure); margin: 0; color: var(--ink); line-height: var(--leading-text); }
.gv-product__subhead { max-width: var(--measure); margin: 0; color: var(--ink); font-size: var(--text-body); font-weight: 600; line-height: var(--leading-text); }
.gv-product__inci { max-width: var(--measure); margin: 0; color: var(--ink-muted); font-size: var(--text-ui); line-height: var(--leading-text); }

/* See it fade (#results): the circle, then the points in one list; from 640
   the two halves of the points side by side under it; from 900 either side. */
.gv-proof { display: flex; flex-direction: column; align-items: center; gap: var(--space-5); }
.gv-proof__stage { width: 100%; max-width: calc(var(--space-9) * 5.5); }
.gv-proof__points { display: grid; gap: var(--space-4); width: 100%; max-width: calc(var(--space-9) * 7); }
.gv-proof__side { min-width: 0; }
.gv-proof__note { margin: 0; color: var(--ink-subtle); font-size: var(--text-caption); line-height: var(--leading-text); text-align: center; }
@media (min-width: 640px) {
  .gv-proof__points { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--space-6); max-width: none; }
}
@media (min-width: 900px) {
  .gv-proof { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, calc(var(--space-9) * 5.5)) minmax(0, 1fr); grid-template-areas: "one stage two"; align-items: center; column-gap: var(--space-7); }
  .gv-proof__stage { grid-area: stage; }
  .gv-proof__points { display: contents; }
  .gv-proof__side { width: 100%; max-width: calc(var(--space-9) * 4); justify-self: center; } /* a short measure, so the two sides line up (the live store's 250) */
  .gv-proof__side:first-child { grid-area: one; }
  .gv-proof__side + .gv-proof__side { grid-area: two; }
}

/* The buy form: stepper, then Add to bag taking the rest of the row. */
.gv-buy-form { margin: 0; }
.gv-buy-form__row { align-items: flex-start; }
.gv-buy-form__row .gv-stepper { flex: none; }
.gv-buy-form__row > .gv-button { flex: 1; }

/* The science comparison: one row per formula, dots filled for what it blocks. */
.gv-science__row { display: flex; flex-direction: column; gap: var(--space-1); }
.gv-science__label { margin: 0; color: var(--ink); font-size: var(--text-ui); font-weight: 600; }
.gv-science__dots { display: flex; flex-wrap: wrap; gap: var(--space-1); }
.gv-science__dot { width: var(--space-3); height: var(--space-3); border: 1px solid var(--line-control); border-radius: 50%; }
.gv-science__dot.is-on { border-color: var(--ink); background: var(--ink); }
.gv-science__result { margin: 0; color: var(--ink); font-family: var(--font-display); font-size: var(--display-md); font-weight: var(--weight-display); letter-spacing: var(--tracking-display); line-height: var(--leading-display); }

/* The founder's note. */
.gv-founder__photo img { display: block; width: 100%; height: auto; aspect-ratio: 3 / 4; border-radius: var(--radius-lg); object-fit: cover; }
.gv-founder__heading { font-family: var(--font-display); font-size: var(--display-md); font-weight: var(--weight-display); letter-spacing: var(--tracking-display); line-height: var(--leading-display); }
.gv-founder__sign { margin: 0; color: var(--ink-muted); font-size: var(--text-ui); font-weight: 600; }

/* Reviews: the average beside the stars. */
.gv-reviews__average { margin: 0; font-family: var(--font-display); font-size: var(--display-md); font-weight: var(--weight-display); letter-spacing: var(--tracking-display); line-height: var(--leading-display); }
