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

/* ── Logo ── */
function MagicLogo({ size = 40 }) {
  const h = size;
  const w = Math.round(h * 3.6);
  return (
    <svg width={w} height={h} viewBox="0 0 144 40" fill="none" xmlns="http://www.w3.org/2000/svg" aria-label="Magic Home Renovation">
      {/* Mark — abstract roof / M glyph */}
      <g>
        {/* Roof outline — two peaks = letter M + house */}
        <polyline points="2,28 14,10 22,20 30,10 42,28" stroke="#C9A84C" strokeWidth="1.5" strokeLinejoin="round" fill="none"/>
        {/* Ground line */}
        <line x1="2" y1="28" x2="42" y2="28" stroke="#C9A84C" strokeWidth="1" opacity="0.5"/>
        {/* Door hint */}
        <rect x="18" y="21" width="8" height="7" stroke="#C9A84C" strokeWidth="0.8" opacity="0.6"/>
      </g>
      {/* Divider */}
      <line x1="52" y1="8" x2="52" y2="32" stroke="#C9A84C" strokeWidth="0.5" opacity="0.4"/>
      {/* Wordmark */}
      <text x="60" y="20" fontFamily="'Playfair Display', Georgia, serif" fontWeight="700" fontSize="11" letterSpacing="3" fill="#C9A84C" dominantBaseline="middle">MAGIC</text>
      <text x="60" y="32" fontFamily="'Inter', sans-serif" fontWeight="300" fontSize="6.5" letterSpacing="3.5" fill="#8A8A8E" dominantBaseline="middle">HOME RENOVATION</text>
    </svg>
  );
}

/* ── Scroll reveal ── */
function useReveal(threshold = 0.08) {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current; if (!el) return;
    const obs = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) { el.style.opacity='1'; el.style.transform='none'; }
    }, { threshold, rootMargin:'0px 0px -40px 0px' });
    obs.observe(el);
    return () => obs.disconnect();
  }, []);
  return ref;
}

/* ── Parallax + hover zoom for photo bg images ── */
function useImageParallax(speed = 0.1) {
  const imgRef = useRef(null);
  useEffect(() => {
    const el = imgRef.current; if (!el) return;
    const section = el.parentElement;
    let lastY = 0;
    const getY = () => { const r = section.getBoundingClientRect(); return (r.top + r.height / 2 - window.innerHeight / 2) * speed; };
    const onScroll = () => { lastY = getY(); el.style.transition = 'none'; el.style.transform = `scale(1.1) translateY(${lastY}px)`; };
    const onEnter = () => { lastY = getY(); el.style.transition = 'transform 500ms var(--ease-cinematic)'; el.style.transform = `scale(1.16) translateY(${lastY}px)`; };
    const onLeave = () => { lastY = getY(); el.style.transition = 'transform 500ms var(--ease-cinematic)'; el.style.transform = `scale(1.1) translateY(${lastY}px)`; };
    window.addEventListener('scroll', onScroll, { passive: true });
    section.addEventListener('mouseenter', onEnter);
    section.addEventListener('mouseleave', onLeave);
    onScroll();
    return () => { window.removeEventListener('scroll', onScroll); section.removeEventListener('mouseenter', onEnter); section.removeEventListener('mouseleave', onLeave); };
  }, []);
  return imgRef;
}

/* ── Animated counter ── */
function useCounter(target, duration, active) {
  const [val, setVal] = useState(0);
  const done = useRef(false);
  useEffect(() => {
    if (!active || done.current) return;
    done.current = true;
    const num = parseInt(String(target).replace(/[^0-9]/g, '')) || 0;
    if (!num) return;
    const t0 = performance.now();
    const tick = now => {
      const p = Math.min((now - t0) / duration, 1);
      setVal(Math.round((1 - Math.pow(1 - p, 3)) * num));
      if (p < 1) requestAnimationFrame(tick); else setVal(num);
    };
    requestAnimationFrame(tick);
  }, [active]);
  return val;
}

/* ── Typewriter ── */
function useTypewriter(text, speed = 55) {
  const [i, setI] = useState(0);
  useEffect(() => {
    if (i >= text.length) return;
    const t = setTimeout(() => setI(n => n + 1), speed);
    return () => clearTimeout(t);
  }, [i]);
  return text.slice(0, i);
}

/* ── Stat counter (animated on reveal) ── */
function StatCounter({ value, label }) {
  const [active, setActive] = useState(false);
  const ref = useRef(null);
  const num = parseInt(String(value).replace(/[^0-9]/g, '')) || 0;
  const suffix = value.replace(/[\d,]/g, '');
  const counted = useCounter(num, 2200, active);
  const display = num >= 1000 ? counted.toLocaleString('en-US') : String(counted);
  useEffect(() => {
    const el = ref.current; if (!el) return;
    const obs = new IntersectionObserver(([e]) => { if (e.isIntersecting) setActive(true); }, { threshold: 0.1 });
    obs.observe(el);
    return () => obs.disconnect();
  }, []);
  return (
    <div ref={ref} style={{ textAlign:'right' }}>
      <div style={{ font:'600 clamp(20px,2.2vw,28px)/1 var(--font-serif)',color:'var(--gold)',letterSpacing:'-0.02em' }}>{display}{suffix}</div>
      <div style={{ font:'400 9px var(--font-sans)',letterSpacing:'0.22em',textTransform:'uppercase',color:'rgba(245,245,240,0.35)',marginTop:6 }}>{label}</div>
    </div>
  );
}

/* ── Gold trailing cursor dot ── */
function Cursor() {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current; if (!el) return;
    let cx = -20, cy = -20, tx = -20, ty = -20, raf, moving = false;
    const onMove = e => { tx = e.clientX; ty = e.clientY; if (!moving) { moving = true; raf = requestAnimationFrame(loop); } };
    window.addEventListener('mousemove', onMove, { passive: true });
    const loop = () => { const dx = tx-cx, dy = ty-cy; cx += dx*0.13; cy += dy*0.13; el.style.transform=`translate(${cx}px,${cy}px)`; if (Math.abs(dx) > 0.1 || Math.abs(dy) > 0.1) { raf = requestAnimationFrame(loop); } else { moving = false; } };
    return () => { window.removeEventListener('mousemove', onMove); cancelAnimationFrame(raf); };
  }, []);
  return <div ref={ref} style={{ position:'fixed',top:-5,left:-5,width:10,height:10,borderRadius:'50%',background:'var(--gold)',pointerEvents:'none',zIndex:9998,opacity:0.6,mixBlendMode:'screen' }}/>;
}

/* ── Scroll progress bar ── */
function ScrollProgress() {
  const [pct, setPct] = useState(0);
  useEffect(() => {
    const fn = () => { const max = document.documentElement.scrollHeight - window.innerHeight; setPct(max>0?(window.scrollY/max)*100:0); };
    window.addEventListener('scroll', fn, { passive: true });
    return () => window.removeEventListener('scroll', fn);
  }, []);
  return (
    <div style={{ position:'fixed',top:0,left:0,right:0,height:2,zIndex:200,pointerEvents:'none' }}>
      <div style={{ height:'100%',width:`${pct}%`,background:'linear-gradient(90deg,var(--gold-deep),var(--gold),var(--gold-bright))',transition:'width 60ms linear' }}/>
    </div>
  );
}

/* ── Nav ── */
function Nav() {
  const [scrolled, setScrolled] = useState(false);
  const [open, setOpen] = useState(false);
  useEffect(() => {
    const fn = () => setScrolled(window.scrollY > 80);
    window.addEventListener('scroll', fn, { passive:true });
    return () => window.removeEventListener('scroll', fn);
  }, []);
  const close = () => { setOpen(false); document.body.style.overflow=''; };
  const toggle = () => { const n=!open; setOpen(n); document.body.style.overflow=n?'hidden':''; };
  const links = [['Services','#services'],['Estimate','#estimate'],['Process','#process'],['Inspections','#inspection'],['Contact','#contact']];
  const ls = { font:'600 10px var(--font-sans)',letterSpacing:'0.26em',textTransform:'uppercase',color:'var(--text-muted)',textDecoration:'none',transition:'color 200ms' };
  return (
    <>
      <nav style={{ position:'fixed',top:0,left:0,right:0,zIndex:100,height:72,display:'flex',alignItems:'center',padding:'0 var(--gutter)',background:scrolled?'rgba(10,10,10,0.88)':'transparent',backdropFilter:scrolled?'blur(24px) saturate(160%)':'none',borderBottom:`1px solid ${scrolled?'rgba(201,168,76,0.12)':'transparent'}`,transition:'all 400ms var(--ease-cinematic)' }}>
        <a href="#" style={{ textDecoration:'none',display:'flex',alignItems:'center',gap:12 }}>
          <MagicLogo size={40}/>
        </a>
        <div style={{ display:'flex',gap:36,marginLeft:'auto',alignItems:'center' }} className="nav-links">
          {links.map(([l,h]) => <a key={l} href={h} style={ls} onMouseEnter={e=>e.currentTarget.style.color='var(--gold)'} onMouseLeave={e=>e.currentTarget.style.color='var(--text-muted)'}>{l}</a>)}
          <a href="#contact" style={{ font:'600 10px var(--font-sans)',letterSpacing:'0.26em',textTransform:'uppercase',color:'var(--text-inverse)',background:'var(--gold)',padding:'10px 20px',textDecoration:'none',transition:'background 200ms',marginLeft:8 }} onMouseEnter={e=>e.currentTarget.style.background='var(--gold-bright)'} onMouseLeave={e=>e.currentTarget.style.background='var(--gold)'}>Book Walkthrough</a>
        </div>
        <button onClick={toggle} style={{ display:'none',background:'none',border:'none',cursor:'pointer',marginLeft:'auto',padding:8,flexDirection:'column',gap:5 }} className="hamburger" aria-label="Menu">
          <span style={{ display:'block',width:20,height:1,background:'var(--text)',transition:'all 280ms',transform:open?'translateY(6px) rotate(45deg)':'none' }}/>
          <span style={{ display:'block',width:20,height:1,background:'var(--text)',transition:'all 280ms',opacity:open?0:1 }}/>
          <span style={{ display:'block',width:20,height:1,background:'var(--text)',transition:'all 280ms',transform:open?'translateY(-6px) rotate(-45deg)':'none' }}/>
        </button>
      </nav>
      {open&&<div style={{ position:'fixed',inset:0,top:72,zIndex:99,background:'rgba(10,10,10,0.98)',backdropFilter:'blur(24px)',display:'flex',flexDirection:'column',alignItems:'center',justifyContent:'center',gap:48 }}>
        {links.map(([l,h])=><a key={l} href={h} onClick={close} style={{ ...ls,fontSize:13,color:'var(--text)' }}>{l}</a>)}
        <a href="#contact" onClick={close} className="btn btn--solid" style={{ marginTop:16 }}>Book Walkthrough</a>
      </div>}
      <style>{`@media(max-width:768px){.nav-links{display:none!important}.hamburger{display:flex!important}}`}</style>
    </>
  );
}

/* ── Hero — full screen video/photo + cinematic overlay ── */
function Hero() {
  const VIDEO_SRC = 'assets/hero.mp4';
  const HERO_IMG  = 'assets/hero.jpg';
  const [videoError, setVideoError] = useState(false);
  const ref = useReveal(0.02);
  const eyebrowText = useTypewriter('North Shore Exterior Specialists', 50);
  return (
    <section style={{ position:'relative',height:'100vh',minHeight:680,display:'flex',alignItems:'flex-end',overflow:'hidden' }}>
      {/* Background */}
      {!videoError
        ? <video autoPlay muted loop playsInline onError={()=>setVideoError(true)}
            style={{ position:'absolute',inset:0,width:'100%',height:'100%',objectFit:'cover',objectPosition:'center 30%',zIndex:0 }}>
            <source src={VIDEO_SRC} type="video/mp4" onError={()=>setVideoError(true)}/>
          </video>
        : <img src={HERO_IMG} alt="" aria-hidden style={{ position:'absolute',inset:0,width:'100%',height:'100%',objectFit:'cover',objectPosition:'center 35%',zIndex:0 }}/>
      }
      {/* Cinematic overlays */}
      <div style={{ position:'absolute',inset:0,zIndex:1,background:'linear-gradient(180deg,rgba(10,10,10,.62) 0%,rgba(10,10,10,.18) 35%,rgba(10,10,10,.55) 65%,rgba(10,10,10,.97) 100%)' }}/>
      <div style={{ position:'absolute',inset:0,zIndex:1,background:'radial-gradient(ellipse at 30% 80%,rgba(201,168,76,0.06) 0%,transparent 60%)' }}/>
      {/* Gold vertical line — Ferrari-style accent */}
      <div style={{ position:'absolute',left:'var(--gutter)',top:0,bottom:0,zIndex:2,display:'flex',alignItems:'flex-start',paddingTop:180 }}>
        <div style={{ width:1,height:80,background:'linear-gradient(180deg,transparent,var(--gold),transparent)',opacity:0.6 }}/>
      </div>
      {/* Content */}
      <div ref={ref} style={{ position:'relative',zIndex:3,padding:'0 var(--gutter) clamp(56px,8vh,96px)',width:'100%',maxWidth:920,opacity:0,transform:'translateY(32px)',transition:'opacity 1s var(--ease-out),transform 1s var(--ease-out)' }}>
        <div style={{ display:'flex',alignItems:'center',gap:16,marginBottom:32 }}>
          <div style={{ width:40,height:1,background:'var(--gold)' }}/>
          <span style={{ font:'600 10px var(--font-sans)',letterSpacing:'0.32em',textTransform:'uppercase',color:'var(--gold)' }}>
            {eyebrowText}
            <span style={{ display:'inline-block',width:1,height:'0.9em',background:'var(--gold)',marginLeft:2,verticalAlign:'middle',animation:'blink 0.9s step-end infinite',opacity:eyebrowText.length<'North Shore Exterior Specialists'.length?1:0 }}/>
          </span>
        </div>
        <h1 style={{ font:'700 clamp(48px,7vw,96px)/0.95 var(--font-serif)',letterSpacing:'-0.03em',color:'var(--text)',marginBottom:32 }}>
          A different<br/><em style={{ color:'var(--gold)',fontStyle:'italic' }}>standard</em><br/>of exterior.
        </h1>
        <p style={{ font:'300 clamp(16px,1.6vw,20px)/1.7 var(--font-sans)',color:'rgba(245,245,240,0.65)',maxWidth:520,marginBottom:48 }}>
          Serving Glenview, Highland Park, Winnetka and the North Shore — James Hardie, Nichiha, Equitone. Installed by one crew. Inspected after by someone who doesn't work for us.
        </p>
        <div style={{ display:'flex',gap:24,alignItems:'center',flexWrap:'wrap' }}>
          <a href="#contact" style={{ font:'600 10px var(--font-sans)',letterSpacing:'0.28em',textTransform:'uppercase',color:'var(--text-inverse)',background:'var(--gold)',padding:'16px 32px',textDecoration:'none',transition:'background 200ms' }} onMouseEnter={e=>e.currentTarget.style.background='var(--gold-bright)'} onMouseLeave={e=>e.currentTarget.style.background='var(--gold)'}>Request Walkthrough</a>
          <a href="#services" style={{ font:'600 10px var(--font-sans)',letterSpacing:'0.28em',textTransform:'uppercase',color:'rgba(245,245,240,0.55)',textDecoration:'none',display:'flex',alignItems:'center',gap:12,transition:'color 200ms' }} onMouseEnter={e=>e.currentTarget.style.color='var(--gold)'} onMouseLeave={e=>e.currentTarget.style.color='rgba(245,245,240,0.55)'}>
            Our work
            <svg width="24" height="1" viewBox="0 0 24 1"><line x1="0" y1="0.5" x2="24" y2="0.5" stroke="currentColor" strokeWidth="1"/></svg>
          </a>
        </div>
      </div>
      {/* Stats — animated counters */}
      <div style={{ position:'absolute',bottom:'clamp(48px,7vh,80px)',right:'var(--gutter)',zIndex:3,display:'flex',gap:40 }}>
        {[['40','years'],['1,200+','homes'],['0','subs']].map(([n,l])=>(
          <StatCounter key={l} value={n} label={l}/>
        ))}
      </div>
      {/* Scroll indicator */}
      <div style={{ position:'absolute',bottom:32,left:'50%',transform:'translateX(-50%)',zIndex:3,display:'flex',flexDirection:'column',alignItems:'center',gap:8 }}>
        <div style={{ width:1,height:40,background:'linear-gradient(180deg,transparent,rgba(201,168,76,0.5))',animation:'scrollPulse 2s ease-in-out infinite' }}/>
      </div>
      <style>{`@keyframes scrollPulse{0%,100%{opacity:0.3;transform:scaleY(0.7)}50%{opacity:1;transform:scaleY(1)}}@keyframes blink{0%,100%{opacity:1}50%{opacity:0}}`}</style>
    </section>
  );
}

/* ── Full-screen photo section (reusable) ── */
function PhotoSection({ id, img, align='left', eyebrow, headline, body, cta, ctaHref='#contact', children }) {
  const ref = useReveal(0.06);
  const imgRef = useImageParallax(0.1);
  return (
    <section id={id} style={{ position:'relative',height:'100vh',minHeight:600,display:'flex',alignItems:'center',overflow:'hidden' }}>
      <img ref={imgRef} src={img} alt="" aria-hidden style={{ position:'absolute',inset:0,width:'100%',height:'100%',objectFit:'cover',objectPosition:'center',zIndex:0,willChange:'transform' }}/>
      <div style={{ position:'absolute',inset:0,zIndex:1,background: align==='left'
        ? 'linear-gradient(90deg,rgba(10,10,10,0.96) 0%,rgba(10,10,10,0.75) 45%,rgba(10,10,10,0.15) 100%)'
        : 'linear-gradient(270deg,rgba(10,10,10,0.96) 0%,rgba(10,10,10,0.75) 45%,rgba(10,10,10,0.15) 100%)'
      }}/>
      <div ref={ref} style={{ position:'relative',zIndex:2,padding:'0 var(--gutter)',width:'100%',maxWidth:'var(--container)',margin:'0 auto',display:'flex',justifyContent: align==='left'?'flex-start':'flex-end',opacity:0,transform:`translateX(${align==='left'?-32:32}px)`,transition:'opacity .9s var(--ease-out),transform .9s var(--ease-out)' }}>
        <div style={{ maxWidth:560 }}>
          {eyebrow&&<div style={{ display:'flex',alignItems:'center',gap:14,marginBottom:28 }}>
            <div style={{ width:32,height:1,background:'var(--gold)' }}/>
            <span style={{ font:'600 10px var(--font-sans)',letterSpacing:'0.30em',textTransform:'uppercase',color:'var(--gold)' }}>{eyebrow}</span>
          </div>}
          {headline&&<h2 style={{ font:'600 clamp(36px,4.5vw,60px)/1.05 var(--font-serif)',letterSpacing:'-0.025em',color:'var(--text)',marginBottom:24 }}>{headline}</h2>}
          {body&&<p style={{ font:'300 clamp(15px,1.4vw,18px)/1.75 var(--font-sans)',color:'rgba(245,245,240,0.65)',marginBottom:40 }}>{body}</p>}
          {children}
          {cta&&<a href={ctaHref} style={{ display:'inline-flex',alignItems:'center',gap:16,font:'600 10px var(--font-sans)',letterSpacing:'0.28em',textTransform:'uppercase',color:'var(--gold)',textDecoration:'none',borderBottom:'1px solid var(--gold-40)',paddingBottom:8,transition:'gap 200ms,border-color 200ms' }} onMouseEnter={e=>{e.currentTarget.style.gap='24px';e.currentTarget.style.borderColor='var(--gold)'}} onMouseLeave={e=>{e.currentTarget.style.gap='16px';e.currentTarget.style.borderColor='var(--gold-40)'}}>
            {cta}
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1"><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg>
          </a>}
        </div>
      </div>
    </section>
  );
}

/* ── Services dark grid ── */
function Services() {
  const ref = useReveal(0.05);
  const svcs = [
    { n:'01',tag:'Cladding',title:'Siding & Exteriors',body:"James Hardie ColorPlus, LP SmartSide, cedar restoration. Full tear-off, proper vapor barrier. We don't install over the old." },
    { n:'02',tag:'Apertures',title:'Windows',body:'Marvin and Pella exclusively. Full-frame replacements with proper flashing — not the foam-and-pray method.' },
    { n:'03',tag:'Trim',title:'Soffit, Fascia & Gutters',body:'Aluminum wrapped on-site. Seamless 6″ gutters, hidden hangers. Heat tape on north faces that need it.' },
    { n:'04',tag:'Verification',title:'Post-Contractor Inspection',body:'Independent inspector. Thermal camera, moisture meter. Full written report — with no incentive to find nothing.' },
  ];
  return (
    <section id="services" style={{ background:'var(--bg-primary)',padding:'clamp(80px,12vw,160px) var(--gutter)' }}>
      <div style={{ maxWidth:'var(--container)',margin:'0 auto' }}>
        <div ref={ref} style={{ display:'flex',justifyContent:'space-between',alignItems:'flex-end',marginBottom:'clamp(60px,8vw,100px)',opacity:0,transform:'translateY(24px)',transition:'opacity .8s var(--ease-out),transform .8s var(--ease-out)' }}>
          <div>
            <div style={{ font:'600 10px var(--font-sans)',letterSpacing:'0.30em',textTransform:'uppercase',color:'var(--gold)',marginBottom:20 }}>What we do</div>
            <h2 style={{ font:'600 clamp(36px,4vw,54px)/1.05 var(--font-serif)',letterSpacing:'-0.025em',color:'var(--text)',maxWidth:600 }}>Everything on the outside. Nothing it doesn't need.</h2>
          </div>
          <a href="#contact" style={{ font:'600 10px var(--font-sans)',letterSpacing:'0.24em',textTransform:'uppercase',color:'var(--text-muted)',textDecoration:'none',whiteSpace:'nowrap',borderBottom:'1px solid var(--color-border)',paddingBottom:6,flexShrink:0,display:'none' }} className="svc-all-link">All services →</a>
        </div>
        <div className="svc-grid" style={{ display:'grid',gridTemplateColumns:'repeat(4,1fr)',borderTop:'1px solid var(--color-border)' }}>
          {svcs.map((s,i)=><ServiceCard key={s.n} {...s} last={i===svcs.length-1}/>)}
        </div>
      </div>
      <style>{`@media(max-width:900px){.svc-grid{grid-template-columns:repeat(2,1fr)!important}}@media(max-width:560px){.svc-grid{grid-template-columns:1fr!important}}`}</style>
    </section>
  );
}

function ServiceCard({ n, tag, title, body, last }) {
  const [h, setH] = useState(false);
  const ref = useReveal(0.1);
  const onMove = e => {
    const el = e.currentTarget, r = el.getBoundingClientRect();
    const x = (e.clientX - r.left) / r.width - 0.5;
    const y = (e.clientY - r.top) / r.height - 0.5;
    el.style.transform = `perspective(800px) rotateX(${-y*7}deg) rotateY(${x*7}deg) translateZ(6px)`;
  };
  const onLeave = e => { e.currentTarget.style.transform = 'perspective(800px) rotateX(0deg) rotateY(0deg) translateZ(0)'; setH(false); };
  return (
    <div ref={ref} style={{ borderRight:last?'none':'1px solid var(--color-border)',borderBottom:'1px solid var(--color-border)',opacity:0,transform:'translateY(24px)',transition:'opacity .7s var(--ease-out),transform .7s var(--ease-out)' }}>
      <div onMouseEnter={()=>setH(true)} onMouseMove={onMove} onMouseLeave={onLeave}
        style={{ padding:'clamp(28px,3.5vw,48px) clamp(20px,2.5vw,36px)',minHeight:340,display:'flex',flexDirection:'column',cursor:'default',transition:'background 360ms var(--ease-cinematic),transform 400ms var(--ease-out)',background:h?'var(--bg-elevated)':'transparent' }}>
        <div style={{ font:'500 11px var(--font-mono)',color:h?'var(--gold)':'var(--text-faint)',letterSpacing:'0.2em',marginBottom:'auto',transition:'color 360ms' }}>{n} / {tag}</div>
        <div style={{ marginTop:40 }}>
          <h3 style={{ font:'500 clamp(20px,2vw,26px)/1.2 var(--font-serif)',color:'var(--text)',marginBottom:16 }}>{title}</h3>
          <p style={{ font:'400 14px/1.7 var(--font-sans)',color:'var(--text-muted)' }}>{body}</p>
          <div style={{ marginTop:28,display:'flex',alignItems:'center',gap:10,font:'600 10px var(--font-sans)',letterSpacing:'0.24em',textTransform:'uppercase',color:h?'var(--gold)':'var(--text-faint)',transition:'color 360ms,gap 360ms' }}>
            Learn more
            <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5"><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg>
          </div>
        </div>
      </div>
    </div>
  );
}

function ProcessStep({ n, t, b }) {
  const r = useReveal(0.1);
  return (
    <div ref={r} style={{ background:'var(--bg-secondary)',padding:'clamp(28px,3vw,44px)',opacity:0,transform:'translateY(20px)',transition:'opacity .7s var(--ease-out),transform .7s var(--ease-out)' }}>
      <div style={{ font:'400 32px/1 var(--font-mono)',color:'var(--gold)',opacity:0.4,marginBottom:24 }}>{n}</div>
      <h4 style={{ font:'500 clamp(17px,1.6vw,21px)/1.3 var(--font-serif)',color:'var(--text)',marginBottom:16 }}>{t}</h4>
      <p style={{ font:'400 14px/1.75 var(--font-sans)',color:'var(--text-muted)' }}>{b}</p>
    </div>
  );
}

/* ── Process — editorial dark ── */
function Process() {
  const ref = useReveal(0.05);
  const steps = [
    ['01','Two-hour Walkthrough',"Every elevation. Thermal camera if useful. We don't leave until we understand the whole house — not twenty minutes and a clipboard."],
    ['02','Line-by-line Spec',"Materials chosen with you. We tell you what you don't need. No upsells. Half our walkthroughs end with 'wait another year.'"],
    ['03','One Crew. On-site Daily.','In-house only. No subcontractors. The people who quoted the job are the people doing it, every morning.'],
    ['04','Independent Inspection','After we finish, a separate inspector — not ours — verifies every elevation. Written report, yours to keep.'],
  ];
  return (
    <section id="process" style={{ background:'var(--bg-secondary)',padding:'clamp(80px,12vw,160px) var(--gutter)',borderTop:'1px solid var(--color-border)' }}>
      <div style={{ maxWidth:'var(--container)',margin:'0 auto' }}>
        <div ref={ref} style={{ display:'grid',gridTemplateColumns:'1fr 3fr',gap:'clamp(48px,6vw,96px)',marginBottom:'clamp(60px,8vw,100px)',alignItems:'end',opacity:0,transform:'translateY(24px)',transition:'opacity .8s var(--ease-out),transform .8s var(--ease-out)' }}>
          <div>
            <div style={{ font:'600 10px var(--font-sans)',letterSpacing:'0.30em',textTransform:'uppercase',color:'var(--gold)',marginBottom:16 }}>The process</div>
            <div style={{ width:1,height:60,background:'linear-gradient(180deg,var(--gold),transparent)',marginTop:20 }}/>
          </div>
          <h2 style={{ font:'600 clamp(36px,4.5vw,60px)/1.05 var(--font-serif)',letterSpacing:'-0.025em',color:'var(--text)' }}>Built once.<br/><em style={{ fontStyle:'italic',color:'var(--gold)' }}>Inspected after.</em></h2>
        </div>
        <div className="process-grid" style={{ display:'grid',gridTemplateColumns:'repeat(4,1fr)',gap:1,background:'var(--color-border)' }}>
          {steps.map(([n,t,b])=><ProcessStep key={n} n={n} t={t} b={b}/>)}
        </div>
      </div>
      <style>{`@media(max-width:900px){.process-grid{grid-template-columns:repeat(2,1fr)!important}}@media(max-width:560px){.process-grid{grid-template-columns:1fr!important}}`}</style>
    </section>
  );
}

/* ── Testimonial — large, centered ── */
function Quote() {
  const ref = useReveal(0.06);
  return (
    <section style={{ padding:'clamp(100px,14vw,180px) var(--gutter)',borderTop:'1px solid var(--color-border)',position:'relative',overflow:'hidden' }}>
      <div style={{ position:'absolute',top:'50%',left:'50%',transform:'translate(-50%,-50%)',font:'400 320px/1 var(--font-serif)',color:'rgba(201,168,76,0.03)',pointerEvents:'none',userSelect:'none',letterSpacing:'-0.05em' }}>"</div>
      <div ref={ref} style={{ maxWidth:880,margin:'0 auto',textAlign:'center',opacity:0,transform:'translateY(28px)',transition:'opacity 1s var(--ease-out),transform 1s var(--ease-out)' }}>
        <svg width="32" height="26" viewBox="0 0 40 32" fill="none" style={{ marginBottom:48,opacity:0.6 }}>
          <path d="M0 32V16C0 7.16 7.16 0 16 0v6.4C10.7 6.4 6.4 10.7 6.4 16H16v16H0zm24 0V16c0-8.84 7.16-16 16-16v6.4c-5.3 0-9.6 4.3-9.6 9.6H40v16H24z" fill="#C9A84C"/>
        </svg>
        <p style={{ font:`400 italic clamp(22px,2.8vw,36px)/1.55 var(--font-serif)`,color:'var(--text)',letterSpacing:'-0.01em',marginBottom:56 }}>
          They tore off the siding a previous contractor had installed two years earlier. Showed me the rot underneath with photos. Then rebuilt the wall correctly. That's not what most contractors do.
        </p>
        <div style={{ display:'flex',alignItems:'center',justifyContent:'center',gap:20 }}>
          <div style={{ width:1,height:32,background:'var(--color-border)' }}/>
          <div style={{ textAlign:'left' }}>
            <div style={{ font:'500 13px var(--font-sans)',color:'var(--text)',letterSpacing:'0.04em' }}>Margaret S.</div>
            <div style={{ font:'400 11px var(--font-sans)',color:'var(--text-faint)',marginTop:4,letterSpacing:'0.06em' }}>Lincoln Park · Siding & windows · 2024</div>
          </div>
        </div>
      </div>
    </section>
  );
}

/* ── Contact ── */
function Contact() {
  const [sent, setSent] = useState(false);
  const ref = useReveal(0.04);
  const onSubmit = e => { e.preventDefault(); setSent(true); };
  return (
    <section id="contact" style={{ padding:'clamp(80px,12vw,160px) var(--gutter)',borderTop:'1px solid var(--color-border)',background:'var(--bg-primary)' }}>
      <div style={{ maxWidth:'var(--container)',margin:'0 auto',display:'grid',gridTemplateColumns:'1fr 1fr',gap:'clamp(60px,8vw,120px)',alignItems:'start' }}>
        <div ref={ref} style={{ opacity:0,transform:'translateX(-24px)',transition:'opacity .9s var(--ease-out),transform .9s var(--ease-out)' }}>
          <div style={{ font:'600 10px var(--font-sans)',letterSpacing:'0.30em',textTransform:'uppercase',color:'var(--gold)',marginBottom:24 }}>Schedule</div>
          <h2 style={{ font:'600 clamp(36px,4vw,56px)/1.05 var(--font-serif)',letterSpacing:'-0.025em',color:'var(--text)',marginBottom:28 }}>A two-hour<br/>walkthrough.</h2>
          <p style={{ font:'300 clamp(15px,1.4vw,17px)/1.8 var(--font-sans)',color:'var(--text-muted)',marginBottom:56,maxWidth:420 }}>We come out, look at every elevation, and tell you exactly what's wrong. No hard sell — and no charge for the walkthrough.</p>
          <div style={{ borderTop:'1px solid var(--color-border)',paddingTop:40,display:'flex',flexDirection:'column',gap:28 }}>
            {[['Phone','(773) 503-8017'],['Email','info@magichomerenovation.com'],['Area','North Shore · Glenview · Highland Park · Winnetka · Morton Grove']].map(([l,v])=>(
              <div key={l} style={{ display:'grid',gridTemplateColumns:'80px 1fr',gap:16,alignItems:'baseline' }}>
                <span style={{ font:'600 9px var(--font-sans)',letterSpacing:'0.26em',textTransform:'uppercase',color:'var(--text-faint)' }}>{l}</span>
                <span style={{ font:'400 14px var(--font-sans)',color:'var(--text-muted)' }}>{v}</span>
              </div>
            ))}
          </div>
        </div>
        <div>
          {sent
            ? <div style={{ padding:'48px 0' }}>
                <div style={{ width:40,height:1,background:'var(--gold)',marginBottom:24 }}/>
                <h3 style={{ font:'500 28px var(--font-serif)',color:'var(--text)',marginBottom:16 }}>We'll be in touch.</h3>
                <p style={{ font:'400 15px var(--font-sans)',color:'var(--text-muted)' }}>Expect a call within one business day.</p>
              </div>
            : <form onSubmit={onSubmit} style={{ display:'flex',flexDirection:'column',gap:32 }}>
                {[['Full name','text','John Smith'],['Phone','tel','312-000-0000'],['Email','email','you@email.com']].map(([l,t,p])=>(
                  <TextField key={l} label={l} type={t} placeholder={p} required/>
                ))}
                <SelectField label="Service" options={['Siding Installation','Window Replacement','Soffit, Fascia & Gutters','Post-Contractor Inspection','New Buyer Exterior Audit','Exterior Repairs','Not sure — need advice']}/>
                <TextareaField label="Tell us about the project" placeholder="What's going on with your home's exterior?"/>
                <button type="submit" style={{ alignSelf:'flex-start',font:'600 10px var(--font-sans)',letterSpacing:'0.28em',textTransform:'uppercase',color:'var(--text-inverse)',background:'var(--gold)',border:'none',padding:'16px 32px',cursor:'pointer',transition:'background 200ms' }} onMouseEnter={e=>e.currentTarget.style.background='var(--gold-bright)'} onMouseLeave={e=>e.currentTarget.style.background='var(--gold)'}>
                  Request Walkthrough
                </button>
              </form>
          }
        </div>
      </div>
      <style>{`@media(max-width:768px){#contact>div{grid-template-columns:1fr!important}}`}</style>
    </section>
  );
}

function TextField({ label, type='text', placeholder, required }) {
  const [f,setF]=useState(false);
  return (
    <label style={{ display:'flex',flexDirection:'column',gap:10 }}>
      <span style={{ font:'600 9px var(--font-sans)',letterSpacing:'0.28em',textTransform:'uppercase',color:f?'var(--gold)':'var(--text-faint)',transition:'color 200ms' }}>{label}</span>
      <input type={type} placeholder={placeholder} required={required} onFocus={()=>setF(true)} onBlur={()=>setF(false)}
        style={{ background:'transparent',border:0,borderBottom:`1px solid ${f?'var(--gold)':'rgba(245,245,240,0.12)'}`,outline:'none',color:'var(--text)',font:'400 15px var(--font-sans)',padding:'10px 0',transition:'border-color 200ms' }}/>
    </label>
  );
}

function CustomSelect({ label, options, value, onChange }) {
  const [open, setOpen] = useState(false);
  const [focused, setFocused] = useState(false);
  const [hovered, setHovered] = useState(null);
  const ref = useRef(null);
  useEffect(() => {
    if (!open) return;
    const onMouse = e => { if (!ref.current?.contains(e.target)) { setOpen(false); setFocused(false); } };
    const onKey = e => { if (e.key === 'Escape') { setOpen(false); setFocused(false); } };
    document.addEventListener('mousedown', onMouse);
    document.addEventListener('keydown', onKey);
    return () => { document.removeEventListener('mousedown', onMouse); document.removeEventListener('keydown', onKey); };
  }, [open]);
  const toggle = () => { setOpen(o => !o); setFocused(true); };
  const pick = opt => { onChange(opt); setOpen(false); setFocused(false); setHovered(null); };
  const active = open || focused;
  return (
    <div ref={ref} style={{ position:'relative', display:'flex', flexDirection:'column', gap:10 }}>
      {label && <span style={{ font:'600 9px var(--font-sans)',letterSpacing:'0.28em',textTransform:'uppercase',color:active?'var(--gold)':'var(--text-faint)',transition:'color 200ms' }}>{label}</span>}
      <button type="button" onClick={toggle} onBlur={e=>{ if (!ref.current?.contains(e.relatedTarget)) setFocused(false); }}
        style={{ background:'transparent',border:0,borderBottom:`1px solid ${active?'var(--gold)':'rgba(245,245,240,0.12)'}`,outline:'none',color:'var(--text)',font:'400 clamp(15px,1.4vw,17px) var(--font-sans)',padding:'12px 0',textAlign:'left',cursor:'pointer',display:'flex',justifyContent:'space-between',alignItems:'center',transition:'border-color 200ms',width:'100%' }}>
        <span>{value}</span>
        <svg width="10" height="6" viewBox="0 0 10 6" fill="none" style={{ transform:open?'rotate(180deg)':'none',transition:'transform 220ms',flexShrink:0,marginLeft:12 }}>
          <path d="M1 1l4 4 4-4" stroke="var(--gold)" strokeWidth="1.2" strokeLinecap="round" strokeLinejoin="round"/>
        </svg>
      </button>
      {open && (
        <div style={{ position:'absolute',top:'calc(100% + 2px)',left:0,right:0,zIndex:300,background:'#111111',border:'1px solid rgba(201,168,76,0.2)',boxShadow:'0 24px 64px rgba(0,0,0,0.8)',maxHeight:300,overflowY:'auto' }}>
          {options.map(opt => (
            <button key={opt} type="button" onClick={() => pick(opt)}
              onMouseEnter={() => setHovered(opt)}
              onMouseLeave={() => setHovered(null)}
              style={{ display:'block',width:'100%',textAlign:'left',background:opt===value?'rgba(201,168,76,0.1)':opt===hovered?'rgba(245,245,240,0.04)':'transparent',border:'none',borderLeft:`2px solid ${opt===value?'var(--gold)':'transparent'}`,color:opt===value?'var(--gold)':opt===hovered?'var(--text)':'var(--text-muted)',font:'400 14px var(--font-sans)',padding:'12px 18px',cursor:'pointer',transition:'all 140ms',letterSpacing:'0.01em' }}>
              {opt}
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

function SelectField({ label, options }) {
  const [val, setVal] = useState(options[0] || '');
  return <CustomSelect label={label} options={options} value={val} onChange={setVal}/>;
}

function TextareaField({ label, placeholder }) {
  const [f,setF]=useState(false);
  return (
    <label style={{ display:'flex',flexDirection:'column',gap:10 }}>
      <span style={{ font:'600 9px var(--font-sans)',letterSpacing:'0.28em',textTransform:'uppercase',color:f?'var(--gold)':'var(--text-faint)',transition:'color 200ms' }}>{label}</span>
      <textarea placeholder={placeholder} rows={3} onFocus={()=>setF(true)} onBlur={()=>setF(false)}
        style={{ background:'transparent',border:0,borderBottom:`1px solid ${f?'var(--gold)':'rgba(245,245,240,0.12)'}`,outline:'none',color:'var(--text)',font:'400 15px var(--font-sans)',padding:'10px 0',resize:'none',transition:'border-color 200ms',fontFamily:'var(--font-sans)' }}/>
    </label>
  );
}

/* ── Estimator ── */
function Estimator() {
  const [sqft, setSqft] = useState('');
  const [material, setMaterial] = useState('hardie');
  const [anim, setAnim] = useState(false);
  const [fSqft, setFSqft] = useState(false);
  const ref = useReveal(0.05);

  const mats = {
    hardie:    { label:'James Hardie ColorPlus', short:'Hardie',    lo:14, hi:19, dur:50, daysPerK:3.2, split:[40,45,10,5] },
    smartside: { label:'LP SmartSide',           short:'SmartSide', lo:10, hi:14, dur:30, daysPerK:2.4, split:[35,48,12,5] },
    vinyl:     { label:'Premium Vinyl',          short:'Vinyl',     lo: 7, hi:10, dur:25, daysPerK:1.8, split:[30,52,13,5] },
    nichiha:   { label:'Nichiha Panel System',    short:'Nichiha',   lo:20, hi:28, dur:35, daysPerK:4.2, split:[45,43, 8,4] },
    equitone:  { label:'Equitone',               short:'Equitone',  lo:24, hi:32, dur:50, daysPerK:5.0, split:[48,40, 8,4] },
  };

  const sf = parseInt(sqft) || 0;
  const m = mats[material];
  const ok = sf >= 100;
  const fmt = n => '$' + n.toLocaleString('en-US');
  const rnd = (n, base=500) => Math.round(n / base) * base;
  const loT = ok ? rnd(sf * m.lo) : 0;
  const hiT = ok ? rnd(sf * m.hi) : 0;
  const mid = ok ? rnd((loT + hiT) / 2, 100) : 0;
  /* days scale with sqft: daysPerK = days per 1000 sqft, min 2 days */
  const days = ok ? Math.max(2, Math.round(sf / 1000 * m.daysPerK)) : 0;
  const daysRange = ok ? (days <= 3 ? `${days}` : `${days - 1}–${days + 1}`) : '';
  const cats = ['Materials', 'Labor', 'Prep & tear-off', 'Permits & disposal'];
  /* breakdown sums to mid (average of range) — shown with label */
  const amts = m.split.map(p => ok ? rnd(mid * p / 100, 100) : 0);

  /* 3-material comparison: cheapest / chosen / priciest */
  const sorted = Object.keys(mats).sort((a,b) => mats[a].lo - mats[b].lo);
  const picks = [...new Set([sorted[0], material, sorted[sorted.length-1]])];
  if (picks.length < 3) { for (const k of sorted) { if (!picks.includes(k)) { picks.push(k); break; } } }
  const compare = picks.sort((a,b) => mats[a].lo - mats[b].lo);
  const maxMid = sf ? Math.max(...compare.map(k => sf * (mats[k].lo + mats[k].hi) / 2)) : 1;

  useEffect(() => {
    if (!ok) { setAnim(false); return; }
    setAnim(false);
    const t = setTimeout(() => setAnim(true), 80);
    return () => clearTimeout(t);
  }, [sqft, material]);

  const inputS = f => ({ background:'transparent', border:0, borderBottom:`1px solid ${f?'var(--gold)':'rgba(245,245,240,0.12)'}`, outline:'none', color:'var(--text)', font:'400 clamp(15px,1.4vw,17px) var(--font-sans)', padding:'12px 0', width:'100%', transition:'border-color 200ms' });

  return (
    <section id="estimate" style={{ background:'var(--bg-secondary)', padding:'clamp(80px,12vw,160px) var(--gutter)', borderTop:'1px solid var(--color-border)' }}>
      <div style={{ maxWidth:'var(--container)', margin:'0 auto' }}>
        <div ref={ref} style={{ opacity:0, transform:'translateY(24px)', transition:'opacity .9s var(--ease-out),transform .9s var(--ease-out)' }}>
          <div style={{ display:'flex', alignItems:'center', gap:14, marginBottom:24 }}>
            <div style={{ width:32, height:1, background:'var(--gold)' }}/>
            <span style={{ font:'600 10px var(--font-sans)', letterSpacing:'0.30em', textTransform:'uppercase', color:'var(--gold)' }}>Project Estimate</span>
          </div>

          {/* Inputs + total */}
          <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:'clamp(48px,6vw,96px)', alignItems:'start', marginBottom: ok ? 64 : 0 }} className="est-grid">
            <div>
              <h2 style={{ font:'600 clamp(32px,3.8vw,52px)/1.08 var(--font-serif)', letterSpacing:'-0.025em', color:'var(--text)', marginBottom:20 }}>How much will it cost?</h2>
              <p style={{ font:'300 clamp(14px,1.3vw,16px)/1.8 var(--font-sans)', color:'var(--text-muted)', maxWidth:400, marginBottom:16 }}>
                Enter your exterior wall square footage. We break down where every dollar goes and compare it against alternatives.
              </p>
              <p style={{ font:'400 11px/1.6 var(--font-sans)', color:'var(--text-faint)', maxWidth:380, marginBottom:36 }}>
                Exterior wall sq. ft. ≈ 1.0–1.5× your heated floor area.
              </p>
              <div style={{ display:'flex', flexDirection:'column', gap:28 }}>
                <label style={{ display:'flex', flexDirection:'column', gap:10 }}>
                  <span style={{ font:'600 9px var(--font-sans)', letterSpacing:'0.28em', textTransform:'uppercase', color:fSqft?'var(--gold)':'var(--text-faint)', transition:'color 200ms' }}>Exterior wall sq. ft.</span>
                  <input type="number" min="100" max="20000" placeholder="e.g. 2400" value={sqft} onChange={e=>setSqft(e.target.value)} onFocus={()=>setFSqft(true)} onBlur={()=>setFSqft(false)} style={inputS(fSqft)}/>
                </label>
                <CustomSelect
                  label="Material"
                  options={Object.values(mats).map(v => v.label)}
                  value={mats[material].label}
                  onChange={lbl => setMaterial(Object.keys(mats).find(k => mats[k].label === lbl))}
                />
              </div>
            </div>
            <div>
              {ok ? (
                <>
                  <div style={{ font:'400 10px/1 var(--font-sans)', letterSpacing:'0.24em', textTransform:'uppercase', color:'var(--text-faint)', marginBottom:12 }}>Estimated range</div>
                  <div style={{ font:'700 clamp(38px,4.5vw,60px)/1 var(--font-serif)', letterSpacing:'-0.03em', color:'var(--gold)', marginBottom:10 }}>{fmt(loT)} – {fmt(hiT)}</div>
                  <div style={{ font:'400 12px/1.6 var(--font-sans)', color:'var(--text-faint)', marginBottom:4 }}>{sf.toLocaleString()} sq. ft. · {m.lo}–{m.hi} $/sqft · ~{daysRange} days</div>
                  <div style={{ font:'400 11px/1.6 var(--font-sans)', color:'var(--text-faint)', opacity:0.65, marginBottom:28 }}>Estimate only — substrate and site access affect final price.</div>
                  <a href="#contact" style={{ display:'inline-flex', alignItems:'center', gap:14, font:'600 10px var(--font-sans)', letterSpacing:'0.26em', textTransform:'uppercase', color:'var(--gold)', textDecoration:'none', borderBottom:'1px solid var(--gold-40)', paddingBottom:8, transition:'gap 200ms' }} onMouseEnter={e=>e.currentTarget.style.gap='22px'} onMouseLeave={e=>e.currentTarget.style.gap='14px'}>
                    Get accurate quote
                    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.2"><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg>
                  </a>
                </>
              ) : (
                <div style={{ font:'300 clamp(15px,1.4vw,17px)/1.8 var(--font-sans)', color:'var(--text-faint)' }}>Enter square footage to see your estimate.</div>
              )}
            </div>
          </div>

          {/* Breakdown + comparison */}
          {ok && (
            <div style={{ borderTop:'1px solid var(--color-border)', paddingTop:56 }}>
              <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:'clamp(40px,5vw,80px)' }} className="est-grid">

                {/* Cost breakdown */}
                <div>
                  <div style={{ display:'flex', justifyContent:'space-between', alignItems:'baseline', marginBottom:32 }}>
                    <span style={{ font:'600 9px var(--font-sans)', letterSpacing:'0.28em', textTransform:'uppercase', color:'var(--text-faint)' }}>Where your money goes</span>
                    <span style={{ font:'400 10px var(--font-sans)', color:'var(--text-faint)', opacity:0.6 }}>based on {fmt(mid)} mid-estimate</span>
                  </div>
                  <div style={{ display:'flex', flexDirection:'column', gap:28 }}>
                    {cats.map((cat, i) => (
                      <div key={cat}>
                        <div style={{ display:'flex', justifyContent:'space-between', marginBottom:10 }}>
                          <span style={{ font:'400 13px var(--font-sans)', color:'var(--text-muted)' }}>{cat}</span>
                          <div style={{ textAlign:'right' }}>
                            <span style={{ font:'600 13px var(--font-sans)', color:'var(--text)' }}>{fmt(amts[i])}</span>
                            <span style={{ font:'400 11px var(--font-sans)', color:'var(--text-faint)', marginLeft:8 }}>{m.split[i]}%</span>
                          </div>
                        </div>
                        <div style={{ height:3, background:'rgba(245,245,240,0.07)', borderRadius:2, overflow:'hidden' }}>
                          <div style={{ height:'100%', width: anim ? `${m.split[i]}%` : '0%', background:'linear-gradient(90deg,var(--gold-deep),var(--gold))', borderRadius:2, transition:`width 800ms var(--ease-out) ${i*130}ms` }}/>
                        </div>
                      </div>
                    ))}
                  </div>
                </div>

                {/* Material comparison */}
                <div>
                  <div style={{ font:'600 9px var(--font-sans)', letterSpacing:'0.28em', textTransform:'uppercase', color:'var(--text-faint)', marginBottom:32 }}>Compare materials</div>
                  <div style={{ display:'flex', flexDirection:'column', gap:16 }}>
                    {compare.map((k, ci) => {
                      const mv = mats[k];
                      const thisMid = sf * (mv.lo + mv.hi) / 2;
                      const barW = (thisMid / maxMid) * 100;
                      const isMe = k === material;
                      return (
                        <div key={k} style={{ padding:'18px 20px', background: isMe ? 'rgba(201,168,76,0.07)' : 'rgba(255,255,255,0.02)', border: `1px solid ${isMe ? 'var(--gold-24)' : 'rgba(245,245,240,0.06)'}`, borderRadius:2, transition:'border-color 300ms' }}>
                          <div style={{ display:'flex', justifyContent:'space-between', alignItems:'baseline', marginBottom:12 }}>
                            <span style={{ font:`${isMe?600:400} 13px var(--font-sans)`, color: isMe ? 'var(--gold)' : 'var(--text-muted)' }}>
                              {mv.short} {isMe && <span style={{ font:'400 10px var(--font-sans)', letterSpacing:'0.1em', marginLeft:6, opacity:0.7 }}>← selected</span>}
                            </span>
                            <span style={{ font:'500 13px var(--font-sans)', color: isMe ? 'var(--text)' : 'var(--text-muted)' }}>{fmt(rnd(sf*mv.lo))} – {fmt(rnd(sf*mv.hi))}</span>
                          </div>
                          <div style={{ height:2, background:'rgba(245,245,240,0.07)', borderRadius:1, overflow:'hidden', marginBottom:10 }}>
                            <div style={{ height:'100%', width: anim ? `${barW}%` : '0%', background: isMe ? 'linear-gradient(90deg,var(--gold-deep),var(--gold))' : 'rgba(245,245,240,0.18)', borderRadius:1, transition:`width 800ms var(--ease-out) ${ci*150+100}ms` }}/>
                          </div>
                          <div style={{ display:'flex', gap:20 }}>
                            <span style={{ font:'400 10px var(--font-sans)', color:'var(--text-faint)' }}>~{Math.max(2, Math.round(sf/1000*mv.daysPerK))} days</span>
                            <span style={{ font:'400 10px var(--font-sans)', color:'var(--text-faint)' }}>{mv.dur}yr lifespan</span>
                            <span style={{ font:'400 10px var(--font-sans)', color:'var(--text-faint)' }}>{mv.lo}–{mv.hi} $/sqft</span>
                          </div>
                        </div>
                      );
                    })}
                  </div>
                </div>

              </div>
            </div>
          )}
        </div>
      </div>
      <style>{`@media(max-width:768px){.est-grid{grid-template-columns:1fr!important}}`}</style>
    </section>
  );
}

/* ── Footer ── */
function Footer() {
  return (
    <footer style={{ borderTop:'1px solid var(--color-border)',padding:'clamp(48px,6vw,80px) var(--gutter) clamp(32px,4vw,48px)',background:'var(--bg-primary)' }}>
      <div style={{ maxWidth:'var(--container)',margin:'0 auto' }}>
        <div className="footer-grid" style={{ display:'grid',gridTemplateColumns:'2fr 1fr 1fr 1fr',gap:48,marginBottom:64,paddingBottom:48,borderBottom:'1px solid var(--color-border)' }}>
          <div>
            <div style={{ marginBottom:20 }}>
              <MagicLogo size={32}/>
            </div>
            <p style={{ font:'400 13px/1.75 var(--font-sans)',color:'var(--text-faint)',maxWidth:260 }}>Chicagoland's premier exterior contractor. Premium materials, independent inspections, zero subcontractors.</p>
          </div>
          {[
            ['Services',['Siding','Windows','Soffit & Fascia','Gutters','Inspections']],
            ['Company',['Our Process','About','Contact']],
            ['Service Area',['Glenview','Highland Park','Winnetka','Morton Grove','North Shore']],
          ].map(([h,ls])=>(
            <div key={h}>
              <div style={{ font:'600 9px var(--font-sans)',letterSpacing:'0.28em',textTransform:'uppercase',color:'var(--text-faint)',marginBottom:20 }}>{h}</div>
              <ul style={{ listStyle:'none',padding:0,margin:0,display:'flex',flexDirection:'column',gap:12 }}>
                {ls.map(l=><li key={l}><a href="#" style={{ font:'400 13px var(--font-sans)',color:'var(--text-muted)',textDecoration:'none',transition:'color 200ms' }} onMouseEnter={e=>e.currentTarget.style.color='var(--gold)'} onMouseLeave={e=>e.currentTarget.style.color='var(--text-muted)'}>{l}</a></li>)}
              </ul>
            </div>
          ))}
        </div>
        <div style={{ display:'flex',justifyContent:'space-between',alignItems:'center',flexWrap:'wrap',gap:12 }}>
          <span style={{ font:'400 11px var(--font-sans)',color:'var(--text-faint)',letterSpacing:'0.06em' }}>© 2026 Magic Home Renovation. All rights reserved.</span>
          <div style={{ display:'flex', gap:24, alignItems:'center',flexWrap:'wrap' }}>
            <a href="/privacy.html" style={{ font:'400 11px var(--font-sans)',color:'var(--text-faint)',textDecoration:'none',letterSpacing:'0.06em',transition:'color 200ms' }} onMouseEnter={e=>e.currentTarget.style.color='var(--gold)'} onMouseLeave={e=>e.currentTarget.style.color='var(--text-faint)'}>Privacy Policy</a>
            <span style={{ font:'400 11px var(--font-sans)',color:'rgba(201,168,76,0.4)',letterSpacing:'0.12em',textTransform:'uppercase' }}>Built once. Inspected after.</span>
            <a href="https://pyroxai.com" target="_blank" rel="noopener" style={{ font:'400 11px var(--font-sans)',color:'var(--text-faint)',textDecoration:'none',letterSpacing:'0.08em',transition:'color 200ms' }} onMouseEnter={e=>e.currentTarget.style.color='var(--gold)'} onMouseLeave={e=>e.currentTarget.style.color='var(--text-faint)'}>Built by PYROX AI</a>
          </div>
        </div>
      </div>
      <style>{`@media(max-width:768px){.footer-grid{grid-template-columns:1fr 1fr!important;gap:32px!important}}@media(max-width:480px){.footer-grid{grid-template-columns:1fr!important}}`}</style>
    </footer>
  );
}

/* ── App ── */
const App = () => (
  <>
    <Cursor/>
    <ScrollProgress/>
    <Nav/>
    <Hero/>
    <PhotoSection
      img="assets/siding-detail.jpg"
      align="left"
      eyebrow="Premium Materials"
      headline="We don't install what we wouldn't put on our own home."
      body="James Hardie ColorPlus, Marvin windows, LP SmartSide. Not the cheapest. Not the most popular. The right one for the house."
      cta="View our materials"
    />
    <Services/>
    <PhotoSection
      id="inspection"
      img="assets/hero-night.jpg"
      align="right"
      eyebrow="Post-contractor inspection"
      headline="Had a bad contractor? We'll find every flaw."
      body="A licensed inspector with a thermal camera and moisture meter — completely independent of us. Full written report you can use with your contractor, or in court."
      cta="Schedule inspection"
      ctaHref="#contact"
    />
    <Process/>
    <Quote/>
    <Estimator/>
    <Contact/>
    <Footer/>
  </>
);

