codex-autorunner 0.1.0__py3-none-any.whl

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 (147) hide show
  1. codex_autorunner/__init__.py +3 -0
  2. codex_autorunner/bootstrap.py +151 -0
  3. codex_autorunner/cli.py +886 -0
  4. codex_autorunner/codex_cli.py +79 -0
  5. codex_autorunner/codex_runner.py +17 -0
  6. codex_autorunner/core/__init__.py +1 -0
  7. codex_autorunner/core/about_car.py +125 -0
  8. codex_autorunner/core/codex_runner.py +100 -0
  9. codex_autorunner/core/config.py +1465 -0
  10. codex_autorunner/core/doc_chat.py +547 -0
  11. codex_autorunner/core/docs.py +37 -0
  12. codex_autorunner/core/engine.py +720 -0
  13. codex_autorunner/core/git_utils.py +206 -0
  14. codex_autorunner/core/hub.py +756 -0
  15. codex_autorunner/core/injected_context.py +9 -0
  16. codex_autorunner/core/locks.py +57 -0
  17. codex_autorunner/core/logging_utils.py +158 -0
  18. codex_autorunner/core/notifications.py +465 -0
  19. codex_autorunner/core/optional_dependencies.py +41 -0
  20. codex_autorunner/core/prompt.py +107 -0
  21. codex_autorunner/core/prompts.py +275 -0
  22. codex_autorunner/core/request_context.py +21 -0
  23. codex_autorunner/core/runner_controller.py +116 -0
  24. codex_autorunner/core/runner_process.py +29 -0
  25. codex_autorunner/core/snapshot.py +576 -0
  26. codex_autorunner/core/state.py +156 -0
  27. codex_autorunner/core/update.py +567 -0
  28. codex_autorunner/core/update_runner.py +44 -0
  29. codex_autorunner/core/usage.py +1221 -0
  30. codex_autorunner/core/utils.py +108 -0
  31. codex_autorunner/discovery.py +102 -0
  32. codex_autorunner/housekeeping.py +423 -0
  33. codex_autorunner/integrations/__init__.py +1 -0
  34. codex_autorunner/integrations/app_server/__init__.py +6 -0
  35. codex_autorunner/integrations/app_server/client.py +1386 -0
  36. codex_autorunner/integrations/app_server/supervisor.py +206 -0
  37. codex_autorunner/integrations/github/__init__.py +10 -0
  38. codex_autorunner/integrations/github/service.py +889 -0
  39. codex_autorunner/integrations/telegram/__init__.py +1 -0
  40. codex_autorunner/integrations/telegram/adapter.py +1401 -0
  41. codex_autorunner/integrations/telegram/commands_registry.py +104 -0
  42. codex_autorunner/integrations/telegram/config.py +450 -0
  43. codex_autorunner/integrations/telegram/constants.py +154 -0
  44. codex_autorunner/integrations/telegram/dispatch.py +162 -0
  45. codex_autorunner/integrations/telegram/handlers/__init__.py +0 -0
  46. codex_autorunner/integrations/telegram/handlers/approvals.py +241 -0
  47. codex_autorunner/integrations/telegram/handlers/callbacks.py +72 -0
  48. codex_autorunner/integrations/telegram/handlers/commands.py +160 -0
  49. codex_autorunner/integrations/telegram/handlers/commands_runtime.py +5262 -0
  50. codex_autorunner/integrations/telegram/handlers/messages.py +477 -0
  51. codex_autorunner/integrations/telegram/handlers/selections.py +545 -0
  52. codex_autorunner/integrations/telegram/helpers.py +2084 -0
  53. codex_autorunner/integrations/telegram/notifications.py +164 -0
  54. codex_autorunner/integrations/telegram/outbox.py +174 -0
  55. codex_autorunner/integrations/telegram/rendering.py +102 -0
  56. codex_autorunner/integrations/telegram/retry.py +37 -0
  57. codex_autorunner/integrations/telegram/runtime.py +270 -0
  58. codex_autorunner/integrations/telegram/service.py +921 -0
  59. codex_autorunner/integrations/telegram/state.py +1223 -0
  60. codex_autorunner/integrations/telegram/transport.py +318 -0
  61. codex_autorunner/integrations/telegram/types.py +57 -0
  62. codex_autorunner/integrations/telegram/voice.py +413 -0
  63. codex_autorunner/manifest.py +150 -0
  64. codex_autorunner/routes/__init__.py +53 -0
  65. codex_autorunner/routes/base.py +470 -0
  66. codex_autorunner/routes/docs.py +275 -0
  67. codex_autorunner/routes/github.py +197 -0
  68. codex_autorunner/routes/repos.py +121 -0
  69. codex_autorunner/routes/sessions.py +137 -0
  70. codex_autorunner/routes/shared.py +137 -0
  71. codex_autorunner/routes/system.py +175 -0
  72. codex_autorunner/routes/terminal_images.py +107 -0
  73. codex_autorunner/routes/voice.py +128 -0
  74. codex_autorunner/server.py +23 -0
  75. codex_autorunner/spec_ingest.py +113 -0
  76. codex_autorunner/static/app.js +95 -0
  77. codex_autorunner/static/autoRefresh.js +209 -0
  78. codex_autorunner/static/bootstrap.js +105 -0
  79. codex_autorunner/static/bus.js +23 -0
  80. codex_autorunner/static/cache.js +52 -0
  81. codex_autorunner/static/constants.js +48 -0
  82. codex_autorunner/static/dashboard.js +795 -0
  83. codex_autorunner/static/docs.js +1514 -0
  84. codex_autorunner/static/env.js +99 -0
  85. codex_autorunner/static/github.js +168 -0
  86. codex_autorunner/static/hub.js +1511 -0
  87. codex_autorunner/static/index.html +622 -0
  88. codex_autorunner/static/loader.js +28 -0
  89. codex_autorunner/static/logs.js +690 -0
  90. codex_autorunner/static/mobileCompact.js +300 -0
  91. codex_autorunner/static/snapshot.js +116 -0
  92. codex_autorunner/static/state.js +87 -0
  93. codex_autorunner/static/styles.css +4966 -0
  94. codex_autorunner/static/tabs.js +50 -0
  95. codex_autorunner/static/terminal.js +21 -0
  96. codex_autorunner/static/terminalManager.js +3535 -0
  97. codex_autorunner/static/todoPreview.js +25 -0
  98. codex_autorunner/static/types.d.ts +8 -0
  99. codex_autorunner/static/utils.js +597 -0
  100. codex_autorunner/static/vendor/LICENSE.xterm +24 -0
  101. codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-400-cyrillic-ext.woff2 +0 -0
  102. codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-400-cyrillic.woff2 +0 -0
  103. codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-400-greek.woff2 +0 -0
  104. codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-400-latin-ext.woff2 +0 -0
  105. codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-400-latin.woff2 +0 -0
  106. codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-400-vietnamese.woff2 +0 -0
  107. codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-500-cyrillic-ext.woff2 +0 -0
  108. codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-500-cyrillic.woff2 +0 -0
  109. codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-500-greek.woff2 +0 -0
  110. codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-500-latin-ext.woff2 +0 -0
  111. codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-500-latin.woff2 +0 -0
  112. codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-500-vietnamese.woff2 +0 -0
  113. codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-600-cyrillic-ext.woff2 +0 -0
  114. codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-600-cyrillic.woff2 +0 -0
  115. codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-600-greek.woff2 +0 -0
  116. codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-600-latin-ext.woff2 +0 -0
  117. codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-600-latin.woff2 +0 -0
  118. codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-600-vietnamese.woff2 +0 -0
  119. codex_autorunner/static/vendor/fonts/jetbrains-mono/OFL.txt +93 -0
  120. codex_autorunner/static/vendor/xterm-addon-fit.js +2 -0
  121. codex_autorunner/static/vendor/xterm.css +209 -0
  122. codex_autorunner/static/vendor/xterm.js +2 -0
  123. codex_autorunner/static/voice.js +591 -0
  124. codex_autorunner/voice/__init__.py +39 -0
  125. codex_autorunner/voice/capture.py +349 -0
  126. codex_autorunner/voice/config.py +167 -0
  127. codex_autorunner/voice/provider.py +66 -0
  128. codex_autorunner/voice/providers/__init__.py +7 -0
  129. codex_autorunner/voice/providers/openai_whisper.py +345 -0
  130. codex_autorunner/voice/resolver.py +36 -0
  131. codex_autorunner/voice/service.py +210 -0
  132. codex_autorunner/web/__init__.py +1 -0
  133. codex_autorunner/web/app.py +1037 -0
  134. codex_autorunner/web/hub_jobs.py +181 -0
  135. codex_autorunner/web/middleware.py +552 -0
  136. codex_autorunner/web/pty_session.py +357 -0
  137. codex_autorunner/web/runner_manager.py +25 -0
  138. codex_autorunner/web/schemas.py +253 -0
  139. codex_autorunner/web/static_assets.py +430 -0
  140. codex_autorunner/web/terminal_sessions.py +78 -0
  141. codex_autorunner/workspace.py +16 -0
  142. codex_autorunner-0.1.0.dist-info/METADATA +240 -0
  143. codex_autorunner-0.1.0.dist-info/RECORD +147 -0
  144. codex_autorunner-0.1.0.dist-info/WHEEL +5 -0
  145. codex_autorunner-0.1.0.dist-info/entry_points.txt +3 -0
  146. codex_autorunner-0.1.0.dist-info/licenses/LICENSE +21 -0
  147. codex_autorunner-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,4966 @@
1
+ /* JetBrains Mono (self-hosted). Keep in sync with Google Fonts subsets. */
2
+ /* cyrillic */
3
+ @font-face {
4
+ font-family: 'JetBrains Mono';
5
+ font-style: normal;
6
+ font-weight: 400;
7
+ font-display: swap;
8
+ src: url('./vendor/fonts/jetbrains-mono/JetBrainsMono-400-cyrillic.woff2') format('woff2');
9
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
10
+ }
11
+ /* cyrillic-ext */
12
+ @font-face {
13
+ font-family: 'JetBrains Mono';
14
+ font-style: normal;
15
+ font-weight: 400;
16
+ font-display: swap;
17
+ src: url('./vendor/fonts/jetbrains-mono/JetBrainsMono-400-cyrillic-ext.woff2') format('woff2');
18
+ unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
19
+ }
20
+ /* greek */
21
+ @font-face {
22
+ font-family: 'JetBrains Mono';
23
+ font-style: normal;
24
+ font-weight: 400;
25
+ font-display: swap;
26
+ src: url('./vendor/fonts/jetbrains-mono/JetBrainsMono-400-greek.woff2') format('woff2');
27
+ unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
28
+ }
29
+ /* latin */
30
+ @font-face {
31
+ font-family: 'JetBrains Mono';
32
+ font-style: normal;
33
+ font-weight: 400;
34
+ font-display: swap;
35
+ src: url('./vendor/fonts/jetbrains-mono/JetBrainsMono-400-latin.woff2') format('woff2');
36
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
37
+ }
38
+ /* latin-ext */
39
+ @font-face {
40
+ font-family: 'JetBrains Mono';
41
+ font-style: normal;
42
+ font-weight: 400;
43
+ font-display: swap;
44
+ src: url('./vendor/fonts/jetbrains-mono/JetBrainsMono-400-latin-ext.woff2') format('woff2');
45
+ unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
46
+ }
47
+ /* vietnamese */
48
+ @font-face {
49
+ font-family: 'JetBrains Mono';
50
+ font-style: normal;
51
+ font-weight: 400;
52
+ font-display: swap;
53
+ src: url('./vendor/fonts/jetbrains-mono/JetBrainsMono-400-vietnamese.woff2') format('woff2');
54
+ unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
55
+ }
56
+ /* cyrillic */
57
+ @font-face {
58
+ font-family: 'JetBrains Mono';
59
+ font-style: normal;
60
+ font-weight: 500;
61
+ font-display: swap;
62
+ src: url('./vendor/fonts/jetbrains-mono/JetBrainsMono-500-cyrillic.woff2') format('woff2');
63
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
64
+ }
65
+ /* cyrillic-ext */
66
+ @font-face {
67
+ font-family: 'JetBrains Mono';
68
+ font-style: normal;
69
+ font-weight: 500;
70
+ font-display: swap;
71
+ src: url('./vendor/fonts/jetbrains-mono/JetBrainsMono-500-cyrillic-ext.woff2') format('woff2');
72
+ unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
73
+ }
74
+ /* greek */
75
+ @font-face {
76
+ font-family: 'JetBrains Mono';
77
+ font-style: normal;
78
+ font-weight: 500;
79
+ font-display: swap;
80
+ src: url('./vendor/fonts/jetbrains-mono/JetBrainsMono-500-greek.woff2') format('woff2');
81
+ unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
82
+ }
83
+ /* latin */
84
+ @font-face {
85
+ font-family: 'JetBrains Mono';
86
+ font-style: normal;
87
+ font-weight: 500;
88
+ font-display: swap;
89
+ src: url('./vendor/fonts/jetbrains-mono/JetBrainsMono-500-latin.woff2') format('woff2');
90
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
91
+ }
92
+ /* latin-ext */
93
+ @font-face {
94
+ font-family: 'JetBrains Mono';
95
+ font-style: normal;
96
+ font-weight: 500;
97
+ font-display: swap;
98
+ src: url('./vendor/fonts/jetbrains-mono/JetBrainsMono-500-latin-ext.woff2') format('woff2');
99
+ unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
100
+ }
101
+ /* vietnamese */
102
+ @font-face {
103
+ font-family: 'JetBrains Mono';
104
+ font-style: normal;
105
+ font-weight: 500;
106
+ font-display: swap;
107
+ src: url('./vendor/fonts/jetbrains-mono/JetBrainsMono-500-vietnamese.woff2') format('woff2');
108
+ unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
109
+ }
110
+ /* cyrillic */
111
+ @font-face {
112
+ font-family: 'JetBrains Mono';
113
+ font-style: normal;
114
+ font-weight: 600;
115
+ font-display: swap;
116
+ src: url('./vendor/fonts/jetbrains-mono/JetBrainsMono-600-cyrillic.woff2') format('woff2');
117
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
118
+ }
119
+ /* cyrillic-ext */
120
+ @font-face {
121
+ font-family: 'JetBrains Mono';
122
+ font-style: normal;
123
+ font-weight: 600;
124
+ font-display: swap;
125
+ src: url('./vendor/fonts/jetbrains-mono/JetBrainsMono-600-cyrillic-ext.woff2') format('woff2');
126
+ unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
127
+ }
128
+ /* greek */
129
+ @font-face {
130
+ font-family: 'JetBrains Mono';
131
+ font-style: normal;
132
+ font-weight: 600;
133
+ font-display: swap;
134
+ src: url('./vendor/fonts/jetbrains-mono/JetBrainsMono-600-greek.woff2') format('woff2');
135
+ unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
136
+ }
137
+ /* latin */
138
+ @font-face {
139
+ font-family: 'JetBrains Mono';
140
+ font-style: normal;
141
+ font-weight: 600;
142
+ font-display: swap;
143
+ src: url('./vendor/fonts/jetbrains-mono/JetBrainsMono-600-latin.woff2') format('woff2');
144
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
145
+ }
146
+ /* latin-ext */
147
+ @font-face {
148
+ font-family: 'JetBrains Mono';
149
+ font-style: normal;
150
+ font-weight: 600;
151
+ font-display: swap;
152
+ src: url('./vendor/fonts/jetbrains-mono/JetBrainsMono-600-latin-ext.woff2') format('woff2');
153
+ unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
154
+ }
155
+ /* vietnamese */
156
+ @font-face {
157
+ font-family: 'JetBrains Mono';
158
+ font-style: normal;
159
+ font-weight: 600;
160
+ font-display: swap;
161
+ src: url('./vendor/fonts/jetbrains-mono/JetBrainsMono-600-vietnamese.woff2') format('woff2');
162
+ unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
163
+ }
164
+
165
+ :root {
166
+ --bg: #0a0c12;
167
+ --panel: #10131c;
168
+ --muted: #7a8ba8;
169
+ --text: #e5ecff;
170
+ --accent: #6cf5d8;
171
+ --accent-2: #6ca8ff;
172
+ --border: #1a2033;
173
+ --error: #ff5566;
174
+ --shadow: 0 4px 24px rgba(0, 0, 0, 0.4);
175
+ --radius: 3px;
176
+ }
177
+
178
+ * {
179
+ box-sizing: border-box;
180
+ }
181
+
182
+ /* Custom selection */
183
+ ::selection {
184
+ background: rgba(108, 245, 216, 0.3);
185
+ color: var(--text);
186
+ }
187
+
188
+ .mobile-terminal-view ::selection,
189
+ .mobile-terminal-view span::selection {
190
+ background: rgba(190, 190, 190, 0.6);
191
+ color: #0a0c12;
192
+ }
193
+
194
+ /* Focus visible for keyboard nav */
195
+ :focus-visible {
196
+ outline: 2px solid var(--accent);
197
+ outline-offset: 1px;
198
+ }
199
+
200
+ :focus:not(:focus-visible) {
201
+ outline: none;
202
+ }
203
+
204
+ body {
205
+ margin: 0;
206
+ background: var(--bg);
207
+ color: var(--text);
208
+ font-family: "JetBrains Mono", "SF Mono", "Consolas", monospace;
209
+ font-size: 13px;
210
+ line-height: 1.5;
211
+ /* Firefox scrollbar */
212
+ scrollbar-width: thin;
213
+ scrollbar-color: var(--border) transparent;
214
+ }
215
+
216
+ .hidden {
217
+ display: none !important;
218
+ }
219
+
220
+ .app-shell {
221
+ max-width: 1400px;
222
+ margin: 0 auto;
223
+ padding: 8px;
224
+ }
225
+
226
+ /* Combined nav bar: brand + tabs in one row */
227
+ .nav-bar {
228
+ display: flex;
229
+ align-items: center;
230
+ gap: 8px;
231
+ margin-bottom: 8px;
232
+ /* Ensure tabs remain clickable (avoid overlays stealing clicks). */
233
+ position: relative;
234
+ z-index: 1500;
235
+ }
236
+
237
+ .nav-brand {
238
+ font-size: 11px;
239
+ font-weight: 600;
240
+ color: var(--accent);
241
+ letter-spacing: 0.05em;
242
+ padding: 0 8px;
243
+ flex-shrink: 0;
244
+ user-select: none;
245
+ }
246
+
247
+ .nav-repo-name {
248
+ font-size: 11px;
249
+ font-weight: 500;
250
+ color: var(--muted);
251
+ padding: 0 8px;
252
+ flex-shrink: 0;
253
+ max-width: 150px;
254
+ overflow: hidden;
255
+ text-overflow: ellipsis;
256
+ white-space: nowrap;
257
+ }
258
+
259
+ .hub-back-btn {
260
+ display: flex;
261
+ align-items: center;
262
+ padding: 4px 8px;
263
+ font-size: 10px;
264
+ font-weight: 500;
265
+ color: var(--muted);
266
+ text-decoration: none;
267
+ border: 1px solid var(--border);
268
+ border-radius: var(--radius);
269
+ background: var(--bg);
270
+ flex-shrink: 0;
271
+ transition: all 0.1s ease;
272
+ }
273
+
274
+ .hub-back-btn:hover {
275
+ color: var(--text);
276
+ border-color: var(--muted);
277
+ background: #161b28;
278
+ }
279
+
280
+ /* Tabs - compact horizontal bar */
281
+ .tabs {
282
+ display: flex;
283
+ flex: 1;
284
+ gap: 2px;
285
+ background: var(--panel);
286
+ padding: 2px;
287
+ border: 1px solid var(--border);
288
+ border-radius: var(--radius);
289
+ position: relative;
290
+ z-index: 1501;
291
+ }
292
+
293
+ .nav-actions {
294
+ display: flex;
295
+ align-items: center;
296
+ gap: 6px;
297
+ flex-shrink: 0;
298
+ }
299
+
300
+ .tab {
301
+ flex: 1;
302
+ padding: 6px 10px;
303
+ border-radius: var(--radius);
304
+ border: none;
305
+ background: transparent;
306
+ color: var(--muted);
307
+ cursor: pointer;
308
+ font-size: 11px;
309
+ font-weight: 500;
310
+ font-family: inherit;
311
+ transition: all 0.1s ease;
312
+ text-transform: uppercase;
313
+ letter-spacing: 0.04em;
314
+ user-select: none;
315
+ touch-action: manipulation;
316
+ -webkit-tap-highlight-color: transparent;
317
+ }
318
+
319
+ .tab:hover:not(.active) {
320
+ color: var(--text);
321
+ background: rgba(255, 255, 255, 0.03);
322
+ }
323
+
324
+ .tab.active {
325
+ color: var(--bg);
326
+ background: var(--accent);
327
+ }
328
+
329
+ main {
330
+ display: block;
331
+ }
332
+
333
+ .panel {
334
+ display: none;
335
+ }
336
+
337
+ .panel.active {
338
+ display: block;
339
+ }
340
+
341
+ /* Cards grid */
342
+ .cards {
343
+ display: grid;
344
+ grid-template-columns: 1fr 220px;
345
+ gap: 8px;
346
+ }
347
+
348
+ .card {
349
+ background: var(--panel);
350
+ border-radius: var(--radius);
351
+ border: 1px solid var(--border);
352
+ padding: 10px;
353
+ }
354
+
355
+ /* ===== Compact Per-Repo Usage Card ===== */
356
+ .usage-card-compact {
357
+ background: var(--panel);
358
+ border: 1px solid var(--border);
359
+ border-radius: var(--radius);
360
+ padding: 8px 10px;
361
+ }
362
+
363
+ .usage-header {
364
+ display: flex;
365
+ align-items: center;
366
+ gap: 8px;
367
+ margin-bottom: 6px;
368
+ }
369
+
370
+ .usage-total-badge {
371
+ background: linear-gradient(135deg, rgba(108, 245, 216, 0.15), rgba(108, 168, 255, 0.1));
372
+ border: 1px solid rgba(108, 245, 216, 0.3);
373
+ color: var(--accent);
374
+ font-weight: 700;
375
+ font-size: 13px;
376
+ padding: 2px 8px;
377
+ border-radius: var(--radius);
378
+ letter-spacing: -0.02em;
379
+ }
380
+
381
+ .usage-events-badge {
382
+ color: var(--muted);
383
+ font-size: 10px;
384
+ padding: 2px 6px;
385
+ border: 1px solid var(--border);
386
+ border-radius: var(--radius);
387
+ background: var(--bg);
388
+ }
389
+
390
+ .usage-breakdown {
391
+ display: flex;
392
+ gap: 3px;
393
+ margin-bottom: 6px;
394
+ }
395
+
396
+ .usage-chart {
397
+ background: var(--bg);
398
+ border: 1px solid var(--border);
399
+ border-radius: var(--radius);
400
+ padding: 6px;
401
+ margin-bottom: 6px;
402
+ }
403
+
404
+ .usage-chart-header {
405
+ display: flex;
406
+ align-items: center;
407
+ justify-content: space-between;
408
+ gap: 6px;
409
+ margin-bottom: 4px;
410
+ }
411
+
412
+ .usage-chart-title {
413
+ font-size: 10px;
414
+ text-transform: uppercase;
415
+ letter-spacing: 0.04em;
416
+ color: var(--muted);
417
+ }
418
+
419
+ .usage-chart-controls {
420
+ display: flex;
421
+ align-items: center;
422
+ gap: 6px;
423
+ flex-wrap: wrap;
424
+ }
425
+
426
+ .usage-chart-label {
427
+ font-size: 9px;
428
+ color: var(--muted);
429
+ }
430
+
431
+ .usage-chart-select {
432
+ font-size: 10px;
433
+ background: var(--panel);
434
+ color: var(--text);
435
+ border: 1px solid var(--border);
436
+ border-radius: var(--radius);
437
+ padding: 2px 6px;
438
+ min-width: 44px;
439
+ }
440
+
441
+ .usage-chart-canvas {
442
+ height: 88px;
443
+ width: 100%;
444
+ border-radius: var(--radius);
445
+ background: linear-gradient(180deg, rgba(108, 245, 216, 0.06), rgba(0, 0, 0, 0));
446
+ border: 1px dashed rgba(108, 245, 216, 0.2);
447
+ position: relative;
448
+ overflow: hidden;
449
+ }
450
+
451
+ .usage-chart-canvas svg {
452
+ width: 100%;
453
+ height: 100%;
454
+ display: block;
455
+ }
456
+
457
+ .usage-chart-canvas.loading::after {
458
+ content: "";
459
+ position: absolute;
460
+ left: 50%;
461
+ top: 50%;
462
+ width: 18px;
463
+ height: 18px;
464
+ margin: -9px 0 0 -9px;
465
+ border: 2px solid var(--border);
466
+ border-top-color: var(--accent);
467
+ border-radius: 50%;
468
+ animation: spin 0.6s linear infinite;
469
+ }
470
+
471
+ .usage-chart-canvas.loading::before {
472
+ content: "";
473
+ position: absolute;
474
+ inset: 0;
475
+ background: rgba(10, 12, 18, 0.25);
476
+ pointer-events: none;
477
+ }
478
+
479
+ .usage-chart-focus {
480
+ position: absolute;
481
+ top: 8px;
482
+ bottom: 8px;
483
+ width: 1px;
484
+ background: rgba(108, 245, 216, 0.5);
485
+ pointer-events: none;
486
+ opacity: 0;
487
+ }
488
+
489
+ .usage-chart-dot {
490
+ position: absolute;
491
+ width: 6px;
492
+ height: 6px;
493
+ border-radius: 50%;
494
+ background: #6cf5d8;
495
+ box-shadow: 0 0 6px rgba(108, 245, 216, 0.6);
496
+ transform: translate(-50%, -50%);
497
+ pointer-events: none;
498
+ opacity: 0;
499
+ }
500
+
501
+ .usage-chart-tooltip {
502
+ position: absolute;
503
+ top: 8px;
504
+ left: 8px;
505
+ padding: 6px 8px;
506
+ background: rgba(9, 13, 20, 0.95);
507
+ border: 1px solid rgba(108, 245, 216, 0.2);
508
+ border-radius: var(--radius);
509
+ font-size: 10px;
510
+ color: var(--text);
511
+ pointer-events: none;
512
+ opacity: 0;
513
+ max-width: 180px;
514
+ }
515
+
516
+ .usage-chart-tooltip-title {
517
+ font-weight: 600;
518
+ color: var(--accent);
519
+ margin-bottom: 2px;
520
+ }
521
+
522
+ .usage-chart-tooltip-row {
523
+ display: flex;
524
+ justify-content: space-between;
525
+ gap: 8px;
526
+ color: var(--muted);
527
+ }
528
+
529
+ .usage-chart-empty {
530
+ font-size: 10px;
531
+ color: var(--muted);
532
+ display: flex;
533
+ align-items: center;
534
+ justify-content: center;
535
+ height: 100%;
536
+ }
537
+
538
+ .hub-usage-chart {
539
+ background: var(--panel);
540
+ border: 1px solid var(--border);
541
+ border-radius: var(--radius);
542
+ padding: 10px;
543
+ margin-bottom: 10px;
544
+ }
545
+
546
+ .hub-usage-chart-header {
547
+ display: flex;
548
+ align-items: center;
549
+ justify-content: space-between;
550
+ gap: 8px;
551
+ margin-bottom: 6px;
552
+ }
553
+
554
+ .hub-usage-chart-canvas {
555
+ height: 160px;
556
+ border-style: solid;
557
+ }
558
+
559
+ @media (max-width: 720px) {
560
+ .usage-chart-header {
561
+ flex-direction: column;
562
+ align-items: flex-start;
563
+ gap: 6px;
564
+ }
565
+
566
+ .hub-usage-chart-header {
567
+ flex-direction: column;
568
+ align-items: flex-start;
569
+ }
570
+
571
+ .usage-chart-controls {
572
+ width: 100%;
573
+ justify-content: flex-start;
574
+ }
575
+ }
576
+
577
+ .usage-stat {
578
+ flex: 1;
579
+ display: flex;
580
+ flex-direction: column;
581
+ align-items: center;
582
+ padding: 4px 2px;
583
+ background: var(--bg);
584
+ border: 1px solid var(--border);
585
+ border-radius: var(--radius);
586
+ min-width: 0;
587
+ }
588
+
589
+ .usage-stat-cached {
590
+ background: rgba(108, 245, 216, 0.05);
591
+ border-color: rgba(108, 245, 216, 0.2);
592
+ }
593
+
594
+ .usage-stat-cached .usage-stat-val {
595
+ color: var(--accent);
596
+ }
597
+
598
+ .usage-stat-val {
599
+ font-size: 12px;
600
+ font-weight: 600;
601
+ color: var(--text);
602
+ line-height: 1.2;
603
+ }
604
+
605
+ .usage-stat-lbl {
606
+ font-size: 8px;
607
+ color: var(--muted);
608
+ text-transform: uppercase;
609
+ letter-spacing: 0.04em;
610
+ }
611
+
612
+ .usage-footer {
613
+ display: flex;
614
+ justify-content: space-between;
615
+ font-size: 9px;
616
+ color: var(--muted);
617
+ opacity: 0.7;
618
+ padding-top: 4px;
619
+ border-top: 1px solid var(--border);
620
+ margin-top: 6px;
621
+ }
622
+
623
+ /* Usage Progress Bars */
624
+ .usage-rates-visual {
625
+ display: flex;
626
+ flex-direction: column;
627
+ gap: 4px;
628
+ margin-bottom: 2px;
629
+ }
630
+
631
+ .usage-rate-row {
632
+ display: flex;
633
+ align-items: center;
634
+ gap: 6px;
635
+ }
636
+
637
+ .usage-rate-label {
638
+ font-size: 9px;
639
+ color: var(--muted);
640
+ width: 45px;
641
+ flex-shrink: 0;
642
+ }
643
+
644
+ .usage-rate-bar-container {
645
+ flex: 1;
646
+ display: flex;
647
+ align-items: center;
648
+ gap: 6px;
649
+ }
650
+
651
+ .usage-progress-bar {
652
+ flex: 1;
653
+ height: 4px;
654
+ background: var(--bg);
655
+ border-radius: 2px;
656
+ overflow: hidden;
657
+ position: relative;
658
+ border: 1px solid var(--border);
659
+ }
660
+
661
+ .usage-progress-bar-empty {
662
+ opacity: 0.5;
663
+ }
664
+
665
+ .usage-progress-fill {
666
+ height: 100%;
667
+ border-radius: 2px;
668
+ transition: width 0.3s ease;
669
+ }
670
+
671
+ .usage-bar-ok {
672
+ background: var(--accent);
673
+ }
674
+
675
+ .usage-bar-warning {
676
+ background: #ffcc00;
677
+ }
678
+
679
+ .usage-bar-critical {
680
+ background: #ff5566;
681
+ }
682
+
683
+ .usage-progress-label {
684
+ font-size: 9px;
685
+ color: var(--text);
686
+ font-family: monospace;
687
+ min-width: 50px;
688
+ text-align: right;
689
+ }
690
+
691
+ /* ===== Compact Hub Usage Section ===== */
692
+ .hub-usage-compact {
693
+ background: var(--panel);
694
+ border: 1px solid var(--border);
695
+ border-radius: var(--radius);
696
+ padding: 8px 10px;
697
+ margin: 8px 0;
698
+ }
699
+
700
+ .hub-usage-header {
701
+ display: flex;
702
+ align-items: center;
703
+ gap: 8px;
704
+ margin-bottom: 6px;
705
+ }
706
+
707
+ .hub-usage-path {
708
+ flex: 1;
709
+ font-size: 9px;
710
+ color: var(--muted);
711
+ opacity: 0.6;
712
+ overflow: hidden;
713
+ text-overflow: ellipsis;
714
+ white-space: nowrap;
715
+ text-align: right;
716
+ }
717
+
718
+ .hub-usage-grid {
719
+ display: flex;
720
+ flex-wrap: wrap;
721
+ gap: 4px;
722
+ }
723
+
724
+ .hub-usage-chip {
725
+ display: flex;
726
+ align-items: center;
727
+ gap: 6px;
728
+ padding: 4px 8px;
729
+ background: var(--bg);
730
+ border: 1px solid var(--border);
731
+ border-radius: var(--radius);
732
+ font-size: 10px;
733
+ min-width: 0;
734
+ flex: 0 0 auto;
735
+ }
736
+
737
+ .hub-usage-chip:hover {
738
+ border-color: var(--accent);
739
+ background: rgba(108, 245, 216, 0.04);
740
+ }
741
+
742
+ .hub-usage-chip-unmatched {
743
+ opacity: 0.6;
744
+ }
745
+
746
+ .hub-usage-chip-name {
747
+ font-weight: 600;
748
+ color: var(--text);
749
+ max-width: 100px;
750
+ overflow: hidden;
751
+ text-overflow: ellipsis;
752
+ white-space: nowrap;
753
+ }
754
+
755
+ .hub-usage-chip-total {
756
+ font-weight: 700;
757
+ color: var(--accent);
758
+ font-size: 11px;
759
+ }
760
+
761
+ .hub-usage-chip-meta {
762
+ color: var(--muted);
763
+ font-size: 9px;
764
+ white-space: nowrap;
765
+ }
766
+
767
+ /* Hub shell */
768
+ .hub-shell {
769
+ max-width: 1200px;
770
+ margin: 0 auto;
771
+ padding: 8px;
772
+ }
773
+
774
+ .hub-hero {
775
+ display: flex;
776
+ justify-content: space-between;
777
+ align-items: center;
778
+ gap: 10px;
779
+ background: linear-gradient(120deg, rgba(108, 245, 216, 0.08), rgba(108, 168, 255, 0.05));
780
+ border: 1px solid var(--border);
781
+ border-radius: var(--radius);
782
+ padding: 10px 12px;
783
+ }
784
+
785
+ .hub-hero h1 {
786
+ margin: 0;
787
+ font-size: 14px;
788
+ letter-spacing: 0.02em;
789
+ color: var(--accent);
790
+ }
791
+
792
+ .hub-hero p {
793
+ margin: 0;
794
+ font-size: 11px;
795
+ }
796
+
797
+ .hub-hero-text {
798
+ display: flex;
799
+ align-items: center;
800
+ gap: 12px;
801
+ flex-wrap: wrap;
802
+ }
803
+
804
+ .hub-hero-text > .muted.small {
805
+ display: none;
806
+ }
807
+
808
+ .hub-hero-actions {
809
+ display: flex;
810
+ gap: 4px;
811
+ flex-wrap: wrap;
812
+ align-items: center;
813
+ }
814
+
815
+ .hub-hero-meta {
816
+ display: flex;
817
+ gap: 6px;
818
+ flex-wrap: wrap;
819
+ }
820
+
821
+ .hub-stats {
822
+ display: flex;
823
+ gap: 6px;
824
+ margin: 8px 0;
825
+ }
826
+
827
+ .hub-stat {
828
+ flex: 1;
829
+ background: var(--panel);
830
+ border: 1px solid var(--border);
831
+ border-radius: var(--radius);
832
+ padding: 6px 10px;
833
+ display: flex;
834
+ align-items: center;
835
+ gap: 8px;
836
+ }
837
+
838
+ .hub-stat p {
839
+ margin: 0;
840
+ font-size: 10px;
841
+ }
842
+
843
+ .hub-stat-value {
844
+ font-size: 18px;
845
+ font-weight: 700;
846
+ margin: 0;
847
+ }
848
+
849
+ .hub-repo-panel {
850
+ background: var(--panel);
851
+ border: 1px solid var(--border);
852
+ border-radius: var(--radius);
853
+ padding: 8px;
854
+ }
855
+
856
+ .hub-panel-header {
857
+ display: flex;
858
+ align-items: center;
859
+ justify-content: space-between;
860
+ gap: 8px;
861
+ margin-bottom: 6px;
862
+ padding-bottom: 6px;
863
+ border-bottom: 1px solid var(--border);
864
+ }
865
+
866
+ .hub-panel-header p {
867
+ margin: 0;
868
+ font-size: 10px;
869
+ }
870
+
871
+ .hub-panel-actions {
872
+ display: flex;
873
+ gap: 4px;
874
+ }
875
+
876
+ .hub-repo-list {
877
+ display: flex;
878
+ flex-direction: column;
879
+ gap: 4px;
880
+ }
881
+
882
+ /* Hub worktrees (worktree repos grouped under a base repo) */
883
+ .hub-worktree-list {
884
+ display: flex;
885
+ flex-direction: column;
886
+ gap: 4px;
887
+ margin-left: 14px;
888
+ padding-left: 10px;
889
+ border-left: 1px solid var(--border);
890
+ margin-top: 4px;
891
+ margin-bottom: 6px;
892
+ }
893
+
894
+ .hub-worktree-row-inner {
895
+ display: block;
896
+ }
897
+
898
+ .hub-worktree-card {
899
+ padding-left: 8px;
900
+ }
901
+
902
+ .hub-worktree-orphans {
903
+ margin: 8px 0 4px;
904
+ }
905
+
906
+ /* Legacy hub-usage-list styles removed - using hub-usage-grid now */
907
+
908
+ /* Repo card - compact single-row layout */
909
+ .hub-repo-card {
910
+ border: 1px solid var(--border);
911
+ border-radius: var(--radius);
912
+ padding: 6px 10px;
913
+ background: var(--bg);
914
+ transition: all 0.1s ease;
915
+ }
916
+
917
+ .hub-repo-card.hub-repo-clickable {
918
+ cursor: pointer;
919
+ }
920
+
921
+ .hub-repo-card.hub-repo-clickable:hover {
922
+ border-color: var(--accent);
923
+ background: rgba(108, 245, 216, 0.04);
924
+ }
925
+
926
+ .hub-repo-card.hub-repo-clickable:focus-visible {
927
+ outline: 2px solid var(--accent);
928
+ outline-offset: 1px;
929
+ }
930
+
931
+ /* New compact row layout */
932
+ .hub-repo-row {
933
+ display: flex;
934
+ align-items: center;
935
+ gap: 8px;
936
+ min-height: 28px;
937
+ }
938
+
939
+ .hub-repo-left {
940
+ display: flex;
941
+ align-items: center;
942
+ gap: 4px;
943
+ flex-shrink: 0;
944
+ }
945
+
946
+ .hub-repo-center {
947
+ flex: 1;
948
+ min-width: 0;
949
+ display: flex;
950
+ align-items: baseline;
951
+ gap: 8px;
952
+ overflow: hidden;
953
+ }
954
+
955
+ .hub-repo-right {
956
+ display: flex;
957
+ align-items: center;
958
+ gap: 4px;
959
+ flex-shrink: 0;
960
+ }
961
+
962
+ .hub-repo-title {
963
+ color: var(--text);
964
+ font-weight: 600;
965
+ font-size: 12px;
966
+ white-space: nowrap;
967
+ overflow: hidden;
968
+ text-overflow: ellipsis;
969
+ flex-shrink: 0;
970
+ }
971
+
972
+ .hub-repo-clickable:hover .hub-repo-title {
973
+ color: var(--accent);
974
+ }
975
+
976
+ .hub-repo-info-line {
977
+ color: var(--muted);
978
+ font-size: 10px;
979
+ white-space: nowrap;
980
+ overflow: hidden;
981
+ text-overflow: ellipsis;
982
+ }
983
+
984
+ .hub-repo-subline {
985
+ display: flex;
986
+ align-items: center;
987
+ gap: 8px;
988
+ min-width: 0;
989
+ overflow: hidden;
990
+ }
991
+
992
+ a.hub-pr-pill {
993
+ text-decoration: none;
994
+ border-color: rgba(108, 245, 216, 0.35);
995
+ color: var(--accent);
996
+ }
997
+
998
+ a.hub-pr-pill:hover {
999
+ border-color: var(--accent);
1000
+ }
1001
+
1002
+ .hub-repo-open-indicator {
1003
+ color: var(--muted);
1004
+ font-size: 14px;
1005
+ margin-left: 2px;
1006
+ opacity: 0.5;
1007
+ transition: all 0.1s ease;
1008
+ }
1009
+
1010
+ .hub-repo-clickable:hover .hub-repo-open-indicator {
1011
+ color: var(--accent);
1012
+ opacity: 1;
1013
+ transform: translateX(2px);
1014
+ }
1015
+
1016
+ .hub-repo-note {
1017
+ margin-top: 4px;
1018
+ color: #ff8899;
1019
+ font-size: 10px;
1020
+ padding-left: 4px;
1021
+ }
1022
+
1023
+ /* Legacy support - keep for backwards compat */
1024
+ .hub-repo-main {
1025
+ display: flex;
1026
+ justify-content: space-between;
1027
+ align-items: center;
1028
+ gap: 10px;
1029
+ }
1030
+
1031
+ .hub-repo-info {
1032
+ flex: 1;
1033
+ min-width: 0;
1034
+ }
1035
+
1036
+ .hub-repo-name {
1037
+ display: flex;
1038
+ align-items: baseline;
1039
+ gap: 8px;
1040
+ flex-wrap: wrap;
1041
+ }
1042
+
1043
+ .hub-repo-path {
1044
+ color: var(--muted);
1045
+ font-size: 10px;
1046
+ opacity: 0.7;
1047
+ }
1048
+
1049
+ .hub-repo-meta {
1050
+ display: flex;
1051
+ gap: 6px;
1052
+ align-items: center;
1053
+ margin-top: 2px;
1054
+ flex-wrap: wrap;
1055
+ }
1056
+
1057
+ .hub-repo-actions {
1058
+ display: flex;
1059
+ align-items: center;
1060
+ gap: 4px;
1061
+ flex-wrap: nowrap;
1062
+ flex-shrink: 0;
1063
+ }
1064
+
1065
+ .hub-empty {
1066
+ border: 1px dashed var(--border);
1067
+ border-radius: var(--radius);
1068
+ padding: 10px;
1069
+ font-size: 11px;
1070
+ }
1071
+
1072
+ .card-header {
1073
+ display: flex;
1074
+ justify-content: space-between;
1075
+ align-items: center;
1076
+ gap: 8px;
1077
+ margin-bottom: 8px;
1078
+ padding-bottom: 6px;
1079
+ border-bottom: 1px solid var(--border);
1080
+ }
1081
+
1082
+ .card-header-left {
1083
+ display: flex;
1084
+ align-items: center;
1085
+ gap: 8px;
1086
+ }
1087
+
1088
+ .label {
1089
+ color: var(--muted);
1090
+ letter-spacing: 0.06em;
1091
+ font-size: 10px;
1092
+ text-transform: uppercase;
1093
+ font-weight: 500;
1094
+ user-select: none;
1095
+ }
1096
+
1097
+ .hub-version,
1098
+ .version-label {
1099
+ font-size: 10px;
1100
+ color: var(--muted);
1101
+ letter-spacing: 0.01em;
1102
+ }
1103
+
1104
+ /* Status pills */
1105
+ .pill {
1106
+ padding: 2px 6px;
1107
+ border-radius: var(--radius);
1108
+ font-size: 10px;
1109
+ text-transform: uppercase;
1110
+ letter-spacing: 0.04em;
1111
+ font-weight: 600;
1112
+ border: 1px solid transparent;
1113
+ }
1114
+
1115
+ .pill-idle {
1116
+ border-color: var(--border);
1117
+ background: var(--bg);
1118
+ color: var(--muted);
1119
+ }
1120
+
1121
+ .pill-running {
1122
+ border-color: var(--accent);
1123
+ background: rgba(108, 245, 216, 0.12);
1124
+ color: var(--accent);
1125
+ animation: pulse-running 1.5s ease-in-out infinite;
1126
+ }
1127
+
1128
+ @keyframes pulse-running {
1129
+ 0%, 100% { opacity: 1; }
1130
+ 50% { opacity: 0.7; }
1131
+ }
1132
+
1133
+ .pill-error {
1134
+ border-color: #ff5566;
1135
+ background: rgba(255, 85, 102, 0.12);
1136
+ color: #ff8899;
1137
+ }
1138
+
1139
+ .pill-warn {
1140
+ border-color: var(--accent-2);
1141
+ background: rgba(108, 168, 255, 0.12);
1142
+ color: var(--accent-2);
1143
+ }
1144
+
1145
+ .pill-small {
1146
+ padding: 1px 5px;
1147
+ font-size: 9px;
1148
+ }
1149
+
1150
+ /* Compact status pill for repo cards */
1151
+ .hub-repo-left .pill-small {
1152
+ padding: 2px 6px;
1153
+ font-size: 9px;
1154
+ min-width: 42px;
1155
+ text-align: center;
1156
+ }
1157
+
1158
+ /* Metrics grid */
1159
+ .grid-two {
1160
+ display: grid;
1161
+ grid-template-columns: repeat(3, 1fr);
1162
+ gap: 6px;
1163
+ }
1164
+
1165
+ .grid-two > div {
1166
+ padding: 4px 6px;
1167
+ background: var(--bg);
1168
+ border: 1px solid var(--border);
1169
+ border-radius: var(--radius);
1170
+ }
1171
+
1172
+ .grid-two .muted {
1173
+ font-size: 9px;
1174
+ text-transform: uppercase;
1175
+ letter-spacing: 0.04em;
1176
+ margin: 0;
1177
+ }
1178
+
1179
+ .metric {
1180
+ font-size: 13px;
1181
+ font-weight: 600;
1182
+ margin: 1px 0 0;
1183
+ color: var(--text);
1184
+ }
1185
+
1186
+ .muted {
1187
+ color: var(--muted);
1188
+ }
1189
+
1190
+ .small {
1191
+ font-size: 11px;
1192
+ }
1193
+
1194
+ .runner-config {
1195
+ margin-top: 6px;
1196
+ padding-top: 6px;
1197
+ border-top: 1px solid var(--border);
1198
+ display: flex;
1199
+ align-items: baseline;
1200
+ gap: 8px;
1201
+ }
1202
+
1203
+ .runner-config-label {
1204
+ font-size: 10px;
1205
+ color: var(--muted);
1206
+ letter-spacing: 0.08em;
1207
+ white-space: nowrap;
1208
+ text-transform: uppercase;
1209
+ opacity: 0.75;
1210
+ }
1211
+
1212
+ .runner-config-value {
1213
+ font-size: 12px;
1214
+ font-weight: 600;
1215
+ color: var(--text);
1216
+ }
1217
+
1218
+
1219
+ /* Actions */
1220
+ .actions {
1221
+ display: flex;
1222
+ gap: 4px;
1223
+ margin-top: 8px;
1224
+ flex-wrap: wrap;
1225
+ }
1226
+
1227
+ /* Buttons */
1228
+ button {
1229
+ border: 1px solid var(--border);
1230
+ background: var(--bg);
1231
+ color: var(--text);
1232
+ border-radius: var(--radius);
1233
+ padding: 5px 10px;
1234
+ cursor: pointer;
1235
+ font-size: 11px;
1236
+ font-weight: 500;
1237
+ font-family: inherit;
1238
+ transition: all 0.1s ease;
1239
+ text-transform: uppercase;
1240
+ letter-spacing: 0.02em;
1241
+ user-select: none;
1242
+ touch-action: manipulation;
1243
+ -webkit-tap-highlight-color: transparent;
1244
+ }
1245
+
1246
+ button:hover:not(:disabled) {
1247
+ border-color: var(--muted);
1248
+ background: #161b28;
1249
+ }
1250
+
1251
+ button:active:not(:disabled) {
1252
+ transform: scale(0.98);
1253
+ }
1254
+
1255
+ button.primary {
1256
+ background: var(--accent);
1257
+ color: var(--bg);
1258
+ font-weight: 600;
1259
+ border: none;
1260
+ }
1261
+
1262
+ button.primary:hover:not(:disabled) {
1263
+ background: #5de6c9;
1264
+ }
1265
+
1266
+ button.ghost {
1267
+ background: transparent;
1268
+ color: var(--muted);
1269
+ border-color: transparent;
1270
+ }
1271
+
1272
+ button.ghost:hover:not(:disabled) {
1273
+ background: rgba(108, 168, 255, 0.08);
1274
+ color: var(--text);
1275
+ border-color: var(--border);
1276
+ }
1277
+
1278
+ button.danger {
1279
+ background: rgba(255, 85, 102, 0.1);
1280
+ border-color: #ff5566;
1281
+ color: #ff8899;
1282
+ }
1283
+
1284
+ button.danger:hover:not(:disabled) {
1285
+ background: rgba(255, 85, 102, 0.2);
1286
+ }
1287
+
1288
+ button.sm {
1289
+ padding: 4px 8px;
1290
+ font-size: 10px;
1291
+ }
1292
+
1293
+ button:disabled {
1294
+ opacity: 0.4;
1295
+ cursor: not-allowed;
1296
+ }
1297
+
1298
+ /* Icon-only buttons (e.g. ↻) */
1299
+ button.icon-btn {
1300
+ padding: 0;
1301
+ width: 32px;
1302
+ height: 32px;
1303
+ min-width: 32px;
1304
+ min-height: 32px;
1305
+ display: inline-flex;
1306
+ align-items: center;
1307
+ justify-content: center;
1308
+ font-size: 14px;
1309
+ line-height: 1;
1310
+ }
1311
+
1312
+ /* TODO checklist */
1313
+ .todo-preview .checklist {
1314
+ list-style: none;
1315
+ padding: 0;
1316
+ margin: 0;
1317
+ display: flex;
1318
+ flex-direction: column;
1319
+ gap: 3px;
1320
+ }
1321
+
1322
+ .checklist li {
1323
+ display: grid;
1324
+ grid-template-columns: 14px 1fr;
1325
+ align-items: center;
1326
+ gap: 6px;
1327
+ padding: 4px 6px;
1328
+ border-radius: var(--radius);
1329
+ background: var(--bg);
1330
+ border: 1px solid var(--border);
1331
+ font-size: 11px;
1332
+ }
1333
+
1334
+ .checklist .box {
1335
+ width: 12px;
1336
+ height: 12px;
1337
+ border-radius: 2px;
1338
+ border: 1px solid var(--border);
1339
+ background: var(--bg);
1340
+ position: relative;
1341
+ flex-shrink: 0;
1342
+ }
1343
+
1344
+ .checklist .box.done {
1345
+ border-color: var(--accent);
1346
+ background: var(--accent);
1347
+ }
1348
+
1349
+ .checklist .box.done::after {
1350
+ content: "✓";
1351
+ position: absolute;
1352
+ top: -1px;
1353
+ left: 1px;
1354
+ font-size: 10px;
1355
+ color: var(--bg);
1356
+ font-weight: 700;
1357
+ }
1358
+
1359
+ /* GitHub card */
1360
+ .github-card .github-grid {
1361
+ display: grid;
1362
+ gap: 8px;
1363
+ margin: 10px 0 6px;
1364
+ }
1365
+
1366
+ .github-card .github-row {
1367
+ display: grid;
1368
+ grid-template-columns: 50px 1fr;
1369
+ gap: 8px;
1370
+ align-items: center;
1371
+ }
1372
+
1373
+ .github-card .github-link {
1374
+ overflow: hidden;
1375
+ text-overflow: ellipsis;
1376
+ white-space: nowrap;
1377
+ }
1378
+
1379
+ .github-card .github-mono {
1380
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
1381
+ "Courier New", monospace;
1382
+ font-size: 12px;
1383
+ }
1384
+
1385
+ .github-card .github-pr-group {
1386
+ display: flex;
1387
+ align-items: center;
1388
+ gap: 6px;
1389
+ }
1390
+
1391
+ .github-card .icon-btn-inline {
1392
+ padding: 2px 4px;
1393
+ min-width: unset;
1394
+ font-size: 12px;
1395
+ line-height: 1;
1396
+ opacity: 0.7;
1397
+ transition: opacity 0.15s;
1398
+ }
1399
+
1400
+ .github-card .icon-btn-inline:hover:not(:disabled) {
1401
+ opacity: 1;
1402
+ }
1403
+
1404
+ .github-card .icon-btn-inline:disabled {
1405
+ opacity: 0.3;
1406
+ cursor: not-allowed;
1407
+ }
1408
+
1409
+ .github-card .github-actions {
1410
+ margin-top: 10px;
1411
+ }
1412
+
1413
+ /* Docs nav */
1414
+ .doc-nav {
1415
+ display: flex;
1416
+ align-items: center;
1417
+ gap: 4px;
1418
+ margin-bottom: 8px;
1419
+ }
1420
+
1421
+ .spec-issue-import {
1422
+ display: flex;
1423
+ gap: 8px;
1424
+ align-items: center;
1425
+ margin: 0 0 8px;
1426
+ flex-wrap: wrap;
1427
+ }
1428
+
1429
+ .spec-issue-input-row {
1430
+ display: flex;
1431
+ gap: 8px;
1432
+ align-items: center;
1433
+ flex: 1;
1434
+ min-width: 0;
1435
+ }
1436
+
1437
+ .spec-issue-input-row.hidden {
1438
+ display: none;
1439
+ }
1440
+
1441
+ .spec-issue-import input {
1442
+ flex: 1;
1443
+ padding: 8px 10px;
1444
+ border-radius: var(--radius);
1445
+ border: 1px solid var(--border);
1446
+ background: var(--bg);
1447
+ color: var(--text);
1448
+ font-size: 12px;
1449
+ min-width: 200px;
1450
+ }
1451
+
1452
+ .doc-editor {
1453
+ display: flex;
1454
+ flex-direction: column;
1455
+ gap: 6px;
1456
+ }
1457
+
1458
+ .chip {
1459
+ padding: 5px 10px;
1460
+ border-radius: var(--radius);
1461
+ border: 1px solid var(--border);
1462
+ background: var(--bg);
1463
+ color: var(--muted);
1464
+ cursor: pointer;
1465
+ font-size: 10px;
1466
+ font-family: inherit;
1467
+ text-transform: uppercase;
1468
+ letter-spacing: 0.04em;
1469
+ user-select: none;
1470
+ touch-action: manipulation;
1471
+ -webkit-tap-highlight-color: transparent;
1472
+ }
1473
+
1474
+ .chip:hover {
1475
+ color: var(--text);
1476
+ border-color: var(--muted);
1477
+ }
1478
+
1479
+ .chip.active {
1480
+ border-color: var(--accent);
1481
+ color: var(--accent);
1482
+ background: rgba(108, 245, 216, 0.08);
1483
+ }
1484
+
1485
+ /* Editor textarea */
1486
+ .doc-editor textarea {
1487
+ width: 100%;
1488
+ min-height: calc(100vh - 140px);
1489
+ background: var(--bg);
1490
+ color: var(--text);
1491
+ border: 1px solid var(--border);
1492
+ border-radius: var(--radius);
1493
+ padding: 8px;
1494
+ font-family: inherit;
1495
+ font-size: 12px;
1496
+ line-height: 1.5;
1497
+ resize: vertical;
1498
+ scrollbar-width: thin;
1499
+ scrollbar-color: var(--border) transparent;
1500
+ }
1501
+
1502
+ .doc-editor textarea::-webkit-scrollbar {
1503
+ width: 6px;
1504
+ }
1505
+
1506
+ .doc-editor textarea::-webkit-scrollbar-track {
1507
+ background: transparent;
1508
+ }
1509
+
1510
+ .doc-editor textarea::-webkit-scrollbar-thumb {
1511
+ background: var(--border);
1512
+ border-radius: 2px;
1513
+ }
1514
+
1515
+ .doc-editor textarea::placeholder {
1516
+ color: var(--muted);
1517
+ opacity: 0.6;
1518
+ }
1519
+
1520
+ .doc-editor textarea:focus {
1521
+ outline: none;
1522
+ border-color: var(--accent);
1523
+ }
1524
+
1525
+ /* Removed .snapshot-editor - snapshot now uses shared doc editor */
1526
+
1527
+ .doc-patch-main {
1528
+ border: 1px solid var(--border);
1529
+ border-radius: var(--radius);
1530
+ background: var(--panel);
1531
+ padding: 10px;
1532
+ margin-bottom: 8px;
1533
+ display: flex;
1534
+ flex-direction: column;
1535
+ gap: 8px;
1536
+ }
1537
+
1538
+ .doc-patch-main.hidden {
1539
+ display: none;
1540
+ }
1541
+
1542
+ .doc-patch-header {
1543
+ display: flex;
1544
+ justify-content: space-between;
1545
+ align-items: flex-start;
1546
+ gap: 12px;
1547
+ }
1548
+
1549
+ .doc-patch-info {
1550
+ flex: 1;
1551
+ min-width: 0;
1552
+ }
1553
+
1554
+ .doc-patch-legend {
1555
+ display: flex;
1556
+ gap: 12px;
1557
+ font-size: 9px;
1558
+ color: var(--muted);
1559
+ margin-top: 6px;
1560
+ }
1561
+
1562
+ .doc-patch-legend-item {
1563
+ display: flex;
1564
+ align-items: center;
1565
+ gap: 4px;
1566
+ }
1567
+
1568
+ .doc-patch-legend-add::before {
1569
+ content: "+";
1570
+ display: inline-flex;
1571
+ align-items: center;
1572
+ justify-content: center;
1573
+ width: 14px;
1574
+ height: 14px;
1575
+ background: rgba(46, 160, 67, 0.15);
1576
+ color: #3fb950;
1577
+ border-radius: 2px;
1578
+ font-weight: 600;
1579
+ font-size: 10px;
1580
+ }
1581
+
1582
+ .doc-patch-legend-del::before {
1583
+ content: "−";
1584
+ display: inline-flex;
1585
+ align-items: center;
1586
+ justify-content: center;
1587
+ width: 14px;
1588
+ height: 14px;
1589
+ background: rgba(248, 81, 73, 0.15);
1590
+ color: #f85149;
1591
+ border-radius: 2px;
1592
+ font-weight: 600;
1593
+ font-size: 10px;
1594
+ }
1595
+
1596
+ .doc-patch-summary {
1597
+ color: var(--text);
1598
+ font-weight: 600;
1599
+ font-size: 12px;
1600
+ }
1601
+
1602
+ .doc-patch-actions {
1603
+ display: flex;
1604
+ gap: 6px;
1605
+ flex-wrap: wrap;
1606
+ }
1607
+
1608
+ .doc-patch-body {
1609
+ background: #0d1117;
1610
+ color: #d6dbe0;
1611
+ border-radius: var(--radius);
1612
+ padding: 0;
1613
+ max-height: 320px;
1614
+ overflow: auto;
1615
+ font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
1616
+ font-size: 11px;
1617
+ line-height: 1;
1618
+ border: 1px solid #21262d;
1619
+ }
1620
+
1621
+ /* Diff syntax highlighting - line-by-line with gutters */
1622
+ .diff-view {
1623
+ display: flex;
1624
+ flex-direction: column;
1625
+ }
1626
+
1627
+ .diff-line {
1628
+ display: flex;
1629
+ align-items: stretch;
1630
+ min-height: 1.5em;
1631
+ line-height: 1.5;
1632
+ }
1633
+
1634
+ .diff-gutter {
1635
+ flex: 0 0 36px;
1636
+ text-align: right;
1637
+ padding-right: 8px;
1638
+ color: #6e7681;
1639
+ font-size: 10px;
1640
+ user-select: none;
1641
+ border-right: 1px solid #21262d;
1642
+ background: #161b22;
1643
+ }
1644
+
1645
+ .diff-gutter-add {
1646
+ background: rgba(46, 160, 67, 0.2);
1647
+ color: #7ee787;
1648
+ }
1649
+
1650
+ .diff-gutter-del {
1651
+ background: rgba(248, 81, 73, 0.2);
1652
+ color: #f97583;
1653
+ }
1654
+
1655
+ .diff-gutter-ctx {
1656
+ background: #161b22;
1657
+ }
1658
+
1659
+ .diff-gutter-hunk {
1660
+ background: rgba(56, 139, 253, 0.1);
1661
+ color: #58a6ff;
1662
+ text-align: center;
1663
+ padding-right: 0;
1664
+ }
1665
+
1666
+ .diff-sign {
1667
+ flex: 0 0 16px;
1668
+ text-align: center;
1669
+ font-weight: 600;
1670
+ user-select: none;
1671
+ }
1672
+
1673
+ .diff-add .diff-sign {
1674
+ color: #3fb950;
1675
+ background: rgba(46, 160, 67, 0.15);
1676
+ }
1677
+
1678
+ .diff-del .diff-sign {
1679
+ color: #f85149;
1680
+ background: rgba(248, 81, 73, 0.15);
1681
+ }
1682
+
1683
+ .diff-ctx .diff-sign {
1684
+ color: transparent;
1685
+ }
1686
+
1687
+ .diff-content {
1688
+ flex: 1;
1689
+ padding-left: 8px;
1690
+ white-space: pre-wrap;
1691
+ word-break: break-word;
1692
+ }
1693
+
1694
+ /* Line type backgrounds */
1695
+ .diff-line.diff-add {
1696
+ background: rgba(46, 160, 67, 0.12);
1697
+ }
1698
+
1699
+ .diff-line.diff-add .diff-content {
1700
+ color: #aff5b4;
1701
+ }
1702
+
1703
+ .diff-line.diff-del {
1704
+ background: rgba(248, 81, 73, 0.12);
1705
+ }
1706
+
1707
+ .diff-line.diff-del .diff-content {
1708
+ color: #ffc1c8;
1709
+ }
1710
+
1711
+ .diff-line.diff-hunk {
1712
+ background: rgba(56, 139, 253, 0.08);
1713
+ border-top: 1px solid rgba(56, 139, 253, 0.3);
1714
+ border-bottom: 1px solid rgba(56, 139, 253, 0.3);
1715
+ margin-top: 4px;
1716
+ }
1717
+
1718
+ .diff-line.diff-hunk:first-child {
1719
+ margin-top: 0;
1720
+ }
1721
+
1722
+ .diff-line.diff-hunk .diff-content {
1723
+ color: #a5d6ff;
1724
+ font-weight: 600;
1725
+ padding-left: 8px;
1726
+ }
1727
+
1728
+ .diff-line.diff-file {
1729
+ background: transparent;
1730
+ }
1731
+
1732
+ .diff-line.diff-file .diff-content {
1733
+ color: #d2a8ff;
1734
+ font-weight: 500;
1735
+ }
1736
+
1737
+ .diff-line.diff-ctx .diff-content {
1738
+ color: #8b949e;
1739
+ }
1740
+
1741
+ .diff-line.diff-meta .diff-content {
1742
+ color: #6e7681;
1743
+ font-style: italic;
1744
+ padding-left: 60px; /* Align with content after gutter + sign */
1745
+ }
1746
+
1747
+ /* Empty line marker - visible symbol for blank lines */
1748
+ .diff-empty-marker {
1749
+ color: #6e7681;
1750
+ background: rgba(110, 118, 129, 0.15);
1751
+ padding: 0 4px;
1752
+ border-radius: 2px;
1753
+ font-size: 10px;
1754
+ font-style: italic;
1755
+ }
1756
+
1757
+ .diff-add .diff-empty-marker {
1758
+ color: #56d364;
1759
+ background: rgba(46, 160, 67, 0.25);
1760
+ }
1761
+
1762
+ .diff-del .diff-empty-marker {
1763
+ color: #f97583;
1764
+ background: rgba(248, 81, 73, 0.25);
1765
+ }
1766
+
1767
+ .doc-actions {
1768
+ display: flex;
1769
+ gap: 4px;
1770
+ margin-top: 6px;
1771
+ align-items: center;
1772
+ flex-wrap: wrap;
1773
+ }
1774
+
1775
+ .doc-actions.hidden {
1776
+ display: none;
1777
+ }
1778
+
1779
+ /* Shared compose panel styling (terminal + doc chat) */
1780
+ .compose-panel {
1781
+ margin-top: 4px;
1782
+ padding: 6px;
1783
+ border: 1px solid var(--border);
1784
+ border-radius: var(--radius);
1785
+ background: var(--panel);
1786
+ display: flex;
1787
+ flex-direction: column;
1788
+ gap: 4px;
1789
+ }
1790
+
1791
+ .compose-row {
1792
+ display: flex;
1793
+ align-items: stretch;
1794
+ gap: 6px;
1795
+ }
1796
+
1797
+ .compose-row textarea {
1798
+ flex: 1 1 auto;
1799
+ width: 100%;
1800
+ min-height: 56px;
1801
+ max-height: 160px;
1802
+ background: var(--bg);
1803
+ border: 1px solid var(--border);
1804
+ border-radius: var(--radius);
1805
+ color: var(--text);
1806
+ padding: 6px;
1807
+ font-family: inherit;
1808
+ font-size: 12px;
1809
+ line-height: 1.3;
1810
+ resize: vertical;
1811
+ overflow-y: auto;
1812
+ }
1813
+
1814
+ .compose-row textarea:focus {
1815
+ border-color: var(--accent);
1816
+ outline: none;
1817
+ }
1818
+
1819
+ .compose-row textarea::placeholder {
1820
+ color: var(--muted);
1821
+ opacity: 0.6;
1822
+ }
1823
+
1824
+ .compose-buttons {
1825
+ display: flex;
1826
+ flex-direction: column;
1827
+ gap: 6px;
1828
+ flex: 0 0 auto;
1829
+ }
1830
+
1831
+ .compose-buttons button {
1832
+ width: 34px;
1833
+ height: 34px;
1834
+ min-width: 34px;
1835
+ min-height: 34px;
1836
+ padding: 0;
1837
+ display: flex;
1838
+ align-items: center;
1839
+ justify-content: center;
1840
+ font-size: 12px;
1841
+ border-radius: 10px;
1842
+ }
1843
+
1844
+ .compose-buttons .voice-button svg {
1845
+ width: 14px;
1846
+ height: 14px;
1847
+ min-width: 14px;
1848
+ min-height: 14px;
1849
+ fill: none;
1850
+ }
1851
+
1852
+ /* Doc chat panel - compact inline design */
1853
+ .doc-chat-panel {
1854
+ flex-shrink: 0;
1855
+ }
1856
+
1857
+ .doc-chat-compose {
1858
+ display: flex;
1859
+ flex-direction: column;
1860
+ gap: 2px;
1861
+ }
1862
+
1863
+ .voice-button {
1864
+ border: 1px solid var(--border);
1865
+ background: var(--panel);
1866
+ color: var(--text);
1867
+ display: inline-flex;
1868
+ align-items: center;
1869
+ justify-content: center;
1870
+ flex-shrink: 0;
1871
+ position: relative;
1872
+ }
1873
+
1874
+ .voice-button svg {
1875
+ width: 16px;
1876
+ height: 16px;
1877
+ min-width: 16px;
1878
+ min-height: 16px;
1879
+ stroke: currentColor;
1880
+ flex-shrink: 0;
1881
+ }
1882
+
1883
+ .voice-button.voice-recording {
1884
+ background: #b3261e;
1885
+ color: #fff;
1886
+ border-color: #b3261e;
1887
+ box-shadow: 0 0 0 2px rgba(179, 38, 30, 0.2);
1888
+ }
1889
+
1890
+ .voice-button.voice-sending {
1891
+ background: var(--accent);
1892
+ color: #fff;
1893
+ border-color: var(--accent);
1894
+ }
1895
+
1896
+ .voice-button.voice-sending .voice-spinner {
1897
+ animation: voice-spin 0.8s linear infinite;
1898
+ }
1899
+
1900
+ @keyframes voice-spin {
1901
+ to {
1902
+ transform: rotate(360deg);
1903
+ }
1904
+ }
1905
+
1906
+ .voice-button.voice-sending svg {
1907
+ opacity: 0.35;
1908
+ }
1909
+
1910
+ .voice-button.voice-sending::after {
1911
+ content: "";
1912
+ position: absolute;
1913
+ width: 14px;
1914
+ height: 14px;
1915
+ border: 2px solid rgba(255, 255, 255, 0.5);
1916
+ border-top-color: #fff;
1917
+ border-radius: 50%;
1918
+ animation: voice-spin 0.8s linear infinite;
1919
+ pointer-events: none;
1920
+ }
1921
+
1922
+ @keyframes voice-spin {
1923
+ to {
1924
+ transform: rotate(360deg);
1925
+ }
1926
+ }
1927
+
1928
+ .voice-button.voice-error {
1929
+ border-color: #d35400;
1930
+ color: #d35400;
1931
+ }
1932
+
1933
+ .voice-button.voice-retry {
1934
+ background: #fff7e6;
1935
+ border-color: #e0c080;
1936
+ color: #8c5b00;
1937
+ }
1938
+
1939
+ .voice-button.disabled {
1940
+ opacity: 0.5;
1941
+ cursor: not-allowed;
1942
+ }
1943
+
1944
+ .voice-button.voice-disconnected {
1945
+ opacity: 0.65;
1946
+ }
1947
+
1948
+ .voice-status {
1949
+ color: var(--muted);
1950
+ }
1951
+
1952
+ /* Audio level meter visualization - positioned relative to parent */
1953
+ .voice-level-meter {
1954
+ display: inline-flex;
1955
+ align-items: flex-end;
1956
+ gap: 2px;
1957
+ height: 20px;
1958
+ padding: 0 4px;
1959
+ vertical-align: middle;
1960
+ flex-shrink: 0;
1961
+ }
1962
+
1963
+ .voice-level-meter.voice-level-stop {
1964
+ cursor: pointer;
1965
+ }
1966
+
1967
+ .voice-level-bar {
1968
+ width: 3px;
1969
+ min-height: 3px;
1970
+ height: 15%;
1971
+ background: var(--accent);
1972
+ border-radius: 1px;
1973
+ transition: height 0.05s ease-out;
1974
+ opacity: 0.4;
1975
+ }
1976
+
1977
+ .voice-level-bar.active {
1978
+ opacity: 1;
1979
+ background: #4ade80;
1980
+ }
1981
+
1982
+ .doc-chat-meta {
1983
+ display: flex;
1984
+ align-items: center;
1985
+ justify-content: space-between;
1986
+ gap: 6px;
1987
+ padding: 0;
1988
+ font-size: 10px;
1989
+ }
1990
+
1991
+ .doc-chat-meta .loading {
1992
+ color: var(--accent);
1993
+ }
1994
+
1995
+ .doc-chat-meta .loading::before {
1996
+ content: "●";
1997
+ display: inline-block;
1998
+ margin-right: 4px;
1999
+ animation: pulse-dot 1s ease-in-out infinite;
2000
+ }
2001
+
2002
+ @keyframes pulse-dot {
2003
+ 0%, 100% { opacity: 1; }
2004
+ 50% { opacity: 0.3; }
2005
+ }
2006
+
2007
+ /* Response wrapper - only visible when there's content */
2008
+ .doc-chat-response-wrapper {
2009
+ border: 1px solid var(--border);
2010
+ border-radius: var(--radius);
2011
+ background: var(--bg);
2012
+ padding: 4px 6px;
2013
+ max-height: 120px;
2014
+ overflow-y: auto;
2015
+ font-size: 11px;
2016
+ }
2017
+
2018
+ .doc-chat-response-wrapper.hidden {
2019
+ display: none;
2020
+ }
2021
+
2022
+ .doc-chat-response {
2023
+ white-space: pre-wrap;
2024
+ word-break: break-word;
2025
+ font-size: 12px;
2026
+ line-height: 1.5;
2027
+ }
2028
+
2029
+ .doc-chat-response.streaming {
2030
+ color: var(--accent);
2031
+ border-left: 2px solid var(--accent);
2032
+ padding-left: 8px;
2033
+ margin-left: -2px;
2034
+ }
2035
+
2036
+ .doc-chat-patch-wrapper {
2037
+ border: 1px solid var(--border);
2038
+ border-radius: var(--radius);
2039
+ background: var(--bg);
2040
+ padding: 8px;
2041
+ max-height: 240px;
2042
+ overflow: hidden;
2043
+ display: flex;
2044
+ flex-direction: column;
2045
+ gap: 6px;
2046
+ }
2047
+
2048
+ .doc-chat-patch-wrapper.hidden {
2049
+ display: none;
2050
+ }
2051
+
2052
+ .doc-chat-patch-actions {
2053
+ display: flex;
2054
+ gap: 6px;
2055
+ align-items: center;
2056
+ }
2057
+
2058
+ .spacer {
2059
+ flex: 1;
2060
+ }
2061
+
2062
+ .doc-chat-patch {
2063
+ background: #0f1116;
2064
+ color: #d6dbe0;
2065
+ border-radius: var(--radius);
2066
+ padding: 8px;
2067
+ overflow: auto;
2068
+ max-height: 160px;
2069
+ font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
2070
+ font-size: 11px;
2071
+ line-height: 1.4;
2072
+ }
2073
+
2074
+ .doc-chat-error {
2075
+ margin-top: 6px;
2076
+ color: var(--error);
2077
+ font-size: 11px;
2078
+ }
2079
+
2080
+ /* Collapsible history */
2081
+ .doc-chat-history-details {
2082
+ border: 1px solid var(--border);
2083
+ border-radius: var(--radius);
2084
+ background: var(--bg);
2085
+ }
2086
+
2087
+ .doc-chat-history-details[open] {
2088
+ background: var(--panel);
2089
+ }
2090
+
2091
+ .doc-chat-history-toggle {
2092
+ display: flex;
2093
+ align-items: center;
2094
+ justify-content: space-between;
2095
+ padding: 3px 6px;
2096
+ cursor: pointer;
2097
+ font-size: 9px;
2098
+ text-transform: uppercase;
2099
+ letter-spacing: 0.04em;
2100
+ color: var(--muted);
2101
+ user-select: none;
2102
+ list-style: none;
2103
+ }
2104
+
2105
+ .doc-chat-history-toggle::-webkit-details-marker {
2106
+ display: none;
2107
+ }
2108
+
2109
+ .doc-chat-history-toggle::before {
2110
+ content: "▶";
2111
+ font-size: 8px;
2112
+ margin-right: 6px;
2113
+ transition: transform 0.15s ease;
2114
+ }
2115
+
2116
+ .doc-chat-history-details[open] .doc-chat-history-toggle::before {
2117
+ transform: rotate(90deg);
2118
+ }
2119
+
2120
+ .doc-chat-history-count {
2121
+ background: var(--border);
2122
+ padding: 2px 6px;
2123
+ border-radius: 10px;
2124
+ font-size: 9px;
2125
+ min-width: 18px;
2126
+ text-align: center;
2127
+ }
2128
+
2129
+ .doc-chat-history {
2130
+ max-height: 100px;
2131
+ overflow-y: auto;
2132
+ padding: 0 6px 4px;
2133
+ }
2134
+
2135
+ .doc-chat-entry {
2136
+ display: grid;
2137
+ grid-template-columns: 1fr auto;
2138
+ grid-template-rows: auto auto;
2139
+ gap: 0 4px;
2140
+ border-bottom: 1px solid var(--border);
2141
+ padding: 3px 0;
2142
+ align-items: baseline;
2143
+ }
2144
+
2145
+ .doc-chat-entry-detail {
2146
+ grid-column: 1 / -1;
2147
+ margin-top: 4px;
2148
+ }
2149
+
2150
+ .doc-chat-entry-detail pre {
2151
+ background: #0f1116;
2152
+ color: #d6dbe0;
2153
+ padding: 6px;
2154
+ border-radius: var(--radius);
2155
+ overflow: auto;
2156
+ font-size: 11px;
2157
+ white-space: pre-wrap;
2158
+ word-break: break-word;
2159
+ }
2160
+
2161
+ .doc-chat-entry-patch {
2162
+ border-left: 2px solid var(--accent);
2163
+ }
2164
+
2165
+ .doc-chat-entry:last-child {
2166
+ border-bottom: none;
2167
+ }
2168
+
2169
+ .doc-chat-entry .prompt-row {
2170
+ display: flex;
2171
+ align-items: center;
2172
+ gap: 4px;
2173
+ grid-column: 1;
2174
+ min-width: 0;
2175
+ }
2176
+
2177
+ .doc-chat-entry .prompt {
2178
+ font-weight: 500;
2179
+ font-size: 10px;
2180
+ color: var(--accent-2);
2181
+ white-space: nowrap;
2182
+ overflow: hidden;
2183
+ text-overflow: ellipsis;
2184
+ flex: 1;
2185
+ min-width: 0;
2186
+ }
2187
+
2188
+ .doc-chat-entry .copy-prompt-btn {
2189
+ flex-shrink: 0;
2190
+ width: 18px;
2191
+ height: 18px;
2192
+ padding: 0;
2193
+ display: flex;
2194
+ align-items: center;
2195
+ justify-content: center;
2196
+ font-size: 10px;
2197
+ background: transparent;
2198
+ border: 1px solid var(--border);
2199
+ border-radius: var(--radius);
2200
+ color: var(--muted);
2201
+ cursor: pointer;
2202
+ opacity: 0;
2203
+ transition: all 0.1s ease;
2204
+ }
2205
+
2206
+ .doc-chat-entry:hover .copy-prompt-btn {
2207
+ opacity: 0.7;
2208
+ }
2209
+
2210
+ .doc-chat-entry .copy-prompt-btn:hover {
2211
+ opacity: 1;
2212
+ color: var(--accent);
2213
+ border-color: var(--accent);
2214
+ background: rgba(108, 245, 216, 0.1);
2215
+ }
2216
+
2217
+ .doc-chat-entry .response {
2218
+ color: var(--muted);
2219
+ font-size: 10px;
2220
+ white-space: nowrap;
2221
+ overflow: hidden;
2222
+ text-overflow: ellipsis;
2223
+ grid-column: 1 / -1;
2224
+ }
2225
+
2226
+ .doc-chat-entry .meta {
2227
+ font-size: 9px;
2228
+ color: var(--muted);
2229
+ display: flex;
2230
+ gap: 3px;
2231
+ align-items: center;
2232
+ opacity: 0.6;
2233
+ grid-column: 2;
2234
+ grid-row: 1;
2235
+ }
2236
+
2237
+ .doc-chat-entry .status-dot {
2238
+ width: 6px;
2239
+ height: 6px;
2240
+ border-radius: 50%;
2241
+ background: var(--border);
2242
+ flex-shrink: 0;
2243
+ }
2244
+
2245
+ .doc-chat-entry.running .status-dot {
2246
+ background: var(--accent);
2247
+ box-shadow: 0 0 0 2px rgba(108, 245, 216, 0.2);
2248
+ }
2249
+
2250
+ .doc-chat-entry.error .status-dot {
2251
+ background: var(--error);
2252
+ }
2253
+
2254
+ .doc-chat-empty {
2255
+ padding: 8px 0;
2256
+ text-align: center;
2257
+ }
2258
+
2259
+ /* Entry details (View details) */
2260
+ .doc-chat-entry-detail {
2261
+ margin-top: 2px;
2262
+ font-size: 10px;
2263
+ }
2264
+
2265
+ .doc-chat-entry-detail summary {
2266
+ cursor: pointer;
2267
+ color: var(--muted);
2268
+ font-size: 9px;
2269
+ padding: 2px 0;
2270
+ }
2271
+
2272
+ .doc-chat-entry-detail summary:hover {
2273
+ color: var(--text);
2274
+ }
2275
+
2276
+ .doc-chat-entry-body {
2277
+ margin-top: 4px;
2278
+ max-height: 100px;
2279
+ overflow-y: auto;
2280
+ }
2281
+
2282
+ .doc-chat-entry-body pre {
2283
+ margin: 0;
2284
+ padding: 4px;
2285
+ font-size: 9px;
2286
+ background: var(--bg);
2287
+ border-radius: var(--radius);
2288
+ white-space: pre-wrap;
2289
+ word-break: break-word;
2290
+ }
2291
+
2292
+ .doc-chat-entry-patch {
2293
+ border-left: 2px solid var(--accent);
2294
+ margin-top: 4px;
2295
+ }
2296
+
2297
+ .card .row {
2298
+ display: flex;
2299
+ align-items: center;
2300
+ gap: 6px;
2301
+ flex-wrap: wrap;
2302
+ }
2303
+
2304
+ /* Inputs */
2305
+ input[type="number"],
2306
+ input[type="text"] {
2307
+ background: var(--bg);
2308
+ border: 1px solid var(--border);
2309
+ border-radius: var(--radius);
2310
+ color: var(--text);
2311
+ padding: 4px 6px;
2312
+ font-size: 11px;
2313
+ font-family: inherit;
2314
+ width: 60px;
2315
+ }
2316
+
2317
+ input[type="number"]::placeholder,
2318
+ input[type="text"]::placeholder {
2319
+ color: var(--muted);
2320
+ opacity: 0.6;
2321
+ }
2322
+
2323
+ input[type="number"]:focus,
2324
+ input[type="text"]:focus {
2325
+ outline: none;
2326
+ border-color: var(--accent);
2327
+ }
2328
+
2329
+ label {
2330
+ display: flex;
2331
+ align-items: center;
2332
+ gap: 4px;
2333
+ font-size: 10px;
2334
+ color: var(--muted);
2335
+ user-select: none;
2336
+ }
2337
+
2338
+ /* Inline toolbar for Logs/Terminal - super compact */
2339
+ .inline-toolbar {
2340
+ display: flex;
2341
+ align-items: center;
2342
+ gap: 8px;
2343
+ padding: 6px 8px;
2344
+ background: var(--panel);
2345
+ border: 1px solid var(--border);
2346
+ border-radius: var(--radius);
2347
+ margin-bottom: 6px;
2348
+ }
2349
+
2350
+ .inline-toolbar .terminal-voice {
2351
+ margin-left: auto;
2352
+ display: flex;
2353
+ align-items: center;
2354
+ gap: 6px;
2355
+ }
2356
+
2357
+ .inline-toolbar .terminal-voice .voice-button {
2358
+ width: 28px;
2359
+ height: 28px;
2360
+ min-width: 28px;
2361
+ min-height: 28px;
2362
+ padding: 0;
2363
+ flex-shrink: 0;
2364
+ }
2365
+
2366
+ .inline-toolbar .terminal-voice .voice-button svg {
2367
+ width: 14px;
2368
+ height: 14px;
2369
+ min-width: 14px;
2370
+ min-height: 14px;
2371
+ }
2372
+
2373
+ .inline-toolbar .terminal-voice .voice-status {
2374
+ white-space: nowrap;
2375
+ }
2376
+
2377
+ /* Log viewer - maximize height (accounts for nav + toolbar + legend) */
2378
+ .log-viewer {
2379
+ background: var(--bg);
2380
+ border-radius: var(--radius);
2381
+ border: 1px solid var(--border);
2382
+ padding: 8px;
2383
+ color: #b0c0d8;
2384
+ height: calc(100vh - 130px);
2385
+ overflow: auto;
2386
+ white-space: pre-wrap;
2387
+ font-family: inherit;
2388
+ font-size: 11px;
2389
+ line-height: 1.4;
2390
+ margin: 0;
2391
+ scroll-behavior: smooth;
2392
+ scrollbar-width: thin;
2393
+ scrollbar-color: var(--border) transparent;
2394
+ }
2395
+
2396
+ .log-viewer:empty::before,
2397
+ .log-viewer.empty::before {
2398
+ content: "(no logs)";
2399
+ color: var(--muted);
2400
+ font-style: italic;
2401
+ }
2402
+
2403
+ .log-viewer::-webkit-scrollbar {
2404
+ width: 6px;
2405
+ }
2406
+
2407
+ .log-viewer::-webkit-scrollbar-track {
2408
+ background: transparent;
2409
+ }
2410
+
2411
+ .log-viewer::-webkit-scrollbar-thumb {
2412
+ background: var(--border);
2413
+ border-radius: 2px;
2414
+ }
2415
+
2416
+ .log-viewer::-webkit-scrollbar-thumb:hover {
2417
+ background: #2a3450;
2418
+ }
2419
+
2420
+ /* ========== LOG LINE TYPES ========== */
2421
+
2422
+ .log-line {
2423
+ padding: 1px 4px;
2424
+ border-radius: 2px;
2425
+ margin: 1px 0;
2426
+ position: relative;
2427
+ }
2428
+
2429
+ /* Icons before certain line types */
2430
+ .log-line[data-icon]::before {
2431
+ content: attr(data-icon);
2432
+ display: inline-block;
2433
+ margin-right: 6px;
2434
+ font-size: 10px;
2435
+ opacity: 0.8;
2436
+ }
2437
+
2438
+ /* Run boundaries - prominent separators */
2439
+ .log-line.log-run-start,
2440
+ .log-line.log-run-end {
2441
+ background: linear-gradient(90deg, rgba(108, 245, 216, 0.15) 0%, transparent 100%);
2442
+ border-left: 3px solid var(--accent);
2443
+ color: var(--accent);
2444
+ font-weight: 600;
2445
+ padding: 6px 8px;
2446
+ margin: 12px 0 8px 0;
2447
+ font-size: 12px;
2448
+ letter-spacing: 0.02em;
2449
+ }
2450
+
2451
+ .log-line.log-run-end {
2452
+ background: linear-gradient(90deg, rgba(108, 168, 255, 0.12) 0%, transparent 100%);
2453
+ border-left-color: var(--accent-2);
2454
+ color: var(--accent-2);
2455
+ margin: 8px 0 12px 0;
2456
+ }
2457
+
2458
+ /* Thinking/reasoning - italicized, muted */
2459
+ .log-line.log-thinking-label {
2460
+ color: #9b7aff;
2461
+ font-style: italic;
2462
+ opacity: 0.7;
2463
+ font-size: 10px;
2464
+ text-transform: uppercase;
2465
+ letter-spacing: 0.05em;
2466
+ margin-top: 6px;
2467
+ }
2468
+
2469
+ .log-line.log-thinking {
2470
+ color: #b8a3ff;
2471
+ font-style: italic;
2472
+ padding-left: 20px;
2473
+ border-left: 2px solid rgba(155, 122, 255, 0.3);
2474
+ background: rgba(155, 122, 255, 0.05);
2475
+ }
2476
+
2477
+ /* Tool execution - highlighted */
2478
+ .log-line.log-exec-label {
2479
+ color: #ffa64d;
2480
+ font-size: 10px;
2481
+ text-transform: uppercase;
2482
+ letter-spacing: 0.05em;
2483
+ opacity: 0.8;
2484
+ margin-top: 6px;
2485
+ }
2486
+
2487
+ .log-line.log-exec-command {
2488
+ color: #ffcc80;
2489
+ background: rgba(255, 166, 77, 0.08);
2490
+ border-left: 2px solid rgba(255, 166, 77, 0.4);
2491
+ padding-left: 20px;
2492
+ font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
2493
+ }
2494
+
2495
+ /* File updates */
2496
+ .log-line.log-file-update-label {
2497
+ color: #4dc9ff;
2498
+ font-size: 10px;
2499
+ text-transform: uppercase;
2500
+ letter-spacing: 0.05em;
2501
+ opacity: 0.8;
2502
+ margin-top: 6px;
2503
+ }
2504
+
2505
+ .log-line.log-file-modified {
2506
+ color: #80d4ff;
2507
+ background: rgba(77, 201, 255, 0.08);
2508
+ border-left: 2px solid rgba(77, 201, 255, 0.4);
2509
+ padding-left: 20px;
2510
+ }
2511
+
2512
+ /* Diff styling */
2513
+ .log-line.log-diff-header {
2514
+ color: #d2a8ff;
2515
+ font-size: 10px;
2516
+ opacity: 0.7;
2517
+ }
2518
+
2519
+ .log-line.log-diff-hunk {
2520
+ color: #58a6ff;
2521
+ background: rgba(56, 139, 253, 0.08);
2522
+ font-weight: 500;
2523
+ }
2524
+
2525
+ .log-line.log-diff-add {
2526
+ color: #7ee787;
2527
+ background: rgba(46, 160, 67, 0.12);
2528
+ border-left: 2px solid #3fb950;
2529
+ padding-left: 20px;
2530
+ }
2531
+
2532
+ .log-line.log-diff-del {
2533
+ color: #f97583;
2534
+ background: rgba(248, 81, 73, 0.12);
2535
+ border-left: 2px solid #f85149;
2536
+ padding-left: 20px;
2537
+ }
2538
+
2539
+ /* Prompt/context markers - dimmed, collapsible appearance */
2540
+ .log-line.log-prompt-marker,
2541
+ .log-line.log-prompt-marker-end {
2542
+ color: #6e7681;
2543
+ font-size: 10px;
2544
+ opacity: 0.5;
2545
+ font-style: italic;
2546
+ }
2547
+
2548
+ .log-line.log-prompt-context {
2549
+ color: #6e7681;
2550
+ opacity: 0.4;
2551
+ font-size: 10px;
2552
+ padding-left: 12px;
2553
+ border-left: 1px dashed rgba(110, 118, 129, 0.3);
2554
+ }
2555
+
2556
+ /* System messages */
2557
+ .log-line.log-system {
2558
+ color: #6e7681;
2559
+ font-size: 10px;
2560
+ opacity: 0.6;
2561
+ }
2562
+
2563
+ .log-line.log-tokens {
2564
+ color: #a371f7;
2565
+ font-size: 10px;
2566
+ background: rgba(163, 113, 247, 0.08);
2567
+ border-radius: 3px;
2568
+ padding: 2px 6px;
2569
+ display: inline-block;
2570
+ margin: 4px 0;
2571
+ }
2572
+
2573
+ /* Success/exit status */
2574
+ .log-line.log-success {
2575
+ color: #56d364;
2576
+ }
2577
+
2578
+ .log-line.log-exit-code {
2579
+ color: #8b949e;
2580
+ font-size: 10px;
2581
+ }
2582
+
2583
+ /* Agent output - most prominent! This is the final answer */
2584
+ .log-line.log-agent-output {
2585
+ color: var(--text);
2586
+ background: linear-gradient(90deg, rgba(108, 245, 216, 0.12) 0%, rgba(108, 168, 255, 0.08) 100%);
2587
+ border: 1px solid rgba(108, 245, 216, 0.3);
2588
+ border-radius: 4px;
2589
+ padding: 8px 12px;
2590
+ margin: 8px 0;
2591
+ font-weight: 500;
2592
+ font-size: 12px;
2593
+ line-height: 1.5;
2594
+ }
2595
+
2596
+ /* Regular output */
2597
+ .log-line.log-output {
2598
+ color: #b0c0d8;
2599
+ }
2600
+
2601
+ /* Test output */
2602
+ .log-line.log-test-output {
2603
+ color: #58a6ff;
2604
+ font-size: 10px;
2605
+ }
2606
+
2607
+ /* Error/traceback output */
2608
+ .log-line.log-error-output {
2609
+ color: #f97583;
2610
+ background: rgba(248, 81, 73, 0.08);
2611
+ border-left: 2px solid #f85149;
2612
+ padding-left: 20px;
2613
+ }
2614
+
2615
+ /* Blank lines */
2616
+ .log-line.log-blank {
2617
+ height: 8px;
2618
+ }
2619
+
2620
+ /* ========== LOG LEGEND ========== */
2621
+ .log-legend {
2622
+ display: flex;
2623
+ flex-wrap: wrap;
2624
+ gap: 8px;
2625
+ padding: 4px 8px;
2626
+ background: var(--panel);
2627
+ border: 1px solid var(--border);
2628
+ border-radius: var(--radius);
2629
+ margin-bottom: 6px;
2630
+ font-size: 9px;
2631
+ align-items: center;
2632
+ }
2633
+
2634
+ .log-legend-item {
2635
+ display: flex;
2636
+ align-items: center;
2637
+ gap: 4px;
2638
+ color: var(--muted);
2639
+ }
2640
+
2641
+ .log-legend-dot {
2642
+ width: 8px;
2643
+ height: 8px;
2644
+ border-radius: 2px;
2645
+ flex-shrink: 0;
2646
+ }
2647
+
2648
+ .log-legend-dot.thinking { background: #9b7aff; }
2649
+ .log-legend-dot.exec { background: #ffa64d; }
2650
+ .log-legend-dot.file { background: #4dc9ff; }
2651
+ .log-legend-dot.diff-add { background: #3fb950; }
2652
+ .log-legend-dot.diff-del { background: #f85149; }
2653
+ .log-legend-dot.output { background: var(--accent); }
2654
+ .log-legend-dot.context { background: #6e7681; opacity: 0.5; }
2655
+
2656
+ /* ========== COLLAPSIBLE CONTEXT BLOCKS ========== */
2657
+ .log-context-block {
2658
+ margin: 4px 0;
2659
+ border: 1px solid rgba(110, 118, 129, 0.2);
2660
+ border-radius: 4px;
2661
+ background: rgba(110, 118, 129, 0.05);
2662
+ }
2663
+
2664
+ .log-context-block[open] {
2665
+ background: rgba(110, 118, 129, 0.08);
2666
+ }
2667
+
2668
+ .log-context-summary {
2669
+ display: flex;
2670
+ align-items: center;
2671
+ gap: 6px;
2672
+ padding: 4px 8px;
2673
+ cursor: pointer;
2674
+ font-size: 10px;
2675
+ color: #6e7681;
2676
+ user-select: none;
2677
+ list-style: none;
2678
+ }
2679
+
2680
+ .log-context-summary::-webkit-details-marker {
2681
+ display: none;
2682
+ }
2683
+
2684
+ .log-context-summary:hover {
2685
+ color: #8b949e;
2686
+ background: rgba(110, 118, 129, 0.1);
2687
+ }
2688
+
2689
+ .log-context-icon {
2690
+ font-size: 8px;
2691
+ transition: transform 0.15s ease;
2692
+ }
2693
+
2694
+ .log-context-block[open] .log-context-icon {
2695
+ transform: rotate(90deg);
2696
+ }
2697
+
2698
+ .log-context-count {
2699
+ opacity: 0.6;
2700
+ font-size: 9px;
2701
+ }
2702
+
2703
+ .log-context-content {
2704
+ padding: 4px 8px 8px;
2705
+ border-top: 1px solid rgba(110, 118, 129, 0.15);
2706
+ max-height: 200px;
2707
+ overflow-y: auto;
2708
+ font-size: 10px;
2709
+ }
2710
+
2711
+ .log-context-content .log-line {
2712
+ margin: 0;
2713
+ padding: 1px 4px;
2714
+ }
2715
+
2716
+ /* ========== RUN SECTION STYLING ========== */
2717
+ .log-run-section {
2718
+ margin: 8px 0;
2719
+ border-left: 2px solid var(--border);
2720
+ padding-left: 8px;
2721
+ }
2722
+
2723
+ /* ========== LOG CONTAINER WITH JUMP BUTTON ========== */
2724
+ .log-container {
2725
+ position: relative;
2726
+ height: calc(100vh - 130px);
2727
+ }
2728
+
2729
+ .log-container .log-viewer {
2730
+ height: 100%;
2731
+ }
2732
+
2733
+ .log-load-btn {
2734
+ position: absolute;
2735
+ top: 16px;
2736
+ left: 16px;
2737
+ background: var(--panel);
2738
+ color: var(--text);
2739
+ border: 1px solid var(--border);
2740
+ border-radius: 16px;
2741
+ padding: 6px 12px;
2742
+ font-size: 10px;
2743
+ font-weight: 600;
2744
+ cursor: pointer;
2745
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35);
2746
+ z-index: 10;
2747
+ transition: all 0.15s ease;
2748
+ opacity: 0;
2749
+ transform: translateY(-6px);
2750
+ pointer-events: none;
2751
+ }
2752
+
2753
+ .log-load-btn:not(.hidden) {
2754
+ opacity: 1;
2755
+ transform: translateY(0);
2756
+ pointer-events: auto;
2757
+ }
2758
+
2759
+ .log-load-btn:hover {
2760
+ border-color: rgba(108, 245, 216, 0.5);
2761
+ color: var(--accent);
2762
+ }
2763
+
2764
+ .log-jump-btn {
2765
+ position: absolute;
2766
+ bottom: 16px;
2767
+ right: 16px;
2768
+ background: var(--accent);
2769
+ color: var(--bg);
2770
+ border: none;
2771
+ border-radius: 20px;
2772
+ padding: 8px 16px;
2773
+ font-size: 11px;
2774
+ font-weight: 600;
2775
+ cursor: pointer;
2776
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
2777
+ z-index: 10;
2778
+ transition: all 0.15s ease;
2779
+ opacity: 0;
2780
+ transform: translateY(10px);
2781
+ pointer-events: none;
2782
+ }
2783
+
2784
+ .log-jump-btn:not(.hidden) {
2785
+ opacity: 1;
2786
+ transform: translateY(0);
2787
+ pointer-events: auto;
2788
+ }
2789
+
2790
+ .log-jump-btn:hover {
2791
+ background: #5de6c9;
2792
+ transform: translateY(-2px);
2793
+ box-shadow: 0 6px 16px rgba(0, 0, 0, 0.5);
2794
+ }
2795
+
2796
+ .log-jump-btn:active {
2797
+ transform: translateY(0);
2798
+ }
2799
+
2800
+ /* Terminal - maximize space */
2801
+ .terminal-container {
2802
+ position: relative;
2803
+ border: 1px solid var(--border);
2804
+ border-radius: var(--radius);
2805
+ background: var(--bg);
2806
+ height: calc(100vh - 100px);
2807
+ height: calc(100dvh - 100px);
2808
+ overflow: hidden;
2809
+ overscroll-behavior-y: contain;
2810
+ touch-action: pan-y;
2811
+ }
2812
+
2813
+ /* ===== MOBILE TERMINAL CONTROLS ===== */
2814
+ /* Hidden by default - only shown on touch devices */
2815
+ .terminal-mobile-controls {
2816
+ display: none;
2817
+ }
2818
+
2819
+ .terminal-overlay {
2820
+ position: absolute;
2821
+ inset: 0;
2822
+ display: flex;
2823
+ align-items: center;
2824
+ justify-content: center;
2825
+ text-align: center;
2826
+ background: rgba(10, 12, 18, 0.95);
2827
+ color: var(--muted);
2828
+ z-index: 2;
2829
+ padding: 20px;
2830
+ }
2831
+
2832
+ .terminal-container .xterm {
2833
+ padding: 6px;
2834
+ }
2835
+
2836
+ .terminal-container .xterm-viewport {
2837
+ overscroll-behavior-y: contain;
2838
+ touch-action: pan-y;
2839
+ -webkit-overflow-scrolling: touch;
2840
+ }
2841
+
2842
+ .terminal-jump-btn {
2843
+ position: absolute;
2844
+ bottom: 12px;
2845
+ right: 12px;
2846
+ padding: 8px 12px;
2847
+ border-radius: 999px;
2848
+ background: rgba(108, 245, 216, 0.12);
2849
+ border: 1px solid rgba(108, 245, 216, 0.3);
2850
+ color: var(--accent);
2851
+ font-weight: 600;
2852
+ font-size: 12px;
2853
+ cursor: pointer;
2854
+ backdrop-filter: blur(8px);
2855
+ transition: transform 0.15s ease, opacity 0.15s ease;
2856
+ z-index: 4;
2857
+ }
2858
+
2859
+ .terminal-jump-btn:hover {
2860
+ background: rgba(108, 245, 216, 0.2);
2861
+ transform: translateY(-1px);
2862
+ }
2863
+
2864
+ .terminal-jump-btn:active {
2865
+ transform: translateY(0);
2866
+ }
2867
+
2868
+ /* ===== TERMINAL TEXT INPUT (optional panel) ===== */
2869
+ #terminal-text-input-toggle[aria-expanded="true"] {
2870
+ background: rgba(108, 245, 216, 0.12);
2871
+ border-color: rgba(108, 245, 216, 0.3);
2872
+ color: var(--accent);
2873
+ }
2874
+
2875
+ #terminal.composer-sticky .terminal-text-input {
2876
+ position: sticky;
2877
+ bottom: calc(env(safe-area-inset-bottom) + var(--vv-bottom, 0px));
2878
+ z-index: 8;
2879
+ box-shadow: 0 -10px 24px rgba(0, 0, 0, 0.45);
2880
+ }
2881
+
2882
+ .terminal-text-input-title {
2883
+ font-size: 10px;
2884
+ text-transform: uppercase;
2885
+ letter-spacing: 0.04em;
2886
+ color: var(--muted);
2887
+ display: none; /* Hide on mobile, show on desktop */
2888
+ }
2889
+
2890
+ .terminal-text-input-actions {
2891
+ display: flex;
2892
+ align-items: center;
2893
+ gap: 6px;
2894
+ }
2895
+
2896
+ .terminal-text-input-hint {
2897
+ flex: 1 1 auto;
2898
+ min-width: 0;
2899
+ font-size: 10px;
2900
+ }
2901
+
2902
+ .terminal-text-input-buttons .voice-button,
2903
+ .terminal-text-input-buttons .terminal-text-image,
2904
+ .terminal-text-send-icon {
2905
+ padding: 0;
2906
+ }
2907
+
2908
+ .terminal-text-input-buttons .terminal-text-image {
2909
+ font-size: 11px;
2910
+ letter-spacing: 0.2px;
2911
+ }
2912
+
2913
+ button.terminal-text-send-icon {
2914
+ display: inline-flex;
2915
+ align-items: center;
2916
+ justify-content: center;
2917
+ color: #0b0f14;
2918
+ background: var(--accent);
2919
+ font-size: 18px;
2920
+ font-weight: 600;
2921
+ line-height: 1;
2922
+ }
2923
+
2924
+ button.terminal-text-send-icon.disconnected {
2925
+ opacity: 0.55;
2926
+ }
2927
+
2928
+ .terminal-text-input-buttons .voice-level-meter {
2929
+ width: 34px;
2930
+ height: 34px;
2931
+ padding: 4px 2px;
2932
+ border-radius: 10px;
2933
+ border: 1px solid var(--accent);
2934
+ background: rgba(108, 245, 216, 0.12);
2935
+ cursor: pointer;
2936
+ }
2937
+
2938
+ /* When the panel is open, shrink xterm height to keep controls visible (JS toggles the class). */
2939
+ #terminal.text-input-open .terminal-container {
2940
+ height: max(180px, calc(100vh - 260px));
2941
+ height: max(180px, calc(100dvh - 260px));
2942
+ }
2943
+
2944
+ /* Toast */
2945
+ .toast {
2946
+ position: fixed;
2947
+ top: calc(8px + env(safe-area-inset-top, 0px) + var(--vv-top, 0px));
2948
+ right: 8px;
2949
+ bottom: auto;
2950
+ padding: 6px 12px;
2951
+ border-radius: var(--radius);
2952
+ background: var(--panel);
2953
+ border: 1px solid var(--accent);
2954
+ color: var(--text);
2955
+ font-size: 11px;
2956
+ font-weight: 500;
2957
+ opacity: 0;
2958
+ transition: opacity 0.15s ease, transform 0.15s ease;
2959
+ transform: translateY(8px);
2960
+ z-index: 1000;
2961
+ }
2962
+
2963
+ .toast.show {
2964
+ opacity: 1;
2965
+ transform: translateY(0);
2966
+ }
2967
+
2968
+ .toast.error {
2969
+ border-color: var(--error);
2970
+ color: #ffaab5;
2971
+ }
2972
+
2973
+ /* Screen reader only */
2974
+ .sr-only {
2975
+ border: 0;
2976
+ clip: rect(0 0 0 0);
2977
+ height: 1px;
2978
+ margin: -1px;
2979
+ overflow: hidden;
2980
+ padding: 0;
2981
+ position: absolute;
2982
+ width: 1px;
2983
+ white-space: nowrap;
2984
+ }
2985
+
2986
+ /* Confirmation Modal */
2987
+ .modal-overlay {
2988
+ position: fixed;
2989
+ inset: 0;
2990
+ background: rgba(0, 0, 0, 0.7);
2991
+ display: flex;
2992
+ align-items: center;
2993
+ justify-content: center;
2994
+ z-index: 2000;
2995
+ padding: 16px;
2996
+ }
2997
+
2998
+ #confirm-modal,
2999
+ #input-modal {
3000
+ z-index: 3000;
3001
+ }
3002
+
3003
+ .modal-overlay[hidden] {
3004
+ display: none;
3005
+ }
3006
+
3007
+ .modal-dialog {
3008
+ background: var(--panel);
3009
+ border: 1px solid var(--border);
3010
+ border-radius: var(--radius);
3011
+ padding: 20px 24px;
3012
+ max-width: 400px;
3013
+ width: 100%;
3014
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
3015
+ }
3016
+
3017
+ .modal-dialog p {
3018
+ margin: 0 0 20px;
3019
+ font-size: 14px;
3020
+ line-height: 1.5;
3021
+ color: var(--text);
3022
+ }
3023
+
3024
+ .modal-actions {
3025
+ display: flex;
3026
+ gap: 12px;
3027
+ justify-content: flex-end;
3028
+ }
3029
+
3030
+ .modal-actions button {
3031
+ min-width: 80px;
3032
+ }
3033
+
3034
+ /* Input modal */
3035
+ .modal-input {
3036
+ max-width: 420px;
3037
+ }
3038
+
3039
+ .modal-input p {
3040
+ margin: 0 0 12px;
3041
+ }
3042
+
3043
+ .modal-input input[type="text"] {
3044
+ width: 100%;
3045
+ padding: 10px 12px;
3046
+ font-size: 13px;
3047
+ background: var(--bg);
3048
+ border: 1px solid var(--border);
3049
+ border-radius: var(--radius);
3050
+ color: var(--text);
3051
+ margin-bottom: 16px;
3052
+ box-sizing: border-box;
3053
+ }
3054
+
3055
+ .modal-input input[type="text"]:focus {
3056
+ outline: none;
3057
+ border-color: var(--accent);
3058
+ }
3059
+
3060
+ .modal-input input[type="text"]::placeholder {
3061
+ color: var(--muted);
3062
+ }
3063
+
3064
+ /* Create repo modal */
3065
+ .modal-create-repo {
3066
+ max-width: 440px;
3067
+ }
3068
+
3069
+ .modal-header {
3070
+ margin-bottom: 16px;
3071
+ padding-bottom: 10px;
3072
+ border-bottom: 1px solid var(--border);
3073
+ }
3074
+
3075
+ .modal-header .label {
3076
+ font-size: 12px;
3077
+ }
3078
+
3079
+ .modal-body {
3080
+ display: flex;
3081
+ flex-direction: column;
3082
+ gap: 14px;
3083
+ margin-bottom: 20px;
3084
+ }
3085
+
3086
+ .form-group {
3087
+ display: flex;
3088
+ flex-direction: column;
3089
+ gap: 4px;
3090
+ }
3091
+
3092
+ .form-group label {
3093
+ font-size: 11px;
3094
+ color: var(--text);
3095
+ font-weight: 500;
3096
+ }
3097
+
3098
+ .form-group .required {
3099
+ color: var(--error);
3100
+ }
3101
+
3102
+ .form-group .optional {
3103
+ color: var(--muted);
3104
+ font-weight: 400;
3105
+ }
3106
+
3107
+ .form-group input[type="text"] {
3108
+ width: 100%;
3109
+ padding: 8px 10px;
3110
+ font-size: 12px;
3111
+ background: var(--bg);
3112
+ border: 1px solid var(--border);
3113
+ border-radius: var(--radius);
3114
+ color: var(--text);
3115
+ }
3116
+
3117
+ .form-group input[type="text"]:focus {
3118
+ outline: none;
3119
+ border-color: var(--accent);
3120
+ }
3121
+
3122
+ .form-group select {
3123
+ width: 100%;
3124
+ padding: 8px 10px;
3125
+ font-size: 12px;
3126
+ background: var(--bg);
3127
+ border: 1px solid var(--border);
3128
+ border-radius: var(--radius);
3129
+ color: var(--text);
3130
+ }
3131
+
3132
+ .form-group select:focus {
3133
+ outline: none;
3134
+ border-color: var(--accent);
3135
+ }
3136
+
3137
+ .form-hint {
3138
+ font-size: 10px;
3139
+ color: var(--muted);
3140
+ }
3141
+
3142
+ .form-checkbox {
3143
+ flex-direction: row;
3144
+ align-items: center;
3145
+ }
3146
+
3147
+ .form-checkbox label {
3148
+ display: flex;
3149
+ align-items: center;
3150
+ gap: 8px;
3151
+ cursor: pointer;
3152
+ }
3153
+
3154
+ .form-checkbox input[type="checkbox"] {
3155
+ width: 16px;
3156
+ height: 16px;
3157
+ accent-color: var(--accent);
3158
+ cursor: pointer;
3159
+ }
3160
+
3161
+ /* Loading button state */
3162
+ button.loading {
3163
+ position: relative;
3164
+ color: transparent !important;
3165
+ pointer-events: none;
3166
+ }
3167
+
3168
+ button.loading::after {
3169
+ content: "";
3170
+ position: absolute;
3171
+ left: 50%;
3172
+ top: 50%;
3173
+ width: 14px;
3174
+ height: 14px;
3175
+ margin: -7px 0 0 -7px;
3176
+ border: 2px solid var(--muted);
3177
+ border-top-color: var(--accent);
3178
+ border-radius: 50%;
3179
+ animation: spin 0.6s linear infinite;
3180
+ }
3181
+
3182
+ @keyframes spin {
3183
+ to { transform: rotate(360deg); }
3184
+ }
3185
+
3186
+ /* Runner pid info */
3187
+ #runner-pid {
3188
+ margin: 6px 0 0;
3189
+ padding-top: 6px;
3190
+ border-top: 1px solid var(--border);
3191
+ font-size: 10px;
3192
+ }
3193
+
3194
+ /* ===== RESPONSIVE ===== */
3195
+ @media (max-width: 900px) {
3196
+ .cards {
3197
+ grid-template-columns: 1fr;
3198
+ }
3199
+
3200
+ .grid-two {
3201
+ grid-template-columns: repeat(2, 1fr);
3202
+ }
3203
+
3204
+ .hub-hero {
3205
+ flex-direction: row;
3206
+ align-items: center;
3207
+ gap: 8px;
3208
+ }
3209
+
3210
+ .hub-hero-text {
3211
+ flex: 1;
3212
+ flex-direction: row;
3213
+ align-items: center;
3214
+ gap: 8px;
3215
+ }
3216
+
3217
+ .hub-hero-actions {
3218
+ justify-content: flex-end;
3219
+ }
3220
+
3221
+ .hub-stats {
3222
+ flex-wrap: wrap;
3223
+ }
3224
+
3225
+ .hub-stat {
3226
+ min-width: 80px;
3227
+ }
3228
+
3229
+ /* Compact repo cards on tablet */
3230
+ .hub-repo-row {
3231
+ flex-wrap: wrap;
3232
+ gap: 6px;
3233
+ }
3234
+
3235
+ .hub-repo-center {
3236
+ flex-direction: column;
3237
+ align-items: flex-start;
3238
+ gap: 2px;
3239
+ }
3240
+
3241
+ .hub-repo-open-indicator {
3242
+ display: none;
3243
+ }
3244
+ }
3245
+
3246
+ /* Mobile: 640px and below */
3247
+ @media (max-width: 640px) {
3248
+ :root {
3249
+ --mobile-top-pad: max(4px, env(safe-area-inset-top));
3250
+ --mobile-bottom-nav: calc(52px + env(safe-area-inset-bottom, 0px));
3251
+ --mobile-input-font-size: 16px;
3252
+ }
3253
+
3254
+ html.mobile-chrome-hidden {
3255
+ --mobile-bottom-nav: env(safe-area-inset-bottom, 0px);
3256
+ }
3257
+
3258
+ /* Safe area support for notches */
3259
+ .app-shell {
3260
+ padding: 4px;
3261
+ padding-top: var(--mobile-top-pad);
3262
+ padding-bottom: var(--mobile-bottom-nav);
3263
+ min-height: 100vh;
3264
+ min-height: 100dvh;
3265
+ }
3266
+
3267
+ /* Hub mobile styles - compact layout */
3268
+ .hub-shell {
3269
+ padding: 4px;
3270
+ padding-top: max(4px, env(safe-area-inset-top));
3271
+ }
3272
+
3273
+ .hub-hero {
3274
+ padding: 8px 10px;
3275
+ gap: 8px;
3276
+ }
3277
+
3278
+ .hub-hero h1 {
3279
+ font-size: 13px;
3280
+ }
3281
+
3282
+ .hub-hero-text {
3283
+ gap: 8px;
3284
+ }
3285
+
3286
+ .hub-hero-actions {
3287
+ gap: 4px;
3288
+ }
3289
+
3290
+ .hub-hero-actions button {
3291
+ padding: 6px 10px;
3292
+ }
3293
+
3294
+ .hub-stats {
3295
+ gap: 4px;
3296
+ margin: 6px 0;
3297
+ }
3298
+
3299
+ .hub-stat {
3300
+ padding: 6px 10px;
3301
+ gap: 6px;
3302
+ }
3303
+
3304
+ .hub-stat-value {
3305
+ font-size: 16px;
3306
+ }
3307
+
3308
+ .hub-stat p {
3309
+ font-size: 9px;
3310
+ }
3311
+
3312
+ .hub-repo-panel {
3313
+ padding: 8px;
3314
+ }
3315
+
3316
+ .hub-panel-header {
3317
+ padding-bottom: 6px;
3318
+ margin-bottom: 6px;
3319
+ }
3320
+
3321
+ .hub-repo-list {
3322
+ gap: 4px;
3323
+ }
3324
+
3325
+ .hub-repo-card {
3326
+ padding: 8px 10px;
3327
+ }
3328
+
3329
+ .hub-repo-row {
3330
+ gap: 6px;
3331
+ }
3332
+
3333
+ .hub-repo-left {
3334
+ gap: 3px;
3335
+ }
3336
+
3337
+ .hub-repo-center {
3338
+ flex-direction: row;
3339
+ gap: 6px;
3340
+ }
3341
+
3342
+ .hub-repo-title {
3343
+ font-size: 11px;
3344
+ }
3345
+
3346
+ .hub-repo-info-line {
3347
+ font-size: 9px;
3348
+ }
3349
+
3350
+ .hub-repo-right {
3351
+ gap: 3px;
3352
+ }
3353
+
3354
+ .hub-repo-right button {
3355
+ padding: 5px 8px;
3356
+ font-size: 9px;
3357
+ }
3358
+
3359
+ .hub-repo-note {
3360
+ font-size: 9px;
3361
+ margin-top: 3px;
3362
+ }
3363
+
3364
+ /* Compact usage on mobile */
3365
+ .hub-usage-compact {
3366
+ padding: 6px 8px;
3367
+ margin: 6px 0;
3368
+ }
3369
+
3370
+ .hub-usage-header {
3371
+ gap: 6px;
3372
+ margin-bottom: 4px;
3373
+ }
3374
+
3375
+ .hub-usage-path {
3376
+ font-size: 8px;
3377
+ }
3378
+
3379
+ .hub-usage-grid {
3380
+ gap: 3px;
3381
+ }
3382
+
3383
+ .hub-usage-chip {
3384
+ padding: 3px 6px;
3385
+ font-size: 9px;
3386
+ gap: 4px;
3387
+ }
3388
+
3389
+ .hub-usage-chip-name {
3390
+ max-width: 70px;
3391
+ }
3392
+
3393
+ .hub-usage-chip-total {
3394
+ font-size: 10px;
3395
+ }
3396
+
3397
+ .hub-usage-chip-meta {
3398
+ font-size: 8px;
3399
+ }
3400
+
3401
+ /* Per-repo usage compact on mobile */
3402
+ .usage-card-compact {
3403
+ padding: 6px 8px;
3404
+ }
3405
+
3406
+ .usage-header {
3407
+ gap: 6px;
3408
+ margin-bottom: 4px;
3409
+ }
3410
+
3411
+ .usage-total-badge {
3412
+ font-size: 11px;
3413
+ padding: 2px 6px;
3414
+ }
3415
+
3416
+ .usage-events-badge {
3417
+ font-size: 9px;
3418
+ padding: 1px 4px;
3419
+ }
3420
+
3421
+ .usage-breakdown {
3422
+ gap: 2px;
3423
+ margin-bottom: 4px;
3424
+ }
3425
+
3426
+ .usage-stat {
3427
+ padding: 3px 1px;
3428
+ }
3429
+
3430
+ .usage-stat-val {
3431
+ font-size: 10px;
3432
+ }
3433
+
3434
+ .usage-stat-lbl {
3435
+ font-size: 7px;
3436
+ }
3437
+
3438
+ .usage-footer {
3439
+ font-size: 8px;
3440
+ padding-top: 3px;
3441
+ }
3442
+
3443
+ /* Modal on mobile */
3444
+ .modal-create-repo {
3445
+ max-width: 100%;
3446
+ margin: 8px;
3447
+ }
3448
+
3449
+ .modal-body {
3450
+ gap: 12px;
3451
+ }
3452
+
3453
+ .form-group input[type="text"] {
3454
+ font-size: 14px;
3455
+ padding: 10px 12px;
3456
+ }
3457
+
3458
+ /* Hide brand and repo name on mobile */
3459
+ .nav-brand,
3460
+ .nav-repo-name {
3461
+ display: none;
3462
+ }
3463
+
3464
+ /* Show back button on mobile */
3465
+ .hub-back-btn {
3466
+ padding: 10px 12px;
3467
+ font-size: 10px;
3468
+ min-height: 44px;
3469
+ border-radius: 0;
3470
+ border: none;
3471
+ border-right: 1px solid var(--border);
3472
+ background: var(--panel);
3473
+ }
3474
+
3475
+ /* Bottom navigation - thumb friendly */
3476
+ .nav-bar {
3477
+ position: fixed;
3478
+ bottom: 0;
3479
+ left: 0;
3480
+ right: 0;
3481
+ margin: 0;
3482
+ padding: 0;
3483
+ padding-bottom: env(safe-area-inset-bottom, 0px);
3484
+ background: linear-gradient(to top, var(--panel) 0%, rgba(16, 19, 28, 0.98) 100%);
3485
+ border-top: 1px solid var(--border);
3486
+ box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.3);
3487
+ z-index: 100;
3488
+ backdrop-filter: blur(8px);
3489
+ -webkit-backdrop-filter: blur(8px);
3490
+ transition: transform 0.18s ease;
3491
+ }
3492
+
3493
+ html.mobile-chrome-hidden .nav-bar {
3494
+ transform: translateY(calc(100% + env(safe-area-inset-bottom, 0px)));
3495
+ }
3496
+
3497
+ html.mobile-chrome-hidden #terminal .terminal-mobile-controls,
3498
+ html.mobile-chrome-hidden #terminal .terminal-text-input-actions {
3499
+ display: none;
3500
+ }
3501
+
3502
+ html.mobile-chrome-hidden #docs #doc-chat-voice,
3503
+ html.mobile-chrome-hidden #docs #doc-chat-cancel,
3504
+ html.mobile-chrome-hidden #docs .doc-chat-meta {
3505
+ display: none;
3506
+ }
3507
+
3508
+ html.mobile-compose-fixed #terminal .terminal-text-input,
3509
+ html.mobile-compose-fixed #docs .doc-chat-panel {
3510
+ position: fixed;
3511
+ left: 4px;
3512
+ right: 4px;
3513
+ bottom: max(var(--mobile-bottom-nav), var(--vv-bottom, 0px));
3514
+ margin: 0;
3515
+ z-index: 120;
3516
+ }
3517
+
3518
+ /* Also fix-position mobile controls above the text input when compose is open */
3519
+ html.mobile-compose-fixed #terminal .terminal-mobile-controls {
3520
+ position: fixed;
3521
+ left: 4px;
3522
+ right: 4px;
3523
+ /* Position above the text input using dynamically measured height */
3524
+ bottom: calc(var(--compose-input-height, 100px) + max(var(--mobile-bottom-nav), var(--vv-bottom, 0px)));
3525
+ margin: 0;
3526
+ z-index: 119;
3527
+ background: var(--bg);
3528
+ border-radius: var(--radius);
3529
+ padding: 4px;
3530
+ }
3531
+
3532
+ /* When compose is fixed, shrink terminal container so it stops above the fixed elements */
3533
+ html.mobile-compose-fixed #terminal .terminal-container {
3534
+ margin-bottom: var(--compose-total-height, 180px);
3535
+ }
3536
+
3537
+ html.mobile-compose-fixed #docs.panel.active {
3538
+ padding-bottom: calc(var(--doc-compose-height, 100px) + max(var(--mobile-bottom-nav), var(--vv-bottom, 0px)));
3539
+ }
3540
+
3541
+ .tabs {
3542
+ border: none;
3543
+ border-radius: 0;
3544
+ background: transparent;
3545
+ padding: 0;
3546
+ gap: 0;
3547
+ }
3548
+
3549
+ /* Larger touch targets - min 44px */
3550
+ .tab {
3551
+ padding: 14px 8px;
3552
+ min-height: 48px;
3553
+ font-size: 10px;
3554
+ border-radius: 0;
3555
+ display: flex;
3556
+ align-items: center;
3557
+ justify-content: center;
3558
+ position: relative;
3559
+ transition: color 0.15s ease, background 0.15s ease;
3560
+ }
3561
+
3562
+ /* Subtle divider between tabs */
3563
+ .tab:not(:last-child)::after {
3564
+ content: "";
3565
+ position: absolute;
3566
+ right: 0;
3567
+ top: 25%;
3568
+ height: 50%;
3569
+ width: 1px;
3570
+ background: var(--border);
3571
+ opacity: 0.5;
3572
+ }
3573
+
3574
+ .tab:active:not(.active) {
3575
+ background: rgba(108, 245, 216, 0.08);
3576
+ }
3577
+
3578
+ .tab.active {
3579
+ color: var(--accent);
3580
+ background: rgba(108, 245, 216, 0.12);
3581
+ border-top: 2px solid var(--accent);
3582
+ font-weight: 600;
3583
+ }
3584
+
3585
+ /* Hide divider next to active tab */
3586
+ .tab.active::after,
3587
+ .tab.active + .tab::before {
3588
+ opacity: 0;
3589
+ }
3590
+
3591
+ /* Inactive tabs on mobile - ensure readable */
3592
+ .tab:not(.active) {
3593
+ color: var(--muted);
3594
+ }
3595
+
3596
+ .tab:not(.active):hover {
3597
+ color: var(--text);
3598
+ }
3599
+
3600
+ /* Content area */
3601
+ main {
3602
+ padding-bottom: 8px;
3603
+ }
3604
+
3605
+ .grid-two {
3606
+ grid-template-columns: repeat(2, 1fr);
3607
+ gap: 6px;
3608
+ }
3609
+
3610
+ .grid-two > div {
3611
+ padding: 8px;
3612
+ }
3613
+
3614
+ .metric {
3615
+ font-size: 14px;
3616
+ }
3617
+
3618
+ /* Larger action buttons - min 44px touch targets */
3619
+ .actions {
3620
+ gap: 6px;
3621
+ margin-top: 12px;
3622
+ }
3623
+
3624
+ .actions button {
3625
+ flex: 1 1 auto;
3626
+ min-width: 60px;
3627
+ min-height: 44px;
3628
+ padding: 12px 8px;
3629
+ font-size: 11px;
3630
+ }
3631
+
3632
+ .actions button:active {
3633
+ transform: scale(0.95);
3634
+ opacity: 0.8;
3635
+ }
3636
+
3637
+ .actions {
3638
+ display: grid;
3639
+ grid-template-columns: repeat(3, minmax(0, 1fr));
3640
+ }
3641
+
3642
+ .actions button {
3643
+ min-width: 0;
3644
+ }
3645
+
3646
+ .card {
3647
+ padding: 10px;
3648
+ }
3649
+
3650
+ .card-header {
3651
+ padding-bottom: 8px;
3652
+ margin-bottom: 10px;
3653
+ }
3654
+
3655
+ /* Compact inline toolbar for mobile - flex row */
3656
+ .inline-toolbar {
3657
+ position: sticky;
3658
+ top: 0;
3659
+ z-index: 10;
3660
+ display: flex;
3661
+ flex-wrap: wrap;
3662
+ gap: 4px;
3663
+ padding: 6px;
3664
+ margin: 0 -4px 4px;
3665
+ border-radius: 0;
3666
+ align-items: center;
3667
+ }
3668
+
3669
+ .inline-toolbar label {
3670
+ font-size: 9px;
3671
+ gap: 2px;
3672
+ flex-shrink: 0;
3673
+ }
3674
+
3675
+ .inline-toolbar label:has(input[type="number"]) {
3676
+ display: none; /* Hide Run/Tail labels on mobile, show just inputs */
3677
+ }
3678
+
3679
+ .inline-toolbar input[type="number"] {
3680
+ width: 50px;
3681
+ min-height: 32px;
3682
+ padding: 4px 6px;
3683
+ font-size: var(--mobile-input-font-size);
3684
+ flex-shrink: 0;
3685
+ }
3686
+
3687
+ .inline-toolbar button {
3688
+ min-height: 32px;
3689
+ padding: 6px 10px;
3690
+ font-size: 10px;
3691
+ flex-shrink: 0;
3692
+ }
3693
+
3694
+ /* Checkbox toggles - fixed width */
3695
+ .inline-toolbar .chip {
3696
+ padding: 4px 8px;
3697
+ font-size: 9px;
3698
+ min-height: 28px;
3699
+ flex-shrink: 0;
3700
+ flex-grow: 0;
3701
+ }
3702
+
3703
+ .inline-toolbar .chip span {
3704
+ display: none; /* Hide label text, show just checkbox */
3705
+ }
3706
+
3707
+ .inline-toolbar .chip::after {
3708
+ content: attr(data-short);
3709
+ font-size: 9px;
3710
+ }
3711
+
3712
+ /* Logs/Terminal - account for bottom nav and compact toolbar */
3713
+ .log-container {
3714
+ height: calc(100vh - 130px);
3715
+ height: calc(100dvh - 130px);
3716
+ }
3717
+
3718
+ .log-viewer {
3719
+ font-size: 10px;
3720
+ padding: 4px;
3721
+ }
3722
+
3723
+ /* Hide log legend on mobile - too cluttered */
3724
+ .log-legend {
3725
+ display: none;
3726
+ }
3727
+
3728
+ /* Simplified log line styling on mobile */
3729
+ .log-line {
3730
+ padding: 1px 2px;
3731
+ font-size: 10px;
3732
+ }
3733
+
3734
+ .log-line[data-icon]::before {
3735
+ display: none;
3736
+ }
3737
+
3738
+ .log-line.log-run-start,
3739
+ .log-line.log-run-end {
3740
+ padding: 3px 6px;
3741
+ margin: 6px 0 3px 0;
3742
+ font-size: 10px;
3743
+ }
3744
+
3745
+ .log-line.log-agent-output {
3746
+ padding: 4px 6px;
3747
+ margin: 4px 0;
3748
+ font-size: 10px;
3749
+ }
3750
+
3751
+ .log-line.log-thinking,
3752
+ .log-line.log-exec-command {
3753
+ padding-left: 8px;
3754
+ }
3755
+
3756
+ /* Collapsible blocks more compact */
3757
+ .log-context-block {
3758
+ margin: 2px 0;
3759
+ }
3760
+
3761
+ .log-context-summary {
3762
+ padding: 2px 4px;
3763
+ font-size: 9px;
3764
+ }
3765
+
3766
+ .log-context-content {
3767
+ padding: 2px 4px;
3768
+ max-height: 100px;
3769
+ font-size: 9px;
3770
+ }
3771
+
3772
+ /* Jump button on mobile */
3773
+ .log-jump-btn {
3774
+ bottom: 10px;
3775
+ right: 10px;
3776
+ padding: 6px 10px;
3777
+ font-size: 9px;
3778
+ }
3779
+
3780
+ #terminal.panel.active {
3781
+ display: flex;
3782
+ flex-direction: column;
3783
+ height: calc(100dvh - var(--mobile-top-pad) - var(--mobile-bottom-nav));
3784
+ overflow: hidden;
3785
+ }
3786
+
3787
+ #terminal .terminal-container {
3788
+ height: auto;
3789
+ flex: 1 1 auto;
3790
+ min-height: 0;
3791
+ }
3792
+
3793
+ #terminal .inline-toolbar {
3794
+ flex-wrap: wrap;
3795
+ gap: 6px;
3796
+ }
3797
+
3798
+ #terminal-status {
3799
+ flex: 1 0 100%;
3800
+ }
3801
+
3802
+ #terminal .inline-toolbar button {
3803
+ min-height: 36px;
3804
+ padding: 8px 10px;
3805
+ }
3806
+
3807
+ #terminal.text-input-open .terminal-container {
3808
+ height: auto;
3809
+ }
3810
+
3811
+ #terminal .terminal-mobile-controls,
3812
+ #terminal .terminal-text-input {
3813
+ flex: 0 0 auto;
3814
+ }
3815
+
3816
+ .compose-row textarea {
3817
+ min-height: 52px;
3818
+ max-height: 100px;
3819
+ font-size: 16px;
3820
+ line-height: 1.3;
3821
+ resize: none;
3822
+ }
3823
+
3824
+ .compose-row {
3825
+ gap: 4px;
3826
+ }
3827
+
3828
+ .compose-buttons {
3829
+ gap: 4px;
3830
+ }
3831
+
3832
+ .compose-buttons button {
3833
+ width: 30px;
3834
+ height: 30px;
3835
+ min-width: 30px;
3836
+ min-height: 30px;
3837
+ border-radius: 8px;
3838
+ }
3839
+
3840
+ .terminal-text-input-buttons .terminal-text-image {
3841
+ font-size: 10px;
3842
+ }
3843
+
3844
+ .compose-buttons .voice-button svg {
3845
+ width: 12px;
3846
+ height: 12px;
3847
+ min-width: 12px;
3848
+ min-height: 12px;
3849
+ }
3850
+
3851
+ .terminal-text-input-buttons .voice-level-meter {
3852
+ width: 30px;
3853
+ height: 30px;
3854
+ padding: 3px 2px;
3855
+ border-radius: 8px;
3856
+ }
3857
+
3858
+ .terminal-text-input-actions {
3859
+ gap: 6px;
3860
+ }
3861
+
3862
+ html.mobile-compose-fixed #terminal .terminal-text-input {
3863
+ position: fixed;
3864
+ bottom: max(var(--mobile-bottom-nav), var(--vv-bottom, 0px));
3865
+ }
3866
+
3867
+ html.mobile-compose-fixed #terminal .terminal-mobile-controls {
3868
+ position: fixed;
3869
+ left: 4px;
3870
+ right: 4px;
3871
+ bottom: calc(var(--compose-input-height, 100px) + max(var(--mobile-bottom-nav), var(--vv-bottom, 0px)));
3872
+ z-index: 119;
3873
+ margin: 0;
3874
+ }
3875
+
3876
+ html.mobile-compose-fixed #terminal .terminal-container {
3877
+ margin-bottom: var(--compose-total-height, 180px);
3878
+ }
3879
+
3880
+ /* Mobile terminal control bar */
3881
+ .terminal-mobile-controls {
3882
+ display: flex;
3883
+ flex-direction: column;
3884
+ gap: 3px;
3885
+ padding: 4px;
3886
+ background: var(--panel);
3887
+ border: 1px solid var(--border);
3888
+ border-radius: var(--radius);
3889
+ margin-top: 4px;
3890
+ }
3891
+
3892
+ .tmb-row {
3893
+ display: flex;
3894
+ gap: 3px;
3895
+ align-items: center;
3896
+ }
3897
+
3898
+ .tmb-key {
3899
+ flex: 1;
3900
+ min-height: 34px;
3901
+ padding: 6px 5px;
3902
+ border: 1px solid var(--border);
3903
+ border-radius: var(--radius);
3904
+ background: var(--bg);
3905
+ color: var(--text);
3906
+ font-family: inherit;
3907
+ font-size: 10px;
3908
+ font-weight: 500;
3909
+ cursor: pointer;
3910
+ touch-action: manipulation;
3911
+ -webkit-tap-highlight-color: transparent;
3912
+ user-select: none;
3913
+ transition: all 0.08s ease;
3914
+ text-transform: none;
3915
+ letter-spacing: 0;
3916
+ }
3917
+
3918
+ .tmb-key:active {
3919
+ background: rgba(108, 245, 216, 0.2);
3920
+ border-color: var(--accent);
3921
+ transform: scale(0.94);
3922
+ }
3923
+
3924
+ /* Modifier keys (Ctrl/Alt) - toggle state */
3925
+ .tmb-mod {
3926
+ flex: 1;
3927
+ background: var(--bg);
3928
+ color: var(--muted);
3929
+ }
3930
+
3931
+ .tmb-mod.active {
3932
+ background: var(--accent);
3933
+ color: var(--bg);
3934
+ border-color: var(--accent);
3935
+ font-weight: 600;
3936
+ }
3937
+
3938
+ /* Arrow keys - fixed width, larger icon */
3939
+ .tmb-arrow {
3940
+ flex: 0 0 32px;
3941
+ font-size: 14px;
3942
+ padding: 5px 3px;
3943
+ order: 3;
3944
+ }
3945
+
3946
+ /* Enter key - primary action */
3947
+ .tmb-primary {
3948
+ background: rgba(108, 245, 216, 0.12);
3949
+ border-color: rgba(108, 245, 216, 0.3);
3950
+ color: var(--accent);
3951
+ font-weight: 600;
3952
+ }
3953
+
3954
+ .tmb-primary:active {
3955
+ background: rgba(108, 245, 216, 0.3);
3956
+ border-color: var(--accent);
3957
+ }
3958
+
3959
+ /* Ctrl combos - danger styled for interrupt signals */
3960
+ .tmb-ctrl-combo {
3961
+ flex: 0 0 auto;
3962
+ min-width: 32px;
3963
+ order: 1;
3964
+ background: rgba(255, 85, 102, 0.08);
3965
+ border-color: rgba(255, 85, 102, 0.25);
3966
+ color: #ff8899;
3967
+ font-weight: 600;
3968
+ }
3969
+
3970
+ .tmb-bksp {
3971
+ order: 2;
3972
+ }
3973
+
3974
+ .tmb-ctrl-combo:active {
3975
+ background: rgba(255, 85, 102, 0.25);
3976
+ border-color: #ff5566;
3977
+ }
3978
+
3979
+ /* Hide terminal voice from toolbar on mobile - it's in the mobile controls */
3980
+ .inline-toolbar .terminal-voice {
3981
+ display: none;
3982
+ }
3983
+
3984
+ /* Mobile terminal voice button - integrated into mobile controls */
3985
+ .tmb-voice {
3986
+ flex: 0 0 auto;
3987
+ min-width: 34px;
3988
+ background: var(--bg);
3989
+ border-color: var(--border);
3990
+ color: var(--muted);
3991
+ display: flex;
3992
+ align-items: center;
3993
+ justify-content: center;
3994
+ gap: 3px;
3995
+ padding: 5px 6px;
3996
+ }
3997
+
3998
+ .tmb-voice svg {
3999
+ width: 14px;
4000
+ height: 14px;
4001
+ min-width: 14px;
4002
+ min-height: 14px;
4003
+ flex-shrink: 0;
4004
+ }
4005
+
4006
+ .tmb-voice.voice-recording {
4007
+ background: #b3261e;
4008
+ color: #fff;
4009
+ border-color: #b3261e;
4010
+ animation: tmb-voice-pulse 1s ease-in-out infinite;
4011
+ }
4012
+
4013
+ @keyframes tmb-voice-pulse {
4014
+ 0%, 100% { opacity: 1; }
4015
+ 50% { opacity: 0.7; }
4016
+ }
4017
+
4018
+ .tmb-voice.voice-sending {
4019
+ background: rgba(108, 245, 216, 0.2);
4020
+ color: var(--accent);
4021
+ border-color: var(--accent);
4022
+ }
4023
+
4024
+ .tmb-voice.voice-error {
4025
+ border-color: #d35400;
4026
+ color: #d35400;
4027
+ }
4028
+
4029
+ .tmb-voice.disabled,
4030
+ .tmb-voice.voice-disconnected {
4031
+ opacity: 0.4;
4032
+ }
4033
+
4034
+ /* Level meter in mobile controls - more compact */
4035
+ .tmb-row .voice-level-meter {
4036
+ height: 16px;
4037
+ padding: 0 2px;
4038
+ gap: 1px;
4039
+ }
4040
+
4041
+ .tmb-row .voice-level-bar {
4042
+ width: 2px;
4043
+ }
4044
+
4045
+ /* Docs nav - compact chips on mobile */
4046
+ .doc-nav {
4047
+ display: flex;
4048
+ flex-wrap: nowrap;
4049
+ gap: 4px;
4050
+ margin-bottom: 6px;
4051
+ overflow-x: auto;
4052
+ -webkit-overflow-scrolling: touch;
4053
+ }
4054
+
4055
+ .doc-nav .chip {
4056
+ padding: 8px 10px;
4057
+ min-height: 36px;
4058
+ font-size: 10px;
4059
+ flex-shrink: 0;
4060
+ }
4061
+
4062
+ .doc-nav .chip:active {
4063
+ transform: scale(0.95);
4064
+ }
4065
+
4066
+ #doc-status {
4067
+ display: none;
4068
+ }
4069
+
4070
+ .doc-editor textarea {
4071
+ /* Let the editor consume usable vertical space (no arbitrary cap). */
4072
+ flex: 1 1 auto;
4073
+ min-height: 0;
4074
+ height: auto;
4075
+ font-size: var(--mobile-input-font-size);
4076
+ padding: 10px;
4077
+ resize: none;
4078
+ }
4079
+
4080
+ /* Make Docs panel a fill-the-screen flex layout (avoids wasted space). */
4081
+ #docs.panel.active {
4082
+ display: flex;
4083
+ flex-direction: column;
4084
+ height: calc(100dvh - var(--mobile-top-pad) - var(--mobile-bottom-nav));
4085
+ overflow: hidden;
4086
+ }
4087
+
4088
+ #docs.panel.active .doc-editor {
4089
+ flex: 1 1 auto;
4090
+ min-height: 0;
4091
+ }
4092
+
4093
+ #doc-content {
4094
+ flex: 1 1 auto;
4095
+ min-height: 0;
4096
+ }
4097
+
4098
+ /* Patch view should also fill space when active. */
4099
+ .doc-patch-main {
4100
+ flex: 1 1 auto;
4101
+ min-height: 0;
4102
+ }
4103
+
4104
+ .doc-patch-body {
4105
+ flex: 1 1 auto;
4106
+ min-height: 0;
4107
+ max-height: none;
4108
+ }
4109
+
4110
+ /* Larger tap targets for icon-only buttons (refresh, etc.) */
4111
+ button.icon-btn {
4112
+ width: 44px;
4113
+ height: 44px;
4114
+ min-width: 44px;
4115
+ min-height: 44px;
4116
+ font-size: 18px;
4117
+ }
4118
+
4119
+ .doc-actions {
4120
+ display: flex;
4121
+ flex-wrap: nowrap;
4122
+ gap: 6px;
4123
+ margin-top: 6px;
4124
+ align-items: center;
4125
+ overflow-x: auto;
4126
+ -webkit-overflow-scrolling: touch;
4127
+ }
4128
+
4129
+ .doc-actions button {
4130
+ flex: 0 0 auto;
4131
+ min-height: 36px;
4132
+ padding: 8px 6px;
4133
+ font-size: 10px;
4134
+ }
4135
+
4136
+ /* Use short labels on mobile */
4137
+ .doc-actions button[data-short] {
4138
+ font-size: 0;
4139
+ }
4140
+
4141
+ .doc-actions button[data-short]::after {
4142
+ content: attr(data-short);
4143
+ font-size: 10px;
4144
+ }
4145
+
4146
+ /* Chat panel - mobile meta/response sizing */
4147
+ .doc-chat-compose {
4148
+ gap: 2px;
4149
+ }
4150
+
4151
+ .doc-chat-meta {
4152
+ font-size: 9px;
4153
+ }
4154
+
4155
+ .doc-chat-response-wrapper {
4156
+ max-height: 80px;
4157
+ padding: 6px;
4158
+ font-size: 11px;
4159
+ }
4160
+
4161
+ .doc-chat-history-details {
4162
+ margin-top: 2px;
4163
+ }
4164
+
4165
+ .doc-chat-history-toggle {
4166
+ padding: 3px 6px;
4167
+ font-size: 8px;
4168
+ }
4169
+
4170
+ .doc-chat-history {
4171
+ max-height: 60px;
4172
+ padding: 0 6px 4px;
4173
+ }
4174
+
4175
+ .doc-chat-entry {
4176
+ padding: 2px 0;
4177
+ }
4178
+
4179
+ .doc-chat-entry .prompt,
4180
+ .doc-chat-entry .response {
4181
+ font-size: 9px;
4182
+ }
4183
+
4184
+ .doc-chat-entry .copy-prompt-btn {
4185
+ opacity: 0.7; /* Always visible on mobile for touch */
4186
+ width: 22px;
4187
+ height: 22px;
4188
+ font-size: 11px;
4189
+ }
4190
+
4191
+ .doc-chat-entry-detail summary {
4192
+ font-size: 8px;
4193
+ }
4194
+
4195
+ .doc-chat-entry-body pre {
4196
+ font-size: 8px;
4197
+ }
4198
+
4199
+ .doc-chat-history-count {
4200
+ font-size: 8px;
4201
+ padding: 1px 4px;
4202
+ min-width: 14px;
4203
+ }
4204
+
4205
+ /* Patch wrapper on mobile */
4206
+ .doc-chat-patch-wrapper {
4207
+ padding: 6px;
4208
+ }
4209
+
4210
+ .doc-chat-patch {
4211
+ max-height: 60px;
4212
+ font-size: 10px;
4213
+ }
4214
+
4215
+ .doc-chat-patch-actions {
4216
+ font-size: 9px;
4217
+ flex-wrap: wrap;
4218
+ gap: 4px;
4219
+ }
4220
+
4221
+ .doc-chat-patch-actions button {
4222
+ font-size: 9px;
4223
+ padding: 6px 10px;
4224
+ }
4225
+
4226
+ /* Main patch panel on mobile - stacked layout */
4227
+ .doc-patch-main {
4228
+ padding: 10px;
4229
+ gap: 10px;
4230
+ }
4231
+
4232
+ .doc-patch-header {
4233
+ flex-direction: column;
4234
+ align-items: stretch;
4235
+ gap: 10px;
4236
+ }
4237
+
4238
+ .doc-patch-info {
4239
+ order: 1;
4240
+ }
4241
+
4242
+ .doc-patch-summary {
4243
+ font-size: 12px;
4244
+ line-height: 1.4;
4245
+ padding: 8px;
4246
+ background: var(--bg);
4247
+ border-radius: var(--radius);
4248
+ border-left: 3px solid var(--accent);
4249
+ }
4250
+
4251
+ .doc-patch-legend {
4252
+ display: none; /* Hide on mobile - the colors are self-explanatory */
4253
+ }
4254
+
4255
+ .doc-patch-actions {
4256
+ display: flex;
4257
+ flex-direction: column;
4258
+ gap: 6px;
4259
+ order: 2;
4260
+ }
4261
+
4262
+ .doc-patch-actions button {
4263
+ min-height: 44px;
4264
+ padding: 12px 16px;
4265
+ font-size: 12px;
4266
+ justify-content: center;
4267
+ width: 100%;
4268
+ }
4269
+
4270
+ .doc-patch-actions button.primary {
4271
+ order: -1; /* Move Apply button to top */
4272
+ }
4273
+
4274
+ .doc-patch-body {
4275
+ max-height: 300px;
4276
+ padding: 0;
4277
+ font-size: 11px;
4278
+ line-height: 1.5;
4279
+ -webkit-overflow-scrolling: touch;
4280
+ border-radius: var(--radius);
4281
+ overflow: auto;
4282
+ }
4283
+
4284
+ /* Diff line adjustments for mobile */
4285
+ .diff-gutter {
4286
+ flex: 0 0 28px;
4287
+ font-size: 9px;
4288
+ padding-right: 4px;
4289
+ }
4290
+
4291
+ .diff-sign {
4292
+ flex: 0 0 14px;
4293
+ font-size: 10px;
4294
+ }
4295
+
4296
+ .diff-content {
4297
+ padding-left: 6px;
4298
+ font-size: 11px;
4299
+ }
4300
+
4301
+ .diff-line.diff-hunk .diff-content {
4302
+ font-size: 10px;
4303
+ }
4304
+
4305
+ .diff-empty-marker {
4306
+ font-size: 9px;
4307
+ padding: 0 3px;
4308
+ }
4309
+
4310
+ /* Toast below top safe area */
4311
+ .toast {
4312
+ left: 8px;
4313
+ right: 8px;
4314
+ top: calc(8px + var(--mobile-top-pad) + var(--vv-top, 0px));
4315
+ bottom: auto;
4316
+ text-align: center;
4317
+ }
4318
+
4319
+ /* Checklist items - larger touch area */
4320
+ .checklist li {
4321
+ padding: 10px 12px;
4322
+ gap: 10px;
4323
+ min-height: 44px;
4324
+ }
4325
+
4326
+ .checklist .box {
4327
+ width: 18px;
4328
+ height: 18px;
4329
+ }
4330
+
4331
+ .checklist .box.done::after {
4332
+ font-size: 14px;
4333
+ top: 0;
4334
+ left: 2px;
4335
+ }
4336
+
4337
+ /* ===== MOBILE TERMINAL TALL VIEW ===== */
4338
+ /* Mirrors the terminal buffer while the text input is focused on mobile.
4339
+ Keeps scrolling easy without sending keystrokes to the TUI. */
4340
+ .mobile-terminal-view {
4341
+ position: fixed;
4342
+ top: 0;
4343
+ left: 0;
4344
+ right: 0;
4345
+ bottom: 0;
4346
+ background: var(--bg);
4347
+ z-index: 100; /* Below input (z-index 120) */
4348
+ overflow-y: auto;
4349
+ overflow-x: hidden;
4350
+ padding: 10px;
4351
+ padding-bottom: calc(
4352
+ var(--compose-total-height, 120px) + env(safe-area-inset-bottom) + var(--vv-bottom, 0px)
4353
+ );
4354
+ font-family: "JetBrains Mono", monospace;
4355
+ font-size: 10px;
4356
+ line-height: 1.15;
4357
+ letter-spacing: 0;
4358
+ font-variant-ligatures: none;
4359
+ white-space: pre-wrap;
4360
+ overflow-wrap: anywhere;
4361
+ color: var(--text);
4362
+ -webkit-overflow-scrolling: touch;
4363
+ overscroll-behavior-y: contain;
4364
+ touch-action: pan-y;
4365
+ }
4366
+
4367
+ .mobile-terminal-view.hidden {
4368
+ display: none;
4369
+ }
4370
+
4371
+ .mobile-terminal-view .ansi-bold {
4372
+ font-weight: 600;
4373
+ }
4374
+
4375
+ .mobile-terminal-view .ansi-fg-30 { color: #000000; }
4376
+ .mobile-terminal-view .ansi-fg-31 { color: #ff5566; }
4377
+ .mobile-terminal-view .ansi-fg-32 { color: #6cf5d8; }
4378
+ .mobile-terminal-view .ansi-fg-33 { color: #f1fa8c; }
4379
+ .mobile-terminal-view .ansi-fg-34 { color: #6ca8ff; }
4380
+ .mobile-terminal-view .ansi-fg-35 { color: #bd93f9; }
4381
+ .mobile-terminal-view .ansi-fg-36 { color: #8be9fd; }
4382
+ .mobile-terminal-view .ansi-fg-37 { color: #e5ecff; }
4383
+ .mobile-terminal-view .ansi-fg-90 { color: #6272a4; }
4384
+ .mobile-terminal-view .ansi-fg-91 { color: #ff6e6e; }
4385
+ .mobile-terminal-view .ansi-fg-92 { color: #69ff94; }
4386
+ .mobile-terminal-view .ansi-fg-93 { color: #ffffa5; }
4387
+ .mobile-terminal-view .ansi-fg-94 { color: #d6acff; }
4388
+ .mobile-terminal-view .ansi-fg-95 { color: #ff92df; }
4389
+ .mobile-terminal-view .ansi-fg-96 { color: #a4ffff; }
4390
+ .mobile-terminal-view .ansi-fg-97 { color: #ffffff; }
4391
+
4392
+ /* Match xterm's bold-bright mapping for base colors. */
4393
+ .mobile-terminal-view .ansi-bold.ansi-fg-30 { color: #6272a4; }
4394
+ .mobile-terminal-view .ansi-bold.ansi-fg-31 { color: #ff6e6e; }
4395
+ .mobile-terminal-view .ansi-bold.ansi-fg-32 { color: #69ff94; }
4396
+ .mobile-terminal-view .ansi-bold.ansi-fg-33 { color: #ffffa5; }
4397
+ .mobile-terminal-view .ansi-bold.ansi-fg-34 { color: #d6acff; }
4398
+ .mobile-terminal-view .ansi-bold.ansi-fg-35 { color: #ff92df; }
4399
+ .mobile-terminal-view .ansi-bold.ansi-fg-36 { color: #a4ffff; }
4400
+ .mobile-terminal-view .ansi-bold.ansi-fg-37 { color: #ffffff; }
4401
+
4402
+ .mobile-terminal-view .ansi-bg-40 { background-color: #000000; }
4403
+ .mobile-terminal-view .ansi-bg-41 { background-color: #ff5566; }
4404
+ .mobile-terminal-view .ansi-bg-42 { background-color: #6cf5d8; }
4405
+ .mobile-terminal-view .ansi-bg-43 { background-color: #f1fa8c; }
4406
+ .mobile-terminal-view .ansi-bg-44 { background-color: #6ca8ff; }
4407
+ .mobile-terminal-view .ansi-bg-45 { background-color: #bd93f9; }
4408
+ .mobile-terminal-view .ansi-bg-46 { background-color: #8be9fd; }
4409
+ .mobile-terminal-view .ansi-bg-47 { background-color: #e5ecff; }
4410
+ .mobile-terminal-view .ansi-bg-100 { background-color: #6272a4; }
4411
+ .mobile-terminal-view .ansi-bg-101 { background-color: #ff6e6e; }
4412
+ .mobile-terminal-view .ansi-bg-102 { background-color: #69ff94; }
4413
+ .mobile-terminal-view .ansi-bg-103 { background-color: #ffffa5; }
4414
+ .mobile-terminal-view .ansi-bg-104 { background-color: #d6acff; }
4415
+ .mobile-terminal-view .ansi-bg-105 { background-color: #ff92df; }
4416
+ .mobile-terminal-view .ansi-bg-106 { background-color: #a4ffff; }
4417
+ .mobile-terminal-view .ansi-bg-107 { background-color: #ffffff; }
4418
+
4419
+ input[type="text"],
4420
+ input[type="number"],
4421
+ input[type="password"],
4422
+ input[type="search"],
4423
+ input[type="email"],
4424
+ input[type="url"],
4425
+ textarea,
4426
+ select {
4427
+ font-size: var(--mobile-input-font-size);
4428
+ }
4429
+
4430
+ }
4431
+
4432
+ /* Ultra-small screens */
4433
+ @media (max-width: 400px) {
4434
+ .terminal-container {
4435
+ height: calc(100vh - 200px);
4436
+ height: calc(100dvh - 200px);
4437
+ }
4438
+
4439
+ #terminal.text-input-open .terminal-container {
4440
+ height: max(100px, calc(100vh - 340px));
4441
+ height: max(100px, calc(100dvh - 340px));
4442
+ }
4443
+
4444
+ .terminal-mobile-controls {
4445
+ padding: 3px;
4446
+ gap: 2px;
4447
+ }
4448
+
4449
+ .tmb-row {
4450
+ gap: 2px;
4451
+ }
4452
+
4453
+ .tmb-key {
4454
+ min-height: 30px;
4455
+ padding: 4px 3px;
4456
+ font-size: 9px;
4457
+ }
4458
+
4459
+ .tmb-arrow {
4460
+ flex: 0 0 26px;
4461
+ font-size: 12px;
4462
+ }
4463
+
4464
+ .tmb-ctrl-combo {
4465
+ min-width: 28px;
4466
+ font-size: 9px;
4467
+ }
4468
+
4469
+ .tmb-voice {
4470
+ min-width: 30px;
4471
+ padding: 3px 4px;
4472
+ }
4473
+
4474
+ .tmb-voice svg {
4475
+ width: 11px;
4476
+ height: 11px;
4477
+ min-width: 11px;
4478
+ min-height: 11px;
4479
+ }
4480
+
4481
+ .tab {
4482
+ padding: 12px 4px;
4483
+ font-size: 9px;
4484
+ letter-spacing: 0;
4485
+ }
4486
+
4487
+ .tab.active {
4488
+ color: var(--accent);
4489
+ font-weight: 600;
4490
+ }
4491
+
4492
+ .metric {
4493
+ font-size: 13px;
4494
+ }
4495
+
4496
+ .actions button {
4497
+ font-size: 10px;
4498
+ min-height: 42px;
4499
+ }
4500
+
4501
+ .grid-two {
4502
+ gap: 4px;
4503
+ }
4504
+
4505
+ /* Ultra-compact logs toolbar */
4506
+ .inline-toolbar {
4507
+ gap: 3px;
4508
+ padding: 4px;
4509
+ }
4510
+
4511
+ .inline-toolbar input[type="number"] {
4512
+ width: 45px;
4513
+ min-height: 28px;
4514
+ font-size: var(--mobile-input-font-size);
4515
+ }
4516
+
4517
+ .inline-toolbar button {
4518
+ min-height: 28px;
4519
+ padding: 4px 8px;
4520
+ font-size: 9px;
4521
+ }
4522
+
4523
+ .inline-toolbar .chip {
4524
+ padding: 2px 6px;
4525
+ min-height: 24px;
4526
+ }
4527
+
4528
+ .inline-toolbar .chip::after {
4529
+ font-size: 8px;
4530
+ }
4531
+
4532
+ .log-container {
4533
+ height: calc(100vh - 110px);
4534
+ height: calc(100dvh - 110px);
4535
+ }
4536
+
4537
+ .log-viewer {
4538
+ font-size: 9px;
4539
+ padding: 3px;
4540
+ }
4541
+
4542
+ .log-line {
4543
+ font-size: 9px;
4544
+ }
4545
+
4546
+ .log-line.log-run-start,
4547
+ .log-line.log-run-end {
4548
+ font-size: 9px;
4549
+ padding: 2px 4px;
4550
+ margin: 4px 0 2px 0;
4551
+ }
4552
+
4553
+ .log-line.log-agent-output {
4554
+ font-size: 9px;
4555
+ padding: 3px 4px;
4556
+ margin: 3px 0;
4557
+ }
4558
+
4559
+ .log-jump-btn {
4560
+ padding: 4px 8px;
4561
+ font-size: 8px;
4562
+ bottom: 8px;
4563
+ right: 8px;
4564
+ }
4565
+
4566
+ .doc-nav .chip {
4567
+ padding: 6px 8px;
4568
+ min-height: 32px;
4569
+ font-size: 9px;
4570
+ }
4571
+
4572
+ .doc-actions button {
4573
+ min-height: 32px;
4574
+ padding: 6px 4px;
4575
+ }
4576
+
4577
+ .doc-actions button[data-short]::after {
4578
+ font-size: 9px;
4579
+ }
4580
+
4581
+ .doc-chat-panel {
4582
+ padding: 4px;
4583
+ }
4584
+
4585
+
4586
+ /* Patch panel for ultra-small screens */
4587
+ .doc-patch-main {
4588
+ padding: 8px;
4589
+ gap: 8px;
4590
+ }
4591
+
4592
+ .doc-patch-summary {
4593
+ font-size: 11px;
4594
+ padding: 6px;
4595
+ }
4596
+
4597
+ .doc-patch-legend {
4598
+ display: none;
4599
+ }
4600
+
4601
+ .doc-patch-actions button {
4602
+ min-height: 40px;
4603
+ padding: 10px 12px;
4604
+ font-size: 11px;
4605
+ }
4606
+
4607
+ .doc-patch-body {
4608
+ max-height: 220px;
4609
+ }
4610
+
4611
+ input[type="text"],
4612
+ input[type="number"],
4613
+ input[type="password"],
4614
+ input[type="search"],
4615
+ input[type="email"],
4616
+ input[type="url"],
4617
+ textarea,
4618
+ select {
4619
+ font-size: var(--mobile-input-font-size);
4620
+ }
4621
+
4622
+ .diff-gutter {
4623
+ flex: 0 0 24px;
4624
+ font-size: 8px;
4625
+ padding-right: 3px;
4626
+ }
4627
+
4628
+ .diff-sign {
4629
+ flex: 0 0 12px;
4630
+ font-size: 9px;
4631
+ }
4632
+
4633
+ .diff-content {
4634
+ padding-left: 4px;
4635
+ font-size: 10px;
4636
+ }
4637
+
4638
+ .diff-empty-marker {
4639
+ font-size: 8px;
4640
+ padding: 0 2px;
4641
+ }
4642
+ }
4643
+
4644
+ /* Landscape phone - side-by-side layout */
4645
+ @media (max-width: 900px) and (max-height: 500px) and (orientation: landscape) {
4646
+ :root {
4647
+ --mobile-input-font-size: 16px;
4648
+ }
4649
+
4650
+ .app-shell {
4651
+ padding-bottom: 4px;
4652
+ }
4653
+
4654
+ .nav-bar {
4655
+ position: static;
4656
+ margin-bottom: 4px;
4657
+ }
4658
+
4659
+ /* Compact logs for landscape */
4660
+ .inline-toolbar {
4661
+ display: flex;
4662
+ flex-wrap: nowrap;
4663
+ gap: 4px;
4664
+ padding: 4px;
4665
+ margin-bottom: 4px;
4666
+ }
4667
+
4668
+ .inline-toolbar label:has(input[type="number"]) {
4669
+ display: flex;
4670
+ }
4671
+
4672
+ .inline-toolbar input[type="number"] {
4673
+ width: 45px;
4674
+ min-height: 26px;
4675
+ }
4676
+
4677
+ .inline-toolbar button {
4678
+ min-height: 26px;
4679
+ padding: 4px 8px;
4680
+ }
4681
+
4682
+ .inline-toolbar .chip {
4683
+ padding: 2px 4px;
4684
+ min-height: 24px;
4685
+ }
4686
+
4687
+ .inline-toolbar .chip span {
4688
+ display: inline;
4689
+ }
4690
+
4691
+ .inline-toolbar .chip::after {
4692
+ content: none;
4693
+ }
4694
+
4695
+ .log-legend {
4696
+ display: flex;
4697
+ padding: 2px 6px;
4698
+ margin-bottom: 4px;
4699
+ font-size: 7px;
4700
+ }
4701
+
4702
+ .log-container {
4703
+ height: calc(100vh - 90px);
4704
+ }
4705
+
4706
+ .log-viewer {
4707
+ font-size: 9px;
4708
+ padding: 4px;
4709
+ }
4710
+
4711
+ .tabs {
4712
+ border: 1px solid var(--border);
4713
+ border-radius: var(--radius);
4714
+ }
4715
+
4716
+ .tab {
4717
+ min-height: 36px;
4718
+ padding: 8px;
4719
+ border-radius: var(--radius);
4720
+ }
4721
+
4722
+ /* Landscape retains solid accent background with dark text for high contrast */
4723
+ .tab.active {
4724
+ border-top: none;
4725
+ background: var(--accent);
4726
+ color: var(--bg);
4727
+ font-weight: 600;
4728
+ }
4729
+
4730
+ .tab:not(.active) {
4731
+ color: var(--muted);
4732
+ }
4733
+
4734
+ .log-viewer {
4735
+ height: calc(100vh - 80px);
4736
+ }
4737
+
4738
+ #terminal.panel.active {
4739
+ display: flex;
4740
+ flex-direction: column;
4741
+ height: calc(100dvh - 120px);
4742
+ overflow: hidden;
4743
+ }
4744
+
4745
+ #terminal .terminal-container {
4746
+ height: auto;
4747
+ flex: 1 1 auto;
4748
+ min-height: 0;
4749
+ }
4750
+
4751
+ #terminal.text-input-open .terminal-container {
4752
+ height: auto;
4753
+ }
4754
+
4755
+ .compose-panel {
4756
+ padding: 4px;
4757
+ gap: 3px;
4758
+ }
4759
+
4760
+ .compose-row textarea {
4761
+ min-height: 52px;
4762
+ max-height: 70px;
4763
+ padding: 4px;
4764
+ font-size: 16px;
4765
+ line-height: 1.3;
4766
+ resize: none;
4767
+ }
4768
+
4769
+ .compose-row {
4770
+ gap: 4px;
4771
+ }
4772
+
4773
+ .compose-buttons {
4774
+ gap: 4px;
4775
+ }
4776
+
4777
+ .compose-buttons button {
4778
+ width: 28px;
4779
+ height: 28px;
4780
+ min-width: 28px;
4781
+ min-height: 28px;
4782
+ border-radius: 8px;
4783
+ }
4784
+
4785
+ .terminal-text-input-buttons .terminal-text-image {
4786
+ font-size: 9px;
4787
+ }
4788
+
4789
+ .compose-buttons .voice-button svg {
4790
+ width: 11px;
4791
+ height: 11px;
4792
+ min-width: 11px;
4793
+ min-height: 11px;
4794
+ }
4795
+
4796
+ .terminal-text-input-buttons .voice-level-meter {
4797
+ width: 28px;
4798
+ height: 28px;
4799
+ padding: 3px 2px;
4800
+ border-radius: 8px;
4801
+ }
4802
+
4803
+ .terminal-text-input-actions {
4804
+ gap: 4px;
4805
+ }
4806
+
4807
+ .terminal-text-input-hint {
4808
+ display: none;
4809
+ }
4810
+
4811
+ .terminal-text-input #terminal-text-send {
4812
+ font-size: 14px;
4813
+ }
4814
+
4815
+ /* Compact mobile controls in landscape - single row */
4816
+ .terminal-mobile-controls {
4817
+ display: flex;
4818
+ flex-direction: row;
4819
+ gap: 3px;
4820
+ padding: 3px 4px;
4821
+ margin-top: 3px;
4822
+ }
4823
+
4824
+ .tmb-row {
4825
+ flex: 1;
4826
+ gap: 2px;
4827
+ }
4828
+
4829
+ .tmb-key {
4830
+ min-height: 26px;
4831
+ padding: 3px 2px;
4832
+ font-size: 9px;
4833
+ }
4834
+
4835
+ .tmb-arrow {
4836
+ flex: 0 0 24px;
4837
+ font-size: 11px;
4838
+ }
4839
+
4840
+ .tmb-ctrl-combo {
4841
+ min-width: 24px;
4842
+ font-size: 9px;
4843
+ }
4844
+
4845
+ .tmb-voice {
4846
+ min-width: 26px;
4847
+ padding: 3px;
4848
+ }
4849
+
4850
+ .tmb-voice svg {
4851
+ width: 10px;
4852
+ height: 10px;
4853
+ }
4854
+
4855
+ .doc-editor textarea {
4856
+ flex: 1 1 auto;
4857
+ min-height: 0;
4858
+ max-height: none;
4859
+ }
4860
+
4861
+ #docs.panel.active {
4862
+ display: flex;
4863
+ flex-direction: column;
4864
+ height: calc(100vh - 90px);
4865
+ overflow: hidden;
4866
+ }
4867
+
4868
+ #docs.panel.active .doc-editor {
4869
+ flex: 1 1 auto;
4870
+ min-height: 0;
4871
+ }
4872
+
4873
+ #doc-content {
4874
+ flex: 1 1 auto;
4875
+ min-height: 0;
4876
+ }
4877
+
4878
+ /* Compact chat for landscape */
4879
+ .doc-chat-panel {
4880
+ padding: 4px;
4881
+ gap: 2px;
4882
+ }
4883
+
4884
+
4885
+ .doc-chat-response-wrapper {
4886
+ max-height: 60px;
4887
+ }
4888
+
4889
+ .doc-chat-history {
4890
+ max-height: 50px;
4891
+ }
4892
+
4893
+ .doc-actions {
4894
+ display: flex;
4895
+ flex-wrap: wrap;
4896
+ gap: 4px;
4897
+ }
4898
+
4899
+ .doc-actions button {
4900
+ flex: 0 0 auto;
4901
+ }
4902
+
4903
+ .doc-actions button[data-short] {
4904
+ font-size: 0;
4905
+ }
4906
+
4907
+ .doc-actions button[data-short]::after {
4908
+ font-size: 9px;
4909
+ }
4910
+
4911
+ /* Patch panel in landscape */
4912
+ .doc-patch-main {
4913
+ padding: 6px;
4914
+ gap: 6px;
4915
+ }
4916
+
4917
+ .doc-patch-header {
4918
+ flex-direction: row;
4919
+ align-items: center;
4920
+ }
4921
+
4922
+ .doc-patch-summary {
4923
+ font-size: 10px;
4924
+ padding: 4px 6px;
4925
+ }
4926
+
4927
+ .doc-patch-legend {
4928
+ display: none;
4929
+ }
4930
+
4931
+ .doc-patch-actions {
4932
+ flex-direction: row;
4933
+ gap: 4px;
4934
+ }
4935
+
4936
+ .doc-patch-actions button {
4937
+ min-height: 32px;
4938
+ padding: 6px 10px;
4939
+ font-size: 10px;
4940
+ width: auto;
4941
+ }
4942
+
4943
+ .doc-patch-body {
4944
+ max-height: 140px;
4945
+ }
4946
+
4947
+ input[type="text"],
4948
+ input[type="number"],
4949
+ input[type="password"],
4950
+ input[type="search"],
4951
+ input[type="email"],
4952
+ input[type="url"],
4953
+ textarea,
4954
+ select {
4955
+ font-size: var(--mobile-input-font-size);
4956
+ }
4957
+
4958
+ .diff-gutter {
4959
+ flex: 0 0 28px;
4960
+ font-size: 9px;
4961
+ }
4962
+
4963
+ .diff-content {
4964
+ font-size: 10px;
4965
+ }
4966
+ }