// AlphaEdge — Shared UI Components (v2 · Light Premium Editorial)
// Re-skinned from the dark trading-terminal look to a clean, warm-paper,
// editorial system. Component names + prop APIs are preserved so every page
// keeps composing the same way.

const FD = "'Schibsted Grotesk', system-ui, -apple-system, sans-serif"; // display
const FB = "'Hanken Grotesk', system-ui, -apple-system, sans-serif"; // body / ui
const FS = "'Newsreader', Georgia, 'Times New Roman', serif"; // editorial

const INK = { 1: '#1A1B20', 2: '#54565E', 3: '#82848C', 4: '#A8A9AE', 5: '#C9C9C7' };
const PAPER = { 0: '#FFFFFF', 1: '#FBFAF7', 2: '#F5F3EE', 3: '#EEEBE3', 4: '#E4E0D6', dark: '#15161B' };
const BORDER = { subtle: '#EEEBE3', default: '#E2DFD5', strong: '#CFCBBF' };
const UP = '#157A40';

// Derive a small accent ramp from a single brand hex (pages pass a string).
function mix(c, pct, into) {return `color-mix(in srgb, ${c} ${pct}%, ${into})`;}
function acc(c) {
  return {
    c,
    h: mix(c, 82, '#000000'), // hover / darker
    soft: mix(c, 60, '#ffffff'), // muted accent
    tint: mix(c, 9, '#ffffff'), // chip / wash background
    chip: mix(c, 24, '#ffffff'), // chip border
    a12: mix(c, 12, 'transparent'),
    a20: mix(c, 20, 'transparent')
  };
}

window.Object.assign(window, { FD, FB, FS, INK, PAPER, BORDER, UP, acc, mix });

const FM = "'JetBrains Mono', ui-monospace, SFMono-Regular, monospace"; // data / ticker
const DOWN = '#C0392B';

/* Inline SVG icons — used inside animated components that re-render often
   (lucide.createIcons only runs on App-level renders, so <i data-lucide> there
   would never convert). */
function SvgCheck({ size = 12, color = '#fff' }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color}
    strokeWidth="3.2" strokeLinecap="round" strokeLinejoin="round" style={{ display: 'block' }}>
      <path d="M20 6 9 17l-4-4" />
    </svg>);

}
function SvgCpu({ size = 17, color = 'currentColor' }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color}
    strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" style={{ display: 'block' }}>
      <rect width="16" height="16" x="4" y="4" rx="2.5" />
      <rect width="6" height="6" x="9" y="9" rx="1" />
      <path d="M15 2v2M15 20v2M2 15h2M2 9h2M20 15h2M20 9h2M9 2v2M9 20v2" />
    </svg>);

}
function SvgArrow({ up, size = 11, color }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color}
    strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" style={{ display: 'block' }}>
      {up ? <path d="M7 17 17 7M8 7h9v9" /> : <path d="M7 7 17 17M17 8v9H8" />}
    </svg>);

}

/* ============================================================ MARKET TICKER (hero strip)
   Ported from the original dark trading-terminal version — a live, continuously
   scrolling market tape. Prices flicker on a timer; up/down use semantic colors. */
const TICKER_SEED = [
{ sym: 'BTC/USDT', price: 68420.50, chg: 1.24 },
{ sym: 'ETH/USDT', price: 3821.10, chg: -0.87 },
{ sym: 'SOL/USDT', price: 183.40, chg: 3.11 },
{ sym: 'BNB/USDT', price: 612.80, chg: 0.43 },
{ sym: 'ARB/USDT', price: 1.24, chg: -1.02 },
{ sym: 'OP/USDT', price: 2.87, chg: 2.55 },
{ sym: 'AVAX/USDT', price: 38.92, chg: 0.78 },
{ sym: 'LINK/USDT', price: 17.45, chg: -0.34 },
{ sym: 'DOGE/USDT', price: 0.1620, chg: 4.10 },
{ sym: 'INJ/USDT', price: 24.18, chg: 1.67 },
{ sym: 'TIA/USDT', price: 8.41, chg: -2.13 },
{ sym: 'RNDR/USDT', price: 7.92, chg: 0.92 }];

function fmtPrice(p) {
  const dp = p >= 1000 ? 2 : p >= 1 ? 2 : 4;
  return p.toLocaleString('en-US', { minimumFractionDigits: dp, maximumFractionDigits: dp });
}
function MarketTicker({ accent }) {
  const a = acc(accent);
  const reduce = typeof window !== 'undefined' && window.matchMedia &&
  window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  const [rows, setRows] = React.useState(TICKER_SEED);
  React.useEffect(() => {
    if (reduce) return;
    const t = setInterval(() => {
      setRows((prev) => prev.map((r) => {
        const drift = (Math.random() - 0.48) * 0.0016; // ±~0.16%
        const price = Math.max(0.0001, r.price * (1 + drift));
        const chg = Math.max(-9.9, Math.min(9.9, r.chg + drift * 100));
        return { ...r, price, chg };
      }));
    }, 1400);
    return () => clearInterval(t);
  }, [reduce]);

  const Item = ({ r, i }) => {
    const up = r.chg >= 0;
    return (
      <div style={{ display: 'inline-flex', alignItems: 'center', gap: 9, padding: '0 22px',
        borderRight: `1px solid ${BORDER.subtle}` }}>
        <span style={{ fontFamily: FM, fontSize: 12, fontWeight: 600, letterSpacing: '0.03em', color: INK[3] }}>{r.sym}</span>
        <span style={{ fontFamily: FM, fontSize: 12, fontWeight: 500, color: INK[1], fontVariantNumeric: 'tabular-nums' }}>{fmtPrice(r.price)}</span>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 2, fontFamily: FM, fontSize: 11.5,
          fontWeight: 600, color: up ? UP : DOWN, fontVariantNumeric: 'tabular-nums' }}>
          <SvgArrow up={up} size={11} color={up ? UP : DOWN} />
          {up ? '+' : ''}{r.chg.toFixed(2)}%
        </span>
      </div>);

  };

  const track = rows.map((r, i) => <Item key={'a' + i} r={r} i={i} />).
  concat(rows.map((r, i) => <Item key={'b' + i} r={r} i={i} />)); // duplicate for seamless loop

  return (
    <div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, height: 46, overflow: 'hidden',
      borderTop: `1px solid ${BORDER.subtle}`, background: 'rgba(255,255,255,0.72)',
      backdropFilter: 'blur(8px)', WebkitBackdropFilter: 'blur(8px)',
      display: 'flex', alignItems: 'center', maskImage: 'linear-gradient(90deg, transparent 0, #000 5%, #000 95%, transparent 100%)',
      WebkitMaskImage: 'linear-gradient(90deg, transparent 0, #000 5%, #000 95%, transparent 100%)' }}>
      <style>{`
        @keyframes ae-ticker { from { transform: translateX(0); } to { transform: translateX(-50%); } }
        .ae-ticker-track { display: inline-flex; align-items: center; white-space: nowrap;
          animation: ae-ticker 48s linear infinite; will-change: transform; }
        @media (prefers-reduced-motion: reduce){ .ae-ticker-track { animation: none; } }
      `}</style>
      <div className="ae-ticker-track">{track}</div>
    </div>);

}
window.Object.assign(window, { FM, DOWN, MarketTicker });


/* ============================================================ NAV */
function Nav({ accent }) {
  const a = acc(accent);
  const [scrolled, setScrolled] = React.useState(false);
  const [hov, setHov] = React.useState(null);
  React.useEffect(() => {
    const f = () => setScrolled(window.scrollY > 12);
    f();window.addEventListener('scroll', f, { passive: true });
    return () => window.removeEventListener('scroll', f);
  }, []);
  const page = window.location.pathname.split('/').pop() || 'index.html';
  const links = [
  { label: 'Solutions', href: 'services.html' },
  { label: 'About', href: 'about.html' },
  { label: 'Case study', href: 'case-study.html' }];

  return (
    <nav style={{ position: 'fixed', top: 0, left: 0, right: 0, zIndex: 100, height: 72,
      background: PAPER[1],
      borderBottom: `1px solid ${scrolled ? BORDER.subtle : 'transparent'}`,
      boxShadow: scrolled ? '0 1px 3px rgba(26,27,32,0.05)' : 'none',
      transition: 'all 280ms cubic-bezier(0.22,1,0.36,1)' }}>
      <div style={{ maxWidth: 1200, margin: '0 auto', padding: '0 32px', height: '100%',
        display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <a href="index.html" style={{ display: 'flex', alignItems: 'center', gap: 10, textDecoration: 'none' }}>
          <svg width="30" height="30" viewBox="0 0 48 48" fill="none">
            <polyline points="5,34 17,26 27,30 41,11" stroke={INK[1]} strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" />
            <circle cx="41" cy="11" r="5.5" fill={a.c} />
          </svg>
          <div style={{ fontFamily: FD, fontSize: 20, fontWeight: 700, letterSpacing: '-0.02em', lineHeight: 1 }}>
            <span style={{ color: INK[1] }}>Tr</span><span style={{ color: a.c }}>agentic</span>
          </div>
        </a>
        <div style={{ display: 'flex', alignItems: 'center', gap: 30 }}>
          {links.map((m) => {
            const active = m.href === page;
            return (
              <a key={m.label} href={m.href}
              onMouseEnter={() => setHov(m.label)} onMouseLeave={() => setHov(null)}
              style={{ position: 'relative', fontFamily: FB, fontSize: 14.5, fontWeight: 500,
                textDecoration: 'none', color: active || hov === m.label ? INK[1] : INK[2],
                transition: 'color 160ms', padding: '4px 0', textAlign: "right" }}>
                {m.label}
                {active && <span style={{ position: 'absolute', left: 0, right: 0, bottom: -4, height: 2,
                  borderRadius: 2, background: a.c }} />}
              </a>);

          })}
          <CTAButton accent={accent} small href="contact.html">Book a call</CTAButton>
        </div>
      </div>
    </nav>);

}

/* ============================================================ BUTTON */
function CTAButton({ accent, small, outline, children, onClick, href, icon }) {
  const a = acc(accent);
  const [hov, setHov] = React.useState(false);
  const base = {
    display: 'inline-flex', alignItems: 'center', gap: 8, fontFamily: FB, fontWeight: 600,
    cursor: 'pointer', border: 'none', textDecoration: 'none', whiteSpace: 'nowrap',
    transition: 'all 180ms cubic-bezier(0.22,1,0.36,1)',
    fontSize: small ? 14 : 15, padding: small ? '9px 18px' : '12px 26px', borderRadius: 10
  };
  const Tag = href ? 'a' : 'button';
  const extra = href ? { href } : { onClick, type: 'button' };
  const style = outline ?
  { ...base, background: hov ? PAPER[2] : PAPER[0], color: INK[1],
    border: `1px solid ${hov ? BORDER.strong : BORDER.default}` } :
  { ...base, background: hov ? a.h : a.c, color: '#fff',
    boxShadow: hov ? `0 8px 20px ${a.a20}` : '0 1px 2px rgba(26,27,32,0.10)',
    transform: hov ? 'translateY(-1px)' : 'none' };
  return (
    <Tag {...extra} style={style} onMouseEnter={() => setHov(true)} onMouseLeave={() => setHov(false)}>
      {icon && <i data-lucide={icon} style={{ width: small ? 15 : 17, height: small ? 15 : 17 }}></i>}
      {children}
    </Tag>);

}

/* ============================================================ EYEBROW */
function SectionLabel({ accent, children }) {
  return (
    <div style={{ fontFamily: FB, fontSize: 12, fontWeight: 600, letterSpacing: '0.1em',
      textTransform: 'uppercase', color: acc(accent).c, marginBottom: 14 }}>
      {children}
    </div>);

}

/* ============================================================ ICON CHIP */
function IconChip({ accent, icon, size = 44 }) {
  const a = acc(accent);
  return (
    <div style={{ width: size, height: size, borderRadius: Math.round(size / 4), flexShrink: 0,
      background: a.tint, border: `1px solid ${a.chip}`, color: a.c,
      display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
      <i data-lucide={icon} style={{ width: Math.round(size * 0.47), height: Math.round(size * 0.47) }}></i>
    </div>);

}

/* ============================================================ SERVICE CARD */
function ServiceCard({ accent, icon, title, desc, tag }) {
  const [hov, setHov] = React.useState(false);
  return (
    <div onMouseEnter={() => setHov(true)} onMouseLeave={() => setHov(false)}
    style={{ background: PAPER[0], border: `1px solid ${hov ? BORDER.strong : BORDER.subtle}`,
      borderRadius: 14, padding: 26, display: 'flex', flexDirection: 'column', gap: 14,
      boxShadow: hov ? '0 14px 40px rgba(26,27,32,0.08)' : '0 1px 3px rgba(26,27,32,0.05)',
      transform: hov ? 'translateY(-3px)' : 'none', transition: 'all 240ms cubic-bezier(0.22,1,0.36,1)', height: '100%' }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <IconChip accent={accent} icon={icon} />
        {tag && <span style={{ fontFamily: FB, fontSize: 11, fontWeight: 600, color: INK[3],
          border: `1px solid ${BORDER.default}`, borderRadius: 9999, padding: '3px 11px' }}>{tag}</span>}
      </div>
      <div style={{ fontFamily: FD, fontSize: 18, fontWeight: 700, color: INK[1], letterSpacing: '-0.01em' }}>{title}</div>
      <div style={{ fontFamily: FB, fontSize: 14, color: INK[3], lineHeight: 1.6 }}>{desc}</div>
    </div>);

}

/* ============================================================ PROBLEM CARD */
function ProblemCard({ accent, icon, title, desc, stat, statLabel }) {
  const a = acc(accent);
  const [hov, setHov] = React.useState(false);
  return (
    <div onMouseEnter={() => setHov(true)} onMouseLeave={() => setHov(false)}
    style={{ background: PAPER[0], border: `1px solid ${hov ? BORDER.strong : BORDER.subtle}`,
      borderRadius: 16, padding: '30px 28px', display: 'flex', flexDirection: 'column',
      justifyContent: 'space-between', gap: 22, height: '100%',
      boxShadow: hov ? '0 14px 40px rgba(26,27,32,0.07)' : '0 1px 3px rgba(26,27,32,0.05)',
      transform: hov ? 'translateY(-2px)' : 'none', transition: 'all 240ms cubic-bezier(0.22,1,0.36,1)' }}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
        <IconChip accent={accent} icon={icon} size={42} />
        <div style={{ fontFamily: FD, fontSize: 19, fontWeight: 700, color: INK[1], letterSpacing: '-0.01em', lineHeight: 1.25 }}>{title}</div>
        <div style={{ fontFamily: FB, fontSize: 14.5, color: INK[3], lineHeight: 1.6 }}>{desc}</div>
      </div>
      {stat &&
      <div style={{ paddingTop: 20, borderTop: `1px solid ${BORDER.subtle}` }}>
          <div style={{ fontFamily: FD, fontSize: 34, fontWeight: 800, color: a.c, lineHeight: 1, letterSpacing: '-0.03em' }}>{stat}</div>
          <div style={{ fontFamily: FB, fontSize: 13, color: INK[4], marginTop: 9, lineHeight: 1.5 }}>{statLabel}</div>
        </div>
      }
    </div>);

}

/* ============================================================ PIPELINE STEP */
function PipelineStep({ accent, n, title, desc, tags, last }) {
  const a = acc(accent);
  return (
    <div style={{ display: 'flex', gap: 22, position: 'relative' }}>
      <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', flexShrink: 0 }}>
        <div style={{ width: 46, height: 46, borderRadius: 12, background: a.tint, border: `1px solid ${a.chip}`,
          display: 'flex', alignItems: 'center', justifyContent: 'center', fontFamily: FD, fontSize: 15,
          fontWeight: 700, color: a.c, zIndex: 1 }}>{n}</div>
        {!last && <div style={{ width: 1.5, flex: 1, minHeight: 38, background: BORDER.default, marginTop: 4 }} />}
      </div>
      <div style={{ paddingBottom: last ? 0 : 34, flex: 1 }}>
        <div style={{ fontFamily: FD, fontSize: 19, fontWeight: 700, color: INK[1], letterSpacing: '-0.01em', marginBottom: 8 }}>{title}</div>
        <div style={{ fontFamily: FB, fontSize: 14.5, color: INK[3], lineHeight: 1.65, maxWidth: 560, marginBottom: tags ? 14 : 0 }}>{desc}</div>
        {tags &&
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
            {tags.map((t) =>
          <span key={t} style={{ fontFamily: FB, fontSize: 13, fontWeight: 500, color: INK[2],
            background: PAPER[2], border: `1px solid ${BORDER.default}`, borderRadius: 8, padding: '6px 12px' }}>{t}</span>
          )}
          </div>
        }
      </div>
    </div>);

}

/* ============================================================ ARCH DIAGRAM */
function ArchDiagram({ accent }) {
  const a = acc(accent);
  const nodes = [
  { label: 'Windows VPS', sub: 'MT5 + data EAs · 24/7', edge: 'WebRequest' },
  { label: 'Ubuntu VPS', sub: 'Self-hosted dashboard + REST APIs', edge: 'Webhook trigger' },
  { label: 'n8n', sub: 'Automation & data routing', edge: 'MCP · API' },
  { label: 'You', sub: 'Strategies · alerts · AI agents', edge: null }];

  return (
    <div style={{ background: PAPER[0], border: `1px solid ${BORDER.subtle}`, borderRadius: 16,
      padding: '22px 20px', boxShadow: '0 1px 3px rgba(26,27,32,0.05), 0 14px 40px rgba(26,27,32,0.05)' }}>
      <div style={{ fontFamily: FB, fontSize: 11.5, fontWeight: 600, letterSpacing: '0.1em',
        textTransform: 'uppercase', color: INK[4], marginBottom: 16 }}>Data flow</div>
      <div style={{ display: 'flex', flexDirection: 'column' }}>
        {nodes.map((nd, i) => {
          const lastNode = i === nodes.length - 1;
          return (
            <React.Fragment key={nd.label}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 12,
                background: lastNode ? a.tint : PAPER[1],
                border: `1px solid ${lastNode ? a.chip : BORDER.subtle}`, borderRadius: 11, padding: '12px 14px' }}>
                <span style={{ width: 8, height: 8, borderRadius: '50%', flexShrink: 0,
                  background: lastNode ? a.c : INK[4] }} />
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontFamily: FD, fontSize: 14.5, fontWeight: 700, color: INK[1] }}>{nd.label}</div>
                  <div style={{ fontFamily: FB, fontSize: 12, color: INK[3], marginTop: 1 }}>{nd.sub}</div>
                </div>
              </div>
              {nd.edge &&
              <div style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '7px 0 7px 18px' }}>
                  <i data-lucide="arrow-down" style={{ width: 13, height: 13, color: a.c }}></i>
                  <span style={{ fontFamily: FB, fontSize: 12, color: INK[4] }}>{nd.edge}</span>
                </div>
              }
            </React.Fragment>);

        })}
      </div>
    </div>);

}

/* ============================================================ API CARD */
function APICard({ accent, icon, title, desc, cat }) {
  const [hov, setHov] = React.useState(false);
  return (
    <div onMouseEnter={() => setHov(true)} onMouseLeave={() => setHov(false)}
    style={{ background: PAPER[0], border: `1px solid ${hov ? BORDER.strong : BORDER.subtle}`,
      borderRadius: 14, padding: '20px 20px', display: 'flex', flexDirection: 'column', gap: 11, height: '100%',
      boxShadow: hov ? '0 12px 32px rgba(26,27,32,0.07)' : '0 1px 3px rgba(26,27,32,0.05)',
      transform: hov ? 'translateY(-2px)' : 'none', transition: 'all 220ms cubic-bezier(0.22,1,0.36,1)' }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <IconChip accent={accent} icon={icon} size={36} />
        <span style={{ fontFamily: FB, fontSize: 11, fontWeight: 600, letterSpacing: '0.06em',
          textTransform: 'uppercase', color: INK[4] }}>{cat}</span>
      </div>
      <div style={{ fontFamily: FD, fontSize: 16, fontWeight: 700, color: INK[1], letterSpacing: '-0.01em', lineHeight: 1.3 }}>{title}</div>
      <div style={{ fontFamily: FB, fontSize: 13, color: INK[3], lineHeight: 1.55 }}>{desc}</div>
    </div>);

}

/* ============================================================ FORM */
function Field({ label, required, full, children }) {
  return (
    <label style={{ display: 'flex', flexDirection: 'column', gap: 7, gridColumn: full ? '1 / -1' : 'auto' }}>
      <span style={{ fontFamily: FB, fontSize: 12.5, fontWeight: 600, color: INK[2] }}>
        {label}{required && <span style={{ color: 'var(--accent)' }}> *</span>}
      </span>
      {children}
    </label>);

}
function AEInput({ placeholder, type = 'text' }) {
  return <input className="ae-input" type={type} placeholder={placeholder} />;
}
function AETextarea({ placeholder }) {
  return <textarea className="ae-input ae-textarea" placeholder={placeholder} rows={4} />;
}
function AESelect({ placeholder, options }) {
  return (
    <select className="ae-input ae-select" defaultValue="">
      <option value="" disabled>{placeholder}</option>
      {options.map((o) => <option key={o} value={o}>{o}</option>)}
    </select>);

}

/* ============================================================ LOGO WALL */
function LogoWall({ accent }) {
  const names = ['Meridian Capital', 'Northgate', 'Vela Markets', 'Arc Quant', 'Helios Fund', 'Tessellate'];
  return (
    <div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center', justifyContent: 'center', gap: '20px 48px' }}>
      {names.map((n) =>
      <span key={n} style={{ fontFamily: FD, fontSize: 19, fontWeight: 600, color: '#B6B3A9', letterSpacing: '-0.01em' }}>{n}</span>
      )}
    </div>);

}

/* ============================================================ PRODUCT MOCKUP (hero visual) */
// "Agent Reasoning in Progress" — 6 reasoning steps check off top→bottom, square-in-square
// spinner on the active step, automation progress bar climbs, then loops.

const CHIP_BLUE  = '#2563EB';
const CARD_GREEN = '#16A34A';
const REASON_STEPS = [
  'Context propagation complete',
  'Establishing inter-agent communication',
  'Executing parallel LLM tool calls',
  'Initiating retrieval-augmented reasoning',
  'Running constraint checks',
  'Verifying policy alignment',
];

/* dot-grid chip in card header */
function DotGridChip({ color = CHIP_BLUE }) {
  return (
    <div style={{ width: 34, height: 34, borderRadius: 8, flexShrink: 0,
      background: color, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
      <svg width="17" height="17" viewBox="0 0 18 18" fill="#fff">
        {[3,9,15].flatMap(x => [3,9,15].map(y => (
          <circle key={x+'-'+y} cx={x} cy={y} r="1.9" />
        )))}
      </svg>
    </div>
  );
}

/* 4 activity bars that wave smoothly like an equalizer (staggered CSS animation) */
function ActivityBars({ color = CHIP_BLUE }) {
  const bars = [
    { h: 13, d: '0s' },
    { h: 17, d: '0.12s' },
    { h: 14, d: '0.24s' },
    { h: 18, d: '0.36s' },
  ];
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 2.5, height: 18 }}>
      {bars.map((b, i) => (
        <div key={i} style={{ width: 3.5, height: b.h, borderRadius: 1, background: color,
          transformOrigin: 'center',
          animation: `bar-wave 1.1s ${b.d} ease-in-out infinite` }}/>
      ))}
    </div>
  );
}

/* square-inside-square spinner: outer square spins, filled inner square spins & pulses */
function SquareSpinner({ size = 20, color = CHIP_BLUE }) {
  const inner = Math.round(size * 0.42);
  return (
    <div style={{ width: size, height: size, flexShrink: 0, borderRadius: 0,
      border: `1.5px solid ${color}`, boxSizing: 'border-box',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      animation: 'sq-outer 1.15s linear infinite' }}>
      <div style={{ width: inner, height: inner, borderRadius: 0,
        background: color,
        animation: 'sq-spin 1.15s linear infinite' }}/>
    </div>
  );
}

function SmallLabel({ children, style }) {
  return (
    <div style={{ fontFamily: FB, fontSize: 10, fontWeight: 600, letterSpacing: '0.07em',
      textTransform: 'uppercase', color: INK[4], ...style }}>{children}</div>
  );
}

function InnerPanel({ children, style }) {
  return (
    <div style={{ background: PAPER[0], border: `1px solid ${BORDER.subtle}`,
      borderRadius: 10, padding: '16px 16px', ...style }}>{children}</div>
  );
}

/* ---- main card: "Agent Reasoning in Progress" ---- */
const REASON_FLOWS_FALLBACK = [{ title: 'Agent reasoning', trigger: 'Live', tagline: '', steps: REASON_STEPS }];

function ProductMockup({ accent, automations }) {
  const a = acc(accent);
  const C = a.c; // theme accent (follows Tweaks)
  const reduce = typeof window !== 'undefined' && window.matchMedia
    && window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  const flows = (automations && automations.length) ? automations : REASON_FLOWS_FALLBACK;
  const [flowIdx, setFlowIdx] = React.useState(0);
  const [checked, setChecked] = React.useState(0);
  const [phase, setPhase] = React.useState('in'); // 'in' (enter/run) | 'out' (leaving)

  const flow = flows[flowIdx];
  const TOTAL = flow.steps.length;
  const maxSteps = flows.reduce((m, f) => Math.max(m, f.steps.length), 0);

  React.useEffect(() => {
    if (reduce) { setChecked(flows[flowIdx].steps.length); return; }
    const timers = [];
    let n = 0;
    const total = flows[flowIdx].steps.length;
    setPhase('in');
    setChecked(0);
    const step = () => {
      if (n < total) { n += 1; setChecked(n); timers.push(setTimeout(step, 760)); }
      else {
        // hold the completed flow, then play it OUT and advance
        timers.push(setTimeout(() => {
          setPhase('out');
          timers.push(setTimeout(() => {
            // swap content + reset to enter state in one batch (no flash)
            setFlowIdx(i => (i + 1) % flows.length);
            setChecked(0);
            setPhase('in');
          }, 460));
        }, 1250));
      }
    };
    timers.push(setTimeout(step, 560));
    return () => { timers.forEach(clearTimeout); };
  }, [reduce, flowIdx, flows]);

  const complete  = checked >= TOTAL;
  const activeIdx = complete ? -1 : checked;
  const progress  = complete ? 100 : Math.round((checked / TOTAL) * 100);
  const contentAnim = reduce ? 'none'
    : phase === 'out' ? 'flow-out 460ms cubic-bezier(0.4,0,1,1) both'
    : 'flow-in 480ms cubic-bezier(0.22,1,0.36,1) both';

  return (
    <div style={{ width: '100%', maxWidth: 440 }}>
      <div style={{
        background: PAPER[1],
        border: `1px solid ${BORDER.subtle}`,
        borderRadius: 16,
        boxShadow: '0 1px 3px rgba(26,27,32,0.05), 0 20px 56px rgba(26,27,32,0.07)',
        padding: '18px 18px',
      }}>
        <style>{`
          @keyframes ae-pop{0%{transform:scale(.3);opacity:0}55%{transform:scale(1.14)}100%{transform:scale(1);opacity:1}}
          @keyframes sq-spin{0%{transform:rotate(0deg) scale(0.45)}50%{transform:rotate(180deg) scale(1)}100%{transform:rotate(360deg) scale(0.45)}}
          @keyframes sq-outer{to{transform:rotate(360deg)}}
          @keyframes bar-wave{0%,100%{transform:scaleY(0.22)}50%{transform:scaleY(0.62)}}
          @keyframes item-in{from{opacity:0;transform:translateX(10px)}to{opacity:1;transform:translateX(0)}}
          @keyframes flow-in{from{opacity:0;transform:translateY(-16px)}to{opacity:1;transform:translateY(0)}}
          @keyframes flow-out{from{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(16px)}}
          @media (prefers-reduced-motion: reduce){ [style*="bar-wave"],[style*="sq-spin"],[style*="sq-outer"]{animation:none !important} }
        `}</style>

        <div style={{ animation: contentAnim }}>
        {/* header */}
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 16, gap: 12 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, minWidth: 0 }}>
            <DotGridChip color={C}/>
            <span style={{ fontFamily: FD, fontSize: 14.5, fontWeight: 700, color: INK[1],
              letterSpacing: '-0.01em', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{flow.title}</span>
          </div>
          <span style={{ flexShrink: 0, fontFamily: FB, fontSize: 11, fontWeight: 600, color: C,
            background: a.tint, border: `1px solid ${a.chip}`, borderRadius: 9999,
            padding: '3px 10px', whiteSpace: 'nowrap' }}>{flow.trigger}</span>
        </div>

        {/* body */}
        <InnerPanel>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 11,
            minHeight: maxSteps * 20 + (maxSteps - 1) * 11 }}>
            {flow.steps.map((label, i) => {
              const done = i < checked;
              const active = i === activeIdx;
              const pending = !done && !active;
              return (
                <div key={`${flowIdx}-${done ? `d${i}` : `p${i}`}`}
                  style={{ display: 'flex', alignItems: 'center', gap: 11,
                    opacity: pending ? 0.32 : 1,
                    animation: done ? 'item-in 320ms cubic-bezier(0.22,1,0.36,1)' : 'none' }}>
                  {done ? (
                    <div style={{ width: 20, height: 20, borderRadius: 0, flexShrink: 0,
                      background: CARD_GREEN, display: 'flex', alignItems: 'center', justifyContent: 'center',
                      animation: 'ae-pop 320ms cubic-bezier(0.16,1,0.3,1)' }}>
                      <SvgCheck size={12} color="#fff"/>
                    </div>
                  ) : active ? <SquareSpinner size={20} color={C}/> : (
                    <div style={{ width: 20, height: 20, borderRadius: 0, flexShrink: 0,
                      border: `1.5px solid ${BORDER.default}` }}/>
                  )}
                  <span style={{ fontFamily: FB, fontSize: 13.5,
                    fontWeight: (done || active) ? 600 : 400,
                    color: active ? C : done ? INK[1] : INK[3] }}>{label}</span>
                </div>
              );
            })}
          </div>

          <div style={{ borderTop: `1px solid ${BORDER.subtle}`, marginTop: 16, paddingTop: 14 }}>
            <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 8 }}>
              <SmallLabel>Automation Progress</SmallLabel>
              <span style={{ fontFamily: FB, fontSize: 11.5, fontWeight: 700, color: C,
                fontVariantNumeric: 'tabular-nums' }}>{progress}%</span>
            </div>
            <div style={{ height: 6, borderRadius: 3, background: PAPER[3], overflow: 'hidden' }}>
              <div style={{ height: '100%', width: `${progress}%`, borderRadius: 3, background: C,
                transition: 'width 700ms cubic-bezier(0.22,1,0.36,1)' }}/>
            </div>
            <div style={{ fontFamily: FB, fontSize: 11.5, fontStyle: 'italic', color: INK[3], marginTop: 8,
              whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
              {complete ? 'Flow complete · queuing next' : flow.tagline || 'Running'}
            </div>
          </div>
        </InnerPanel>
        </div>
      </div>
    </div>
  );
}

/* ============================================================ FOOTER */
function FooterComp({ accent }) {
  const a = acc(accent);
  const cols = [
  ['Services', [['Market data', 'services.html'], ['Agentic workflows', 'services.html'], ['Automations', 'services.html'], ['Dashboard suite', 'services.html']]],
  ['Company', [['About', 'about.html'], ['Case study', 'case-study.html']]],
  ['Resources', [['FAQ', 'faq.html'], ['Book a call', 'contact.html']]]];

  return (
    <footer style={{ background: PAPER[0], borderTop: `1px solid ${BORDER.subtle}`, padding: '56px 32px 36px' }}>
      <div style={{ maxWidth: 1200, margin: '0 auto' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', flexWrap: 'wrap', gap: 40, marginBottom: 44 }}>
          <div style={{ maxWidth: 300 }}>
            <a href="index.html" style={{ display: 'flex', alignItems: 'center', gap: 9, marginBottom: 14, textDecoration: 'none' }}>
              <svg width="26" height="26" viewBox="0 0 48 48" fill="none">
                <polyline points="5,34 17,26 27,30 41,11" stroke={INK[1]} strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" />
                <circle cx="41" cy="11" r="5.5" fill={a.c} />
              </svg>
              <div style={{ fontFamily: FD, fontSize: 19, fontWeight: 700, letterSpacing: '-0.02em' }}>
                <span style={{ color: INK[1] }}>Tr</span><span style={{ color: a.c }}>agentic</span>
              </div>
            </a>
            <p style={{ fontFamily: FB, fontSize: 14, color: INK[3], lineHeight: 1.6 }}>
              Autonomous trading infrastructure, built for precision and scale.
            </p>
          </div>
          <div style={{ display: 'flex', gap: 56, flexWrap: 'wrap' }}>
            {cols.map(([title, links]) =>
            <div key={title}>
                <div style={{ fontFamily: FB, fontSize: 12, fontWeight: 600, letterSpacing: '0.08em',
                textTransform: 'uppercase', color: INK[4], marginBottom: 14 }}>{title}</div>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
                  {links.map(([label, href]) =>
                <a key={label} href={href} style={{ fontFamily: FB, fontSize: 14, color: INK[2],
                  textDecoration: 'none', whiteSpace: 'nowrap', transition: 'color 160ms' }}
                onMouseEnter={(e) => e.currentTarget.style.color = a.c}
                onMouseLeave={(e) => e.currentTarget.style.color = INK[2]}>{label}</a>
                )}
                </div>
              </div>
            )}
          </div>
        </div>
        <div style={{ borderTop: `1px solid ${BORDER.subtle}`, paddingTop: 22, display: 'flex',
          justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 12 }}>
          <span style={{ fontFamily: FB, fontSize: 13, color: INK[4] }}>© 2026 Tragentic. All rights reserved.</span>
          <span style={{ fontFamily: FB, fontSize: 13, color: INK[4] }}>Built for precision.</span>
        </div>
      </div>
    </footer>);

}

window.Object.assign(window, {
  Nav, CTAButton, SectionLabel, IconChip, ServiceCard, ProblemCard, PipelineStep,
  ArchDiagram, APICard, Field, AEInput, AETextarea, AESelect, LogoWall, ProductMockup, FooterComp
});