@desplega.ai/agent-swarm 2.7.6 → 2.7.7
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/dist/{acp-adapter-bp91d37f.js → acp-adapter-7b4vk3h5.js} +5 -4
- package/dist/{actions-yj0eeaqh.js → actions-3tt153af.js} +18 -18
- package/dist/{amp-adapter-4pg9h34q.js → amp-adapter-njpts0yr.js} +1 -1
- package/dist/{anthropic-messages-x4q6rfq5.js → anthropic-messages-xey2skwx.js} +7 -7
- package/dist/{app-909e97cr.js → app-nky4378f.js} +3 -3
- package/dist/{assistant-qdyb5fyy.js → assistant-jnb669pa.js} +19 -19
- package/dist/{azure-openai-responses-s1w5n70z.js → azure-openai-responses-26t7j9ra.js} +5 -5
- package/dist/{boot-reembed-fk0s9z18.js → boot-reembed-9mgvaztt.js} +1 -1
- package/dist/{boot-reembed-gs1rzrnh.js → boot-reembed-qs2djdej.js} +1 -1
- package/dist/{boot-scrub-sweep-4qfd4kfx.js → boot-scrub-sweep-yjpdj7s1.js} +3 -3
- package/dist/{boot-seeds-yr00k13d.js → boot-seeds-5cm6ambd.js} +4 -4
- package/dist/{boxd-vdmfssd9.js → boxd-nv507va8.js} +1 -1
- package/dist/{claude-adapter-qta1f1xn.js → claude-adapter-fn287zmm.js} +5 -4
- package/dist/{claude-managed-setup-sc6j4dm0.js → claude-managed-setup-wtdz2mj2.js} +1 -1
- package/dist/{claude-sdk-session-zgrz6yvc.js → claude-sdk-session-x91kqyhm.js} +8288 -8224
- package/dist/{cli-wp9sp1qb.js → cli-08bmz9z9.js} +1 -1
- package/dist/{cli-yy3rhsdw.js → cli-1c6tzt8g.js} +7 -7
- package/dist/{cli-q0k1w5zd.js → cli-35rsp8ye.js} +1 -1
- package/dist/{cli-xnrwazav.js → cli-3fg0bdcv.js} +1 -1
- package/dist/{cli-89knwags.js → cli-5b456bpf.js} +2 -2
- package/dist/{cli-drr5v6av.js → cli-5jnhv72d.js} +1 -1
- package/dist/{cli-dxae2yg7.js → cli-5zx699j9.js} +2 -2
- package/dist/{cli-0at8w34w.js → cli-6g0hb4cp.js} +8 -8
- package/dist/{cli-e3r2neck.js → cli-6pfd54vx.js} +5 -5
- package/dist/{cli-bsn8nhrq.js → cli-6vcp76qk.js} +3 -3
- package/dist/{cli-ekwks2vs.js → cli-72v799xn.js} +1 -1
- package/dist/cli-82j36f2m.js +45 -0
- package/dist/{cli-yx4kfngt.js → cli-8305gbq0.js} +29 -16
- package/dist/{cli-4necwtsv.js → cli-8sckt74b.js} +8 -8
- package/dist/{cli-vvpx3gsx.js → cli-95jzxcp3.js} +1 -1
- package/dist/{cli-hr2e2fft.js → cli-adeegh7d.js} +7 -7
- package/dist/{cli-m48g6p95.js → cli-afkqkrtw.js} +3 -3
- package/dist/{cli-0qatpy8q.js → cli-ayayvfg4.js} +24 -4
- package/dist/{cli-bqt1mptt.js → cli-az48n0nr.js} +4 -4
- package/dist/{cli-zm72anhg.js → cli-bfv7vdg6.js} +9 -9
- package/dist/{cli-hgaazk69.js → cli-caj33vcq.js} +5 -5
- package/dist/{cli-3ypk9vk1.js → cli-cb2a8pna.js} +1 -1
- package/dist/{cli-waqbxg08.js → cli-cppkf404.js} +17 -17
- package/dist/{cli-yn4kxs06.js → cli-ddaanqkd.js} +4 -4
- package/dist/{cli-386tyxxg.js → cli-e0kmphd6.js} +2 -2
- package/dist/{cli-54t00gt8.js → cli-e46hg0xw.js} +1 -1
- package/dist/{cli-jm2vfpfd.js → cli-e5bzrn01.js} +1 -1
- package/dist/{cli-436532ck.js → cli-excnnjg2.js} +165 -153
- package/dist/{cli-71ptav7x.js → cli-ferkkrg9.js} +1 -1
- package/dist/{cli-vpf89f34.js → cli-fmjd0t1y.js} +3 -3
- package/dist/{cli-pd7vagab.js → cli-fyt2g4wd.js} +3 -3
- package/dist/{cli-gdhpcbhf.js → cli-g08zdaec.js} +1 -1
- package/dist/{cli-ehq736cn.js → cli-g7s47cc5.js} +4 -4
- package/dist/{cli-svj5090z.js → cli-gz6q4eve.js} +3 -3
- package/dist/{cli-8snvgs5r.js → cli-je518txm.js} +10 -10
- package/dist/{cli-rmmmrjkd.js → cli-jtjtabxe.js} +1 -1
- package/dist/{cli-611a1294.js → cli-k0wwfqbg.js} +18 -1
- package/dist/{cli-es6va8jk.js → cli-k1nje3v3.js} +38 -43
- package/dist/{cli-p5gp8pcx.js → cli-k8196sh2.js} +6 -6
- package/dist/{cli-nwj0ee2w.js → cli-k899ehvh.js} +2 -2
- package/dist/{cli-decfb6v8.js → cli-m0da8j35.js} +23 -9
- package/dist/{cli-he9wchme.js → cli-mkk9rnzz.js} +4 -4
- package/dist/{cli-nhrvpaj7.js → cli-n6bv12jn.js} +510 -4
- package/dist/{cli-8bc1w0tw.js → cli-nmzhp1b5.js} +14 -12
- package/dist/{cli-0yv5z2pg.js → cli-p82cnnjq.js} +1 -1
- package/dist/{cli-c60vetmm.js → cli-pc6n7fre.js} +1 -1
- package/dist/{cli-xds5f77d.js → cli-pjctyea3.js} +2 -2
- package/dist/{cli-xbbndvjy.js → cli-pq73h5mz.js} +3 -3
- package/dist/{cli-aa6yxc7m.js → cli-pz4rk021.js} +1 -1
- package/dist/{cli-xnqgpshy.js → cli-q3tkegby.js} +1 -1
- package/dist/cli-qghe0h66.js +67 -0
- package/dist/{cli-zbbwez0r.js → cli-qh4d4tvk.js} +4 -4
- package/dist/{cli-w6dt9ged.js → cli-rtt8g4v9.js} +1 -1
- package/dist/{cli-1h3wcpbw.js → cli-snpj5zbj.js} +2 -2
- package/dist/{cli-a7v854rf.js → cli-tgrv9cjx.js} +263 -12
- package/dist/{cli-faxe6thg.js → cli-vz22fyqv.js} +186 -54
- package/dist/{cli-k2gzwsj2.js → cli-wk5yrfwd.js} +160 -26
- package/dist/{cli-shpbx5ee.js → cli-ws19768n.js} +1641 -49
- package/dist/{cli-70r77n04.js → cli-xae4g51r.js} +1 -1
- package/dist/{cli-kqdg1bsb.js → cli-yndmfxb3.js} +2 -2
- package/dist/{cli-bjb3z51z.js → cli-yyj3j5m4.js} +2 -2
- package/dist/cli.js +21 -21
- package/dist/{cloudflare-workers-ai-system-one-bm60fjm0.js → cloudflare-workers-ai-system-one-ef2a980q.js} +2 -2
- package/dist/{codex-adapter-ayd1fb6h.js → codex-adapter-cf2yxe9m.js} +3 -2
- package/dist/{codex-hook-9efm2x1m.js → codex-hook-a0c6g6t6.js} +1 -1
- package/dist/{codex-session-runner-jesa32xc.js → codex-session-runner-6vfzdgbd.js} +3 -2
- package/dist/{commands-hanewgf2.js → commands-t3mfy7vn.js} +3 -3
- package/dist/{controller-dt1n3c1q.js → controller-q7xrbaz0.js} +3 -3
- package/dist/{controllers-connect-xx8x64n5.js → controllers-connect-c6nm70kg.js} +19 -19
- package/dist/{cursor-adapter-9s4dwwdw.js → cursor-adapter-ftd81ga8.js} +1 -1
- package/dist/{db-3vttcbv4.js → db-dk572x25.js} +3 -3
- package/dist/{db-9dv0g1ab.js → db-vemtpmcc.js} +4 -2
- package/dist/{dispatcher-tx9hd1sv.js → dispatcher-kh7ecxh9.js} +17 -17
- package/dist/{dsh-adapter-007y4ejs.js → dsh-adapter-v8628r89.js} +1 -1
- package/dist/{e2b-we6hs6q5.js → e2b-fr12yccx.js} +1 -1
- package/dist/{e2b-a19d28rz.js → e2b-x6ywzak3.js} +1 -1
- package/dist/{easter-egg-3d-rgbrqb8s.js → easter-egg-3d-nenw4x63.js} +1 -1
- package/dist/{embedding-space-ny1e2940.js → embedding-space-0jepb239.js} +6 -6
- package/dist/{embeddings-2t386t13.js → embeddings-xxt49yxg.js} +1 -1
- package/dist/{execute-pksh0ceh.js → execute-1mhw6e4x.js} +1 -1
- package/dist/{external-channel-phgmhmd7.js → external-channel-55v12e60.js} +2 -2
- package/dist/{fx-adapter-fy8rr921.js → fx-adapter-bs8wqrk5.js} +6 -5
- package/dist/{google-generative-ai-8y3m3k4b.js → google-generative-ai-v94hr7h0.js} +5 -5
- package/dist/{google-vertex-w3v98n7b.js → google-vertex-g7vr6cf8.js} +5 -5
- package/dist/{grok-adapter-q0abvpaj.js → grok-adapter-gpjqmkcq.js} +6 -5
- package/dist/handlers-zxmp1ta4.js +32 -0
- package/dist/{heartbeat-kadyek8p.js → heartbeat-k42svnr0.js} +20 -20
- package/dist/{hook-9k551xnj.js → hook-114m7hap.js} +4 -3
- package/dist/{hook-5zs3msf6.js → hook-6nphweh0.js} +24 -9
- package/dist/{http-mhz9vw1f.js → http-r8cc4wz7.js} +1025 -173
- package/dist/index-a8phxqnk.js +37 -0
- package/dist/{index-vdygbq10.js → index-e3s8wmxy.js} +1 -1
- package/dist/{index-q361cg2f.js → index-fpk4bcd9.js} +1 -1
- package/dist/index-k6h00t4c.js +30 -0
- package/dist/{index-rvr00sg7.js → index-nh3wyqdt.js} +1017 -574
- package/dist/index-xrz7te8h.js +33 -0
- package/dist/{keepalive-w56f32cg.js → keepalive-x060nt9p.js} +3 -3
- package/dist/lead-956sd2yc.js +71 -0
- package/dist/{maintenance-7mdgxcea.js → maintenance-2xxfexhf.js} +1 -1
- package/dist/{mistral-conversations-4pmwj1c0.js → mistral-conversations-3gjpdb4b.js} +4 -4
- package/dist/{oauth-refresh-sweep-29txy9vk.js → oauth-refresh-sweep-fckc4ar5.js} +2 -2
- package/dist/{onboard-kpsrkarj.js → onboard-zc48j237.js} +3 -3
- package/dist/{openai-codex-responses-44j573nm.js → openai-codex-responses-8pbxq9h5.js} +5 -5
- package/dist/{openai-completions-a4gee2a8.js → openai-completions-rm00s912.js} +4 -4
- package/dist/{openai-decisions-w4qkrcar.js → openai-decisions-8v957r2r.js} +1 -1
- package/dist/{openai-responses-rbp6h5kr.js → openai-responses-agxpf96k.js} +5 -5
- package/dist/{opencode-adapter-j25vm3rr.js → opencode-adapter-r690h1cr.js} +4 -3
- package/dist/{otel-impl-6kkct7a8.js → otel-impl-r5xbh81q.js} +4 -4
- package/dist/{pi-mono-adapter-exhkzhn2.js → pi-mono-adapter-c7v8sdec.js} +7 -6
- package/dist/{pricing-refresh-n2x7jh6k.js → pricing-refresh-3pmre11v.js} +3 -3
- package/dist/{rbac-roles-81ypx6es.js → rbac-roles-3vbshwsb.js} +1 -1
- package/dist/{rbac-roles-b5htkjby.js → rbac-roles-910mmkgz.js} +2 -2
- package/dist/{render-v2-qn6jmpk4.js → render-v2-pxykkbab.js} +3 -3
- package/dist/{resume-wd30wx23.js → resume-adda0bwy.js} +6 -6
- package/dist/{runtime-4hsg7h60.js → runtime-fnbm7stk.js} +1 -1
- package/dist/{session-access-5qvfevhk.js → session-access-2fvamrdc.js} +4 -4
- package/dist/{session-source-backfill-n1czavbr.js → session-source-backfill-08xvv0sm.js} +2 -2
- package/dist/{setup-dnb56qy5.js → setup-1aqmvmh1.js} +1 -1
- package/dist/{typesafe-system-one-5mavm259.js → typesafe-system-one-0bmqcxfg.js} +2 -2
- package/dist/{virtual-modules-76xxv9fs.js → virtual-modules-d2pjk9j1.js} +5 -5
- package/dist/{work-objects-4n21tfkm.js → work-objects-9s0yrm5j.js} +20 -20
- package/dist/{worker-follow-up-77hvzxww.js → worker-follow-up-3q78fqmr.js} +17 -17
- package/dist/worker-y15hy08h.js +71 -0
- package/openapi.json +197 -4
- package/package.json +5 -5
- package/src/apps/definition.ts +6 -5
- package/src/be/db/page-theme-tokens.ts +12 -0
- package/src/be/db/tasks/read.ts +9 -1
- package/src/be/db/tasks/write.ts +19 -0
- package/src/be/db-client.ts +107 -7
- package/src/be/db.ts +34 -2
- package/src/be/migrations/269_pages_design_system.sql +23 -0
- package/src/be/seed/schedules-seeder.ts +0 -10
- package/src/be/seed-scripts/catalog/catalog-report.inline.ts +2 -0
- package/src/be/seed-scripts/catalog/catalog-report.ts +2 -0
- package/src/be/seed-scripts/catalog/memory-eval.ts +2 -0
- package/src/be/seed-scripts/catalog/swarm-update-check.ts +150 -0
- package/src/be/seed-scripts/index.ts +9 -0
- package/src/be/seed-skills/bundled-files.generated.json +3 -3
- package/src/be/swarm-config-guard.ts +32 -0
- package/src/be/task-auto-title-listener.ts +127 -0
- package/src/commands/onboard/agent-fs-version.ts +1 -1
- package/src/commands/profile-sync.ts +151 -16
- package/src/commands/runner.ts +15 -7
- package/src/hooks/hook.ts +20 -9
- package/src/http/index.ts +3 -0
- package/src/http/pages-public.ts +93 -129
- package/src/http/pages.ts +94 -21
- package/src/pages/browser-sdk.ts +48 -21
- package/src/pages/color-literals.ts +115 -0
- package/src/pages/page-head.ts +766 -0
- package/src/pages/version.ts +3 -0
- package/src/providers/amp-adapter.ts +1 -1
- package/src/providers/codex-adapter.ts +1 -0
- package/src/providers/codex-app-server.ts +27 -1
- package/src/providers/pi-mono-extension.ts +30 -15
- package/src/tasks/follow-up-gate.ts +318 -0
- package/src/tasks/worker-follow-up.ts +21 -1
- package/src/tests/codex-app-server.test.ts +59 -0
- package/src/tests/codex-gateway-route.test.ts +50 -1
- package/src/tests/create-page-tool.test.ts +501 -0
- package/src/tests/db-client-busy-retry.test.ts +81 -0
- package/src/tests/db-task-read-contract.test.ts +1 -0
- package/src/tests/db-task-write-contract.test.ts +2 -0
- package/src/tests/db-tasks-read.test.ts +21 -0
- package/src/tests/fixtures/pages/head-v1.html +56 -0
- package/src/tests/follow-up-gate-shadow.test.ts +513 -0
- package/src/tests/identity-field-budget.test.ts +1 -1
- package/src/tests/internal-ai/credentials.test.ts +62 -0
- package/src/tests/internal-ai/task-title.test.ts +283 -0
- package/src/tests/merge-gate-detect-changes.test.ts +145 -0
- package/src/tests/page-proxy.test.ts +1 -1
- package/src/tests/page-session-dev-cookie.test.ts +188 -0
- package/src/tests/pages-frame-ancestors.test.ts +28 -1
- package/src/tests/pages-head-v2.test.ts +534 -0
- package/src/tests/pages-http.test.ts +330 -0
- package/src/tests/pages-public-html.test.ts +43 -0
- package/src/tests/pages-storage.test.ts +182 -0
- package/src/tests/pages-versioning.test.ts +72 -0
- package/src/tests/profile-sync-stale-writeback.test.ts +334 -0
- package/src/tests/profile-sync.test.ts +11 -15
- package/src/tests/scheduled-task-required-params-migration.test.ts +3 -1
- package/src/tests/script-connections.test.ts +2 -0
- package/src/tests/seed-registry.test.ts +28 -6
- package/src/tests/seed-schedules.test.ts +61 -8
- package/src/tests/seed-scripts.test.ts +142 -2
- package/src/tests/swarm-diff.test.ts +121 -2
- package/src/tests/task-auto-title-config-guard.test.ts +37 -0
- package/src/tests/task-auto-title-listener.test.ts +165 -0
- package/src/tests/theme-import.test.ts +758 -0
- package/src/tests/themes-page-theme.test.ts +155 -0
- package/src/tests/themes-presets.test.ts +172 -0
- package/src/tests/workflow-script-principal.test.ts +2 -1
- package/src/themes/classics.ts +949 -0
- package/src/themes/import.ts +420 -0
- package/src/themes/page-fields.ts +40 -0
- package/src/themes/page-theme.ts +102 -0
- package/src/themes/presets.ts +561 -0
- package/src/themes/tokens.ts +218 -0
- package/src/tools/app-upsert.ts +1 -1
- package/src/tools/create-page.ts +118 -12
- package/src/tools/utils.ts +33 -0
- package/src/types.ts +45 -3
- package/src/utils/constants.ts +19 -0
- package/src/utils/follow-up-gate-schedule-ids.ts +13 -0
- package/src/utils/internal-ai/credentials.ts +146 -93
- package/src/utils/internal-ai/index.ts +10 -0
- package/src/utils/internal-ai/models.ts +18 -0
- package/src/utils/internal-ai/task-title.ts +282 -0
- package/src/utils/page-session.ts +37 -0
- package/templates/schedules/daily-status-report/content.md +88 -2
- package/templates/schedules/daily-swarm-update-check/content.md +16 -40
- package/templates/skills/apps/SKILL.md +1 -1
- package/templates/skills/apps/content.md +1 -1
- package/templates/skills/heartbeat-runbook/content.md +1 -1
- package/templates/skills/pages/config.json +1 -1
- package/templates/skills/pages/content.md +539 -86
- package/templates/skills/pages/files/examples/annotated-pr.html +21 -12
- package/templates/skills/pages/files/examples/multiplayer-board.html +41 -41
- package/templates/skills/pages/files/examples/report-page.html +125 -124
- package/dist/cli-2pnswgh8.js +0 -189
- package/dist/handlers-by3sfxyx.js +0 -32
- package/dist/index-4f2pvxae.js +0 -37
- package/dist/index-98gz7tmp.js +0 -30
- package/dist/index-k08z2cak.js +0 -33
- package/dist/lead-enq35nqp.js +0 -70
- package/dist/worker-gg1576j3.js +0 -70
- package/templates/schedules/daily-workflow-health-audit/config.json +0 -19
- package/templates/schedules/daily-workflow-health-audit/content.md +0 -191
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme presets: the parametric layer on top of the token system.
|
|
3
|
+
*
|
|
4
|
+
* Every color in the dashboard resolves through the CSS custom properties
|
|
5
|
+
* declared in `apps/ui/src/styles/globals.css` (`--color-primary`,
|
|
6
|
+
* `--color-background`, ...). A preset is nothing but a curated bundle of
|
|
7
|
+
* overrides for a SUBSET of those properties, emitted as `[data-theme="<id>"]`
|
|
8
|
+
* rules, so a theme can be applied at ANY scope: on `<html>` (the whole
|
|
9
|
+
* dashboard, via the Appearance settings) or on a wrapper element (one
|
|
10
|
+
* swarm-app's canvas, via `definition.theme` / the viewer's `$theme` override).
|
|
11
|
+
*
|
|
12
|
+
* Deliberate constraints:
|
|
13
|
+
* - `hive` (the Mission Control identity from DESIGN.md) is the base: its
|
|
14
|
+
* values ARE the globals.css defaults. An app inherits the dashboard theme
|
|
15
|
+
* by carrying NO `data-theme` attribute; `data-theme="hive"` is an explicit
|
|
16
|
+
* reset back to the stock look (meaningful inside a themed dashboard).
|
|
17
|
+
* - Every emitted preset block is SELF-CONTAINED: the builder spreads the
|
|
18
|
+
* stock base values (`BASE_SCOPE_VARS`) under each preset's own overrides,
|
|
19
|
+
* so a scoped preset fully resets the canvas instead of blending with
|
|
20
|
+
* whatever full-field preset the surrounding dashboard runs (an accent
|
|
21
|
+
* preset under an Ember dashboard must deliver its promised zinc field,
|
|
22
|
+
* and a classic dashboard's status palette must not leak into an app).
|
|
23
|
+
* - Action (`--color-action-*`) and destructive tokens are NEVER themed.
|
|
24
|
+
* Status (`--color-status-*`) is themed ONLY by the classic-theme presets
|
|
25
|
+
* (classics.ts) whose identity includes a status palette; hue
|
|
26
|
+
* SEMANTICS stay fixed everywhere (success=green, error=red, …) so a failed
|
|
27
|
+
* task chip reads as "failed" under every preset.
|
|
28
|
+
* - Light and dark values are both declared per preset; the global `.dark`
|
|
29
|
+
* class keeps choosing the mode, so scoped themes follow the mode switch
|
|
30
|
+
* for free.
|
|
31
|
+
*
|
|
32
|
+
* Selector shape (specificity matters):
|
|
33
|
+
* - light: `html[data-theme="x"], [data-theme="x"]`. The `html`-qualified
|
|
34
|
+
* form (0,1,1) outranks the base `.dark` block (0,1,0) by column, so rule
|
|
35
|
+
* order against the compiled stylesheet is irrelevant; the bare attribute
|
|
36
|
+
* form covers scoped wrappers.
|
|
37
|
+
* - dark: `html.dark[data-theme="x"], .dark [data-theme="x"]`. (0,2,1)/(0,2,0)
|
|
38
|
+
* outranks every light form above.
|
|
39
|
+
* This only works because `globals.css` scopes dark overrides to `.dark`
|
|
40
|
+
* itself (inheritance), NOT `.dark *` (per-element stamping). Do not
|
|
41
|
+
* reintroduce the descendant form there.
|
|
42
|
+
*
|
|
43
|
+
* This module is pure (no DOM), so the API server and the dashboard share it.
|
|
44
|
+
* The dashboard re-exports it from `apps/ui/src/lib/themes.ts` and adds the
|
|
45
|
+
* `<head>` injection there. HTML pages read the same presets, contract keys
|
|
46
|
+
* only, through `page-theme.ts`.
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
import { CLASSIC_THEME_PRESETS } from "./classics";
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Stock (Hive) values for every custom property that ANY preset overrides,
|
|
53
|
+
* copied from the `@theme` / `.dark` blocks in `apps/ui/src/styles/globals.css`
|
|
54
|
+
* (keep in sync when a base token there changes; `themes-presets.test.ts`
|
|
55
|
+
* fails on drift). Spread under each preset's own overrides at emit time so
|
|
56
|
+
* every `[data-theme]` block is self-contained: tokens a preset doesn't
|
|
57
|
+
* override reset to stock instead of inheriting the surrounding dashboard
|
|
58
|
+
* preset. Tokens NO preset touches (destructive, action-*, chart-2…5) are
|
|
59
|
+
* deliberately absent: inheriting those is always inheriting the base.
|
|
60
|
+
*/
|
|
61
|
+
export const BASE_SCOPE_VARS: { light: Record<string, string>; dark: Record<string, string> } = {
|
|
62
|
+
light: {
|
|
63
|
+
"--color-background": "oklch(1 0 0)",
|
|
64
|
+
"--color-foreground": "oklch(0.141 0.005 285.823)",
|
|
65
|
+
"--color-card": "oklch(1 0 0)",
|
|
66
|
+
"--color-card-foreground": "oklch(0.141 0.005 285.823)",
|
|
67
|
+
"--color-surface": "oklch(0.985 0.0015 286)",
|
|
68
|
+
"--color-popover": "oklch(1 0 0)",
|
|
69
|
+
"--color-popover-foreground": "oklch(0.141 0.005 285.823)",
|
|
70
|
+
"--color-primary": "oklch(0.555 0.163 48.998)",
|
|
71
|
+
"--color-primary-foreground": "oklch(0.985 0 0)",
|
|
72
|
+
"--color-secondary": "oklch(0.967 0.001 286.375)",
|
|
73
|
+
"--color-secondary-foreground": "oklch(0.21 0.006 285.885)",
|
|
74
|
+
"--color-muted": "oklch(0.967 0.001 286.375)",
|
|
75
|
+
"--color-muted-foreground": "oklch(0.552 0.016 285.938)",
|
|
76
|
+
"--color-accent": "oklch(0.943 0.003 286.375)",
|
|
77
|
+
"--color-accent-foreground": "oklch(0.21 0.006 285.885)",
|
|
78
|
+
"--color-border": "oklch(0.92 0.004 286.32)",
|
|
79
|
+
"--color-border-subtle": "oklch(0.945 0.003 286)",
|
|
80
|
+
"--color-input": "oklch(0.92 0.004 286.32)",
|
|
81
|
+
"--color-ring": "oklch(0.555 0.163 48.998)",
|
|
82
|
+
"--color-chart-1": "oklch(0.646 0.222 41.116)",
|
|
83
|
+
"--color-sidebar": "oklch(0.985 0 0)",
|
|
84
|
+
"--color-sidebar-foreground": "oklch(0.141 0.005 285.823)",
|
|
85
|
+
"--color-sidebar-primary": "oklch(0.555 0.163 48.998)",
|
|
86
|
+
"--color-sidebar-primary-foreground": "oklch(0.985 0 0)",
|
|
87
|
+
"--color-sidebar-accent": "oklch(0.943 0.003 286.375)",
|
|
88
|
+
"--color-sidebar-accent-foreground": "oklch(0.21 0.006 285.885)",
|
|
89
|
+
"--color-sidebar-border": "oklch(0.945 0.003 286)",
|
|
90
|
+
"--color-sidebar-ring": "oklch(0.555 0.163 48.998)",
|
|
91
|
+
"--color-status-success": "oklch(0.74 0.1 163)",
|
|
92
|
+
"--color-status-success-strong": "oklch(0.5 0.09 163)",
|
|
93
|
+
"--color-status-success-foreground": "oklch(0.21 0.006 285.885)",
|
|
94
|
+
"--color-status-active": "oklch(0.81 0.11 75)",
|
|
95
|
+
"--color-status-active-strong": "oklch(0.55 0.1 68)",
|
|
96
|
+
"--color-status-active-foreground": "oklch(0.21 0.006 285.885)",
|
|
97
|
+
"--color-status-error": "oklch(0.72 0.12 25)",
|
|
98
|
+
"--color-status-error-strong": "oklch(0.51 0.14 25)",
|
|
99
|
+
"--color-status-error-foreground": "oklch(0.21 0.006 285.885)",
|
|
100
|
+
"--color-status-info": "oklch(0.74 0.09 235)",
|
|
101
|
+
"--color-status-info-strong": "oklch(0.5 0.09 240)",
|
|
102
|
+
"--color-status-info-foreground": "oklch(0.21 0.006 285.885)",
|
|
103
|
+
"--color-status-pending": "oklch(0.84 0.1 95)",
|
|
104
|
+
"--color-status-pending-strong": "oklch(0.55 0.09 90)",
|
|
105
|
+
"--color-status-pending-foreground": "oklch(0.21 0.006 285.885)",
|
|
106
|
+
"--color-status-warning": "oklch(0.76 0.11 55)",
|
|
107
|
+
"--color-status-warning-strong": "oklch(0.53 0.11 50)",
|
|
108
|
+
"--color-status-warning-foreground": "oklch(0.21 0.006 285.885)",
|
|
109
|
+
"--color-status-paused": "oklch(0.71 0.1 262)",
|
|
110
|
+
"--color-status-paused-strong": "oklch(0.5 0.1 262)",
|
|
111
|
+
"--color-status-paused-foreground": "oklch(0.21 0.006 285.885)",
|
|
112
|
+
"--color-status-neutral": "oklch(0.62 0.014 286)",
|
|
113
|
+
"--color-status-neutral-strong": "oklch(0.48 0.014 286)",
|
|
114
|
+
"--color-status-neutral-foreground": "oklch(0.21 0.006 285.885)",
|
|
115
|
+
},
|
|
116
|
+
dark: {
|
|
117
|
+
"--color-background": "oklch(0.141 0.005 285.823)",
|
|
118
|
+
"--color-foreground": "oklch(0.985 0 0)",
|
|
119
|
+
"--color-card": "oklch(0.21 0.006 285.885)",
|
|
120
|
+
"--color-card-foreground": "oklch(0.985 0 0)",
|
|
121
|
+
"--color-surface": "oklch(0.185 0.006 286)",
|
|
122
|
+
"--color-popover": "oklch(0.21 0.006 285.885)",
|
|
123
|
+
"--color-popover-foreground": "oklch(0.985 0 0)",
|
|
124
|
+
"--color-primary": "oklch(0.769 0.188 70.08)",
|
|
125
|
+
"--color-primary-foreground": "oklch(0.21 0.006 285.885)",
|
|
126
|
+
"--color-secondary": "oklch(0.274 0.006 286.033)",
|
|
127
|
+
"--color-secondary-foreground": "oklch(0.985 0 0)",
|
|
128
|
+
"--color-muted": "oklch(0.274 0.006 286.033)",
|
|
129
|
+
"--color-muted-foreground": "oklch(0.705 0.015 286.067)",
|
|
130
|
+
"--color-accent": "oklch(0.274 0.006 286.033)",
|
|
131
|
+
"--color-accent-foreground": "oklch(0.985 0 0)",
|
|
132
|
+
"--color-border": "oklch(1 0 0 / 10%)",
|
|
133
|
+
"--color-border-subtle": "oklch(1 0 0 / 8%)",
|
|
134
|
+
"--color-input": "oklch(1 0 0 / 15%)",
|
|
135
|
+
"--color-ring": "oklch(0.769 0.188 70.08)",
|
|
136
|
+
"--color-chart-1": "oklch(0.488 0.243 264.376)",
|
|
137
|
+
"--color-sidebar": "oklch(0.21 0.006 285.885)",
|
|
138
|
+
"--color-sidebar-foreground": "oklch(0.985 0 0)",
|
|
139
|
+
"--color-sidebar-primary": "oklch(0.769 0.188 70.08)",
|
|
140
|
+
"--color-sidebar-primary-foreground": "oklch(0.985 0 0)",
|
|
141
|
+
"--color-sidebar-accent": "oklch(0.274 0.006 286.033)",
|
|
142
|
+
"--color-sidebar-accent-foreground": "oklch(0.985 0 0)",
|
|
143
|
+
"--color-sidebar-border": "oklch(1 0 0 / 8%)",
|
|
144
|
+
"--color-sidebar-ring": "oklch(0.769 0.188 70.08)",
|
|
145
|
+
"--color-status-success": "oklch(0.78 0.1 163)",
|
|
146
|
+
"--color-status-success-strong": "oklch(0.78 0.1 163)",
|
|
147
|
+
"--color-status-success-foreground": "oklch(0.21 0.006 285.885)",
|
|
148
|
+
"--color-status-active": "oklch(0.84 0.1 80)",
|
|
149
|
+
"--color-status-active-strong": "oklch(0.84 0.1 80)",
|
|
150
|
+
"--color-status-active-foreground": "oklch(0.21 0.006 285.885)",
|
|
151
|
+
"--color-status-error": "oklch(0.74 0.11 22)",
|
|
152
|
+
"--color-status-error-strong": "oklch(0.74 0.11 22)",
|
|
153
|
+
"--color-status-error-foreground": "oklch(0.21 0.006 285.885)",
|
|
154
|
+
"--color-status-info": "oklch(0.78 0.09 235)",
|
|
155
|
+
"--color-status-info-strong": "oklch(0.78 0.09 235)",
|
|
156
|
+
"--color-status-info-foreground": "oklch(0.21 0.006 285.885)",
|
|
157
|
+
"--color-status-pending": "oklch(0.86 0.09 95)",
|
|
158
|
+
"--color-status-pending-strong": "oklch(0.86 0.09 95)",
|
|
159
|
+
"--color-status-pending-foreground": "oklch(0.21 0.006 285.885)",
|
|
160
|
+
"--color-status-warning": "oklch(0.79 0.1 55)",
|
|
161
|
+
"--color-status-warning-strong": "oklch(0.79 0.1 55)",
|
|
162
|
+
"--color-status-warning-foreground": "oklch(0.21 0.006 285.885)",
|
|
163
|
+
"--color-status-paused": "oklch(0.74 0.09 260)",
|
|
164
|
+
"--color-status-paused-strong": "oklch(0.74 0.09 260)",
|
|
165
|
+
"--color-status-paused-foreground": "oklch(0.21 0.006 285.885)",
|
|
166
|
+
"--color-status-neutral": "oklch(0.72 0.012 286)",
|
|
167
|
+
"--color-status-neutral-strong": "oklch(0.72 0.012 286)",
|
|
168
|
+
"--color-status-neutral-foreground": "oklch(0.21 0.006 285.885)",
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
export interface ThemePreset {
|
|
173
|
+
id: string;
|
|
174
|
+
name: string;
|
|
175
|
+
description: string;
|
|
176
|
+
/** Representative accent per mode, picker swatches only, never rendering. */
|
|
177
|
+
accent: { light: string; dark: string };
|
|
178
|
+
/** Representative field (background) per mode, picker swatches only. */
|
|
179
|
+
field: { light: string; dark: string };
|
|
180
|
+
/**
|
|
181
|
+
* CSS custom-property overrides, keyed by full var name.
|
|
182
|
+
*
|
|
183
|
+
* INVARIANT: every key set in `light` must also be set in `dark`. The light
|
|
184
|
+
* rule is not mode-guarded (it matches in dark mode too and only loses to
|
|
185
|
+
* the higher-specificity dark rule), so a key missing from `dark` leaks its
|
|
186
|
+
* LIGHT value into dark mode. (Dark-only keys are fine: in light mode the
|
|
187
|
+
* base token simply applies.)
|
|
188
|
+
*/
|
|
189
|
+
vars: { light: Record<string, string>; dark: Record<string, string> };
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export const DEFAULT_THEME_ID = "hive";
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Accent-swap preset: keeps the zinc field and replaces the one voice of
|
|
196
|
+
* color (primary / ring / sidebar accent / lead chart series).
|
|
197
|
+
*/
|
|
198
|
+
function accentPreset(
|
|
199
|
+
id: string,
|
|
200
|
+
name: string,
|
|
201
|
+
description: string,
|
|
202
|
+
light: { primary: string; primaryForeground: string },
|
|
203
|
+
dark: { primary: string; primaryForeground: string },
|
|
204
|
+
): ThemePreset {
|
|
205
|
+
return {
|
|
206
|
+
id,
|
|
207
|
+
name,
|
|
208
|
+
description,
|
|
209
|
+
accent: { light: light.primary, dark: dark.primary },
|
|
210
|
+
field: { light: "oklch(1 0 0)", dark: "oklch(0.141 0.005 285.823)" },
|
|
211
|
+
vars: {
|
|
212
|
+
light: {
|
|
213
|
+
"--color-primary": light.primary,
|
|
214
|
+
"--color-primary-foreground": light.primaryForeground,
|
|
215
|
+
"--color-ring": light.primary,
|
|
216
|
+
"--color-sidebar-primary": light.primary,
|
|
217
|
+
"--color-sidebar-primary-foreground": light.primaryForeground,
|
|
218
|
+
"--color-sidebar-ring": light.primary,
|
|
219
|
+
"--color-chart-1": light.primary,
|
|
220
|
+
},
|
|
221
|
+
dark: {
|
|
222
|
+
"--color-primary": dark.primary,
|
|
223
|
+
"--color-primary-foreground": dark.primaryForeground,
|
|
224
|
+
"--color-ring": dark.primary,
|
|
225
|
+
"--color-sidebar-primary": dark.primary,
|
|
226
|
+
"--color-sidebar-primary-foreground": dark.primaryForeground,
|
|
227
|
+
"--color-sidebar-ring": dark.primary,
|
|
228
|
+
"--color-chart-1": dark.primary,
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const NEAR_WHITE = "oklch(0.985 0 0)";
|
|
235
|
+
const ZINC_900 = "oklch(0.21 0.006 285.885)";
|
|
236
|
+
|
|
237
|
+
export const THEME_PRESETS: ThemePreset[] = [
|
|
238
|
+
{
|
|
239
|
+
id: DEFAULT_THEME_ID,
|
|
240
|
+
name: "Hive",
|
|
241
|
+
description: "The stock Mission Control look: zinc field, one amber voice.",
|
|
242
|
+
accent: { light: "oklch(0.555 0.163 48.998)", dark: "oklch(0.769 0.188 70.08)" },
|
|
243
|
+
field: { light: "oklch(1 0 0)", dark: "oklch(0.141 0.005 285.823)" },
|
|
244
|
+
// The base theme IS globals.css: no overrides of its own. The builder
|
|
245
|
+
// still emits a `[data-theme="hive"]` block (the BASE_SCOPE_VARS spread)
|
|
246
|
+
// so an explicit Hive selection resets a canvas inside a themed
|
|
247
|
+
// dashboard; "inherit the surrounding theme" is the ABSENCE of the
|
|
248
|
+
// attribute, not this preset.
|
|
249
|
+
vars: { light: {}, dark: {} },
|
|
250
|
+
},
|
|
251
|
+
accentPreset(
|
|
252
|
+
"meadow",
|
|
253
|
+
"Meadow",
|
|
254
|
+
"Zinc field with an emerald voice.",
|
|
255
|
+
{ primary: "oklch(0.596 0.145 163.225)", primaryForeground: NEAR_WHITE },
|
|
256
|
+
{ primary: "oklch(0.765 0.177 163.223)", primaryForeground: ZINC_900 },
|
|
257
|
+
),
|
|
258
|
+
accentPreset(
|
|
259
|
+
"iris",
|
|
260
|
+
"Iris",
|
|
261
|
+
"Zinc field with a violet voice.",
|
|
262
|
+
{ primary: "oklch(0.541 0.281 293.009)", primaryForeground: NEAR_WHITE },
|
|
263
|
+
{ primary: "oklch(0.702 0.183 293.541)", primaryForeground: ZINC_900 },
|
|
264
|
+
),
|
|
265
|
+
accentPreset(
|
|
266
|
+
"rose",
|
|
267
|
+
"Rose",
|
|
268
|
+
"Zinc field with a deep rose voice.",
|
|
269
|
+
{ primary: "oklch(0.586 0.253 17.585)", primaryForeground: NEAR_WHITE },
|
|
270
|
+
{ primary: "oklch(0.712 0.194 13.428)", primaryForeground: ZINC_900 },
|
|
271
|
+
),
|
|
272
|
+
{
|
|
273
|
+
id: "cobalt",
|
|
274
|
+
name: "Cobalt",
|
|
275
|
+
description: "Cool slate field with a saturated blue voice.",
|
|
276
|
+
accent: { light: "oklch(0.546 0.245 262.881)", dark: "oklch(0.707 0.165 254.624)" },
|
|
277
|
+
field: { light: "oklch(1 0 0)", dark: "oklch(0.129 0.042 264.695)" },
|
|
278
|
+
vars: {
|
|
279
|
+
light: {
|
|
280
|
+
"--color-foreground": "oklch(0.129 0.042 264.695)",
|
|
281
|
+
"--color-card-foreground": "oklch(0.129 0.042 264.695)",
|
|
282
|
+
"--color-popover-foreground": "oklch(0.129 0.042 264.695)",
|
|
283
|
+
"--color-surface": "oklch(0.984 0.003 247.858)",
|
|
284
|
+
"--color-primary": "oklch(0.546 0.245 262.881)",
|
|
285
|
+
"--color-primary-foreground": NEAR_WHITE,
|
|
286
|
+
"--color-secondary": "oklch(0.968 0.007 247.896)",
|
|
287
|
+
"--color-secondary-foreground": "oklch(0.208 0.042 265.755)",
|
|
288
|
+
"--color-muted": "oklch(0.968 0.007 247.896)",
|
|
289
|
+
"--color-muted-foreground": "oklch(0.554 0.046 257.417)",
|
|
290
|
+
// Hover/highlight fill one step below muted (slate-100 → ~slate-150)
|
|
291
|
+
// so light-mode hovers read (same rationale as the base accent).
|
|
292
|
+
"--color-accent": "oklch(0.945 0.01 251.7)",
|
|
293
|
+
"--color-accent-foreground": "oklch(0.208 0.042 265.755)",
|
|
294
|
+
"--color-border": "oklch(0.929 0.013 255.508)",
|
|
295
|
+
"--color-border-subtle": "oklch(0.948 0.01 252)",
|
|
296
|
+
"--color-input": "oklch(0.929 0.013 255.508)",
|
|
297
|
+
"--color-ring": "oklch(0.546 0.245 262.881)",
|
|
298
|
+
"--color-chart-1": "oklch(0.546 0.245 262.881)",
|
|
299
|
+
"--color-sidebar": "oklch(0.984 0.003 247.858)",
|
|
300
|
+
"--color-sidebar-foreground": "oklch(0.129 0.042 264.695)",
|
|
301
|
+
"--color-sidebar-primary": "oklch(0.546 0.245 262.881)",
|
|
302
|
+
"--color-sidebar-primary-foreground": NEAR_WHITE,
|
|
303
|
+
"--color-sidebar-accent": "oklch(0.945 0.01 251.7)",
|
|
304
|
+
"--color-sidebar-accent-foreground": "oklch(0.208 0.042 265.755)",
|
|
305
|
+
"--color-sidebar-border": "oklch(0.948 0.01 252)",
|
|
306
|
+
"--color-sidebar-ring": "oklch(0.546 0.245 262.881)",
|
|
307
|
+
},
|
|
308
|
+
dark: {
|
|
309
|
+
"--color-background": "oklch(0.129 0.042 264.695)",
|
|
310
|
+
"--color-foreground": NEAR_WHITE,
|
|
311
|
+
"--color-card": "oklch(0.208 0.042 265.755)",
|
|
312
|
+
"--color-card-foreground": NEAR_WHITE,
|
|
313
|
+
"--color-surface": "oklch(0.17 0.042 265)",
|
|
314
|
+
"--color-popover": "oklch(0.208 0.042 265.755)",
|
|
315
|
+
"--color-popover-foreground": NEAR_WHITE,
|
|
316
|
+
"--color-primary": "oklch(0.707 0.165 254.624)",
|
|
317
|
+
"--color-primary-foreground": "oklch(0.129 0.042 264.695)",
|
|
318
|
+
"--color-secondary": "oklch(0.279 0.041 260.031)",
|
|
319
|
+
"--color-secondary-foreground": NEAR_WHITE,
|
|
320
|
+
"--color-muted": "oklch(0.279 0.041 260.031)",
|
|
321
|
+
"--color-muted-foreground": "oklch(0.704 0.04 256.788)",
|
|
322
|
+
"--color-accent": "oklch(0.279 0.041 260.031)",
|
|
323
|
+
"--color-accent-foreground": NEAR_WHITE,
|
|
324
|
+
"--color-border": "oklch(1 0 0 / 10%)",
|
|
325
|
+
"--color-border-subtle": "oklch(1 0 0 / 8%)",
|
|
326
|
+
"--color-input": "oklch(1 0 0 / 15%)",
|
|
327
|
+
"--color-ring": "oklch(0.707 0.165 254.624)",
|
|
328
|
+
"--color-chart-1": "oklch(0.707 0.165 254.624)",
|
|
329
|
+
"--color-sidebar": "oklch(0.208 0.042 265.755)",
|
|
330
|
+
"--color-sidebar-foreground": NEAR_WHITE,
|
|
331
|
+
"--color-sidebar-primary": "oklch(0.707 0.165 254.624)",
|
|
332
|
+
"--color-sidebar-primary-foreground": NEAR_WHITE,
|
|
333
|
+
"--color-sidebar-accent": "oklch(0.279 0.041 260.031)",
|
|
334
|
+
"--color-sidebar-accent-foreground": NEAR_WHITE,
|
|
335
|
+
"--color-sidebar-border": "oklch(1 0 0 / 8%)",
|
|
336
|
+
"--color-sidebar-ring": "oklch(0.707 0.165 254.624)",
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
id: "ember",
|
|
342
|
+
name: "Ember",
|
|
343
|
+
description: "Warm stone field with a burnt orange voice.",
|
|
344
|
+
accent: { light: "oklch(0.646 0.222 41.116)", dark: "oklch(0.75 0.183 55.934)" },
|
|
345
|
+
field: { light: "oklch(0.985 0.001 106.423)", dark: "oklch(0.147 0.004 49.25)" },
|
|
346
|
+
vars: {
|
|
347
|
+
light: {
|
|
348
|
+
"--color-background": "oklch(0.985 0.001 106.423)",
|
|
349
|
+
"--color-foreground": "oklch(0.147 0.004 49.25)",
|
|
350
|
+
"--color-card": "oklch(1 0 0)",
|
|
351
|
+
"--color-card-foreground": "oklch(0.147 0.004 49.25)",
|
|
352
|
+
"--color-surface": "oklch(0.97 0.001 106.424)",
|
|
353
|
+
"--color-popover": "oklch(1 0 0)",
|
|
354
|
+
"--color-popover-foreground": "oklch(0.147 0.004 49.25)",
|
|
355
|
+
"--color-primary": "oklch(0.646 0.222 41.116)",
|
|
356
|
+
"--color-primary-foreground": NEAR_WHITE,
|
|
357
|
+
"--color-secondary": "oklch(0.97 0.001 106.424)",
|
|
358
|
+
"--color-secondary-foreground": "oklch(0.216 0.006 56.043)",
|
|
359
|
+
"--color-muted": "oklch(0.97 0.001 106.424)",
|
|
360
|
+
"--color-muted-foreground": "oklch(0.553 0.013 58.071)",
|
|
361
|
+
// Hover/highlight fill one step below muted (stone-100 → ~stone-150);
|
|
362
|
+
// the sidebar-accent below was already at stone-200 and stays.
|
|
363
|
+
"--color-accent": "oklch(0.946 0.002 48.7)",
|
|
364
|
+
"--color-accent-foreground": "oklch(0.216 0.006 56.043)",
|
|
365
|
+
"--color-border": "oklch(0.923 0.003 48.717)",
|
|
366
|
+
"--color-border-subtle": "oklch(0.947 0.002 48.717)",
|
|
367
|
+
"--color-input": "oklch(0.923 0.003 48.717)",
|
|
368
|
+
"--color-ring": "oklch(0.646 0.222 41.116)",
|
|
369
|
+
"--color-chart-1": "oklch(0.646 0.222 41.116)",
|
|
370
|
+
"--color-sidebar": "oklch(0.97 0.001 106.424)",
|
|
371
|
+
"--color-sidebar-foreground": "oklch(0.147 0.004 49.25)",
|
|
372
|
+
"--color-sidebar-primary": "oklch(0.646 0.222 41.116)",
|
|
373
|
+
"--color-sidebar-primary-foreground": NEAR_WHITE,
|
|
374
|
+
"--color-sidebar-accent": "oklch(0.923 0.003 48.717)",
|
|
375
|
+
"--color-sidebar-accent-foreground": "oklch(0.216 0.006 56.043)",
|
|
376
|
+
"--color-sidebar-border": "oklch(0.947 0.002 48.717)",
|
|
377
|
+
"--color-sidebar-ring": "oklch(0.646 0.222 41.116)",
|
|
378
|
+
},
|
|
379
|
+
dark: {
|
|
380
|
+
"--color-background": "oklch(0.147 0.004 49.25)",
|
|
381
|
+
"--color-foreground": NEAR_WHITE,
|
|
382
|
+
"--color-card": "oklch(0.216 0.006 56.043)",
|
|
383
|
+
"--color-card-foreground": NEAR_WHITE,
|
|
384
|
+
"--color-surface": "oklch(0.185 0.005 49)",
|
|
385
|
+
"--color-popover": "oklch(0.216 0.006 56.043)",
|
|
386
|
+
"--color-popover-foreground": NEAR_WHITE,
|
|
387
|
+
"--color-primary": "oklch(0.75 0.183 55.934)",
|
|
388
|
+
"--color-primary-foreground": "oklch(0.147 0.004 49.25)",
|
|
389
|
+
"--color-secondary": "oklch(0.268 0.007 34.298)",
|
|
390
|
+
"--color-secondary-foreground": NEAR_WHITE,
|
|
391
|
+
"--color-muted": "oklch(0.268 0.007 34.298)",
|
|
392
|
+
"--color-muted-foreground": "oklch(0.709 0.01 56.259)",
|
|
393
|
+
"--color-accent": "oklch(0.268 0.007 34.298)",
|
|
394
|
+
"--color-accent-foreground": NEAR_WHITE,
|
|
395
|
+
"--color-border": "oklch(1 0 0 / 10%)",
|
|
396
|
+
"--color-border-subtle": "oklch(1 0 0 / 8%)",
|
|
397
|
+
"--color-input": "oklch(1 0 0 / 15%)",
|
|
398
|
+
"--color-ring": "oklch(0.75 0.183 55.934)",
|
|
399
|
+
"--color-chart-1": "oklch(0.75 0.183 55.934)",
|
|
400
|
+
"--color-sidebar": "oklch(0.216 0.006 56.043)",
|
|
401
|
+
"--color-sidebar-foreground": NEAR_WHITE,
|
|
402
|
+
"--color-sidebar-primary": "oklch(0.75 0.183 55.934)",
|
|
403
|
+
"--color-sidebar-primary-foreground": NEAR_WHITE,
|
|
404
|
+
"--color-sidebar-accent": "oklch(0.268 0.007 34.298)",
|
|
405
|
+
"--color-sidebar-accent-foreground": NEAR_WHITE,
|
|
406
|
+
"--color-sidebar-border": "oklch(1 0 0 / 8%)",
|
|
407
|
+
"--color-sidebar-ring": "oklch(0.75 0.183 55.934)",
|
|
408
|
+
},
|
|
409
|
+
},
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
id: "carbon",
|
|
413
|
+
name: "Carbon",
|
|
414
|
+
description: "Pure monochrome. The interface recedes, the data speaks.",
|
|
415
|
+
accent: { light: ZINC_900, dark: NEAR_WHITE },
|
|
416
|
+
field: { light: "oklch(1 0 0)", dark: "oklch(0.141 0.005 285.823)" },
|
|
417
|
+
vars: {
|
|
418
|
+
light: {
|
|
419
|
+
"--color-primary": ZINC_900,
|
|
420
|
+
"--color-primary-foreground": NEAR_WHITE,
|
|
421
|
+
"--color-ring": "oklch(0.552 0.016 285.938)",
|
|
422
|
+
"--color-sidebar-primary": ZINC_900,
|
|
423
|
+
"--color-sidebar-primary-foreground": NEAR_WHITE,
|
|
424
|
+
"--color-sidebar-ring": "oklch(0.552 0.016 285.938)",
|
|
425
|
+
},
|
|
426
|
+
dark: {
|
|
427
|
+
"--color-primary": NEAR_WHITE,
|
|
428
|
+
"--color-primary-foreground": ZINC_900,
|
|
429
|
+
"--color-ring": "oklch(0.705 0.015 286.067)",
|
|
430
|
+
"--color-sidebar-primary": NEAR_WHITE,
|
|
431
|
+
"--color-sidebar-primary-foreground": ZINC_900,
|
|
432
|
+
"--color-sidebar-ring": "oklch(0.705 0.015 286.067)",
|
|
433
|
+
},
|
|
434
|
+
},
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
// The warm editorial look of the original pages skill: off-white canvas
|
|
438
|
+
// (#F7F6F3), white cards, warm borders (#DEDBD2), charcoal text (#18181B),
|
|
439
|
+
// muted text (#62646A), one blue voice (#2563EB). Full-field like Ember;
|
|
440
|
+
// status tokens stay stock.
|
|
441
|
+
id: "paper",
|
|
442
|
+
name: "Paper",
|
|
443
|
+
description: "Warm editorial paper: off-white field, white cards, one blue voice.",
|
|
444
|
+
accent: { light: "oklch(0.546 0.215 262.881)", dark: "oklch(0.714 0.143 254.624)" },
|
|
445
|
+
field: { light: "oklch(0.973 0.004 91.446)", dark: "oklch(0.21 0.005 91.5)" },
|
|
446
|
+
vars: {
|
|
447
|
+
light: {
|
|
448
|
+
"--color-background": "oklch(0.973 0.004 91.446)",
|
|
449
|
+
"--color-foreground": ZINC_900,
|
|
450
|
+
"--color-card": "oklch(1 0 0)",
|
|
451
|
+
"--color-card-foreground": ZINC_900,
|
|
452
|
+
"--color-surface": "oklch(0.988 0.001 106.423)",
|
|
453
|
+
"--color-popover": "oklch(1 0 0)",
|
|
454
|
+
"--color-popover-foreground": ZINC_900,
|
|
455
|
+
"--color-primary": "oklch(0.546 0.215 262.881)",
|
|
456
|
+
"--color-primary-foreground": NEAR_WHITE,
|
|
457
|
+
"--color-secondary": "oklch(0.951 0.006 91.5)",
|
|
458
|
+
"--color-secondary-foreground": ZINC_900,
|
|
459
|
+
"--color-muted": "oklch(0.951 0.006 91.5)",
|
|
460
|
+
"--color-muted-foreground": "oklch(0.504 0.01 271.22)",
|
|
461
|
+
"--color-accent": "oklch(0.932 0.008 91.5)",
|
|
462
|
+
"--color-accent-foreground": ZINC_900,
|
|
463
|
+
"--color-border": "oklch(0.891 0.013 91.529)",
|
|
464
|
+
"--color-border-subtle": "oklch(0.925 0.009 91.5)",
|
|
465
|
+
"--color-input": "oklch(0.891 0.013 91.529)",
|
|
466
|
+
"--color-ring": "oklch(0.546 0.215 262.881)",
|
|
467
|
+
"--color-chart-1": "oklch(0.546 0.215 262.881)",
|
|
468
|
+
"--color-sidebar": "oklch(0.951 0.006 91.5)",
|
|
469
|
+
"--color-sidebar-foreground": ZINC_900,
|
|
470
|
+
"--color-sidebar-primary": "oklch(0.546 0.215 262.881)",
|
|
471
|
+
"--color-sidebar-primary-foreground": NEAR_WHITE,
|
|
472
|
+
"--color-sidebar-accent": "oklch(0.915 0.01 91.5)",
|
|
473
|
+
"--color-sidebar-accent-foreground": ZINC_900,
|
|
474
|
+
"--color-sidebar-border": "oklch(0.925 0.009 91.5)",
|
|
475
|
+
"--color-sidebar-ring": "oklch(0.546 0.215 262.881)",
|
|
476
|
+
},
|
|
477
|
+
dark: {
|
|
478
|
+
"--color-background": "oklch(0.21 0.005 91.5)",
|
|
479
|
+
"--color-foreground": "oklch(0.94 0.008 91.5)",
|
|
480
|
+
"--color-card": "oklch(0.25 0.006 91.5)",
|
|
481
|
+
"--color-card-foreground": "oklch(0.94 0.008 91.5)",
|
|
482
|
+
"--color-surface": "oklch(0.23 0.0055 91.5)",
|
|
483
|
+
"--color-popover": "oklch(0.25 0.006 91.5)",
|
|
484
|
+
"--color-popover-foreground": "oklch(0.94 0.008 91.5)",
|
|
485
|
+
"--color-primary": "oklch(0.714 0.143 254.624)",
|
|
486
|
+
"--color-primary-foreground": "oklch(0.21 0.005 91.5)",
|
|
487
|
+
"--color-secondary": "oklch(0.3 0.007 91.5)",
|
|
488
|
+
"--color-secondary-foreground": "oklch(0.94 0.008 91.5)",
|
|
489
|
+
"--color-muted": "oklch(0.3 0.007 91.5)",
|
|
490
|
+
"--color-muted-foreground": "oklch(0.72 0.012 91.5)",
|
|
491
|
+
"--color-accent": "oklch(0.3 0.007 91.5)",
|
|
492
|
+
"--color-accent-foreground": "oklch(0.94 0.008 91.5)",
|
|
493
|
+
"--color-border": "oklch(0.95 0.02 91.5 / 12%)",
|
|
494
|
+
"--color-border-subtle": "oklch(0.95 0.02 91.5 / 8%)",
|
|
495
|
+
"--color-input": "oklch(0.95 0.02 91.5 / 16%)",
|
|
496
|
+
"--color-ring": "oklch(0.714 0.143 254.624)",
|
|
497
|
+
"--color-chart-1": "oklch(0.714 0.143 254.624)",
|
|
498
|
+
"--color-sidebar": "oklch(0.25 0.006 91.5)",
|
|
499
|
+
"--color-sidebar-foreground": "oklch(0.94 0.008 91.5)",
|
|
500
|
+
"--color-sidebar-primary": "oklch(0.714 0.143 254.624)",
|
|
501
|
+
"--color-sidebar-primary-foreground": NEAR_WHITE,
|
|
502
|
+
"--color-sidebar-accent": "oklch(0.3 0.007 91.5)",
|
|
503
|
+
"--color-sidebar-accent-foreground": "oklch(0.94 0.008 91.5)",
|
|
504
|
+
"--color-sidebar-border": "oklch(0.95 0.02 91.5 / 8%)",
|
|
505
|
+
"--color-sidebar-ring": "oklch(0.714 0.143 254.624)",
|
|
506
|
+
},
|
|
507
|
+
},
|
|
508
|
+
},
|
|
509
|
+
// Classic editor/platform themes: the only presets that override
|
|
510
|
+
// `--color-status-*` (their identity includes a status palette; hue
|
|
511
|
+
// semantics stay fixed). See classics.ts.
|
|
512
|
+
...CLASSIC_THEME_PRESETS,
|
|
513
|
+
];
|
|
514
|
+
|
|
515
|
+
const PRESETS_BY_ID = new Map(THEME_PRESETS.map((preset) => [preset.id, preset]));
|
|
516
|
+
|
|
517
|
+
/** Every preset id, in catalog order (server-side validation and error messages). */
|
|
518
|
+
export const THEME_PRESET_IDS: readonly string[] = THEME_PRESETS.map((preset) => preset.id);
|
|
519
|
+
|
|
520
|
+
export function getThemePreset(id: string | null | undefined): ThemePreset | null {
|
|
521
|
+
if (!id) return null;
|
|
522
|
+
return PRESETS_BY_ID.get(id) ?? null;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
export function isThemePresetId(id: string): boolean {
|
|
526
|
+
return PRESETS_BY_ID.has(id);
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* DASHBOARD-ROOT normalization of an untrusted stored id: a known preset id,
|
|
531
|
+
* or null for unknown ids AND for `hive` (at the `<html>` level the base
|
|
532
|
+
* needs no attribute: there is nothing outer to reset from). Scoped app
|
|
533
|
+
* canvases must NOT use this: there `hive` is a meaningful explicit reset
|
|
534
|
+
* (see the resolution in `apps/ui/src/components/apps/app-surface.tsx`).
|
|
535
|
+
*/
|
|
536
|
+
export function resolveThemeId(id: string | null | undefined): string | null {
|
|
537
|
+
const preset = getThemePreset(id);
|
|
538
|
+
return preset && preset.id !== DEFAULT_THEME_ID ? preset.id : null;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
function declarations(vars: Record<string, string>, indent: string): string {
|
|
542
|
+
return Object.entries(vars)
|
|
543
|
+
.map(([name, value]) => `${indent}${name}: ${value};`)
|
|
544
|
+
.join("\n");
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
export function buildThemePresetCss(): string {
|
|
548
|
+
const blocks: string[] = [];
|
|
549
|
+
for (const preset of THEME_PRESETS) {
|
|
550
|
+
// Self-contained blocks: base values under the preset's own overrides,
|
|
551
|
+
// so a scoped canvas resets fully instead of blending with the outer
|
|
552
|
+
// dashboard preset. `hive` emits the bare base: the explicit reset.
|
|
553
|
+
const light = { ...BASE_SCOPE_VARS.light, ...preset.vars.light };
|
|
554
|
+
const dark = { ...BASE_SCOPE_VARS.dark, ...preset.vars.dark };
|
|
555
|
+
blocks.push(
|
|
556
|
+
`html[data-theme="${preset.id}"],\n[data-theme="${preset.id}"] {\n${declarations(light, " ")}\n}`,
|
|
557
|
+
`html.dark[data-theme="${preset.id}"],\n.dark [data-theme="${preset.id}"] {\n${declarations(dark, " ")}\n}`,
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
return blocks.join("\n\n");
|
|
561
|
+
}
|