// cache-bust: 1779468723-8d9735
// =========================================================
// Landing.jsx — The Build Lab public marketing page
// Long-scroll. 1440px artboard width. Warm coral / paper / dark.
// =========================================================

const { useState, useEffect, useRef, useMemo } = React;
const D = window.BL_DATA;

// ────────────────────────────────────────────────────────────────
// Small primitives
// ────────────────────────────────────────────────────────────────

function Eyebrow({ children, dot = true }) {
  return (
    <div className="bl-eyebrow">
      {dot && <span className="dot"></span>}
      {children}
    </div>
  );
}

function CornerMarks() {
  return (
    <>
      <span className="bl-cornermark tl"></span>
      <span className="bl-cornermark tr"></span>
      <span className="bl-cornermark bl"></span>
      <span className="bl-cornermark br"></span>
    </>
  );
}

function LockBadge({ size = 14, color = 'var(--ink-mute)' }) {
  return (
    <svg width={size} height={size} viewBox="0 0 16 16" fill="none" style={{ flex: '0 0 auto' }}>
      <path d="M4 7V5a4 4 0 1 1 8 0v2" stroke={color} strokeWidth="1.4" strokeLinecap="round"/>
      <rect x="3" y="7" width="10" height="7" rx="1.5" stroke={color} strokeWidth="1.4"/>
      <circle cx="8" cy="10.5" r="1" fill={color}/>
    </svg>
  );
}

function PlayBadge({ size = 14, color = 'var(--accent)' }) {
  return (
    <svg width={size} height={size} viewBox="0 0 16 16" fill="none">
      <circle cx="8" cy="8" r="7" stroke={color} strokeWidth="1.4"/>
      <path d="M6.5 5.5L11 8l-4.5 2.5v-5z" fill={color}/>
    </svg>
  );
}

// ────────────────────────────────────────────────────────────────
// Nav
// ────────────────────────────────────────────────────────────────

function ThemeToggle() {
  // Subscribe to BL_THEME so the icon flips on toggle
  const [, _tt_setTick] = React.useState(0);
  React.useEffect(() => {
    if (!window.BL_THEME) return;
    const fn = () => _tt_setTick((t) => t + 1);
    window.BL_THEME._listeners.add(fn);
    return () => window.BL_THEME._listeners.delete(fn);
  }, []);
  const isDark = !!(window.BL_THEME && window.BL_THEME.get() === 'dark');
  return (
    <button
      type="button"
      onClick={() => window.BL_THEME && window.BL_THEME.toggle()}
      className="bl-theme-toggle"
      aria-label={isDark ? 'Switch to light mode' : 'Switch to dark mode'}
      title={isDark ? 'Switch to light mode' : 'Switch to dark mode'}
    >
      {isDark ? (
        // Sun (we're in dark, click to go light)
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <circle cx="12" cy="12" r="4" />
          <path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" />
        </svg>
      ) : (
        // Moon (we're in light, click to go dark)
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
        </svg>
      )}
    </button>
  );
}

function Nav() {
  const _bl_auth = window.useBLAuth ? window.useBLAuth() : { isLoggedIn: false, openLogin: () => {}, logout: () => {}, email: null };
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 18,
      padding: '20px 56px',
      borderBottom: '1px solid var(--line-paper)',
      background: 'var(--nav-bg)',
      backdropFilter: 'blur(8px)',
      position: 'sticky', top: 0, zIndex: 30,
    }}>
      <Logo />
      <span style={{ width: 1, height: 18, background: 'var(--line-paper-2)' }}></span>
      <span className="bl-mono" style={{ fontSize: 11, color: 'var(--ink-mute)', letterSpacing: '.06em' }}>
        reloadin5.com<span style={{ color: 'var(--accent)' }}>/build</span>
      </span>
      <span className="bl-mono" style={{ fontSize: 10, color: 'var(--ink-mute)', padding: '3px 8px', border: '1px solid var(--line-paper)', borderRadius: 999 }}>
        ↗ see it live at reloadin5.com
      </span>
      <span style={{ flex: 1 }}></span>
      <a href="#curriculum" onClick={(e) => { e.preventDefault(); const t=document.getElementById('curriculum'); if(t) t.scrollIntoView({behavior:'smooth'}); }} className="bl-mono" style={{ fontSize: 13, color: 'var(--ink-dim)', cursor: 'pointer', textDecoration: 'none' }}>Curriculum</a>
      <a href="#arch" onClick={(e) => { e.preventDefault(); const t=document.getElementById('arch'); if(t) t.scrollIntoView({behavior:'smooth'}); }} className="bl-mono" style={{ fontSize: 13, color: 'var(--ink-dim)', cursor: 'pointer', textDecoration: 'none' }}>Architecture</a>
      <a href="#log" onClick={(e) => { e.preventDefault(); const t=document.getElementById('log'); if(t) t.scrollIntoView({behavior:'smooth'}); }} className="bl-mono" style={{ fontSize: 13, color: 'var(--ink-dim)', cursor: 'pointer', textDecoration: 'none' }}>Build log</a>
      <a href="#pricing" onClick={(e) => { e.preventDefault(); const t=document.getElementById('pricing'); if(t) t.scrollIntoView({behavior:'smooth'}); }} className="bl-mono" style={{ fontSize: 13, color: 'var(--ink-dim)', cursor: 'pointer', textDecoration: 'none' }}>Pricing</a>
      <ThemeToggle />
      {_bl_auth.isLoggedIn ? (
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, borderLeft: '1px solid var(--line-paper-2)', paddingLeft: 18 }}>
          <span className="bl-mono" style={{ fontSize: 12, color: 'var(--ink-dim)' }}>{_bl_auth.email || 'signed in'}</span>
          <button onClick={_bl_auth.logout} className="bl-mono" style={{ fontSize: 11, color: 'var(--ink-mute)', textDecoration: 'underline', background: 'transparent', border: 0, padding: 0, cursor: 'pointer' }}>sign out</button>
        </div>
      ) : (
        <button onClick={_bl_auth.openLogin} className="bl-mono" style={{ fontSize: 13, color: 'var(--ink-dim)', borderLeft: '1px solid var(--line-paper-2)', paddingLeft: 18, background: 'transparent', border: 0, cursor: 'pointer' }}>Sign in</button>
      )}
      <button onClick={() => { const t=document.getElementById('pricing'); if(t) t.scrollIntoView({behavior:'smooth'}); }} className="bl-btn bl-btn-primary" style={{ padding: '10px 16px', fontSize: 13 }}>
        Join the lab →
      </button>
    </div>
  );
}

function Logo({ dark = false }) {
  const fg = dark ? 'var(--bone)' : 'var(--ink)';
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
      <svg width="28" height="28" viewBox="0 0 28 28" fill="none">
        <rect x="1" y="1" width="26" height="26" rx="6" stroke={fg} strokeWidth="1.4"/>
        <path d="M7 9 L11 14 L7 19" stroke="var(--accent)" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/>
        <line x1="13" y1="19" x2="21" y2="19" stroke={fg} strokeWidth="1.6" strokeLinecap="round"/>
      </svg>
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>
        <span className="bl-serif" style={{ fontSize: 19, color: fg }}>The Build Lab</span>
        <span className="bl-mono" style={{ fontSize: 10, color: 'var(--accent)', letterSpacing: '.1em' }}>v1.0</span>
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────────
// Hero
// ────────────────────────────────────────────────────────────────

function Hero() {
  return (
    <section style={{ padding: '88px 56px 96px', position: 'relative' }}>
      {/* warm glow behind content */}
      <div style={{
        position: 'absolute', top: 80, right: -120, width: 700, height: 600,
        background: 'radial-gradient(closest-side, rgba(255,139,98,.18), transparent 70%)',
        pointerEvents: 'none', zIndex: 0,
      }}></div>

      <div style={{ display: 'grid', gridTemplateColumns: '1.05fr 1fr', gap: 56, alignItems: 'center', position: 'relative', zIndex: 1 }}>
        {/* left */}
        <div>
          <Eyebrow>Members-only · curriculum v1.0 · 5 modules · 24 lessons</Eyebrow>

          <h1 className="bl-display" style={{ fontSize: 92, marginTop: 18, color: 'var(--ink)', lineHeight: 1.02 }}>
            Ship a real <span className="bl-italic" style={{ color: 'var(--accent)' }}>SaaS</span>.<br/>
            With <span className="bl-italic">Claude</span>. From scratch.
          </h1>

          <p style={{
            fontSize: 19, lineHeight: 1.5, color: 'var(--ink-dim)',
            maxWidth: 540, marginTop: 32,
          }}>
            See it live at <a href="https://reloadin5.com" target="_blank" rel="noopener noreferrer" style={{ color: 'var(--accent-deep)', borderBottom: '1px solid var(--accent-soft)', cursor: 'pointer' }}>reloadin5.com</a>.
            Then come here — <span className="bl-mono" style={{ fontSize: 16, color: 'var(--ink)' }}>reloadin5.com/build</span> —
            and watch the whole thing get built. Domain, DNS, Workers, D1, Stripe, SSO, the Anthropic API,
            the actual prompts, the actual commits. No toy demos.
          </p>

          <div style={{ display: 'flex', gap: 12, marginTop: 32 }}>
            <button onClick={() => { const t=document.getElementById('pricing'); if(t) t.scrollIntoView({behavior:'smooth'}); }} className="bl-btn bl-btn-accent" style={{ padding: '14px 22px', fontSize: 15 }}>
              Get the lab — $149/yr
              <span style={{ opacity: .7, marginLeft: 6 }}>→</span>
            </button>
            <button onClick={() => { window.location.hash = '#ep/1.0'; }} className="bl-btn bl-btn-ghost" style={{ padding: '14px 22px', fontSize: 15 }}>
              <PlayBadge color="var(--ink)" />
              Try episode 1.0 free
            </button>
          </div>

          {/* trust strip */}
          <div style={{ display: 'flex', gap: 28, marginTop: 40, alignItems: 'center' }}>
            <div className="bl-mono" style={{ fontSize: 11, color: 'var(--ink-mute)', letterSpacing: '.08em' }}>
              BUILT&nbsp;ON
            </div>
            {['CLOUDFLARE', 'WORKERS', 'D1', 'STRIPE', 'CLAUDE', 'GITHUB'].map((t, i) => (
              <span key={i} className="bl-mono" style={{ fontSize: 12, color: 'var(--ink-dim)', fontWeight: 600, letterSpacing: '.02em' }}>
                {t}
              </span>
            ))}
          </div>
        </div>

        {/* right: terminal/editor mockup */}
        <HeroTerminal />
      </div>
    </section>
  );
}

function HeroTerminal() {
  return (
    <div style={{ position: 'relative' }}>
      <CornerMarks />
      <div className="bl-card-dark" style={{
        overflow: 'hidden',
        boxShadow: '0 30px 80px -30px rgba(26,22,18,.4), 0 0 0 1px rgba(255,255,255,.04)',
      }}>
        {/* window chrome */}
        <div style={{
          display: 'flex', alignItems: 'center', gap: 8,
          padding: '12px 14px',
          background: 'var(--dark-3)',
          borderBottom: '1px solid var(--line-dark)',
        }}>
          <span style={{ width: 11, height: 11, borderRadius: '50%', background: '#ff5f57' }}></span>
          <span style={{ width: 11, height: 11, borderRadius: '50%', background: '#febc2e' }}></span>
          <span style={{ width: 11, height: 11, borderRadius: '50%', background: '#28c840' }}></span>
          <span style={{ flex: 1 }}></span>
          <span className="bl-mono" style={{ fontSize: 11, color: 'var(--bone-mute)' }}>reloadin5.com/build — wrangler tail</span>
          <span style={{ flex: 1 }}></span>
        </div>

        {/* split: claude pane + terminal pane */}
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', minHeight: 420 }}>
          {/* Claude pane */}
          <div style={{ padding: '18px 18px', borderRight: '1px solid var(--line-dark)' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 14 }}>
              <span style={{ width: 6, height: 6, borderRadius: '50%', background: 'var(--accent)' }}></span>
              <span className="bl-mono" style={{ fontSize: 10, color: 'var(--bone-mute)', letterSpacing: '.08em' }}>CLAUDE · SONNET 4.5</span>
            </div>

            <div className="bl-mono" style={{ fontSize: 11.5, lineHeight: 1.6, color: 'var(--bone-dim)' }}>
              <div style={{ color: 'var(--accent-soft)' }}>{'>'} you</div>
              <div style={{ marginTop: 4, color: 'var(--bone)' }}>
                Patch <span style={{ color: 'var(--accent-glow)' }}>Pricing.jsx</span> so the yearly
                tier shows a "SAVE $79" pill, and emit a one-shot Python
                patch script.
              </div>

              <div style={{ marginTop: 16, color: 'var(--sage)' }}>{'>'} claude</div>
              <div style={{ marginTop: 4 }}>
                Here's <span style={{ color: 'var(--accent-glow)' }}>~/Downloads/patch-pricing-save79.py</span>.
                It uses str.replace anchored on the yearly tier card; idempotent.
              </div>

              <div style={{
                marginTop: 12,
                background: 'var(--dark-4)',
                border: '1px solid var(--line-dark-2)',
                borderRadius: 6,
                padding: '10px 12px',
                fontSize: 10.5,
              }}>
                <div style={{ color: 'var(--sage)' }}>import subprocess, pathlib</div>
                <div style={{ color: 'var(--bone-dim)' }}>p = pathlib.Path(<span style={{ color: 'var(--amber)' }}>"src/Pricing.jsx"</span>)</div>
                <div style={{ color: 'var(--bone-dim)' }}>old = <span style={{ color: 'var(--amber)' }}>"$149/yr"</span></div>
                <div style={{ color: 'var(--bone-dim)' }}>new = <span style={{ color: 'var(--amber)' }}>"$149/yr · SAVE $79"</span></div>
                <div style={{ color: 'var(--bone-dim)' }}>p.write_text(p.read_text().replace(old, new))</div>
                <div style={{ color: 'var(--bone-mute)' }}>subprocess.run([<span style={{ color: 'var(--amber)' }}>"npm","run","build"</span>])</div>
                <div style={{ color: 'var(--bone-mute)' }}>subprocess.run([<span style={{ color: 'var(--amber)' }}>"git","commit","-am","feat: save79"</span>])</div>
              </div>

              <div className="bl-cursor" style={{ marginTop: 14, color: 'var(--bone-mute)' }}>type a follow-up</div>
            </div>
          </div>

          {/* Terminal pane */}
          <div style={{ padding: '18px 18px', background: 'var(--dark)' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 14 }}>
              <span style={{ width: 6, height: 6, borderRadius: '50%', background: 'var(--sage)' }}></span>
              <span className="bl-mono" style={{ fontSize: 10, color: 'var(--bone-mute)', letterSpacing: '.08em' }}>iTerm · reloadin5</span>
            </div>

            <div className="bl-mono" style={{ fontSize: 11.5, lineHeight: 1.65, color: 'var(--bone-dim)' }}>
              <div><span style={{ color: 'var(--sage)' }}>$</span> python3 ~/Downloads/patch-pricing-save79.py</div>
              <div style={{ color: 'var(--bone)' }}>✓ patched src/Pricing.jsx (1 replacement)</div>
              <div style={{ color: 'var(--bone-mute)' }}>vite v5 — building…</div>
              <div style={{ color: 'var(--bone-mute)' }}>  ✓ 1142 modules transformed</div>
              <div style={{ color: 'var(--bone-mute)' }}>  ✓ dist/assets/index-9f3b.js  186.4 kb</div>
              <div style={{ color: 'var(--sage)' }}>✓ built in 1.84s</div>
              <div style={{ color: 'var(--bone-dim)', marginTop: 6 }}>[main 4f9a82e] feat: save79</div>
              <div style={{ color: 'var(--bone-mute)' }}> 1 file changed, 1 insertion(+)</div>
              <div style={{ color: 'var(--bone-dim)' }}>To github.com:srrq/reloadin5.git</div>
              <div style={{ color: 'var(--bone-mute)' }}>   8a21cd9..4f9a82e  main → main</div>

              <div style={{ marginTop: 14 }}>
                <span style={{ color: 'var(--accent)' }}>cloudflare</span> · deploying…
              </div>
              <div style={{ color: 'var(--bone-mute)' }}> ▰▰▰▰▰▰▰▱▱ 78%</div>
              <div style={{ color: 'var(--sage)', marginTop: 6 }}>✓ live · https://reloadin5.com/build</div>
              <div className="bl-cursor" style={{ color: 'var(--bone-mute)', marginTop: 10 }}>$</div>
            </div>
          </div>
        </div>

        {/* footer ribbon */}
        <div style={{
          padding: '10px 14px',
          background: 'var(--dark-3)',
          borderTop: '1px solid var(--line-dark)',
          display: 'flex', alignItems: 'center', gap: 14,
        }}>
          <span className="bl-mono" style={{ fontSize: 10, color: 'var(--sage)' }}>● live</span>
          <span className="bl-mono" style={{ fontSize: 10, color: 'var(--bone-mute)' }}>edge: cf-iad · 38 ms TTFB</span>
          <span style={{ flex: 1 }}></span>
          <span className="bl-mono" style={{ fontSize: 10, color: 'var(--bone-mute)' }}>commit 4f9a82e · 12s ago</span>
        </div>
      </div>

      {/* engineer marker */}
      <div className="bl-marker" style={{ bottom: -28, right: 0 }}>
        fig 01 · the actual loop. nothing faked.
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────────
// Metrics strip
// ────────────────────────────────────────────────────────────────

function MetricsStrip() {
  return (
    <section style={{
      borderTop: '1px solid var(--line-paper)',
      borderBottom: '1px solid var(--line-paper)',
      background: 'var(--paper-2)',
      padding: '24px 56px',
      display: 'flex', gap: 0, alignItems: 'center',
    }}>
      {D.metrics.map((m, i) => (
        <React.Fragment key={i}>
          {i > 0 && <span style={{ width: 1, height: 36, background: 'var(--line-paper-2)' }}></span>}
          <div style={{ flex: 1, padding: '0 28px' }}>
            <div className="bl-mono" style={{ fontSize: 10, color: 'var(--ink-mute)', letterSpacing: '.08em', textTransform: 'uppercase', marginBottom: 6 }}>
              {m.label}
            </div>
            <div className="bl-serif" style={{ fontSize: 36, color: m.accent ? 'var(--accent-deep)' : 'var(--ink)' }}>
              {m.prefix && m.suffix}{m.value}{!m.prefix && m.suffix}
            </div>
          </div>
        </React.Fragment>
      ))}
    </section>
  );
}

// ────────────────────────────────────────────────────────────────
// Story / about creator
// ────────────────────────────────────────────────────────────────

function Story() {
  return (
    <section style={{ padding: '96px 56px', display: 'grid', gridTemplateColumns: '1fr 1.4fr', gap: 72 }}>
      <div>
        <Eyebrow>Who builds this</Eyebrow>
        <h2 className="bl-display" style={{ fontSize: 56, marginTop: 16, lineHeight: 1.02 }}>
          Built by an <span className="bl-italic" style={{ color: 'var(--accent)' }}>engineer</span>,
          not a marketer.
        </h2>

        {/* face placeholder */}
        <div style={{ marginTop: 32, display: 'flex', alignItems: 'center', gap: 16 }}>
          <div style={{
            width: 72, height: 72, borderRadius: '50%',
            background: 'linear-gradient(135deg, var(--accent-soft), var(--accent))',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            color: '#fff', fontFamily: 'var(--serif)', fontSize: 32,
            boxShadow: '0 8px 28px -10px rgba(217,104,70,.45)',
          }}>SQ</div>
          <div>
            <div className="bl-serif" style={{ fontSize: 22 }}>{D.brand.creator.name}</div>
            <div className="bl-mono" style={{ fontSize: 11, color: 'var(--ink-mute)', letterSpacing: '.04em', marginTop: 2 }}>
              {D.brand.creator.role}
            </div>
          </div>
        </div>
      </div>

      <div>
        <p style={{ fontSize: 22, lineHeight: 1.5, color: 'var(--ink-2)', fontFamily: 'var(--serif)' }}>
          "{D.brand.creator.pitch}"
        </p>

        <div style={{ marginTop: 32, display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 16 }}>
          {[
            { k: 'day job',       v: 'SSO + database systems' },
            { k: 'side project',  v: 'reloadin5.com (live)' },
            { k: 'time to v1',    v: '1 weekend + 3 evenings' },
          ].map((x, i) => (
            <div key={i} style={{ padding: '14px 16px', background: 'var(--paper-2)', borderRadius: 'var(--r-sm)' }}>
              <div className="bl-mono" style={{ fontSize: 10, color: 'var(--ink-mute)', letterSpacing: '.08em', textTransform: 'uppercase' }}>
                {x.k}
              </div>
              <div style={{ fontSize: 15, color: 'var(--ink)', marginTop: 4, fontWeight: 500 }}>{x.v}</div>
            </div>
          ))}
        </div>

        <p style={{ marginTop: 24, color: 'var(--ink-dim)', fontSize: 15, lineHeight: 1.55 }}>
          I'm not a YouTuber. I'm not a course creator. I'm an infrastructure engineer who shipped
          a real product over a weekend and figured out a workflow that should not be a secret.
          This is that workflow, recorded, edited, and indexed — episode by episode.
        </p>
      </div>
    </section>
  );
}

// ────────────────────────────────────────────────────────────────
// Curriculum — 5 modules
// ────────────────────────────────────────────────────────────────

function Curriculum() {
  const [active, setActive] = useState('m1');
  const mod = D.modules.find((m) => m.id === active);
  const _curriculum_auth = window.useBLAuth ? window.useBLAuth() : { hasBuildLabAccess: false, openLogin: () => {} };

  return (
    <section id="curriculum" style={{ padding: '96px 56px', background: 'var(--paper-2)', position: 'relative' }}>
      <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', marginBottom: 48 }}>
        <div>
          <Eyebrow>The curriculum</Eyebrow>
          <h2 className="bl-display" style={{ fontSize: 64, marginTop: 14, lineHeight: 1 }}>
            Five modules. <span className="bl-italic" style={{ color: 'var(--accent)' }}>One real build.</span>
          </h2>
          <p style={{ marginTop: 14, fontSize: 17, color: 'var(--ink-dim)', maxWidth: 540 }}>
            Each module is a phase of building reloadin5.com.
            Watch in order or jump straight to the part you're stuck on.
            <br/><span style={{ color: 'var(--ink-mute)', fontSize: 15 }}>
              The first 3 lessons in Module 1 are free. The other 21 unlock with the lab.
            </span>
          </p>
        </div>
        <div className="bl-chip bl-chip-accent" style={{ fontSize: 12, padding: '6px 12px' }}>
          updated weekly · last drop 17m ago
        </div>
      </div>

      {/* module strip */}
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(5, 1fr)', gap: 10, marginBottom: 32 }}>
        {D.modules.map((m) => {
          const isActive = m.id === active;
          return (
            <button
              key={m.id}
              onClick={() => setActive(m.id)}
              className="bl-card"
              style={{
                textAlign: 'left',
                padding: '16px 16px 18px',
                background: isActive ? 'var(--ink)' : 'var(--surface-1)',
                color: isActive ? 'var(--paper)' : 'var(--ink)',
                borderColor: isActive ? 'var(--ink)' : 'var(--line-paper)',
                cursor: 'pointer',
                position: 'relative',
                transition: 'all .15s ease',
              }}
            >
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
                <span className="bl-mono" style={{ fontSize: 11, opacity: .55, letterSpacing: '.08em' }}>MOD {m.n}</span>
                {isActive && <span style={{ width: 6, height: 6, borderRadius: '50%', background: 'var(--accent)' }}></span>}
              </div>
              <div className="bl-serif" style={{ fontSize: 26, marginTop: 12, lineHeight: 1 }}>{m.title}</div>
              <div style={{ fontSize: 12.5, opacity: .65, marginTop: 6 }}>{m.subtitle}</div>
              <div className="bl-mono" style={{ fontSize: 10, opacity: .5, marginTop: 12, letterSpacing: '.05em' }}>
                {m.episodes.length} EP · {m.duration}
              </div>
            </button>
          );
        })}
      </div>

      {/* selected module — episode list + still frame */}
      <div style={{ display: 'grid', gridTemplateColumns: '1.5fr 1fr', gap: 28 }}>
        {/* episodes */}
        <div className="bl-card" style={{ padding: '6px 0 6px' }}>
          <div style={{ padding: '20px 28px 18px', borderBottom: '1px solid var(--line-paper)' }}>
            <div style={{ display: 'flex', alignItems: 'baseline', gap: 12 }}>
              <span className="bl-mono" style={{ fontSize: 11, color: 'var(--accent)', letterSpacing: '.08em' }}>MODULE {mod.n}</span>
              <span className="bl-serif" style={{ fontSize: 30 }}>{mod.title}</span>
            </div>
            <p style={{ marginTop: 8, color: 'var(--ink-dim)', fontSize: 14.5, maxWidth: 620, lineHeight: 1.5 }}>
              {mod.blurb}
            </p>
          </div>

          <div>
            {mod.episodes.map((ep, i) => {
              const _ep_locked = !ep.free && !_curriculum_auth.hasBuildLabAccess;
              const _ep_onClick = () => {
                if (_ep_locked) {
                  const target = document.getElementById('pricing');
                  if (target) target.scrollIntoView({ behavior: 'smooth' });
                  return;
                }
                // free episode — open the guided lesson route
                window.location.hash = '#ep/' + ep.n;
              };
              return (
                <div key={i}
                  onClick={_ep_onClick}
                  style={{
                    display: 'grid', gridTemplateColumns: '52px 1fr auto auto auto',
                    alignItems: 'center', gap: 14,
                    padding: '14px 28px',
                    borderBottom: i === mod.episodes.length - 1 ? 'none' : '1px solid var(--line-paper)',
                    cursor: 'pointer',
                    transition: 'background .12s, opacity .12s',
                    opacity: _ep_locked ? 0.62 : 1,
                  }}
                  onMouseEnter={(e) => e.currentTarget.style.background = 'var(--paper-2)'}
                  onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
                >
                  <span className="bl-mono" style={{ fontSize: 12, color: 'var(--ink-mute)' }}>{ep.n}</span>
                  <div>
                    <div style={{ fontSize: 14.5, color: 'var(--ink)', fontWeight: 500 }}>{ep.title}</div>
                    <div className="bl-mono" style={{ fontSize: 10.5, color: 'var(--ink-mute)', marginTop: 3, letterSpacing: '.04em' }}>
                      {ep.dur} · video lesson{ep.fresh ? ' · just dropped' : ''}
                    </div>
                  </div>
                  {ep.hot && <span className="bl-chip bl-chip-accent" style={{ fontSize: 10, padding: '3px 8px' }}>start here</span>}
                  {ep.fresh && <span className="bl-chip bl-chip-sage" style={{ fontSize: 10, padding: '3px 8px' }}>NEW</span>}
                  {ep.free
                    ? <span className="bl-chip" style={{ fontSize: 10, padding: '3px 8px', background: 'var(--surface-1)', color: 'var(--ink)' }}>
                        <PlayBadge size={11} color="var(--ink)" /> free
                      </span>
                    : _ep_locked
                      ? <span className="bl-chip" style={{ fontSize: 10, padding: '3px 8px', background: 'var(--accent-tint)', color: 'var(--accent-deep)', borderColor: 'var(--accent-soft)' }}>
                          <LockBadge size={11} color="var(--accent-deep)" /> unlock
                        </span>
                      : <span className="bl-chip bl-chip-sage" style={{ fontSize: 10, padding: '3px 8px' }}>
                          <PlayBadge size={11} color="var(--sage-deep)" /> ready
                        </span>}
                </div>
              );
            })}
          </div>
        </div>

        {/* preview frame */}
        <ModulePreview mod={mod} />
      </div>
    </section>
  );
}

function ModulePreview({ mod }) {
  return (
    <div style={{ position: 'relative' }}>
      <div className="bl-card" style={{ overflow: 'hidden', padding: 0 }}>
        {/* faux video frame */}
        <div style={{ position: 'relative', aspectRatio: '16/10', background: 'var(--dark)' }}>
          {/* IDE-ish content */}
          <div style={{
            position: 'absolute', inset: 16,
            background: 'var(--dark-2)',
            border: '1px solid var(--line-dark)',
            borderRadius: 6,
            display: 'grid',
            gridTemplateRows: '24px 1fr',
          }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '0 10px', borderBottom: '1px solid var(--line-dark)' }}>
              <span style={{ width: 7, height: 7, borderRadius: '50%', background: '#ff5f57' }}></span>
              <span style={{ width: 7, height: 7, borderRadius: '50%', background: '#febc2e' }}></span>
              <span style={{ width: 7, height: 7, borderRadius: '50%', background: '#28c840' }}></span>
              <span className="bl-mono" style={{ fontSize: 9, color: 'var(--bone-mute)', marginLeft: 8 }}>
                {mod.slug}.jsx
              </span>
            </div>
            <pre className="bl-mono" style={{
              margin: 0, padding: 12, fontSize: 9, lineHeight: 1.55,
              color: 'var(--bone-dim)', overflow: 'hidden',
            }}>
{`// module ${mod.n} · ${mod.title.toLowerCase()}
import { Worker } from '@cloudflare/workers'
import { db }     from './d1'

export async function handler(req, env) {
  const user = await getUser(req, env)
  if (!user) return new Response('401', { status: 401 })
  ${mod.id === 'm3' ? '// stripe webhook idempotency' : mod.id === 'm4' ? '// claude — rate-limited' : '// 80 lines of real code'}
  const data = await db
    .prepare('SELECT * FROM users WHERE id = ?')
    .bind(user.id)
    .first()
  return Response.json(data)
}`}
            </pre>
          </div>

          {/* play button center */}
          <div style={{
            position: 'absolute', inset: 0, display: 'flex',
            alignItems: 'center', justifyContent: 'center',
          }}>
            <div style={{
              width: 56, height: 56, borderRadius: '50%',
              background: 'var(--accent)',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              boxShadow: '0 0 0 6px rgba(217,104,70,.18), 0 12px 32px -8px rgba(0,0,0,.4)',
            }}>
              <svg width="20" height="20" viewBox="0 0 24 24" fill="#fff"><path d="M8 5l11 7-11 7V5z"/></svg>
            </div>
          </div>

          {/* timecode + chip */}
          <div style={{
            position: 'absolute', left: 16, bottom: 16,
            display: 'flex', alignItems: 'center', gap: 8,
          }}>
            <span className="bl-mono" style={{ fontSize: 10, color: 'var(--bone-mute)', background: 'rgba(0,0,0,.5)', padding: '4px 8px', borderRadius: 4 }}>
              EP {mod.episodes[0].n} · 00:00 / {mod.episodes[0].dur}
            </span>
          </div>
        </div>

        <div style={{ padding: '16px 18px' }}>
          <div className="bl-mono" style={{ fontSize: 10, color: 'var(--ink-mute)', letterSpacing: '.06em', marginBottom: 8 }}>
            NOW PLAYING · MODULE {mod.n}
          </div>
          <div className="bl-serif" style={{ fontSize: 22, lineHeight: 1.15 }}>{mod.episodes[0].title}</div>
        </div>
      </div>
      <div className="bl-marker" style={{ bottom: -22, right: 4 }}>
        chapters · transcript · redacted regions
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────────
// Architecture diagram
// ────────────────────────────────────────────────────────────────

function Architecture() {
  return (
    <section id="arch" style={{ padding: '96px 56px', background: 'var(--dark)', color: 'var(--bone)', position: 'relative', overflow: 'hidden' }}>
      <div style={{
        position: 'absolute', top: -200, left: -200, width: 700, height: 700,
        background: 'radial-gradient(closest-side, rgba(217,104,70,.18), transparent 70%)',
      }}></div>
      <div style={{
        position: 'absolute', bottom: -250, right: -150, width: 700, height: 700,
        background: 'radial-gradient(closest-side, rgba(139,154,95,.10), transparent 70%)',
      }}></div>

      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1.4fr', gap: 72, alignItems: 'center', position: 'relative' }}>
        <div>
          <Eyebrow>Architecture</Eyebrow>
          <h2 className="bl-display" style={{ fontSize: 60, marginTop: 14, lineHeight: 1 }}>
            Nine boxes.<br/>
            <span className="bl-italic" style={{ color: 'var(--accent)' }}>Zero hand-waving.</span>
          </h2>
          <p style={{ marginTop: 22, fontSize: 17, lineHeight: 1.55, color: 'var(--bone-dim)', maxWidth: 460 }}>
            The whole stack fits on one page. We show every wire — what calls what, what
            persists where, which boxes you can swap, which you can't.
          </p>

          <div style={{ marginTop: 28, display: 'grid', gap: 10, maxWidth: 380 }}>
            {[
              ['Edge',    'Domain, Cloudflare DNS, WAF, CDN',           'var(--accent)'],
              ['Compute', 'Pages (Vite) + Workers (functions/api)',     'var(--amber)'],
              ['Data',    'D1 SQLite + R2 object storage',              'var(--sage)'],
              ['External','Stripe checkout · Claude API · Resend mail', 'var(--lavender)'],
            ].map((r, i) => (
              <div key={i} style={{ display: 'flex', gap: 14, alignItems: 'baseline' }}>
                <span style={{ width: 8, height: 8, borderRadius: '50%', background: r[2], marginTop: 2 }}></span>
                <div>
                  <div className="bl-mono" style={{ fontSize: 11, color: 'var(--bone)', letterSpacing: '.06em' }}>{r[0].toUpperCase()}</div>
                  <div style={{ fontSize: 13.5, color: 'var(--bone-dim)' }}>{r[1]}</div>
                </div>
              </div>
            ))}
          </div>
        </div>

        <ArchDiagram />
      </div>
    </section>
  );
}

function ArchDiagram() {
  // hand-positioned 4-col layout for clarity
  const nodes = D.arch;
  const edges = D.arch_edges;
  const byId = Object.fromEntries(nodes.map(n => [n.id, n]));
  const W = 880, H = 380;
  const nx = (n) => n.x + 60;
  const ny = (n) => n.y + 40;

  const kindColor = {
    edge:    'var(--accent)',
    compute: 'var(--amber)',
    data:    'var(--sage)',
    ext:     'var(--lavender)',
  };

  return (
    <div style={{ position: 'relative' }}>
      <CornerMarks />
      <div style={{
        background: 'var(--dark-2)',
        border: '1px solid var(--line-dark)',
        borderRadius: 'var(--r-md)',
        padding: 24,
        position: 'relative',
        overflow: 'hidden',
      }}>
        <svg viewBox={`0 0 ${W} ${H}`} width="100%" style={{ display: 'block' }}>
          <defs>
            <radialGradient id="pulse-grad" cx="0.5" cy="0.5" r="0.5">
              <stop offset="0%" stopColor="var(--accent-glow)" stopOpacity="1"/>
              <stop offset="100%" stopColor="var(--accent-glow)" stopOpacity="0"/>
            </radialGradient>
          </defs>

          {/* edges */}
          {edges.map(([a, b], i) => {
            const A = byId[a], B = byId[b];
            const x1 = nx(A) + 70, y1 = ny(A);
            const x2 = nx(B) - 70, y2 = ny(B);
            // smooth orthogonal-ish curve
            const midX = (x1 + x2) / 2;
            const d = `M ${x1} ${y1} C ${midX} ${y1}, ${midX} ${y2}, ${x2} ${y2}`;
            return (
              <g key={i}>
                <path d={d} stroke="var(--line-dark-2)" strokeWidth="1.2" fill="none"/>
                <circle r="3" fill="var(--accent-glow)">
                  <animateMotion dur={`${3 + (i * 0.4)}s`} repeatCount="indefinite" path={d} begin={`${i * 0.3}s`}/>
                  <animate attributeName="opacity" values="0;1;1;0" dur={`${3 + (i * 0.4)}s`} repeatCount="indefinite" begin={`${i * 0.3}s`}/>
                </circle>
              </g>
            );
          })}

          {/* nodes */}
          {nodes.map((n) => {
            const x = nx(n), y = ny(n);
            const col = kindColor[n.k];
            return (
              <g key={n.id} transform={`translate(${x - 70} ${y - 30})`}>
                <rect width="140" height="60" rx="8"
                  fill="var(--dark-3)" stroke={col} strokeOpacity="0.55" strokeWidth="1"/>
                <circle cx="14" cy="14" r="4" fill={col}/>
                <text x="26" y="18" fill="var(--bone)" fontSize="13" fontFamily="var(--sans)" fontWeight="500">{n.label}</text>
                <text x="14" y="42" fill="var(--bone-mute)" fontSize="10" fontFamily="var(--mono)">{n.sub}</text>
              </g>
            );
          })}
        </svg>

        {/* legend / status footer */}
        <div style={{
          display: 'flex', gap: 18, marginTop: 14, paddingTop: 14,
          borderTop: '1px solid var(--line-dark)',
        }}>
          <span className="bl-mono" style={{ fontSize: 10, color: 'var(--sage)' }}>● live · 1.4ms median worker</span>
          <span className="bl-mono" style={{ fontSize: 10, color: 'var(--bone-mute)' }}>uptime 99.99 · 30d</span>
          <span style={{ flex: 1 }}></span>
          <span className="bl-mono" style={{ fontSize: 10, color: 'var(--bone-mute)' }}>monthly bill · $0.00</span>
        </div>
      </div>

      <div className="bl-marker" style={{ bottom: -24, left: 4, color: 'var(--bone-mute)' }}>
        fig 02 · the reloadin5.com stack. animated packets are not decorative — they're the requests.
      </div>
    </div>
  );
}

// expose
Object.assign(window, {
  LandingNav: Nav, LandingHero: Hero, LandingMetrics: MetricsStrip,
  LandingStory: Story, LandingCurriculum: Curriculum, LandingArch: Architecture,
  LandingLogo: Logo, BLEyebrow: Eyebrow, BLCorners: CornerMarks,
  BLLock: LockBadge, BLPlay: PlayBadge,
});
// cf-cache-bust: 20260522-170707
