@adukiorg/anza 0.2.8 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/bin/anza/anza-linux-arm64 +0 -0
- package/bin/anza/anza-linux-x64 +0 -0
- package/bin/anza/anza-macos-arm64 +0 -0
- package/bin/anza/anza-macos-x64 +0 -0
- package/bin/anza/anza-windows-x64.exe +0 -0
- package/bin/anza/index.js +0 -0
- package/bin/create/index.js +0 -0
- package/bin/create/run.js +5 -3
- package/package.json +1 -1
- package/src/core/api/index.js +26 -1
- package/src/core/router/boot.js +37 -3
- package/src/core/router/cascade.js +5 -5
- package/src/core/router/container.js +17 -10
- package/src/core/router/graph.js +20 -7
- package/src/core/router/index.js +8 -2
- package/src/core/router/intercept.js +20 -2
- package/src/core/ui/define/container.js +1 -1
- package/src/core/ui/define/element.js +9 -2
- package/src/core/ui/define/orchestrator.js +8 -1
- package/src/core/ui/defs/dock.js +2 -2
- package/src/elements/forms/input/index.js +1 -2
- package/src/styles/base.css +15 -0
- package/src/tokens/primitives/colors.css +62 -45
- package/src/tokens/primitives/motion.css +0 -8
- package/src/tokens/primitives/spacing.css +9 -17
- package/src/tokens/primitives/typography.css +32 -29
- package/src/tokens/registered/dimensions.css +3 -3
- package/src/tokens/semantic/components.css +74 -76
- package/src/tokens/semantic/dark.css +34 -34
- package/src/tokens/semantic/light.css +35 -38
package/CHANGELOG.md
CHANGED
|
@@ -17,6 +17,14 @@ Versioning follows [Semantic Versioning](https://semver.org/).
|
|
|
17
17
|
|
|
18
18
|
---
|
|
19
19
|
|
|
20
|
+
## [0.3.0] — 2026-06-13
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- Sync `tools/Cargo.toml` version with npm package version (0.2.1 → 0.3.0)
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
20
28
|
## [0.2.8] — 2026-06-09
|
|
21
29
|
|
|
22
30
|
### Fixed
|
|
Binary file
|
package/bin/anza/anza-linux-x64
CHANGED
|
Binary file
|
|
Binary file
|
package/bin/anza/anza-macos-x64
CHANGED
|
Binary file
|
|
Binary file
|
package/bin/anza/index.js
CHANGED
|
File without changes
|
package/bin/create/index.js
CHANGED
|
File without changes
|
package/bin/create/run.js
CHANGED
|
@@ -36,7 +36,9 @@ const HTML = (name) => `<!DOCTYPE html>
|
|
|
36
36
|
|
|
37
37
|
<script type="module" src="/dist/app.js"></script>
|
|
38
38
|
</head>
|
|
39
|
-
<body
|
|
39
|
+
<body>
|
|
40
|
+
<dock-main id="main"></dock-main>
|
|
41
|
+
</body>
|
|
40
42
|
</html>
|
|
41
43
|
`;
|
|
42
44
|
|
|
@@ -48,10 +50,10 @@ import { dock } from '@adukiorg/anza/ui';
|
|
|
48
50
|
import '@adukiorg/anza/theme';
|
|
49
51
|
|
|
50
52
|
// Service Worker
|
|
51
|
-
navigator.serviceWorker.register('/dist/sw.js');
|
|
53
|
+
navigator.serviceWorker.register('/dist/sw.js', { type: 'module' });
|
|
52
54
|
|
|
53
55
|
// Layout shell
|
|
54
|
-
dock('main'
|
|
56
|
+
dock('main');
|
|
55
57
|
|
|
56
58
|
// Pages
|
|
57
59
|
import './pages/index.js';
|
package/package.json
CHANGED
package/src/core/api/index.js
CHANGED
|
@@ -18,6 +18,24 @@ import { prefixes } from './prefixes/index.js';
|
|
|
18
18
|
import { events } from './events/index.js';
|
|
19
19
|
import { cache as apiCache } from './caches/index.js';
|
|
20
20
|
|
|
21
|
+
let cache = null;
|
|
22
|
+
|
|
23
|
+
export function sync() {
|
|
24
|
+
if (typeof document === 'undefined') return;
|
|
25
|
+
const el = document.getElementById('anza-state');
|
|
26
|
+
if (el) {
|
|
27
|
+
try {
|
|
28
|
+
cache = JSON.parse(el.textContent);
|
|
29
|
+
} catch (_) {
|
|
30
|
+
cache = null;
|
|
31
|
+
}
|
|
32
|
+
} else {
|
|
33
|
+
cache = null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
sync();
|
|
38
|
+
|
|
21
39
|
// Register global telemetry inbound interceptor to emit requests status/errors events
|
|
22
40
|
pipeline.inbound((responseOrError) => {
|
|
23
41
|
const requestId = responseOrError?.requestId;
|
|
@@ -58,6 +76,11 @@ pipeline.inbound((responseOrError) => {
|
|
|
58
76
|
*/
|
|
59
77
|
async function request(url, method, body, opts = {}) {
|
|
60
78
|
const resolvedUrl = prefixes.resolve(url);
|
|
79
|
+
|
|
80
|
+
if (method === 'GET' && cache && resolvedUrl in cache) {
|
|
81
|
+
return JSON.parse(JSON.stringify(cache[resolvedUrl]));
|
|
82
|
+
}
|
|
83
|
+
|
|
61
84
|
const headers = new Headers(opts.headers || {});
|
|
62
85
|
|
|
63
86
|
// Auto-serialize JSON bodies
|
|
@@ -133,6 +156,8 @@ async function request(url, method, body, opts = {}) {
|
|
|
133
156
|
|
|
134
157
|
export const api = {
|
|
135
158
|
get: (url, opts) => request(url, 'GET', null, opts),
|
|
159
|
+
state: () => cache ? JSON.parse(JSON.stringify(cache.__route || {})) : null,
|
|
160
|
+
sync,
|
|
136
161
|
post: (url, body, opts) => request(url, 'POST', body, opts),
|
|
137
162
|
put: (url, body, opts) => request(url, 'PUT', body, opts),
|
|
138
163
|
patch: (url, body, opts) => request(url, 'PATCH', body, opts),
|
|
@@ -153,6 +178,6 @@ export const api = {
|
|
|
153
178
|
emit: (event, detail) => events.emit(event, detail)
|
|
154
179
|
};
|
|
155
180
|
|
|
156
|
-
export { pipeline, PlatformError, execute, retry, createNDJSONTransform, stream, upload, prefixes, events, apiCache as cache };
|
|
181
|
+
export { pipeline, PlatformError, execute, retry, createNDJSONTransform, stream, upload, prefixes, events, apiCache as cache, sync };
|
|
157
182
|
|
|
158
183
|
|
package/src/core/router/boot.js
CHANGED
|
@@ -6,9 +6,14 @@
|
|
|
6
6
|
* has resolved. This is what makes a hard refresh on a deep route work: the
|
|
7
7
|
* first match no longer races ahead of element registration.
|
|
8
8
|
*
|
|
9
|
-
* Source: tasks.md Phase 1
|
|
9
|
+
* Source: tasks.md Phase 1 / Migration 2
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
+
import { root as graphRoot } from './graph.js';
|
|
13
|
+
import { registerContainer } from './container.js';
|
|
14
|
+
|
|
15
|
+
const ROOT = 'main';
|
|
16
|
+
|
|
12
17
|
// Outstanding prerequisites the initial match must wait for.
|
|
13
18
|
const gates = new Set();
|
|
14
19
|
|
|
@@ -34,6 +39,24 @@ export function gate(promise) {
|
|
|
34
39
|
return promise;
|
|
35
40
|
}
|
|
36
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Wires <main id="main"> into the graph. Must be called after DOMContentLoaded
|
|
44
|
+
* so the element is guaranteed to exist. Throws a hard error if absent —
|
|
45
|
+
* there is no body fallback.
|
|
46
|
+
*/
|
|
47
|
+
function anchor() {
|
|
48
|
+
console.log('[Boot] anchor() started.');
|
|
49
|
+
const el = document.getElementById('main');
|
|
50
|
+
if (!el) {
|
|
51
|
+
throw new Error(
|
|
52
|
+
`[Router] <main id="main"> is required but was not found in the document. ` +
|
|
53
|
+
`Ensure your HTML shell contains exactly one <main id="main"> before any scripts run.`
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
graphRoot.ref = new WeakRef(el);
|
|
57
|
+
registerContainer(ROOT, el, null); // null parent — root has no parent
|
|
58
|
+
}
|
|
59
|
+
|
|
37
60
|
/**
|
|
38
61
|
* Fires the initial route match once the document is interactive and all gates
|
|
39
62
|
* have settled. Idempotent — only the first call wins.
|
|
@@ -41,27 +64,37 @@ export function gate(promise) {
|
|
|
41
64
|
* @param {() => any | Promise<any>} emitFn - runs the initial match + emit.
|
|
42
65
|
*/
|
|
43
66
|
export function boot(emitFn) {
|
|
67
|
+
console.log('[Boot] boot() called. booted =', booted);
|
|
44
68
|
if (booted) return;
|
|
45
69
|
trigger = emitFn;
|
|
46
70
|
|
|
47
71
|
const launch = async () => {
|
|
72
|
+
console.log('[Boot] launch() started. booted =', booted, 'gates count =', gates.size);
|
|
48
73
|
if (booted) return;
|
|
74
|
+
|
|
75
|
+
anchor(); // 1. wire main#main into the graph — must be first
|
|
76
|
+
|
|
49
77
|
// Snapshot current gates; settle them all (failures are non-fatal — a
|
|
50
78
|
// single element that fails to define must not wedge the whole router).
|
|
51
79
|
const pending = Array.from(gates);
|
|
80
|
+
console.log('[Boot] pending gates:', pending);
|
|
52
81
|
if (pending.length) {
|
|
53
82
|
await Promise.allSettled(pending);
|
|
54
83
|
}
|
|
84
|
+
console.log('[Boot] all gates settled!');
|
|
55
85
|
booted = true;
|
|
56
86
|
const fn = trigger;
|
|
57
87
|
trigger = null;
|
|
58
|
-
if (fn)
|
|
88
|
+
if (fn) {
|
|
89
|
+
console.log('[Boot] executing initial match trigger...');
|
|
90
|
+
await fn(); // 3. first match + emit
|
|
91
|
+
}
|
|
59
92
|
};
|
|
60
93
|
|
|
61
94
|
if (typeof document !== 'undefined' && document.readyState === 'loading') {
|
|
62
95
|
document.addEventListener('DOMContentLoaded', () => { launch(); }, { once: true });
|
|
63
96
|
} else {
|
|
64
|
-
launch
|
|
97
|
+
setTimeout(launch, 0);
|
|
65
98
|
}
|
|
66
99
|
}
|
|
67
100
|
|
|
@@ -79,4 +112,5 @@ export function reset() {
|
|
|
79
112
|
gates.clear();
|
|
80
113
|
booted = false;
|
|
81
114
|
trigger = null;
|
|
115
|
+
graphRoot.ref = null; // invalidate the WeakRef so anchor() re-queries on next boot
|
|
82
116
|
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* Source: tasks.md Phase 5
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import { get, element as resolve
|
|
12
|
+
import { get, element as resolve } from './graph.js';
|
|
13
13
|
import { path } from './lca.js';
|
|
14
14
|
|
|
15
15
|
/** Yields one frame so a freshly-connected element can register itself. */
|
|
@@ -23,10 +23,10 @@ function frame() {
|
|
|
23
23
|
* containers from the deepest currently-mounted ancestor downward.
|
|
24
24
|
*
|
|
25
25
|
* @param {string} target - container name that must end up in the DOM.
|
|
26
|
-
* @param {string} [current='
|
|
26
|
+
* @param {string} [current='main'] - the source container to path from.
|
|
27
27
|
* @returns {Promise<Element|null>} the resolved target element.
|
|
28
28
|
*/
|
|
29
|
-
export async function ensure(target, current = '
|
|
29
|
+
export async function ensure(target, current = 'main') {
|
|
30
30
|
// Already mounted — nothing to do.
|
|
31
31
|
const live = resolve(target);
|
|
32
32
|
if (live) return live;
|
|
@@ -41,13 +41,13 @@ export async function ensure(target, current = 'body') {
|
|
|
41
41
|
if (el && el.isConnected) mounted = node;
|
|
42
42
|
else break;
|
|
43
43
|
}
|
|
44
|
-
if (!mounted) mounted = root
|
|
44
|
+
if (!mounted) mounted = get('main'); // fall back to the graph root
|
|
45
45
|
|
|
46
46
|
// Mount sequentially from the first unmounted node down to the target.
|
|
47
47
|
const start = segments.indexOf(mounted) + 1;
|
|
48
48
|
for (let i = start; i < segments.length; i++) {
|
|
49
49
|
const node = segments[i];
|
|
50
|
-
const parentEl = node.parent?.ref?.deref() ??
|
|
50
|
+
const parentEl = node.parent?.ref?.deref() ?? null;
|
|
51
51
|
if (!parentEl || !parentEl.isConnected) {
|
|
52
52
|
throw new Error(`CascadeError: parent '${node.parent?.name}' is disconnected while mounting '${node.name}'`);
|
|
53
53
|
}
|
|
@@ -26,11 +26,14 @@ function ensureObserver() {
|
|
|
26
26
|
|
|
27
27
|
const attach = () => {
|
|
28
28
|
if (observer) return;
|
|
29
|
+
const root = document.getElementById('main');
|
|
30
|
+
if (!root) return; // framework root absent — nothing to observe
|
|
31
|
+
|
|
29
32
|
observer = new MutationObserver(() => {
|
|
30
33
|
let stillWaiting = false;
|
|
31
34
|
for (const selector of observedSelectors) {
|
|
32
35
|
if (!graphElement(selector)) {
|
|
33
|
-
const el =
|
|
36
|
+
const el = root.querySelector(selector); // scope to root, not document
|
|
34
37
|
if (el) registerContainer(selector, el);
|
|
35
38
|
else stillWaiting = true;
|
|
36
39
|
}
|
|
@@ -40,7 +43,8 @@ function ensureObserver() {
|
|
|
40
43
|
observer = null;
|
|
41
44
|
}
|
|
42
45
|
});
|
|
43
|
-
|
|
46
|
+
|
|
47
|
+
observer.observe(root, { childList: true, subtree: true });
|
|
44
48
|
};
|
|
45
49
|
|
|
46
50
|
if (typeof requestIdleCallback !== 'undefined') {
|
|
@@ -55,9 +59,10 @@ function ensureObserver() {
|
|
|
55
59
|
*
|
|
56
60
|
* @param {string} name - unique registry key (or CSS selector).
|
|
57
61
|
* @param {HTMLElement} element - the DOM element instance.
|
|
58
|
-
* @param {string} [parent='
|
|
62
|
+
* @param {string|null} [parent='main'] - parent container key in the graph.
|
|
63
|
+
* Pass null explicitly when registering the root (no parent).
|
|
59
64
|
*/
|
|
60
|
-
export function registerContainer(name, element, parent = '
|
|
65
|
+
export function registerContainer(name, element, parent = 'main') {
|
|
61
66
|
add(name, element, parent);
|
|
62
67
|
}
|
|
63
68
|
|
|
@@ -86,8 +91,9 @@ export function getContainer(name) {
|
|
|
86
91
|
if (el) return el;
|
|
87
92
|
|
|
88
93
|
if (isSelector(name) && typeof document !== 'undefined') {
|
|
94
|
+
const root = document.getElementById('main');
|
|
89
95
|
try {
|
|
90
|
-
el =
|
|
96
|
+
el = root ? root.querySelector(name) : null;
|
|
91
97
|
if (el) {
|
|
92
98
|
registerContainer(name, el);
|
|
93
99
|
return el;
|
|
@@ -100,15 +106,16 @@ export function getContainer(name) {
|
|
|
100
106
|
return el ?? undefined;
|
|
101
107
|
}
|
|
102
108
|
|
|
103
|
-
// Warn when a plain key shadows a real DOM element
|
|
109
|
+
// Warn when a plain key shadows a real DOM element inside the root.
|
|
104
110
|
if (typeof name === 'string' && typeof document !== 'undefined') {
|
|
111
|
+
const root = document.getElementById('main');
|
|
105
112
|
let queryResult = null;
|
|
106
|
-
try { queryResult =
|
|
113
|
+
try { queryResult = root?.querySelector(name) ?? null; } catch (_) {}
|
|
107
114
|
if (queryResult) {
|
|
108
115
|
console.warn(
|
|
109
|
-
`[Router] Container name "${name}"
|
|
110
|
-
`but is being treated as a registry key.
|
|
111
|
-
`
|
|
116
|
+
`[Router] Container name "${name}" matches a DOM element inside <main id="main"> ` +
|
|
117
|
+
`but is being treated as a registry key. ` +
|
|
118
|
+
`Use a selector prefix or register it via registerContainer().`
|
|
112
119
|
);
|
|
113
120
|
}
|
|
114
121
|
}
|
package/src/core/router/graph.js
CHANGED
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
*
|
|
8
8
|
* Every node holds a WeakRef to its element so an unmounted container can be
|
|
9
9
|
* garbage-collected without a manual unregister. A FinalizationRegistry prunes
|
|
10
|
-
* stale nodes. The virtual root '
|
|
10
|
+
* stale nodes. The virtual root 'main' always exists; its WeakRef is filled in
|
|
11
|
+
* by boot.js anchor() once <main id="main"> is live in the DOM.
|
|
11
12
|
*
|
|
12
13
|
* Source: tasks.md Phase 3
|
|
13
14
|
*/
|
|
@@ -28,8 +29,13 @@ class Node {
|
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
const nodes = new Map();
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
|
|
33
|
+
// The permanent root node. ref is null at module-evaluation time because
|
|
34
|
+
// modules may be evaluated before the parser reaches <main id="main">.
|
|
35
|
+
// boot.js fills in the WeakRef during anchor().
|
|
36
|
+
const root = new Node('main', null, null);
|
|
37
|
+
root.depth = 0;
|
|
38
|
+
nodes.set('main', root);
|
|
33
39
|
|
|
34
40
|
// Explicit unregistrations. element() returns undefined for a name in this set
|
|
35
41
|
// so a just-unmounted container is not confused with a GC'd one (RT bug 8.2).
|
|
@@ -61,14 +67,20 @@ function detach(name) {
|
|
|
61
67
|
*
|
|
62
68
|
* @param {string} name - unique registry key.
|
|
63
69
|
* @param {Element} el - the container element.
|
|
64
|
-
* @param {string} [parent='
|
|
70
|
+
* @param {string} [parent='main'] - parent registry key.
|
|
65
71
|
* @returns {Node} the inserted node.
|
|
66
72
|
*/
|
|
67
|
-
export function add(name, el, parent = '
|
|
73
|
+
export function add(name, el, parent = 'main') {
|
|
68
74
|
gone.delete(name);
|
|
69
75
|
|
|
70
76
|
const existing = nodes.get(name);
|
|
71
|
-
if (existing
|
|
77
|
+
if (existing) {
|
|
78
|
+
if (existing === root) {
|
|
79
|
+
// Root re-registration from anchor(): refresh the WeakRef and return.
|
|
80
|
+
// The root cannot be reparented and must not spawn a duplicate node.
|
|
81
|
+
existing.ref = new WeakRef(el);
|
|
82
|
+
return existing;
|
|
83
|
+
}
|
|
72
84
|
const prev = existing.ref?.deref();
|
|
73
85
|
if (prev && prev !== el) {
|
|
74
86
|
throw new Error(`ContainerError: Singleton violation — '${name}' is already mounted. A second instance cannot register while the first is active.`);
|
|
@@ -138,7 +150,8 @@ export function clear() {
|
|
|
138
150
|
nodes.clear();
|
|
139
151
|
root.children.clear();
|
|
140
152
|
gone.clear();
|
|
141
|
-
|
|
153
|
+
root.ref = null; // reset the WeakRef so anchor() re-queries on next boot
|
|
154
|
+
nodes.set('main', root); // root is 'main'; 'body' has no special status
|
|
142
155
|
}
|
|
143
156
|
|
|
144
157
|
export { Node, root };
|
package/src/core/router/index.js
CHANGED
|
@@ -13,7 +13,8 @@ import {
|
|
|
13
13
|
setup, destroy,
|
|
14
14
|
addGuard, setNotFound,
|
|
15
15
|
guardsApi, missApi,
|
|
16
|
-
on, nav, registerNavigator
|
|
16
|
+
on, nav, registerNavigator,
|
|
17
|
+
getShell, getWin
|
|
17
18
|
} from './intercept.js';
|
|
18
19
|
import {
|
|
19
20
|
navigate,
|
|
@@ -103,7 +104,12 @@ export const router = {
|
|
|
103
104
|
|
|
104
105
|
// Lifecycle
|
|
105
106
|
setup,
|
|
106
|
-
destroy
|
|
107
|
+
destroy,
|
|
108
|
+
|
|
109
|
+
// Root accessors — useful for components that need the shell element
|
|
110
|
+
// without importing intercept directly.
|
|
111
|
+
shell: getShell, // router.shell() → <main id="main">
|
|
112
|
+
win: getWin // router.win() → window
|
|
107
113
|
};
|
|
108
114
|
|
|
109
115
|
// Auto-bootstrap client-side navigation listeners on client load
|
|
@@ -19,6 +19,16 @@ let guards = [];
|
|
|
19
19
|
let notFoundHandler = null;
|
|
20
20
|
let ready = false;
|
|
21
21
|
|
|
22
|
+
// Module-level root slots — captured once in setup(), cleared in destroy().
|
|
23
|
+
let win = null;
|
|
24
|
+
let shell = null; // WeakRef<HTMLElement> — points to <main id="main">
|
|
25
|
+
|
|
26
|
+
/** Returns the live <main id="main"> element, or null if GC'd. */
|
|
27
|
+
export function getShell() { return shell?.deref() ?? null; }
|
|
28
|
+
|
|
29
|
+
/** Returns the captured window reference. */
|
|
30
|
+
export function getWin() { return win; }
|
|
31
|
+
|
|
22
32
|
// Navigation API listener references for teardown
|
|
23
33
|
let navListener = null;
|
|
24
34
|
let successListener = null;
|
|
@@ -110,6 +120,13 @@ export function setup() {
|
|
|
110
120
|
if (typeof window === 'undefined' || !window.navigation) return;
|
|
111
121
|
ready = true;
|
|
112
122
|
|
|
123
|
+
win = window;
|
|
124
|
+
const mainEl = document.getElementById('main');
|
|
125
|
+
// Only wrap in WeakRef when the element exists. setup() may be called at
|
|
126
|
+
// module-evaluation time (before DOMContentLoaded), so the element may not
|
|
127
|
+
// be in the DOM yet. anchor() in boot.js is the authoritative check that
|
|
128
|
+
// throws if the element is absent at boot time.
|
|
129
|
+
if (mainEl) shell = new WeakRef(mainEl);
|
|
113
130
|
navListener = (event) => {
|
|
114
131
|
// Skip cross-origin navigations, file downloads, or same-document hash scrolls
|
|
115
132
|
if (!event.canIntercept || event.hashChange || event.downloadRequest) {
|
|
@@ -163,7 +180,7 @@ export function setup() {
|
|
|
163
180
|
try {
|
|
164
181
|
for (let i = 0; i < chain.length; i++) {
|
|
165
182
|
if (!getContainer(chain[i])) {
|
|
166
|
-
await ensure(chain[i], chain[i - 1] ?? '
|
|
183
|
+
await ensure(chain[i], chain[i - 1] ?? 'main'); // was 'body'
|
|
167
184
|
}
|
|
168
185
|
}
|
|
169
186
|
} catch (err) {
|
|
@@ -289,7 +306,8 @@ export function setup() {
|
|
|
289
306
|
export function destroy() {
|
|
290
307
|
if (!ready) return;
|
|
291
308
|
ready = false;
|
|
292
|
-
|
|
309
|
+
win = null;
|
|
310
|
+
shell = null;
|
|
293
311
|
if (typeof window !== 'undefined' && window.navigation) {
|
|
294
312
|
if (navListener) window.navigation.removeEventListener('navigate', navListener);
|
|
295
313
|
if (successListener) window.navigation.removeEventListener('navigatesuccess', successListener);
|
|
@@ -56,7 +56,7 @@ export function container(tag, spec, base = import.meta.url) {
|
|
|
56
56
|
// Strategy 1: Element-scoped transition (Chrome 147+, concurrent-safe)
|
|
57
57
|
if (typeof this.startViewTransition === 'function') {
|
|
58
58
|
try {
|
|
59
|
-
const vt = this.startViewTransition(
|
|
59
|
+
const vt = this.startViewTransition(doSwap);
|
|
60
60
|
await vt.ready;
|
|
61
61
|
} catch (err) {
|
|
62
62
|
if (err?.name !== 'AbortError') console.warn('[UI Container] Scoped VT aborted:', err);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BaseElement } from '../base.js';
|
|
2
|
-
import { scheduleFrame } from '../schedule.js';
|
|
2
|
+
import { scheduleFrame, yieldTask } from '../schedule.js';
|
|
3
3
|
import { router } from '../../router/index.js';
|
|
4
4
|
import { specRegistry, internalsMap, initializedMap, pendingUpdatesMap, updateScheduledMap } from './state.js';
|
|
5
5
|
import { preloadResources } from './utils.js';
|
|
@@ -84,7 +84,7 @@ export function element(tag, spec, base) {
|
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
};
|
|
87
|
-
window.addEventListener('
|
|
87
|
+
window.addEventListener('anza:hmr:css', hmrHandler);
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
|
|
@@ -138,6 +138,13 @@ export function element(tag, spec, base) {
|
|
|
138
138
|
return;
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
+
if (typeof document !== 'undefined' && document.readyState === 'loading') {
|
|
142
|
+
await yieldTask();
|
|
143
|
+
if (!this.ctrl || this.ctrl.signal.aborted || !this.isConnected) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
141
148
|
if (templateNode && this.shadowRoot.childNodes.length === 0) {
|
|
142
149
|
this.shadowRoot.appendChild(templateNode.cloneNode(true));
|
|
143
150
|
}
|
|
@@ -11,6 +11,7 @@ export function initOrchestrator() {
|
|
|
11
11
|
if (typeof window !== 'undefined') {
|
|
12
12
|
dispose?.();
|
|
13
13
|
dispose = router.on('found', async ({ tag, params, query, hash, chain, direction }) => {
|
|
14
|
+
console.log('[Orchestrator] FOUND event received for tag:', tag);
|
|
14
15
|
// Resolve the top-level layout element in the chain
|
|
15
16
|
const topTag = chain && chain.length > 0 ? chain[0].tag : tag;
|
|
16
17
|
const topParams = chain && chain.length > 0 ? chain[0].params : params;
|
|
@@ -21,16 +22,22 @@ export function initOrchestrator() {
|
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
const spec = specRegistry.get(topTag.toLowerCase());
|
|
25
|
+
console.log('[Orchestrator] Resolved spec for tag', topTag, ':', spec);
|
|
24
26
|
// Resolve the render target: the last container in the `via` chain, or
|
|
25
27
|
// the legacy single `container`. Without either there is nothing to mount.
|
|
26
28
|
const target = (Array.isArray(spec?.via) && spec.via.length)
|
|
27
29
|
? spec.via[spec.via.length - 1]
|
|
28
30
|
: spec?.container;
|
|
29
|
-
|
|
31
|
+
console.log('[Orchestrator] Target container name:', target);
|
|
32
|
+
if (!spec || !target) {
|
|
33
|
+
console.warn('[Orchestrator] Early return: missing spec or target');
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
30
36
|
|
|
31
37
|
// Use Advanced Container Registry lookup instead of blind DOM query.
|
|
32
38
|
// The interceptor's cascade has already ensured the chain is mounted.
|
|
33
39
|
const containerEl = router.getContainer(target);
|
|
40
|
+
console.log('[Orchestrator] containerEl found in registry:', containerEl);
|
|
34
41
|
if (!containerEl) {
|
|
35
42
|
console.warn(`Target container "${target}" not found in DOM for element <${topTag}>`);
|
|
36
43
|
return;
|
package/src/core/ui/defs/dock.js
CHANGED
|
@@ -28,7 +28,7 @@ const CONTAIN = ':host { contain: layout; display: block; }';
|
|
|
28
28
|
*/
|
|
29
29
|
export function dock(name, config = {}, base) {
|
|
30
30
|
const tag = config.tag ?? `dock-${name}`;
|
|
31
|
-
const parent = config.parent ?? '
|
|
31
|
+
const parent = config.parent ?? 'main';
|
|
32
32
|
|
|
33
33
|
const spec = translate(config);
|
|
34
34
|
|
|
@@ -106,7 +106,7 @@ async function swap(el, options = {}) {
|
|
|
106
106
|
|
|
107
107
|
if (typeof this.startViewTransition === 'function') {
|
|
108
108
|
try {
|
|
109
|
-
this._tx = this.startViewTransition(
|
|
109
|
+
this._tx = this.startViewTransition(go);
|
|
110
110
|
await this._tx.finished;
|
|
111
111
|
} catch (err) {
|
|
112
112
|
if (err?.name !== 'AbortError') console.warn('[Native UI] dock scoped VT aborted:', err);
|
|
@@ -67,7 +67,7 @@ ui.element('ui-input', {
|
|
|
67
67
|
const input = tags.one('input');
|
|
68
68
|
input.disabled = disabled;
|
|
69
69
|
}
|
|
70
|
-
};
|
|
70
|
+
}, import.meta.url);
|
|
71
71
|
|
|
72
72
|
function syncAttributes(el, tags) {
|
|
73
73
|
const input = tags.one('input');
|
|
@@ -100,4 +100,3 @@ function validate(el, internals, input) {
|
|
|
100
100
|
internals.setValidity({});
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
|
-
}, import.meta.url);
|
package/src/styles/base.css
CHANGED
|
@@ -63,4 +63,19 @@
|
|
|
63
63
|
outline: 2px solid var(--color-border-focus);
|
|
64
64
|
outline-offset: 2px;
|
|
65
65
|
}
|
|
66
|
+
|
|
67
|
+
/* Prevent layout shift of un-upgraded custom elements */
|
|
68
|
+
:not(:defined) {
|
|
69
|
+
display: block;
|
|
70
|
+
opacity: 0;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* Full-page containers reserve viewport height */
|
|
74
|
+
[id="main"]:not(:defined),
|
|
75
|
+
main:not(:defined),
|
|
76
|
+
body > :not(:defined),
|
|
77
|
+
[class*="page"]:not(:defined),
|
|
78
|
+
[class*="dock"]:not(:defined) {
|
|
79
|
+
min-height: 100vh;
|
|
80
|
+
}
|
|
66
81
|
}
|
|
@@ -1,54 +1,71 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* tokens/primitives/colors.css
|
|
3
3
|
*
|
|
4
|
-
* Perceptually uniform
|
|
5
|
-
*
|
|
6
|
-
* Source: doc 26 §3
|
|
4
|
+
* Perceptually uniform color scales using OKLCH.
|
|
5
|
+
* Converted from hex values provided in the design system.
|
|
7
6
|
*/
|
|
8
7
|
|
|
9
8
|
:root {
|
|
10
|
-
/*
|
|
11
|
-
--
|
|
12
|
-
--
|
|
13
|
-
--
|
|
14
|
-
--
|
|
15
|
-
--
|
|
16
|
-
--
|
|
17
|
-
--
|
|
18
|
-
--
|
|
19
|
-
--
|
|
20
|
-
--
|
|
21
|
-
--
|
|
9
|
+
/* Gray scale — 11-step perceptual scale */
|
|
10
|
+
--gray-0: oklch(100% 0 0);
|
|
11
|
+
--gray-50: oklch(98% 0.002 264);
|
|
12
|
+
--gray-100: oklch(95% 0.004 264);
|
|
13
|
+
--gray-200: oklch(90% 0.006 264);
|
|
14
|
+
--gray-300: oklch(80% 0.008 264);
|
|
15
|
+
--gray-400: oklch(65% 0.01 264);
|
|
16
|
+
--gray-500: oklch(50% 0.012 264);
|
|
17
|
+
--gray-600: oklch(38% 0.014 264);
|
|
18
|
+
--gray-700: oklch(28% 0.016 264);
|
|
19
|
+
--gray-800: oklch(18% 0.018 264);
|
|
20
|
+
--gray-900: oklch(10% 0.02 264);
|
|
21
|
+
--gray-950: oklch(5% 0.022 264);
|
|
22
22
|
|
|
23
|
-
/*
|
|
24
|
-
--
|
|
25
|
-
--
|
|
26
|
-
--
|
|
27
|
-
--
|
|
28
|
-
--
|
|
29
|
-
--
|
|
30
|
-
--
|
|
31
|
-
--
|
|
32
|
-
--
|
|
33
|
-
--
|
|
34
|
-
--
|
|
35
|
-
--color-neutral-950: oklch(6% 0 0);
|
|
36
|
-
--color-neutral-1000: oklch(0% 0 0);
|
|
23
|
+
/* Brand green palette — based on #07a45f, #09d379 */
|
|
24
|
+
--brand-50: oklch(96% 0.08 155);
|
|
25
|
+
--brand-100: oklch(90% 0.12 155);
|
|
26
|
+
--brand-200: oklch(82% 0.16 155);
|
|
27
|
+
--brand-300: oklch(72% 0.18 155);
|
|
28
|
+
--brand-400: oklch(62% 0.20 155);
|
|
29
|
+
--brand-500: oklch(55% 0.22 155);
|
|
30
|
+
--brand-600: oklch(48% 0.20 155);
|
|
31
|
+
--brand-700: oklch(40% 0.18 155);
|
|
32
|
+
--brand-800: oklch(32% 0.16 155);
|
|
33
|
+
--brand-900: oklch(24% 0.14 155);
|
|
34
|
+
--brand-950: oklch(15% 0.12 155);
|
|
37
35
|
|
|
38
|
-
/*
|
|
39
|
-
--
|
|
40
|
-
--
|
|
41
|
-
--
|
|
42
|
-
|
|
43
|
-
--
|
|
44
|
-
--
|
|
45
|
-
--
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
--
|
|
49
|
-
--
|
|
50
|
-
|
|
51
|
-
--
|
|
52
|
-
--
|
|
53
|
-
--
|
|
36
|
+
/* Success palette — based on #10b981 */
|
|
37
|
+
--success-50: oklch(96% 0.08 155);
|
|
38
|
+
--success-100: oklch(88% 0.12 155);
|
|
39
|
+
--success-200: oklch(78% 0.16 155);
|
|
40
|
+
--success-300: oklch(68% 0.18 155);
|
|
41
|
+
--success-400: oklch(58% 0.20 155);
|
|
42
|
+
--success-500: oklch(52% 0.22 155);
|
|
43
|
+
--success-600: oklch(45% 0.20 155);
|
|
44
|
+
|
|
45
|
+
/* Error palette — based on #ec4b19 */
|
|
46
|
+
--error-50: oklch(96% 0.06 35);
|
|
47
|
+
--error-100: oklch(90% 0.10 35);
|
|
48
|
+
--error-200: oklch(80% 0.14 35);
|
|
49
|
+
--error-300: oklch(70% 0.18 35);
|
|
50
|
+
--error-400: oklch(60% 0.22 35);
|
|
51
|
+
--error-500: oklch(54% 0.24 35);
|
|
52
|
+
--error-600: oklch(47% 0.22 35);
|
|
53
|
+
|
|
54
|
+
/* Warn palette — based on #fa6436 */
|
|
55
|
+
--warn-50: oklch(96% 0.08 45);
|
|
56
|
+
--warn-100: oklch(90% 0.12 45);
|
|
57
|
+
--warn-200: oklch(80% 0.16 45);
|
|
58
|
+
--warn-300: oklch(70% 0.20 45);
|
|
59
|
+
--warn-400: oklch(60% 0.24 45);
|
|
60
|
+
--warn-500: oklch(54% 0.26 45);
|
|
61
|
+
--warn-600: oklch(47% 0.24 45);
|
|
62
|
+
|
|
63
|
+
/* Info palette */
|
|
64
|
+
--info-50: oklch(96% 0.06 240);
|
|
65
|
+
--info-100: oklch(90% 0.10 240);
|
|
66
|
+
--info-200: oklch(80% 0.14 240);
|
|
67
|
+
--info-300: oklch(70% 0.18 240);
|
|
68
|
+
--info-400: oklch(60% 0.22 240);
|
|
69
|
+
--info-500: oklch(54% 0.24 240);
|
|
70
|
+
--info-600: oklch(47% 0.22 240);
|
|
54
71
|
}
|
|
@@ -2,33 +2,25 @@
|
|
|
2
2
|
* tokens/primitives/motion.css
|
|
3
3
|
*
|
|
4
4
|
* Durations and easing curves for transitions and animations.
|
|
5
|
-
* Features central global prefers-reduced-motion token-layer overrides.
|
|
6
|
-
* Source: doc 26 §4
|
|
7
5
|
*/
|
|
8
6
|
|
|
9
7
|
:root {
|
|
10
8
|
/* Durations */
|
|
11
|
-
--duration-instant: 50ms;
|
|
12
9
|
--duration-fast: 100ms;
|
|
13
10
|
--duration-normal: 200ms;
|
|
14
11
|
--duration-slow: 300ms;
|
|
15
|
-
--duration-slower: 500ms;
|
|
16
12
|
|
|
17
13
|
/* Easing curves */
|
|
18
|
-
--ease-default: cubic-bezier(0.4, 0, 0.2, 1);
|
|
19
14
|
--ease-in: cubic-bezier(0.4, 0, 1, 1);
|
|
20
15
|
--ease-out: cubic-bezier(0, 0, 0.2, 1);
|
|
21
16
|
--ease-in-out: cubic-bezier(0.4, 0, 0.6, 1);
|
|
22
|
-
--ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
23
17
|
--ease-linear: linear;
|
|
24
18
|
}
|
|
25
19
|
|
|
26
20
|
@media (prefers-reduced-motion: reduce) {
|
|
27
21
|
:root {
|
|
28
|
-
--duration-instant: 0ms;
|
|
29
22
|
--duration-fast: 0ms;
|
|
30
23
|
--duration-normal: 0ms;
|
|
31
24
|
--duration-slow: 0ms;
|
|
32
|
-
--duration-slower: 0ms;
|
|
33
25
|
}
|
|
34
26
|
}
|
|
@@ -2,26 +2,18 @@
|
|
|
2
2
|
* tokens/primitives/spacing.css
|
|
3
3
|
*
|
|
4
4
|
* Fixed spacing scale using rem units based on a 4px increment system.
|
|
5
|
-
* Source: doc 26 §4
|
|
6
5
|
*/
|
|
7
6
|
|
|
8
7
|
:root {
|
|
9
8
|
--space-px: 1px;
|
|
10
9
|
--space-0: 0px;
|
|
11
|
-
--space-
|
|
12
|
-
--space-
|
|
13
|
-
--space-
|
|
14
|
-
--space-
|
|
15
|
-
--space-
|
|
16
|
-
--space-
|
|
17
|
-
--space-
|
|
18
|
-
--space-
|
|
19
|
-
--space-
|
|
20
|
-
--space-8: 2rem; /* 32px */
|
|
21
|
-
--space-10: 2.5rem; /* 40px */
|
|
22
|
-
--space-12: 3rem; /* 48px */
|
|
23
|
-
--space-16: 4rem; /* 64px */
|
|
24
|
-
--space-20: 5rem; /* 80px */
|
|
25
|
-
--space-24: 6rem; /* 96px */
|
|
26
|
-
--space-32: 8rem; /* 128px */
|
|
10
|
+
--space-xs: 0.25rem; /* 4px */
|
|
11
|
+
--space-sm: 0.5rem; /* 8px */
|
|
12
|
+
--space-md: 1rem; /* 16px */
|
|
13
|
+
--space-lg: 1.5rem; /* 24px */
|
|
14
|
+
--space-xl: 2rem; /* 32px */
|
|
15
|
+
--space-2xl: 3rem; /* 48px */
|
|
16
|
+
--space-3xl: 4rem; /* 64px */
|
|
17
|
+
--space-4xl: 6rem; /* 96px */
|
|
18
|
+
--space-5xl: 8rem; /* 128px */
|
|
27
19
|
}
|
|
@@ -2,45 +2,48 @@
|
|
|
2
2
|
* tokens/primitives/typography.css
|
|
3
3
|
*
|
|
4
4
|
* Typography scales, weights, line-heights, letter-spacings, and font stacks.
|
|
5
|
-
*
|
|
5
|
+
* Google Fonts: Inter, JetBrains Mono, IBM Plex Sans
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap");
|
|
9
|
+
@import url("https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap");
|
|
10
|
+
@import url("https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,100..900;1,100..900&display=swap");
|
|
11
|
+
|
|
8
12
|
:root {
|
|
9
13
|
/* Modular type scale (1.25 ratio) */
|
|
10
|
-
--
|
|
11
|
-
--
|
|
12
|
-
--
|
|
13
|
-
--
|
|
14
|
-
--
|
|
15
|
-
--
|
|
16
|
-
--
|
|
17
|
-
--
|
|
18
|
-
--
|
|
19
|
-
--font-size-5xl: 3.75rem; /* 60px */
|
|
14
|
+
--text-xs: 0.75rem; /* 12px */
|
|
15
|
+
--text-sm: 0.875rem; /* 14px */
|
|
16
|
+
--text-md: 1rem; /* 16px */
|
|
17
|
+
--text-lg: 1.25rem; /* 20px */
|
|
18
|
+
--text-xl: 1.5rem; /* 24px */
|
|
19
|
+
--text-2xl: 1.875rem; /* 30px */
|
|
20
|
+
--text-3xl: 2.25rem; /* 36px */
|
|
21
|
+
--text-4xl: 3rem; /* 48px */
|
|
22
|
+
--text-5xl: 3.75rem; /* 60px */
|
|
20
23
|
|
|
21
24
|
/* Font weights */
|
|
22
|
-
--font-
|
|
23
|
-
--font-
|
|
24
|
-
--font-
|
|
25
|
-
--font-
|
|
26
|
-
--font-
|
|
25
|
+
--font-light: 300;
|
|
26
|
+
--font-normal: 400;
|
|
27
|
+
--font-medium: 500;
|
|
28
|
+
--font-semibold: 600;
|
|
29
|
+
--font-bold: 700;
|
|
27
30
|
|
|
28
31
|
/* Line heights */
|
|
29
|
-
--
|
|
30
|
-
--
|
|
31
|
-
--
|
|
32
|
-
--
|
|
33
|
-
--
|
|
32
|
+
--leading-tight: 1.25;
|
|
33
|
+
--leading-snug: 1.375;
|
|
34
|
+
--leading-normal: 1.5;
|
|
35
|
+
--leading-relaxed: 1.625;
|
|
36
|
+
--leading-loose: 2;
|
|
34
37
|
|
|
35
38
|
/* Letter spacing */
|
|
36
|
-
--
|
|
37
|
-
--
|
|
38
|
-
--
|
|
39
|
-
--
|
|
40
|
-
--
|
|
39
|
+
--tracking-tight: -0.025em;
|
|
40
|
+
--tracking-normal: 0;
|
|
41
|
+
--tracking-wide: 0.025em;
|
|
42
|
+
--tracking-wider: 0.05em;
|
|
43
|
+
--tracking-widest: 0.1em;
|
|
41
44
|
|
|
42
45
|
/* Font families */
|
|
43
|
-
--font-
|
|
44
|
-
--font-
|
|
45
|
-
--font-
|
|
46
|
+
--font-sans: 'Inter', system-ui, -apple-system, sans-serif;
|
|
47
|
+
--font-serif: 'IBM Plex Sans', serif;
|
|
48
|
+
--font-mono: 'JetBrains Mono', monospace;
|
|
46
49
|
}
|
|
@@ -9,19 +9,19 @@
|
|
|
9
9
|
@property --space-4 {
|
|
10
10
|
syntax: '<length>';
|
|
11
11
|
inherits: true;
|
|
12
|
-
initial-value:
|
|
12
|
+
initial-value: 16px;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
@property --radius-md {
|
|
16
16
|
syntax: '<length>';
|
|
17
17
|
inherits: true;
|
|
18
|
-
initial-value:
|
|
18
|
+
initial-value: 6px;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
@property --font-size-base {
|
|
22
22
|
syntax: '<length>';
|
|
23
23
|
inherits: true;
|
|
24
|
-
initial-value:
|
|
24
|
+
initial-value: 16px;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
@property --duration-normal {
|
|
@@ -2,124 +2,122 @@
|
|
|
2
2
|
* tokens/semantic/components.css
|
|
3
3
|
*
|
|
4
4
|
* Semantic component-level design tokens.
|
|
5
|
-
* Consolidates recurring component-specific tokens from individual elements
|
|
6
|
-
* into a shared semantic layer for consistency across the design system.
|
|
7
5
|
*/
|
|
8
6
|
|
|
9
7
|
:root {
|
|
10
8
|
/* Form Controls */
|
|
11
|
-
--input-bg: var(--
|
|
12
|
-
--input-border: var(--
|
|
13
|
-
--input-border-focus: var(--
|
|
9
|
+
--input-bg: var(--background);
|
|
10
|
+
--input-border: var(--border);
|
|
11
|
+
--input-border-focus: var(--border-focus);
|
|
14
12
|
--input-radius: var(--radius-md);
|
|
15
|
-
--input-font-size: var(--
|
|
16
|
-
--input-padding-y: var(--space-
|
|
17
|
-
--input-padding-x: var(--space-
|
|
18
|
-
--input-text-color: var(--
|
|
19
|
-
|
|
20
|
-
--textarea-bg: var(--
|
|
21
|
-
--textarea-border: var(--
|
|
22
|
-
--textarea-border-focus: var(--
|
|
13
|
+
--input-font-size: var(--text-md);
|
|
14
|
+
--input-padding-y: var(--space-sm);
|
|
15
|
+
--input-padding-x: var(--space-md);
|
|
16
|
+
--input-text-color: var(--foreground);
|
|
17
|
+
|
|
18
|
+
--textarea-bg: var(--background);
|
|
19
|
+
--textarea-border: var(--border);
|
|
20
|
+
--textarea-border-focus: var(--border-focus);
|
|
23
21
|
--textarea-radius: var(--radius-md);
|
|
24
|
-
--textarea-font-size: var(--
|
|
25
|
-
--textarea-padding-y: var(--space-
|
|
26
|
-
--textarea-padding-x: var(--space-
|
|
27
|
-
--textarea-text-color: var(--
|
|
28
|
-
|
|
29
|
-
--check-bg: var(--
|
|
30
|
-
--check-bg-checked: var(--
|
|
31
|
-
--check-border: var(--
|
|
32
|
-
--check-border-focus: var(--
|
|
22
|
+
--textarea-font-size: var(--text-md);
|
|
23
|
+
--textarea-padding-y: var(--space-sm);
|
|
24
|
+
--textarea-padding-x: var(--space-md);
|
|
25
|
+
--textarea-text-color: var(--foreground);
|
|
26
|
+
|
|
27
|
+
--check-bg: var(--background);
|
|
28
|
+
--check-bg-checked: var(--primary);
|
|
29
|
+
--check-border: var(--border);
|
|
30
|
+
--check-border-focus: var(--border-focus);
|
|
33
31
|
--check-radius: var(--radius-sm);
|
|
34
|
-
--check-size: var(--space-
|
|
35
|
-
--check-color: var(--
|
|
32
|
+
--check-size: var(--space-lg);
|
|
33
|
+
--check-color: var(--primary-foreground);
|
|
36
34
|
|
|
37
|
-
--radio-bg: var(--
|
|
38
|
-
--radio-bg-checked: var(--
|
|
39
|
-
--radio-border: var(--
|
|
40
|
-
--radio-border-focus: var(--
|
|
35
|
+
--radio-bg: var(--background);
|
|
36
|
+
--radio-bg-checked: var(--primary);
|
|
37
|
+
--radio-border: var(--border);
|
|
38
|
+
--radio-border-focus: var(--border-focus);
|
|
41
39
|
--radio-radius: var(--radius-full);
|
|
42
|
-
--radio-size: var(--space-
|
|
43
|
-
--radio-color: var(--
|
|
44
|
-
|
|
45
|
-
--switch-bg: var(--
|
|
46
|
-
--switch-bg-on: var(--
|
|
47
|
-
--switch-thumb-color: var(--
|
|
48
|
-
--switch-width: var(--space-
|
|
49
|
-
--switch-height: var(--space-
|
|
50
|
-
--switch-thumb-size: calc(var(--switch-height) - var(--space-
|
|
51
|
-
|
|
52
|
-
--select-bg: var(--
|
|
53
|
-
--select-border: var(--
|
|
54
|
-
--select-border-focus: var(--
|
|
40
|
+
--radio-size: var(--space-lg);
|
|
41
|
+
--radio-color: var(--primary-foreground);
|
|
42
|
+
|
|
43
|
+
--switch-bg: var(--border-strong);
|
|
44
|
+
--switch-bg-on: var(--primary);
|
|
45
|
+
--switch-thumb-color: var(--primary-foreground);
|
|
46
|
+
--switch-width: var(--space-xl);
|
|
47
|
+
--switch-height: var(--space-lg);
|
|
48
|
+
--switch-thumb-size: calc(var(--switch-height) - var(--space-xs));
|
|
49
|
+
|
|
50
|
+
--select-bg: var(--background);
|
|
51
|
+
--select-border: var(--border);
|
|
52
|
+
--select-border-focus: var(--border-focus);
|
|
55
53
|
--select-radius: var(--radius-md);
|
|
56
|
-
--select-font-size: var(--
|
|
57
|
-
--select-padding-y: var(--space-
|
|
58
|
-
--select-padding-x: var(--space-
|
|
59
|
-
--select-text-color: var(--
|
|
60
|
-
|
|
61
|
-
--upload-bg: var(--
|
|
62
|
-
--upload-border: var(--
|
|
63
|
-
--upload-border-focus: var(--
|
|
54
|
+
--select-font-size: var(--text-md);
|
|
55
|
+
--select-padding-y: var(--space-sm);
|
|
56
|
+
--select-padding-x: var(--space-md);
|
|
57
|
+
--select-text-color: var(--foreground);
|
|
58
|
+
|
|
59
|
+
--upload-bg: var(--background);
|
|
60
|
+
--upload-border: var(--border);
|
|
61
|
+
--upload-border-focus: var(--border-focus);
|
|
64
62
|
--upload-radius: var(--radius-lg);
|
|
65
|
-
--upload-padding: var(--space-
|
|
66
|
-
--upload-color: var(--
|
|
63
|
+
--upload-padding: var(--space-xl);
|
|
64
|
+
--upload-color: var(--foreground-muted);
|
|
67
65
|
|
|
68
66
|
/* Feedback */
|
|
69
67
|
--alert-radius: var(--radius-md);
|
|
70
|
-
--alert-bg: var(--
|
|
71
|
-
--alert-color: var(--
|
|
72
|
-
--alert-border: var(--
|
|
68
|
+
--alert-bg: var(--background-elevated);
|
|
69
|
+
--alert-color: var(--foreground);
|
|
70
|
+
--alert-border: var(--border);
|
|
73
71
|
|
|
74
|
-
--skeleton-bg: var(--
|
|
72
|
+
--skeleton-bg: var(--foreground-disabled);
|
|
75
73
|
--skeleton-radius: var(--radius-md);
|
|
76
74
|
--skeleton-width: 100%;
|
|
77
|
-
--skeleton-height: var(--space-
|
|
75
|
+
--skeleton-height: var(--space-md);
|
|
78
76
|
|
|
79
77
|
/* Data Display */
|
|
80
78
|
--card-radius: var(--radius-lg);
|
|
81
79
|
|
|
82
|
-
--stat-label: var(--
|
|
83
|
-
--stat-value: var(--
|
|
80
|
+
--stat-label: var(--text-xs);
|
|
81
|
+
--stat-value: var(--text-3xl);
|
|
84
82
|
|
|
85
83
|
/* Navigation */
|
|
86
|
-
--link-color: var(--
|
|
87
|
-
--link-color-hover: var(--
|
|
88
|
-
--link-color-active: var(--
|
|
84
|
+
--link-color: var(--foreground-link);
|
|
85
|
+
--link-color-hover: var(--primary-hover);
|
|
86
|
+
--link-color-active: var(--primary-active);
|
|
89
87
|
|
|
90
88
|
/* Layout */
|
|
91
|
-
--stack-gap: var(--space-
|
|
89
|
+
--stack-gap: var(--space-md);
|
|
92
90
|
|
|
93
|
-
--grid-gap: var(--space-
|
|
91
|
+
--grid-gap: var(--space-md);
|
|
94
92
|
--grid-cols: repeat(auto-fit, minmax(250px, 1fr));
|
|
95
93
|
|
|
96
|
-
--surface-bg: var(--
|
|
94
|
+
--surface-bg: var(--background);
|
|
97
95
|
--surface-border: transparent;
|
|
98
96
|
--surface-shadow: none;
|
|
99
97
|
--surface-radius: var(--radius-none);
|
|
100
98
|
|
|
101
99
|
/* Overlay */
|
|
102
100
|
--dialog-radius: var(--radius-lg);
|
|
103
|
-
--dialog-shadow: var(--shadow-
|
|
101
|
+
--dialog-shadow: var(--shadow-xl);
|
|
104
102
|
|
|
105
|
-
--popover-bg: var(--
|
|
106
|
-
--popover-border: var(--
|
|
107
|
-
--popover-shadow: var(--shadow-
|
|
103
|
+
--popover-bg: var(--background-elevated);
|
|
104
|
+
--popover-border: var(--border);
|
|
105
|
+
--popover-shadow: var(--shadow-lg);
|
|
108
106
|
--popover-radius: var(--radius-md);
|
|
109
107
|
|
|
110
|
-
--tooltip-bg: var(--
|
|
111
|
-
--tooltip-color: var(--
|
|
108
|
+
--tooltip-bg: var(--background-inverse);
|
|
109
|
+
--tooltip-color: var(--foreground-inverse);
|
|
112
110
|
--tooltip-radius: var(--radius-sm);
|
|
113
111
|
|
|
114
|
-
--menu-bg: var(--
|
|
115
|
-
--menu-border: var(--
|
|
112
|
+
--menu-bg: var(--background-elevated);
|
|
113
|
+
--menu-border: var(--border);
|
|
116
114
|
--menu-shadow: var(--shadow-lg);
|
|
117
115
|
--menu-radius: var(--radius-md);
|
|
118
116
|
|
|
119
|
-
--drawer-shadow: var(--shadow-
|
|
120
|
-
--drawer-width: min(calc(var(--space-
|
|
117
|
+
--drawer-shadow: var(--shadow-xl);
|
|
118
|
+
--drawer-width: min(calc(var(--space-5xl) * 3), 85vw);
|
|
121
119
|
|
|
122
120
|
--sheet-radius: var(--radius-lg);
|
|
123
|
-
--sheet-shadow: var(--shadow-
|
|
124
|
-
--sheet-max-width: min(calc(var(--space-
|
|
121
|
+
--sheet-shadow: var(--shadow-xl);
|
|
122
|
+
--sheet-max-width: min(calc(var(--space-5xl) * 6), 100vw);
|
|
125
123
|
}
|
|
@@ -2,60 +2,60 @@
|
|
|
2
2
|
* tokens/semantic/dark.css
|
|
3
3
|
*
|
|
4
4
|
* Semantic design token overrides for the Dark theme.
|
|
5
|
-
* Integrates with data-theme attribute and OS media preference (guarded to respect user selection).
|
|
6
|
-
* Source: doc 26 §3
|
|
7
5
|
*/
|
|
8
6
|
|
|
9
7
|
[data-theme="dark"] {
|
|
10
8
|
/* Surfaces */
|
|
11
|
-
--
|
|
12
|
-
--
|
|
13
|
-
--
|
|
14
|
-
--color-surface-inverse: var(--color-neutral-50);
|
|
9
|
+
--background: var(--gray-950);
|
|
10
|
+
--background-elevated: var(--gray-900);
|
|
11
|
+
--background-inverse: var(--gray-50);
|
|
15
12
|
|
|
16
13
|
/* Content (Text & Icons) */
|
|
17
|
-
--
|
|
18
|
-
--
|
|
19
|
-
--
|
|
20
|
-
--
|
|
21
|
-
--
|
|
14
|
+
--foreground: var(--gray-50);
|
|
15
|
+
--foreground-muted: var(--gray-400);
|
|
16
|
+
--foreground-disabled: var(--gray-600);
|
|
17
|
+
--foreground-inverse: var(--gray-900);
|
|
18
|
+
--foreground-link: var(--brand-300);
|
|
22
19
|
|
|
23
20
|
/* Interactive Elements */
|
|
24
|
-
--
|
|
25
|
-
--
|
|
26
|
-
--
|
|
27
|
-
--
|
|
21
|
+
--primary: var(--brand-400);
|
|
22
|
+
--primary-hover: var(--brand-300);
|
|
23
|
+
--primary-active: var(--brand-200);
|
|
24
|
+
--primary-focus: var(--brand-400);
|
|
25
|
+
--primary-disabled: var(--gray-700);
|
|
26
|
+
--primary-foreground: var(--gray-0);
|
|
28
27
|
|
|
29
28
|
/* Borders */
|
|
30
|
-
--
|
|
31
|
-
--
|
|
32
|
-
--
|
|
29
|
+
--border: var(--gray-800);
|
|
30
|
+
--border-strong: var(--gray-600);
|
|
31
|
+
--border-focus: var(--brand-400);
|
|
33
32
|
}
|
|
34
33
|
|
|
35
34
|
@media (prefers-color-scheme: dark) {
|
|
36
35
|
:root:not([data-theme="light"]) {
|
|
37
36
|
/* Surfaces */
|
|
38
|
-
--
|
|
39
|
-
--
|
|
40
|
-
--
|
|
41
|
-
--color-surface-inverse: var(--color-neutral-50);
|
|
37
|
+
--background: var(--gray-950);
|
|
38
|
+
--background-elevated: var(--gray-900);
|
|
39
|
+
--background-inverse: var(--gray-50);
|
|
42
40
|
|
|
43
41
|
/* Content (Text & Icons) */
|
|
44
|
-
--
|
|
45
|
-
--
|
|
46
|
-
--
|
|
47
|
-
--
|
|
48
|
-
--
|
|
42
|
+
--foreground: var(--gray-50);
|
|
43
|
+
--foreground-muted: var(--gray-400);
|
|
44
|
+
--foreground-disabled: var(--gray-600);
|
|
45
|
+
--foreground-inverse: var(--gray-900);
|
|
46
|
+
--foreground-link: var(--brand-300);
|
|
49
47
|
|
|
50
48
|
/* Interactive Elements */
|
|
51
|
-
--
|
|
52
|
-
--
|
|
53
|
-
--
|
|
54
|
-
--
|
|
49
|
+
--primary: var(--brand-400);
|
|
50
|
+
--primary-hover: var(--brand-300);
|
|
51
|
+
--primary-active: var(--brand-200);
|
|
52
|
+
--primary-focus: var(--brand-400);
|
|
53
|
+
--primary-disabled: var(--gray-700);
|
|
54
|
+
--primary-foreground: var(--gray-0);
|
|
55
55
|
|
|
56
56
|
/* Borders */
|
|
57
|
-
--
|
|
58
|
-
--
|
|
59
|
-
--
|
|
57
|
+
--border: var(--gray-800);
|
|
58
|
+
--border-strong: var(--gray-600);
|
|
59
|
+
--border-focus: var(--brand-400);
|
|
60
60
|
}
|
|
61
61
|
}
|
|
@@ -2,59 +2,56 @@
|
|
|
2
2
|
* tokens/semantic/light.css
|
|
3
3
|
*
|
|
4
4
|
* Semantic design token assignments for the default Light theme.
|
|
5
|
-
* Standardizes semantic mapping to primitives and sets up GPU-accelerated theme transition rules on :root.
|
|
6
|
-
* Source: doc 26 §3, §6
|
|
7
5
|
*/
|
|
8
6
|
|
|
9
7
|
:root {
|
|
10
8
|
/* Surfaces */
|
|
11
|
-
--
|
|
12
|
-
--
|
|
13
|
-
--
|
|
14
|
-
--color-surface-inverse: var(--color-neutral-900);
|
|
9
|
+
--background: var(--gray-50);
|
|
10
|
+
--background-elevated: var(--gray-0);
|
|
11
|
+
--background-inverse: var(--gray-900);
|
|
15
12
|
|
|
16
13
|
/* Content (Text & Icons) */
|
|
17
|
-
--
|
|
18
|
-
--
|
|
19
|
-
--
|
|
20
|
-
--
|
|
21
|
-
--
|
|
14
|
+
--foreground: var(--gray-900);
|
|
15
|
+
--foreground-muted: var(--gray-600);
|
|
16
|
+
--foreground-disabled: var(--gray-400);
|
|
17
|
+
--foreground-inverse: var(--gray-50);
|
|
18
|
+
--foreground-link: var(--brand-600);
|
|
22
19
|
|
|
23
20
|
/* Interactive Elements */
|
|
24
|
-
--
|
|
25
|
-
--
|
|
26
|
-
--
|
|
27
|
-
--
|
|
28
|
-
--
|
|
21
|
+
--primary: var(--brand-500);
|
|
22
|
+
--primary-hover: var(--brand-600);
|
|
23
|
+
--primary-active: var(--brand-700);
|
|
24
|
+
--primary-focus: var(--brand-500);
|
|
25
|
+
--primary-disabled: var(--gray-300);
|
|
26
|
+
--primary-foreground: var(--gray-0);
|
|
29
27
|
|
|
30
28
|
/* Feedback Semantics */
|
|
31
|
-
--
|
|
32
|
-
--
|
|
33
|
-
--
|
|
34
|
-
--
|
|
29
|
+
--success: var(--success-500);
|
|
30
|
+
--warn: var(--warn-500);
|
|
31
|
+
--error: var(--error-500);
|
|
32
|
+
--info: var(--info-500);
|
|
35
33
|
|
|
36
34
|
/* Borders */
|
|
37
|
-
--
|
|
38
|
-
--
|
|
39
|
-
--
|
|
35
|
+
--border: var(--gray-200);
|
|
36
|
+
--border-strong: var(--gray-400);
|
|
37
|
+
--border-focus: var(--brand-500);
|
|
40
38
|
|
|
41
39
|
/* Automatic theme morph configuration */
|
|
42
40
|
transition:
|
|
43
|
-
--
|
|
44
|
-
--
|
|
45
|
-
--
|
|
46
|
-
--
|
|
47
|
-
--
|
|
48
|
-
--
|
|
49
|
-
--
|
|
50
|
-
--
|
|
51
|
-
--
|
|
52
|
-
--
|
|
53
|
-
--
|
|
54
|
-
--
|
|
55
|
-
--
|
|
56
|
-
--
|
|
57
|
-
--color-border-focus 180ms var(--ease-out);
|
|
41
|
+
--background 220ms var(--ease-out),
|
|
42
|
+
--background-elevated 220ms var(--ease-out),
|
|
43
|
+
--background-inverse 220ms var(--ease-out),
|
|
44
|
+
--foreground 180ms var(--ease-out),
|
|
45
|
+
--foreground-muted 180ms var(--ease-out),
|
|
46
|
+
--foreground-disabled 180ms var(--ease-out),
|
|
47
|
+
--foreground-inverse 180ms var(--ease-out),
|
|
48
|
+
--foreground-link 180ms var(--ease-out),
|
|
49
|
+
--primary 180ms var(--ease-out),
|
|
50
|
+
--primary-hover 180ms var(--ease-out),
|
|
51
|
+
--primary-active 180ms var(--ease-out),
|
|
52
|
+
--border 180ms var(--ease-out),
|
|
53
|
+
--border-strong 180ms var(--ease-out),
|
|
54
|
+
--border-focus 180ms var(--ease-out);
|
|
58
55
|
}
|
|
59
56
|
|
|
60
57
|
@media (prefers-reduced-motion: reduce) {
|