// Tablet app — iPad shell with collapsible sidebar + tab strip + screen content
// Orientation toggle (landscape/portrait), screen chips for review.

function TabletApp() {
  const [orientation, setOrientation] = React.useState('landscape');
  const [screen, setScreen] = React.useState('ntp');
  const [sidebarOpen, setSidebarOpen] = React.useState(true);
  const [activeTabId, setActiveTabId] = React.useState('ntp');
  // null | 'overview' | 'handle' | 'share' | 'scan'
  const [showAdd, setShowAdd] = React.useState(null);
  const [showFirstRun, setShowFirstRun] = React.useState(false);
  const [privateMode, setPrivateMode] = React.useState(false);
  const [privateToast, setPrivateToast] = React.useState(false);
  // null | DOMRect — when set, anchors the overflow menu
  const [menuAnchor, setMenuAnchor] = React.useState(null);
  // null | groupId — when set we're in group detail view
  const [activeGroupId, setActiveGroupId] = React.useState(null);
  const [showNewGroup, setShowNewGroup] = React.useState(false);
  const [overlay, setOverlay] = React.useState(null);  // page-level overlays
  const [zoom, setZoom] = React.useState(100);
  const wrapRef = React.useRef(null);
  const [scale, setScale] = React.useState(1);
  const websiteScrollRef = React.useRef(null);
  const [chromeCompact, setChromeCompact] = React.useState(false);
  const lastDirRef = React.useRef({ y: 0 });

  const landscape = orientation === 'landscape';
  const dim = landscape ? TABLET_LANDSCAPE : TABLET_PORTRAIT;
  const FRAME_W = dim.w + 36;
  const FRAME_H = dim.h + 36;

  React.useEffect(() => {
    const fit = () => {
      const el = wrapRef.current;
      if (!el) return;
      const r = el.getBoundingClientRect();
      const sx = (r.width  - 16) / FRAME_W;
      const sy = (r.height - 16) / FRAME_H;
      const s = Math.min(1, sx, sy);
      setScale(s);
    };
    fit();
    const ro = new ResizeObserver(fit);
    if (wrapRef.current) ro.observe(wrapRef.current);
    window.addEventListener('resize', fit);
    return () => { ro.disconnect(); window.removeEventListener('resize', fit); };
  }, [FRAME_W, FRAME_H]);

  // Browser tabs (top strip) — first one is always the active screen's container
  const tabs = [
    { id: 'ntp',    fav: '⌂', favBg: 'linear-gradient(135deg,#6EE7B7,#60A5FA)', favColor: '#0B0C0F', title: 'New tab',           url: 'ajna://newtab' },
    { id: 'linear', fav: 'L', favBg: '#5E6AD2', title: 'Linear — Inbox',          url: 'linear.app/ajna-inc/inbox' },
    { id: 'gh',     fav: 'G', favBg: '#24292F', title: 'GitHub · ajna-inc',       url: 'github.com/ajna-inc/browser' },
    { id: 'figma',  fav: 'F', favBg: '#000',    title: 'Figma — Ajna iPad explor.', url: 'figma.com/file/ajna-ipad' },
    { id: 'rohan',  fav: 'R', favBg: '#F472B6', title: 'Rohan Sharma',            url: 'ajna://chat/rohan', conn: 'internet' },
  ];

  const sidebarSections = [
    {
      title: 'Ajna',
      items: [
        { id: 'ntp',      icon: MIc.home({ s: 18 }),     label: 'Home' },
        { id: 'tabs',     icon: MIc.tabs({ s: 18 }),     label: 'All tabs',     hint: '6' },
        { id: 'chat',     icon: MIc.chat({ s: 18 }),     label: 'Chat',         badge: 3 },
        { id: 'mesh',     icon: MIc.mesh({ s: 18 }),     label: 'Mesh',         hint: '3 peers' },
        { id: 'files',    icon: MIc.files({ s: 18 }),    label: 'Files' },
        { id: 'calls',    icon: MIc.calls({ s: 18 }),    label: 'Calls' },
      ],
    },
  ];

  const currentTab = tabs.find(t => t.id === activeTabId) || tabs[0];

  // Selecting a sidebar app maps to a screen
  const openScreen = (id) => {
    setScreen(id);
    if (id === 'ntp') setActiveTabId('ntp');
  };

  // Reset compact state whenever the screen changes (only website triggers it)
  React.useEffect(() => { setChromeCompact(false); }, [screen]);

  // Scroll handler with hysteresis — collapse past 40px, expand below 16px
  // and always re-expand if user scrolls UP within 8px.
  const handleWebsiteScroll = (e) => {
    const y = e.currentTarget.scrollTop;
    const last = lastDirRef.current.y;
    const dy = y - last;
    lastDirRef.current.y = y;
    if (y < 16) { setChromeCompact(false); return; }
    if (dy < -8) { setChromeCompact(false); return; }
    if (y > 40 && dy > 4) { setChromeCompact(true); return; }
  };

  const expandChromeAndScroll = () => {
    setChromeCompact(false);
    if (websiteScrollRef.current) websiteScrollRef.current.scrollTo({ top: 0, behavior: 'smooth' });
  };

  const enterPrivate = () => {
    setPrivateMode(true);
    setScreen('private');
    setShowAdd(null);
    setShowFirstRun(false);
    setPrivateToast(true);
    setTimeout(() => setPrivateToast(false), 2400);
  };
  const exitPrivate = () => {
    setPrivateMode(false);
    setScreen('ntp');
  };

  // Map overflow-menu actions onto the prototype's state.
  // Most actions are stubs (no real history/downloads to open), but the ones
  // that DO have a destination route correctly — esp. "New private tab".
  const onMenuAction = (id) => {
    if (id === 'new-private') { enterPrivate(); return; }
    if (id === 'new-tab')     { setPrivateMode(false); setScreen('ntp'); return; }
    if (id === 'settings')    { setPrivateMode(false); setScreen('settings'); return; }
    if (id === 'bookmarks' || id === 'history' || id === 'downloads' || id === 'passwords' || id === 'reading-list' || id === 'permissions' || id === 'help' || id === 'credits') {
      setPrivateMode(false); setScreen(id); return;
    }
    if (id === 'reopen') { setPrivateMode(false); setScreen('recently-closed'); return; }
    // Page-action overlays
    if (['find', 'zoom', 'page-info', 'clear', 'reader', 'voice', 'privacy-review', 'sad-tab', 'permission-prompt'].includes(id)) {
      setOverlay(id); return;
    }
    // Other ids (reload, copy-url, share, translate, request-desktop, pin-tab,
    // pip, mute-tab, save-pdf, print) are page-action stubs
  };

  const ScreenView = () => {
    switch (screen) {
      case 'ntp':         return <TScreenNTP landscape={landscape} onOpenSearch={() => {}}/>;
      case 'tabs':        return <TScreenTabs landscape={landscape} onOpenPrivate={enterPrivate} onOpenGroup={(id) => { setScreen('groups'); setActiveGroupId(id); }} onNewGroup={() => setShowNewGroup(true)}/>;
      case 'groups':      return activeGroupId
                            ? <TGroupDetail groupId={activeGroupId} landscape={landscape} onBack={() => setActiveGroupId(null)}/>
                            : <TGroupsOverview landscape={landscape} onOpen={(id) => setActiveGroupId(id)} onNewGroup={() => setShowNewGroup(true)}/>;
      case 'chat':        return <TScreenChatSplit landscape={landscape} onAdd={setShowAdd}/>;
      case 'chat-empty':  return <TScreenChatSplit landscape={landscape} empty onAdd={setShowAdd}/>;
      case 'thread-empty':return <TScreenChatSplit landscape={landscape} threadEmpty onAdd={setShowAdd}/>;
      case 'group':       return <TScreenChatSplit landscape={landscape} group onAdd={setShowAdd}/>;
      case 'mesh':        return <TScreenMesh landscape={landscape}/>;
      case 'site':        return <TScreenWebsite landscape={landscape} scrollRef={websiteScrollRef} onScroll={handleWebsiteScroll}/>;
      case 'files':       return <TabletEmpty icon={MIc.files} title="Files" subtitle="Synced over DIDComm · 0 items"/>;
      case 'calls':       return <TScreenCallsEmpty onCall={() => {}}/>;
      case 'settings':    return <TScreenSettings landscape={landscape}/>;
      case 'history':       return <TScreenHistory       landscape={landscape} onOpen={() => { setPrivateMode(false); setScreen('ntp'); }}/>;
      case 'bookmarks':     return <TScreenBookmarks     landscape={landscape} onOpen={() => { setPrivateMode(false); setScreen('ntp'); }}/>;
      case 'downloads':     return <TScreenDownloads     landscape={landscape} onOpen={() => {}}/>;
      case 'recently-closed': return <TScreenRecentlyClosed onOpen={() => { setPrivateMode(false); setScreen('ntp'); }}/>;
      case 'passwords':     return <TScreenPasswords/>;
      case 'reading-list':  return <TScreenReadingList   onOpen={() => setOverlay('reader')}/>;
      case 'permissions':   return <TScreenSitePermissions/>;
      case 'help':          return <TScreenHelp/>;
      case 'credits':       return <TScreenCredits/>;
      default:            return <TScreenNTP landscape={landscape}/>;
    }
  };

  // ── outer review chrome ──
  const chips = [
    { id: 'ntp',          label: 'Home' },
    { id: 'tabs',         label: 'Tabs' },
    { id: 'chat',         label: 'Chat · split' },
    { id: 'group',        label: 'Chat · group' },
    { id: 'chat-empty',   label: 'Chat · empty' },
    { id: 'thread-empty', label: 'New thread' },
    { id: 'mesh',         label: 'Mesh' },
    { id: 'settings',     label: 'Settings' },
    { id: 'site',         label: 'Website' },
    { id: '__private',    label: '🎭 Private' },
    { id: '__add',        label: '+ Add' },
    { id: '__setup',      label: 'First-run' },
  ];
  const onChip = (id) => {
    if (id === '__add') { setShowAdd('overview'); return; }
    if (id === '__setup') { setShowFirstRun(true); return; }
    if (id === '__private') { enterPrivate(); return; }
    setShowAdd(null);
    setShowFirstRun(false);
    if (privateMode && id !== 'private' && id !== 'private-tabs') setPrivateMode(false);
    openScreen(id);
  };

  return (
    <div style={{
      width: '100%', height: '100%',
      background: 'radial-gradient(ellipse at 50% 30%, #1a1c22 0%, #0a0b0d 100%)',
      display: 'flex', flexDirection: 'column', overflow: 'hidden',
    }}>
      {/* top review controls */}
      <div style={{
        display: 'flex', gap: 6, justifyContent: 'center', alignItems: 'center',
        padding: '16px 24px 12px', flexShrink: 0, flexWrap: 'wrap',
      }}>
        {chips.map(c => {
          const active = (c.id === '__add' && showAdd) || (c.id === '__setup' && showFirstRun) || (c.id === '__private' && privateMode) || (!c.id.startsWith('__') && screen === c.id && !showAdd && !showFirstRun);
          return (
            <button key={c.id} onClick={() => onChip(c.id)} style={{
              padding: '5px 11px', borderRadius: 999,
              background: active ? (c.id === '__private' ? 'rgba(167,139,250,0.18)' : 'rgba(255,255,255,0.1)') : 'transparent',
              color: active ? (c.id === '__private' ? '#C4B5FD' : '#ECECEE') : 'rgba(236,236,238,0.45)',
              border: '1px solid ' + (active && c.id === '__private' ? 'rgba(167,139,250,0.4)' : 'rgba(255,255,255,0.08)'),
              cursor: 'pointer',
              fontSize: 11, fontFamily: 'Inter, sans-serif',
            }}>{c.label}</button>
          );
        })}
        <div style={{ width: 1, height: 16, background: 'rgba(255,255,255,0.1)', margin: '0 6px' }}/>
        <div style={{ display: 'inline-flex', background: 'rgba(255,255,255,0.04)', borderRadius: 999, padding: 2, gap: 2 }}>
          {['landscape','portrait'].map(o => (
            <button key={o} onClick={() => setOrientation(o)} style={{
              padding: '4px 10px', borderRadius: 999,
              background: orientation === o ? 'rgba(255,255,255,0.1)' : 'transparent',
              color: orientation === o ? '#ECECEE' : 'rgba(236,236,238,0.45)',
              border: 0, cursor: 'pointer', fontSize: 11, fontFamily: 'Inter, sans-serif',
              textTransform: 'capitalize',
            }}>{o}</button>
          ))}
        </div>
      </div>

      {/* device frame */}
      <div ref={wrapRef} style={{ flex: 1, display: 'flex', justifyContent: 'center', alignItems: 'center', padding: '0 24px 16px', overflow: 'hidden', minHeight: 0 }}>
        <div style={{
          width: FRAME_W, height: FRAME_H,
          transform: `scale(${scale})`, transformOrigin: 'center center',
          flexShrink: 0,
        }}>
        <TDevice orientation={orientation}>
          {privateMode ? (
            <div style={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column', background: PRIV_BG, position: 'relative' }}>
              <TStatusBar/>
              <TPrivateTabStrip
                tabs={[
                  { id: 'p1', fav: 'D', favBg: '#7C3AED', title: 'Search', url: 'duckduckgo.com' },
                  { id: 'p2', fav: 'W', favBg: '#000',    title: 'Wikipedia', url: 'en.wikipedia.org' },
                ]}
                activeId={'p1'}
                onToggleSidebar={() => setSidebarOpen(o => !o)}
                sidebarOpen={sidebarOpen}
                currentUrl={screen === 'private-tabs' ? 'ajna://private/tabs' : 'ajna://private/newtab'}
                onExitPrivate={exitPrivate}
                onMore={(rect) => setMenuAnchor(rect)}
              />
              <div style={{ flex: 1, display: 'flex', minHeight: 0, background: PRIV_BG }}>
                {sidebarOpen && (
                  <TPrivateSidebar
                    screen={screen === 'private-tabs' ? 'private-tabs' : 'private'}
                    onPick={(id) => setScreen(id)}
                    onExit={exitPrivate}
                  />
                )}
                <main style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column' }}>
                  {screen === 'private-tabs' ? <TPrivateTabs landscape={landscape} onExitPrivate={exitPrivate}/> : <TPrivateNTP landscape={landscape}/>}
                </main>
              </div>
              <THomeIndicator/>
              {privateToast && <TPrivateEntryToast/>}
              {menuAnchor && <TMoreMenu anchorRect={menuAnchor} onClose={() => setMenuAnchor(null)} onAction={onMenuAction} privateMode/>}
              {overlay === 'find'      && <TFindInPage onClose={() => setOverlay(null)}/>}
              {overlay === 'zoom'      && <TZoomControl value={zoom} onChange={setZoom} onClose={() => setOverlay(null)}/>}
              {overlay === 'page-info' && <TPageInfo onClose={() => setOverlay(null)}/>}
              {overlay === 'clear'     && <TClearDataSheet onClose={() => setOverlay(null)}/>}
              {overlay === 'reader'    && <TReader onClose={() => setOverlay(null)}/>}
              {overlay === 'voice'     && <TVoiceSearch onClose={() => setOverlay(null)} onCommit={() => setOverlay(null)}/>}
              {overlay === 'privacy-review' && <TPrivacyReview onClose={() => setOverlay(null)}/>}
              {overlay === 'permission-prompt' && <TPermissionPrompt onResolve={() => setOverlay(null)}/>}
              {overlay === 'sad-tab'   && <TSadTab onClose={() => setOverlay(null)}/>}
            </div>
          ) : (
          <div style={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column', background: M_BG }}>
            <TStatusBar/>
            <TTabStrip
              tabs={tabs}
              activeId={activeTabId}
              onActivate={(id) => {
                setActiveTabId(id);
                if (id === 'ntp') setScreen('ntp');
                else if (id === 'rohan') setScreen('chat');
              }}
              onNewTab={() => {}}
              onClose={() => {}}
              onToggleSidebar={() => setSidebarOpen(o => !o)}
              sidebarOpen={sidebarOpen}
              currentUrl={screen === 'site' ? 'engineering.example.com/post/p2p-browsers' : currentTab.url}
              onUrlClick={() => {}}
              compact={screen === 'site' && chromeCompact}
              onExpand={expandChromeAndScroll}
              onMore={(rect) => setMenuAnchor(rect)}
              onBack={() => {
                if (screen === 'site') setScreen('ntp');
                else if (activeGroupId) setActiveGroupId(null);
                else if (screen !== 'ntp') setScreen('ntp');
              }}
              canBack={screen === 'site' || !!activeGroupId || screen !== 'ntp'}
              canForward={false}
            />

            {/* body: sidebar + content */}
            <div style={{ flex: 1, display: 'flex', minHeight: 0, background: M_BG }}>
              {sidebarOpen && (
                <aside style={{
                  width: 220, flexShrink: 0,
                  background: M_SURFACE,
                  borderRight: '1px solid ' + M_BORDER_SOFT,
                  padding: '12px 10px',
                  display: 'flex', flexDirection: 'column', gap: 14, minHeight: 0, overflow: 'auto',
                }}>
                  {sidebarSections.map((sec, i) => {
                    return (
                      <div key={i}>
                        <div style={{
                          fontSize: 10, color: M_FG_DIM, letterSpacing: '0.12em',
                          textTransform: 'uppercase', fontWeight: 600,
                          padding: '4px 11px 6px',
                        }}>{sec.title}</div>
                        <div style={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
                          {sec.items.map(it => (
                            <TSidebarItem key={it.id}
                              icon={it.icon} label={it.label}
                              active={screen === it.id && (it.id !== 'groups' || !activeGroupId)}
                              onClick={() => { if (it.id === 'groups') setActiveGroupId(null); openScreen(it.id); }}
                              badge={it.badge} hint={it.hint}
                            />
                          ))}
                        </div>
                      </div>
                    );
                  })}

                  <div style={{ marginTop: 'auto', padding: '8px 8px 4px', borderTop: '1px solid ' + M_BORDER_SOFT }}>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '6px 6px' }}>
                      <MTile size={26} bg="#A78BFA" color="#fff" label="MC" radius={13}/>
                      <div style={{ flex: 1, minWidth: 0 }}>
                        <div style={{ fontSize: 12, fontWeight: 500, color: M_FG, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>Maya Chen</div>
                        <div style={{ fontSize: 10, color: M_FG_DIM, fontFamily: 'JetBrains Mono, monospace' }}>did:key:…9kTp</div>
                      </div>
                      <button style={tIconBtn(false)} aria-label="Settings">{MIc.settings({ s: 14 })}</button>
                    </div>
                  </div>
                </aside>
              )}

              {/* main */}
              <main style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column' }}>
                <ScreenView/>
              </main>
            </div>

            <THomeIndicator/>

            {/* Add connection — iPad centered dialog */}
            {showAdd && (
              <TScreenAddConnection
                mode={showAdd}
                landscape={landscape}
                onClose={() => setShowAdd(null)}
              />
            )}

            {/* First-run setup — wraps mobile flow in an iPad-sized centered card */}
            {showFirstRun && (
              <TFirstRunOverlay onClose={() => setShowFirstRun(false)}/>
            )}

            {/* Overflow menu */}
            {menuAnchor && <TMoreMenu anchorRect={menuAnchor} onClose={() => setMenuAnchor(null)} onAction={onMenuAction}/>}

            {/* Page-level overlays — Arc-style, surface from the menu popover */}
            {overlay === 'find'      && <TFindInPage onClose={() => setOverlay(null)}/>}
            {overlay === 'zoom'      && <TZoomControl value={zoom} onChange={setZoom} onClose={() => setOverlay(null)}/>}
            {overlay === 'page-info' && <TPageInfo onClose={() => setOverlay(null)}/>}
            {overlay === 'clear'     && <TClearDataSheet onClose={() => setOverlay(null)}/>}
            {overlay === 'reader'    && <TReader onClose={() => setOverlay(null)}/>}
            {overlay === 'voice'     && <TVoiceSearch onClose={() => setOverlay(null)} onCommit={() => setOverlay(null)}/>}
            {overlay === 'privacy-review' && <TPrivacyReview onClose={() => setOverlay(null)}/>}
            {overlay === 'permission-prompt' && <TPermissionPrompt onResolve={() => setOverlay(null)}/>}
            {overlay === 'sad-tab'   && <TSadTab onClose={() => setOverlay(null)}/>}

            {/* New tab group dialog */}
            {showNewGroup && <TNewGroupDialog onClose={() => setShowNewGroup(false)} onCreate={() => setShowNewGroup(false)}/>}
          </div>
          )}
        </TDevice>
        </div>
      </div>

      {/* bottom info strip */}
      <div style={{
        padding: '10px 20px', background: 'rgba(10,11,13,0.85)',
        borderTop: '1px solid rgba(255,255,255,0.06)',
        backdropFilter: 'blur(12px)',
        display: 'flex', alignItems: 'center', gap: 16, flexShrink: 0,
        fontSize: 11, fontFamily: 'JetBrains Mono, monospace', color: 'rgba(236,236,238,0.55)',
      }}>
        <span style={{ color: '#6EE7B7' }}>●</span>
        <span style={{ flex: 1 }}>
          iPad · {orientation} · {sidebarOpen ? 'sidebar open' : 'sidebar collapsed'}
          {screen === 'chat' && landscape && ' · master-detail split'}
          {screen === 'site' && (chromeCompact ? ' · chrome collapsed (scroll to top or tap pill to expand)' : ' · scroll page to collapse chrome')}
        </span>
        <span>{TABLET_LANDSCAPE.w}×{TABLET_LANDSCAPE.h} landscape · {TABLET_PORTRAIT.w}×{TABLET_PORTRAIT.h} portrait</span>
      </div>
    </div>
  );
}

function TabletEmpty({ icon, title, subtitle }) {
  return (
    <div style={{ flex: 1, display: 'grid', placeItems: 'center', color: M_FG_MUTED, padding: 40, textAlign: 'center' }}>
      <div>
        <div style={{ opacity: 0.4, marginBottom: 14 }}>{icon({ s: 44 })}</div>
        <div style={{ fontSize: 18, fontFamily: 'Geist', fontWeight: 600, color: M_FG, letterSpacing: '-0.02em' }}>{title}</div>
        {subtitle && <div style={{ fontSize: 12, color: M_FG_MUTED, marginTop: 6 }}>{subtitle}</div>}
      </div>
    </div>
  );
}

// First-run overlay — embeds the mobile MFirstRunFlow in an iPad-sized centered card.
// On iPad, onboarding feels native as a focused modal panel rather than a full-screen wash.
function TFirstRunOverlay({ onClose }) {
  return (
    <div style={{ position: 'absolute', inset: 0, zIndex: 90 }}>
      <div onClick={onClose} style={{
        position: 'absolute', inset: 0,
        background: 'rgba(7,8,10,0.78)', backdropFilter: 'blur(12px)',
        animation: 'tFade 220ms ease',
      }}/>
      <div style={{
        position: 'absolute', top: '50%', left: '50%',
        transform: 'translate(-50%, -50%)',
        width: 460, height: 720, maxHeight: '92%',
        background: M_BG, border: '1px solid ' + M_BORDER,
        borderRadius: 28, overflow: 'hidden',
        boxShadow: '0 50px 120px -20px rgba(0,0,0,0.75), 0 0 0 1px rgba(255,255,255,0.04)',
        animation: 'tPop 260ms cubic-bezier(0.2,0.8,0.2,1)',
        display: 'flex', flexDirection: 'column',
      }}>
        <div style={{
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          padding: '14px 18px', borderBottom: '1px solid ' + M_BORDER_SOFT,
          flexShrink: 0,
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            <div style={{
              width: 26, height: 26, borderRadius: 8,
              background: 'linear-gradient(135deg,' + M_ACCENT + ',' + M_ACCENT_B + ')',
              display: 'grid', placeItems: 'center', color: '#0B0C0F',
              fontFamily: 'Geist', fontSize: 13, fontWeight: 700,
            }}>A</div>
            <div style={{ fontSize: 13, fontWeight: 600, fontFamily: 'Geist, Inter, sans-serif', letterSpacing: '-0.01em' }}>Set up Ajna</div>
          </div>
          <button onClick={onClose} style={{
            width: 28, height: 28, borderRadius: 8,
            background: M_SURFACE, border: '1px solid ' + M_BORDER_SOFT,
            color: M_FG_MUTED, display: 'grid', placeItems: 'center', cursor: 'pointer',
          }}>{MIc.close({ s: 13 })}</button>
        </div>
        <div style={{ flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
          <MFirstRunFlow onComplete={onClose}/>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { TabletApp });
