/* ---- Hero word-stagger + typewriter ---- */
function HeroH1() {
  const ref = React.useRef(null);
  const [phase, setPhase] = React.useState(0); // 0=hidden, 1=words-in, 2=typewriter-done
  const [typed, setTyped] = React.useState("");
  const target = "через AI";

  React.useEffect(() => {
    // Start immediately (hero is above fold)
    const t1 = setTimeout(() => setPhase(1), 120);
    return () => clearTimeout(t1);
  }, []);

  // After words land, start typewriter on "через AI"
  React.useEffect(() => {
    if (phase < 1) return;
    // Estimate when last word lands: ~6 words * 80ms stagger + 600ms anim ≈ 1080ms
    const t = setTimeout(() => {
      let i = 0;
      const tick = setInterval(() => {
        i++;
        setTyped(target.slice(0, i));
        if (i >= target.length) { clearInterval(tick); setPhase(2); }
      }, 72);
      return () => clearInterval(tick);
    }, 1100);
    return () => clearTimeout(t);
  }, [phase]);

  const words = ["Автоматизируйте", "рутину", "1С"];
  return (
    <h1 ref={ref} style={{ marginTop: 20, maxWidth: 920, textShadow: "0 2px 40px rgba(8,8,10,0.9), 0 0 80px rgba(8,8,10,0.7)" }}>
      {words.map((w, i) => (
        <React.Fragment key={i}>
          <span
            className={"h1-word" + (phase >= 1 ? " in" : "")}
            style={{ transitionDelay: `${i * 80}ms` }}
          >{w}</span>
          {" "}
        </React.Fragment>
      ))}
      <span
        className={"h1-word serif" + (phase >= 1 ? " in" : "")}
        style={{ transitionDelay: "240ms", color: "var(--accent)" }}
      >
        {typed || "\u00a0"}
        {phase < 2 && <span className="tw-cursor" />}
      </span>
      {typed === target && phase >= 1 && (
        <span className="serif" style={{ color: "var(--accent)" }}>-агента.</span>
      )}
      {(typed !== target || phase < 1) && (
        <span style={{ opacity: 0 }}>-агента.</span>
      )}
    </h1>
  );
}
function TopNav() {
  const [scrolled, setScrolled] = React.useState(false);
  React.useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 12);
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  return (
    <header style={{
      position: "fixed", top: 0, left: 0, right: 0, zIndex: 50,
      transition: "all .3s ease",
      backdropFilter: scrolled ? "blur(18px)" : "blur(0)",
      WebkitBackdropFilter: scrolled ? "blur(18px)" : "blur(0)",
      background: scrolled ? "rgba(8,8,10,0.7)" : "transparent",
      borderBottom: "1px solid " + (scrolled ? "var(--line)" : "transparent")
    }}>
      <div className="container" style={{ display: "flex", alignItems: "center", justifyContent: "space-between", height: 68 }}>
        <Logo />
        <nav style={{ display: "flex", alignItems: "center", gap: 28 }} className="nav-links">
          {["Возможности", "Как работает", "Тарифы", "Безопасность", "FAQ"].map((l) =>
          <a key={l} href={`#${l}`} style={{ fontSize: 13.5, color: "var(--fg-dim)", letterSpacing: "-0.005em" }}
          onMouseEnter={(e) => e.currentTarget.style.color = "var(--fg)"}
          onMouseLeave={(e) => e.currentTarget.style.color = "var(--fg-dim)"}>{l}</a>
          )}
        </nav>
        <div style={{ display: "flex", gap: 10 }}>
          <a href="#cta" className="pill" style={{ height: 38, fontSize: 13, whiteSpace: "nowrap" }}>Войти</a>
          <a href="#cta" className="pill pill-primary" style={{ height: 38, fontSize: 13, whiteSpace: "nowrap" }}>
            Демо <IconArrow size={14} />
          </a>
        </div>
      </div>
      <style>{`
        @media (max-width: 900px) {
          .nav-links { display: none !important; }
        }
      `}</style>
    </header>);

}

/* =================================================================
   Hero
================================================================= */
function Hero() {
  return (
    <section style={{ position: "relative", paddingTop: 80, paddingBottom: 60, overflow: "hidden" }}>
      {/* Subtle drifting starfield */}
      <div className="stars-layer" />

      {/* Orbs */}
      <div className="orb" style={{ width: 620, height: 620, left: "-180px", top: "-120px", background: "radial-gradient(circle, rgba(122,245,200,0.55), transparent 60%)" }} />
      <div className="orb" style={{ width: 520, height: 520, right: "-140px", top: "180px", background: "radial-gradient(circle, rgba(139,111,255,0.45), transparent 60%)", animationDelay: "-3s" }} />

      <div className="container" style={{ position: "relative" }}>
        {/* Overlapping layout: text on top, mockup behind right */}
        <div style={{ position: "relative", minHeight: 580 }} className="hero-grid">

          {/* Text — always first in DOM, foreground on desktop */}
          <div style={{ position: "relative", zIndex: 2 }}>
            <Reveal>
              <span className="pill-tag" style={{ whiteSpace: "nowrap", marginTop: 0 }}><span className="dot" /> AI · 1С · Telegram</span>
            </Reveal>

            <Reveal delay={80}>
              <HeroH1 />
            </Reveal>

            <Reveal delay={160}>
              <p style={{ marginTop: 20, maxWidth: 620, fontSize: 18, color: "var(--fg-dim)" }}>
                Платежи, ЭСФ, УПД-сверка, начисление ЗП и отчётность — закрываются агентом из Telegram и веб-кабинета. SaaS или On-Premise в вашем периметре.
              </p>
            </Reveal>

            <Reveal delay={240}>
              <div style={{ marginTop: 28, display: "flex", flexWrap: "wrap", gap: 12 }}>
                <Magnetic><a href="#cta" className="pill pill-primary" style={{ whiteSpace: "nowrap" }}>Попробовать SaaS <IconArrow size={14} /></a></Magnetic>
                <Magnetic strength={5}><a href="#cta" className="pill" style={{ whiteSpace: "nowrap" }}>On-Premise demo</a></Magnetic>
              </div>
            </Reveal>

            <Reveal delay={320}>
              <div style={{ marginTop: 22, display: "flex", alignItems: "center", gap: 14, fontSize: 13, color: "var(--fg-mute)", flexWrap: "wrap" }}>
                <div style={{ display: "flex", flexShrink: 0 }}>
                  {[0, 1, 2, 3].map((i) =>
                  <span key={i} style={{
                    width: 22, height: 22, borderRadius: 50,
                    background: ["#1f2a26", "#2a2336", "#1f2630", "#262019"][i],
                    border: "1.5px solid var(--bg)",
                    marginLeft: i ? -7 : 0
                  }} />
                  )}
                </div>
                <span style={{ whiteSpace: "nowrap" }}>Уже используют <span style={{ color: "var(--fg)" }}><CountUp to={50} duration={1200} suffix="+" /></span> компаний в Казахстане</span>
              </div>
            </Reveal>
          </div>

          {/* Mockup — behind on desktop (absolute), below on mobile */}
          <Reveal delay={300} className="hero-mock-wrap">
            <div style={{ position: "relative", width: "100%" }}>
              <div className="orb" style={{ width: 360, height: 360, right: "10%", top: "10%", background: "radial-gradient(circle, rgba(168,245,208,0.18), transparent 60%)", animationDelay: "-5s" }} />
              {/* Gradient fade on the left so hero text stays readable */}
              <div style={{
                position: "absolute", inset: 0, zIndex: 3,
                background: "linear-gradient(to right, var(--bg) 0%, rgba(8,8,10,0.85) 22%, rgba(8,8,10,0.3) 45%, transparent 65%)",
                borderRadius: 18,
                pointerEvents: "none"
              }} />
              <HeroMockup />
            </div>
          </Reveal>

        </div>
      </div>

      <style>{`
        @media (min-width: 900px) {
          .hero-grid { min-height: 580px; }
          .hero-mock-wrap {
            position: absolute !important;
            right: -240px;
            top: 60px;
            width: 74% !important;
            z-index: 1;
          }
          .hero-mock-wrap.in {
            opacity: 0.82 !important;
            transform: none !important;
          }
          .hero-mock-wrap:not(.in) {
            opacity: 0 !important;
            transform: translateY(20px) !important;
          }
        }
        @media (max-width: 899px) {
          .hero-mock-wrap { margin-top: 40px; }
        }
      `}</style>
    </section>);

}

/* =================================================================
   Marquee
================================================================= */
function Marquee() {
  return (
    <section style={{ padding: "8px 0 56px" }}>
      <div className="container" style={{ marginBottom: 22 }}>
        <div className="eyebrow" style={{ justifyContent: "center", display: "flex" }}>Нам доверяют учёт</div>
      </div>
      <LogoMarquee />
    </section>);

}

/* =================================================================
   Bento — Возможности
================================================================= */
function Bento() {
  return (
    <section id="Возможности" className="section-pad" style={{ position: "relative" }}>
      <div className="container">
        <div style={{ display: "grid", gridTemplateColumns: "1fr", gap: 16, marginBottom: 14 }} className="bento-head">
          <Reveal>
            <span className="eyebrow">/ возможности</span>
            <h2 style={{ marginTop: 14, maxWidth: 760 }}>
              Шесть рутин, которые <span className="serif" style={{ color: "var(--accent)" }}>агент закрывает</span> за вас
            </h2>
          </Reveal>
          <Reveal delay={120}>
            <p style={{ maxWidth: 560 }}>
              Каждый модуль работает автономно. Можно подключить один — остальные включить позже из кабинета.
            </p>
          </Reveal>
        </div>

        <div className="bento-grid" style={{ textAlign: "center", padding: "0px" }}>
          <BentoCard area="a" title="Банковские выписки" Icon={IconBank} desc="Распознавание контрагента по БИН/ИИН, авто-проводка ПКО/РКО, привязка к договору и акту.">
            <BankViz />
          </BentoCard>

          <BentoCard area="b" title="ЭСФ" Icon={IconReceipt} desc="Загрузка и выписка электронных счетов-фактур через ИС ЭСФ. Автоматическая сверка с поступлениями.">
            <EsfViz />
          </BentoCard>

          <BentoCard area="c" title="УПД-сверка" Icon={IconLayers} desc="Сравнение актов с поставщиками построчно. Подсветка расхождений, автоматический акт сверки.">
            <UpdViz />
          </BentoCard>

          <BentoCard area="d" title="Начисление ЗП" Icon={IconUsers} desc="Расчёт ЗП с учётом ОПВ, ВОСМС, ИПН. Уведомления сотрудникам в Telegram, расчётные листки в PDF.">
            <PayrollViz />
          </BentoCard>

          <BentoCard area="e" title="AI Telegram-агент" Icon={IconTelegram} desc="Бот в чате компании: спросите остаток, проведите оплату, выгрузите отчёт — голосом или текстом.">
            <BotViz />
          </BentoCard>

          <BentoCard area="f" title="Отчётность" Icon={IconChart} desc="Налоговые формы 100, 200, 300, 910, 328 — заполняются на основании учётных данных. Контроль сроков сдачи.">
            <ReportViz />
          </BentoCard>
        </div>
      </div>

      <style>{`
        .bento-grid {
          display: grid;
          grid-template-columns: 1fr;
          grid-template-areas: "a" "b" "c" "d" "e" "f";
          gap: 14px;
          margin-left: -10px;
          margin-right: -10px;
        }
        @media (min-width: 768px) {
          .bento-grid {
            margin-left: -26px;
            margin-right: -26px;
          }
        }
        @media (min-width: 720px) {
          .bento-grid { grid-template-columns: repeat(2, 1fr); grid-template-areas: "a b" "c d" "e f"; }
        }
        @media (min-width: 1024px) {
          .bento-grid {
            grid-template-columns: repeat(6, 1fr);
            grid-template-areas:
              "a a a b b b"
              "c c d d e e"
              "f f f f e e";
          }
        }
      `}</style>
    </section>);

}

function BentoCard({ area, title, desc, Icon, children }) {
  return (
    <Reveal as="article" className="glass grad-border glass-hover" style={{ gridArea: area, padding: 22, display: "flex", flexDirection: "column", gap: 14, minHeight: 240 }}>
      <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
        <span style={{ width: 32, height: 32, borderRadius: 10, border: "1px solid var(--line)", display: "grid", placeItems: "center", color: "var(--accent)", background: "rgba(168,245,208,0.04)" }}>
          <Icon size={16} />
        </span>
        <h3 style={{ fontSize: 18 }}>{title}</h3>
      </div>
      <p style={{ fontSize: 14, color: "var(--fg-dim)" }}>{desc}</p>
      <div style={{ marginTop: "auto", paddingTop: 8 }}>{children}</div>
    </Reveal>);

}

/* ---- Bento mini-visualizations ---- */

/* Shared hook: fires once when element enters viewport */
function useVisible(delay = 0) {
  const ref = React.useRef(null);
  const [visible, setVisible] = React.useState(false);
  React.useEffect(() => {
    const el = ref.current; if (!el) return;
    const t = setTimeout(() => {
      const io = new IntersectionObserver(([e]) => {
        if (e.isIntersecting) { setVisible(true); io.disconnect(); }
      }, { threshold: 0.3 });
      io.observe(el);
      return () => io.disconnect();
    }, delay);
    return () => clearTimeout(t);
  }, [delay]);
  return [ref, visible];
}

/* Animated number that counts from 0 */
function AnimNum({ value, delay = 0, suffix = "" }) {
  const [ref, vis] = useVisible(delay);
  const [n, setN] = React.useState(0);
  React.useEffect(() => {
    if (!vis) return;
    const raw = parseInt(String(value).replace(/\s/g, "").replace(/[^\d]/g, ""), 10);
    if (!raw) return;
    const dur = 1200, t0 = performance.now();
    let raf;
    const tick = (t) => {
      const p = Math.min(1, (t - t0) / dur);
      const eased = 1 - Math.pow(1 - p, 3);
      setN(Math.round(raw * eased));
      if (p < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [vis, value]);
  const fmt = n.toLocaleString("ru-RU");
  return <span ref={ref} className="mono counter-num">{fmt}{suffix}</span>;
}

function BankViz() {
  const rows = [
    { n: "ТОО Ромашка",    a: "+1 248 500", ok: true },
    { n: "ИП Алматинский", a: "+ 84 200",   ok: true },
    { n: "АО ЦентрФинанс", a: "+ 2 410 000",ok: true },
  ];
  const [ref, vis] = useVisible();
  return (
    <div ref={ref} style={{ display: "flex", flexDirection: "column", gap: 6 }}>
      {rows.map((r, i) => (
        <div key={i} style={{
          display: "flex", justifyContent: "space-between",
          padding: "6px 10px", border: "1px solid var(--line)", borderRadius: 8, fontSize: 12,
          opacity: vis ? 1 : 0,
          transform: vis ? "none" : "translateY(8px)",
          transition: `opacity .5s ease ${i * 130}ms, transform .5s ease ${i * 130}ms`,
        }}>
          <span style={{ display: "flex", alignItems: "center", gap: 7 }}>
            <span style={{
              width: 16, height: 16, borderRadius: 4,
              background: vis ? "rgba(168,245,208,0.18)" : "var(--line)",
              display: "grid", placeItems: "center",
              transition: `background .4s ease ${i * 130 + 300}ms`,
            }}>
              <IconCheck size={9} color="var(--accent)" />
            </span>
            {r.n}
          </span>
          <span className="mono" style={{ color: "var(--accent)" }}>{r.a} ₸</span>
        </div>
      ))}
    </div>
  );
}

function EsfViz() {
  const rows = [
    { id: "ESF-2026-04-1248", st: "проведён",  done: true  },
    { id: "ESF-2026-04-1249", st: "обработка", done: false },
    { id: "ESF-2026-04-1250", st: "проведён",  done: true  },
  ];
  const [ref, vis] = useVisible();
  const [active, setActive] = React.useState(1); // middle row animates
  React.useEffect(() => {
    if (!vis) return;
    const t = setTimeout(() => setActive(null), 2200);
    return () => clearTimeout(t);
  }, [vis]);
  return (
    <div ref={ref} style={{ display: "flex", flexDirection: "column", gap: 6, fontSize: 11 }} className="mono">
      {rows.map((r, i) => {
        const processing = active === i;
        const done = active === null ? true : r.done;
        return (
          <div key={r.id} style={{
            display: "flex", justifyContent: "space-between", alignItems: "center",
            gap: 12, color: "var(--fg-dim)",
            opacity: vis ? 1 : 0,
            transition: `opacity .45s ease ${i * 100}ms`,
          }}>
            <span style={{ whiteSpace: "nowrap" }}>{r.id}</span>
            <span style={{
              color: processing ? "var(--violet)" : done ? "var(--accent)" : "var(--fg-mute)",
              whiteSpace: "nowrap", flexShrink: 0,
              transition: "color .4s ease",
            }}>
              {processing ? "⟳ " : "● "}
              {processing ? "обработка" : (done ? "проведён" : r.st)}
            </span>
          </div>
        );
      })}
    </div>
  );
}

function UpdViz() {
  const [ref, vis] = useVisible();
  const [matched, setMatched] = React.useState(false);
  React.useEffect(() => {
    if (!vis) return;
    const t = setTimeout(() => setMatched(true), 900);
    return () => clearTimeout(t);
  }, [vis]);
  return (
    <div ref={ref} style={{ display: "flex", flexDirection: "column", gap: 8, fontSize: 11 }}>
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }}>
        {[{ label: "НАШ АКТ" }, { label: "ПОСТАВЩИК" }].map((side, i) => (
          <div key={i} style={{
            padding: 10, borderRadius: 8,
            border: `1px solid ${matched ? "rgba(168,245,208,0.35)" : "var(--line)"}`,
            transition: "border-color .5s ease",
          }}>
            <div className="mono" style={{ color: "var(--fg-mute)", fontSize: 10, marginBottom: 6 }}>{side.label}</div>
            <div style={{ opacity: vis ? 1 : 0, transition: `opacity .4s ease ${i * 150}ms` }}>4 позиции</div>
            <div style={{
              color: matched ? "var(--accent)" : "var(--fg-dim)",
              transition: "color .5s ease .4s",
            }} className="mono">
              <AnimNum value={412800} delay={200} /> ₸
            </div>
          </div>
        ))}
      </div>
      <div style={{
        display: "flex", alignItems: "center", justifyContent: "center", gap: 6,
        fontSize: 10, padding: "6px 0",
        opacity: matched ? 1 : 0,
        transform: matched ? "none" : "translateY(4px)",
        transition: "opacity .4s ease .6s, transform .4s ease .6s",
        color: "var(--accent)",
      }}>
        <IconCheck size={11} color="var(--accent)" />
        <span className="mono">Расхождений нет · 100%</span>
      </div>
    </div>
  );
}

function PayrollViz() {
  const bars = [
    { label: "ОПВ 10%",   pct: 78 },
    { label: "ВОСМС 2%",  pct: 22 },
    { label: "ИПН 10%",   pct: 60 },
  ];
  const [ref, vis] = useVisible();
  return (
    <div ref={ref} style={{ display: "flex", flexDirection: "column", gap: 7, fontSize: 11 }}>
      {bars.map((b, i) => (
        <div key={b.label} style={{ display: "flex", alignItems: "center", gap: 10 }}>
          <span style={{ width: 70, color: "var(--fg-dim)", flexShrink: 0 }}>{b.label}</span>
          <span style={{ flex: 1, height: 4, background: "var(--line)", borderRadius: 2, overflow: "hidden" }}>
            <span style={{
              display: "block", height: "100%",
              width: vis ? b.pct + "%" : "0%",
              background: "linear-gradient(90deg, var(--accent-2), var(--accent))",
              borderRadius: 2,
              transition: `width .8s cubic-bezier(.2,.7,.2,1) ${i * 120 + 100}ms`,
              boxShadow: vis ? "0 0 6px rgba(168,245,208,0.5)" : "none",
            }} />
          </span>
          <span className="mono" style={{ fontSize: 10, color: "var(--fg-mute)", width: 28, textAlign: "right" }}>{b.pct}%</span>
        </div>
      ))}
    </div>
  );
}

function BotViz() {
  const [ref, vis] = useVisible();
  const [showTyping, setShowTyping] = React.useState(false);
  const [showReply, setShowReply] = React.useState(false);
  React.useEffect(() => {
    if (!vis) return;
    const t1 = setTimeout(() => setShowTyping(true), 600);
    const t2 = setTimeout(() => { setShowTyping(false); setShowReply(true); }, 2000);
    return () => { clearTimeout(t1); clearTimeout(t2); };
  }, [vis]);
  return (
    <div ref={ref} style={{ display: "flex", flexDirection: "column", gap: 6 }}>
      <Bubble side="out" small>остаток на КЗТ-счёте?</Bubble>
      {showTyping && (
        <div style={{ display: "flex", alignItems: "center", gap: 5, paddingLeft: 4 }}>
          <span className="typing-dot" />
          <span className="typing-dot" />
          <span className="typing-dot" />
        </div>
      )}
      {showReply && (
        <div style={{ opacity: 0, animation: "bento-fadein .4s ease forwards" }}>
          <Bubble side="in" small>
            <span style={{ color: "var(--accent)" }}>4 218 540 ₸</span> · Halyk · 04.05
          </Bubble>
        </div>
      )}
    </div>
  );
}

function ReportViz() {
  const forms = [
    { n: "100.00", st: "готово",   done: true  },
    { n: "200.00", st: "до 15.05", done: false },
    { n: "300.00", st: "готово",   done: true  },
    { n: "910.00", st: "до 15.05", done: false },
  ];
  const [ref, vis] = useVisible();
  return (
    <div ref={ref} style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 6 }}>
      {forms.map((f, i) => (
        <div key={f.n} style={{
          padding: "8px 6px", borderRadius: 8, textAlign: "center",
          border: `1px solid ${vis && f.done ? "rgba(168,245,208,0.30)" : "var(--line)"}`,
          background: vis && f.done ? "rgba(168,245,208,0.04)" : "transparent",
          opacity: vis ? 1 : 0,
          transform: vis ? "none" : "scale(0.85)",
          transition: `opacity .45s ease ${i * 90}ms, transform .45s ease ${i * 90}ms, border-color .5s ease ${i * 90 + 200}ms, background .5s ease ${i * 90 + 200}ms`,
        }}>
          <div className="mono" style={{ fontSize: 11, color: "var(--fg)" }}>{f.n}</div>
          <div style={{ fontSize: 9, color: f.done ? "var(--accent)" : "var(--fg-mute)" }}>{f.st}</div>
        </div>
      ))}
    </div>
  );
}

/* =================================================================
   Stepper — Как работает
================================================================= */
function StepNumber({ n, visible }) {
  return (
    <svg width={72} height={64} viewBox="0 0 72 64" fill="none" aria-hidden="true" style={{ overflow: "visible" }}>
      <text
        x="2" y="56"
        fontFamily="'Instrument Serif', serif"
        fontStyle="italic"
        fontSize="58"
        fill="none"
        stroke="var(--accent)"
        strokeWidth="0.7"
        strokeLinecap="round"
        strokeDasharray="320"
        strokeDashoffset={visible ? 0 : 320}
        style={{ transition: "stroke-dashoffset 1.2s cubic-bezier(.4,0,.2,1)" }}
      >{n}</text>
    </svg>
  );
}

function Stepper() {
  const steps = [
    { n: "01", t: "Подключаем 1С", d: "SOAP-коннектор за 30 минут. Поддержка 1С:БК 3.0, УНФ, ERP, ЗУП — Казахстан и Россия." },
    { n: "02", t: "Настраиваем модули", d: "Включаем то, что нужно: банк, ЭСФ, УПД, payroll. Модули можно расширять по ходу." },
    { n: "03", t: "Обучаем агента", d: "Показываем правила вашей компании: контрагенты, статьи, лимиты согласования." },
    { n: "04", t: "Работаем из чата", d: "Главбух пишет в Telegram. Агент проводит, сверяет, готовит отчёты — с аудиторским логом." },
  ];

  const [visibleSteps, setVisibleSteps] = React.useState([]);
  const refs = React.useRef([]);

  React.useEffect(() => {
    const observers = steps.map((_, i) => {
      const io = new IntersectionObserver(([e]) => {
        if (e.isIntersecting) {
          setVisibleSteps(prev => prev.includes(i) ? prev : [...prev, i]);
          io.disconnect();
        }
      }, { threshold: 0.25 });
      if (refs.current[i]) io.observe(refs.current[i]);
      return io;
    });
    return () => observers.forEach(io => io.disconnect());
  }, []);

  return (
    <section id="Как работает" className="section-pad">
      <div className="container">
        <div style={{ marginBottom: 56 }}>
          <Reveal><span className="eyebrow">/ как работает</span></Reveal>
          <Reveal delay={100}>
            <h2 style={{ marginTop: 14, maxWidth: 760 }}>
              От подключения до первой <span className="serif" style={{ color: "var(--accent)" }}>проводки</span> — 3 дня
            </h2>
          </Reveal>
        </div>

        <div className="stepper-grid">
          {steps.map((s, i) => {
            const vis = visibleSteps.includes(i);
            return (
              <Reveal key={s.n} delay={i * 100} className="step">
                <div ref={el => refs.current[i] = el}>
                  <StepNumber n={s.n} visible={vis} />
                </div>
                <h3 style={{
                  marginTop: 10, fontSize: 20,
                  opacity: vis ? 1 : 0,
                  transform: vis ? "none" : "translateY(8px)",
                  transition: `opacity .5s ease 200ms, transform .5s ease 200ms`,
                }}>{s.t}</h3>
                <p style={{
                  fontSize: 14, marginTop: 8,
                  opacity: vis ? 1 : 0,
                  transition: `opacity .6s ease 350ms`,
                }}>{s.d}</p>
              </Reveal>
            );
          })}
        </div>
      </div>

      <style>{`
        .stepper-grid {
          display: grid;
          gap: 28px 32px;
          grid-template-columns: 1fr;
        }
        @media (min-width: 640px) { .stepper-grid { grid-template-columns: 1fr 1fr; } }
        @media (min-width: 1024px) {
          .stepper-grid { grid-template-columns: repeat(4, 1fr); }
          .step { position: relative; padding-right: 24px; }
          .step:not(:last-child)::after {
            content: ""; position: absolute;
            top: 32px; right: -16px;
            width: 48px; height: 1px;
            background: linear-gradient(90deg, rgba(168,245,208,0.45), transparent);
            transform-origin: left center;
            transform: scaleX(0);
            transition: transform .7s cubic-bezier(.4,0,.2,1) .9s;
          }
          .step.in:not(:last-child)::after { transform: scaleX(1); }
        }
      `}</style>
    </section>
  );
}

window.TopNav = TopNav;
window.Hero = Hero;
window.Marquee = Marquee;
window.Bento = Bento;
window.Stepper = Stepper;
window.Bubble = Bubble;