// app.jsx — Connect waitlist landing
// Single-file React/TS-style component, vanilla CSS classes for everything.

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

const STORAGE_KEY = 'connect_waitlist';
const LANG_KEY = 'connect_lang';

function useLang() {
  const [lang, setLangState] = useState(() => {
    try {
      const saved = localStorage.getItem(LANG_KEY);
      if (saved === 'en' || saved === 'zh') return saved;
    } catch (e) { /* ignore */ }
    return 'en';
  });
  const setLang = useCallback((next) => {
    setLangState(next);
    try { localStorage.setItem(LANG_KEY, next); } catch (e) { /* ignore */ }
    document.documentElement.lang = next === 'zh' ? 'zh-Hans' : 'en';
    document.documentElement.setAttribute('data-lang', next);
  }, []);
  useEffect(() => {
    document.documentElement.lang = lang === 'zh' ? 'zh-Hans' : 'en';
    document.documentElement.setAttribute('data-lang', lang);
  }, [lang]);
  return [lang, setLang];
}

function useScrollIn(rootMargin = '0px 0px -10% 0px') {
  const ref = useRef(null);
  const [seen, setSeen] = useState(false);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) { setSeen(true); io.disconnect(); }
      });
    }, { threshold: 0.12, rootMargin });
    io.observe(el);
    return () => io.disconnect();
  }, [rootMargin]);
  return [ref, seen];
}

function Reveal({ children, delay = 0, as: As = 'div', className = '', ...rest }) {
  const [ref, seen] = useScrollIn();
  return (
    <As
      ref={ref}
      className={`reveal ${seen ? 'reveal-in' : ''} ${className}`}
      style={{ transitionDelay: `${delay}ms` }}
      {...rest}
    >
      {children}
    </As>
  );
}

// ─── Logo (Connect mark) ──────────────────────────────────────────────────
// Two coral nodes connected by a line, with a yellow "memory" dot at the link.
function ConnectLogo({ size = 28 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 48 48" fill="none" aria-hidden="true">
      <circle cx="24" cy="24" r="22" fill="#15110E"></circle>
      <line x1="13" y1="32" x2="35" y2="16" stroke="#FBF7F0" strokeWidth="2" strokeLinecap="round"></line>
      <circle cx="13" cy="32" r="5" fill="#FF5C8A" stroke="#FBF7F0" strokeWidth="1.5"></circle>
      <circle cx="35" cy="16" r="5" fill="#FF5C8A" stroke="#FBF7F0" strokeWidth="1.5"></circle>
      <circle cx="24" cy="24" r="3" fill="#FFE34D"></circle>
    </svg>
  );
}

// ─── Nav ──────────────────────────────────────────────────────────────────
function Nav({ t, lang, setLang, onJoinClick }) {
  const [scrolled, setScrolled] = useState(false);
  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 32);
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  return (
    <nav className={`nav ${scrolled ? 'nav-scrolled' : ''}`}>
      <a href="#top" className="nav-brand" aria-label="Connect">
        <ConnectLogo size={26} />
        <span>connect</span>
      </a>
      <div className="nav-right">
        <button
          type="button"
          className="lang-toggle"
          onClick={() => setLang(lang === 'en' ? 'zh' : 'en')}
          aria-label={`Switch to ${t.lang_label}`}
        >
          <span className={lang === 'en' ? 'lang-on' : 'lang-off'}>EN</span>
          <span className="lang-sep">/</span>
          <span className={lang === 'zh' ? 'lang-on' : 'lang-off'}>中文</span>
        </button>
        <button type="button" className="btn btn-yellow btn-sm" onClick={onJoinClick}>
          {t.nav.join}
        </button>
      </div>
    </nav>
  );
}

// ─── Hero ─────────────────────────────────────────────────────────────────
function Hero({ t, lang }) {
  const [email, setEmail] = useState('');
  const [state, setState] = useState('idle'); // idle | loading | success | error
  const [errMsg, setErrMsg] = useState('');
  const inputRef = useRef(null);

  // Restore success state if user already joined
  useEffect(() => {
    try {
      const raw = localStorage.getItem(STORAGE_KEY);
      if (raw) {
        const parsed = JSON.parse(raw);
        if (parsed && parsed.email) {
          setEmail(parsed.email);
          setState('success');
        }
      }
    } catch (e) { /* ignore */ }
  }, []);

  const validate = (v) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v.trim());

  const onSubmit = (e) => {
    e.preventDefault();
    if (state === 'success') return;
    if (!validate(email)) {
      setState('error');
      setErrMsg(t.hero.error_email);
      return;
    }
    setState('loading');
    setTimeout(() => {
      try {
        localStorage.setItem(STORAGE_KEY, JSON.stringify({
          email: email.trim(),
          lang,
          ts: Date.now(),
        }));
      } catch (err) { /* ignore */ }
      setState('success');
    }, 600);
  };

  return (
    <section id="top" className="hero">
      <div className="hero-grid">
        <div className="hero-copy">
          <Reveal className="hero-eyebrow-wrap">
            <span className="eyebrow-pill">
              <span className="eyebrow-dot"></span>
              {t.hero.eyebrow}
            </span>
          </Reveal>

          <Reveal as="h1" className="hero-headline" delay={80}>
            {t.hero.headline_a}{' '}
            <span className="hero-underline-wrap">
              {t.hero.headline_b}
              <svg className="hero-underline" viewBox="0 0 200 12" preserveAspectRatio="none" aria-hidden="true">
                <path d="M2 8 C 40 2, 80 12, 120 6 C 160 0, 180 10, 198 4"
                      stroke="#FFE34D" strokeWidth="6" strokeLinecap="round" fill="none"></path>
              </svg>
            </span>
          </Reveal>

          <Reveal as="p" className="hero-sub" delay={160}>
            {t.hero.sub}
          </Reveal>

          <Reveal className="hero-form-wrap" delay={240}>
            <form className={`hero-form ${state === 'error' ? 'is-error' : ''} ${state === 'success' ? 'is-success' : ''}`} onSubmit={onSubmit} noValidate>
              <input
                ref={inputRef}
                type="email"
                inputMode="email"
                autoComplete="email"
                className="hero-input"
                placeholder={t.hero.email_placeholder}
                value={email}
                onChange={(e) => { setEmail(e.target.value); if (state === 'error') setState('idle'); }}
                disabled={state === 'success' || state === 'loading'}
                aria-label={t.hero.email_placeholder}
              />
              <button
                type="submit"
                className="btn btn-primary btn-form"
                disabled={state === 'loading' || state === 'success'}
              >
                {state === 'loading' ? t.hero.cta_loading
                  : state === 'success' ? '✓'
                  : t.hero.cta}
                {(state === 'idle' || state === 'error') && <span className="btn-arrow">→</span>}
              </button>
            </form>
            {state === 'error' && (
              <div className="hero-form-msg hero-form-err">{errMsg}</div>
            )}
            {state === 'success' && (
              <div className="hero-form-msg hero-form-ok">
                <strong>{t.hero.success_title}</strong>
                <span>{t.hero.success_sub}</span>
              </div>
            )}
          </Reveal>
        </div>

        <Reveal className="hero-visual" delay={120}>
          <HeroVisual t={t} />
        </Reveal>
      </div>
    </section>
  );
}

// Hero visual — the signature motif: a small live conversation that "becomes graph"
function HeroVisual({ t }) {
  return (
    <div className="hv">
      <div className="hv-card hv-chat">
        <div className="hv-chat-head">
          <span className="hv-chip">
            <span className="hv-chip-dot"></span>
            connect
          </span>
          <span className="hv-chat-time">now</span>
        </div>
        <div className="hv-bubble hv-bubble-user">
          Had lunch w/ Sasha at Bridgepoint. She intro'd me to Devon — he's the new CS lead. They're piloting Data Cloud.
        </div>
        <div className="hv-bubble hv-bubble-bot">
          Got it. Linked <em>Sasha Iyer</em> → <em>Devon Hart</em> as <strong>colleague</strong> at Bridgepoint, tagged Data&nbsp;Cloud pilot, surfaced <strong>3 warm paths</strong> to Devon through your network.
        </div>
        <div className="hv-composer">
          <span className="hv-composer-prompt">›</span>
          <span className="hv-composer-text">tell connect…</span>
          <span className="hv-cursor"></span>
        </div>
      </div>

      <div className="hv-card hv-graphlet" aria-hidden="true">
        <div className="hv-graphlet-label">graph · just now</div>
        <svg viewBox="0 0 220 140" width="100%" height="100%">
          <line x1="40"  y1="100" x2="110" y2="60" stroke="#15110E" strokeWidth="2"></line>
          <line x1="110" y1="60"  x2="180" y2="100" stroke="#FF5C8A" strokeWidth="2" strokeDasharray="4 4"></line>
          <line x1="40"  y1="100" x2="180" y2="100" stroke="#15110E" strokeWidth="1.5" opacity="0.35"></line>
          <circle cx="40"  cy="100" r="14" fill="#15110E"></circle>
          <text x="40" y="103" textAnchor="middle" fontFamily="'Space Grotesk', sans-serif" fontWeight="700" fontSize="9" fill="#FBF7F0">YOU</text>
          <circle cx="110" cy="60"  r="11" fill="#FF5C8A" stroke="#15110E" strokeWidth="1.5"></circle>
          <circle cx="180" cy="100" r="11" fill="#FF5C8A" stroke="#15110E" strokeWidth="1.5"></circle>
          <text x="110" y="44" textAnchor="middle" fontFamily="'Space Grotesk', sans-serif" fontWeight="600" fontSize="10" fill="#15110E">Sasha</text>
          <text x="180" y="124" textAnchor="middle" fontFamily="'Space Grotesk', sans-serif" fontWeight="600" fontSize="10" fill="#15110E">Devon</text>
        </svg>
      </div>

      {/* sticker arrow from chat to graph */}
      <svg className="hv-arrow" viewBox="0 0 80 60" aria-hidden="true">
        <path d="M8 12 C 30 8, 55 18, 68 38 M 68 38 L 60 28 M 68 38 L 56 40"
              stroke="#15110E" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" fill="none"></path>
      </svg>
    </div>
  );
}

// ─── Problem ──────────────────────────────────────────────────────────────
function Problem({ t }) {
  return (
    <section className="section section-problem">
      <Reveal className="section-head">
        <div className="eyebrow">{t.problem.eyebrow}</div>
        <h2 className="section-title">{t.problem.title}</h2>
      </Reveal>

      <div className="problem-grid">
        {t.problem.cards.map((c, i) => (
          <Reveal key={i} className="problem-card" delay={i * 90}>
            <div className="problem-num">0{i + 1}</div>
            <h3 className="problem-title">{c.title}</h3>
            <p className="problem-body">{c.body}</p>
            <ProblemGlyph idx={i} />
          </Reveal>
        ))}
      </div>
    </section>
  );
}

function ProblemGlyph({ idx }) {
  if (idx === 0) {
    // CRM form being abandoned
    return (
      <svg className="problem-glyph" viewBox="0 0 120 80" aria-hidden="true">
        <rect x="6" y="8" width="108" height="64" rx="8" fill="none" stroke="#15110E" strokeWidth="1.5"></rect>
        <rect x="16" y="20" width="60" height="6" rx="2" fill="#BDB7B1"></rect>
        <rect x="16" y="32" width="88" height="6" rx="2" fill="#BDB7B1"></rect>
        <rect x="16" y="44" width="44" height="6" rx="2" fill="#BDB7B1"></rect>
        <rect x="16" y="56" width="72" height="6" rx="2" fill="#BDB7B1"></rect>
        <line x1="2" y1="2" x2="118" y2="78" stroke="#FF5C8A" strokeWidth="3" strokeLinecap="round"></line>
        <line x1="118" y1="2" x2="2" y2="78" stroke="#FF5C8A" strokeWidth="3" strokeLinecap="round"></line>
      </svg>
    );
  }
  if (idx === 1) {
    // person walking out with cloud/memory
    return (
      <svg className="problem-glyph" viewBox="0 0 120 80" aria-hidden="true">
        <rect x="6" y="8" width="108" height="64" rx="8" fill="none" stroke="#15110E" strokeWidth="1.5"></rect>
        <circle cx="32" cy="34" r="8" fill="#15110E"></circle>
        <path d="M20 64 C 22 50, 42 50, 44 64 Z" fill="#15110E"></path>
        <path d="M58 38 L 96 38" stroke="#15110E" strokeWidth="1.5" strokeDasharray="3 3"></path>
        <path d="M88 32 L 96 38 L 88 44" stroke="#15110E" strokeWidth="1.5" fill="none" strokeLinecap="round" strokeLinejoin="round"></path>
        <ellipse cx="78" cy="60" rx="20" ry="8" fill="#FFE34D" stroke="#15110E" strokeWidth="1.5"></ellipse>
        <text x="78" y="64" textAnchor="middle" fontFamily="'JetBrains Mono', monospace" fontSize="8" fill="#15110E">memory</text>
      </svg>
    );
  }
  // who-knows-who, hidden path
  return (
    <svg className="problem-glyph" viewBox="0 0 120 80" aria-hidden="true">
      <circle cx="14" cy="40" r="7" fill="#15110E"></circle>
      <circle cx="106" cy="40" r="7" fill="#FF5C8A" stroke="#15110E" strokeWidth="1.5"></circle>
      <circle cx="44" cy="20" r="5" fill="#FBF7F0" stroke="#15110E" strokeWidth="1.5"></circle>
      <circle cx="60" cy="56" r="5" fill="#FBF7F0" stroke="#15110E" strokeWidth="1.5"></circle>
      <circle cx="80" cy="24" r="5" fill="#FBF7F0" stroke="#15110E" strokeWidth="1.5"></circle>
      <line x1="14" y1="40" x2="44" y2="20" stroke="#15110E" strokeWidth="1.2" opacity="0.3" strokeDasharray="2 3"></line>
      <line x1="44" y1="20" x2="80" y2="24" stroke="#15110E" strokeWidth="1.2" opacity="0.3" strokeDasharray="2 3"></line>
      <line x1="80" y1="24" x2="106" y2="40" stroke="#15110E" strokeWidth="1.2" opacity="0.3" strokeDasharray="2 3"></line>
      <line x1="14" y1="40" x2="60" y2="56" stroke="#15110E" strokeWidth="1.2" opacity="0.3" strokeDasharray="2 3"></line>
      <line x1="60" y1="56" x2="106" y2="40" stroke="#15110E" strokeWidth="1.2" opacity="0.3" strokeDasharray="2 3"></line>
      <path d="M14 40 Q 60 8, 106 40" stroke="#FFE34D" strokeWidth="3" strokeLinecap="round" fill="none"></path>
    </svg>
  );
}

// ─── How it works ────────────────────────────────────────────────────────
function How({ t }) {
  return (
    <section className="section section-how">
      <Reveal className="section-head">
        <div className="eyebrow">{t.how.eyebrow}</div>
        <h2 className="section-title">{t.how.title}</h2>
      </Reveal>

      <div className="how-grid">
        {t.how.steps.map((s, i) => (
          <Reveal key={i} className="how-step" delay={i * 100}>
            <div className="how-num">{s.num}</div>
            <div className="how-visual">
              <HowGlyph idx={i} t={t} />
            </div>
            <h3 className="how-step-title">{s.title}</h3>
            <p className="how-step-body">{s.body}</p>
          </Reveal>
        ))}
      </div>
    </section>
  );
}

function HowGlyph({ idx, t }) {
  const v = (t && t.how && t.how.visual) || {
    vpc: 'Your VPC', sales: 'Sales Agent', research: 'Research Bot',
    llm: 'Internal LLM', mcp: 'MCP', connect: 'Connect',
  };
  if (idx === 0) {
    // Chat with Connect — short bubbles, generous padding
    return (
      <svg viewBox="0 0 280 130" aria-hidden="true" preserveAspectRatio="xMidYMid meet">
        <rect x="6" y="14" width="220" height="36" rx="18" fill="#FBF7F0" stroke="#15110E" strokeWidth="1.5"></rect>
        <text x="20" y="37" fontFamily="'Inter', sans-serif" fontSize="11" fill="#15110E">Met Maya — she's CRO at Acme now.</text>
        <rect x="54" y="66" width="220" height="50" rx="14" fill="#FF5C8A" stroke="#15110E" strokeWidth="1.5"></rect>
        <text x="68" y="86" fontFamily="'Inter', sans-serif" fontSize="11" fill="#FFFFFF">Linked Maya Chen → Acme,</text>
        <text x="68" y="103" fontFamily="'Inter', sans-serif" fontSize="11" fill="#FFFFFF">role: CRO. Last seen: today.</text>
      </svg>
    );
  }
  if (idx === 1) {
    return (
      <svg viewBox="0 0 280 130" aria-hidden="true" preserveAspectRatio="xMidYMid meet">
        <line x1="60" y1="100" x2="140" y2="48" stroke="#15110E" strokeWidth="1.5"></line>
        <line x1="140" y1="48" x2="220" y2="92" stroke="#FF5C8A" strokeWidth="1.5" strokeDasharray="4 3"></line>
        <line x1="60" y1="100" x2="220" y2="92" stroke="#15110E" strokeWidth="1" opacity="0.4"></line>
        <line x1="140" y1="48" x2="86" y2="22" stroke="#15110E" strokeWidth="1" opacity="0.4"></line>
        <circle cx="60" cy="100" r="13" fill="#15110E"></circle>
        <circle cx="140" cy="48" r="11" fill="#FFE34D" stroke="#15110E" strokeWidth="1.5"></circle>
        <circle cx="220" cy="92" r="11" fill="#FF5C8A" stroke="#15110E" strokeWidth="1.5"></circle>
        <circle cx="86" cy="22" r="8" fill="#E8E0FF" stroke="#15110E" strokeWidth="1.5"></circle>
        <circle cx="248" cy="34" r="6" fill="#FBF7F0" stroke="#15110E" strokeWidth="1.2" opacity="0.5"></circle>
        <line x1="220" y1="92" x2="248" y2="34" stroke="#15110E" strokeWidth="1" opacity="0.3" strokeDasharray="2 3"></line>
      </svg>
    );
  }
  return (
    <svg viewBox="0 0 280 140" aria-hidden="true" preserveAspectRatio="xMidYMid meet">
      <defs>
        <radialGradient id="how-vpc-halo" cx="0.5" cy="0.5" r="0.5">
          <stop offset="0%" stopColor="#FFE34D" stopOpacity="0.42"></stop>
          <stop offset="100%" stopColor="#FFE34D" stopOpacity="0"></stop>
        </radialGradient>
      </defs>

      {/* Soft yellow halo behind Connect — same channel-halo treatment as graph preview */}
      <ellipse cx="206" cy="70" rx="76" ry="58" fill="url(#how-vpc-halo)"></ellipse>

      {/* VPC boundary — vertical divider with eyebrow tag at the top, NOT a closed box */}
      <line x1="146" y1="14" x2="146" y2="126" stroke="#15110E" strokeWidth="1" strokeDasharray="3 4" opacity="0.55"></line>
      <text x="146" y="13"
            fontFamily="'JetBrains Mono', monospace" fontSize="9"
            fill="#5C5550" letterSpacing="0.12em" fontWeight="600">{v.vpc.toUpperCase()}</text>

      {/* Three short MCP edges — each agent → Connect, no crossing of labels */}
      <line x1="36"  y1="42" x2="186" y2="64" stroke="#FF5C8A" strokeWidth="1.5" strokeDasharray="4 4" strokeLinecap="round" className="mcp-edge mcp-edge-1"></line>
      <line x1="30"  y1="78" x2="184" y2="70" stroke="#FF5C8A" strokeWidth="1.5" strokeDasharray="4 4" strokeLinecap="round" className="mcp-edge mcp-edge-2"></line>
      <line x1="36"  y1="114" x2="186" y2="76" stroke="#FF5C8A" strokeWidth="1.5" strokeDasharray="4 4" strokeLinecap="round" className="mcp-edge mcp-edge-3"></line>

      {/* MCP pill — sits at the boundary line, not in mid-edge whitespace */}
      <rect x="130" y="62" width="32" height="16" rx="8"
            fill="#15110E" stroke="#15110E" strokeWidth="1"></rect>
      <text x="146" y="73" textAnchor="middle"
            fontFamily="'JetBrains Mono', monospace"
            fontSize="9" fill="#FFE34D" fontWeight="600" letterSpacing="0.06em">{v.mcp}</text>

      {/* Connect node — coral ring + ink fill, matches the graph's "you" node visual weight */}
      <circle cx="206" cy="70" r="24" fill="#15110E" opacity="0.95" transform="translate(2 2)"></circle>
      <circle cx="206" cy="70" r="24" fill="#15110E" stroke="#FF5C8A" strokeWidth="2"></circle>
      <text x="206" y="74" textAnchor="middle"
            fontFamily="'Space Grotesk', system-ui, sans-serif"
            fontWeight="700" fontSize="11" fill="#FBF7F0"
            letterSpacing="-0.01em">{v.connect}</text>

      {/* External agent nodes — lavender, with tiny dot glyphs to differentiate from blanks */}
      <g>
        <circle cx="20" cy="42" r="10" fill="#E8E0FF" stroke="#15110E" strokeWidth="1.5"></circle>
        <circle cx="20" cy="42" r="3" fill="#15110E"></circle>
      </g>
      <g>
        <circle cx="14" cy="78" r="10" fill="#E8E0FF" stroke="#15110E" strokeWidth="1.5"></circle>
        <circle cx="14" cy="78" r="3" fill="#15110E"></circle>
      </g>
      <g>
        <circle cx="20" cy="114" r="10" fill="#E8E0FF" stroke="#15110E" strokeWidth="1.5"></circle>
        <circle cx="20" cy="114" r="3" fill="#15110E"></circle>
      </g>

      {/* Agent captions — sit to the right of each node, vertically centered, never crossing edges */}
      <text x="36" y="46" fontFamily="'Space Grotesk', sans-serif" fontWeight="600" fontSize="11" fill="#15110E">{v.sales}</text>
      <text x="30" y="82" fontFamily="'Space Grotesk', sans-serif" fontWeight="600" fontSize="11" fill="#15110E">{v.research}</text>
      <text x="36" y="118" fontFamily="'Space Grotesk', sans-serif" fontWeight="600" fontSize="11" fill="#15110E">{v.llm}</text>
    </svg>
  );
}

// ─── Pricing ──────────────────────────────────────────────────────────────
function Pricing({ t }) {
  return (
    <section className="section section-pricing">
      <Reveal className="pricing-card">
        <div className="pricing-eyebrow">
          <span className="eyebrow-dot eyebrow-dot-mint"></span>
          <span className="eyebrow">{t.pricing.eyebrow}</span>
        </div>
        <h2 className="pricing-title">{t.pricing.title}</h2>
        <p className="pricing-sub">{t.pricing.sub}</p>
        <a className="btn btn-primary btn-lg" href="mailto:hello@g2gsolutions.ca">
          {t.pricing.cta} <span className="btn-arrow">→</span>
        </a>
      </Reveal>
    </section>
  );
}

// ─── Footer ───────────────────────────────────────────────────────────────
function Footer({ t, lang, setLang }) {
  return (
    <footer className="footer">
      <div className="footer-grid">
        <div className="footer-brand-col">
          <div className="footer-brand">
            <ConnectLogo size={26} />
            <span>connect</span>
          </div>
          <p className="footer-tag">{t.footer.tag}</p>
        </div>
        <div className="footer-meta">
          <a href="mailto:hello@g2gsolutions.ca" className="footer-contact">
            {t.footer.contact}
          </a>
          <button
            type="button"
            className="lang-toggle"
            onClick={() => setLang(lang === 'en' ? 'zh' : 'en')}
          >
            <span className={lang === 'en' ? 'lang-on' : 'lang-off'}>EN</span>
            <span className="lang-sep">/</span>
            <span className={lang === 'zh' ? 'lang-on' : 'lang-off'}>中文</span>
          </button>
        </div>
      </div>
      <div className="footer-rule"></div>
      <div className="footer-bottom">
        <span>{t.footer.rights}</span>
        <span className="footer-status">
          <span className="footer-status-dot"></span>
          private beta
        </span>
      </div>
    </footer>
  );
}

// ─── App ──────────────────────────────────────────────────────────────────
function App() {
  const [lang, setLang] = useLang();
  const t = window.I18N[lang];

  const onJoinClick = () => {
    const form = document.querySelector('.hero-form');
    const input = document.querySelector('.hero-input');
    const submit = document.querySelector('.hero-form .btn-primary');
    if (form) {
      form.scrollIntoView({ behavior: 'smooth', block: 'center' });
      setTimeout(() => {
        form.classList.remove('hero-form-flash');
        void form.offsetWidth;
        form.classList.add('hero-form-flash');
        if (submit) {
          submit.classList.remove('btn-pulse');
          void submit.offsetWidth;
          submit.classList.add('btn-pulse');
        }
        if (input) input.focus({ preventScroll: true });
      }, 420);
    }
  };

  return (
    <div className={`app lang-${lang}`}>
      <Nav t={t} lang={lang} setLang={setLang} onJoinClick={onJoinClick} />
      <main>
        <Hero t={t} lang={lang} />
        <Problem t={t} />
        <How t={t} />
        <section className="section section-graph">
          <Reveal className="section-head section-head-center">
            <div className="eyebrow">{t.preview.eyebrow}</div>
            <h2 className="section-title">{t.preview.title}</h2>
            <p className="section-sub">{t.preview.sub}</p>
          </Reveal>
          <Reveal delay={120}>
            <GraphPreview t={t} />
          </Reveal>
        </section>
        <Pricing t={t} />
      </main>
      <Footer t={t} lang={lang} setLang={setLang} />
    </div>
  );
}

window.App = App;
