// Desktop Calls page + page-action overlays (Find / Zoom / Page info /
// Clear data / Permission prompt / Sad tab / Voice / Reader / Privacy review /
// Help / Credits). CSS-var palette so light/dark + accent work automatically.

const D_CALL_SUGGESTED = [
  { name: 'Rohan Sharma',   bg: '#F472B6', avatar: 'https://i.pravatar.cc/120?img=12', sub: 'Online now',  domain: 'rohan' },
  { name: 'Aishwarya Iyer', bg: '#EF4444', avatar: 'https://i.pravatar.cc/120?img=49', sub: 'Nearby · BLE', domain: 'aishwarya' },
  { name: 'Priya Nair',     bg: '#22D3EE', avatar: 'https://i.pravatar.cc/120?img=47', sub: 'On mesh',      domain: 'priya' },
  { name: 'Arjun Mehta',    bg: '#6EE7B7', avatar: 'https://i.pravatar.cc/120?img=14', sub: 'On mesh',      domain: 'arjun' },
];

function DAvatar({ name, bg, avatar, size = 44 }) {
  const initials = name.split(/\s+/).slice(0, 2).map(s => s[0]).join('').toUpperCase();
  return (
    <div style={{ width: size, height: size, borderRadius: size / 2, background: bg, position: 'relative', overflow: 'hidden', flexShrink: 0, display: 'grid', placeItems: 'center', color: '#fff', fontWeight: 700, fontSize: size * 0.34, fontFamily: 'Geist, Inter, sans-serif' }}>
      <span style={{ position: 'absolute', inset: 0, display: 'grid', placeItems: 'center' }}>{initials}</span>
      {avatar && <img src={avatar} alt="" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover' }} onError={e => { e.currentTarget.style.display = 'none'; }}/>}
    </div>
  );
}

function DScreenCalls() {
  return (
    <div style={{ height: '100%', overflowY: 'auto', background: 'var(--sidebar-bg)', color: 'var(--fg)', fontFamily: 'Inter, sans-serif' }}>
      <div style={{ maxWidth: 760, margin: '0 auto', padding: '40px clamp(20px,4vw,56px) 80px' }}>
        <div style={{ fontSize: 27, fontWeight: 700, fontFamily: 'Geist, Inter, sans-serif', letterSpacing: '-0.03em', marginBottom: 4 }}>Calls</div>

        <div style={{ textAlign: 'center', padding: '44px 16px 36px' }}>
          <div style={{ position: 'relative', width: 150, height: 150, margin: '0 auto 26px', display: 'grid', placeItems: 'center' }}>
            {[0, 1, 2, 3].map(i => <div key={i} style={{ position: 'absolute', borderRadius: '50%', inset: i * 20, border: '1px solid color-mix(in oklch, var(--accent-a) ' + (28 - i * 6) + '%, transparent)' }}/>)}
            <div style={{ width: 76, height: 76, borderRadius: 22, background: 'var(--accent-grad)', display: 'grid', placeItems: 'center', color: '#0F1114' }}>
              <svg width="34" height="34" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.8 19.8 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.8 19.8 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.91.34 1.85.57 2.81.7A2 2 0 0 1 22 16.92z"/></svg>
            </div>
          </div>
          <div style={{ fontSize: 24, fontWeight: 700, fontFamily: 'Geist, Inter, sans-serif', letterSpacing: '-0.03em', marginBottom: 10 }}>No calls yet</div>
          <div style={{ fontSize: 14, color: 'var(--fg-muted)', lineHeight: 1.55, maxWidth: 400, margin: '0 auto 24px' }}>Start an end-to-end encrypted voice or video call over DIDComm — no phone number, no account, no servers in the middle.</div>
          <div style={{ display: 'inline-flex', gap: 10 }}>
            <button style={{ display: 'inline-flex', alignItems: 'center', gap: 8, padding: '11px 18px', borderRadius: 10, background: 'var(--accent-grad)', border: 0, color: '#0F1114', fontSize: 13, fontWeight: 600, fontFamily: 'inherit', cursor: 'pointer' }}>
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.8 19.8 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.8 19.8 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.91.34 1.85.57 2.81.7A2 2 0 0 1 22 16.92z"/></svg>
              New audio call</button>
            <button style={{ display: 'inline-flex', alignItems: 'center', gap: 8, padding: '11px 18px', borderRadius: 10, background: 'var(--bg-elev)', border: '1px solid var(--border-soft)', color: 'var(--fg)', fontSize: 13, fontWeight: 600, fontFamily: 'inherit', cursor: 'pointer' }}>
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="m23 7-7 5 7 5z"/><rect x="1" y="5" width="15" height="14" rx="2"/></svg>
              New video call</button>
          </div>
        </div>

        <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--fg-dim)', letterSpacing: '0.14em', textTransform: 'uppercase', fontFamily: 'JetBrains Mono, monospace', padding: '0 4px 12px' }}>Suggested · from your mesh</div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 10, marginBottom: 24 }}>
          {D_CALL_SUGGESTED.map(c => (
            <div key={c.name} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '13px 15px', background: 'var(--bg-elev)', border: '1px solid var(--border-soft)', borderRadius: 12 }}>
              <DAvatar name={c.name} bg={c.bg} avatar={c.avatar} size={42}/>
              <div style={{ flex: 1, minWidth: 0 }}><div style={{ fontSize: 14, fontWeight: 500, fontFamily: 'Geist, Inter, sans-serif', letterSpacing: '-0.01em' }}>{c.name}</div><div style={{ fontSize: 11, color: 'var(--fg-dim)', fontFamily: 'JetBrains Mono, monospace', marginTop: 3 }}>{c.sub}</div></div>
              <button aria-label="Call" style={dCallBtn('#6EE7B7')}><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.8 19.8 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.8 19.8 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.91.34 1.85.57 2.81.7A2 2 0 0 1 22 16.92z"/></svg></button>
              <button aria-label="Video" style={dCallBtn('#60A5FA')}><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="m23 7-7 5 7 5z"/><rect x="1" y="5" width="15" height="14" rx="2"/></svg></button>
            </div>
          ))}
        </div>

        <div style={{ padding: '12px 15px', background: 'color-mix(in oklch, #6EE7B7 6%, transparent)', border: '1px solid color-mix(in oklch, #6EE7B7 16%, transparent)', borderRadius: 11, display: 'flex', alignItems: 'center', gap: 10 }}>
          <span style={{ color: '#6EE7B7' }}><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" 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></span>
          <div style={{ flex: 1, fontSize: 12, color: 'var(--fg-muted)', lineHeight: 1.45 }}>Calls are end-to-end encrypted via DIDComm WebRTC. Ajna never sees who you talk to, or when.</div>
        </div>
      </div>
    </div>
  );
}
function dCallBtn(c) { return { width: 36, height: 36, borderRadius: 18, background: 'color-mix(in oklch, ' + c + ' 16%, transparent)', border: 0, color: c, display: 'grid', placeItems: 'center', cursor: 'pointer', flexShrink: 0 }; }

// ── Overlay scaffolding ────────────────────────────────────────
function DScrim({ onClose, children, blur = true }) {
  return (
    <div onClick={onClose} style={{ position: 'absolute', inset: 0, zIndex: 90, background: 'rgba(0,0,0,0.5)', backdropFilter: blur ? 'blur(4px)' : 'none', display: 'grid', placeItems: 'center', animation: 'dFade 160ms ease-out' }}>
      <style>{`@keyframes dFade{from{opacity:0}to{opacity:1}}@keyframes dPop{from{opacity:0;transform:translateY(10px) scale(0.98)}to{opacity:1;transform:none}}`}</style>
      <div onClick={e => e.stopPropagation()} style={{ animation: 'dPop 200ms cubic-bezier(0.2,0.85,0.3,1)' }}>{children}</div>
    </div>
  );
}

// Find in page — top-right docked bar
function DFindInPage({ onClose }) {
  const [q, setQ] = React.useState('mesh');
  return (
    <div className="glass" style={{ position: 'absolute', top: 10, right: 16, zIndex: 92, width: 420, borderRadius: 12, padding: 10, animation: 'dPop 180ms ease-out' }}>
      <style>{`@keyframes dPop{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}`}</style>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
        <div style={{ flex: 1, display: 'flex', alignItems: 'center', gap: 8, padding: '7px 11px', background: 'var(--bg)', border: '1px solid color-mix(in oklch, var(--accent-b) 45%, transparent)', borderRadius: 8, boxShadow: '0 0 0 3px color-mix(in oklch, var(--accent-b) 10%, transparent)' }}>
          <span style={{ color: 'var(--accent-b)' }}><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="11" cy="11" r="7"/><path d="m20 20-4-4"/></svg></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: 'var(--fg)', fontSize: 13, fontFamily: 'inherit' }}/>
          <span style={{ fontSize: 10.5, color: 'var(--fg-dim)', fontFamily: 'JetBrains Mono, monospace' }}>{q ? '3 / 12' : '0 / 0'}</span>
        </div>
        <button style={dIconBtn()}><svg width="13" height="13" 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={dIconBtn()}><svg width="13" height="13" 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={dIconBtn()}><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M18 6 6 18M6 6l12 12"/></svg></button>
      </div>
    </div>
  );
}
function dIconBtn() { return { width: 30, height: 30, borderRadius: 7, background: 'transparent', border: '1px solid var(--border-soft)', color: 'var(--fg-muted)', display: 'grid', placeItems: 'center', cursor: 'pointer', flexShrink: 0 }; }

// Zoom
function DZoom({ value = 100, onChange, onClose }) {
  const presets = [50, 75, 90, 100, 110, 125, 150, 200];
  return (
    <div className="glass" style={{ position: 'absolute', top: 10, right: 16, zIndex: 92, width: 320, borderRadius: 12, padding: 14, animation: 'dPop 180ms ease-out' }}>
      <style>{`@keyframes dPop{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}`}</style>
      <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 12 }}><span style={dKick()}>Page zoom</span><button onClick={() => onChange(100)} style={{ fontSize: 10.5, color: 'var(--accent-b)', background: 'transparent', border: 0, cursor: 'pointer', fontFamily: 'inherit' }}>Reset</button></div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 14 }}>
        <button onClick={() => onChange(Math.max(50, value - 10))} style={{ ...dIconBtn(), width: 34, height: 34, fontSize: 17 }}>−</button>
        <div style={{ flex: 1, textAlign: 'center', fontSize: 26, fontWeight: 700, fontFamily: 'Geist', letterSpacing: '-0.03em' }}>{value}<span style={{ fontSize: 14, color: 'var(--fg-muted)' }}>%</span></div>
        <button onClick={() => onChange(Math.min(300, value + 10))} style={{ ...dIconBtn(), width: 34, height: 34, fontSize: 17 }}>+</button>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4,1fr)', gap: 5 }}>
        {presets.map(p => <button key={p} onClick={() => onChange(p)} style={{ padding: '5px 0', borderRadius: 7, background: value === p ? 'var(--fg)' : 'transparent', border: '1px solid ' + (value === p ? 'var(--fg)' : 'var(--border-soft)'), color: value === p ? 'var(--bg)' : 'var(--fg-muted)', fontSize: 10.5, fontWeight: 600, cursor: 'pointer', fontFamily: 'JetBrains Mono, monospace' }}>{p}%</button>)}
      </div>
    </div>
  );
}

// Page info
function DPageInfo({ url = 'linear.app/inbox', onClose }) {
  return (
    <div className="glass" style={{ position: 'absolute', top: 48, left: '50%', transform: 'translateX(-50%)', zIndex: 92, width: 380, maxHeight: '80%', overflowY: 'auto', borderRadius: 12, padding: 16, animation: 'dPop 180ms ease-out' }}>
      <style>{`@keyframes dPop{from{opacity:0;transform:translate(-50%,-10px)}to{opacity:1;transform:translateX(-50%)}}`}</style>
      <div style={{ display: 'flex', alignItems: 'center', gap: 11, marginBottom: 14 }}>
        <div style={{ width: 34, height: 34, borderRadius: 9, background: 'color-mix(in oklch,#6EE7B7 16%,transparent)', color: '#6EE7B7', display: 'grid', placeItems: 'center', border: '1px solid color-mix(in oklch,#6EE7B7 32%,transparent)' }}><svg width="16" height="16" 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, fontWeight: 600, fontFamily: 'Geist', letterSpacing: '-0.01em' }}>Connection is secure</div><div style={{ fontSize: 10.5, color: 'var(--fg-dim)', fontFamily: 'JetBrains Mono, monospace', marginTop: 2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>https://{url}</div></div>
        <button onClick={onClose} style={dIconBtn()}><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M18 6 6 18M6 6l12 12"/></svg></button>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gap: 7, marginBottom: 12 }}>
        {[['12', 'Trackers', '#6EE7B7'], ['4', 'Cookies', '#FBBF24'], ['2', 'Permissions', '#A78BFA']].map(([n, l, c]) => <div key={l} style={{ padding: '8px 10px', background: 'var(--bg)', border: '1px solid var(--border-soft)', borderRadius: 9 }}><div style={{ fontSize: 18, fontWeight: 700, color: c, fontFamily: 'Geist', letterSpacing: '-0.03em', lineHeight: 1 }}>{n}</div><div style={{ fontSize: 9, color: 'var(--fg-dim)', fontFamily: 'JetBrains Mono, monospace', marginTop: 4 }}>{l}</div></div>)}
      </div>
      <div style={{ ...dKick(), padding: '0 2px 5px' }}>Permissions</div>
      <div style={{ background: 'var(--bg)', border: '1px solid var(--border-soft)', borderRadius: 10, overflow: 'hidden', marginBottom: 10 }}>
        {[['Notifications', 'Allow'], ['Camera', 'Ask'], ['Microphone', 'Ask'], ['Location', 'Block']].map(([l, v], i) => <div key={l} style={{ display: 'flex', alignItems: 'center', padding: '8px 11px', borderTop: i === 0 ? 0 : '1px solid var(--border-soft)' }}><span style={{ flex: 1, fontSize: 12, fontFamily: 'Geist' }}>{l}</span><span style={{ fontSize: 9.5, padding: '2px 7px', borderRadius: 999, fontWeight: 600, background: v === 'Allow' ? 'color-mix(in oklch,#6EE7B7 12%,transparent)' : v === 'Block' ? 'color-mix(in oklch,#F87171 12%,transparent)' : 'var(--bg-elev-2)', color: v === 'Allow' ? '#6EE7B7' : v === 'Block' ? '#F87171' : 'var(--fg-muted)', fontFamily: 'JetBrains Mono, monospace' }}>{v.toUpperCase()}</span></div>)}
      </div>
      <div style={{ padding: '8px 11px', background: 'var(--bg)', border: '1px solid var(--border-soft)', borderRadius: 10, fontSize: 11, color: 'var(--fg)', fontFamily: 'JetBrains Mono, monospace', lineHeight: 1.6 }}>Cloudflare Inc. ECC CA-3<br/>Valid until Aug 14, 2026<br/>TLS_AES_256_GCM_SHA384</div>
    </div>
  );
}

// Clear data
function DClearData({ 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 = [['history', 'History', '47 entries today'], ['cookies', 'Cookies & site data', '142 sites · 8.4 MB'], ['cache', 'Cached files', '184 MB'], ['downloads', 'Downloads', 'List only · keeps files'], ['forms', 'Autofill form data', '38 entries'], ['passwords', 'Saved passwords', '128 saved · synced']];
  return (
    <DScrim onClose={onClose}>
      <div style={{ width: 460, maxHeight: '86vh', overflowY: 'auto', background: 'var(--bg-elev)', border: '1px solid var(--border)', borderRadius: 16, padding: 20, boxShadow: '0 24px 60px rgba(0,0,0,0.6)' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 18 }}>
          <div style={{ width: 36, height: 36, borderRadius: 9, background: 'color-mix(in oklch,#F87171 16%,transparent)', color: '#F87171', display: 'grid', placeItems: 'center' }}><svg width="18" height="18" 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-2V6"/></svg></div>
          <div style={{ flex: 1 }}><div style={{ fontSize: 17, fontWeight: 700, fontFamily: 'Geist', letterSpacing: '-0.02em' }}>Clear browsing data</div><div style={{ fontSize: 11, color: 'var(--fg-muted)', marginTop: 2 }}>Only on this device. Synced data stays on your other devices.</div></div>
        </div>
        <div style={{ ...dKick(), padding: '0 2px 7px' }}>Time range</div>
        <div style={{ display: 'flex', gap: 5, marginBottom: 16, flexWrap: 'wrap' }}>
          {[['hour', 'Last hour'], ['day', 'Last 24 hours'], ['week', 'Last 7 days'], ['month', 'Last 4 weeks'], ['all', 'All time']].map(([k, l]) => <button key={k} onClick={() => setRange(k)} style={{ padding: '6px 11px', borderRadius: 999, background: range === k ? 'var(--fg)' : 'transparent', border: '1px solid ' + (range === k ? 'var(--fg)' : 'var(--border-soft)'), color: range === k ? 'var(--bg)' : 'var(--fg-muted)', fontSize: 11, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit' }}>{l}</button>)}
        </div>
        <div style={{ ...dKick(), padding: '0 2px 7px' }}>What to clear</div>
        <div style={{ background: 'var(--bg)', border: '1px solid var(--border-soft)', borderRadius: 11, overflow: 'hidden', marginBottom: 18 }}>
          {opts.map(([id, label, size], i) => (
            <div key={id} onClick={() => setPicked(p => ({ ...p, [id]: !p[id] }))} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '10px 12px', borderTop: i === 0 ? 0 : '1px solid var(--border-soft)', cursor: 'pointer' }}>
              <div style={{ width: 18, height: 18, borderRadius: 4, background: picked[id] ? 'var(--fg)' : 'transparent', border: '1.5px solid ' + (picked[id] ? 'var(--fg)' : 'var(--border)'), display: 'grid', placeItems: 'center', flexShrink: 0 }}>{picked[id] && <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="var(--bg)" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><path d="M20 6 9 17l-5-5"/></svg>}</div>
              <div style={{ flex: 1 }}><div style={{ fontSize: 12.5, fontFamily: 'Geist', fontWeight: 500 }}>{label}</div><div style={{ fontSize: 10, color: 'var(--fg-dim)', fontFamily: 'JetBrains Mono, monospace', marginTop: 2 }}>{size}</div></div>
            </div>
          ))}
        </div>
        <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8 }}>
          <button onClick={onClose} style={{ padding: '9px 18px', borderRadius: 9, background: 'var(--bg)', border: '1px solid var(--border-soft)', color: 'var(--fg)', fontSize: 12.5, fontWeight: 500, fontFamily: 'inherit', cursor: 'pointer' }}>Cancel</button>
          <button onClick={onClose} style={{ padding: '9px 18px', borderRadius: 9, background: '#F87171', border: 0, color: '#0B0C0F', fontSize: 12.5, fontWeight: 700, fontFamily: 'inherit', cursor: 'pointer' }}>Clear data</button>
        </div>
      </div>
    </DScrim>
  );
}

// Permission prompt — anchored under the URL bar (top-left)
function DPermissionPrompt({ type = 'camera', site = 'meet.google.com', onResolve }) {
  const meta = { camera: { label: 'use your camera', c: '#F472B6', icon: <><path d="M3 7h4l2-3h6l2 3h4v12H3z"/><circle cx="12" cy="13" r="4"/></> }, mic: { label: 'use your microphone', c: '#22D3EE', icon: <><rect x="9" y="3" width="6" height="12" rx="3"/><path d="M5 11a7 7 0 0 0 14 0M12 18v3"/></> }, location: { label: 'know your location', c: '#FBBF24', icon: <><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"/></> }, notif: { label: 'send notifications', c: '#A78BFA', icon: <><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"/></> } }[type];
  return (
    <div style={{ position: 'absolute', top: 50, left: 16, zIndex: 92, width: 380, background: 'var(--glass)', backdropFilter: 'blur(var(--glass-blur)) saturate(1.5)', WebkitBackdropFilter: 'blur(var(--glass-blur)) saturate(1.5)', border: '1px solid color-mix(in oklch,' + meta.c + ' 38%, transparent)', borderRadius: 14, padding: 14, boxShadow: 'inset 0 1px 0 var(--glass-highlight), var(--lift-soft)', animation: 'dPop 180ms ease-out' }}>
      <style>{`@keyframes dPop{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:none}}`}</style>
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 12 }}>
        <div style={{ width: 34, height: 34, borderRadius: 9, background: 'color-mix(in oklch,' + meta.c + ' 18%,transparent)', color: meta.c, display: 'grid', placeItems: 'center', flexShrink: 0 }}><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">{meta.icon}</svg></div>
        <div style={{ flex: 1, minWidth: 0 }}><div style={{ fontSize: 11.5, color: 'var(--fg-muted)', fontFamily: 'JetBrains Mono, monospace', marginBottom: 2 }}>{site}</div><div style={{ fontSize: 13.5, fontFamily: 'Geist', letterSpacing: '-0.01em' }}>wants to {meta.label}.</div></div>
      </div>
      <div style={{ display: 'flex', gap: 7 }}>
        <button onClick={() => onResolve('block')} style={dPrmpt()}>Block</button>
        <button onClick={() => onResolve('once')} style={dPrmpt()}>This time</button>
        <button onClick={() => onResolve('always')} style={{ ...dPrmpt(), background: meta.c, border: 0, color: '#0B0C0F', fontWeight: 700 }}>Allow</button>
      </div>
    </div>
  );
}
function dPrmpt() { return { flex: 1, padding: '8px 0', borderRadius: 8, background: 'var(--bg)', border: '1px solid var(--border-soft)', color: 'var(--fg)', fontSize: 12, fontWeight: 600, fontFamily: 'inherit', cursor: 'pointer' }; }

// Sad tab — fills content area
function DSadTab({ kind = 'offline', url = 'linear.app/inbox', onClose }) {
  const cases = { offline: { t: "You're offline", s: "We couldn't reach this page. Try the mesh — a peer might have it cached.", i: '⛅', d: 'ERR_INTERNET_DISCONNECTED', p: 'Try mesh', sec: 'Reload' }, dns: { t: "We can't find that site", s: "The domain didn't resolve.", i: '🔎', d: 'ERR_NAME_NOT_RESOLVED', p: 'Reload', sec: 'Search instead' }, cert: { t: "This connection isn't private", s: "The site's certificate doesn't check out.", i: '⚠️', d: 'NET::ERR_CERT_AUTHORITY_INVALID', p: 'Go back', sec: 'Details' }, crash: { t: 'This tab crashed', s: 'Something went wrong rendering this page.', i: '💥', d: 'STATUS_ACCESS_VIOLATION', p: 'Reload', sec: 'Send report' } }[kind];
  return (
    <div style={{ height: '100%', display: 'grid', placeItems: 'center', background: 'var(--sidebar-bg)', color: 'var(--fg)', padding: 40 }}>
      <div style={{ maxWidth: 480, textAlign: 'center' }}>
        <div style={{ fontSize: 80, marginBottom: 22 }}>{cases.i}</div>
        <div style={{ fontSize: 30, fontWeight: 700, fontFamily: 'Geist', letterSpacing: '-0.03em', marginBottom: 12 }}>{cases.t}</div>
        <div style={{ fontSize: 14.5, color: 'var(--fg-muted)', lineHeight: 1.55, marginBottom: 26 }}>{cases.s}</div>
        <div style={{ padding: '12px 16px', background: 'var(--bg-elev)', border: '1px solid var(--border-soft)', borderRadius: 11, marginBottom: 26, fontFamily: 'JetBrains Mono, monospace', textAlign: 'left', maxWidth: 400, margin: '0 auto 26px' }}>
          <div style={{ fontSize: 10, color: 'var(--fg-dim)', letterSpacing: '0.14em', textTransform: 'uppercase', fontWeight: 700, marginBottom: 6 }}>Tried to load</div>
          <div style={{ fontSize: 12, wordBreak: 'break-all', marginBottom: 6 }}>{url}</div>
          <div style={{ fontSize: 10.5, color: 'var(--fg-dim)' }}>{cases.d}</div>
        </div>
        <div style={{ display: 'flex', gap: 10, justifyContent: 'center' }}>
          <button onClick={onClose} style={{ padding: '11px 22px', borderRadius: 10, background: 'var(--bg-elev)', border: '1px solid var(--border-soft)', color: 'var(--fg)', fontSize: 13, fontWeight: 500, fontFamily: 'inherit', cursor: 'pointer' }}>{cases.sec}</button>
          <button onClick={onClose} style={{ padding: '11px 22px', borderRadius: 10, background: 'var(--fg)', border: 0, color: 'var(--bg)', fontSize: 13, fontWeight: 600, fontFamily: 'inherit', cursor: 'pointer' }}>{cases.p}</button>
        </div>
      </div>
    </div>
  );
}

// Voice search
function DVoiceSearch({ onClose, onCommit }) {
  const [phase, setPhase] = React.useState('listening');
  const transcript = 'search for distributed protocols';
  React.useEffect(() => { const t = setTimeout(() => setPhase('heard'), 1800); return () => clearTimeout(t); }, []);
  return (
    <DScrim onClose={onClose}>
      <div style={{ width: 460, padding: '42px 32px 32px', background: 'var(--bg-elev)', border: '1px solid var(--border)', borderRadius: 18, textAlign: 'center' }}>
        <style>{`@keyframes dvP{0%,100%{transform:scale(1);opacity:.85}50%{transform:scale(1.16);opacity:1}}@keyframes dvP2{0%,100%{transform:scale(1);opacity:.4}50%{transform:scale(1.32);opacity:.7}}`}</style>
        <div style={{ position: 'relative', width: 150, height: 150, margin: '0 auto 30px' }}>
          <div style={{ position: 'absolute', inset: -18, borderRadius: '50%', background: 'radial-gradient(circle, color-mix(in oklch, var(--accent-b) 32%, transparent), transparent 70%)', animation: 'dvP2 1.6s ease-in-out infinite' }}/>
          <div style={{ position: 'absolute', inset: 0, borderRadius: '50%', background: 'var(--accent-grad)', display: 'grid', placeItems: 'center', animation: 'dvP 1.6s ease-in-out infinite' }}>
            <svg width="50" height="50" 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: 11, color: 'var(--fg-dim)', fontFamily: 'JetBrains Mono, monospace', letterSpacing: '0.14em', textTransform: 'uppercase', fontWeight: 700, marginBottom: 14 }}>{phase === 'listening' ? 'Listening' : 'Heard'}</div>
        <div style={{ fontSize: 24, fontWeight: 600, fontFamily: 'Geist', letterSpacing: '-0.025em', lineHeight: 1.3, marginBottom: 22, minHeight: 60 }}>{phase === 'listening' ? <span style={{ color: 'var(--fg-muted)' }}>I'm listening…</span> : '"' + transcript + '"'}</div>
        <div style={{ display: 'flex', gap: 10, justifyContent: 'center' }}>
          <button onClick={onClose} style={{ padding: '10px 18px', borderRadius: 9, background: 'var(--bg)', border: '1px solid var(--border-soft)', color: 'var(--fg-muted)', fontSize: 12.5, fontFamily: 'inherit', cursor: 'pointer' }}>Cancel</button>
          <button onClick={() => onCommit && onCommit(transcript)} disabled={phase !== 'heard'} style={{ padding: '10px 22px', borderRadius: 9, background: phase === 'heard' ? 'var(--fg)' : 'var(--bg-elev-2)', border: 0, color: phase === 'heard' ? 'var(--bg)' : 'var(--fg-dim)', fontSize: 12.5, fontWeight: 700, fontFamily: 'inherit', cursor: phase === 'heard' ? 'pointer' : 'default' }}>Use this</button>
        </div>
      </div>
    </DScrim>
  );
}

// Reader — full content overlay
function DReader({ onClose }) {
  const [theme, setTheme] = React.useState('dark');
  const [size, setSize] = React.useState(2);
  const [font, setFont] = React.useState('serif');
  const sizes = [15, 17, 19, 21, 24];
  const T = { dark: { bg: '#0F1115', text: '#E5E7EB', mute: '#9CA3AF', border: 'rgba(255,255,255,0.08)' }, 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 ff = 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: 92, background: T.bg, color: T.text, display: 'flex', flexDirection: 'column' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '14px 24px', borderBottom: '1px solid ' + T.border }}>
        <button onClick={onClose} style={{ padding: '6px 12px', borderRadius: 8, background: 'transparent', border: '1px solid ' + T.border, color: T.text, fontSize: 11.5, fontFamily: 'inherit', cursor: 'pointer' }}>← Exit reader</button>
        <div style={{ flex: 1, textAlign: 'center', fontSize: 11, color: T.mute, fontFamily: 'JetBrains Mono, monospace' }}>engineering.ajna.dev / mesh · 18 min read</div>
        <div style={{ display: 'flex', gap: 7 }}>
          <div style={{ display: 'flex', gap: 3, padding: 3, background: theme === 'dark' ? 'rgba(255,255,255,0.04)' : 'rgba(0,0,0,0.05)', borderRadius: 8 }}>{['dark', 'sepia', 'light'].map(t => <button key={t} onClick={() => setTheme(t)} style={{ width: 26, height: 26, borderRadius: 6, background: t === 'dark' ? '#0F1115' : t === 'sepia' ? '#F4ECDC' : '#FFFFFF', border: theme === t ? '2px solid ' + (theme === 'dark' ? '#fff' : '#111827') : '1px solid ' + T.border, padding: 0, cursor: 'pointer' }}/>)}</div>
          <div style={{ display: 'flex', gap: 3, padding: 3, background: theme === 'dark' ? 'rgba(255,255,255,0.04)' : 'rgba(0,0,0,0.05)', borderRadius: 8 }}>{[['serif', 'Georgia, serif'], ['sans', 'Geist, sans-serif'], ['mono', "'JetBrains Mono', monospace"]].map(([id, f]) => <button key={id} onClick={() => setFont(id)} style={{ padding: '4px 9px', borderRadius: 6, background: font === id ? (theme === 'dark' ? 'rgba(255,255,255,0.10)' : 'rgba(0,0,0,0.08)') : 'transparent', border: 0, color: T.text, fontFamily: f, fontSize: 12, fontWeight: 600, cursor: 'pointer' }}>Aa</button>)}</div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '0 10px', background: theme === 'dark' ? 'rgba(255,255,255,0.04)' : 'rgba(0,0,0,0.05)', borderRadius: 8 }}><button onClick={() => setSize(s => Math.max(0, s - 1))} style={{ background: 'transparent', border: 0, color: T.text, fontFamily: 'Geist', fontSize: 12, fontWeight: 700, cursor: 'pointer', padding: 4 }}>A</button><button onClick={() => setSize(s => Math.min(4, s + 1))} style={{ background: 'transparent', border: 0, color: T.text, fontFamily: 'Geist', fontSize: 18, fontWeight: 700, cursor: 'pointer', padding: 4 }}>A</button></div>
        </div>
      </div>
      <div style={{ flex: 1, overflowY: 'auto', padding: '44px 24px 80px' }}>
        <div style={{ maxWidth: 720, margin: '0 auto' }}>
          <div style={{ fontSize: 11, color: T.mute, fontFamily: 'JetBrains Mono, monospace', letterSpacing: '0.12em', textTransform: 'uppercase', fontWeight: 700, marginBottom: 14 }}>Ajna Engineering · 18 min read</div>
          <h1 style={{ fontFamily: ff, fontWeight: 700, fontSize: 46, lineHeight: 1.1, letterSpacing: '-0.03em', margin: '0 0 18px' }}>Engineering an offline-first mesh</h1>
          <div style={{ fontSize: 14, color: T.mute, marginBottom: 32 }}>By Maya Chen · May 12, 2026</div>
          <div style={{ fontFamily: ff, fontSize: sizes[size], lineHeight: 1.7 }}>
            <p style={{ margin: '0 0 22px' }}>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.</p>
            <p style={{ margin: '0 0 22px' }}>Going from five devices in a lab to five thousand in the wild took eighteen months and three protocol revisions. 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: ff, fontWeight: 700, fontSize: sizes[size] * 1.5, lineHeight: 1.2, letterSpacing: '-0.02em', margin: '36px 0 16px' }}>Why offline-first, why now</h2>
            <p style={{ margin: '0 0 22px' }}>The web spent twenty years assuming a stable connection. Bluetooth 5.4 made device-to-device throughput practical, 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>
      </div>
    </div>
  );
}

// Privacy review wizard
function DPrivacyReview({ 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.', kind: 'option', value: 'strict', options: [['strict', 'Strict', 'Block everything cross-site', '🛡'], ['balanced', 'Balanced', 'Block known trackers', '⚖'], ['off', 'Off', 'Compatibility — not recommended', '⚠']] },
    { title: 'Search engine', sub: 'Pick what powers the command bar. We never log your queries.', kind: 'option', value: 'ajna', options: [['ajna', 'Ajna', 'No logs, mesh-aware', 'A'], ['ddg', 'DuckDuckGo', 'No tracking', 'D'], ['google', 'Google', 'Personalized but logged', '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 (
    <DScrim onClose={onClose}>
      <div style={{ width: 560, maxHeight: '86vh', overflowY: 'auto', background: 'var(--bg-elev)', border: '1px solid var(--border)', borderRadius: 18, boxShadow: '0 24px 60px rgba(0,0,0,0.6)' }}>
        <div style={{ padding: '22px 26px 16px', borderBottom: '1px solid var(--border-soft)', display: 'flex', alignItems: 'center', gap: 14 }}>
          <div style={{ flex: 1, height: 4, borderRadius: 2, background: 'var(--bg-elev-2)', overflow: 'hidden' }}><div style={{ height: '100%', width: ((step + 1) / steps.length * 100) + '%', background: 'var(--accent-grad)', transition: 'width 240ms' }}/></div>
          <span style={{ fontSize: 10.5, color: 'var(--fg-dim)', fontFamily: 'JetBrains Mono, monospace' }}>{step + 1} / {steps.length}</span>
          <button onClick={onClose} style={dIconBtn()}><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M18 6 6 18M6 6l12 12"/></svg></button>
        </div>
        <div style={{ padding: '26px 30px' }}>
          <div style={{ fontSize: 28, fontWeight: 700, fontFamily: 'Geist', letterSpacing: '-0.03em', lineHeight: 1.15, marginBottom: 10 }}>{s.title}</div>
          <div style={{ fontSize: 14, color: 'var(--fg-muted)', lineHeight: 1.55, marginBottom: 22 }}>{s.sub}</div>
          {s.kind === 'intro' && <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>{[['Tracking protection', '🛡', '#6EE7B7'], ['Search engine', '🔎', '#60A5FA'], ['Site permissions', '🔓', '#A78BFA'], ["You're all set", '✓', '#FBBF24']].map(([l, ic, c], i) => <div key={l} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '14px 16px', background: 'var(--bg)', border: '1px solid var(--border-soft)', borderRadius: 12 }}><span style={{ width: 32, height: 32, borderRadius: 8, background: 'color-mix(in oklch,' + c + ' 18%,transparent)', color: c, display: 'grid', placeItems: 'center', fontSize: 15 }}>{ic}</span><span style={{ fontSize: 13.5, fontFamily: 'Geist' }}>{i + 1}. {l}</span></div>)}</div>}
          {s.kind === 'option' && <div style={{ display: 'flex', flexDirection: 'column', gap: 9 }}>{s.options.map(([id, label, sub, ic]) => <div key={id} style={{ display: 'flex', alignItems: 'center', gap: 14, padding: '14px 16px', background: 'var(--bg)', borderRadius: 11, border: '1px solid ' + (s.value === id ? 'color-mix(in oklch, var(--accent-b) 45%, transparent)' : 'var(--border-soft)'), cursor: 'pointer' }}><div style={{ width: 36, height: 36, borderRadius: 9, background: 'var(--bg-elev-2)', display: 'grid', placeItems: 'center', fontSize: 16, fontWeight: 700, fontFamily: 'Geist' }}>{ic}</div><div style={{ flex: 1 }}><div style={{ fontSize: 14, fontWeight: 600, fontFamily: 'Geist', letterSpacing: '-0.01em' }}>{label}</div><div style={{ fontSize: 11.5, color: 'var(--fg-muted)', marginTop: 2 }}>{sub}</div></div><div style={{ width: 20, height: 20, borderRadius: 10, background: s.value === id ? 'var(--accent-b)' : 'transparent', border: '2px solid ' + (s.value === id ? 'var(--accent-b)' : 'var(--border)'), display: 'grid', placeItems: 'center' }}>{s.value === id && <span style={{ width: 8, height: 8, borderRadius: 4, background: '#0B0C0F' }}/>}</div></div>)}</div>}
          {s.kind === 'perms' && <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gap: 10 }}>{A_PERMS_SUMMARY.slice(0, 6).map(p => <div key={p.id} style={{ padding: 14, background: 'var(--bg)', border: '1px solid var(--border-soft)', borderRadius: 11 }}><div style={{ fontSize: 12.5, fontFamily: 'Geist', fontWeight: 600 }}>{p.label}</div><div style={{ marginTop: 8, fontSize: 11, fontFamily: 'JetBrains Mono, monospace' }}><span style={{ color: '#6EE7B7' }}>{p.allowed} allow</span><span style={{ color: 'var(--fg-dim)', margin: '0 6px' }}>·</span><span style={{ color: '#F87171' }}>{p.blocked} block</span></div></div>)}</div>}
          {s.kind === 'done' && <div style={{ padding: 28, background: 'color-mix(in oklch,#6EE7B7 8%,var(--bg))', border: '1px solid color-mix(in oklch,#6EE7B7 32%,transparent)', borderRadius: 14, textAlign: 'center' }}><div style={{ fontSize: 72, marginBottom: 8 }}>✓</div><div style={{ fontSize: 15, fontFamily: 'Geist', fontWeight: 600 }}>Privacy review complete</div></div>}
        </div>
        <div style={{ padding: '14px 26px 22px', borderTop: '1px solid var(--border-soft)', display: 'flex', justifyContent: 'flex-end', gap: 8 }}>
          {step > 0 && <button onClick={() => setStep(step - 1)} style={{ padding: '10px 22px', borderRadius: 9, background: 'var(--bg)', border: '1px solid var(--border-soft)', color: 'var(--fg)', fontSize: 12.5, fontWeight: 500, fontFamily: 'inherit', cursor: 'pointer' }}>Back</button>}
          <button onClick={() => step === steps.length - 1 ? onClose() : setStep(step + 1)} style={{ padding: '10px 26px', borderRadius: 9, background: 'var(--fg)', border: 0, color: 'var(--bg)', fontSize: 12.5, fontWeight: 700, fontFamily: 'inherit', cursor: 'pointer' }}>{step === steps.length - 1 ? 'Done' : step === 0 ? 'Start' : 'Continue'}</button>
        </div>
      </div>
    </DScrim>
  );
}

function dKick() { return { fontSize: 10, fontWeight: 700, color: 'var(--fg-dim)', letterSpacing: '0.12em', textTransform: 'uppercase', fontFamily: 'JetBrains Mono, monospace' }; }

Object.assign(window, {
  DScreenCalls, DFindInPage, DZoom, DPageInfo, DClearData, DPermissionPrompt,
  DSadTab, DVoiceSearch, DReader, DPrivacyReview, DScrim,
});
