// Nav + Hero
// ============================================================
//   MEGA MENU — sourced 1:1 from QTG sitemap PDF (Section 6)
// ============================================================
const MENU = {
  platforms: {
    label: 'Platforms',
    coord: 'PLATFORMS / QUANT SUITE',
    meta: '06 PRODUCTS',
    layout: 'platforms',
    feature: {
      tag: 'OVERVIEW',
      title: 'The Operating Layer.',
      desc: 'Quant Suite is QTG\u2019s Operating Layer for\nProp Firms, Brokers, and Trading Organizations — Branded Platforms Running on One Normalized Core.',
      href: 'platforms.html',
      cta: 'Explore Quant Suite',
      glyph: 'platforms'
    },
    groups: [
    { label: 'Operator Platforms', items: [
      { k: 'YourPropFirm', d: 'Launch and Run a Prop Firm', href: 'yourpropfirm.html' },
      { k: 'Broker Infrastructure', d: 'Technology Infrastructure for Brokers', href: 'broker-infrastructure.html' }]
    },
    { label: 'Risk · CX · Payments', items: [
      { k: 'QuantSentry', d: 'Risk Monitoring and Surveillance', href: 'quantsentry.html' },
      { k: 'QuantCX', d: 'Customer Experience and Engagement', href: 'quantcx.html' }]
    },
    { label: 'Ecosystem', items: [
      { k: 'PropTradeGroup', d: 'A Managed White-Label Prop Firm', href: 'proptradegroup.html' },
      { k: 'TradoPay', d: 'Payments and Payout Infrastructure', href: 'tradopay.html' }]
    }]

  },
  applications: {
    label: 'Components',
    coord: 'COMPONENTS / FUNCTIONAL SURFACE',
    meta: '15 SURFACES · GROUPED',
    layout: 'cols-4',
    groups: [
    { label: 'Operations & Risk', items: [
      { k: 'Prop CRM', d: 'Built for Prop Firms', href: 'prop-crm.html' },
      { k: 'Broker CRM', d: 'Built for Brokerages', href: 'broker-crm.html' },
      { k: 'Risk & Rules Engine', d: 'Real-Time Scoring and Enforcement', href: 'risk-rules-engine.html' }]
    },
    { label: 'Commercial', items: [
      { k: 'Checkout System', d: 'A Conversion-Optimized Buyer Flow', href: 'checkout-system.html' },
      { k: 'Payments & Payouts', d: 'Multi-Rail Treasury and Payouts', href: 'payments-payouts.html' },
      { k: 'Affiliate & IB Management', d: 'Multi-Tier Affiliate Programs', href: 'affiliate-ib-management.html' },
      { k: 'Loyalty Program', d: 'Keep Traders Coming Back', href: 'loyalty-program.html' }]
    },
    { label: 'Trader Experience', items: [
      { k: 'Trader Dashboard', d: 'A Home Base for Traders', href: 'trader-dashboard.html' },
      { k: 'Trading Journal', d: 'Structured Performance Review', href: 'trading-journal.html' },
      { k: 'Trading Competitions', d: 'Leaderboards and Prize Pools', href: 'trading-competitions.html' },
      { k: 'Copy Trading', d: 'Distribute Trading Strategies', href: 'copy-trading.html' },
      { k: 'Algo Trading Tools', d: 'Automation and Execution Helpers', href: 'algo-trading-tools.html' }]
    },
    { label: 'Data & Intelligence', items: [
      { k: 'Business Intelligence', d: 'Group P&L and Cohorts', href: 'business-intelligence.html' },
      { k: 'Reports & Analytics', d: 'The Operator Reporting Plane', href: 'reports-analytics.html' },
      { k: 'AI Agents', d: 'Your Operations Copilot', href: 'ai-agents.html' }]
    }]

  },
  industries: {
    label: 'Industries',
    coord: 'INDUSTRIES / WHERE QTG OPERATES',
    meta: '07 SECTORS · LIVE',
    layout: 'cols-3',
    groups: [
    { label: 'Core Markets', items: [
      { k: 'Proprietary Trading Firms', d: 'Funded and Evaluation Models', href: 'industries/prop-trading-firms.html' },
      { k: 'Brokers', d: 'Multi-Asset Brokerages', href: 'industries/brokers.html' },
      { k: 'Fintech & Trading Platforms', d: 'Embedded and White-Label', href: 'industries/fintech-platforms.html' }]
    },
    { label: 'Trading Organizations', items: [
      { k: 'Trading Academies & Communities', d: 'Education and Trading Cohorts', href: 'industries/academies-communities.html' },
      { k: 'Professional Trading Teams', d: 'Internal Trading Desks and Pods', href: 'industries/professional-teams.html' }]
    },
    { label: 'Institutional & Infrastructure', items: [
      { k: 'Funds & Asset Managers', d: 'Pooled Capital and Allocators', href: 'industries/funds-asset-managers.html' },
      { k: 'Liquidity Providers', d: 'Connectivity and Routing', href: 'industries/liquidity-providers.html' }]
    }]

  },
  services: {
    label: 'Services',
    coord: 'SERVICES / TEAMS BEHIND THE PLATFORMS',
    meta: '04 LINES · 24/7',
    layout: 'cols-2',
    feature: {
      tag: 'ENGINEERING',
      title: 'Custom Trading Technology',
      desc: 'Bespoke builds on the Quant Suite core — platform, web, app, UI/UX, integrations, and migration.',
      href: 'services.html#engineering-customization',
      cta: 'See Engineering Practice',
      glyph: 'services'
    },
    groups: [
    { label: 'Service Lines', cols: 2, items: [
      { k: 'Dedicated Tech Teams', d: 'Embedded Engineering Pods', href: 'dedicated-tech-teams.html' },
      { k: 'Customer Support Service', d: '24/7 Trader-Side Support', href: 'customer-support-service.html' },
      { k: 'Technical Support', d: 'Operator-Grade L2 and L3', href: 'technical-support.html' },
      { k: 'Custom Trading Technology', d: 'Bespoke Builds on the QTG Core', href: 'custom-trading-technology.html' }]
    }]

  },
  insights: {
    label: 'News & Insights',
    coord: 'NEWS & INSIGHTS / EDITORIAL',
    meta: 'ONE HUB · MANY CATEGORIES',
    layout: 'cols-2',
    feature: {
      tag: 'LATEST',
      title: 'All News & Insights',
      desc: 'Company news, industry insights, product updates, events. One hub, browse by category.',
      href: 'insights.html',
      cta: 'Open the Hub',
      glyph: 'insights'
    },
    groups: [
    { label: 'Categories', cols: 2, items: [
      { k: 'Company News', d: 'News From Inside QTG', href: 'insights.html#company' },
      { k: 'Industry Insights', d: 'Operator-Grade Analysis', href: 'insights.html#industry' },
      { k: 'Product Updates', d: 'What Shipped, and When', href: 'insights.html#product' },
      { k: 'Event Recaps', d: 'From the Expo Floor', href: 'insights.html#event' }]
    }]

  },
  company: {
    label: 'Company',
    coord: 'COMPANY / QUANT TECHNOLOGY GROUP',
    meta: '04 SECTIONS · LIVE',
    layout: 'cols-2',
    feature: {
      tag: 'ABOUT',
      title: 'About QTG',
      desc: 'The team and story behind QTG — operators building infrastructure for operators.',
      href: 'company.html',
      cta: 'Inside QTG',
      glyph: 'company'
    },
    groups: [
    { label: 'Pages', cols: 2, items: [
      { k: 'About QTG', d: 'Who We Are and How We Operate', href: 'company.html' },
      { k: 'Integrated Partners', d: 'Our Ecosystem of Partners', href: 'partners.html' },
      { k: 'Expos & Events', d: 'Where QTG Shows Up', href: 'events.html' },
      { k: 'Contact', d: 'Talk to a QTG Operator', href: 'contact.html' }]
    }]

  }
};

// ============================================================
//   Feature glyphs — one per mega-menu feature card
// ============================================================
const FeatureGlyph = ({ kind }) => {
  const accent = 'rgba(0,255,255,0.55)';
  const dim = 'rgba(0,255,255,0.18)';
  const faint = 'rgba(0,255,255,0.10)';
  if (kind === 'platforms') {
    // Simple six-tile grid — reads cleanly at small sizes.
    // Tiles fade in around a steady core; a pulse sweeps the foundation bar.
    const tiles = [
    { x: 30, y: 40, d: 0.0 },
    { x: 84, y: 40, d: 0.15 },
    { x: 138, y: 40, d: 0.30 },
    { x: 30, y: 90, d: 0.45 },
    { x: 84, y: 90, d: 0.60 },
    { x: 138, y: 90, d: 0.75 }];

    return (
      <svg className="ft-glyph ft-glyph-platforms" viewBox="0 0 200 200" fill="none">
        <defs>
          <linearGradient id="pf-found" x1="0" y1="0" x2="1" y2="0">
            <stop offset="0" stopColor="rgba(0,255,255,0)" />
            <stop offset="0.5" stopColor="rgba(0,255,255,0.9)" />
            <stop offset="1" stopColor="rgba(0,255,255,0)" />
          </linearGradient>
        </defs>

        {tiles.map((t, i) =>
        <rect key={i} className="pf-tile" style={{ animationDelay: `${t.d}s` }}
        x={t.x} y={t.y} width="32" height="32" rx="4"
        fill="rgba(0,255,255,0.08)" stroke={accent} strokeWidth="1.2" />
        )}

        {/* Foundation bar */}
        <rect x="30" y="150" width="140" height="14" rx="3"
        fill="rgba(0,255,255,0.06)" stroke={accent} strokeWidth="1.1" />

        {/* Pulse traveling along foundation */}
        <rect className="pf-pulse" x="30" y="150" width="40" height="14" rx="3"
        fill="url(#pf-found)" opacity="0.7" />
      </svg>);

  }
  if (kind === 'services') {
    // Embedded pods plugging into a central spine.
    // Reads well at small sizes — bars cycling on/off feels like teams "plugging in".
    return (
      <svg className="ft-glyph ft-glyph-services" viewBox="0 0 200 200" fill="none">
        {/* Central spine */}
        <line x1="100" y1="30" x2="100" y2="170" stroke={accent} strokeWidth="1.2" opacity="0.7" />
        <circle cx="100" cy="30" r="3" fill={accent} />
        <circle cx="100" cy="170" r="3" fill={accent} />

        {/* Four embedded team bars — alternating sides, staggered */}
        {[
        { y: 50, side: 'L', d: 0.0 },
        { y: 84, side: 'R', d: 0.25 },
        { y: 118, side: 'L', d: 0.5 },
        { y: 152, side: 'R', d: 0.75 }].
        map((p, i) => {
          const isL = p.side === 'L';
          const x = isL ? 30 : 100;
          return (
            <g key={i} className="svc-pod" style={{ animationDelay: `${p.d}s` }}>
              <rect x={x} y={p.y - 8} width="70" height="16" rx="3"
              fill="rgba(0,255,255,0.06)" stroke={accent} strokeWidth="1" />
              <circle cx={isL ? 36 : 164} cy={p.y} r="2.6" fill={accent} />
              <line x1={isL ? 44 : 110} y1={p.y - 2} x2={isL ? 78 : 144} y2={p.y - 2}
              stroke={accent} strokeWidth="0.8" opacity="0.9" />
              <line x1={isL ? 44 : 110} y1={p.y + 3} x2={isL ? 70 : 136} y2={p.y + 3}
              stroke={dim} strokeWidth="0.7" />
            </g>);

        })}
      </svg>);

  }
  if (kind === 'insights') {
    // Clean editorial feed — three cards, soft float, single sweep.
    return (
      <svg className="ft-glyph ft-glyph-insights" viewBox="0 0 200 200" fill="none">
        <defs>
          <linearGradient id="ins-sweep" x1="0" y1="0" x2="1" y2="0">
            <stop offset="0" stopColor="rgba(0,255,255,0)" />
            <stop offset="0.5" stopColor="rgba(0,255,255,0.55)" />
            <stop offset="1" stopColor="rgba(0,255,255,0)" />
          </linearGradient>
          <clipPath id="ins-clip"><rect x="20" y="34" width="140" height="132" rx="6" /></clipPath>
        </defs>

        {/* Three editorial cards — top one is "active" */}
        <g clipPath="url(#ins-clip)">
          <g className="ins-card ins-card-1">
            <rect x="28" y="46" width="124" height="22" rx="4"
            fill="rgba(0,255,255,0.05)" stroke={accent} strokeWidth="0.9" />
            <line x1="38" y1="55" x2="98" y2="55" stroke={accent} strokeWidth="1" />
            <line x1="38" y1="61" x2="78" y2="61" stroke={dim} strokeWidth="0.8" />
          </g>
          <g className="ins-card ins-card-2">
            <rect x="32" y="80" width="120" height="22" rx="4"
            stroke={dim} strokeWidth="0.8" />
            <line x1="42" y1="89" x2="92" y2="89" stroke={dim} strokeWidth="0.8" />
            <line x1="42" y1="95" x2="74" y2="95" stroke={faint} strokeWidth="0.7" />
          </g>
          <g className="ins-card ins-card-3">
            <rect x="36" y="114" width="116" height="22" rx="4"
            stroke={faint} strokeWidth="0.7" />
            <line x1="46" y1="123" x2="86" y2="123" stroke={faint} strokeWidth="0.7" />
            <line x1="46" y1="129" x2="68" y2="129" stroke={faint} strokeWidth="0.6" />
          </g>

          {/* Single elegant sweep across the active card */}
          <rect className="ins-sweep" x="-60" y="46" width="60" height="22" rx="4" fill="url(#ins-sweep)" />
        </g>

        {/* Right-side category rail */}
        <g transform="translate(174, 50)">
          <line x1="0" y1="0" x2="0" y2="100" stroke={faint} strokeWidth="0.7" />
          <g className="ins-active-dot">
            <circle r="6.5" fill="none" stroke={accent} strokeWidth="0.6" className="ins-ring" />
            <circle r="3" fill={accent} />
          </g>
          <circle cy="32" r="2" fill={dim} />
          <circle cy="60" r="2" fill={dim} />
          <circle cy="88" r="2" fill={faint} />
        </g>
      </svg>);

  }
  if (kind === 'company') {
    // Simple org tree — one parent node, three child nodes connected by lines.
    // Reads as "company / group structure" and matches the line-art style of
    // platforms / services / insights.
    return (
      <svg className="ft-glyph ft-glyph-company" viewBox="0 0 200 200" fill="none">
        {/* Connector trunk */}
        <line x1="100" y1="62" x2="100" y2="100" stroke={accent} strokeWidth="1.2" />
        {/* Horizontal bus */}
        <line x1="40" y1="100" x2="160" y2="100" stroke={accent} strokeWidth="1.2" />
        {/* Drop lines to children */}
        <line x1="40" y1="100" x2="40" y2="128" stroke={accent} strokeWidth="1.2" />
        <line x1="100" y1="100" x2="100" y2="128" stroke={accent} strokeWidth="1.2" />
        <line x1="160" y1="100" x2="160" y2="128" stroke={accent} strokeWidth="1.2" />

        {/* Parent node — the group */}
        <rect x="68" y="34" width="64" height="28" rx="4"
        fill="rgba(0,255,255,0.10)" stroke={accent} strokeWidth="1.2"
        className="co-parent" />
        <line x1="80" y1="46" x2="120" y2="46" stroke={accent} strokeWidth="1.1" />
        <line x1="80" y1="52" x2="108" y2="52" stroke={dim} strokeWidth="0.9" />

        {/* Three child nodes — staggered fade */}
        {[
        { x: 16, d: 0.0 },
        { x: 76, d: 0.25 },
        { x: 136, d: 0.50 }].
        map((c, i) =>
        <g key={i} className="co-child" style={{ animationDelay: `${c.d}s` }}>
            <rect x={c.x} y="128" width="48" height="36" rx="4"
          fill="rgba(0,255,255,0.05)" stroke={accent} strokeWidth="1" />
            <line x1={c.x + 8} y1="140" x2={c.x + 36} y2="140" stroke={accent} strokeWidth="0.9" />
            <line x1={c.x + 8} y1="148" x2={c.x + 28} y2="148" stroke={dim} strokeWidth="0.8" />
            <line x1={c.x + 8} y1="155" x2={c.x + 32} y2="155" stroke={faint} strokeWidth="0.7" />
          </g>
        )}

        {/* Junction dots */}
        <circle cx="40" cy="100" r="2.2" fill={accent} />
        <circle cx="100" cy="100" r="2.6" fill={accent} className="co-hub" />
        <circle cx="160" cy="100" r="2.2" fill={accent} />
      </svg>);

  }
  return null;
};

const MEGA_KEYS = ['platforms', 'applications', 'industries', 'services', 'insights', 'company'];

// ============================================================
//   Top announcement bar — auto-rotating (crossfade)
// ============================================================
const ANNOUNCEMENTS = [
  { html: '<b>QuantSentry</b> is now generally available — AI-native risk infrastructure.',
    cta: 'Read the announcement', href: 'insights/quant-technology-group-launches-quantsentry.html' },
  { html: 'Meet QTG at <b>iFX EXPO Cyprus</b> \uD83C\uDDE8\uD83C\uDDFE · Jun 16–18 · Limassol.',
    cta: 'Book a meeting', href: 'contact.html' },
];
const AnnouncementBar = () => {
  const [i, setI] = React.useState(0);
  const [paused, setPaused] = React.useState(false);
  const base = (window.QTG_BASE || '');
  React.useEffect(() => {
    if (paused || ANNOUNCEMENTS.length < 2) return;
    const t = setInterval(() => setI((n) => (n + 1) % ANNOUNCEMENTS.length), 7500);
    return () => clearInterval(t);
  }, [paused]);
  return (
    <div className="qtg-abar" onMouseEnter={() => setPaused(true)} onMouseLeave={() => setPaused(false)}>
      {ANNOUNCEMENTS.map((a, k) => (
        <div key={k} className={'aba-slide' + (k === i ? ' on' : '')} aria-hidden={k !== i}>
          <span className="aba-dot" />
          <span className="aba-msg" dangerouslySetInnerHTML={{ __html: a.html }} />
          <a className="aba-lk" href={base + a.href}>{a.cta} <ArrowRight /></a>
        </div>
      ))}
      <div className="aba-dots">
        {ANNOUNCEMENTS.map((a, k) => (
          <button key={k} className={k === i ? 'on' : ''} aria-label={'Show announcement ' + (k + 1)} onClick={() => setI(k)} />
        ))}
      </div>
    </div>
  );
};

const Nav = () => {
  const [open, setOpen] = React.useState(null); // current key
  const closeTimer = React.useRef(null);

  const enter = (k) => {
    if (closeTimer.current) {clearTimeout(closeTimer.current);closeTimer.current = null;}
    setOpen(k);
  };
  const leave = () => {
    if (closeTimer.current) clearTimeout(closeTimer.current);
    closeTimer.current = setTimeout(() => setOpen(null), 320);
  };

  React.useEffect(() => {
    const onKey = (e) => {if (e.key === 'Escape') setOpen(null);};
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);

  return (
    <>
      <AnnouncementBar />
      <nav className="nav" onMouseLeave={leave}>
        <div className="container nav-inner">
          <a className="brand" href="index.html">
            <img src={(window.__resources && window.__resources.logo) || (window.QTG_BASE || '') + "assets/qtg-lockup-white.png"} alt="Quant Technology Group" style={{ height: 32, display: 'block' }} />
          </a>
          <div className="nav-links" onMouseLeave={leave}>
            {MEGA_KEYS.map((k) =>
            <a key={k}
            className={`nav-link ${open === k ? 'is-open' : ''}`}
            href={k === 'platforms' ? 'platforms.html' :
            k === 'applications' ? 'components.html' :
            k === 'industries' ? 'industries.html' :
            k === 'services' ? 'services.html' :
            k === 'company' ? 'company.html' : 'insights.html'}
            onMouseEnter={() => enter(k)}
            onFocus={() => enter(k)}>
              
                {MENU[k].label}
                <svg className="caret" viewBox="0 0 8 8" fill="none">
                  <path d="M1.5 3 L4 5.5 L6.5 3" stroke="currentColor" strokeWidth="1" strokeLinecap="square" />
                </svg>
              </a>
            )}
          </div>
          <div className="nav-cta">
            <a className="btn btn-primary btn-sm" href="contact.html">Contact<span className="nav-cta-suffix">QTG</span> <ArrowRight /></a>
          </div>
        </div>

        {/* Mega panels: siblings of .nav-inner so they span full nav width */}
        {MEGA_KEYS.map((k) =>
        <div key={k}
        className={`mega ${open === k ? 'is-open' : ''}`}
        onMouseEnter={() => enter(k)}
        onMouseLeave={leave}>
          
            <MegaPanel data={MENU[k]} />
          </div>
        )}
      </nav>

      <div className={`mega-backdrop ${open ? 'is-open' : ''}`} onClick={() => setOpen(null)} />
    </>);

};

const MegaPanel = ({ data }) => {
  const colsClass =
  data.layout === 'platforms' ? 'cols-platforms' :
  data.layout === 'cols-2' ? 'cols-2' :
  data.layout === 'cols-3' ? 'cols-3' :
  data.layout === 'cols-4' ? 'cols-4' : 'cols-3';

  // For the platforms layout we render the feature card as the first column.
  const renderFeature = (data.layout === 'platforms' || data.feature) && data.feature;

  return (
    <div className="mega-inner">
      <div className="mega-head">
        <span className="coord">— <b>{data.coord.split(' / ')[0]}</b> / {data.coord.split(' / ').slice(1).join(' / ')}</span>
      </div>
      <div className={`mega-grid ${colsClass}`}>
        {renderFeature &&
        <a className="mega-feature" href={data.feature.href}>
            {data.feature.glyph && <FeatureGlyph kind={data.feature.glyph} />}
            {data.feature.tag && <span className="ft-tag">{data.feature.tag}</span>}
            <h4>{data.feature.title}</h4>
            <p style={{whiteSpace:'pre-line'}}>{data.feature.desc}</p>
            <span className="ft-arrow" aria-hidden="true"><ArrowRight /></span>
          </a>
        }
        {data.groups.map((g, gi) =>
        <div key={gi} className="mega-group">
            <div className="mega-group-label">{g.label}</div>
            <div style={g.cols === 2 ? { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px 24px' } : { display: 'flex', flexDirection: 'column', gap: 6 }}>
            {g.items.map((it, ii) =>
            <a key={ii} href={it.href} className="mega-item">
                <span>
                  <span style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                    <span style={{ width: 4, height: 4, borderRadius: '50%', background: 'rgba(0,255,255,0.55)', flexShrink: 0 }} />
                    <span className="k">{it.k}</span>
                  </span>
                  {it.d && <span className="d" style={{ display: 'block', paddingLeft: 10 }}>{it.d}</span>}
                </span>
                <span className="arr"><ArrowRight /></span>
              </a>
            )}
            </div>
          </div>
        )}
      </div>
    </div>);

};


const Ticker = () => {
  const items = [
  { sym: 'INFRA', v: '225,431', d: 'Accounts Under Management', dir: 'pos' },
  { sym: 'RISK', v: '14.2ms', d: 'Avg Event Latency', dir: 'pos' },
  { sym: 'OPS', v: '$450.8M', d: 'Group Client Revenue Powered', dir: 'pos' },
  { sym: 'NODES', v: '126', d: 'Integrations Live', dir: 'pos' },
  { sym: 'AI', v: '2.1B', d: 'Risk Events Scored / mo', dir: 'pos' },
  { sym: 'UPTIME', v: '99.98%', d: '30-Day Rolling', dir: 'pos' },
  { sym: 'CLIENTS', v: '125+', d: 'Clients Operating', dir: 'pos' },
  { sym: 'GLOBAL', v: '10 / 24', d: 'Locations · Timezone Cover', dir: 'pos' }];

  const Track = () =>
  <div className="ticker-track">
      {items.map((it, i) =>
    <div className="ticker-item" key={i}>
          <span className="sym">{it.sym}</span>
          <span className="v">{it.v}</span>
          <span>{it.d}</span>
          <span className={it.dir}>●</span>
        </div>
    )}
    </div>;

  return <div className="ticker"><Track /><Track /></div>;
};

const Hero = () => {
  const gridRef = React.useRef(null);
  const metaRef = React.useRef(null);
  React.useEffect(() => {
    const fit = () => {
      const grid = gridRef.current, meta = metaRef.current;
      if (!grid || !meta) return;
      const top = grid.parentElement.getBoundingClientRect().top;
      const mTop = meta.getBoundingClientRect().top;
      grid.style.height = Math.max(0, mTop - top - 28) + 'px';
    };
    fit();
    const t1 = setTimeout(fit, 200);
    const t2 = setTimeout(fit, 600);
    window.addEventListener('resize', fit);
    return () => { window.removeEventListener('resize', fit); clearTimeout(t1); clearTimeout(t2); };
  }, []);
  return (
<section className="hero hero-home-centered">
    <div className="hero-grid-bg" ref={gridRef} style={{bottom:'auto'}} />
    <div className="hero-glow" />
    <div className="container hero-inner">
      <div className="hero-pill">
        <span className="tag">QTG</span>
        <span>Modular Trading Infrastructure</span>
      </div>
      <h1 style={{fontSize:'clamp(48px, 6vw, 78px)'}}>
        Building the <i className="accent">Infrastructure layer</i> for Modern Trading.
      </h1>
      <p className="hero-sub" style={{fontSize:17}}>
        Modular infrastructure for prop firms, brokers, and fintech platforms &mdash; operations, risk, automation, and AI on one connected core.
      </p>
      <div className="hero-ctas">
        <a className="btn btn-primary" href="#platforms">Explore Platforms <ArrowRight /></a>
        <a className="btn btn-ghost" href="#contact">Partner With QTG</a>
      </div>
      <div className="hero-meta" ref={metaRef}>
        <div className="hero-meta-item"><span className="k">Founded</span><span className="v">2022</span></div>
        <div className="hero-meta-item"><span className="k">Team headcount</span><span className="v">65<span className="accent">+</span></span></div>
        <div className="hero-meta-item"><span className="k">Clients worldwide</span><span className="v">125<span className="accent">+</span></span></div>
        <div className="hero-meta-item"><span className="k">End-users served</span><span className="v">2.6M<span className="accent">+</span></span></div>
      </div>
      <HeroDashboard />
    </div>
  </section>
  );
};


// HERO DASHBOARD MOCK
const HeroDashboard = () =>
<div className="hero-product">
    <div className="dash">
      <div className="dash-chrome">
        <div className="traffic"><span /><span /><span /></div>
        <div className="dash-tabs">
          <span className="dash-tab active">OVERVIEW</span>
          <span className="dash-tab">RISK</span>
          <span className="dash-tab">ACCOUNTS</span>
          <span className="dash-tab">PAYOUTS</span>
          <span className="dash-tab">SUPPORT</span>
        </div>
        <div className="mono" style={{ fontSize: 11, color: 'var(--text-3)' }}>qtg.cloud / yourpropfirm · prod-eu-1</div>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: '1.1fr 1.5fr 1fr', borderTop: '1px solid var(--line)' }}>
        <DashSidebar />
        <DashMainChart />
        <DashRiskFeed />
      </div>
      <DashBottomStrip />
    </div>
  </div>;


// Reduced motion check
const usePrefersReducedMotion = () => {
  const [reduced, setReduced] = React.useState(false);
  React.useEffect(() => {
    const m = window.matchMedia('(prefers-reduced-motion: reduce)');
    setReduced(m.matches);
    const h = (e) => setReduced(e.matches);
    m.addEventListener?.('change', h);
    return () => m.removeEventListener?.('change', h);
  }, []);
  return reduced;
};

// Visibility-aware interval — pauses when tab is hidden.
// (We deliberately do NOT gate this on prefers-reduced-motion: the live data
// IS the content here, while the visual flourishes — pulses, slide-ins,
// transitions — are gated separately via CSS @media rules.)
const useLiveInterval = (fn, ms) => {
  React.useEffect(() => {
    let id = null;
    const start = () => {if (id == null) id = setInterval(fn, ms);};
    const stop = () => {if (id != null) {clearInterval(id);id = null;}};
    const onVis = () => document.hidden ? stop() : start();
    start();
    document.addEventListener('visibilitychange', onVis);
    return () => {stop();document.removeEventListener('visibilitychange', onVis);};
  }, [fn, ms]);
};

const DashSidebar = () => {
  // Risk index slowly drifts within the "normal" band (0.39 – 0.47)
  const [risk, setRisk] = React.useState(0.42);
  const [trader, setTrader] = React.useState(24182);
  const [payouts, setPayouts] = React.useState(46);
  const [overview, setOverview] = React.useState(12);
  const [challenges, setChallenges] = React.useState(3402);
  const [accounts, setAccounts] = React.useState(225431);
  const [queued, setQueued] = React.useState(1.24);
  const [affiliates, setAffiliates] = React.useState(892);
  const [support, setSupport] = React.useState(12);
  useLiveInterval(React.useCallback(() => {
    setRisk((r) => {
      const next = r + (Math.random() - 0.5) * 0.022;
      return Math.max(0.39, Math.min(0.47, next));
    });
    setTrader((t) => t + Math.floor(Math.random() * 7 + 1));
    if (Math.random() < 0.45) setPayouts((p) => Math.max(40, Math.min(58, p + (Math.random() < 0.55 ? 1 : -1))));
    if (Math.random() < 0.55) setOverview((o) => Math.max(8, Math.min(18, o + (Math.random() < 0.5 ? -1 : 1))));
    setChallenges((c) => Math.max(3380, Math.min(3445, c + Math.floor((Math.random() - 0.4) * 7))));
    setAccounts((a) => a + Math.floor(Math.random() * 22 + 4));
    if (Math.random() < 0.45) setQueued((q) => +Math.max(1.10, Math.min(1.38, q + (Math.random() - 0.45) * 0.022)).toFixed(2));
    if (Math.random() < 0.30) setAffiliates((a) => a + (Math.random() < 0.7 ? 1 : 0));
    if (Math.random() < 0.40) setSupport((s) => Math.max(8, Math.min(18, s + (Math.random() < 0.55 ? -1 : 1))));
  }, []), 900);
  const riskPct = Math.round((risk - 0.30) / (0.70 - 0.30) * 100);
  const status = risk < 0.45 ? 'NORMAL' : risk < 0.55 ? 'ELEVATED' : 'HIGH';
  const statusColor = risk < 0.45 ? 'var(--accent)' : risk < 0.55 ? 'var(--warn)' : 'var(--danger)';

  const items = [
  ['Overview', String(overview)],
  ['Traders', trader.toLocaleString()],
  ['Challenges', challenges.toLocaleString() + ' active'],
  ['Accounts', accounts.toLocaleString()],
  ['Payouts', '$' + queued.toFixed(2) + 'M queued'],
  ['Risk alerts', payouts + ' / live'],
  ['Affiliates', affiliates.toLocaleString()],
  ['Support', support + ' open'],
  ['Reporting', '—']];


  return (
    <div style={{ padding: '24px', borderRight: '1px solid var(--line)' }}>
      <div className="kicker" style={{ marginBottom: 18 }}>OPERATING SYSTEM</div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
        {items.map(([k, v], i) =>
        <div key={i} style={{ display: 'flex', justifyContent: 'space-between', padding: '7px 10px', borderRadius: 6,
          background: i === 5 ? 'var(--accent-faint)' : 'transparent',
          color: i === 5 ? 'var(--accent)' : 'var(--text-2)' }}>
            <span style={{ fontSize: 13 }}>{k}</span>
            <span className="mono" style={{ fontSize: 11, color: i === 5 ? 'var(--accent)' : 'var(--text-3)', transition: 'color 0.4s' }}>{v}</span>
          </div>
        )}
      </div>
      <div style={{ marginTop: 24, padding: 14, border: '1px solid var(--line)', borderRadius: 8, background: 'rgba(255,255,255,0.015)' }}>
        <div className="kicker" style={{ fontSize: 10, color: 'var(--text-3)', display: 'flex', alignItems: 'center', gap: 6 }}>
          <span style={{
            width: 5, height: 5, borderRadius: '50%', background: 'var(--accent)',
            animation: 'qtgPulse 1.6s ease-in-out infinite',
            boxShadow: '0 0 0 0 rgba(0,255,255,0.5)'
          }} />
          QUANTSENTRY · LIVE
        </div>
        <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, marginTop: 8 }}>
          <span style={{ fontSize: 28, fontFamily: 'var(--font-sans)', letterSpacing: '-0.02em', fontVariantNumeric: 'tabular-nums' }}>{risk.toFixed(2)}</span>
          <span className="mono" style={{ fontSize: 11, color: statusColor, transition: 'color 0.4s' }}>RISK INDEX · {status}</span>
        </div>
        <div style={{ height: 4, background: 'rgba(255,255,255,0.05)', borderRadius: 2, marginTop: 10, position: 'relative', overflow: 'hidden' }}>
          <div style={{ position: 'absolute', left: 0, top: 0, height: '100%', width: riskPct + '%', background: statusColor, borderRadius: 2, transition: 'width 1.2s ease-out, background 0.4s' }} />
        </div>
      </div>
    </div>);

};

const buildCandle = (i, prevClose) => {
  const base = prevClose != null ? prevClose : 50 + Math.sin(i / 4) * 18 + i * 0.6;
  const drift = (Math.random() - 0.48) * 3.2;
  const o = base;
  const c = base + drift + Math.sin(i * 1.3) * 1.5;
  const h = Math.max(o, c) + Math.random() * 4 + 1.5;
  const l = Math.min(o, c) - Math.random() * 4 - 1.5;
  return { o, c, h, l };
};

const DashMainChart = () => {
  // Build initial candle-like series
  const initial = React.useMemo(() => {
    const arr = [];
    let prev = null;
    for (let i = 0; i < 48; i++) {
      const base = 50 + Math.sin(i / 4) * 18 + i * 0.6;
      const o = base + Math.sin(i * 1.7) * 4;
      const c = base + Math.cos(i * 1.3) * 5;
      const h = Math.max(o, c) + Math.abs(Math.sin(i * 0.9)) * 4 + 2;
      const l = Math.min(o, c) - Math.abs(Math.cos(i * 0.7)) * 4 - 2;
      arr.push({ o, c, h, l });
      prev = c;
    }
    return arr;
  }, []);

  const [candles, setCandles] = React.useState(initial);
  const [revenue, setRevenue] = React.useState(3.842);
  const [pct, setPct] = React.useState(18.4);
  const [traders, setTraders] = React.useState(24182);
  const [payout, setPayout] = React.useState(2840);
  const [tickets, setTickets] = React.useState(98.2);
  const idxRef = React.useRef(48);

  // Tick the *last* candle every ~900ms (live price action)
  useLiveInterval(React.useCallback(() => {
    setCandles((prev) => {
      const next = prev.slice();
      const last = { ...next[next.length - 1] };
      last.c += (Math.random() - 0.5) * 1.4;
      last.h = Math.max(last.h, last.c + Math.random() * 0.6);
      last.l = Math.min(last.l, last.c - Math.random() * 0.6);
      next[next.length - 1] = last;
      return next;
    });
    setRevenue((r) => +(r + (Math.random() - 0.45) * 0.004).toFixed(3));
    setPct((p) => +(p + (Math.random() - 0.5) * 0.08).toFixed(1));
  }, []), 900);

  // Append a brand-new candle every ~6s, drop oldest
  useLiveInterval(React.useCallback(() => {
    setCandles((prev) => {
      const last = prev[prev.length - 1];
      const fresh = buildCandle(idxRef.current++, last.c);
      return [...prev.slice(1), fresh];
    });
    setTraders((t) => t + Math.floor(Math.random() * 8 + 1));
    setPayout((p) => p + Math.floor((Math.random() - 0.4) * 6));
    setTickets((tk) => +Math.max(96.5, Math.min(99.5, tk + (Math.random() - 0.5) * 0.2)).toFixed(1));
  }, []), 6000);

  const max = Math.max(...candles.map((c) => c.h));
  const min = Math.min(...candles.map((c) => c.l));
  const norm = (v) => 100 - (v - min) / (max - min) * 100;
  return (
    <div style={{ padding: '20px 24px 24px', display: 'flex', flexDirection: 'column', gap: 12 }}>
      <div className="dmc-head" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
        <div>
          <div className="kicker">CLIENT REVENUE POWERED · 30D</div>
          <div className="dmc-figs" style={{ display: 'flex', alignItems: 'baseline', gap: 14, marginTop: 8 }}>
            <span style={{ fontFamily: 'var(--font-sans)', fontSize: 32, letterSpacing: '-0.025em', fontVariantNumeric: 'tabular-nums' }}>${revenue.toFixed(3)}M</span>
            <span className="mono" style={{ fontSize: 12, color: pct >= 0 ? 'var(--accent)' : 'var(--danger)', fontVariantNumeric: 'tabular-nums', transition: 'color 0.4s', whiteSpace: 'nowrap' }}>{pct >= 0 ? '+' : ''}{pct.toFixed(1)}%</span>
          </div>
        </div>
        <div className="dmc-ranges" style={{ display: 'flex', gap: 6 }}>
          {['1D', '1W', '1M', '3M', 'YTD', 'ALL'].map((t) =>
          <span key={t} className="mono" style={{
            fontSize: 10.5, padding: '4px 8px', borderRadius: 4,
            background: t === '1M' ? 'rgba(255,255,255,0.06)' : 'transparent',
            color: t === '1M' ? 'var(--text)' : 'var(--text-3)',
            border: '1px solid ' + (t === '1M' ? 'var(--line-strong)' : 'transparent')
          }}>{t}</span>
          )}
        </div>
      </div>
      <div style={{ height: 200, position: 'relative', borderTop: '1px solid var(--line)', borderBottom: '1px solid var(--line)' }}>
        <svg width="100%" height="100%" viewBox="0 0 480 200" preserveAspectRatio="none">
          {/* horizontal grid */}
          {[0, 25, 50, 75, 100].map((y) =>
          <line key={y} x1="0" x2="480" y1={y * 2} y2={y * 2} stroke="rgba(255,255,255,0.04)" strokeDasharray="2 4" />
          )}
          {/* candles */}
          {candles.map((c, i) => {
            const x = i / (candles.length - 1) * 470 + 5;
            const up = c.c >= c.o;
            const color = up ? '#00ffff' : 'oklch(0.72 0.18 25)';
            const top = norm(c.h) * 2;
            const bot = norm(c.l) * 2;
            const yo = norm(c.o) * 2;
            const yc = norm(c.c) * 2;
            const bodyTop = Math.min(yo, yc);
            const bodyH = Math.max(2, Math.abs(yo - yc));
            const isLast = i === candles.length - 1;
            return (
              <g key={i} style={{ transition: 'transform 0.6s ease-out' }}>
                <line x1={x} x2={x} y1={top} y2={bot} stroke={color} strokeWidth="1" opacity={isLast ? 0.85 : 0.5} style={{ transition: 'y1 0.4s, y2 0.4s' }} />
                <rect x={x - 3} y={bodyTop} width="6" height={bodyH} fill={color} opacity={up ? 0.95 : 0.85} style={{ transition: 'y 0.4s, height 0.4s, fill 0.3s' }} />
                {isLast && <circle cx={x} cy={yc} r="2.5" fill={color} opacity="0.9"><animate attributeName="opacity" values="0.9;0.3;0.9" dur="1.4s" repeatCount="indefinite" /></circle>}
              </g>);

          })}
          {/* trend line */}
          <path d={candles.map((c, i) => {
            const x = i / (candles.length - 1) * 470 + 5;
            const y = norm((c.o + c.c) / 2) * 2;
            return (i === 0 ? 'M' : 'L') + x + ',' + y;
          }).join(' ')} stroke="#00ffff" strokeWidth="1.2" fill="none" opacity="0.7" />
        </svg>
        <div className="mono" style={{ position: 'absolute', left: 8, top: 6, fontSize: 10, color: 'var(--text-4)' }}>USD</div>
        <div className="mono" style={{ position: 'absolute', right: 8, top: 6, fontSize: 10, color: 'var(--text-4)' }}>+18.4% MoM</div>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 14 }}>
        {[
        ['Active traders', traders.toLocaleString(), '+' + (412 + Math.floor((traders - 24182) / 1)).toLocaleString().slice(0, 4)],
        ['Avg payout', '$' + payout.toLocaleString(), '+6.2%'],
        ['Pass rate', '11.4%', '—'],
        ['Tickets / SLA', tickets.toFixed(1) + '%', tickets >= 98 ? '+1.1%' : '—']].
        map(([k, v, d], i) =>
        <div key={i}>
            <div className="kicker" style={{ fontSize: 10 }}>{k}</div>
            <div style={{ fontFamily: 'var(--font-sans)', fontSize: 18, marginTop: 4, letterSpacing: '-0.015em', fontVariantNumeric: 'tabular-nums' }}>{v}</div>
            <div className="mono" style={{ fontSize: 10.5, color: d.startsWith('+') ? 'var(--accent)' : 'var(--text-3)' }}>{d}</div>
          </div>
        )}
      </div>
    </div>);

};

const EVENT_TEMPLATES = [
{ sev: 'high', tag: 'auto-flag', msg: 'Latency arbitrage pattern · acct {ACCT}' },
{ sev: 'med', tag: 'review', msg: 'Copy-trade cluster · {N} accts linked' },
{ sev: 'low', tag: 'enforced', msg: 'Drawdown breach · acct {ACCT}' },
{ sev: 'med', tag: 'review', msg: 'IP velocity · region {R1} → {R2}' },
{ sev: 'low', tag: 'observed', msg: 'News-tick anomaly · {WIN} window' },
{ sev: 'high', tag: 'auto-flag', msg: 'Martingale escalation · acct {ACCT}' },
{ sev: 'low', tag: 'observed', msg: 'Slippage outlier · venue {V}' },
{ sev: 'med', tag: 'review', msg: 'Hedge-pair detection · {N} accts' },
{ sev: 'high', tag: 'auto-flag', msg: 'Same-IP cluster · {N} accounts' },
{ sev: 'low', tag: 'observed', msg: 'Tick latency spike · venue {V}' },
{ sev: 'med', tag: 'review', msg: 'KYC mismatch · acct {ACCT}' },
{ sev: 'low', tag: 'enforced', msg: 'Daily DD breach · acct {ACCT}' }];

const REGIONS = ['SG', 'AE', 'UK', 'DE', 'US', 'BR', 'HK', 'TR', 'IN', 'ZA'];
const VENUES = ['A', 'B', 'C', 'D', 'E'];
const WINDOWS = ['NFP', 'CPI', 'FOMC', 'ECB', 'OPEC'];
const fillTemplate = (m) => m.
replace('{ACCT}', String(70000 + Math.floor(Math.random() * 15000))).
replace('{N}', String(3 + Math.floor(Math.random() * 9))).
replace('{R1}', REGIONS[Math.floor(Math.random() * REGIONS.length)]).
replace('{R2}', REGIONS[Math.floor(Math.random() * REGIONS.length)]).
replace('{V}', VENUES[Math.floor(Math.random() * VENUES.length)]).
replace('{WIN}', WINDOWS[Math.floor(Math.random() * WINDOWS.length)]);
const fmtTime = (d) => [d.getHours(), d.getMinutes(), d.getSeconds()].map((n) => String(n).padStart(2, '0')).join(':');
let __evCounter = 2034;

const DashRiskFeed = () => {
  const initial = React.useMemo(() => [
  { id: 1, t: '14:02:11', sev: 'high', code: 'RX-2034', msg: 'Latency arbitrage pattern · acct 80213', tag: 'auto-flag' },
  { id: 2, t: '14:01:48', sev: 'med', code: 'RX-2033', msg: 'Copy-trade cluster · 6 accts linked', tag: 'review' },
  { id: 3, t: '14:01:12', sev: 'low', code: 'RX-2032', msg: 'Drawdown breach · acct 79114', tag: 'enforced' },
  { id: 4, t: '14:00:55', sev: 'med', code: 'RX-2031', msg: 'IP velocity · region SG → AE', tag: 'review' },
  { id: 5, t: '14:00:21', sev: 'low', code: 'RX-2030', msg: 'News-tick anomaly · NFP window', tag: 'observed' },
  { id: 6, t: '13:59:47', sev: 'high', code: 'RX-2029', msg: 'Martingale escalation · acct 78992', tag: 'auto-flag' },
  { id: 7, t: '13:59:02', sev: 'low', code: 'RX-2028', msg: 'Slippage outlier · venue B', tag: 'observed' }],
  []);
  const [events, setEvents] = React.useState(initial);
  const idRef = React.useRef(8);

  useLiveInterval(React.useCallback(() => {
    const tpl = EVENT_TEMPLATES[Math.floor(Math.random() * EVENT_TEMPLATES.length)];
    __evCounter += 1;
    const id = idRef.current++;
    const fresh = {
      id, t: fmtTime(new Date()), sev: tpl.sev,
      code: 'RX-' + __evCounter,
      msg: fillTemplate(tpl.msg),
      tag: tpl.tag,
      isNew: true
    };
    setEvents((prev) => [fresh, ...prev].slice(0, 7));
  }, []), 3200);

  const sevColor = (s) => s === 'high' ? 'var(--danger)' : s === 'med' ? 'var(--warn)' : 'var(--accent)';
  return (
    <div style={{ padding: '20px 22px', borderLeft: '1px solid var(--line)', display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 14 }}>
        <div className="kicker">QUANTSENTRY · EVENT FEED</div>
        <span className="pill pill-accent" style={{ display: 'inline-flex', alignItems: 'center', gap: 5 }}>
          <span style={{ width: 5, height: 5, borderRadius: '50%', background: 'var(--accent)', animation: 'qtgPulse 1.6s ease-in-out infinite' }} />
          LIVE
        </span>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10, fontSize: 12 }}>
        {events.map((e, i) =>
        <div key={e.id} style={{
          display: 'flex', gap: 10, paddingBottom: 10,
          borderBottom: i < events.length - 1 ? '1px solid var(--line)' : 'none',
          animation: e.isNew ? 'qtgFeedIn 0.5s ease-out both' : 'none'
        }}>
            <span className="mono" style={{ color: 'var(--text-4)', fontSize: 10.5, flexShrink: 0, marginTop: 2 }}>{e.t}</span>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                <span style={{ width: 5, height: 5, borderRadius: '50%', background: sevColor(e.sev) }} />
                <span className="mono" style={{ fontSize: 10.5, color: 'var(--text-3)' }}>{e.code}</span>
                <span className="mono" style={{ fontSize: 10, color: 'var(--text-4)', marginLeft: 'auto' }}>{e.tag}</span>
              </div>
              <div style={{ color: 'var(--text-2)', marginTop: 3, fontSize: 12, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{e.msg}</div>
            </div>
          </div>
        )}
      </div>
    </div>);

};

const DashBottomStrip = () => {
  const [latency, setLatency] = React.useState(83);
  const [queue, setQueue] = React.useState(312);
  useLiveInterval(React.useCallback(() => {
    setLatency((l) => Math.max(72, Math.min(98, l + Math.round((Math.random() - 0.5) * 4))));
    setQueue((q) => Math.max(280, Math.min(360, q + Math.round((Math.random() - 0.5) * 8))));
  }, []), 2200);
  const cells = [
  ['SYSTEM', 'operational', 'var(--accent)', true],
  ['SENTRY', 'scoring', 'var(--accent)', true],
  ['PAYOUTS', 'queued · ' + queue, 'var(--text-2)', false],
  ['QUEUE', latency + 'ms p95', 'var(--text-2)', false],
  ['REGION', 'EU-1 · SG-2', 'var(--text-2)', false],
  ['BUILD', 'v4.18.2', 'var(--text-3)', false]];

  return (
    <div style={{ display: 'grid', gridTemplateColumns: 'repeat(6,1fr)', borderTop: '1px solid var(--line)', background: 'rgba(255,255,255,0.01)' }}>
      {cells.map(([k, v, c, pulse], i) =>
      <div key={i} style={{ padding: '12px 16px', borderRight: i < 5 ? '1px solid var(--line)' : 'none', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <span className="mono" style={{ fontSize: 10, color: 'var(--text-4)', letterSpacing: '0.1em' }}>{k}</span>
          <span className="mono" style={{ fontSize: 11, color: c, display: 'inline-flex', alignItems: 'center', gap: 6, fontVariantNumeric: 'tabular-nums' }}>
            {pulse && <span style={{ width: 5, height: 5, borderRadius: '50%', background: c, animation: 'qtgPulse 1.6s ease-in-out infinite' }} />}
            {v}
          </span>
        </div>
      )}
    </div>);

};

Object.assign(window, { Nav: Nav, Hero: Hero, Ticker: Ticker });