/* global React */
const { useState, useEffect } = React;

/* ============================================================
   Shared chrome
   ============================================================ */
window.Nav = function Nav({ route, setRoute }) {
  const [open, setOpen] = useState(false);
  const TOOL_ROUTES = ['revscout-s', 'revtoolbox', 'emi', 'revfield', 'revsizer', 'optimize'];
  const toolLinks = [
    { id: 'revscout-s', label: 'RevScout S',            sub: 'Fruit count + size camera', badge: 'NEW' },
    { id: 'revtoolbox', label: 'RevToolbox',             sub: 'Data portal + satellite vigour' },
    { id: 'emi',        label: 'EMI Soil Scanning',      sub: 'Soil conductivity at 3 depths' },
    { id: 'revfield',   label: 'RevField',               sub: 'Pest & disease scouting' },
    { id: 'revsizer',   label: 'Rev-Sizer',              sub: 'Hand-held caliper' },
    { id: 'optimize',   label: 'Precision Go-to Guide',  sub: 'Putting the layers to work' },
  ];
  const toolActive = TOOL_ROUTES.includes(route);
  const [toolsOpen, setToolsOpen] = useState(false);
  const toolsRef = React.useRef(null);
  useEffect(() => {
    if (!toolsOpen) return;
    const onDoc = (e) => {
      if (toolsRef.current && !toolsRef.current.contains(e.target)) setToolsOpen(false);
    };
    const onKey = (e) => { if (e.key === 'Escape') setToolsOpen(false); };
    document.addEventListener('mousedown', onDoc);
    document.addEventListener('keydown', onKey);
    return () => {
      document.removeEventListener('mousedown', onDoc);
      document.removeEventListener('keydown', onKey);
    };
  }, [toolsOpen]);
  useEffect(() => { setToolsOpen(false); }, [route]);

  const links = [
    { id: 'home',       label: 'Home' },
    { id: 'pricing',    label: 'Pricing' },
    { id: 'contact',    label: 'Contact' },
  ];
  // Close drawer on route change
  useEffect(() => { setOpen(false); }, [route]);
  // Lock body scroll when drawer open
  useEffect(() => {
    document.body.style.overflow = open ? 'hidden' : '';
    return () => { document.body.style.overflow = ''; };
  }, [open]);
  const go = (id) => (e) => { e.preventDefault(); setRoute(id); };
  return (
    <nav className="nav">
      <div className="nav-inner">
        <a className="logo" href="#" onClick={go('home')}>
          <window.RevGlyph size={40} />
          <div className="logo-words">
            <span className="name">Revolute Systems</span>
            <span className="tag">Making precision practical</span>
          </div>
        </a>
        <div className="nav-links">
          {links.slice(0, 1).map(l => (
            <a key={l.id} href="#" data-nav-id={l.id} className={`nav-link ${route === l.id ? 'active' : ''}`}
               onClick={go(l.id)}>
              {l.label}
            </a>
          ))}

          {/* Tools dropdown */}
          <div className={`nav-dropdown ${toolsOpen ? 'open' : ''}`} ref={toolsRef}>
            <button
              type="button"
              className={`nav-link nav-dropdown-trigger ${toolActive ? 'active' : ''}`}
              aria-haspopup="true"
              aria-expanded={toolsOpen}
              onClick={() => setToolsOpen(o => !o)}>
              <span>Tools</span>
              <svg className="nav-dropdown-caret" width="10" height="6" viewBox="0 0 10 6" aria-hidden="true">
                <path d="M1 1l4 4 4-4" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" />
              </svg>
            </button>
            <div className="nav-dropdown-panel" role="menu">
              <div className="nav-dropdown-eyebrow">Tools &amp; Services</div>
              <div className="nav-dropdown-list">
                {toolLinks.map(t => (
                  <a
                    key={t.id}
                    href="#"
                    role="menuitem"
                    className={`nav-dropdown-item ${route === t.id ? 'active' : ''}`}
                    onClick={(e) => { e.preventDefault(); setToolsOpen(false); setRoute(t.id); }}>
                    <div className="nav-dropdown-item-main">
                      <span className="nav-dropdown-item-label">{t.label}</span>
                      {t.badge && <span className="nav-dropdown-item-badge">{t.badge}</span>}
                    </div>
                    <span className="nav-dropdown-item-sub">{t.sub}</span>
                  </a>
                ))}
              </div>
            </div>
          </div>

          {links.slice(1).map(l => (
            <a key={l.id} href="#" data-nav-id={l.id} className={`nav-link ${route === l.id ? 'active' : ''}`}
               onClick={go(l.id)}>
              {l.label}
            </a>
          ))}
        </div>
        <div className="nav-actions">
          <a className="btn btn-ghost nav-cta-toolbox" href="http://revtoolbox.co.za" target="_blank" rel="noreferrer">RevToolbox ↗</a>
          <a className="btn btn-primary nav-cta-contact" href="#" onClick={go('contact')}>Get in touch</a>
          <button className="nav-burger" aria-label="Menu" aria-expanded={open} onClick={() => setOpen(o => !o)}>
            <span className={`nav-burger-bars ${open ? 'open' : ''}`}>
              <span></span><span></span><span></span>
            </span>
          </button>
        </div>
      </div>
      {/* Mobile drawer */}
      <div className={`nav-drawer ${open ? 'open' : ''}`} role="dialog" aria-modal="true" aria-hidden={!open}>
        <div className="nav-drawer-scroll">
          <div className="nav-drawer-links">
            {links.slice(0, 1).map(l => (
              <a key={l.id} href="#" className={`nav-drawer-link ${route === l.id ? 'active' : ''}`}
                 onClick={go(l.id)}>
                <span>{l.label}</span>
              </a>
            ))}
            <div className="nav-drawer-group-label">Tools</div>
            {toolLinks.map(l => (
              <a key={l.id} href="#" className={`nav-drawer-link nav-drawer-link-sub ${route === l.id ? 'active' : ''}`}
                 onClick={go(l.id)}>
                <span>{l.label}</span>
                {l.badge && <span className="nav-drawer-badge">{l.badge}</span>}
              </a>
            ))}
            {links.slice(1).map(l => (
              <a key={l.id} href="#" className={`nav-drawer-link ${route === l.id ? 'active' : ''}`}
                 onClick={go(l.id)}>
                <span>{l.label}</span>
              </a>
            ))}
          </div>
          <div className="nav-drawer-actions">
            <a className="btn btn-ghost" href="http://revtoolbox.co.za" target="_blank" rel="noreferrer" onClick={() => setOpen(false)}>RevToolbox</a>
            <a className="btn btn-primary" href="#" onClick={go('contact')}>Get in touch</a>
          </div>
          <div className="nav-drawer-foot">
            <div>Datavoice House, 16 Elektron Avenue</div>
            <div>Technopark · Stellenbosch · ZA</div>
          </div>
        </div>
      </div>
    </nav>
  );
};

window.Footer = function Footer({ setRoute }) {
  return (
    <footer className="footer">
      <div className="container-wide">
        <div className="footer-grid">
          <div>
            <div style={{ marginBottom: 16 }}>
              <window.RevWordmark variant="light" height={56} />
            </div>
            <p style={{ fontSize: 13.5, lineHeight: 1.6, color: 'rgba(255,255,255,0.6)', maxWidth: 320 }}>
              Tree-level precision agriculture for orchards. We turn satellite, soil, fruit and canopy data into actions you can take this season.
            </p>
          </div>
          <div>
            <h5>Tools</h5>
            <ul>
              <li><a href="#" onClick={e => { e.preventDefault(); setRoute('revscout-s'); }}>RevScout S</a></li>
              <li><a href="#" onClick={e => { e.preventDefault(); setRoute('revtoolbox'); }}>RevToolbox &amp; Satellite</a></li>
              <li><a href="#" onClick={e => { e.preventDefault(); setRoute('emi'); }}>EMI Soil Scanning</a></li>
              <li><a href="#" onClick={e => { e.preventDefault(); setRoute('revfield'); }}>RevField App</a></li>
              <li><a href="#" onClick={e => { e.preventDefault(); setRoute('revsizer'); }}>Rev-Sizer Caliper</a></li>
              <li><a href="#" onClick={e => { e.preventDefault(); setRoute('optimize'); }}>Precision Go-to Guide</a></li>
            </ul>
          </div>
          <div>
            <h5>Applications</h5>
            <ul>
              <li><a href="#" onClick={e => { e.preventDefault(); setRoute('optimize'); }}>Variable Rate Nitrogen</a></li>
              <li><a href="#" onClick={e => { e.preventDefault(); setRoute('optimize'); }}>Yield Estimation</a></li>
              <li><a href="#" onClick={e => { e.preventDefault(); setRoute('optimize'); }}>Fruit Size Mgmt</a></li>
              <li><a href="#" onClick={e => { e.preventDefault(); setRoute('optimize'); }}>Irrigation Optimizing</a></li>
              <li><a href="#" onClick={e => { e.preventDefault(); setRoute('optimize'); }}>Soil pH & Nutrient</a></li>
            </ul>
          </div>
          <div>
            <h5>Company</h5>
            <ul>
              <li><a href="#" onClick={e => { e.preventDefault(); setRoute('pricing'); }}>Pricing</a></li>
              <li><a href="#" onClick={e => { e.preventDefault(); setRoute('contact'); }}>Contact</a></li>
              <li><a href="http://revtoolbox.co.za" target="_blank" rel="noreferrer">RevToolbox Login ↗</a></li>
              <li><a href="https://revfruitsizing.co.za/" target="_blank" rel="noreferrer">RevFruitsizing Login ↗</a></li>
            </ul>
            <div style={{ marginTop: 24, fontSize: 12.5, lineHeight: 1.7, color: 'rgba(255,255,255,0.55)' }}>
              Datavoice House, 16 Elektron Avenue<br />
              Technopark, Stellenbosch<br />
              Western Cape, South Africa
            </div>
          </div>
        </div>
        <div className="footer-bottom">
          <span>© 2026 Revolute Systems</span>
          <span>STELLENBOSCH · ZA · 33°55'12"S 18°51'30"E</span>
        </div>
      </div>
    </footer>
  );
};

/* ============================================================
   HOME
   ============================================================ */
/* ============================================================
   RevScoutHub — hub & spoke flow showing RevScout S at center,
   inputs feeding in from the left, outputs flowing to the right.
   ============================================================ */
window.RevScoutHub = function RevScoutHub({ setRoute }) {
  const hubRef = React.useRef(null);
  const progress = window.useScrollProgress(hubRef, { start: 0.15, end: 0.55 });
  // Each spoke draws sequentially: 6 spokes share progress.
  const spokeP = (idx) => Math.max(0, Math.min(1, (progress * 6) - idx));
  const inputs = [
    { key: 'EMI',       title: 'EMI soil scanning',     copy: 'Underlying variation map. Where problems live.', viz: <div role="img" aria-label="Block EC zone map" data-img-file="assets/portal-ec-mapping.png" style={{ width: '100%', height: '100%', backgroundImage: "url('assets/portal-ec-mapping.png')", backgroundSize: 'cover', backgroundPosition: 'center' }} />, route: 'emi', color: 'var(--data-soil)' },
    { key: 'SATELLITE', title: 'Canopy vigour mapping', copy: '4 yrs of NDVI at 10 m. 80 cm on demand.',        viz: <div role="img" aria-label="Block canopy-vigour zone map" data-img-file="assets/portal-vigour-mapping.png" style={{ width: '100%', height: '100%', backgroundImage: "url('assets/portal-vigour-mapping.png')", backgroundSize: 'cover', backgroundPosition: 'center' }} />, route: 'revtoolbox', color: 'var(--data-canopy)' },
    { key: 'REVSCOUT',  title: 'Fruit load mapping',    copy: 'AI camera counts every fruit on every tree.',    viz: <div role="img" aria-label="Block fruit-load zone map" data-img-file="assets/portal-fruit-mapping.png" style={{ width: '100%', height: '100%', backgroundImage: "url('assets/portal-fruit-mapping.png')", backgroundSize: 'cover', backgroundPosition: 'center' }} />, route: 'revscout-s', color: 'var(--lime)' },
  ];
  const outputs = [
    { key: 'REVSCOUT',   title: 'Fruit size mapping',    copy: 'Diameter measured per fruit, mapped to GPS.',     viz: <div role="img" aria-label="Block fruit-size zone map" data-img-file="assets/portal-fruit-sizing.png" style={{ width: '100%', height: '100%', backgroundImage: "url('assets/portal-fruit-sizing.png')", backgroundSize: 'cover', backgroundPosition: 'center' }} />, route: 'revsizer', color: 'var(--lime)' },
    { key: 'GROWTH',     title: 'Fruit size prediction', copy: 'Growth curves predict harvest sizes into your packhouse bins.', viz: <div role="img" aria-label="Fruit size timeseries — measured vs projected" data-img-file="assets/portal-fruit-size-graph.png" style={{ width: '100%', height: '100%', backgroundColor: '#fff', backgroundImage: "url('assets/portal-fruit-size-graph.png')", backgroundSize: '180% auto', backgroundPosition: '22% center', backgroundRepeat: 'no-repeat' }} />, route: 'revsizer', color: 'var(--data-yield)' },
    { key: 'VRA',        title: 'Variable rate application', copy: 'Export prescription files straight to your spreader or sprayer.', viz: <div role="img" aria-label="Variable-rate application prescription map" data-img-file="assets/portal-vra-map.png" style={{ width: '100%', height: '100%', backgroundImage: "url('assets/portal-vra-map.png')", backgroundSize: 'cover', backgroundPosition: 'center' }} />, route: 'revtoolbox', color: 'var(--data-vra)' },
  ];

  const Spoke = ({ side, items }) => (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
      {items.map((it, i) => {
        const handleKey = (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); setRoute(it.route); } };
        return (
        <article key={i}
          onClick={() => setRoute(it.route)}
          onKeyDown={handleKey}
          tabIndex={0}
          role="button"
          aria-label={`${it.title} — ${it.copy}`}
          style={{
            background: 'var(--paper)', border: '1px solid var(--line)',
            borderLeft: side === 'right' ? `3px solid ${it.color}` : '1px solid var(--line)',
            borderRight: side === 'left' ? `3px solid ${it.color}` : '1px solid var(--line)',
            borderRadius: 'var(--radius-lg)', padding: 14,
            display: 'grid',
            gridTemplateColumns: side === 'left' ? '1fr 76px' : '76px 1fr',
            gap: 14, alignItems: 'center', cursor: 'pointer',
            textAlign: side === 'left' ? 'right' : 'left',
            transition: 'transform 0.18s, box-shadow 0.18s',
          }}
          onMouseEnter={e => { e.currentTarget.style.transform = 'translateX(' + (side === 'left' ? '4px' : '-4px') + ')'; e.currentTarget.style.boxShadow = `0 8px 24px -10px ${it.color}55`; }}
          onMouseLeave={e => { e.currentTarget.style.transform = 'translateX(0)'; e.currentTarget.style.boxShadow = 'none'; }}
        >
          {side === 'right' && (
            <div data-hub-viz style={{ width: 76, height: 76, borderRadius: 8, overflow: 'hidden', border: `1px solid ${it.color}33` }}>{it.viz}</div>
          )}
          <div style={{ minWidth: 0 }}>
            <div style={{
              fontFamily: 'JetBrains Mono, monospace', fontSize: 10, letterSpacing: '0.08em',
              color: it.color, marginBottom: 4,
            }}>{side === 'left' ? '→ FEEDS IN' : 'FLOWS OUT →'} · {it.key}</div>
            <h3 style={{ margin: 0, fontSize: 17, lineHeight: 1.2, letterSpacing: '-0.01em', fontWeight: 600 }}>{it.title}</h3>
            <p style={{ margin: '6px 0 0', fontSize: 13, lineHeight: 1.45, color: 'var(--muted)' }}>{it.copy}</p>
          </div>
          {side === 'left' && (
            <div data-hub-viz style={{ width: 76, height: 76, borderRadius: 8, overflow: 'hidden', border: `1px solid ${it.color}33` }}>{it.viz}</div>
          )}
        </article>
      );})}
    </div>
  );

  return (
    <div ref={hubRef} className="revscout-hub" style={{ position: 'relative' }}>
      <svg viewBox="0 0 1000 600" preserveAspectRatio="none" aria-hidden="true" style={{
        position: 'absolute', inset: 0, width: '100%', height: '100%', pointerEvents: 'none', zIndex: 1,
      }}>
        <defs>
          {['soil','canopy','sizer','sizing','toolbox','vra'].map((k, i) => {
            const colors = { soil: '#B89968', canopy: '#6E9CC4', sizer: '#B8DC73', sizing: '#B8DC73', toolbox: '#83B535', vra: '#1C4100' };
            return <marker key={k} id={`arr-${k}`} viewBox="0 0 12 12" refX="10" refY="6" markerWidth="9" markerHeight="9" orient="auto">
              <path d="M0,0 L12,6 L0,12 L3,6 z" fill={colors[k]} />
            </marker>;
          })}
          {[['soil','#B89968','#B8DC73'],['canopy','#6E9CC4','#B8DC73'],['sizer','#B8DC73','#B8DC73']].map(([k,a,b]) =>
            <linearGradient key={'gi'+k} id={`grad-in-${k}`} x1="0" y1="0" x2="1" y2="0">
              <stop offset="0%" stopColor={a} stopOpacity="0.85" />
              <stop offset="100%" stopColor={b} stopOpacity="0.95" />
            </linearGradient>
          )}
          {[['sizing','#B8DC73','#B8DC73'],['toolbox','#B8DC73','#83B535'],['vra','#B8DC73','#1C4100']].map(([k,a,b]) =>
            <linearGradient key={'go'+k} id={`grad-out-${k}`} x1="0" y1="0" x2="1" y2="0">
              <stop offset="0%" stopColor={a} stopOpacity="0.95" />
              <stop offset="100%" stopColor={b} stopOpacity="0.85" />
            </linearGradient>
          )}
        </defs>
        {[['soil',80],['canopy',300],['sizer',520]].map(([k,y],i) => {
          const len = 250; const p = spokeP(i);
          return <path key={'in'+i}
            d={`M 320 ${y + 40} C 400 ${y + 40}, 440 300, 470 300`}
            fill="none" stroke={`url(#grad-in-${k})`} strokeWidth="2.5"
            markerEnd={p > 0.95 ? `url(#arr-${k})` : undefined}
            strokeDasharray={len} strokeDashoffset={len * (1 - p)}
            style={{ transition: 'stroke-dashoffset 200ms linear' }} />;
        })}
        {[['sizing',80],['toolbox',300],['vra',520]].map(([k,y],i) => {
          const len = 250; const p = spokeP(i + 3);
          return <path key={'out'+i}
            d={`M 530 300 C 560 300, 600 ${y + 40}, 680 ${y + 40}`}
            fill="none" stroke={`url(#grad-out-${k})`} strokeWidth="2.5"
            markerEnd={p > 0.95 ? `url(#arr-${k})` : undefined}
            strokeDasharray={len} strokeDashoffset={len * (1 - p)}
            style={{ transition: 'stroke-dashoffset 200ms linear' }} />;
        })}
      </svg>

      <div className="revscout-hub-grid" style={{
        display: 'grid', gridTemplateColumns: '1fr 1.05fr 1fr',
        gap: 24, alignItems: 'center', position: 'relative', zIndex: 2,
      }}>
        <Spoke side="left" items={inputs} />

        {/* Center node */}
        <div
          onClick={() => setRoute('revscout-s')}
          onKeyDown={e => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); setRoute('revscout-s'); } }}
          tabIndex={0}
          role="button"
          aria-label="RevScout S — the centerpiece"
          style={{
            aspectRatio: '1 / 1', maxWidth: 380, margin: '0 auto', width: '100%',
            borderRadius: '50%',
            background: 'radial-gradient(circle at 50% 40%, #243027 0%, #14181a 70%)',
            color: 'white',
            padding: 28, display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center',
            textAlign: 'center', cursor: 'pointer', position: 'relative',
            boxShadow: '0 0 0 1px rgba(184,220,115,0.25), 0 24px 64px rgba(28,65,0,0.28), 0 0 80px -20px rgba(184,220,115,0.45)',
            overflow: 'hidden',
        }}>
          <video
            src="assets/revscout-video.mp4"
            autoPlay muted loop playsInline preload="auto"
            poster="assets/revscout-field.png"
            aria-hidden="true"
            ref={(el) => { if (el) { try { el.muted = true; el.volume = 0; el.playbackRate = 0.8; el.play().catch(() => {}); } catch (_) {} } }}
            style={{
              position: 'absolute', inset: 0, width: '100%', height: '100%',
              objectFit: 'cover', borderRadius: '50%',
              filter: 'saturate(0.95) brightness(0.85)',
              zIndex: 0,
            }} />
          {/* Dark scrim for legibility */}
          <div aria-hidden="true" style={{
            position: 'absolute', inset: 0, borderRadius: '50%',
            background: 'radial-gradient(circle at 50% 45%, rgba(15,20,16,0.55) 0%, rgba(15,20,16,0.78) 60%, rgba(15,20,16,0.88) 100%)',
            zIndex: 1,
          }} />
          {/* Pulsing inner ring */}
          <div aria-hidden="true" style={{
            position: 'absolute', inset: '8%', borderRadius: '50%',
            border: '1px solid rgba(184,220,115,0.35)',
            animation: 'hubPulse 2.8s ease-in-out infinite',
            pointerEvents: 'none',
          }}></div>
          <style>{`@keyframes hubPulse { 0%,100% { transform: scale(1); opacity: 0.6; } 50% { transform: scale(1.04); opacity: 1; } }`}</style>
          <div style={{ position: 'relative', zIndex: 2, display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center', width: '100%' }}>
          <div style={{
            fontFamily: 'JetBrains Mono, monospace', fontSize: 10, letterSpacing: '0.12em',
            color: '#B8DC73', marginBottom: 10,
          }}>THE CENTERPIECE</div>
          <h3 style={{
            fontFamily: 'var(--font-display)', fontSize: 'clamp(28px, 3vw, 40px)',
            lineHeight: 1.05, fontWeight: 600, letterSpacing: '-0.02em', margin: '0 0 10px',
          }}>RevScout <em style={{ fontFamily: "'Instrument Serif', serif", fontStyle: 'italic', color: '#B8DC73' }}>S</em></h3>
          <p style={{
            fontSize: 14, lineHeight: 1.5, color: 'rgba(255,255,255,0.75)',
            maxWidth: 280, margin: '0 0 16px',
          }}>AI field camera. Counts and sizes every fruit on every tree, in a single drive.</p>
          <div style={{
            fontFamily: 'JetBrains Mono, monospace', fontSize: 11, color: '#B8DC73',
            borderTop: '1px solid rgba(255,255,255,0.12)', paddingTop: 10, width: '100%',
            display: 'flex', justifyContent: 'space-around',
          }}>
            <span>30 / 100 ha/d</span>
            <span>±1 mm</span>
            <span>2026</span>
          </div>
          </div>
        </div>

        <Spoke side="right" items={outputs} />
      </div>
    </div>
  );
};

window.HomePage = function HomePage({ setRoute }) {
  // Reveal fallback — guarantees [data-reveal] content appears on scroll even
  // in environments where IntersectionObserver callbacks aren't delivered.
  useEffect(() => {
    const reveal = () => {
      const vh = window.innerHeight || 800;
      document.querySelectorAll('[data-reveal]:not(.is-revealed)').forEach(el => {
        if (el.getBoundingClientRect().top < vh * 0.92) el.classList.add('is-revealed');
      });
    };
    reveal();
    window.addEventListener('scroll', reveal, { passive: true });
    window.addEventListener('resize', reveal);
    const t = setTimeout(reveal, 200);
    return () => {
      window.removeEventListener('scroll', reveal);
      window.removeEventListener('resize', reveal);
      clearTimeout(t);
    };
  }, []);

  const layers = [
    {
      n: '01', phase: 'SOIL', tool: 'emi', toolLabel: 'EMI Soil Scanning',
      ramp: 'linear-gradient(90deg,#FFF7EC,#F6C68A,#E08A3C,#B5651D,#6B3410)',
      title: 'Where the variation begins.',
      copy: 'Electromagnetic induction maps soil conductivity at three depths — 25, 50 and 90 cm. Clay, moisture and structure, the ground every root has to work with, mapped before a single tree is judged.',
      meta: 'Soil EC · 8 zones · 18.9–22.8 mS/m',
      img: 'assets/home-block-ec.png',
      alt: 'Soil EC zone map of the block — orange conductivity ramp, eight zones over the orchard footprint',
    },
    {
      n: '02', phase: 'CANOPY', tool: 'revtoolbox', toolLabel: 'RevToolbox & Satellite',
      ramp: 'linear-gradient(90deg,#F2F8EC,#B7D89A,#6FA84C,#2F7A2E,#14532D)',
      title: 'How each tree responds.',
      copy: 'Canopy vigour every few days across the whole season — the green morph you just watched fill in. Four years of NDVI history at 10 m, sharpened to 0.5 m on demand — the same block, read from above.',
      meta: 'Canopy NDVI · 8 zones · 0.33–0.59 idx',
      img: 'assets/home-block-vigour.png',
      alt: 'Canopy vigour zone map of the same block — green NDVI ramp, eight zones',
    },
    {
      n: '03', phase: 'FRUIT SIZE', tool: 'revscout-s', toolLabel: 'RevScout S',
      ramp: 'linear-gradient(90deg,#A50026,#F46D43,#FEE08B,#A6D96A,#1A9850)',
      title: 'How big the fruit runs.',
      copy: 'RevScout S stereo-sizes every fruit on every tree as it drives the row. Mean diameter lands per tree, mapped straight to GPS — the same ground again, now in millimetres.',
      meta: 'Mean diameter · 8 zones · 57–65 mm',
      img: 'assets/home-block-fruitsize.png',
      alt: 'Fruit size zone map of the same block — eight zones, 57 to 65 mm',
    },
    {
      n: '04', phase: 'YIELD', tool: 'revscout-s', toolLabel: 'RevScout S',
      ramp: 'linear-gradient(90deg,#A50026,#F46D43,#FEE08B,#A6D96A,#1A9850)',
      title: 'What it pays out.',
      copy: 'Count times size becomes modelled yield, mapped tree by tree — the top of the stack. This is where the soil signal at the very bottom finally shows its return.',
      meta: 'Modelled yield · 8 zones · 65–152',
      img: 'assets/home-block-yield.png',
      alt: 'Yield zone map of the same block — red-to-green ramp, eight zones',
    },
  ];

  return (
    <>
      {/* ===== 3D scroll hero — "The Living Block" soil-to-fruit reveal of Block 110 (v3) ===== */}
      <window.HeroBlock110V3 setRoute={setRoute} />

      {/* ===== Thesis — frames what the hero just showed ===== */}
      <section className="section">
        <div className="container-wide">
          <div className="section-head" data-reveal>
            <div>
              <div className="section-eyebrow">What you just watched</div>
              <h2 className="section-title">One block, read from the <em>soil up</em>.</h2>
            </div>
            <p className="section-lede">
              Block 110 is a single orchard block, scanned the way we scan every block: the soil beneath it, the canopy growing over a season, the fruit it finally carries. Layer by layer of the same ground — measured, aligned, and stacked into one decision.
            </p>
          </div>
          <div className="b110-spec-band" data-reveal>
            <div className="b110-spec"><span className="b110-spec-num">5×5 m</span><span className="b110-spec-lab">Soil EC resolution</span></div>
            <div className="b110-spec"><span className="b110-spec-num">every 5 days</span><span className="b110-spec-lab">Canopy NDVI cadence</span></div>
            <div className="b110-spec"><span className="b110-spec-num">per tree</span><span className="b110-spec-lab">Fruit count &amp; size</span></div>
            <div className="b110-spec"><span className="b110-spec-num">one portal</span><span className="b110-spec-lab">All the way to the spreader</span></div>
          </div>
        </div>
      </section>

      {/* ===== The layers — same block, every read ===== */}
      <section className="section warm">
        <div className="container-wide">
          <div className="section-eyebrow" data-reveal>Every layer · one block</div>
          <h2 className="section-title" data-reveal style={{ marginBottom: 'var(--space-5)' }}>The same ground, <em>read four ways</em>.</h2>

          {layers.map((L, i) => (
            <div key={L.n} className={'usecase-row' + (i % 2 === 1 ? ' flip' : '')} data-reveal>
              <div className="uc-text">
                <div className="uc-num">LAYER {L.n} · {L.phase}</div>
                <h3>{L.title}</h3>
                <p>{L.copy}</p>
                <div style={{ height: 8, borderRadius: 3, margin: '20px 0 14px', border: '1px solid var(--line)', background: L.ramp }} aria-hidden="true" />
                <div style={{ display: 'flex', alignItems: 'center', gap: 16, flexWrap: 'wrap' }}>
                  <span style={{ fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.14em', color: 'var(--muted)' }}>{L.meta}</span>
                  <a href="#" onClick={e => { e.preventDefault(); setRoute(L.tool); }}
                    style={{ fontFamily: 'var(--font-mono)', fontSize: 12, letterSpacing: '0.08em', color: 'var(--accent)', fontWeight: 500 }}>
                    {L.toolLabel} →
                  </a>
                </div>
              </div>
              <div className="uc-visual" data-img-file={L.img} role="img" aria-label={L.alt}
                style={{ borderRadius: 14, overflow: 'hidden', backgroundColor: '#0d140c', backgroundImage: "url('" + L.img + "')", backgroundSize: 'cover', backgroundPosition: 'center', aspectRatio: '679 / 548' }} />
            </div>
          ))}

          {/* Fruit-size forecast — the golden thread closes on a prediction */}
          <div className="usecase-row" data-reveal style={{ marginTop: 'var(--space-3)' }}>
            <div className="uc-text">
              <div className="uc-num">THE FORECAST · FRUIT SIZE OVER TIME</div>
              <h3>And where it's all heading.</h3>
              <p>Weekly caliper and camera readings on the same block build a growth curve per season. Plotted on days-after-bloom, this season sits against last — and the dashed projection lands a final harvest size weeks before the pick.</p>
              <div style={{ display: 'flex', alignItems: 'center', gap: 16, flexWrap: 'wrap', marginTop: 14 }}>
                <span style={{ fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.14em', color: 'var(--muted)' }}>Fuji Suprema · 2025 → 71.0 mm · 2026 → 66.5 mm</span>
                <a href="#" onClick={e => { e.preventDefault(); setRoute('revsizer'); }}
                  style={{ fontFamily: 'var(--font-mono)', fontSize: 12, letterSpacing: '0.08em', color: 'var(--accent)', fontWeight: 500 }}>
                  Rev-Sizer &amp; RevSizing →
                </a>
              </div>
            </div>
            <div className="uc-visual" data-img-file="assets/home-block-fruitsize-graph.png" role="img"
              aria-label="Fruit size timeseries — two seasons plotted on days-after-bloom with dashed harvest-size projections"
              style={{ borderRadius: 14, overflow: 'hidden', backgroundColor: '#fff', backgroundImage: "url('assets/home-block-fruitsize-graph.png')", backgroundSize: 'contain', backgroundRepeat: 'no-repeat', backgroundPosition: 'center', aspectRatio: '1019 / 652', border: '1px solid var(--line)' }} />
          </div>
        </div>
      </section>

      {/* ===== The platform — how the layers converge ===== */}
      <section className="section">
        <div className="container-wide">
          <div className="section-head" data-reveal>
            <div>
              <div className="section-eyebrow">The platform</div>
              <h2 className="section-title">Three layers, <em>one portal</em>.</h2>
            </div>
            <p className="section-lede">
              Soil, canopy and fruit don't live in three apps. They converge in RevToolbox — with RevScout S at the centre — and come out the other side as a prescription file your spreader runs, tree by tree.
            </p>
          </div>
          <window.RevScoutHub setRoute={setRoute} />
        </div>
      </section>

      {/* ===== Outcome — variable-rate from the stack ===== */}
      <section className="section warm">
        <div className="container-wide">
          <div className="section-eyebrow" data-reveal>The outcome</div>
          <h2 className="section-title" data-reveal>Work precisely, <em>from the ground up</em>.</h2>
          <div className="usecase-row" data-reveal>
            <div className="uc-text">
              <div className="uc-num">APPLICATION · VARIABLE RATE</div>
              <h3>Nitrogen by tree, not by block</h3>
              <p>The same stack you watched build becomes a prescription map. Vigorous trees get less, weak trees get more — the spreader follows it row by row, and the block evens out by next season.</p>
              <div className="uc-meta">
                <div>AVG REDUCTION<strong>−18% N use</strong></div>
                <div>YIELD UNIFORMITY<strong>+24%</strong></div>
              </div>
            </div>
            <div className="uc-visual" data-img-file="assets/vigour-hr-prescription.png" role="img"
              aria-label="High-resolution canopy vigour driving a variable-rate prescription map"
              style={{ borderRadius: 14, overflow: 'hidden', backgroundImage: "url('assets/vigour-hr-prescription.png')", backgroundSize: 'cover', backgroundPosition: 'center', aspectRatio: '16 / 10' }} />
          </div>
        </div>
      </section>

      {/* ===== CTA ===== */}
      <section className="cta-banner">
        <div className="container-wide cta-banner-grid" style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 'var(--space-4)', alignItems: 'center' }}>
          <div>
            <h2>Want to see <em style={{ fontFamily: "'Instrument Serif', serif", color: '#B8DC73', fontStyle: 'italic', fontWeight: 400 }}>your</em> blocks like this?</h2>
            <p>Book a 30-minute walk-through with one of our agronomists. We'll load your farm into RevToolbox and read it back to you — soil, canopy and fruit, layer by layer.</p>
            <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap' }}>
              <a className="btn btn-primary btn-lg" href="#" onClick={e => { e.preventDefault(); setRoute('contact'); }}>Book a demo →</a>
              <a className="btn btn-light btn-lg" href="#" onClick={e => { e.preventDefault(); setRoute('pricing'); }}>See pricing</a>
            </div>
          </div>
          <div>
            <div role="img" aria-label="Per-tree fruit size and yield map"
              data-img-file="assets/per-tree-size-yield.png"
              style={{ width: '100%', aspectRatio: '16 / 10', borderRadius: 'var(--radius-lg)', backgroundImage: "url('assets/per-tree-size-yield.png')", backgroundSize: 'cover', backgroundPosition: 'center', border: '1px solid rgba(255,255,255,0.12)' }} />
          </div>
        </div>
      </section>
    </>
  );
};
