// yueva-app.jsx — YUEVA homepage (validation-focused)

const { useState, useEffect, useRef, useMemo } = React;

/* ----------------------------------------------------------
   Analytics scaffold — gated by cookie consent.
   All event names match the validation spec.
   ---------------------------------------------------------- */
const ANALYTICS_QUEUE_KEY = 'yueva_analytics_queue';
const CONSENT_KEY = 'yueva_consent_v1';
const VARIANT_KEY = 'yueva_page_variant';
const TOPIC_ORDER_KEY = 'yueva_topic_order_v1';

// External Typeform that delivers the Hormone & Biomarker Guide.
// All site CTAs that say "Get the guide" open this in a new tab.
const TYPEFORM_GUIDE_URL = 'https://form.typeform.com/to/nhtRYylO';

// External Cal.eu page for booking the 45-min Clarity Session.
// All site CTAs that say "Book a Clarity Session" open this in a new tab.
const CLARITY_BOOKING_URL = 'https://cal.eu/yueva/45minclaritysession';

// TODO: Replace with real measurement ID once legal review of analytics is complete.
const TODO_GA_MEASUREMENT_ID = 'G-XXXXXXXXXX';

function getPageVariant() {
  let v = localStorage.getItem(VARIANT_KEY);
  if (!v) {
    v = 'v1-launch';
    try {localStorage.setItem(VARIANT_KEY, v);} catch {}
  }
  return v;
}

/* ----------------------------------------------------------
   UTM capture (Newzapiens campaign) — persists to localStorage
   and attaches to every tracked event.
   ---------------------------------------------------------- */
const UTM_KEYS = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'];
const UTM_STORAGE_KEY = 'yueva_utm_v1';

function captureUtms() {
  try {
    const url = new URL(window.location.href);
    const fresh = {};
    let anyFound = false;
    UTM_KEYS.forEach((k) => {
      const v = url.searchParams.get(k);
      if (v) {fresh[k] = v;anyFound = true;}
    });
    if (anyFound) {
      fresh.first_seen = Date.now();
      localStorage.setItem(UTM_STORAGE_KEY, JSON.stringify(fresh));
      return fresh;
    }
    const cached = localStorage.getItem(UTM_STORAGE_KEY);
    return cached ? JSON.parse(cached) : {};
  } catch {return {};}
}

function getUtms() {
  try {
    const cached = localStorage.getItem(UTM_STORAGE_KEY);
    return cached ? JSON.parse(cached) : {};
  } catch {return {};}
}

function track(event, params = {}) {
  const utms = getUtms();
  const fullParams = { ...params, ...utms, page_variant: getPageVariant() };
  const payload = { event, params: fullParams, ts: Date.now() };

  // Vercel Web Analytics — privacy-friendly (no cookies, no PII).
  // Fires regardless of consent state. Custom events use window.va('event', {...}).
  // The Vercel script (loaded in the HTML) shims window.va before it loads,
  // so calls made early are queued automatically.
  if (typeof window !== 'undefined' && typeof window.va === 'function') {
    try {
      // Vercel expects a flat object; coerce non-primitive values to strings.
      const flat = { name: event };
      Object.entries(fullParams).forEach(([k, v]) => {
        if (v == null) return;
        flat[k] = typeof v === 'object' ? JSON.stringify(v) : v;
      });
      window.va('event', flat);
    } catch {}
  }

  // Cookie-based providers (none yet) — still consent-gated and queued.
  const consent = readConsent();
  if (!consent.analytics) {
    try {
      const q = JSON.parse(sessionStorage.getItem(ANALYTICS_QUEUE_KEY) || '[]');
      q.push(payload);
      sessionStorage.setItem(ANALYTICS_QUEUE_KEY, JSON.stringify(q));
    } catch {}
    return;
  }
  // Future providers (e.g. GA4) would fire here once consent is given.
  // window.gtag && window.gtag('event', event, fullParams);
  console.info('[yueva:track]', event, fullParams);
}

function flushQueuedAnalytics() {
  try {
    const q = JSON.parse(sessionStorage.getItem(ANALYTICS_QUEUE_KEY) || '[]');
    q.forEach((e) => console.info('[yueva:track:flushed]', e.event, e.params));
    sessionStorage.removeItem(ANALYTICS_QUEUE_KEY);
  } catch {}
}

function readConsent() {
  try {
    const raw = localStorage.getItem(CONSENT_KEY);
    if (!raw) return { decided: false, analytics: false, marketing: false };
    return JSON.parse(raw);
  } catch {
    return { decided: false, analytics: false, marketing: false };
  }
}

function writeConsent(consent) {
  try {
    localStorage.setItem(CONSENT_KEY, JSON.stringify({ ...consent, decided: true, ts: Date.now() }));
  } catch {}
}

/* ----------------------------------------------------------
   Logo (SVG, matches styleguide: crescent + 3 ascending dots)
   ---------------------------------------------------------- */
/* ----------------------------------------------------------
   Logo — real YUEVA marks (inlined SVG paths, currentColor)
   ---------------------------------------------------------- */
function LogoIcon({ size = 22 }) {
  // viewBox 35.77 × 35.77 — circle + 3 ascending dots
  return (
    <svg width={size} height={size} viewBox="0 0 35.7736478 35.7736322" fill="currentColor" aria-hidden="true">
      <path d="M35.7736478,17.8868161C35.7736478,8.0081972,27.765435,0,17.8868161,0S0,8.0081972,0,17.8868161s8.0081972,17.8868161,17.8868161,17.8868161,17.8868317-8.0081972,17.8868317-17.8868161ZM2.7755542,15.3305029C2.7755542,6.9847834,9.5411126.2192249,17.8868159.2192249c8.3457358,0,15.1112617,6.7655585,15.1112617,15.111278,0,8.3457358-6.7655259,15.111278-15.1112617,15.111278-8.3457033,0-15.1112617-6.7655422-15.1112617-15.111278Z" />
      <circle cx="17.8868239" cy="10.2689651" r="1.7032311" />
      <circle cx="17.8868239" cy="4.7132568" r=".9512663" />
      <circle cx="17.8868239" cy="17.8868161" r="3.0134088" />
    </svg>);

}

function LogoWordmark({ height = 18 }) {
  // viewBox 137.30 × 53.88 — YUEVA + LONGEVITY descriptor
  const width = 137.3033061 / 53.8764648 * height;
  return (
    <svg width={width} height={height} viewBox="0 0 137.3033061 53.8764648" fill="currentColor" aria-hidden="true">
      <path d="M25.6887754,0l-10.9973467,16.8032227v12.6020508h-3.694082v-12.6020508L0,0h4.1089306l10.2091344,15.6269531L24.4847497,0h1.2040257Z" />
      <path d="M30.2067659,17.769043V0h3.694082v18.4414062c0,6.0908203,3.9420264,10.0395508,9.8762907,10.0395508s9.6283463-3.9487305,9.6283463-10.0395508V0h.9956366v18.4833984c0,6.847168-4.356875,11.3417969-11.5366499,11.3417969-7.4286841,0-12.6577058-4.7885742-12.6577058-12.0561523Z" />
      <path d="M82.1998362,28.5649414v.840332h-20.4587888V0h20.0439402v.840332h-16.350823v13.2324219h13.0310695v.8398438h-13.0310695v13.6523438h16.7656716Z" />
      <path d="M112.1586577,0l-12.7406755,29.4052734h-1.6188743L85.100882,0h3.8590567l11.0388315,25.5825195L110.9961169,0h1.1625408Z" />
      <path d="M129.7086826,20.7099609h-14.5245245l-3.7770517,8.6953125h-1.1615761L122.9862059,0h1.6179095l12.6991907,29.4052734h-3.8600214l-3.7346021-8.6953125ZM129.3353189,19.8696289l-6.8893809-16.0048828-6.929901,16.0048828h13.8192819Z" />
      {/* LONGEVITY */}
      <path d="M27.2541052,53.7802734v-8.3881836h1.398908v7.0439453h3.7818755v1.3442383h-5.1807836Z" />
      <path d="M42.4404579,52.6220703c-.8383801.828125-1.873572,1.2421875-3.1065406,1.2421875s-2.2681605-.4140625-3.1055758-1.2421875c-.8383801-.8276367-1.2570877-1.8598633-1.2570877-3.0957031,0-1.2363281.4187076-2.2680664,1.2570877-3.0961914.8374153-.828125,1.8726072-1.2416992,3.1055758-1.2416992s2.2681605.4135742,3.1065406,1.2416992c.8374153.828125,1.2561229,1.8598633,1.2561229,3.0961914,0,1.2358398-.4187076,2.2680664-1.2561229,3.0957031ZM41.4149136,47.3720703c-.5653518-.5917969-1.2590172-.8876953-2.0809963-.8876953s-1.5156445.2958984-2.0800315.8876953c-.5653518.5922852-.8480277,1.3100586-.8480277,2.1542969s.2826759,1.5620117.8480277,2.1538086c.564387.5922852,1.2580525.8881836,2.0800315.8881836s1.5156445-.2958984,2.0809963-.8881836c.564387-.5917969.8470629-1.3095703.8470629-2.1538086s-.2826759-1.5620117-.8470629-2.1542969Z" />
      <path d="M53.4532408,45.3920898h1.398908v8.3881836h-1.517574l-4.6945424-6.1201172v6.1201172h-1.398908v-8.3881836h1.398908l4.8132084,6.2641602v-6.2641602Z" />
      <path d="M64.6686242,49.7001953h1.398908v2.8681641c-.7824237.8720703-1.9015502,1.3081055-3.3554498,1.3081055-1.2252505,0-2.2507948-.4082031-3.0766329-1.2241211s-1.2387572-1.8481445-1.2387572-3.0961914.4206372-2.2875977,1.2628763-3.1201172c.8412743-.831543,1.8591005-1.2475586,3.0525138-1.2475586s2.1851908.3520508,2.9753327,1.0556641l-.7467275,1.0800781c-.3241608-.2797852-.650251-.4741211-.9782709-.5820312s-.7091017-.1621094-1.1432455-.1621094c-.8383801,0-1.5416931.2744141-2.110904.8222656-.5682461.5478516-.8528515,1.2680664-.8528515,2.1601562s.2759226,1.6079102.8296972,2.1479492c.5528099.5400391,1.2223562.8100586,2.0096038.8100586.7862828,0,1.444252-.1723633,1.9739075-.5161133v-2.3041992Z" />
      <path d="M75.5038905,45.3920898v1.3320312h-4.4224789v2.2202148h3.9719341v1.2597656h-3.9719341v2.2441406h4.5642993v1.3320312h-5.9632073v-8.3881836h5.821387Z" />
      <path d="M82.996249,53.7802734h-1.5648475l-3.3313307-8.3881836h1.5648475l2.5489069,6.2641602,2.5479422-6.2641602h1.5648475l-3.3303659,8.3881836Z" />
      <path d="M89.2913352,45.3920898h1.398908v8.3881836h-1.398908v-8.3881836Z" />
      <path d="M97.8979963,46.6884766v7.0917969h-1.398908v-7.0917969h-2.5132106v-1.2963867h6.4253293v1.2963867h-2.5132106Z" />
      <path d="M106.9667794,53.7802734h-1.4230271v-3.3120117l-3.0824215-5.0761719h1.530116l2.2643015,3.8164062,2.2643015-3.8164062h1.5291512l-3.0824215,5.0761719v3.3120117Z" />
    </svg>);

}

function Logo({ size = 'nav' }) {
  // nav: wordmark only, larger for legibility
  // lg:  full vertical lockup (icon stacked above wordmark) — used in footer
  if (size === 'lg') {
    return (
      <span className="logo-lockup logo--full" aria-label="YUEVA Longevity">
        <LogoIcon size={44} />
        <LogoWordmark height={26} />
      </span>);

  }
  return (
    <span className="logo-lockup logo--nav" aria-label="YUEVA Longevity">
      <LogoWordmark height={56} />
    </span>);

}

/* ----------------------------------------------------------
   Navigation
   ---------------------------------------------------------- */
function Nav() {
  const [menuOpen, setMenuOpen] = useState(false);
  const close = () => setMenuOpen(false);

  // Lock body scroll + Escape-to-close while the drawer is open.
  useEffect(() => {
    if (!menuOpen) return;
    const onKey = (e) => { if (e.key === 'Escape') close(); };
    const prevOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    window.addEventListener('keydown', onKey);
    return () => {
      window.removeEventListener('keydown', onKey);
      document.body.style.overflow = prevOverflow;
    };
  }, [menuOpen]);

  return (
    <header className={`nav${menuOpen ? ' is-menu-open' : ''}`}>
      <div className="shell nav-inner">
        <a href="index.html" aria-label="YUEVA home" className="logo--nav" onClick={close}>
          <img
            src="assets/Wordmark_Yueva_Charcoal.svg"
            alt="YUEVA Longevity"
            className="logo-nav-img" />
        </a>

        {/* Desktop nav — hidden under the burger breakpoint via CSS */}
        <nav className="nav-links" aria-label="Primary">
          <a href="clarity-session.html" className="nav-link">Clarity Session</a>
          <a href="#how" className="nav-link">How it works</a>
          <a href="about.html" className="nav-link">About</a>
          {/* Nav CTA links to the Guide landing page (which has its own
              primary button to the Typeform). All other "Get the guide"
              CTAs across the site open the Typeform directly. */}
          <a href="guide.html" className="btn nav-cta">
            Get the guide <span className="arrow" aria-hidden="true">→</span>
          </a>
        </nav>

        {/* Mobile burger toggle — only visible under the breakpoint */}
        <button
          type="button"
          className={`nav-burger${menuOpen ? ' is-open' : ''}`}
          aria-label={menuOpen ? 'Close menu' : 'Open menu'}
          aria-expanded={menuOpen}
          aria-controls="mobile-menu"
          onClick={() => setMenuOpen((o) => !o)}>
          <span className="nav-burger__bar" aria-hidden="true"></span>
          <span className="nav-burger__bar" aria-hidden="true"></span>
          <span className="nav-burger__bar" aria-hidden="true"></span>
        </button>
      </div>

      {/* Mobile drawer + scrim. Hidden on desktop via CSS. */}
      <div
        className={`nav-mobile${menuOpen ? ' is-open' : ''}`}
        aria-hidden={!menuOpen}>
        <div
          className="nav-mobile__scrim"
          onClick={close}
          aria-hidden="true"></div>
        <nav
          id="mobile-menu"
          className="nav-mobile__panel"
          aria-label="Mobile primary">
          <a href="clarity-session.html" className="nav-mobile__link" onClick={close}>Clarity Session</a>
          <a href="#how" className="nav-mobile__link" onClick={close}>How it works</a>
          <a href="about.html" className="nav-mobile__link" onClick={close}>About</a>
          <a href="guide.html" className="btn nav-mobile__cta" onClick={close}>
            Get the guide <span className="arrow" aria-hidden="true">→</span>
          </a>
        </nav>
      </div>
    </header>);

}

/* ----------------------------------------------------------
   Hero
   ---------------------------------------------------------- */
const HERO_HEADLINES = {
  navigate: 'Is this normal, or is it my hormones?',
  important: 'Your 30s are not too early to understand your hormones.',
  structured: 'Before you test everything, know what is worth asking for.'
};

function Hero({ headlineKey, onPrimary, onSecondary }) {
  const headline = HERO_HEADLINES[headlineKey] || HERO_HEADLINES.navigate;
  return (
    <section className="hero" id="top">
      <div className="shell hero-grid">
        <div className="hero-copy">
          <div className="hero-eyebrow-row">
            <span className="pip" />
            {/* TYPE FIX — inline color/margin removed; styled via .hero .hero-eyebrow */}
            <p className="eyebrow hero-eyebrow">WOMEN’S LONGEVITY INTELLIGENCE</p>
          </div>
          <h1 className="h-display-xl">{headline}</h1>
          {/* TYPE FIX — inline fontSize:19px / inline color removed; uses --fs-body-l */}
          <p className="lede hero-lede">
            YUEVA helps women in their 30s and 40s make sense of hormones, biomarkers,
            fertility, energy, metabolism, and cycle changes. Evidence-informed guides and
            physician-led sessions.
          </p>

          <div className="hero-ctas">
            <a
              className="btn"
              href={CLARITY_BOOKING_URL}
              target="_blank"
              rel="noopener noreferrer"
              data-track="hero_clarity_cta_click">
              Book a Clarity Session <span className="arrow" aria-hidden="true">→</span>
            </a>
            {/* Hero secondary routes to the Guide landing page (not the
                                Typeform directly), matching the Nav CTA. */}
            <a className="btn btn--ghost" href="guide.html" data-track="hero_guide_cta_click">
              Get the Hormone &amp; Biomarker Guide
            </a>
          </div>

          <ul className="hero-cred" aria-label="Credibility">
            <li>CERTIFIED WOMEN’S HEALTH COACHES</li>
            <li>DOCTOR CO-FOUNDER & GYNECOLOGIST NETWORK</li>
            <li>EVIDENCE-INFORMED & PHYSICIAN-REVIEWED</li>
            <li>BUILT EXCLUSIVELY FOR WOMEN IN EUROPE</li>
          </ul>

        </div>

        <div className="hero-media">
          <figure className="hero-figure">
            <img
              src="assets/hero-portrait.jpg"
              alt="Editorial portrait — woman smiling in warm natural light"
              className="hero-img"
              loading="eager"
              decoding="async"
              width="2256"
              height="2820" />
          </figure>
        </div>
      </div>

      <div className="shell hero-stats-shell">
        <div className="hero-stats-marquee" role="list" aria-label="Highlights">
          {/* Two identical tracks back-to-back create the seamless loop */}
          {[0, 1].map((dup) =>
          <div className="hero-stats-track" aria-hidden={dup === 1 ? 'true' : undefined} key={dup}>
              <div className="hero-stat" role={dup === 0 ? 'listitem' : undefined}>
                <p className="hero-stat__num"><span className="accent">30s</span> and 40s</p>
                <p className="hero-stat__label">Hormones, biomarkers, fertility</p>
              </div>
              <div className="hero-stat" role={dup === 0 ? 'listitem' : undefined}>
                <p className="hero-stat__num">Free</p>
                <p className="hero-stat__label">Hormone &amp; Biomarker Guide</p>
              </div>
              <div className="hero-stat" role={dup === 0 ? 'listitem' : undefined}>
                <p className="hero-stat__num">€<span className="accent">89</span></p>
                <p className="hero-stat__label">Clarity Session entry point</p>
              </div>
              <div className="hero-stat" role={dup === 0 ? 'listitem' : undefined}>
                <p className="hero-stat__num"><span className="accent">MD</span>-reviewed</p>
                <p className="hero-stat__label">Educational, not medical advice</p>
              </div>
            </div>
          )}
        </div>
      </div>
    </section>);

}

/* ----------------------------------------------------------
   Symptom recognition
   ---------------------------------------------------------- */
const SYMPTOM_CLUSTERS = [
{
  id: 'cycle',
  label: 'Cycle and fertility',
  image: 'assets/symptom-cycle.png',
  imageAlt: 'Ovarian ultrasound — clinical reference',
  items: ['Irregular or shifting cycles', 'PMS getting heavier with age', 'Fertility planning questions', 'Egg freezing decisions']
},
{
  id: 'energy',
  label: 'Energy & Metabolism',
  image: 'assets/symptom-energy.png',
  imageAlt: 'Mitochondria — clinical illustration of cellular energy',
  items: ['Fatigue that sleep does not fix', 'Weight changes without diet changes', 'Cravings, brain fog, cold hands', 'Thinning hair or low resilience']
},
{
  id: 'stress',
  label: 'Stress and sleep',
  image: 'assets/symptom-stress.png',
  imageAlt: 'Low heart-rate variability trend — clinical wearable data',
  items: ['Wired but tired all day', '2 to 4 AM wake-ups, racing thoughts', 'Anxiety with no clear trigger', 'Lowered libido and motivation']
},
{
  id: 'skin',
  label: 'Skin, Hair, & Androgens',
  image: 'assets/symptom-skin.png',
  imageAlt: 'Macro view of skin surface — clinical reference',
  items: ['Adult acne, oily skin shifts', 'New facial hair or hairline changes', 'Scalp thinning', 'PCOS questions on the table']
}];


function SymptomSection({ onGuide }) {
  const [active, setActive] = useState(0);
  const stageRef = useRef(null);
  const total = SYMPTOM_CLUSTERS.length;

  const goTo = (i) => setActive((i + total) % total);

  // Keyboard navigation when the stage is focused
  useEffect(() => {
    const stage = stageRef.current;
    if (!stage) return;
    const onKey = (e) => {
      if (e.key === 'ArrowLeft') {e.preventDefault();goTo(active - 1);} else
      if (e.key === 'ArrowRight') {e.preventDefault();goTo(active + 1);}
    };
    stage.addEventListener('keydown', onKey);
    return () => stage.removeEventListener('keydown', onKey);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [active]);

  return (
    <section className="section section--light symptom" id="symptoms">
      <div className="shell symptom-shell">
        {/* TYPE FIX — inline width:750px / textAlign:justify removed.
                            Now uses .symptom-head__lede class for spacing. */}
        <div className="symptom-head">
          <p className="section-eyebrow">SYMPTOM RECOGNITION</p>
          <h2 className="h-display-l">Your symptoms deserve a structured explanation.</h2>
          <p className="lede symptom-head__lede">Fatigue, irregular periods, brain fog, weight changes, or 3 AM wake-ups are often explained away as stress, age, or a busy life. But when these signals repeat or appear together, they deserve a more structured look.</p>
          <p className="lede symptom-head__lede">YUEVA helps you map your symptoms, cycle context, hormone questions, biomarkers, fertility goals, metabolism, and lifestyle factors, so you can prepare better questions, avoid guesswork, and choose your next step with more clarity.</p>

          <div className="symptom-cta">
            <button className="btn" type="button" onClick={onGuide} data-track="hero_guide_cta_click">
              Get the Hormone &amp; Biomarker Guide <span className="arrow" aria-hidden="true">→</span>
            </button>
            <p className="symptom-cta__note">
              Free. Educational. Built around what is worth asking before you test.
            </p>
          </div>
        </div>

        <div className="symptom-coverflow"
        role="region"
        aria-roledescription="carousel"
        aria-label="Symptom clusters"
        tabIndex={0}
        ref={stageRef}>
          
          <div className="coverflow-stage">
            {SYMPTOM_CLUSTERS.map((c, i) => {
              // Signed shortest distance on the ring, so wrap-around feels continuous
              let offset = i - active;
              if (offset > total / 2) offset -= total;
              if (offset < -total / 2) offset += total;
              const isActive = offset === 0;
              return (
                <article
                  key={c.id}
                  className={`coverflow-card ${isActive ? 'is-active' : ''}`}
                  data-offset={offset}
                  aria-roledescription="slide"
                  aria-label={`${i + 1} of ${total}: ${c.label}`}
                  aria-hidden={!isActive}
                  onClick={() => !isActive && goTo(i)}
                  style={{ '--offset': offset }}>
                  
                  <img
                    className="coverflow-card__img"
                    src={c.image}
                    alt={c.imageAlt}
                    loading={Math.abs(offset) <= 1 ? 'eager' : 'lazy'}
                    decoding="async" />
                  
                  <div className="coverflow-card__shade" aria-hidden="true" />
                  <div className="coverflow-card__panel">
                    {/* TYPE FIX — inline fontSize/fontWeight removed; styled via class */}
                    <h3 className="coverflow-card__title">{c.label}</h3>
                    <ul className="coverflow-card__list">
                      {c.items.map((it) => <li key={it}>{it}</li>)}
                    </ul>
                  </div>
                </article>);

            })}
          </div>

          <div className="symptom-controls">
            <button
              type="button"
              className="symptom-nav"
              onClick={() => goTo(active - 1)}
              aria-label="Previous cluster">
              
              <span aria-hidden="true">←</span>
            </button>
            <ol className="symptom-dots" role="tablist" aria-label="Choose a cluster">
              {SYMPTOM_CLUSTERS.map((c, i) =>
              <li key={c.id}>
                  <button
                  type="button"
                  role="tab"
                  aria-selected={i === active}
                  aria-label={c.label}
                  className={`symptom-dot ${i === active ? 'is-active' : ''}`}
                  onClick={() => goTo(i)} />
                
                </li>
              )}
            </ol>
            <button
              type="button"
              className="symptom-nav"
              onClick={() => goTo(active + 1)}
              aria-label="Next cluster">
              
              <span aria-hidden="true">→</span>
            </button>
          </div>
        </div>
      </div>
    </section>);

}

/* ----------------------------------------------------------
   Problem
   ---------------------------------------------------------- */
function ProblemSection() {
  return (
    <section className="problem" id="problem">
      <div className="shell problem-grid">
        <div className="problem-text">
          <p className="section-eyebrow">THE GAP</p>
          <h2 className="h-display-l">Most women aren’t getting the hormone and biomarker insights they deserve.</h2>
          {/* TYPE FIX — inline fontSize/color/text-align removed; left-aligned per styleguide */}
          <div className="problem-callout" style={{ fontSize: "21px" }}>
            If something has changed, you deserve a structured way to understand what’s really happening, and what is actually worth testing.
            <br /><br />
            Women in their 30s and 40s are often told their symptoms are stress, age, or normal. The symptoms are real. So are the costs of acting on guesswork: random tests, unhelpful supplements, dismissed appointments, or lost time.
          </div>
          <p className="problem-pull">
            YUEVA helps you map your symptoms, cycle context, fertility goals, and biomarker priorities. You walk into your next clinical appointment with structured questions and a clearer sense of what to ask and what is worth testing.
          </p>
        </div>
        {/* TYPE FIX — inline fontSize:18 / color / textAlign:justify removed.
                            Styling now lives in .problem-callout. */}
        <div className="problem-media" aria-hidden="true">
          <img src="assets/the-gap-portrait-cutout.png" alt="" loading="lazy" decoding="async" />
        </div>
      </div>
    </section>);} /* ----------------------------------------------------------
Topic cards
---------------------------------------------------------- */
const TOPIC_DATA = {
  'perimenopause-hormone-navigation': {
    id: 'perimenopause-hormone-navigation',
    eyebrow: 'Path 01 · Perimenopause',
    title: 'Perimenopause & Hormone Navigation',
    copy:
    'Sleep changes, mood shifts, energy crashes, irregular cycles, and brain fog often arrive together. We help you track what’s happening, understand your options, and prepare clear questions for your clinician.',
    best:
    'women in their late 30s to 50s who want to feel like themselves again and stop navigating these changes alone.',
    cta: 'paid',
    photo: 'photo-peri',
    photoLabel: 'Editorial · thoughtful · natural light · late 30s–early 50s'
  },
  'thyroid-autoimmune-metabolic': {
    id: 'thyroid-autoimmune-metabolic',
    eyebrow: 'Path 02 · Thyroid & Metabolism',
    title: 'Thyroid, Autoimmune & Metabolic Balance',
    copy:
    'Hashimoto’s, unexplained weight changes, crushing fatigue, and overlapping symptoms are frequently dismissed. We help you map your personal picture and build supportive lifestyle protocols.',
    best:
    'women dealing with thyroid issues, autoimmune overlap, or persistent fatigue and metabolic changes.',
    cta: 'paid',
    photo: 'photo-bio',
    photoLabel: 'Quiet · notebook · clinic-adjacent · self-aware'
  },
  'lifestyle-longevity-protocols': {
    id: 'lifestyle-longevity-protocols',
    eyebrow: 'Path 03 · Longevity',
    title: 'Lifestyle & Longevity Protocols',
    copy:
    'Evidence-informed coaching on sleep optimization, mood support, movement, nutrition, and daily habits tailored to women in perimenopause and beyond.',
    best:
    'women who want practical, sustainable tools for long-term vitality and feel overwhelmed by generic advice.',
    cta: 'paid',
    photo: 'photo-egg',
    photoLabel: 'Daily rituals · sleep, movement, nutrition'
  },
  'fertility-transition-prep': {
    id: 'fertility-transition-prep',
    eyebrow: 'Path 04 · Fertility transition',
    title: 'Fertility Transition & Egg-Freezing / IVF Prep',
    copy:
    'Whether you are considering egg freezing, preparing for IVF, or mapping your options as cycles change. We help you organize the information and prepare for confident conversations with fertility specialists.',
    best:
    'women who want structured preparation and clarity before speaking with fertility specialists.',
    cta: 'paid',
    photo: 'photo-ivf',
    photoLabel: 'Calm · planning · clinic-adjacent'
  }
};

const FIXED_ORDER = [
'perimenopause-hormone-navigation',
'thyroid-autoimmune-metabolic',
'lifestyle-longevity-protocols',
'fertility-transition-prep'];


function getTopicOrder(randomize) {
  if (!randomize) return FIXED_ORDER;
  try {
    const cached = localStorage.getItem(TOPIC_ORDER_KEY);
    if (cached) return JSON.parse(cached);
  } catch {}
  // Persistent visitor-level shuffle
  const arr = [...FIXED_ORDER];
  for (let i = arr.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [arr[i], arr[j]] = [arr[j], arr[i]];
  }
  try {localStorage.setItem(TOPIC_ORDER_KEY, JSON.stringify(arr));} catch {}
  return arr;
}

function TopicCard({ topic, position, ivfMode, onPaid, onWaitlist, onGuide }) {
  const ref = useRef(null);
  // Fire topic_card_impression when card enters viewport (once)
  useEffect(() => {
    if (!ref.current) return;
    const io = new IntersectionObserver(
      (entries) => {
        entries.forEach((e) => {
          if (e.isIntersecting) {
            track('topic_card_impression', { topic: topic.id, position });
            io.disconnect();
          }
        });
      },
      { threshold: 0.4 }
    );
    io.observe(ref.current);
    return () => io.disconnect();
  }, [topic.id, position]);

  // IVF can be flipped to waitlist via Tweaks
  const ctaMode =
  topic.id === 'fertility-transition-prep' && ivfMode === 'waitlist' ? 'waitlist' : topic.cta;

  const ctaCopy =
  ctaMode === 'waitlist' ?
  'Join expert-led waitlist' :
  'Book €89 clarity session';

  const handleCTA = () => {
    track('topic_card_click', {
      topic: topic.id,
      cta_type: ctaMode,
      position,
      button_copy: ctaCopy
    });
    if (ctaMode === 'waitlist') {
      onWaitlist(topic);
    } else {
      // Booking now goes directly to the external Cal.eu URL.
      window.open(CLARITY_BOOKING_URL, '_blank', 'noopener,noreferrer');
    }
  };

  return (
    <article className="topic-card" ref={ref}>
      <div className="topic-card__media">
        <div className="photo-placeholder" style={{ aspectRatio: '16/9' }}>
          <div className={topic.photo} style={{ position: 'absolute', inset: 0, aspectRatio: 'auto' }} />
          <span className="ph-label" style={{ position: 'relative', zIndex: 1 }}>{topic.photoLabel}</span>
        </div>
        <div className="tag-row">
          <span className={`tag ${ctaMode === 'waitlist' ? 'tag--waitlist' : 'tag--paid'}`}>
            <span className="dot" />
            {ctaMode === 'waitlist' ? 'Waitlist' : 'Paid now · €89'}
          </span>
        </div>
      </div>
      <div className="topic-card__body">
        <p className="topic-card__num">{topic.eyebrow}</p>
        <h3 className="topic-card__title">{topic.title}</h3>
        <p className="topic-card__copy">{topic.copy}</p>
        <p className="topic-card__best"><strong>Best for: </strong>{topic.best}</p>
      </div>
      <div className="topic-card__foot">
        <div>
          <button
            className={`topic-card__cta ${ctaMode === 'waitlist' ? 'topic-card__cta--sage' : ''}`}
            onClick={handleCTA}
            type="button">
            
            {ctaCopy} <span aria-hidden="true">→</span>
          </button>
          {topic.micro &&
          <button
            className="topic-card__micro"
            onClick={() => {
              track('topic_card_click', {
                topic: topic.id,
                cta_type: 'guide',
                position,
                button_copy: topic.micro
              });
              onGuide(topic.id);
            }}
            type="button">
            
              {topic.micro}
            </button>
          }
        </div>
        <span className="topic-card__price">
          {ctaMode === 'waitlist' ? 'Pilot pending' : '45 min · €89'}
        </span>
      </div>
    </article>);

}

/* ----------------------------------------------------------
   Dedicated Clarity Session block
   ---------------------------------------------------------- */
const CLARITY_BEST_FOR = [
'Women planning fertility decisions or egg freezing',
'Women with fatigue, brain fog, weight changes, or low libido',
'Women with cycle changes, PMS, or irregular periods',
'Women with existing lab results who do not know what to ask next',
'Women who feel dismissed but do not want generic wellness advice'];


const CLARITY_DELIVERABLES = [
{ included: 'A structured symptom and goal summary', means: 'We organize the patterns you described.' },
{ included: 'Your top priority areas', means: 'The 2 to 3 themes that seem most important to clarify next.' },
{ included: 'A doctor discussion list', means: 'Questions to bring to your clinician or lab appointment.' },
{ included: 'A biomarker and testing preparation checklist', means: 'What to prepare before testing, depending on your situation.' },
{ included: 'A clear next step', means: 'Whether to test, track, wait, prepare, or escalate.' }];


function ClaritySection({ onApply }) {
  const ref = useRef(null);
  useEffect(() => {
    if (!ref.current) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {track('clarity_section_view', {});io.disconnect();}
      });
    }, { threshold: 0.3 });
    io.observe(ref.current);
    return () => io.disconnect();
  }, []);

  return (
    <section className="section clarity" id="clarity" ref={ref}>
      <div className="shell">
        <div className="clarity-grid">
          <div className="clarity-lede">
            <p className="section-eyebrow">PAID ENTRY OFFER</p>
            <h2 className="h-display-l">Book a Clarity Session</h2>
            {/* TYPE FIX — inline fontWeight removed; routed through class */}
            <p className="clarity-meta">45 minutes · structured intake · written Clarity Summary</p>
            <p className="lede clarity-lede__body">
              A focused session for women who want to make sense of symptoms, cycle changes,
              fertility questions, energy, metabolism, or biomarker confusion before their next
              health decision. We help you organize what you know, identify what is unclear, and
              prepare better questions for your clinician.
            </p>
            <p className="clarity-subnote">
              Coach-delivered. Physician-reviewed method. Doctor support available where
              appropriate.
            </p>
            <p className="clarity-price">
              <span className="clarity-price__num">€89</span>
              <span className="clarity-price__meta">45 MINUTES · FOUNDING PRICE · ONLY A FEW SPOTS REMAIN EACH MONTH.</span>
            </p>
            <div className="clarity-ctas">
              <a
                className="btn"
                href={CLARITY_BOOKING_URL}
                target="_blank"
                rel="noopener noreferrer"
                data-track="clarity_cta_click">
                Book Your Clarity Session <span className="arrow" aria-hidden="true">→</span>
              </a>
              <a
                className="btn btn--ghost"
                href={TYPEFORM_GUIDE_URL}
                target="_blank"
                rel="noopener noreferrer"
                data-track="clarity_guide_cta_click">
                Get the free Hormone &amp; Biomarker Guide
              </a>
            </div>
            <p className="clarity-note">LIMITED SPOTS AVAILABLE EACH MONTH AT THIS INTRODUCTORY RATE. SECURE YOUR CLARITY SESSION BEFORE THE PRICE INCREASES.</p>
          </div>

          <div className="clarity-cards">
            <div className="clarity-card clarity-card--table">
              <p className="clarity-card__label">You leave with</p>
              <table className="clarity-table" aria-label="Clarity Session deliverables">
                <thead>
                  <tr>
                    <th scope="col">Included</th>
                    <th scope="col">What it means</th>
                  </tr>
                </thead>
                <tbody>
                  {CLARITY_DELIVERABLES.map((d) =>
                  <tr key={d.included}>
                      <th scope="row">{d.included}</th>
                      <td>{d.means}</td>
                    </tr>
                  )}
                </tbody>
              </table>
            </div>
            <div className="clarity-card">
              <p className="clarity-card__label">Best for</p>
              <ul className="clarity-card__list clarity-card__list--soft">
                {CLARITY_BEST_FOR.map((d) => <li key={d}>{d}</li>)}
              </ul>
            </div>
          </div>
        </div>
      </div>
    </section>);

}

function TopicsSection({ randomize, ivfMode, onPaid, onWaitlist, onGuide }) {
  const order = useMemo(() => getTopicOrder(randomize), [randomize]);
  return (
    <section className="section topics" id="topics">
      <div className="shell">
        <div className="topics-head">
          <div>
            <p className="section-eyebrow">03 / Coaching paths</p>
            <h2 className="h-display-l">Four coaching paths. One clinical method.</h2>
          </div>
          <p className="text-muted">
            Each Clarity Session is a 45-minute call with a certified health coach. You leave with
            a structured decision map, a starter lifestyle protocol, and a clear question list for
            your clinician. Sessions are research-led, physician-reviewed, and non-medical by design.
          </p>
        </div>

        <div className="topics-grid">
          {order.map((id, i) =>
          <TopicCard
            key={id}
            topic={TOPIC_DATA[id]}
            position={i + 1}
            ivfMode={ivfMode}
            onPaid={onPaid}
            onWaitlist={onWaitlist}
            onGuide={onGuide} />

          )}
        </div>

        <ScopeNote />
      </div>
    </section>);

}

function ScopeNote() {
  const ref = useRef(null);
  useEffect(() => {
    if (!ref.current) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {
          track('scope_disclaimer_view', {});
          io.disconnect();
        }
      });
    }, { threshold: 0.6 });
    io.observe(ref.current);
    return () => io.disconnect();
  }, []);
  return (
    <p className="scope-note" ref={ref}>
      <strong>Scope.</strong> YUEVA Clarity Sessions are health-coaching sessions. They are
      educational and navigational and do not provide diagnosis, treatment, prescribing, or
      individualized medical advice. They help you understand your options, build supportive
      lifestyle protocols, and prepare clinical questions for licensed clinicians.
    </p>);

}

/* ----------------------------------------------------------
   How it works
   ---------------------------------------------------------- */
const STEPS = [
{
  n: '01',
  t: 'Choose your path',
  c: 'Tell us where you are. Perimenopause, thyroid, longevity, or fertility transition.'
},
{
  n: '02',
  t: 'Pre-call intake',
  c: 'A short clinical questionnaire so the session focuses on your physiology, not generic advice.'
},
{
  n: '03',
  t: '45-minute Clarity Session',
  c: 'A research-led call with a certified health coach. We organize what you know and map what is next.'
},
{
  n: '04',
  t: 'Your decision map',
  c: 'Leave with a structured decision map, a starter protocol, and clinical questions for your doctor.'
}];


/* ----------------------------------------------------------
   Journey ladder — Free Guide → Clarity → 1:1 → Community/Retreats
   ---------------------------------------------------------- */
const JOURNEY = [
{
  n: '01',
  pill: 'Free',
  title: 'Free Longevity Guide + Community',
  copy:
  'Research-led starting point for perimenopause, thyroid, and longevity decisions. Includes optional access to our private DACH community on WhatsApp and Lu.ma.',
  cta: 'Start free',
  href: '#guide'
},
{
  n: '02',
  pill: '€89',
  title: 'Clarity Session',
  copy:
  '45-minute research-led Clarity Session delivered by experienced, certified health coaches. Structured decision map and written Clarity Summary included.',
  cta: 'Book Clarity Session',
  href: '#topics'
},
{
  n: '03',
  pill: '€399–599',
  title: '1:1 Health Coaching Package',
  copy:
  'Personalized lifestyle protocol for sleep, mood, metabolism, and thyroid balance. Follow-up calls and structured accountability across six weeks.',
  cta: 'See packages',
  href: '#topics'
},
{
  n: '04',
  pill: 'Members',
  title: 'Ongoing Community and Retreats',
  copy:
  'Member community and quarterly retreats in Provence and Mallorca. Long-form coaching for women already inside the YUEVA method.',
  cta: 'Explore retreats',
  href: '#guide'
}];


function JourneySection() {
  return (
    <section className="section section--light journey" id="journey">
      <div className="shell">
        <div className="section-head journey-head">
          <p className="section-eyebrow">04 / The YUEVA method</p>
          <h2 className="h-display-l">From clarity to lasting confidence. At your own pace.</h2>
          <p className="lede" style={{ marginTop: '1rem' }}>
            Four steps. No contracts. No upsell pressure. Start anywhere. Move as life changes.
          </p>
        </div>

        <ol className="journey-ladder" aria-label="The YUEVA coaching journey">
          {JOURNEY.map((j, i) =>
          <li className="journey-step" key={j.n}>
              <div className="journey-step__top">
                <span className="journey-step__num">{j.n}</span>
                <span className="journey-step__pill">{j.pill}</span>
              </div>
              <h3 className="journey-step__title">{j.title}</h3>
              <p className="journey-step__copy">{j.copy}</p>
              <a className="journey-step__cta" href={j.href}>
                {j.cta} <span aria-hidden="true">→</span>
              </a>
              {i < JOURNEY.length - 1 && <span className="journey-step__arrow" aria-hidden="true" />}
            </li>
          )}
        </ol>

        <p className="journey-foot">
          Every step is optional. Start anywhere. Move at your pace.
        </p>
      </div>
    </section>);

}

/* ----------------------------------------------------------
   Trust strip — community / sessions / retreats
   Notes:
   - All numbers below are PLACEHOLDERS. Do not publish without
     real audited figures. TODO: replace with real community
     and engagement metrics before launch.
   ---------------------------------------------------------- */
const TRUST_STATS = [
{ num: '500+', label: 'Women in the YUEVA DACH community', accent: '500' },
{ num: '€89', label: '45-minute Clarity Session. Entry point.', accent: '€89' },
{ num: '2 / yr', label: 'Quarterly retreats. Provence and Mallorca.', accent: '2' }];


function TrustStrip() {
  return (
    <section className="trust" aria-label="At-a-glance trust signals">
      <div className="shell">
        <div className="trust-grid" role="list">
          {TRUST_STATS.map((s) =>
          <div className="trust-stat" key={s.label} role="listitem">
              <p className="trust-stat__num">
                {s.num.split(s.accent).map((part, i, arr) =>
              <React.Fragment key={i}>
                    {part}
                    {i < arr.length - 1 && <span className="accent">{s.accent}</span>}
                  </React.Fragment>
              )}
              </p>
              <p className="trust-stat__label">{s.label}</p>
            </div>
          )}
        </div>
      </div>
    </section>);

}

/* ----------------------------------------------------------
   Testimonials — compliant: first names + region only,
   no medical outcomes promised; presence-of-experience only.
   TODO: REPLACE with real signed/consented testimonials before launch.
   Do not publish placeholder quotes as real social proof.
   ---------------------------------------------------------- */
const TESTIMONIALS = [
{
  quote:
  'For the first time, I walked into my gynecologist with a real list of questions. I left feeling heard.',
  name: 'Anneliese',
  region: '44 · Munich'
},
{
  quote:
  'YUEVA gave me a way to organize what I already knew about my body. The protocol was sensible and actually livable.',
  name: 'Sofia',
  region: '38 · Vienna'
},
{
  quote:
  'I had spent two years being told it was stress. One conversation here gave me language and a path I could hold on to.',
  name: 'Camille',
  region: '47 · Zürich'
}];


function TestimonialsSection() {
  return (
    <section className="testimonials" aria-labelledby="testimonials-title">
      <div className="shell">
        <div className="section-head" style={{ marginBottom: 0 }}>
          <p className="section-eyebrow">IN THEIR WORDS</p>
          <h2 className="h-display-l" id="testimonials-title">
            Women who came to us tired of being dismissed.
          </h2>
        </div>
        <div className="testimonial-grid" role="list">
          {TESTIMONIALS.map((t) =>
          <figure className="testimonial" key={t.name} role="listitem">
              <blockquote className="testimonial__quote">{t.quote}</blockquote>
              <figcaption className="testimonial__attr">
                <strong>{t.name}</strong> · {t.region}
              </figcaption>
            </figure>
          )}
        </div>
      </div>
    </section>);

}

/* ----------------------------------------------------------
   Clarity Session Section (replaces legacy HowItWorks)
   Editorial register — gold rule motif, italic display, sharp corners.
   Three sub-blocks: Reframe → Journey → Deliverables → CTA.
   All animations scroll-triggered via IntersectionObserver and
   respect prefers-reduced-motion.
   ---------------------------------------------------------- */
/* ----------------------------------------------------------
   Clarity Session Section (replaces legacy HowItWorks)
   Reuses the site design system: Geist + IBM Plex Mono, sage accent,
   existing .section-eyebrow / .h-display-l / .lede / .btn classes.
   Three sub-blocks: Reframe → Journey (interactive) → Deliverables.
   All animations scroll-triggered via IntersectionObserver and
   respect prefers-reduced-motion.
   ---------------------------------------------------------- */

const CS_EASE = 'cubic-bezier(0.22, 0.61, 0.36, 1)';

// Hook: reveal on scroll. Returns a ref + visible flag.
function useReveal(threshold = 0.2) {
  const ref = useRef(null);
  const [visible, setVisible] = useState(false);
  useEffect(() => {
    const node = ref.current;
    if (!node) return;
    if (typeof window !== 'undefined' &&
    window.matchMedia &&
    window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
      setVisible(true);
      return;
    }
    const io = new IntersectionObserver(
      (entries) => {
        entries.forEach((e) => {
          if (e.isIntersecting) {
            setVisible(true);
            io.disconnect();
          }
        });
      },
      { threshold, rootMargin: '0px 0px -8% 0px' }
    );
    io.observe(node);
    return () => io.disconnect();
  }, [threshold]);
  return [ref, visible];
}

// Animated wrapper used for every reveal element.
// TYPE FIX — removed `width: "1000px"` inline style; it was forcing every
// CSReveal to a fixed 1000px width which clipped/overflowed sections on
// any viewport narrower than 1000px and broke the type system layout.
function CSReveal({ visible, delay = 0, from = 'up', distance = 20, duration = 600, style, children, ...rest }) {
  const map = {
    up: `translateY(${distance}px)`,
    down: `translateY(-${distance}px)`,
    left: `translateX(${distance}px)`,
    right: `translateX(-${distance}px)`,
    none: 'none'
  };
  return (
    <div
      {...rest}
      style={{
        opacity: visible ? 1 : 0,
        transform: visible ? 'none' : map[from],
        transition: `opacity ${duration}ms ${CS_EASE} ${delay}ms, transform ${duration}ms ${CS_EASE} ${delay}ms`,
        ...style
      }}>
      {children}
    </div>);

}

/* ---- Sub-block 1: Reframe ---- */
function CSReframe() {
  const [ref, visible] = useReveal(0.2);
  return (
    <div ref={ref} className="cs-reframe">
      <CSReveal visible={visible} duration={500}>
        <p className="section-eyebrow" style={{ margin: 0 }}>Clarity Session</p>
      </CSReveal>
      <CSReveal visible={visible} delay={120} duration={600}>
        <h2 className="h-display-l" style={{ margin: '1.25rem 0 0', textWrap: 'balance' }}>
          You already know something is off.{' '}
          <span style={{ color: 'var(--fg-muted)' }}>We help you understand what to do next.</span>
        </h2>
      </CSReveal>
      <CSReveal visible={visible} delay={260} duration={500}>
        <p className="lede" style={{ marginTop: '1.5rem' }}>
          You have read the articles. You have tracked the symptoms. You have sat in a doctor's
          appointment and left with more questions than answers. A YUEVA Clarity Session is not
          another consultation. It is a structured 45-minute conversation that organizes what
          you already know, identifies what is still unclear, and gives you a concrete list of
          next steps — including the exact questions to bring to your own physician.
        </p>
      </CSReveal>
    </div>);

}

/* ---- Sub-block 2: Journey (interactive) ---- */
const CS_JOURNEY_STEPS = [
{
  n: '01',
  title: 'Book your Clarity Session',
  copy: 'Find the right time for a brief call and tell us where you are.',
  image: 'assets/journey-step-1.png',
  imageAlt: 'Choosing a Clarity Session topic on the YUEVA app'
},
{
  n: '02',
  title: 'Complete the pre-session intake',
  copy: 'A short written questionnaire so the session focuses on your situation, not generic patterns.',
  image: 'assets/journey-step-2.png',
  imageAlt: 'Scheduling a Clarity Session on the YUEVA app'
},
{
  n: '03',
  title: 'Your 45-minute Clarity Session',
  copy: 'A structured conversation with a YUEVA navigator. We organize what you know and map what is next.',
  image: 'assets/journey-step-3.png',
  imageAlt: 'A certified YUEVA navigator on a video Clarity Session'
},
{
  n: '04',
  title: 'Receive your decision summary',
  copy: 'A written document delivered within 24 hours. Yours to keep and bring to any appointment.',
  image: 'assets/journey-step-4.png',
  imageAlt: 'YUEVA decision summary dashboard'
}];


function CSJourney() {
  const [headRef, headVisible] = useReveal(0.25);
  const [bodyRef, bodyVisible] = useReveal(0.15);
  const [active, setActive] = useState(0);

  const select = (i) => {
    setActive(i);
  };

  return (
    <div className="cs-journey">
      <div ref={headRef} className="cs-journey__head">
        <CSReveal visible={headVisible} duration={500}>
          <p className="section-eyebrow" style={{ margin: 0 }}>Your Journey</p>
        </CSReveal>
        <CSReveal visible={headVisible} delay={120} duration={600}>
          <h2 className="h-display-l cs-journey__title" style={{ margin: '1.25rem 0 0' }}>
            <span className="cs-journey__title-line">You already know something is off.</span>
            <span className="cs-journey__title-line" style={{ color: 'var(--sage)' }}>We help you understand what to do next.</span>
          </h2>
        </CSReveal>
        <CSReveal visible={headVisible} delay={260} duration={500}>
          <p className="lede" style={{ marginTop: '1.25rem' }}>You have read the articles. You have tracked the symptoms. You have sat in a doctor's appointment and left with more questions than answers. A YUEVA Clarity Session is not another consultation.
We listen first. We organize what you described and surface what is still unclear. You leave with a written summary and a concrete list of next steps and recommendations.


          </p>
        </CSReveal>
      </div>

      <div ref={bodyRef} className="cs-journey__stage" aria-roledescription="journey">
        <CSReveal visible={bodyVisible} duration={600}>
          <div className="cs-tracklane" role="tablist" aria-label="Clarity Session steps">
            {CS_JOURNEY_STEPS.map((s, i) => {
              const isActive = i === active;
              return (
                <div
                  key={s.n}
                  className={`cs-step ${isActive ? 'is-active' : ''}`}>
                  <button
                    type="button"
                    role="tab"
                    aria-selected={isActive}
                    aria-label={`Step ${i + 1}: ${s.title}`}
                    className="cs-tile"
                    onClick={() => select(i)}>
                    <span className="cs-tile__frame" aria-hidden="true">
                      <img
                        src={s.image}
                        alt={s.imageAlt}
                        className="cs-tile__img"
                        loading="lazy"
                        decoding="async" />
                      <span className="cs-tile__overlay" />
                    </span>
                  </button>
                  <button
                    type="button"
                    className={`cs-step__label ${isActive ? 'is-active' : ''}`}
                    onClick={() => select(i)}
                    aria-label={`Go to step ${i + 1}`}>
                    <span>Step {i + 1}</span>
                  </button>
                </div>);

            })}
            <span className="cs-tracklane__rule" aria-hidden="true" />
            <span
              className="cs-tracklane__progress"
              aria-hidden="true"
              style={{ '--cs-progress': `${(active + 1) / CS_JOURNEY_STEPS.length * 100}%` }} />
          </div>
        </CSReveal>

        <CSReveal visible={bodyVisible} delay={280} duration={500}>
          <div className="cs-caption" aria-live="polite">
            <div
              key={CS_JOURNEY_STEPS[active].n}
              className="cs-caption__inner">
              <h3 className="cs-caption__title">{CS_JOURNEY_STEPS[active].title}</h3>
              <p className="cs-caption__copy">{CS_JOURNEY_STEPS[active].copy}</p>
            </div>
          </div>
        </CSReveal>
      </div>

      <CSReveal visible={bodyVisible} delay={420} duration={500}>
        <p className="cs-included">
          <em>Included.</em> A structured symptom and goal summary · Your top 2–3 priority areas · A doctor discussion list · A biomarker and testing preparation checklist · Clear next steps (what to test, track, prepare or escalate).
        

        </p>
      </CSReveal>
    </div>);

}

/* ---- Sub-block 3: Deliverables ---- */
const CS_DELIVERABLES = [
{ name: 'Structured symptom and goal summary', desc: 'We organize the patterns you described in your own words.' },
{ name: 'Your top priority areas', desc: 'The 2–3 themes that need the most clarity right now.' },
{ name: 'Doctor discussion list', desc: 'Specific questions to bring to your clinician or lab appointment.' },
{ name: 'Biomarker and testing preparation checklist', desc: 'What to prepare before testing, depending on your situation.' },
{ name: 'One clear next step', desc: 'Whether to test, track, wait, prepare, or escalate — and why.' }];


function CSDeliverables() {
  const [ref, visible] = useReveal(0.2);
  return (
    <div ref={ref} className="cs-deliverables">
      <div className="cs-deliverables__grid">
        <CSReveal visible={visible} from="right" distance={24} duration={600}>
          <p className="section-eyebrow" style={{ margin: 0 }}>What You Receive</p>
          <h2 className="h-display-m" style={{ margin: '1.25rem 0 0' }}>
            Not a recommendation.{' '}
            <span style={{ color: 'var(--sage)' }}>A map.</span>
          </h2>
          <p className="lede" style={{ marginTop: '1.25rem', maxWidth: '440px' }}>
            We do not tell you what to do. We give you the clearest possible picture of where
            you are, what the evidence says about your situation, and what your most important
            next question is. Every Clarity Session produces the same five outputs — structured,
            written, and yours.
          </p>
        </CSReveal>

        <ol className="cs-deliverables__list">
          {CS_DELIVERABLES.map((d, i) =>
          <CSReveal
            key={d.name}
            visible={visible}
            from="left"
            distance={24}
            duration={500}
            delay={120 + i * 60}>
              <li className="cs-deliverable">
                <span className="cs-deliverable__name">{d.name}</span>
                <span className="cs-deliverable__desc">{d.desc}</span>
              </li>
            </CSReveal>
          )}
        </ol>
      </div>
    </div>);

}

/* ---- CTA block ---- */
function CSCallToAction({ onApply }) {
  const [ref, visible] = useReveal(0.3);
  return (
    <div ref={ref} className="cs-cta">
      <CSReveal visible={visible} duration={700} distance={16}>
        <figure className="cs-cta__media">
          <img
            src="assets/ready-to-stop-guessing-cutout.png"
            alt="Editorial portrait — woman in cream blazer, hand resting near her face"
            loading="lazy"
            decoding="async" />
        </figure>
      </CSReveal>
      <div className="cs-cta__body">
        <CSReveal visible={visible} delay={120} duration={600}>
          <h2 className="h-display-m" style={{ margin: 0 }}>
            Ready to stop guessing?
          </h2>
        </CSReveal>
        <CSReveal visible={visible} delay={240} duration={500}>
          <p className="lede" style={{ marginTop: '1rem' }}>
            Book a 45-minute Clarity Session for €89. No medical advice. No protocols.
            Just clarity.
          </p>
        </CSReveal>
        <CSReveal visible={visible} delay={360} duration={500}>
          <div className="cs-cta__row">
            <a
              className="btn"
              href={CLARITY_BOOKING_URL}
              target="_blank"
              rel="noopener noreferrer"
              data-track="cs_clarity_cta_click">
              Book a Clarity Session <span className="arrow" aria-hidden="true">→</span>
            </a>
            <a className="cs-cta__link" href={TYPEFORM_GUIDE_URL} target="_blank" rel="noopener noreferrer">
              Get the free Hormone &amp; Biomarker Guide <span aria-hidden="true">→</span>
            </a>
          </div>
        </CSReveal>
        <CSReveal visible={visible} delay={480} duration={500}>
          <p className="text-faint cs-cta__legal">
            YUEVA provides educational navigation and research support only. We do not offer
            medical advice, diagnosis, or treatment. Always consult a qualified healthcare
            professional.
          </p>
        </CSReveal>
      </div>
    </div>);

}

function ClaritySessionSection({ onApply }) {
  return (
    <section className="section cs-section cs-section--light" id="how">
      <style>{`
        .cs-section.cs-section--light {
          background: #ffffff;
          color: #0c0d0c;
          /* Scoped token overrides so all descendants flip to light mode */
          --fg: #0c0d0c;
          --fg-muted: #5d5f57;
          --fg-faint: #8b8d86;
          --bg: #ffffff;
          --bg-elev: #f4f3ee;
          --bg-elev-2: #e9e7df;
          --line: rgba(12, 13, 12, 0.10);
          --line-strong: rgba(12, 13, 12, 0.18);
          --sage-glow: rgba(148, 180, 159, 0.20);
        }
        .cs-section.cs-section--light .section-eyebrow { color: var(--fg-muted); }
        .cs-section.cs-section--light .section-eyebrow::before { background: var(--sage-deep, #94B49F); }
        .cs-section.cs-section--light .lede { color: var(--fg-muted); }
        .cs-section.cs-section--light .h-display-l,
        .cs-section.cs-section--light .h-display-m { color: var(--fg); }
        .cs-section { padding: clamp(2.5rem, 4vw, 3.5rem) 0 clamp(3.5rem, 6vw, 6rem); }
        .cs-section .cs-reframe,
        .cs-section .cs-journey,
        .cs-section .cs-deliverables,
        .cs-section .cs-cta { max-width: var(--container-max); }

        .cs-reframe { max-width: 760px; }
        .cs-journey { margin-top: clamp(80px, 10vw, 120px); }
        .cs-deliverables { margin-top: clamp(80px, 10vw, 120px); }
        .cs-cta {
          margin-top: clamp(80px, 10vw, 120px);
          max-width: clamp(320px, 92vw, 1080px);
          margin-left: auto;
          margin-right: auto;
          display: flex;
          flex-direction: column;
          align-items: center;
          gap: clamp(1.5rem, 3vw, 2.5rem);
          text-align: center;
        }
        .cs-cta__media {
          margin: 0 auto;
          display: block;
          width: 100%;
          max-width: clamp(320px, 48vw, 560px);
          overflow: visible;
          background: transparent;
        }
        .cs-cta__media img {
          display: block;
          width: 100%;
          height: auto;
          margin: 0 auto;
        }
        .cs-cta__body {
          display: flex;
          flex-direction: column;
          align-items: center;
          text-align: center;
          max-width: clamp(320px, 80vw, 720px);
        }
        /* CSReveal wraps each child in a <div>. In a flex column those wrappers
           shrink to content width, which can leave inline-content children
           (like a button row) anchored off-axis. Force the wrappers full-width
           and center-justified so every block lines up under the headline. */
        .cs-cta__body > div {
          width: 100%;
          display: flex;
          flex-direction: column;
          align-items: center;
        }
        .cs-cta__body .h-display-m { text-align: center; }
        .cs-cta__body .lede {
          margin-left: auto;
          margin-right: auto;
          text-align: center;
        }
        .cs-cta__row {
          margin-top: 32px;
          display: flex;
          justify-content: center;
          align-items: center;
          gap: 20px;
          flex-wrap: wrap;
        }
        .cs-cta__legal {
          margin-top: 32px;
          font-size: var(--fs-caption);
          line-height: 1.6;
          max-width: 520px;
          margin-left: auto;
          margin-right: auto;
          text-align: center;
        }

        /* --- Journey: interactive circle→square tiles ---
           All sub-blocks share the same outer width grid so the eyebrow,
           headline, lede, step row, caption and "included" line all read
           as a single centered editorial column. */
        .cs-journey { text-align: center; }
        .cs-journey__head,
        .cs-journey__stage,
        .cs-included {
          max-width: clamp(320px, 92vw, 1080px);
          margin-left: auto;
          margin-right: auto;
        }
        .cs-journey__head { margin-top: 0; }
        .cs-journey__title-line {
          display: block;
          /* On wide screens the journey head expands to its outer cap, so the
             black line and the sage line each get their own row. text-wrap:
             balance keeps the wrap point tidy when a smaller viewport forces
             a 2-line black headline. */
          text-wrap: balance;
        }
        @media (max-width: 720px) {
          .cs-journey__title-line { text-wrap: balance; }
        }
        .cs-journey__head .section-eyebrow { justify-content: center; }
        .cs-journey__head .h-display-l { text-align: center; }
        .cs-journey__head .lede {
          max-width: clamp(320px, 94vw, 1200px);
          margin-left: auto;
          margin-right: auto;
          text-align: center;
        }
        .cs-caption {
          max-width: clamp(320px, 80vw, 720px);
          margin-left: auto;
          margin-right: auto;
          text-align: center;
        }
        .cs-journey__stage {
          margin-top: clamp(36px, 5vw, 56px);
        }

        /* Row of 4 equal columns — each tile centered in its column so the
           row stays symmetric regardless of which step is the large square. */
        .cs-tracklane {
          position: relative;
          display: grid;
          grid-template-columns: repeat(4, 1fr);
          align-items: end;
          gap: clamp(8px, 1.5vw, 24px);
          padding-bottom: 56px;
        }
        .cs-step {
          display: flex;
          flex-direction: column;
          align-items: center;
          gap: clamp(20px, 2.5vw, 28px);
          justify-self: center;
        }
        .cs-tile {
          position: relative;
          padding: 0;
          border: none;
          background: none;
          cursor: pointer;
          display: inline-flex;
          align-items: center;
          justify-content: center;
          outline: none;
        }
        .cs-tile__frame {
          position: relative;
          display: block;
          overflow: hidden;
          width: 140px;
          height: 140px;
          border-radius: 999px;
          background: var(--bg-elev);
          border: 1px solid var(--line);
          transition:
            width 600ms var(--ease),
            height 600ms var(--ease),
            border-radius 600ms var(--ease),
            border-color 600ms var(--ease),
            box-shadow 600ms var(--ease);
          box-shadow: 0 6px 24px -16px rgba(0,0,0,0.6);
        }
        .cs-step.is-active .cs-tile__frame {
          width: clamp(240px, 28vw, 340px);
          height: clamp(240px, 28vw, 340px);
          border-radius: 20px;
          border-color: var(--line-strong);
          box-shadow: 0 24px 60px -28px rgba(0,0,0,0.8);
        }
        .cs-tile__img {
          position: absolute;
          inset: 0;
          width: 100%;
          height: 100%;
          object-fit: cover;
          filter: grayscale(0.15) saturate(0.95);
          transition: filter 600ms var(--ease), transform 600ms var(--ease);
          transform: scale(1.04);
        }
        .cs-step.is-active .cs-tile__img {
          filter: none;
          transform: scale(1);
        }
        .cs-tile__overlay {
          position: absolute;
          inset: 0;
          background: rgba(12, 13, 12, 0.42);
          transition: background 600ms var(--ease);
        }
        .cs-step.is-active .cs-tile__overlay { background: rgba(12, 13, 12, 0); }
        .cs-tile:hover .cs-tile__frame { border-color: var(--sage); }
        .cs-step:not(.is-active) .cs-tile:hover .cs-tile__overlay { background: rgba(12, 13, 12, 0.25); }
        .cs-tile:focus-visible .cs-tile__frame {
          border-color: var(--sage);
          box-shadow: 0 0 0 3px var(--sage-glow);
        }

        /* Step label centered under each tile */
        .cs-step__label {
          background: none;
          border: none;
          padding: 0;
          font-family: var(--font-mono);
          font-size: var(--fs-eyebrow);
          letter-spacing: var(--ls-eyebrow);
          text-transform: uppercase;
          color: var(--fg-faint);
          cursor: pointer;
          text-align: center;
          transition: color var(--dur) var(--ease);
        }
        .cs-step__label span {
          display: inline-block;
          padding: 4px 10px;
          border: 1px solid transparent;
          border-radius: 999px;
          font-size: 11px;
          transition: background var(--dur) var(--ease), color var(--dur) var(--ease), border-color var(--dur) var(--ease);
        }
        .cs-step__label:hover { color: var(--fg-muted); }
        .cs-step__label.is-active { color: var(--fg); }
        .cs-step__label.is-active span {
          background: var(--fg);
          color: var(--bg);
          border-color: var(--fg);
        }

        /* Horizontal rule across the whole track with sage progress */
        .cs-tracklane__rule {
          position: absolute;
          left: 0; right: 0; bottom: 0;
          height: 1px;
          background: var(--line);
        }
        .cs-tracklane__progress {
          position: absolute;
          left: 0; bottom: 0;
          height: 2px;
          width: var(--cs-progress, 25%);
          background: var(--sage);
          transition: width 600ms var(--ease);
        }

        .cs-caption {
          margin: clamp(28px, 3vw, 36px) auto 0;
        }
        .cs-caption__inner {
          animation: cs-caption-in 600ms var(--ease);
        }
        @keyframes cs-caption-in {
          from { opacity: 0; transform: translateY(8px); }
          to { opacity: 1; transform: none; }
        }
        @media (prefers-reduced-motion: reduce) {
          .cs-caption__inner { animation: none; }
        }
        .cs-caption__title {
          font-family: var(--font-display);
          font-weight: 500;
          font-size: var(--fs-display-s);
          line-height: var(--lh-heading);
          letter-spacing: var(--ls-heading);
          color: var(--fg);
          margin: 0;
        }
        .cs-caption__copy {
          font-size: var(--fs-body);
          line-height: var(--lh-body);
          color: var(--fg-muted);
          margin: 12px 0 0;
        }

        .cs-included {
          margin: clamp(40px, 5vw, 56px) auto 0;
          max-width: clamp(320px, 88vw, 960px);
          font-size: var(--fs-body-s);
          line-height: 1.7;
          color: var(--fg-muted);
          text-align: center;
        }
        .cs-included em {
          font-style: italic;
          color: var(--fg);
          margin-right: 4px;
        }

        /* --- Deliverables --- */
        .cs-deliverables__grid {
          display: grid;
          grid-template-columns: 1fr 1fr;
          gap: clamp(40px, 6vw, 96px);
          align-items: start;
        }
        .cs-deliverables__list {
          list-style: none;
          padding: 0;
          margin: 0;
        }
        .cs-deliverable {
          border-top: var(--hairline);
          padding: 22px 0;
          display: flex;
          flex-direction: column;
          gap: 6px;
        }
        .cs-deliverable__name {
          font-family: var(--font-sans);
          font-weight: 500;
          font-size: var(--fs-body-s);
          color: var(--fg);
          line-height: 1.4;
        }
        .cs-deliverable__desc {
          font-size: var(--fs-caption);
          line-height: 1.55;
          color: var(--fg-muted);
        }

        /* --- CTA --- */
        .cs-cta__row {
          margin-top: 32px;
          display: flex;
          justify-content: flex-start;
          align-items: center;
          gap: 20px;
          flex-wrap: wrap;
        }
        .cs-cta__link {
          font-family: var(--font-sans);
          font-size: var(--fs-body-s);
          color: var(--fg-muted);
          border-bottom: 1px solid transparent;
          padding-bottom: 2px;
          transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
        }
        .cs-cta__link:hover {
          color: var(--fg);
          border-bottom-color: var(--sage);
        }

        /* Responsive */
        @media (max-width: 760px) {
          .cs-cta__media { max-width: clamp(260px, 70vw, 420px); }
        }
        @media (max-width: 900px) {
          .cs-tracklane {
            gap: 12px;
            overflow-x: auto;
            padding-bottom: 56px;
          }
          .cs-tile__frame { width: 96px; height: 96px; }
          .cs-step.is-active .cs-tile__frame {
            width: clamp(200px, 64vw, 280px);
            height: clamp(200px, 64vw, 280px);
            border-radius: 18px;
          }
          .cs-deliverables__grid { grid-template-columns: 1fr; gap: 32px; }
        }
        @media (max-width: 560px) {
          .cs-step__label { font-size: 11px; }
          .cs-step__label span { padding: 4px 8px; }
        }
      `}</style>
      <div className="shell">
        <CSJourney />
        <CSCallToAction onApply={onApply} />
      </div>
    </section>);

}


/* ----------------------------------------------------------
   Studies — "We study the studies so you don't have to"
   Curated research teasers across the four YUEVA topic areas.
   All summaries cite generalized peer-reviewed direction, not specific
   trials. TODO: link each to a proper internal summary page with
   full citations once research microsite is live.
   ---------------------------------------------------------- */
const STUDIES = [
{
  id: 'peri-thyroid',
  date: '05 / 03 / 2026',
  readMin: 12,
  headline: 'When perimenopause and thyroid dysfunction overlap: the case for paired-marker testing in women aged 35 to 50',
  image: 'assets/study-thyroid.jpg',
  imageAlt: 'Editorial black-and-white portrait — woman resting in soft light',
  href: 'study-peri-thyroid.html'
},
{
  id: 'ovarian-health',
  date: '04 / 21 / 2026',
  readMin: 9,
  headline: 'The limits of AMH and AFC: why single-marker fertility planning misses the real clinical picture',
  image: 'assets/symptom-cycle.png',
  imageAlt: 'Ovarian ultrasound reference',
  comingSoon: true
},
{
  id: 'hrt-evidence',
  date: '03 / 08 / 2026',
  readMin: 18,
  headline: 'Twenty years after WHI: what the updated literature now says about HRT timing, formulation, and personal risk',
  image: 'assets/study-hrt.jpg',
  imageAlt: 'Still life — water glass and hormone capsules in soft natural light',
  comingSoon: true
},
{
  id: 'lifestyle-metabolic',
  date: '02 / 14 / 2026',
  readMin: 11,
  headline: 'Resistance training and protein dosing: how women over 35 build body composition, insulin sensitivity, and bone density',
  image: 'assets/study-protein.jpg',
  imageAlt: 'Flat lay — spoons of protein powder on marble surface'
}];


function StudiesSection() {
  return (
    <section className="section section--light studies" id="studies" aria-labelledby="studies-title">
      <div className="shell">
        <div className="section-head studies-head">
          <p className="section-eyebrow">EVIDENCE LIBRARY</p>
          <h2 className="h-display-l" id="studies-title">We study the studies so you don't have to.</h2>
          <p className="lede" style={{ marginTop: '1rem' }}>
            Curated peer-reviewed research, translated into clinical questions you can bring to
            your next appointment. Updated as the literature evolves.
          </p>
        </div>

        <ul className="studies-grid" aria-label="Curated research teasers">
          {STUDIES.map((s, i) => {
            // Zigzag pattern: images face outward of each row.
            // Positions 0 and 3 = image on left; 1 and 2 = image on right.
            const imgRight = i === 1 || i === 2;
            return (
              <li
                className="study-card"
                key={s.id}
                data-img={imgRight ? 'right' : 'left'}>
                
                <figure className="study-card__mat" aria-hidden="true">
                  <img
                    className="study-card__img"
                    src={s.image}
                    alt={s.imageAlt}
                    loading="lazy"
                    decoding="async" />
                  
                </figure>
                <div className="study-card__body">
                  <p className="study-card__meta">
                    {s.comingSoon ? (
                      <span className="study-card__date">To be released soon</span>
                    ) : (
                      <>
                        <span className="study-card__date" style={{ backgroundColor: "rgb(244, 243, 238)" }}>{s.date}</span>
                        <span className="study-card__dot" aria-hidden="true"></span>
                        <span className="study-card__read">{s.readMin} min read</span>
                      </>
                    )}
                  </p>
                  <h3 className="study-card__headline">{s.headline}</h3>
                  <a
                    className="study-card__cta"
                    href={s.href || `#study-${s.id}`}
                    data-track="study_summary_click"
                    data-study={s.id}>
                    
                    Read more <span aria-hidden="true">→</span>
                  </a>
                </div>
              </li>);

          })}
        </ul>

        <p className="studies-foot">
          Every summary is reviewed by our medical advisory before publication. We cite sources in
          each full summary.
        </p>
      </div>
    </section>);

}

/* ----------------------------------------------------------
   Boundary (do / don't)
   ---------------------------------------------------------- */
function BoundarySection() {
  return (
    <section className="section section--bone" id="scope">
      <div className="shell">
        <div className="section-head">
          <p className="section-eyebrow">06 / Scope</p>
          <h2 className="h-display-l">Health coaching, clearly defined.</h2>
          <p className="lede">
            We are certified health coaches, not clinicians. Our protocols and decision maps are
            developed in collaboration with and reviewed by licensed physicians. The boundaries
            below are how we keep coaching and medicine cleanly separated.
          </p>
        </div>

        <div className="boundary">
          <div className="boundary__col boundary__col--do">
            <div className="boundary__label"><span className="bar" /> We help you</div>
            <h3 className="boundary__head">Structured health coaching.</h3>
            <ul className="boundary__list">
              <li>track your symptoms and surface patterns over time,</li>
              <li>build sustainable lifestyle protocols for sleep, mood, energy, and metabolism,</li>
              <li>understand your options across hormones, thyroid, fertility, and longevity,</li>
              <li>prepare clear, confident questions for your doctor or clinic,</li>
              <li>compare paths, costs, and trade-offs without pressure,</li>
              <li>make sense of research, terminology, and lab vocabulary.</li>
            </ul>
          </div>

          <div className="boundary__col boundary__col--dont">
            <div className="boundary__label"><span className="bar" /> We do not</div>
            <h3 className="boundary__head">Practice medicine.</h3>
            <ul className="boundary__list">
              <li>diagnose any condition,</li>
              <li>prescribe medication, hormones, or supplements,</li>
              <li>provide individualized medical advice,</li>
              <li>replace your doctor, gynecologist, or endocrinologist,</li>
              <li>order tests or interpret labs as medical conclusions,</li>
              <li>provide emergency or acute care,</li>
              <li>recommend HRT or treatment protocols.</li>
            </ul>
          </div>
        </div>
      </div>
    </section>);

}

/* ----------------------------------------------------------
   Lead magnet — Longevity Guide
   ---------------------------------------------------------- */
const TOPIC_OPTIONS = [
{ v: 'fertility', l: 'Fertility planning or egg freezing' },
{ v: 'cycle', l: 'Cycle changes, PMS, or hormones' },
{ v: 'metabolism', l: 'Weight, metabolism, or energy' },
{ v: 'fatigue-sleep', l: 'Fatigue, sleep, or stress' },
{ v: 'thyroid', l: 'Thyroid or autoimmune concerns' },
{ v: 'unsure', l: 'I am not sure yet' }];


function GuideSection({ guideTopicSeed, onApply }) {
  const ctaRef = useRef(null);

  // Fire guide_form_view when the CTA enters viewport (once)
  useEffect(() => {
    if (!ctaRef.current) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {track('guide_form_view', {});io.disconnect();}
      });
    }, { threshold: 0.5 });
    io.observe(ctaRef.current);
    return () => io.disconnect();
  }, []);

  const handleClick = () => {
    track('guide_signup_submit', { source: 'guide_page_cta' });
  };

  return (
    <section className="section section--warm guide-section" id="guide">
      <div className="shell guide-grid">
        <div className="guide-copy">
          <p className="section-eyebrow">Free guide</p>
          <h2 className="h-display-l">The Hormone &amp; Biomarker Guide for Women.</h2>
          <p className="lede guide-lede">
            What to discuss with your doctor, when timing matters, and how to prepare before
            testing fertility, cycle health, energy, metabolism, and long-term health.
          </p>

          <ul className="guide-inside" aria-label="What is inside the guide">
            <li>When hormone testing may be worth discussing with a clinician.</li>
            <li>Which markers relate to cycle health, fertility planning, energy, thyroid, metabolism, cortisol, and nutrient status.</li>
            <li>Why timing in the menstrual cycle matters.</li>
            <li>How contraception, irregular cycles, stress, travel, illness, and supplements can affect results.</li>
            <li>How to prepare for a more useful doctor conversation.</li>
          </ul>

          <div ref={ctaRef} className="guide-cta">
            <a
              href="https://form.typeform.com/to/nhtRYylO"
              target="_blank"
              rel="noopener noreferrer"
              className="btn"
              onClick={handleClick}
              data-track="guide_signup_click">
              Get the Hormone &amp; Biomarker Guide <span className="arrow" aria-hidden="true">→</span>
            </a>
            <p className="guide-form-note">
              Free. Educational. Not medical advice.
            </p>
          </div>
        </div>

        <aside className="guide-media" aria-hidden="true">
          <img
            src="assets/guide-cover.png"
            alt="Hormone & Biomarker Guide cover — YUEVA Longevity"
            className="guide-cover"
            loading="eager"
            decoding="async"
            width="1080"
            height="1350" />
        </aside>
      </div>
    </section>);

}

/* ----------------------------------------------------------
   Expert-backed approach
   ---------------------------------------------------------- */
const EXPERT_DOMAINS = [
{ n: '01', name: 'Licensed physician input. Gynecology and reproductive health.' },
{ n: '02', name: 'Biologists and longevity researchers.' },
{ n: '03', name: 'Nutrition and metabolic health professionals.' },
{ n: '04', name: 'Clinic and lab operators across DACH.' }];


function ExpertSection() {
  return (
    <section className="section section--paper" id="approach">
      <div className="shell expert">
        <div>
          <p className="section-eyebrow">08 / Approach</p>
          <h2 className="h-display-l">Expert-informed. Physician-reviewed.</h2>
        </div>

        <div>
          <p className="lede" style={{ marginTop: 0 }}>
            YUEVA’s protocols and decision maps are developed in collaboration with and reviewed
            by licensed physicians. Our coaches are certified health coaches trained in women’s
            longevity. Medicine stays in the hands of clinicians.
          </p>
          <div className="expert-domains">
            {EXPERT_DOMAINS.map((d) =>
            <div className="expert-domain" key={d.n}>
                <span className="expert-domain__num">{d.n}</span>
                <span className="expert-domain__name">{d.name}</span>
              </div>
            )}
          </div>
          <p className="text-faint" style={{ marginTop: '1.5rem', fontSize: 'var(--fs-caption)' }}>
            We do not list names, credentials, or institutional logos at this stage. When pilots
            launch with named expert leads, this section will be updated.
          </p>
        </div>
      </div>
    </section>);

}

/* ----------------------------------------------------------
   Founder / operator credibility
   ---------------------------------------------------------- */
function FounderSection() {
  return (
    <section className="section section--bone founder-section" id="about">
      <div className="shell founder">
        <div className="founder-media">
          <img
            src="assets/founders-portrait.jpg"
            alt="YUEVA founders Laura Schaefer and Dr. Tamara Radaković in a quiet garden setting"
            className="founder-img"
            loading="eager"
            decoding="async"
            width="3808"
            height="5195" />
        </div>
        <div className="founder-copy">
          <p className="section-eyebrow">About YUEVA</p>
          <h2 className="h-display-l">Women’s longevity, approached differently.</h2>
          <p className="founder-subhead">Built in Europe for women who want clarity, not noise.</p>

          <p className="lede founder-lede">
            YUEVA helps women navigate hormones, fertility, perimenopause, thyroid health, and
            longevity with structured guidance grounded in science, prevention, and real-life
            practicality.
          </p>
          <p className="lede founder-lede">
            We created YUEVA because too many women are left piecing together fragmented
            information, conflicting advice, and symptoms that are often minimized or
            misunderstood.
          </p>
          <p className="lede founder-lede">
            Our approach combines evidence-based education, structured decision support,
            physician-informed thinking, and lifestyle optimization, helping women make more
            confident, informed choices about their health over time.
          </p>
        </div>
      </div>

      {/* Founders */}
      <div className="shell founder-team">
        <p className="section-eyebrow">Founders</p>
        <div className="founder-team__grid">
          <div className="founder-card">
            <p className="founder-card__role">Co-Founder · Strategy &amp; Longevity Research</p>
            <h3 className="founder-card__name">Laura Schaefer</h3>
            <p className="founder-card__copy">
              Laura leads YUEVA’s strategy, research translation, and ecosystem-building.
              With a background spanning technology, operations, business, private markets,
              and longevity-focused health optimization, she translates complex women’s
              health and longevity research into clear, structured guidance women can
              actually use.
            </p>
            <p className="founder-card__copy">
              Her work focuses on building the bridge between science, medical expertise,
              and the everyday questions women have about hormones, prevention, and
              long-term health.
            </p>
          </div>

          <div className="founder-card">
            <p className="founder-card__role">Co-Founder · Medical Lead</p>
            <h3 className="founder-card__name">Dr. Tamara Radaković</h3>
            <p className="founder-card__copy">
              Dr. Tamara Radaković leads the medical and product direction of YUEVA. As a
              physician focused on women’s health, hormones, metabolic health, and longevity
              medicine, she builds the clinical foundation behind YUEVA’s programs, evidence
              standards, and client experience.
            </p>
            <p className="founder-card__copy">
              Her work ensures that YUEVA’s guidance is medically grounded, practical, and
              individualized for women who want to understand and optimize their long-term health.
            </p>
          </div>
        </div>
      </div>

      {/* Connected approach */}
      <div className="shell founder-approach">
        <p className="section-eyebrow">Our approach</p>
        <h2 className="h-display-l">A connected approach to women’s health.</h2>
        <p className="lede founder-lede">
          Women’s health is rarely one-dimensional. Hormones, metabolism, fertility, stress,
          sleep, and longevity are deeply interconnected.
        </p>
        <p className="lede founder-lede">That is why YUEVA’s approach is informed not only by coaching and education, but also by ongoing exchange with a trusted network of physicians, scientists and health experts across multiple disciplines.



        </p>
        <p className="lede founder-lede">
          While YUEVA does not provide medical care, we believe women deserve better guidance in
          understanding when additional clinical support, testing, or specialist care may be
          worth exploring.
        </p>
      </div>
    </section>);

}

/* ----------------------------------------------------------
   Closing CTA strip
   ---------------------------------------------------------- */
function ClosingCTA({ onPaid, onGuide }) {
  return (
    <section className="closing">
      <div className="shell closing-grid">
        <div>
          <p className="section-eyebrow">NEXT STEP</p>
          <h2 className="h-display-l">Walk into your next appointment feeling prepared.</h2>
        </div>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.75rem', justifyContent: 'flex-end' }}>
          <a
            className="btn btn--on-dark"
            href={CLARITY_BOOKING_URL}
            target="_blank"
            rel="noopener noreferrer"
            data-track="closing_clarity_cta_click">
            Book a Clarity Session <span className="arrow" aria-hidden="true">→</span>
          </a>
          <button className="btn btn--ghost" onClick={onGuide} type="button">
            Get the free guide
          </button>
        </div>
      </div>
    </section>);

}

/* ----------------------------------------------------------
   Footer + Medical Disclaimer
   ---------------------------------------------------------- */
function Footer({ onCookieOpen }) {
  return (
    <footer className="footer" id="footer">
      <div className="shell">
        <div className="footer-grid">
          <div>
            <a href="index.html#top" aria-label="YUEVA Longevity — back to homepage" className="footer-wordmark-link">
              <img
                src="assets/Wordmark_Yueva_White.png"
                alt="YUEVA Longevity"
                className="footer-wordmark" />
            </a>
          </div>

          <div>
            <h4>YUEVA</h4>
            <ul>
              <li><a href="about.html">About</a></li>
              <li><a href={TYPEFORM_GUIDE_URL} target="_blank" rel="noopener noreferrer">Free Guide</a></li>
              <li><a href="index.html#studies">Evidence Library</a></li>
              <li><a href="#how">How it works</a></li>
            </ul>
          </div>

          <div>
            <h4>Legal</h4>
            <ul>
              <li><a href="legal.html#imprint">Imprint / Impressum</a></li>
              <li><a href="legal.html#privacy">Privacy Policy</a></li>
              <li><a href="legal.html#terms">Terms of Service</a></li>
              <li><a href="legal.html#disclaimer">Medical Disclaimer</a></li>
              <li><button onClick={onCookieOpen} className="btn--link" style={{ font: 'inherit', color: 'rgba(255,255,255,0.78)', borderBottomColor: 'rgba(255,255,255,0.4)', padding: 0 }}>Cookie preferences</button></li>
            </ul>
          </div>
        </div>

        <p className="footer-disclaimer" id="disclaimer">
          <strong style={{ color: 'var(--fg)' }}>Health-coaching disclaimer.</strong>{' '}
          YUEVA Clarity Sessions are health-coaching sessions. They are educational and
          navigational and do not provide diagnosis, treatment, prescribing, emergency care,
          individualized medical advice, HRT recommendations, or replacement of a qualified
          doctor. If you are experiencing a medical emergency, contact local emergency services.
          Always discuss treatment decisions with a licensed clinician.
        </p>

        <div className="footer-bottom">
          <span>© 2026 YUEVA Longevity · All rights reserved</span>
        </div>

        {/*
                                                                                                          TODO: Confirm final contracting entity and imprint.
                                                                                                          TODO: Legal review of paid-session scope.
                                                                                                          TODO: Confirm privacy policy and GDPR data controller.
                                                                                                          TODO: Confirm payment provider and cancellation terms.
                                                                                                          TODO: Confirm whether any medical professional is named publicly.
                                                                                                         */}
      </div>
    </footer>);

}

/* ----------------------------------------------------------
   Cookie consent
   ---------------------------------------------------------- */
function CookieBanner({ open, onAccept, onReject, onCustom }) {
  if (!open) return null;
  return (
    <div className="cookie" role="dialog" aria-labelledby="cookie-title">
      <h3 className="cookie__title" id="cookie-title">Cookies and analytics</h3>
      <p className="cookie__copy">
        We use a minimal set of cookies to make the site work and, with your consent, to measure
        which topics matter most to you. Analytics never fire before you accept. See{' '}
        <a href="legal.html#privacy" style={{ color: 'var(--sage)', textDecoration: 'underline' }}>Privacy</a>.
      </p>
      <div className="cookie__actions">
        <button className="btn" onClick={onAccept} type="button">Accept all</button>
        <button className="btn btn--ghost" onClick={onReject} type="button">Reject non-essential</button>
        <button className="btn--link" onClick={onCustom} type="button">Customize</button>
      </div>
    </div>);

}

/* ----------------------------------------------------------
   Waitlist modal
   ---------------------------------------------------------- */
function WaitlistModal({ topic, onClose }) {
  const [email, setEmail] = useState('');
  const [stage, setStage] = useState('');
  const [consent, setConsent] = useState(false);
  const [errors, setErrors] = useState({});
  const [submitted, setSubmitted] = useState(false);

  useEffect(() => {
    const onKey = (e) => {if (e.key === 'Escape') onClose();};
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [onClose]);

  const validate = () => {
    const e = {};
    if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) e.email = 'Please enter a valid email.';
    if (!consent) e.consent = 'Please confirm consent.';
    setErrors(e);
    return Object.keys(e).length === 0;
  };

  const handleSubmit = (ev) => {
    ev.preventDefault();
    if (!validate()) return;
    track('waitlist_signup', { topic: topic.id, source: 'topic_card' });
    setSubmitted(true);
  };

  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()} role="dialog" aria-modal="true" aria-labelledby="wl-title">
        <button className="modal__close" onClick={onClose} aria-label="Close">×</button>
        {!submitted ?
        <>
            <p className="modal__eyebrow">Waitlist · {topic.title}</p>
            <h2 className="modal__title" id="wl-title">Join the expert-led waitlist.</h2>
            <p className="modal__copy">
              We’ll contact you if this topic opens as an expert-led pilot. No guaranteed launch,
              no spam, and you can leave the list at any time.
            </p>
            <form onSubmit={handleSubmit} className="lead-form" noValidate>
              <div className={`field ${errors.email ? 'field--invalid' : ''}`}>
                <label htmlFor="wl-email">Email address</label>
                <input
                id="wl-email"
                type="email"
                inputMode="email"
                placeholder="you@example.com"
                value={email}
                onChange={(e) => setEmail(e.target.value)} />
              
                {errors.email && <span className="field-error">{errors.email}</span>}
              </div>

              <div className="field">
                <label htmlFor="wl-stage">Current stage or main question <span style={{ textTransform: 'none', color: 'var(--fg-faint)' }}>(optional)</span></label>
                <input
                id="wl-stage"
                type="text"
                placeholder="e.g. researching, mid-cycle, post-diagnosis…"
                value={stage}
                onChange={(e) => setStage(e.target.value)} />
              
              </div>

              <label className="checkbox">
                <input type="checkbox" checked={consent} onChange={(e) => setConsent(e.target.checked)} />
                <span className="box" aria-hidden="true" />
                <span>
                  I agree to receive emails from YUEVA about this topic. I can unsubscribe at any time.{' '}
                  <a href="legal.html#privacy" className="link-inline">Privacy policy →</a>
                </span>
              </label>
              {errors.consent && <span className="field-error">{errors.consent}</span>}

              <button type="submit" className="btn btn--sage" style={{ alignSelf: 'flex-start', marginTop: '0.5rem' }}>
                Join expert-led waitlist <span className="arrow" aria-hidden="true">→</span>
              </button>
            </form>
          </> :

        <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
            <span className="success__mark" aria-hidden="true">✓</span>
            <p className="modal__eyebrow">Confirmed</p>
            <h2 className="modal__title">You’re on the list.</h2>
            <p className="modal__copy">
              We’ll contact you if <strong>{topic.title}</strong> opens as an expert-led pilot.
              No guaranteed launch.
            </p>
            <button className="btn btn--ghost" onClick={onClose} type="button" style={{ alignSelf: 'flex-start' }}>Close</button>
          </div>
        }
      </div>
    </div>);

}

/* ----------------------------------------------------------
   Paid-session redirect modal (placeholder until booking is wired)
   ---------------------------------------------------------- */
function PaidRedirectModal({ topic, onClose }) {
  useEffect(() => {
    const onKey = (e) => {if (e.key === 'Escape') onClose();};
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [onClose]);

  // Placeholder URL — production would window.location to TODO_BOOKING_PAYMENT_URL_TOPIC
  const url = `#TODO_BOOKING_PAYMENT_URL_TOPIC?topic=${topic.id}`;
  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()} role="dialog" aria-modal="true">
        <button className="modal__close" onClick={onClose} aria-label="Close">×</button>
        <p className="modal__eyebrow">Booking · {topic.title}</p>
        <h2 className="modal__title">Continue to checkout. €89</h2>
        <p className="modal__copy">
          45 minutes. 1:1 Clarity Session with a certified health coach. Not medical advice. You
          receive a pre-call questionnaire by email after booking, plus your starter lifestyle
          protocol within 48 hours of your session.
        </p>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.5rem' }}>
          <a className="btn" href={url} onClick={() => track('paid_session_click', { topic: topic.id, price: 89, source: 'booking_modal' })}>
            Continue to checkout <span className="arrow">→</span>
          </a>
          <button className="btn btn--ghost" onClick={onClose} type="button">Not yet</button>
        </div>
        <p className="text-faint" style={{ fontSize: 'var(--fs-caption)', marginTop: '1rem' }}>
          {/* TODO: Confirm payment provider and cancellation terms. */}
          TODO: Wire to live booking + payment URL (Stripe / Calendly / Cal.com).
        </p>
      </div>
    </div>);

}

/* ----------------------------------------------------------
   Application modal — Founding Clarity Session
   ---------------------------------------------------------- */
function ApplyModal({ onClose }) {
  const [email, setEmail] = useState('');
  const [focus, setFocus] = useState('');
  const [stage, setStage] = useState('');
  const [consent, setConsent] = useState(false);
  const [errors, setErrors] = useState({});
  const [submitted, setSubmitted] = useState(false);

  useEffect(() => {
    const onKey = (e) => {if (e.key === 'Escape') onClose();};
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [onClose]);

  const validate = () => {
    const e = {};
    if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) e.email = 'Please enter a valid email.';
    if (!focus) e.focus = 'Select your primary focus.';
    if (!consent) e.consent = 'Please confirm consent.';
    setErrors(e);
    return Object.keys(e).length === 0;
  };

  const handleSubmit = (ev) => {
    ev.preventDefault();
    if (!validate()) return;
    track('application_submitted', { focus, has_stage: !!stage });
    // TODO: POST application to your CRM / waitlist endpoint.
    setSubmitted(true);
  };

  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()} role="dialog" aria-modal="true" aria-labelledby="apply-title">
        <button className="modal__close" onClick={onClose} aria-label="Close">×</button>
        {!submitted ?
        <>
            <p className="modal__eyebrow">Founding Clarity Session · €89</p>
            <h2 className="modal__title" id="apply-title">Apply for a founding session.</h2>
            <p className="modal__copy">
              Founding sessions are limited while we validate the YUEVA method. Tell us a little
              about your focus and we will confirm fit within 24 hours.
            </p>
            <form onSubmit={handleSubmit} className="lead-form" noValidate>
              <div className={`field ${errors.email ? 'field--invalid' : ''}`}>
                <label htmlFor="apply-email">Email address</label>
                <input id="apply-email" type="email" inputMode="email" placeholder="you@example.com" value={email} onChange={(e) => setEmail(e.target.value)} />
                {errors.email && <span className="field-error">{errors.email}</span>}
              </div>

              <div className={`field ${errors.focus ? 'field--invalid' : ''}`}>
                <label htmlFor="apply-focus">Your primary focus</label>
                <select id="apply-focus" value={focus} onChange={(e) => setFocus(e.target.value)}>
                  <option value="">Choose a focus…</option>
                  {TOPIC_OPTIONS.map((t) => <option value={t.v} key={t.v}>{t.l}</option>)}
                </select>
                {errors.focus && <span className="field-error">{errors.focus}</span>}
              </div>

              <div className="field">
                <label htmlFor="apply-stage">Current stage or main question <span style={{ textTransform: 'none', color: 'var(--fg-faint)' }}>(optional)</span></label>
                <input id="apply-stage" type="text" placeholder="e.g. cycle changes since March, planning fertility decisions, recent labs unclear…" value={stage} onChange={(e) => setStage(e.target.value)} />
              </div>

              <label className="checkbox">
                <input type="checkbox" checked={consent} onChange={(e) => setConsent(e.target.checked)} />
                <span className="box" aria-hidden="true" />
                <span>
                  I agree to receive emails from YUEVA about this application. I can unsubscribe at any time.{' '}
                  <a href="legal.html#privacy" className="link-inline">Privacy policy.</a>
                </span>
              </label>
              {errors.consent && <span className="field-error">{errors.consent}</span>}

              <button type="submit" className="btn" style={{ alignSelf: 'flex-start', marginTop: '0.5rem' }}>
                Submit application <span className="arrow" aria-hidden="true">→</span>
              </button>
              <p className="field-help" style={{ marginTop: '0.25rem' }}>
                Educational health-coaching session. Not medical advice.
              </p>
            </form>
          </> :

        <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
            <span className="success__mark" aria-hidden="true">✓</span>
            <p className="modal__eyebrow">Application received</p>
            <h2 className="modal__title">We will confirm fit within 24 hours.</h2>
            <p className="modal__copy">
              Thank you. We will email <strong style={{ color: 'var(--fg)' }}>{email}</strong> with
              next steps. Your focus on <strong style={{ color: 'var(--fg)' }}>{TOPIC_OPTIONS.find((t) => t.v === focus)?.l}</strong> helps us match the right session lead.
            </p>
            <button className="btn btn--ghost" onClick={onClose} type="button" style={{ alignSelf: 'flex-start' }}>Close</button>
          </div>
        }
      </div>
    </div>);

}
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "headlineKey": "navigate",
  "ivfMode": "paid",
  "randomizeTopics": false
} /*EDITMODE-END*/;

/* ----------------------------------------------------------
   App
   ---------------------------------------------------------- */
function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [applyOpen, setApplyOpen] = useState(false);
  const openApply = () => {track('application_started', {});setApplyOpen(true);};
  const [consent, setConsent] = useState(readConsent);
  const [cookieOpen, setCookieOpen] = useState(false);

  useEffect(() => {
    captureUtms();
    const c = readConsent();
    setConsent(c);
    if (!c.decided) {
      const id = setTimeout(() => setCookieOpen(true), 900);
      return () => clearTimeout(id);
    }
  }, []);

  const handleAcceptAll = () => {
    const c = { decided: true, analytics: true, marketing: true };
    writeConsent(c);
    setConsent(c);
    setCookieOpen(false);
    flushQueuedAnalytics();
  };
  const handleReject = () => {
    const c = { decided: true, analytics: false, marketing: false };
    writeConsent(c);
    setConsent(c);
    setCookieOpen(false);
  };
  const handleCustom = () => {
    // For prototype: just toggle analytics-only
    const c = { decided: true, analytics: true, marketing: false };
    writeConsent(c);
    setConsent(c);
    setCookieOpen(false);
    flushQueuedAnalytics();
  };

  const openTopics = () => {
    const el = document.getElementById('clarity');
    if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
  };
  const openGuide = () => {
    // Opens the external Typeform that delivers the Hormone & Biomarker
    // Guide in a new tab. Single source of truth: TYPEFORM_GUIDE_URL.
    window.open(TYPEFORM_GUIDE_URL, '_blank', 'noopener,noreferrer');
  };

  return (
    <>
      <Nav />
      <Hero
        headlineKey={t.headlineKey}
        onPrimary={() => openGuide()}
        onSecondary={() => openApply()} />
      
      <SymptomSection onGuide={() => openGuide()} />
      <ProblemSection />
      <ClaritySessionSection onApply={() => openApply()} />
      <TestimonialsSection />
      <StudiesSection />
      <ClosingCTA onPaid={() => openApply()} onGuide={() => openGuide()} />
      <Footer onCookieOpen={() => setCookieOpen(true)} />

      <CookieBanner
        open={cookieOpen}
        onAccept={handleAcceptAll}
        onReject={handleReject}
        onCustom={handleCustom} />
      

      {applyOpen &&
      <ApplyModal onClose={() => setApplyOpen(false)} />
      }

      <TweaksPanel>
        <TweakSection label="Hero headline" />
        <TweakRadio
          label="Variant"
          value={t.headlineKey}
          options={[
          { value: 'navigate', label: 'Navigate' },
          { value: 'important', label: 'Too important' },
          { value: 'structured', label: 'Structured' }]
          }
          onChange={(v) => setTweak('headlineKey', v)} />
        
        <TweakSection label="IVF / Fertility path CTA" />
        <TweakRadio
          label="Mode"
          value={t.ivfMode}
          options={[
          { value: 'paid', label: 'Paid now' },
          { value: 'waitlist', label: 'Pilot waitlist' }]
          }
          onChange={(v) => setTweak('ivfMode', v)} />
        
        <TweakSection label="Topic order" />
        <TweakToggle
          label="Randomize per visitor"
          value={t.randomizeTopics}
          onChange={(v) => setTweak('randomizeTopics', v)} />
        
        <TweakSection label="Validation tools" />
        <TweakButton
          label="Reset visitor state"
          onClick={() => {
            try {
              localStorage.removeItem(CONSENT_KEY);
              localStorage.removeItem(TOPIC_ORDER_KEY);
              localStorage.removeItem(VARIANT_KEY);
              sessionStorage.removeItem(ANALYTICS_QUEUE_KEY);
            } catch {}
            location.reload();
          }} />
        
      </TweaksPanel>
    </>);

}

/* ----------------------------------------------------------
   Clarity Session sub-page
   Composes: Nav → Book a Clarity Session → Your Journey → Scope → Footer
   Rendered when #root has data-page="clarity".
   ---------------------------------------------------------- */
function ClarityPage() {
  const [applyOpen, setApplyOpen] = useState(false);
  const openApply = () => {track('application_started', { source: 'clarity_page' });setApplyOpen(true);};
  const [consent, setConsent] = useState(readConsent);
  const [cookieOpen, setCookieOpen] = useState(false);

  useEffect(() => {
    captureUtms();
    const c = readConsent();
    setConsent(c);
    if (!c.decided) {
      const id = setTimeout(() => setCookieOpen(true), 900);
      return () => clearTimeout(id);
    }
  }, []);

  const handleAcceptAll = () => {
    const c = { decided: true, analytics: true, marketing: true };
    writeConsent(c);
    setConsent(c);
    setCookieOpen(false);
    flushQueuedAnalytics();
  };
  const handleReject = () => {
    const c = { decided: true, analytics: false, marketing: false };
    writeConsent(c);
    setConsent(c);
    setCookieOpen(false);
  };
  const handleCustom = () => {
    const c = { decided: true, analytics: true, marketing: false };
    writeConsent(c);
    setConsent(c);
    setCookieOpen(false);
    flushQueuedAnalytics();
  };

  return (
    <>
      <Nav />
      <ClaritySection onApply={() => openApply()} />
      <ClaritySessionSection onApply={() => openApply()} />
      <Footer onCookieOpen={() => setCookieOpen(true)} />

      <CookieBanner
        open={cookieOpen}
        onAccept={handleAcceptAll}
        onReject={handleReject}
        onCustom={handleCustom} />

      {applyOpen && <ApplyModal onClose={() => setApplyOpen(false)} />}
    </>);

}

/* ----------------------------------------------------------
   Guide sub-page — dedicated standalone page for the
   Hormone & Biomarker Guide lead-magnet form.
   Composes: Nav → GuideSection → Footer
   Rendered when #root has data-page="guide".
   Reads `?topic=…` from the URL to seed the topic select.
   ---------------------------------------------------------- */
function GuidePage() {
  const [applyOpen, setApplyOpen] = useState(false);
  const openApply = () => {track('application_started', { source: 'guide_page' });setApplyOpen(true);};
  const [consent, setConsent] = useState(readConsent);
  const [cookieOpen, setCookieOpen] = useState(false);

  // Read ?topic= from the URL once on mount so the form can preselect.
  const initialTopic = useMemo(() => {
    try {
      const params = new URLSearchParams(window.location.search);
      return params.get('topic') || null;
    } catch {return null;}
  }, []);

  useEffect(() => {
    captureUtms();
    const c = readConsent();
    setConsent(c);
    if (!c.decided) {
      const id = setTimeout(() => setCookieOpen(true), 900);
      return () => clearTimeout(id);
    }
  }, []);

  const handleAcceptAll = () => {
    const c = { decided: true, analytics: true, marketing: true };
    writeConsent(c);setConsent(c);setCookieOpen(false);flushQueuedAnalytics();
  };
  const handleReject = () => {
    const c = { decided: true, analytics: false, marketing: false };
    writeConsent(c);setConsent(c);setCookieOpen(false);
  };
  const handleCustom = () => {
    const c = { decided: true, analytics: true, marketing: false };
    writeConsent(c);setConsent(c);setCookieOpen(false);flushQueuedAnalytics();
  };

  return (
    <>
      <Nav />
      <GuideSection guideTopicSeed={initialTopic} onApply={() => openApply()} />
      <Footer onCookieOpen={() => setCookieOpen(true)} />

      <CookieBanner
        open={cookieOpen}
        onAccept={handleAcceptAll}
        onReject={handleReject}
        onCustom={handleCustom} />

      {applyOpen && <ApplyModal onClose={() => setApplyOpen(false)} />}
    </>);

}

/* ----------------------------------------------------------
   About sub-page — founder / operator credibility on its own page.
   Composes: Nav → FounderSection → ClosingCTA → Footer
   Rendered when #root has data-page="about".
   ---------------------------------------------------------- */
function AboutPage() {
  const [applyOpen, setApplyOpen] = useState(false);
  const openApply = () => {track('application_started', { source: 'about_page' });setApplyOpen(true);};
  const openGuide = () => {window.open(TYPEFORM_GUIDE_URL, '_blank', 'noopener,noreferrer');};
  const [consent, setConsent] = useState(readConsent);
  const [cookieOpen, setCookieOpen] = useState(false);

  useEffect(() => {
    captureUtms();
    const c = readConsent();
    setConsent(c);
    if (!c.decided) {
      const id = setTimeout(() => setCookieOpen(true), 900);
      return () => clearTimeout(id);
    }
  }, []);

  const handleAcceptAll = () => {
    const c = { decided: true, analytics: true, marketing: true };
    writeConsent(c);setConsent(c);setCookieOpen(false);flushQueuedAnalytics();
  };
  const handleReject = () => {
    const c = { decided: true, analytics: false, marketing: false };
    writeConsent(c);setConsent(c);setCookieOpen(false);
  };
  const handleCustom = () => {
    const c = { decided: true, analytics: true, marketing: false };
    writeConsent(c);setConsent(c);setCookieOpen(false);flushQueuedAnalytics();
  };

  return (
    <>
      <Nav />
      <FounderSection />
      <ClosingCTA onPaid={() => openApply()} onGuide={() => openGuide()} />
      <Footer onCookieOpen={() => setCookieOpen(true)} />

      <CookieBanner
        open={cookieOpen}
        onAccept={handleAcceptAll}
        onReject={handleReject}
        onCustom={handleCustom} />

      {applyOpen && <ApplyModal onClose={() => setApplyOpen(false)} />}
    </>);

}

/* ----------------------------------------------------------
   Legal & Policies page
   Single consolidated page containing the imprint, privacy
   policy, terms of service, medical disclaimer, and cookie
   notice. Rendered when #root has data-page="legal".
   Body is intentionally static markup so the editor can
   direct-edit copy.
   ---------------------------------------------------------- */
function LegalPage() {
  const [applyOpen, setApplyOpen] = useState(false);
  const openApply = () => { track('application_started', { source: 'legal_page' }); setApplyOpen(true); };
  const openGuide = () => { window.open(TYPEFORM_GUIDE_URL, '_blank', 'noopener,noreferrer'); };
  const [consent, setConsent] = useState(readConsent);
  const [cookieOpen, setCookieOpen] = useState(false);

  useEffect(() => {
    captureUtms();
    const c = readConsent();
    setConsent(c);
    if (!c.decided) {
      const id = setTimeout(() => setCookieOpen(true), 900);
      return () => clearTimeout(id);
    }
  }, []);

  const handleAcceptAll = () => {
    const c = { decided: true, analytics: true, marketing: true };
    writeConsent(c); setConsent(c); setCookieOpen(false); flushQueuedAnalytics();
  };
  const handleReject = () => {
    const c = { decided: true, analytics: false, marketing: false };
    writeConsent(c); setConsent(c); setCookieOpen(false);
  };
  const handleCustom = () => {
    const c = { decided: true, analytics: true, marketing: false };
    writeConsent(c); setConsent(c); setCookieOpen(false); flushQueuedAnalytics();
  };

  return (
    <>
      <Nav />

      <article className="article legal">
        <header className="article__head">
          <div className="shell shell--article">
            <p className="article__crumb">
              <a href="index.html">Home</a>
              <span aria-hidden="true"> · </span>
              <span>Legal &amp; Policies</span>
            </p>
            <h1 className="h-display-l article__title">Legal &amp; Policies</h1>
            <p className="article__byline">
              <em>YUEVA · YLDLIFE GmbH</em>
              <span aria-hidden="true"> · </span>
              <span>Last updated 18 May 2026</span>
            </p>
          </div>
        </header>

        {/* Table of contents */}
        <nav className="legal__toc" aria-label="Document sections">
          <div className="shell shell--article">
            <ol className="legal__toc-list">
              <li><a href="#imprint">Imprint / Legal Notice</a></li>
              <li><a href="#privacy">Privacy Policy</a></li>
              <li><a href="#terms">Terms of Service</a></li>
              <li><a href="#disclaimer">Medical Disclaimer</a></li>
              <li><a href="#cookies">Cookie Notice</a></li>
            </ol>
          </div>
        </nav>

        <div className="article__body shell shell--article">

          {/* ============ IMPRINT ============ */}
          <h2 className="article__h2" id="imprint">Imprint / Legal Notice</h2>
          <p><strong>Information according to Section 5 DDG (Germany)</strong></p>
          <p>YUEVA is a brand operated by YLDLIFE GmbH.</p>
          <p>
            YLDLIFE GmbH<br />
            Schillerstrasse 5<br />
            82049 Pullach im Isartal<br />
            Germany
          </p>
          <p>
            Represented by the Managing Director:<br />
            Laura Schäfer
          </p>
          <p>
            <strong>Commercial Register:</strong><br />
            Register Court: Local Court of Munich (Amtsgericht München)<br />
            Registration Number: HRB 260960
          </p>
          <p>
            <strong>VAT ID according to Section 27a German VAT Act:</strong><br />
            DE337273559
          </p>
          <p>
            <strong>Contact:</strong><br />
            Telephone: [INSERT PHONE NUMBER]<br />
            Email: <a href="mailto:info@yuevalongevity.com">info@yuevalongevity.com</a><br />
            Website: <a href="https://yuevalongevity.com" target="_blank" rel="noopener noreferrer">yuevalongevity.com</a>
          </p>
          <p><strong>Responsible for content according to Section 18 para. 2 MStV</strong></p>
          <p>
            Laura Schäfer<br />
            YLDLIFE GmbH<br />
            Schillerstrasse 5<br />
            82049 Pullach im Isartal<br />
            Germany
          </p>
          <p><strong>Consumer dispute resolution / EU Online Dispute Resolution</strong></p>
          <p>
            The European Commission provides a platform for online dispute resolution (ODR):{' '}
            <a href="https://ec.europa.eu/consumers/odr/" target="_blank" rel="noopener noreferrer">
              ec.europa.eu/consumers/odr
            </a>
          </p>
          <p>
            YLDLIFE GmbH is neither obliged nor willing to participate in dispute resolution
            proceedings before a consumer arbitration board.
          </p>

          {/* ============ PRIVACY POLICY ============ */}
          <h2 className="article__h2" id="privacy">Privacy Policy</h2>

          <h3 className="legal__h3">1. General information</h3>
          <p>
            YUEVA is a brand operated by YLDLIFE GmbH. Personal data is processed in accordance
            with the General Data Protection Regulation (GDPR) and the applicable German data
            protection laws.
          </p>
          <p>
            This Privacy Policy explains what personal data may be collected, why it is collected,
            how it is processed, the legal basis relied upon, and what rights data subjects have
            under applicable law.
          </p>

          <h3 className="legal__h3">2. Controller</h3>
          <p>Controller for the processing of personal data on this website is:</p>
          <p>
            YLDLIFE GmbH<br />
            Schillerstrasse 5<br />
            82049 Pullach im Isartal<br />
            Germany<br />
            Email: <a href="mailto:info@yuevalongevity.com">info@yuevalongevity.com</a><br />
            Telephone: [INSERT PHONE NUMBER]
          </p>

          <h3 className="legal__h3">3. Hosting and server log files</h3>
          <p>
            This website is hosted through Vercel. When the website is visited, technical
            information may be processed automatically to deliver the site and maintain security
            and stability.
          </p>
          <p>
            This may include the IP address, date and time of access, time zone, requested page or
            file, HTTP status code, referrer URL, browser type, operating system, and language
            settings.
          </p>
          <p>
            The legal basis is Article 6(1)(f) GDPR. The legitimate interest is the secure, stable,
            and technically reliable operation of the website.
          </p>
          <p>
            <strong>Vercel Web Analytics.</strong> This website additionally uses Vercel Web
            Analytics, a privacy-friendly measurement tool provided by Vercel Inc. that does not
            use cookies, does not store personal data, and does not allow visitors to be
            identified. Vercel Web Analytics anonymises IP addresses and collects only aggregate,
            non-personal information such as page paths, referrer, country, browser, device type,
            and aggregated custom events. The legal basis is Article 6(1)(f) GDPR. The legitimate
            interest is understanding overall website performance and content effectiveness
            without tracking individual users.
          </p>
          <p>
            <strong>Vercel Speed Insights.</strong> The website may also use Vercel Speed Insights
            to measure Core Web Vitals (loading speed, interactivity, layout stability). This
            collection is anonymous, does not use cookies, and is processed solely to maintain
            and improve technical performance. The legal basis is Article 6(1)(f) GDPR.
          </p>

          <h3 className="legal__h3">4. Categories of personal data</h3>
          <p>Depending on how the website and services are used, the following categories of personal data may be processed:</p>
          <ul className="legal__list">
            <li>Name</li>
            <li>Email address</li>
            <li>Telephone number</li>
            <li>Appointment booking details</li>
            <li>Questionnaire and intake form responses</li>
            <li>Wellness, lifestyle, cycle, hormone, nutrition, sleep, and other health-related information voluntarily submitted by the user</li>
            <li>Payment and transaction metadata</li>
            <li>Communication history</li>
            <li>Technical usage data</li>
          </ul>

          <h3 className="legal__h3">5. Purposes and legal bases of processing</h3>
          <p>Personal data may be processed for the following purposes:</p>
          <ul className="legal__list">
            <li>Responding to inquiries</li>
            <li>Preparing and delivering coaching, educational, and informational services</li>
            <li>Scheduling appointments</li>
            <li>Processing payments</li>
            <li>Sending newsletters and service communications</li>
            <li>Organising events or online sessions</li>
            <li>Protecting the website against misuse and maintaining technical security</li>
          </ul>
          <p>
            The legal bases may include Article 6(1)(a) GDPR (consent), Article 6(1)(b) GDPR
            (performance of a contract or pre-contractual steps), Article 6(1)(c) GDPR (legal
            obligation), and Article 6(1)(f) GDPR (legitimate interests).
          </p>

          <h3 className="legal__h3">6. Health-related information and special category data</h3>
          <p>
            Some forms or intake processes may allow users to provide wellness- or health-related
            information, including information related to symptoms, cycle, hormones, sleep,
            nutrition, stress, pregnancy-related interests, or other sensitive topics.
          </p>
          <p>
            To the extent such information qualifies as health data under Article 9 GDPR, it will
            only be processed where the user has provided explicit consent.
          </p>
          <p>
            The legal basis for such processing is Article 6(1)(a) GDPR in conjunction with
            Article 9(2)(a) GDPR.
          </p>
          <p>
            Consent is voluntary and may be withdrawn at any time with effect for the future.
            Withdrawal does not affect the lawfulness of processing carried out before the
            withdrawal.
          </p>
          <p>
            Users should not submit medical records or particularly sensitive information unless
            specifically requested and necessary for the intended purpose.
          </p>

          <h3 className="legal__h3">7. Contact requests</h3>
          <p>
            If a user contacts YUEVA by email or through a form, the submitted data will be
            processed for the purpose of handling the request.
          </p>
          <p>
            The legal basis is Article 6(1)(b) GDPR where the request relates to a potential or
            existing contractual relationship, and otherwise Article 6(1)(f) GDPR based on the
            legitimate interest in responding to inquiries.
          </p>

          <h3 className="legal__h3">8. Appointment booking via Cal.eu</h3>
          <p>
            This website may use Cal.eu for appointment scheduling. When a user books an
            appointment, the data entered for booking may be transmitted to Cal.eu and processed
            there for scheduling and related communications.
          </p>
          <p>
            This may include name, email address, telephone number, appointment preferences, and
            any additional information voluntarily provided by the user.
          </p>
          <p>
            The legal basis is Article 6(1)(b) GDPR where the booking is made in connection with
            requested services.
          </p>

          <h3 className="legal__h3">9. Payments via Stripe</h3>
          <p>
            Payments may be processed through Stripe. In the course of payment handling, data
            required for the transaction may be transmitted directly to Stripe.
          </p>
          <p>
            This may include billing details, payment metadata, transaction details, IP address,
            and other payment-related information necessary for fraud prevention and transaction
            processing.
          </p>
          <p>The legal basis is Article 6(1)(b) GDPR.</p>
          <p>Full payment card data is generally not stored by YLDLIFE GmbH.</p>

          <h3 className="legal__h3">10. Forms and questionnaires via Typeform</h3>
          <p>
            This website may use Typeform for questionnaires, lead forms, intake forms, and
            similar data collection processes.
          </p>
          <p>
            Data entered into Typeform may include contact details and, where voluntarily
            submitted, wellness- or health-related information.
          </p>
          <p>
            The legal basis depends on the form context. For general contact or service-related
            forms, the legal basis may be Article 6(1)(a) or Article 6(1)(b) GDPR. Where health
            data is involved, the additional legal basis is the user’s explicit consent under
            Article 9(2)(a) GDPR.
          </p>

          <h3 className="legal__h3">11. Newsletter, email communications, and event tools</h3>
          <p>
            YUEVA may use providers such as Brevo, Substack, and Luma for newsletters, email
            communications, event management, registrations, and related updates.
          </p>
          <p>
            Newsletter subscriptions are processed on the basis of consent under Article 6(1)(a)
            GDPR. Double opt-in should be used for newsletter subscriptions.
          </p>
          <p>Users may unsubscribe or withdraw consent at any time with effect for the future.</p>

          <h3 className="legal__h3">12. Processors and service providers</h3>
          <p>
            External service providers may be used for hosting, forms, booking, payments,
            communications, and event management. Where required by law, data processing
            agreements are concluded with processors under Article 28 GDPR.
          </p>

          <h3 className="legal__h3">13. International data transfers</h3>
          <p>
            Some service providers may process personal data outside the European Union or the
            European Economic Area, including in the United States.
          </p>
          <p>
            Where an adequacy decision is not available, transfers are based on appropriate
            safeguards, in particular the European Commission’s Standard Contractual Clauses.
            Where applicable, transfers may also rely on certification under the EU-U.S. Data
            Privacy Framework.
          </p>
          <p>
            Despite contractual and technical protections, an equivalent level of protection
            cannot always be guaranteed in every third country transfer scenario.
          </p>

          <h3 className="legal__h3">14. Retention period</h3>
          <p>
            Personal data is stored only for as long as necessary for the relevant purposes,
            unless longer retention is required by law or necessary to establish, exercise, or
            defend legal claims.
          </p>
          <p>
            Once the purpose no longer applies and no retention obligation exists, the data will
            be deleted or restricted in accordance with applicable law.
          </p>

          <h3 className="legal__h3">15. Rights of data subjects</h3>
          <p>
            Under the GDPR, data subjects may have the right to access, rectify, erase, restrict
            processing, object to processing, receive data portability, and withdraw consent at
            any time where processing is based on consent.
          </p>
          <p>
            Data subjects also have the right to lodge a complaint with a supervisory authority,
            including the competent authority in their place of residence, workplace, or the place
            of the alleged infringement.
          </p>

          <h3 className="legal__h3">16. Supervisory authority</h3>
          <p>
            For a company based in Bavaria, a complaint may in particular be addressed to the
            competent Bavarian data protection supervisory authority, such as the Bavarian State
            Office for Data Protection Supervision (BayLDA), depending on the case.
          </p>

          <h3 className="legal__h3">17. Obligation to provide data</h3>
          <p>
            The provision of personal data is generally neither legally nor contractually required.
            However, certain information may be necessary to respond to inquiries, process
            bookings, or provide services.
          </p>

          <h3 className="legal__h3">18. No automated decision-making</h3>
          <p>
            No automated decision-making, including profiling within the meaning of Article 22
            GDPR, is carried out unless expressly stated otherwise in this Privacy Policy.
          </p>

          <h3 className="legal__h3">19. External links</h3>
          <p>
            This website may contain links to third-party websites. Responsibility for the content
            and data processing on those external websites lies solely with their respective
            operators.
          </p>

          <h3 className="legal__h3">20. Updates to this Privacy Policy</h3>
          <p>
            This Privacy Policy may be updated where necessary due to legal, technical, or
            business developments.
          </p>

          {/* ============ TERMS OF SERVICE ============ */}
          <h2 className="article__h2" id="terms">Terms of Service</h2>

          <h3 className="legal__h3">1. Scope</h3>
          <p>
            These Terms of Service govern the use of the YUEVA website and the booking or use of
            related coaching, informational, educational, and wellness-oriented services provided
            by YLDLIFE GmbH.
          </p>

          <h3 className="legal__h3">2. Provider</h3>
          <p>The provider and contractual partner is:</p>
          <p>
            YLDLIFE GmbH<br />
            Schillerstrasse 5<br />
            82049 Pullach im Isartal<br />
            Germany<br />
            Email: <a href="mailto:info@yuevalongevity.com">info@yuevalongevity.com</a><br />
            Telephone: [INSERT PHONE NUMBER]
          </p>

          <h3 className="legal__h3">3. Nature of services</h3>
          <p>
            YUEVA provides informational, educational, coaching, and wellness-oriented content and
            services.
          </p>
          <p>
            Unless expressly stated otherwise, YUEVA does not provide medical treatment, medical
            diagnosis, psychotherapy, or other licensed healthcare services.
          </p>

          <h3 className="legal__h3">4. No medical services</h3>
          <p>
            All content and services are provided for general informational, educational, and
            wellness purposes only.
          </p>
          <p>
            Nothing on the website or in any session, guide, webinar, form, newsletter, or
            communication constitutes medical advice, diagnosis, treatment, psychotherapy, or
            healthcare services.
          </p>

          <h3 className="legal__h3">5. No doctor-patient or therapist-patient relationship</h3>
          <p>
            Use of the website or participation in any coaching or informational offering does not
            create a doctor-patient relationship, therapist-patient relationship, or any other
            treatment relationship.
          </p>

          <h3 className="legal__h3">6. Contract formation</h3>
          <p>
            Descriptions of services on the website do not constitute a binding legal offer unless
            explicitly stated otherwise.
          </p>
          <p>
            A contract is formed only when a booking is expressly confirmed or the requested
            service is provided.
          </p>

          <h3 className="legal__h3">7. Eligibility</h3>
          <p>Users must be at least 18 years old to purchase paid services.</p>

          <h3 className="legal__h3">8. Appointments, rescheduling, and cancellation</h3>
          <p>Booked appointments are binding.</p>
          <p>
            Appointments may be rescheduled or cancelled free of charge up to [24 / 48] hours
            before the agreed time.
          </p>
          <p>
            For later cancellations or no-shows, YLDLIFE GmbH reserves the right to charge
            [50% / 100%] of the agreed fee unless the user proves that no damage or significantly
            lower damage was incurred.
          </p>
          <p>
            YLDLIFE GmbH may reschedule or cancel appointments for good cause. In that case,
            prepaid amounts will be refunded unless an equivalent replacement service is offered.
          </p>

          <h3 className="legal__h3">9. Prices and payment</h3>
          <p>The prices displayed at the time of booking apply.</p>
          <p>
            Payments may be processed through the payment methods offered on the website,
            including Stripe.
          </p>
          <p>Unless otherwise agreed, invoices are due immediately upon receipt.</p>

          <h3 className="legal__h3">10. Consumer withdrawal rights</h3>
          <p>
            Consumers may have a statutory right of withdrawal for distance contracts concluded
            online.
          </p>
          <p>
            If paid services are offered to consumers through the website, a separate withdrawal
            policy should be provided and displayed before contract conclusion.
          </p>
          <p>
            Where legally permissible, the user may be asked to expressly consent to the start of
            the service before the withdrawal period expires and acknowledge that the right of
            withdrawal may be reduced or lost once the service has been fully performed.
          </p>

          <h3 className="legal__h3">11. User responsibility</h3>
          <p>
            Users remain solely responsible for decisions and actions taken on the basis of
            website content, coaching, or informational services.
          </p>

          <h3 className="legal__h3">12. Intellectual property</h3>
          <p>
            All texts, graphics, branding elements, materials, downloads, and other content on the
            website are protected by intellectual property laws unless stated otherwise.
          </p>
          <p>
            No content may be copied, reproduced, distributed, published, or commercially
            exploited without prior written permission, except where mandatory law permits
            otherwise.
          </p>

          <h3 className="legal__h3">13. Digital materials</h3>
          <p>
            Any guides, recordings, worksheets, or other digital materials made available in
            connection with the services are provided for personal use only unless expressly
            agreed otherwise.
          </p>

          <h3 className="legal__h3">14. Liability</h3>
          <p>
            YLDLIFE GmbH has unlimited liability in cases of intent, gross negligence, and injury
            to life, body, or health to the extent required by law.
          </p>
          <p>
            In cases of slight negligence, liability is limited to breach of essential contractual
            obligations and to the foreseeable damage typical for the contract.
          </p>
          <p>Any further liability is excluded to the extent permitted by law.</p>

          <h3 className="legal__h3">15. External links and third-party services</h3>
          <p>
            The website may contain links to third-party websites or use third-party services. No
            responsibility is assumed for the content, availability, or data processing practices
            of third parties.
          </p>

          <h3 className="legal__h3">16. Applicable law and jurisdiction</h3>
          <p>
            These Terms are governed by the laws of the Federal Republic of Germany, excluding
            the UN Convention on Contracts for the International Sale of Goods, unless mandatory
            consumer protection law provides otherwise.
          </p>
          <p>
            If the user is a merchant, a legal entity under public law, or a special fund under
            public law, the place of jurisdiction shall be Munich, Germany, to the extent legally
            permissible.
          </p>

          <h3 className="legal__h3">17. Language</h3>
          <p>
            The English version of these Terms is provided for use on the English-language
            website. If a German version is later introduced for legal clarification, YLDLIFE
            GmbH may specify which version prevails in case of conflict.
          </p>

          {/* ============ MEDICAL DISCLAIMER ============ */}
          <h2 className="article__h2" id="disclaimer">Medical Disclaimer</h2>
          <p>YUEVA is an educational and wellness-focused platform.</p>
          <p>
            All information provided on this website and in any coaching session, webinar, call,
            guide, questionnaire, newsletter, event, or other material is intended solely for
            general educational, informational, and wellness purposes.
          </p>
          <p>
            Nothing on this website or in any YUEVA service constitutes medical advice, diagnosis,
            treatment, psychotherapy, or healthcare services.
          </p>
          <p>
            YUEVA and YLDLIFE GmbH do not provide medical care unless expressly stated otherwise.
          </p>
          <p>
            No doctor-patient relationship, therapist-patient relationship, or other treatment
            relationship is created through use of this website or participation in any service.
          </p>
          <p>
            Health-related information on this website is general in nature and does not replace
            individual examination, diagnosis, or advice from a licensed physician or other
            qualified healthcare professional.
          </p>
          <p>
            Users should always seek advice from a qualified physician or other appropriate
            healthcare professional regarding any symptoms, diagnosis, treatment decisions,
            medications, or health concerns.
          </p>
          <p>
            Users must not disregard or delay seeking professional medical advice because of
            information obtained from this website.
          </p>
          <p>
            Users must not stop, change, or delay medication, treatment, or medical assessment
            without consulting a qualified healthcare professional.
          </p>
          <p>
            In emergencies, users should immediately contact local emergency services or the
            appropriate medical emergency line.
          </p>
          <p>
            Any implementation of wellness, nutrition, lifestyle, movement, recovery, or
            behavioural suggestions is done solely at the user’s own responsibility.
          </p>

          {/* ============ COOKIE NOTICE ============ */}
          <h2 className="article__h2" id="cookies">Cookie Notice</h2>

          <h3 className="legal__h3">1. General information</h3>
          <p>
            This website uses cookies and similar technologies. These are small files or technical
            mechanisms that may store information on a user’s device or access information
            already stored there.
          </p>

          <h3 className="legal__h3">2. Strictly necessary cookies and similar technologies</h3>
          <p>
            At present, this website is intended to use only strictly necessary cookies or similar
            technologies required to provide the website, ensure security, or enable functions
            expressly requested by the user.
          </p>
          <p>
            The legal basis for storing or accessing information on the user’s device in this
            context is Section 25(2) no. 2 TDDDG. Where personal data is processed in connection
            with such technologies, the legal basis is Article 6(1)(f) GDPR.
          </p>

          <h3 className="legal__h3">3. Privacy-friendly analytics (no cookies)</h3>
          <p>
            This website uses Vercel Web Analytics and Vercel Speed Insights for aggregate
            measurement of page views, technical performance, and custom interactions. Both tools
            are cookie-free, do not store personal data, anonymise IP addresses, and are
            therefore not subject to consent under Section 25 TDDDG.
          </p>
          <p>
            This website does <strong>not</strong> use optional analytics, advertising,
            retargeting, or tracking technologies such as Google Analytics, Meta Pixel, LinkedIn
            Insight Tag, or Hotjar.
          </p>

          <h3 className="legal__h3">4. Future use of optional technologies</h3>
          <p>
            If non-essential cookies or similar technologies are added in the future, they will
            only be activated after the user has given the legally required consent through an
            appropriate consent mechanism.
          </p>
          <p>The Cookie Notice and Privacy Policy will then be updated accordingly.</p>

          <h3 className="legal__h3">5. Third-party functional integrations</h3>
          <p>
            When third-party services are embedded for functions expressly requested by the user,
            such as appointment booking, payments, forms, or event registration, technically
            necessary storage or device access may occur to the extent required for those
            services to function.
          </p>
        </div>
      </article>

      <Footer onCookieOpen={() => setCookieOpen(true)} />

      <CookieBanner
        open={cookieOpen}
        onAccept={handleAcceptAll}
        onReject={handleReject}
        onCustom={handleCustom} />

      {applyOpen && <ApplyModal onClose={() => setApplyOpen(false)} />}
    </>);

}

/* ----------------------------------------------------------
   Research article — "Perimenopause & Thyroid"
   Long-form review in the editorial column layout used by
   healthspan-style sites. Renders when #root has
   data-page="study-peri-thyroid". Body is intentionally
   static markup so the editor can direct-edit copy.
   ---------------------------------------------------------- */
function PeriThyroidArticlePage() {
  const [applyOpen, setApplyOpen] = useState(false);
  const openApply = () => { track('application_started', { source: 'article_peri_thyroid' }); setApplyOpen(true); };
  const openGuide = () => { window.open(TYPEFORM_GUIDE_URL, '_blank', 'noopener,noreferrer'); };
  const [consent, setConsent] = useState(readConsent);
  const [cookieOpen, setCookieOpen] = useState(false);

  useEffect(() => {
    captureUtms();
    const c = readConsent();
    setConsent(c);
    if (!c.decided) {
      const id = setTimeout(() => setCookieOpen(true), 900);
      return () => clearTimeout(id);
    }
  }, []);

  const handleAcceptAll = () => {
    const c = { decided: true, analytics: true, marketing: true };
    writeConsent(c); setConsent(c); setCookieOpen(false); flushQueuedAnalytics();
  };
  const handleReject = () => {
    const c = { decided: true, analytics: false, marketing: false };
    writeConsent(c); setConsent(c); setCookieOpen(false);
  };
  const handleCustom = () => {
    const c = { decided: true, analytics: true, marketing: false };
    writeConsent(c); setConsent(c); setCookieOpen(false); flushQueuedAnalytics();
  };

  // Small superscript number that links to the citation list at the bottom.
  const Ref = ({ n }) => (
    <sup className="article__ref"><a href={`#cite-${n}`}>{n}</a></sup>
  );

  return (
    <>
      <Nav />

      <article className="article">
        <header className="article__head">
          <div className="shell shell--article">
            <p className="article__crumb">
              <a href="index.html#studies">Evidence Library</a>
              <span aria-hidden="true"> · </span>
              <span>Research Review</span>
            </p>
            <h1 className="h-display-l article__title">
              When perimenopause and thyroid dysfunction overlap: the case for paired-marker
              testing in women aged 35 to 50
            </h1>
            <p className="article__byline">
              <em>A YUEVA Longevity research review</em>
              <span aria-hidden="true"> · </span>
              <span>03 May 2026</span>
              <span aria-hidden="true"> · </span>
              <span>12 min read</span>
            </p>
          </div>
        </header>

        <figure className="article__hero">
          <div className="shell shell--article">
            <img
              src="assets/study-thyroid.jpg"
              alt="Editorial black-and-white portrait — woman resting in soft natural light"
              loading="eager"
              decoding="async" />
          </div>
        </figure>

        <section className="article__takeaways">
          <div className="shell shell--article">
            <p className="section-eyebrow">Take home points</p>
            <ul className="article__takeaways-list">
              <li>
                <strong>The symptoms are nearly identical, but the underlying biology is not.</strong>{' '}
                Perimenopause and hypothyroidism present with the same constellation of complaints:
                fatigue, weight gain, low mood, sleep disruption, brain fog, hair thinning, and cold
                intolerance. A 2023 systematic review in <em>Deutsches Ärzteblatt International</em>{' '}
                concluded that the threshold for measuring TSH in perimenopausal women should be
                deliberately broad rather than restrictive, because symptom-based diagnosis fails
                in this age group.
              </li>
              <li>
                <strong>A single TSH measurement is an inadequate screen during the menopausal transition.</strong>{' '}
                Standard reference ranges typically run from 0.3 to 4.0 mIU/L, but population data
                show TSH naturally rises with age in women starting from approximately age 30. A
                single TSH does not detect autoimmune thyroid disease in its early stages, when
                antibodies are present but TSH remains within range. The prevalence of
                anti-thyroid peroxidase (TPO) antibodies rises from around 7&thinsp;% in teenage
                girls to approximately 30&thinsp;% in women over 80.
              </li>
              <li>
                <strong>Thyroid autoimmunity is associated with faster ovarian decline.</strong>{' '}
                A 2025 study of 1,460 euthyroid infertile women aged 18 to 45 (Arlıer and Kükrer,
                {' '}<em>Journal of Clinical Medicine</em>) found that anti-TPO positivity is linked
                to lower antral follicle count and lower anti-Müllerian hormone (AMH), with the
                strongest effect in women over 35. This suggests autoimmune thyroid disease may be
                a quiet accelerator of reproductive ageing.
              </li>
              <li>
                <strong>The 2024 EMAS Position Statement formally recognises the diagnostic challenge.</strong>{' '}
                The European Menopause and Andropause Society (Mintziori et al., <em>Maturitas</em>)
                concluded that thyroid disease and menopause frequently co-exist, that the symptom
                overlap creates real risk of delayed diagnosis, and that a personalised,
                multi-system approach is required. A meaningful workup pairs a full thyroid panel
                (TSH, free T4, free T3, anti-TPO, anti-thyroglobulin) with reproductive hormones
                (oestradiol, progesterone, FSH, LH, testosterone, AMH) and adrenal context
                (diurnal cortisol).
              </li>
            </ul>
          </div>
        </section>

        <div className="article__body shell shell--article">
          <p className="article__lede">
            The years between 35 and 50 sit at a complex biological crossroads. The ovaries begin
            their long taper towards menopause, often quietly, before most women notice. At the
            same time the thyroid, the body’s central metabolic regulator, is undergoing changes
            that disproportionately affect women in this decade. The two systems do not behave
            independently, and yet conventional medicine continues to treat them as separate
            clinical questions, often with a single TSH measurement and a wait-and-see approach.
          </p>
          <p>
            This review examines the evidence for what should be the new standard: paired testing
            of thyroid and reproductive hormones in women aged 35 to 50, with adrenal context
            where indicated. The case rests on three converging lines of research: the high
            prevalence of thyroid dysfunction in this age group, the overlapping symptom profile
            that makes symptom-based diagnosis unreliable, and the growing evidence that thyroid
            autoimmunity directly affects ovarian reserve.
          </p>

          <h2 className="article__h2">How common is thyroid dysfunction in midlife women?</h2>
          <p>
            Thyroid dysfunction is one of the most common endocrinopathies in women, and its
            prevalence rises with age<Ref n={1} />. The two largest population studies provide a
            clear picture across iodine status. In a previously iodine-deficient region of northern
            Germany, between 8 and 10&thinsp;% of women aged 40 to 59 had abnormally low TSH
            levels, rising to 14 to 20&thinsp;% in those aged 60 to 79<Ref n={2} /><Ref n={3} />.
            In an iodine-replete population, the Colorado Thyroid Disease Prevalence Study found
            elevated TSH consistent with hypothyroidism or subclinical hypothyroidism in
            approximately 10&thinsp;% of women aged 45 to 54, rising to 21&thinsp;% in those aged
            75 and older<Ref n={4} />.
          </p>
          <p>
            In other words, depending on where a woman lives and how her clinical biochemistry is
            interpreted, somewhere between 10 and 20&thinsp;% of women in their 40s and 50s have
            measurable thyroid dysfunction, and a meaningful proportion of these cases are
            undiagnosed.
          </p>
          <p>
            Autoimmune disease drives much of this. Anti-thyroid peroxidase (TPO) antibodies, the
            principal serological marker of Hashimoto’s thyroiditis, are found in around
            7&thinsp;% of teenage girls and rise progressively with age to roughly 30&thinsp;% of
            women over 80. The reasons are multifactorial. Oestrogen modulates T-helper cell
            populations and influences thyroid peroxidase activity, and the immune fluctuations
            that accompany changing sex hormones during perimenopause appear to lower the
            threshold for autoimmune activation.
          </p>

          <h2 className="article__h2">Why the symptoms are nearly identical</h2>
          <p>
            Hypothyroidism and perimenopause produce clinical pictures that are difficult to
            distinguish without specific testing. Both cause fatigue, weight gain (particularly
            central adiposity), brain fog, low mood, anxiety, sleep disturbance, hair thinning,
            and cold intolerance.
          </p>
          <p>
            A 2020 study by Słopień and colleagues in the <em>Journal of Endocrinological
            Investigation</em> found that climacteric symptoms in euthyroid menopausal women
            correlate with thyroid hormone status even within the conventional reference
            range<Ref n={5} />. Where exactly a woman’s thyroid markers sit inside the so-called
            normal range appears to predict how severely she experiences menopausal symptoms,
            which has direct implications for how testing is interpreted.
          </p>
          <p>
            Hyperthyroidism, often overlooked in midlife, also mimics perimenopause. Sweating,
            palpitations, sleep disorders, and nervousness occur in both. A large cross-sectional
            study by Boelaert and colleagues found that women over 61 with hyperthyroidism
            frequently present with few or no classical symptoms, making the diagnosis harder
            still<Ref n={6} />. The German review by Frank-Raue and Raue concludes that the
            threshold for measuring TSH in this age group should be deliberately low<Ref n={1} />.
          </p>

          <h2 className="article__h2">Why TSH alone is not enough</h2>
          <p>
            The standard clinical approach to thyroid screening relies heavily on TSH alone, with
            a reference range typically spanning 0.3 to 4.0 mIU/L. Three problems make this
            insufficient for women aged 35 to 50.
          </p>
          <p>
            First, <strong>TSH rises naturally with age in women.</strong> A French study of more
            than 156,000 TSH measurements (Rosario and colleagues) demonstrated that the upper
            limit of the TSH reference range increases continuously in women from age 30
            onwards<Ref n={7} />. The American Thyroid Association has reported that the upper
            normal limit in 50-year-old women is approximately 4.0 mIU/L, rising by roughly
            50&thinsp;% by age 90. Using a single fixed cut-off across all ages misclassifies a
            substantial number of women in both directions.
          </p>
          <p>
            Second, <strong>TSH normalises late in autoimmune thyroid disease.</strong> In the
            natural history of Hashimoto’s thyroiditis, antibodies appear first, followed by
            thyroid tissue infiltration, with TSH rising only once the gland’s reserve capacity is
            depleted. A woman can have positive anti-TPO antibodies and active thyroid
            autoimmunity for years while her TSH remains in range. The 2015 meta-analysis by Blum
            and colleagues in <em>JAMA</em> confirmed that subclinical thyroid dysfunction is
            itself an independent risk factor for adverse outcomes: subclinical hyperthyroidism
            increased vertebral fracture risk by approximately 3.6-fold<Ref n={8} />.
          </p>
          <p>
            Third, <strong>TSH does not measure the active hormone reaching the cells.</strong>{' '}
            TSH reflects the brain’s instruction to the thyroid. Free T3 and free T4 reflect the
            active hormone available to tissues. Conversion of T4 to active T3 happens
            peripherally, is mediated by the deiodinase enzymes, depends on selenium and zinc, and
            is inhibited by elevated cortisol. A woman can have normal TSH and free T4 but low
            free T3 if conversion is impaired, often producing a clinical picture indistinguishable
            from overt hypothyroidism.
          </p>

          <h2 className="article__h2">Thyroid autoimmunity is linked to ovarian decline</h2>
          <p>
            One of the more striking developments in the last three years is the body of evidence
            linking thyroid autoimmunity to diminished ovarian reserve, even in women with normal
            TSH.
          </p>
          <p>
            The most recent and largest study, by Arlıer and Kükrer in <em>Journal of Clinical
            Medicine</em> (November 2025), evaluated 1,460 euthyroid infertile women aged 18 to
            45<Ref n={9} />. After adjustment for age, BMI, and TSH, anti-TPO positivity was
            associated with lower AMH and lower antral follicle count, with the strongest effect
            observed in women over 35. The authors concluded that thyroid autoimmunity may
            identify a subgroup of women at higher risk of accelerated reproductive ageing.
          </p>
          <p>
            An earlier prospective study in <em>International Journal of Molecular Sciences</em>{' '}
            (Tańska and colleagues) compared 45 women with thyroid autoimmunity to 45 age-matched
            controls undergoing infertility treatment<Ref n={10} />. Anti-TPO-positive women had a
            median AMH of 1.7 ng/mL compared with 3.6 ng/mL in antibody-negative controls, and
            significantly lower antral follicle counts (medians of 8 versus 11). They also had a
            higher rate of sub-optimal response to ovarian stimulation, lower fertilisation rate,
            and fewer high-quality embryos.
          </p>
          <p>
            A 2024 study in <em>Frontiers in Endocrinology</em> of 2,867 women undergoing first
            IVF cycles (Zhang and colleagues) found that both subclinical and overt hypothyroidism
            were independently associated with diminished ovarian reserve, suggesting that
            thyroid hormone insufficiency and thyroid autoimmunity contribute through separate
            but additive pathways<Ref n={11} />.
          </p>
          <p>
            The clinical implication is significant. A woman in her late 30s presenting with
            subfertility, cycle changes, or early signs of perimenopause may be carrying
            undiagnosed autoimmune thyroid disease that is actively reducing her ovarian reserve,
            while her TSH reads as normal.
          </p>

          <h2 className="article__h2">The HPO, HPT, and HPA axes are linked</h2>
          <p>
            The hypothalamic-pituitary-ovarian (HPO) axis, the hypothalamic-pituitary-thyroid
            (HPT) axis, and the hypothalamic-pituitary-adrenal (HPA) axis share signalling
            architecture and respond to each other. Three specific interactions matter for paired
            testing.
          </p>
          <p>
            <strong>Oestrogen affects thyroid hormone bioavailability.</strong> A randomised
            crossover study by Shifren and colleagues found that oral oestrogen therapy raised
            thyroxine-binding globulin by approximately 40&thinsp;%, reducing free thyroid hormone
            availability, while transdermal oestradiol had no such effect<Ref n={12} />. In a
            separate study, 10 of 25 women on levothyroxine required dose increases when oral
            hormone replacement was started<Ref n={13} />. This matters: a woman beginning oral
            menopausal hormone therapy needs her thyroid panel rechecked at two to three months.
            Transdermal delivery avoids this issue.
          </p>
          <p>
            <strong>Cortisol suppresses T4 to T3 conversion.</strong> Elevated cortisol inhibits
            5′-deiodinase, shunting T4 toward inactive reverse T3 instead of active free T3.
            Chronic stress can therefore produce a clinical picture of hypothyroidism with
            apparently normal TSH and total thyroid hormones. Diurnal salivary cortisol
            assessment or a DUTCH (dried urine) test can identify this pattern.
          </p>
          <p>
            <strong>Thyroid dysfunction can accelerate reproductive decline.</strong>{' '}
            Hypothyroidism elevates prolactin, which suppresses GnRH and lowers oestrogen and
            testosterone production. The combination of autoimmune attack on the thyroid and
            prolactin-mediated suppression of the ovary may compound the natural reproductive
            decline of perimenopause.
          </p>

          <h2 className="article__h2">What a paired-marker workup looks like</h2>
          <p>
            The 2024 EMAS Position Statement on Thyroid Disease and Menopause recommends a
            personalised, multi-system approach in this age group<Ref n={14} />. Translating that
            recommendation into specific markers, a comprehensive workup includes the following.
          </p>
          <p>
            <strong>For the thyroid:</strong> TSH, free T4, free T3, reverse T3, anti-TPO
            antibodies, and anti-thyroglobulin antibodies. Conventional laboratory reference
            ranges typically place the upper limit of TSH at around 4.0 to 4.5 mIU/L. Functional
            medicine practice, drawn from observational data and clinical experience rather than
            randomised trials, typically targets TSH in the 0.3 to 2.0 mIU/L range, free T3 above
            approximately 3.2 pg/mL, and TPO antibodies below 9 IU/mL. The distinction between
            conventional and functional ranges is important: the conventional range identifies
            overt disease, while the functional range aims to identify subclinical dysfunction
            that may already be producing symptoms.
          </p>
          <p>
            <strong>For the reproductive axis:</strong> oestradiol, progesterone, FSH, LH, total
            and free testosterone, and AMH. AMH is particularly useful in women aged 35 to 50 as
            a quantitative marker of ovarian reserve, though it does fluctuate. A single FSH
            measurement can be misleading in perimenopause because levels vary significantly
            cycle to cycle.
          </p>
          <p>
            <strong>For adrenal context:</strong> diurnal salivary cortisol measured at four
            timepoints, or a DUTCH test, which provides cortisol metabolites in addition to free
            cortisol and can identify slow cortisol clearance, often itself a sign of underlying
            hypothyroidism.
          </p>

          <h2 className="article__h2">What this means</h2>
          <p>
            The clinical case for paired testing in women aged 35 to 50 is no longer experimental.
            Three independent lines of evidence converge: thyroid dysfunction is common in this
            age group, its symptoms are clinically indistinguishable from perimenopause, and
            thyroid autoimmunity appears to accelerate ovarian reserve decline through mechanisms
            that may be independent of overt hormonal change.
          </p>
          <p>
            For women, this means that a normal TSH does not rule out thyroid involvement, and
            that fatigue, weight gain, cycle changes, and mood symptoms in midlife deserve a more
            complete laboratory workup than a single-marker approach can provide. For clinicians,
            it means that treating perimenopause and thyroid dysfunction as separate problems,
            sequentially investigated, can delay diagnosis by years.
          </p>
          <p>
            The next frontier in research is whether early identification and treatment of
            subclinical or autoimmune thyroid disease in women aged 35 to 50 modifies the
            trajectory of perimenopausal symptoms or preserves ovarian reserve. Trials addressing
            this question directly are limited, but the observational and mechanistic data
            already support a more thorough diagnostic approach now, while the trials catch up.
          </p>
        </div>

        <section className="article__citations">
          <div className="shell shell--article">
            <p className="section-eyebrow">Citations</p>
            <ol className="article__cite-list">
              <li id="cite-1">
                Frank-Raue K, Raue F.{' '}
                <a href="https://pmc.ncbi.nlm.nih.gov/articles/PMC10398375/" target="_blank" rel="noopener noreferrer">
                  Thyroid Dysfunction in Peri- and Postmenopausal Women: Cumulative Risks
                </a>.{' '}
                <em>Deutsches Ärzteblatt International</em>. 2023;120(18):311–316.
                doi:10.3238/arztebl.m2023.0069
              </li>
              <li id="cite-2">
                Völzke H, Lüdemann J, Robinson DM, et al.{' '}
                <a href="https://pubmed.ncbi.nlm.nih.gov/14558922/" target="_blank" rel="noopener noreferrer">
                  The prevalence of undiagnosed thyroid disorders in a previously iodine-deficient area
                </a>.{' '}
                <em>Thyroid</em>. 2003;13:803–810.
              </li>
              <li id="cite-3">
                Khattak RM, Ittermann T, Nauck M, Below H, Völzke H.{' '}
                <a href="https://pubmed.ncbi.nlm.nih.gov/27833458/" target="_blank" rel="noopener noreferrer">
                  Monitoring the prevalence of thyroid disorders in the adult population of Northeast Germany
                </a>.{' '}
                <em>Population Health Metrics</em>. 2016;14.
              </li>
              <li id="cite-4">
                Canaris GJ, Manowitz NR, Mayor G, Ridgway EC.{' '}
                <a href="https://pubmed.ncbi.nlm.nih.gov/10695693/" target="_blank" rel="noopener noreferrer">
                  The Colorado Thyroid Disease Prevalence Study
                </a>.{' '}
                <em>Archives of Internal Medicine</em>. 2000;160:526–534.
              </li>
              <li id="cite-5">
                Słopień R, Owecki M, Słopień A, Bala G, Meczekalski B.{' '}
                <a href="https://pubmed.ncbi.nlm.nih.gov/31392574/" target="_blank" rel="noopener noreferrer">
                  Climacteric symptoms are related to thyroid status in euthyroid menopausal women
                </a>.{' '}
                <em>Journal of Endocrinological Investigation</em>. 2020;43:75–80.
              </li>
              <li id="cite-6">
                Boelaert K, Torlinska B, Holder RL, Franklyn JA.{' '}
                <a href="https://pubmed.ncbi.nlm.nih.gov/20392869/" target="_blank" rel="noopener noreferrer">
                  Older subjects with hyperthyroidism present with a paucity of symptoms and signs
                </a>.{' '}
                <em>Journal of Clinical Endocrinology and Metabolism</em>. 2010;95:2715–2726.
              </li>
              <li id="cite-7">
                Rosario PW, Bessa B, Valadão MMA, Purisch S.{' '}
                <a href="https://pmc.ncbi.nlm.nih.gov/articles/PMC7141356/" target="_blank" rel="noopener noreferrer">
                  Age- and Sex-Specific TSH Upper-Limit Reference Intervals in the General French Population
                </a>.{' '}
                <em>Journal of Clinical Medicine</em>. 2020.
              </li>
              <li id="cite-8">
                Blum MR, Bauer DC, Collet TH, et al.{' '}
                <a href="https://pubmed.ncbi.nlm.nih.gov/26010634/" target="_blank" rel="noopener noreferrer">
                  Subclinical thyroid dysfunction and fracture risk: a meta-analysis
                </a>.{' '}
                <em>JAMA</em>. 2015;313:2055–2065.
              </li>
              <li id="cite-9">
                Arlıer S, Kükrer S.{' '}
                <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC12653286/" target="_blank" rel="noopener noreferrer">
                  Autoimmune Thyroid Disease and Female Fertility: Does Anti-TPO Accelerate Ovarian Aging?
                </a>{' '}
                <em>Journal of Clinical Medicine</em>. 2025;14(22):8024.
                doi:10.3390/jcm14228024
              </li>
              <li id="cite-10">
                Tańska K, et al.{' '}
                <a href="https://www.mdpi.com/1422-0067/24/5/4705" target="_blank" rel="noopener noreferrer">
                  Impact of Antithyroperoxidase Antibodies (Anti-TPO) on Ovarian Reserve and Early Embryo Development in Assisted Reproductive Technology Cycles
                </a>.{' '}
                <em>International Journal of Molecular Sciences</em>. 2023;24(5):4705.
              </li>
              <li id="cite-11">
                Zhang H, Qiu H, Liu Z, et al.{' '}
                <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC11666349/" target="_blank" rel="noopener noreferrer">
                  Subclinical/overt hypothyroidism may be associated with diminished ovarian reserve in infertile women independent of thyroid autoimmunity
                </a>.{' '}
                <em>Frontiers in Endocrinology</em>. 2024.
                doi:10.3389/fendo.2024.1477665
              </li>
              <li id="cite-12">
                Shifren JL, Desindes S, McIlwain M, Doros G, Mazer NA.{' '}
                <a href="https://pubmed.ncbi.nlm.nih.gov/17507833/" target="_blank" rel="noopener noreferrer">
                  A randomized, open-label, crossover study comparing the effects of oral versus transdermal estrogen therapy on serum androgens, thyroid hormones, and adrenal hormones in naturally menopausal women
                </a>.{' '}
                <em>Menopause</em>. 2007;14:985–994.
              </li>
              <li id="cite-13">
                Arafah BM.{' '}
                <a href="https://pubmed.ncbi.nlm.nih.gov/11396440/" target="_blank" rel="noopener noreferrer">
                  Increased need for thyroxine in women with hypothyroidism during estrogen therapy
                </a>.{' '}
                <em>New England Journal of Medicine</em>. 2001;344:1743–1749.
              </li>
              <li id="cite-14">
                Mintziori G, Veneti S, Poppe K, et al.{' '}
                <a href="https://pubmed.ncbi.nlm.nih.gov/38658290/" target="_blank" rel="noopener noreferrer">
                  EMAS position statement: Thyroid disease and menopause
                </a>.{' '}
                <em>Maturitas</em>. 2024;185:107991.
                doi:10.1016/j.maturitas.2024.107991
              </li>
            </ol>
          </div>
        </section>
      </article>

      <ClosingCTA onPaid={() => openApply()} onGuide={() => openGuide()} />
      <Footer onCookieOpen={() => setCookieOpen(true)} />

      <CookieBanner
        open={cookieOpen}
        onAccept={handleAcceptAll}
        onReject={handleReject}
        onCustom={handleCustom} />

      {applyOpen && <ApplyModal onClose={() => setApplyOpen(false)} />}
    </>);

}

/* ----------------------------------------------------------
   Page router — dispatches based on the root element's
   data-page attribute. Default = homepage.
   ---------------------------------------------------------- */
const __rootEl = document.getElementById('root');
const __pageKey = __rootEl && __rootEl.dataset.page;
const PageComponent =
__pageKey === 'clarity' ? ClarityPage :
__pageKey === 'guide' ? GuidePage :
__pageKey === 'about' ? AboutPage :
__pageKey === 'legal' ? LegalPage :
__pageKey === 'study-peri-thyroid' ? PeriThyroidArticlePage :
App;
ReactDOM.createRoot(__rootEl).render(<PageComponent />);