// ============================================
// App entry
// ============================================
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#00A0E0",
  "backdrop": "cinematic",
  "noise": true,
  "cursor": true,
  "headFont": "cormorant",
  "hero": "editorial"
}/*EDITMODE-END*/;

function App() {
  const [tweaks, setTweak] = useTweaks(TWEAK_DEFAULTS);

  // Apply tweaks to root
  React.useEffect(() => {
    const r = document.documentElement;
    r.style.setProperty('--gold', tweaks.accent);
    r.setAttribute('data-backdrop', tweaks.backdrop);
    r.setAttribute('data-noise', tweaks.noise ? 'on' : 'off');
    r.setAttribute('data-cursor', tweaks.cursor ? 'on' : 'off');
    r.setAttribute('data-headfont', tweaks.headFont);
    r.setAttribute('data-hero', tweaks.hero);
  }, [tweaks]);

  // Scroll-reveal — scroll-based, with hidden-iframe fallback
  React.useEffect(() => {
    let pending = [];

    const revealNoAnim = (el) => {
      // When the tab is hidden, CSS transitions are paused — we need to skip them.
      el.style.transition = 'none';
      el.classList.add('is-in');
    };
    const revealAll = () => {
      document.querySelectorAll('.reveal:not(.is-in)').forEach(revealNoAnim);
      pending = [];
    };
    const refresh = () => {
      if (document.hidden) { revealAll(); return; }
      pending = [...document.querySelectorAll('.reveal:not(.is-in)')];
      check();
    };
    const check = () => {
      const vh = window.innerHeight;
      const trigger = vh - 60;
      pending = pending.filter(el => {
        const rect = el.getBoundingClientRect();
        if (rect.top < trigger && rect.bottom > 0) {
          el.classList.add('is-in');
          return false;
        }
        return true;
      });
    };

    refresh();
    let raf = 0;
    const onScroll = () => {
      if (raf) return;
      raf = requestAnimationFrame(() => {
        raf = 0;
        check();
      });
    };
    const onVis = () => {
      if (document.hidden) revealAll();
      // When becoming visible, clear any inline 'transition: none' we added
      else document.querySelectorAll('.reveal.is-in').forEach(el => { el.style.transition = ''; });
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', refresh);
    document.addEventListener('visibilitychange', onVis);
    const t1 = setTimeout(refresh, 200);
    const t2 = setTimeout(refresh, 1000);

    return () => {
      window.removeEventListener('scroll', onScroll);
      window.removeEventListener('resize', refresh);
      document.removeEventListener('visibilitychange', onVis);
      clearTimeout(t1);
      clearTimeout(t2);
      if (raf) cancelAnimationFrame(raf);
    };
  }, []);

  return (
    <>
      {tweaks.cursor && <Cursor/>}
      {tweaks.noise && <div className="backdrop-noise" aria-hidden="true"></div>}
      <Nav/>
      <main>
        <Hero/>
        <Services/>
        <Process/>
        <Portfolio/>
        <Tools/>
        <Testimonial/>
        <Pricing/>
        <Why/>
        <Contact/>
      </main>
      <Footer/>
      <Tweaks t={tweaks} setTweak={setTweak}/>
    </>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App/>);
