/* =====================================================================
   GRUG GROUP — shared CORE (helpers + chrome)
   Loaded on every page before grug-sections.jsx.
   Exposes window.GRUG with helpers + chrome components.
   ===================================================================== */

/* ---- Resource map (replaces per-page <meta> resource tags) ---- */
window.__resources = {
  logoGrug:            './assets/web/logo-grug-2026.png',
  bjSunset:            './assets/web/jet-supersonic-coast-sunset.jpg',
  bjDay:               './assets/web/jet-supersonic-coast-day.jpg',
  bjAlps:              './assets/web/jet-supersonic-1.jpg',
  bjTopdown:           './assets/web/jet-supersonic-topdown.jpg',
  bjWhite:             './assets/web/jet-supersonic-white.jpg',
  ghostCity:           './assets/web/ghost-x-passenger-city.jpg',
  ghostCargo:          './assets/web/ghost-x-cargo-tarmac.jpg',
  sbxFront:            './assets/web/aircraft-render-front.png',
  clientNavy:          './assets/web/client-navy-evtol-carrier.jpg',
  clientNasa:          './assets/web/client-nasa-titan-explorer.jpg',
  clientStealthFleet:  './assets/web/client-usaf-stealth-fleet.jpg',
  clientStealthSunset: './assets/web/client-stealth-runway-sunset.jpg',
  clientStealthClouds: './assets/web/client-stealth-clouds.jpg',
  clientVeltro:        './assets/web/client-veltro-nyc.jpg',
  clientVtolNyc:       './assets/web/client-vtol-manhattan-sunset.jpg',
  clientJetx:          './assets/web/client-jetx-ground.jpg',
  clientVeloce:        './assets/web/client-veloce-jetworks-board.jpg',
  teamNelson:          './assets/web/team-nelson.jpg',
  teamUrupagua:        './assets/web/team-urupagua.jpg',
  clientHelipad:       './assets/web/client-evtol-helipad-coast.jpg',
  doggyHero:           './assets/web/doggy-drone-hero.jpg',
  doggyWheel:          './assets/web/doggy-drone-wheelchair.jpg',
  doggyApp:            './assets/web/doggy-drone-app.jpg',
  doggyDetail:         './assets/web/doggy-drone-detail.jpg',
  logoJetx:            './assets/web/logo-jetx.png',
  logoJetxReal:        './assets/web/logo-jetx-real.png',
  awardXtech:          './assets/web/award-xtech.png',
  awardSbirAf:         './assets/web/award-sbir-af.png',
  awardAfwerx:         './assets/web/award-afwerx.png',
  awardArmySbir:       './assets/web/award-army-sbir.jpg',
  logoMatrix:          './assets/web/logo-matrix.png',
  logoNalwa:           './assets/web/logo-nalwa.png',
  reelVideo:           './assets/web/reel-aircraft.mp4',
  reelVideo2:          './assets/web/reel-02.mp4',
  reelVideo3:          './assets/web/reel-03.mp4',
  reelVideo4:          './assets/web/reel-04.mp4',
  reelVideo5:          './assets/web/reel-05.mp4',
  processBoard:        './assets/web/process-showcase.jpg',
  extraNasa:           './assets/web/extra-nasa-titan.jpg',
  extraDoggy:          './assets/web/extra-doggy-paw.jpg',
  extraEvtol:          './assets/web/extra-evtol-city.jpg',
  favoriteAlpine:      './assets/web/favorite-alpine-jet.jpg',
  ryzrSide:            './assets/web/ryzr-speedster-side-pano.jpg',
  ryzrRooftop:         './assets/web/ryzr-speedster-rooftop-dusk.jpg',
  ryzr3View:           './assets/web/ryzr-speedster-3view.jpg',
  ryzrSkyline:         './assets/web/ryzr-speedster-skyline-sunset.jpg',
  nalwaExterior:       './assets/web/nalwa-5x-exterior.png',
  nalwaMountains:      './assets/web/nalwa-mountains.png',
  nalwaCabin:          './assets/web/nalwa-cabin-2seat.png',
  nalwaCockpit:        './assets/web/nalwa-cockpit.png',
  nalwaCruise:         './assets/web/nalwa-cruise.png',
  prototypeHover:      './assets/web/prototype-hover.jpg',
  prototypeGround:     './assets/web/prototype-ground.jpg',
  protoAirframe:       './assets/web/proto-airframe.png',
  protoFluidic:        './assets/web/proto-fluidic.png',
  protoTwinFans:       './assets/web/proto-twin-fans.jpg',
  protoHinge:          './assets/web/proto-nozzle-hinge.jpg',
  protoNozzleFlow:     './assets/web/proto-nozzle-flow.jpg',
  protoNozzleSide:     './assets/web/proto-nozzle-side.jpg',
  protoVane:           './assets/web/proto-vane.jpg',
  nalwaProtoPark:      './assets/web/nalwa-hover-park.jpg',
  nalwaProtoRooftop:   './assets/web/nalwa-hover-rooftop.jpg',
  nalwaProtoGround:    './assets/web/nalwa-ground-pad.jpg',
  nalwaProtoClouds:    './assets/web/nalwa-cruise-clouds.jpg',
};

const R = () => window.__resources || {};
const { useState, useEffect, useRef } = React;

/* ============ HOOKS ============ */
const useReveal = () => {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current; if (!el) return;
    // Already in (or near) the viewport on mount → reveal immediately.
    const inView = () => {
      const r = el.getBoundingClientRect();
      const vh = window.innerHeight || document.documentElement.clientHeight;
      return r.top < vh * 0.92 && r.bottom > 0;
    };
    if (inView()) { el.classList.add('is-visible'); return; }
    let done = false;
    const reveal = () => { if (!done) { done = true; el.classList.add('is-visible'); } };
    let io;
    if ('IntersectionObserver' in window) {
      io = new IntersectionObserver(entries => {
        entries.forEach(e => { if (e.isIntersecting) { reveal(); io.disconnect(); } });
      }, { threshold: 0.12, rootMargin: '0px 0px -8% 0px' });
      io.observe(el);
    } else {
      reveal();
    }
    // Safety net: never let content stay hidden. If nothing fired, reveal.
    const onScroll = () => { if (inView()) { reveal(); cleanup(); } };
    const fallback = setTimeout(reveal, 2600);
    window.addEventListener('scroll', onScroll, { passive: true });
    function cleanup() {
      window.removeEventListener('scroll', onScroll);
      clearTimeout(fallback);
      if (io) io.disconnect();
    }
    return cleanup;
  }, []);
  return ref;
};

const useScrolled = (threshold = 24) => {
  const [scrolled, setScrolled] = useState(false);
  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > threshold);
    window.addEventListener('scroll', onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener('scroll', onScroll);
  }, [threshold]);
  return scrolled;
};

const useCountUp = (target, duration = 1800) => {
  const ref = useRef(null);
  const [value, setValue] = useState(0);
  useEffect(() => {
    let raf;
    const t0 = performance.now() + 350;            // tiny delay after mount, then always animate
    const tick = (t) => {
      if (t < t0) { raf = requestAnimationFrame(tick); return; }
      const p = Math.min(1, (t - t0) / duration);
      const eased = 1 - Math.pow(1 - p, 3);
      setValue(Math.round(eased * target));
      if (p < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [target, duration]);
  return [ref, value];
};

/* ============ SCROLL PROGRESS BAR ============ */
const ScrollProgress = () => {
  const fillRef = useRef(null);
  useEffect(() => {
    const onScroll = () => {
      const h = document.documentElement;
      const max = (h.scrollHeight - h.clientHeight) || 1;
      const pct = Math.min(100, Math.max(0, (window.scrollY / max) * 100));
      if (fillRef.current) fillRef.current.style.width = pct + '%';
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  return (
    <div className="grug-progress" aria-hidden="true">
      <div className="grug-progress__fill" ref={fillRef} />
    </div>
  );
};

/* ============ CUSTOM CURSOR ============ */
const CursorFollower = () => {
  const ringRef = useRef(null);
  const dotRef  = useRef(null);
  useEffect(() => {
    if (window.matchMedia('(hover: none)').matches) return;
    const ring = ringRef.current, dot = dotRef.current;
    let tx = 0, ty = 0, rx = 0, ry = 0, raf, idleTimer;
    const onMove = (e) => {
      tx = e.clientX; ty = e.clientY;
      if (dot) { dot.style.transform = `translate(${tx}px, ${ty}px) translate(-50%, -50%)`; }
      if (!ring.classList.contains('is-ready')) ring.classList.add('is-ready');
      if (!dot.classList.contains('is-ready')) dot.classList.add('is-ready');
      ring.classList.remove('is-idle'); dot.classList.remove('is-idle');
      clearTimeout(idleTimer);
      idleTimer = setTimeout(() => { ring.classList.add('is-idle'); dot.classList.add('is-idle'); }, 2400);
    };
    const tick = () => {
      rx += (tx - rx) * 0.18; ry += (ty - ry) * 0.18;
      if (ring) ring.style.transform = `translate(${rx}px, ${ry}px) translate(-50%, -50%)`;
      raf = requestAnimationFrame(tick);
    };
    const onOver = (e) => { const el = e.target.closest && e.target.closest('a, button, [role="button"], .grug-project, .grug-cap-row, .grug-client'); if (el) ring.classList.add('is-hot'); };
    const onOut  = (e) => { const el = e.target.closest && e.target.closest('a, button, [role="button"], .grug-project, .grug-cap-row, .grug-client'); if (el) ring.classList.remove('is-hot'); };
    const onDown = () => ring.classList.add('is-pressed');
    const onUp   = () => ring.classList.remove('is-pressed');
    const onLeave = () => { ring.classList.remove('is-ready'); dot.classList.remove('is-ready'); };
    window.addEventListener('mousemove', onMove, { passive: true });
    window.addEventListener('mouseover', onOver, true);
    window.addEventListener('mouseout', onOut, true);
    window.addEventListener('mousedown', onDown);
    window.addEventListener('mouseup', onUp);
    document.addEventListener('mouseleave', onLeave);
    raf = requestAnimationFrame(tick);
    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener('mousemove', onMove);
      window.removeEventListener('mouseover', onOver, true);
      window.removeEventListener('mouseout', onOut, true);
      window.removeEventListener('mousedown', onDown);
      window.removeEventListener('mouseup', onUp);
      document.removeEventListener('mouseleave', onLeave);
    };
  }, []);
  return (
    <>
      <div className="grug-cursor" ref={ringRef} aria-hidden="true" />
      <div className="grug-cursor__dot" ref={dotRef} aria-hidden="true" />
    </>
  );
};

/* ============ ANIMATED ICONS ============ */
const Ico = {
  pencil: (
    <svg viewBox="0 0 64 64" className="ico ico--pencil">
      <defs><linearGradient id="icoBlu" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stopColor="#8FBCF6"/><stop offset="1" stopColor="#1A66D6"/></linearGradient></defs>
      <path className="ico-draw" d="M14 44 L26 32 L20 26 L34 16 L46 28 L40 34 L52 46" fill="none" stroke="url(#icoBlu)" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/>
      <g className="ico-pencil"><path d="M0 -2 L12 -2 L18 4 L12 10 L0 10 Z" fill="url(#icoBlu)" opacity="0.85"/><path d="M12 -2 L18 4 L12 10 Z" fill="#fff" opacity="0.4"/></g>
      <g className="ico-spark"><path d="M50 14 l0 5 M47.5 16.5 l5 0" stroke="#fff" strokeWidth="1.2" strokeLinecap="round"/><circle cx="50" cy="16.5" r="1" fill="#fff"/></g>
    </svg>
  ),
  design: (
    <svg viewBox="0 0 64 64" className="ico ico--globe">
      <g className="ico-rot" transform-origin="32 32">
        <circle cx="32" cy="32" r="18" fill="none" stroke="#4F95EE" strokeWidth="1.4"/>
        <ellipse cx="32" cy="32" rx="18" ry="7" fill="none" stroke="#4F95EE" strokeWidth="1" opacity="0.6"/>
        <ellipse cx="32" cy="32" rx="7" ry="18" fill="none" stroke="#4F95EE" strokeWidth="1" opacity="0.6"/>
        <line x1="14" y1="32" x2="50" y2="32" stroke="#8FBCF6" strokeWidth="1.2"/>
        <line x1="32" y1="14" x2="32" y2="50" stroke="#8FBCF6" strokeWidth="1.2"/>
      </g>
      <g className="ico-cross">
        <line x1="4" y1="32" x2="10" y2="32" stroke="#fff" strokeWidth="1.4" strokeLinecap="round"/>
        <line x1="54" y1="32" x2="60" y2="32" stroke="#fff" strokeWidth="1.4" strokeLinecap="round"/>
        <line x1="32" y1="4" x2="32" y2="10" stroke="#fff" strokeWidth="1.4" strokeLinecap="round"/>
        <line x1="32" y1="54" x2="32" y2="60" stroke="#fff" strokeWidth="1.4" strokeLinecap="round"/>
      </g>
      <circle className="ico-dot" cx="32" cy="32" r="2.4" fill="#fff"/>
    </svg>
  ),
  render: (
    <svg viewBox="0 0 64 64" className="ico ico--lens">
      <rect x="8" y="16" width="48" height="32" rx="3" fill="none" stroke="#4F95EE" strokeWidth="1.4"/>
      <circle cx="32" cy="32" r="10" fill="none" stroke="#8FBCF6" strokeWidth="1.4"/>
      <circle cx="32" cy="32" r="6" fill="none" stroke="#fff" strokeWidth="1" opacity="0.6"/>
      <circle className="ico-iris" cx="32" cy="32" r="3" fill="#1A66D6"/>
      <line className="ico-scan" x1="22" y1="22" x2="22" y2="42" stroke="#fff" strokeWidth="1" opacity="0.6" strokeDasharray="2 3"/>
      <rect x="46" y="19" width="4" height="2.4" rx="0.6" fill="#E40521" className="ico-blip"/>
    </svg>
  ),
  cabin: (
    <svg viewBox="0 0 64 64" className="ico ico--cabin">
      <path d="M8 32 C8 22 18 14 32 14 C46 14 56 22 56 32 C56 42 46 50 32 50 C18 50 8 42 8 32 Z" fill="none" stroke="#4F95EE" strokeWidth="1.4"/>
      <line x1="14" y1="32" x2="50" y2="32" stroke="#8FBCF6" strokeWidth="0.8" strokeDasharray="2 2" opacity="0.7"/>
      <g className="ico-seats">
        <rect x="18" y="22" width="6" height="3.5" rx="0.8" fill="#1A66D6"/><rect x="18" y="38.5" width="6" height="3.5" rx="0.8" fill="#1A66D6"/>
        <rect x="29" y="22" width="6" height="3.5" rx="0.8" fill="#1A66D6"/><rect x="29" y="38.5" width="6" height="3.5" rx="0.8" fill="#1A66D6"/>
        <rect x="40" y="22" width="6" height="3.5" rx="0.8" fill="#1A66D6"/><rect x="40" y="38.5" width="6" height="3.5" rx="0.8" fill="#1A66D6"/>
      </g>
      <circle cx="52" cy="32" r="1.6" fill="#fff"/>
    </svg>
  ),
  strategy: (
    <svg viewBox="0 0 64 64" className="ico ico--radar">
      <circle cx="32" cy="32" r="22" fill="none" stroke="rgba(143,188,246,0.35)" strokeWidth="1"/>
      <circle cx="32" cy="32" r="14" fill="none" stroke="rgba(143,188,246,0.45)" strokeWidth="1"/>
      <circle cx="32" cy="32" r="6" fill="none" stroke="rgba(143,188,246,0.6)" strokeWidth="1"/>
      <line x1="32" y1="10" x2="32" y2="54" stroke="#4F95EE" strokeWidth="0.8" opacity="0.5"/>
      <line x1="10" y1="32" x2="54" y2="32" stroke="#4F95EE" strokeWidth="0.8" opacity="0.5"/>
      <g className="ico-sweep" transform-origin="32 32">
        <path d="M32 32 L54 32 A22 22 0 0 0 47 16 Z" fill="url(#icoSweep)"/>
        <defs><linearGradient id="icoSweep" x1="1" y1="0.5" x2="0.2" y2="0"><stop offset="0" stopColor="#1A66D6" stopOpacity="0.55"/><stop offset="1" stopColor="#1A66D6" stopOpacity="0"/></linearGradient></defs>
        <line x1="32" y1="32" x2="54" y2="32" stroke="#8FBCF6" strokeWidth="1.4"/>
      </g>
      <circle className="ico-blip-a" cx="44" cy="24" r="1.6" fill="#fff"/>
      <circle className="ico-blip-b" cx="20" cy="40" r="1.6" fill="#E40521"/>
    </svg>
  ),
};

/* ============ SECTION INDEX ============ */
const SectionIndex = ({ no, title, meta }) => (
  <div className="grug-index" aria-hidden="true">
    <div className="grug-index__no">{no}</div>
    <div className="grug-index__title">{title}</div>
    <div className="grug-index__meta">{meta}</div>
    <div className="grug-index__live"><span className="grug-index__dot" />LIVE</div>
  </div>
);

/* ============ NAV — multipage with mobile drawer ============ */
const NAV_ITEMS = [
  { label: 'Home',         href: 'index.html',        key: 'home' },
  { label: 'Portfolio',    href: 'portfolio.html',    key: 'portfolio' },
  { label: 'Capabilities', href: 'capabilities.html', key: 'capabilities' },
  { label: 'About',        href: 'about.html',        key: 'about' },
  { label: 'Contact',      href: 'contact.html',      key: 'contact' },
];
const Nav = ({ active }) => {
  const scrolled = useScrolled();
  const [open, setOpen] = useState(false);
  useEffect(() => {
    document.body.style.overflow = open ? 'hidden' : '';
    return () => { document.body.style.overflow = ''; };
  }, [open]);
  return (
    <header className={`grug-nav ${scrolled ? 'is-scrolled' : ''} ${open ? 'is-open' : ''}`}>
      <a href="index.html" className="grug-nav__logo">
        <img src={R().logoGrug} alt="GRUG GROUP — Future Technologies" />
      </a>
      <nav className="grug-nav__items">
        {NAV_ITEMS.map(i => (
          <a key={i.key} href={i.href} className={`grug-nav__link ${active === i.key ? 'is-active' : ''}`}>{i.label}</a>
        ))}
      </nav>
      <div className="grug-nav__extras">
        <a className="grug-btn grug-btn--primary grug-btn--sm" href="contact.html">Start a project <span className="chev">›</span></a>
      </div>
      <button type="button" className="grug-nav__burger" aria-label="Menu" aria-expanded={open} onClick={() => setOpen(o => !o)}>
        <span /><span /><span />
      </button>

      <div className={`grug-navmenu ${open ? 'is-open' : ''}`} onClick={() => setOpen(false)}>
        <nav className="grug-navmenu__inner" onClick={(e) => e.stopPropagation()}>
          {NAV_ITEMS.map((i, n) => (
            <a key={i.key} href={i.href} className={`grug-navmenu__link ${active === i.key ? 'is-active' : ''}`}>
              <span className="grug-navmenu__n">{String(n + 1).padStart(2, '0')}</span>
              {i.label}
            </a>
          ))}
          <a href="contact.html" className="grug-btn grug-btn--primary grug-navmenu__cta">Start a project <span className="chev">›</span></a>
        </nav>
      </div>
    </header>
  );
};

/* ============ PAGE HERO — compact inner-page banner ============ */
const PageHero = ({ index, eyebrow, title, sub, imgKey, accent }) => {
  const ref = useReveal();
  return (
    <section className="grug-pagehero" data-screen-label={`${title} hero`}>
      <div className="grug-pagehero__img" style={{ backgroundImage: `url(${R()[imgKey]})` }} />
      <div className="grug-pagehero__scrim" />
      <div className="grug-pagehero__grid" />
      <div ref={ref} className="grug-pagehero__content reveal">
        <div className="grug-pagehero__index">{index}</div>
        <div className="grug-eyebrow">{eyebrow}</div>
        <h1 className="grug-pagehero__title" dangerouslySetInnerHTML={{ __html: title }} />
        {sub && <p className="grug-pagehero__sub">{sub}</p>}
      </div>
      <div className="grug-pagehero__scroll" aria-hidden="true">
        <span>SCROLL</span><i />
      </div>
    </section>
  );
};

/* ============ FOOTER ============ */
const SOCIALS = [
  { k: 'Instagram', href: 'https://www.instagram.com/gruggroup/',
    svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="18" height="18" rx="5"/><circle cx="12" cy="12" r="4"/><circle cx="17.5" cy="6.5" r="0.6" fill="currentColor"/></svg> },
  { k: 'YouTube', href: 'https://www.youtube.com/channel/UCWertDHMVt-howVsm3IJ6DA',
    svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><rect x="2.5" y="5.5" width="19" height="13" rx="3"/><path d="M10 9.5l5 2.5-5 2.5z" fill="currentColor" stroke="none"/></svg> },
  { k: 'Facebook', href: 'https://www.facebook.com/gruggroupllc',
    svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M14 8h2.5V5H14c-2 0-3.5 1.5-3.5 3.5V11H8v3h2.5v6.5h3V14H16l.5-3h-3V8.5c0-.3.2-.5.5-.5z"/></svg> },
  { k: 'X · Twitter', href: 'https://twitter.com/LlcGrug',
    svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6"><path d="M4 4l7.5 9.5L4.5 20h2L12.5 14l4.7 6H20l-7.7-9.8L19.4 4h-2l-5.3 5.7L7.7 4z" fill="currentColor" stroke="none"/></svg> },
  { k: 'WhatsApp', href: 'https://wa.link/33zwnl',
    svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M3.5 20.5l1.4-4.6A8 8 0 1 1 8.1 19.4L3.5 20.5z"/><path d="M8.5 9c.2-.4.6-.5 1-.5h.8c.2 0 .4.1.5.3l.7 1.6c.1.2.1.4 0 .6l-.5.8a6.5 6.5 0 0 0 3 3l.8-.5c.2-.1.4-.1.6 0l1.6.7c.2.1.3.3.3.5v.8c0 .4-.1.8-.5 1A4 4 0 0 1 8.5 9z" fill="currentColor" stroke="none"/></svg> },
];
const Footer = () => (
  <footer className="grug-footer" data-screen-label="Footer">
    <div className="grug-footer__inner">
      <div className="grug-footer__brand">
        <img src={R().logoGrug} alt="GRUG GROUP — Future Technologies" />
        <p>An aerospace design studio and aviation solutions company operating since 2017. Headquartered in Fort Lauderdale, Florida. We help our clients turn ideas into concept-ready aircraft and the stories that surround them.</p>
        <div className="grug-footer__socialsTall" aria-label="Social media">
          {SOCIALS.map(s => (
            <a key={s.k} href={s.href} target="_blank" rel="noopener noreferrer" className="grug-footer__social is-tall" aria-label={s.k} title={s.k}>{s.svg}</a>
          ))}
        </div>
      </div>
      <div className="grug-footer__col">
        <div className="grug-footer__h">Pages</div>
        <a href="index.html">Home</a>
        <a href="portfolio.html">Portfolio &amp; Prototyping</a>
        <a href="capabilities.html">Capabilities</a>
        <a href="about.html">About</a>
        <a href="contact.html">Contact</a>
      </div>
      <div className="grug-footer__col">
        <div className="grug-footer__h">Capabilities</div>
        <a href="capabilities.html">Concept Design</a>
        <a href="capabilities.html">Industrial Design</a>
        <a href="capabilities.html">Visualization</a>
        <a href="capabilities.html">Cabin &amp; Interior</a>
        <a href="capabilities.html">Aviation Consulting</a>
      </div>
      <div className="grug-footer__col">
        <div className="grug-footer__h">Connect</div>
        <a href="mailto:info@gruggroup.com">info@gruggroup.com</a>
        <a href="contact.html">Fort Lauderdale, FL · USA</a>
        <a href="contact.html">Start a project</a>
      </div>
    </div>
    <div className="grug-footer__legal">
      <span>© 2017–2026 GRUG GROUP LLC</span>
      <span>FUTURE TECHNOLOGIES</span>
    </div>
  </footer>
);

/* ---- export ---- */
window.GRUG = Object.assign(window.GRUG || {}, {
  R, useReveal, useScrolled, useCountUp,
  ScrollProgress, CursorFollower, Ico, SectionIndex,
  Nav, PageHero, Footer, SOCIALS,
});
