/* SEMAI marketing site — sections.
   Composes the design-system primitives into a real marketing page view.
   Logo-forward hero + Linear/Vercel-inspired motion layer.
   Exports each section to window for index.html to assemble. */

const { Button, Badge, Card, Avatar, Tabs, Input,
        AnswerCard, CitationChip, MetricStat, VisibilityMeter, PromptBar, ProductCard } = window.SEMAIDesignSystem_fb5e7f;

const LOGO_DARK = window.SEMAI_LOGO_DARK || '../../assets/semai-logo.svg';
const LOGO_LIGHT = window.SEMAI_LOGO_LIGHT || '../../assets/semai-logo-light.svg';
const SYGNET = window.SEMAI_SYGNET || '../../assets/semai-sygnet.svg';

/* ---------- tiny inline icons (Lucide-style, 1.75 stroke) ---------- */
const I = (p) => (<svg width={p.s||18} height={p.s||18} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round" style={p.style}>{p.children}</svg>);
const Radar = (p)=>(<I {...p}><circle cx="12" cy="12" r="9"/><circle cx="12" cy="12" r="4.5"/><path d="M12 12 20 6"/></I>);
const Msg = (p)=>(<I {...p}><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></I>);
const Doc = (p)=>(<I {...p}><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/></I>);
const TargetIco = (p)=>(<I {...p}><circle cx="12" cy="12" r="9"/><circle cx="12" cy="12" r="5"/><circle cx="12" cy="12" r="1.5"/></I>);
const Chart = (p)=>(<I {...p}><path d="M3 3v18h18"/><path d="M7 15l4-4 3 3 5-6"/></I>);
const ArrowR = (p)=>(<I {...p}><path d="M5 12h14M13 6l6 6-6 6"/></I>);

const Logo = ({light, h=28}) => (
  <img src={light?LOGO_LIGHT:LOGO_DARK} alt="SEMAI" style={{height:h,display:'block'}}/>
);

const WRAP = { maxWidth: 1440, margin: '0 auto', padding: '0 clamp(16px, 4vw, 64px)' };

/* ---- Minimal hash routing so /performance works in a standalone file ---- */
function go(route, e) {
  if (e) e.preventDefault();
  if (window.location.hash !== route) window.location.hash = route;
  window.scrollTo(0, 0);
}
function useRoute() {
  const read = () => (window.location.hash || '#/').replace(/^#/, '');
  const [route, setRoute] = React.useState(read);
  React.useEffect(() => {
    const on = () => { setRoute(read()); };
    window.addEventListener('hashchange', on);
    return () => window.removeEventListener('hashchange', on);
  }, []);
  return route;
}

/* Mount-triggered visibility — drives staggered entrance via TRANSITIONS
   (transitions don't reset on React re-render the way CSS animations do). */
function useMounted(delay = 0) {
  const [shown, setShown] = React.useState(() => typeof document !== 'undefined' && document.visibilityState === 'hidden');
  React.useEffect(() => {
    if (shown) return;
    const t = setTimeout(() => setShown(true), delay + 30);
    return () => clearTimeout(t);
  }, [shown, delay]);
  return shown;
}
function enter(shown, ms = 0, y = 16) {
  return {
    opacity: shown ? 1 : 0,
    transform: shown ? 'none' : `translateY(${y}px)`,
    transition: `opacity .8s var(--ease-entrance) ${ms}ms, transform .8s var(--ease-entrance) ${ms}ms`,
    willChange: 'opacity, transform',
  };
}

/* Live scroll position (px). rAF-throttled. */
function useScrollY() {
  const [y, setY] = React.useState(() => (typeof window !== 'undefined' ? window.scrollY : 0));
  React.useEffect(() => {
    let raf = 0;
    const on = () => { if (raf) return; raf = requestAnimationFrame(() => { raf = 0; setY(window.scrollY); }); };
    window.addEventListener('scroll', on, { passive: true });
    return () => { window.removeEventListener('scroll', on); if (raf) cancelAnimationFrame(raf); };
  }, []);
  return y;
}

/* Responsive helper — resolves a value from an ascending [[maxWidth, value], ...]
   list against the live window width, re-evaluating on resize. Used for values
   CSS media queries can't reach (grid-template-columns switches, JS-computed
   decorative graphic sizes). Desktop (above the largest maxWidth) always
   returns `fallback`, so nothing changes above ~1024px unless listed. */
function useBreakpointValue(map, fallback) {
  const read = () => {
    const w = typeof window !== 'undefined' ? window.innerWidth : 1440;
    for (const [max, val] of map) if (w <= max) return val;
    return fallback;
  };
  const [val, setVal] = React.useState(read);
  React.useEffect(() => {
    const on = () => setVal(read());
    window.addEventListener('resize', on, { passive: true });
    return () => window.removeEventListener('resize', on);
  }, []);
  return val;
}

/* Self-playing answer demo — types the prompt, "thinks", then streams the
   answer word-by-word and reveals citations, on a loop. Non-interactive:
   it's part of the hero animation under the sygnet. */
function AnswerDemo({ compact = false, stageHeight = 258 } = {}) {
  const PROMPT = 'Jaka firma od klimatyzacji w Krakowie?';
  const ANSWER = 'Warto wybrać wykonawcę z dobrymi opiniami, szybką wyceną i gwarancją montażu. Wśród rekomendowanych firm pojawia się m.in.';
  const CITES = [{domain:'google.com'},{domain:'twojamarka.pl',brand:true},{domain:'fixly.pl'},{domain:'oferteo.pl'}];
  const [p, setP] = React.useState('');
  const [a, setA] = React.useState('');
  const [hl, setHl] = React.useState(false);
  const [nc, setNc] = React.useState(0);
  const [org, setOrg] = React.useState('thinking'); // thinking | answering | done
  const [scene, setScene] = React.useState('organic'); // organic | ad
  const [adStep, setAdStep] = React.useState(0);

  // Mobile (compact) crossfade: only one scene is ever mounted (so the card
  // auto-sizes to content), but we still want the same fade transition feel
  // as desktop — fade the old scene out, swap content, then fade the new
  // scene in — instead of an abrupt cut.
  const [displayScene, setDisplayScene] = React.useState('organic');
  const [sceneVisible, setSceneVisible] = React.useState(true);
  React.useEffect(() => {
    if (!compact || scene === displayScene) return;
    setSceneVisible(false);
    const t = setTimeout(() => {
      setDisplayScene(scene);
      requestAnimationFrame(() => requestAnimationFrame(() => setSceneVisible(true)));
    }, 220);
    return () => clearTimeout(t);
  }, [scene, compact]);

  React.useEffect(() => {
    let cancelled = false; const timers = new Set();
    const wait = (ms) => new Promise((r) => { const t = setTimeout(() => { timers.delete(t); r(); }, ms); timers.add(t); });
    (async function loop() {
      while (!cancelled) {
        // reset to a clean organic card, then show the prompt each cycle
        setScene('organic'); setA(''); setHl(false); setNc(0); setOrg('idle');
        setP('');
        await wait(650);
        // Prompt bar always types character-by-character (desktop + mobile) —
        // this is the short "search" line, never the long answer body, so
        // it stays quick and never leaves the card in a half-finished state.
        for (let i = 1; i <= PROMPT.length; i++) { if (cancelled) return; setP(PROMPT.slice(0, i)); await wait(42); }
        await wait(320);
        /* ---- Scene 1: organic answer (LLM Visibility) ---- */
        setScene('organic'); setA(''); setHl(false); setNc(0); setOrg('thinking');
        await wait(950);
        setOrg('answering');
        for (let i = 1; i <= ANSWER.length; i++) { if (cancelled) return; setA(ANSWER.slice(0, i)); await wait(16); }
        await wait(200); setHl(true);
        for (let i = 1; i <= CITES.length; i++) { if (cancelled) return; setNc(i); await wait(240); }
        setOrg('done');
        await wait(3000);

        /* ---- Scene 2: same brand, now positioned via LLM Ads ---- */
        setScene('ad'); setAdStep(0);
        await wait(560); setAdStep(1);
        await wait(520); setAdStep(2);
        await wait(620); setAdStep(3);
        await wait(4200);
      }
    })();
    return () => { cancelled = true; timers.forEach(clearTimeout); };
  }, []);

  const caret = (
    <span style={{ display: 'inline-block', width: 2, height: '0.95em', marginLeft: 2, background: 'var(--accent-core)', verticalAlign: '-2px', animation: 'semai-blink 1s step-end infinite' }} />
  );
  const rise = (on, d = 0) => ({ opacity: on ? 1 : 0, transform: on ? 'none' : 'translateY(10px)', transition: `opacity .5s var(--ease-out) ${d}ms, transform .5s var(--ease-out) ${d}ms` });

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
      {/* animated prompt bar (non-interactive) */}
      <div className="semai-prompt-bar" style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '7px 7px 7px 15px', background: 'var(--surface-1)', backgroundImage: 'var(--grad-surface)', border: '1px solid var(--border-strong)', borderRadius: 'var(--radius-pill)', boxShadow: 'var(--shadow-md), var(--glow-md)' }}>
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--text-accent)" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round" style={{ flexShrink: 0 }}><path d="M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M18.4 5.6l-2.1 2.1M7.7 16.3l-2.1 2.1" /></svg>
        <span className="semai-prompt-text" style={{ flex: 1, minWidth: 0, fontSize: 13.5, color: p ? 'var(--text-strong)' : 'var(--text-faint)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{p || 'Zapytaj AI…'}{p && p.length < PROMPT.length && caret}</span>
        <span className="semai-badge-search" style={{ fontFamily: 'var(--font-mono)', fontSize: 9, letterSpacing: '0.08em', textTransform: 'uppercase', color: 'var(--text-accent)', background: 'var(--accent-tint)', border: '1px solid var(--border-accent)', borderRadius: 999, padding: '3px 6px', flexShrink: 0 }}>AI Search</span>
        <span className="semai-send-btn" style={{ width: 32, height: 32, flexShrink: 0, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', borderRadius: '50%', background: 'var(--accent)', color: '#fff', boxShadow: 'var(--glow-sm)' }}>
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12h14M13 6l6 6-6 6" /></svg>
        </span>
      </div>

      {/* Answer stage. Desktop/tablet: fixed-height crossfade so the sygnet
         layer above never moves. Mobile (compact): only the active scene is
         mounted, in normal flow, so the box always sizes to its content —
         no guessed height, no overflow/overlap. */}
      {compact ? (
        <div style={{ position: 'relative', opacity: sceneVisible ? 1 : 0, transform: sceneVisible ? 'none' : 'translateY(6px)', transition: 'opacity .22s var(--ease-out), transform .22s var(--ease-out)' }}>
          {displayScene === 'organic' ? (
            <AnswerCard model="ChatGPT" highlight={hl ? 'Marka klienta' : undefined} citations={CITES.slice(0, nc)} style={{ maxWidth: 'none', textAlign: 'left' }}>
              {org === 'thinking'
                ? <span style={{ display: 'inline-flex', gap: 5, alignItems: 'center' }}>
                    {[0, 1, 2].map((i) => (<span key={i} style={{ width: 6, height: 6, borderRadius: '50%', background: 'var(--text-faint)', animation: `semai-pulse 1.1s ${i * 0.16}s ease-in-out infinite` }} />))}
                  </span>
                : <React.Fragment>{a}{org === 'answering' && !hl && caret}</React.Fragment>}
            </AnswerCard>
          ) : (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 12, padding: 'var(--space-7)', background: 'var(--surface-1)', backgroundImage: 'var(--grad-surface)', border: '1px solid var(--border-default)', borderRadius: 'var(--radius-lg)', boxShadow: 'var(--shadow-md)' }}>
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                  <Avatar model size={26} />
                  <span style={{ fontSize: 13, fontWeight: 'var(--fw-semibold)', color: 'var(--text-strong)' }}>ChatGPT</span>
                  <span style={{ width: 5, height: 5, borderRadius: '50%', background: 'var(--positive)', boxShadow: '0 0 8px rgba(62,207,142,0.7)' }} />
                </div>
                <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5, fontFamily: 'var(--font-mono)', fontSize: 9.5, letterSpacing: '0.12em', textTransform: 'uppercase', color: 'var(--text-accent)', background: 'var(--accent-tint)', border: '1px solid var(--border-accent)', borderRadius: 999, padding: '3px 8px', ...rise(adStep >= 1) }}>
                  <span style={{ width: 5, height: 5, borderRadius: '50%', background: 'var(--accent-core)' }} /> LLM Ad · Sponsorowane
                </span>
              </div>

              <span style={{ fontSize: 12.5, color: 'var(--text-muted)', ...rise(adStep >= 1, 60) }}>Rekomendowane w odpowiedzi:</span>

              <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '12px 13px', borderRadius: 'var(--radius-md)', background: 'var(--accent-tint)', border: '1px solid var(--border-accent)', boxShadow: 'var(--glow-sm)', ...rise(adStep >= 2), transform: adStep >= 2 ? 'none' : 'translateY(10px) scale(0.98)' }}>
                <span style={{ flexShrink: 0, width: 38, height: 38, borderRadius: 'var(--radius-md)', background: 'var(--grad-ai)', boxShadow: 'var(--glow-sm)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', color: '#fff', font: 'var(--fw-bold) 14px/1 var(--font-sans)', letterSpacing: '0.02em' }}>MK</span>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                    <span style={{ fontSize: 14.5, fontWeight: 'var(--fw-semibold)', color: 'var(--text-strong)' }}>Marka klienta</span>
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="var(--accent-core)" stroke="#fff" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10" stroke="none" /><path d="M8 12l3 3 5-6" /></svg>
                  </div>
                  <span style={{ fontSize: 12.5, color: 'var(--text-muted)' }}>Montaż klimatyzacji — opinie, termin, gwarancja</span>
                </div>
                <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5, flexShrink: 0, height: 30, padding: '0 12px', borderRadius: 'var(--radius-sm)', background: 'var(--accent)', color: '#fff', font: 'var(--fw-semibold) 12.5px/1 var(--font-sans)', boxShadow: 'var(--glow-sm)', ...rise(adStep >= 3) }}>
                  Sprawdź
                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12h14M13 6l6 6-6 6" /></svg>
                </span>
              </div>

              <div style={{ display: 'flex', alignItems: 'center', gap: 7, ...rise(adStep >= 3, 120) }}>
                <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="var(--text-faint)" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="9" /><path d="M12 8v4M12 16h.01" /></svg>
                <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10, letterSpacing: '0.04em', color: 'var(--text-faint)' }}>Pozycja reklamowa w odpowiedzi AI · LLM Ads</span>
              </div>
            </div>
          )}
        </div>
      ) : (
      <div style={{ position: 'relative', height: stageHeight }} className="semai-answer-stage">
        {/* Scene 1 — organic answer (LLM Visibility) */}
        <div style={{ position: 'absolute', inset: 0, opacity: scene === 'organic' ? 1 : 0, transition: 'opacity .45s var(--ease-out)', pointerEvents: 'none' }}>
          <AnswerCard model="ChatGPT" highlight={hl ? 'Marka klienta' : undefined} citations={CITES.slice(0, nc)} style={{ maxWidth: 'none', textAlign: 'left', height: '100%' }}>
            {org === 'thinking'
              ? <span style={{ display: 'inline-flex', gap: 5, alignItems: 'center' }}>
                  {[0, 1, 2].map((i) => (<span key={i} style={{ width: 6, height: 6, borderRadius: '50%', background: 'var(--text-faint)', animation: `semai-pulse 1.1s ${i * 0.16}s ease-in-out infinite` }} />))}
                </span>
              : <React.Fragment>{a}{org === 'answering' && !hl && caret}</React.Fragment>}
          </AnswerCard>
        </div>

        {/* Scene 2 — same brand, now positioned via LLM Ads */}
        <div style={{ position: 'absolute', inset: 0, opacity: scene === 'ad' ? 1 : 0, transition: 'opacity .45s var(--ease-out)', pointerEvents: 'none' }}>
          <div style={{ height: '100%', display: 'flex', flexDirection: 'column', gap: 12, padding: 'var(--space-7)', background: 'var(--surface-1)', backgroundImage: 'var(--grad-surface)', border: '1px solid var(--border-default)', borderRadius: 'var(--radius-lg)', boxShadow: 'var(--shadow-md)' }}>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                <Avatar model size={26} />
                <span style={{ fontSize: 13, fontWeight: 'var(--fw-semibold)', color: 'var(--text-strong)' }}>ChatGPT</span>
                <span style={{ width: 5, height: 5, borderRadius: '50%', background: 'var(--positive)', boxShadow: '0 0 8px rgba(62,207,142,0.7)' }} />
              </div>
              <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5, fontFamily: 'var(--font-mono)', fontSize: 9.5, letterSpacing: '0.12em', textTransform: 'uppercase', color: 'var(--text-accent)', background: 'var(--accent-tint)', border: '1px solid var(--border-accent)', borderRadius: 999, padding: '3px 8px', ...rise(adStep >= 1) }}>
                <span style={{ width: 5, height: 5, borderRadius: '50%', background: 'var(--accent-core)' }} /> LLM Ad · Sponsorowane
              </span>
            </div>

            <span style={{ fontSize: 12.5, color: 'var(--text-muted)', ...rise(adStep >= 1, 60) }}>Rekomendowane w odpowiedzi:</span>

            {/* sponsored brand card */}
            <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '12px 13px', borderRadius: 'var(--radius-md)', background: 'var(--accent-tint)', border: '1px solid var(--border-accent)', boxShadow: 'var(--glow-sm)', ...rise(adStep >= 2), transform: adStep >= 2 ? 'none' : 'translateY(10px) scale(0.98)' }}>
              <span style={{ flexShrink: 0, width: 38, height: 38, borderRadius: 'var(--radius-md)', background: 'var(--grad-ai)', boxShadow: 'var(--glow-sm)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', color: '#fff', font: 'var(--fw-bold) 14px/1 var(--font-sans)', letterSpacing: '0.02em' }}>MK</span>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                  <span style={{ fontSize: 14.5, fontWeight: 'var(--fw-semibold)', color: 'var(--text-strong)' }}>Marka klienta</span>
                  <svg width="14" height="14" viewBox="0 0 24 24" fill="var(--accent-core)" stroke="#fff" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10" stroke="none" /><path d="M8 12l3 3 5-6" /></svg>
                </div>
                <span style={{ fontSize: 12.5, color: 'var(--text-muted)' }}>Montaż klimatyzacji — opinie, termin, gwarancja</span>
              </div>
              <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5, flexShrink: 0, height: 30, padding: '0 12px', borderRadius: 'var(--radius-sm)', background: 'var(--accent)', color: '#fff', font: 'var(--fw-semibold) 12.5px/1 var(--font-sans)', boxShadow: 'var(--glow-sm)', ...rise(adStep >= 3) }}>
                Sprawdź
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12h14M13 6l6 6-6 6" /></svg>
              </span>
            </div>

            <div style={{ marginTop: 'auto', display: 'flex', alignItems: 'center', gap: 7, ...rise(adStep >= 3, 120) }}>
              <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="var(--text-faint)" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="9" /><path d="M12 8v4M12 16h.01" /></svg>
              <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10, letterSpacing: '0.04em', color: 'var(--text-faint)' }}>Pozycja reklamowa w odpowiedzi AI · LLM Ads</span>
            </div>
          </div>
        </div>
      </div>
      )}
    </div>
  );
}

/* ===================== MOTION PRIMITIVES ===================== */

/* Scroll-reveal wrapper — fades + lifts children when they enter the viewport */
function Reveal({ children, delay = 0, y = 26, as = 'div', style, ...rest }) {
  const ref = React.useRef(null);
  const [seen, setSeen] = React.useState(() => typeof document !== 'undefined' && document.visibilityState === 'hidden');
  React.useEffect(() => {
    if (seen) return;
    const el = ref.current; if (!el) return;
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) { setSeen(true); io.disconnect(); }
    }, { threshold: 0.14, rootMargin: '0px 0px -8% 0px' });
    io.observe(el);
    // Safety: never leave content permanently hidden (print / offscreen / PDF)
    const t = setTimeout(() => setSeen(true), 1600);
    return () => { io.disconnect(); clearTimeout(t); };
  }, [seen]);
  const Tag = as;
  return (
    <Tag ref={ref} style={{
      ...style,
      opacity: seen ? 1 : 0,
      transform: seen ? 'none' : `translateY(${y}px)`,
      transition: `opacity .72s var(--ease-entrance) ${delay}ms, transform .72s var(--ease-entrance) ${delay}ms`,
      willChange: 'opacity, transform',
    }} {...rest}>{children}</Tag>
  );
}

/* The big animated brand sygnet — a "listening / answering" mark */
function SygnetMark({ size = 132 }) {
  return (
    <div style={{ position: 'relative', width: size, height: size, display: 'grid', placeItems: 'center' }}>
      {/* breathing glow */}
      <div style={{ position: 'absolute', inset: '-30%', background: 'radial-gradient(circle, rgba(139,63,212,0.5), rgba(139,63,212,0) 62%)', animation: 'semai-breathe 4.6s var(--ease-in-out) infinite', filter: 'blur(6px)' }} />
      {/* radar pings */}
      {[0, 1.4, 2.8].map((d, i) => (
        <div key={i} style={{ position: 'absolute', width: size * 0.66, height: size * 0.66, borderRadius: '50%', border: '1px solid rgba(171,101,214,0.5)', animation: `semai-ping 4.2s var(--ease-out) ${d}s infinite` }} />
      ))}
      {/* rotating dashed ring */}
      <svg viewBox="0 0 100 100" width={size} height={size} style={{ position: 'absolute', animation: 'semai-ring-rotate 22s linear infinite', opacity: 0.5 }}>
        <circle cx="50" cy="50" r="46" fill="none" stroke="url(#ringg)" strokeWidth="1" strokeDasharray="2 7" strokeLinecap="round" />
        <defs><linearGradient id="ringg" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stopColor="#6B2DD9"/><stop offset="1" stopColor="#D1A6FF"/></linearGradient></defs>
      </svg>
      {/* the sygnet glyph */}
      <img src={SYGNET} alt="" style={{ position: 'relative', width: size * 0.52, filter: 'drop-shadow(0 6px 20px rgba(139,63,212,0.55))' }} />
    </div>
  );
}

/* Cinematic hero showcase for the sygnet — Vercel-style staged backdrop:
   conic halo sweep, counter-rotating dashed rings, radar pings, orbiting
   satellite, radial spotlight and a soft floor reflection. */
function SygnetShowcase({ size = 340, simple = false }) {
  const S = size;
  return (
    <div style={{ position: 'relative', width: S, height: S, display: 'grid', placeItems: 'center', margin: '0 auto' }}>
      {/* radial spotlight */}
      <div aria-hidden style={{ position: 'absolute', inset: '-28%', background: 'radial-gradient(circle at 50% 42%, rgba(139,63,212,0.42), rgba(139,63,212,0.10) 40%, rgba(139,63,212,0) 66%)', filter: 'blur(4px)' }} />
      {/* conic halo sweep */}
      <div aria-hidden style={{ position: 'absolute', width: S * 0.92, height: S * 0.92, borderRadius: '50%', background: 'conic-gradient(from 0deg, rgba(107,45,217,0) 0deg, rgba(171,101,214,0.55) 90deg, rgba(209,166,255,0.15) 160deg, rgba(107,45,217,0) 250deg)', animation: 'semai-conic-spin 14s linear infinite', filter: 'blur(14px)', opacity: 0.8 }} />
      {/* breathing core glow */}
      <div aria-hidden style={{ position: 'absolute', width: S * 0.5, height: S * 0.5, borderRadius: '50%', background: 'radial-gradient(circle, rgba(171,101,214,0.55), rgba(171,101,214,0) 68%)', animation: 'semai-breathe 4.6s var(--ease-in-out) infinite' }} />

      {/* radar pings */}
      {[0, 1.5, 3].map((d, i) => (
        <div key={i} aria-hidden style={{ position: 'absolute', width: S * 0.5, height: S * 0.5, borderRadius: '50%', border: '1px solid rgba(171,101,214,0.45)', animation: `semai-ping 4.5s var(--ease-out) ${d}s infinite` }} />
      ))}

      {/* outer dashed ring — slow */}
      <svg viewBox="0 0 100 100" width={S} height={S} aria-hidden style={{ position: 'absolute', animation: 'semai-ring-rotate 30s linear infinite', opacity: 0.55 }}>
        <circle cx="50" cy="50" r="48" fill="none" stroke="url(#showg1)" strokeWidth="0.6" strokeDasharray="1.5 6" strokeLinecap="round" />
        <defs><linearGradient id="showg1" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stopColor="#6B2DD9"/><stop offset="1" stopColor="#D1A6FF"/></linearGradient></defs>
      </svg>
      {/* mid solid thin ring — counter-rotate */}
      <svg viewBox="0 0 100 100" width={S * 0.78} height={S * 0.78} aria-hidden style={{ position: 'absolute', animation: 'semai-ring-rotate-rev 24s linear infinite' }}>
        <circle cx="50" cy="50" r="48" fill="none" stroke="rgba(255,255,255,0.10)" strokeWidth="0.5" />
        <circle cx="50" cy="2" r="1.6" fill="#D1A6FF" />
      </svg>
      {/* inner ring with orbiting satellite */}
      <div aria-hidden style={{ position: 'absolute', width: S * 0.6, height: S * 0.6, animation: 'semai-orbit 9s linear infinite' }}>
        <span style={{ position: 'absolute', top: -3, left: '50%', width: 7, height: 7, marginLeft: -3.5, borderRadius: '50%', background: 'var(--violet-200)', boxShadow: '0 0 12px rgba(209,166,255,0.9)' }} />
      </div>
      {/* second satellite — larger orbit, counter-direction, offset */}
      {!simple && <div aria-hidden style={{ position: 'absolute', width: S * 0.82, height: S * 0.82, animation: 'semai-ring-rotate-rev 13s linear infinite' }}>
        <span style={{ position: 'absolute', top: -2.5, left: '50%', width: 5, height: 5, marginLeft: -2.5, borderRadius: '50%', background: 'var(--violet-300)', boxShadow: '0 0 10px rgba(171,101,214,0.9)' }} />
      </div>}
      {/* third satellite — tiny, fast, tight orbit */}
      {!simple && <div aria-hidden style={{ position: 'absolute', width: S * 0.44, height: S * 0.44, animation: 'semai-orbit 6s linear infinite reverse' }}>
        <span style={{ position: 'absolute', top: -2, left: '50%', width: 4, height: 4, marginLeft: -2, borderRadius: '50%', background: '#fff', boxShadow: '0 0 8px rgba(255,255,255,0.9)' }} />
      </div>}
      {/* conic scanning sweep — a thin radar line */}
      {!simple && <div aria-hidden style={{ position: 'absolute', width: S * 0.6, height: S * 0.6, borderRadius: '50%', background: 'conic-gradient(from 0deg, rgba(209,166,255,0.5), rgba(209,166,255,0) 22%)', animation: 'semai-conic-spin 3.6s linear infinite', mixBlendMode: 'screen', opacity: 0.55, maskImage: 'radial-gradient(circle, transparent 30%, #000 31%, #000 100%)', WebkitMaskImage: 'radial-gradient(circle, transparent 30%, #000 31%, #000 100%)' }} />}

      {/* the sygnet glyph */}
      <img src={SYGNET} alt="SEMAI" style={{ position: 'relative', width: S * 0.46, filter: 'drop-shadow(0 10px 34px rgba(139,63,212,0.6))', animation: 'semai-breathe 4.6s var(--ease-in-out) infinite' }} />

      {/* floor reflection */}
      <div aria-hidden style={{ position: 'absolute', bottom: S * 0.06, width: S * 0.5, height: S * 0.18, background: 'radial-gradient(50% 100% at 50% 0%, rgba(139,63,212,0.35), rgba(139,63,212,0) 72%)', filter: 'blur(6px)' }} />
    </div>
  );
}

/* ============================ NAV ============================ */
function SiteNav({ active = '/' }) {
  const links = ['LLM Ads','LLM Visibility','AI Search','Measurement'];
  const [scrolled, setScrolled] = React.useState(false);
  const [open, setOpen] = React.useState(false);
  React.useEffect(() => {
    const on = () => setScrolled(window.scrollY > 12);
    window.addEventListener('scroll', on); return () => window.removeEventListener('scroll', on);
  }, []);
  React.useEffect(() => { setOpen(false); }, [active]);
  const onPerf = active === '/performance';
  return (
    <React.Fragment>
    <header className="site-nav" style={{position:'fixed',top:0,left:0,right:0,zIndex:9999,paddingTop:14,transition:'background .3s var(--ease-out), border-color .3s var(--ease-out)'}}>
      <div className="site-nav-bar" style={{maxWidth:1500,width:'calc(100% - 96px)',margin:'0 auto',height:64,display:'flex',alignItems:'center',justifyContent:'space-between',padding:'0 22px',borderRadius:'var(--radius-lg)',border:`1px solid ${scrolled?'var(--border-default)':'var(--hairline)'}`,background:scrolled||open?'rgba(14,14,19,0.72)':'rgba(14,14,19,0.5)',backdropFilter:'var(--blur-panel)',WebkitBackdropFilter:'var(--blur-panel)',boxShadow:scrolled?'var(--shadow-md)':'none',transition:'background .3s var(--ease-out), border-color .3s var(--ease-out), box-shadow .3s var(--ease-out)'}}>
        <a href="#/" onClick={(e)=>go('#/',e)} style={{display:'inline-flex',alignItems:'center'}}><Logo h={30}/></a>
        <nav className="nav-links" style={{display:'flex',gap:28,alignItems:'center'}}>
          {links.map(l=>(<a key={l} href="#/" onClick={(e)=>go('#/',e)} style={{fontSize:14,color:'var(--text-muted)',transition:'color .14s var(--ease-out)'}} onMouseEnter={e=>e.currentTarget.style.color='var(--text-strong)'} onMouseLeave={e=>e.currentTarget.style.color='var(--text-muted)'}>{l}</a>))}
          <span style={{width:1,height:16,background:'var(--border-strong)'}}/>
          <a href="#/performance" onClick={(e)=>go('#/performance',e)} style={{display:'inline-flex',alignItems:'center',gap:7,fontSize:14,color:onPerf?'var(--text-strong)':'var(--perf-text)',transition:'color .14s var(--ease-out)'}} onMouseEnter={e=>e.currentTarget.style.color='var(--perf-accent)'} onMouseLeave={e=>e.currentTarget.style.color=onPerf?'var(--text-strong)':'var(--perf-text)'}>
            <span style={{width:6,height:6,borderRadius:'50%',background:'var(--perf-accent)',boxShadow:onPerf?'0 0 8px var(--perf-glow)':'none'}}/>
            SEM Performance
          </a>
        </nav>
        <div className="nav-actions" style={{display:'flex',gap:10,alignItems:'center'}}>
          <Button variant="ghost" size="sm">Zaloguj</Button>
          {onPerf ? <PerfButton size="sm">Umów konsultację</PerfButton> : <Button size="sm" trailingIcon={<ArrowR s={15}/>}>Zamów audyt</Button>}
        </div>
        <button
          className="nav-burger"
          aria-label={open ? 'Zamknij menu' : 'Otwórz menu'}
          onClick={()=>setOpen(o=>!o)}
          style={{display:'none',width:40,height:40,alignItems:'center',justifyContent:'center',background:'transparent',border:'1px solid var(--border-default)',borderRadius:'var(--radius-sm)',color:'var(--text-strong)',cursor:'pointer',flexShrink:0}}>
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round">
            {open ? <path d="M18 6 6 18M6 6l12 12"/> : <path d="M3 6h18M3 12h18M3 18h18"/>}
          </svg>
        </button>
      </div>

      {/* mobile dropdown panel — plain JS toggle, no extra libraries */}
      <div className="nav-mobile-panel" style={{display: open ? 'flex' : 'none', flexDirection:'column', gap:4, padding:'8px clamp(16px,5vw,32px) 20px', borderTop:'1px solid var(--hairline)'}}>
        {links.map(l=>(<a key={l} href="#/" onClick={(e)=>go('#/',e)} style={{padding:'12px 4px',fontSize:15,color:'var(--text-body)',borderBottom:'1px solid var(--hairline)'}}>{l}</a>))}
        <a href="#/performance" onClick={(e)=>go('#/performance',e)} style={{display:'flex',alignItems:'center',gap:8,padding:'12px 4px',fontSize:15,color:onPerf?'var(--text-strong)':'var(--perf-text)'}}>
          <span style={{width:6,height:6,borderRadius:'50%',background:'var(--perf-accent)'}}/>
          SEM Performance
        </a>
        <div style={{display:'flex',gap:10,marginTop:14,flexWrap:'wrap'}}>
          <Button variant="ghost" size="sm">Zaloguj</Button>
          {onPerf ? <PerfButton size="sm">Umów konsultację</PerfButton> : <Button size="sm" trailingIcon={<ArrowR s={15}/>}>Zamów audyt</Button>}
        </div>
      </div>
    </header>
    <div className="nav-spacer" style={{height:78}} aria-hidden="true"></div>
    </React.Fragment>
  );
}

/* ============================ HERO ============================ */
/* ============================ SECTION 1: BRAND INTRO ============================ */
/* ============================ HERO: intro-stage + intro-sticky + intro-hold + content-layer ============================
   One shared scene, matching the required DOM/CSS contract exactly:
     .intro-stage   { position: relative }                       — shared coordinate space for both layers
     .intro-sticky  { position: sticky; top:0; height:100vh; z-index:1; overflow:hidden } — Section 1, pinned
     .intro-hold    { height: 40-60vh }                          — scroll room reserved for the intro animation alone
     .content-layer { position: relative; z-index:2; opacity:1; transform:none; opaque bg } — Section 2, natural flow
   Section 2 has NO JS-driven opacity/transform of its own — it only moves because
   it is a normal block after .intro-hold, riding the document's native scroll.
   Section 1's fade/scale/blur is driven ENTIRELY by content-layer's own
   getBoundingClientRect().top (measured via a ref forwarded into it), so as
   content-layer's top crosses from `vh` (fully below) to `0` (reached the top
   of the viewport), Section 1 fades from opaque to fully invisible in lockstep. */
function HeroFlow() {
  const isMobile = useBreakpointValue([[767, true]], false);
  const holdVh = isMobile ? 12 : 25; // intro-hold: pure intro scroll before Section 2 begins entering

  const contentRef = React.useRef(null);
  const symbolStartRef = React.useRef(null); // invisible placeholder marking the intro sygnet's slot
  const symbolTargetRef = React.useRef(null); // the slot the sygnet lands in, inside Section 2
  const travelRef = React.useRef(null);       // the single travelling sygnet element (styled imperatively)
  const [coverProgress, setCoverProgress] = React.useState(0); // 0 = hero-content fully below viewport · 1 = fully covers it
  const [landed, setLanded] = React.useState(false);
  const landedRef = React.useRef(false);
  const introSymbolSize = useBreakpointValue([[480,150],[767,190],[1024,230]],270);

  React.useEffect(() => {
    let raf = 0;
    const calc = () => {
      raf = 0;
      const el = contentRef.current; if (!el) return;
      const vh = window.innerHeight;
      const top = el.getBoundingClientRect().top;
      setCoverProgress(Math.max(0, Math.min(1, (vh - top) / vh)));

      const a = symbolStartRef.current, b = symbolTargetRef.current, mover = travelRef.current;
      if (!a || !b || !mover) return;

      // MOBILE (≤767px): no shared-element transition at all. The travelling
      // sygnet is parked/hidden; the intro sygnet simply fades in place and
      // Section 2's own sygnet appears later, already at its final position.
      if (window.matchMedia('(max-width: 767px)').matches) {
        mover.style.visibility = 'hidden';
        if (landedRef.current !== true) { landedRef.current = true; setLanded(true); }
        return;
      }

      const ra = a.getBoundingClientRect(), rb = b.getBoundingClientRect();
      if (!(ra.width > 0 && rb.width > 0)) return;

      // Travel progress is derived from the TARGET's real on-screen position,
      // not from a fixed cover window — so the sygnet can never be dragged
      // off-screen chasing a target still far below the fold (this also keeps it
      // correct in the single-column layout, where the target stacks low).
      const t0 = Math.max(0, Math.min(1, (vh - rb.top) / (vh * 0.55)));
      const t = t0 * t0 * (3 - 2 * t0); // smoothstep — calm, no overshoot

      const dx = (rb.left + rb.width / 2) - (ra.left + ra.width / 2);
      const dy = (rb.top + rb.height / 2) - (ra.top + ra.height / 2);
      const endScale = rb.width / ra.width;
      // Scale eases DOWN through the middle of the move, then settles on the
      // target's scale — the mark recedes while travelling, per spec.
      const scale = 1 + (endScale - 1) * t - Math.sin(Math.PI * t) * 0.12;

      mover.style.left = ra.left + 'px';
      mover.style.top = ra.top + 'px';
      mover.style.width = ra.width + 'px';
      mover.style.height = ra.height + 'px';
      mover.style.transform = `translate3d(${dx * t}px, ${dy * t}px, 0) scale(${scale})`;
      mover.style.filter = (t > 0.001 && t < 0.995) ? `blur(${Math.sin(Math.PI * t) * 3.5}px)` : 'none';

      const isLanded = t0 >= 0.995;
      mover.style.visibility = isLanded ? 'hidden' : 'visible';
      if (isLanded !== landedRef.current) { landedRef.current = isLanded; setLanded(isLanded); }
    };
    const on = () => { if (raf) return; raf = requestAnimationFrame(calc); };
    window.addEventListener('scroll', on, { passive: true });
    window.addEventListener('resize', on, { passive: true });
    calc();
    return () => { window.removeEventListener('scroll', on); window.removeEventListener('resize', on); if (raf) cancelAnimationFrame(raf); };
  }, []);

  return (
    <div className="hero-transition" style={{position:'relative',marginTop:-78}}>
      <section className="intro-sticky" style={{position:'sticky',top:0,height:'100vh',overflow:'hidden',zIndex:1}}>
        <BrandIntro coverProgress={coverProgress} symbolStartRef={symbolStartRef} symbolSize={introSymbolSize}/>
      </section>
      <div className="intro-hold" aria-hidden="true" style={{height:`${holdVh}vh`,position:'relative',zIndex:0}}/>
      <ContentHero contentRef={contentRef} coverProgress={coverProgress} symbolTargetRef={symbolTargetRef} symbolLanded={landed}/>

      {/* THE one travelling sygnet — a single DOM element above both layers,
         always mounted and positioned imperatively each frame (so the sygnet
         tree is not re-rendered by React on every scroll frame). The intro slot
         and the Section 2 slot are invisible placeholders, so two sygnets are
         never on screen; at the landing point the swap is visually identical. */}
      <div ref={travelRef} aria-hidden style={{position:'fixed',left:0,top:0,zIndex:3,pointerEvents:'none',willChange:'transform, filter'}}>
        <SygnetShowcase size={introSymbolSize} simple={isMobile}/>
      </div>
    </div>
  );
}

/* ---- Section 1: pure brand intro. Fixed and centered for the ENTIRE
   transition — the composition itself never translates/parallaxes; only
   opacity, a sub-3% scale, and blur respond to Section 2 covering it.
   Fade formula (exact, per spec): fadeProgress = clamp((coverProgress-0.2)/0.7, 0, 1)
   — Section 1 stays fully visible until Section 2 has covered 20% of the
   viewport, then fades over the remaining 70%. Sygnet and wordmark are two
   clearly separated elements stacked vertically with a real gap — the
   sygnet's animation never crosses or backlights the wordmark. */
function BrandIntro({ coverProgress, symbolStartRef, symbolSize }) {
  const isMobile = useBreakpointValue([[767, true]], false);
  const shown = useMounted(80);

  // Retreat: the intro only reacts once Section 2 has begun covering it (15%),
  // then the WHOLE composition recedes as one unit — drifting slightly down
  // (opposite Section 2's upward travel), scaling back, softening and fading.
  // Reads as "tucking under" Section 2, never as sliding out of the viewport.
  // MOBILE: no shared-element travel, so the intro must clear the screen sooner —
  // fully invisible by ~58% cover, before Section 2's text reaches mid-viewport.
  const retreat = isMobile
    ? Math.max(0, Math.min(1, (coverProgress - 0.18) / 0.4))
    : Math.max(0, Math.min(1, (coverProgress - 0.15) / 0.8));
  const fadeProgress = isMobile ? retreat : Math.pow(retreat, 1.3);
  const maxY = isMobile ? 24 : 30; // wordmark drifts 20-30px, no more
  const maxBlur = isMobile ? 4 : 8;

  const buildIn = shown ? 1 : 0;
  const visualStyle = {
    transform: `translate3d(0, ${retreat * maxY}px, 0) scale(${1 - retreat * (isMobile ? 0.03 : 0.035)})`,
    filter: retreat > 0.001 ? `blur(${retreat * maxBlur}px)` : 'none',
    opacity: 1 - fadeProgress,
    willChange: 'transform, opacity, filter',
  };
  const glowOpacity = 0.85 * (1 - Math.pow(retreat, 0.55)); // glow clears well before the sygnet finishes travelling
  const meshOpacity = 0.55 * (1 - Math.pow(retreat, 0.45));  // decorative mesh thins out first

  const logoStyle = {
    opacity: buildIn,
    filter: `blur(${(1 - buildIn) * 6}px)`,
    transition: 'opacity 1.1s var(--ease-entrance) .5s, filter 1.1s var(--ease-entrance) .5s',
  };

  const seq = (delayMs) => ({ opacity: buildIn ? 1 : 0, transition: `opacity .9s var(--ease-entrance) ${delayMs}ms` });

  return (
    <div className="intro-visual" style={{position:'absolute',inset:0,display:'grid',placeItems:'center',background:'#08080B',...visualStyle}}>
      <div aria-hidden style={{position:'absolute',inset:0,backgroundImage:'var(--grid-mesh)',backgroundSize:'40px 40px',animation:'semai-grid-pan 8s linear infinite',maskImage:'radial-gradient(70% 60% at 50% 50%, #000, transparent)',WebkitMaskImage:'radial-gradient(70% 60% at 50% 50%, #000, transparent)',opacity:meshOpacity}}/>
      <div className="intro-glow" aria-hidden style={{position:'absolute',inset:'-10%',background:'radial-gradient(45% 45% at 50% 44%, rgba(107,45,217,0.26), rgba(107,45,217,0) 66%)',opacity:glowOpacity,filter:'blur(20px)'}}/>

      {/* two clearly separated elements, stacked with a real gap — sygnet above, wordmark below, on the same axis */}
      <div className="brand-lockup" style={{position:'relative',display:'flex',flexDirection:'column',alignItems:'center',gap:isMobile?32:56}}>
        {/* Desktop: invisible slot reserving space + measured as the shared-element START
           (the visible sygnet is the single travelling element rendered by HeroFlow).
           Mobile: no shared-element transition — the sygnet renders here, in place,
           and simply fades with the rest of the intro. */}
        <div className="animated-symbol" ref={symbolStartRef} aria-hidden style={{width:symbolSize,height:symbolSize,visibility:isMobile?'visible':'hidden'}}>
          {isMobile && <SygnetShowcase size={symbolSize} simple={true}/>}
        </div>
        {/* wordmark: its own clean space, flat dark ground, no glow/orbits behind the letters */}
        <img className="brand-wordmark" src={LOGO_DARK} alt="SEMAI" style={{width:useBreakpointValue([[480,'58vw'],[767,'44vw'],[1024,'32vw']],'26vw'),maxWidth:480,minWidth:180,display:'block',filter:'drop-shadow(0 4px 18px rgba(0,0,0,0.5))',...seq(320),...logoStyle}}/>
      </div>

      <div aria-hidden style={{position:'absolute',left:'50%',bottom:30,transform:'translateX(-50%)',display:'flex',flexDirection:'column',alignItems:'center',gap:7,opacity:1-retreat*3,pointerEvents:'none'}}>
        <span style={{fontFamily:'var(--font-mono)',fontSize:10,letterSpacing:'.16em',textTransform:'uppercase',color:'var(--text-faint)'}}>Przewiń</span>
        <span style={{width:22,height:34,borderRadius:12,border:'1px solid var(--border-strong)',position:'relative'}}>
          <span style={{position:'absolute',left:'50%',top:7,width:3,height:6,marginLeft:-1.5,borderRadius:2,background:'var(--violet-300)',animation:'semai-scrollcue 1.6s var(--ease-in-out) infinite'}}/>
        </span>
      </div>
    </div>
  );
}

/* ---- Section 2: the complete content section — headline, copy, CTAs + AI
   demo, two columns on desktop. Top-aligned (not vertically centered) so its
   real content sits close to the top edge and appears almost immediately as
   Section 2 climbs into view — no large empty band before the headline.
   Natural document flow: opacity:1, transform:none, opaque background, no
   JS-driven motion of its own. A soft gradient on its top edge (::before via
   an inline pseudo-equivalent layer) blends the seam instead of a hard line. */
function ContentHero({ contentRef, coverProgress = 0, symbolTargetRef, symbolLanded = false }) {
  const heroCols = useBreakpointValue([[1024, '1fr']], 'minmax(0,1fr) minmax(420px,0.9fr)');
  const sygnetSize = useBreakpointValue([[390,150],[640,190],[768,230],[1024,260]], 300);
  const demoOffset = useBreakpointValue([[1024,-8]], -28);
  const compactDemo = false;
  const answerStageHeight = useBreakpointValue([[767, 386]], 258);
  const isMobileHero = useBreakpointValue([[767, true]], false);
  // Section 2's own decorations only come up once the sygnet has landed, so
  // nothing competes with its travel. On mobile there is no travel — the
  // sygnet reveals in place, gated by an IntersectionObserver instead.
  const sygnetReveal = symbolLanded ? 1 : 0;
  const [inView, setInView] = React.useState(false);
  React.useEffect(() => {
    if (!isMobileHero) return;
    const el = symbolTargetRef && symbolTargetRef.current; if (!el) return;
    const io = new IntersectionObserver((es) => {
      es.forEach((e) => { if (e.isIntersecting) { setInView(true); io.disconnect(); } });
    }, { threshold: 0.35 });
    io.observe(el);
    return () => io.disconnect();
  }, [isMobileHero, symbolTargetRef]);

  return (
    <section ref={contentRef} className="main-hero" style={{position:'relative',zIndex:2,opacity:1,transform:'none',background:'#0D0D12',borderBottom:'1px solid var(--hairline)',minHeight:'100vh',padding:'clamp(90px,11vh,130px) 4vw 100px'}}>
      {/* soft top-edge blend + very soft cast shadow — marks Section 2 as a covering layer without reading as a card */}
      <div aria-hidden style={{position:'absolute',left:0,right:0,top:-140,height:140,pointerEvents:'none',background:'linear-gradient(to bottom, rgba(13,13,18,0), rgba(13,13,18,0.75), #0D0D12)',filter:'drop-shadow(0 -30px 50px rgba(0,0,0,0.18))'}}/>
      <div aria-hidden style={{position:'absolute',inset:0,overflow:'hidden',pointerEvents:'none'}}>
        <div style={{position:'absolute',top:'-10%',right:'6%',width:520,height:520,background:'radial-gradient(50% 50% at 50% 50%, rgba(171,101,214,0.16), rgba(171,101,214,0) 70%)',animation:'semai-aurora 20s var(--ease-in-out) -6s infinite',opacity:sygnetReveal}}/>
      </div>

      <div className="main-hero-grid" style={{maxWidth:'var(--container-wide)',margin:'0 auto',position:'relative',display:'grid',gridTemplateColumns:heroCols,alignItems:'start',gap:'clamp(48px,7vw,110px)'}}>
        {/* LEFT — headline + copy + CTAs */}
        <div className="main-hero-copy" style={{position:'relative',zIndex:3,display:'flex',flexDirection:'column',alignItems:'flex-start',textAlign:'left'}}>
          <div style={{marginBottom:24}}>
            <Badge tone="violet" dot>Nowy kanał · wejdź zanim zrobi się tłoczno</Badge>
          </div>

          <h1 style={{margin:0,font:'var(--fw-bold) clamp(34px,5.2vw,58px)/1.06 var(--font-display)',letterSpacing:'-.035em',color:'var(--text-strong)',textWrap:'balance'}}>
            Bądź <span style={{background:'var(--grad-sygnet)',WebkitBackgroundClip:'text',backgroundClip:'text',color:'transparent',backgroundSize:'200% 100%',animation:'semai-shimmer 6s linear infinite'}}>odpowiedzią</span>, nie tylko wynikiem wyszukiwania.
          </h1>

          <p style={{margin:'22px 0 0',maxWidth:560,width:'100%',font:'var(--fw-regular) clamp(15px,2.2vw,18px)/1.6 var(--font-sans)',color:'var(--text-muted)'}}>
            Twoi klienci coraz częściej pytają AI, co wybrać. Pomagamy markom pojawiać się w tej odpowiedzi — organicznie, płatnie i mierzalnie. LLM Ads, LLM Visibility i performance w ChatGPT, AI Search i innych interfejsach.
          </p>

          <div style={{display:'flex',gap:12,marginTop:28,flexWrap:'wrap'}}>
            <Button size="lg" trailingIcon={<ArrowR s={18}/>}>Zamów LLM Visibility Audit</Button>
            <Button size="lg" variant="secondary">Zobacz metodę</Button>
          </div>
          <p style={{margin:'16px 0 0',maxWidth:520,fontSize:12.5,color:'var(--text-faint)'}}>Nie obiecujemy pozycji nr 1 w ChatGPT. Projektujemy warunki, które zwiększają szansę widoczności — i je mierzymy.</p>
        </div>

        {/* RIGHT — the sygnet, showcased, with the answer it produces below */}
        <div className="main-hero-demo" style={{position:'relative',zIndex:2,display:'flex',flexDirection:'column',alignItems:'center',width:'100%',minWidth:0}}>
          {/* Desktop: landing slot for the travelling sygnet — holds its space
             always, revealing the real element only once the shared transition
             completes. Mobile: no travel at all — the sygnet lives in normal
             document flow, sits below the CTA block (≥40px clear), and simply
             fades/scales up in place once it scrolls into view. */}
          <div ref={symbolTargetRef} style={{width:sygnetSize,height:sygnetSize,marginTop:isMobileHero?40:0,visibility:symbolLanded?'visible':'hidden',opacity:isMobileHero?(inView?1:0):1,transform:isMobileHero?(inView?'scale(1)':'scale(0.96)'):'none',filter:isMobileHero?(inView?'blur(0px)':'blur(3px)'):'none',transition:isMobileHero?'opacity .6s var(--ease-out), transform .6s var(--ease-out), filter .6s var(--ease-out)':'none'}}>
            <SygnetShowcase size={sygnetSize}/>
          </div>
          <div style={{width:'100%',maxWidth:440,marginTop:demoOffset}}>
            <AnswerDemo compact={compactDemo} stageHeight={answerStageHeight}/>
          </div>
        </div>
      </div>
    </section>
  );
}

/* ============================ ECOSYSTEM (marquee) ============================ */
function Ecosystem() {
  const items=['ChatGPT','Gemini','Copilot','Perplexity','AI Overviews','AI Mode','Claude','Grok'];
  const track = [...items, ...items];
  return (
    <div style={{borderBottom:'1px solid var(--hairline)',overflow:'hidden'}}>
      <div style={{...WRAP,padding:'clamp(14px,3vw,22px) clamp(16px,5vw,32px)',display:'flex',alignItems:'center',gap:'clamp(14px,3vw,28px)',flexWrap:'wrap'}}>
        <span style={{fontFamily:'var(--font-mono)',fontSize:11,letterSpacing:'.14em',textTransform:'uppercase',color:'var(--text-faint)',whiteSpace:'nowrap',flexShrink:0}}>Gdzie decyduje klient</span>
        <div style={{position:'relative',flex:1,overflow:'hidden',maskImage:'linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent)',WebkitMaskImage:'linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent)'}}>
          <div style={{display:'flex',gap:44,width:'max-content',animation:'semai-marquee 26s linear infinite'}}>
            {track.map((x,i)=>(<span key={i} style={{fontFamily:'var(--font-mono)',fontSize:15,color:'var(--text-muted)',whiteSpace:'nowrap'}}>{x}</span>))}
          </div>
        </div>
      </div>
    </div>
  );
}

/* ============================ SHIFT (comparison) ============================ */
function Shift() {
  const shiftCols = useBreakpointValue([[768,'1fr']], '1fr 1fr');
  return (
    <section style={{...WRAP,padding:'clamp(56px,10vw,104px) clamp(16px,5vw,32px)'}}>
      <Reveal><span className="semai-eyebrow">Zmiana punktu decyzji</span>
      <h2 style={{margin:'14px 0 0',font:'var(--fw-semibold) clamp(26px,5vw,38px)/1.14 var(--font-display)',letterSpacing:'-.025em',color:'var(--text-strong)',maxWidth:640}}>SEO nie znika. Ale samo SEO przestaje wystarczać.</h2></Reveal>
      <div style={{display:'grid',gridTemplateColumns:shiftCols,gap:20,marginTop:40}}>
        <Reveal delay={40}>
        <Card style={{height:'100%'}}>
          <span style={{fontFamily:'var(--font-mono)',fontSize:11,letterSpacing:'.12em',textTransform:'uppercase',color:'var(--text-faint)'}}>Dotychczas</span>
          <h3 style={{margin:'12px 0 14px',font:'var(--text-h3)',color:'var(--text-body)'}}>Klient wyszukuje</h3>
          <ul style={{margin:0,paddingLeft:18,color:'var(--text-muted)',fontSize:14.5,lineHeight:1.9}}>
            <li>Ranking w Google i feed reklamowy</li>
            <li>Słowa kluczowe i pozycje</li>
            <li>Kliknięcie → strona → decyzja</li>
          </ul>
        </Card></Reveal>
        <Reveal delay={140}>
        <Card glow style={{height:'100%'}}>
          <span style={{fontFamily:'var(--font-mono)',fontSize:11,letterSpacing:'.12em',textTransform:'uppercase',color:'var(--text-accent)'}}>Coraz częściej</span>
          <h3 style={{margin:'12px 0 14px',font:'var(--text-h3)',color:'var(--text-strong)'}}>Klient pyta AI</h3>
          <ul style={{margin:0,paddingLeft:18,color:'var(--text-body)',fontSize:14.5,lineHeight:1.9}}>
            <li>Cytowalność i obecność w odpowiedzi</li>
            <li>Kontekst rozmowy i intencja</li>
            <li>Rekomendacja AI → zawężenie → decyzja</li>
          </ul>
        </Card></Reveal>
      </div>
    </section>
  );
}

/* ============================ PRODUCTS ============================ */
function Products() {
  const cols = useBreakpointValue([[640,'1fr'],[1024,'1fr 1fr']], 'repeat(3,1fr)');
  const items = [
    {icon:<Radar s={20}/>, eyebrow:'Produkt wejściowy', title:'LLM Visibility Audit', description:'Czy i jak marka pojawia się w odpowiedziach ChatGPT, Gemini, Copilot i Perplexity.', outcome:'Raport + priorytety · 10 dni', featured:true},
    {icon:<Msg s={20}/>, eyebrow:'Readiness', title:'ChatGPT Ads Readiness', description:'Przygotowanie oferty, landingów, kontekstów, kreacji i pomiaru pod reklamy w ChatGPT.', outcome:'Plan gotowości · 2 tyg.'},
    {icon:<Doc s={20}/>, eyebrow:'Content', title:'AI Search Content Plan', description:'Treści pod pytania, porównania, intencje i decyzje użytkowników w LLM-ach.', outcome:'Plan treści + mapa'},
    {icon:<TargetIco s={20}/>, eyebrow:'Strategia', title:'LLM Ads Strategy', description:'Segmenty, intencje, konteksty, komunikaty, budżet i pomiar reklam w interfejsach AI.', outcome:'Strategia + budżet'},
    {icon:<Chart s={20}/>, eyebrow:'Analityka', title:'AI Measurement Setup', description:'Ruch i konwersje z nowych źródeł AI: UTM-y, zdarzenia, dashboardy, jakość leadów.', outcome:'Dashboard + definicje'},
  ];
  return (
    <section style={{borderTop:'1px solid var(--hairline)',background:'var(--bg-canvas)'}}>
      <div style={{...WRAP,padding:'clamp(56px,10vw,104px) clamp(16px,5vw,32px)'}}>
        <Reveal><span className="semai-eyebrow">Produkty wejściowe</span>
        <h2 style={{margin:'14px 0 0',font:'var(--fw-semibold) clamp(26px,5vw,38px)/1.14 var(--font-display)',letterSpacing:'-.025em',color:'var(--text-strong)'}}>Konkret, nie „transformacja AI".</h2>
        <p style={{margin:'14px 0 0',maxWidth:560,color:'var(--text-muted)',fontSize:16,lineHeight:1.6}}>Każdy produkt ma mechanikę (co robimy) i miarę (jak sprawdzamy, że działa). Zacznij od audytu.</p></Reveal>
        <div style={{display:'grid',gridTemplateColumns:cols,gap:20,marginTop:40}}>
          {items.map((it,i)=>(<Reveal key={i} delay={i*70} style={{height:'100%'}}><ProductCard {...it} style={{height:'100%'}}/></Reveal>))}
          <Reveal delay={items.length*70} style={{height:'100%'}}>
          <Card style={{height:'100%',display:'flex',flexDirection:'column',justifyContent:'center',gap:12}}>
            <h3 style={{margin:0,font:'var(--text-h3)',color:'var(--text-strong)'}}>Nie wiesz, od czego zacząć?</h3>
            <p style={{margin:0,color:'var(--text-muted)',fontSize:14,lineHeight:1.55}}>15 minut. Powiemy wprost, gdzie jest realna dźwignia, a gdzie hype.</p>
            <Button variant="secondary" style={{alignSelf:'flex-start',marginTop:4}}>Umów rozmowę</Button>
          </Card></Reveal>
        </div>
      </div>
    </section>
  );
}

/* ============================ MEASUREMENT ============================ */
function Measurement() {
  const cols = useBreakpointValue([[768,'1fr']], '0.9fr 1.1fr');
  return (
    <section style={{...WRAP,padding:'clamp(56px,10vw,104px) clamp(16px,5vw,32px)'}}>
      <div style={{display:'grid',gridTemplateColumns:cols,gap:'clamp(28px,6vw,56px)',alignItems:'center'}}>
        <Reveal>
        <div>
          <span className="semai-eyebrow">Measurement &amp; Analytics</span>
          <h2 style={{margin:'14px 0 0',font:'var(--fw-semibold) clamp(26px,5vw,38px)/1.14 var(--font-display)',letterSpacing:'-.025em',color:'var(--text-strong)'}}>Jeśli nie mierzysz, zgadujesz.</h2>
          <p style={{margin:'16px 0 24px',color:'var(--text-muted)',fontSize:16,lineHeight:1.6,maxWidth:460}}>Rozdzielamy ruch z AI Search, dark search i klasycznych źródeł. Jedna definicja wyniku, jeden dashboard, spójne raporty w marketingu, sprzedaży i finansach.</p>
          <div style={{display:'flex',gap:34,flexWrap:'wrap'}}>
            <MetricStat label="Widoczność w AI" value="62" unit="/100" delta="+18" hint="30 dni"/>
            <MetricStat label="Cytowania marki" value="24" delta="+6" hint="wszystkie modele"/>
          </div>
        </div></Reveal>
        <Reveal delay={120}>
        <Card padded>
          <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',marginBottom:20}}>
            <span style={{fontFamily:'var(--font-mono)',fontSize:11,letterSpacing:'.12em',textTransform:'uppercase',color:'var(--text-faint)'}}>Widoczność wg modelu</span>
            <Badge tone="positive" dot>Live</Badge>
          </div>
          <VisibilityMeter score={62} label="Średnia widoczność"
            models={[{name:'ChatGPT',score:71},{name:'Gemini',score:58},{name:'Perplexity',score:44},{name:'Copilot',score:39}]}/>
        </Card></Reveal>
      </div>
    </section>
  );
}

/* ============================ CTA + FOOTER ============================ */
function CTA() {
  const ctaSygnet = useBreakpointValue([[640,64]], 92);
  return (
    <section style={{borderTop:'1px solid var(--hairline)',position:'relative',overflow:'hidden'}}>
      <div aria-hidden style={{position:'absolute',inset:0,pointerEvents:'none'}}>
        <div style={{position:'absolute',top:'-40%',left:'50%',width:760,height:560,marginLeft:-380,background:'radial-gradient(50% 50% at 50% 50%, rgba(107,45,217,0.30), rgba(107,45,217,0) 70%)',animation:'semai-aurora 18s var(--ease-in-out) infinite'}}/>
      </div>
      <div style={{...WRAP,position:'relative',padding:'clamp(56px,10vw,104px) clamp(16px,5vw,32px)',textAlign:'center'}}>
        <Reveal>
        <div style={{display:'flex',justifyContent:'center',marginBottom:26}}><SygnetMark size={ctaSygnet}/></div>
        <h2 style={{margin:0,font:'var(--fw-bold) clamp(28px,7vw,46px)/1.08 var(--font-display)',letterSpacing:'-.03em',color:'var(--text-strong)',textWrap:'balance',maxWidth:720,marginInline:'auto'}}>
          Wejdź w nowy kanał, zanim zbierze w nim uwagę konkurencja.
        </h2>
        <div style={{display:'flex',gap:12,justifyContent:'center',marginTop:32,flexWrap:'wrap'}}>
          <Button size="lg" trailingIcon={<ArrowR s={18}/>}>Zamów LLM Visibility Audit</Button>
          <Button size="lg" variant="outline">Porozmawiaj z nami</Button>
        </div></Reveal>
      </div>
    </section>
  );
}
function Footer() {
  return (
    <footer style={{borderTop:'1px solid var(--hairline)',background:'var(--bg-base)'}}>
      <div style={{...WRAP,padding:'clamp(28px,6vw,44px) clamp(16px,5vw,32px)',display:'flex',alignItems:'center',justifyContent:'space-between',flexWrap:'wrap',gap:16}}>
        <a href="#/" onClick={(e)=>go('#/',e)} style={{display:'inline-flex'}}><Logo h={28}/></a>
        <div style={{display:'flex',gap:22,alignItems:'center'}}>
          <a href="#/" onClick={(e)=>go('#/',e)} style={{fontSize:13,color:'var(--text-muted)'}}>SEMAI LLM</a>
          <a href="#/performance" onClick={(e)=>go('#/performance',e)} style={{fontSize:13,color:'var(--text-muted)'}}>SEMAI Performance</a>
        </div>
        <span style={{fontFamily:'var(--font-mono)',fontSize:11,color:'var(--text-faint)'}}>© 2026 SEMAI</span>
      </div>
    </footer>
  );
}

/* ============ DEDICATED HOMEPAGE SECTION → SEMAI Performance ============
   AI-first homepage keeps violet everywhere; this is the ONE place green
   (#3ECF8E) appears — the product signal for SEMAI Performance. Kept to a
   single, clearly-separated band so it reads as "second product", not
   "second half of the homepage" (Brandbook v1.1: max 3-5% green on home). */
function PerformanceBridge() {
  const bridgeCols = useBreakpointValue([[1024,'1fr']], '1.25fr 0.75fr');
  const Check = (p)=>(<I {...p}><path d="M20 6 9 17l-5-5"/></I>);
  const feats = [
    ['Google Ads · Meta · SEM','Search, PMax, Meta Ads, remarketing'],
    ['Analityka i pomiar','GA4, GTM, konwersje, dashboardy'],
    ['Decyzje budżetowe','CPA, ROAS, jakość leadów, skalowanie'],
  ];
  return (
    <section style={{position:'relative',borderTop:'1px solid var(--hairline)',overflow:'hidden'}}>
      {/* green product atmosphere — the only green on the homepage */}
      <div aria-hidden style={{position:'absolute',inset:0,pointerEvents:'none'}}>
        <div style={{position:'absolute',top:'-20%',right:'-6%',width:640,height:520,background:'radial-gradient(50% 50% at 50% 50%, rgba(62,207,142,0.14), rgba(62,207,142,0) 70%)',animation:'semai-aurora 20s var(--ease-in-out) infinite'}}/>
      </div>
      <div style={{...WRAP,position:'relative',padding:'clamp(48px,9vw,92px) clamp(16px,5vw,32px)'}}>
        <Reveal>
        <div style={{position:'relative',overflow:'hidden',border:'1px solid var(--perf-border)',borderRadius:'var(--radius-2xl)',background:'linear-gradient(180deg, rgba(14,42,34,0.55), var(--surface-1))',boxShadow:'0 0 0 1px rgba(62,207,142,0.10), var(--shadow-lg)'}}>
          {/* top product ribbon */}
          <div style={{display:'flex',alignItems:'center',gap:10,padding:'16px clamp(16px,5vw,32px)',borderBottom:'1px solid var(--perf-border)',background:'rgba(14,42,34,0.4)',flexWrap:'wrap'}}>
            <span style={{display:'inline-flex',alignItems:'center',gap:8,fontFamily:'var(--font-mono)',fontSize:11,letterSpacing:'.14em',textTransform:'uppercase',color:'var(--perf-accent)'}}>
              <span style={{width:7,height:7,borderRadius:'50%',background:'var(--perf-accent)',boxShadow:'0 0 10px var(--perf-glow)'}}/>
              Drugi produkt SEMAI
            </span>
            <span style={{fontFamily:'var(--font-mono)',fontSize:11,color:'var(--text-faint)'}}>— osobna ścieżka</span>
          </div>

          <div style={{position:'relative',padding:'clamp(24px,5vw,44px)',display:'grid',gridTemplateColumns:bridgeCols,gap:44,alignItems:'center'}}>
            <div style={{position:'absolute',inset:0,backgroundImage:'var(--grid-mesh)',backgroundSize:'40px 40px',opacity:0.3,maskImage:'linear-gradient(90deg,transparent,#000)',WebkitMaskImage:'linear-gradient(90deg,transparent,#000)',pointerEvents:'none'}}/>
            <div style={{position:'relative'}}>
              <div style={{display:'flex',alignItems:'center',gap:10,marginBottom:16}}>
                <img src={LOGO_DARK} alt="SEMAI" style={{height:24}}/>
                <span style={{fontFamily:'var(--font-mono)',fontSize:13,letterSpacing:'.04em',color:'var(--perf-accent)',borderLeft:'1px solid var(--perf-border)',paddingLeft:10}}>Performance</span>
              </div>
              <h2 style={{margin:'0 0 14px',font:'var(--fw-semibold) clamp(22px,5vw,34px)/1.16 var(--font-display)',letterSpacing:'-.025em',color:'var(--text-strong)',maxWidth:560,textWrap:'balance'}}>Szukasz klasycznego SEM i performance marketingu?</h2>
              <p style={{margin:0,maxWidth:560,color:'var(--text-muted)',fontSize:16,lineHeight:1.62}}>
                SEMAI to nie tylko widoczność w AI. Jeśli potrzebujesz kampanii Google Ads i Meta, precyzyjnej analityki, poprawnego pomiaru konwersji i decyzji budżetowych opartych na danych, przejdź do SEMAI Performance.
              </p>
              <button onClick={()=>go('#/performance')}
                onMouseEnter={e=>{e.currentTarget.style.background='var(--perf-accent-hover)';}}
                onMouseLeave={e=>{e.currentTarget.style.background='var(--perf-accent)';}}
                style={{marginTop:28,display:'inline-flex',alignItems:'center',gap:9,height:48,padding:'0 24px',border:'none',borderRadius:'var(--radius-md)',cursor:'pointer',background:'var(--perf-accent)',color:'#08120E',font:'var(--fw-semibold) 15px/1 var(--font-sans)',boxShadow:'0 0 0 1px rgba(62,207,142,0.4), 0 8px 28px rgba(62,207,142,0.22)',transition:'background .14s var(--ease-out)'}}>
                Zobacz SEMAI Performance
                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg>
              </button>
            </div>
            <div style={{position:'relative',display:'flex',flexDirection:'column',gap:12}}>
              {feats.map(([t,d],i)=>(
                <div key={i} style={{display:'flex',gap:12,alignItems:'flex-start',padding:'14px 16px',border:'1px solid var(--perf-border)',borderRadius:'var(--radius-md)',background:'var(--perf-tint)'}}>
                  <span style={{flexShrink:0,marginTop:1,width:22,height:22,borderRadius:6,background:'var(--perf-deep)',border:'1px solid var(--perf-border)',color:'var(--perf-accent)',display:'inline-flex',alignItems:'center',justifyContent:'center'}}><Check s={13}/></span>
                  <span style={{display:'flex',flexDirection:'column',gap:2}}>
                    <span style={{fontSize:14,fontWeight:'var(--fw-semibold)',color:'var(--text-strong)'}}>{t}</span>
                    <span style={{fontSize:12.5,color:'var(--text-muted)',lineHeight:1.4}}>{d}</span>
                  </span>
                </div>
              ))}
            </div>
          </div>
        </div>
        </Reveal>
      </div>
    </section>
  );
}

/* small icons for Performance */
const Check = (p)=>(<I {...p}><path d="M20 6 9 17l-5-5"/></I>);
const Gauge = (p)=>(<I {...p}><path d="M12 15l4-4"/><path d="M20.5 16a9 9 0 1 0-17 0"/></I>);
const Funnel = (p)=>(<I {...p}><path d="M3 4h18l-7 8v6l-4 2v-8z"/></I>);
const Sliders = (p)=>(<I {...p}><path d="M4 21v-7M4 10V3M12 21v-9M12 8V3M20 21v-5M20 12V3M1 14h6M9 8h6M17 16h6"/></I>);
const Layers2 = (p)=>(<I {...p}><path d="m12 2 9 5-9 5-9-5 9-5z"/><path d="m3 12 9 5 9-5"/><path d="m3 17 9 5 9-5"/></I>);

/* Green product CTA (SEMAI Performance) */
function PerfButton({ children, size = 'md', variant = 'solid', onClick }) {
  const [h, setH] = React.useState(false);
  const dims = size === 'lg' ? { height: 48, pad: '0 24px', fs: 15 } : { height: 40, pad: '0 18px', fs: 14 };
  const solid = variant === 'solid';
  return (
    <button onClick={onClick} onMouseEnter={()=>setH(true)} onMouseLeave={()=>setH(false)}
      style={{
        display:'inline-flex',alignItems:'center',gap:9,height:dims.height,padding:dims.pad,
        border:solid?'none':'1px solid var(--perf-border)',borderRadius:'var(--radius-md)',cursor:'pointer',
        background: solid ? (h?'var(--perf-accent-hover)':'var(--perf-accent)') : (h?'var(--perf-tint)':'transparent'),
        color: solid ? '#08120E' : 'var(--perf-text)',
        font:`var(--fw-semibold) ${dims.fs}px/1 var(--font-sans)`,
        boxShadow: solid ? '0 0 0 1px rgba(62,207,142,0.4), 0 8px 28px rgba(62,207,142,0.22)' : 'none',
        transition:'background .14s var(--ease-out)',
      }}>
      {children}
      <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg>
    </button>
  );
}
/* Green accent tile for Performance icons */
const perfTile = { width:40, height:40, borderRadius:'var(--radius-md)', background:'var(--perf-tint)', border:'1px solid var(--perf-border)', color:'var(--perf-accent)', display:'inline-flex', alignItems:'center', justifyContent:'center' };

/* ============================ PERFORMANCE — HERO ============================ */
function PerfHero() {
  const shown = useMounted(80);
  const cols = useBreakpointValue([[1024,'1fr']], '1.1fr 0.9fr');
  const metricCols = useBreakpointValue([[420,'1fr']], '1fr 1fr');
  return (
    <section style={{position:'relative',overflow:'hidden',borderBottom:'1px solid var(--hairline)'}}>
      <div aria-hidden style={{position:'absolute',inset:0,overflow:'hidden',pointerEvents:'none'}}>
        <div style={{position:'absolute',top:'-30%',left:'46%',width:820,height:560,marginLeft:-410,background:'radial-gradient(50% 50% at 50% 50%, rgba(107,45,217,0.26), rgba(107,45,217,0) 70%)',animation:'semai-aurora 18s var(--ease-in-out) infinite'}}/>
        <div style={{position:'absolute',inset:0,backgroundImage:'var(--grid-mesh)',backgroundSize:'40px 40px',opacity:0.5,maskImage:'radial-gradient(80% 70% at 50% 0%, #000, transparent)',WebkitMaskImage:'radial-gradient(80% 70% at 50% 0%, #000, transparent)'}}/>
      </div>
      <div style={{...WRAP,position:'relative',padding:'clamp(48px,10vw,84px) clamp(16px,5vw,32px) clamp(52px,10vw,88px)',display:'grid',gridTemplateColumns:cols,gap:'clamp(28px,5vw,56px)',alignItems:'center'}}>
        <div>
          <div style={{...enter(shown,0),display:'flex',alignItems:'center',gap:10,marginBottom:22}}>
            <img src={LOGO_DARK} alt="SEMAI" style={{height:26}}/>
            <span style={{fontFamily:'var(--font-mono)',fontSize:13,letterSpacing:'.06em',color:'var(--perf-accent)',borderLeft:'1px solid var(--perf-border)',paddingLeft:10}}>Performance</span>
          </div>
          <div style={{...enter(shown,80),display:'inline-flex',alignItems:'center',gap:8,padding:'4px 10px',borderRadius:999,background:'var(--perf-tint)',border:'1px solid var(--perf-border)'}}>
            <span style={{width:6,height:6,borderRadius:'50%',background:'var(--perf-accent)',boxShadow:'0 0 8px var(--perf-glow)'}}/>
            <span style={{fontFamily:'var(--font-mono)',fontSize:11,letterSpacing:'.1em',textTransform:'uppercase',color:'var(--perf-text)'}}>Google Ads · Meta · Analityka</span>
          </div>
          <h1 style={{...enter(shown,180),margin:'20px 0 0',font:'var(--fw-bold) clamp(28px,6vw,50px)/1.1 var(--font-display)',letterSpacing:'-.03em',color:'var(--text-strong)',textWrap:'balance'}}>
            SEM i performance marketing oparty na precyzyjnej analityce.
          </h1>
          <p style={{...enter(shown,300),margin:'22px 0 0',maxWidth:540,font:'var(--fw-regular) 17px/1.62 var(--font-sans)',color:'var(--text-muted)'}}>
            SEMAI Performance pomaga firmom prowadzić kampanie Google Ads, Meta i performance marketing w sposób mierzalny, uporządkowany i oparty na danych. Nie chodzi o same kliknięcia. Chodzi o poprawny pomiar, jakość konwersji, kontrolę budżetu i decyzje, które da się obronić liczbami.
          </p>
          <div style={{...enter(shown,420),display:'flex',gap:12,marginTop:30,flexWrap:'wrap'}}>
            <PerfButton size="lg">Umów konsultację</PerfButton>
            <Button size="lg" variant="secondary">Sprawdź zakres usługi</Button>
          </div>
        </div>
        <div style={{...enter(shown,540,28)}}>
          <Card padded style={{animation:'semai-float 7s var(--ease-in-out) 1s infinite'}}>
            <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',marginBottom:18}}>
              <span style={{fontFamily:'var(--font-mono)',fontSize:11,letterSpacing:'.12em',textTransform:'uppercase',color:'var(--text-faint)'}}>Dashboard kampanii</span>
              <Badge tone="positive" dot>Live</Badge>
            </div>
            <div style={{display:'grid',gridTemplateColumns:metricCols,gap:20,marginBottom:20}}>
              <MetricStat label="ROAS" value="4.8" unit="×" delta="+0.6" hint="30 dni"/>
              <MetricStat label="CPA" value="112" unit="zł" delta="-18%" deltaDir="down" hint="cel 140 zł"/>
              <MetricStat label="CVR" value="3.9" unit="%" delta="+0.7"/>
              <MetricStat label="Jakość leadów" value="72" unit="/100" delta="+9"/>
            </div>
            <div style={{borderTop:'1px solid var(--hairline)',paddingTop:16,display:'flex',flexDirection:'column',gap:11}}>
              {[['Search',82],['Performance Max',64],['Meta Ads',57],['Demand Gen',44],['Remarketing',33]].map(([n,v])=>(
                <div key={n} style={{display:'grid',gridTemplateColumns:'120px 1fr 32px',alignItems:'center',gap:12}}>
                  <span style={{fontSize:13,color:'var(--text-muted)'}}>{n}</span>
                  <span style={{position:'relative',height:6,borderRadius:999,background:'var(--surface-inset)',border:'1px solid var(--border-subtle)',overflow:'hidden'}}>
                    <span style={{position:'absolute',left:0,top:0,bottom:0,width:v+'%',background:'var(--grad-perf)',borderRadius:999}}/>
                  </span>
                  <span style={{fontFamily:'var(--font-mono)',fontSize:12,color:'var(--text-body)',textAlign:'right'}}>{v}</span>
                </div>
              ))}
            </div>
          </Card>
        </div>
      </div>
    </section>
  );
}

/* ==================== PERFORMANCE — FOR WHOM + SCOPE ==================== */
function PerfForWhom() {
  const cols = useBreakpointValue([[1024,'1fr']], '1fr 1fr');
  const scopeCols = useBreakpointValue([[520,'1fr']], '1fr 1fr');
  const pains = [
    'Inwestujesz w Google Ads i Meta, ale nie masz pewności, co realnie działa.',
    'Nie wiesz, czy konwersje są poprawnie mierzone.',
    'Raporty pokazują liczby, ale nie prowadzą do decyzji.',
    'Kampanie generują leady, ale jakość jest nierówna.',
    'Budżet rośnie, ale nie wiadomo, czy powinien być skalowany.',
    'Potrzebujesz analityki, a nie tylko obsługi reklam.',
  ];
  const scope = [
    'Audyt kont Google Ads i Meta','Search, PMax, Demand Gen, remarketing','Meta Ads: Advantage+, retargeting','Struktura kampanii i grup reklam','Analiza budżetu','Analiza kosztów i konwersji','GA4 i GTM','Konfiguracja eventów i konwersji','Dashboardy','Analiza lejka','Analiza jakości leadów','Rekomendacje: skalować, ciąć, testować','Poprawa landingów i trackingu',
  ];
  return (
    <section style={{...WRAP,padding:'clamp(48px,9vw,96px) clamp(16px,5vw,32px)'}}>
      <div style={{display:'grid',gridTemplateColumns:cols,gap:48}}>
        <Reveal>
        <div>
          <span className="semai-eyebrow">Dla kogo</span>
          <h2 style={{margin:'14px 0 16px',font:'var(--fw-semibold) clamp(22px,5vw,32px)/1.18 var(--font-display)',letterSpacing:'-.02em',color:'var(--text-strong)'}}>Dla firm, które inwestują w Google Ads i Meta — ale nie mają pełnej kontroli nad wynikiem.</h2>
          <p style={{margin:'0 0 24px',color:'var(--text-muted)',fontSize:15.5,lineHeight:1.62,maxWidth:520}}>Dla firm, które widzą koszty, kliknięcia i konwersje, ale nie wiedzą, które działania realnie dowożą biznes.</p>
          <div style={{display:'flex',flexDirection:'column',gap:12}}>
            {pains.map((p,i)=>(
              <div key={i} style={{display:'flex',gap:11,alignItems:'flex-start'}}>
                <span style={{flexShrink:0,marginTop:2,width:20,height:20,borderRadius:6,background:'var(--surface-3)',border:'1px solid var(--border-strong)',color:'var(--text-faint)',display:'inline-flex',alignItems:'center',justifyContent:'center'}}><I s={12}><path d="M12 8v4M12 16h.01"/><circle cx="12" cy="12" r="9"/></I></span>
                <span style={{fontSize:14.5,lineHeight:1.5,color:'var(--text-body)'}}>{p}</span>
              </div>
            ))}
          </div>
        </div></Reveal>
        <Reveal delay={120}>
        <Card style={{height:'100%',borderColor:'var(--perf-border)'}}>
          <span style={{fontFamily:'var(--font-mono)',fontSize:11,letterSpacing:'.12em',textTransform:'uppercase',color:'var(--perf-text)'}}>Co obejmuje usługa</span>
          <div style={{display:'grid',gridTemplateColumns:scopeCols,gap:'12px 18px',marginTop:18}}>
            {scope.map((s,i)=>(
              <div key={i} style={{display:'flex',gap:9,alignItems:'flex-start'}}>
                <span style={{flexShrink:0,marginTop:1,color:'var(--perf-accent)'}}><Check s={16}/></span>
                <span style={{fontSize:13.5,lineHeight:1.4,color:'var(--text-body)'}}>{s}</span>
              </div>
            ))}
          </div>
        </Card></Reveal>
      </div>
    </section>
  );
}

/* ==================== PERFORMANCE — ANALYTICS FOUNDATION ==================== */
function PerfAnalytics() {
  const cols = useBreakpointValue([[640,'1fr'],[1024,'1fr 1fr']], 'repeat(3,1fr)');
  const points = [
    ['Poprawny tracking', <Sliders s={18}/>],
    ['Jasna definicja konwersji', <TargetIco s={18}/>],
    ['Rozdzielenie mikro- i makrokonwersji', <Layers2 s={18}/>],
    ['Spójność GA4, GTM, Google Ads i Meta', <Gauge s={18}/>],
    ['Dashboardy prowadzące do decyzji', <Chart s={18}/>],
    ['Analiza jakości leadów, nie tylko liczby', <Funnel s={18}/>],
  ];
  return (
    <section style={{borderTop:'1px solid var(--hairline)',background:'var(--bg-canvas)'}}>
      <div style={{...WRAP,padding:'clamp(48px,9vw,96px) clamp(16px,5vw,32px)'}}>
        <Reveal>
        <div style={{maxWidth:640}}>
          <span className="semai-eyebrow">Analityka jako fundament</span>
          <h2 style={{margin:'14px 0 14px',font:'var(--fw-semibold) clamp(24px,5vw,34px)/1.14 var(--font-display)',letterSpacing:'-.025em',color:'var(--text-strong)'}}>Bez pomiaru performance jest zgadywaniem.</h2>
          <p style={{margin:0,color:'var(--text-muted)',fontSize:16,lineHeight:1.62}}>W SEMAI Performance analityka nie jest dodatkiem. Jest punktem wyjścia. Kampanie mają sens dopiero wtedy, gdy wiadomo, co mierzymy, jaką wartość mają konwersje i które działania faktycznie wpływają na biznes.</p>
        </div></Reveal>
        <div style={{display:'grid',gridTemplateColumns:cols,gap:18,marginTop:38}}>
          {points.map(([t,ic],i)=>(
            <Reveal key={i} delay={i*60} style={{height:'100%'}}>
            <Card style={{height:'100%',display:'flex',flexDirection:'column',gap:14}}>
              <span style={perfTile}>{ic}</span>
              <span style={{fontSize:15,fontWeight:'var(--fw-medium)',color:'var(--text-strong)',lineHeight:1.35}}>{t}</span>
            </Card></Reveal>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ==================== PERFORMANCE — PROCESS ==================== */
function PerfProcess() {
  const cols = useBreakpointValue([[640,'1fr'],[1024,'1fr 1fr']], 'repeat(3,1fr)');
  const steps = [
    ['Diagnoza konta i danych','Sprawdzamy, czy dane są wiarygodne.'],
    ['Weryfikacja pomiaru','Tracking, eventy, konwersje, spójność GA4/GTM.'],
    ['Uporządkowanie kampanii','Struktura kont, grup i kreacji.'],
    ['Optymalizacja budżetu','Koszty, stawki, alokacja między kampanie.'],
    ['Analiza efektów','CPA, ROAS, CVR, jakość leadów, lejek.'],
    ['Decyzje o skalowaniu','Skalować, ciąć, testować albo poprawić.'],
  ];
  return (
    <section style={{...WRAP,padding:'clamp(48px,9vw,96px) clamp(16px,5vw,32px)'}}>
      <Reveal>
      <span className="semai-eyebrow">Proces pracy</span>
      <h2 style={{margin:'14px 0 8px',font:'var(--fw-semibold) clamp(22px,5vw,32px)/1.2 var(--font-display)',letterSpacing:'-.02em',color:'var(--text-strong)',maxWidth:640}}>Najpierw dane. Potem struktura. Dopiero później skalowanie.</h2>
      <p style={{margin:0,color:'var(--text-muted)',fontSize:15.5,lineHeight:1.6,maxWidth:600}}>Najpierw sprawdzamy, czy dane są wiarygodne. Potem poprawiamy strukturę kampanii. Dopiero później podejmujemy decyzje o skalowaniu.</p>
      </Reveal>
      <div style={{display:'grid',gridTemplateColumns:cols,gap:18,marginTop:40}}>
        {steps.map(([t,d],i)=>(
          <Reveal key={i} delay={i*60} style={{height:'100%'}}>
          <Card style={{height:'100%',display:'flex',flexDirection:'column',gap:12}}>
            <span style={{fontFamily:'var(--font-mono)',fontSize:13,fontWeight:600,color:'var(--perf-accent)'}}>{String(i+1).padStart(2,'0')}</span>
            <span style={{fontSize:16,fontWeight:'var(--fw-semibold)',color:'var(--text-strong)'}}>{t}</span>
            <span style={{fontSize:13.5,lineHeight:1.5,color:'var(--text-muted)'}}>{d}</span>
          </Card></Reveal>
        ))}
      </div>
    </section>
  );
}

/* ==================== PERFORMANCE — ENTRY PRODUCTS ==================== */
function PerfProducts() {
  const cols = useBreakpointValue([[520,'1fr'],[900,'1fr 1fr']], 'repeat(4,1fr)');
  const items = [
    {icon:<Gauge s={20}/>, eyebrow:'Produkt wejściowy', title:'Performance Audit', description:'Audyt kampanii, budżetów, struktury konta, konwersji i realnych punktów przepalania pieniędzy.', outcome:'Raport + priorytety', featured:true},
    {icon:<Sliders s={20}/>, eyebrow:'Analityka', title:'Measurement Setup', description:'Uporządkowanie GA4, GTM, eventów, konwersji, dashboardów i standardu danych.', outcome:'Standard pomiaru'},
    {icon:<TargetIco s={20}/>, eyebrow:'Sprint', title:'Campaign Optimization Sprint', description:'Krótki sprint: diagnoza, wdrożenie, analiza efektów i decyzje o dalszym kierunku.', outcome:'Wdrożenie + decyzje'},
    {icon:<Chart s={20}/>, eyebrow:'Plan', title:'Performance Growth Plan', description:'Plan rozwoju kampanii, budżetu, lejka, testów i analityki na 30–90 dni.', outcome:'Plan 30–90 dni'},
  ];
  return (
    <section style={{borderTop:'1px solid var(--hairline)',background:'var(--bg-canvas)'}}>
      <div style={{...WRAP,padding:'clamp(48px,9vw,96px) clamp(16px,5vw,32px)'}}>
        <Reveal>
        <span className="semai-eyebrow">Produkty wejściowe</span>
        <h2 style={{margin:'14px 0 0',font:'var(--fw-semibold) clamp(24px,5vw,34px)/1.14 var(--font-display)',letterSpacing:'-.025em',color:'var(--text-strong)'}}>Zacznij od audytu i pomiaru.</h2>
        </Reveal>
        <div style={{display:'grid',gridTemplateColumns:cols,gap:18,marginTop:38}}>
          {items.map((it,i)=>(
            <Reveal key={i} delay={i*70} style={{height:'100%'}}>
            <div style={{height:'100%',display:'flex',flexDirection:'column',gap:14,padding:'var(--space-7)',borderRadius:'var(--radius-lg)',background:i===0?'linear-gradient(180deg, rgba(14,42,34,0.5), var(--surface-1))':'var(--surface-1)',backgroundImage:i===0?undefined:'var(--grad-surface)',border:`1px solid ${i===0?'var(--perf-border)':'var(--border-default)'}`,boxShadow:i===0?'0 0 0 1px rgba(62,207,142,0.10), var(--shadow-md)':'var(--shadow-sm)'}}>
              <div style={{display:'flex',alignItems:'center',justifyContent:'space-between'}}>
                <span style={perfTile}>{it.icon}</span>
                {i===0 && <span style={{fontFamily:'var(--font-mono)',fontSize:10,letterSpacing:'.12em',textTransform:'uppercase',color:'var(--perf-accent)'}}>Zacznij tu</span>}
              </div>
              <span className="semai-eyebrow" style={{color:'var(--perf-text)'}}>{it.eyebrow}</span>
              <div style={{display:'flex',flexDirection:'column',gap:8,flex:1}}>
                <h3 style={{margin:0,font:'var(--text-h3)',color:'var(--text-strong)',letterSpacing:'var(--ls-snug)'}}>{it.title}</h3>
                <p style={{margin:0,fontSize:14,lineHeight:1.55,color:'var(--text-muted)'}}>{it.description}</p>
              </div>
              <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',paddingTop:12,borderTop:'1px solid var(--hairline)'}}>
                <span style={{fontSize:12.5,color:'var(--text-faint)'}}>{it.outcome}</span>
                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="var(--perf-accent)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg>
              </div>
            </div></Reveal>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ==================== PERFORMANCE — CTA ==================== */
function PerfCTA() {
  return (
    <section style={{borderTop:'1px solid var(--hairline)',position:'relative',overflow:'hidden'}}>
      <div aria-hidden style={{position:'absolute',inset:0,pointerEvents:'none'}}>
        <div style={{position:'absolute',top:'-40%',left:'50%',width:760,height:560,marginLeft:-380,background:'radial-gradient(50% 50% at 50% 50%, rgba(62,207,142,0.20), rgba(62,207,142,0) 70%)',animation:'semai-aurora 18s var(--ease-in-out) infinite'}}/>
      </div>
      <div style={{...WRAP,position:'relative',padding:'clamp(52px,10vw,100px) clamp(16px,5vw,32px)',textAlign:'center'}}>
        <Reveal>
        <h2 style={{margin:0,font:'var(--fw-bold) clamp(26px,6vw,42px)/1.14 var(--font-display)',letterSpacing:'-.03em',color:'var(--text-strong)',textWrap:'balance',maxWidth:760,marginInline:'auto'}}>
          Chcesz wiedzieć, czy Twoje kampanie naprawdę dowożą wynik?
        </h2>
        <p style={{margin:'18px auto 0',maxWidth:600,color:'var(--text-muted)',fontSize:16,lineHeight:1.6}}>
          Sprawdźmy konto, pomiar i dane. Bez prezentacji o marketingu. Konkretnie: co działa, co przepala budżet i co warto poprawić jako pierwsze.
        </p>
        <div style={{display:'flex',gap:12,justifyContent:'center',marginTop:30,flexWrap:'wrap'}}>
          <PerfButton size="lg">Porozmawiajmy o SEMAI Performance</PerfButton>
        </div></Reveal>
      </div>
    </section>
  );
}

function PerformancePage() {
  return (
    <React.Fragment>
      <PerfHero/>
      <PerfForWhom/>
      <PerfAnalytics/>
      <PerfProcess/>
      <PerfProducts/>
      <PerfCTA/>
    </React.Fragment>
  );
}

/* ============================ APP (router) ============================ */
function App() {
  const route = useRoute();
  const perf = route.indexOf('performance') !== -1;
  return (
    <React.Fragment>
      <SiteNav active={perf ? '/performance' : '/'}/>
      {perf ? (
        <PerformancePage/>
      ) : (
        <React.Fragment>
          <HeroFlow/>
          <Ecosystem/>
          <Reveal><Shift/></Reveal>
          <Reveal><Products/></Reveal>
          <Reveal><Measurement/></Reveal>
          <Reveal><PerformanceBridge/></Reveal>
          <Reveal><CTA/></Reveal>
        </React.Fragment>
      )}
      <Footer/>
    </React.Fragment>
  );
}

Object.assign(window, { SiteNav, Hero: HeroFlow, BrandIntro, ContentHero, HeroFlow, Ecosystem, Shift, Products, Measurement, CTA, Footer, PerformanceBridge, PerformancePage, App, Reveal });
