From c0c09426ff0999d5a845d6198ec653e98c871736 Mon Sep 17 00:00:00 2001 From: Ajay Ghanwat Date: Sun, 19 Jul 2026 17:45:13 +0530 Subject: [PATCH] release: WRNexusJS 0.2.57 --- .publish/ai/package.json | 2 +- .publish/authz/package.json | 2 +- .publish/cli/package.json | 22 ++-- .publish/compiler/package.json | 2 +- .publish/core/package.json | 2 +- .publish/csr/package.json | 4 +- .publish/db/package.json | 2 +- .publish/dev-server/package.json | 26 ++-- .publish/encryption/package.json | 2 +- .publish/helpers/package.json | 4 +- .publish/i18n/package.json | 4 +- .publish/jwt/package.json | 2 +- .publish/mobile/package.json | 4 +- .publish/native/package.json | 2 +- .publish/oauth/package.json | 2 +- .publish/pubsub/package.json | 2 +- .publish/queue/package.json | 2 +- .publish/reactive/package.json | 2 +- .publish/router/package.json | 6 +- .publish/ssr/package.json | 4 +- .publish/styles/README.md | 27 +++- .publish/styles/package.json | 4 +- .publish/test/package.json | 2 +- .publish/tracking/package.json | 2 +- .publish/ui/package.json | 4 +- .publish/ui/ui.css | 54 +++++++- .publish/uploader/package.json | 4 +- .publish/validation/package.json | 2 +- README.md | 4 + docs/GUIDE.md | 2 + examples/basic-app/wrnexus.config.ts | 9 +- packages/ai/package.json | 2 +- packages/authz/package.json | 2 +- packages/cli/package.json | 2 +- packages/cli/src/update.ts | 9 ++ packages/compiler/package.json | 2 +- packages/core/package.json | 2 +- packages/csr/package.json | 2 +- packages/db/package.json | 2 +- packages/dev-server/package.json | 2 +- packages/encryption/package.json | 2 +- packages/helpers/package.json | 2 +- packages/i18n/package.json | 2 +- packages/jwt/package.json | 2 +- packages/mobile/package.json | 2 +- packages/native/package.json | 2 +- packages/oauth/package.json | 2 +- packages/pubsub/package.json | 2 +- packages/queue/package.json | 2 +- packages/reactive/package.json | 2 +- packages/router/package.json | 2 +- packages/ssr/package.json | 2 +- packages/styles/README.md | 27 +++- packages/styles/package.json | 2 +- packages/styles/src/index.ts | 10 +- packages/styles/src/theme.ts | 182 ++++++++++++++++++++++++++- packages/styles/test/theme.test.ts | 39 ++++++ packages/test/package.json | 2 +- packages/tracking/package.json | 2 +- packages/ui/package.json | 2 +- packages/ui/test/ui.test.ts | 3 + packages/ui/ui.css | 54 +++++++- packages/uploader/package.json | 2 +- packages/validation/package.json | 2 +- update-package-versions.mjs | 2 +- 65 files changed, 487 insertions(+), 103 deletions(-) diff --git a/.publish/ai/package.json b/.publish/ai/package.json index e2217836..c6870796 100644 --- a/.publish/ai/package.json +++ b/.publish/ai/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/ai", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "Zero-dependency Claude (Anthropic) client for WrNexus apps.", "license": "MIT", diff --git a/.publish/authz/package.json b/.publish/authz/package.json index ef6f4481..a0b0abc6 100644 --- a/.publish/authz/package.json +++ b/.publish/authz/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/authz", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "@wrnexus/authz — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/cli/package.json b/.publish/cli/package.json index 45721daf..cae742a1 100644 --- a/.publish/cli/package.json +++ b/.publish/cli/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/cli", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "@wrnexus/cli — part of the WrNexus framework.", "license": "MIT", @@ -28,16 +28,16 @@ "wrnexus": "./dist/index.js" }, "dependencies": { - "@wrnexus/core": "^0.2.56", - "@wrnexus/router": "^0.2.56", - "@wrnexus/csr": "^0.2.56", - "@wrnexus/compiler": "^0.2.56", - "@wrnexus/styles": "^0.2.56", - "@wrnexus/dev-server": "^0.2.56", - "@wrnexus/ui": "^0.2.56", - "@wrnexus/validation": "^0.2.56", - "@wrnexus/i18n": "^0.2.56", - "@wrnexus/db": "^0.2.56" + "@wrnexus/core": "^0.2.57", + "@wrnexus/router": "^0.2.57", + "@wrnexus/csr": "^0.2.57", + "@wrnexus/compiler": "^0.2.57", + "@wrnexus/styles": "^0.2.57", + "@wrnexus/dev-server": "^0.2.57", + "@wrnexus/ui": "^0.2.57", + "@wrnexus/validation": "^0.2.57", + "@wrnexus/i18n": "^0.2.57", + "@wrnexus/db": "^0.2.57" }, "files": [ "dist" diff --git a/.publish/compiler/package.json b/.publish/compiler/package.json index 4ce7d59f..722e0ff4 100644 --- a/.publish/compiler/package.json +++ b/.publish/compiler/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/compiler", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "@wrnexus/compiler — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/core/package.json b/.publish/core/package.json index b226d43f..ad5179bf 100644 --- a/.publish/core/package.json +++ b/.publish/core/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/core", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "@wrnexus/core — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/csr/package.json b/.publish/csr/package.json index 5f35f36f..719c9f55 100644 --- a/.publish/csr/package.json +++ b/.publish/csr/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/csr", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "@wrnexus/csr — part of the WrNexus framework.", "license": "MIT", @@ -21,7 +21,7 @@ } }, "dependencies": { - "@wrnexus/core": "^0.2.56" + "@wrnexus/core": "^0.2.57" }, "files": [ "dist" diff --git a/.publish/db/package.json b/.publish/db/package.json index a2aa505d..108be003 100644 --- a/.publish/db/package.json +++ b/.publish/db/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/db", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "@wrnexus/db — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/dev-server/package.json b/.publish/dev-server/package.json index d472f10c..bedb6419 100644 --- a/.publish/dev-server/package.json +++ b/.publish/dev-server/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/dev-server", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "@wrnexus/dev-server — part of the WrNexus framework.", "license": "MIT", @@ -25,18 +25,18 @@ } }, "dependencies": { - "@wrnexus/core": "^0.2.56", - "@wrnexus/router": "^0.2.56", - "@wrnexus/ssr": "^0.2.56", - "@wrnexus/csr": "^0.2.56", - "@wrnexus/compiler": "^0.2.56", - "@wrnexus/styles": "^0.2.56", - "@wrnexus/ui": "^0.2.56", - "@wrnexus/validation": "^0.2.56", - "@wrnexus/i18n": "^0.2.56", - "@wrnexus/db": "^0.2.56", - "@wrnexus/pubsub": "^0.2.56", - "@wrnexus/uploader": "^0.2.56" + "@wrnexus/core": "^0.2.57", + "@wrnexus/router": "^0.2.57", + "@wrnexus/ssr": "^0.2.57", + "@wrnexus/csr": "^0.2.57", + "@wrnexus/compiler": "^0.2.57", + "@wrnexus/styles": "^0.2.57", + "@wrnexus/ui": "^0.2.57", + "@wrnexus/validation": "^0.2.57", + "@wrnexus/i18n": "^0.2.57", + "@wrnexus/db": "^0.2.57", + "@wrnexus/pubsub": "^0.2.57", + "@wrnexus/uploader": "^0.2.57" }, "files": [ "dist" diff --git a/.publish/encryption/package.json b/.publish/encryption/package.json index d0737c67..27a395f4 100644 --- a/.publish/encryption/package.json +++ b/.publish/encryption/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/encryption", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "@wrnexus/encryption — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/helpers/package.json b/.publish/helpers/package.json index 8422aceb..0ff52c0f 100644 --- a/.publish/helpers/package.json +++ b/.publish/helpers/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/helpers", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "Safe convenience helpers for WrNexus request contexts and common application flows.", "license": "MIT", @@ -21,7 +21,7 @@ } }, "dependencies": { - "@wrnexus/core": "^0.2.56" + "@wrnexus/core": "^0.2.57" }, "files": [ "dist" diff --git a/.publish/i18n/package.json b/.publish/i18n/package.json index efe2591b..cd71609c 100644 --- a/.publish/i18n/package.json +++ b/.publish/i18n/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/i18n", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "@wrnexus/i18n — part of the WrNexus framework.", "license": "MIT", @@ -21,7 +21,7 @@ } }, "dependencies": { - "@wrnexus/core": "^0.2.56" + "@wrnexus/core": "^0.2.57" }, "files": [ "dist" diff --git a/.publish/jwt/package.json b/.publish/jwt/package.json index b36cc6eb..dcb77f8e 100644 --- a/.publish/jwt/package.json +++ b/.publish/jwt/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/jwt", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "@wrnexus/jwt — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/mobile/package.json b/.publish/mobile/package.json index 085967b3..669f2367 100644 --- a/.publish/mobile/package.json +++ b/.publish/mobile/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/mobile", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "@wrnexus/mobile — part of the WrNexus framework.", "license": "MIT", @@ -21,7 +21,7 @@ } }, "dependencies": { - "@wrnexus/native": "^0.2.56" + "@wrnexus/native": "^0.2.57" }, "files": [ "dist" diff --git a/.publish/native/package.json b/.publish/native/package.json index 47968159..6d60c0ec 100644 --- a/.publish/native/package.json +++ b/.publish/native/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/native", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "@wrnexus/native — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/oauth/package.json b/.publish/oauth/package.json index 2ce0bf95..c9670839 100644 --- a/.publish/oauth/package.json +++ b/.publish/oauth/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/oauth", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "@wrnexus/oauth — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/pubsub/package.json b/.publish/pubsub/package.json index 786b5f21..dcf18bc1 100644 --- a/.publish/pubsub/package.json +++ b/.publish/pubsub/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/pubsub", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "@wrnexus/pubsub — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/queue/package.json b/.publish/queue/package.json index 5df3ca16..0db58972 100644 --- a/.publish/queue/package.json +++ b/.publish/queue/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/queue", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "@wrnexus/queue — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/reactive/package.json b/.publish/reactive/package.json index 916e7e53..e252012c 100644 --- a/.publish/reactive/package.json +++ b/.publish/reactive/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/reactive", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "@wrnexus/reactive — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/router/package.json b/.publish/router/package.json index a0c1fd32..8b95d0d8 100644 --- a/.publish/router/package.json +++ b/.publish/router/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/router", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "@wrnexus/router — part of the WrNexus framework.", "license": "MIT", @@ -21,8 +21,8 @@ } }, "dependencies": { - "@wrnexus/compiler": "^0.2.56", - "@wrnexus/core": "^0.2.56" + "@wrnexus/compiler": "^0.2.57", + "@wrnexus/core": "^0.2.57" }, "files": [ "dist" diff --git a/.publish/ssr/package.json b/.publish/ssr/package.json index 712cb9b4..7acd393b 100644 --- a/.publish/ssr/package.json +++ b/.publish/ssr/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/ssr", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "@wrnexus/ssr — part of the WrNexus framework.", "license": "MIT", @@ -21,7 +21,7 @@ } }, "dependencies": { - "@wrnexus/core": "^0.2.56" + "@wrnexus/core": "^0.2.57" }, "files": [ "dist" diff --git a/.publish/styles/README.md b/.publish/styles/README.md index 555aaf02..4037b990 100644 --- a/.publish/styles/README.md +++ b/.publish/styles/README.md @@ -106,6 +106,7 @@ Tokens are emitted as `--wire-` custom properties, **except** the reserved type ThemeTokens = Record; interface ThemeConfig { + palette?: ThemePaletteName | CustomThemePalette; default?: string; // theme used when no cookie is present themes?: Record; // deep-merged over built-in light/dark } @@ -117,7 +118,30 @@ interface ResolvedTheme { } ``` -Built-in token keys (both `light` and `dark`): `color-scheme`, `color-bg`, `color-surface`, `color-surface-2`, `color-text`, `color-muted`, `color-border`, `color-primary`, `color-primary-hover`, `color-primary-contrast`, `color-danger`, `color-success`, `color-warning`, `radius`, `radius-sm`, `font-sans`, `shadow-1`. +Built-in palettes are `blue`, `indigo`, `violet`, `emerald`, `cyan`, `rose`, +`amber`, and `slate`. Each supplies primary, secondary, info, success, warning, +danger/error, hover, and contrast colors to every light/dark theme. Built-in +token keys also include surfaces, text, borders, radii, fonts, and shadows. + +A custom palette is intentionally complete, so components never fall back to an +unrelated blue status or action color: + +```ts +theme: { + palette: { + primary: "#7c3aed", + primaryHover: "#6d28d9", + primaryContrast: "#ffffff", + secondary: "#db2777", + secondaryHover: "#be185d", + secondaryContrast: "#ffffff", + info: "#2563eb", + success: "#059669", + warning: "#d97706", + danger: "#dc2626", + }, +} +``` The client runtime (`renderThemeRuntime`) exposes `window.wireTheme` with `{ get, set, toggle, bind, themes }`, wires up any `[data-wire-theme-toggle]` and `[data-wire-theme-set]` elements on load, and persists the choice to the `wire-theme` cookie (`max-age` 1 year, `samesite=lax`). `toggle()` cycles through the configured theme names in order. @@ -135,6 +159,7 @@ export default { port: 3000, db: { driver: "sqlite", url: "app.db" }, theme: { + palette: "violet", default: "dark", themes: { light: { "color-primary": "#7c3aed" }, // override one token; rest inherited diff --git a/.publish/styles/package.json b/.publish/styles/package.json index e8d7311b..af9137f8 100644 --- a/.publish/styles/package.json +++ b/.publish/styles/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/styles", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "@wrnexus/styles — part of the WrNexus framework.", "license": "MIT", @@ -21,7 +21,7 @@ } }, "dependencies": { - "@wrnexus/uploader": "^0.2.56" + "@wrnexus/uploader": "^0.2.57" }, "files": [ "dist" diff --git a/.publish/test/package.json b/.publish/test/package.json index 540613d2..bac42173 100644 --- a/.publish/test/package.json +++ b/.publish/test/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/test", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "@wrnexus/test — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/tracking/package.json b/.publish/tracking/package.json index f17eeb1e..6872cc85 100644 --- a/.publish/tracking/package.json +++ b/.publish/tracking/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/tracking", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "@wrnexus/tracking — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/ui/package.json b/.publish/ui/package.json index 601a4636..d50c823d 100644 --- a/.publish/ui/package.json +++ b/.publish/ui/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/ui", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "@wrnexus/ui — part of the WrNexus framework.", "license": "MIT", @@ -23,7 +23,7 @@ "./ui.css": "./ui.css" }, "dependencies": { - "@wrnexus/core": "^0.2.56" + "@wrnexus/core": "^0.2.57" }, "files": [ "dist", diff --git a/.publish/ui/ui.css b/.publish/ui/ui.css index f20fe432..7743be70 100644 --- a/.publish/ui/ui.css +++ b/.publish/ui/ui.css @@ -233,15 +233,15 @@ } .wire-badge--success { background: var(--wire-color-success); - color: #05210f; + color: var(--wire-color-primary-contrast); } .wire-badge--danger { background: var(--wire-color-danger); - color: #fff; + color: var(--wire-color-primary-contrast); } .wire-badge--warning { background: var(--wire-color-warning); - color: #201400; + color: var(--wire-color-primary-contrast); } /* --- Alert ---------------------------------------------------------------- */ @@ -264,7 +264,7 @@ color: var(--wire-color-muted); } .wire-alert--info { - border-left-color: var(--wire-color-primary); + border-left-color: var(--wire-color-info); } .wire-alert--success { border-left-color: var(--wire-color-success); @@ -950,6 +950,52 @@ --wire-ease-emphasized: cubic-bezier(0.16, 1, 0.3, 1); } +/* Tailwind v4 color bridge. Existing utility-authored components inherit the + * configured semantic palette without requiring generated per-palette markup. */ +[data-component] { + --color-violet-50: color-mix(in srgb, var(--wire-color-primary) 7%, white); + --color-violet-100: color-mix(in srgb, var(--wire-color-primary) 14%, white); + --color-violet-200: color-mix(in srgb, var(--wire-color-primary) 25%, white); + --color-violet-300: color-mix(in srgb, var(--wire-color-primary) 42%, white); + --color-violet-400: color-mix(in srgb, var(--wire-color-primary) 72%, white); + --color-violet-500: var(--wire-color-primary); + --color-violet-600: var(--wire-color-primary); + --color-violet-700: var(--wire-color-primary-hover); + --color-violet-800: color-mix(in srgb, var(--wire-color-primary-hover) 82%, black); + --color-violet-900: color-mix(in srgb, var(--wire-color-primary-hover) 65%, black); + --color-violet-950: color-mix(in srgb, var(--wire-color-primary-hover) 42%, black); + --color-indigo-50: var(--color-violet-50); + --color-indigo-100: var(--color-violet-100); + --color-indigo-200: var(--color-violet-200); + --color-indigo-300: var(--color-violet-300); + --color-indigo-400: var(--color-violet-400); + --color-indigo-500: var(--color-violet-500); + --color-indigo-600: var(--color-violet-600); + --color-indigo-700: var(--color-violet-700); + --color-indigo-800: var(--color-violet-800); + --color-indigo-900: var(--color-violet-900); + --color-indigo-950: var(--color-violet-950); + --color-blue-500: var(--wire-color-info); + --color-blue-600: var(--wire-color-info); + --color-blue-700: color-mix(in srgb, var(--wire-color-info) 80%, black); + --color-emerald-500: var(--wire-color-success); + --color-emerald-600: var(--wire-color-success); + --color-emerald-700: color-mix(in srgb, var(--wire-color-success) 80%, black); + --color-green-500: var(--wire-color-success); + --color-green-600: var(--wire-color-success); + --color-amber-500: var(--wire-color-warning); + --color-amber-600: var(--wire-color-warning); + --color-amber-700: color-mix(in srgb, var(--wire-color-warning) 80%, black); + --color-yellow-500: var(--wire-color-warning); + --color-red-400: color-mix(in srgb, var(--wire-color-danger) 75%, white); + --color-red-500: var(--wire-color-danger); + --color-red-600: var(--wire-color-danger); + --color-red-700: color-mix(in srgb, var(--wire-color-danger) 80%, black); + --color-rose-500: var(--wire-color-danger); + --color-rose-600: var(--wire-color-danger); + --color-rose-700: color-mix(in srgb, var(--wire-color-danger) 80%, black); +} + [data-component] { animation: wire-component-enter var(--wire-motion-slow) var(--wire-ease-emphasized) both; } diff --git a/.publish/uploader/package.json b/.publish/uploader/package.json index 2f47da0f..02660e7e 100644 --- a/.publish/uploader/package.json +++ b/.publish/uploader/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/uploader", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "@wrnexus/uploader — part of the WrNexus framework.", "license": "MIT", @@ -21,7 +21,7 @@ } }, "dependencies": { - "@wrnexus/core": "^0.2.56" + "@wrnexus/core": "^0.2.57" }, "files": [ "dist" diff --git a/.publish/validation/package.json b/.publish/validation/package.json index dded1139..c26b2588 100644 --- a/.publish/validation/package.json +++ b/.publish/validation/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/validation", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "description": "@wrnexus/validation — part of the WrNexus framework.", "license": "MIT", diff --git a/README.md b/README.md index 690383a9..5b359380 100644 --- a/README.md +++ b/README.md @@ -334,6 +334,10 @@ and own it (an app component shadows the library one of the same name). -merged over built-in light/dark), served at `/__wrnexus/theme.css`. The server sets `` from the `wire-theme` cookie (no flash); a `theme-toggle` component (or any `[data-wire-theme-toggle]` element) switches and persists it. +Choose a complete semantic palette with `theme: { palette: "violet" }`. Available +palettes are `blue`, `indigo`, `violet`, `emerald`, `cyan`, `rose`, `amber`, and +`slate`; a custom palette must provide every primary, secondary, info, success, +warning, danger, hover, and contrast color. **Page layouts.** Add named layouts under `app/layouts/` — e.g. `public.wrn`, `dashboard.wrn`, `auth.wrn` — each a `component` with a `` where the diff --git a/docs/GUIDE.md b/docs/GUIDE.md index 3f9eb10d..0cc0672c 100644 --- a/docs/GUIDE.md +++ b/docs/GUIDE.md @@ -497,6 +497,7 @@ Themes are flat token maps rendered as `--wire-` CSS variables (server + cl ```ts // wrnexus.config.ts theme: { + palette: "violet", // blue | indigo | violet | emerald | cyan | rose | amber | slate default: "dark", // used when no cookie themes: { light: { "color-primary": "#2563eb" }, // deep-merged over built-in light @@ -1266,6 +1267,7 @@ const config: AppConfig = { }, theme: { + palette: "violet", default: "dark", // theme when no wire-theme cookie themes: { light: { "color-primary": "#2563eb" }, dark: { "color-primary": "#6c8cff" } }, }, diff --git a/examples/basic-app/wrnexus.config.ts b/examples/basic-app/wrnexus.config.ts index b5316c99..26c32e21 100644 --- a/examples/basic-app/wrnexus.config.ts +++ b/examples/basic-app/wrnexus.config.ts @@ -32,14 +32,11 @@ const config: AppConfig = { }, // Design-token themes. Built-in `light`/`dark` are provided; here we set the - // default and override a couple of tokens to show customization. Users can - // also redefine any `--wire-*` variable in their own CSS. + // default and choose one of eight complete semantic color palettes. Users + // can still override individual tokens through `themes` when needed. theme: { + palette: "violet", default: "dark", - themes: { - light: { "color-primary": "#2563eb" }, - dark: { "color-primary": "#6c8cff" }, - }, }, // Database connection for `wrnexus db` migrations (and, later, ctx.db). diff --git a/packages/ai/package.json b/packages/ai/package.json index 7786b897..339f7ef9 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/ai", - "version": "0.2.56", + "version": "0.2.57", "private": true, "type": "module", "description": "Zero-dependency Claude (Anthropic) client for WrNexus apps.", diff --git a/packages/authz/package.json b/packages/authz/package.json index a517e3c9..615c67fc 100644 --- a/packages/authz/package.json +++ b/packages/authz/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/authz", - "version": "0.2.56", + "version": "0.2.57", "private": true, "type": "module", "main": "src/index.ts", diff --git a/packages/cli/package.json b/packages/cli/package.json index 26ebaa3a..77335806 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/cli", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/cli/src/update.ts b/packages/cli/src/update.ts index d476866f..44d6216e 100644 --- a/packages/cli/src/update.ts +++ b/packages/cli/src/update.ts @@ -575,6 +575,15 @@ const MIGRATIONS: Migration[] = [ // No generated application files require automatic migration. }, }, + { + version: "0.2.57", + id: "semantic-theme-palettes", + description: + "Adds eight semantic UI palettes and validated complete custom palette configuration.", + apply() { + // Existing theme configuration remains compatible; blue is the default palette. + }, + }, ]; /** Release tooling uses this to require an explicit migration entry per version. */ diff --git a/packages/compiler/package.json b/packages/compiler/package.json index 25e6bec2..11e28c18 100644 --- a/packages/compiler/package.json +++ b/packages/compiler/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/compiler", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/core/package.json b/packages/core/package.json index cad11ee3..bb9987cc 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/core", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/csr/package.json b/packages/csr/package.json index 434004d2..4b0b6641 100644 --- a/packages/csr/package.json +++ b/packages/csr/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/csr", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/db/package.json b/packages/db/package.json index 19c9432a..ccb674df 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/db", - "version": "0.2.56", + "version": "0.2.57", "private": true, "type": "module", "main": "src/index.ts", diff --git a/packages/dev-server/package.json b/packages/dev-server/package.json index dc876ca4..3e4d69fc 100644 --- a/packages/dev-server/package.json +++ b/packages/dev-server/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/dev-server", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/encryption/package.json b/packages/encryption/package.json index c5439f64..7c3090c8 100644 --- a/packages/encryption/package.json +++ b/packages/encryption/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/encryption", - "version": "0.2.56", + "version": "0.2.57", "private": true, "type": "module", "main": "src/index.ts", diff --git a/packages/helpers/package.json b/packages/helpers/package.json index fae90919..a07fe854 100644 --- a/packages/helpers/package.json +++ b/packages/helpers/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/helpers", - "version": "0.2.56", + "version": "0.2.57", "private": true, "type": "module", "description": "Safe convenience helpers for WrNexus request contexts and common application flows.", diff --git a/packages/i18n/package.json b/packages/i18n/package.json index 452643de..5f5ecae7 100644 --- a/packages/i18n/package.json +++ b/packages/i18n/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/i18n", - "version": "0.2.56", + "version": "0.2.57", "private": true, "type": "module", "main": "src/index.ts", diff --git a/packages/jwt/package.json b/packages/jwt/package.json index 18a721e4..64017856 100644 --- a/packages/jwt/package.json +++ b/packages/jwt/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/jwt", - "version": "0.2.56", + "version": "0.2.57", "private": true, "type": "module", "main": "src/index.ts", diff --git a/packages/mobile/package.json b/packages/mobile/package.json index ef9973f2..2ea4c373 100644 --- a/packages/mobile/package.json +++ b/packages/mobile/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/mobile", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/native/package.json b/packages/native/package.json index 91506316..ed9f2412 100644 --- a/packages/native/package.json +++ b/packages/native/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/native", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/oauth/package.json b/packages/oauth/package.json index 141d1dbf..5f9ee9ec 100644 --- a/packages/oauth/package.json +++ b/packages/oauth/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/oauth", - "version": "0.2.56", + "version": "0.2.57", "private": true, "type": "module", "main": "src/index.ts", diff --git a/packages/pubsub/package.json b/packages/pubsub/package.json index 247c7d49..01108ea4 100644 --- a/packages/pubsub/package.json +++ b/packages/pubsub/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/pubsub", - "version": "0.2.56", + "version": "0.2.57", "private": true, "type": "module", "main": "src/index.ts", diff --git a/packages/queue/package.json b/packages/queue/package.json index 501cffac..85b5e21b 100644 --- a/packages/queue/package.json +++ b/packages/queue/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/queue", - "version": "0.2.56", + "version": "0.2.57", "private": true, "type": "module", "main": "src/index.ts", diff --git a/packages/reactive/package.json b/packages/reactive/package.json index 2b7cf430..34833a5f 100644 --- a/packages/reactive/package.json +++ b/packages/reactive/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/reactive", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/router/package.json b/packages/router/package.json index c6416e8e..36a2f8b1 100644 --- a/packages/router/package.json +++ b/packages/router/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/router", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/ssr/package.json b/packages/ssr/package.json index 16353205..3ec62226 100644 --- a/packages/ssr/package.json +++ b/packages/ssr/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/ssr", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/styles/README.md b/packages/styles/README.md index 555aaf02..4037b990 100644 --- a/packages/styles/README.md +++ b/packages/styles/README.md @@ -106,6 +106,7 @@ Tokens are emitted as `--wire-` custom properties, **except** the reserved type ThemeTokens = Record; interface ThemeConfig { + palette?: ThemePaletteName | CustomThemePalette; default?: string; // theme used when no cookie is present themes?: Record; // deep-merged over built-in light/dark } @@ -117,7 +118,30 @@ interface ResolvedTheme { } ``` -Built-in token keys (both `light` and `dark`): `color-scheme`, `color-bg`, `color-surface`, `color-surface-2`, `color-text`, `color-muted`, `color-border`, `color-primary`, `color-primary-hover`, `color-primary-contrast`, `color-danger`, `color-success`, `color-warning`, `radius`, `radius-sm`, `font-sans`, `shadow-1`. +Built-in palettes are `blue`, `indigo`, `violet`, `emerald`, `cyan`, `rose`, +`amber`, and `slate`. Each supplies primary, secondary, info, success, warning, +danger/error, hover, and contrast colors to every light/dark theme. Built-in +token keys also include surfaces, text, borders, radii, fonts, and shadows. + +A custom palette is intentionally complete, so components never fall back to an +unrelated blue status or action color: + +```ts +theme: { + palette: { + primary: "#7c3aed", + primaryHover: "#6d28d9", + primaryContrast: "#ffffff", + secondary: "#db2777", + secondaryHover: "#be185d", + secondaryContrast: "#ffffff", + info: "#2563eb", + success: "#059669", + warning: "#d97706", + danger: "#dc2626", + }, +} +``` The client runtime (`renderThemeRuntime`) exposes `window.wireTheme` with `{ get, set, toggle, bind, themes }`, wires up any `[data-wire-theme-toggle]` and `[data-wire-theme-set]` elements on load, and persists the choice to the `wire-theme` cookie (`max-age` 1 year, `samesite=lax`). `toggle()` cycles through the configured theme names in order. @@ -135,6 +159,7 @@ export default { port: 3000, db: { driver: "sqlite", url: "app.db" }, theme: { + palette: "violet", default: "dark", themes: { light: { "color-primary": "#7c3aed" }, // override one token; rest inherited diff --git a/packages/styles/package.json b/packages/styles/package.json index 2e879d8c..bc828528 100644 --- a/packages/styles/package.json +++ b/packages/styles/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/styles", - "version": "0.2.56", + "version": "0.2.57", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/styles/src/index.ts b/packages/styles/src/index.ts index be9e6658..bc89a3d5 100644 --- a/packages/styles/src/index.ts +++ b/packages/styles/src/index.ts @@ -19,9 +19,17 @@ export { loadAppConfig, loadRawConfig, headToString, resolveProfile, loadEnv } f export { findStyleEntry, bundleCss } from "./styles.ts"; export type { FontConfig, GoogleFont, LocalFontFace, FontDisplay } from "./fonts.ts"; export { renderFontHead, renderProductionFontHead, fontCspSources } from "./fonts.ts"; -export type { ThemeConfig, ThemeTokens, ResolvedTheme } from "./theme.ts"; +export type { + ThemeConfig, + ThemeTokens, + ResolvedTheme, + ThemePaletteName, + CustomThemePalette, +} from "./theme.ts"; export { DEFAULT_THEMES, + THEME_PALETTES, + THEME_PALETTE_NAMES, THEME_COOKIE, THEME_CSS_HREF, THEME_JS_HREF, diff --git a/packages/styles/src/theme.ts b/packages/styles/src/theme.ts index 25042bc9..eff1c448 100644 --- a/packages/styles/src/theme.ts +++ b/packages/styles/src/theme.ts @@ -13,7 +13,36 @@ export type ThemeTokens = Record; +export const THEME_PALETTE_NAMES = [ + "blue", + "indigo", + "violet", + "emerald", + "cyan", + "rose", + "amber", + "slate", +] as const; + +export type ThemePaletteName = (typeof THEME_PALETTE_NAMES)[number]; + +/** Required semantic colors for a custom application palette. */ +export interface CustomThemePalette { + primary: string; + primaryHover: string; + primaryContrast: string; + secondary: string; + secondaryHover: string; + secondaryContrast: string; + info: string; + success: string; + warning: string; + danger: string; +} + export interface ThemeConfig { + /** Built-in palette name, or a complete custom semantic color palette. */ + palette?: ThemePaletteName | CustomThemePalette; /** Name of the theme used when no `wire-theme` cookie is present. */ default?: string; /** Named token maps. Deep-merged over the framework's built-in light/dark. */ @@ -31,6 +60,142 @@ export const THEME_COOKIE = "wire-theme"; export const THEME_CSS_HREF = "/__wrnexus/theme.css"; export const THEME_JS_HREF = "/__wrnexus/theme.js"; +export const THEME_PALETTES: Record = { + blue: { + primary: "#2563eb", + primaryHover: "#1d4ed8", + primaryContrast: "#ffffff", + secondary: "#475569", + secondaryHover: "#334155", + secondaryContrast: "#ffffff", + info: "#0284c7", + success: "#16a34a", + warning: "#d97706", + danger: "#dc2626", + }, + indigo: { + primary: "#4f46e5", + primaryHover: "#4338ca", + primaryContrast: "#ffffff", + secondary: "#7c3aed", + secondaryHover: "#6d28d9", + secondaryContrast: "#ffffff", + info: "#0284c7", + success: "#16a34a", + warning: "#d97706", + danger: "#dc2626", + }, + violet: { + primary: "#7c3aed", + primaryHover: "#6d28d9", + primaryContrast: "#ffffff", + secondary: "#db2777", + secondaryHover: "#be185d", + secondaryContrast: "#ffffff", + info: "#2563eb", + success: "#059669", + warning: "#d97706", + danger: "#dc2626", + }, + emerald: { + primary: "#059669", + primaryHover: "#047857", + primaryContrast: "#ffffff", + secondary: "#0f766e", + secondaryHover: "#115e59", + secondaryContrast: "#ffffff", + info: "#0284c7", + success: "#16a34a", + warning: "#d97706", + danger: "#dc2626", + }, + cyan: { + primary: "#0891b2", + primaryHover: "#0e7490", + primaryContrast: "#ffffff", + secondary: "#2563eb", + secondaryHover: "#1d4ed8", + secondaryContrast: "#ffffff", + info: "#0284c7", + success: "#16a34a", + warning: "#d97706", + danger: "#dc2626", + }, + rose: { + primary: "#e11d48", + primaryHover: "#be123c", + primaryContrast: "#ffffff", + secondary: "#9333ea", + secondaryHover: "#7e22ce", + secondaryContrast: "#ffffff", + info: "#2563eb", + success: "#059669", + warning: "#d97706", + danger: "#dc2626", + }, + amber: { + primary: "#d97706", + primaryHover: "#b45309", + primaryContrast: "#ffffff", + secondary: "#92400e", + secondaryHover: "#78350f", + secondaryContrast: "#ffffff", + info: "#0284c7", + success: "#15803d", + warning: "#d97706", + danger: "#dc2626", + }, + slate: { + primary: "#475569", + primaryHover: "#334155", + primaryContrast: "#ffffff", + secondary: "#0f172a", + secondaryHover: "#020617", + secondaryContrast: "#ffffff", + info: "#0369a1", + success: "#15803d", + warning: "#b45309", + danger: "#b91c1c", + }, +}; + +function paletteTokens(palette: CustomThemePalette): ThemeTokens { + return { + "color-primary": palette.primary, + "color-primary-hover": palette.primaryHover, + "color-primary-contrast": palette.primaryContrast, + "color-secondary": palette.secondary, + "color-secondary-hover": palette.secondaryHover, + "color-secondary-contrast": palette.secondaryContrast, + "color-info": palette.info, + "color-success": palette.success, + "color-warning": palette.warning, + "color-danger": palette.danger, + "color-error": palette.danger, + }; +} + +function resolvePalette(value?: ThemeConfig["palette"]): CustomThemePalette { + if (!value) return THEME_PALETTES.blue; + if (typeof value === "string") { + const palette = THEME_PALETTES[value]; + if (!palette) { + throw new Error( + `Unknown theme palette "${value}". Choose one of: ${THEME_PALETTE_NAMES.join(", ")}.`, + ); + } + return palette; + } + const missing = Object.keys(THEME_PALETTES.blue).filter((key) => { + const color = value[key as keyof CustomThemePalette]; + return typeof color !== "string" || !color.trim(); + }); + if (missing.length) { + throw new Error(`Custom theme palette is missing required colors: ${missing.join(", ")}.`); + } + return value; +} + /** Built-in themes so components have tokens out of the box. */ export const DEFAULT_THEMES: Record = { light: { @@ -44,9 +209,14 @@ export const DEFAULT_THEMES: Record = { "color-primary": "#2563eb", "color-primary-hover": "#1d4ed8", "color-primary-contrast": "#ffffff", + "color-secondary": "#475569", + "color-secondary-hover": "#334155", + "color-secondary-contrast": "#ffffff", + "color-info": "#0284c7", "color-danger": "#dc2626", "color-success": "#16a34a", "color-warning": "#d97706", + "color-error": "#dc2626", radius: "8px", "radius-sm": "5px", "font-sans": "system-ui, -apple-system, Segoe UI, Roboto, sans-serif", @@ -63,9 +233,14 @@ export const DEFAULT_THEMES: Record = { "color-primary": "#6c8cff", "color-primary-hover": "#8aa2ff", "color-primary-contrast": "#0b1020", + "color-secondary": "#a78bfa", + "color-secondary-hover": "#c4b5fd", + "color-secondary-contrast": "#0b1020", + "color-info": "#38bdf8", "color-danger": "#f87171", "color-success": "#4ade80", "color-warning": "#fbbf24", + "color-error": "#f87171", radius: "10px", "radius-sm": "6px", "font-sans": "system-ui, -apple-system, Segoe UI, Roboto, sans-serif", @@ -75,13 +250,18 @@ export const DEFAULT_THEMES: Record = { /** Merge the user's theme config over the built-in defaults. */ export function resolveThemeConfig(config?: ThemeConfig): ResolvedTheme { + const semanticTokens = paletteTokens(resolvePalette(config?.palette)); const themes: Record = {}; const names = new Set([ ...Object.keys(DEFAULT_THEMES), ...Object.keys(config?.themes ?? {}), ]); for (const name of names) { - themes[name] = { ...(DEFAULT_THEMES[name] ?? {}), ...(config?.themes?.[name] ?? {}) }; + themes[name] = { + ...(DEFAULT_THEMES[name] ?? DEFAULT_THEMES.light), + ...semanticTokens, + ...(config?.themes?.[name] ?? {}), + }; } const list = Object.keys(themes); const preferred = config?.default && themes[config.default] ? config.default : undefined; diff --git a/packages/styles/test/theme.test.ts b/packages/styles/test/theme.test.ts index a238e21f..48bca863 100644 --- a/packages/styles/test/theme.test.ts +++ b/packages/styles/test/theme.test.ts @@ -1,11 +1,50 @@ import { test, expect } from "bun:test"; import { + THEME_PALETTE_NAMES, + THEME_PALETTES, resolveThemeConfig, resolveThemeName, renderThemeCss, renderThemeRuntime, } from "../src/index.ts"; +test("ships eight complete semantic color palettes", () => { + expect(THEME_PALETTE_NAMES).toHaveLength(8); + for (const name of THEME_PALETTE_NAMES) { + expect(Object.keys(THEME_PALETTES[name])).toEqual([ + "primary", + "primaryHover", + "primaryContrast", + "secondary", + "secondaryHover", + "secondaryContrast", + "info", + "success", + "warning", + "danger", + ]); + } +}); + +test("named palettes populate semantic tokens in every theme", () => { + const t = resolveThemeConfig({ palette: "violet" }); + for (const name of t.names) { + expect(t.themes[name]["color-primary"]).toBe(THEME_PALETTES.violet.primary); + expect(t.themes[name]["color-secondary"]).toBe(THEME_PALETTES.violet.secondary); + expect(t.themes[name]["color-info"]).toBe(THEME_PALETTES.violet.info); + expect(t.themes[name]["color-error"]).toBe(THEME_PALETTES.violet.danger); + } +}); + +test("custom palettes require every semantic color", () => { + expect(() => resolveThemeConfig({ palette: { primary: "#000" } as never })).toThrow( + "primaryHover, primaryContrast, secondary", + ); + expect(() => resolveThemeConfig({ palette: "unknown" as never })).toThrow( + "Unknown theme palette", + ); +}); + test("resolveThemeConfig merges user tokens over built-in light/dark", () => { const t = resolveThemeConfig({ default: "dark", themes: { dark: { "color-primary": "#abc" } } }); expect(t.default).toBe("dark"); diff --git a/packages/test/package.json b/packages/test/package.json index 0bb61d4a..4ade71e3 100644 --- a/packages/test/package.json +++ b/packages/test/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/test", - "version": "0.2.56", + "version": "0.2.57", "private": true, "type": "module", "main": "src/index.ts", diff --git a/packages/tracking/package.json b/packages/tracking/package.json index b190d3e2..0a2605df 100644 --- a/packages/tracking/package.json +++ b/packages/tracking/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/tracking", - "version": "0.2.56", + "version": "0.2.57", "private": true, "type": "module", "main": "src/index.ts", diff --git a/packages/ui/package.json b/packages/ui/package.json index efcdcd11..f2212f7b 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/ui", - "version": "0.2.56", + "version": "0.2.57", "private": true, "type": "module", "main": "src/index.ts", diff --git a/packages/ui/test/ui.test.ts b/packages/ui/test/ui.test.ts index db877fb9..4dc6d2c2 100644 --- a/packages/ui/test/ui.test.ts +++ b/packages/ui/test/ui.test.ts @@ -62,6 +62,9 @@ test("component-system CSS includes responsive, theme-token, focus, and reduced- expect(css).toContain("@keyframes wire-component-enter"); expect(css).toContain("@keyframes wire-dialog-enter"); expect(css).toContain("@media (hover: hover) and (pointer: fine)"); + expect(css).toContain("--color-violet-600: var(--wire-color-primary)"); + expect(css).toContain("--color-blue-600: var(--wire-color-info)"); + expect(css).toContain("--color-red-600: var(--wire-color-danger)"); }); test.each(uiComponentNames())("bundled UI component %s compiles", (name) => { diff --git a/packages/ui/ui.css b/packages/ui/ui.css index f20fe432..7743be70 100644 --- a/packages/ui/ui.css +++ b/packages/ui/ui.css @@ -233,15 +233,15 @@ } .wire-badge--success { background: var(--wire-color-success); - color: #05210f; + color: var(--wire-color-primary-contrast); } .wire-badge--danger { background: var(--wire-color-danger); - color: #fff; + color: var(--wire-color-primary-contrast); } .wire-badge--warning { background: var(--wire-color-warning); - color: #201400; + color: var(--wire-color-primary-contrast); } /* --- Alert ---------------------------------------------------------------- */ @@ -264,7 +264,7 @@ color: var(--wire-color-muted); } .wire-alert--info { - border-left-color: var(--wire-color-primary); + border-left-color: var(--wire-color-info); } .wire-alert--success { border-left-color: var(--wire-color-success); @@ -950,6 +950,52 @@ --wire-ease-emphasized: cubic-bezier(0.16, 1, 0.3, 1); } +/* Tailwind v4 color bridge. Existing utility-authored components inherit the + * configured semantic palette without requiring generated per-palette markup. */ +[data-component] { + --color-violet-50: color-mix(in srgb, var(--wire-color-primary) 7%, white); + --color-violet-100: color-mix(in srgb, var(--wire-color-primary) 14%, white); + --color-violet-200: color-mix(in srgb, var(--wire-color-primary) 25%, white); + --color-violet-300: color-mix(in srgb, var(--wire-color-primary) 42%, white); + --color-violet-400: color-mix(in srgb, var(--wire-color-primary) 72%, white); + --color-violet-500: var(--wire-color-primary); + --color-violet-600: var(--wire-color-primary); + --color-violet-700: var(--wire-color-primary-hover); + --color-violet-800: color-mix(in srgb, var(--wire-color-primary-hover) 82%, black); + --color-violet-900: color-mix(in srgb, var(--wire-color-primary-hover) 65%, black); + --color-violet-950: color-mix(in srgb, var(--wire-color-primary-hover) 42%, black); + --color-indigo-50: var(--color-violet-50); + --color-indigo-100: var(--color-violet-100); + --color-indigo-200: var(--color-violet-200); + --color-indigo-300: var(--color-violet-300); + --color-indigo-400: var(--color-violet-400); + --color-indigo-500: var(--color-violet-500); + --color-indigo-600: var(--color-violet-600); + --color-indigo-700: var(--color-violet-700); + --color-indigo-800: var(--color-violet-800); + --color-indigo-900: var(--color-violet-900); + --color-indigo-950: var(--color-violet-950); + --color-blue-500: var(--wire-color-info); + --color-blue-600: var(--wire-color-info); + --color-blue-700: color-mix(in srgb, var(--wire-color-info) 80%, black); + --color-emerald-500: var(--wire-color-success); + --color-emerald-600: var(--wire-color-success); + --color-emerald-700: color-mix(in srgb, var(--wire-color-success) 80%, black); + --color-green-500: var(--wire-color-success); + --color-green-600: var(--wire-color-success); + --color-amber-500: var(--wire-color-warning); + --color-amber-600: var(--wire-color-warning); + --color-amber-700: color-mix(in srgb, var(--wire-color-warning) 80%, black); + --color-yellow-500: var(--wire-color-warning); + --color-red-400: color-mix(in srgb, var(--wire-color-danger) 75%, white); + --color-red-500: var(--wire-color-danger); + --color-red-600: var(--wire-color-danger); + --color-red-700: color-mix(in srgb, var(--wire-color-danger) 80%, black); + --color-rose-500: var(--wire-color-danger); + --color-rose-600: var(--wire-color-danger); + --color-rose-700: color-mix(in srgb, var(--wire-color-danger) 80%, black); +} + [data-component] { animation: wire-component-enter var(--wire-motion-slow) var(--wire-ease-emphasized) both; } diff --git a/packages/uploader/package.json b/packages/uploader/package.json index 6acd24e3..dd8d5e49 100644 --- a/packages/uploader/package.json +++ b/packages/uploader/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/uploader", - "version": "0.2.56", + "version": "0.2.57", "private": true, "type": "module", "main": "src/index.ts", diff --git a/packages/validation/package.json b/packages/validation/package.json index 3e646f1d..e3de71b8 100644 --- a/packages/validation/package.json +++ b/packages/validation/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/validation", - "version": "0.2.56", + "version": "0.2.57", "private": true, "type": "module", "main": "src/index.ts", diff --git a/update-package-versions.mjs b/update-package-versions.mjs index bbdc730a..3005c588 100644 --- a/update-package-versions.mjs +++ b/update-package-versions.mjs @@ -1,7 +1,7 @@ import { existsSync, readdirSync, readFileSync, writeFileSync } from "node:fs"; import { join } from "node:path"; -const version = "0.2.56"; +const version = "0.2.57"; const dependencyGroups = [ "dependencies",