// Mobile overlays + page tools — Find in page, Zoom, Page info, Clear data,
// Permission prompts, Sad tab, Voice search, Reader, Privacy review, Help.
// These render on top of the active screen (zIndex 70+).

// ─── Find in page (top sliding bar) ─────────────────────────────
function MFindInPage({ onClose }) {
  const [q, setQ] = React.useState('mesh');
  const current = 3, total = 12;
  return (
    <div style={{
      position: 'absolute', top: 0, left: 0, right: 0, zIndex: 92,
      background: M_SURFACE, borderBottom: '1px solid ' + M_BORDER,
      animation: 'mFindDown 200ms cubic-bezier(0.2,0.85,0.3,1)',
      paddingTop: 'env(safe-area-inset-top, 0)',
    }}>
      <style>{`@keyframes mFindDown{from{transform:translateY(-100%)}to{transform:translateY(0)}}`}</style>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '12px 12px' }}>
        <div style={{
          flex: 1, display: 'flex', alignItems: 'center', gap: 8,
          padding: '8px 12px', background: M_BG, border: '1px solid rgba(96,165,250,0.45)',
          borderRadius: 10, boxShadow: '0 0 0 3px rgba(96,165,250,0.10)',
        }}>
          <span style={{ color: M_ACCENT_B }}>{MIc.search({ s: 14 })}</span>
          <input value={q} onChange={(e) => setQ(e.target.value)} autoFocus placeholder="Find on page"
            style={{ flex: 1, background: 'transparent', border: 0, outline: 0, color: M_FG, fontSize: 13, fontFamily: 'inherit' }}/>
          <span style={{ fontSize: 10.5, color: M_FG_DIM, fontFamily: 'JetBrains Mono, monospace', flexShrink: 0 }}>
            {q ? <span style={{ color: M_FG_MUTED }}>{current} of {total}</span> : '0 of 0'}
          </span>
        </div>
        <button style={{ width: 32, height: 32, borderRadius: 8, background: M_BG, border: '1px solid ' + M_BORDER_SOFT, color: M_FG_MUTED, display: 'grid', placeItems: 'center', cursor: 'pointer' }}><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="m18 15-6-6-6 6"/></svg></button>
        <button style={{ width: 32, height: 32, borderRadius: 8, background: M_BG, border: '1px solid ' + M_BORDER_SOFT, color: M_FG_MUTED, display: 'grid', placeItems: 'center', cursor: 'pointer' }}><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="m6 9 6 6 6-6"/></svg></button>
        <button onClick={onClose} style={{ width: 32, height: 32, borderRadius: 8, background: 'transparent', border: 0, color: M_FG_MUTED, display: 'grid', placeItems: 'center', cursor: 'pointer' }}>{MIc.close({ s: 16 })}</button>
      </div>
      <div style={{ display: 'flex', gap: 8, padding: '0 12px 10px', overflowX: 'auto' }}>
        {[
          { l: 'Match case', on: false },
          { l: 'Whole word', on: false },
          { l: 'Regex', on: false },
        ].map(c => (
          <button key={c.l} style={{
            flexShrink: 0, padding: '5px 10px', borderRadius: 999,
            background: c.on ? 'rgba(96,165,250,0.18)' : 'transparent',
            border: '1px solid ' + M_BORDER_SOFT,
            color: c.on ? '#93C5FD' : M_FG_MUTED,
            fontSize: 10.5, fontWeight: 500, fontFamily: 'inherit', cursor: 'pointer',
          }}>{c.l}</button>
        ))}
      </div>
    </div>
  );
}

// ─── Zoom floating control ─────────────────────────────────────
function MZoomControl({ value = 100, onChange, onClose }) {
  const presets = [50, 75, 90, 100, 110, 125, 150, 200];
  return (
    <div onClick={onClose} style={{ position: 'absolute', inset: 0, zIndex: 88, background: 'rgba(0,0,0,0.45)', backdropFilter: 'blur(4px)' }}>
      <div onClick={(e) => e.stopPropagation()} style={{
        position: 'absolute', bottom: 96, left: 16, right: 16,
        background: M_SURFACE, border: '1px solid ' + M_BORDER, borderRadius: 14,
        padding: 16, animation: 'mZoomUp 200ms cubic-bezier(0.2,0.85,0.3,1)',
      }}>
        <style>{`@keyframes mZoomUp{from{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}`}</style>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 14 }}>
          <div style={{ fontSize: 10.5, color: M_FG_DIM, letterSpacing: '0.14em', textTransform: 'uppercase', fontWeight: 700, fontFamily: 'JetBrains Mono, monospace' }}>Page zoom</div>
          <button onClick={() => onChange && onChange(100)} style={{ fontSize: 10.5, color: M_ACCENT_B, background: 'transparent', border: 0, fontFamily: 'inherit', cursor: 'pointer', padding: 0 }}>Reset</button>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 16, marginBottom: 14 }}>
          <button onClick={() => onChange && onChange(Math.max(50, value - 10))} style={{ width: 40, height: 40, borderRadius: 10, background: M_BG, border: '1px solid ' + M_BORDER_SOFT, color: M_FG, display: 'grid', placeItems: 'center', cursor: 'pointer', fontSize: 18, fontFamily: 'Geist' }}>−</button>
          <div style={{ flex: 1, textAlign: 'center', fontSize: 30, fontWeight: 700, color: M_FG, fontFamily: 'Geist', letterSpacing: '-0.03em' }}>
            {value}<span style={{ fontSize: 16, color: M_FG_MUTED, fontWeight: 500 }}>%</span>
          </div>
          <button onClick={() => onChange && onChange(Math.min(300, value + 10))} style={{ width: 40, height: 40, borderRadius: 10, background: M_BG, border: '1px solid ' + M_BORDER_SOFT, color: M_FG, display: 'grid', placeItems: 'center', cursor: 'pointer', fontSize: 18, fontFamily: 'Geist' }}>+</button>
        </div>
        <div style={{ display: 'flex', gap: 5, flexWrap: 'wrap' }}>
          {presets.map(p => (
            <button key={p} onClick={() => onChange && onChange(p)} style={{
              flex: '1 0 calc(25% - 4px)', padding: '6px 0', borderRadius: 7,
              background: value === p ? M_FG : 'transparent',
              border: '1px solid ' + (value === p ? M_FG : M_BORDER_SOFT),
              color: value === p ? '#0B0C0F' : M_FG_MUTED,
              fontSize: 11, fontWeight: 600, cursor: 'pointer', fontFamily: 'JetBrains Mono, monospace',
            }}>{p}%</button>
          ))}
        </div>
      </div>
    </div>
  );
}

// ─── Page info bottom sheet ────────────────────────────────────
function MPageInfo({ url = 'linear.app/inbox', onClose }) {
  return (
    <>
      <div onClick={onClose} style={{ position: 'absolute', inset: 0, zIndex: 82, background: 'rgba(0,0,0,0.6)', backdropFilter: 'blur(6px)' }}/>
      <div style={{
        position: 'absolute', left: 0, right: 0, bottom: 0, zIndex: 83,
        background: 'var(--glass-strong)', backdropFilter: 'blur(var(--glass-blur)) saturate(1.5)', WebkitBackdropFilter: 'blur(var(--glass-blur)) saturate(1.5)', borderTop: '1px solid var(--glass-border)',
        borderRadius: '22px 22px 0 0', padding: '10px 14px 24px',
        animation: 'mPageInfoUp 240ms cubic-bezier(0.2,0.85,0.3,1)',
        color: M_FG, maxHeight: '85%', overflowY: 'auto',
      }}>
        <style>{`@keyframes mPageInfoUp{from{transform:translateY(100%)}to{transform:translateY(0)}}`}</style>
        <div style={{ width: 40, height: 4, borderRadius: 2, background: M_FG_DIM, margin: '4px auto 14px', opacity: 0.5 }}/>

        {/* Identity header */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 16 }}>
          <div style={{ width: 38, height: 38, borderRadius: 9, background: 'rgba(110,231,183,0.16)', color: '#6EE7B7', display: 'grid', placeItems: 'center', border: '1px solid rgba(110,231,183,0.32)' }}>
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 13.5, fontWeight: 600, color: M_FG, fontFamily: 'Geist', letterSpacing: '-0.01em' }}>Connection is secure</div>
            <div style={{ fontSize: 10.5, color: M_FG_DIM, fontFamily: 'JetBrains Mono, monospace', marginTop: 2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>https://{url}</div>
          </div>
        </div>

        {/* Trackers/cookies summary */}
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 8, marginBottom: 16 }}>
          {[
            { n: '12', l: 'Trackers blocked', c: '#6EE7B7' },
            { n: '4',  l: 'Cookies set',      c: '#FBBF24' },
            { n: '2',  l: 'Permissions',      c: '#A78BFA' },
          ].map(s => (
            <div key={s.l} style={{ padding: '10px 12px', background: M_BG, border: '1px solid ' + M_BORDER_SOFT, borderRadius: 10 }}>
              <div style={{ fontSize: 22, fontWeight: 700, color: s.c, fontFamily: 'Geist', letterSpacing: '-0.03em', lineHeight: 1 }}>{s.n}</div>
              <div style={{ fontSize: 9.5, color: M_FG_DIM, fontFamily: 'JetBrains Mono, monospace', marginTop: 4, letterSpacing: '0.04em' }}>{s.l}</div>
            </div>
          ))}
        </div>

        <div style={{ fontSize: 10, fontWeight: 700, color: M_FG_DIM, letterSpacing: '0.14em', textTransform: 'uppercase', fontFamily: 'JetBrains Mono, monospace', padding: '0 4px 6px' }}>Permissions</div>
        <div style={{ background: M_BG, border: '1px solid ' + M_BORDER_SOFT, borderRadius: 12, overflow: 'hidden', marginBottom: 14 }}>
          {[
            { l: 'Notifications', v: 'Allow' },
            { l: 'Camera',        v: 'Ask'   },
            { l: 'Microphone',    v: 'Ask'   },
            { l: 'Location',      v: 'Block' },
            { l: 'Clipboard',     v: 'Block' },
          ].map((p, i) => (
            <div key={p.l} style={{ display: 'flex', alignItems: 'center', padding: '10px 12px', borderTop: i === 0 ? 0 : '1px solid ' + M_BORDER_SOFT }}>
              <span style={{ flex: 1, fontSize: 12.5, color: M_FG, fontFamily: 'Geist' }}>{p.l}</span>
              <span style={{
                fontSize: 10, padding: '3px 8px', borderRadius: 999, fontWeight: 600,
                background: p.v === 'Allow' ? 'rgba(110,231,183,0.10)' : p.v === 'Block' ? 'rgba(248,113,113,0.10)' : 'var(--m-tint)',
                color:      p.v === 'Allow' ? '#6EE7B7'                : p.v === 'Block' ? '#F87171'                : M_FG_MUTED,
                fontFamily: 'JetBrains Mono, monospace', letterSpacing: '0.05em',
              }}>{p.v.toUpperCase()}</span>
            </div>
          ))}
        </div>

        <div style={{ fontSize: 10, fontWeight: 700, color: M_FG_DIM, letterSpacing: '0.14em', textTransform: 'uppercase', fontFamily: 'JetBrains Mono, monospace', padding: '0 4px 6px' }}>Certificate</div>
        <div style={{ padding: '10px 12px', background: M_BG, border: '1px solid ' + M_BORDER_SOFT, borderRadius: 12, marginBottom: 14 }}>
          <div style={{ fontSize: 11.5, color: M_FG, fontFamily: 'JetBrains Mono, monospace', lineHeight: 1.6 }}>
            <div>Issuer: Cloudflare Inc. ECC CA-3</div>
            <div>Valid until: Aug 14, 2026</div>
            <div>Cipher: TLS_AES_256_GCM_SHA384</div>
          </div>
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
          <button style={{ padding: '11px 0', borderRadius: 10, background: M_BG, border: '1px solid ' + M_BORDER_SOFT, color: M_FG, fontSize: 12.5, fontWeight: 500, fontFamily: 'inherit', cursor: 'pointer' }}>Storage…</button>
          <button style={{ padding: '11px 0', borderRadius: 10, background: 'rgba(248,113,113,0.10)', border: '1px solid rgba(248,113,113,0.28)', color: '#F87171', fontSize: 12.5, fontWeight: 500, fontFamily: 'inherit', cursor: 'pointer' }}>Reset permissions</button>
        </div>
      </div>
    </>
  );
}

// ─── Clear browsing data sheet ─────────────────────────────────
function MClearDataSheet({ onClose }) {
  const [range, setRange] = React.useState('hour');
  const [picked, setPicked] = React.useState({ history: true, cookies: true, cache: true, downloads: false, forms: false, passwords: false });
  const opts = [
    { id: 'history',   label: 'History',          size: '47 entries today', icon: <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><path d="M3 12a9 9 0 1 0 3-6.7"/><path d="M3 3v6h6"/><path d="M12 7v5l3 2"/></svg> },
    { id: 'cookies',   label: 'Cookies & site data', size: '142 sites · 8.4 MB', icon: <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><path d="M12 22a10 10 0 1 1 0-20c0 2 2 4 4 4s2 2 2 4 2 4 4 4a10 10 0 0 1-10 8z"/></svg> },
    { id: 'cache',     label: 'Cached files',     size: '184 MB',           icon: <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><ellipse cx="12" cy="6" rx="9" ry="3"/><path d="M3 6v12c0 1.7 4 3 9 3s9-1.3 9-3V6"/></svg> },
    { id: 'downloads', label: 'Downloads',        size: 'List only · keeps files', icon: <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><path d="M12 3v12M6 11l6 6 6-6M5 21h14"/></svg> },
    { id: 'forms',     label: 'Autofill form data', size: '38 entries',      icon: <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="4" width="18" height="16" rx="2"/><path d="M7 9h10M7 13h7"/></svg> },
    { id: 'passwords', label: 'Saved passwords',  size: '128 saved · synced', icon: <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="11" width="18" height="10" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg> },
  ];
  const ranges = [
    { id: 'hour',  label: 'Last hour' },
    { id: 'day',   label: 'Last 24 hours' },
    { id: 'week',  label: 'Last 7 days' },
    { id: 'month', label: 'Last 4 weeks' },
    { id: 'all',   label: 'All time' },
  ];
  return (
    <>
      <div onClick={onClose} style={{ position: 'absolute', inset: 0, zIndex: 82, background: 'rgba(0,0,0,0.62)', backdropFilter: 'blur(6px)' }}/>
      <div style={{
        position: 'absolute', left: 0, right: 0, bottom: 0, zIndex: 83,
        background: 'var(--glass-strong)', backdropFilter: 'blur(var(--glass-blur)) saturate(1.5)', WebkitBackdropFilter: 'blur(var(--glass-blur)) saturate(1.5)', borderTop: '1px solid var(--glass-border)',
        borderRadius: '22px 22px 0 0', padding: '10px 14px 22px',
        animation: 'mClearUp 240ms cubic-bezier(0.2,0.85,0.3,1)',
        color: M_FG, maxHeight: '85%', overflowY: 'auto',
      }}>
        <style>{`@keyframes mClearUp{from{transform:translateY(100%)}to{transform:translateY(0)}}`}</style>
        <div style={{ width: 40, height: 4, borderRadius: 2, background: M_FG_DIM, margin: '4px auto 14px', opacity: 0.5 }}/>

        <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 16 }}>
          <div style={{ width: 32, height: 32, borderRadius: 9, background: 'rgba(248,113,113,0.14)', color: '#F87171', display: 'grid', placeItems: 'center' }}>
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M3 6h18M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>
          </div>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 16, fontWeight: 700, color: M_FG, fontFamily: 'Geist', letterSpacing: '-0.02em' }}>Clear browsing data</div>
            <div style={{ fontSize: 10.5, color: M_FG_MUTED, marginTop: 2 }}>Only on this device. Synced data stays on your other devices.</div>
          </div>
        </div>

        <div style={{ fontSize: 10, fontWeight: 700, color: M_FG_DIM, letterSpacing: '0.14em', textTransform: 'uppercase', fontFamily: 'JetBrains Mono, monospace', padding: '0 4px 8px' }}>Time range</div>
        <div style={{ display: 'flex', gap: 5, marginBottom: 14, overflowX: 'auto', paddingBottom: 2 }}>
          {ranges.map(r => (
            <button key={r.id} onClick={() => setRange(r.id)} style={{
              flexShrink: 0, padding: '7px 11px', borderRadius: 999,
              background: range === r.id ? M_FG : 'transparent',
              border: '1px solid ' + (range === r.id ? M_FG : M_BORDER_SOFT),
              color: range === r.id ? '#0B0C0F' : M_FG_MUTED,
              fontSize: 11.5, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit', whiteSpace: 'nowrap',
            }}>{r.label}</button>
          ))}
        </div>

        <div style={{ fontSize: 10, fontWeight: 700, color: M_FG_DIM, letterSpacing: '0.14em', textTransform: 'uppercase', fontFamily: 'JetBrains Mono, monospace', padding: '0 4px 8px' }}>What to clear</div>
        <div style={{ background: M_BG, border: '1px solid ' + M_BORDER_SOFT, borderRadius: 12, overflow: 'hidden', marginBottom: 16 }}>
          {opts.map((o, i) => (
            <div key={o.id} onClick={() => setPicked(p => ({ ...p, [o.id]: !p[o.id] }))} style={{
              display: 'flex', alignItems: 'center', gap: 11, padding: '11px 12px',
              borderTop: i === 0 ? 0 : '1px solid ' + M_BORDER_SOFT, cursor: 'pointer',
            }}>
              <span style={{ color: picked[o.id] ? M_FG : M_FG_DIM }}>{o.icon}</span>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 12.5, color: M_FG, fontFamily: 'Geist', fontWeight: 500 }}>{o.label}</div>
                <div style={{ fontSize: 10, color: M_FG_DIM, fontFamily: 'JetBrains Mono, monospace', marginTop: 2 }}>{o.size}</div>
              </div>
              <div style={{
                width: 20, height: 20, borderRadius: 5,
                background: picked[o.id] ? M_FG : 'transparent',
                border: '1.5px solid ' + (picked[o.id] ? M_FG : M_BORDER),
                display: 'grid', placeItems: 'center',
              }}>
                {picked[o.id] && <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="#0B0C0F" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><path d="M20 6 9 17l-5-5"/></svg>}
              </div>
            </div>
          ))}
        </div>

        <div style={{ display: 'flex', gap: 8 }}>
          <button onClick={onClose} style={{ flex: 1, padding: '12px 0', borderRadius: 10, background: M_BG, border: '1px solid ' + M_BORDER_SOFT, color: M_FG, fontSize: 13, fontWeight: 500, fontFamily: 'inherit', cursor: 'pointer' }}>Cancel</button>
          <button onClick={onClose} style={{ flex: 1, padding: '12px 0', borderRadius: 10, background: '#F87171', border: 0, color: '#0B0C0F', fontSize: 13, fontWeight: 600, fontFamily: 'inherit', cursor: 'pointer' }}>Clear data</button>
        </div>
      </div>
    </>
  );
}

// ─── Permission prompt (inline banner from top) ────────────────
function MPermissionPrompt({ type = 'camera', site = 'meet.google.com', onResolve }) {
  const meta = {
    camera:   { label: 'use your camera',    icon: <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M3 7h4l2-3h6l2 3h4v12H3z"/><circle cx="12" cy="13" r="4"/></svg>, color: '#F472B6' },
    mic:      { label: 'use your microphone',icon: <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><rect x="9" y="3" width="6" height="12" rx="3"/><path d="M5 11a7 7 0 0 0 14 0M12 18v3"/></svg>, color: '#22D3EE' },
    location: { label: 'know your location', icon: <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M12 22s8-8 8-13a8 8 0 1 0-16 0c0 5 8 13 8 13z"/><circle cx="12" cy="9" r="3"/></svg>, color: '#FBBF24' },
    notif:    { label: 'send notifications', icon: <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M6 8a6 6 0 1 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10 21a2 2 0 0 0 4 0"/></svg>, color: '#A78BFA' },
  }[type] || { label: 'access', icon: null, color: M_FG_MUTED };
  return (
    <div style={{
      position: 'absolute', top: 12, left: 12, right: 12, zIndex: 95,
      background: M_SURFACE, border: '1px solid ' + meta.color + '38',
      borderRadius: 14, padding: 14,
      boxShadow: '0 8px 22px rgba(0,0,0,0.45), 0 0 0 3px ' + meta.color + '14',
      animation: 'mPermDown 220ms cubic-bezier(0.2,0.85,0.3,1)',
    }}>
      <style>{`@keyframes mPermDown{from{transform:translateY(-110%);opacity:0}to{transform:translateY(0);opacity:1}}`}</style>
      <div style={{ display: 'flex', alignItems: 'center', gap: 11, marginBottom: 12 }}>
        <div style={{ width: 32, height: 32, borderRadius: 9, background: meta.color + '22', color: meta.color, display: 'grid', placeItems: 'center', flexShrink: 0 }}>{meta.icon}</div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 13, fontWeight: 600, color: M_FG, fontFamily: 'Geist', letterSpacing: '-0.01em' }}>
            <span style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 12, color: M_FG_MUTED }}>{site}</span>
          </div>
          <div style={{ fontSize: 12.5, color: M_FG, marginTop: 2, lineHeight: 1.4 }}>wants to {meta.label}.</div>
        </div>
      </div>
      <div style={{ display: 'flex', gap: 6, marginBottom: 10 }}>
        <button onClick={() => onResolve && onResolve('block')}    style={{ flex: 1, padding: '9px 0', borderRadius: 9, background: M_BG, border: '1px solid ' + M_BORDER_SOFT, color: M_FG_MUTED, fontSize: 12, fontWeight: 600, fontFamily: 'inherit', cursor: 'pointer' }}>Block</button>
        <button onClick={() => onResolve && onResolve('once')}     style={{ flex: 1, padding: '9px 0', borderRadius: 9, background: M_BG, border: '1px solid ' + M_BORDER_SOFT, color: M_FG, fontSize: 12, fontWeight: 600, fontFamily: 'inherit', cursor: 'pointer' }}>This time</button>
        <button onClick={() => onResolve && onResolve('always')}   style={{ flex: 1, padding: '9px 0', borderRadius: 9, background: meta.color, border: 0, color: '#0B0C0F', fontSize: 12, fontWeight: 700, fontFamily: 'inherit', cursor: 'pointer' }}>Allow</button>
      </div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 10.5, color: M_FG_DIM, fontFamily: 'JetBrains Mono, monospace' }}>
        <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
        <span>Choice is stored on this device only. Sites you allow stay allowed.</span>
      </div>
    </div>
  );
}

// ─── Sad tab (error screen) ────────────────────────────────────
function MSadTab({ kind = 'offline', url = 'linear.app/inbox', onClose }) {
  const cases = {
    offline:  { title: "You're offline",          sub: "We couldn't reach this page. Try the mesh — a peer might have it cached.", icon: '⛅', detail: 'ERR_INTERNET_DISCONNECTED', primary: 'Try mesh', secondary: 'Reload' },
    dns:      { title: "We can't find that site", sub: "The domain didn't resolve. Check the spelling or your DNS provider.",     icon: '🔎', detail: 'ERR_NAME_NOT_RESOLVED',     primary: 'Reload',    secondary: 'Search instead' },
    cert:     { title: "This connection isn't private", sub: "The site's certificate doesn't check out. Don't enter sensitive info.", icon: '⚠️', detail: 'NET::ERR_CERT_AUTHORITY_INVALID', primary: 'Go back',   secondary: 'Show details' },
    crash:    { title: "This tab crashed",        sub: "Something went wrong rendering this page. Reload to try again.",            icon: '💥', detail: 'STATUS_ACCESS_VIOLATION',   primary: 'Reload',    secondary: 'Send report' },
  }[kind];
  return (
    <div style={{
      position: 'absolute', inset: 0, zIndex: 84,
      background: M_BG, display: 'flex', flexDirection: 'column', padding: '40px 24px 24px',
      color: M_FG,
    }}>
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', textAlign: 'center', maxWidth: 320, margin: '0 auto' }}>
        <div style={{ fontSize: 60, marginBottom: 18, opacity: 0.85 }}>{cases.icon}</div>
        <div style={{ fontSize: 22, fontWeight: 700, fontFamily: 'Geist', letterSpacing: '-0.025em', marginBottom: 10 }}>{cases.title}</div>
        <div style={{ fontSize: 13, color: M_FG_MUTED, lineHeight: 1.5, marginBottom: 22 }}>{cases.sub}</div>
        <div style={{ padding: '10px 14px', background: M_SURFACE, border: '1px solid ' + M_BORDER_SOFT, borderRadius: 10, marginBottom: 26, fontFamily: 'JetBrains Mono, monospace' }}>
          <div style={{ fontSize: 10, color: M_FG_DIM, letterSpacing: '0.12em', textTransform: 'uppercase', fontWeight: 700, marginBottom: 4 }}>Tried to load</div>
          <div style={{ fontSize: 11, color: M_FG, marginBottom: 6, wordBreak: 'break-all' }}>{url}</div>
          <div style={{ fontSize: 10, color: M_FG_DIM }}>{cases.detail}</div>
        </div>
        <div style={{ display: 'flex', gap: 8, width: '100%', maxWidth: 280 }}>
          <button onClick={onClose} style={{ flex: 1, padding: '11px 0', borderRadius: 10, background: M_SURFACE, border: '1px solid ' + M_BORDER_SOFT, color: M_FG, fontSize: 12.5, fontWeight: 500, fontFamily: 'inherit', cursor: 'pointer' }}>{cases.secondary}</button>
          <button onClick={onClose} style={{ flex: 1, padding: '11px 0', borderRadius: 10, background: M_FG, border: 0, color: '#0B0C0F', fontSize: 12.5, fontWeight: 600, fontFamily: 'inherit', cursor: 'pointer' }}>{cases.primary}</button>
        </div>
      </div>
    </div>
  );
}

// ─── Voice search overlay ──────────────────────────────────────
function MVoiceSearch({ onClose, onCommit }) {
  const [phase, setPhase] = React.useState('listening');
  const [transcript, setTranscript] = React.useState('search for distributed protocols');
  React.useEffect(() => {
    const t1 = setTimeout(() => setPhase('heard'), 1800);
    return () => clearTimeout(t1);
  }, []);
  return (
    <div style={{
      position: 'absolute', inset: 0, zIndex: 96,
      background: 'radial-gradient(ellipse at 50% 60%, rgba(96,165,250,0.18), transparent 70%), ' + M_BG,
      display: 'flex', flexDirection: 'column',
      padding: '50px 24px 24px',
      color: M_FG, animation: 'mVoiceIn 220ms ease-out',
    }}>
      <style>{`@keyframes mVoiceIn{from{opacity:0}to{opacity:1}}
        @keyframes mPulse{0%,100%{transform:scale(1);opacity:0.8}50%{transform:scale(1.18);opacity:1}}
        @keyframes mPulse2{0%,100%{transform:scale(1);opacity:0.45}50%{transform:scale(1.32);opacity:0.7}}
      `}</style>

      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 32 }}>
        <button onClick={onClose} aria-label="Cancel" style={{ width: 36, height: 36, borderRadius: 10, background: M_SURFACE, border: '1px solid ' + M_BORDER_SOFT, color: M_FG_MUTED, display: 'grid', placeItems: 'center', cursor: 'pointer' }}>{MIc.close({ s: 16 })}</button>
        <div style={{ fontSize: 10.5, color: M_FG_DIM, fontFamily: 'JetBrains Mono, monospace', letterSpacing: '0.1em', textTransform: 'uppercase', fontWeight: 700 }}>{phase === 'listening' ? 'Listening' : 'Heard'}</div>
      </div>

      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }}>
        <div style={{ position: 'relative', width: 130, height: 130, marginBottom: 36 }}>
          <div style={{ position: 'absolute', inset: -16, borderRadius: '50%', background: 'radial-gradient(circle, rgba(96,165,250,0.32), transparent 70%)', animation: 'mPulse2 1.6s ease-in-out infinite' }}/>
          <div style={{ position: 'absolute', inset: 0, borderRadius: '50%', background: 'linear-gradient(135deg,#6EE7B7,#60A5FA)', display: 'grid', placeItems: 'center', animation: 'mPulse 1.6s ease-in-out infinite', boxShadow: '0 12px 30px rgba(96,165,250,0.32)' }}>
            <svg width="42" height="42" viewBox="0 0 24 24" fill="none" stroke="#0B0C0F" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="9" y="3" width="6" height="12" rx="3"/><path d="M5 11a7 7 0 0 0 14 0M12 18v3M9 21h6"/></svg>
          </div>
        </div>
        <div style={{ fontSize: 22, fontWeight: 600, color: M_FG, fontFamily: 'Geist', letterSpacing: '-0.025em', textAlign: 'center', lineHeight: 1.3, marginBottom: 6 }}>
          {phase === 'listening' ? <span style={{ color: M_FG_MUTED }}>I'm listening…</span> : '"' + transcript + '"'}
        </div>
        {phase === 'heard' && <div style={{ fontSize: 11.5, color: M_FG_DIM, fontFamily: 'JetBrains Mono, monospace' }}>Tap to use, or speak again</div>}
      </div>

      <div style={{ display: 'flex', gap: 8 }}>
        <button style={{ width: 44, height: 44, borderRadius: 10, background: M_SURFACE, border: '1px solid ' + M_BORDER_SOFT, color: M_FG_MUTED, display: 'grid', placeItems: 'center', cursor: 'pointer' }} title="Languages">
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3c3 3 3 15 0 18M12 3c-3 3-3 15 0 18"/></svg>
        </button>
        <button onClick={() => onCommit && onCommit(transcript)} disabled={phase !== 'heard'} style={{
          flex: 1, padding: '13px 0', borderRadius: 10,
          background: phase === 'heard' ? M_FG : 'var(--m-tint)', border: 0,
          color: phase === 'heard' ? '#0B0C0F' : M_FG_DIM,
          fontSize: 13, fontWeight: 700, fontFamily: 'inherit', cursor: phase === 'heard' ? 'pointer' : 'default',
        }}>Use this</button>
      </div>
    </div>
  );
}

// ─── Reader render ─────────────────────────────────────────────
function MReader({ onClose }) {
  const [theme, setTheme] = React.useState('dark');     // dark / sepia / light
  const [size, setSize] = React.useState(2);            // 0..4
  const [font, setFont] = React.useState('serif');      // serif / sans / mono
  const sizes = [13, 14.5, 16, 18, 20];
  const themes = {
    dark:  { bg: '#0F1115', text: '#E5E7EB', mute: '#9CA3AF', border: 'var(--m-tint)' },
    sepia: { bg: '#F4ECDC', text: '#3F2D1B', mute: '#6B4F33', border: 'rgba(63,45,27,0.16)' },
    light: { bg: '#FFFFFF', text: '#111827', mute: '#6B7280', border: 'rgba(0,0,0,0.08)' },
  }[theme];
  const fontFamily = font === 'serif' ? "'Iowan Old Style', Georgia, serif"
                  : font === 'mono'  ? "'JetBrains Mono', monospace"
                  : "Geist, -apple-system, sans-serif";

  return (
    <div style={{
      position: 'absolute', inset: 0, zIndex: 85,
      background: themes.bg, color: themes.text,
      display: 'flex', flexDirection: 'column',
      animation: 'mReaderIn 220ms ease-out',
    }}>
      <style>{`@keyframes mReaderIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}`}</style>

      {/* Top bar */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '14px 14px 10px', borderBottom: '1px solid ' + themes.border }}>
        <button onClick={onClose} aria-label="Exit reader" style={{ width: 32, height: 32, borderRadius: 8, background: 'transparent', border: '1px solid ' + themes.border, color: themes.text, display: 'grid', placeItems: 'center', cursor: 'pointer' }}>
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M19 12H5M12 19l-7-7 7-7"/></svg>
        </button>
        <div style={{ flex: 1, fontSize: 10.5, color: themes.mute, fontFamily: 'JetBrains Mono, monospace', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>engineering.ajna.dev / mesh</div>
        <button style={{ padding: '6px 10px', borderRadius: 8, background: 'transparent', border: '1px solid ' + themes.border, color: themes.text, fontSize: 11, fontWeight: 600, fontFamily: 'inherit', cursor: 'pointer' }}>Aa</button>
      </div>

      {/* Article */}
      <div style={{ flex: 1, overflowY: 'auto', padding: '24px 24px 80px', maxWidth: 600, margin: '0 auto', width: '100%', boxSizing: 'border-box' }}>
        <div style={{ fontSize: 10.5, color: themes.mute, fontFamily: 'JetBrains Mono, monospace', letterSpacing: '0.1em', textTransform: 'uppercase', fontWeight: 700, marginBottom: 12 }}>Ajna Engineering · 18 min read</div>
        <h1 style={{ fontFamily, fontWeight: 700, fontSize: 30, lineHeight: 1.15, letterSpacing: '-0.025em', margin: '0 0 16px' }}>
          Engineering an offline-first mesh
        </h1>
        <div style={{ fontSize: 13, color: themes.mute, marginBottom: 26 }}>By Maya Chen · May 12, 2026</div>

        <div style={{ fontFamily, fontSize: sizes[size], lineHeight: 1.65 }}>
          <p style={{ margin: '0 0 18px' }}>The first time we shipped Ajna's mesh, three iPhones in a coffee shop in Berlin discovered each other in 380ms and finished a 4MB exchange before the espresso landed. The second time, in a hotel basement with no internet, it just worked. That second moment is the one we kept chasing.</p>
          <p style={{ margin: '0 0 18px' }}>Going from five devices in a lab to five thousand in the wild took eighteen months and three protocol revisions. Along the way we threw out two transports, learned that BLE is not a Wi-Fi replacement (it's a different animal entirely), and discovered that the hardest part of a peer network isn't the peers — it's recovering gracefully when half of them disappear at once.</p>
          <h2 style={{ fontFamily, fontWeight: 700, fontSize: sizes[size] * 1.4, lineHeight: 1.25, letterSpacing: '-0.02em', margin: '30px 0 14px' }}>Why offline-first, why now</h2>
          <p style={{ margin: '0 0 18px' }}>The web spent twenty years assuming a stable connection. Most of those years, that assumption held — in cities. The rest of the time, especially on the move, we ran into the same wall: latency, captive portals, rate limits, paywalls, deplatforming. Mesh networks have always offered an alternative, but the bandwidth used to be too low and the discovery too painful.</p>
          <p style={{ margin: '0 0 18px' }}>Two things changed. Bluetooth 5.4 made device-to-device throughput practical (we're seeing 600KB/s sustained on iPhone 14+), and DIDComm v2 gave us a clean identity primitive that doesn't require a server. With both in hand, it became cheaper to ship a mesh than to keep building around its absence.</p>
        </div>
      </div>

      {/* Bottom toolbar — typography controls */}
      <div style={{ padding: '10px 14px 16px', borderTop: '1px solid ' + themes.border, background: themes.bg }}>
        <div style={{ display: 'flex', gap: 8 }}>
          {/* Theme */}
          <div style={{ display: 'flex', gap: 4, padding: 3, background: theme === 'dark' ? 'var(--m-tint)' : 'rgba(0,0,0,0.05)', borderRadius: 10 }}>
            {['dark', 'sepia', 'light'].map(t => (
              <button key={t} onClick={() => setTheme(t)} style={{
                width: 30, height: 30, borderRadius: 7,
                background: t === 'dark' ? '#0F1115' : t === 'sepia' ? '#F4ECDC' : '#FFFFFF',
                border: theme === t ? '2px solid ' + (theme === 'dark' ? '#fff' : '#111827') : '1px solid ' + themes.border,
                padding: 0, cursor: 'pointer',
              }}/>
            ))}
          </div>
          {/* Font */}
          <div style={{ display: 'flex', gap: 4, padding: 3, background: theme === 'dark' ? 'var(--m-tint)' : 'rgba(0,0,0,0.05)', borderRadius: 10, flex: 1 }}>
            {[
              { id: 'serif', label: 'Aa', f: "Georgia, serif" },
              { id: 'sans',  label: 'Aa', f: "Geist, sans-serif" },
              { id: 'mono',  label: 'Aa', f: "'JetBrains Mono', monospace" },
            ].map(o => (
              <button key={o.id} onClick={() => setFont(o.id)} style={{
                flex: 1, padding: '5px 0', borderRadius: 7,
                background: font === o.id ? (theme === 'dark' ? 'rgba(255,255,255,0.10)' : 'rgba(0,0,0,0.08)') : 'transparent',
                border: 0, color: themes.text, fontFamily: o.f, fontSize: 14, fontWeight: 600, cursor: 'pointer',
              }}>{o.label}</button>
            ))}
          </div>
          {/* Size */}
          <div style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '0 10px', background: theme === 'dark' ? 'var(--m-tint)' : 'rgba(0,0,0,0.05)', borderRadius: 10 }}>
            <button onClick={() => setSize(s => Math.max(0, s - 1))} style={{ background: 'transparent', border: 0, color: themes.text, fontFamily: 'Geist', fontSize: 11, fontWeight: 700, cursor: 'pointer', padding: 4 }}>A</button>
            <button onClick={() => setSize(s => Math.min(4, s + 1))} style={{ background: 'transparent', border: 0, color: themes.text, fontFamily: 'Geist', fontSize: 17, fontWeight: 700, cursor: 'pointer', padding: 4 }}>A</button>
          </div>
        </div>
      </div>
    </div>
  );
}

// ─── Privacy review (multi-step) ───────────────────────────────
function MPrivacyReview({ onClose }) {
  const [step, setStep] = React.useState(0);
  const steps = [
    {
      title: 'Privacy review',
      sub:   'Four quick checks. About 60 seconds.',
      kind:  'intro',
    },
    {
      title: 'Tracking protection',
      sub:   "We block third-party trackers and cross-site cookies by default. You're on Strict.",
      kind:  'option',
      key:   'tracking',
      value: 'strict',
      options: [
        { id: 'strict',   label: 'Strict',   sub: 'Block everything cross-site',     icon: '🛡' },
        { id: 'balanced', label: 'Balanced', sub: 'Block known trackers',            icon: '⚖' },
        { id: 'off',      label: 'Off',      sub: 'Compatibility — not recommended', icon: '⚠' },
      ],
    },
    {
      title: 'Search engine',
      sub:   "Pick what should power the search pill. We never log your queries.",
      kind:  'option',
      key:   'search',
      value: 'ajna',
      options: [
        { id: 'ajna',   label: 'Ajna',       sub: 'No logs, no profiles, mesh-aware', icon: 'A' },
        { id: 'ddg',    label: 'DuckDuckGo', sub: 'No tracking',                       icon: 'D' },
        { id: 'google', label: 'Google',     sub: 'Personalized but logged',           icon: 'G' },
      ],
    },
    {
      title: 'Permissions',
      sub:   "Review which sites have access to camera, mic, and location.",
      kind:  'perms',
    },
    {
      title: "You're all set",
      sub:   'You can revisit any of these in Settings → Privacy.',
      kind:  'done',
    },
  ];
  const s = steps[step];
  return (
    <div style={{ position: 'absolute', inset: 0, zIndex: 86, background: M_BG, display: 'flex', flexDirection: 'column', color: M_FG }}>
      {/* Progress */}
      <div style={{ padding: '40px 22px 0', display: 'flex', alignItems: 'center', gap: 10 }}>
        <button onClick={onClose} aria-label="Close" style={{ width: 32, height: 32, borderRadius: 8, background: M_SURFACE, border: '1px solid ' + M_BORDER_SOFT, color: M_FG_MUTED, display: 'grid', placeItems: 'center', cursor: 'pointer' }}>{MIc.close({ s: 14 })}</button>
        <div style={{ flex: 1, height: 4, borderRadius: 2, background: 'var(--m-tint)', overflow: 'hidden' }}>
          <div style={{ height: '100%', width: ((step + 1) / steps.length * 100) + '%', background: 'linear-gradient(90deg,#6EE7B7,#60A5FA)', transition: 'width 240ms' }}/>
        </div>
        <div style={{ fontSize: 10.5, color: M_FG_DIM, fontFamily: 'JetBrains Mono, monospace' }}>{step + 1}/{steps.length}</div>
      </div>

      <div style={{ flex: 1, overflowY: 'auto', padding: '24px 22px 16px' }}>
        <div style={{ fontSize: 10.5, color: M_FG_DIM, letterSpacing: '0.14em', textTransform: 'uppercase', fontWeight: 700, fontFamily: 'JetBrains Mono, monospace', marginBottom: 8 }}>Step {step + 1} of {steps.length}</div>
        <div style={{ fontSize: 26, fontWeight: 700, fontFamily: 'Geist', letterSpacing: '-0.03em', lineHeight: 1.15, marginBottom: 10 }}>{s.title}</div>
        <div style={{ fontSize: 13.5, color: M_FG_MUTED, lineHeight: 1.5, marginBottom: 22 }}>{s.sub}</div>

        {s.kind === 'intro' && (
          <div style={{ marginTop: 10 }}>
            {[
              { l: '1. Tracking protection',  icon: '🛡', c: '#6EE7B7' },
              { l: '2. Search engine',        icon: '🔎', c: '#60A5FA' },
              { l: '3. Site permissions',     icon: '🔓', c: '#A78BFA' },
              { l: '4. You\u2019re all set',  icon: '✓',  c: '#FBBF24' },
            ].map(b => (
              <div key={b.l} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '12px 14px', background: M_SURFACE, border: '1px solid ' + M_BORDER_SOFT, borderRadius: 12, marginBottom: 8 }}>
                <span style={{ width: 32, height: 32, borderRadius: 8, background: b.c + '22', color: b.c, display: 'grid', placeItems: 'center', fontSize: 14 }}>{b.icon}</span>
                <span style={{ fontSize: 13, color: M_FG, fontFamily: 'Geist' }}>{b.l}</span>
              </div>
            ))}
          </div>
        )}

        {s.kind === 'option' && (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            {s.options.map(o => (
              <div key={o.id} style={{
                display: 'flex', alignItems: 'center', gap: 13, padding: '13px 14px',
                background: M_SURFACE, borderRadius: 12,
                border: '1px solid ' + (s.value === o.id ? 'rgba(96,165,250,0.45)' : M_BORDER_SOFT),
                boxShadow: s.value === o.id ? '0 0 0 3px rgba(96,165,250,0.10)' : 'none',
                cursor: 'pointer',
              }}>
                <div style={{ width: 34, height: 34, borderRadius: 9, background: 'var(--m-tint)', display: 'grid', placeItems: 'center', fontSize: 16, fontFamily: 'Geist', fontWeight: 700 }}>{o.icon}</div>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 13, fontWeight: 600, color: M_FG, fontFamily: 'Geist', letterSpacing: '-0.01em' }}>{o.label}</div>
                  <div style={{ fontSize: 11, color: M_FG_MUTED, marginTop: 2 }}>{o.sub}</div>
                </div>
                <div style={{
                  width: 20, height: 20, borderRadius: 10,
                  background: s.value === o.id ? M_ACCENT_B : 'transparent',
                  border: '2px solid ' + (s.value === o.id ? M_ACCENT_B : M_BORDER),
                  display: 'grid', placeItems: 'center',
                }}>{s.value === o.id && <span style={{ width: 8, height: 8, borderRadius: 4, background: '#0B0C0F' }}/>}</div>
              </div>
            ))}
          </div>
        )}

        {s.kind === 'perms' && (
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 8 }}>
            {A_PERMS_SUMMARY.slice(0, 6).map(p => (
              <div key={p.id} style={{ padding: 12, background: M_SURFACE, border: '1px solid ' + M_BORDER_SOFT, borderRadius: 11 }}>
                <div style={{ fontSize: 11, color: M_FG_MUTED, fontFamily: 'Geist', fontWeight: 600 }}>{p.label}</div>
                <div style={{ marginTop: 6, fontSize: 11, fontFamily: 'JetBrains Mono, monospace' }}>
                  <span style={{ color: '#6EE7B7' }}>{p.allowed}</span>
                  <span style={{ color: M_FG_DIM, margin: '0 5px' }}>·</span>
                  <span style={{ color: '#F87171' }}>{p.blocked}</span>
                </div>
              </div>
            ))}
          </div>
        )}

        {s.kind === 'done' && (
          <div style={{
            padding: 20,
            background: 'linear-gradient(135deg, rgba(110,231,183,0.10), rgba(96,165,250,0.10)), ' + M_SURFACE,
            border: '1px solid rgba(110,231,183,0.32)', borderRadius: 14,
            textAlign: 'center',
          }}>
            <div style={{ fontSize: 56, marginBottom: 8 }}>✓</div>
            <div style={{ fontSize: 13.5, color: M_FG, fontFamily: 'Geist', fontWeight: 600 }}>Privacy review complete</div>
          </div>
        )}
      </div>

      {/* Footer */}
      <div style={{ padding: '12px 22px 26px', display: 'flex', gap: 8 }}>
        {step > 0 && (
          <button onClick={() => setStep(step - 1)} style={{ padding: '12px 18px', borderRadius: 10, background: M_SURFACE, border: '1px solid ' + M_BORDER_SOFT, color: M_FG, fontSize: 13, fontWeight: 500, fontFamily: 'inherit', cursor: 'pointer' }}>Back</button>
        )}
        <button onClick={() => step === steps.length - 1 ? onClose() : setStep(step + 1)} style={{ flex: 1, padding: '12px 18px', borderRadius: 10, background: M_FG, border: 0, color: '#0B0C0F', fontSize: 13, fontWeight: 700, fontFamily: 'inherit', cursor: 'pointer' }}>
          {step === steps.length - 1 ? 'Done' : step === 0 ? 'Start' : 'Continue'}
        </button>
      </div>
    </div>
  );
}

// ─── Help & feedback (settings sub-page body) ──────────────────
function MScreenHelp() {
  const links = [
    { id: 'release',   label: 'Release notes',   sub: 'v0.4.2 · 12 changes', icon: '📰' },
    { id: 'support',   label: 'Get support',     sub: 'support.ajna.dev',     icon: '💬' },
    { id: 'docs',      label: 'Documentation',   sub: 'docs.ajna.dev',        icon: '📘' },
    { id: 'community', label: 'Community',       sub: 'community.ajna.dev',   icon: '🏛' },
    { id: 'roadmap',   label: 'Roadmap',         sub: 'roadmap.ajna.dev',     icon: '🗺' },
    { id: 'feedback',  label: 'Send feedback',   sub: 'Direct to engineering',icon: '✉' },
    { id: 'bug',       label: 'Report a bug',    sub: 'Auto-attaches diagnostics',icon: '🐞' },
    { id: 'privacy',   label: 'Privacy policy',  sub: 'ajna.dev/privacy',     icon: '🔒' },
    { id: 'terms',     label: 'Terms of service',sub: 'ajna.dev/terms',       icon: '📄' },
  ];
  return (
    <div style={{ height: '100%', overflowY: 'auto', padding: '22px 14px 100px', color: M_FG, background: M_BG, boxSizing: 'border-box' }}>
      <MLHeader
        icon={<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="9"/><path d="M9.1 9a3 3 0 1 1 5.8 1c0 2-3 3-3 3"/><path d="M12 17h.01"/></svg>}
        color="#FBBF24"
        title="Help & feedback"
        sub="Real humans · responses in < 24 hours"
      />
      <MLCard>
        {links.map((l, i) => (
          <div key={l.id} style={{
            display: 'flex', alignItems: 'center', gap: 12, padding: '12px 14px',
            borderTop: i === 0 ? 0 : '1px solid ' + M_BORDER_SOFT, cursor: 'pointer',
          }}>
            <span style={{ fontSize: 18, width: 28, textAlign: 'center' }}>{l.icon}</span>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 13, fontWeight: 500, color: M_FG, fontFamily: 'Geist' }}>{l.label}</div>
              <div style={{ fontSize: 10.5, color: M_FG_DIM, fontFamily: 'JetBrains Mono, monospace', marginTop: 1 }}>{l.sub}</div>
            </div>
            <span style={{ color: M_FG_DIM }}>↗</span>
          </div>
        ))}
      </MLCard>
    </div>
  );
}

// ─── Credits (about → credits) ─────────────────────────────────
function MScreenCredits() {
  const team = [
    { name: 'Maya Chen',          role: 'Founder · Mesh',     bg: '#A78BFA', i: 'MC' },
    { name: 'Aishwarya Iyer',     role: 'Identity · DIDComm', bg: '#EF4444', i: 'AI' },
    { name: 'Rohan Sharma',       role: 'Browser · UI',       bg: '#F472B6', i: 'RS' },
    { name: 'Noah Okafor',        role: 'Sync · CRDT',        bg: '#10B981', i: 'NO' },
  ];
  const oss = [
    { name: 'React',          v: '18.3.1' },
    { name: 'Babel standalone', v: '7.29.0' },
    { name: 'Geist',          v: '1.3' },
    { name: 'JetBrains Mono', v: '2.304' },
    { name: 'Tailwind tokens',v: '4.0' },
    { name: 'DIDComm v2',     v: '1.0' },
    { name: 'UCAN spec',      v: '0.10' },
    { name: 'noble crypto',   v: '1.7' },
  ];
  return (
    <div style={{ height: '100%', overflowY: 'auto', padding: '22px 14px 100px', color: M_FG, background: M_BG, boxSizing: 'border-box' }}>
      <MLHeader
        icon={<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><path d="M12 2 4 5v7c0 5 3.5 8.5 8 10 4.5-1.5 8-5 8-10V5z"/></svg>}
        color={M_ACCENT}
        title="Credits"
        sub="People and code that built Ajna"
      />

      <div style={{
        padding: 18, marginBottom: 18, borderRadius: 14,
        background: 'linear-gradient(135deg, rgba(110,231,183,0.08), rgba(96,165,250,0.08)), ' + M_SURFACE,
        border: '1px solid ' + M_BORDER_SOFT, textAlign: 'center',
      }}>
        <div style={{ width: 50, height: 50, borderRadius: 14, background: 'linear-gradient(135deg,#6EE7B7,#60A5FA)', display: 'inline-grid', placeItems: 'center', color: '#0B0C0F', fontFamily: 'Geist', fontWeight: 700, fontSize: 26, marginBottom: 10 }}>A</div>
        <div style={{ fontSize: 16, fontWeight: 700, fontFamily: 'Geist', letterSpacing: '-0.02em' }}>Ajna Browser</div>
        <div style={{ fontSize: 10.5, color: M_FG_MUTED, fontFamily: 'JetBrains Mono, monospace', marginTop: 3 }}>v0.4.2 · build 24891 · May 28 2026</div>
        <div style={{ fontSize: 11.5, color: M_FG_DIM, marginTop: 12, lineHeight: 1.5 }}>Made with care in Berlin, Bangalore, and San Francisco.</div>
      </div>

      <div style={{ fontSize: 11, fontWeight: 700, color: M_FG_DIM, letterSpacing: '0.14em', textTransform: 'uppercase', fontFamily: 'JetBrains Mono, monospace', padding: '0 4px 8px' }}>Team</div>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8, marginBottom: 18 }}>
        {team.map(p => (
          <div key={p.name} style={{ padding: 12, background: M_SURFACE, border: '1px solid ' + M_BORDER_SOFT, borderRadius: 11, display: 'flex', alignItems: 'center', gap: 10 }}>
            <MTile size={30} bg={p.bg} color="#fff" label={p.i} radius={8}/>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 11.5, fontWeight: 600, color: M_FG, fontFamily: 'Geist', letterSpacing: '-0.01em', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{p.name}</div>
              <div style={{ fontSize: 9.5, color: M_FG_DIM, fontFamily: 'JetBrains Mono, monospace', marginTop: 1, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{p.role}</div>
            </div>
          </div>
        ))}
      </div>

      <div style={{ fontSize: 11, fontWeight: 700, color: M_FG_DIM, letterSpacing: '0.14em', textTransform: 'uppercase', fontFamily: 'JetBrains Mono, monospace', padding: '0 4px 8px' }}>Open source</div>
      <MLCard>
        {oss.map((o, i) => (
          <div key={o.name} style={{ display: 'flex', alignItems: 'center', padding: '11px 12px', borderTop: i === 0 ? 0 : '1px solid ' + M_BORDER_SOFT }}>
            <span style={{ flex: 1, fontSize: 12.5, color: M_FG, fontFamily: 'Geist' }}>{o.name}</span>
            <span style={{ fontSize: 10.5, color: M_FG_DIM, fontFamily: 'JetBrains Mono, monospace' }}>v{o.v}</span>
          </div>
        ))}
      </MLCard>
    </div>
  );
}

Object.assign(window, {
  MFindInPage, MZoomControl, MPageInfo, MClearDataSheet, MPermissionPrompt,
  MSadTab, MVoiceSearch, MReader, MPrivacyReview, MScreenHelp, MScreenCredits,
});
