aicodeman 1.18.4 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/README.md +1 -0
  2. package/dist/attachment-registry.d.ts +25 -0
  3. package/dist/attachment-registry.d.ts.map +1 -1
  4. package/dist/attachment-registry.js +45 -1
  5. package/dist/attachment-registry.js.map +1 -1
  6. package/dist/hooks-config.d.ts +22 -16
  7. package/dist/hooks-config.d.ts.map +1 -1
  8. package/dist/hooks-config.js +20 -14
  9. package/dist/hooks-config.js.map +1 -1
  10. package/dist/types/tools.d.ts +1 -1
  11. package/dist/types/tools.d.ts.map +1 -1
  12. package/dist/web/ports/config-port.d.ts +2 -0
  13. package/dist/web/ports/config-port.d.ts.map +1 -1
  14. package/dist/web/public/admin-ui.js.gz +0 -0
  15. package/dist/web/public/api-client.c9b1cddc.js.gz +0 -0
  16. package/dist/web/public/app.a8b08065.js +34 -0
  17. package/dist/web/public/app.a8b08065.js.br +0 -0
  18. package/dist/web/public/app.a8b08065.js.gz +0 -0
  19. package/dist/web/public/approvals-ui.js.gz +0 -0
  20. package/dist/web/public/{constants.04b7b284.js → constants.35c7f91c.js} +133 -0
  21. package/dist/web/public/constants.35c7f91c.js.br +0 -0
  22. package/dist/web/public/constants.35c7f91c.js.gz +0 -0
  23. package/dist/web/public/cron-ui.js.gz +0 -0
  24. package/dist/web/public/entrance-animations.js.gz +0 -0
  25. package/dist/web/public/home-sessions.js +79 -35
  26. package/dist/web/public/home-sessions.js.br +0 -0
  27. package/dist/web/public/home-sessions.js.gz +0 -0
  28. package/dist/web/public/i18n.bb8949de.js +1 -0
  29. package/dist/web/public/i18n.bb8949de.js.br +0 -0
  30. package/dist/web/public/i18n.bb8949de.js.gz +0 -0
  31. package/dist/web/public/image-input.ee16ad88.js.gz +0 -0
  32. package/dist/web/public/index.html +102 -18
  33. package/dist/web/public/index.html.br +0 -0
  34. package/dist/web/public/index.html.gz +0 -0
  35. package/dist/web/public/input-cjk.63794d0b.js.gz +0 -0
  36. package/dist/web/public/keyboard-accessory.0454a3e9.js.gz +0 -0
  37. package/dist/web/public/{mobile-handlers.bc45f976.js → mobile-handlers.05b89237.js} +16 -0
  38. package/dist/web/public/mobile-handlers.05b89237.js.br +0 -0
  39. package/dist/web/public/mobile-handlers.05b89237.js.gz +0 -0
  40. package/dist/web/public/mobile-overview.js +17 -15
  41. package/dist/web/public/mobile-overview.js.br +0 -0
  42. package/dist/web/public/mobile-overview.js.gz +0 -0
  43. package/dist/web/public/mobile.c40d28a6.css +1 -0
  44. package/dist/web/public/mobile.c40d28a6.css.br +0 -0
  45. package/dist/web/public/mobile.c40d28a6.css.gz +0 -0
  46. package/dist/web/public/notification-manager.5d229063.js.gz +0 -0
  47. package/dist/web/public/orchestrator-panel.js.gz +0 -0
  48. package/dist/web/public/{panels-ui.1e4cb4b2.js → panels-ui.c5a82b6e.js} +48 -46
  49. package/dist/web/public/panels-ui.c5a82b6e.js.br +0 -0
  50. package/dist/web/public/panels-ui.c5a82b6e.js.gz +0 -0
  51. package/dist/web/public/ralph-panel.6de2d0f8.js.gz +0 -0
  52. package/dist/web/public/ralph-wizard.13a1831e.js.gz +0 -0
  53. package/dist/web/public/readmymind-ui.js.gz +0 -0
  54. package/dist/web/public/respawn-ui.ff0dae4c.js.gz +0 -0
  55. package/dist/web/public/sanitize-html.bc7078d6.js.gz +0 -0
  56. package/dist/web/public/session-lineage.js +12 -1
  57. package/dist/web/public/session-lineage.js.br +0 -0
  58. package/dist/web/public/session-lineage.js.gz +0 -0
  59. package/dist/web/public/{session-ui.c67565f2.js → session-ui.71a0ce9a.js} +3 -3
  60. package/dist/web/public/session-ui.71a0ce9a.js.br +0 -0
  61. package/dist/web/public/session-ui.71a0ce9a.js.gz +0 -0
  62. package/dist/web/public/{settings-ui.eacb4f92.js → settings-ui.6cb12d4b.js} +2 -2
  63. package/dist/web/public/settings-ui.6cb12d4b.js.br +0 -0
  64. package/dist/web/public/settings-ui.6cb12d4b.js.gz +0 -0
  65. package/dist/web/public/styles.325eb4f3.css +1 -0
  66. package/dist/web/public/styles.325eb4f3.css.br +0 -0
  67. package/dist/web/public/styles.325eb4f3.css.gz +0 -0
  68. package/dist/web/public/{subagent-windows.2a192c3e.js → subagent-windows.e6ca799f.js} +24 -12
  69. package/dist/web/public/subagent-windows.e6ca799f.js.br +0 -0
  70. package/dist/web/public/subagent-windows.e6ca799f.js.gz +0 -0
  71. package/dist/web/public/sw.js.gz +0 -0
  72. package/dist/web/public/terminal-ui.02b89e2c.js +4 -0
  73. package/dist/web/public/terminal-ui.02b89e2c.js.br +0 -0
  74. package/dist/web/public/terminal-ui.02b89e2c.js.gz +0 -0
  75. package/dist/web/public/ultracode-panel.js.gz +0 -0
  76. package/dist/web/public/ultracode-windows.js +15 -19
  77. package/dist/web/public/ultracode-windows.js.br +0 -0
  78. package/dist/web/public/ultracode-windows.js.gz +0 -0
  79. package/dist/web/public/upload.html.gz +0 -0
  80. package/dist/web/public/vendor/dompurify.min.js.gz +0 -0
  81. package/dist/web/public/vendor/marked.min.js.gz +0 -0
  82. package/dist/web/public/vendor/xterm-addon-fit.min.js.gz +0 -0
  83. package/dist/web/public/vendor/xterm-addon-serialize.min.js.gz +0 -0
  84. package/dist/web/public/vendor/xterm-addon-unicode11.min.js.gz +0 -0
  85. package/dist/web/public/vendor/xterm-addon-webgl.min.js.gz +0 -0
  86. package/dist/web/public/vendor/xterm-predictive-echo.6cec0fba.js.gz +0 -0
  87. package/dist/web/public/vendor/xterm-zerolag-input.137ad9f0.js.gz +0 -0
  88. package/dist/web/public/vendor/xterm.css.gz +0 -0
  89. package/dist/web/public/vendor/xterm.min.js.gz +0 -0
  90. package/dist/web/public/voice-input.4ec670b0.js.gz +0 -0
  91. package/dist/web/public/voice-pcm-worklet.js.gz +0 -0
  92. package/dist/web/public/webview-tabs.js +3 -0
  93. package/dist/web/public/webview-tabs.js.br +0 -0
  94. package/dist/web/public/webview-tabs.js.gz +0 -0
  95. package/dist/web/routes/file-routes.d.ts.map +1 -1
  96. package/dist/web/routes/file-routes.js +48 -6
  97. package/dist/web/routes/file-routes.js.map +1 -1
  98. package/dist/web/routes/session-routes.d.ts.map +1 -1
  99. package/dist/web/routes/session-routes.js +50 -12
  100. package/dist/web/routes/session-routes.js.map +1 -1
  101. package/dist/web/schemas.d.ts +5 -0
  102. package/dist/web/schemas.d.ts.map +1 -1
  103. package/dist/web/schemas.js +13 -0
  104. package/dist/web/schemas.js.map +1 -1
  105. package/dist/web/sensitive-path.d.ts.map +1 -1
  106. package/dist/web/sensitive-path.js +17 -0
  107. package/dist/web/sensitive-path.js.map +1 -1
  108. package/dist/web/server.d.ts +20 -0
  109. package/dist/web/server.d.ts.map +1 -1
  110. package/dist/web/server.js +51 -0
  111. package/dist/web/server.js.map +1 -1
  112. package/dist/web/session-listener-wiring.d.ts.map +1 -1
  113. package/dist/web/session-listener-wiring.js +5 -0
  114. package/dist/web/session-listener-wiring.js.map +1 -1
  115. package/package.json +1 -1
  116. package/skills/codeman/SKILL.md +16 -15
  117. package/skills/codeman/preamble.sh +8 -8
  118. package/skills/codeman/reference/endpoints.md +28 -34
  119. package/skills/codeman/reference/messaging.md +8 -6
  120. package/skills/codeman/reference/recipes.md +3 -3
  121. package/skills/codeman/reference/verbs.md +39 -24
  122. package/dist/web/public/app.e2cb9065.js +0 -34
  123. package/dist/web/public/app.e2cb9065.js.br +0 -0
  124. package/dist/web/public/app.e2cb9065.js.gz +0 -0
  125. package/dist/web/public/constants.04b7b284.js.br +0 -0
  126. package/dist/web/public/constants.04b7b284.js.gz +0 -0
  127. package/dist/web/public/i18n.86757605.js +0 -1
  128. package/dist/web/public/i18n.86757605.js.br +0 -0
  129. package/dist/web/public/i18n.86757605.js.gz +0 -0
  130. package/dist/web/public/mobile-handlers.bc45f976.js.br +0 -0
  131. package/dist/web/public/mobile-handlers.bc45f976.js.gz +0 -0
  132. package/dist/web/public/mobile.1eef31fe.css +0 -1
  133. package/dist/web/public/mobile.1eef31fe.css.br +0 -0
  134. package/dist/web/public/mobile.1eef31fe.css.gz +0 -0
  135. package/dist/web/public/panels-ui.1e4cb4b2.js.br +0 -0
  136. package/dist/web/public/panels-ui.1e4cb4b2.js.gz +0 -0
  137. package/dist/web/public/session-ui.c67565f2.js.br +0 -0
  138. package/dist/web/public/session-ui.c67565f2.js.gz +0 -0
  139. package/dist/web/public/settings-ui.eacb4f92.js.br +0 -0
  140. package/dist/web/public/settings-ui.eacb4f92.js.gz +0 -0
  141. package/dist/web/public/styles.d2fa3a17.css +0 -1
  142. package/dist/web/public/styles.d2fa3a17.css.br +0 -0
  143. package/dist/web/public/styles.d2fa3a17.css.gz +0 -0
  144. package/dist/web/public/subagent-windows.2a192c3e.js.br +0 -0
  145. package/dist/web/public/subagent-windows.2a192c3e.js.gz +0 -0
  146. package/dist/web/public/terminal-ui.c182a68d.js +0 -4
  147. package/dist/web/public/terminal-ui.c182a68d.js.br +0 -0
  148. package/dist/web/public/terminal-ui.c182a68d.js.gz +0 -0
@@ -16,16 +16,16 @@
16
16
  <link rel="manifest" href="manifest.json">
17
17
  <title>Codeman</title>
18
18
  <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cdefs%3E%3ClinearGradient id='g' x1='0%25' y1='0%25' x2='100%25' y2='100%25'%3E%3Cstop offset='0%25' stop-color='%2360a5fa'/%3E%3Cstop offset='100%25' stop-color='%233b82f6'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='32' height='32' rx='6' fill='%230a0a0a'/%3E%3Cpath d='M18 4L8 18h6l-2 10 10-14h-6z' fill='url(%23g)'/%3E%3C/svg%3E">
19
- <link rel="stylesheet" href="styles.d2fa3a17.css">
20
- <link rel="stylesheet" href="mobile.1eef31fe.css" media="(max-width: 1023px)">
19
+ <link rel="stylesheet" href="styles.325eb4f3.css">
20
+ <link rel="stylesheet" href="mobile.c40d28a6.css" media="(max-width: 1023px)">
21
21
  <!-- xterm.css loaded async — terminal won't display until xterm.js runs anyway -->
22
22
  <link rel="preload" href="vendor/xterm.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
23
23
  <noscript><link rel="stylesheet" href="vendor/xterm.css"></noscript>
24
24
  <!-- Preload critical resources — lets browser discover these during HTML parse
25
25
  instead of waiting until <script> tags at bottom-of-body are reached. -->
26
26
  <link rel="preload" href="vendor/xterm.min.js" as="script">
27
- <link rel="preload" href="constants.04b7b284.js" as="script">
28
- <link rel="preload" href="app.e2cb9065.js" as="script">
27
+ <link rel="preload" href="constants.35c7f91c.js" as="script">
28
+ <link rel="preload" href="app.a8b08065.js" as="script">
29
29
  <!-- Self-hosted xterm.js — eliminates CDN DNS/TLS latency (~100ms).
30
30
  'defer' preserves execution order (xterm loads before fit addon). -->
31
31
  <script defer src="vendor/xterm.min.js"></script>
@@ -51,6 +51,18 @@
51
51
  layer loads below; setting lang/dir here prevents an English accessibility
52
52
  tree from flashing while the deferred scripts start. -->
53
53
  <script>try{var m=window.innerWidth<768||(('ontouchstart' in window||navigator.maxTouchPoints>0)&&window.innerWidth<1024);var k=m?'codeman-app-settings-mobile':'codeman-app-settings';var l=JSON.parse(localStorage.getItem(k)||'{}').language;l=l==='zh-CN'?'zh-CN':'en';document.documentElement.lang=l;window.__codemanLanguage=l;}catch(e){document.documentElement.lang='en';window.__codemanLanguage='en';}</script>
54
+ <!-- Apply the saved session-list layout (header strip vs. left sidebar) and the
55
+ sidebar collapse state before first paint, so the loading skeleton and the
56
+ first frame already match. Same per-device settings key as the language
57
+ script above. Solo windows (/session/:id) never get a sidebar — mirrors
58
+ _detectSoloSessionId() in app.js. With no stored collapse choice the
59
+ docked desktop sidebar starts open and the off-canvas overlay drawer
60
+ starts closed — the overlay test is `innerWidth < 1024`, matching
61
+ mobile.css's media attribute below and _isSessionSidebarOverlay() in
62
+ app.js, NOT the handheld storage-key test `m`. Use a different predicate
63
+ here and boot will contradict this value, animating the drawer open by
64
+ itself on every load between 768 and 1023px. -->
65
+ <script>try{var m=window.innerWidth<768||(('ontouchstart' in window||navigator.maxTouchPoints>0)&&window.innerWidth<1024);var k=m?'codeman-app-settings-mobile':'codeman-app-settings';var L=JSON.parse(localStorage.getItem(k)||'{}').sessionListLayout;var solo=/^\/session\//.test(location.pathname);var C=localStorage.getItem('codeman-sidebar-collapsed');document.documentElement.dataset.sessionList=(L==='sidebar'&&!solo)?'sidebar':'header';document.documentElement.dataset.sidebar=(C===null?window.innerWidth<1024:C==='1')?'collapsed':'expanded';}catch(e){document.documentElement.dataset.sessionList='header';document.documentElement.dataset.sidebar='expanded';}</script>
54
66
  <!-- Inline critical CSS for instant skeleton paint (before styles.css loads) -->
55
67
  <style>
56
68
  .loading-skeleton{display:flex;flex-direction:column;height:100vh;height:100dvh;background:var(--bg-dark,#11151c)}
@@ -58,8 +70,22 @@
58
70
  .skeleton-brand{color:var(--accent,#38b6f0);font-size:14px;font-weight:700;font-family:'Manrope',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;opacity:.85}
59
71
  .skeleton-tabs{display:flex;gap:4px;margin-left:16px}
60
72
  .skeleton-tab{width:80px;height:24px;background:var(--control-bg,rgba(255,255,255,0.04));border-radius:6px}
73
+ .skeleton-body{flex:1;display:flex;min-height:0}
74
+ .skeleton-sidebar{display:none;width:44px;flex:0 0 44px;background:var(--glass-bg,rgba(31,38,48,0.85));border-right:1px solid var(--glass-border,rgba(255,255,255,0.08))}
61
75
  .skeleton-terminal{flex:1;background:var(--term-bg,#161b23)}
62
76
  .skeleton-toolbar{height:42px;background:var(--glass-bg,rgba(31,38,48,0.85));border-top:1px solid var(--glass-border,rgba(255,255,255,0.08))}
77
+ /* Sidebar layout: the strip skeleton would flash a grey pill where no strip
78
+ will be, so swap it for a rail matching --sidebar-width-collapsed. */
79
+ html[data-session-list="sidebar"] .skeleton-tabs{display:none}
80
+ /* Only >=1024px docks the sidebar and reserves layout width; below that it is
81
+ an off-canvas overlay, so a rail in the skeleton would be a strip that
82
+ vanishes. The pre-paint script has already resolved the collapse state, so
83
+ match the real width and spare the terminal a 216px sideways jump once
84
+ styles.css lands. */
85
+ @media (min-width: 1024px) {
86
+ html[data-session-list="sidebar"] .skeleton-sidebar{display:block}
87
+ html[data-session-list="sidebar"][data-sidebar="expanded"] .skeleton-sidebar{width:260px;flex:0 0 260px}
88
+ }
63
89
  .app-loaded .loading-skeleton{display:none}
64
90
  </style>
65
91
  </head>
@@ -70,7 +96,10 @@
70
96
  <span class="skeleton-brand">Codeman</span>
71
97
  <div class="skeleton-tabs"><div class="skeleton-tab"></div></div>
72
98
  </div>
73
- <div class="skeleton-terminal"></div>
99
+ <div class="skeleton-body">
100
+ <div class="skeleton-sidebar"></div>
101
+ <div class="skeleton-terminal"></div>
102
+ </div>
74
103
  <div class="skeleton-toolbar"></div>
75
104
  </div>
76
105
  <!-- Skip link for keyboard users -->
@@ -84,10 +113,27 @@
84
113
  <span class="logo" onclick="app.goHome()" title="Go to main page"
85
114
  ><span class="logo-text">Codeman</span><span class="logo-compact" aria-hidden="true">C</span></span
86
115
  >
116
+ <!-- Collapse/expand the session sidebar. Lives in .header-brand, NOT in
117
+ #headerRight: test/mobile-header-buttons-policy.test.ts only enumerates
118
+ buttons inside .header-right, and on a phone this button is the only
119
+ way to open the off-canvas session drawer, so it must never be hidden
120
+ by the phone header policy. Shown only in sidebar layout — visibility
121
+ via marker class, never inline style. -->
122
+ <button class="btn-icon-header btn-sidebar-toggle btn-sidebar-toggle--hidden"
123
+ id="sidebarToggleBtn" onclick="app.toggleSessionSidebar()"
124
+ title="Collapse session sidebar" aria-label="Collapse session sidebar"
125
+ aria-expanded="true" aria-controls="sessionSidebar">
126
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M9 3v18"/></svg>
127
+ </button>
87
128
  </div>
88
129
 
89
- <!-- Session Tabs -->
90
- <div class="session-tabs" id="sessionTabs" role="tablist" aria-label="Session tabs">
130
+ <!-- Session Tabs. In sidebar layout THIS VERY #sessionTabs element is
131
+ re-parented into #sessionSidebarList by applySessionListLayout() and
132
+ this host is hidden — it is never cloned or rebuilt, because
133
+ app.$('sessionTabs') caches it by object identity and never invalidates. -->
134
+ <div class="session-tabs-host" id="sessionTabsHost">
135
+ <div class="session-tabs" id="sessionTabs" role="tablist" aria-label="Session tabs" aria-orientation="horizontal">
136
+ </div>
91
137
  </div>
92
138
 
93
139
  <!-- Detached single-session window title (shown only in solo mode) -->
@@ -309,6 +355,26 @@
309
355
 
310
356
  <!-- Main Terminal Area -->
311
357
  <main class="main">
358
+ <!-- Collapsible session sidebar (opt-in layout). Deliberately EMPTY in
359
+ markup: applySessionListLayout() moves #sessionTabs in here, so the
360
+ vertical list is the exact same DOM node as the header strip and every
361
+ renderer, drag handler and webview-tabs.js consumer keeps working.
362
+ Must stay a SIBLING of .terminal-wrap — .main.webview-active hides
363
+ .terminal-wrap, and the sidebar has to survive that. -->
364
+ <aside class="session-sidebar" id="sessionSidebar" aria-label="Sessions">
365
+ <div class="session-sidebar-head">
366
+ <span class="session-sidebar-title">Sessions</span>
367
+ <span class="session-sidebar-count" id="sessionSidebarCount" aria-hidden="true"></span>
368
+ </div>
369
+ <div class="session-sidebar-filter">
370
+ <input type="search" id="sessionSidebarFilter" class="session-sidebar-filter-input"
371
+ placeholder="Filter sessions" aria-label="Filter sessions"
372
+ autocomplete="off" spellcheck="false"
373
+ oninput="app.applySidebarFilter(this.value)">
374
+ </div>
375
+ <div class="session-sidebar-list" id="sessionSidebarList"></div>
376
+ </aside>
377
+
312
378
  <div class="terminal-wrap">
313
379
  <!-- Partial-history notice (#258). Lives OUTSIDE the terminal on purpose:
314
380
  the old notice was a grey line written into the scrollback, so it
@@ -687,6 +753,7 @@
687
753
  <div><kbd>Ctrl</kbd>+<kbd>Tab</kbd></div><div>Next Session</div>
688
754
  <div><kbd>Alt/Option</kbd>+<kbd>[</kbd> / <kbd>Alt/Option</kbd>+<kbd>]</kbd></div><div>Previous / Next Session</div>
689
755
  <div><kbd>Alt/Option</kbd>+<kbd>1-9</kbd></div><div>Switch to Tab N</div>
756
+ <div><kbd>Alt/Option</kbd>+<kbd>B</kbd></div><div>Toggle Session Sidebar</div>
690
757
  </div>
691
758
  </section>
692
759
  <section class="shortcut-section">
@@ -694,8 +761,8 @@
694
761
  <div class="shortcuts-grid">
695
762
  <div><kbd>Ctrl</kbd>+<kbd>{</kbd></div><div>Move Active Tab Left</div>
696
763
  <div><kbd>Ctrl</kbd>+<kbd>}</kbd></div><div>Move Active Tab Right</div>
697
- <div><kbd>ArrowLeft</kbd></div><div>Focus Previous Tab</div>
698
- <div><kbd>ArrowRight</kbd></div><div>Focus Next Tab</div>
764
+ <div><kbd>ArrowLeft</kbd> / <kbd>ArrowUp</kbd></div><div>Focus Previous Tab</div>
765
+ <div><kbd>ArrowRight</kbd> / <kbd>ArrowDown</kbd></div><div>Focus Next Tab</div>
699
766
  <div><kbd>Home</kbd></div><div>Focus First Tab</div>
700
767
  <div><kbd>End</kbd></div><div>Focus Last Tab</div>
701
768
  <div><kbd>Enter</kbd> / <kbd>Space</kbd></div><div>Activate Focused Tab</div>
@@ -1773,6 +1840,16 @@
1773
1840
  <div class="set-group">
1774
1841
  <div class="set-group-head"><h4>Tabs</h4><span class="set-scope">device</span></div>
1775
1842
  <div class="set-group-body">
1843
+ <div class="set-row has-field" data-search="session list layout sidebar tab strip vertical">
1844
+ <div class="set-row-text">
1845
+ <span class="set-row-label">Session List Layout</span>
1846
+ <span class="set-row-desc">Horizontal strip in the header, or a collapsible left sidebar (Alt+B).</span>
1847
+ </div>
1848
+ <select id="appSettingsSessionListLayout" class="set-select">
1849
+ <option value="header">Header tab strip</option>
1850
+ <option value="sidebar">Left sidebar</option>
1851
+ </select>
1852
+ </div>
1776
1853
  <div class="set-row" data-search="tall tabs folder name two rows">
1777
1854
  <div class="set-row-text">
1778
1855
  <span class="set-row-label">Tall Tabs</span>
@@ -1984,6 +2061,13 @@
1984
2061
  </div>
1985
2062
  <label class="switch switch-sm"><input type="checkbox" id="appSettingsAgentSkill"><span class="slider"></span></label>
1986
2063
  </div>
2064
+ <div class="set-row" data-search="workspace hooks alerts approvals notifications settings.local.json">
2065
+ <div class="set-row-text">
2066
+ <span class="set-row-label">Workspace Hooks</span>
2067
+ <span class="set-row-desc">Install Codeman's hooks in each Claude workspace, so tab alerts, the Approvals Inbox and idle detection also work in linked cases and existing repos. Off leaves your repos untouched.</span>
2068
+ </div>
2069
+ <label class="switch switch-sm"><input type="checkbox" id="appSettingsWorkspaceHooks"><span class="slider"></span></label>
2070
+ </div>
1987
2071
  <div class="set-row" data-search="remote auto reconnect ssh">
1988
2072
  <div class="set-row-text">
1989
2073
  <span class="set-row-label">Remote auto-reconnect</span>
@@ -3199,35 +3283,35 @@
3199
3283
  <div class="approvals-list"></div>
3200
3284
  </div>
3201
3285
 
3202
- <script defer src="constants.04b7b284.js"></script>
3203
- <script defer src="i18n.86757605.js"></script>
3204
- <script defer src="mobile-handlers.bc45f976.js"></script>
3286
+ <script defer src="constants.35c7f91c.js"></script>
3287
+ <script defer src="i18n.bb8949de.js"></script>
3288
+ <script defer src="mobile-handlers.05b89237.js"></script>
3205
3289
  <script defer src="voice-input.4ec670b0.js"></script>
3206
3290
  <script defer src="notification-manager.5d229063.js"></script>
3207
3291
  <script defer src="keyboard-accessory.0454a3e9.js"></script>
3208
3292
  <script defer src="input-cjk.63794d0b.js"></script>
3209
3293
  <!-- Hardened markdown HTML sanitizer (wires DOMPurify). Must precede app.js. -->
3210
3294
  <script defer src="sanitize-html.bc7078d6.js"></script>
3211
- <script defer src="app.e2cb9065.js"></script>
3212
- <script defer src="terminal-ui.c182a68d.js"></script>
3295
+ <script defer src="app.a8b08065.js"></script>
3296
+ <script defer src="terminal-ui.02b89e2c.js"></script>
3213
3297
  <script defer src="respawn-ui.ff0dae4c.js"></script>
3214
3298
  <script defer src="ralph-panel.6de2d0f8.js"></script>
3215
3299
  <script defer src="orchestrator-panel.js"></script>
3216
3300
  <script defer src="cron-ui.js"></script>
3217
- <script defer src="settings-ui.eacb4f92.js"></script>
3218
- <script defer src="panels-ui.1e4cb4b2.js"></script>
3301
+ <script defer src="settings-ui.6cb12d4b.js"></script>
3302
+ <script defer src="panels-ui.c5a82b6e.js"></script>
3219
3303
  <script defer src="readmymind-ui.js"></script>
3220
3304
  <script defer src="ultracode-panel.js"></script>
3221
3305
  <script defer src="approvals-ui.js"></script>
3222
3306
  <script defer src="admin-ui.js"></script>
3223
- <script defer src="session-ui.c67565f2.js"></script>
3307
+ <script defer src="session-ui.71a0ce9a.js"></script>
3224
3308
  <script defer src="webview-tabs.js"></script>
3225
3309
  <script defer src="mobile-overview.js"></script>
3226
3310
  <script defer src="home-sessions.js"></script>
3227
3311
  <script defer src="entrance-animations.js"></script>
3228
3312
  <script defer src="ralph-wizard.13a1831e.js"></script>
3229
3313
  <script defer src="api-client.c9b1cddc.js"></script>
3230
- <script defer src="subagent-windows.2a192c3e.js"></script>
3314
+ <script defer src="subagent-windows.e6ca799f.js"></script>
3231
3315
  <script defer src="ultracode-windows.js"></script>
3232
3316
  <script defer src="session-lineage.js"></script>
3233
3317
  <script defer src="image-input.ee16ad88.js"></script>
Binary file
Binary file
@@ -168,6 +168,11 @@ const MobileDetection = {
168
168
  resizeTimeout = setTimeout(() => {
169
169
  this.updateBodyClass();
170
170
  this.updateAppHeight();
171
+ // Whether the session sidebar is a docked column or a modal overlay is
172
+ // decided at 1024px, so crossing that width has to re-sync the drawer
173
+ // state — otherwise the `inert`/aria-hidden set on a closed overlay
174
+ // drawer survives into the docked rail and makes it unclickable.
175
+ if (typeof app !== 'undefined') app.applySessionListLayout?.();
171
176
  // Tab auto-wrap is width-driven, so it must re-evaluate on resize — the only
172
177
  // other trigger is a tab content render. No-op on mobile/tablet (method bails).
173
178
  if (typeof app !== 'undefined') app.updateTabOverflowMode?.();
@@ -652,6 +657,7 @@ const SwipeHandler = {
652
657
  _touchStartHandler: null,
653
658
  _touchEndHandler: null,
654
659
  _element: null,
660
+ _ignoreGesture: false,
655
661
 
656
662
  /** Initialize swipe handling */
657
663
  init() {
@@ -680,6 +686,12 @@ const SwipeHandler = {
680
686
  },
681
687
 
682
688
  onTouchStart(e) {
689
+ // The session sidebar is an overlay child of .main, so its touches bubble in
690
+ // here. Swiping across the open session drawer — the natural "dismiss it"
691
+ // gesture — would otherwise fire nextSession() and drop the user into a
692
+ // session they never tapped.
693
+ this._ignoreGesture = !!e.target?.closest?.('.session-sidebar');
694
+ if (this._ignoreGesture) return;
683
695
  if (!e.touches || e.touches.length !== 1) return;
684
696
  this.startX = e.touches[0].clientX;
685
697
  this.startY = e.touches[0].clientY;
@@ -687,6 +699,10 @@ const SwipeHandler = {
687
699
  },
688
700
 
689
701
  onTouchEnd(e) {
702
+ if (this._ignoreGesture) {
703
+ this._ignoreGesture = false;
704
+ return;
705
+ }
690
706
  if (!e.changedTouches || e.changedTouches.length !== 1) return;
691
707
 
692
708
  const endX = e.changedTouches[0].clientX;
@@ -8,6 +8,10 @@
8
8
  * errored sessions), then SPACES (cases, expandable to their sessions), then
9
9
  * WORKING and IDLE / DONE.
10
10
  *
11
+ * Rows inside a section are ordered by `CodemanSessionOrder` (constants.js),
12
+ * the SAME comparator the desktop rail uses: blocked longest-first, then
13
+ * running longest-first, then quiet most-recently-quiet first.
14
+ *
11
15
  * PHONE ONLY. The gate is `shouldUseMobileOverview()` (viewport < 430px, not a
12
16
  * popped-out solo window, per-device setting on). Tablet and desktop keep the
13
17
  * welcome overlay untouched. The container ships with the `hidden` attribute and
@@ -25,6 +29,7 @@
25
29
  * `buildMobileOverviewModel()` is pure and unit-tested (test/mobile-overview.test.ts).
26
30
  *
27
31
  * @mixin Extends CodemanApp.prototype via Object.assign
32
+ * @dependency constants.js (CodemanSessionOrder, the shared row comparator)
28
33
  * @dependency app.js (this.sessions, this.cases, this.pendingHooks, selectSession, run)
29
34
  * @dependency ralph-panel.js (formatRelativeTime, the app's one relative-time formatter)
30
35
  * @dependency mobile-handlers.js (MobileDetection)
@@ -35,16 +40,6 @@
35
40
  /** Viewport width that counts as a phone. Matches the mobile.css phone block. */
36
41
  const MOBILE_OVERVIEW_PHONE_QUERY = '(max-width: 430px)';
37
42
 
38
- /** Sort rank per state: the most demanding thing sorts first inside a section. */
39
- const MOBILE_OVERVIEW_STATE_RANK = {
40
- needs: 0,
41
- error: 1,
42
- waiting: 2,
43
- working: 3,
44
- idle: 4,
45
- done: 5,
46
- };
47
-
48
43
  /** How many past conversations show before the "Show all" toggle. */
49
44
  const MOBILE_OVERVIEW_PAST_LIMIT = 8;
50
45
 
@@ -188,18 +183,25 @@ Object.assign(CodemanApp.prototype, {
188
183
  // Epoch ms, straight off the session payload; formatting happens at
189
184
  // render time so the clock can redo it without a re-render.
190
185
  createdAt: Number(session.createdAt) || 0,
186
+ // Raw stamps for the shared order comparator; `since` above is the same
187
+ // pair resolved for DISPLAY, and the two must not drift apart.
188
+ lastActivityAt: Number(session.lastActivityAt) || 0,
189
+ lastSubmitAt: Number(session.lastSubmitAt) || 0,
191
190
  since: this._mobileOverviewSince(state, session),
192
191
  orderIndex: orderIndex === -1 ? Number.MAX_SAFE_INTEGER : orderIndex,
193
192
  };
194
193
  });
195
194
 
196
- const bySeverityThenOrder = (a, b) => {
197
- const rank = MOBILE_OVERVIEW_STATE_RANK[a.state] - MOBILE_OVERVIEW_STATE_RANK[b.state];
198
- return rank !== 0 ? rank : a.orderIndex - b.orderIndex;
195
+ // Order is `CodemanSessionOrder` (constants.js), shared with the desktop
196
+ // rail: blocked first (longest-blocked at the top), then running
197
+ // longest-first, then quiet most-recent-first.
198
+ // Guarded: a stale cached constants.js (iOS Safari after a deploy) must
199
+ // degrade to tab order, not TypeError the overview away.
200
+ const inSection = (states) => {
201
+ const filtered = rows.filter((r) => states.includes(r.state));
202
+ return window.CodemanSessionOrder ? window.CodemanSessionOrder.sort(filtered) : filtered;
199
203
  };
200
204
 
201
- const inSection = (states) => rows.filter((r) => states.includes(r.state)).sort(bySeverityThenOrder);
202
-
203
205
  // Past = conversations from the unified list that are not currently live.
204
206
  // The endpoint already folds a transcript into its owning session (via the
205
207
  // claudeSessionId alias map), so a plain id check is enough to avoid listing
@@ -0,0 +1 @@
1
+ html.mobile-init .header-font-controls,html.mobile-init .header-system-stats,html.mobile-init .header-tokens,html.mobile-init .monitor-panel,html.mobile-init .subagents-panel,html.mobile-init .project-insights-panel,html.mobile-init .file-browser-panel{display:none!important}@media(max-width:768px){input,textarea,select{font-size:16px!important}html{touch-action:manipulation}.session-tab .tab-detach{display:none!important}}@media(max-width:768px)and (min-width:430px){.header{position:fixed;top:0;left:0;right:0;min-height:48px;max-height:48px;padding:.35rem .5rem;padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right));background:#0a0a0a;border-bottom:1px solid rgba(255,255,255,.08);contain:none;overflow:visible;z-index:1200}.ios-device .header{padding-top:calc(.35rem + var(--safe-area-top));min-height:calc(48px + var(--safe-area-top));max-height:calc(48px + var(--safe-area-top))}.app{padding-top:54px}.ios-device .app{padding-top:calc(54px + var(--safe-area-top))}.header-font-controls{gap:.15rem;padding:.15rem .25rem}.header-font-controls .btn-icon-sm{width:18px;height:18px}.header-system-stats{font-size:.6rem;gap:.25rem}.header-right{gap:.35rem}.btn-icon-header:not(.btn-sm){width:44px;height:44px}.session-tabs,.session-tabs.tabs-two-rows{flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;scrollbar-width:none;max-height:52px;gap:3px}.session-tabs::-webkit-scrollbar{display:none}.session-tab{padding:.4rem .6rem;font-size:.75rem;min-height:40px}.session-tab .tab-name{max-width:80px}.toolbar{padding:.4rem .5rem;padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right));gap:.4rem}.tab-count-group{display:none}.btn-toolbar{padding:.4rem .8rem;font-size:.8rem;min-height:40px}.case-select-group{max-width:none}.case-combobox{width:160px}.toolbar-select{font-size:.75rem}.monitor-panel,.subagents-panel{width:100%;max-width:100%;left:0;right:0;border-radius:8px 8px 0 0;max-height:40vh}.project-insights-panel{max-width:280px;font-size:.7rem}.modal{z-index:1300}.command-palette-modal{padding:10vh .75rem 0}.command-palette-shell{width:100%;max-height:74vh}.command-palette-input-row{grid-template-columns:20px minmax(0,1fr)}.command-palette-input-row kbd{display:none}.command-palette-item{min-height:56px}.settings-grid{gap:.4rem .75rem}.settings-item{font-size:.7rem}.event-type-grid{grid-template-columns:1fr 40px 40px 40px;gap:5px 6px}.event-label{font-size:.7rem}.subagent-window{width:320px;height:280px;min-width:240px;min-height:160px}.subagent-window-header{padding:.35rem .5rem}.subagent-window-title .id{font-size:.7rem;max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.subagent-window-title .status{font-size:.55rem}.subagent-window-body{font-size:.7rem}.respawn-banner{padding:.25rem .5rem;padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right));font-size:.65rem}.respawn-compact-layout{gap:.75rem}.respawn-status-row1{gap:.4rem}.respawn-action-log{max-height:2.6em;font-size:.6rem}.respawn-countdown-timer{font-size:.55rem}.respawn-timer-bar{width:24px}.toolbar-center .btn-toolbar.btn-voice{display:flex!important}.toolbar{padding:0 .5rem;gap:.5rem}.toolbar-left,.toolbar-right,.toolbar-group{gap:.5rem}.btn-toolbar{padding:.4rem .75rem;font-size:.75rem;min-height:unset}}@media(max-width:430px){:root{--header-height: 44px}.header-brand{padding-right:0;margin-right:.1rem;border-right:none}.header-brand .logo{display:inline-flex;align-items:center;justify-content:center;min-width:44px;height:var(--header-height);margin-left:-.3rem;font-size:1.15rem;line-height:1;border-radius:8px;-webkit-tap-highlight-color:transparent}.header-brand .logo:active{background:#60a5fa29}.header-brand .logo .logo-text{display:none}.header-brand .logo .logo-compact{display:inline}.header-font-controls{gap:.1rem;padding:.1rem .2rem}.header-font-controls .btn-icon-sm{width:16px;height:16px}.header-font-controls .font-size-display{font-size:.6rem;min-width:14px}.header-system-stats{font-size:.55rem;gap:.15rem}.header-tokens{font-size:.6rem;padding:.1rem .3rem}.header{position:fixed;top:0;left:0;right:0;min-height:var(--header-height);max-height:var(--header-height);align-items:center;padding:.15rem .3rem;padding-left:calc(.3rem + var(--safe-area-left));padding-right:calc(.3rem + var(--safe-area-right));gap:.15rem;overflow:hidden;background:#0a0a0a;border-bottom:1px solid rgba(255,255,255,.08);contain:none;z-index:1200}.ios-device .header{padding-top:calc(.15rem + var(--safe-area-top));min-height:calc(var(--header-height) + var(--safe-area-top));max-height:calc(var(--header-height) + var(--safe-area-top))}.app{padding-top:calc(var(--header-height) + 6px)}.ios-device .app{padding-top:calc(var(--header-height) + 6px + var(--safe-area-top))}.main{padding-bottom:calc(40px + var(--safe-area-bottom))}.ios-device.safari-browser .main{padding-bottom:calc(40px + var(--safe-area-bottom) + (100vh - var(--app-height, 100vh)))}.header-right{padding-left:.2rem;gap:.1rem;flex-shrink:0;border-left:none}.btn-icon-header{width:26px;height:26px;padding:0}.btn-icon-header svg{width:12px;height:12px}html[data-session-list=sidebar] #sidebarToggleBtn{width:44px;height:44px}html[data-session-list=sidebar] #sidebarToggleBtn svg{width:18px;height:18px}.btn-icon-header.btn-settings,.btn-icon-header.btn-lifecycle-log,.btn-icon-header.btn-away-digest,.btn-icon-header.btn-session-manager,.btn-icon-header.btn-file-viewer,.btn-icon-header.btn-approvals,.btn-icon-header.btn-readmymind,.btn-admin-panel{display:none!important}.btn-voice-mobile{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;background:#1a2a3f;border:1px solid rgba(59,130,246,.3);border-radius:4px;color:#93c5fd;cursor:pointer;flex-shrink:0;order:5}.btn-voice-mobile svg{width:13px;height:13px}.btn-voice-mobile:active{background:#2a3a5f}.btn-voice-mobile.recording{background:#ef444440;border-color:#ef444499;color:#ef4444;animation:mobile-voice-pulse 1.2s ease-in-out infinite}@keyframes mobile-voice-pulse{0%,to{box-shadow:inset 0 0 0 1px #ef444459;background:#ef444433}50%{box-shadow:inset 0 0 0 2px #ef4444bf;background:#ef444459}}.btn-settings-mobile{display:inline-flex!important;align-items:center;justify-content:center;width:26px;height:26px;background:transparent;border:1px solid rgba(255,255,255,.2);border-radius:4px;color:#9ca3af;font-size:.85rem;cursor:pointer;flex-shrink:0;order:6;position:relative}.btn-settings-mobile svg{width:13px;height:13px}.btn-settings-mobile:active{background:#ffffff1a;color:#fff}.app{overflow:hidden;position:relative}.keyboard-visible .app{position:fixed;inset:0 0 auto;height:var(--app-height, 100dvh)}.session-tabs,.session-tabs.tabs-two-rows{flex:1;flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;scrollbar-width:none;max-height:36px;gap:2px;padding:0}.session-tabs::-webkit-scrollbar{display:none}.session-tab{flex-shrink:0;min-height:32px;max-height:32px;padding:.35rem .5rem;font-size:.7rem;gap:.25rem;border-radius:4px}.session-tab .tab-status{width:4px;height:4px}.session-tab .tab-status.busy{width:9px;height:9px;box-shadow:0 0 8px 2px color-mix(in srgb,var(--green) 55%,transparent)!important}.session-tab .tab-status.busy:after{display:none}.session-tab .tab-name{max-width:50px;overflow:hidden;text-overflow:ellipsis}.session-tab .tab-close,.session-tab .tab-gear{display:none}.session-tab.active .tab-gear{display:inline-flex;align-items:center;justify-content:center;font-size:.65rem;line-height:1;width:32px;height:32px;margin-left:auto;opacity:.6}.session-tab.active .tab-close{display:inline-flex;align-items:center;justify-content:center;font-size:1.1rem;line-height:1;width:20px;height:18px;margin-left:-2px}.toolbar{position:fixed;bottom:var(--safe-area-bottom);left:0;right:0;height:40px;min-height:40px;max-height:40px;padding:.3rem .4rem;padding-left:calc(.4rem + var(--safe-area-left));padding-right:calc(.4rem + var(--safe-area-right));flex-wrap:nowrap;gap:.3rem;align-items:center;justify-content:space-between;background:#111;border-top:1px solid rgba(255,255,255,.1);z-index:50;transition:transform .15s ease-out;will-change:transform}.ios-device.safari-browser .toolbar{bottom:calc(var(--safe-area-bottom) + (100vh - var(--app-height, 100vh)))}.keyboard-visible.ios-device.safari-browser .toolbar{bottom:var(--safe-area-bottom)}.keyboard-visible.ios-device.safari-browser .keyboard-accessory-bar{bottom:calc(var(--safe-area-bottom) + 40px)}.toolbar-center{display:flex!important;align-items:center}.toolbar-center .btn-toolbar.btn-voice,.toolbar-right,.version-display{display:none!important}.toolbar-left{flex:1 1 0;min-width:0;align-items:center;gap:.3rem}.toolbar-left .toolbar-group{display:flex;flex:1 1 0;min-width:0;align-items:center;gap:.3rem}.toolbar-left .toolbar-group:first-child{flex:1 1 0;min-width:0;justify-content:space-between;gap:.3rem;flex-wrap:nowrap;align-items:center}.tab-count-group{display:none!important}.btn-toolbar{min-height:26px!important;max-height:26px!important;height:26px!important;padding:0 .5rem!important;font-size:.65rem!important;border-radius:4px;line-height:26px;display:inline-flex;align-items:center;justify-content:center;font-weight:500;letter-spacing:.01em;color:#fff}.run-btn-group{display:flex;flex:0 0 auto}.btn-toolbar.btn-run{flex:0 0 auto;padding:0 .6rem!important;font-weight:500;border-radius:4px 0 0 4px!important;border-right:none!important}.btn-toolbar.btn-run svg{width:10px;height:10px;margin-right:3px}.btn-toolbar.btn-run-gear{flex:0 0 auto;padding:0 .35rem!important;min-width:unset!important;border-radius:0 4px 4px 0!important;border-left:1px solid rgba(255,255,255,.15)!important}.btn-toolbar.btn-run-gear svg{width:10px;height:10px}.btn-toolbar.btn-run.mode-claude,.btn-toolbar.btn-run-gear.mode-claude{background:#1e3a5f;border-color:#3b82f64d;color:#93c5fd}.btn-toolbar.btn-run.mode-claude:active,.btn-toolbar.btn-run-gear.mode-claude:active{background:#2563eb;border-color:#3b82f680}.btn-toolbar.btn-run.mode-opencode,.btn-toolbar.btn-run-gear.mode-opencode{background:#0a2e2a;border-color:#10b9814d;color:#6ee7b7}.btn-toolbar.btn-run.mode-opencode:active,.btn-toolbar.btn-run-gear.mode-opencode:active{background:#0d4a40;border-color:#10b98180}.btn-toolbar.btn-run.mode-gemini,.btn-toolbar.btn-run-gear.mode-gemini{background:#10243f;border-color:#60a5fa4d;color:#dbeafe}.btn-toolbar.btn-run.mode-gemini:active,.btn-toolbar.btn-run-gear.mode-gemini:active{background:#174ea6;border-color:#60a5fa80}.btn-toolbar.btn-run.mode-antigravity,.btn-toolbar.btn-run-gear.mode-antigravity{background:#0b2b33;border-color:#22d3ee4d;color:#cffafe}.btn-toolbar.btn-run.mode-antigravity:active,.btn-toolbar.btn-run-gear.mode-antigravity:active{background:#0e7490;border-color:#22d3ee80}.btn-toolbar.btn-run.mode-pi,.btn-toolbar.btn-run-gear.mode-pi{background:#33121f!important;border-color:#f472b64d!important;color:#fce7f3!important}.btn-toolbar.btn-run.mode-pi:active,.btn-toolbar.btn-run-gear.mode-pi:active{background:#9d174d!important;border-color:#f472b680!important}.run-mode-menu{bottom:100%;left:0;margin-bottom:6px;min-width:160px;max-width:80vw}.run-mode-option{padding:10px 12px;font-size:.8rem;cursor:pointer;-webkit-tap-highlight-color:rgba(255,255,255,.1)}.run-mode-row-btn{width:34px;height:34px;font-size:1rem;-webkit-tap-highlight-color:rgba(255,255,255,.1)}.run-mode-webview-delete{font-size:1.2rem}.run-mode-history{-webkit-overflow-scrolling:touch;touch-action:manipulation}.btn-toolbar.btn-stop{display:flex!important;flex:0 0 auto;padding:0 8px!important;min-width:unset;order:3}.btn-toolbar.btn-stop svg{width:10px;height:10px;margin-right:0}.btn-toolbar.btn-shell{display:none!important}.btn-toolbar.btn-enter{display:flex!important;flex:0 0 auto;align-items:center;justify-content:center;min-width:54px;width:54px;white-space:nowrap;padding:0 8px!important;overflow:hidden;font-size:.65rem;font-weight:600;letter-spacing:.01em;background:#1e3a5fd9!important;border:1px solid rgba(59,130,246,.45)!important;color:#dbeafe!important;order:4}.btn-toolbar.btn-enter:hover,.btn-toolbar.btn-enter:active{background:#254a7af2!important;border-color:#3b82f6b3!important;color:#fff!important}.case-select-group{display:none!important}.toolbar-left .toolbar-group:first-child{width:100%;gap:8px}.btn-toolbar.btn-case-mobile{display:flex!important;flex:1 1 0!important;min-width:0;padding:0 8px!important;order:2;overflow:hidden;justify-content:center;gap:4px}.btn-toolbar.btn-case-mobile #mobileCaseName{max-width:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.btn-case-settings-mobile{display:inline-flex!important;align-items:center;justify-content:center;width:26px;height:26px;background:transparent;border:1px solid rgba(255,255,255,.2);border-radius:4px;color:#9ca3af;cursor:pointer;flex-shrink:0;order:1}.btn-case-settings-mobile:active{background:#ffffff1a;color:#fff}@media(max-width:374px){.toolbar{padding:0 2px}.toolbar-left,.toolbar-left .toolbar-group,.toolbar-left .toolbar-group:first-child{gap:2px}}.btn-case-settings-mobile{display:none!important}.case-settings-popover-mobile{position:fixed;bottom:calc(var(--safe-area-bottom) + 46px);left:8px;right:8px;background:#1e1e1e;border:1px solid rgba(255,255,255,.15);border-radius:8px;padding:.6rem .75rem;z-index:1000;box-shadow:0 4px 16px #00000080;display:block}.case-settings-popover-mobile.hidden{display:none!important}.case-settings-popover-mobile .checkbox-inline{display:flex;align-items:center;gap:6px;font-size:.75rem;color:#e5e7eb}.case-settings-popover-mobile .form-hint{display:block;margin-top:.2rem;font-size:.6rem;color:#6b7280}.keyboard-accessory-bar{display:none;position:fixed;bottom:calc(var(--safe-area-bottom) + 40px);left:0;right:0;height:44px;background:#1a1a1a;border-top:1px solid rgba(255,255,255,.1);padding:6px 8px;padding-left:calc(8px + var(--safe-area-left));padding-right:calc(8px + var(--safe-area-right));gap:8px;align-items:center;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;z-index:51;transition:transform .15s ease-out;will-change:transform}.keyboard-accessory-bar.visible{display:flex}.keyboard-accessory-bar::-webkit-scrollbar{display:none}.accessory-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;gap:4px;padding:6px 12px;background:#2a2a2a;border:1px solid rgba(255,255,255,.15);border-radius:6px;color:#e5e5e5;font-size:.65rem;font-weight:500;cursor:pointer;transition:background .15s,border-color .15s}.accessory-btn.confirming{background:#6b4f00;border-color:#b8860b;color:#ffd54f}.accessory-btn.accessory-btn-ctrl.armed{background:#2563eb;border-color:#3b82f6e6;color:#fff;font-weight:700;box-shadow:0 0 0 2px #3b82f673}.accessory-btn:active{background:#3a3a3a}.accessory-btn svg{width:14px;height:14px}.accessory-btn-arrow{padding:6px 10px;background:#2563eb;border-color:#3b82f680;color:#fff}.accessory-btn-arrow:active{background:#1d4ed8}.accessory-btn-dismiss{margin-left:auto;flex:1 1 0;max-width:100px;padding:10px 8px;background:#2563eb;border-color:#3b82f680;color:#fff;font-weight:600}.accessory-btn-dismiss svg{width:22px;height:22px}.accessory-btn-dismiss:active{background:#1d4ed8}.voice-preview{bottom:calc(var(--safe-area-bottom) + 94px);font-size:.8rem;max-width:90%;padding:6px 14px}.btn-case-add,.btn-case-settings,.toolbar-select{display:none!important}.toolbar .btn-case-add{min-width:26px!important;max-width:26px!important;width:26px!important;min-height:26px!important;max-height:26px!important;height:26px!important;padding:0!important;font-size:.9rem;font-weight:700;display:inline-flex!important;align-items:center;justify-content:center;line-height:1;border-radius:4px;background:transparent;border:1px solid rgba(255,255,255,.15);color:#9ca3af}.btn-case-add:hover,.btn-case-add:active{background:#ffffff1a;color:#fff}.monitor-panel,.subagents-panel{width:100%;max-width:100%;left:0;right:0;border-radius:8px 8px 0 0;bottom:calc(44px + 2rem + var(--safe-area-bottom));max-height:35vh}.modal{z-index:1300}.modal-content{width:100%;max-width:100%;height:100%;max-height:100%;border-radius:0;margin:0;display:flex;flex-direction:column}.modal-content.modal-sm,.modal-content.readmymind-modal{height:auto;max-height:85vh;border-radius:12px;margin:1rem;width:calc(100% - 2rem)}.readmymind-modal .modal-footer{flex-wrap:wrap}.readmymind-modal .modal-footer .btn-toolbar{flex:1 1 auto;justify-content:center;min-height:38px}.readmymind-alt,.readmymind-steer-input{min-height:38px}.ios-device .modal-content{padding-top:var(--safe-area-top);padding-bottom:var(--safe-area-bottom);padding-left:var(--safe-area-left);padding-right:var(--safe-area-right)}.modal-header{padding:.75rem 1rem}.modal-header h3{font-size:1rem}.modal-body{padding:.75rem 1rem;flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch}.away-digest-modal{width:100%;max-width:100%;height:100%;max-height:100%}.away-digest-ranges{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.4rem}.away-digest-ranges .filter-btn{min-height:38px;padding:.4rem .5rem}.away-digest-custom-range,.away-digest-custom-range.active{grid-template-columns:1fr}.away-digest-summary{grid-template-columns:repeat(2,minmax(0,1fr));gap:.5rem}.away-digest-item{grid-template-columns:1fr;gap:.5rem}.away-digest-action{width:100%;min-height:38px}.modal-footer,.form-actions{padding:.75rem 1rem;padding-bottom:calc(.75rem + var(--safe-area-bottom))}.ios-device .terminal-container{padding-bottom:var(--safe-area-bottom)}.main{flex:1;min-height:0}.cli-info-bar{display:block}.terminal-container{height:100%;min-height:0;position:relative;overflow:visible;touch-action:none}.terminal-container .xterm,.terminal-container .xterm-viewport,.terminal-container .xterm-screen{touch-action:none}.response-viewer{padding-bottom:var(--safe-area-bottom, 0px);max-height:88vh;max-height:92dvh}.response-viewer-body{font-size:14.5px;line-height:1.65;padding:16px 16px 24px;--rv-content-max: 100%}.response-viewer-body .rv-text pre,.response-viewer-body pre{padding:12px 14px;margin-left:-4px;margin-right:-4px;border-radius:6px}.response-viewer-body .rv-text pre code,.response-viewer-body pre code{font-size:11.5px;line-height:1.5}.response-viewer-body .rv-text h1,.response-viewer-body>h1{font-size:1.35em}.response-viewer-body .rv-text h2,.response-viewer-body>h2{font-size:1.2em}.response-viewer-body .rv-text h3,.response-viewer-body>h3{font-size:1.08em}.welcome-content{max-width:calc(100vw - 1.5rem);padding:1rem .75rem}.welcome-title{font-size:1.2rem;margin-bottom:.5rem}.welcome-desc{font-size:.8rem;margin-bottom:.4rem}.welcome-actions{flex-direction:column;gap:.5rem;margin-top:1rem}.welcome-btn{width:100%;justify-content:center;min-height:44px;padding:.75rem 1rem;font-size:.85rem}.history-show-more{display:block;margin-bottom:.75rem}.welcome-ralph-link{display:block;margin:.75rem auto 0}.welcome-hint{font-size:.7rem;margin-top:.75rem}.modal-wizard{display:flex;flex-direction:column}.wizard-progress{padding:.5rem}.wizard-step{padding:.3rem}.wizard-step-number{width:24px;height:24px;font-size:.7rem}.wizard-step-label{display:none}.timer-banner{padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right))}.respawn-banner{padding:.3rem .5rem;padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right));font-size:.65rem}.respawn-compact-layout{flex-direction:column;gap:.15rem}.respawn-status-col{flex-shrink:1;min-width:0;gap:.1rem}.respawn-status-row1{flex-wrap:wrap;gap:.25rem;row-gap:.1rem}.respawn-state{font-size:.6rem;padding:.05rem .3rem}.respawn-banner .detection-confidence{font-size:.5rem;padding:.02rem .2rem}.respawn-cycles{font-size:.55rem}.respawn-timer{font-size:.55rem;padding:0 .25rem}.respawn-tokens{font-size:.55rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:120px}.respawn-indicator{font-size:.65rem}.respawn-banner .btn-icon-only{min-width:36px;min-height:36px;font-size:1rem;display:flex;align-items:center;justify-content:center;margin-left:auto;border-radius:6px;flex-shrink:0}.respawn-status-row2{font-size:.55rem;gap:.3rem;min-height:0;flex-wrap:wrap}.respawn-banner .detection-hook,.respawn-banner .detection-ai-check,.respawn-banner .detection-status{font-size:.55rem;padding:.02rem .2rem}.respawn-countdown-timers{gap:.2rem}.respawn-countdown-timer{font-size:.5rem;padding:.02rem .2rem;gap:.15rem}.respawn-countdown-timer .respawn-timer-bar{display:none}.respawn-action-log{border-left:none;border-top:1px solid rgba(34,197,94,.15);padding-left:0;padding-top:.15rem;max-height:1.4em;font-size:.55rem;overflow:hidden}.respawn-header{flex-direction:row;gap:.4rem;align-items:center}.respawn-header .respawn-actions{display:flex;gap:.3rem;flex-shrink:0}.respawn-header .respawn-actions .btn-toolbar{min-height:28px!important;font-size:.7rem!important;padding:.2rem .5rem!important;border-radius:5px}.duration-presets{display:flex;flex-wrap:wrap;gap:.2rem}.duration-preset-btn{min-height:24px;padding:.1rem .4rem;font-size:.6rem;border-radius:4px;text-align:center}.duration-custom{display:flex;gap:.2rem;align-items:center}.duration-custom-input.visible{flex:0 1 auto}.duration-custom-input input{width:64px;min-height:24px;font-size:16px;padding:.1rem .3rem}.preset-selector{display:grid;grid-template-columns:1fr 1fr;gap:.25rem}.preset-selector select{grid-column:1 / -1;min-height:32px;font-size:16px;border-radius:5px;padding:.2rem .4rem}.preset-selector .btn{min-height:32px;font-size:.65rem;border-radius:5px;padding:.2rem .4rem}#sessionOptionsModal textarea{font-size:16px;min-height:32px!important;max-height:56px;height:auto!important;border-radius:6px;padding:.3rem .5rem}#modalRespawnPrompt{min-height:32px!important;max-height:56px}#modalRespawnKickstart{min-height:32px!important;max-height:48px}#sessionOptionsModal .checkbox-inline{min-height:30px;font-size:.75rem;padding:.15rem 0;gap:.4rem}#sessionOptionsModal .checkbox-inline input[type=checkbox]{width:18px;height:18px}#sessionOptionsModal .respawn-loop-title{font-size:.75rem}#sessionOptionsModal .respawn-loop-box .checkbox-inline{font-size:.65rem}#sessionOptionsModal .respawn-options-row{gap:.5rem}#sessionOptionsModal .form-section-header{margin-top:.75rem;padding-top:.5rem;font-size:.65rem}#sessionOptionsModal .form-row{margin-bottom:.5rem}#sessionOptionsModal .form-row label{font-size:.65rem;margin-bottom:.2rem}#sessionOptionsModal .form-hint{font-size:.6rem;margin-top:.2rem}.context-setting{padding:.625rem}.context-setting-header{flex-wrap:wrap;gap:.4rem}.context-setting-header .input-suffix-sm input{width:60px;font-size:16px;min-height:36px}.context-setting input[type=text]{font-size:16px;min-height:36px;padding:.4rem .6rem;border-radius:6px}.color-picker{gap:8px}.color-swatch{width:36px;height:36px;border-radius:6px}.form-row-switch{min-height:40px;gap:.4rem}.context-settings-grid input[type=number]{font-size:16px;min-height:36px}.ralph-limits-grid{grid-template-columns:1fr 1fr;gap:.5rem}.ralph-limits-grid .form-col input[type=number]{font-size:16px;min-height:36px;padding:.4rem .5rem;border-radius:6px}#modalRalphPhrase{font-size:16px;min-height:40px;border-radius:6px}.ralph-config-actions{margin-top:1rem}.ralph-config-actions .btn-toolbar{width:100%;min-height:44px;font-size:.85rem;border-radius:8px}.run-summary-filters{gap:.3rem;margin-bottom:.5rem}.filter-btn{padding:.35rem .75rem;font-size:.7rem;min-height:32px}.timeline-event{padding:.4rem .5rem;margin-bottom:.25rem;font-size:.7rem}.run-summary-footer{flex-direction:column;gap:.4rem;padding:.5rem 0}.run-summary-actions{flex-wrap:wrap;gap:.3rem}.run-summary-actions .btn-toolbar{flex:1;min-height:36px;font-size:.7rem;white-space:nowrap}.auto-refresh-label{font-size:.7rem}.ralph-panel{font-size:.75rem}.ralph-summary{padding:.4rem .5rem;padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right))}.project-insights-panel{max-width:100%;font-size:.65rem;bottom:calc(44px + 2rem + var(--safe-area-bottom))}.file-browser-panel{max-width:100%;max-height:50vh;bottom:calc(44px + 2rem + var(--safe-area-bottom))}.file-preview-window{width:100vw;max-width:100vw;height:var(--app-height, 100vh);max-height:var(--app-height, 100vh);border-radius:0;border-left:none;border-right:none}.file-preview-editbar{padding-bottom:calc(.4rem + var(--safe-area-bottom))}.file-preview-overlay .file-preview-footer{padding-bottom:calc(.35rem + var(--safe-area-bottom))}.file-preview-body textarea.file-preview-editor{font-size:16px}.notification-drawer{width:100%;max-width:100%;right:0;border-radius:0;padding-left:var(--safe-area-left);padding-right:var(--safe-area-right);padding-bottom:var(--safe-area-bottom)}input,textarea,[contenteditable]{scroll-margin-bottom:200px;scroll-margin-top:80px}.keyboard-visible .modal-body{max-height:40vh;overflow-y:auto}.keyboard-visible #createCaseModal .modal-body{max-height:60vh}.mobile-case-picker .modal-backdrop{background:#00000080}.mobile-case-picker-sheet{max-height:60vh;padding-bottom:var(--safe-area-bottom);animation:slideUp .2s ease-out}@keyframes slideUp{0%{transform:translateY(100%)}to{transform:translateY(0)}}.mobile-case-picker-header .modal-close{width:32px;height:32px;font-size:1.5rem}.mobile-case-picker-footer{padding-bottom:calc(12px + var(--safe-area-bottom))}#createCaseModal .form-row{margin-bottom:1rem}#createCaseModal .form-row label{font-size:.8rem;margin-bottom:.4rem;font-weight:500;color:#e5e7eb}#createCaseModal .form-row input[type=text]{min-height:44px;font-size:16px;padding:.5rem .75rem;border-radius:8px}#createCaseModal .form-row .form-hint{font-size:.65rem;margin-top:.35rem;line-height:1.4}#createCaseModal .form-actions{padding:.75rem 1rem;padding-bottom:calc(.75rem + var(--safe-area-bottom));gap:.75rem}#createCaseModal .form-actions .btn-toolbar{min-height:44px!important;max-height:44px!important;height:44px!important;font-size:.85rem!important;font-weight:500;border-radius:8px}#caseModalSubmit.loading{opacity:.6;pointer-events:none}#createCaseModal.from-mobile .modal-content{animation:caseModalSlideUp .25s ease-out}@keyframes caseModalSlideUp{0%{transform:translateY(30px);opacity:0}to{transform:translateY(0);opacity:1}}.btn-case-create-mobile{min-height:48px!important;max-height:48px!important;height:48px!important;font-size:.85rem!important;font-weight:500;border-radius:10px}.settings-grid{grid-template-columns:1fr;gap:.35rem}.settings-grid-3col{grid-template-columns:1fr 1fr 1fr}.settings-item{padding:.35rem .5rem;font-size:.7rem}.settings-item-label{font-size:.7rem}.settings-section-header{font-size:.6rem;padding:.35rem 0 .2rem;margin-top:.5rem}.form-row{margin-bottom:.5rem}.form-row label{font-size:.7rem;margin-bottom:.2rem}.form-row .form-hint{font-size:.6rem}.form-row input[type=text],.form-row input[type=number],.form-row textarea,.form-row .form-select,.form-row select{font-size:.75rem;padding:.35rem .5rem;min-height:32px}.form-row-switch{gap:.3rem}.form-row-switch>label:first-child{font-size:.7rem}.form-section-header{font-size:.6rem;margin-top:.75rem}.event-type-grid{grid-template-columns:1fr 36px 36px 36px;gap:4px 4px;padding:6px;margin-top:6px}.event-header{font-size:.55rem}.event-label{font-size:.65rem}.event-type-grid input[type=checkbox]{width:12px;height:12px}.form-actions{gap:.5rem}.form-actions .btn-toolbar{flex:1;min-height:36px!important;max-height:36px!important;height:36px!important;font-size:.75rem!important}.subagent-window{position:fixed;width:calc(100% - 8px);max-width:calc(100% - 8px);height:110px;min-height:80px;max-height:110px;min-width:200px;border-radius:6px;resize:none;box-shadow:0 2px 8px #0006}.subagent-window:after{display:none}.subagent-window-header{padding:.2rem .4rem;min-height:24px}.subagent-window-title{gap:.2rem;overflow:hidden}.subagent-window-title .icon{font-size:.7rem}.subagent-window-title .id{font-size:.6rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:45vw}.subagent-window-title .status{font-size:.45rem;padding:.05rem .15rem}.subagent-model-badge{font-size:.45rem!important;padding:.05rem .15rem!important}.subagent-window-actions button{font-size:.7rem;padding:.15rem .35rem;min-width:26px;min-height:26px;display:flex;align-items:center;justify-content:center}.subagent-window-body{font-size:.6rem;padding:.2rem .35rem}.subagent-window-body .activity-line{gap:.15rem;padding:.05rem 0}.subagent-window-body .activity-line .time{font-size:.5rem}.subagent-window-body .activity-line .tool-name,.subagent-window-body .activity-line .tool-detail{font-size:.55rem}.subagent-window-parent{display:none}.session-tab .tab-subagent-badge{height:14px;padding:0 3px;border-radius:7px;margin-left:2px}.session-tab .tab-subagent-badge .subagent-label{font-size:.45rem}.subagent-dropdown{position:fixed!important;left:8px!important;right:8px!important;bottom:auto!important;min-width:auto!important;max-width:none!important;border-radius:8px;transform:none!important}.mobile-overview.visible{position:absolute;inset:0;z-index:10;display:flex;flex-direction:column;gap:.75rem;padding:.75rem .6rem calc(1rem + var(--safe-area-bottom));background:var(--bg-dark);overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain}.mobile-overview-top{display:flex;align-items:center;justify-content:space-between;gap:.5rem;padding:0}.mobile-overview-brand{display:inline-flex;align-items:center;min-height:48px;font-size:1.5rem;font-weight:800;line-height:1;color:var(--accent-hover);letter-spacing:-.02em}.mobile-overview-header{position:relative;display:flex;flex-direction:column}.mobile-overview-run-group{display:flex;align-items:stretch;flex-shrink:0}.mobile-overview-run-group .mobile-overview-run{display:inline-flex;align-items:center;gap:.4rem;min-height:48px!important;height:48px!important;max-height:48px!important;padding:0 1.15rem!important;font-size:.95rem!important;line-height:1;font-weight:700;font-family:inherit;border-radius:10px 0 0 10px!important}.mobile-overview-run-mode{font-weight:600;font-size:.85rem;opacity:.8}.mobile-overview-run-group .mobile-overview-run-caret{display:inline-flex;align-items:center;justify-content:center;min-height:48px!important;height:48px!important;max-height:48px!important;min-width:48px!important;width:48px!important;padding:0!important;line-height:1;font-family:inherit;border-radius:0 10px 10px 0!important}.mobile-overview-run-group .mobile-overview-run-caret svg{display:block;width:20px!important;height:20px!important;margin:0!important}.mobile-overview-run-menu{display:flex;flex-direction:column;gap:.15rem;margin:.5rem 0 0;padding:.35rem;border:1px solid var(--border);border-radius:12px;background:var(--floating-bg);box-shadow:var(--elevated-shadow)}.mobile-overview-run-option{display:flex;align-items:center;gap:.5rem;min-height:44px;padding:0 .6rem;border:none;border-radius:8px;background:transparent;color:var(--text);font-family:inherit;font-size:.82rem;text-align:left}.mobile-overview-run-option.selected{background:var(--control-bg-hover)}.mobile-overview-run-option:active{background:var(--bg-hover)}.mobile-overview-run-option--add{color:var(--accent)}.mobile-overview-run-header{padding:.4rem .6rem .2rem;font-size:.6rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--text-muted)}.mobile-overview-section{display:flex;flex-direction:column;gap:.4rem}.mobile-overview-heading{display:flex;align-items:center;gap:.35rem;margin:.35rem 0 0;padding:0;font-size:.65rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--text-muted)}.mobile-overview-heading-count{color:var(--text-dim);font-weight:600}.mobile-overview-empty{margin:0;padding:.5rem 0;font-size:.75rem;color:var(--text-muted)}.mobile-overview-row{display:flex;align-items:center;gap:.6rem;width:100%;min-height:56px;padding:.5rem .7rem;border:1px solid var(--border);border-radius:12px;background:var(--bg-card);color:var(--text);font-family:inherit;text-align:left}.mobile-overview-row:active{background:var(--bg-hover)}.mobile-overview-row-wrap{width:100%}.mobile-overview-approval-strip{display:flex;flex-wrap:wrap;gap:.4rem;padding:.4rem .2rem .1rem}.mobile-overview-approval-btn{border:1px solid var(--border);border-radius:8px;background:var(--bg-card);color:var(--text);font-family:inherit;font-size:.72rem;padding:.35rem .6rem;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mobile-overview-approval-btn.primary{background:var(--accent);border-color:var(--accent);color:#fff}.mobile-overview-approval-btn.danger{border-color:var(--error);color:var(--error)}.mobile-overview-row--needs{border-color:var(--red);animation:mobile-overview-blink-red 2.5s ease-in-out infinite}.mobile-overview-row--waiting{border-color:var(--yellow);animation:mobile-overview-blink-yellow 3.5s ease-in-out infinite}.mobile-overview-row--error{border-color:var(--red)}.mobile-overview-row--working{border-color:var(--green);animation:mobile-overview-breathe-green 2.2s ease-in-out infinite}@keyframes mobile-overview-breathe-green{0%,to{background:var(--bg-card);border-color:var(--border)}50%{background:#22c55e1a;border-color:var(--green)}}.mobile-overview-pill--working:after{content:"";display:inline-block;width:.75em;text-align:left;animation:mobile-overview-pill-dots 1.5s steps(1,end) infinite}@keyframes mobile-overview-pill-dots{0%{content:""}25%{content:"."}50%{content:".."}75%{content:"..."}}@keyframes mobile-overview-blink-red{0%,to{background:var(--bg-card);border-color:var(--border)}50%{background:#ef444424;border-color:var(--red)}}@keyframes mobile-overview-blink-yellow{0%,to{background:var(--bg-card);border-color:var(--border)}50%{background:#eab3081f;border-color:var(--yellow)}}.mobile-overview-row-body{display:flex;flex-direction:column;gap:.15rem;flex:1;min-width:0}.mobile-overview-row-title{display:block;font-size:.9rem;font-weight:600;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-overview-row-case{color:var(--text-dim);font-weight:500}.mobile-overview-row-sub{display:block;font-size:.68rem;color:var(--text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-overview-row-meta{display:flex;align-items:center;gap:.3rem;min-width:0;font-family:var(--font-mono, monospace);font-size:.63rem;color:var(--text-muted);white-space:nowrap;overflow:hidden}.mobile-overview-meta-item{min-width:0;overflow:hidden;text-overflow:ellipsis}.mobile-overview-meta-key{margin-right:.3rem;opacity:.6;text-transform:uppercase;letter-spacing:.05em}.mobile-overview-meta-sep{opacity:.45}.mobile-overview-row--working .mobile-overview-meta-since{color:var(--green);opacity:.95}.mobile-overview-dot{flex-shrink:0;width:9px;height:9px;border-radius:50%;background:var(--text-muted)}.mobile-overview-dot--needs,.mobile-overview-dot--error{background:var(--red)}.mobile-overview-dot--waiting{background:var(--yellow)}.mobile-overview-dot--working{background:var(--green);animation:pulse 1.5s infinite;box-shadow:0 0 8px 2px color-mix(in srgb,var(--green) 55%,transparent);will-change:opacity}.mobile-overview-dot{position:relative}.mobile-overview-dot--working:after{content:"";position:absolute;inset:-4px;border:2px solid rgba(34,197,94,.25);border-top-color:var(--green);border-radius:50%;animation:tab-load-spin .7s linear infinite}.mobile-overview-dot--idle{background:var(--green)}.mobile-overview-dot--done{background:var(--text-muted);opacity:.5}.mobile-overview-pill{flex-shrink:0;display:inline-flex;align-items:center;gap:.25rem;padding:.2rem .45rem;border:1px solid var(--border-light);border-radius:999px;font-size:.62rem;font-weight:600;color:var(--text-dim);white-space:nowrap}.mobile-overview-pill--needs,.mobile-overview-pill--error{border-color:var(--red);color:var(--red)}.mobile-overview-pill--waiting{border-color:var(--yellow);color:var(--yellow)}.mobile-overview-pill--idle,.mobile-overview-pill--working{border-color:var(--green);color:var(--green)}.mobile-overview-chevron{flex-shrink:0;color:var(--text-muted);font-size:1rem;line-height:1}.mobile-overview-row--past{background:transparent;border-style:dashed}.mobile-overview-row--past .mobile-overview-row-title{font-weight:500;color:var(--text-dim)}.mobile-overview-dot--past{background:transparent;border:1px solid var(--border-light)}.mobile-overview-pill--past{border-color:var(--border-light);color:var(--text-muted)}.mobile-overview-more{display:flex;align-items:center;justify-content:center;gap:.35rem;min-height:40px;border:none;border-radius:10px;background:var(--control-bg);color:var(--text-dim);font-family:inherit;font-size:.72rem;font-weight:600}.mobile-overview-more-count{padding:.05rem .35rem;border-radius:999px;background:var(--control-bg-hover);color:var(--text-muted)}}@media(prefers-reduced-motion:reduce){.mobile-overview-row--needs,.mobile-overview-row--waiting{animation:none}.mobile-overview-row--needs{background:#ef444424}.mobile-overview-row--waiting{background:#eab3081f}.mobile-overview-dot--working{animation:none}.mobile-overview-dot--working:after{border-color:var(--green);animation:none}.mobile-overview-row--working{animation:none}.mobile-overview-pill--working:after{content:"...";animation:none}}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.header,.toolbar,.keyboard-accessory-bar){background:var(--glass-bg);border-color:var(--glass-border);color:var(--text)}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-voice-mobile,.btn-settings-mobile,.btn-toolbar.btn-shell,.toolbar .btn-case-add,.accessory-btn:not(.armed)){background:var(--control-bg);border-color:var(--control-border);color:var(--text-dim)}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-voice-mobile:active,.btn-settings-mobile:active,.btn-toolbar.btn-shell:hover,.btn-toolbar.btn-shell:active,.btn-case-add:hover,.btn-case-add:active,.accessory-btn:active){background:var(--control-bg-hover);border-color:var(--control-border-hover);color:var(--text)}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-toolbar.btn-run.mode-claude,.btn-toolbar.btn-run-gear.mode-claude){background:linear-gradient(135deg,var(--accent-grad-a),var(--accent-grad-b));border-color:var(--accent);color:var(--accent-ink)}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-toolbar.btn-run.mode-opencode,.btn-toolbar.btn-run-gear.mode-opencode){background:linear-gradient(135deg,var(--accent-d),var(--accent-grad-b));border-color:var(--accent);color:var(--accent-ink)}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-toolbar.btn-run.mode-gemini,.btn-toolbar.btn-run-gear.mode-gemini){background:linear-gradient(135deg,#174ea6,#4f46e5);border-color:#315fc3;color:#fff}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-toolbar.btn-run.mode-antigravity,.btn-toolbar.btn-run-gear.mode-antigravity){background:linear-gradient(135deg,#0e7490,#0891b2);border-color:#155e75;color:#fff}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-toolbar.btn-run.mode-pi,.btn-toolbar.btn-run-gear.mode-pi){background:linear-gradient(135deg,#be185d,#db2777);border-color:#9d174d;color:#fff}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) .btn-toolbar.btn-run-gear{border-left-color:var(--control-border-hover)!important}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.case-settings-popover-mobile,.mobile-case-picker-sheet){background:var(--floating-bg);border-color:var(--control-border);color:var(--text);box-shadow:var(--elevated-shadow)}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.case-settings-popover-mobile .checkbox-inline,#createCaseModal .form-row label){color:var(--text)}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) .case-settings-popover-mobile .form-hint{color:var(--text-muted)}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) .mobile-case-picker .modal-backdrop{background:var(--modal-backdrop)}.ios-device.safari-browser{overscroll-behavior:none}@media(hover:none)and (pointer:coarse){.session-tab .tab-close,.session-tab .tab-gear{opacity:1;width:auto;padding:.15rem .25rem;align-items:center;justify-content:center}.btn-toolbar:hover,.btn-icon-header:hover{transform:none}.subagent-dropdown-trigger:active+.subagent-dropdown-menu,.subagent-dropdown-trigger:focus+.subagent-dropdown-menu{display:block}}@media(max-width:430px){.attachment-history-drawer{top:0;bottom:0;width:100%;max-width:100%;height:100vh;height:100dvh;border-left:none;border-radius:0;padding-top:var(--safe-area-top);padding-left:var(--safe-area-left);padding-right:var(--safe-area-right);padding-bottom:var(--safe-area-bottom)}.attachment-history-header{padding:12px}.attachment-history-list{padding:6px}.attachment-history-item{grid-template-columns:104px minmax(0,1fr);gap:8px;padding:8px 6px}.attachment-history-thumb{width:104px}.attachment-history-actions{gap:4px}.attachment-history-actions button{padding:4px 7px}}@media(max-width:430px){.offline-banner{padding:.4rem .5rem;padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right));font-size:.7rem;gap:.4rem}.offline-banner-detail{display:none}.offline-banner-retry{padding:.25rem .5rem;margin-left:auto}.offline-overlay-card{padding:22px 18px 18px}.offline-overlay-title{font-size:1.05rem}.offline-overlay-actions{flex-direction:column}.offline-overlay-btn{width:100%;padding:.65rem 1rem}}@media(max-width:860px){:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .modal-content.modal-lg{width:100%;max-width:100%;height:100%;max-height:100%}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-body{display:flex;flex-direction:column;min-height:0}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-rail{flex-direction:row;align-items:center;border-right:0;border-bottom:1px solid var(--border);background:transparent;padding:10px 14px;overflow:visible;flex-shrink:0}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-rail-items,:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-rail-foot{display:none}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-search{margin:0;flex:1}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-search input{padding:9px 10px 9px 30px;border-radius:10px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-head-actions:has(.set-head-save){padding:3px;border:1px solid var(--border);border-radius:12px;background:var(--bg-input)}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-head-save{display:inline-flex;height:36px;padding:0 16px;font-size:.86rem}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-head-actions .modal-close{width:36px;height:36px;font-size:1.35rem}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-foot{display:none}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-doc{padding:0 14px 34px;flex:1}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump{display:flex;position:sticky;top:0;z-index:4;align-items:center;gap:8px;width:100%;margin:10px 0 2px;padding:10px 12px;border-radius:11px;font:inherit;font-size:.82rem;color:var(--text);background:rgba(var(--accent-rgb),.13);border:1px solid rgba(var(--accent-rgb),.3);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);cursor:pointer}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-ico{color:var(--accent);flex-shrink:0}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-label{font-weight:580;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-chev{margin-left:auto;color:var(--text-muted);flex-shrink:0;transition:transform .18s}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump[aria-expanded=true] .set-jump-chev{transform:rotate(180deg)}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-veil{display:none;position:fixed;inset:0;z-index:8;background:#04080d9e}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-menu{display:none;position:absolute;left:14px;right:14px;z-index:9;padding:7px;border-radius:16px;background:var(--bg-card);border:1px solid var(--control-border);box-shadow:var(--elevated-shadow);max-height:70vh;overflow-y:auto}#appSettingsModal.jump-open .set-jump-veil,#appSettingsModal.jump-open .set-jump-menu{display:block}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-row{display:flex;align-items:center;gap:11px;width:100%;padding:11px 12px;border:0;border-radius:11px;background:transparent;color:var(--text-dim);font:inherit;font-size:.82rem;text-align:left}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-row svg{color:var(--text-muted);flex-shrink:0}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-row .set-jump-count{margin-left:auto;font-size:.62rem;color:var(--text-muted)}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-row.active{background:rgba(var(--accent-rgb),.14);color:var(--text);font-weight:570}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-row.active svg{color:var(--accent)}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-section{padding-top:0}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-section+.set-section{border-top:0;margin-top:0}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-section-head{gap:7px;margin:18px 0 2px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-section-head svg{padding:0;border:0;background:none;color:var(--text-muted);width:12px;height:12px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-section-head h2{font-size:.6rem;font-weight:640;letter-spacing:.1em;text-transform:uppercase;color:var(--text-muted)}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-section-head:after{content:"";flex:1;height:1px;background:linear-gradient(90deg,var(--border),transparent)}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-section-blurb{display:none}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-preview{margin-bottom:12px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-preview-stage{min-height:62px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group{margin-top:14px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group+.set-group{margin-top:16px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-head{margin-bottom:7px;padding:0 3px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-hint{padding:0 3px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-body{gap:0;background:#ffffff09;border:1px solid rgba(255,255,255,.06);border-radius:13px;overflow:hidden}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-body>.set-row{background:transparent;border:0;border-radius:0;padding:12px 13px;gap:12px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-body>.set-row+.set-row{border-top:1px solid rgba(255,255,255,.055)}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-body>.set-chips,:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-body>.set-modelgrid,:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-body>.set-minigrid,:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-body>#appSettingsShortcutsList{padding:12px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-body>.event-type-grid{padding:12px;margin:0}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-row-label{font-size:.84rem}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-row-desc{font-size:.69rem;max-width:none}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-row.has-field{flex-direction:column;align-items:stretch;gap:9px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-row.has-field .set-select,:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-row.has-field .set-input{width:100%;min-width:0;max-width:none;box-sizing:border-box}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-row-actions-wide{width:100%}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-row-actions-wide .set-input{flex:1;min-width:0}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-num{width:76px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .switch-sm{width:40px;height:24px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .switch-sm .slider:before{height:18px;width:18px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .switch-sm input:checked+.slider:before{transform:translate(16px)}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-chip{font-size:.78rem;padding:9px 14px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-modelgrid{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-minigrid{grid-template-columns:1fr}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-mini .set-select{width:148px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-segment{overflow-x:auto;scrollbar-width:none}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-segment::-webkit-scrollbar{display:none}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-segment button{flex:0 0 auto;padding:8px 12px}}@media(max-width:860px){:is(#sessionOptionsModal,#createCaseModal) .set-rail{padding:8px 10px}:is(#sessionOptionsModal,#createCaseModal) .set-rail-items{display:flex;flex-direction:row;flex:1;min-width:0;gap:4px;overflow-x:auto;scrollbar-width:none}:is(#sessionOptionsModal,#createCaseModal) .set-rail-items::-webkit-scrollbar{display:none}:is(#sessionOptionsModal,#createCaseModal) .set-rail-item{white-space:nowrap;padding:8px 12px}:is(#sessionOptionsModal,#createCaseModal) .set-rail-item.active:before{display:none}:is(#sessionOptionsModal,#createCaseModal) .set-rail-item.active{background:rgba(var(--accent-rgb),.13)}}html[data-session-list=sidebar] .session-sidebar{position:absolute;top:0;bottom:0;left:0;width:min(280px,80vw);flex:0 0 auto;transform:translate(-100%);visibility:hidden;transition:transform var(--sidebar-transition),visibility var(--sidebar-transition);box-shadow:10px 0 28px #0000005c;z-index:12;padding-left:var(--safe-area-left)}html[data-session-list=sidebar] .session-sidebar.open{transform:translate(0);visibility:visible}html[data-session-list=sidebar][data-sidebar=collapsed] .session-sidebar{flex-basis:auto;width:min(280px,80vw)}html[data-session-list=sidebar][data-sidebar=collapsed] .session-sidebar-head,html[data-session-list=sidebar][data-sidebar=collapsed] .session-sidebar-filter{display:flex}html[data-session-list=sidebar][data-sidebar=collapsed] .session-sidebar .session-tab{justify-content:flex-start;flex-wrap:nowrap;padding:.4rem .5rem}html[data-session-list=sidebar][data-sidebar=collapsed] .session-sidebar .tab-info{display:flex}html[data-session-list=sidebar][data-sidebar=collapsed] .session-sidebar .tab-number{display:inline-flex}html[data-session-list=sidebar][data-sidebar=collapsed] .session-sidebar .tab-subagent-badge{margin-left:4px}html[data-session-list=sidebar] .session-sidebar .session-tab{min-height:44px;max-height:none;flex-shrink:0}html[data-session-list=sidebar] .session-sidebar .session-tab .tab-gear,html[data-session-list=sidebar] .session-sidebar .session-tab .tab-close{display:inline-flex;align-items:center;justify-content:center;opacity:1;width:auto;min-width:28px;height:auto;margin-left:0;padding:.15rem .25rem}@media(prefers-reduced-motion:reduce){html[data-session-list=sidebar] .session-sidebar{transition:none}}