pmx-canvas 0.4.0 → 0.4.2
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.
- package/CHANGELOG.md +51 -0
- package/Readme.md +9 -4
- package/dist/canvas/global.css +397 -0
- package/dist/canvas/index.js +89 -89
- package/dist/canvas/surface-theme.css +160 -0
- package/dist/json-render/index.css +1 -1
- package/dist/types/client/nodes/iframe-document-url.d.ts +1 -0
- package/dist/types/client/nodes/use-surface-frame.d.ts +13 -0
- package/dist/types/client/state/canvas-store.d.ts +1 -0
- package/dist/types/client/state/iframe-mode.d.ts +26 -0
- package/dist/types/client/types.d.ts +2 -1
- package/dist/types/server/canvas-db.d.ts +2 -1
- package/dist/types/server/html-surface.d.ts +8 -1
- package/dist/types/shared/themes.d.ts +27 -0
- package/docs/RELEASE.md +10 -4
- package/docs/cli.md +1 -1
- package/docs/environment.md +2 -1
- package/docs/http-api.md +29 -0
- package/docs/plans/plan-009-tech-debt-backlog.md +9 -1
- package/docs/screenshot.png +0 -0
- package/package.json +1 -1
- package/skills/pmx-canvas/SKILL.md +32 -4
- package/skills/pmx-canvas/references/full-reference.md +3 -3
- package/skills/pmx-canvas-testing/SKILL.md +3 -0
- package/src/cli/index.ts +3 -2
- package/src/client/App.tsx +201 -53
- package/src/client/index.tsx +5 -0
- package/src/client/nodes/ExtAppFrame.tsx +36 -1
- package/src/client/nodes/HtmlNode.tsx +5 -1
- package/src/client/nodes/McpAppNode.tsx +9 -2
- package/src/client/nodes/iframe-document-url.ts +62 -9
- package/src/client/nodes/use-surface-frame.ts +53 -0
- package/src/client/state/canvas-store.ts +5 -0
- package/src/client/state/iframe-mode.ts +118 -0
- package/src/client/state/sse-bridge.ts +8 -2
- package/src/client/theme/global.css +397 -0
- package/src/client/theme/surface-theme.css +160 -0
- package/src/client/types.ts +3 -1
- package/src/server/canvas-db.ts +3 -2
- package/src/server/html-surface.ts +17 -3
- package/src/server/operations/ops/canvas-wire.ts +6 -1
- package/src/server/server.ts +59 -2
- package/src/shared/themes.ts +58 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,55 @@
|
|
|
3
3
|
All notable changes to `pmx-canvas` are documented here. This project follows
|
|
4
4
|
[Semantic Versioning](https://semver.org/).
|
|
5
5
|
|
|
6
|
+
## [0.4.2] - 2026-08-04
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- Five new themes — `midnight`, `sepia`, `arctic`, `ember`, and `forest` —
|
|
11
|
+
alongside `dark`, `light`, and `high-contrast`, selectable from a new theme
|
|
12
|
+
picker in the toolbar, via `--theme=...`, or `PMX_CANVAS_THEME`.
|
|
13
|
+
- The toolbar now collapses on narrow screens and mobile into a single compact
|
|
14
|
+
bar with a "⋯" menu holding every secondary action as labeled touch-friendly
|
|
15
|
+
rows, replacing the wrapped two-bar layout.
|
|
16
|
+
- Amp orbs are auto-detected: when the server runs with `AMP_ORB` set, the
|
|
17
|
+
embedded canvas skips the (there-unreliable) iframe probe and uses `srcdoc`
|
|
18
|
+
mode directly.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Refreshed the bundled skill's accuracy: tool tables verified against the
|
|
23
|
+
live 22-tool MCP surface, stale composite counts corrected, and the browser
|
|
24
|
+
guidance now documents the toolbar theme picker and the narrow-screen More
|
|
25
|
+
menu.
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- HTML surfaces now inline their theme stylesheet instead of linking it, so
|
|
30
|
+
srcdoc-rendered surfaces in nested-iframe hosts render styled instead of
|
|
31
|
+
blank (dark-on-dark).
|
|
32
|
+
|
|
33
|
+
## [0.4.1] - 2026-08-04
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
|
|
37
|
+
- Iframe-backed nodes (HTML, graph, json-render, MCP apps) now render inside
|
|
38
|
+
nested-iframe hosts like Amp orb portals: the canvas probes at boot whether
|
|
39
|
+
the embedding context loads iframe `src` URLs at all, and falls back to
|
|
40
|
+
fetching same-origin surfaces and rendering them inline via `srcdoc` when it
|
|
41
|
+
does not. Force a mode with `/workbench?iframe-mode=srcdoc` (or `=src`).
|
|
42
|
+
|
|
43
|
+
### Fixed
|
|
44
|
+
|
|
45
|
+
- Ext-app nodes now survive a daemon restart without a full panel reload
|
|
46
|
+
(Finding S): the browser revalidates its frame-document URLs on every
|
|
47
|
+
reconnect and automatically re-mints them against the new server process
|
|
48
|
+
when they have gone stale.
|
|
49
|
+
- Best-effort mitigation for residual black ext-app tiles in WebKit host
|
|
50
|
+
panels (Finding N): after an app finishes booting, the canvas briefly nudges
|
|
51
|
+
the iframe's layout size so WebKit must re-rasterize the frame — the same
|
|
52
|
+
mechanism as the manual enlarge-then-close unstick, without the reload. The
|
|
53
|
+
nudge is recorded as `repaint-nudge` in the ext-app recovery trail.
|
|
54
|
+
|
|
6
55
|
## [0.4.0] - 2026-08-04
|
|
7
56
|
|
|
8
57
|
### Breaking
|
|
@@ -2831,6 +2880,8 @@ otherwise have to discover by trial and error.
|
|
|
2831
2880
|
- Regression coverage for snapshot flat-`id` aliases on both MCP and
|
|
2832
2881
|
HTTP surfaces, plus async / top-level-`await` WebView script bodies.
|
|
2833
2882
|
|
|
2883
|
+
[0.4.2]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.4.2
|
|
2884
|
+
[0.4.1]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.4.1
|
|
2834
2885
|
[0.4.0]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.4.0
|
|
2835
2886
|
[0.3.4]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.3.4
|
|
2836
2887
|
[0.3.3]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.3.3
|
package/Readme.md
CHANGED
|
@@ -144,10 +144,15 @@ surfaces (the core never imports a host SDK).
|
|
|
144
144
|
built-in browser pane alongside the PMX MCP server, same zero-adapter recipe
|
|
145
145
|
as Codex: open `http://localhost:4313/workbench` in the app's browser and the
|
|
146
146
|
live board, pins, and Ghost Cursor all work in-panel.
|
|
147
|
-
- **Amp orb portals** (and other buffering proxies
|
|
148
|
-
the live event stream is being buffered by the proxy
|
|
149
|
-
switches to a polling transport, so the board boots and
|
|
150
|
-
the portal with no proxy shims
|
|
147
|
+
- **Amp orb portals** (and other buffering proxies / nested-iframe embeds) —
|
|
148
|
+
the canvas detects when the live event stream is being buffered by the proxy
|
|
149
|
+
and automatically switches to a polling transport, so the board boots and
|
|
150
|
+
stays live through the portal with no proxy shims
|
|
151
|
+
(`/workbench?transport=poll` forces it). It also detects when the nested
|
|
152
|
+
iframe embed blocks `src`-URL iframes entirely and renders HTML, graph,
|
|
153
|
+
json-render, and app surfaces inline via `srcdoc` instead
|
|
154
|
+
(`?iframe-mode=srcdoc` forces it), so iframe-backed nodes work in the portal
|
|
155
|
+
too.
|
|
151
156
|
|
|
152
157
|
The contract is host-agnostic, so a new host plugs in the same way: map its
|
|
153
158
|
hooks, canvas, and session APIs onto PMX's AX primitives — no core changes.
|
package/dist/canvas/global.css
CHANGED
|
@@ -171,6 +171,281 @@
|
|
|
171
171
|
--c-annotation: #ffff00;
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
+
:root[data-theme="midnight"] {
|
|
175
|
+
/* ── Core palette (midnight · deep indigo night) ─────────── */
|
|
176
|
+
--c-bg: #0A0D1C;
|
|
177
|
+
--c-panel: #12172E;
|
|
178
|
+
--c-panel-soft: #0D1224;
|
|
179
|
+
--c-line: #232B4A;
|
|
180
|
+
--c-text: #E6E9F7;
|
|
181
|
+
--c-text-soft: #C6CCE8;
|
|
182
|
+
--c-muted: #8D96BC;
|
|
183
|
+
--c-dim: #5B6383;
|
|
184
|
+
--c-accent: #8B96FF;
|
|
185
|
+
--c-ok: #34D399;
|
|
186
|
+
--c-warn: #F5C452;
|
|
187
|
+
--c-warn-alt: #FFB300;
|
|
188
|
+
--c-danger: #FF6B8A;
|
|
189
|
+
--c-purple: #B388FF;
|
|
190
|
+
--c-thinking: #B388FF;
|
|
191
|
+
--c-subagent: #22D3EE;
|
|
192
|
+
--c-input-bg: #0D1224;
|
|
193
|
+
--c-dot-grid: rgba(139, 150, 255, 0.08);
|
|
194
|
+
--c-panel-overlay: rgba(10, 13, 28, 0.6);
|
|
195
|
+
--c-panel-glass: rgba(18, 23, 46, 0.92);
|
|
196
|
+
--c-shadow: rgba(0, 0, 0, 0.3);
|
|
197
|
+
--c-shadow-heavy: rgba(0, 0, 0, 0.5);
|
|
198
|
+
--c-glow-accent: rgba(139, 150, 255, 0.15);
|
|
199
|
+
--c-surface-hover: rgba(255, 255, 255, 0.06);
|
|
200
|
+
--c-surface-subtle: rgba(255, 255, 255, 0.03);
|
|
201
|
+
--c-surface-th: rgba(255, 255, 255, 0.04);
|
|
202
|
+
--c-accent-8: rgba(139, 150, 255, 0.08);
|
|
203
|
+
--c-accent-10: rgba(139, 150, 255, 0.1);
|
|
204
|
+
--c-accent-12: rgba(139, 150, 255, 0.12);
|
|
205
|
+
--c-accent-15: rgba(139, 150, 255, 0.15);
|
|
206
|
+
--c-accent-25: rgba(139, 150, 255, 0.25);
|
|
207
|
+
--c-accent-30: rgba(139, 150, 255, 0.3);
|
|
208
|
+
--c-accent-40: rgba(139, 150, 255, 0.4);
|
|
209
|
+
--c-ok-10: rgba(52, 211, 153, 0.1);
|
|
210
|
+
--c-ok-12: rgba(52, 211, 153, 0.12);
|
|
211
|
+
--c-ok-20: rgba(52, 211, 153, 0.2);
|
|
212
|
+
--c-ok-25: rgba(52, 211, 153, 0.25);
|
|
213
|
+
--c-warn-10: rgba(245, 196, 82, 0.1);
|
|
214
|
+
--c-warn-12: rgba(245, 196, 82, 0.12);
|
|
215
|
+
--c-warn-15: rgba(245, 196, 82, 0.15);
|
|
216
|
+
--c-warn-20: rgba(245, 196, 82, 0.2);
|
|
217
|
+
--c-warn-22: rgba(245, 196, 82, 0.22);
|
|
218
|
+
--c-warn-30: rgba(245, 196, 82, 0.3);
|
|
219
|
+
--c-warn-60: rgba(245, 196, 82, 0.6);
|
|
220
|
+
--c-danger-12: rgba(255, 107, 138, 0.12);
|
|
221
|
+
--c-line-30: rgba(35, 43, 74, 0.3);
|
|
222
|
+
--c-contrast-fg: #0A0D1C;
|
|
223
|
+
--c-accent-hover: #A3ACFF;
|
|
224
|
+
--c-warn-hover: #F7D06E;
|
|
225
|
+
--c-canvas-wash: linear-gradient(180deg, rgba(255, 255, 255, 0.02), rgba(0, 0, 0, 0));
|
|
226
|
+
--c-annotation: #EDEDF7;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
:root[data-theme="sepia"] {
|
|
230
|
+
/* ── Core palette (sepia · warm amber paper) ─────────────── */
|
|
231
|
+
--c-bg: #F2E7D5;
|
|
232
|
+
--c-panel: #EBDCC2;
|
|
233
|
+
--c-panel-soft: #E8D8BC;
|
|
234
|
+
--c-line: #D3C1A0;
|
|
235
|
+
--c-text: #2E2416;
|
|
236
|
+
--c-text-soft: #554833;
|
|
237
|
+
--c-muted: #77664C;
|
|
238
|
+
--c-dim: #978870;
|
|
239
|
+
--c-accent: #B4632C;
|
|
240
|
+
--c-ok: #3E7D4F;
|
|
241
|
+
--c-warn: #A97B1E;
|
|
242
|
+
--c-warn-alt: #8F6A0D;
|
|
243
|
+
--c-danger: #B3402E;
|
|
244
|
+
--c-purple: #8456B0;
|
|
245
|
+
--c-thinking: #8456B0;
|
|
246
|
+
--c-subagent: #0E7C7B;
|
|
247
|
+
--c-input-bg: #F7EEDD;
|
|
248
|
+
--c-dot-grid: rgba(46, 36, 22, 0.08);
|
|
249
|
+
--c-panel-overlay: rgba(242, 231, 213, 0.88);
|
|
250
|
+
--c-panel-glass: rgba(235, 220, 194, 0.88);
|
|
251
|
+
--c-shadow: rgba(46, 36, 22, 0.08);
|
|
252
|
+
--c-shadow-heavy: rgba(46, 36, 22, 0.16);
|
|
253
|
+
--c-glow-accent: rgba(180, 99, 44, 0.12);
|
|
254
|
+
--c-surface-hover: rgba(46, 36, 22, 0.06);
|
|
255
|
+
--c-surface-subtle: rgba(46, 36, 22, 0.03);
|
|
256
|
+
--c-surface-th: rgba(46, 36, 22, 0.04);
|
|
257
|
+
--c-accent-8: rgba(180, 99, 44, 0.08);
|
|
258
|
+
--c-accent-10: rgba(180, 99, 44, 0.1);
|
|
259
|
+
--c-accent-12: rgba(180, 99, 44, 0.12);
|
|
260
|
+
--c-accent-15: rgba(180, 99, 44, 0.15);
|
|
261
|
+
--c-accent-25: rgba(180, 99, 44, 0.25);
|
|
262
|
+
--c-accent-30: rgba(180, 99, 44, 0.3);
|
|
263
|
+
--c-accent-40: rgba(180, 99, 44, 0.4);
|
|
264
|
+
--c-ok-10: rgba(62, 125, 79, 0.1);
|
|
265
|
+
--c-ok-12: rgba(62, 125, 79, 0.12);
|
|
266
|
+
--c-ok-20: rgba(62, 125, 79, 0.2);
|
|
267
|
+
--c-ok-25: rgba(62, 125, 79, 0.25);
|
|
268
|
+
--c-warn-10: rgba(169, 123, 30, 0.1);
|
|
269
|
+
--c-warn-12: rgba(169, 123, 30, 0.12);
|
|
270
|
+
--c-warn-15: rgba(169, 123, 30, 0.15);
|
|
271
|
+
--c-warn-20: rgba(169, 123, 30, 0.2);
|
|
272
|
+
--c-warn-22: rgba(169, 123, 30, 0.22);
|
|
273
|
+
--c-warn-30: rgba(169, 123, 30, 0.3);
|
|
274
|
+
--c-warn-60: rgba(169, 123, 30, 0.6);
|
|
275
|
+
--c-danger-12: rgba(179, 64, 46, 0.12);
|
|
276
|
+
--c-line-30: rgba(211, 193, 160, 0.5);
|
|
277
|
+
--c-contrast-fg: #F2E7D5;
|
|
278
|
+
--c-accent-hover: #C4763F;
|
|
279
|
+
--c-warn-hover: #BD9037;
|
|
280
|
+
--c-canvas-wash: linear-gradient(180deg, rgba(255, 255, 255, 0.12), rgba(46, 36, 22, 0.02));
|
|
281
|
+
--c-annotation: #2E2416;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
:root[data-theme="arctic"] {
|
|
285
|
+
/* ── Core palette (arctic · cool slate + ice) ────────────── */
|
|
286
|
+
--c-bg: #20242E;
|
|
287
|
+
--c-panel: #2A2F3C;
|
|
288
|
+
--c-panel-soft: #242936;
|
|
289
|
+
--c-line: #3A4152;
|
|
290
|
+
--c-text: #E9EDF4;
|
|
291
|
+
--c-text-soft: #CBD3E1;
|
|
292
|
+
--c-muted: #939DB1;
|
|
293
|
+
--c-dim: #667082;
|
|
294
|
+
--c-accent: #7FC8DE;
|
|
295
|
+
--c-ok: #74C596;
|
|
296
|
+
--c-warn: #E8C476;
|
|
297
|
+
--c-warn-alt: #E0A93F;
|
|
298
|
+
--c-danger: #D9707C;
|
|
299
|
+
--c-purple: #B48EAD;
|
|
300
|
+
--c-thinking: #B48EAD;
|
|
301
|
+
--c-subagent: #6FD6C4;
|
|
302
|
+
--c-input-bg: #242936;
|
|
303
|
+
--c-dot-grid: rgba(127, 200, 222, 0.08);
|
|
304
|
+
--c-panel-overlay: rgba(32, 36, 46, 0.6);
|
|
305
|
+
--c-panel-glass: rgba(42, 47, 60, 0.92);
|
|
306
|
+
--c-shadow: rgba(0, 0, 0, 0.3);
|
|
307
|
+
--c-shadow-heavy: rgba(0, 0, 0, 0.5);
|
|
308
|
+
--c-glow-accent: rgba(127, 200, 222, 0.15);
|
|
309
|
+
--c-surface-hover: rgba(255, 255, 255, 0.06);
|
|
310
|
+
--c-surface-subtle: rgba(255, 255, 255, 0.03);
|
|
311
|
+
--c-surface-th: rgba(255, 255, 255, 0.04);
|
|
312
|
+
--c-accent-8: rgba(127, 200, 222, 0.08);
|
|
313
|
+
--c-accent-10: rgba(127, 200, 222, 0.1);
|
|
314
|
+
--c-accent-12: rgba(127, 200, 222, 0.12);
|
|
315
|
+
--c-accent-15: rgba(127, 200, 222, 0.15);
|
|
316
|
+
--c-accent-25: rgba(127, 200, 222, 0.25);
|
|
317
|
+
--c-accent-30: rgba(127, 200, 222, 0.3);
|
|
318
|
+
--c-accent-40: rgba(127, 200, 222, 0.4);
|
|
319
|
+
--c-ok-10: rgba(116, 197, 150, 0.1);
|
|
320
|
+
--c-ok-12: rgba(116, 197, 150, 0.12);
|
|
321
|
+
--c-ok-20: rgba(116, 197, 150, 0.2);
|
|
322
|
+
--c-ok-25: rgba(116, 197, 150, 0.25);
|
|
323
|
+
--c-warn-10: rgba(232, 196, 118, 0.1);
|
|
324
|
+
--c-warn-12: rgba(232, 196, 118, 0.12);
|
|
325
|
+
--c-warn-15: rgba(232, 196, 118, 0.15);
|
|
326
|
+
--c-warn-20: rgba(232, 196, 118, 0.2);
|
|
327
|
+
--c-warn-22: rgba(232, 196, 118, 0.22);
|
|
328
|
+
--c-warn-30: rgba(232, 196, 118, 0.3);
|
|
329
|
+
--c-warn-60: rgba(232, 196, 118, 0.6);
|
|
330
|
+
--c-danger-12: rgba(217, 112, 124, 0.12);
|
|
331
|
+
--c-line-30: rgba(58, 65, 82, 0.3);
|
|
332
|
+
--c-contrast-fg: #20242E;
|
|
333
|
+
--c-accent-hover: #9AD5E7;
|
|
334
|
+
--c-warn-hover: #EDD194;
|
|
335
|
+
--c-canvas-wash: linear-gradient(180deg, rgba(255, 255, 255, 0.02), rgba(0, 0, 0, 0));
|
|
336
|
+
--c-annotation: #ECEFF4;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
:root[data-theme="ember"] {
|
|
340
|
+
/* ── Core palette (ember · charcoal + vivid warm orange) ─── */
|
|
341
|
+
--c-bg: #0E0E11;
|
|
342
|
+
--c-panel: #17181D;
|
|
343
|
+
--c-panel-soft: #121317;
|
|
344
|
+
--c-line: #2A2C34;
|
|
345
|
+
--c-text: #ECEDF0;
|
|
346
|
+
--c-text-soft: #C9CCD4;
|
|
347
|
+
--c-muted: #8E939F;
|
|
348
|
+
--c-dim: #5F646E;
|
|
349
|
+
--c-accent: #FF5C2E;
|
|
350
|
+
--c-ok: #4CC38A;
|
|
351
|
+
--c-warn: #F5B944;
|
|
352
|
+
--c-warn-alt: #FFB300;
|
|
353
|
+
--c-danger: #F0566A;
|
|
354
|
+
--c-purple: #A78BFA;
|
|
355
|
+
--c-thinking: #A78BFA;
|
|
356
|
+
--c-subagent: #38BDF8;
|
|
357
|
+
--c-input-bg: #121317;
|
|
358
|
+
--c-dot-grid: rgba(255, 92, 46, 0.08);
|
|
359
|
+
--c-panel-overlay: rgba(14, 14, 17, 0.6);
|
|
360
|
+
--c-panel-glass: rgba(23, 24, 29, 0.92);
|
|
361
|
+
--c-shadow: rgba(0, 0, 0, 0.3);
|
|
362
|
+
--c-shadow-heavy: rgba(0, 0, 0, 0.5);
|
|
363
|
+
--c-glow-accent: rgba(255, 92, 46, 0.15);
|
|
364
|
+
--c-surface-hover: rgba(255, 255, 255, 0.06);
|
|
365
|
+
--c-surface-subtle: rgba(255, 255, 255, 0.03);
|
|
366
|
+
--c-surface-th: rgba(255, 255, 255, 0.04);
|
|
367
|
+
--c-accent-8: rgba(255, 92, 46, 0.08);
|
|
368
|
+
--c-accent-10: rgba(255, 92, 46, 0.1);
|
|
369
|
+
--c-accent-12: rgba(255, 92, 46, 0.12);
|
|
370
|
+
--c-accent-15: rgba(255, 92, 46, 0.15);
|
|
371
|
+
--c-accent-25: rgba(255, 92, 46, 0.25);
|
|
372
|
+
--c-accent-30: rgba(255, 92, 46, 0.3);
|
|
373
|
+
--c-accent-40: rgba(255, 92, 46, 0.4);
|
|
374
|
+
--c-ok-10: rgba(76, 195, 138, 0.1);
|
|
375
|
+
--c-ok-12: rgba(76, 195, 138, 0.12);
|
|
376
|
+
--c-ok-20: rgba(76, 195, 138, 0.2);
|
|
377
|
+
--c-ok-25: rgba(76, 195, 138, 0.25);
|
|
378
|
+
--c-warn-10: rgba(245, 185, 68, 0.1);
|
|
379
|
+
--c-warn-12: rgba(245, 185, 68, 0.12);
|
|
380
|
+
--c-warn-15: rgba(245, 185, 68, 0.15);
|
|
381
|
+
--c-warn-20: rgba(245, 185, 68, 0.2);
|
|
382
|
+
--c-warn-22: rgba(245, 185, 68, 0.22);
|
|
383
|
+
--c-warn-30: rgba(245, 185, 68, 0.3);
|
|
384
|
+
--c-warn-60: rgba(245, 185, 68, 0.6);
|
|
385
|
+
--c-danger-12: rgba(240, 86, 106, 0.12);
|
|
386
|
+
--c-line-30: rgba(42, 44, 52, 0.3);
|
|
387
|
+
--c-contrast-fg: #0E0E11;
|
|
388
|
+
--c-accent-hover: #FF7A52;
|
|
389
|
+
--c-warn-hover: #F7C868;
|
|
390
|
+
--c-canvas-wash: linear-gradient(180deg, rgba(255, 255, 255, 0.02), rgba(0, 0, 0, 0));
|
|
391
|
+
--c-annotation: #F2F2F4;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
:root[data-theme="forest"] {
|
|
395
|
+
/* ── Core palette (forest · deep green) ──────────────────── */
|
|
396
|
+
--c-bg: #0C1712;
|
|
397
|
+
--c-panel: #14231B;
|
|
398
|
+
--c-panel-soft: #101D16;
|
|
399
|
+
--c-line: #26402F;
|
|
400
|
+
--c-text: #E4EFE7;
|
|
401
|
+
--c-text-soft: #C4D6CA;
|
|
402
|
+
--c-muted: #8BA695;
|
|
403
|
+
--c-dim: #5D7566;
|
|
404
|
+
--c-accent: #5CCF8F;
|
|
405
|
+
--c-ok: #74D99F;
|
|
406
|
+
--c-warn: #E0B84F;
|
|
407
|
+
--c-warn-alt: #D9A421;
|
|
408
|
+
--c-danger: #E57373;
|
|
409
|
+
--c-purple: #A88FE0;
|
|
410
|
+
--c-thinking: #A88FE0;
|
|
411
|
+
--c-subagent: #4FD8CE;
|
|
412
|
+
--c-input-bg: #101D16;
|
|
413
|
+
--c-dot-grid: rgba(92, 207, 143, 0.08);
|
|
414
|
+
--c-panel-overlay: rgba(12, 23, 18, 0.6);
|
|
415
|
+
--c-panel-glass: rgba(20, 35, 27, 0.92);
|
|
416
|
+
--c-shadow: rgba(0, 0, 0, 0.3);
|
|
417
|
+
--c-shadow-heavy: rgba(0, 0, 0, 0.5);
|
|
418
|
+
--c-glow-accent: rgba(92, 207, 143, 0.15);
|
|
419
|
+
--c-surface-hover: rgba(255, 255, 255, 0.06);
|
|
420
|
+
--c-surface-subtle: rgba(255, 255, 255, 0.03);
|
|
421
|
+
--c-surface-th: rgba(255, 255, 255, 0.04);
|
|
422
|
+
--c-accent-8: rgba(92, 207, 143, 0.08);
|
|
423
|
+
--c-accent-10: rgba(92, 207, 143, 0.1);
|
|
424
|
+
--c-accent-12: rgba(92, 207, 143, 0.12);
|
|
425
|
+
--c-accent-15: rgba(92, 207, 143, 0.15);
|
|
426
|
+
--c-accent-25: rgba(92, 207, 143, 0.25);
|
|
427
|
+
--c-accent-30: rgba(92, 207, 143, 0.3);
|
|
428
|
+
--c-accent-40: rgba(92, 207, 143, 0.4);
|
|
429
|
+
--c-ok-10: rgba(116, 217, 159, 0.1);
|
|
430
|
+
--c-ok-12: rgba(116, 217, 159, 0.12);
|
|
431
|
+
--c-ok-20: rgba(116, 217, 159, 0.2);
|
|
432
|
+
--c-ok-25: rgba(116, 217, 159, 0.25);
|
|
433
|
+
--c-warn-10: rgba(224, 184, 79, 0.1);
|
|
434
|
+
--c-warn-12: rgba(224, 184, 79, 0.12);
|
|
435
|
+
--c-warn-15: rgba(224, 184, 79, 0.15);
|
|
436
|
+
--c-warn-20: rgba(224, 184, 79, 0.2);
|
|
437
|
+
--c-warn-22: rgba(224, 184, 79, 0.22);
|
|
438
|
+
--c-warn-30: rgba(224, 184, 79, 0.3);
|
|
439
|
+
--c-warn-60: rgba(224, 184, 79, 0.6);
|
|
440
|
+
--c-danger-12: rgba(229, 115, 115, 0.12);
|
|
441
|
+
--c-line-30: rgba(38, 64, 47, 0.3);
|
|
442
|
+
--c-contrast-fg: #0C1712;
|
|
443
|
+
--c-accent-hover: #7BDAA4;
|
|
444
|
+
--c-warn-hover: #E8C871;
|
|
445
|
+
--c-canvas-wash: linear-gradient(180deg, rgba(255, 255, 255, 0.02), rgba(0, 0, 0, 0));
|
|
446
|
+
--c-annotation: #EDF5EF;
|
|
447
|
+
}
|
|
448
|
+
|
|
174
449
|
* {
|
|
175
450
|
box-sizing: border-box;
|
|
176
451
|
margin: 0;
|
|
@@ -669,6 +944,7 @@ body,
|
|
|
669
944
|
}
|
|
670
945
|
|
|
671
946
|
.toolbar-group {
|
|
947
|
+
position: relative;
|
|
672
948
|
display: flex;
|
|
673
949
|
flex-wrap: wrap;
|
|
674
950
|
align-items: center;
|
|
@@ -681,6 +957,127 @@ body,
|
|
|
681
957
|
display: block;
|
|
682
958
|
}
|
|
683
959
|
|
|
960
|
+
/* ── Toolbar popover menus (theme picker + narrow-screen More menu) ── */
|
|
961
|
+
.toolbar-menu {
|
|
962
|
+
position: absolute;
|
|
963
|
+
top: calc(100% + 8px);
|
|
964
|
+
right: 0;
|
|
965
|
+
z-index: 1200;
|
|
966
|
+
display: flex;
|
|
967
|
+
flex-direction: column;
|
|
968
|
+
gap: 2px;
|
|
969
|
+
min-width: 224px;
|
|
970
|
+
max-height: min(70vh, 560px);
|
|
971
|
+
overflow-y: auto;
|
|
972
|
+
padding: 6px;
|
|
973
|
+
background: var(--c-panel-glass);
|
|
974
|
+
backdrop-filter: blur(12px);
|
|
975
|
+
border: 1px solid var(--c-line);
|
|
976
|
+
border-radius: var(--radius);
|
|
977
|
+
box-shadow: 0 18px 48px var(--c-shadow-heavy);
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
.toolbar-menu-item {
|
|
981
|
+
display: flex;
|
|
982
|
+
align-items: center;
|
|
983
|
+
gap: 10px;
|
|
984
|
+
width: 100%;
|
|
985
|
+
min-height: 40px;
|
|
986
|
+
padding: 8px 12px;
|
|
987
|
+
background: none;
|
|
988
|
+
border: 1px solid transparent;
|
|
989
|
+
border-radius: var(--radius-sm);
|
|
990
|
+
color: var(--c-text-soft);
|
|
991
|
+
font: inherit;
|
|
992
|
+
font-size: 13px;
|
|
993
|
+
text-align: left;
|
|
994
|
+
cursor: pointer;
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
.toolbar-menu-item:hover {
|
|
998
|
+
background: var(--c-surface-hover);
|
|
999
|
+
color: var(--c-text);
|
|
1000
|
+
border-color: var(--c-line);
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
.toolbar-menu-item.active {
|
|
1004
|
+
color: var(--c-accent);
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
.toolbar-menu-item svg {
|
|
1008
|
+
flex-shrink: 0;
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
.toolbar-menu-check {
|
|
1012
|
+
margin-left: auto;
|
|
1013
|
+
color: var(--c-accent);
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
.toolbar-menu-separator {
|
|
1017
|
+
height: 1px;
|
|
1018
|
+
margin: 4px 8px;
|
|
1019
|
+
background: var(--c-line);
|
|
1020
|
+
flex-shrink: 0;
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
.toolbar-menu-heading {
|
|
1024
|
+
padding: 6px 12px 2px;
|
|
1025
|
+
font-size: 10px;
|
|
1026
|
+
letter-spacing: 0.08em;
|
|
1027
|
+
text-transform: uppercase;
|
|
1028
|
+
color: var(--c-dim);
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
.theme-swatch {
|
|
1032
|
+
display: inline-flex;
|
|
1033
|
+
align-items: center;
|
|
1034
|
+
justify-content: center;
|
|
1035
|
+
width: 18px;
|
|
1036
|
+
height: 18px;
|
|
1037
|
+
border: 1px solid var(--c-line);
|
|
1038
|
+
border-radius: 50%;
|
|
1039
|
+
flex-shrink: 0;
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
.theme-swatch-dot {
|
|
1043
|
+
width: 7px;
|
|
1044
|
+
height: 7px;
|
|
1045
|
+
border-radius: 50%;
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
.toolbar-more-glyph {
|
|
1049
|
+
display: block;
|
|
1050
|
+
font-size: 16px;
|
|
1051
|
+
font-weight: 700;
|
|
1052
|
+
line-height: 1;
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
/* Wide screens: the full two-bar toolbar; the More trigger stays hidden. */
|
|
1056
|
+
.toolbar-collapsible {
|
|
1057
|
+
display: contents;
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
.toolbar-more {
|
|
1061
|
+
display: none;
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
/* Narrow screens / embedded panels: ONE compact bar (brand, status, view
|
|
1065
|
+
controls) — every secondary control folds into the More menu instead of
|
|
1066
|
+
wrapping into a second toolbar row. */
|
|
1067
|
+
@media (max-width: 900px) {
|
|
1068
|
+
.toolbar-collapsible {
|
|
1069
|
+
display: none;
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
.toolbar-actions-bar {
|
|
1073
|
+
display: none;
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
.toolbar-more {
|
|
1077
|
+
display: contents;
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
|
|
684
1081
|
@media (max-width: 900px) {
|
|
685
1082
|
.toolbar-tooltip {
|
|
686
1083
|
min-width: 150px;
|