// Inkly landing page sections.

const PROOF_TILES = [
  { glyph: 'mountain',  style: 'Fine-line',    aspect: 1.0, hint: 'Mountain range' },
  { glyph: 'rose',      style: 'Traditional',  aspect: 1.35, hint: 'American rose' },
  { glyph: 'snake',     style: 'Blackwork',    aspect: 0.85, hint: 'Coiled serpent' },
  { glyph: 'moth',      style: 'Neo-trad',     aspect: 1.15, hint: 'Death\u2019s-head moth' },
  { glyph: 'wave',      style: 'Japanese',     aspect: 1.0, hint: 'Great wave' },
  { glyph: 'eye',       style: 'Geometric',    aspect: 1.25, hint: 'Watching eye' },
  { glyph: 'dagger',    style: 'Traditional',  aspect: 1.4, hint: 'Through the heart' },
  { glyph: 'swallow',   style: 'Fine-line',    aspect: 0.9, hint: 'Single swallow' },
  { glyph: 'heart',     style: 'Watercolour',  aspect: 1.0, hint: 'Sacred heart' },
  { glyph: 'hand',      style: 'Blackwork',    aspect: 1.3, hint: 'Hamsa hand' },
  { glyph: 'sun',       style: 'Neo-trad',     aspect: 1.0, hint: 'Smiling sun' },
  { glyph: 'anchor',    style: 'Geometric',    aspect: 1.2, hint: 'Steady anchor' },
];

const STYLES = [
  { key: 'fine-line',    glyph: 'swallow',  name: 'Fine-line',    desc: 'Minimalist single-needle work' },
  { key: 'traditional',  glyph: 'rose',     name: 'Traditional',  desc: 'Bold lines, classic flash' },
  { key: 'blackwork',    glyph: 'snake',    name: 'Blackwork',    desc: 'Heavy ink, high contrast' },
  { key: 'watercolour',  glyph: 'heart',    name: 'Watercolour',  desc: 'Soft washes, painterly edges' },
  { key: 'neo-trad',     glyph: 'moth',     name: 'Neo-trad',     desc: 'Traditional shapes, modern palette' },
  { key: 'geometric',    glyph: 'eye',      name: 'Geometric',    desc: 'Linework, symmetry, sacred forms' },
  { key: 'japanese',     glyph: 'wave',     name: 'Japanese',     desc: 'Irezumi flow and storytelling' },
];

// ───────────────────────────── Reveal-on-scroll wrapper ─────────────────────────────
const Reveal = ({ children, delay = 0, duration = 700, as: As = 'div', className = '', once = true }) => {
  const ref = React.useRef(null);
  const [shown, setShown] = React.useState(true);
  React.useEffect(() => {
    if (!ref.current) return;
    const reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    if (reduce) { setShown(true); return; }
    setShown(false);
    const fallback = setTimeout(() => setShown(true), 120 + delay);
    if (typeof IntersectionObserver === 'undefined') {
      return () => clearTimeout(fallback);
    }
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting) {
          setShown(true);
          clearTimeout(fallback);
          if (once) io.disconnect();
        } else if (!once) {
          setShown(false);
        }
      });
    }, { threshold: 0.05 });
    io.observe(ref.current);
    return () => { clearTimeout(fallback); io.disconnect(); };
  }, [once, delay]);
  return (
    <As
      ref={ref}
      className={className}
      style={{
        opacity: shown ? 1 : 0,
        transform: shown ? 'translateY(0)' : 'translateY(14px)',
        transition: `opacity ${duration}ms ease ${delay}ms, transform ${duration}ms ease ${delay}ms`,
      }}
    >
      {children}
    </As>
  );
};

// ───────────────────────────── Email form ─────────────────────────────
const EmailForm = ({ accent, onSuccess, variant = 'hero', count }) => {
  const [email, setEmail] = React.useState('');
  const [state, setState] = React.useState('idle'); // idle | error | submitting | done
  const [msg, setMsg] = React.useState('');

  const submit = async (e) => {
    e.preventDefault();
    const v = email.trim();
    const ok = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v);
    if (!ok) { setState('error'); setMsg('Enter a valid email.'); return; }
    setState('submitting'); setMsg('');
    try {
      const res = await fetch('/api/subscribe', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email: v }),
      });
      if (!res.ok) throw new Error('Subscription failed');
      setState('done');
      onSuccess && onSuccess(v);
    } catch (err) {
      setState('error');
      setMsg('Something went wrong. Try again.');
    }
  };

  if (state === 'done') {
    return <SuccessState accent={accent} count={count} email={email} />;
  }

  return (
    <form onSubmit={submit} className="w-full" noValidate>
      <div className="flex flex-col sm:flex-row gap-2 sm:gap-0 sm:rounded-none">
        <label className="sr-only" htmlFor={`email-${variant}`}>Email address</label>
        <input
          id={`email-${variant}`}
          type="email"
          inputMode="email"
          autoComplete="email"
          placeholder="you@example.com"
          value={email}
          onChange={(e) => { setEmail(e.target.value); if (state === 'error') setState('idle'); }}
          className="flex-1 min-w-0 h-[52px] sm:h-[56px] px-4 bg-transparent border border-[#2a2a2a] sm:border-r-0 text-[#F5F5F5] placeholder-[#6b6b6b] outline-none focus:border-[#5a5a5a] transition-colors text-[16px] tracking-[0.01em]"
          aria-invalid={state === 'error'}
        />
        <button
          type="submit"
          disabled={state === 'submitting'}
          className="h-[52px] sm:h-[56px] px-6 sm:px-7 text-[#F5F5F5] font-medium tracking-[0.04em] uppercase text-[13px] transition-transform active:scale-[0.99] disabled:opacity-70"
          style={{ background: accent, minHeight: 48 }}
        >
          {state === 'submitting' ? 'Adding…' : 'Get early access'}
        </button>
      </div>
      <div className="mt-3 text-[13px] text-[#9a9a9a] leading-relaxed flex flex-wrap items-center gap-x-3 gap-y-1">
        {state === 'error' ? (
          <span style={{ color: accent }}>{msg}</span>
        ) : (
          <>
            <span className="inline-flex items-center gap-2">
              <span className="inline-block h-[6px] w-[6px] rounded-full" style={{ background: accent }} />
              Join <span className="text-[#F5F5F5] font-medium">{count - 1}+</span> on the early access list
            </span>
            <span className="hidden sm:inline text-[#3a3a3a]">·</span>
            <span>One email. When it's ready. That's it.</span>
          </>
        )}
      </div>
    </form>
  );
};

// ───────────────────────────── Success state (viral) ─────────────────────────────
const SuccessState = ({ accent, count, email }) => {
  const [copied, setCopied] = React.useState(false);
  const shareUrl = 'https://inkly.pics/?ref=' + encodeURIComponent((email || '').split('@')[0] || 'friend');
  const shareText = "I just joined Inkly — AI tattoo designs in 30 seconds. Get on the early access list:";
  const tweetHref = `https://twitter.com/intent/tweet?text=${encodeURIComponent(shareText)}&url=${encodeURIComponent(shareUrl)}`;
  const copy = async () => {
    try {
      await navigator.clipboard.writeText(shareUrl);
      setCopied(true);
      setTimeout(() => setCopied(false), 1800);
    } catch { setCopied(true); setTimeout(() => setCopied(false), 1800); }
  };
  return (
    <div role="status" aria-live="polite" className="border border-[#2a2a2a] p-5 sm:p-6">
      <div className="flex items-start gap-3">
        <div className="mt-[6px] h-[10px] w-[10px] rounded-full shrink-0" style={{ background: accent }} />
        <div className="flex-1 min-w-0">
          <div className="font-serif text-[22px] sm:text-[26px] leading-[1.15] tracking-[-0.005em] text-[#F5F5F5]">
            You're #{count} on the list.
          </div>
          <div className="mt-2 text-[14px] text-[#cfcfcf] leading-[1.6]">
            Move up the line — share Inkly with one friend and we'll bump you up <span className="text-[#F5F5F5] font-medium">10 places</span>.
          </div>
          <div className="mt-4 flex flex-wrap gap-2">
            <a
              href={tweetHref}
              target="_blank"
              rel="noopener noreferrer"
              className="inline-flex items-center gap-2 h-[44px] px-4 text-[13px] uppercase tracking-[0.06em] font-medium text-[#0A0A0A] bg-[#F5F5F5] hover:bg-white transition-colors"
            >
              <svg viewBox="0 0 24 24" className="h-[14px] w-[14px]" fill="currentColor" aria-hidden="true">
                <path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" />
              </svg>
              Share on X
            </a>
            <button
              type="button"
              onClick={copy}
              className="inline-flex items-center gap-2 h-[44px] px-4 text-[13px] uppercase tracking-[0.06em] font-medium text-[#F5F5F5] border border-[#2a2a2a] hover:border-[#5a5a5a] transition-colors"
            >
              <svg viewBox="0 0 24 24" className="h-[14px] w-[14px]" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <rect x="9" y="9" width="11" height="11" rx="1.5" />
                <path d="M5 15V5a1 1 0 0 1 1-1h10" />
              </svg>
              {copied ? 'Copied' : 'Copy link'}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
};

// ───────────────────────────── Counter ─────────────────────────────
const useCounter = (initial = 200) => {
  const [n, setN] = React.useState(initial);
  const bump = () => setN((v) => v + 1);
  return [n, bump];
};

// ───────────────────────────── Hero ─────────────────────────────
const Hero = ({ accent, ambient, count, onJoin, launchLabel }) => {
  const Ambient = window.AMBIENTS[ambient] || window.AMBIENTS.mountain;
  return (
    <section className="relative isolate overflow-hidden bg-[#0A0A0A] text-[#F5F5F5]">
      {/* Ambient illustration */}
      <div className="absolute inset-0 pointer-events-none flex items-center justify-center" aria-hidden="true">
        <div className="w-[180%] sm:w-[110%] max-w-[1800px] opacity-[0.20] sm:opacity-[0.12]">
          <Ambient />
        </div>
      </div>
      {/* Top bar */}
      <div className="relative max-w-[1240px] mx-auto px-6 sm:px-10 pt-7 sm:pt-9 flex items-center justify-between">
        <div className="flex items-center gap-2">
          <span className="font-serif text-[22px] sm:text-[24px] tracking-[-0.01em]">Inkly</span>
          <span className="hidden sm:inline-block h-[14px] w-px bg-[#2a2a2a] mx-2" />
          <span className="hidden sm:inline text-[12px] uppercase tracking-[0.18em] text-[#7a7a7a]">Pre-launch</span>
        </div>
        <div className="text-[12px] uppercase tracking-[0.18em] text-[#7a7a7a]">
          <span className="hidden sm:inline">Launching</span> {launchLabel}
        </div>
      </div>

      {/* Hero body */}
      <div className="relative max-w-[1240px] mx-auto px-6 sm:px-10 pt-14 sm:pt-24 pb-16 sm:pb-28">
        <Reveal duration={400}>
          <div className="text-[12px] uppercase tracking-[0.22em] text-[#9a9a9a] mb-6 sm:mb-8 flex items-center gap-3">
            <span className="inline-block h-px w-8" style={{ background: accent }} />
            AI tattoo design generator · For people getting tattooed
          </div>
        </Reveal>

        <Reveal delay={20} duration={400}>
          <div
            className="font-mono text-[11px] sm:text-[12px] uppercase tracking-[0.18em] mb-6 sm:mb-8 inline-flex items-center gap-2 px-3 py-2 border"
            style={{ color: accent, borderColor: accent + '55' }}
          >
            <span aria-hidden="true">★</span>
            <span>Founder pricing $9/mo locked forever — {Math.max(0, 200 - count)} of 200 spots left</span>
          </div>
        </Reveal>

        <Reveal delay={40} duration={400}>
          <h1 className="font-serif font-bold leading-[0.98] tracking-[-0.015em] text-[44px] sm:text-[68px] lg:text-[84px] max-w-[14ch]">
            Generate your perfect tattoo before you commit to it forever.
          </h1>
        </Reveal>

        <Reveal delay={80} duration={400}>
          <p className="mt-6 sm:mt-8 max-w-[58ch] text-[19px] sm:text-[22px] leading-[1.45] text-[#e5e5e5] font-serif">
            Type your idea. Pick a style. Six designs in thirty seconds.
          </p>
        </Reveal>

        <Reveal delay={80} duration={400}>
          <div className="mt-3 sm:mt-4 font-mono text-[11px] sm:text-[12px] uppercase tracking-[0.22em] text-[#7a7a7a] flex items-center gap-3">
            <span className="inline-block h-px w-6" style={{ background: accent }} />
            Early access opens {launchLabel}
          </div>
        </Reveal>

        <Reveal delay={80} duration={400}>
          <div className="mt-8 sm:mt-12 max-w-[560px]">
            <EmailForm accent={accent} onSuccess={onJoin} variant="hero" count={count + 1} />
          </div>
        </Reveal>

        {/* Mobile mini-preview: 3 sample tiles below the form, above the fold */}
        <Reveal delay={120} duration={400}>
          <div className="sm:hidden mt-7">
            <div className="grid grid-cols-3 gap-2">
              {[
                { glyph: 'mountain', label: 'Fine-line' },
                { glyph: 'rose',     label: 'Traditional' },
                { glyph: 'snake',    label: 'Blackwork' },
              ].map((p, i) => {
                const G = window.GLYPHS[p.glyph];
                return (
                  <div key={i} className="bg-white aspect-square flex items-center justify-center">
                    <div className="w-[60%] h-[60%]"><G stroke={1.3} /></div>
                  </div>
                );
              })}
            </div>
            <div className="mt-2 font-mono text-[10px] uppercase tracking-[0.22em] text-[#7a7a7a]">
              ↓ 12 examples below
            </div>
          </div>
        </Reveal>
      </div>

      {/* Soft fade into next section */}
      <div className="pointer-events-none absolute inset-x-0 bottom-0 h-24 bg-gradient-to-b from-transparent to-[#0A0A0A]" />
    </section>
  );
};

// ───────────────────────────── Proof gallery ─────────────────────────────
const ProofTile = ({ tile, idx }) => {
  const Glyph = window.GLYPHS[tile.glyph];
  const [hover, setHover] = React.useState(false);
  return (
    <Reveal delay={Math.min(idx * 40, 400)} className="group">
      <figure
        className="relative overflow-hidden bg-white"
        style={{ aspectRatio: tile.aspect }}
        onMouseEnter={() => setHover(true)}
        onMouseLeave={() => setHover(false)}
      >
        <div
          className="absolute inset-0 flex items-center justify-center transition-transform duration-[700ms] ease-out"
          style={{ transform: hover ? 'scale(1.04)' : 'scale(1)' }}
        >
          <div className="w-[68%] h-[68%]">
            <Glyph stroke={1.3} />
          </div>
        </div>
        {/* Hover overlay (desktop only via CSS) */}
        <figcaption
          className="absolute inset-x-0 bottom-0 px-4 py-3 text-[11px] uppercase tracking-[0.2em] text-[#0A0A0A] bg-white/80 backdrop-blur-[2px] hidden sm:flex items-center justify-between transition-opacity duration-300"
          style={{ opacity: hover ? 1 : 0 }}
        >
          <span>{tile.style}</span>
          <span className="text-[#7a7a7a] normal-case tracking-normal text-[12px] font-serif italic">{tile.hint}</span>
        </figcaption>
      </figure>
      <div className="mt-3 flex items-center justify-between sm:hidden">
        <span className="text-[11px] uppercase tracking-[0.2em] text-[#cfcfcf]">{tile.style}</span>
      </div>
      <div className="mt-3 text-[11px] uppercase tracking-[0.2em] text-[#9a9a9a] hidden sm:block">{tile.style}</div>
    </Reveal>
  );
};

const ProofGallery = ({ accent }) => {
  return (
    <section className="bg-[#0A0A0A] text-[#F5F5F5] pt-4 pb-24 sm:pb-32">
      <div className="max-w-[1240px] mx-auto px-6 sm:px-10">
        <Reveal>
          <div className="flex items-end justify-between mb-8 sm:mb-12 flex-wrap gap-4">
            <div>
              <div className="text-[12px] uppercase tracking-[0.22em] text-[#9a9a9a] mb-3 flex items-center gap-3">
                <span className="inline-block h-px w-8" style={{ background: accent }} />
                A few we made earlier
              </div>
              <h2 className="font-serif text-[34px] sm:text-[44px] leading-[1.05] tracking-[-0.01em] max-w-[18ch]">
                Generated by Inkly. Black ink, white background, ready for your artist.
              </h2>
            </div>
            <div className="text-[13px] text-[#9a9a9a] max-w-[36ch] leading-[1.65]">
              Black ink on white, like real flash. No 3D, no AI mascots, no painterly noise.
            </div>
          </div>
        </Reveal>

        <div className="columns-2 sm:columns-3 lg:columns-4 gap-4 sm:gap-5 [column-fill:_balance]">
          {PROOF_TILES.map((t, i) => (
            <div key={i} className="break-inside-avoid mb-4 sm:mb-5">
              <ProofTile tile={t} idx={i} />
            </div>
          ))}
        </div>
      </div>
    </section>
  );
};

// ───────────────────────────── Problem ─────────────────────────────
const ProblemCard = ({ num, title, sub, idx, emphasis = false, accent }) => (
  <Reveal delay={idx * 100} className={`pt-6 sm:pt-8 ${emphasis ? 'sm:pt-10' : ''}`}>
    <div
      className="border-t pt-6 sm:pt-8 h-full"
      style={{ borderColor: emphasis ? accent : '#2a2a2a' }}
    >
      <div className="text-[11px] uppercase tracking-[0.22em] mb-4 sm:mb-6 font-mono"
           style={{ color: emphasis ? accent : '#7a7a7a' }}>
        {num}{emphasis ? ' — the expensive one' : ''}
      </div>
      <div
        className={`font-serif tracking-[-0.01em] text-[#F5F5F5] ${
          emphasis ? 'text-[30px] sm:text-[44px] leading-[1.05]' : 'text-[22px] sm:text-[26px] leading-[1.2]'
        }`}
      >
        {title}
      </div>
      {sub && <div className={`mt-3 leading-[1.6] ${emphasis ? 'text-[15px] sm:text-[16px] text-[#cfcfcf]' : 'text-[14px] text-[#9a9a9a]'}`}>{sub}</div>}
    </div>
  </Reveal>
);

const Problem = ({ accent }) => (
  <section className="bg-[#0E0E0E] text-[#F5F5F5] py-24 sm:py-32 border-t border-[#1a1a1a]">
    <div className="max-w-[1240px] mx-auto px-6 sm:px-10">
      <Reveal>
        <div className="text-[12px] uppercase tracking-[0.22em] text-[#9a9a9a] mb-10 sm:mb-14 flex items-center gap-3">
          <span className="inline-block h-px w-8" style={{ background: accent }} />
          Why this exists
        </div>
      </Reveal>
      <div className="grid grid-cols-1 sm:grid-cols-4 gap-8 sm:gap-10">
        <div className="sm:col-span-1">
          <ProblemCard idx={0} num="01" title="Hours lost on Pinterest." sub="Boards full of other people's tattoos that aren't quite right." />
        </div>
        <div className="sm:col-span-2">
          <ProblemCard idx={1} num="02" title="$250+ for a custom artist draft." sub="Before you've decided if you even want it on your skin. Before you've slept on it. Before you've changed your mind twice." emphasis accent={accent} />
        </div>
        <div className="sm:col-span-1">
          <ProblemCard idx={2} num="03" title="Showing up with the wrong reference." sub="And realising it in the chair." />
        </div>
      </div>
    </div>
  </section>
);

// ───────────────────────────── How it works ─────────────────────────────
const StepBubble = () => (
  <div className="relative w-full h-full flex items-center justify-center">
    <svg viewBox="0 0 320 200" className="w-full h-full" fill="none" stroke="#0A0A0A" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round">
      <path d="M30 30 L290 30 L290 130 L120 130 L80 168 L88 130 L30 130 Z" />
      <path d="M60 60 L240 60" />
      <path d="M60 80 L200 80" />
      <path d="M60 100 L160 100" />
      <path d="M60 100 L160 100" />
    </svg>
    <div className="absolute inset-0 flex flex-col items-start justify-start px-[12%] pt-[14%] font-mono text-[11px] sm:text-[12px] text-[#0A0A0A] tracking-[0.02em] leading-[1.6]">
      <div>a fine-line mountain</div>
      <div>range across my</div>
      <div className="opacity-70">forearm…</div>
    </div>
  </div>
);

const StepSwatches = () => {
  const items = [
    { label: 'Fine-line', glyph: 'swallow' },
    { label: 'Traditional', glyph: 'rose' },
    { label: 'Blackwork', glyph: 'snake' },
    { label: 'Geometric', glyph: 'eye' },
  ];
  return (
    <div className="grid grid-cols-2 gap-2 w-full h-full p-3 sm:p-4">
      {items.map((s, i) => {
        const G = window.GLYPHS[s.glyph];
        const selected = i === 0;
        return (
          <div
            key={i}
            className="relative bg-white border flex items-center justify-center"
            style={{ borderColor: selected ? '#0A0A0A' : '#e5e5e5', borderWidth: selected ? 2 : 1 }}
          >
            <div className="w-[55%] h-[55%]"><G stroke={1.4} /></div>
            <div className="absolute bottom-1.5 left-2 text-[9px] sm:text-[10px] uppercase tracking-[0.16em] text-[#0A0A0A]">{s.label}</div>
          </div>
        );
      })}
    </div>
  );
};

const StepGrid = () => {
  const tiles = ['mountain', 'mountain', 'mountain', 'mountain', 'mountain', 'mountain'];
  return (
    <div className="grid grid-cols-3 grid-rows-2 gap-1.5 w-full h-full p-3 sm:p-4">
      {tiles.map((g, i) => {
        const G = window.GLYPHS[g];
        return (
          <div key={i} className="bg-white flex items-center justify-center border border-[#e5e5e5]">
            <div className="w-[60%] h-[60%]" style={{ opacity: 0.5 + (i % 3) * 0.18 }}><G stroke={1.2} /></div>
          </div>
        );
      })}
    </div>
  );
};

const HowStep = ({ n, title, sub, children, idx }) => (
  <Reveal delay={idx * 120} className="flex-1 flex flex-col">
    <div className="aspect-[3/2] bg-[#fafafa] border border-[#1f1f1f]/10" style={{ background: '#F5F5F5' }}>
      {children}
    </div>
    <div className="mt-5 sm:mt-6">
      <div className="font-mono text-[11px] uppercase tracking-[0.22em] text-[#9a9a9a]">Step {n}</div>
      <div className="mt-2 font-serif text-[22px] sm:text-[26px] leading-[1.15] tracking-[-0.01em] text-[#F5F5F5]">{title}</div>
      <div className="mt-2 text-[14px] text-[#9a9a9a] leading-[1.6]">{sub}</div>
    </div>
  </Reveal>
);

const HowItWorks = ({ accent }) => (
  <section className="bg-[#0A0A0A] text-[#F5F5F5] py-24 sm:py-32">
    <div className="max-w-[1240px] mx-auto px-6 sm:px-10">
      <Reveal>
        <div className="flex items-end justify-between flex-wrap gap-4 mb-12 sm:mb-16">
          <h2 className="font-serif text-[34px] sm:text-[44px] leading-[1.05] tracking-[-0.01em] max-w-[18ch]">
            Three steps. Thirty seconds.
          </h2>
          <div className="text-[12px] uppercase tracking-[0.22em] text-[#9a9a9a] flex items-center gap-3">
            <span className="inline-block h-px w-8" style={{ background: accent }} />
            How it works
          </div>
        </div>
      </Reveal>
      <div className="flex flex-col sm:flex-row gap-8 sm:gap-6">
        <HowStep idx={0} n="01" title="Describe your idea" sub="Plain language. As specific or as vague as you want.">
          <StepBubble />
        </HowStep>
        <HowStep idx={1} n="02" title="Pick a style" sub="Seven styles, hand-tuned by tattoo artists.">
          <StepSwatches />
        </HowStep>
        <HowStep idx={2} n="03" title="Get six designs in thirty seconds" sub="Save your favourites. Take them to your artist.">
          <StepGrid />
        </HowStep>
      </div>
    </div>
  </section>
);

// ───────────────────────────── Styles preview ─────────────────────────────
const StyleCard = ({ s, idx }) => {
  const G = window.GLYPHS[s.glyph];
  return (
    <Reveal delay={Math.min(idx * 50, 320)} className="snap-start shrink-0 w-[260px] sm:w-auto">
      <div className="bg-white aspect-[4/5] flex items-center justify-center">
        <div className="w-[58%] h-[58%]"><G stroke={1.3} /></div>
      </div>
      <div className="mt-4">
        <div className="font-serif text-[20px] sm:text-[22px] tracking-[-0.005em] text-[#F5F5F5]">{s.name}</div>
        <div className="mt-1 text-[13px] sm:text-[14px] text-[#9a9a9a] leading-[1.55]">— {s.desc}</div>
      </div>
    </Reveal>
  );
};

const StylesPreview = ({ accent }) => (
  <section className="bg-[#0E0E0E] text-[#F5F5F5] py-24 sm:py-32 border-t border-[#1a1a1a]">
    <div className="max-w-[1240px] mx-auto px-6 sm:px-10">
      <Reveal>
        <div className="flex items-end justify-between flex-wrap gap-4 mb-10 sm:mb-14">
          <h2 className="font-serif text-[34px] sm:text-[44px] leading-[1.05] tracking-[-0.01em] max-w-[18ch]">
            Seven styles. Pick the one that's already on your moodboard.
          </h2>
          <div className="text-[12px] uppercase tracking-[0.22em] text-[#9a9a9a] flex items-center gap-3">
            <span className="inline-block h-px w-8" style={{ background: accent }} />
            Styles
          </div>
        </div>
      </Reveal>
    </div>
    {/* Edge-bleeding scroll on mobile, contained grid on desktop */}
    <div className="sm:max-w-[1240px] sm:mx-auto sm:px-10">
      <div className="flex sm:grid sm:grid-cols-4 gap-4 sm:gap-5 overflow-x-auto sm:overflow-visible snap-x snap-mandatory pl-6 pr-6 sm:pl-0 sm:pr-0 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden">
        {STYLES.map((s, i) => <StyleCard key={s.key} s={s} idx={i} />)}
      </div>
    </div>
  </section>
);

// ───────────────────────────── Secondary CTA ─────────────────────────────
const SecondaryCTA = ({ accent, count, onJoin, city }) => (
  <section className="bg-[#0A0A0A] text-[#F5F5F5] py-24 sm:py-32 border-t border-[#1a1a1a]">
    <div className="max-w-[820px] mx-auto px-6 sm:px-10 text-center">
      <Reveal>
        <div className="text-[12px] uppercase tracking-[0.22em] text-[#9a9a9a] mb-6 inline-flex items-center gap-3">
          <span className="inline-block h-px w-8" style={{ background: accent }} />
          Early access
          <span className="inline-block h-px w-8" style={{ background: accent }} />
        </div>
      </Reveal>
      <Reveal delay={120}>
        <h2 className="font-serif text-[36px] sm:text-[52px] leading-[1.05] tracking-[-0.015em]">
          Be first in line.
        </h2>
      </Reveal>
      <Reveal delay={220}>
        <p className="mt-5 text-[16px] sm:text-[18px] text-[#cfcfcf] leading-[1.65] max-w-[52ch] mx-auto">
          We're emailing the first 200 people on the waitlist before public launch. Currently {count} on the list.
        </p>
      </Reveal>

      <Reveal delay={300}>
        <div className="mt-8 mx-auto max-w-[560px] border p-5 sm:p-6 text-left flex items-start gap-4" style={{ borderColor: accent }}>
          <div className="font-serif text-[28px] sm:text-[32px] leading-none" style={{ color: accent }}>★</div>
          <div className="flex-1">
            <div className="font-mono text-[11px] uppercase tracking-[0.22em]" style={{ color: accent }}>
              Founder pricing — first 200 only
            </div>
            <div className="mt-2 font-serif text-[20px] sm:text-[22px] leading-[1.25] tracking-[-0.005em] text-[#F5F5F5]">
              <span className="line-through text-[#7a7a7a] decoration-[#7a7a7a]/60 mr-2">$19/mo</span>
              <span>$9/month, locked in forever.</span>
            </div>
            <div className="mt-2 text-[13px] text-[#9a9a9a] leading-[1.6]">
              Only for the first 200 emails on the list. {Math.max(0, 200 - count)} spots left.
            </div>
          </div>
        </div>
      </Reveal>

      <Reveal delay={400}>
        <div className="mt-8 max-w-[520px] mx-auto text-left">
          <EmailForm accent={accent} onSuccess={onJoin} variant="cta" count={count + 1} />
        </div>
      </Reveal>
      <Reveal delay={520}>
        <div className="mt-10 text-[13px] text-[#7a7a7a] leading-[1.7]">
          Made by two people in {city}. Reply to any email — you'll get one of us.
        </div>
      </Reveal>
    </div>
  </section>
);

// ───────────────────────────── Footer ─────────────────────────────
const Footer = ({ contactEmail = 'hello@inkly.pics' }) => (
  <footer className="bg-[#0A0A0A] text-[#F5F5F5] border-t border-[#1a1a1a]">
    <div className="max-w-[1240px] mx-auto px-6 sm:px-10 py-10 flex flex-col sm:flex-row items-start sm:items-center justify-between gap-6">
      <div className="font-serif text-[22px] tracking-[-0.01em]">Inkly</div>
      <div className="flex flex-wrap items-center gap-x-7 gap-y-3 text-[13px] text-[#9a9a9a]">
        <span>© 2026 Inkly</span>
        <a href="privacy.html" className="hover:text-[#F5F5F5] transition-colors">Privacy</a>
        <a href={`mailto:${contactEmail}`} className="hover:text-[#F5F5F5] transition-colors">{contactEmail}</a>
      </div>
    </div>
  </footer>
);

Object.assign(window, {
  Hero, ProofGallery, Problem, HowItWorks, StylesPreview, SecondaryCTA, Footer,
  useCounter,
});
