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

// ============ DATA ============
const PROJECTS = [
  { slug: 'sasohan', name: '사소한',  title: '데이팅 웹 서비스', caption: 'Web · Next.js', year: '2024', metric: '월 방문 120K+', domain: 'Web · B2C', image: 'assets/portfolio/sasohan.png' },
  { slug: 'allsaju', name: '올데이사주', title: 'AI 기반 운세·사주 웹 서비스', caption: 'Web · LLM', year: '2024', metric: '월 PV 240K', domain: 'Web · LLM', image: 'assets/portfolio/allsaju.png' },
  { slug: 'topvisual', name: '탑비주얼', title: '1:1 영상 매칭 데이팅 앱', caption: 'App · Flutter', year: '2024', metric: 'MAU 12K+', domain: 'Mobile · AI', image: 'assets/portfolio/topvisual.png' },
  { slug: 'community', name: '커뮤니티', title: '동네 기반 커뮤니티 앱', caption: 'App · Flutter', year: '2023', metric: '주간 재방문 62%', domain: 'Mobile · Social', image: 'assets/portfolio/community.png' },
];

const SERVICES = [
  { n: '01', ko: 'Web Product', en: 'Full-stack', desc: 'Next.js / TypeScript / Edge. 디자인부터 배포·운영까지 한 팀이 책임지는 풀스택 웹 제품.', tags: ['Next.js', 'TypeScript', 'Vercel', 'Postgres'] },
  { n: '02', ko: 'Mobile App', en: 'Flutter / RN', desc: '단일 코드베이스로 iOS·Android 동시 출시. 자체 데이팅 앱 운영 노하우를 그대로 적용합니다.', tags: ['Flutter', 'React Native', 'Firebase'] },
  { n: '03', ko: 'Automation · Data', en: 'Pipelines', desc: '크롤링·ETL·내부 도구 자동화. 사람이 반복하던 일을 시스템이 처리하게 만듭니다.', tags: ['Crawling', 'Pipelines', 'Dashboards'] },
  { n: '04', ko: 'Custom Software', en: 'Desktop · Internal', desc: '웹·앱이 아닌 모든 형태의 프로그램. 사내에서 직접 만들어 써본 도구가 출발선입니다.', tags: ['Desktop', 'Internal Tools', 'CLI', 'Backend'] },
  { n: '05', ko: 'Design · Branding', en: 'Identity', desc: '디자인부터 풀 시안까지. 운영 중인 프로젝트의 리브랜딩도 가능합니다.', tags: ['Web', 'Mobile', 'Branding'] },
];

const PROCESS = [
  { n: '01', t: 'Discover', d: '진짜 풀어야 할 문제부터 정의합니다. 사용자, 비즈니스 모델, 운영 환경을 함께 들여다보고 최소한의 MVP 범위를 합의합니다.' },
  { n: '02', t: 'Design', d: '시안과 프로토타입을 직접 만듭니다. Figma 기반의 디자인 시스템부터 풀 시안까지 개발과 끊김 없이 연결합니다.' },
  { n: '03', t: 'Build with AI', d: 'AI 페어 프로그래밍으로 가속합니다. 디자인 토큰부터 백엔드 API까지 빠르게 시제품을 만들고 매주 살아있는 빌드를 공유합니다.' },
  { n: '04', t: 'Handover', d: '운영 가능한 상태로 넘겨드립니다. 분석·모니터링·문서·체크리스트까지 바로 굴릴 수 있게 인계합니다.' },
];

const TOOLS = [
  ['Figma', 'Design'], ['Notion', 'Docs'], ['Slack', 'Chat'], ['GitHub', 'Code'],
  ['Linear', 'Issues'], ['Vercel', 'Deploy'], ['Sentry', 'Errors'], ['Posthog', 'Analytics'],
];

const FAQS = [
  { q: '개발은 처음입니다. 어떤 것부터 준비해야 하나요?', a: '아이디어 한 줄만 있으셔도 충분해요. 무료 상담을 통해 무엇을 만들지, 어떤 기능이 필요한지부터 같이 정리해 드립니다. 견적·일정·기술 스택까지 24시간 안에 안내드려요.' },
  { q: '예산이 정해져 있는데 가능한가요?', a: '예산을 알려주시면 그에 맞춰 우선순위를 잡아드립니다. MVP(최소 기능 제품)부터 단계적으로 키워가는 방식도 가능해요. 솔직하게 가능 여부를 안내드려요.' },
  { q: '제작 기간은 얼마나 걸리나요?', a: '간단한 랜딩페이지는 1~2주, 일반 웹·앱은 4~12주 정도입니다. 기능·디자인 복잡도에 따라 다르며, 첫 상담에서 정확한 일정을 드려요.' },
  { q: '계약 후 진행 과정은 어떻게 되나요?', a: 'Discover → Design → Build → Handover 4단계로 진행됩니다. 매주 작업 진행 상황을 공유드리고, Slack 또는 카톡으로 언제든 소통 가능해요.' },
  { q: '런칭 후에도 도움받을 수 있나요?', a: '네, 6개월 무상 유지보수가 기본 포함됩니다. 버그 수정·소소한 개선은 무료, 추가 기능 개발은 별도 협의로 진행해요.' },
  { q: '디자인만 또는 개발만 맡길 수 있나요?', a: '풀패키지(기획~인계)가 기본이지만, 클라이언트사에 디자이너가 있으면 개발만 진행 가능합니다. 운영 중인 프로젝트의 리브랜딩(디자인만)도 가능해요. 자세한 건 상담에서.' },
];

const LIVE_ROTATION = [
  { name: 'AI 운세·사주 웹 서비스', metric: 'Web · LLM', domain: 'web · llm' },
  { name: '영상 매칭 데이팅 앱', metric: 'App · Flutter', domain: 'app · flutter' },
  { name: '데이팅 웹 서비스', metric: 'Web · Next.js', domain: 'web · next.js' },
  { name: '동네 기반 커뮤니티 앱', metric: 'App · Flutter', domain: 'app · flutter' },
];

// ============ HOOKS ============
function useReveal() {
  useEffect(() => {
    const els = document.querySelectorAll('.reveal');
    // Immediately reveal anything already in viewport at mount
    const vh = window.innerHeight || 800;
    els.forEach(el => {
      const r = el.getBoundingClientRect();
      if (r.top < vh * 0.95) el.classList.add('in');
    });
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => { if (e.isIntersecting) { e.target.classList.add('in'); io.unobserve(e.target); } });
    }, { threshold: 0, rootMargin: '0px 0px -5% 0px' });
    els.forEach(el => { if (!el.classList.contains('in')) io.observe(el); });
    // Safety net: ensure everything is visible after 1.2s regardless
    const t = setTimeout(() => { els.forEach(el => el.classList.add('in')); }, 1200);
    return () => { io.disconnect(); clearTimeout(t); };
  }, []);
}

// ============ COMPONENTS ============
function Nav() {
  return (
    <header className="nav">
      <div className="nav-row">
        <a href="#top" className="brand">
          <span className="pulse" aria-hidden />
          <img src="assets/logo.svg" alt="NEVLAB" />
        </a>
        <nav className="nav-links">
          <a href="#services">Services</a>
          <a href="#work">Work</a>
          <a href="#process">Process</a>
          <a href="#about">About</a>
          <a href="#faq">FAQ</a>
        </nav>
        <a href="#contact" className="nav-cta">Start a project →</a>
      </div>
    </header>
  );
}

function Hero() {
  const [idx, setIdx] = useState(0);
  useEffect(() => {
    const t = setInterval(() => setIdx(i => (i + 1) % LIVE_ROTATION.length), 2800);
    return () => clearInterval(t);
  }, []);
  const live = LIVE_ROTATION[idx];

  return (
    <section className="hero" id="top">
      <div className="hero-glow-a" />
      <div className="hero-glow-b" />
      <div className="shell" style={{ position: 'relative', zIndex: 2, width: '100%' }}>
        <span className="hero-eyebrow">
          <svg viewBox="0 0 24 24"><path d="M12 2l2.9 6.9L22 10l-5.5 4.8L18 22l-6-3.5L6 22l1.5-7.2L2 10l7.1-1.1L12 2z"/></svg>
          클라이언트 평점 4.9 / 5.0
        </span>

        <h1 className="reveal">
          누적 <em className="accent">100만+ 유저</em> 서비스를<br />
          <span className="underline">직접 운영</span>하는 네브랩이 만듭니다.
        </h1>

        <p className="hero-sub reveal">
          직접 서비스를 운영해온 네브랩은 디테일까지 챙깁니다.
        </p>

        <div className="hero-ctas reveal">
          <a href="#contact" className="btn btn-primary">
            무료 상담 신청
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12h14M13 5l7 7-7 7"/></svg>
          </a>
          <a href="#work" className="btn btn-ghost">포트폴리오 보기</a>
        </div>

        <div className="hero-guaranteed reveal">
          <span><span className="check">✓</span> 24시간 내 답변</span>
          <span><span className="check">✓</span> 6개월 무상 보증</span>
          <span><span className="check">✓</span> 친절한 비전공자 안내</span>
        </div>

        <div className="hero-live reveal" aria-live="polite">
          <span className="live-dot" />
          <span className="live-label">now running</span>
          <span key={live.name} className="live-svc" style={{ animation: 'fadein .4s ease' }}>{live.name}</span>
          <span className="live-metric">{live.metric}</span>
        </div>
      </div>
      <style>{`@keyframes fadein { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }`}</style>
    </section>
  );
}

function Ticker() {
  const items = [
    ['40+', 'Shipped projects'],
    ['1,000,000+', 'Users reached'],
    ['4', 'Live services'],
    ['24h', 'Reply SLA'],
    ['6mo', 'Warranty'],
    ['2014—', 'In production'],
    ['4.9/5.0', 'Client rating'],
  ];
  const double = [...items, ...items];
  return (
    <div className="ticker-wrap" aria-label="Trust metrics">
      <div className="ticker">
        {double.map(([v, l], i) => (
          <span className="ticker-item" key={i}>
            <span className="dot" />
            <strong>{v}</strong>
            <span>{l}</span>
          </span>
        ))}
      </div>
    </div>
  );
}

function Services() {
  return (
    <section className="section" id="services">
      <div className="shell">
        <div className="section-head reveal">
          <div>
            <div className="eyebrow"><span className="mark" /> §02 · Services</div>
            <h2 style={{ marginTop: 18 }}>한 팀이 만듭니다,<br />직접 운영해본 시선으로.</h2>
          </div>
          <p>AI · 웹 · 모바일 · 자동화 · 디자인. 다섯 영역을 네브랩은 한 팀으로 책임지고 만듭니다.</p>
        </div>

        <div className="svc-list reveal">
          {SERVICES.map(s => (
            <div key={s.n} className="svc-row">
              <div className="svc-num">{s.n}</div>
              <div className="svc-title">
                {s.ko}
                <span className="en">{s.en}</span>
              </div>
              <div className="svc-desc">
                {s.desc}
                <div className="svc-tags">
                  {s.tags.map(t => <span key={t} className="svc-tag">{t}</span>)}
                </div>
              </div>
              <div className="svc-arrow">→</div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

function FeaturedWork() {
  const [active, setActive] = useState(0);
  const p = PROJECTS[active];
  return (
    <section className="section" id="work">
      <div className="shell">
        <div className="section-head reveal">
          <div>
            <div className="eyebrow"><span className="mark" /> §03 · Selected Work</div>
            <h2 style={{ marginTop: 18 }}>머릿속 아이디어가 아닌,<br />실제로 서비스로 이어집니다.</h2>
          </div>
          <p>일부는 네브랩이 직접 운영하고, 일부는 클라이언트와 함께 만들었습니다. 썸네일을 눌러 확인해 보세요.</p>
        </div>

        <div className="work-layout reveal">
          <div className="work-hero" key={p.slug}>
            <img className="work-hero-img" src={p.image} alt={p.title} />
            <div className="work-hero-overlay" />
            <div className="work-hero-stamp">OPERATED<br/>BY NEVLAB</div>
            <div className="work-hero-meta">
              <span className="tag">● Featured · {p.year}</span>
              <h3>{p.title}</h3>
              <div className="caption">{p.caption}</div>
            </div>
          </div>

          <div className="work-list">
            {PROJECTS.map((item, i) => (
              <button
                key={item.slug}
                onClick={() => setActive(i)}
                className={'work-thumb' + (i === active ? ' active' : '')}
                style={{ all: 'unset', cursor: 'pointer', display: 'grid', gridTemplateColumns: '96px 1fr auto', gap: 14, alignItems: 'center', padding: 10, border: '1px solid ' + (i === active ? 'var(--gold)' : 'var(--line)'), borderRadius: 10, background: i === active ? 'rgba(212,184,150,0.06)' : 'var(--bg-2)', transition: 'border-color .2s, background .2s' }}
              >
                <img className="work-thumb-img" src={item.image} alt={item.title} />
                <div className="work-thumb-meta">
                  <div className="t">{item.title}</div>
                  <div className="c">{item.caption}</div>
                </div>
                <div className="work-thumb-num">{String(i + 1).padStart(2, '0')}</div>
              </button>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}

function Process() {
  return (
    <section className="section" id="process">
      <div className="shell">
        <div className="section-head reveal">
          <div>
            <div className="eyebrow"><span className="mark" /> §04 · Process</div>
            <h2 style={{ marginTop: 18 }}>처음부터 마무리까지,<br />4단계로 함께 합니다.</h2>
          </div>
          <p>속도를 위한 가속과 운영자 시선의 디테일, 둘을 동시에 만족시키기 위해 만든 프로세스입니다.</p>
        </div>

        <div className="process-rail reveal">
          {PROCESS.map(s => (
            <div className="process-step" key={s.n}>
              <div className="process-dot" />
              <div className="process-num">STEP {s.n}</div>
              <h3>{s.t}</h3>
              <p>{s.d}</p>
            </div>
          ))}
        </div>

        <div className="callout reveal">
          <span className="dot-br" />
          <div>
            <strong>시작부터 마무리까지 한 팀이 책임져요.</strong>{' '}
            <span>— 인수인계 없이, 같은 사람들이 끝까지 함께합니다.</span>
          </div>
        </div>
      </div>
    </section>
  );
}

function Tools() {
  return (
    <section className="section" id="tools" style={{ paddingTop: 40, paddingBottom: 60 }}>
      <div className="shell">
        <div className="section-head reveal" style={{ marginBottom: 32 }}>
          <div>
            <div className="eyebrow"><span className="mark" /> §05 · Tools</div>
            <h2 style={{ marginTop: 18 }}>네브랩이 일하는 방식,<br />검증된 도구로 모두 공개합니다.</h2>
          </div>
          <p>진행 상황을 항상 투명하게 공유합니다.</p>
        </div>
        <div className="tools-wrap reveal">
          {TOOLS.map(([n, d]) => (
            <span className="tool" key={n}>
              <span className="n">{n}</span>
              <span className="d">{d}</span>
            </span>
          ))}
        </div>
      </div>
    </section>
  );
}

function About() {
  const facts = [
    ['2014', 'Founded'],
    ['4', 'Live services'],
    ['40+', 'Shipped'],
    ['24h', 'Response'],
  ];
  return (
    <section className="section" id="about">
      <div className="shell">
        <div className="about-grid">
          <div className="reveal">
            <div className="eyebrow"><span className="mark" /> §06 · About</div>
            <h2 style={{ marginTop: 18, fontSize: 'clamp(32px, 4.4vw, 52px)', fontWeight: 600, letterSpacing: '-0.02em', lineHeight: 1.1, wordBreak: 'keep-all' }}>
              직접 만들고 운영해본<br />팀의 차이
            </h2>
          </div>
          <div className="about-body reveal">
            <p>
              네브랩은 2014년부터 자체 서비스를 직접 만들고 운영해온 팀이에요.
              데이팅, 매칭, 운세, 자동화 등 여러 분야에서 실제로 서비스를 굴려본
              경험이 우리의 출발점입니다.
            </p>
            <p>
              그래서 우리는 만들기만 하고 떠나는 외주사가 아닙니다. "이게 한 달 뒤에
              어떻게 운영될까?"를 먼저 생각하면서, 디자인 한 화면, 코드 한 줄까지
              직접 운영해본 사람의 시선으로 만들어 드려요.
            </p>
            <dl className="about-facts">
              {facts.map(([v, l]) => (
                <div className="fact" key={l}>
                  <div className="v">{v}</div>
                  <div className="l">{l}</div>
                </div>
              ))}
            </dl>
          </div>
        </div>
      </div>
    </section>
  );
}

function Faq() {
  const [open, setOpen] = useState(0);
  const refs = useRef([]);
  return (
    <section className="section" id="faq">
      <div className="shell">
        <div className="section-head reveal" style={{ gridTemplateColumns: '1fr' }}>
          <div>
            <div className="eyebrow"><span className="mark" /> §07 · FAQ</div>
            <h2 style={{ marginTop: 18 }}>자주 묻는 질문</h2>
            <p style={{ marginTop: 16, color: 'var(--ink-dim)', fontSize: 16, lineHeight: 1.7, maxWidth: 520 }}>
              시작 전에 가장 많이 받는 질문들이에요. 더 궁금한 게 있으면 편하게 문의해 주세요.
            </p>
          </div>
        </div>

        <div className="faq-list reveal">
          {FAQS.map((f, i) => {
            const isOpen = open === i;
            return (
              <div key={i} className={'faq-item' + (isOpen ? ' open' : '')}>
                <button className="faq-q" onClick={() => setOpen(isOpen ? -1 : i)}>
                  <span style={{ display: 'inline-flex', alignItems: 'center' }}>
                    <span className="idx">Q·{String(i + 1).padStart(2, '0')}</span>
                    <span>{f.q}</span>
                  </span>
                  <span className="plus">+</span>
                </button>
                <div
                  className="faq-a"
                  ref={el => refs.current[i] = el}
                  style={{ maxHeight: isOpen ? (refs.current[i]?.scrollHeight || 400) : 0 }}
                >
                  <div className="faq-a-inner">{f.a}</div>
                </div>
              </div>
            );
          })}
        </div>
      </div>
    </section>
  );
}

function Contact() {
  const [budget, setBudget] = useState('');
  const [submitting, setSubmitting] = useState(false);
  const [status, setStatus] = useState(null); // {type:'ok'|'err', msg:string}
  const formRef = useRef(null);
  const budgets = ['~ 1,000만', '1,000 — 3,000만', '3,000 — 8,000만', '8,000만 ~', '아직 미정'];

  async function handleSubmit(e) {
    e.preventDefault();
    if (submitting) return;
    const fd = new FormData(e.target);
    const payload = {
      name: fd.get('name') || '',
      company: fd.get('company') || '',
      email: fd.get('email') || '',
      phone: fd.get('phone') || '',
      service: fd.get('service') || '',
      brief: fd.get('brief') || '',
      budget,
    };
    setSubmitting(true);
    setStatus(null);
    try {
      const res = await fetch('/api/contact', {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify(payload),
      });
      if (!res.ok) {
        const j = await res.json().catch(() => ({}));
        throw new Error(j.error || '전송 실패');
      }
      setStatus({ type: 'ok', msg: '접수되었습니다. 24시간 내 답변드려요.' });
      formRef.current?.reset();
      setBudget('');
    } catch (err) {
      setStatus({ type: 'err', msg: '전송 중 문제가 발생했어요. 잠시 후 다시 시도해 주세요.' });
    } finally {
      setSubmitting(false);
    }
  }

  return (
    <section className="section" id="contact">
      <div className="shell">
        <div className="contact-card reveal">
          <div className="contact-glow" />
          <div className="contact-inner">
            <div className="eyebrow"><span className="mark" /> §08 · Contact</div>
            <h2>아이디어가 있으신가요?<br />처음이어도 괜찮아요.</h2>
            <p>처음 사업을 시작하시는 분도 환영해요. 무엇이 필요한지 모르셔도, 같이 정리해 드립니다.</p>

            <form ref={formRef} className="form-grid" onSubmit={handleSubmit}>
              <div className="form-field">
                <label>이름 / Name</label>
                <input name="name" type="text" placeholder="홍길동" required />
              </div>
              <div className="form-field">
                <label>회사 / Company</label>
                <input name="company" type="text" placeholder="Optional" />
              </div>
              <div className="form-field">
                <label>이메일 / Email</label>
                <input name="email" type="email" placeholder="you@company.com" required />
              </div>
              <div className="form-field">
                <label>연락처 / Phone</label>
                <input name="phone" type="tel" placeholder="010-1234-5678" inputMode="tel" pattern="[0-9+\-\s()]{7,20}" required />
              </div>
              <div className="form-field full">
                <label>서비스 / Service</label>
                <select name="service" defaultValue="">
                  <option value="" disabled>선택해 주세요</option>
                  <option>Web Product</option>
                  <option>Mobile App</option>
                  <option>Automation · Data</option>
                  <option>Custom Software</option>
                  <option>Design · Branding</option>
                </select>
              </div>
              <div className="form-field full">
                <label>예산 / Budget (KRW)</label>
                <div className="budget-pills">
                  {budgets.map(b => (
                    <button type="button" key={b} onClick={() => setBudget(b)} className={'budget-pill' + (budget === b ? ' selected' : '')}>{b}</button>
                  ))}
                </div>
              </div>
              <div className="form-field full">
                <label>프로젝트 설명 / Brief</label>
                <textarea name="brief" placeholder="한 문단이면 충분합니다. 무엇을, 누구를 위해, 언제까지 필요한지." />
              </div>
              <div className="form-field full form-submit">
                <span className="hint" style={{ color: status?.type === 'err' ? '#f15a4a' : status?.type === 'ok' ? '#36d399' : undefined }}>
                  {status ? status.msg : '↳ 24h 내 답변 · nevlab@nevlab.com'}
                </span>
                <button type="submit" className="btn btn-primary" disabled={submitting}>
                  {submitting ? '전송 중...' : '문의 보내기'}
                  {!submitting && (
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12h14M13 5l7 7-7 7"/></svg>
                  )}
                </button>
              </div>
            </form>
          </div>
        </div>
      </div>
    </section>
  );
}

function Footer() {
  return (
    <footer className="footer">
      <div className="shell">
        <div className="footer-grid">
          <div className="footer-brand">
            <img src="assets/logo.svg" alt="NEVLAB" />
            <p>누적 100만+ 유저 서비스를<br />직접 운영하는 개발사가 만듭니다.</p>
          </div>
          <div className="footer-col">
            <h4>Studio</h4>
            <a href="#services">Services</a>
            <a href="#process">Process</a>
            <a href="#about">About</a>
          </div>
          <div className="footer-col">
            <h4>Discover</h4>
            <a href="#work">Work</a>
            <a href="#faq">FAQ</a>
            <a href="#tools">Tools</a>
          </div>
          <div className="footer-col">
            <h4>Contact</h4>
            <a href="#contact">상담 신청</a>
            <a href="mailto:nevlab@nevlab.com">nevlab@nevlab.com</a>
          </div>
        </div>
        <div className="footer-legal" style={{
          marginTop: 32,
          paddingTop: 24,
          borderTop: '1px solid var(--line)',
          display: 'flex', flexWrap: 'wrap', gap: '8px 24px',
          fontSize: 12, color: 'var(--ink-mute)', lineHeight: 1.6,
        }}>
          <span>사업자 번호 : 000-00-00000</span>
          <span>대표 : 서정승</span>
          <span style={{ flexBasis: '100%' }}>주소 : 충청북도 청주시 서원구 사창동 222-7 재미슨타워 11층</span>
        </div>
        <div className="footer-bottom">
          <span>© NEVLAB Corp. All rights reserved.</span>
          <span>Built with care · 2026</span>
        </div>
      </div>
    </footer>
  );
}

// ============ TWEAK PANEL ============
function TweakPanel({ visible, tweaks, setTweaks }) {
  if (!visible) return null;
  return (
    <div className="tweak-panel">
      <h4>TWEAKS</h4>
      <div className="tweak-row">
        <label>Grain</label>
        <input type="range" min="0" max="1" step="0.05" value={tweaks.grainIntensity}
          onChange={(e) => setTweaks({ ...tweaks, grainIntensity: parseFloat(e.target.value) })} />
      </div>
      <div className="tweak-row">
        <label>Paper tone</label>
        <input type="color" value={tweaks.paperTone}
          onChange={(e) => setTweaks({ ...tweaks, paperTone: e.target.value })} />
      </div>
      <div className="tweak-row">
        <label>Seal color</label>
        <input type="color" value={tweaks.sealColor}
          onChange={(e) => setTweaks({ ...tweaks, sealColor: e.target.value })} />
      </div>
    </div>
  );
}

// ============ APP ============
function App() {
  const [tweaks, setTweaks] = useState(window.__TWEAKS__ || { grainIntensity: 0.25, sealColor: '#B72D24', paperTone: '#F5F2E8' });
  const [tweakOn, setTweakOn] = useState(false);

  useReveal();

  useEffect(() => {
    try {
      let vid = localStorage.getItem('nv_vid');
      if (!vid) {
        vid = (crypto?.randomUUID?.() || (Date.now().toString(36) + Math.random().toString(36).slice(2)));
        localStorage.setItem('nv_vid', vid);
      }
      fetch('/api/track', {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify({ vid, path: location.pathname }),
        keepalive: true,
      }).catch(() => {});
    } catch (e) { /* tracking is best-effort */ }
  }, []);

  useEffect(() => {
    const root = document.documentElement;
    root.style.setProperty('--grain', String(tweaks.grainIntensity));
    root.style.setProperty('--ink', tweaks.paperTone);
    root.style.setProperty('--seal', tweaks.sealColor);
  }, [tweaks]);

  useEffect(() => {
    const handler = (e) => {
      if (!e.data || typeof e.data !== 'object') return;
      if (e.data.type === '__activate_edit_mode') setTweakOn(true);
      if (e.data.type === '__deactivate_edit_mode') setTweakOn(false);
    };
    window.addEventListener('message', handler);
    window.parent.postMessage({ type: '__edit_mode_available' }, '*');
    return () => window.removeEventListener('message', handler);
  }, []);

  useEffect(() => {
    window.parent.postMessage({ type: '__edit_mode_set_keys', edits: tweaks }, '*');
  }, [tweaks]);

  return (
    <>
      <div className="grain" aria-hidden />
      <Nav />
      <Hero />
      <Ticker />
      <Services />
      <FeaturedWork />
      <Process />
      <Tools />
      <About />
      <Faq />
      <Contact />
      <Footer />
      <TweakPanel visible={tweakOn} tweaks={tweaks} setTweaks={setTweaks} />
    </>
  );
}

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