@flowdular/sdk 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/.ai/skills/test-hardening/SKILL.md +1 -1
  2. package/README.md +69 -12
  3. package/assets/flowdular-banner.png +0 -0
  4. package/modules/agents/package.json +1 -1
  5. package/modules/auth/package.json +1 -1
  6. package/modules/auth/src/client/AuthenticationCore.tsrx +3 -1
  7. package/modules/auth/src/server/endpoints.ts +3 -1
  8. package/modules/auth/src/server/runtime.ts +4 -0
  9. package/modules/automations/package.json +1 -1
  10. package/modules/automations-workflows-integration/package.json +1 -1
  11. package/modules/profile/package.json +1 -1
  12. package/modules/sandbox/package.json +1 -1
  13. package/modules/system/package.json +1 -1
  14. package/modules/users/package.json +1 -1
  15. package/modules/workflows/package.json +1 -1
  16. package/package.json +5 -13
  17. package/packages/ai-provider/package.json +1 -1
  18. package/packages/cli-protocol/package.json +1 -1
  19. package/packages/client/package.json +1 -1
  20. package/packages/client/src/routing.ts +39 -2
  21. package/packages/client/src/shell/BrandMark.tsrx +5 -1
  22. package/packages/client/src/shell/navigation.ts +3 -1
  23. package/packages/client/src/state.ts +6 -2
  24. package/packages/contracts/package.json +1 -1
  25. package/packages/contracts/schemas/project.schema.json +16 -42
  26. package/packages/database/package.json +1 -1
  27. package/packages/database-pglite/package.json +1 -1
  28. package/packages/database-testing/package.json +1 -1
  29. package/packages/dev-console/package.json +1 -1
  30. package/packages/harness/package.json +1 -1
  31. package/packages/kernel/package.json +1 -1
  32. package/packages/server/package.json +1 -1
  33. package/packages/server/src/application-routes.ts +80 -8
  34. package/packages/server/src/index.ts +4 -1
  35. package/packages/server/src/web-html.ts +9 -5
  36. package/packages/server/src/web.ts +59 -7
  37. package/packages/ui/package.json +1 -1
  38. package/packages/coding-agent/package.json +0 -44
  39. package/packages/coding-agent/src/drivers/byok.ts +0 -322
  40. package/packages/coding-agent/src/drivers/claude-code.ts +0 -290
  41. package/packages/coding-agent/src/drivers/codex.ts +0 -281
  42. package/packages/coding-agent/src/index.ts +0 -56
  43. package/packages/coding-agent/src/registry.ts +0 -119
  44. package/packages/coding-agent/src/roles/contract.ts +0 -60
  45. package/packages/coding-agent/src/roles/defaults.ts +0 -134
  46. package/packages/coding-agent/src/roles/handoff.ts +0 -41
  47. package/packages/coding-agent/src/roles/registry.ts +0 -156
  48. package/packages/coding-agent/src/roles/skills.ts +0 -72
  49. package/packages/coding-agent/src/roles/sync.ts +0 -88
  50. package/packages/coding-agent/src/types.ts +0 -102
  51. package/packages/coding-agent/src/workspace.ts +0 -275
  52. package/packages/sandbox/README.md +0 -691
  53. package/packages/sandbox/bin/flowdular-sandbox.mjs +0 -393
  54. package/packages/sandbox/dist/client/assets/App-ClMOrpyg.js +0 -11
  55. package/packages/sandbox/dist/client/assets/PreviewHost-BHiHrfbQ.js +0 -1
  56. package/packages/sandbox/dist/client/assets/auto-buGEq6de.js +0 -3
  57. package/packages/sandbox/dist/client/assets/ibm-plex-mono-cyrillic-400-normal-BSMlKf0J.woff2 +0 -0
  58. package/packages/sandbox/dist/client/assets/ibm-plex-mono-cyrillic-400-normal-CEL4l2ZJ.woff +0 -0
  59. package/packages/sandbox/dist/client/assets/ibm-plex-mono-cyrillic-500-normal-Ael50iVv.woff +0 -0
  60. package/packages/sandbox/dist/client/assets/ibm-plex-mono-cyrillic-500-normal-Bq9vWWag.woff2 +0 -0
  61. package/packages/sandbox/dist/client/assets/ibm-plex-mono-cyrillic-ext-400-normal-DMdlQ8Kv.woff +0 -0
  62. package/packages/sandbox/dist/client/assets/ibm-plex-mono-cyrillic-ext-400-normal-xuaO2J-f.woff2 +0 -0
  63. package/packages/sandbox/dist/client/assets/ibm-plex-mono-cyrillic-ext-500-normal-BIfNGwUT.woff +0 -0
  64. package/packages/sandbox/dist/client/assets/ibm-plex-mono-cyrillic-ext-500-normal-BqneJy0T.woff2 +0 -0
  65. package/packages/sandbox/dist/client/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  66. package/packages/sandbox/dist/client/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  67. package/packages/sandbox/dist/client/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
  68. package/packages/sandbox/dist/client/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
  69. package/packages/sandbox/dist/client/assets/ibm-plex-mono-latin-ext-400-normal-BmRBH3aV.woff2 +0 -0
  70. package/packages/sandbox/dist/client/assets/ibm-plex-mono-latin-ext-400-normal-D3D2R8hC.woff +0 -0
  71. package/packages/sandbox/dist/client/assets/ibm-plex-mono-latin-ext-500-normal-CAhNIIs5.woff2 +0 -0
  72. package/packages/sandbox/dist/client/assets/ibm-plex-mono-latin-ext-500-normal-CZ70TYgx.woff +0 -0
  73. package/packages/sandbox/dist/client/assets/ibm-plex-mono-vietnamese-400-normal-BulugwFq.woff2 +0 -0
  74. package/packages/sandbox/dist/client/assets/ibm-plex-mono-vietnamese-400-normal-DDuiU_S-.woff +0 -0
  75. package/packages/sandbox/dist/client/assets/ibm-plex-mono-vietnamese-500-normal-C8zxqsMH.woff +0 -0
  76. package/packages/sandbox/dist/client/assets/ibm-plex-mono-vietnamese-500-normal-DZ4AoWbu.woff2 +0 -0
  77. package/packages/sandbox/dist/client/assets/ibm-plex-sans-cyrillic-ext-wght-normal-d45eAU9y.woff2 +0 -0
  78. package/packages/sandbox/dist/client/assets/ibm-plex-sans-cyrillic-wght-normal-BAAhND-U.woff2 +0 -0
  79. package/packages/sandbox/dist/client/assets/ibm-plex-sans-greek-wght-normal-CmyJS8uq.woff2 +0 -0
  80. package/packages/sandbox/dist/client/assets/ibm-plex-sans-latin-ext-wght-normal-CIII54If.woff2 +0 -0
  81. package/packages/sandbox/dist/client/assets/ibm-plex-sans-latin-wght-normal-IvpUvPa2.woff2 +0 -0
  82. package/packages/sandbox/dist/client/assets/ibm-plex-sans-vietnamese-wght-normal-Dg1JeJN0.woff2 +0 -0
  83. package/packages/sandbox/dist/client/assets/index-CvwhlQ87.js +0 -4
  84. package/packages/sandbox/dist/client/assets/styles-BPWaGf55.js +0 -3
  85. package/packages/sandbox/dist/client/assets/styles-Dx1_KOag.css +0 -1
  86. package/packages/sandbox/dist/client/favicon.svg +0 -1
  87. package/packages/sandbox/dist/server/assets/auto-CVGNYyb3.js +0 -12785
  88. package/packages/sandbox/dist/server/assets/chunk-DDJLRBDX-3OUNo51g.js +0 -4125
  89. package/packages/sandbox/dist/server/assets/nodefs-DVSI7kG0.js +0 -24
  90. package/packages/sandbox/dist/server/assets/opfs-ahp-D56iokt1.js +0 -388
  91. package/packages/sandbox/dist/server/assets/token-Bvaq7Anz.js +0 -55
  92. package/packages/sandbox/dist/server/assets/token-util-BqSvdIPQ.js +0 -3
  93. package/packages/sandbox/dist/server/assets/token-util-CktFFT4z.js +0 -494
  94. package/packages/sandbox/dist/server/entry.js +0 -91671
  95. package/packages/sandbox/dist/server/favicon.svg +0 -1
  96. package/packages/sandbox/dist/server/index.html +0 -161
  97. package/packages/sandbox/index.html +0 -159
  98. package/packages/sandbox/octane.config.ts +0 -36
  99. package/packages/sandbox/package.json +0 -83
  100. package/packages/sandbox/public/favicon.svg +0 -1
  101. package/packages/sandbox/public/og.png +0 -0
  102. package/packages/sandbox/src/App.tsrx +0 -924
  103. package/packages/sandbox/src/client/ApprovalHandoff.tsrx +0 -39
  104. package/packages/sandbox/src/client/ChatPane.tsrx +0 -694
  105. package/packages/sandbox/src/client/ConnectView.tsrx +0 -86
  106. package/packages/sandbox/src/client/DiffPane.tsrx +0 -150
  107. package/packages/sandbox/src/client/EjectModal.tsrx +0 -571
  108. package/packages/sandbox/src/client/GateResults.tsrx +0 -60
  109. package/packages/sandbox/src/client/GitHubSettingsModal.tsrx +0 -219
  110. package/packages/sandbox/src/client/NewSessionForm.tsrx +0 -214
  111. package/packages/sandbox/src/client/SessionBar.tsrx +0 -151
  112. package/packages/sandbox/src/client/SessionPicker.tsrx +0 -472
  113. package/packages/sandbox/src/client/SpecEditor.tsrx +0 -109
  114. package/packages/sandbox/src/client/SpecReviewCard.tsrx +0 -321
  115. package/packages/sandbox/src/client/WorkCard.tsrx +0 -128
  116. package/packages/sandbox/src/client/WorkbenchModal.tsrx +0 -161
  117. package/packages/sandbox/src/client/WorkspaceMenu.tsrx +0 -100
  118. package/packages/sandbox/src/client/api.ts +0 -797
  119. package/packages/sandbox/src/client/attachments.ts +0 -73
  120. package/packages/sandbox/src/client/dashboard.ts +0 -46
  121. package/packages/sandbox/src/client/github-settings.ts +0 -48
  122. package/packages/sandbox/src/client/highlight.ts +0 -105
  123. package/packages/sandbox/src/client/i18n.ts +0 -32
  124. package/packages/sandbox/src/client/locales/en.json +0 -466
  125. package/packages/sandbox/src/client/locales/pl.json +0 -466
  126. package/packages/sandbox/src/client/session-labels.ts +0 -77
  127. package/packages/sandbox/src/client/state.ts +0 -108
  128. package/packages/sandbox/src/index.ts +0 -10
  129. package/packages/sandbox/src/preview/PreviewHost.tsrx +0 -373
  130. package/packages/sandbox/src/preview/load-module.ts +0 -16
  131. package/packages/sandbox/src/server/attachments.ts +0 -308
  132. package/packages/sandbox/src/server/auto-review.ts +0 -181
  133. package/packages/sandbox/src/server/checkpoints.ts +0 -90
  134. package/packages/sandbox/src/server/config.ts +0 -460
  135. package/packages/sandbox/src/server/dashboard.ts +0 -245
  136. package/packages/sandbox/src/server/delivery/configuration.ts +0 -193
  137. package/packages/sandbox/src/server/delivery/git-pr.ts +0 -1473
  138. package/packages/sandbox/src/server/delivery/index.ts +0 -83
  139. package/packages/sandbox/src/server/delivery/local.ts +0 -151
  140. package/packages/sandbox/src/server/delivery/official-modules.ts +0 -516
  141. package/packages/sandbox/src/server/delivery/plan.ts +0 -218
  142. package/packages/sandbox/src/server/delivery/policies.ts +0 -239
  143. package/packages/sandbox/src/server/delivery/record.ts +0 -41
  144. package/packages/sandbox/src/server/delivery/steps.ts +0 -464
  145. package/packages/sandbox/src/server/delivery/types.ts +0 -158
  146. package/packages/sandbox/src/server/dependencies.ts +0 -88
  147. package/packages/sandbox/src/server/diff.ts +0 -230
  148. package/packages/sandbox/src/server/gates.ts +0 -388
  149. package/packages/sandbox/src/server/index.ts +0 -139
  150. package/packages/sandbox/src/server/path-guard.ts +0 -282
  151. package/packages/sandbox/src/server/planning.ts +0 -749
  152. package/packages/sandbox/src/server/platform-client.ts +0 -189
  153. package/packages/sandbox/src/server/preview-database-host.ts +0 -340
  154. package/packages/sandbox/src/server/preview-database-protocol.ts +0 -163
  155. package/packages/sandbox/src/server/preview-database-proxy.ts +0 -356
  156. package/packages/sandbox/src/server/preview-database.ts +0 -109
  157. package/packages/sandbox/src/server/preview-ipc.ts +0 -15
  158. package/packages/sandbox/src/server/preview-modules.ts +0 -83
  159. package/packages/sandbox/src/server/preview-revision.ts +0 -44
  160. package/packages/sandbox/src/server/preview-runtime.ts +0 -467
  161. package/packages/sandbox/src/server/preview-worker-manager.ts +0 -436
  162. package/packages/sandbox/src/server/preview-worker.ts +0 -168
  163. package/packages/sandbox/src/server/reference.ts +0 -251
  164. package/packages/sandbox/src/server/routes.ts +0 -2258
  165. package/packages/sandbox/src/server/runtime.ts +0 -188
  166. package/packages/sandbox/src/server/session-owner.ts +0 -23
  167. package/packages/sandbox/src/server/sessions.ts +0 -849
  168. package/packages/sandbox/src/server/spec.ts +0 -471
  169. package/packages/sandbox/src/server/turn-lifecycle.ts +0 -56
  170. package/packages/sandbox/src/server/turns.ts +0 -993
  171. package/packages/sandbox/src/server/workspace-install.ts +0 -266
  172. package/packages/sandbox/src/server/workspace-root.ts +0 -73
  173. package/packages/sandbox/src/styles.css +0 -1573
  174. package/packages/sandbox/vite.config.ts +0 -133
@@ -1,1573 +0,0 @@
1
- /* Sandbox shell. Layout only: every colour, size, and font comes from the
2
- @flowdular/sdk/ui tokens so the preview matches the real application. */
3
-
4
- .sandbox {
5
- display: flex;
6
- /* Application bar, an optional notice, the session bar, then the work. The
7
- bars take what they need and the work takes the rest, whatever number of
8
- bars this view has, so a long transcript never pushes the composer off the
9
- screen. */
10
- flex-direction: column;
11
- height: 100vh;
12
- min-width: 0;
13
- overflow: hidden;
14
- background: var(--surface);
15
- }
16
-
17
- .sandbox__body,
18
- .sandbox > .sandbox__scroll {
19
- flex: 1 1 auto;
20
- min-height: 0;
21
- }
22
-
23
- .sandbox__notice {
24
- padding: 12px 18px 0;
25
- }
26
-
27
- .sandbox__notice:empty {
28
- display: none;
29
- }
30
-
31
- .sandbox__bar {
32
- display: flex;
33
- flex: 0 0 auto;
34
- flex-wrap: wrap;
35
- align-items: center;
36
- gap: 10px;
37
- min-height: var(--topbar-h);
38
- padding: 0 16px;
39
- background: var(--surface);
40
- border-bottom: 1px solid var(--line);
41
- }
42
-
43
- .sandbox__brand {
44
- display: inline-flex;
45
- align-items: center;
46
- gap: 8px;
47
- padding: 0;
48
- font-family: var(--font-sans);
49
- font-size: 15px;
50
- font-weight: 600;
51
- color: var(--ink);
52
- letter-spacing: -0.01em;
53
- background: transparent;
54
- border: 0;
55
- cursor: pointer;
56
- }
57
-
58
- /* Workspace and connection, the only global controls beside the brand. */
59
- .workspace-menu {
60
- position: relative;
61
- }
62
-
63
- .workspace-menu__button {
64
- display: inline-flex;
65
- align-items: center;
66
- gap: 10px;
67
- max-width: 320px;
68
- padding: 8px 12px;
69
- background: transparent;
70
- border: 1px solid transparent;
71
- border-radius: var(--r-lg);
72
- cursor: pointer;
73
- transition: background var(--t-fast) var(--ease);
74
- }
75
-
76
- .workspace-menu__button:hover,
77
- .workspace-menu__button[aria-expanded='true'] {
78
- background: var(--surface-2);
79
- }
80
-
81
- .workspace-menu__label {
82
- display: grid;
83
- min-width: 0;
84
- text-align: left;
85
- }
86
-
87
- .workspace-menu__label b {
88
- font-size: var(--text-md);
89
- font-weight: 600;
90
- overflow: hidden;
91
- text-overflow: ellipsis;
92
- white-space: nowrap;
93
- }
94
-
95
- .workspace-menu__label small {
96
- font-size: var(--text-sm);
97
- color: var(--ink-3);
98
- overflow: hidden;
99
- text-overflow: ellipsis;
100
- white-space: nowrap;
101
- }
102
-
103
- .workspace-menu__panel {
104
- position: absolute;
105
- top: calc(100% + 6px);
106
- right: 0;
107
- z-index: 40;
108
- width: 300px;
109
- }
110
-
111
- /* One session, its state, and the actions that belong to it. */
112
- .session-bar {
113
- display: flex;
114
- flex-wrap: wrap;
115
- align-items: center;
116
- gap: 10px;
117
- padding: 10px 18px;
118
- background: var(--surface);
119
- border-bottom: 1px solid var(--line-2);
120
- }
121
-
122
- .session-bar__back {
123
- display: inline-flex;
124
- align-items: center;
125
- gap: 4px;
126
- padding: 4px 8px 4px 4px;
127
- font-family: var(--font-sans);
128
- font-size: var(--text-sm);
129
- font-weight: 500;
130
- color: var(--ink-3);
131
- background: transparent;
132
- border: 0;
133
- border-radius: var(--r);
134
- cursor: pointer;
135
- }
136
-
137
- .session-bar__back:hover {
138
- color: var(--ink);
139
- background: var(--surface-2);
140
- }
141
-
142
- .session-bar__back svg {
143
- transform: rotate(90deg);
144
- }
145
-
146
- .session-bar__title {
147
- display: inline-flex;
148
- align-items: baseline;
149
- gap: 8px;
150
- min-width: 0;
151
- }
152
-
153
- .session-bar__add {
154
- display: inline-flex;
155
- align-items: center;
156
- gap: 4px;
157
- padding: 2px 6px;
158
- font-family: var(--font-sans);
159
- font-size: var(--text-xs);
160
- font-weight: 600;
161
- letter-spacing: 0.04em;
162
- text-transform: uppercase;
163
- color: var(--ink-3);
164
- background: transparent;
165
- border: 0;
166
- border-radius: var(--r-sm);
167
- cursor: pointer;
168
- transition: color var(--t-fast) var(--ease);
169
- }
170
-
171
- .session-bar__add:hover:not(:disabled) {
172
- color: var(--primary);
173
- }
174
-
175
- .session-bar__add:disabled {
176
- cursor: not-allowed;
177
- opacity: 0.5;
178
- }
179
-
180
- .session-bar__title b {
181
- font-size: var(--text-md);
182
- font-weight: 600;
183
- overflow: hidden;
184
- text-overflow: ellipsis;
185
- white-space: nowrap;
186
- }
187
-
188
- .session-bar__title small {
189
- flex: none;
190
- font-size: var(--text-sm);
191
- color: var(--ink-3);
192
- }
193
-
194
- .sandbox__spacer {
195
- flex: 1;
196
- }
197
-
198
- /* The conversation is the page. The work card floats over it on the right,
199
- inside the same surface, instead of sitting in a separate panel. */
200
- .sandbox__body {
201
- --sandbox-preview-width: clamp(
202
- calc(var(--sidebar-w) * 1.5),
203
- 38vw,
204
- calc(var(--sidebar-w) * 2.4)
205
- );
206
- position: relative;
207
- display: grid;
208
- grid-template-columns: minmax(0, 1fr);
209
- min-width: 0;
210
- min-height: 0;
211
- }
212
-
213
- .sandbox__chat {
214
- display: grid;
215
- grid-template-rows: minmax(0, 1fr) auto;
216
- min-width: 0;
217
- min-height: 0;
218
- }
219
-
220
- .sandbox__side {
221
- position: absolute;
222
- inset: 0 0 0 auto;
223
- z-index: 1;
224
- width: var(--sandbox-preview-width);
225
- display: grid;
226
- grid-template-rows: minmax(0, 1fr);
227
- min-width: 0;
228
- min-height: 0;
229
- padding: 18px 18px 18px 0;
230
- }
231
-
232
- @media (min-width: 1101px) {
233
- /* The card overlays the chat surface, but never its text or controls. */
234
- .sandbox__chat > .sandbox__scroll,
235
- .sandbox__chat > .chat__composer {
236
- padding-right: calc(var(--sandbox-preview-width) + var(--content-pad));
237
- }
238
- }
239
-
240
- @media (max-width: 1100px) {
241
- .sandbox__body {
242
- grid-template-columns: minmax(0, 1fr);
243
- }
244
-
245
- .sandbox__side {
246
- display: none;
247
- }
248
- }
249
-
250
- .sandbox__pane-head {
251
- display: flex;
252
- flex-wrap: wrap;
253
- align-items: center;
254
- gap: 8px;
255
- padding: 10px 18px;
256
- background: var(--surface);
257
- border-bottom: 1px solid var(--line-2);
258
- }
259
-
260
- .sandbox__pane-title {
261
- font-size: var(--text-sm);
262
- font-weight: 600;
263
- letter-spacing: 0.04em;
264
- text-transform: uppercase;
265
- color: var(--ink-3);
266
- }
267
-
268
- /* Controls in a pane header stay compact so the header reads as a header. */
269
- .workbench__head .ui-select,
270
- .work-card__head .ui-select,
271
- .sandbox__pane-head .ui-select {
272
- width: auto;
273
- min-width: 150px;
274
- max-width: 220px;
275
- }
276
-
277
- .sandbox__scroll {
278
- min-height: 0;
279
- overflow-y: auto;
280
- overflow-x: hidden;
281
- padding: 18px;
282
- }
283
-
284
- .sandbox__column {
285
- width: min(760px, 100%);
286
- margin: 0 auto;
287
- }
288
-
289
- /* Chat */
290
- .chat {
291
- display: grid;
292
- align-content: start;
293
- gap: 10px;
294
- }
295
-
296
- .chat__turn {
297
- display: grid;
298
- gap: 6px;
299
- padding: 12px 14px;
300
- background: var(--surface);
301
- border: 1px solid var(--line);
302
- border-radius: var(--r-md);
303
- }
304
-
305
- .chat__turn--user {
306
- background: var(--primary-tint);
307
- border-color: var(--primary-soft);
308
- }
309
-
310
- .chat__meta {
311
- display: flex;
312
- flex-wrap: wrap;
313
- align-items: center;
314
- gap: 8px;
315
- font-size: var(--text-xs);
316
- font-weight: 600;
317
- letter-spacing: 0.06em;
318
- text-transform: uppercase;
319
- color: var(--ink-3);
320
- }
321
-
322
- /* Which module an entry belongs to, quiet enough to ignore in a session that
323
- only has one. */
324
- .chat__module {
325
- font-size: var(--text-xs);
326
- font-weight: 500;
327
- letter-spacing: 0;
328
- text-transform: none;
329
- color: var(--ink-3);
330
- }
331
-
332
- .chat__text {
333
- margin: 0;
334
- font-size: var(--text-md);
335
- line-height: 1.55;
336
- white-space: pre-wrap;
337
- overflow-wrap: anywhere;
338
- }
339
-
340
- .chat__events {
341
- display: grid;
342
- gap: 4px;
343
- margin: 0;
344
- padding: 0;
345
- list-style: none;
346
- }
347
-
348
- .chat__event {
349
- display: flex;
350
- align-items: center;
351
- gap: 8px;
352
- min-width: 0;
353
- font-family: var(--font-mono);
354
- font-size: var(--text-sm);
355
- color: var(--ink-3);
356
- }
357
-
358
- .chat__event-text {
359
- min-width: 0;
360
- overflow: hidden;
361
- text-overflow: ellipsis;
362
- white-space: nowrap;
363
- }
364
-
365
- .chat__event--error {
366
- color: var(--danger);
367
- }
368
-
369
- .chat__composer {
370
- display: grid;
371
- justify-items: center;
372
- gap: 8px;
373
- padding: 12px 14px;
374
- background: var(--surface);
375
- border-top: 1px solid var(--line);
376
- }
377
-
378
- .chat__composer > * {
379
- width: min(760px, 100%);
380
- }
381
-
382
- .chat__composer-row {
383
- display: flex;
384
- flex-wrap: wrap;
385
- align-items: center;
386
- gap: 12px;
387
- }
388
-
389
- .chat__composer-status {
390
- margin: 0;
391
- font-size: var(--text-sm);
392
- color: var(--ink-3);
393
- }
394
-
395
- /* Role and agent sit with the send action, as quiet underlined pickers rather
396
- than boxed controls that compete with the conversation. */
397
- .chat__picker {
398
- height: 26px;
399
- padding: 0 22px 0 2px;
400
- font-family: var(--font-sans);
401
- font-size: var(--text-sm);
402
- font-weight: 500;
403
- color: var(--ink-2);
404
- appearance: none;
405
- background-color: transparent;
406
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2364738F' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
407
- background-repeat: no-repeat;
408
- background-position: right 2px center;
409
- background-size: 14px;
410
- border: 0;
411
- border-bottom: 1px solid var(--line);
412
- border-radius: 0;
413
- cursor: pointer;
414
- transition: border-color var(--t-fast) var(--ease);
415
- }
416
-
417
- .chat__picker:hover {
418
- border-bottom-color: var(--ink-3);
419
- }
420
-
421
- .chat__picker:focus-visible {
422
- border-bottom-color: var(--primary);
423
- outline: 0;
424
- }
425
-
426
- /* A handoff is the orchestrator speaking, not a specialist: it names who works
427
- next and carries the action that starts them. */
428
- .chat__handoff {
429
- display: grid;
430
- gap: 8px;
431
- padding: 12px 14px;
432
- background: var(--surface);
433
- border: 1px dashed var(--line);
434
- border-left: 3px solid var(--primary);
435
- border-radius: var(--r-md);
436
- }
437
-
438
- .chat__handoff--question,
439
- .chat__handoff--approval {
440
- background: var(--warning-bg);
441
- border-color: var(--warning-line);
442
- border-left-color: var(--warning);
443
- }
444
-
445
- .chat__handoff--blocked {
446
- border-left-color: var(--danger);
447
- }
448
-
449
- .chat__handoff--review {
450
- border-left-color: var(--success);
451
- }
452
-
453
- .chat__handoff .ui-form__actions {
454
- margin-left: 0;
455
- }
456
-
457
- /* The specification the operator approves, and what the session changed in it.
458
- Long lists stay readable: they wrap, they never scroll sideways, and only an
459
- identifier is monospaced. */
460
- .spec-review {
461
- display: grid;
462
- gap: 10px;
463
- padding: 12px;
464
- background: var(--surface);
465
- border: 1px solid var(--line);
466
- border-radius: var(--r-md);
467
- min-width: 0;
468
- }
469
-
470
- .spec-review__head {
471
- display: flex;
472
- flex-wrap: wrap;
473
- align-items: center;
474
- gap: 8px;
475
- font-size: var(--text-sm);
476
- }
477
-
478
- .spec-review__path {
479
- font-size: var(--text-xs);
480
- color: var(--ink-3);
481
- overflow-wrap: anywhere;
482
- }
483
-
484
- .spec-review__block {
485
- display: grid;
486
- gap: 6px;
487
- min-width: 0;
488
- }
489
-
490
- .spec-review__title {
491
- margin: 0;
492
- font-size: var(--text-xs);
493
- font-weight: 600;
494
- letter-spacing: 0.06em;
495
- text-transform: uppercase;
496
- color: var(--ink-3);
497
- }
498
-
499
- .spec-review__text,
500
- .spec-review__empty {
501
- margin: 0;
502
- font-size: var(--text-sm);
503
- line-height: 1.5;
504
- overflow-wrap: anywhere;
505
- }
506
-
507
- .spec-review__empty {
508
- color: var(--ink-3);
509
- }
510
-
511
- .spec-review__facts {
512
- display: grid;
513
- grid-template-columns: auto minmax(0, 1fr);
514
- gap: 2px 10px;
515
- margin: 0;
516
- font-size: var(--text-sm);
517
- }
518
-
519
- .spec-review__facts dt {
520
- color: var(--ink-3);
521
- }
522
-
523
- .spec-review__facts dd {
524
- margin: 0;
525
- overflow-wrap: anywhere;
526
- }
527
-
528
- .spec-review__changes,
529
- .spec-review__list {
530
- display: grid;
531
- gap: 4px;
532
- margin: 0;
533
- padding: 0;
534
- list-style: none;
535
- font-size: var(--text-sm);
536
- }
537
-
538
- .spec-review__change,
539
- .spec-review__item {
540
- display: flex;
541
- flex-wrap: wrap;
542
- align-items: baseline;
543
- gap: 6px;
544
- padding: 3px 6px;
545
- border-radius: var(--r-sm);
546
- overflow-wrap: anywhere;
547
- }
548
-
549
- .spec-review__scenario {
550
- display: grid;
551
- gap: 2px;
552
- padding: 6px;
553
- border-radius: var(--r-sm);
554
- overflow-wrap: anywhere;
555
- }
556
-
557
- .spec-review__change--added,
558
- .spec-review__item--added {
559
- background: var(--success-bg);
560
- }
561
-
562
- .spec-review__change--removed,
563
- .spec-review__item--removed {
564
- background: var(--danger-bg);
565
- }
566
-
567
- .spec-review__change--changed,
568
- .spec-review__item--changed {
569
- background: var(--warning-bg);
570
- }
571
-
572
- .spec-review__sign {
573
- font-family: var(--font-mono);
574
- font-weight: 600;
575
- color: var(--ink-3);
576
- }
577
-
578
- .spec-review__field {
579
- font-size: var(--text-xs);
580
- font-weight: 600;
581
- letter-spacing: 0.04em;
582
- text-transform: uppercase;
583
- color: var(--ink-3);
584
- }
585
-
586
- .spec-review__value {
587
- color: var(--ink-2);
588
- }
589
-
590
- .spec-review__ask {
591
- display: grid;
592
- gap: 8px;
593
- }
594
-
595
- /* The specification as text, for the operator who would rather fix it than
596
- describe it. */
597
- .spec-editor {
598
- display: grid;
599
- grid-template-rows: auto auto minmax(0, 1fr);
600
- gap: 8px;
601
- height: 100%;
602
- padding: 12px;
603
- }
604
-
605
- .spec-editor__bar {
606
- display: flex;
607
- flex-wrap: wrap;
608
- align-items: center;
609
- gap: 8px;
610
- font-size: var(--text-sm);
611
- }
612
-
613
- .spec-editor__error {
614
- margin: 0;
615
- font-size: var(--text-sm);
616
- color: var(--danger);
617
- }
618
-
619
- .spec-editor__notice {
620
- margin: 0;
621
- font-size: var(--text-sm);
622
- color: var(--ink-3);
623
- }
624
-
625
- .spec-editor__text {
626
- min-height: 60vh;
627
- font-family: var(--font-mono);
628
- font-size: var(--text-sm);
629
- line-height: 1.5;
630
- white-space: pre;
631
- resize: none;
632
- }
633
-
634
- /* A recovery action, kept quiet: it sits under a turn and only offers to roll
635
- the workspace back to that point. */
636
- .chat__restore {
637
- display: flex;
638
- flex-wrap: wrap;
639
- align-items: center;
640
- gap: 8px;
641
- }
642
-
643
- .chat__restore-toggle,
644
- .chat__restore-go,
645
- .chat__restore-cancel {
646
- display: inline-flex;
647
- align-items: center;
648
- gap: 4px;
649
- padding: 2px 6px;
650
- font-family: var(--font-sans);
651
- font-size: var(--text-xs);
652
- font-weight: 600;
653
- letter-spacing: 0.04em;
654
- text-transform: uppercase;
655
- color: var(--ink-3);
656
- background: transparent;
657
- border: 0;
658
- border-radius: var(--r-sm);
659
- cursor: pointer;
660
- transition: color var(--t-fast) var(--ease);
661
- }
662
-
663
- .chat__restore-toggle:hover,
664
- .chat__restore-go:hover:not(:disabled),
665
- .chat__restore-cancel:hover:not(:disabled) {
666
- color: var(--primary);
667
- }
668
-
669
- .chat__restore-go:disabled,
670
- .chat__restore-cancel:disabled {
671
- cursor: not-allowed;
672
- opacity: 0.5;
673
- }
674
-
675
- .chat__restore-ask {
676
- font-size: var(--text-sm);
677
- color: var(--ink-3);
678
- }
679
-
680
- .chat__restore-error {
681
- width: 100%;
682
- font-size: var(--text-sm);
683
- color: var(--danger);
684
- }
685
-
686
- .chat__auto {
687
- display: inline-flex;
688
- align-items: center;
689
- gap: 6px;
690
- font-size: var(--text-sm);
691
- color: var(--ink-3);
692
- white-space: nowrap;
693
- }
694
-
695
- .chat__selection {
696
- display: grid;
697
- gap: 4px;
698
- padding: 8px 10px;
699
- font-size: var(--text-sm);
700
- background: var(--primary-tint);
701
- border: 1px solid var(--primary-soft);
702
- border-radius: var(--r);
703
- }
704
-
705
- /* The attachment strip sits above the textarea: one chip per file, an image
706
- thumbnail or a file icon, its name, its size, and a remove control. */
707
- .chat__attachments {
708
- display: flex;
709
- flex-wrap: wrap;
710
- gap: 8px;
711
- }
712
-
713
- .chat__attachment {
714
- display: flex;
715
- align-items: center;
716
- gap: 8px;
717
- max-width: 240px;
718
- padding: 4px 6px 4px 4px;
719
- background: var(--surface-2);
720
- border: 1px solid var(--line);
721
- border-radius: var(--r);
722
- }
723
-
724
- .chat__attachment--error {
725
- border-color: var(--danger);
726
- background: var(--danger-bg);
727
- }
728
-
729
- .chat__attachment-thumb {
730
- flex: none;
731
- width: 40px;
732
- height: 40px;
733
- object-fit: cover;
734
- border-radius: var(--r-sm);
735
- background: var(--surface);
736
- }
737
-
738
- .chat__attachment-thumb--file {
739
- display: flex;
740
- align-items: center;
741
- justify-content: center;
742
- color: var(--ink-3);
743
- border: 1px solid var(--line);
744
- }
745
-
746
- .chat__attachment-info {
747
- display: grid;
748
- gap: 2px;
749
- min-width: 0;
750
- }
751
-
752
- .chat__attachment-name {
753
- overflow: hidden;
754
- font-size: var(--text-sm);
755
- text-overflow: ellipsis;
756
- white-space: nowrap;
757
- }
758
-
759
- .chat__attachment-size {
760
- font-size: var(--text-xs);
761
- color: var(--ink-3);
762
- }
763
-
764
- .chat__attachment-remove {
765
- display: flex;
766
- flex: none;
767
- align-items: center;
768
- justify-content: center;
769
- padding: 2px;
770
- color: var(--ink-3);
771
- background: transparent;
772
- border: 0;
773
- border-radius: var(--r-sm);
774
- cursor: pointer;
775
- transition: color var(--t-fast) var(--ease);
776
- }
777
-
778
- .chat__attachment-remove:hover {
779
- color: var(--danger);
780
- }
781
-
782
- .chat__attachment-error {
783
- width: 100%;
784
- font-size: var(--text-sm);
785
- color: var(--danger);
786
- }
787
-
788
- /* The attach button matches the quiet composer pickers, and the file input it
789
- opens stays out of the layout. */
790
- .chat__attach {
791
- display: flex;
792
- align-items: center;
793
- justify-content: center;
794
- width: 26px;
795
- height: 26px;
796
- color: var(--ink-2);
797
- background: transparent;
798
- border: 1px solid var(--line);
799
- border-radius: var(--r-sm);
800
- cursor: pointer;
801
- transition:
802
- color var(--t-fast) var(--ease),
803
- border-color var(--t-fast) var(--ease);
804
- }
805
-
806
- .chat__attach:hover:not(:disabled) {
807
- color: var(--primary);
808
- border-color: var(--primary);
809
- }
810
-
811
- .chat__attach:disabled {
812
- cursor: not-allowed;
813
- opacity: 0.5;
814
- }
815
-
816
- .chat__attach-input {
817
- display: none;
818
- }
819
-
820
- /* The work card: preview or code, floating on the right of the conversation.
821
- A click opens the same content full screen. */
822
- .work-card {
823
- position: relative;
824
- display: grid;
825
- grid-template-rows: auto minmax(0, 1fr);
826
- min-width: 0;
827
- min-height: 0;
828
- background: var(--surface);
829
- border: 1px solid var(--line);
830
- border-radius: var(--r-lg);
831
- box-shadow:
832
- 0 1px 2px rgb(16 24 40 / 6%),
833
- 0 18px 40px rgb(16 24 40 / 8%);
834
- overflow: hidden;
835
- transition:
836
- box-shadow var(--t-base) var(--ease),
837
- border-color var(--t-base) var(--ease);
838
- }
839
-
840
- .work-card:hover {
841
- border-color: var(--primary-soft);
842
- box-shadow:
843
- 0 1px 2px rgb(16 24 40 / 8%),
844
- 0 24px 52px rgb(16 24 40 / 12%);
845
- }
846
-
847
- .work-card__head {
848
- display: flex;
849
- align-items: center;
850
- gap: 8px;
851
- padding: 10px 12px;
852
- border-bottom: 1px solid var(--line-2);
853
- }
854
-
855
- .work-card__stage {
856
- position: relative;
857
- min-width: 0;
858
- min-height: 0;
859
- background: var(--surface-2);
860
- overflow: hidden;
861
- }
862
-
863
- .work-card__stage--code {
864
- overflow-y: auto;
865
- background: var(--bg);
866
- }
867
-
868
- /* The preview renders at a real workspace width and is scaled to the card, so
869
- the card shows the true desktop layout instead of a narrow rendering. */
870
- .work-card__viewport {
871
- position: absolute;
872
- inset: 0;
873
- overflow: hidden;
874
- }
875
-
876
- .work-card__viewport .preview-frame {
877
- width: 1440px;
878
- height: 900px;
879
- transform-origin: top left;
880
- }
881
-
882
- .work-card__open {
883
- position: absolute;
884
- inset: 0;
885
- z-index: 2;
886
- display: grid;
887
- place-items: center;
888
- padding: 0;
889
- background: transparent;
890
- border: 0;
891
- cursor: zoom-in;
892
- }
893
-
894
- .work-card__hint {
895
- display: inline-flex;
896
- align-items: center;
897
- gap: 6px;
898
- padding: 6px 10px;
899
- font-size: var(--text-sm);
900
- font-weight: 500;
901
- color: var(--ink-0);
902
- background: rgb(16 24 40 / 72%);
903
- border-radius: var(--r);
904
- opacity: 0;
905
- transition: opacity var(--t-base) var(--ease);
906
- }
907
-
908
- .work-card__open:hover .work-card__hint,
909
- .work-card__open:focus-visible .work-card__hint {
910
- opacity: 1;
911
- }
912
-
913
- .work-card__foot {
914
- display: flex;
915
- flex-wrap: wrap;
916
- align-items: center;
917
- gap: 6px;
918
- padding: 8px 12px;
919
- border-top: 1px solid var(--line-2);
920
- }
921
-
922
- /* Full-screen workbench: the same preview at working size, or the diff. */
923
- .workbench {
924
- position: fixed;
925
- inset: 0;
926
- z-index: 80;
927
- display: grid;
928
- place-items: center;
929
- padding: 24px;
930
- background: rgb(12 18 34 / 55%);
931
- }
932
-
933
- .workbench__panel {
934
- display: grid;
935
- grid-template-rows: auto minmax(0, 1fr);
936
- width: min(1600px, 100%);
937
- height: min(960px, 100%);
938
- min-width: 0;
939
- background: var(--surface);
940
- border: 1px solid var(--line);
941
- border-radius: var(--r-lg);
942
- box-shadow: 0 24px 64px rgb(16 24 40 / 24%);
943
- overflow: hidden;
944
- }
945
-
946
- .workbench__head {
947
- display: flex;
948
- flex-wrap: wrap;
949
- align-items: center;
950
- gap: 8px;
951
- padding: 10px 14px;
952
- border-bottom: 1px solid var(--line);
953
- }
954
-
955
- .workbench__body {
956
- position: relative;
957
- min-width: 0;
958
- min-height: 0;
959
- background: var(--surface-2);
960
- overflow: hidden;
961
- }
962
-
963
- .workbench__body--scroll {
964
- overflow-y: auto;
965
- background: var(--bg);
966
- }
967
-
968
- .preview-frame {
969
- width: 100%;
970
- height: 100%;
971
- border: 0;
972
- background: var(--surface);
973
- }
974
-
975
- .preview-frame__wrap {
976
- position: relative;
977
- min-height: 0;
978
- background: var(--surface-2);
979
- }
980
-
981
- .preview-frame__wrap--selecting::after {
982
- position: absolute;
983
- inset: 0;
984
- content: '';
985
- border: 2px dashed var(--primary);
986
- pointer-events: none;
987
- }
988
-
989
- /* Eject: a delivery screen, not a banner. */
990
- .eject__panel {
991
- display: grid;
992
- grid-template-rows: auto minmax(0, 1fr) auto;
993
- width: min(560px, 100%);
994
- max-height: min(680px, 100%);
995
- background: var(--surface);
996
- border: 1px solid var(--line);
997
- border-radius: var(--r-lg);
998
- box-shadow: 0 24px 64px rgb(16 24 40 / 24%);
999
- overflow: hidden;
1000
- }
1001
-
1002
- .eject__head {
1003
- display: flex;
1004
- align-items: center;
1005
- gap: 8px;
1006
- padding: 14px 18px;
1007
- border-bottom: 1px solid var(--line-2);
1008
- }
1009
-
1010
- .eject__title {
1011
- display: inline-flex;
1012
- align-items: center;
1013
- gap: 8px;
1014
- font-size: var(--text-lg);
1015
- font-weight: 600;
1016
- }
1017
-
1018
- .eject__body {
1019
- display: grid;
1020
- align-content: start;
1021
- gap: 14px;
1022
- min-height: 0;
1023
- padding: 18px;
1024
- overflow-y: auto;
1025
- }
1026
-
1027
- .eject__lead {
1028
- margin: 0;
1029
- font-size: var(--text-md);
1030
- }
1031
-
1032
- .eject__steps {
1033
- display: grid;
1034
- gap: 8px;
1035
- margin: 0;
1036
- padding: 0;
1037
- list-style: none;
1038
- }
1039
-
1040
- .eject__step {
1041
- display: flex;
1042
- align-items: center;
1043
- gap: 10px;
1044
- font-size: var(--text-md);
1045
- color: var(--ink-3);
1046
- }
1047
-
1048
- .eject__step--passed {
1049
- color: var(--ink);
1050
- }
1051
-
1052
- .eject__step--failed {
1053
- color: var(--danger);
1054
- }
1055
-
1056
- .eject__step--note {
1057
- color: var(--warning);
1058
- }
1059
-
1060
- .eject__error {
1061
- display: block;
1062
- max-height: 40vh;
1063
- overflow: auto;
1064
- font-family: var(--font-mono);
1065
- font-size: var(--text-sm);
1066
- white-space: pre-wrap;
1067
- overflow-wrap: anywhere;
1068
- }
1069
-
1070
- .eject__step--running {
1071
- color: var(--primary-hover);
1072
- }
1073
-
1074
- .eject__step-dot {
1075
- width: 6px;
1076
- height: 6px;
1077
- background: var(--ink-4);
1078
- border-radius: 50%;
1079
- }
1080
-
1081
- .eject__step-icon {
1082
- display: inline-grid;
1083
- place-items: center;
1084
- width: 22px;
1085
- height: 22px;
1086
- background: var(--surface-2);
1087
- border-radius: 50%;
1088
- }
1089
-
1090
- .eject__step--passed .eject__step-icon {
1091
- color: var(--success);
1092
- background: var(--success-bg);
1093
- }
1094
-
1095
- .eject__step--failed .eject__step-icon {
1096
- color: var(--danger);
1097
- background: var(--danger-bg);
1098
- }
1099
-
1100
- .eject__step-icon--spin {
1101
- color: var(--primary);
1102
- background: var(--primary-tint);
1103
- animation: eject-spin 1.1s linear infinite;
1104
- }
1105
-
1106
- @keyframes eject-spin {
1107
- to {
1108
- transform: rotate(360deg);
1109
- }
1110
- }
1111
-
1112
- @media (prefers-reduced-motion: reduce) {
1113
- .eject__step-icon--spin {
1114
- animation: none;
1115
- }
1116
- }
1117
-
1118
- .eject__step-label {
1119
- min-width: 0;
1120
- overflow-wrap: anywhere;
1121
- }
1122
-
1123
- .eject__step-detail {
1124
- font-family: var(--font-mono);
1125
- font-size: var(--text-sm);
1126
- color: var(--ink-3);
1127
- overflow-wrap: anywhere;
1128
- }
1129
-
1130
- .eject__done {
1131
- display: grid;
1132
- gap: 4px;
1133
- padding: 14px 16px;
1134
- background: var(--success-bg);
1135
- border: 1px solid var(--success-line);
1136
- border-radius: var(--r);
1137
- }
1138
-
1139
- .eject__body .ui-checkbox {
1140
- margin-top: 4px;
1141
- padding-top: 10px;
1142
- border-top: 1px solid var(--line-2);
1143
- }
1144
-
1145
- .eject__foot {
1146
- display: flex;
1147
- align-items: center;
1148
- justify-content: flex-end;
1149
- gap: 8px;
1150
- padding: 12px 18px;
1151
- border-top: 1px solid var(--line-2);
1152
- }
1153
-
1154
- /* GitHub delivery settings use the same calm, three-part modal anatomy as the
1155
- eject plan. Secrets stay write-only and the form remains scannable. */
1156
- .github-settings__panel {
1157
- display: grid;
1158
- grid-template-rows: auto minmax(0, 1fr) auto;
1159
- width: min(720px, 100%);
1160
- max-height: min(760px, 100%);
1161
- background: var(--surface);
1162
- border: 1px solid var(--line);
1163
- border-radius: var(--r-lg);
1164
- box-shadow: 0 24px 64px rgb(16 24 40 / 24%);
1165
- overflow: hidden;
1166
- }
1167
-
1168
- .github-settings__head,
1169
- .github-settings__foot {
1170
- display: flex;
1171
- align-items: center;
1172
- gap: 8px;
1173
- padding: 14px 18px;
1174
- }
1175
-
1176
- .github-settings__head {
1177
- border-bottom: 1px solid var(--line-2);
1178
- }
1179
-
1180
- .github-settings__title {
1181
- display: inline-flex;
1182
- align-items: center;
1183
- gap: 8px;
1184
- font-size: var(--text-lg);
1185
- font-weight: 600;
1186
- }
1187
-
1188
- .github-settings__body {
1189
- display: grid;
1190
- gap: 14px;
1191
- min-height: 0;
1192
- padding: 18px;
1193
- overflow-y: auto;
1194
- }
1195
-
1196
- .github-settings__body > .ui-help {
1197
- margin: 0;
1198
- }
1199
-
1200
- .github-settings__foot {
1201
- justify-content: flex-end;
1202
- border-top: 1px solid var(--line-2);
1203
- }
1204
-
1205
- /* Session picker */
1206
- .sessions {
1207
- display: grid;
1208
- grid-template-columns: minmax(0, 1fr);
1209
- gap: 18px;
1210
- width: min(calc(var(--sidebar-w) * 5), 100%);
1211
- margin: 0 auto;
1212
- padding: 8px 0 24px;
1213
- }
1214
-
1215
- .sessions > * {
1216
- min-width: 0;
1217
- }
1218
-
1219
- .sessions__actions {
1220
- display: flex;
1221
- flex-wrap: wrap;
1222
- gap: 0.5em;
1223
- }
1224
-
1225
- .sessions__head {
1226
- display: grid;
1227
- gap: 6px;
1228
- }
1229
-
1230
- .sessions__head h1 {
1231
- margin: 0;
1232
- font-size: var(--text-2xl);
1233
- letter-spacing: -0.01em;
1234
- }
1235
-
1236
- .sessions__head p {
1237
- margin: 0;
1238
- font-size: var(--text-md);
1239
- color: var(--ink-3);
1240
- }
1241
-
1242
- .sessions__start {
1243
- background: var(--surface);
1244
- border: 1px solid var(--line);
1245
- border-radius: var(--r-lg);
1246
- box-shadow: 0 1px 2px rgb(16 24 40 / 5%);
1247
- }
1248
-
1249
- .sessions__brief {
1250
- min-height: 108px;
1251
- font-size: var(--text-base);
1252
- line-height: 1.55;
1253
- resize: vertical;
1254
- }
1255
-
1256
- .sessions__composer {
1257
- display: grid;
1258
- gap: 10px;
1259
- padding: 16px;
1260
- }
1261
-
1262
- .sessions__composer-row {
1263
- display: flex;
1264
- align-items: center;
1265
- gap: 12px;
1266
- }
1267
-
1268
- .sessions__blocked {
1269
- display: grid;
1270
- gap: 6px;
1271
- margin: 12px 0 0;
1272
- padding: 0;
1273
- list-style: none;
1274
- }
1275
-
1276
- .sessions__blocked li {
1277
- display: flex;
1278
- flex-wrap: wrap;
1279
- align-items: center;
1280
- gap: 8px;
1281
- font-size: var(--text-sm);
1282
- color: var(--ink-3);
1283
- }
1284
-
1285
- .sessions__team {
1286
- margin: 10px 0 0;
1287
- }
1288
-
1289
- .sessions__grid {
1290
- display: grid;
1291
- grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
1292
- gap: 12px;
1293
- }
1294
-
1295
- .sessions__toolbar {
1296
- display: flex;
1297
- align-items: center;
1298
- justify-content: space-between;
1299
- gap: 8px;
1300
- }
1301
-
1302
- /* The card opens the session; its actions sit in a corner of their own so a
1303
- click on the menu never opens the session by accident. */
1304
- .session-card {
1305
- position: relative;
1306
- background: var(--surface);
1307
- border: 1px solid var(--line);
1308
- border-radius: var(--r-lg);
1309
- transition:
1310
- border-color var(--t-base) var(--ease),
1311
- box-shadow var(--t-base) var(--ease),
1312
- transform var(--t-base) var(--ease);
1313
- }
1314
-
1315
- .session-card:hover {
1316
- border-color: var(--primary-soft);
1317
- box-shadow: 0 8px 20px rgb(16 24 40 / 8%);
1318
- transform: translateY(-1px);
1319
- }
1320
-
1321
- .session-card--archived {
1322
- opacity: 0.72;
1323
- }
1324
-
1325
- .session-card__open {
1326
- display: grid;
1327
- align-content: start;
1328
- gap: 10px;
1329
- width: 100%;
1330
- padding: 16px 44px 16px 16px;
1331
- font: inherit;
1332
- color: inherit;
1333
- text-align: left;
1334
- background: transparent;
1335
- border: 0;
1336
- border-radius: var(--r-lg);
1337
- cursor: pointer;
1338
- }
1339
-
1340
- .session-card__actions {
1341
- position: absolute;
1342
- top: 10px;
1343
- right: 10px;
1344
- }
1345
-
1346
- .session-card__menu {
1347
- display: grid;
1348
- width: 28px;
1349
- height: 28px;
1350
- place-items: center;
1351
- color: var(--ink-3);
1352
- background: transparent;
1353
- border: 1px solid transparent;
1354
- border-radius: var(--r);
1355
- cursor: pointer;
1356
- }
1357
-
1358
- .session-card__menu:hover,
1359
- .session-card__menu[aria-expanded='true'] {
1360
- color: var(--ink);
1361
- background: var(--surface-2);
1362
- border-color: var(--line);
1363
- }
1364
-
1365
- .session-card__panel {
1366
- position: absolute;
1367
- top: calc(100% + 4px);
1368
- right: 0;
1369
- z-index: 30;
1370
- width: 260px;
1371
- }
1372
-
1373
- .session-card__confirm {
1374
- margin: 0;
1375
- padding: 6px 8px 10px;
1376
- }
1377
-
1378
- .session-card__title {
1379
- display: grid;
1380
- gap: 2px;
1381
- min-width: 0;
1382
- }
1383
-
1384
- .session-card__title b {
1385
- font-size: var(--text-base);
1386
- font-weight: 600;
1387
- overflow-wrap: anywhere;
1388
- }
1389
-
1390
- .session-card__title small {
1391
- font-family: var(--font-mono);
1392
- font-size: var(--text-sm);
1393
- color: var(--ink-3);
1394
- overflow-wrap: anywhere;
1395
- }
1396
-
1397
- .session-card__meta {
1398
- display: flex;
1399
- flex-wrap: wrap;
1400
- align-items: center;
1401
- gap: 8px;
1402
- }
1403
-
1404
- .session-card__meta small {
1405
- font-size: var(--text-sm);
1406
- color: var(--ink-3);
1407
- }
1408
-
1409
- .session-card__foot {
1410
- display: flex;
1411
- align-items: center;
1412
- justify-content: space-between;
1413
- gap: 8px;
1414
- font-size: var(--text-sm);
1415
- color: var(--ink-3);
1416
- }
1417
-
1418
- /* Diff */
1419
- .diff {
1420
- display: grid;
1421
- gap: 12px;
1422
- min-width: 0;
1423
- }
1424
-
1425
- .diff__group {
1426
- display: grid;
1427
- gap: 12px;
1428
- min-width: 0;
1429
- }
1430
-
1431
- /* One header per module, so a session that spans modules reads as grouped
1432
- files instead of one long list. */
1433
- .diff__module {
1434
- display: flex;
1435
- align-items: baseline;
1436
- gap: 8px;
1437
- padding: 0 2px;
1438
- }
1439
-
1440
- .diff__file {
1441
- min-width: 0;
1442
- background: var(--surface);
1443
- border: 1px solid var(--line);
1444
- border-radius: var(--r-md);
1445
- overflow: hidden;
1446
- }
1447
-
1448
- .diff__file-head {
1449
- display: flex;
1450
- flex-wrap: wrap;
1451
- align-items: center;
1452
- gap: 8px;
1453
- padding: 8px 12px;
1454
- background: var(--surface-2);
1455
- border-bottom: 1px solid var(--line);
1456
- }
1457
-
1458
- .diff__path {
1459
- font-family: var(--font-mono);
1460
- font-size: var(--text-sm);
1461
- overflow-wrap: anywhere;
1462
- }
1463
-
1464
- .diff__stat {
1465
- font-family: var(--font-mono);
1466
- font-size: var(--text-xs);
1467
- }
1468
-
1469
- .diff__stat--add {
1470
- color: var(--success);
1471
- }
1472
-
1473
- .diff__stat--del {
1474
- color: var(--danger);
1475
- }
1476
-
1477
- .diff__hunk {
1478
- overflow-x: auto;
1479
- border-top: 1px solid var(--line-2);
1480
- }
1481
-
1482
- .diff__hunk-header {
1483
- padding: 4px 12px;
1484
- font-family: var(--font-mono);
1485
- font-size: var(--text-xs);
1486
- color: var(--ink-3);
1487
- background: var(--surface-2);
1488
- }
1489
-
1490
- .diff__line {
1491
- display: grid;
1492
- grid-template-columns: 48px 1fr;
1493
- font-family: var(--font-mono);
1494
- font-size: var(--text-sm);
1495
- line-height: 1.5;
1496
- white-space: pre;
1497
- }
1498
-
1499
- .diff__line--add {
1500
- background: var(--success-bg);
1501
- }
1502
-
1503
- .diff__line--del {
1504
- background: var(--danger-bg);
1505
- }
1506
-
1507
- .diff__gutter {
1508
- padding: 0 8px;
1509
- color: var(--ink-4);
1510
- text-align: right;
1511
- user-select: none;
1512
- }
1513
-
1514
- .diff__code {
1515
- padding: 0 12px;
1516
- overflow-wrap: normal;
1517
- }
1518
-
1519
- /* Syntax tokens, tuned for both diff backgrounds. */
1520
- .tok-keyword {
1521
- color: var(--primary-hover);
1522
- font-weight: 500;
1523
- }
1524
-
1525
- .tok-string {
1526
- color: var(--success);
1527
- }
1528
-
1529
- .tok-comment {
1530
- color: var(--ink-4);
1531
- font-style: italic;
1532
- }
1533
-
1534
- .tok-number {
1535
- color: var(--warning);
1536
- }
1537
-
1538
- .tok-type {
1539
- color: var(--brand-weft);
1540
- }
1541
-
1542
- /* Connect screen */
1543
- .connect {
1544
- display: grid;
1545
- place-items: center;
1546
- min-height: 100vh;
1547
- padding: 32px 16px;
1548
- background: var(--bg);
1549
- }
1550
-
1551
- .connect__card {
1552
- width: min(560px, 100%);
1553
- background: var(--surface);
1554
- border: 1px solid var(--line);
1555
- border-radius: var(--r-lg);
1556
- }
1557
-
1558
- .connect__head {
1559
- display: grid;
1560
- gap: 6px;
1561
- padding: 22px 24px 0;
1562
- }
1563
-
1564
- .connect__head h1 {
1565
- margin: 0;
1566
- font-size: var(--text-2xl);
1567
- }
1568
-
1569
- .connect__head p {
1570
- margin: 0;
1571
- font-size: var(--text-md);
1572
- color: var(--ink-3);
1573
- }