// ff-hero.jsx — Hero section with rotating audience text + two variants

const { useState: __h_useState, useEffect: __h_useEffect } = React;

// Fade-in-up rotator — whole phrase swaps with a stable width
function Rotator({ items, interval = 2800 }) {
  const [i, setI] = __h_useState(0);
  const [key, setKey] = __h_useState(0);
  __h_useEffect(() => {
    setI(0);
    setKey((k) => k + 1);
  }, [items]);
  __h_useEffect(() => {
    const id = setInterval(() => {
      setI((v) => (v + 1) % items.length);
      setKey((k) => k + 1);
    }, interval);
    return () => clearInterval(id);
  }, [items, interval]);
  return (
    <span className="rotator">
      <span key={key} className="rotator-item">{items[i]}</span>
    </span>
  );
}

function HeroMetric({ value, label, sub }) {
  return (
    <div className="hero-metric">
      <div className="hero-metric-v">{value}</div>
      <div className="hero-metric-l">{label}</div>
      {sub && <div className="hero-metric-s">{sub}</div>}
    </div>
  );
}

function Hero({ variant = "flow", accent, s }) {
  return (
    <section
      id="top"
      data-screen-label="01 Hero"
      className={`hero hero-${variant}`}
    >
      <div className="hero-bg">
        {variant === "split" && <FlowMesh accent={accent} density={16} opacity={0.35} />}
        <div className="hero-grid" />
        <div className="hero-vignette" />
      </div>

      {variant === "flow" ? <HeroFlow s={s} /> : <HeroSplit s={s} />}
    </section>
  );
}

function HeroFlow({ s }) {
  return (
    <div className="wrap hero-inner hero-inner-flow">
      <Reveal className="hero-brand" as="div">
        <BrandIcon height={28} />
      </Reveal>

      <Reveal delay={1} as="h1" className="hero-title">
        <span>{s.hero.titlePre}</span>
        <br />
        <Rotator items={s.hero.audiences} />
      </Reveal>

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

      <Reveal delay={3} className="hero-cta">
        <a href="#contact" className="btn btn-primary btn-lg">
          {s.hero.ctaPrimary} <span className="arrow">→</span>
        </a>
        <a href="#cases" className="btn btn-ghost btn-lg">
          {s.hero.ctaSecondary}
        </a>
      </Reveal>

      <Reveal delay={4} className="hero-live" as="div">
        <LiveDemo />
      </Reveal>

      <Reveal delay={5} className="hero-metrics" as="div">
        <HeroMetric value={<><Counter to={50} suffix="+" /></>} label={s.hero.metric1.label} sub={s.hero.metric1.sub} />
        <HeroMetric value={<><Counter to={12} /></>}            label={s.hero.metric2.label} sub={s.hero.metric2.sub} />
        <HeroMetric value={<><Counter to={4} suffix="×" /></>}  label={s.hero.metric3.label} sub={s.hero.metric3.sub} />
        <HeroMetric value={<>~<Counter to={6} suffix={s.hero.timeUnit} /></>} label={s.hero.metric4.label} sub={s.hero.metric4.sub} />
      </Reveal>
    </div>
  );
}

// ─────────── Live demo — running automation flow ───────────
// Two-pane design: left = static topology with CSS-animated rail flow;
// right = live event console where rows stream upward. No travelling SVG
// nodes — eliminates the chip-leak class of bug entirely.
const LIVE_TOPO_SOURCES = [
  { y: 56,  icon: "letter",   label: "Email",    sub: "imap",   tag: "EML" },
  { y: 130, icon: "code",     label: "Webhook",  sub: "POST",   tag: "WEB" },
  { y: 204, icon: "telegram", label: "Telegram", sub: "bot",    tag: "TG"  },
];
const LIVE_TOPO_SINKS = [
  { y: 56,  icon: "shop",   label: "CRM",   sub: "leads",  tag: "CRM" },
  { y: 130, icon: "server", label: "ERP",   sub: "orders", tag: "ERP" },
  { y: 204, icon: "slack",  label: "Slack", sub: "ops",    tag: "SLK" },
];

// Payload examples per source kind. Realistic-feeling shorthand that reads as
// "things are happening" rather than placeholder text.
const LIVE_PAYLOADS = {
  EML: [
    { sink: "CRM", text: "lead@acme.co · RFQ #4821" },
    { sink: "CRM", text: "info@vela.eu · pricing" },
    { sink: "ERP", text: "po@northbound.co · invoice" },
    { sink: "CRM", text: "hello@stride.io · demo" },
    { sink: "SLK", text: "support@kr.co · urgent" },
  ],
  WEB: [
    { sink: "ERP", text: "POST /order/4821 · 200" },
    { sink: "CRM", text: "POST /signup · 201" },
    { sink: "ERP", text: "POST /invoice/19 · 200" },
    { sink: "SLK", text: "POST /alert/disk · 200" },
    { sink: "CRM", text: "POST /lead · 201" },
  ],
  TG: [
    { sink: "SLK", text: "@kfomenko · invoice?" },
    { sink: "CRM", text: "@dani · status update" },
    { sink: "SLK", text: "@team · daily report" },
    { sink: "ERP", text: "@ops · ship status" },
    { sink: "SLK", text: "@anna · onboarding" },
  ],
};
const LIVE_SOURCE_KEYS = ["EML", "WEB", "TG"];

// Solar Bold Duotone + Simple Icons (Slack/Telegram).
// Returns bare <path> elements (no wrapping <svg>) so they can be embedded
// inside a parent SVG via <g transform="…">. 24×24 source viewBox.
function LiveNodeIcon({ kind }) {
  switch (kind) {
    case "letter":
      return (
        <React.Fragment>
          <path fill="currentColor" opacity=".5" d="M14.2 3H9.8C5.652 3 3.577 3 2.289 4.318S1 7.758 1 12s0 6.364 1.289 7.682S5.652 21 9.8 21h4.4c4.148 0 6.223 0 7.511-1.318S23 16.242 23 12s0-6.364-1.289-7.682S18.348 3 14.2 3" />
          <path fill="currentColor" d="M19.128 8.033a.825.825 0 0 0-1.056-1.268l-2.375 1.98c-1.026.855-1.738 1.447-2.34 1.833c-.582.375-.977.5-1.357.5s-.774-.125-1.357-.5c-.601-.386-1.314-.978-2.34-1.834L5.928 6.765a.825.825 0 0 0-1.056 1.268l2.416 2.014c.975.812 1.765 1.47 2.463 1.92c.726.466 1.434.762 2.25.762c.814 0 1.522-.296 2.249-.763c.697-.448 1.487-1.107 2.462-1.92z" />
        </React.Fragment>
      );
    case "code":
      return (
        <React.Fragment>
          <path fill="currentColor" opacity=".5" d="M2 12c0-4.714 0-7.071 1.464-8.536C4.93 2 7.286 2 12 2s7.071 0 8.535 1.464C22 4.93 22 7.286 22 12s0 7.071-1.465 8.535C19.072 22 16.714 22 12 22s-7.071 0-8.536-1.465C2 19.072 2 16.714 2 12" />
          <path fill="currentColor" d="M13.488 6.446a.75.75 0 0 1 .53.918l-2.588 9.66a.75.75 0 0 1-1.449-.389l2.589-9.659a.75.75 0 0 1 .918-.53M14.97 8.47a.75.75 0 0 1 1.06 0l.209.208c.635.635 1.165 1.165 1.529 1.642c.384.504.654 1.036.654 1.68s-.27 1.176-.654 1.68c-.364.477-.894 1.007-1.53 1.642l-.208.208a.75.75 0 1 1-1.06-1.06l.171-.172c.682-.682 1.139-1.14 1.434-1.528c.283-.37.347-.586.347-.77s-.064-.4-.347-.77c-.295-.387-.752-.846-1.434-1.528l-.171-.172a.75.75 0 0 1 0-1.06m-7 0a.75.75 0 0 1 1.06 1.06l-.171.172c-.682.682-1.138 1.14-1.434 1.528c-.283.37-.346.586-.346.77s.063.4.346.77c.296.387.752.846 1.434 1.528l.172.172a.75.75 0 1 1-1.061 1.06l-.208-.208c-.636-.635-1.166-1.165-1.53-1.642c-.384-.504-.653-1.036-.653-1.68s.27-1.176.653-1.68c.364-.477.894-1.007 1.53-1.642z" />
        </React.Fragment>
      );
    case "telegram":
      return (
        <path fill="currentColor" d="M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12a12 12 0 0 0 12-12A12 12 0 0 0 12 0zm4.962 7.224c.1-.002.321.023.465.14a.5.5 0 0 1 .171.325c.016.093.036.306.02.472c-.18 1.898-.962 6.502-1.36 8.627c-.168.9-.499 1.201-.82 1.23c-.696.065-1.225-.46-1.9-.902c-1.056-.693-1.653-1.124-2.678-1.8c-1.185-.78-.417-1.21.258-1.91c.177-.184 3.247-2.977 3.307-3.23c.007-.032.014-.15-.056-.212s-.174-.041-.249-.024q-.159.037-5.061 3.345q-.72.495-1.302.48c-.428-.008-1.252-.241-1.865-.44c-.752-.245-1.349-.374-1.297-.789q.04-.324.893-.663q5.247-2.286 6.998-3.014c3.332-1.386 4.025-1.627 4.476-1.635" />
      );
    case "junction":
      return (
        <React.Fragment>
          <path fill="currentColor" opacity=".5" d="M3.464 20.536C4.93 22 7.286 22 12 22s7.071 0 8.535-1.465C22 19.072 22 16.714 22 12s0-7.071-1.465-8.536C19.072 2 16.714 2 12 2S4.929 2 3.464 3.464C2 4.93 2 7.286 2 12s0 7.071 1.464 8.535" />
          <path fill="currentColor" d="M12.75 6.5a.75.75 0 0 0-1.5 0v6A3.25 3.25 0 0 1 8 15.75h-.19l.22-.22a.75.75 0 1 0-1.06-1.06l-1.5 1.5a.75.75 0 0 0 0 1.06l1.5 1.5a.75.75 0 0 0 1.06-1.06l-.22-.22H8c1.68 0 3.155-.872 4-2.187a4.75 4.75 0 0 0 4 2.187h.19l-.22.22a.75.75 0 1 0 1.06 1.06l1.5-1.5a.75.75 0 0 0 0-1.06l-1.5-1.5a.75.75 0 1 0-1.06 1.06l.22.22H16a3.25 3.25 0 0 1-3.25-3.25z" />
        </React.Fragment>
      );
    case "shop":
      return (
        <React.Fragment>
          <path fill="currentColor" d="M14.5 21.991V18.5c0-.935 0-1.402-.201-1.75a1.5 1.5 0 0 0-.549-.549C13.402 16 12.935 16 12 16s-1.402 0-1.75.201a1.5 1.5 0 0 0-.549.549c-.201.348-.201.815-.201 1.75v3.491z" />
          <path fill="currentColor" fillRule="evenodd" clipRule="evenodd" opacity=".5" d="M5.732 12c-.89 0-1.679-.376-2.232-.967V14c0 3.771 0 5.657 1.172 6.828c.943.944 2.348 1.127 4.828 1.163h5c2.48-.036 3.885-.22 4.828-1.163C20.5 19.657 20.5 17.771 20.5 14v-2.966a3.06 3.06 0 0 1-5.275-1.789l-.073-.728a3.167 3.167 0 1 1-6.307.038l-.069.69A3.06 3.06 0 0 1 5.732 12m8.768 6.5v3.491h-5V18.5c0-.935 0-1.402.201-1.75a1.5 1.5 0 0 1 .549-.549C10.598 16 11.065 16 12 16s1.402 0 1.75.201a1.5 1.5 0 0 1 .549.549c.201.348.201.815.201 1.75" />
          <path fill="currentColor" d="M9.5 2h5l.652 6.517a3.167 3.167 0 1 1-6.304 0z" />
          <path fill="currentColor" opacity=".7" d="M3.33 5.351c.178-.89.267-1.335.448-1.696a3 3 0 0 1 1.889-1.548C6.057 2 6.51 2 7.418 2h2.083l-.725 7.245a3.06 3.06 0 1 1-6.044-.904zm17.34 0c-.178-.89-.267-1.335-.448-1.696a3 3 0 0 0-1.888-1.548C17.944 2 17.49 2 16.582 2H14.5l.725 7.245a3.06 3.06 0 1 0 6.043-.904z" />
        </React.Fragment>
      );
    case "server":
      return (
        <React.Fragment>
          <path fill="currentColor" opacity=".5" d="M6 13h12c1.886 0 2.828 0 3.414.586S22 15.114 22 17s0 2.828-.586 3.414S19.886 21 18 21H6c-1.886 0-2.828 0-3.414-.586S2 18.886 2 17s0-2.828.586-3.414S4.114 13 6 13M6 3h12c1.886 0 2.828 0 3.414.586S22 5.114 22 7s0 2.828-.586 3.414S19.886 11 18 11H6c-1.886 0-2.828 0-3.414-.586S2 8.886 2 7s0-2.828.586-3.414S4.114 3 6 3" />
          <path fill="currentColor" d="M12.75 7a.75.75 0 0 1 .75-.75H18a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75M6 8.75A.75.75 0 0 1 5.25 8V6a.75.75 0 0 1 1.5 0v2a.75.75 0 0 1-.75.75m3 0A.75.75 0 0 1 8.25 8V6a.75.75 0 0 1 1.5 0v2a.75.75 0 0 1-.75.75M12.75 17a.75.75 0 0 1 .75-.75H18a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75M6 18.75a.75.75 0 0 1-.75-.75v-2a.75.75 0 0 1 1.5 0v2a.75.75 0 0 1-.75.75m3 0a.75.75 0 0 1-.75-.75v-2a.75.75 0 0 1 1.5 0v2a.75.75 0 0 1-.75.75" />
        </React.Fragment>
      );
    case "slack":
      return (
        <path fill="currentColor" d="M5.042 15.165a2.53 2.53 0 0 1-2.52 2.523A2.53 2.53 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52zm1.271 0a2.527 2.527 0 0 1 2.521-2.52a2.527 2.527 0 0 1 2.521 2.52v6.313A2.53 2.53 0 0 1 8.834 24a2.53 2.53 0 0 1-2.521-2.522zM8.834 5.042a2.53 2.53 0 0 1-2.521-2.52A2.53 2.53 0 0 1 8.834 0a2.53 2.53 0 0 1 2.521 2.522v2.52zm0 1.271a2.53 2.53 0 0 1 2.521 2.521a2.53 2.53 0 0 1-2.521 2.521H2.522A2.53 2.53 0 0 1 0 8.834a2.53 2.53 0 0 1 2.522-2.521zm10.122 2.521a2.53 2.53 0 0 1 2.522-2.521A2.53 2.53 0 0 1 24 8.834a2.53 2.53 0 0 1-2.522 2.521h-2.522zm-1.268 0a2.53 2.53 0 0 1-2.523 2.521a2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.165 0a2.53 2.53 0 0 1 2.523 2.522zm-2.523 10.122a2.53 2.53 0 0 1 2.523 2.522A2.53 2.53 0 0 1 15.165 24a2.527 2.527 0 0 1-2.52-2.522v-2.522zm0-1.268a2.527 2.527 0 0 1-2.52-2.523a2.526 2.526 0 0 1 2.52-2.52h6.313A2.527 2.527 0 0 1 24 15.165a2.53 2.53 0 0 1-2.522 2.523z" />
      );
    default:
      return null;
  }
}

// Icon glyph as an inline SVG <g>; expects to be placed inside a parent SVG.
// Scales 24×24 source to size px, translated so its top-left lands at (x,y).
function LiveIconG({ kind, x, y, size = 24, className = "hero-live-icon-g" }) {
  const k = size / 24;
  return (
    <g transform={`translate(${x} ${y}) scale(${k})`} className={className}>
      <LiveNodeIcon kind={kind} />
    </g>
  );
}

// Compact topology node: 32px round-rect tile + side label/sub. Placed by
// vertical centerline (y) at a fixed x for either side of the lane band.
function LiveTopoNode({ x, y, icon, label, sub, side }) {
  const tile = 32;
  const tx = x - tile / 2;
  const ty = y - tile / 2;
  const labelX = side === "left" ? x + tile / 2 + 10 : x - tile / 2 - 10;
  const anchor = side === "left" ? "start" : "end";
  return (
    <g>
      <rect x={tx} y={ty} width={tile} height={tile} rx="9" className="hero-live-node" />
      <LiveIconG kind={icon} x={tx + 6} y={ty + 6} size={20} />
      <text x={labelX} y={y - 1} textAnchor={anchor} className="hero-live-node-label">{label}</text>
      <text x={labelX} y={y + 11} textAnchor={anchor} className="hero-live-node-sub">{sub}</text>
    </g>
  );
}

function LiveDemo() {
  // Event feed: one entry every ~700ms. We keep the last 6 for the console,
  // plus a rolling counter for the header. Per-lane intensity is derived from
  // how recently each source fired — implies a real working system.
  const [events, setEvents] = __h_useState([]);
  const [count, setCount] = __h_useState(0);

  __h_useEffect(() => {
    let seq = 0;
    // Lightly weighted picker so lanes "feel" alive at different rates.
    const weights = [
      { k: "WEB", w: 5 },
      { k: "EML", w: 3 },
      { k: "TG",  w: 2 },
    ];
    const wsum = weights.reduce((a, b) => a + b.w, 0);
    const pick = () => {
      let r = Math.random() * wsum;
      for (const x of weights) { if ((r -= x.w) < 0) return x.k; }
      return "WEB";
    };
    const tick = () => {
      const src = pick();
      const pool = LIVE_PAYLOADS[src];
      const item = pool[seq % pool.length];
      seq += 1;
      const id = Date.now() + "-" + seq;
      const t = new Date();
      const hh = String(t.getHours()).padStart(2, "0");
      const mm = String(t.getMinutes()).padStart(2, "0");
      const ss = String(t.getSeconds()).padStart(2, "0");
      const ms = String(t.getMilliseconds()).padStart(3, "0").slice(0, 2);
      setEvents((es) => [...es.slice(-5), {
        id,
        src,
        sink: item.sink,
        text: item.text,
        ts: `${hh}:${mm}:${ss}.${ms}`,
      }]);
      setCount((c) => c + 1);
    };
    tick();
    const id = setInterval(tick, 720);
    return () => clearInterval(id);
  }, []);

  const counter = String(count).padStart(4, "0");

  // 800×280 canvas. Topology lives on the left half (0–360); console on the
  // right (380–796). Lane band spans y=56..204; junction at x=320.
  const LANE_X_IN = 84;   // where rails start (right edge of source tile)
  const LANE_X_OUT = 320; // junction center x
  const SINK_X = 348;     // sink fan-out start (left edge of sink tile)
  const HUB = { cx: 320, cy: 130, r: 16 };

  // Build lane paths source → junction → sink. Straight middle lane, gentle
  // S-curves for top/bottom. Three lanes total (one per source).
  const lanes = LIVE_TOPO_SOURCES.map((s, i) => {
    const yS = s.y;
    const yH = HUB.cy;
    return {
      key: s.tag,
      inPath:  `M ${LANE_X_IN} ${yS} C ${LANE_X_IN + 80} ${yS}, ${LANE_X_OUT - 60} ${yH}, ${HUB.cx - HUB.r} ${yH}`,
      // Each source fans to a single matching sink (visually 1:1); reroutes
      // happen in the console feed.
      outPath: `M ${HUB.cx + HUB.r} ${yH} C ${LANE_X_OUT + 60} ${yH}, ${SINK_X - 80} ${LIVE_TOPO_SINKS[i].y}, ${SINK_X} ${LIVE_TOPO_SINKS[i].y}`,
      yS,
      yD: LIVE_TOPO_SINKS[i].y,
      tag: s.tag,
    };
  });

  return (
    <div className="hero-live-frame">
      <div className="hero-live-head">
        <span className="hero-live-tag">intake.flow</span>
        <span className="hero-live-head-meta">live · 3 sources → junction → 3 sinks</span>
        <span className="hero-live-head-stats">
          <span className="hero-live-stat"><em>events</em><b>{counter}</b></span>
          <span className="hero-live-stat hero-live-stat-ok"><em>err</em><b>0000</b></span>
        </span>
      </div>

      <div className="hero-live-body">
        {/* Left: topology with CSS-animated rail flow. SVG content never
           leaves the viewBox — animations are stroke-dashoffset only. */}
        <svg
          viewBox="0 0 400 260"
          className="hero-live-topo"
          preserveAspectRatio="xMidYMid meet"
          aria-hidden="true"
        >
          {/* hairline lane backgrounds */}
          {lanes.map((l) => (
            <React.Fragment key={`bg-${l.key}`}>
              <path d={l.inPath}  className="hero-live-rail-bg" />
              <path d={l.outPath} className="hero-live-rail-bg" />
            </React.Fragment>
          ))}
          {/* animated flow strokes (dashoffset) — continuous, lane-specific
             speeds so the system reads as actively varying */}
          {lanes.map((l) => (
            <React.Fragment key={`fg-${l.key}`}>
              <path d={l.inPath}  className={`hero-live-rail-flow hero-live-rail-${l.tag.toLowerCase()}`} />
              <path d={l.outPath} className={`hero-live-rail-flow hero-live-rail-${l.tag.toLowerCase()}`} />
            </React.Fragment>
          ))}

          {/* junction — minimal concentric ring + W-glyph; not "AI brain" */}
          <g className="hero-live-junction" transform={`translate(${HUB.cx} ${HUB.cy})`}>
            <circle r={HUB.r + 6} className="hero-live-junction-halo" />
            <circle r={HUB.r}     className="hero-live-junction-disc" />
            <g transform="translate(-9.7 -7) scale(0.5)" className="hero-live-hub-icon">
              <path d="M39 23.3448L35.7209 26.3954L28.4302 19.2598L19.5 28L10.5698 19.2598L3.27907 26.3954L0 23.3448L10.5698 13L19.5 21.7402L28.4302 13L39 23.3448Z" fill="currentColor" opacity=".55"/>
              <path d="M39 10.3448L35.7209 13.3954L28.4302 6.25982L19.5 15L10.5698 6.25982L3.27907 13.3954L0 10.3448L10.5698 0L19.5 8.74018L28.4302 0L39 10.3448Z" fill="currentColor"/>
            </g>
          </g>

          {/* source + sink nodes */}
          {LIVE_TOPO_SOURCES.map((n) => (
            <LiveTopoNode key={`s-${n.tag}`} x={68}  y={n.y} side="left"  {...n} />
          ))}
          {LIVE_TOPO_SINKS.map((n) => (
            <LiveTopoNode key={`d-${n.tag}`} x={364} y={n.y} side="right" {...n} />
          ))}
        </svg>

        {/* Right: live event console. Rows are React-rendered into a column;
           CSS animates the newest row in (slide-up + fade) so the panel is
           always in motion between event ticks. */}
        <div className="hero-live-console" aria-hidden="true">
          <div className="hero-live-console-head">
            <span className="hero-live-console-dots">
              <i /><i /><i />
            </span>
            <span className="hero-live-console-title">events.tail —f</span>
            <span className="hero-live-console-cursor">_</span>
          </div>
          <ol className="hero-live-console-list">
            {events.map((e, i) => (
              <li
                key={e.id}
                className={`hero-live-row ${i === events.length - 1 ? "is-new" : ""}`}
                data-src={e.src}
                data-sink={e.sink}
              >
                <span className="hero-live-row-ts">{e.ts}</span>
                <span className={`hero-live-row-tag hero-live-tag-${e.src.toLowerCase()}`}>{e.src}</span>
                <span className="hero-live-row-arrow">→</span>
                <span className={`hero-live-row-tag hero-live-tag-${e.sink.toLowerCase()}`}>{e.sink}</span>
                <span className="hero-live-row-text">{e.text}</span>
                <span className="hero-live-row-ok">ok</span>
              </li>
            ))}
          </ol>
          <div className="hero-live-console-foot">
            <span className="hero-live-foot-dot" />
            <span>streaming · {counter} events · 0 errors</span>
          </div>
        </div>
      </div>
    </div>
  );
}

function HeroSplit({ s }) {
  return (
    <div className="wrap hero-inner hero-inner-split">
      <div className="hero-split-left">
        <Reveal className="hero-brand hero-brand-split" as="div">
          <BrandIcon height={24} />
        </Reveal>
        <Reveal delay={1} as="h1" className="hero-title hero-title-split">
          <span>{s.hero.titlePre}</span>
          <br />
          <Rotator items={s.hero.audiences} />
        </Reveal>
        <Reveal delay={2} className="hero-sub" as="p">
          {s.hero.sub}
        </Reveal>
        <Reveal delay={3} className="hero-cta">
          <a href="#contact" className="btn btn-primary btn-lg">
            {s.hero.ctaPrimary} <span className="arrow">→</span>
          </a>
          <a href="#cases" className="btn btn-ghost btn-lg">
            {s.hero.ctaSecondary}
          </a>
        </Reveal>
      </div>

      <Reveal delay={2} className="hero-split-right" as="div">
        <HeroDiagram s={s} />
      </Reveal>
    </div>
  );
}

function HeroDiagram({ s }) {
  return (
    <div className="hero-diagram card">
      <div className="hero-diagram-head">
        <span className="dot dot-r" /><span className="dot dot-y" /><span className="dot dot-g" />
        <span className="hero-diagram-title">{s.hero.diagramHead}</span>
      </div>
      <svg viewBox="0 0 360 280" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
        <defs>
          <marker id="ar" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto">
            <path d="M0 0 L10 5 L0 10 Z" fill="var(--accent)" />
          </marker>
        </defs>
        {[
          { x: 30,  y: 40,  w: 96, h: 32, label: "Email" },
          { x: 30,  y: 124, w: 96, h: 32, label: "Webhook" },
          { x: 30,  y: 208, w: 96, h: 32, label: "Telegram" },
          { x: 160, y: 124, w: 92, h: 36, label: "AI Router", on: true },
          { x: 286, y: 40,  w: 64, h: 32, label: "CRM" },
          { x: 286, y: 124, w: 64, h: 32, label: "ERP" },
          { x: 286, y: 208, w: 64, h: 32, label: "Slack" },
        ].map((n, i) => (
          <g key={i}>
            <rect x={n.x} y={n.y} width={n.w} height={n.h} rx="6"
              fill="var(--bg-2)"
              stroke={n.on ? "var(--accent)" : "var(--line-strong)"}
              strokeWidth={n.on ? 1.4 : 1} />
            <text x={n.x + 10} y={n.y + n.h / 2 + 4} fontFamily="var(--font-mono)" fontSize="11" fill="var(--fg)">
              {n.label}
            </text>
            <circle cx={n.x + n.w - 9} cy={n.y + n.h / 2} r="3" fill={n.on ? "var(--accent)" : "var(--fg-4)"}>
              {n.on && <animate attributeName="opacity" values="0.3;1;0.3" dur="1.6s" repeatCount="indefinite" />}
            </circle>
          </g>
        ))}
        {[
          ["M126,56 C 145,56 145,142 158,142"],
          ["M126,140 L158,140"],
          ["M126,224 C 145,224 145,144 158,144"],
          ["M252,142 C 270,142 270,56 284,56"],
          ["M252,142 L284,140"],
          ["M252,144 C 270,144 270,224 284,224"],
        ].map((d, i) => (
          <path key={i} d={d[0]} fill="none" stroke="var(--accent)" strokeOpacity="0.55"
            strokeWidth="1.2" markerEnd="url(#ar)" />
        ))}
      </svg>
      <div className="hero-diagram-foot">
        <span className="tag">n8n</span>
        <span className="tag">openai</span>
        <span className="tag">postgres</span>
        <span className="tag">+8</span>
      </div>
    </div>
  );
}

window.Hero = Hero;
