// boot-screens.jsx — §00 Boot & onboarding A–F
// A: Cold boot splash · B: Permissions · C: Helper install · D: Token check
// E: Provider missing · F: Update available

const BOOT_W = 1280;
const BOOT_H = 800;

// Boot frame: borderless macOS window, no traffic lights for some scenarios
function BootFrame({ dark, children, chrome = true }) {
  const t = dark ? G.d : G.l;
  return (
    <div style={{
      width: BOOT_W, height: BOOT_H, background: t.bg, color: t.fg,
      fontFamily: G.font, fontSize: 14, position: 'relative', overflow: 'hidden',
      borderRadius: 12, border: `1px solid ${t.border}`,
    }}>
      {chrome && (
        <div style={{ position: 'absolute', top: 12, left: 14, display: 'flex', gap: 7, zIndex: 5 }}>
          <div style={{ width: 12, height: 12, borderRadius: 6, background: '#ff5f57' }} />
          <div style={{ width: 12, height: 12, borderRadius: 6, background: '#febc2e' }} />
          <div style={{ width: 12, height: 12, borderRadius: 6, background: '#28c840' }} />
        </div>
      )}
      {children}
    </div>
  );
}

// ═════════════════════════════════════════════════════════════
// E · PROVIDER MISSING (chat empty + giant CTA)
// ═════════════════════════════════════════════════════════════

function BootProviderMissing({ dark }) {
  const t = dark ? G.d : G.l;
  const cards = [
    { name: 'Anthropic', desc: 'Claude 4.5 Sonnet · Haiku', logo: 'A', color: '#D97757', recommended: true },
    { name: 'OpenAI', desc: 'GPT-4 · GPT-4o · o3', logo: 'O', color: '#10A37F' },
    { name: 'Local', desc: 'Ollama · LM Studio', logo: 'L', color: t.fg2 },
    { name: 'Others', desc: 'Mistral · Together · Groq', logo: '+', color: t.fg3 },
  ];

  return (
    <AppShell dark={dark} active="chat" sidebar={chatSidebar(dark)}
      topBar={<AppTopBar dark={dark} breadcrumbs={['Chat']} />}
    >
      <div style={{ height: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: 40 }}>
        <GhastLogo size={48} color={t.fg2} style={{ marginBottom: 18 }} />
        <div style={{ fontSize: 26, fontWeight: 500, letterSpacing: -0.4, marginBottom: 6 }}>Add your first model to start</div>
        <div style={{ fontSize: 13, color: t.fg3, marginBottom: 32, textAlign: 'center', maxWidth: 480 }}>
          Ghast doesn't bundle a default model. Pick a provider below — you can add more later, and switch per message.
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 200px)', gap: 12, marginBottom: 24 }}>
          {cards.map(c => (
            <div key={c.name} style={{
              padding: '20px 18px', background: t.surface, border: `1px solid ${c.recommended ? t.fg : t.border}`,
              borderRadius: 14, cursor: 'pointer', position: 'relative',
            }}>
              {c.recommended && <Tag style={{ position: 'absolute', top: -10, left: 14, height: 18, fontSize: 9, background: t.fg, color: t.bg, border: 'none' }}>Recommended</Tag>}
              <div style={{ width: 32, height: 32, borderRadius: 8, background: c.color, color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 16, fontWeight: 600, marginBottom: 12 }}>{c.logo}</div>
              <div style={{ fontSize: 14, fontWeight: 500, marginBottom: 4 }}>{c.name}</div>
              <div style={{ fontSize: 11, color: t.fg3, lineHeight: 1.4 }}>{c.desc}</div>
              <div style={{ marginTop: 16, fontSize: 11, color: t.fg2, display: 'flex', alignItems: 'center', gap: 4 }}>
                Add <Icon name="arrowRight" size={11} color={t.fg2} />
              </div>
            </div>
          ))}
        </div>
        <a style={{ fontSize: 12, color: t.fg3, textDecoration: 'underline', cursor: 'pointer' }}>I'll do this later</a>
      </div>
    </AppShell>
  );
}


// ═════════════════════════════════════════════════════════════
// F · UPDATE AVAILABLE
// ═════════════════════════════════════════════════════════════

function BootUpdateAvailable({ dark, variant = 'dock-idle' }) {
  const t = dark ? G.d : G.l;

  // ── Dock idle: just the arrow-down-to-line icon w/ red dot, no popover ──
  if (variant === 'dock-idle' || variant === 'banner') {
    return (
      <AppShell dark={dark} active="settings" sidebar={null}
        update={{ available: true, version: '0.2.1', title: 'Ghast 0.2.1 available — click to review' }}
        topBar={<AppTopBar dark={dark} breadcrumbs={['Settings']} />}
      >
        <div style={{ padding: 40, fontSize: 14, color: t.fg3 }}>Settings · General</div>
      </AppShell>
    );
  }

  // ── Dock popover: clicked the dock icon, small card flies out next to dock ──
  if (variant === 'dock-popover') {
    return (
      <AppShell dark={dark} active="update" sidebar={null}
        update={{ available: true, version: '0.2.1', title: 'Ghast 0.2.1 available' }}
        topBar={<AppTopBar dark={dark} breadcrumbs={['Settings']} />}
      >
        <div style={{ padding: 40, fontSize: 14, color: t.fg3 }}>Settings · General</div>
        {/* Popover anchored to the dock — sits at left:84 (dock width + gap) */}
        <div style={{
          position: 'absolute', left: 78, bottom: 96, width: 320,
          background: t.bg, border: `1px solid ${t.border}`, borderRadius: 14,
          boxShadow: t.shadowLg || '0 16px 40px rgba(0,0,0,0.18), 0 4px 10px rgba(0,0,0,0.06)',
          padding: 16,
        }}>
          {/* Tail pointing back at the dock icon */}
          <div style={{
            position: 'absolute', left: -6, bottom: 36, width: 12, height: 12,
            background: t.bg, borderLeft: `1px solid ${t.border}`, borderBottom: `1px solid ${t.border}`,
            transform: 'rotate(45deg)',
          }} />
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 4 }}>
            <div style={{
              width: 28, height: 28, borderRadius: 8, background: t.surface2,
              display: 'flex', alignItems: 'center', justifyContent: 'center',
            }}>
              <Icon name="arrow-down-to-line" size={14} color={t.fg2} />
            </div>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 13, fontWeight: 600, letterSpacing: -0.1 }}>Ghast 0.2.1</div>
              <div style={{ fontSize: 10.5, color: t.fg3, fontFamily: G.mono }}>52 MB · stable channel</div>
            </div>
            <Tag>New</Tag>
          </div>
          <div style={{ fontSize: 12, color: t.fg2, lineHeight: 1.55, margin: '10px 0 12px' }}>
            Better tool-use, faster boot, fewer crashes. Multi-cursor in editor; agent budget caps.
          </div>
          <div style={{ display: 'flex', gap: 6, marginBottom: 12 }}>
            <span style={{ fontSize: 10.5, color: t.fg3, fontFamily: G.mono }}>0.2.0 → 0.2.1</span>
            <span style={{ flex: 1 }} />
            <a style={{ fontSize: 11, color: t.fg2, textDecoration: 'underline', cursor: 'pointer' }}>What's new</a>
          </div>
          <div style={{ display: 'flex', gap: 8 }}>
            <Button variant="ghost" size="sm" style={{ flex: 1 }}>On next quit</Button>
            <Button variant="primary" size="sm" icon={<Icon name="arrow-down-to-line" size={11} color={t.bg} />} style={{ flex: 1.4 }}>
              Update now
            </Button>
          </div>
        </div>
      </AppShell>
    );
  }

  if (variant === 'changelog') {
    return (
      <BootFrame dark={dark}>
        <div style={{ position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.4)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <div style={{ width: 600, maxHeight: 640, background: t.bg, borderRadius: 14, border: `1px solid ${t.border}`, boxShadow: t.shadow, overflow: 'hidden', display: 'flex', flexDirection: 'column' }}>
            {/* Hero */}
            <div style={{ padding: '40px 32px 24px', background: dark ? '#111' : '#fafaf9', borderBottom: `1px solid ${t.border}` }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 6 }}>
                <Tag style={{ background: '#5865F2', color: '#fff', border: 'none' }}>0.2.1</Tag>
                <span style={{ fontSize: 11, color: t.fg3, fontFamily: G.mono }}>May 4, 2026</span>
              </div>
              <div style={{ fontSize: 22, fontWeight: 500, letterSpacing: -0.3 }}>Faster, calmer, harder to break</div>
            </div>
            {/* Body */}
            <div className="gh-scroll" style={{ flex: 1, overflow: 'auto', padding: 28, fontSize: 13, lineHeight: 1.6, color: t.fg2 }}>
              <div style={{ display: 'flex', gap: 12, marginBottom: 18 }}>
                <Tag>New</Tag>
                <div><strong style={{ color: t.fg }}>Multi-cursor in editor.</strong> Hold ⌥ and click to drop additional cursors — like in Cursor.</div>
              </div>
              <div style={{ display: 'flex', gap: 12, marginBottom: 18 }}>
                <Tag>New</Tag>
                <div><strong style={{ color: t.fg }}>Agent budget caps.</strong> Set a max token spend per agent run; soft warning at 80%, hard stop at 100%.</div>
              </div>
              <div style={{ display: 'flex', gap: 12, marginBottom: 18 }}>
                <Tag style={{ background: 'rgba(40,200,64,0.15)', color: '#28c840', border: 'none' }}>Faster</Tag>
                <div><strong style={{ color: t.fg }}>Boot 2.4× faster.</strong> Skills now load lazily; chat opens before all providers connect.</div>
              </div>
              <div style={{ display: 'flex', gap: 12, marginBottom: 18 }}>
                <Tag>Fixed</Tag>
                <div>Markdown tables no longer overflow on narrow chat panes (#4189).</div>
              </div>
              <div style={{ display: 'flex', gap: 12, marginBottom: 4 }}>
                <Tag>Fixed</Tag>
                <div>Tool calls hanging on flaky network — now retried with backoff (#4202).</div>
              </div>
            </div>
            {/* Actions */}
            <div style={{ padding: '14px 24px', borderTop: `1px solid ${t.border}`, display: 'flex', gap: 8, alignItems: 'center' }}>
              <a style={{ fontSize: 12, color: t.fg3, textDecoration: 'underline', cursor: 'pointer' }}>Full changelog</a>
              <span style={{ flex: 1 }} />
              <Button variant="ghost" size="sm">Update on next quit</Button>
              <Button variant="primary" size="sm">Update and restart</Button>
            </div>
          </div>
        </div>
      </BootFrame>
    );
  }

  if (variant === 'downloading') {
    return (
      <BootFrame dark={dark}>
        <div style={{ position: 'absolute', inset: 0, background: 'transparent' }}>
          <div style={{ padding: 60, fontSize: 14, color: t.fg3 }}>Settings · General</div>
        </div>
        <div style={{
          position: 'absolute', bottom: 24, right: 24, width: 280, padding: '12px 16px',
          background: t.surface, border: `1px solid ${t.border}`, borderRadius: 12, boxShadow: t.shadow,
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 8 }}>
            <Icon name="download" size={14} color={t.fg2} />
            <span style={{ fontSize: 13, fontWeight: 500, flex: 1 }}>Downloading 0.2.1</span>
            <span style={{ fontSize: 11, fontFamily: G.mono, color: t.fg3 }}>72%</span>
          </div>
          <div style={{ width: '100%', height: 3, background: t.surface2, borderRadius: 2, overflow: 'hidden' }}>
            <div style={{ width: '72%', height: '100%', background: '#5865F2' }} />
          </div>
          <div style={{ fontSize: 10, color: t.fg3, fontFamily: G.mono, marginTop: 6 }}>32 MB / 44 MB · 1.2 MB/s</div>
        </div>
      </BootFrame>
    );
  }

  // ── Download complete · waiting for user to restart ──
  if (variant === 'restart') {
    return (
      <BootFrame dark={dark}>
        <div style={{ position: 'absolute', inset: 0 }}>
          <div style={{ padding: 60, fontSize: 14, color: t.fg3 }}>Settings · General</div>
        </div>
        <div style={{
          position: 'absolute', bottom: 24, right: 24, width: 320, padding: '14px 16px',
          background: t.surface, border: `1px solid ${t.border}`, borderRadius: 12, boxShadow: t.shadow,
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 4 }}>
            <Icon name="check" size={14} color="#28c840" />
            <span style={{ fontSize: 13, fontWeight: 600, flex: 1 }}>Ghast 0.2.1 ready to install</span>
          </div>
          <div style={{ fontSize: 11, color: t.fg3, lineHeight: 1.55, marginBottom: 12 }}>
            Restart now or finish what you're doing — we'll install on your next quit.
          </div>
          <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
            <Button variant="ghost" size="sm">Later</Button>
            <Button variant="primary" size="sm" icon={<Icon name="refresh" size={11} color={t.bg} />}>Restart now</Button>
          </div>
        </div>
      </BootFrame>
    );
  }

  // ── Installing — full-screen progress, blocks input ──
  if (variant === 'installing') {
    const phases = [
      { label: 'Verifying signature', done: true },
      { label: 'Replacing app bundle', done: true, active: false },
      { label: 'Migrating settings',   done: false, active: true },
      { label: 'Restarting',           done: false, active: false },
    ];
    return (
      <BootFrame dark={dark}>
        <div style={{
          position: 'absolute', inset: 0,
          display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
          background: dark ? '#0a0a0a' : '#fafaf9', gap: 36,
        }}>
          <GhastLogo size={72} dark={dark} style={{ opacity: 0.95 }} />
          <div style={{ textAlign: 'center' }}>
            <div style={{ fontSize: 20, fontWeight: 600, letterSpacing: -0.4 }}>Installing Ghast 0.2.1</div>
            <div style={{ fontSize: 12, color: t.fg3, marginTop: 6 }}>Don't quit — we'll bring you back in a moment.</div>
          </div>
          {/* Phase list */}
          <div style={{ width: 320 }}>
            {phases.map((p, i) => (
              <div key={i} style={{
                display: 'flex', alignItems: 'center', gap: 12, padding: '8px 0',
                borderBottom: i === phases.length - 1 ? 'none' : `0.5px solid ${t.border2}`,
                opacity: p.done || p.active ? 1 : 0.4,
              }}>
                {p.done ? (
                  <Icon name="check" size={13} color="#28c840" />
                ) : p.active ? (
                  <span style={{
                    width: 12, height: 12, borderRadius: 6,
                    border: `1.5px solid ${t.fg2}`, borderTopColor: 'transparent',
                    animation: 'gh-spin .8s linear infinite',
                  }} />
                ) : (
                  <span style={{ width: 12, height: 12, borderRadius: 6, border: `1.5px solid ${t.fg4}` }} />
                )}
                <span style={{ fontSize: 13, color: p.done || p.active ? t.fg : t.fg3 }}>{p.label}</span>
              </div>
            ))}
          </div>
          {/* Progress bar */}
          <div style={{ width: 320 }}>
            <div style={{ height: 3, background: t.surface2, borderRadius: 2, overflow: 'hidden' }}>
              <div style={{ width: '62%', height: '100%', background: t.fg, transition: 'width .3s ease' }} />
            </div>
            <div style={{ marginTop: 8, fontSize: 11, color: t.fg3, fontFamily: G.mono, textAlign: 'center' }}>
              62% · ETA 8s
            </div>
          </div>
        </div>
      </BootFrame>
    );
  }

  // ── Failed: network drop during download ──
  if (variant === 'failed-network') {
    return (
      <BootFrame dark={dark}>
        <div style={{ padding: 60, fontSize: 14, color: t.fg3 }}>Settings · General</div>
        <div style={{
          position: 'absolute', bottom: 24, right: 24, width: 320, padding: '14px 16px',
          background: t.surface, border: `1px solid #ff5f57`, borderRadius: 12, boxShadow: t.shadow,
        }}>
          <div style={{ display: 'flex', alignItems: 'flex-start', gap: 10, marginBottom: 8 }}>
            <Icon name="warn" size={14} color="#ff5f57" style={{ flexShrink: 0, marginTop: 1 }} />
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 13, fontWeight: 600 }}>Download interrupted</div>
              <div style={{ fontSize: 11, color: t.fg3, marginTop: 4, lineHeight: 1.55 }}>
                Lost connection at 32 MB of 44 MB. We've kept the partial file — you can resume.
              </div>
            </div>
          </div>
          <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end', marginTop: 6 }}>
            <Button variant="ghost" size="sm">Cancel</Button>
            <Button variant="secondary" size="sm">Restart</Button>
            <Button variant="primary" size="sm" icon={<Icon name="refresh" size={11} color={t.bg} />}>Resume</Button>
          </div>
        </div>
      </BootFrame>
    );
  }

  // ── Failed: signature verification (potentially tampered binary) ──
  if (variant === 'failed-signature') {
    return (
      <BootFrame dark={dark}>
        <div style={{ position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.5)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <div style={{ width: 460, padding: 28, background: t.bg, borderRadius: 14, border: `1px solid ${t.border}`, boxShadow: t.shadowLg }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 14 }}>
              <div style={{
                width: 36, height: 36, borderRadius: 18,
                background: 'rgba(255,95,87,0.15)', border: `1px solid #ff5f57`,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
              }}>
                <Icon name="lock" size={16} color="#ff5f57" />
              </div>
              <div>
                <div style={{ fontSize: 15, fontWeight: 600 }}>Update signature invalid</div>
                <div style={{ fontSize: 11, color: t.fg3, marginTop: 2, fontFamily: G.mono }}>code: ESIGFAIL</div>
              </div>
            </div>
            <div style={{ fontSize: 13, color: t.fg2, lineHeight: 1.6, marginBottom: 18 }}>
              The downloaded build doesn't match Trapezohe's signing key. We refused to install it. This often means a bad mirror or a corrupted download — but it could also mean tampering. Don't install manually.
            </div>
            <div style={{
              padding: 12, marginBottom: 18,
              background: t.surface2, border: `1px solid ${t.border2}`, borderRadius: 10,
              fontFamily: G.mono, fontSize: 11, color: t.fg2, lineHeight: 1.5,
            }}>
              expected SHA256: <span style={{ color: t.fg }}>9c4a…f018</span><br/>
              received: <span style={{ color: '#ff5f57' }}>e7b1…2d3a</span>
            </div>
            <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
              <Button variant="ghost" size="sm">Report</Button>
              <Button variant="secondary" size="sm">Discard</Button>
              <Button variant="primary" size="sm">Retry from official source</Button>
            </div>
          </div>
        </div>
      </BootFrame>
    );
  }

  // ── Failed: not enough disk space to install ──
  if (variant === 'disk-full') {
    return (
      <BootFrame dark={dark}>
        <div style={{ position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.5)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <div style={{ width: 440, padding: 28, background: t.bg, borderRadius: 14, border: `1px solid ${t.border}`, boxShadow: t.shadowLg }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 14 }}>
              <div style={{
                width: 36, height: 36, borderRadius: 18,
                background: 'rgba(254,188,46,0.15)', border: `1px solid #febc2e`,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
              }}>
                <Icon name="warn" size={16} color="#febc2e" />
              </div>
              <div style={{ fontSize: 15, fontWeight: 600 }}>Not enough disk space</div>
            </div>
            <div style={{ fontSize: 13, color: t.fg2, lineHeight: 1.6, marginBottom: 14 }}>
              The 0.2.1 update needs <strong style={{ color: t.fg }}>340 MB free</strong> on your boot disk. You have 92 MB.
            </div>
            <div style={{
              padding: 12, marginBottom: 18, background: t.surface2,
              border: `1px solid ${t.border2}`, borderRadius: 10,
            }}>
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', fontSize: 12, color: t.fg2, marginBottom: 6 }}>
                <span>Macintosh HD</span>
                <span style={{ fontFamily: G.mono, color: t.fg3 }}>92 MB free of 1 TB</span>
              </div>
              <div style={{ height: 4, background: t.surface, borderRadius: 2, overflow: 'hidden' }}>
                <div style={{ width: '99.1%', height: '100%', background: '#febc2e' }} />
              </div>
            </div>
            <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
              <Button variant="ghost" size="sm">Open Storage</Button>
              <Button variant="secondary" size="sm">Try later</Button>
              <Button variant="primary" size="sm">Choose another disk</Button>
            </div>
          </div>
        </div>
      </BootFrame>
    );
  }

  // ── Force-update (security) — modal with countdown, can't dismiss ──
  if (variant === 'force') {
    return (
      <BootFrame dark={dark}>
        <div style={{ position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.7)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <div style={{ width: 480, padding: 32, background: t.bg, borderRadius: 14, border: `1px solid ${t.border}`, boxShadow: t.shadowLg, textAlign: 'center' }}>
            <div style={{
              width: 48, height: 48, borderRadius: 24, margin: '0 auto 18px',
              background: 'rgba(255,95,87,0.15)', border: `1px solid #ff5f57`,
              display: 'flex', alignItems: 'center', justifyContent: 'center',
            }}>
              <Icon name="warn" size={22} color="#ff5f57" />
            </div>
            <div style={{ fontSize: 17, fontWeight: 600, letterSpacing: -0.3, marginBottom: 8 }}>Critical security update</div>
            <div style={{ fontSize: 13, color: t.fg2, lineHeight: 1.6, marginBottom: 18, maxWidth: 360, margin: '0 auto 18px' }}>
              Ghast 0.2.1 patches <strong style={{ color: t.fg }}>CVE-2026-1284</strong>, a tool-use sandbox escape. We have to update before you can keep using Ghast.
            </div>
            <div style={{
              padding: '8px 14px', marginBottom: 18, marginInline: 'auto', maxWidth: 280,
              background: t.surface2, borderRadius: 8,
              fontFamily: G.mono, fontSize: 12, color: t.fg2,
            }}>
              Auto-installing in <strong style={{ color: '#ff5f57' }}>00:23</strong>
            </div>
            <Button variant="primary" size="md" full>Install now & restart</Button>
            <a style={{ marginTop: 14, display: 'inline-block', fontSize: 11, color: t.fg3, textDecoration: 'underline' }}>Read the advisory</a>
          </div>
        </div>
      </BootFrame>
    );
  }

  // ── Channel switch warning (e.g. user tries stable → dev) ──
  if (variant === 'channel-warn') {
    return (
      <BootFrame dark={dark}>
        <div style={{ position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.5)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <div style={{ width: 440, padding: 28, background: t.bg, borderRadius: 14, border: `1px solid ${t.border}`, boxShadow: t.shadowLg }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 14 }}>
              <div style={{
                width: 36, height: 36, borderRadius: 18,
                background: 'rgba(254,188,46,0.15)', border: `1px solid #febc2e`,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
              }}>
                <Icon name="warn" size={16} color="#febc2e" />
              </div>
              <div>
                <div style={{ fontSize: 15, fontWeight: 600 }}>Switch to Dev channel?</div>
                <div style={{ fontSize: 11, color: t.fg3, fontFamily: G.mono, marginTop: 2 }}>stable → dev</div>
              </div>
            </div>
            <div style={{ fontSize: 13, color: t.fg2, lineHeight: 1.6, marginBottom: 14 }}>
              Dev builds ship hourly straight from main. They can break workflows, corrupt local data, or roll back features without notice.
            </div>
            <div style={{
              padding: 12, marginBottom: 18, background: t.surface2,
              border: `1px solid ${t.border2}`, borderRadius: 10,
              fontSize: 12, color: t.fg2, lineHeight: 1.55,
            }}>
              <div style={{ display: 'flex', gap: 8, alignItems: 'flex-start', marginBottom: 6 }}>
                <Icon name="info" size={11} color={t.fg3} style={{ marginTop: 2, flexShrink: 0 }} />
                <span>Auto-update will fetch a new build every hour you're online.</span>
              </div>
              <div style={{ display: 'flex', gap: 8, alignItems: 'flex-start' }}>
                <Icon name="info" size={11} color={t.fg3} style={{ marginTop: 2, flexShrink: 0 }} />
                <span>Switching back to Stable later may require a clean reinstall.</span>
              </div>
            </div>
            <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
              <Button variant="ghost" size="sm">Cancel</Button>
              <Button variant="primary" size="sm">Switch to Dev</Button>
            </div>
          </div>
        </div>
      </BootFrame>
    );
  }

  // Fallback for unknown variants — show nothing rather than a confusing
  // copy of the downloading state.
  return null;
}


Object.assign(window, {
  BOOT_W, BOOT_H, BootFrame,
  BootProviderMissing, BootUpdateAvailable,
});
