// Shared chrome: nav, footer, hero background, bio section, social icons.
// Desktop (> 810 px) — original 1920-px fixed layout, scaled by index.html JS.
// Tablet (≤ 810 px) / Mobile (≤ 390 px) — fluid responsive layouts per Figma V3.

// ─── Breakpoint hook ─────────────────────────────────────────────────────────
// FIVE isolated breakpoints — each renders its own JSX branch in every
// responsive component, so a direct edit at one width never bleeds into
// the others.
//
//   smallMobile  : ≤ 480 px        (Small Mobile  320 – 480)
//   largeMobile  : 481 – 767 px    (Large Mobile)
//   tablet       : 768 – 1024 px
//   desktop      : 1025 – 1200 px
//   largeDesktop : > 1200 px       (e.g. 1400, 1920)
//
// Legacy back-compat: if __forcedBp is the old 3-bucket string
// ('mobile'/'tablet'/'desktop'), we map it to the closest 5-bucket name.
function useBreakpoint() {
  const get = () => {
    if (typeof window === 'undefined') return 'largeDesktop';
    const forced = window.__forcedBp;
    if (forced === 'smallMobile' || forced === 'largeMobile' ||
    forced === 'tablet' || forced === 'desktop' || forced === 'largeDesktop') {
      return forced;
    }
    // Legacy strings → 5-bucket
    if (forced === 'mobile') return 'largeMobile';
    if (forced === 'desktop') return 'desktop'; // explicit caller likely means non-large
    // When a numeric forced width is set, classify by *that* width — not
    // the host window — so the preview shows the right layout.
    const w = typeof forced === 'number' ? forced : window.innerWidth;
    if (w <= 480) return 'smallMobile';
    if (w <= 767) return 'largeMobile';
    if (w <= 1024) return 'tablet';
    if (w <= 1200) return 'desktop';
    return 'largeDesktop';
  };
  const [bp, setBp] = React.useState(get);
  React.useEffect(() => {
    const update = () => setBp(get());
    window.addEventListener('resize', update);
    window.addEventListener('forcedBpChange', update);
    return () => {
      window.removeEventListener('resize', update);
      window.removeEventListener('forcedBpChange', update);
    };
  }, []);
  return bp;
}

// ─── Animation styles (injected once) ────────────────────────────────────────
if (typeof document !== 'undefined' && !document.getElementById('spl-anim-styles')) {
  const s = document.createElement('style');
  s.id = 'spl-anim-styles';
  s.textContent = `
    @keyframes splFadeUp {
      0%   { opacity: 0; transform: translate3d(0, 28px, 0); filter: blur(4px); }
      60%  { filter: blur(0); }
      100% { opacity: 1; transform: translate3d(0, 0, 0); filter: blur(0); }
    }
    .spl-fade-up {
      display: inline-block;
      opacity: 0;
      animation: splFadeUp 1100ms cubic-bezier(.22,.61,.36,1) both;
    }
    .spl-fade-up-1 { animation-delay: 120ms; }
    .spl-fade-up-2 { animation-delay: 340ms; }

    .spl-reveal {
      opacity: 0;
      transform: translate3d(0, 24px, 0);
      filter: blur(3px);
      transition:
        opacity 1000ms cubic-bezier(.22,.61,.36,1),
        transform 1000ms cubic-bezier(.22,.61,.36,1),
        filter 800ms cubic-bezier(.22,.61,.36,1);
      will-change: opacity, transform, filter;
    }
    .spl-reveal.is-in {
      opacity: 1;
      transform: translate3d(0, 0, 0);
      filter: blur(0);
    }

    @media (prefers-reduced-motion: reduce) {
      .spl-fade-up, .spl-reveal {
        animation: none !important;
        transition: none !important;
        opacity: 1 !important;
        transform: none !important;
        filter: none !important;
      }
    }
  `;
  document.head.appendChild(s);
}

// ─── In-view hook ────────────────────────────────────────────────────────────
// One-shot IntersectionObserver: returns [ref, hasEnteredViewport].
function useInView({ threshold = 0.25, rootMargin = '0px 0px -8% 0px' } = {}) {
  const ref = React.useRef(null);
  const [seen, setSeen] = React.useState(false);
  React.useEffect(() => {
    if (!ref.current || seen) return;
    if (typeof IntersectionObserver === 'undefined') {setSeen(true);return;}
    const io = new IntersectionObserver(([entry]) => {
      if (entry.isIntersecting) {setSeen(true);io.disconnect();}
    }, { threshold, rootMargin });
    io.observe(ref.current);
    return () => io.disconnect();
  }, [seen, threshold, rootMargin]);
  return [ref, seen];
}

// ─── Stack-overlap hook ───────────────────────────────────────────────────────
// Makes a section rise up and overlap the section before it as you scroll into
// it. The section keeps a permanent negative margin so its rounded top always
// sits over the previous block; this hook animates a transient translateY that
// cancels that overlap on entry and eases it to zero, so the overlap grows with
// scroll. Respects prefers-reduced-motion (no-op → static overlap).
function useStackOverlap({ rise = 72 } = {}) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
    let raf = null;
    const update = () => {
      raf = null;
      const rect = el.getBoundingClientRect();
      const vh = window.innerHeight || document.documentElement.clientHeight;
      const start = vh;
      const end = vh * 0.45;
      let p = (start - rect.top) / (start - end);
      p = Math.max(0, Math.min(1, p));
      const eased = 1 - Math.pow(1 - p, 3); // easeOutCubic
      el.style.transform = `translate3d(0, ${((1 - eased) * rise).toFixed(1)}px, 0)`;
    };
    const onScroll = () => {if (raf == null) raf = requestAnimationFrame(update);};
    update();
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', onScroll);
    return () => {
      window.removeEventListener('scroll', onScroll);
      window.removeEventListener('resize', onScroll);
      if (raf) cancelAnimationFrame(raf);
    };
  }, [rise]);
  return ref;
}

// ─── Social Icons ─────────────────────────────────────────────────────────────
// Three icons in a row, no label.
//
// IMPORTANT: there are THREE separate components below — one per breakpoint.
// This is intentional. Direct-editing a size in the preview rewrites the inline
// style of the JSX branch currently rendered, so keeping the breakpoints in
// separate components ensures a desktop edit never touches tablet/mobile and
// vice versa. Do NOT collapse these back into a single shared component.

const SVG_YOUTUBE =
<>
    <path d="M23.5 2.6a3 3 0 0 0-2.1-2.1C19.5 0 12 0 12 0S4.5 0 2.6.5A3 3 0 0 0 .5 2.6C0 4.5 0 8.5 0 8.5s0 4 .5 5.9A3 3 0 0 0 2.6 16.5C4.5 17 12 17 12 17s7.5 0 9.4-.5a3 3 0 0 0 2.1-2.1c.5-1.9.5-5.9.5-5.9s0-4-.5-5.9Z" fill="#000" />
    <path d="M9.6 12.1V4.9l6.3 3.6-6.3 3.6Z" fill="#fff" />
  </>;

const SVG_INSTAGRAM =
<>
    <rect x="2" y="2" width="20" height="20" rx="5" stroke="#000" strokeWidth="2" />
    <circle cx="12" cy="12" r="4.5" stroke="#000" strokeWidth="2" />
    <circle cx="17.6" cy="6.4" r="1.2" fill="#000" />
  </>;

const SVG_TIKTOK =
<path d="M14.7 0h-3.5v14.7c0 1.7-1.4 3.1-3.2 3.1S4.9 16.4 4.9 14.7s1.4-3.1 3.1-3.1c.3 0 .7.1 1 .2v-3.5c-.3 0-.7-.1-1-.1C4.4 8.2 1.4 11.1 1.4 14.7S4.4 21.2 8 21.2s6.6-3 6.6-6.6V7.1c1.5 1 3.2 1.6 5 1.6V5.2c-3 0-5-2.4-5-5.2Z" fill="#000" />;

const SOCIAL_BTN_BASE = {
  borderRadius: '50%', background: '#f8ebe3',
  display: 'grid', placeItems: 'center', textDecoration: 'none', flexShrink: 0
};

// ── Desktop ──────────────────────────────────────────────────────────────────
const SocialIconsDesktop = () =>
<div style={{ display: 'flex', alignItems: 'center', gap: 24 }}>
    <a href="#" className="social-btn" onClick={(e) => e.preventDefault()} style={{ ...SOCIAL_BTN_BASE, width: 70, height: 70 }}>
      <svg width={40} height={28} viewBox="0 0 24 17" fill="none">{SVG_YOUTUBE}</svg>
    </a>
    <a href="#" className="social-btn" onClick={(e) => e.preventDefault()} style={{ ...SOCIAL_BTN_BASE, width: 70, height: 70 }}>
      <svg width={36} height={36} viewBox="0 0 24 24" fill="none">{SVG_INSTAGRAM}</svg>
    </a>
    <a href="#" className="social-btn" onClick={(e) => e.preventDefault()} style={{ ...SOCIAL_BTN_BASE, width: 70, height: 70 }}>
      <svg width={33} height={36} viewBox="0 0 20 22" fill="none">{SVG_TIKTOK}</svg>
    </a>
  </div>;


// ── Tablet ───────────────────────────────────────────────────────────────────
const SocialIconsTablet = () =>
<div style={{ display: 'flex', alignItems: 'center', gap: 20 }}>
    <a href="#" className="social-btn" onClick={(e) => e.preventDefault()} style={{ ...SOCIAL_BTN_BASE, width: 50, height: 50 }}>
      <svg width={25} height={18} viewBox="0 0 24 17" fill="none">{SVG_YOUTUBE}</svg>
    </a>
    <a href="#" className="social-btn" onClick={(e) => e.preventDefault()} style={{ ...SOCIAL_BTN_BASE, width: 50, height: 50 }}>
      <svg width={25} height={25} viewBox="0 0 24 24" fill="none">{SVG_INSTAGRAM}</svg>
    </a>
    <a href="#" className="social-btn" onClick={(e) => e.preventDefault()} style={{ ...SOCIAL_BTN_BASE, width: 50, height: 50 }}>
      <svg width={23} height={25} viewBox="0 0 20 22" fill="none">{SVG_TIKTOK}</svg>
    </a>
  </div>;


// ── Mobile ───────────────────────────────────────────────────────────────────
const SocialIconsMobile = () =>
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
    <a href="#" className="social-btn" onClick={(e) => e.preventDefault()} style={{ ...SOCIAL_BTN_BASE, width: 38, height: 38 }}>
      <svg width={21} height={15} viewBox="0 0 24 17" fill="none">{SVG_YOUTUBE}</svg>
    </a>
    <a href="#" className="social-btn" onClick={(e) => e.preventDefault()} style={{ ...SOCIAL_BTN_BASE, width: 38, height: 38 }}>
      <svg width={21} height={21} viewBox="0 0 24 24" fill="none">{SVG_INSTAGRAM}</svg>
    </a>
    <a href="#" className="social-btn" onClick={(e) => e.preventDefault()} style={{ ...SOCIAL_BTN_BASE, width: 38, height: 38 }}>
      <svg width={20} height={20} viewBox="0 0 20 22" fill="none">{SVG_TIKTOK}</svg>
    </a>
  </div>;


// Back-compat wrapper for any caller still using <SocialIcons size="…" />
const SocialIcons = ({ size = 'desktop' }) => {
  if (size === 'tablet') return <SocialIconsTablet />;
  if (size === 'mobile') return <SocialIconsMobile />;
  return <SocialIconsDesktop />;
};

// ─── NavBar ───────────────────────────────────────────────────────────────────
const NavBar = ({ brand }) => {
  const bp = useBreakpoint();

  // ── Desktop: exact original ────────────────────────────────────────────────
  // ── Large Desktop ───────────────────────────────────────────────────────
  if (bp === 'largeDesktop') {
    return (
      <header style={{
        position: 'absolute', left: 0, top: 0, right: 0, height: 149,
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        zIndex: 5, padding: '128px 128px 64px'
      }}>
        <div style={{ fontFamily: 'Instrument Serif', letterSpacing: '-0.02em', color: '#000', fontWeight: 500, fontSize: "36px" }}>{brand}</div>
        <SocialIconsDesktop />
      </header>);

  }

  if (bp === 'desktop') {
    return (
      <header style={{
        position: 'absolute', left: 0, top: 0, right: 0, height: 149,
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        zIndex: 5, padding: '128px 128px 64px'
      }}>
        <div style={{ fontFamily: 'Instrument Serif', letterSpacing: '-0.02em', color: '#000', fontWeight: 500, fontSize: "36px" }}>{brand}</div>
        <SocialIconsDesktop />
      </header>);

  }

  // ── Tablet: more top margin so logo + socials sit lower ──────────────────
  if (bp === 'tablet') {
    return (
      <header style={{
        position: 'absolute', left: 0, top: 0, right: 0,
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        zIndex: 5, padding: '56px 64px 0'
      }}>
        <div style={{ fontFamily: 'Instrument Serif', letterSpacing: '-0.02em', color: '#000', fontWeight: 500, fontSize: "30px" }}>{brand}</div>
        <SocialIconsTablet />
      </header>);

  }

  // ── Large Mobile ──────────────────────────────────────────────────────
  if (bp === 'largeMobile') {
    return (
      <header style={{
        position: 'absolute', left: 0, top: 0, right: 0,
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        zIndex: 5, padding: '32px 24px 0'
      }}>
        <div style={{ fontFamily: 'Instrument Serif', fontSize: 20, letterSpacing: '-0.02em', color: '#000', fontWeight: "500" }}>{brand}</div>
        <SocialIconsMobile />
      </header>);

  }

  // ── Small Mobile ──────────────────────────────────────────────────────
  return (
    <header style={{
      position: 'absolute', left: 0, top: 0, right: 0,
      display: 'flex', justifyContent: 'space-between', alignItems: 'center',
      zIndex: 5, padding: '32px 24px 0'
    }}>
      <div style={{ fontFamily: 'Instrument Serif', fontSize: 20, letterSpacing: '-0.02em', color: '#000', fontWeight: "500" }}>{brand}</div>
      <SocialIconsMobile />
    </header>);

};

// ─── Hero Backdrop ────────────────────────────────────────────────────────────
// Desktop: fixed 1500 px tall.
// Tablet/Mobile: shrinks so the warm zone ends at the vertical midpoint of the
// main product image (measured live from the DOM — robust against per-template
// padding variation).
const HeroBackdrop = ({ fraction, tilt }) => {
  const bp = useBreakpoint();
  const ref = React.useRef(null);
  const [height, setHeight] = React.useState(1500);

  const isDesktopBp = bp === 'desktop' || bp === 'largeDesktop';
  // `tilt` is only honored on desktop / large desktop. When on, the backdrop
  // gets a taller container + a diagonal mask so the warm zone slopes down to
  // the right (more visible on the right side). Avg coverage still ≈ 1/3 of
  // main thanks to the gradient stops.
  const tiltOn = !!tilt && isDesktopBp;

  // On desktop / large desktop, default the warm zone to 1/3 of the page
  // (parent <main>) height. Pages can still pass `fraction` to override.
  // In tilt mode we use a larger share so the diagonal has room.
  const effectiveFraction = typeof fraction === 'number' && fraction > 0 ?
  fraction :
  tiltOn ? 0.55 : isDesktopBp ? 1 / 3 : null;

  React.useEffect(() => {
    // ── Fraction mode ───────────────────────────────────────────────────────
    // When a fraction is in play, the backdrop sizes itself to that share of
    // the parent <main> height (live-measured). Used by the payment page —
    // and by default on desktop / large desktop — so the warm animation zone
    // only occupies the top third of the page.
    if (effectiveFraction) {
      const el = ref.current;
      if (!el) return;
      const main = el.closest('main');
      if (!main) return;
      const measure = () => {
        // Use offsetHeight (unscaled layout px) — the parent <main> sits
        // inside #scale-root which is transform: scale()'d on desktop, so
        // getBoundingClientRect would return visual (scaled) pixels and the
        // resulting inline `height` style — interpreted in layout px — would
        // shrink by the scale factor.
        const h = main.offsetHeight;
        if (h > 0) setHeight(Math.round(h * effectiveFraction));
      };
      measure();
      const ro = new ResizeObserver(measure);
      ro.observe(main);
      window.addEventListener('resize', measure);
      return () => {
        ro.disconnect();
        window.removeEventListener('resize', measure);
      };
    }

    const el = ref.current;
    if (!el) return;
    const main = el.closest('main');
    if (!main) return;

    const findAnchor = () =>
    // Prefer an explicit hero anchor (used by templates whose main image is
    // a <div> with a background-image rather than an <img>). Fall back to
    // the first <img> inside any <section>.
    main.querySelector('[data-hero-anchor]') ||
    main.querySelector('section img');

    const measure = () => {
      const anchor = findAnchor();
      if (!anchor) return;
      const mainTop = main.getBoundingClientRect().top;
      const aRect = anchor.getBoundingClientRect();
      const midRel = aRect.top - mainTop + aRect.height / 2;
      if (midRel > 0) setHeight(Math.round(midRel));
    };

    measure();
    const ro = new ResizeObserver(measure);
    ro.observe(main);
    const imgs = main.querySelectorAll('section img, [data-hero-anchor] img');
    imgs.forEach((i) => i.addEventListener('load', measure));
    window.addEventListener('resize', measure);
    return () => {
      ro.disconnect();
      imgs.forEach((i) => i.removeEventListener('load', measure));
      window.removeEventListener('resize', measure);
    };
  }, [bp, effectiveFraction]);

  return (
    <div ref={ref} style={{
      position: 'absolute', top: 0,
      left: 'var(--bg-offset)',
      width: 'var(--bg-width)',
      height: height, overflow: 'hidden', pointerEvents: 'none',
      background: '#ffffff',
      // Fade the bottom of the animation container to transparent so the
      // hard container edge — and any blob clipping at that edge — is never
      // visible against the white page below. In tilt mode the fade runs
      // diagonally (warm zone slopes down to the right).
      WebkitMaskImage: tiltOn ?
      'linear-gradient(220deg, #000 0%, #000 38%, rgba(0,0,0,0) 88%)' :
      'linear-gradient(to bottom, #000 0%, #000 65%, rgba(0,0,0,0) 100%)',
      maskImage: tiltOn ?
      'linear-gradient(220deg, #000 0%, #000 38%, rgba(0,0,0,0) 88%)' :
      'linear-gradient(to bottom, #000 0%, #000 65%, rgba(0,0,0,0) 100%)'
    }}>
    <style>{`
      /* Visibly drifting warm blobs — faster cycles (4–8s), wider translation
         ranges, and stronger opacity swings so motion reads at a glance.
         Prime-ish durations keep the layers from re-syncing. */
      @keyframes heroSpotA {
        0%   { transform: translate(0%,    0%)  scale(1.00); }
        50%  { transform: translate(-130%, 30%) scale(1.70); }
        100% { transform: translate(0%,    0%)  scale(1.00); }
      }
      @keyframes heroSpotB {
        0%   { transform: translate(0%,    0%)  scale(1.00); }
        50%  { transform: translate(150%, -25%) scale(1.70); }
        100% { transform: translate(0%,    0%)  scale(1.00); }
      }
      @keyframes heroSpotC {
        0%   { transform: translate(-85%,  18%) scale(1.20); }
        50%  { transform: translate(100%, -28%) scale(1.70); }
        100% { transform: translate(-85%,  18%) scale(1.20); }
      }
      @keyframes heroSpotD {
        0%   { transform: translate( 60%, -22%) scale(1.20); }
        50%  { transform: translate(-95%,  26%) scale(1.75); }
        100% { transform: translate( 60%, -22%) scale(1.20); }
      }
      @keyframes heroPulseA { 0%,100% { opacity: 0.55; } 50% { opacity: 1.00; } }
      @keyframes heroPulseB { 0%,100% { opacity: 0.45; } 50% { opacity: 1.00; } }
      @keyframes heroPulseC { 0%,100% { opacity: 0.45; } 50% { opacity: 1.00; } }
      @keyframes heroPulseD { 0%,100% { opacity: 0.40; } 50% { opacity: 1.00; } }
    `}</style>
    {/* Base vertical wash — static, so the top edge always reads warm */}
    <div style={{
        position: 'absolute', inset: 0,
        background: `linear-gradient(180deg,
        rgba(222,193,175,1.00) 0%,
        rgba(222,193,175,0.85) 12%,
        rgba(222,193,175,0.55) 28%,
        rgba(222,193,175,0.28) 42%,
        rgba(222,193,175,0.10) 55%,
        rgba(222,193,175,0.00) 68%)`
      }} />
    {/* Spot A — right-side warm hotspot, drifts left (~7s motion / 11s pulse) */}
    <div style={{
        position: 'absolute', top: '-30%', right: '-15%', width: '110%', height: '90%',
        background: 'radial-gradient(closest-side, rgba(205,160,128,1.00) 0%, rgba(222,193,175,0.55) 45%, rgba(222,193,175,0) 75%)',
        filter: 'blur(25px)',
        animation: 'heroSpotA 5.5s ease-in-out infinite, heroPulseA 8.5s ease-in-out infinite',
        willChange: 'transform, opacity'
      }} />
    {/* Spot B — left cream highlight, drifts right (~9s motion / 13s pulse) */}
    <div style={{
        position: 'absolute', top: '-10%', left: '-15%', width: '70%', height: '60%',
        background: 'radial-gradient(closest-side, rgba(255,242,228,1.00) 0%, rgba(255,242,228,0) 70%)',
        filter: 'blur(30px)',
        animation: 'heroSpotB 7s ease-in-out infinite -1.5s, heroPulseB 10s ease-in-out infinite -3s',
        willChange: 'transform, opacity'
      }} />
    {/* Spot C — center peach glow, drifts horizontally (~11s motion / 17s pulse) */}
    <div style={{
        position: 'absolute', top: '-20%', left: '15%', width: '70%', height: '80%',
        background: 'radial-gradient(closest-side, rgba(228,190,160,1.00) 0%, rgba(228,190,160,0) 70%)',
        filter: 'blur(40px)',
        animation: 'heroSpotC 8.5s ease-in-out infinite -4s, heroPulseC 13s ease-in-out infinite -5.5s',
        willChange: 'transform, opacity'
      }} />
    {/* Spot D — lower-mid amber, drifts the opposite way (~13s motion / 19s pulse). */}
    <div style={{
        position: 'absolute', top: '0%', left: '30%', width: '60%', height: '70%',
        background: 'radial-gradient(closest-side, rgba(210,170,135,1.00) 0%, rgba(210,170,135,0) 70%)',
        filter: 'blur(35px)',
        animation: 'heroSpotD 10s ease-in-out infinite -6s, heroPulseD 15s ease-in-out infinite -2.5s',
        willChange: 'transform, opacity'
      }} />
  </div>);
};


// ─── Bio Section ──────────────────────────────────────────────────────────────
// Desktop: side-by-side (text left, portrait right) — unchanged.
// Tablet + Mobile: single column — portrait (3:2 crop) on top, text below (Figma V3).
const BioSection = ({ portrait, role, story, headline }) => {
  const bp = useBreakpoint();
  const [titleRef, titleSeen] = useInView({ threshold: 0.35, rootMargin: '0px 0px -10% 0px' });
  const titleCls = 'serif spl-reveal' + (titleSeen ? ' is-in' : '');

  // Stack-overlap: the section rises and overlaps the block above it on scroll.
  const isDesk = bp === 'largeDesktop' || bp === 'desktop';
  const overlap = isDesk ? 72 : bp === 'tablet' ? 52 : 40;
  const radius = 0;
  // Classic scroll: no stack-overlap. Section flows normally below the block above.
  const secRef = React.useRef(null);
  const overlapStyle = { zIndex: 2 };
  const topShadow = 'none';

  // ── Desktop: exact original ────────────────────────────────────────────────
  // ── Large Desktop ───────────────────────────────────────────────────────
  if (bp === 'largeDesktop') {
    return (
      <section ref={secRef} style={{ position: 'relative', width: '100%', height: 1191, ...overlapStyle }}>
        <div style={{
          position: 'absolute', top: 0, bottom: 0,
          left: 'var(--bg-offset)', width: 'var(--bg-width)',
          background: '#fffbf9', zIndex: 0,
          borderTopLeftRadius: radius, borderTopRightRadius: radius, boxShadow: topShadow
        }} />
        <div style={{
          position: 'absolute', left: 0, top: 0, width: 1014, height: 1191,
          display: 'flex', alignItems: 'center', justifyContent: 'flex-start',
          paddingLeft: 192, zIndex: 1
        }}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 24, alignItems: 'flex-start', width: 500 }}>
            <div ref={titleRef} className={titleCls} style={{ lineHeight: '100%', letterSpacing: '-0.02em', color: '#101010', whiteSpace: 'nowrap', fontSize: "80px" }}>{headline}</div>
            <div style={{ fontFamily: 'Inter', fontWeight: 500, letterSpacing: '-1.6px', color: '#101010', fontSize: 32, lineHeight: "1.3" }}>{role}</div>
            <div style={{ fontFamily: 'Inter', fontWeight: 400, fontSize: 22, letterSpacing: '-1.1px', color: '#696a6d', lineHeight: "1.65" }}>{story}</div>
          </div>
        </div>
        <div style={{ position: 'absolute', right: 0, top: 0, width: 906, height: 1191, background: `url(${portrait}) center/cover no-repeat`, borderTopRightRadius: radius, zIndex: 1 }} />
      </section>);

  }

  if (bp === 'desktop') {
    return (
      <section ref={secRef} style={{ position: 'relative', width: '100%', height: 1191, ...overlapStyle }}>
        <div style={{
          position: 'absolute', top: 0, bottom: 0,
          left: 'var(--bg-offset)', width: 'var(--bg-width)',
          background: '#fffbf9', zIndex: 0,
          borderTopLeftRadius: radius, borderTopRightRadius: radius, boxShadow: topShadow
        }} />
        <div style={{
          position: 'absolute', left: 0, top: 0, width: 1014, height: 1191,
          display: 'flex', alignItems: 'center', justifyContent: 'flex-start',
          paddingLeft: 192, zIndex: 1
        }}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 24, alignItems: 'flex-start', width: 500 }}>
            <div ref={titleRef} className={titleCls} style={{ fontSize: 96, lineHeight: '100%', letterSpacing: '-0.02em', color: '#101010', whiteSpace: 'nowrap' }}>{headline}</div>
            <div style={{ fontFamily: 'Inter', fontWeight: 500, lineHeight: 'normal', letterSpacing: '-1.6px', color: '#101010', fontSize: 32 }}>{role}</div>
            <div style={{ fontFamily: 'Inter', fontWeight: 400, fontSize: 22, letterSpacing: '-1.1px', color: '#696a6d', lineHeight: "1.65" }}>{story}</div>
          </div>
        </div>
        <div style={{ position: 'absolute', right: 0, top: 0, width: 906, height: 1191, background: `url(${portrait}) center/cover no-repeat`, borderTopRightRadius: radius, zIndex: 1 }} />
      </section>);

  }

  // ── Tablet: single column, portrait 3:2 on top, text below ───────────────
  if (bp === 'tablet') {
    return (
      <section ref={secRef} style={{ position: 'relative', width: '100%', ...overlapStyle }}>
        <div style={{ position: 'absolute', top: 0, bottom: 0, left: 'var(--bg-offset)', width: 'var(--bg-width)', background: '#fffbf9', zIndex: 0, borderTopLeftRadius: radius, borderTopRightRadius: radius, boxShadow: topShadow }} />
        <div style={{ position: 'relative', zIndex: 1, padding: '40px 64px 64px' }}>
          {/* Portrait — full content width, 3:2 landscape crop */}
          <div style={{ width: '100%', aspectRatio: '3/2', background: `url(${portrait}) center/cover no-repeat`, marginBottom: 32, borderRadius: 16 }} />
          <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
            <div ref={titleRef} className={titleCls} style={{ lineHeight: 1, letterSpacing: '-0.02em', color: '#101010', fontSize: "48px" }}>{headline}</div>
            <div style={{ fontFamily: 'Inter', fontWeight: 500, fontSize: 17, letterSpacing: '-0.04em', color: '#101010', lineHeight: 1.35 }}>{role}</div>
            <div style={{ fontFamily: 'Inter', fontSize: 15, color: '#696a6d', lineHeight: 1.65, letterSpacing: '-0.01em' }}>{story}</div>
          </div>
        </div>
      </section>);

  }

  // ── Mobile: single column, portrait 3:2 on top (16 px side padding), text below
  // ── Large Mobile ──────────────────────────────────────────────────────
  if (bp === 'largeMobile') {
    return (
      <section ref={secRef} style={{ position: 'relative', width: '100%', ...overlapStyle }}>
        <div style={{ position: 'absolute', top: 0, bottom: 0, left: 'var(--bg-offset)', width: 'var(--bg-width)', background: '#fffbf9', zIndex: 0, borderTopLeftRadius: radius, borderTopRightRadius: radius, boxShadow: topShadow }} />
        <div style={{ position: 'relative', zIndex: 1, padding: "32px 32px 64px" }}>
          {/* Portrait — 3:2 aspect ratio, 16 px side padding → 358 px on 390 px mobile */}
          <div style={{ width: '100%', aspectRatio: '3/2', background: `url(${portrait}) 50% 20%/cover no-repeat`, marginBottom: 32, borderRadius: 14 }} />
          <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
            <div ref={titleRef} className={titleCls} style={{ lineHeight: 1, letterSpacing: '-0.02em', color: '#101010', fontSize: "32px" }}>{headline}</div>
            <div style={{ fontFamily: 'Inter', fontWeight: 500, fontSize: 15, letterSpacing: '-0.03em', color: '#101010', lineHeight: 1.4 }}>{role}</div>
            <div style={{ fontFamily: 'Inter', fontSize: 14, color: '#696a6d', lineHeight: 1.65 }}>{story}</div>
          </div>
        </div>
      </section>);

  }

  // ── Small Mobile (fallback) ──────────────────────────────────────────
  return (
    <section ref={secRef} style={{ position: 'relative', width: '100%', ...overlapStyle }}>
      <div style={{ position: 'absolute', top: 0, bottom: 0, left: 'var(--bg-offset)', width: 'var(--bg-width)', background: '#fffbf9', zIndex: 0, borderTopLeftRadius: radius, borderTopRightRadius: radius, boxShadow: topShadow }} />
      <div style={{ position: 'relative', zIndex: 1, padding: '32px 16px 64px' }}>
        {/* Portrait — 3:2 aspect ratio, 16 px side padding → 358 px on 390 px mobile */}
        <div style={{ width: '100%', aspectRatio: '3/2', background: `url(${portrait}) 50% 20%/cover no-repeat`, marginBottom: 32, borderRadius: 14 }} />
        <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          <div ref={titleRef} className={titleCls} style={{ lineHeight: 1, letterSpacing: '-0.02em', color: '#101010', fontSize: "32px" }}>{headline}</div>
          <div style={{ fontFamily: 'Inter', fontWeight: 500, fontSize: 15, letterSpacing: '-0.03em', color: '#101010', lineHeight: 1.4 }}>{role}</div>
          <div style={{ fontFamily: 'Inter', fontSize: 14, color: '#696a6d', lineHeight: 1.65 }}>{story}</div>
        </div>
      </div>
    </section>);

};

// ─── Footer ───────────────────────────────────────────────────────────────────
const Footer = ({ tagline, sub }) => {
  const bp = useBreakpoint();

  // Footer legal links open the in-page reading overlay (handled in App).
  const openLegal = key => window.dispatchEvent(new CustomEvent('openLegal', { detail: key }));
  const legalLinks = (fontSize) =>
    [['Privacy Policy', 'privacy'], ['Terms and Conditions', 'terms']].map(([label, key]) =>
      <a key={key} href="#" onClick={(e) => { e.preventDefault(); openLegal(key); }}
        onMouseEnter={(e) => (e.currentTarget.style.color = '#fff')}
        onMouseLeave={(e) => (e.currentTarget.style.color = '#b5b5b7')}
        style={{ fontFamily: 'Inter', fontWeight: 400, fontSize, letterSpacing: '-0.01em', color: '#b5b5b7', textDecoration: 'none', cursor: 'pointer', transition: 'color 180ms ease' }}>{label}</a>
    );

  // ── Desktop: exact original ────────────────────────────────────────────────
  // ── Large Desktop ───────────────────────────────────────────────────────
  if (bp === 'largeDesktop') {
    return (
      <footer style={{ position: 'relative', color: '#fff', minHeight: 276 }}>
        <div style={{ position: 'absolute', top: 0, bottom: 0, left: 'var(--bg-offset)', width: 'var(--bg-width)', background: '#101010' }} />
        <div style={{ position: 'relative', padding: '64px 128px', display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', minHeight: 276 }}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 16, maxWidth: 312 }}>
            <div className="serif" style={{ fontSize: 48, lineHeight: '54px', color: '#fff' }}>{tagline}</div>
            <div style={{ fontFamily: 'Inter', fontSize: 20, letterSpacing: '-0.05em', color: '#8b8b8b' }}>{sub}</div>
          </div>
          <nav style={{ display: 'flex', gap: 32, alignItems: 'center' }}>
            {legalLinks(16)}
          </nav>
        </div>
      </footer>);

  }

  if (bp === 'desktop') {
    return (
      <footer style={{ position: 'relative', color: '#fff', minHeight: 276 }}>
        <div style={{ position: 'absolute', top: 0, bottom: 0, left: 'var(--bg-offset)', width: 'var(--bg-width)', background: '#101010' }} />
        <div style={{ position: 'relative', padding: '64px 128px', display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', minHeight: 276 }}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 16, maxWidth: 312 }}>
            <div className="serif" style={{ fontSize: 48, lineHeight: '54px', color: '#fff' }}>{tagline}</div>
            <div style={{ fontFamily: 'Inter', fontSize: 20, letterSpacing: '-0.05em', color: '#8b8b8b' }}>{sub}</div>
          </div>
          <nav style={{ display: 'flex', gap: 32, alignItems: 'center' }}>
            {legalLinks(16)}
          </nav>
        </div>
      </footer>);

  }

  // ── Tablet: 64 px padding, tagline 28 px, 4 nav links in a row ────────────
  if (bp === 'tablet') {
    return (
      <footer style={{ position: 'relative', color: '#fff' }}>
        <div style={{ position: 'absolute', top: 0, bottom: 0, left: 'var(--bg-offset)', width: 'var(--bg-width)', background: '#101010' }} />
        <div style={{ position: 'relative', padding: '64px 64px', display: 'flex', flexDirection: 'column', gap: 48 }}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: "8px" }}>
            <div className="serif" style={{ fontSize: 28, lineHeight: 1.1, color: '#fff' }}>{tagline}</div>
            <div style={{ fontFamily: 'Inter', fontSize: 16, letterSpacing: '-0.05em', color: '#8b8b8b' }}>{sub}</div>
          </div>
          <nav style={{ display: 'flex', gap: 32, alignItems: 'center', flexWrap: 'wrap' }}>
            {legalLinks(13)}
          </nav>
        </div>
      </footer>);

  }

  // ── Mobile: 32 px padding, tagline 20 px, links in 2 columns (Figma V3) ────
  // ── Large Mobile ──────────────────────────────────────────────────────
  if (bp === 'largeMobile') {
    return (
      <footer style={{ position: 'relative', color: '#fff' }}>
        <div style={{ position: 'absolute', top: 0, bottom: 0, left: 'var(--bg-offset)', width: 'var(--bg-width)', background: '#101010' }} />
        <div style={{ position: 'relative', display: 'flex', flexDirection: 'column', gap: 28, padding: "32px" }}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: "4px" }}>
            <div className="serif" style={{ lineHeight: 1.1, color: '#fff', fontSize: "24px" }}>{tagline}</div>
            <div style={{ fontFamily: 'Inter', letterSpacing: '-0.05em', color: '#8b8b8b', fontSize: "12px" }}>{sub}</div>
          </div>
          <nav style={{ display: 'flex', flexDirection: 'row', gap: 28, alignItems: 'flex-start', flexWrap: 'wrap' }}>
            {legalLinks(11)}
          </nav>
        </div>
      </footer>);

  }

  // ── Small Mobile (fallback) ──────────────────────────────────────────
  return (
    <footer style={{ position: 'relative', color: '#fff' }}>
      <div style={{ position: 'absolute', top: 0, bottom: 0, left: 'var(--bg-offset)', width: 'var(--bg-width)', background: '#101010' }} />
      <div style={{ position: 'relative', padding: '32px 16px', display: 'flex', flexDirection: 'column', gap: 28 }}>
        <div style={{ display: 'flex', flexDirection: 'column', gap: "4px" }}>
          <div className="serif" style={{ lineHeight: 1.1, color: '#fff', fontSize: "24px" }}>{tagline}</div>
          <div style={{ fontFamily: 'Inter', letterSpacing: '-0.05em', color: '#8b8b8b', fontSize: "12px" }}>{sub}</div>
        </div>
        <nav style={{ display: 'flex', flexDirection: 'row', gap: 28, alignItems: 'flex-start', flexWrap: 'wrap' }}>
          {legalLinks(11)}
        </nav>
      </div>
    </footer>);

};

// ─── Page Title ───────────────────────────────────────────────────────────────
// THREE separate branches per breakpoint. Direct-editing the desktop branch
// never touches tablet/mobile and vice versa. Do NOT collapse back into a
// shared block with ternaries — that's exactly what made edits bleed across
// breakpoints before.
const PageTitle = ({ line1, line2 }) => {
  const bp = useBreakpoint();

  // ── Desktop ──────────────────────────────────────────────────────────────
  // ── Large Desktop ───────────────────────────────────────────────────────
  if (bp === 'largeDesktop') {
    return (
      <h1 className="serif" style={{
        margin: '0 0 24px', padding: 0,
        letterSpacing: '-0.01em', textAlign: 'center', color: '#000',
        textShadow: '0 4px 26.6px rgba(0,0,0,0.25)'
      }}>
        <span className="spl-fade-up spl-fade-up-1" style={{ display: 'inline-block', fontSize: 128, lineHeight: '120px' }}>{line1}</span><br />
        <span className="italic spl-fade-up spl-fade-up-2" style={{ display: 'inline-block', color: 'rgb(121,95,78)', fontSize: 128, lineHeight: '120px' }}>{line2}</span>
      </h1>);

  }

  if (bp === 'desktop') {
    return (
      <h1 className="serif" style={{
        margin: '0 0 24px', padding: 0,
        letterSpacing: '-0.01em', textAlign: 'center', color: '#000',
        textShadow: '0 4px 26.6px rgba(0,0,0,0.25)'
      }}>
        <span className="spl-fade-up spl-fade-up-1" style={{ display: 'inline-block', fontSize: 128, lineHeight: '120px' }}>{line1}</span><br />
        <span className="italic spl-fade-up spl-fade-up-2" style={{ display: 'inline-block', color: 'rgb(121,95,78)', fontSize: 128, lineHeight: '120px' }}>{line2}</span>
      </h1>);

  }

  // ── Tablet ───────────────────────────────────────────────────────────────
  if (bp === 'tablet') {
    return (
      <h1 className="serif" style={{
        margin: '0 0 24px', padding: 0,
        letterSpacing: '-0.01em', textAlign: 'center', color: '#000',
        textShadow: '0 4px 26.6px rgba(0,0,0,0.25)'
      }}>
        <span className="spl-fade-up spl-fade-up-1" style={{ display: 'inline-block', fontSize: 72, lineHeight: '70px' }}>{line1}</span><br />
        <span className="italic spl-fade-up spl-fade-up-2" style={{ display: 'inline-block', color: 'rgb(121,95,78)', fontSize: 72, lineHeight: '70px' }}>{line2}</span>
      </h1>);

  }

  // ── Mobile ───────────────────────────────────────────────────────────────
  // ── Large Mobile ──────────────────────────────────────────────────────
  if (bp === 'largeMobile') {
    return (
      <h1 className="serif" style={{
        margin: '0 0 24px', padding: 0,
        letterSpacing: '-0.01em', textAlign: 'center', color: '#000',
        textShadow: '0 4px 26.6px rgba(0,0,0,0.25)'
      }}>
        <span className="spl-fade-up spl-fade-up-1" style={{ display: 'inline-block', lineHeight: '44px', fontSize: "48px" }}>{line1}</span><br />
        <span className="italic spl-fade-up spl-fade-up-2" style={{ display: 'inline-block', color: 'rgb(121,95,78)', lineHeight: '44px', fontSize: "48px" }}>{line2}</span>
      </h1>);

  }

  // ── Small Mobile (fallback) ──────────────────────────────────────────
  return (
    <h1 className="serif" style={{
      margin: '0 0 24px', padding: 0,
      letterSpacing: '-0.01em', textAlign: 'center', color: '#000',
      textShadow: '0 4px 26.6px rgba(0,0,0,0.25)'
    }}>
      <span className="spl-fade-up spl-fade-up-1" style={{ display: 'inline-block', lineHeight: '44px', fontSize: "40px" }}>{line1}</span><br />
      <span className="italic spl-fade-up spl-fade-up-2" style={{ display: 'inline-block', color: 'rgb(121,95,78)', lineHeight: '44px', fontSize: "40px" }}>{line2}</span>
    </h1>);

};

// ─── Highlights ───────────────────────────────────────────────────────────────
// THREE separate branches per breakpoint — same isolation pattern as NavBar.
// Edit one without touching the others.
const Highlights = ({ label, items }) => {
  const bp = useBreakpoint();

  // ── Desktop ──────────────────────────────────────────────────────────────
  // ── Large Desktop ───────────────────────────────────────────────────────
  if (bp === 'largeDesktop') {
    return (
      <div style={{ display: 'flex', flexDirection: 'column', gap: 16, padding: 0 }}>
        <div style={{ fontFamily: 'Inter', fontWeight: 600, color: '#101010', fontSize: 22 }}>{label}</div>
        <ul style={{ margin: 0, padding: '0 0 0 20px', display: 'flex', flexDirection: 'column', gap: 10 }}>
          {items.map((it, i) =>
          <li key={i} style={{ fontFamily: 'Inter', fontWeight: 400, color: '#101010', letterSpacing: '-0.01em', fontSize: 22 }}>{it}</li>
          )}
        </ul>
      </div>);

  }

  if (bp === 'desktop') {
    return (
      <div style={{ display: 'flex', flexDirection: 'column', gap: 16, padding: 0 }}>
        <div style={{ fontFamily: 'Inter', fontWeight: 600, color: '#101010', fontSize: 22 }}>{label}</div>
        <ul style={{ margin: 0, padding: '0 0 0 20px', display: 'flex', flexDirection: 'column', gap: 10 }}>
          {items.map((it, i) =>
          <li key={i} style={{ fontFamily: 'Inter', fontWeight: 400, color: '#101010', letterSpacing: '-0.01em', fontSize: 22 }}>{it}</li>
          )}
        </ul>
      </div>);

  }

  // ── Tablet ───────────────────────────────────────────────────────────────
  if (bp === 'tablet') {
    return (
      <div style={{ display: 'flex', flexDirection: 'column', gap: 16, padding: 0 }}>
        <div style={{ fontFamily: 'Inter', fontWeight: 500, color: '#101010', fontSize: 20 }}>{label}</div>
        <ul style={{ margin: 0, padding: '0 0 0 20px', display: 'flex', flexDirection: 'column', gap: 12 }}>
          {items.map((it, i) =>
          <li key={i} style={{ fontFamily: 'Inter', fontWeight: 400, color: '#101010', letterSpacing: '-0.05em', fontSize: 20 }}>{it}</li>
          )}
        </ul>
      </div>);

  }

  // ── Mobile ───────────────────────────────────────────────────────────────
  // ── Large Mobile ──────────────────────────────────────────────────────
  if (bp === 'largeMobile') {
    return (
      <div style={{ display: 'flex', flexDirection: 'column', gap: 16, padding: 0 }}>
        <div style={{ fontFamily: 'Inter', fontWeight: 500, color: '#101010', fontSize: 14 }}>{label}</div>
        <ul style={{ margin: 0, padding: '0 0 0 20px', display: 'flex', flexDirection: 'column', gap: 8 }}>
          {items.map((it, i) =>
          <li key={i} style={{ fontFamily: 'Inter', fontWeight: 400, color: '#101010', letterSpacing: '-0.05em', fontSize: 14 }}>{it}</li>
          )}
        </ul>
      </div>);

  }

  // ── Small Mobile (fallback) ──────────────────────────────────────────
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 16, padding: 0 }}>
      <div style={{ fontFamily: 'Inter', fontWeight: 500, color: '#101010', fontSize: 14 }}>{label}</div>
      <ul style={{ margin: 0, padding: '0 0 0 20px', display: 'flex', flexDirection: 'column', gap: 8 }}>
        {items.map((it, i) =>
        <li key={i} style={{ fontFamily: 'Inter', fontWeight: 400, color: '#101010', letterSpacing: '-0.05em', fontSize: 14 }}>{it}</li>
        )}
      </ul>
    </div>);

};

// ─── Pill ─────────────────────────────────────────────────────────────────────
// THREE separate branches per breakpoint.
const Pill = ({ children }) => {
  const bp = useBreakpoint();

  // ── Desktop ──────────────────────────────────────────────────────────────
  // ── Large Desktop ───────────────────────────────────────────────────────
  if (bp === 'largeDesktop') {
    return (
      <span style={{
        display: 'inline-flex', alignItems: 'center', alignSelf: 'flex-start',
        padding: '4px 16px', borderRadius: 75,
        border: '1px solid #91837a', fontFamily: 'Inter', fontWeight: 500,
        fontSize: 22, letterSpacing: '-0.05em', color: '#795f4e',
        height: 35, width: 'fit-content'
      }}>{children}</span>);

  }

  if (bp === 'desktop') {
    return (
      <span style={{
        display: 'inline-flex', alignItems: 'center', alignSelf: 'flex-start',
        padding: '4px 16px', borderRadius: 75,
        border: '1px solid #91837a', fontFamily: 'Inter', fontWeight: 500,
        fontSize: 22, letterSpacing: '-0.05em', color: '#795f4e',
        height: 35, width: 'fit-content'
      }}>{children}</span>);

  }

  // ── Tablet ───────────────────────────────────────────────────────────────
  if (bp === 'tablet') {
    return (
      <span style={{
        display: 'inline-flex', alignItems: 'center', alignSelf: 'flex-start',
        padding: '4px 16px', borderRadius: 75,
        border: '1px solid #91837a', fontFamily: 'Inter', fontWeight: 500,
        fontSize: 20, letterSpacing: '-0.05em', color: '#795f4e',
        height: 32, width: 'fit-content'
      }}>{children}</span>);

  }

  // ── Mobile ───────────────────────────────────────────────────────────────
  // ── Large Mobile ──────────────────────────────────────────────────────
  if (bp === 'largeMobile') {
    return (
      <span style={{
        display: 'inline-flex', alignItems: 'center', alignSelf: 'flex-start',
        padding: '4px 12px', borderRadius: 75,
        border: '1px solid #91837a', fontFamily: 'Inter', fontWeight: 500,
        fontSize: 16, letterSpacing: '-0.05em', color: '#795f4e',
        height: 27, width: 'fit-content'
      }}>{children}</span>);

  }

  // ── Small Mobile (fallback) ──────────────────────────────────────────
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', alignSelf: 'flex-start',
      padding: '4px 12px', borderRadius: 75,
      border: '1px solid #91837a', fontFamily: 'Inter', fontWeight: 500,
      fontSize: 16, letterSpacing: '-0.05em', color: '#795f4e',
      height: 27, width: 'fit-content'
    }}>{children}</span>);

};

// ─── Email Form ───────────────────────────────────────────────────────────────
const EmailForm = ({ onSubmit, copy, defaultEmail, forcedError, formState }) => {
  const [email, setEmail] = React.useState(defaultEmail || '');
  const [error, setError] = React.useState(forcedError || null);
  const bp = useBreakpoint();

  // Once the email validates + submits, the CTA flips to a success state:
  // "Download" → "Sent", "Subscribe" → "Subscribed" (with a check mark).
  const sent = formState === 'success';
  const ctaLabel = sent ? (copy?.sentCta || 'Sent') : (copy?.cta || 'Download');
  const ctaBg = sent ? '#1f8a5b' : '#101010';
  const CtaLabel = () => sent
    ? <span style={{ display: 'inline-flex', alignItems: 'center', gap: '0.4em' }}>
        <svg width="1em" height="1em" viewBox="0 0 28 28" style={{ flexShrink: 0, verticalAlign: '-0.12em' }} aria-hidden="true">
          <path d="M6 14.5 11.5 20 22 8.5" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" fill="none" />
        </svg>
        {ctaLabel}
      </span>
    : ctaLabel;

  React.useEffect(() => {
    setEmail(defaultEmail || '');
    setError(forcedError || null);
  }, [defaultEmail, forcedError]);

  const validate = (v) => {
    if (!v || !v.trim()) return 'Missing Field';
    if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v.trim())) return 'Please enter a valid email';
    return null;
  };

  const submit = (e) => {
    e.preventDefault();
    const err = validate(email);
    setError(err);
    if (err) return;
    onSubmit(email.trim());
  };

  // ── Desktop: exact original sizes ─────────────────────────────────────────
  // ── Large Desktop ───────────────────────────────────────────────────────
  if (bp === 'largeDesktop') {
    return (
      <form onSubmit={submit} style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        <div style={{ ...{
            position: 'relative', borderRadius: 24,
            padding: 8, display: 'flex', gap: 8, alignItems: 'center', height: 93,
            border: error ? '1.5px solid #d6553e' : '1.5px solid transparent',
            transition: 'border-color 160ms', background: "rgb(255, 251, 249)"
          }, borderStyle: "solid", borderColor: "rgb(240, 230, 220)", borderImage: "initial", borderWidth: "0px 0px 0px 2px", border: "0px solid rgb(240, 230, 220)", background: "rgb(248, 235, 227)" }}>
          <style>{`
            .spl-email-input::placeholder { color:#968A7C; font-family:Inter; font-size:20px; font-weight:500; line-height:normal; letter-spacing:-0.2px; opacity:1; }
            .spl-cta { transition: transform 280ms cubic-bezier(.2,.7,.2,1), box-shadow 280ms cubic-bezier(.2,.7,.2,1), background-color 220ms ease; will-change: transform, box-shadow; }
            .spl-cta:hover { transform: translateY(-1.5px); background-color:#1c1c1c; box-shadow: 0 12px 28px rgba(0,0,0,0.28); }
            .spl-cta:active { transform: translateY(0); box-shadow: 0 4px 14px rgba(0,0,0,0.22); transition-duration: 90ms; }
          `}</style>
          <input className="spl-email-input" type="text" value={email}
          onChange={(e) => {setEmail(e.target.value);if (error) setError(null);}}
          placeholder="Enter your email" aria-label="Email address"
          style={{ flex: 1, height: 61, border: 'none', background: 'transparent', outline: 'none', padding: '0 32px', fontFamily: 'Inter', fontWeight: 500, fontSize: 22, lineHeight: 'normal', color: '#101010', letterSpacing: '-0.22px' }} />
          <button className="spl-cta" type="submit" disabled={sent} style={{ height: 61, padding: '0 32px', borderRadius: 105, background: ctaBg, color: '#fff', border: 'none', cursor: sent ? 'default' : 'pointer', pointerEvents: sent ? 'none' : 'auto', fontWeight: 700, fontSize: 22, letterSpacing: '-0.01em', boxShadow: '0 6px 19.9px rgba(0,0,0,0.2)' }}><CtaLabel /></button>
        </div>
        {error && <div style={{ fontFamily: 'Inter', fontWeight: 500, fontSize: 16, color: '#d6553e', paddingLeft: 16, marginTop: 4 }}>{error}</div>}
        <div style={{ fontFamily: 'Inter', fontSize: 20, letterSpacing: '-0.025em', color: '#696a6d', padding: '16px 16px 0', lineHeight: "1.65" }}>{copy?.disclaimer}</div>
      </form>);

  }

  if (bp === 'desktop') {
    return (
      <form onSubmit={submit} style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        <div style={{
          position: 'relative', borderRadius: 24, background: '#f8ebe3',
          padding: 8, display: 'flex', gap: 8, alignItems: 'center', height: 93,
          border: error ? '1.5px solid #d6553e' : '1.5px solid transparent',
          transition: 'border-color 160ms'
        }}>
          <style>{`
            .spl-email-input::placeholder { color:#968A7C; font-family:Inter; font-size:20px; font-weight:500; line-height:normal; letter-spacing:-0.2px; opacity:1; }
            .spl-cta-d { transition: transform 280ms cubic-bezier(.2,.7,.2,1), box-shadow 280ms cubic-bezier(.2,.7,.2,1), background-color 220ms ease; will-change: transform, box-shadow; }
            .spl-cta-d:hover { transform: translateY(-1.5px); background-color:#1c1c1c; box-shadow: 0 12px 28px rgba(0,0,0,0.28); }
            .spl-cta-d:active { transform: translateY(0); box-shadow: 0 4px 14px rgba(0,0,0,0.22); transition-duration: 90ms; }
          `}</style>
          <input className="spl-email-input" type="text" value={email}
          onChange={(e) => {setEmail(e.target.value);if (error) setError(null);}}
          placeholder="Enter your email" aria-label="Email address"
          style={{ flex: 1, height: 61, border: 'none', background: 'transparent', outline: 'none', padding: '0 32px', fontFamily: 'Inter', fontWeight: 500, fontSize: 22, lineHeight: 'normal', color: '#101010', letterSpacing: '-0.22px' }} />
          <button className="spl-cta-d" type="submit" disabled={sent} style={{ height: 61, padding: '0 32px', borderRadius: 105, background: ctaBg, color: '#fff', border: 'none', cursor: sent ? 'default' : 'pointer', pointerEvents: sent ? 'none' : 'auto', fontWeight: 700, fontSize: 22, letterSpacing: '-0.01em', boxShadow: '0 6px 19.9px rgba(0,0,0,0.2)' }}><CtaLabel /></button>
        </div>
        {error && <div style={{ fontFamily: 'Inter', fontWeight: 500, color: '#d6553e', paddingLeft: 16, marginTop: 4, fontSize: "20px" }}>{error}</div>}
        <div style={{ fontFamily: 'Inter', fontSize: 20, letterSpacing: '-0.025em', color: '#696a6d', padding: '16px 16px 0', lineHeight: "1.65" }}>{copy?.disclaimer}</div>
      </form>);

  }

  // ── Tablet: 88 px form, 56 px inner, 20 px button font (Figma V3) ─────────
  if (bp === 'tablet') {
    return (
      <form onSubmit={submit} style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        <div style={{
          borderRadius: 24, background: '#f8ebe3',
          padding: 16, display: 'flex', gap: 8, alignItems: 'center', height: 88,
          border: error ? '1.5px solid #d6553e' : '1.5px solid transparent',
          transition: 'border-color 160ms'
        }}>
          <style>{`
            .spl-email-input-t::placeholder { color:#968A7C; font-family:Inter; font-size:16px; font-weight:500; letter-spacing:-0.01em; opacity:1; }
            .spl-cta-t { transition: transform 280ms cubic-bezier(.2,.7,.2,1), box-shadow 280ms cubic-bezier(.2,.7,.2,1), background-color 220ms ease; will-change: transform, box-shadow; }
            .spl-cta-t:hover { transform: translateY(-1.5px); background-color:#1c1c1c; box-shadow: 0 12px 26px rgba(0,0,0,0.26); }
            .spl-cta-t:active { transform: translateY(0); box-shadow: 0 4px 14px rgba(0,0,0,0.22); transition-duration: 90ms; }
          `}</style>
          <input className="spl-email-input-t" type="text" value={email}
          onChange={(e) => {setEmail(e.target.value);if (error) setError(null);}}
          placeholder="Enter your email" aria-label="Email address"
          style={{ flex: 1, minWidth: 0, height: 56, border: 'none', background: 'transparent', outline: 'none', padding: '0 16px', fontFamily: 'Inter', fontWeight: 500, fontSize: 16, color: '#101010', letterSpacing: '-0.01em' }} />
          <button className="spl-cta-t" type="submit" disabled={sent} style={{ height: 56, padding: '0 28px', borderRadius: 100, background: ctaBg, color: '#fff', border: 'none', cursor: sent ? 'default' : 'pointer', pointerEvents: sent ? 'none' : 'auto', boxShadow: '0 6px 20px rgba(0,0,0,0.2)', whiteSpace: 'nowrap', flexShrink: 0, fontWeight: "600", fontSize: "16px" }}><CtaLabel /></button>
        </div>
        {error && <div style={{ fontFamily: 'Inter', fontWeight: 500, color: '#d6553e', paddingLeft: 16, marginTop: 4, fontSize: "16px" }}>{error}</div>}
        <div style={{ fontFamily: 'Inter', fontSize: 16, letterSpacing: '-0.05em', color: '#696a6d', padding: '12px 8px 0', lineHeight: "1.65" }}>{copy?.disclaimer}</div>
      </form>);

  }

  // ── Mobile: 67 px form, 51 px inner, 16 px button font (Figma V3) ─────────
  // ── Large Mobile ──────────────────────────────────────────────────────
  if (bp === 'largeMobile') {
    return (
      <form onSubmit={submit} style={{ display: 'flex', flexDirection: 'column', gap: "4px" }}>
        <div style={{
          background: '#f8ebe3',
          padding: 8, display: 'flex', gap: 6, alignItems: 'center', height: 67,
          border: error ? '1.5px solid #d6553e' : '1.5px solid transparent',
          transition: 'border-color 160ms', borderRadius: "24px"
        }}>
          <style>{`
            .spl-email-input-m::placeholder { color:#968A7C; font-family:Inter; font-size:15px; font-weight:500; opacity:1; }
            .spl-cta-lm { transition: transform 280ms cubic-bezier(.2,.7,.2,1), box-shadow 280ms cubic-bezier(.2,.7,.2,1), background-color 220ms ease; will-change: transform, box-shadow; }
            .spl-cta-lm:hover { transform: translateY(-1px); background-color:#1c1c1c; box-shadow: 0 8px 20px rgba(0,0,0,0.24); }
            .spl-cta-lm:active { transform: translateY(0); box-shadow: 0 3px 10px rgba(0,0,0,0.2); transition-duration: 90ms; }
          `}</style>
          <input className="spl-email-input-m" type="text" value={email}
          onChange={(e) => {setEmail(e.target.value);if (error) setError(null);}}
          placeholder="Enter your email" aria-label="Email address"
          style={{ flex: 1, minWidth: 0, height: 51, border: 'none', background: 'transparent', outline: 'none', padding: '0 10px', fontFamily: 'Inter', fontWeight: 500, fontSize: 15, color: '#101010' }} />
          <button className="spl-cta-lm" type="submit" disabled={sent} style={{ height: 51, background: ctaBg, color: '#fff', border: 'none', cursor: sent ? 'default' : 'pointer', pointerEvents: sent ? 'none' : 'auto', boxShadow: '0 4px 12px rgba(0,0,0,0.18)', whiteSpace: 'nowrap', flexShrink: 0, fontWeight: "600", fontSize: "14px", borderRadius: "32px", padding: "0px 32px 0px 16px" }}><CtaLabel /></button>
        </div>
        {error && <div style={{ fontFamily: 'Inter', fontWeight: 500, color: '#d6553e', paddingLeft: 10, marginTop: 4, fontSize: "14px" }}>{error}</div>}
        <div style={{ fontFamily: 'Inter', fontSize: 12, lineHeight: '20px', letterSpacing: '-0.05em', color: '#696a6d', padding: '8px 8px 0' }}>{copy?.disclaimer}</div>
      </form>);

  }

  // ── Small Mobile (fallback) ──────────────────────────────────────────
  return (
    <form onSubmit={submit} style={{ display: 'flex', flexDirection: 'column', gap: "4px" }}>
      <div style={{
        background: '#f8ebe3',
        padding: 8, display: 'flex', gap: 6, alignItems: 'center', height: 67,
        border: error ? '1.5px solid #d6553e' : '1.5px solid transparent',
        transition: 'border-color 160ms', borderRadius: "24px"
      }}>
        <style>{`
          .spl-email-input-m::placeholder { color:#968A7C; font-family:Inter; font-size:15px; font-weight:500; opacity:1; }
          .spl-cta-sm { transition: transform 280ms cubic-bezier(.2,.7,.2,1), box-shadow 280ms cubic-bezier(.2,.7,.2,1), background-color 220ms ease; will-change: transform, box-shadow; }
          .spl-cta-sm:hover { transform: translateY(-1px); background-color:#1c1c1c; box-shadow: 0 8px 20px rgba(0,0,0,0.24); }
          .spl-cta-sm:active { transform: translateY(0); box-shadow: 0 3px 10px rgba(0,0,0,0.2); transition-duration: 90ms; }
        `}</style>
        <input className="spl-email-input-m" type="text" value={email}
        onChange={(e) => {setEmail(e.target.value);if (error) setError(null);}}
        placeholder="Enter your email" aria-label="Email address"
        style={{ flex: 1, minWidth: 0, height: 51, border: 'none', background: 'transparent', outline: 'none', padding: '0 10px', fontFamily: 'Inter', fontWeight: 500, fontSize: 15, color: '#101010' }} />
        <button className="spl-cta-sm" type="submit" disabled={sent} style={{ height: 51, background: ctaBg, color: '#fff', border: 'none', cursor: sent ? 'default' : 'pointer', pointerEvents: sent ? 'none' : 'auto', boxShadow: '0 4px 12px rgba(0,0,0,0.18)', whiteSpace: 'nowrap', flexShrink: 0, fontWeight: "600", fontSize: "14px", padding: "0px 16px", borderRadius: "30px" }}><CtaLabel /></button>
      </div>
      {error && <div style={{ fontFamily: 'Inter', fontWeight: 500, fontSize: 13, color: '#d6553e', paddingLeft: 10, marginTop: 4 }}>{error}</div>}
      <div style={{ fontFamily: 'Inter', fontSize: 12, lineHeight: '20px', letterSpacing: '-0.05em', color: '#696a6d', padding: '8px 8px 0' }}>{copy?.disclaimer}</div>
    </form>);

};

// ─── Success Toast ────────────────────────────────────────────────────────────
// FIVE separate components per breakpoint — same pattern as SocialIcons.
// Each component is a distinct source location, so a direct-edit in the
// preview only touches the breakpoint currently rendered. Do NOT collapse
// these back into a shared component with internal branches; the editor
// cannot pin an edit to the right branch and changes will leak across sizes.

// ── Large Desktop (> 1200 px) ────────────────────────────────────────────────
const SuccessToastLargeDesktop = ({ visible, message }) =>
ReactDOM.createPortal(
  <div style={{
    position: 'fixed', left: '50%', bottom: 32,
    transform: `translate(-50%, ${visible ? 0 : 16}px)`,
    opacity: visible ? 1 : 0,
    transition: 'opacity 240ms ease, transform 240ms ease',
    background: '#fff', borderRadius: 16,
    boxShadow: '0 16px 48px rgba(0,0,0,0.16), 0 2px 6px rgba(0,0,0,0.06)',
    display: 'flex', alignItems: 'center',
    pointerEvents: visible ? 'auto' : 'none', whiteSpace: 'nowrap', zIndex: 100, gap: "8px", padding: "20px 24px"
  }}>
    <svg width="28" height="28" viewBox="0 0 28 28" style={{ width: "24px", height: "24px" }}>
      <circle cx="14" cy="14" r="14" fill="#1f8a5b" />
      <path d="M8 14.5 12 18 20 10" stroke="#fff" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" fill="none" />
    </svg>
    <span style={{ fontFamily: 'Inter', color: '#101010', fontWeight: "500", fontSize: "18px" }}>{message}</span>
  </div>,
  document.body
);

// ── Desktop (1025 – 1200 px) ─────────────────────────────────────────────────
const SuccessToastDesktop = ({ visible, message }) =>
ReactDOM.createPortal(
  <div style={{
    position: 'fixed', left: '50%', bottom: 32,
    transform: `translate(-50%, ${visible ? 0 : 16}px)`,
    opacity: visible ? 1 : 0,
    transition: 'opacity 240ms ease, transform 240ms ease',
    background: '#fff', borderRadius: 16,
    boxShadow: '0 16px 48px rgba(0,0,0,0.16), 0 2px 6px rgba(0,0,0,0.06)',
    display: 'flex', alignItems: 'center',
    pointerEvents: visible ? 'auto' : 'none', whiteSpace: 'nowrap', zIndex: 100, gap: "8px", padding: "18px 22px"
  }}>
    <svg width="28" height="28" viewBox="0 0 28 28" style={{ width: "24px", height: "24px" }}>
      <circle cx="14" cy="14" r="14" fill="#1f8a5b" />
      <path d="M8 14.5 12 18 20 10" stroke="#fff" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" fill="none" />
    </svg>
    <span style={{ fontFamily: 'Inter', color: '#101010', fontWeight: "500", fontSize: "16px" }}>{message}</span>
  </div>,
  document.body
);

// ── Tablet (768 – 1024 px) ───────────────────────────────────────────────────
const SuccessToastTablet = ({ visible, message }) =>
ReactDOM.createPortal(
  <div style={{
    position: 'fixed', left: '50%', bottom: 28,
    transform: `translate(-50%, ${visible ? 0 : 16}px)`,
    opacity: visible ? 1 : 0,
    transition: 'opacity 240ms ease, transform 240ms ease',
    background: '#fff', borderRadius: 14,
    boxShadow: '0 16px 48px rgba(0,0,0,0.16), 0 2px 6px rgba(0,0,0,0.06)',
    display: 'flex', alignItems: 'center',
    pointerEvents: visible ? 'auto' : 'none', whiteSpace: 'nowrap', zIndex: 100, gap: "8px", padding: "18px 20px"
  }}>
    <svg width="28" height="28" viewBox="0 0 28 28" style={{ width: "22px", height: "22px" }}>
      <circle cx="14" cy="14" r="14" fill="#1f8a5b" />
      <path d="M8 14.5 12 18 20 10" stroke="#fff" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" fill="none" />
    </svg>
    <span style={{ fontFamily: 'Inter', color: '#101010', fontWeight: "500", fontSize: "18px" }}>{message}</span>
  </div>,
  document.body
);

// ── Large Mobile (481 – 767 px) ──────────────────────────────────────────────
const SuccessToastLargeMobile = ({ visible, message }) =>
ReactDOM.createPortal(
  <div style={{
    position: 'fixed', left: '50%', bottom: 24,
    transform: `translate(-50%, ${visible ? 0 : 16}px)`,
    opacity: visible ? 1 : 0,
    transition: 'opacity 240ms ease, transform 240ms ease',
    background: '#fff', borderRadius: 12,
    boxShadow: '0 12px 36px rgba(0,0,0,0.14), 0 2px 6px rgba(0,0,0,0.06)',
    display: 'flex', alignItems: 'center',
    pointerEvents: visible ? 'auto' : 'none', whiteSpace: 'nowrap', zIndex: 100, gap: "8px", padding: "16px 18px"
  }}>
    <svg width="28" height="28" viewBox="0 0 28 28" style={{ width: "20px", height: "20px" }}>
      <circle cx="14" cy="14" r="14" fill="#1f8a5b" />
      <path d="M8 14.5 12 18 20 10" stroke="#fff" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" fill="none" />
    </svg>
    <span style={{ fontFamily: 'Inter', color: '#101010', fontWeight: "500", fontSize: "15px" }}>{message}</span>
  </div>,
  document.body
);

// ── Small Mobile (≤ 480 px) ──────────────────────────────────────────────────
const SuccessToastSmallMobile = ({ visible, message }) =>
ReactDOM.createPortal(
  <div style={{
    position: 'fixed', left: '50%', bottom: 20,
    transform: `translate(-50%, ${visible ? 0 : 16}px)`,
    opacity: visible ? 1 : 0,
    transition: 'opacity 240ms ease, transform 240ms ease',
    background: '#fff', borderRadius: 12,
    boxShadow: '0 12px 36px rgba(0,0,0,0.14), 0 2px 6px rgba(0,0,0,0.06)',
    display: 'flex', alignItems: 'center',
    pointerEvents: visible ? 'auto' : 'none', whiteSpace: 'nowrap', zIndex: 100, gap: "6px", padding: "16px"
  }}>
    <svg width="28" height="28" viewBox="0 0 28 28" style={{ width: "18px", height: "18px" }}>
      <circle cx="14" cy="14" r="14" fill="#1f8a5b" />
      <path d="M8 14.5 12 18 20 10" stroke="#fff" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" fill="none" />
    </svg>
    <span style={{ fontFamily: 'Inter', color: '#101010', fontWeight: "500", fontSize: "14px" }}>{message}</span>
  </div>,
  document.body
);

// Thin router — picks the right component for the current breakpoint.
// Does NO styling of its own. To change a size, edit the matching
// SuccessToast<Breakpoint> component above.
const SuccessToast = (props) => {
  if (typeof document === 'undefined') return null;
  const bp = useBreakpoint();
  if (bp === 'smallMobile') return <SuccessToastSmallMobile {...props} />;
  if (bp === 'largeMobile') return <SuccessToastLargeMobile {...props} />;
  if (bp === 'tablet') return <SuccessToastTablet {...props} />;
  if (bp === 'desktop') return <SuccessToastDesktop {...props} />;
  return <SuccessToastLargeDesktop {...props} />;
};

// ─── Pricing context ─────────────────────────────────────────────────────────
// Threaded through App so any nested component (Pill, sharedForm) can decide
// whether to show the free or paid variant. Default = free.
const PricingContext = React.createContext({
  model: 'free', // 'free' | 'paid'
  price: '20', // e.g. '20'
  currency: 'CAD', // e.g. 'CAD'
  onPurchase: () => {}
});

// Drop-in replacement for `<Pill>Free</Pill>` — pulls label from context.
const PricePill = () => {
  const { model, price, currency } = React.useContext(PricingContext);
  return <Pill>{model === 'paid' ? `$${price} ${currency}` : 'Free'}</Pill>;
};

// ─── Paid CTA ────────────────────────────────────────────────────────────────
// Replaces the EmailForm block on paid templates: single big "Get this template"
// button, no email field, no disclaimer (per Figma node 102:196).
// FIVE separate branches per breakpoint — same isolation pattern as the rest
// of the file. Edits to one breakpoint never bleed into others.
const PaidCTA = ({ label = 'Get this template' }) => {
  const { onPurchase } = React.useContext(PricingContext);
  const bp = useBreakpoint();

  const baseBtn = {
    width: '100%', background: '#101010', color: '#fff',
    border: 'none', cursor: 'pointer',
    fontFamily: 'Inter', fontWeight: 700, letterSpacing: '-0.01em',
    boxShadow: '0 6px 19.9px rgba(0,0,0,0.2)',
    display: 'flex', alignItems: 'center', justifyContent: 'center',
    transition: 'transform 120ms ease, box-shadow 120ms ease'
  };

  if (bp === 'largeDesktop') {
    return (
      <button onClick={onPurchase} style={{
        ...baseBtn, borderRadius: 84,
        padding: "0px 32px", fontSize: "22px", height: "80px"
      }}>{label}</button>);

  }
  if (bp === 'desktop') {
    return (
      <button onClick={onPurchase} style={{
        ...baseBtn, height: 107, padding: '0 64px', borderRadius: 84,
        fontSize: 22
      }}>{label}</button>);

  }
  if (bp === 'tablet') {
    return (
      <button onClick={onPurchase} style={{
        ...baseBtn, borderRadius: 72,
        fontSize: 20, height: "80px", padding: "0px"
      }}>{label}</button>);

  }
  if (bp === 'largeMobile') {
    return (
      <button onClick={onPurchase} style={{
        ...baseBtn, height: 64, borderRadius: 56,
        fontSize: 16, justifyContent: "center", padding: "0px", margin: "32px 0px 0px"
      }}>{label}</button>);

  }
  return (
    <button onClick={onPurchase} style={{
      ...baseBtn, height: 60, padding: '0 24px', borderRadius: 52,
      fontSize: 15
    }}>{label}</button>);

};

Object.assign(window, {
  useBreakpoint, SocialIcons, SocialIconsDesktop, SocialIconsTablet, SocialIconsMobile,
  NavBar, HeroBackdrop, BioSection, Footer,
  PageTitle, Highlights, Pill, EmailForm,
  SuccessToast,
  SuccessToastSmallMobile, SuccessToastLargeMobile, SuccessToastTablet,
  SuccessToastDesktop, SuccessToastLargeDesktop,
  PricingContext, PricePill, PaidCTA
});