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

/* ============================================================
   Router (hash-based)
   ============================================================ */

function useHashRoute() {
  const [route, setRoute] = useState(() => parseHash(window.location.hash));
  useEffect(() => {
    const onHash = () => setRoute(parseHash(window.location.hash));
    window.addEventListener('hashchange', onHash);
    return () => window.removeEventListener('hashchange', onHash);
  }, []);
  return route;
}
function parseHash(h) {
  const path = (h || '').replace(/^#/, '') || '/';
  return path.startsWith('/') ? path : '/' + path;
}
function navigate(to) {
  window.location.hash = to;
  window.scrollTo({ top: 0, behavior: 'instant' });
}

/* Internal Link component — converts hrefs to hash routes for in-app paths */
function Link({ href, children, className, ...rest }) {
  const isInternal = href && href.startsWith('/');
  const onClick = (e) => {
    if (isInternal) {
      e.preventDefault();
      navigate(href);
    }
  };
  return (
    <a href={isInternal ? '#' + href : href}
       onClick={onClick}
       className={className}
       {...(isInternal ? {} : { target: '_blank', rel: 'noopener noreferrer' })}
       {...rest}>
      {children}
    </a>
  );
}

/* ============================================================
   Nav + Footer
   ============================================================ */

const NAV_ITEMS = [
  { href: '/market', label: 'Market' },
  { href: '/trust', label: 'Trust' },
  { href: '/agents', label: 'Agents' },
  { href: '/whitepaper', label: 'Whitepaper' },
  { href: '/about', label: 'About' },
];

function Nav({ route }) {
  return (
    <header className="nav">
      <div className="nav-inner">
        <Link href="/" className="brand" aria-label="BitID home">
          <IDGlyph size={26} className="brand-glyph" />
          <span className="brand-word"><span className="bw-bit">Bit</span><span className="bw-id">ID</span></span>
        </Link>
        <nav className="nav-links" aria-label="Primary">
          {NAV_ITEMS.map(item => (
            <Link key={item.href} href={item.href}
                  className={route === item.href ? 'is-active' : ''}>
              {item.label}
            </Link>
          ))}
        </nav>
        <Link href="/partners" className="nav-cta">Talk to the team</Link>
      </div>
    </header>
  );
}

function BlockHeight() {
  const [height, setHeight] = useState(null);
  useEffect(() => {
    let mounted = true;
    fetch('https://mempool.space/api/blocks/tip/height')
      .then(r => r.text())
      .then(t => { if (mounted) setHeight(parseInt(t, 10)); })
      .catch(() => {});
    return () => { mounted = false; };
  }, []);
  return (
    <span className="block-height">
      Block height · <span>{height ? height.toLocaleString() : '—'}</span>
    </span>
  );
}

function Footer() {
  return (
    <footer className="footer">
      <div className="footer-cols">
        <div>
          <Link href="/" className="footer-brand">
            <IDGlyph size={24} className="brand-glyph" />
            <span className="brand-word"><span className="bw-bit">Bit</span><span className="bw-id">ID</span></span>
          </Link>
          <p className="footer-tagline">The neutral identity layer for a machine-first world.</p>
        </div>
        <div className="footer-col">
          <h4>Product</h4>
          <ul>
            <li><Link href="/">Home</Link></li>
            <li><Link href="/market">Market</Link></li>
            <li><Link href="/trust">Trust</Link></li>
            <li><Link href="/agents">Agents</Link></li>
            <li><Link href="/whitepaper">Whitepaper</Link></li>
            <li><Link href="/roadmap">Roadmap</Link></li>
          </ul>
        </div>
        <div className="footer-col">
          <h4>Company</h4>
          <ul>
            <li><Link href="/about">About</Link></li>
            <li><Link href="/press">Press</Link></li>
            <li><Link href="/glossary">Glossary</Link></li>
            <li><Link href="/vs/pay-per-check-identity">vs Pay-per-check</Link></li>
            <li><Link href="/vs/closed-identity">vs Closed identity</Link></li>
          </ul>
        </div>
        <div className="footer-col">
          <h4>Legal</h4>
          <ul>
            <li><Link href="/legal/terms">Terms</Link></li>
            <li><Link href="/legal/privacy">Privacy</Link></li>
            <li><Link href="/legal/acceptable-use">Acceptable Use</Link></li>
            <li><a href="/security.txt">security.txt</a></li>
          </ul>
        </div>
      </div>
      <div className="footer-meta">
        <span className="anchor-line">
          <span className="anchor">Anchored on Bitcoin</span>
          {' · '}Issued by BitID · © 2026 BitID
        </span>
        <BlockHeight />
        <a className="footer-x" href="https://x.com/bitid_org" target="_blank" rel="noopener noreferrer" aria-label="BitID on X">
          <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M18.244 2H21.5l-7.5 8.563L23 22h-7.07l-5.53-7.156L4.13 22H.876l8.014-9.144L.5 2h7.21l4.99 6.514L18.244 2zm-2.475 18h2.012L7.32 4H5.166l10.604 16z"/></svg>
        </a>
      </div>
    </footer>
  );
}

/* ============================================================
   Bitcoin anchor mark (single, restrained)
   ============================================================ */

/* BitcoinMark — kept ONLY for the on-chain "anchored" indicator.
   For the brand mark (header/footer/cards/favicon), use <IDGlyph />. */
function BitcoinMark({ size = 16, color }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" aria-hidden="true">
      <circle cx="12" cy="12" r="11" fill={color || 'currentColor'} />
      <path d="M15.5 10.6c.2-1.5-.95-2.3-2.5-2.83l.5-2.04-1.24-.31-.5 1.99c-.32-.08-.66-.16-.99-.23l.5-2-1.24-.32-.5 2.04c-.27-.06-.54-.12-.8-.18v-.01l-1.71-.43-.33 1.32s.92.21.9.22c.5.13.6.46.58.73l-.58 2.32c.04.01.08.02.13.04-.04-.01-.08-.02-.13-.03l-.81 3.26c-.06.15-.22.38-.57.29.01.02-.9-.22-.9-.22l-.62 1.42 1.61.4c.3.08.59.15.88.23l-.5 2.06 1.24.31.5-2.04c.34.09.67.17.99.25l-.5 2.03 1.24.31.5-2.06c2.13.4 3.73.24 4.4-1.68.54-1.55-.03-2.45-1.15-3.03.82-.19 1.43-.73 1.6-1.84zm-2.85 4c-.39 1.55-3 .71-3.85.5l.66-2.66c.85.21 3.6.62 3.19 2.16zm.39-4.02c-.35 1.41-2.52.69-3.23.51l.6-2.41c.71.18 2.99.52 2.63 1.9z" fill="#0A0A0B"/>
    </svg>
  );
}

/* ============================================================
   IDGlyph — the BitID brand mark
   "ID" set in Bitcoin's typographic DNA: two thick vertical stems
   piercing two letterforms top + bottom, sharing a 13° italic shear.

   Geometry (1000-unit grid, per spec):
     cap height       = 700 units, vertical pad 150 / 150
     stem weight      = 168 units (24% of cap)
     stem overshoot   = 154 units (22% of cap) above & below
     letter spacing   = 64 units between I and D stems
     D bowl outer R   = 350 units, inner R = 182 units (wall = 168)
     italic shear     = -13° on a parent <g>
     bowl optical overshoot = 6 units past cap / baseline (stems do NOT)
   ============================================================ */

function IDGlyph({ size = 22, color, className, title = 'BitID' }) {
  /* Layout math, written once so the spec is auditable:
       grid 1000, cap top = 150, cap bottom = 850
       I stem:  x = 240..408   (width 168)
       gap:     408..472       (64 units)
       D stem:  x = 472..640   (width 168)
       D bowl:  centered on left-stem right edge (x=640), y centered between cap top and bottom (y=500)
                outer arc R=350, inner arc R=182, wall thickness = 168 (matches stems)
       Stem y: 150 - 154 = -4 ... 850 + 154 = 1004  (extends past cap & baseline)
       Bowl y: 150 - 6 = 144 ... 850 + 6 = 856      (only the optical overshoot)
  */
  const fill = color || 'currentColor';
  // Bowl path: starts at top of left stem (640, 144), arcs clockwise out to (640, 856),
  // then back inward via the inner ring to close. Compound path = outer half-ring minus inner.
  // Outer arc: vertical R = 356 so the bowl reaches cap-top -6 and baseline +6 (optical overshoot).
  // Inner arc: R = 182 → wall thickness = 174 (≈168 spec, refined for clean overshoot).
  // Center of both arcs at (640, 500).
  // Locked SVG geometry per spec: I + D in Bitcoin's typographic DNA.
  // I stem 280→448, D stem 540→708, both 168 wide, y 146→854 (708 tall).
  // D bowl: outer R=350, inner R=182, wall thickness 168, centered at (708, 500).
  // viewBox is 0 0 1100 1000 to fit the full bowl (x=708+350=1058) before the
  // skew transform shifts it further right.
  return (
    <svg
      width={size}
      height={size}
      viewBox="0 0 1100 1000"
      role="img"
      aria-label={title}
      className={className}
    >
      <title>{title}</title>
      <g transform="translate(550 500) skewX(-13) translate(-550 -500)" fill={fill}>
        <rect x="280" y="146" width="168" height="708" />
        <rect x="540" y="146" width="168" height="708" />
        <path d="M 708 150 A 350 350 0 0 1 708 850 L 708 682 A 182 182 0 0 0 708 318 Z" />
      </g>
    </svg>
  );
}

/* IDLockup — glyph + "BitID" wordmark, baseline aligned.
   Used in the nav header, footer, anywhere the brand spells itself out. */
function IDLockup({ size = 22, color, className }) {
  return (
    <span className={`id-lockup ${className || ''}`} aria-label="BitID">
      <IDGlyph size={size} color={color} />
      <span className="id-wordmark" aria-hidden="true">
        <span className="idw-bit">Bit</span><span className="idw-id">ID</span>
      </span>
    </span>
  );
}

/* ============================================================
   Credential Card (dark-glass Apple-Wallet pass, 3D rotation)
   ============================================================ */

function CredentialCard() {
  // Single-card legacy (kept for the consumer scene). The hero now uses CardFamily.
  return (
    <div className="cred-stage" aria-label="BitID credential card, anchored on Bitcoin, valid">
      <div className="cred-card">
        <div className="cred-head">
          <span>BitID · Pass</span>
          <span className="anchor-mark">
            <BitcoinMark size={12} />
            <span>BTC</span>
          </span>
        </div>
        <div>
          <div className="cred-tier-label">Tier</div>
          <div className="cred-tier">Anchored</div>
        </div>
        <dl className="cred-rows">
          <div><dt>Member</dt><dd>412 days</dd></div>
          <div><dt>Anchored</dt><dd>Bitcoin · L1</dd></div>
        </dl>
        <div className="cred-foot">
          <span className="cred-did">bid:••••••3f7a</span>
          <span className="cred-check"><span className="dot" aria-hidden="true"></span>Valid</span>
        </div>
      </div>
    </div>
  );
}

/* Mastercard mark — two interlocking circles */
function MastercardMark({ size = 64 }) {
  return (
    <svg width={size} height={size * 0.62} viewBox="0 0 64 40" aria-hidden="true" className="mc-mark">
      <circle cx="24" cy="20" r="18" fill="#EB001B" />
      <circle cx="40" cy="20" r="18" fill="#F79E1B" style={{ mixBlendMode: 'multiply' }} />
    </svg>
  );
}

function EMVChip({ silver }) {
  const grad = silver ? 'url(#chipS)' : 'url(#chipG)';
  return (
    <svg width="56" height="44" viewBox="0 0 56 44" aria-hidden="true" className="emv-chip">
      <defs>
        <linearGradient id="chipG" x1="0" y1="0" x2="1" y2="1">
          <stop offset="0%" stopColor="#C9A961" /><stop offset="50%" stopColor="#E8CC83" /><stop offset="100%" stopColor="#A88846" />
        </linearGradient>
        <linearGradient id="chipS" x1="0" y1="0" x2="1" y2="1">
          <stop offset="0%" stopColor="#B8B8B8" /><stop offset="50%" stopColor="#E0E0E0" /><stop offset="100%" stopColor="#909090" />
        </linearGradient>
      </defs>
      <rect x="0.5" y="0.5" width="55" height="43" rx="6" fill={grad} stroke="rgba(0,0,0,0.2)" />
      <line x1="4"  y1="10" x2="52" y2="10" stroke="rgba(0,0,0,0.35)" strokeWidth="1" />
      <line x1="4"  y1="22" x2="52" y2="22" stroke="rgba(0,0,0,0.35)" strokeWidth="1" />
      <line x1="4"  y1="34" x2="52" y2="34" stroke="rgba(0,0,0,0.35)" strokeWidth="1" />
      <line x1="4"  y1="16" x2="52" y2="16" stroke="rgba(0,0,0,0.2)"  strokeWidth="1" />
      <line x1="4"  y1="28" x2="52" y2="28" stroke="rgba(0,0,0,0.2)"  strokeWidth="1" />
      <line x1="28" y1="4"  x2="28" y2="40" stroke="rgba(0,0,0,0.3)"  strokeWidth="1" />
    </svg>
  );
}

function ContactlessGlyph({ color }) {
  return (
    <svg width="22" height="28" viewBox="0 0 22 28" aria-hidden="true" className="cl-glyph">
      <g fill="none" stroke={color} strokeWidth="1.5" strokeLinecap="round">
        <path d="M4 9 Q8 14 4 19" />
        <path d="M9 6 Q15 14 9 22" />
        <path d="M14 3 Q22 14 14 25" />
      </g>
    </svg>
  );
}

const STACK_TIERS = [
  { id: 'trusted',   label: 'TRUSTED',   bg: '#E8872C', fg: '#0A0A0B', expires: '12/31',         desc: 'Government ID + biometric · default for finance', silverChip: false, accent: '#E8872C' },
  { id: 'anchored',  label: 'ANCHORED',  bg: '#CFFF50', fg: '#0A0A0B', expires: 'ANCHORED',      desc: 'On-chain proof · auditable, permanent, public root', silverChip: false, accent: '#CFFF50' },
  { id: 'sovereign', label: 'SOVEREIGN', bg: '#FAFAF7', fg: '#0A0A0B', expires: 'SELF-CUSTODY',  desc: 'Self-custodied keys · power-user identity',         silverChip: true,  accent: '#FAFAF7' },
  { id: 'verified',  label: 'VERIFIED',  bg: '#1A1A1C', fg: '#FAFAF7', expires: '12/29',         desc: 'Email + device · baseline assurance',                silverChip: false, accent: '#FAFAF7' },
];

function StackCard({ tier, depth, dragX, isActive, idle }) {
  // depth: 0 = active, 1/2/3 = behind
  const ty = depth * -14;
  const sc = 1 - depth * 0.04;
  const op = [1, 0.7, 0.4, 0.2][depth];
  const rot = [0, -2, 2, -3][depth];
  const dragRot = isActive ? (dragX / 18) : 0;
  const transform = `translate3d(${isActive ? dragX : 0}px, ${ty}px, 0) scale(${sc}) rotate(${rot + dragRot}deg)`;
  return (
    <div
      className={`mc-card t-${tier.id} ${isActive ? 'is-active' : ''} ${isActive && idle ? 'is-idle' : ''}`}
      style={{
        transform,
        opacity: op,
        zIndex: 10 - depth,
        '--accent': tier.accent,
        background: tier.bg,
        color: tier.fg,
      }}
      aria-hidden={!isActive}
    >
      <div className={`mc-tex tex-${tier.id}`} aria-hidden="true"></div>
      <div className="mc-row mc-top">
        <span className="mc-brand">BitID</span>
        <span className="mc-tier-label">{tier.label}</span>
      </div>
      <div className="mc-mid">
        <EMVChip silver={tier.silverChip} />
        <ContactlessGlyph color={tier.fg} />
      </div>
      <div className="mc-number">5412&nbsp;&nbsp;••••&nbsp;&nbsp;••••&nbsp;&nbsp;3F7A</div>
      <div className="mc-bottom">
        <div className="mc-bot-l">
          <div className="mc-pair">
            <span className="k">CARDHOLDER</span>
            <span className="v">ALEX RAMS</span>
          </div>
          <div className="mc-pair">
            <span className="k">EXPIRES</span>
            <span className="v">{tier.expires}</span>
          </div>
        </div>
        <div className="mc-bot-r">
          <MastercardMark size={56} />
          <span className="mc-net">mastercard</span>
        </div>
      </div>
    </div>
  );
}

function BitIDCardStack() {
  const [active, setActive] = useState(0); // index into STACK_TIERS
  const [dragX, setDragX] = useState(0);
  const [animating, setAnimating] = useState(false);
  const [idle, setIdle] = useState(false);
  const idleTimer = useRef(null);
  const dragRef = useRef({ active: false, startX: 0, startY: 0, locked: null });
  const containerRef = useRef(null);

  const reduced = typeof window !== 'undefined' &&
    window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  const N = STACK_TIERS.length;
  const ordered = []; // depth 0..3 from active
  for (let i = 0; i < N; i++) ordered.push(STACK_TIERS[(active + i) % N]);

  const cycle = (dir = 1) => {
    if (animating) return;
    setAnimating(true);
    setActive(a => (a + dir + N) % N);
    setTimeout(() => { setDragX(0); setAnimating(false); }, reduced ? 160 : 360);
    bumpIdle();
  };

  const bumpIdle = () => {
    setIdle(false);
    if (idleTimer.current) clearTimeout(idleTimer.current);
    idleTimer.current = setTimeout(() => setIdle(true), 6000);
  };

  useEffect(() => { bumpIdle(); return () => clearTimeout(idleTimer.current); }, []);

  // pointer drag on active card
  const onPointerDown = (e) => {
    if (reduced || animating) return;
    dragRef.current = { active: true, startX: e.clientX, startY: e.clientY, locked: null };
    e.currentTarget.setPointerCapture(e.pointerId);
    bumpIdle();
  };
  const onPointerMove = (e) => {
    const d = dragRef.current;
    if (!d.active) return;
    const dx = e.clientX - d.startX;
    const dy = e.clientY - d.startY;
    if (d.locked === null && (Math.abs(dx) + Math.abs(dy)) > 6) {
      d.locked = Math.abs(dx) > Math.abs(dy) ? 'h' : 'v';
    }
    if (d.locked === 'h') setDragX(dx);
  };
  const onPointerUp = (e) => {
    const d = dragRef.current;
    if (!d.active) return;
    const dx = e.clientX - d.startX;
    d.active = false;
    if (Math.abs(dx) > 80) {
      // fling
      setAnimating(true);
      const fling = dx > 0 ? 420 : -420;
      setDragX(fling);
      setTimeout(() => {
        setActive(a => (a + (dx > 0 ? -1 : 1) + N) % N);
        setDragX(0);
        setAnimating(false);
      }, 320);
    } else {
      // snap back
      setDragX(0);
    }
    bumpIdle();
  };

  // keyboard
  const onKeyDown = (e) => {
    if (e.key === 'ArrowRight') { e.preventDefault(); cycle(1); }
    else if (e.key === 'ArrowLeft') { e.preventDefault(); cycle(-1); }
    else if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); cycle(1); }
  };

  const activeTier = STACK_TIERS[active];

  return (
    <div className="mc-stack-wrap">
      <div
        ref={containerRef}
        className={`mc-stack ${animating ? 'is-anim' : ''} ${dragX !== 0 ? 'is-drag' : ''}`}
        role="button"
        tabIndex={0}
        aria-label={`BitID credential stack — active: ${activeTier.label}. Click, swipe, or arrow to cycle.`}
        onClick={() => { if (!dragRef.current.locked) cycle(1); }}
        onPointerDown={onPointerDown}
        onPointerMove={onPointerMove}
        onPointerUp={onPointerUp}
        onPointerCancel={onPointerUp}
        onKeyDown={onKeyDown}
      >
        {ordered.map((t, depth) => (
          <StackCard
            key={t.id}
            tier={t}
            depth={depth}
            dragX={depth === 0 ? dragX : 0}
            isActive={depth === 0}
            idle={idle}
          />
        ))}
      </div>
      <div className="mc-dots" role="tablist" aria-label="Tier indicator">
        {STACK_TIERS.map((t, i) => (
          <button
            key={t.id}
            className={`mc-dot ${i === active ? 'is-active' : ''}`}
            style={{ background: t.bg }}
            onClick={(e) => { e.stopPropagation(); if (!animating) { setActive(i); bumpIdle(); } }}
            aria-selected={i === active}
            aria-label={`Show ${t.label}`}
            role="tab"
          />
        ))}
      </div>
      <div className="mc-meta">
        <span className="mc-meta-label">{activeTier.label}</span>
        <span className="mc-meta-desc">{activeTier.desc}</span>
      </div>
    </div>
  );
}

/* Backwards-compatible alias — the homepage imports CardFamily */
function CardFamily() { return <BitIDCardStack />; }

/* ============================================================
   Beem Card carousel
   ============================================================ */

function FakeQR() {
  // Deterministic abstract QR-like SVG (decorative)
  const cells = [];
  for (let y = 0; y < 21; y++) {
    for (let x = 0; x < 21; x++) {
      const v = (x * 7 + y * 11 + (x ^ y) * 3) % 5;
      if (v < 2) cells.push([x, y]);
    }
  }
  // finder squares (corners)
  const finder = (cx, cy) => (
    <g key={`f${cx}-${cy}`}>
      <rect x={cx} y={cy} width="7" height="7" fill="#0A0A0B" />
      <rect x={cx + 1} y={cy + 1} width="5" height="5" fill="#FAFAF7" />
      <rect x={cx + 2} y={cy + 2} width="3" height="3" fill="#0A0A0B" />
    </g>
  );
  return (
    <svg viewBox="0 0 21 21" shapeRendering="crispEdges" aria-hidden="true">
      <rect width="21" height="21" fill="#FAFAF7" />
      {cells.map(([x, y]) => <rect key={`${x}-${y}`} x={x} y={y} width="1" height="1" fill="#0A0A0B" />)}
      {finder(0, 0)}{finder(14, 0)}{finder(0, 14)}
    </svg>
  );
}

function BeemCardCarousel() {
  const [tierIdx, setTierIdx] = React.useState(1); // default Trusted (orange)
  const [flipped, setFlipped] = React.useState(false);
  const [tilt, setTilt] = React.useState({ x: 0, y: 0 });
  const cardRef = React.useRef(null);

  const reduced = typeof window !== 'undefined' &&
    window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  const TIERS = [
    { id: 'verified',  label: 'VERIFIED',  bg: '#1A1A1C', fg: '#FAFAF7', dark: true },
    { id: 'trusted',   label: 'TRUSTED',   bg: '#E8872C', fg: '#0A0A0B', dark: false },
    { id: 'anchored',  label: 'ANCHORED',  bg: '#CFFF50', fg: '#0A0A0B', dark: false },
    { id: 'sovereign', label: 'SOVEREIGN', bg: '#FAFAF7', fg: '#0A0A0B', dark: false },
  ];
  const tier = TIERS[tierIdx];

  const onMove = (e) => {
    if (reduced || !cardRef.current) return;
    const r = cardRef.current.getBoundingClientRect();
    const cx = (e.clientX - r.left) / r.width - 0.5;
    const cy = (e.clientY - r.top) / r.height - 0.5;
    setTilt({ x: -cy * 8, y: cx * 12 });
  };
  const onLeave = () => setTilt({ x: 0, y: 0 });

  const wrapperTransform = reduced
    ? 'none'
    : `rotateX(${tilt.x}deg) rotateY(${tilt.y}deg)`;

  return (
    <div className="beem-v2">
      {/* Tier selector */}
      <div className="beem-tiers" role="tablist" aria-label="Card tier">
        {TIERS.map((t, i) => (
          <button key={t.id}
                  className={`beem-tier-btn ${i === tierIdx ? 'is-active' : ''}`}
                  onClick={() => setTierIdx(i)}
                  role="tab"
                  aria-selected={i === tierIdx}>
            <span className="swatch" style={{ background: t.bg }} aria-hidden="true"></span>
            <span className="name">{t.label}</span>
          </button>
        ))}
      </div>

      <div className="beem-stage"
           ref={cardRef}
           onMouseMove={onMove}
           onMouseLeave={onLeave}
           onClick={() => setFlipped(f => !f)}>
        <div className={`beem-flip ${flipped ? 'is-flipped' : ''}`}
             style={{ transform: wrapperTransform }}>

          {/* FRONT */}
          <div className="beem-face beem-front-v2"
               style={{ '--bg': tier.bg, '--fg': tier.fg, background: tier.bg, color: tier.fg, borderColor: tier.dark ? 'rgba(255,255,255,0.08)' : 'rgba(0,0,0,0.08)' }}
               aria-hidden={flipped}>
            <div className="beem-grid-tex" aria-hidden="true"></div>
            <div className="beem-hairline" aria-hidden="true"></div>

            {/* Top band — payment */}
            <div className="beem-top">
              <div className="beem-top-l">
                <div className="micro">PAYMENT</div>
                <div className="holder">Akshay Krishnaiah</div>
              </div>
              <div className="beem-top-r">
                <div className="micro">NETWORK</div>
                <MastercardMark size={56} />
                <div className="net">mastercard</div>
              </div>
            </div>

            <div className="beem-num">5412&nbsp;&nbsp;····&nbsp;&nbsp;····&nbsp;&nbsp;3F7A</div>

            {/* Hinge — chip + contactless */}
            <div className="beem-hinge">
              <EMVChip silver={!tier.dark} />
              <ContactlessGlyph color={tier.fg} />
            </div>

            {/* Bottom band — identity */}
            <div className="beem-bot">
              <div className="beem-bot-l">
                <div className="micro">IDENTITY</div>
                <div className="bid">bid:••••••3F7A</div>
                <div className="kv"><span>ANCHOR</span><span>bitcoin · 891,204</span></div>
                <div className="kv"><span>TIER</span><span>{tier.label}</span></div>
              </div>
              <div className="beem-bot-r">
                <div className="micro">IDENTITY ROOT</div>
                <div className="id-glyph" aria-hidden="true">
                  <span className="i">I</span><span className="d">D</span>
                </div>
              </div>
            </div>

            <div className="beem-foot">
              <div className="dotted" aria-hidden="true"></div>
              <div className="foot-cap">TAP TO PAY · SHOW TO PROVE</div>
            </div>
          </div>

          {/* BACK */}
          <div className="beem-face beem-back-v2" aria-hidden={!flipped}>
            <div className="back-top">
              <div className="col"><span className="k">ISSUED</span><span className="v">2026-04-12</span></div>
              <div className="col"><span className="k">EXPIRES</span><span className="v">2027-04-12</span></div>
            </div>
            <div className="back-mid">
              <div className="scan">SCAN TO VERIFY</div>
              <div className="qr"><FakeQR /></div>
              <div className="handle">bid:••••••3F7A</div>
            </div>
            <div className="back-bot">
              <div className="anchor-line">ANCHORED ON BITCOIN · BLOCK 891,204 · MERKLE ROOT 0x4f…8c2a</div>
              <div className="id-glyph" aria-hidden="true"><span className="i">I</span><span className="d">D</span></div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

/* ============================================================
   Schematic — six-into-one collapse
   ============================================================ */

function SchemaCollapse() {
  const items = ['IDV', 'KYC', 'AML', 'Fraud', 'Chargeback', 'Liability'];
  return (
    <div className="schema-collapse">
      <ul className="schema-list">
        {items.map(i => <li key={i}>{i}</li>)}
      </ul>
      <div className="schema-arrow" aria-hidden="true">
        <svg viewBox="0 0 60 240" preserveAspectRatio="none">
          {items.map((_, idx) => {
            const y = 12 + idx * 39;
            return (
              <path key={idx}
                    d={`M 0 ${y} C 30 ${y}, 30 120, 60 120`}
                    stroke="#52525B" strokeWidth="1" fill="none" />
            );
          })}
          <circle cx="60" cy="120" r="3" fill="#E8872C" />
        </svg>
      </div>
      <div className="schema-out">
        <div className="api">bitid.verify()</div>
        <div className="anchor">
          <BitcoinMark size={10} />
          anchored
        </div>
      </div>
    </div>
  );
}

/* ============================================================
   Schematic — agent (split credential)
   ============================================================ */

function SchemaAgent() {
  return (
    <div className="schema-agent">
      <span className="revoke">
        <span className="dot" aria-hidden="true"></span>
        Revocation · active
      </span>
      <div className="pair">
        <div className="node">
          <div className="lbl">Human</div>
          <div>verified · BitID</div>
        </div>
        <div className="link"><span>delegated</span></div>
        <div className="node">
          <div className="lbl">Agent</div>
          <div>scoped · revocable</div>
        </div>
      </div>
    </div>
  );
}

/* ============================================================
   Forms
   ============================================================ */

function IntakeForm({ title, lead, fields, intent }) {
  const [submitted, setSubmitted] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const onSubmit = (e) => {
    e.preventDefault();
    setSubmitting(true);
    const payload = Object.fromEntries(new FormData(e.currentTarget).entries());
    payload.intent = intent;
    // POST /api/intake (stub) — we just log and succeed
    console.log('[/api/intake]', payload);
    setTimeout(() => { setSubmitting(false); setSubmitted(true); }, 600);
  };
  if (submitted) {
    return (
      <div className="form-card">
        <div className="form-success">
          <div className="checkmark" aria-hidden="true">✓</div>
          <h2 style={{ fontSize: 22, marginBottom: 8 }}>Got it.</h2>
          <p>We'll be in touch.</p>
        </div>
      </div>
    );
  }
  return (
    <form className="form-card" onSubmit={onSubmit} noValidate>
      <h1>{title}</h1>
      <p className="lead">{lead}</p>
      {fields.map(f => (
        <div className="field" key={f.name}>
          <label htmlFor={f.name}>{f.label}</label>
          {f.type === 'textarea'
            ? <textarea id={f.name} name={f.name} required={f.required !== false} placeholder={f.placeholder || ''} rows={4} />
            : <input id={f.name} name={f.name} type={f.type || 'text'}
                     required={f.required !== false} placeholder={f.placeholder || ''} />}
        </div>
      ))}
      <button type="submit" className="btn btn--primary" disabled={submitting} style={{ width: '100%', marginTop: 8 }}>
        {submitting ? 'Submitting…' : 'Request access'}
      </button>
      <p style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--fg-muted)', textAlign: 'center', marginTop: 16, marginBottom: 0 }}>
        Posts to /api/intake · No marketing email
      </p>
    </form>
  );
}

/* ============================================================
   JSON-LD injector (per-page schema)
   ============================================================ */

function PageSchema({ schema }) {
  useEffect(() => {
    const tag = document.createElement('script');
    tag.type = 'application/ld+json';
    tag.dataset.pageSchema = '1';
    tag.textContent = JSON.stringify(schema);
    document.head.appendChild(tag);
    return () => { document.head.removeChild(tag); };
  }, [JSON.stringify(schema)]);
  return null;
}

/* ============================================================
   Page hero
   ============================================================ */

function PageHero({ crumbs, title, lead }) {
  return (
    <section className="page-hero">
      <div className="container">
        {crumbs && (
          <nav className="breadcrumb" aria-label="Breadcrumb">
            {crumbs.map((c, i) => (
              <React.Fragment key={i}>
                {i > 0 && <span> / </span>}
                {c.href ? <Link href={c.href}>{c.label}</Link> : <span>{c.label}</span>}
              </React.Fragment>
            ))}
          </nav>
        )}
        <h1>{title}</h1>
        {lead && <p className="lead">{lead}</p>}
      </div>
    </section>
  );
}

Object.assign(window, {
  useHashRoute, navigate, Link,
  Nav, Footer, BlockHeight,
  BitcoinMark, IDGlyph, IDLockup, CredentialCard, CardFamily, BitIDCardStack, BeemCardCarousel, FakeQR,
  SchemaCollapse, SchemaAgent,
  IntakeForm, PageSchema, PageHero,
});
