@zeyos/zx 4.4.0 → 5.0.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 +283 -0
- package/README.md +42 -10
- package/dist/types/components/activity-list/activity-list.d.ts +22 -0
- package/dist/types/components/app-sidebar/app-sidebar.d.ts +5 -3
- package/dist/types/components/avatar/avatar.d.ts +46 -7
- package/dist/types/components/badge/badge.d.ts +21 -1
- package/dist/types/components/button/button.d.ts +15 -0
- package/dist/types/components/chart/chart.d.ts +10 -0
- package/dist/types/components/checklist/checklist.d.ts +9 -0
- package/dist/types/components/code-editor/code-editor.d.ts +6 -17
- package/dist/types/components/datebox/date-range-box.d.ts +5 -1
- package/dist/types/components/datebox/datebox.d.ts +7 -2
- package/dist/types/components/dialog/dialog.d.ts +46 -6
- package/dist/types/components/dropdown/dropdown.d.ts +2 -2
- package/dist/types/components/entity-ref/entity-ref.d.ts +2 -2
- package/dist/types/components/field/field.d.ts +24 -2
- package/dist/types/components/fieldset/fieldset.d.ts +19 -1
- package/dist/types/components/file-item/file-item.d.ts +34 -6
- package/dist/types/components/form/form.d.ts +12 -1
- package/dist/types/components/kanban-view/kanban-card.d.ts +8 -0
- package/dist/types/components/launcher/launcher.d.ts +260 -15
- package/dist/types/components/list-toolbar/list-toolbar.d.ts +1 -1
- package/dist/types/components/menu-button/menu-button.d.ts +33 -5
- package/dist/types/components/message/message.d.ts +119 -17
- package/dist/types/components/modal/modal.d.ts +13 -2
- package/dist/types/components/select/color.d.ts +12 -0
- package/dist/types/components/select/glyphs.d.ts +124 -0
- package/dist/types/components/select/select.d.ts +11 -3
- package/dist/types/components/stat-tile/stat-tile.d.ts +16 -5
- package/dist/types/components/tabbox/tabbox.d.ts +9 -0
- package/dist/types/components/table/table.d.ts +46 -1
- package/dist/types/components/tag-picker/tag-picker.d.ts +21 -4
- package/dist/types/components/tree/tree.d.ts +13 -0
- package/dist/types/core/breakpoint.d.ts +1 -1
- package/dist/types/core/icons.d.ts +23 -25
- package/dist/types/core/motion.d.ts +59 -0
- package/dist/types/core/overlay-host.d.ts +15 -1
- package/dist/types/index.d.ts +5 -3
- package/dist/types/zeyos/connect.d.ts +6 -0
- package/dist/types/zeyos/form.d.ts +50 -9
- package/dist/types/zeyos/index.d.ts +1 -1
- package/dist/types/zeyos/query.d.ts +79 -0
- package/dist/types/zeyos/schema.d.ts +24 -1
- package/dist/types/zeyos/table.d.ts +100 -14
- package/dist/types/zeyos/view.d.ts +10 -0
- package/dist/zx-zeyos.esm.js +1621 -443
- package/dist/zx-zeyos.esm.min.js +53 -5
- package/dist/zx.css +1411 -660
- package/dist/zx.esm.js +1976 -703
- package/dist/zx.esm.min.js +56 -8
- package/dist/zx.global.js +1978 -705
- package/dist/zx.global.min.js +56 -8
- package/dist/zx.min.css +1 -1
- package/docs/api.json +219 -34
- package/docs/llms.md +472 -110
- package/docs/llms.txt +3 -3
- package/package.json +1 -1
- package/src/components/account-menu/account-menu.css +35 -10
- package/src/components/activity-item/activity-item.css +1 -1
- package/src/components/activity-item/activity-item.js +3 -0
- package/src/components/activity-list/activity-list.css +38 -3
- package/src/components/activity-list/activity-list.js +34 -0
- package/src/components/app-icon/app-icon.css +1 -1
- package/src/components/app-rail/app-rail.css +40 -79
- package/src/components/app-sidebar/app-sidebar.css +109 -174
- package/src/components/app-sidebar/app-sidebar.js +21 -6
- package/src/components/aurora/aurora.css +5 -3
- package/src/components/avatar/avatar.css +32 -7
- package/src/components/avatar/avatar.js +72 -8
- package/src/components/badge/badge.css +54 -2
- package/src/components/badge/badge.js +29 -2
- package/src/components/button/button.css +67 -9
- package/src/components/button/button.js +38 -0
- package/src/components/calendar/calendar.css +46 -46
- package/src/components/card/card.css +2 -2
- package/src/components/card-view/card-view.css +9 -7
- package/src/components/chart/chart.css +4 -1
- package/src/components/chart/chart.js +12 -0
- package/src/components/check-button/check-button.css +10 -2
- package/src/components/checklist/checklist.css +9 -2
- package/src/components/checklist/checklist.js +11 -5
- package/src/components/checklist/field-adapter.js +3 -1
- package/src/components/code-editor/code-editor.css +6 -5
- package/src/components/code-editor/code-editor.js +19 -1
- package/src/components/context-menu/context-menu.css +9 -4
- package/src/components/copy/copy-button.css +6 -0
- package/src/components/copy/copy-input.css +8 -3
- package/src/components/data-filter/data-filter.css +5 -4
- package/src/components/date-picker/date-picker.css +6 -6
- package/src/components/date-picker/date-range-picker.css +3 -3
- package/src/components/date-picker/time-picker.css +1 -1
- package/src/components/datebox/date-range-box.css +79 -2
- package/src/components/datebox/date-range-box.js +13 -2
- package/src/components/datebox/datebox.css +79 -2
- package/src/components/datebox/datebox.js +13 -2
- package/src/components/dialog/dialog.css +26 -0
- package/src/components/dialog/dialog.js +99 -17
- package/src/components/dropdown/dropdown.css +1 -1
- package/src/components/dropdown/dropdown.js +5 -3
- package/src/components/empty-state/empty-state.css +2 -2
- package/src/components/entity-ref/entity-ref.css +1 -1
- package/src/components/entity-ref/entity-ref.js +1 -1
- package/src/components/field/field.css +28 -9
- package/src/components/field/field.js +68 -26
- package/src/components/field-upload/field-upload.css +1 -1
- package/src/components/fieldset/fieldset.css +5 -3
- package/src/components/fieldset/fieldset.js +28 -5
- package/src/components/file-item/file-item.js +144 -10
- package/src/components/filter/filter.js +7 -3
- package/src/components/filter-panel/filter-panel.css +1 -1
- package/src/components/finder/finder.css +15 -13
- package/src/components/form/form.css +5 -4
- package/src/components/form/form.js +11 -2
- package/src/components/grid/grid.css +1 -1
- package/src/components/groupbox/groupbox.css +1 -1
- package/src/components/kanban-view/kanban-card.js +11 -3
- package/src/components/kanban-view/kanban-view.css +39 -15
- package/src/components/kanban-view/kanban-view.js +4 -4
- package/src/components/launcher/launcher.css +107 -25
- package/src/components/launcher/launcher.js +503 -41
- package/src/components/list-toolbar/list-toolbar.css +13 -8
- package/src/components/list-toolbar/list-toolbar.js +1 -1
- package/src/components/master-panel/master-panel.css +2 -0
- package/src/components/menu-button/menu-button.css +9 -4
- package/src/components/menu-button/menu-button.js +65 -9
- package/src/components/message/message.css +33 -3
- package/src/components/message/message.js +217 -15
- package/src/components/modal/modal.js +18 -3
- package/src/components/navigation-bar/navigation-bar.css +18 -9
- package/src/components/number-field/field-adapter.js +1 -0
- package/src/components/number-field/number-field.css +70 -0
- package/src/components/number-field/number-field.js +2 -0
- package/src/components/pagination/pagination.css +8 -6
- package/src/components/panel/panel.css +1 -1
- package/src/components/rating/rating.css +7 -0
- package/src/components/select/color.js +22 -0
- package/src/components/select/field-adapter.js +2 -0
- package/src/components/select/glyphs.js +165 -0
- package/src/components/select/select.css +138 -45
- package/src/components/select/select.js +83 -47
- package/src/components/sheet/sheet.css +11 -8
- package/src/components/slider/slider.css +16 -2
- package/src/components/slider/slider.js +1 -1
- package/src/components/sort-control/sort-control.css +4 -1
- package/src/components/stat-tile/stat-tile.css +41 -46
- package/src/components/stat-tile/stat-tile.js +17 -6
- package/src/components/tabbox/tabbox.css +32 -27
- package/src/components/tabbox/tabbox.js +5 -1
- package/src/components/table/table.css +104 -29
- package/src/components/table/table.js +90 -16
- package/src/components/tag-picker/tag-picker.css +83 -5
- package/src/components/tag-picker/tag-picker.js +25 -8
- package/src/components/timebox/timebox.css +22 -2
- package/src/components/toggle/toggle.css +12 -1
- package/src/components/toolbar/toolbar.js +2 -2
- package/src/components/tooltip/tooltip.css +4 -0
- package/src/components/tooltip/tooltip.js +10 -3
- package/src/components/tree/tree.css +25 -16
- package/src/components/tree/tree.js +31 -0
- package/src/components/value-list/value-list.css +3 -3
- package/src/components/view/record-view.js +1 -1
- package/src/core/breakpoint.js +1 -1
- package/src/core/icons.js +193 -60
- package/src/core/motion.js +147 -0
- package/src/core/overlay-host.js +21 -2
- package/src/index.js +5 -3
- package/src/internal/app-rail.js +1 -2
- package/src/zeyos/connect.js +6 -2
- package/src/zeyos/form.js +67 -27
- package/src/zeyos/index.js +1 -1
- package/src/zeyos/query.js +153 -0
- package/src/zeyos/schema.js +144 -27
- package/src/zeyos/table.js +68 -5
- package/src/zeyos/view.js +6 -0
- package/styles/base.css +56 -0
- package/styles/icons.css +11 -1
- package/styles/tokens/dark.css +113 -37
- package/styles/tokens/global.css +121 -27
- package/styles/tokens/semantic.css +100 -31
- package/styles/tokens/themes.css +7 -6
- package/styles/zx.css +0 -1
- package/styles/tokens/density.css +0 -9
package/src/zeyos/table.js
CHANGED
|
@@ -4,10 +4,16 @@ import { buildListQuery } from './query.js';
|
|
|
4
4
|
import { fieldToZxColumn, resolveFields } from './schema.js';
|
|
5
5
|
import { normalizeZeyosListResult } from './select.js';
|
|
6
6
|
|
|
7
|
+
/** @typedef {import('../components/table/table.js').TableOptions} TableOptions */
|
|
8
|
+
|
|
7
9
|
/**
|
|
8
10
|
* @typedef {Object} ZeyosTableOptions
|
|
9
11
|
* @property {string[]} [fields] Curated ordered field allow-list.
|
|
10
12
|
* @property {Record<string, string>} [labels] Per-field label overrides.
|
|
13
|
+
* @property {Record<string, string>} [formats] Per-field semantic format overrides, such as
|
|
14
|
+
* `{ duedate: 'date' }` for a Unix-second field that holds a calendar day.
|
|
15
|
+
* @property {string} [timeZone] IANA time zone of the ZeyOS instance. Date-only columns show the
|
|
16
|
+
* calendar day their stored midnight names in this zone; defaults to the runtime's own zone.
|
|
11
17
|
* @property {string|((row: Record<string, unknown>) => unknown)} [rowId='ID'] Row id accessor.
|
|
12
18
|
* @property {number} [pageSize=50] Server page size.
|
|
13
19
|
* @property {{id: string, dir: 'asc'|'desc'}|null} [sort=null] Initial server sort.
|
|
@@ -16,8 +22,42 @@ import { normalizeZeyosListResult } from './select.js';
|
|
|
16
22
|
* @property {false|'single'|'multi'} [selectable=false] Row selection mode.
|
|
17
23
|
* @property {number|string|null} [height=null] Table scroll-region height.
|
|
18
24
|
* @property {(row: Record<string, unknown>, event: CustomEvent<Record<string, unknown>>) => void} [onRowClick] Row activation callback.
|
|
25
|
+
* @property {TableOptions['variant']} [variant='default'] Table frame treatment; `'plain'` for a
|
|
26
|
+
* table inside a pane or card that already draws the box.
|
|
27
|
+
* @property {boolean} [zebra=true] Whether alternate rows use the zebra background.
|
|
28
|
+
* @property {boolean} [stickyHeader=true] Whether column headers stick while scrolling.
|
|
29
|
+
* @property {TableOptions['responsive']} [responsive=false] Width below which rows stack.
|
|
30
|
+
* @property {TableOptions['growing']} [growing=false] Rows rendered at first from a loaded page.
|
|
31
|
+
* @property {TableOptions['emptyText']} [emptyText=null] What the table shows with no rows.
|
|
32
|
+
* @property {TableOptions['rowClass']} [rowClass=null] Additional row class callback.
|
|
33
|
+
* @property {TableOptions['rowKind']} [rowKind=null] Row property or callback naming each row's kind.
|
|
34
|
+
* @property {TableOptions['rowKinds']} [rowKinds=null] Presentation per row kind.
|
|
35
|
+
* @property {boolean} [columnVisibility=false] Whether a column visibility chooser is rendered.
|
|
36
|
+
* @property {boolean} [columnReorder=false] Whether the column chooser exposes reorder controls.
|
|
37
|
+
* @property {string[]} [hiddenColumns=[]] Initially hidden column ids.
|
|
38
|
+
* @property {TableOptions['onrowclick']} [onrowclick] Table `rowclick` listener, beside `onRowClick`.
|
|
39
|
+
* @property {TableOptions['onrowdblclick']} [onrowdblclick] Table `rowdblclick` listener.
|
|
40
|
+
* @property {TableOptions['onsort']} [onsort] Table `sort` listener; the binding reloads either way.
|
|
41
|
+
* @property {TableOptions['onselectionchange']} [onselectionchange] Table `selectionchange` listener.
|
|
42
|
+
* @property {TableOptions['ondatachange']} [ondatachange] Table `datachange` listener.
|
|
43
|
+
* @property {TableOptions['onstackedchange']} [onstackedchange] Table `stackedchange` listener.
|
|
44
|
+
* @property {TableOptions['ongrow']} [ongrow] Table `grow` listener.
|
|
45
|
+
* @property {TableOptions['oncolumnvisibilitychange']} [oncolumnvisibilitychange] Table `columnvisibilitychange` listener.
|
|
46
|
+
* @property {TableOptions['oncolumnorderchange']} [oncolumnorderchange] Table `columnorderchange` listener.
|
|
19
47
|
*/
|
|
20
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Table options a binding passes through unchanged: presentation and listeners. The binding owns
|
|
51
|
+
* `columns`, `data`, and `sortMode`; editing, row reordering, and `hierarchy` are left out because
|
|
52
|
+
* they rearrange or change rows the server pages and never persists.
|
|
53
|
+
*/
|
|
54
|
+
const TABLE_OPTION_KEYS = [
|
|
55
|
+
'variant', 'zebra', 'stickyHeader', 'responsive', 'growing', 'emptyText', 'rowClass', 'rowKind',
|
|
56
|
+
'rowKinds', 'columnVisibility', 'columnReorder', 'hiddenColumns', 'onrowdblclick', 'onsort',
|
|
57
|
+
'onselectionchange', 'ondatachange', 'onstackedchange', 'ongrow', 'oncolumnvisibilitychange',
|
|
58
|
+
'oncolumnorderchange'
|
|
59
|
+
];
|
|
60
|
+
|
|
21
61
|
/**
|
|
22
62
|
* @typedef {Object} ZeyosTableConfig
|
|
23
63
|
* @property {Record<string, any>[]} fieldMeta Ordered normalized schema metadata.
|
|
@@ -59,7 +99,8 @@ import { normalizeZeyosListResult } from './select.js';
|
|
|
59
99
|
* Builds the DOM-free schema-derived columns and Table options used by {@link zeyosTable}. Entity
|
|
60
100
|
* projections include an `<field>_label` alias from a real label field on the referenced resource.
|
|
61
101
|
* Amount fields use each row's real `currency` value for display while retaining the WP14 typed
|
|
62
|
-
* column strategy and right alignment.
|
|
102
|
+
* column strategy and right alignment. Enum columns show labels, date-only columns calendar days in
|
|
103
|
+
* `timeZone`, and Table presentation options and listeners pass through to `tableOptions`.
|
|
63
104
|
* @param {Record<string, any>} client Injected ZeyOS client instance.
|
|
64
105
|
* @param {string} resource Resource name such as `transactions`.
|
|
65
106
|
* @param {ZeyosTableOptions} [opts={}] Schema, table, and initial query options.
|
|
@@ -68,7 +109,9 @@ import { normalizeZeyosListResult } from './select.js';
|
|
|
68
109
|
export function buildZeyosTableConfig(client, resource, opts = {}) {
|
|
69
110
|
const fieldMeta = resolveFields(client, resource, {
|
|
70
111
|
fields: opts.fields,
|
|
71
|
-
labels: opts.labels
|
|
112
|
+
labels: opts.labels,
|
|
113
|
+
formats: opts.formats,
|
|
114
|
+
timeZone: opts.timeZone
|
|
72
115
|
});
|
|
73
116
|
const projection = {};
|
|
74
117
|
const columns = fieldMeta.map((sourceMeta) => {
|
|
@@ -94,11 +137,16 @@ export function buildZeyosTableConfig(client, resource, opts = {}) {
|
|
|
94
137
|
if (typeof rowId === 'string' && !Object.prototype.hasOwnProperty.call(projection, rowId)) {
|
|
95
138
|
projection[rowId] = rowId;
|
|
96
139
|
}
|
|
140
|
+
const passed = {};
|
|
141
|
+
for (const key of TABLE_OPTION_KEYS) {
|
|
142
|
+
if (opts[key] !== undefined) passed[key] = opts[key];
|
|
143
|
+
}
|
|
97
144
|
return {
|
|
98
145
|
fieldMeta,
|
|
99
146
|
columns,
|
|
100
147
|
projection,
|
|
101
148
|
tableOptions: {
|
|
149
|
+
...passed,
|
|
102
150
|
columns,
|
|
103
151
|
data: [],
|
|
104
152
|
rowId,
|
|
@@ -106,9 +154,7 @@ export function buildZeyosTableConfig(client, resource, opts = {}) {
|
|
|
106
154
|
sortMode: 'server',
|
|
107
155
|
selectable: opts.selectable ?? false,
|
|
108
156
|
height: opts.height ?? null,
|
|
109
|
-
onrowclick:
|
|
110
|
-
? (event) => opts.onRowClick(event.detail.row, event)
|
|
111
|
-
: undefined
|
|
157
|
+
onrowclick: rowClickListener(opts)
|
|
112
158
|
}
|
|
113
159
|
};
|
|
114
160
|
}
|
|
@@ -117,6 +163,8 @@ export function buildZeyosTableConfig(client, resource, opts = {}) {
|
|
|
117
163
|
* Generates a server-backed Zx Table. Sorting automatically reloads page zero. `load({page: 0})`
|
|
118
164
|
* replaces data, higher pages append it, and `loadMore()` uses `limit`/`offset` plus the returned
|
|
119
165
|
* count. DataFilter callers can map state with `dataFilterStateToFilters` before `setFilters()`.
|
|
166
|
+
* Table presentation options (`variant`, `zebra`, `stickyHeader`, `responsive`, `emptyText`, …) and
|
|
167
|
+
* listeners are passed through to the generated Table.
|
|
120
168
|
* @param {Record<string, any>} client Injected ZeyOS client instance.
|
|
121
169
|
* @param {string} resource Resource name such as `transactions`.
|
|
122
170
|
* @param {ZeyosTableOptions} [opts={}] Schema, table, and initial query options.
|
|
@@ -204,6 +252,21 @@ export function zeyosTable(client, resource, opts = {}) {
|
|
|
204
252
|
return binding;
|
|
205
253
|
}
|
|
206
254
|
|
|
255
|
+
/**
|
|
256
|
+
* Combines the Table-style `onrowclick` listener with the binding's row-first `onRowClick`.
|
|
257
|
+
* @param {ZeyosTableOptions} opts
|
|
258
|
+
* @returns {((event: CustomEvent<Record<string, any>>) => void)|undefined}
|
|
259
|
+
*/
|
|
260
|
+
function rowClickListener(opts) {
|
|
261
|
+
const listener = typeof opts.onrowclick === 'function' ? opts.onrowclick : null;
|
|
262
|
+
const callback = typeof opts.onRowClick === 'function' ? opts.onRowClick : null;
|
|
263
|
+
if (!listener && !callback) return undefined;
|
|
264
|
+
return (event) => {
|
|
265
|
+
listener?.(event);
|
|
266
|
+
callback?.(event.detail.row, event);
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
|
|
207
270
|
/** @param {Record<string, any>} meta @returns {string|null} */
|
|
208
271
|
function referencedResourceFor(meta) {
|
|
209
272
|
for (const value of [meta.entity, meta.fk, meta.relation, meta.reference, meta.references]) {
|
package/src/zeyos/view.js
CHANGED
|
@@ -26,6 +26,10 @@ import { buildZeyosTableConfig } from './table.js';
|
|
|
26
26
|
* @property {string[]} [fields] Curated ordered schema field allow-list.
|
|
27
27
|
* @property {string[]} [exclude] Schema fields to omit.
|
|
28
28
|
* @property {Record<string, string>} [labels] Per-field label overrides.
|
|
29
|
+
* @property {Record<string, string>} [formats] Per-field semantic format overrides, such as
|
|
30
|
+
* `{ duedate: 'date' }` for a Unix-second field that holds a calendar day.
|
|
31
|
+
* @property {string} [timeZone] IANA time zone of the ZeyOS instance; date-only fields show the
|
|
32
|
+
* calendar day their stored midnight names in it. Defaults to the runtime's own zone.
|
|
29
33
|
* @property {Record<string, Partial<ViewField>>} [fieldOverrides] View descriptor overrides.
|
|
30
34
|
* @property {string|((record:Record<string,unknown>)=>unknown)} [recordId='ID'] Record id accessor.
|
|
31
35
|
* @property {number} [pageSize=50] Server page size.
|
|
@@ -134,6 +138,8 @@ export function buildZeyosViewConfig(client, resource, opts = {}) {
|
|
|
134
138
|
const table = buildZeyosTableConfig(client, resource, {
|
|
135
139
|
fields: requested,
|
|
136
140
|
labels: opts.labels,
|
|
141
|
+
formats: opts.formats,
|
|
142
|
+
timeZone: opts.timeZone,
|
|
137
143
|
rowId: opts.recordId ?? 'ID',
|
|
138
144
|
sort: opts.sort ?? null
|
|
139
145
|
});
|
package/styles/base.css
CHANGED
|
@@ -12,6 +12,11 @@
|
|
|
12
12
|
color: var(--zx-color-text);
|
|
13
13
|
font-family: var(--zx-font-sans);
|
|
14
14
|
font-size: var(--zx-text-md);
|
|
15
|
+
/* Inter at 13–14px reads better a touch tight. `cv11` is Inter's single-storey a: at interface
|
|
16
|
+
sizes it is rounder and calmer than the double-storey form, and it tells a from o and e
|
|
17
|
+
apart at least as well. Fonts without the feature ignore it. */
|
|
18
|
+
font-feature-settings: "cv11";
|
|
19
|
+
letter-spacing: var(--zx-tracking-tight);
|
|
15
20
|
line-height: 1.5;
|
|
16
21
|
-webkit-font-smoothing: antialiased;
|
|
17
22
|
scrollbar-gutter: stable;
|
|
@@ -67,6 +72,41 @@
|
|
|
67
72
|
background: var(--zx-color-bg-hover);
|
|
68
73
|
}
|
|
69
74
|
|
|
75
|
+
/* Quiet fields. Inside `[data-zx-fields="quiet"]` — a property panel, an inspector, an inline
|
|
76
|
+
record — native text inputs, selects, and textareas drop their border and fill so the values
|
|
77
|
+
read as text, and show that they are editable on hover (the hover fill) and on focus (the
|
|
78
|
+
normal border, the control fill, and the focus ring). Read-only and disabled fields never
|
|
79
|
+
light up. Zero specificity, like the defaults above: a component that styles its own inner
|
|
80
|
+
input keeps doing so. Composite controls opt in through their own stylesheets. */
|
|
81
|
+
:where(.zx-scope[data-zx-fields="quiet"], .zx-scope [data-zx-fields="quiet"]) :where(
|
|
82
|
+
input:not([type="checkbox"], [type="radio"], [type="range"], [type="color"], [type="file"],
|
|
83
|
+
[type="button"], [type="submit"], [type="reset"], [type="image"]),
|
|
84
|
+
select,
|
|
85
|
+
textarea
|
|
86
|
+
) {
|
|
87
|
+
border-color: transparent;
|
|
88
|
+
background: transparent;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
:where(.zx-scope[data-zx-fields="quiet"], .zx-scope [data-zx-fields="quiet"]) :where(
|
|
92
|
+
input:not([type="checkbox"], [type="radio"], [type="range"], [type="color"], [type="file"],
|
|
93
|
+
[type="button"], [type="submit"], [type="reset"], [type="image"]),
|
|
94
|
+
select,
|
|
95
|
+
textarea
|
|
96
|
+
):where(:hover:not(:focus, :disabled, [readonly])) {
|
|
97
|
+
background: var(--zx-color-bg-hover);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
:where(.zx-scope[data-zx-fields="quiet"], .zx-scope [data-zx-fields="quiet"]) :where(
|
|
101
|
+
input:not([type="checkbox"], [type="radio"], [type="range"], [type="color"], [type="file"],
|
|
102
|
+
[type="button"], [type="submit"], [type="reset"], [type="image"]),
|
|
103
|
+
select,
|
|
104
|
+
textarea
|
|
105
|
+
):where(:focus:not([readonly])) {
|
|
106
|
+
border-color: var(--zx-color-border-control);
|
|
107
|
+
background: var(--zx-color-bg-control);
|
|
108
|
+
}
|
|
109
|
+
|
|
70
110
|
/* Ghost icon button: a borderless, transparent hit target for small glyph actions
|
|
71
111
|
(notification close, closable tab ×, field clear). Square, no chrome until hovered. */
|
|
72
112
|
.zx-scope .zx-icon-btn {
|
|
@@ -122,3 +162,19 @@
|
|
|
122
162
|
transition-duration: 0.01ms !important;
|
|
123
163
|
}
|
|
124
164
|
}
|
|
165
|
+
|
|
166
|
+
/* Motion as a setting: the same stop inside any `data-zx-motion="reduced"` region, whatever the
|
|
167
|
+
operating system says (`tokens/global.css` zeroes the duration tokens there too). Only movement
|
|
168
|
+
stops — every transition and animation still runs to its end state, at once, and still fires its
|
|
169
|
+
end event, so a menu still opens and a toast still leaves; a spinner stops turning. There is no
|
|
170
|
+
value that re-enables motion inside a reduced region. */
|
|
171
|
+
[data-zx-motion="reduced"],
|
|
172
|
+
[data-zx-motion="reduced"] *,
|
|
173
|
+
[data-zx-motion="reduced"] *::before,
|
|
174
|
+
[data-zx-motion="reduced"] *::after,
|
|
175
|
+
[data-zx-motion="reduced"] *::backdrop {
|
|
176
|
+
scroll-behavior: auto !important;
|
|
177
|
+
animation-duration: 0.01ms !important;
|
|
178
|
+
animation-iteration-count: 1 !important;
|
|
179
|
+
transition-duration: 0.01ms !important;
|
|
180
|
+
}
|
package/styles/icons.css
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
/* Icons.
|
|
2
2
|
Every icon `icon()` builds carries `.zx-icon`, whether it is one of the bundled inline SVG
|
|
3
3
|
glyphs or a Font Awesome element, so the rules below (and component rules) style both. Font
|
|
4
|
-
Awesome icons are sized by font-size and occupy exactly one em.
|
|
4
|
+
Awesome icons are sized by font-size and occupy exactly one em.
|
|
5
|
+
|
|
6
|
+
The bundled glyphs are outlines: the `<svg>` carries `fill="none"`, `stroke="currentColor"`,
|
|
7
|
+
round caps and joins, and a stroke width in view-box units (1.75 of 24, never under one CSS
|
|
8
|
+
pixel), and the path inherits all of it. The width therefore scales with the box an icon is
|
|
9
|
+
drawn in and needs no `vector-effect`. Glyphs registered as `[viewBox, path]` pairs stay filled.
|
|
10
|
+
Paint is presentation attributes, so plain CSS on `.zx-icon` overrides it: `fill: currentColor`
|
|
11
|
+
turns an outline into its solid form (a set star, a liked heart). */
|
|
5
12
|
|
|
6
13
|
.zx-icon {
|
|
7
14
|
flex: none;
|
|
@@ -17,6 +24,9 @@ i.zx-icon {
|
|
|
17
24
|
|
|
18
25
|
svg.zx-icon {
|
|
19
26
|
vertical-align: middle;
|
|
27
|
+
/* A stroke centred on a path near the view-box edge reaches past it; small icons thicken the
|
|
28
|
+
line to stay at one pixel, so let it draw instead of clipping the outer half. */
|
|
29
|
+
overflow: visible;
|
|
20
30
|
}
|
|
21
31
|
|
|
22
32
|
/* ZeyOS identity hook. `moduleChip()` now delegates vessel geometry and material entirely to
|
package/styles/tokens/dark.css
CHANGED
|
@@ -1,49 +1,92 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Tier-2 semantic tokens — dark theme: a
|
|
3
|
-
* translucent white borders (
|
|
2
|
+
* Tier-2 semantic tokens — dark theme: a charcoal page lifted off black, a chrome tone and four
|
|
3
|
+
* surface steps above it, translucent white borders (9%) and inputs (14%), text softened to about
|
|
4
|
+
* 90% white, and restrained secondary text.
|
|
4
5
|
*
|
|
5
|
-
* The accent roles take the light end of the `--zx-accent-*` ramp (300/400/500)
|
|
6
|
-
* theme takes the dark end, so a preset that repoints the ramp
|
|
6
|
+
* The accent roles take the light end of the `--zx-accent-*` ramp (300/400/500) for text, marks,
|
|
7
|
+
* and the focus ring, where the light theme takes the dark end, so a preset that repoints the ramp
|
|
8
|
+
* lands correctly in both. The solid accent is the exception: the primary button keeps the 600 stop
|
|
9
|
+
* with white ink in both themes rather than turning into a bright 400 slab.
|
|
10
|
+
*
|
|
11
|
+
* Every role that mixes another theme-dependent role (hover and current mix the text colour, tones
|
|
12
|
+
* and status fills mix the surface) is restated here, because a custom property resolves where it
|
|
13
|
+
* is declared: inherited from the light block, it would carry light values into a dark region.
|
|
7
14
|
*
|
|
8
15
|
* The `[data-zx-theme="auto"]` block below repeats these assignments under a
|
|
9
16
|
* `prefers-color-scheme` query; CSS has no way to share a declaration block across a media
|
|
10
|
-
* boundary, so the two lists must be kept in sync.
|
|
17
|
+
* boundary, so the two lists must be kept in sync — `tests/unit/tokens.test.js` fails if they drift.
|
|
11
18
|
*/
|
|
12
19
|
[data-zx-theme="dark"] {
|
|
13
20
|
color-scheme: dark;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
--zx-color-bg-
|
|
21
|
+
/* The ramp is lifted off black: page, chrome, surface, raised, and the overlay base ascend in
|
|
22
|
+
that order, each mixed from two Zinc stops so a tinted neutral ramp carries through. */
|
|
23
|
+
--zx-color-bg-page: color-mix(in srgb, var(--zx-gray-900) 80%, var(--zx-gray-800));
|
|
24
|
+
/* Chrome sits just above the page and below the canvas: as in light, the working area is the
|
|
25
|
+
brightest column and the navigation and inspector recede. */
|
|
26
|
+
--zx-color-bg-chrome: color-mix(in srgb, var(--zx-color-bg-page) 75%, var(--zx-color-bg-surface));
|
|
27
|
+
--zx-color-bg-surface: color-mix(in srgb, var(--zx-gray-900) 40%, var(--zx-gray-800));
|
|
28
|
+
--zx-color-bg-raised: color-mix(in srgb, var(--zx-gray-800) 90%, var(--zx-gray-700));
|
|
17
29
|
--zx-color-bg-control: color-mix(in srgb, var(--zx-gray-0) 5%, transparent);
|
|
18
|
-
--zx-color-bg-muted: var(--zx-
|
|
19
|
-
--zx-color-bg-hover: color-mix(in srgb, var(--zx-
|
|
20
|
-
--zx-color-bg-
|
|
30
|
+
--zx-color-bg-muted: var(--zx-color-bg-raised);
|
|
31
|
+
--zx-color-bg-hover: color-mix(in srgb, var(--zx-color-text) 5%, transparent);
|
|
32
|
+
--zx-color-bg-current: color-mix(in srgb, var(--zx-color-text) 9%, transparent);
|
|
33
|
+
/* Picked, not current: a tint light enough that muted text on it keeps 4.5:1 under every preset. */
|
|
34
|
+
--zx-color-bg-selected: color-mix(in srgb, var(--zx-accent-400) 13%, var(--zx-color-bg-surface));
|
|
21
35
|
--zx-color-bg-backdrop: color-mix(in srgb, var(--zx-gray-950) 75%, transparent);
|
|
22
|
-
--zx-color-overlay-base: color-mix(in srgb, var(--zx-
|
|
36
|
+
--zx-color-overlay-base: color-mix(in srgb, var(--zx-gray-800) 60%, var(--zx-gray-700));
|
|
23
37
|
--zx-color-overlay-backdrop: color-mix(in srgb, var(--zx-gray-950) 38%, transparent);
|
|
24
|
-
--zx-color-border: color-mix(in srgb, var(--zx-gray-0)
|
|
25
|
-
--zx-color-border-
|
|
26
|
-
--zx-color-border-
|
|
27
|
-
--zx-color-
|
|
38
|
+
--zx-color-border: color-mix(in srgb, var(--zx-gray-0) 9%, transparent);
|
|
39
|
+
--zx-color-border-subtle: color-mix(in srgb, var(--zx-gray-0) 6%, transparent);
|
|
40
|
+
--zx-color-border-strong: color-mix(in srgb, var(--zx-gray-0) 24%, transparent);
|
|
41
|
+
--zx-color-border-control: color-mix(in srgb, var(--zx-gray-0) 14%, transparent);
|
|
42
|
+
/* Text is softened off pure white (about 90%), secondary text sits near 63%. */
|
|
43
|
+
--zx-color-text: var(--zx-gray-200);
|
|
28
44
|
--zx-color-text-muted: var(--zx-gray-400);
|
|
45
|
+
--zx-color-text-subtle: color-mix(in srgb, var(--zx-gray-500) 50%, var(--zx-gray-400));
|
|
29
46
|
--zx-color-text-placeholder: var(--zx-gray-500);
|
|
30
47
|
--zx-color-text-invert: var(--zx-gray-950);
|
|
31
48
|
--zx-color-accent: var(--zx-accent-400);
|
|
32
49
|
--zx-color-accent-hover: var(--zx-accent-300);
|
|
33
50
|
--zx-color-accent-active: var(--zx-accent-500);
|
|
34
|
-
--zx-color-accent-subtle: color-mix(in srgb, var(--zx-accent-400) 16%, var(--zx-
|
|
51
|
+
--zx-color-accent-subtle: color-mix(in srgb, var(--zx-accent-400) 16%, var(--zx-color-bg-surface));
|
|
35
52
|
--zx-color-on-accent: var(--zx-gray-950);
|
|
53
|
+
/* The primary button does not glow: it keeps the 600 stop and white ink, as in light. */
|
|
54
|
+
--zx-color-accent-solid: var(--zx-accent-600);
|
|
55
|
+
--zx-color-accent-solid-hover: var(--zx-accent-700);
|
|
56
|
+
--zx-color-accent-solid-active: color-mix(in srgb, var(--zx-accent-700) 82%, var(--zx-gray-950));
|
|
57
|
+
--zx-color-on-accent-solid: var(--zx-gray-0);
|
|
58
|
+
/* Danger's tint is a little lighter than the other statuses' so its ink keeps 4.5:1 on it. */
|
|
36
59
|
--zx-color-danger: var(--zx-red-400);
|
|
37
|
-
--zx-color-danger-bg: color-mix(in srgb, var(--zx-red-400)
|
|
60
|
+
--zx-color-danger-bg: color-mix(in srgb, var(--zx-red-400) 13%, var(--zx-color-bg-surface));
|
|
38
61
|
--zx-color-warning: var(--zx-amber-400);
|
|
39
|
-
--zx-color-warning-bg: color-mix(in srgb, var(--zx-amber-400) 16%, var(--zx-
|
|
62
|
+
--zx-color-warning-bg: color-mix(in srgb, var(--zx-amber-400) 16%, var(--zx-color-bg-surface));
|
|
40
63
|
--zx-color-success: var(--zx-green-400);
|
|
41
|
-
--zx-color-success-bg: color-mix(in srgb, var(--zx-green-400) 16%, var(--zx-
|
|
64
|
+
--zx-color-success-bg: color-mix(in srgb, var(--zx-green-400) 16%, var(--zx-color-bg-surface));
|
|
42
65
|
--zx-color-info: var(--zx-blue-400);
|
|
43
|
-
--zx-color-info-bg: color-mix(in srgb, var(--zx-blue-400) 16%, var(--zx-
|
|
66
|
+
--zx-color-info-bg: color-mix(in srgb, var(--zx-blue-400) 16%, var(--zx-color-bg-surface));
|
|
67
|
+
--zx-color-tone-blue-bg: color-mix(in srgb, var(--zx-tone-blue-500) 20%, var(--zx-color-bg-surface));
|
|
68
|
+
--zx-color-tone-blue-fg: var(--zx-tone-blue-300);
|
|
69
|
+
--zx-color-tone-teal-bg: color-mix(in srgb, var(--zx-tone-teal-500) 20%, var(--zx-color-bg-surface));
|
|
70
|
+
--zx-color-tone-teal-fg: var(--zx-tone-teal-300);
|
|
71
|
+
--zx-color-tone-green-bg: color-mix(in srgb, var(--zx-tone-green-500) 20%, var(--zx-color-bg-surface));
|
|
72
|
+
--zx-color-tone-green-fg: var(--zx-tone-green-300);
|
|
73
|
+
--zx-color-tone-amber-bg: color-mix(in srgb, var(--zx-tone-amber-500) 20%, var(--zx-color-bg-surface));
|
|
74
|
+
--zx-color-tone-amber-fg: var(--zx-tone-amber-300);
|
|
75
|
+
--zx-color-tone-orange-bg: color-mix(in srgb, var(--zx-tone-orange-500) 20%, var(--zx-color-bg-surface));
|
|
76
|
+
--zx-color-tone-orange-fg: var(--zx-tone-orange-300);
|
|
77
|
+
--zx-color-tone-red-bg: color-mix(in srgb, var(--zx-tone-red-500) 20%, var(--zx-color-bg-surface));
|
|
78
|
+
--zx-color-tone-red-fg: var(--zx-tone-red-300);
|
|
79
|
+
--zx-color-tone-pink-bg: color-mix(in srgb, var(--zx-tone-pink-500) 20%, var(--zx-color-bg-surface));
|
|
80
|
+
--zx-color-tone-pink-fg: var(--zx-tone-pink-300);
|
|
81
|
+
--zx-color-tone-violet-bg: color-mix(in srgb, var(--zx-tone-violet-500) 20%, var(--zx-color-bg-surface));
|
|
82
|
+
--zx-color-tone-violet-fg: var(--zx-tone-violet-300);
|
|
83
|
+
--zx-color-tone-slate-bg: color-mix(in srgb, var(--zx-tone-slate-500) 20%, var(--zx-color-bg-surface));
|
|
84
|
+
--zx-color-tone-slate-fg: var(--zx-tone-slate-300);
|
|
44
85
|
--zx-color-ring: var(--zx-color-accent);
|
|
45
86
|
--zx-focus-ring: 0 0 0 3px color-mix(in srgb, var(--zx-color-ring) 45%, transparent);
|
|
46
87
|
--zx-overlay-shadow: 0 12px 36px rgb(0 0 0 / 45%);
|
|
88
|
+
/* A shadow alone barely reads on a dark canvas, so the lifted item also gets a faint light rim. */
|
|
89
|
+
--zx-drag-shadow: 0 0 0 1px color-mix(in srgb, var(--zx-gray-0) 7%, transparent), 0 2px 6px -1px rgb(0 0 0 / 40%), 0 14px 32px -6px rgb(0 0 0 / 60%);
|
|
47
90
|
--zx-header-bg: var(--zx-gray-900);
|
|
48
91
|
--zx-header-text: var(--zx-gray-50);
|
|
49
92
|
}
|
|
@@ -51,39 +94,72 @@
|
|
|
51
94
|
@media (prefers-color-scheme: dark) {
|
|
52
95
|
[data-zx-theme="auto"] {
|
|
53
96
|
color-scheme: dark;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
--zx-color-bg-
|
|
97
|
+
/* The ramp is lifted off black: page, chrome, surface, raised, and the overlay base ascend in
|
|
98
|
+
that order, each mixed from two Zinc stops so a tinted neutral ramp carries through. */
|
|
99
|
+
--zx-color-bg-page: color-mix(in srgb, var(--zx-gray-900) 80%, var(--zx-gray-800));
|
|
100
|
+
/* Chrome sits just above the page and below the canvas: as in light, the working area is the
|
|
101
|
+
brightest column and the navigation and inspector recede. */
|
|
102
|
+
--zx-color-bg-chrome: color-mix(in srgb, var(--zx-color-bg-page) 75%, var(--zx-color-bg-surface));
|
|
103
|
+
--zx-color-bg-surface: color-mix(in srgb, var(--zx-gray-900) 40%, var(--zx-gray-800));
|
|
104
|
+
--zx-color-bg-raised: color-mix(in srgb, var(--zx-gray-800) 90%, var(--zx-gray-700));
|
|
57
105
|
--zx-color-bg-control: color-mix(in srgb, var(--zx-gray-0) 5%, transparent);
|
|
58
|
-
--zx-color-bg-muted: var(--zx-
|
|
59
|
-
--zx-color-bg-hover: color-mix(in srgb, var(--zx-
|
|
60
|
-
--zx-color-bg-
|
|
106
|
+
--zx-color-bg-muted: var(--zx-color-bg-raised);
|
|
107
|
+
--zx-color-bg-hover: color-mix(in srgb, var(--zx-color-text) 5%, transparent);
|
|
108
|
+
--zx-color-bg-current: color-mix(in srgb, var(--zx-color-text) 9%, transparent);
|
|
109
|
+
--zx-color-bg-selected: color-mix(in srgb, var(--zx-accent-400) 13%, var(--zx-color-bg-surface));
|
|
61
110
|
--zx-color-bg-backdrop: color-mix(in srgb, var(--zx-gray-950) 75%, transparent);
|
|
62
|
-
--zx-color-overlay-base: color-mix(in srgb, var(--zx-
|
|
111
|
+
--zx-color-overlay-base: color-mix(in srgb, var(--zx-gray-800) 60%, var(--zx-gray-700));
|
|
63
112
|
--zx-color-overlay-backdrop: color-mix(in srgb, var(--zx-gray-950) 38%, transparent);
|
|
64
|
-
--zx-color-border: color-mix(in srgb, var(--zx-gray-0)
|
|
65
|
-
--zx-color-border-
|
|
66
|
-
--zx-color-border-
|
|
67
|
-
--zx-color-
|
|
113
|
+
--zx-color-border: color-mix(in srgb, var(--zx-gray-0) 9%, transparent);
|
|
114
|
+
--zx-color-border-subtle: color-mix(in srgb, var(--zx-gray-0) 6%, transparent);
|
|
115
|
+
--zx-color-border-strong: color-mix(in srgb, var(--zx-gray-0) 24%, transparent);
|
|
116
|
+
--zx-color-border-control: color-mix(in srgb, var(--zx-gray-0) 14%, transparent);
|
|
117
|
+
/* Text is softened off pure white (about 90%), secondary text sits near 63%. */
|
|
118
|
+
--zx-color-text: var(--zx-gray-200);
|
|
68
119
|
--zx-color-text-muted: var(--zx-gray-400);
|
|
120
|
+
--zx-color-text-subtle: color-mix(in srgb, var(--zx-gray-500) 50%, var(--zx-gray-400));
|
|
69
121
|
--zx-color-text-placeholder: var(--zx-gray-500);
|
|
70
122
|
--zx-color-text-invert: var(--zx-gray-950);
|
|
71
123
|
--zx-color-accent: var(--zx-accent-400);
|
|
72
124
|
--zx-color-accent-hover: var(--zx-accent-300);
|
|
73
125
|
--zx-color-accent-active: var(--zx-accent-500);
|
|
74
|
-
--zx-color-accent-subtle: color-mix(in srgb, var(--zx-accent-400) 16%, var(--zx-
|
|
126
|
+
--zx-color-accent-subtle: color-mix(in srgb, var(--zx-accent-400) 16%, var(--zx-color-bg-surface));
|
|
75
127
|
--zx-color-on-accent: var(--zx-gray-950);
|
|
128
|
+
/* The primary button does not glow: it keeps the 600 stop and white ink, as in light. */
|
|
129
|
+
--zx-color-accent-solid: var(--zx-accent-600);
|
|
130
|
+
--zx-color-accent-solid-hover: var(--zx-accent-700);
|
|
131
|
+
--zx-color-accent-solid-active: color-mix(in srgb, var(--zx-accent-700) 82%, var(--zx-gray-950));
|
|
132
|
+
--zx-color-on-accent-solid: var(--zx-gray-0);
|
|
76
133
|
--zx-color-danger: var(--zx-red-400);
|
|
77
|
-
--zx-color-danger-bg: color-mix(in srgb, var(--zx-red-400)
|
|
134
|
+
--zx-color-danger-bg: color-mix(in srgb, var(--zx-red-400) 13%, var(--zx-color-bg-surface));
|
|
78
135
|
--zx-color-warning: var(--zx-amber-400);
|
|
79
|
-
--zx-color-warning-bg: color-mix(in srgb, var(--zx-amber-400) 16%, var(--zx-
|
|
136
|
+
--zx-color-warning-bg: color-mix(in srgb, var(--zx-amber-400) 16%, var(--zx-color-bg-surface));
|
|
80
137
|
--zx-color-success: var(--zx-green-400);
|
|
81
|
-
--zx-color-success-bg: color-mix(in srgb, var(--zx-green-400) 16%, var(--zx-
|
|
138
|
+
--zx-color-success-bg: color-mix(in srgb, var(--zx-green-400) 16%, var(--zx-color-bg-surface));
|
|
82
139
|
--zx-color-info: var(--zx-blue-400);
|
|
83
|
-
--zx-color-info-bg: color-mix(in srgb, var(--zx-blue-400) 16%, var(--zx-
|
|
140
|
+
--zx-color-info-bg: color-mix(in srgb, var(--zx-blue-400) 16%, var(--zx-color-bg-surface));
|
|
141
|
+
--zx-color-tone-blue-bg: color-mix(in srgb, var(--zx-tone-blue-500) 20%, var(--zx-color-bg-surface));
|
|
142
|
+
--zx-color-tone-blue-fg: var(--zx-tone-blue-300);
|
|
143
|
+
--zx-color-tone-teal-bg: color-mix(in srgb, var(--zx-tone-teal-500) 20%, var(--zx-color-bg-surface));
|
|
144
|
+
--zx-color-tone-teal-fg: var(--zx-tone-teal-300);
|
|
145
|
+
--zx-color-tone-green-bg: color-mix(in srgb, var(--zx-tone-green-500) 20%, var(--zx-color-bg-surface));
|
|
146
|
+
--zx-color-tone-green-fg: var(--zx-tone-green-300);
|
|
147
|
+
--zx-color-tone-amber-bg: color-mix(in srgb, var(--zx-tone-amber-500) 20%, var(--zx-color-bg-surface));
|
|
148
|
+
--zx-color-tone-amber-fg: var(--zx-tone-amber-300);
|
|
149
|
+
--zx-color-tone-orange-bg: color-mix(in srgb, var(--zx-tone-orange-500) 20%, var(--zx-color-bg-surface));
|
|
150
|
+
--zx-color-tone-orange-fg: var(--zx-tone-orange-300);
|
|
151
|
+
--zx-color-tone-red-bg: color-mix(in srgb, var(--zx-tone-red-500) 20%, var(--zx-color-bg-surface));
|
|
152
|
+
--zx-color-tone-red-fg: var(--zx-tone-red-300);
|
|
153
|
+
--zx-color-tone-pink-bg: color-mix(in srgb, var(--zx-tone-pink-500) 20%, var(--zx-color-bg-surface));
|
|
154
|
+
--zx-color-tone-pink-fg: var(--zx-tone-pink-300);
|
|
155
|
+
--zx-color-tone-violet-bg: color-mix(in srgb, var(--zx-tone-violet-500) 20%, var(--zx-color-bg-surface));
|
|
156
|
+
--zx-color-tone-violet-fg: var(--zx-tone-violet-300);
|
|
157
|
+
--zx-color-tone-slate-bg: color-mix(in srgb, var(--zx-tone-slate-500) 20%, var(--zx-color-bg-surface));
|
|
158
|
+
--zx-color-tone-slate-fg: var(--zx-tone-slate-300);
|
|
84
159
|
--zx-color-ring: var(--zx-color-accent);
|
|
85
160
|
--zx-focus-ring: 0 0 0 3px color-mix(in srgb, var(--zx-color-ring) 45%, transparent);
|
|
86
161
|
--zx-overlay-shadow: 0 12px 36px rgb(0 0 0 / 45%);
|
|
162
|
+
--zx-drag-shadow: 0 0 0 1px color-mix(in srgb, var(--zx-gray-0) 7%, transparent), 0 2px 6px -1px rgb(0 0 0 / 40%), 0 14px 32px -6px rgb(0 0 0 / 60%);
|
|
87
163
|
--zx-header-bg: var(--zx-gray-900);
|
|
88
164
|
--zx-header-text: var(--zx-gray-50);
|
|
89
165
|
}
|
package/styles/tokens/global.css
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Tier-1 palette and primitives.
|
|
3
3
|
*
|
|
4
4
|
* The neutral ramp uses Zinc-like values; the accent ramp uses an emerald progression anchored at
|
|
5
|
-
* 400 to the ZeyOS brand green #21cc75. Inter
|
|
6
|
-
* interfaces without coupling the token contract to another UI toolkit.
|
|
5
|
+
* 400 to the ZeyOS brand green #21cc75. Inter, one spacing unit, and small proportional radii
|
|
6
|
+
* support dense business interfaces without coupling the token contract to another UI toolkit.
|
|
7
7
|
*
|
|
8
8
|
* Only tier-2 semantic tokens (tokens/semantic.css, tokens/dark.css) may reference these.
|
|
9
9
|
* Component CSS must never use them directly — tests/lint-tokens.js enforces that.
|
|
@@ -24,12 +24,12 @@
|
|
|
24
24
|
--zx-gray-900: #18181b;
|
|
25
25
|
--zx-gray-950: #09090b;
|
|
26
26
|
|
|
27
|
-
/*
|
|
28
|
-
--zx-
|
|
29
|
-
--zx-
|
|
30
|
-
--zx-
|
|
31
|
-
--zx-
|
|
32
|
-
--zx-
|
|
27
|
+
/* Brand — an emerald ramp with the ZeyOS brand green at 400. The accent, never a status. */
|
|
28
|
+
--zx-emerald-300: #5ee9b5;
|
|
29
|
+
--zx-emerald-400: #21cc75;
|
|
30
|
+
--zx-emerald-500: #009966;
|
|
31
|
+
--zx-emerald-600: #007a55;
|
|
32
|
+
--zx-emerald-700: #006045;
|
|
33
33
|
|
|
34
34
|
/*
|
|
35
35
|
* Accent ramp — the indirection the semantic tier reads. It defaults to the Emerald ramp
|
|
@@ -37,13 +37,21 @@
|
|
|
37
37
|
* every semantic mapping: `tokens/themes.css` repoints these, and light, dark, and auto all
|
|
38
38
|
* follow because each of them picks its own stop off the ramp.
|
|
39
39
|
*/
|
|
40
|
-
--zx-accent-300: var(--zx-
|
|
41
|
-
--zx-accent-400: var(--zx-
|
|
42
|
-
--zx-accent-500: var(--zx-
|
|
43
|
-
--zx-accent-600: var(--zx-
|
|
44
|
-
--zx-accent-700: var(--zx-
|
|
40
|
+
--zx-accent-300: var(--zx-emerald-300);
|
|
41
|
+
--zx-accent-400: var(--zx-emerald-400);
|
|
42
|
+
--zx-accent-500: var(--zx-emerald-500);
|
|
43
|
+
--zx-accent-600: var(--zx-emerald-600);
|
|
44
|
+
--zx-accent-700: var(--zx-emerald-700);
|
|
45
45
|
|
|
46
|
-
/*
|
|
46
|
+
/*
|
|
47
|
+
* Status. Green is a yellow-green (OKLCH hue 130) so that "succeeded" never reads as the
|
|
48
|
+
* brand: the default accent sits at hue 155–165, and the two are told apart at a glance.
|
|
49
|
+
*/
|
|
50
|
+
--zx-green-300: #b3e87a;
|
|
51
|
+
--zx-green-400: #90cd40;
|
|
52
|
+
--zx-green-500: #6ba211;
|
|
53
|
+
--zx-green-600: #4d7800;
|
|
54
|
+
--zx-green-700: #3d5e06;
|
|
47
55
|
--zx-red-400: #ff6467;
|
|
48
56
|
--zx-red-500: #e7000b;
|
|
49
57
|
--zx-red-600: #c10007;
|
|
@@ -54,21 +62,67 @@
|
|
|
54
62
|
--zx-blue-500: #2b7fff;
|
|
55
63
|
--zx-blue-600: #155dfc;
|
|
56
64
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
--zx-
|
|
65
|
+
/*
|
|
66
|
+
* Tone ramps — the categorical palette behind tags, chips, icon tiles, avatars, and chart
|
|
67
|
+
* series. It is deliberately neither the accent nor the status set: nine hues built on one
|
|
68
|
+
* recipe in OKLCH (300 at L 0.86, 500 at L 0.60, 700 at L 0.46, moderate chroma), so every
|
|
69
|
+
* tone carries the same visual weight and none of them shouts. The semantic tier mixes 500 into
|
|
70
|
+
* the surface for a tone's fill and takes 700 (light) or 300 (dark) for its ink.
|
|
71
|
+
*/
|
|
72
|
+
--zx-tone-blue-300: #b3d4ff;
|
|
73
|
+
--zx-tone-blue-500: #3a81d7;
|
|
74
|
+
--zx-tone-blue-700: #1d589d;
|
|
75
|
+
--zx-tone-teal-300: #a8ddda;
|
|
76
|
+
--zx-tone-teal-500: #009390;
|
|
77
|
+
--zx-tone-teal-700: #006663;
|
|
78
|
+
--zx-tone-green-300: #b5deb5;
|
|
79
|
+
--zx-tone-green-500: #419547;
|
|
80
|
+
--zx-tone-green-700: #226929;
|
|
81
|
+
--zx-tone-amber-300: #eacc9b;
|
|
82
|
+
--zx-tone-amber-500: #a77600;
|
|
83
|
+
--zx-tone-amber-700: #745100;
|
|
84
|
+
--zx-tone-orange-300: #fbc3a7;
|
|
85
|
+
--zx-tone-orange-500: #c55f1d;
|
|
86
|
+
--zx-tone-orange-700: #8e3c00;
|
|
87
|
+
--zx-tone-red-300: #ffbfb8;
|
|
88
|
+
--zx-tone-red-500: #ca5551;
|
|
89
|
+
--zx-tone-red-700: #923432;
|
|
90
|
+
--zx-tone-pink-300: #f6bfd7;
|
|
91
|
+
--zx-tone-pink-500: #bc598c;
|
|
92
|
+
--zx-tone-pink-700: #873761;
|
|
93
|
+
--zx-tone-violet-300: #d4c8fe;
|
|
94
|
+
--zx-tone-violet-500: #886acf;
|
|
95
|
+
--zx-tone-violet-700: #5e4697;
|
|
96
|
+
--zx-tone-slate-300: #cad2dd;
|
|
97
|
+
--zx-tone-slate-500: #728295;
|
|
98
|
+
--zx-tone-slate-700: #4d5969;
|
|
99
|
+
|
|
100
|
+
/*
|
|
101
|
+
* Spacing — one unit, eight steps. Every step is a multiple of `--zx-space-unit`, so an
|
|
102
|
+
* application tightens or loosens its whole rhythm with one declaration rather than eight.
|
|
103
|
+
* At the default unit the steps are 4 / 8 / 12 / 16 / 20 / 24 / 32 / 40px.
|
|
104
|
+
*/
|
|
105
|
+
--zx-space-unit: 4px;
|
|
106
|
+
--zx-space-1: calc(var(--zx-space-unit) * 1);
|
|
107
|
+
--zx-space-2: calc(var(--zx-space-unit) * 2);
|
|
108
|
+
--zx-space-3: calc(var(--zx-space-unit) * 3);
|
|
109
|
+
--zx-space-4: calc(var(--zx-space-unit) * 4);
|
|
110
|
+
--zx-space-5: calc(var(--zx-space-unit) * 5);
|
|
111
|
+
--zx-space-6: calc(var(--zx-space-unit) * 6);
|
|
112
|
+
--zx-space-7: calc(var(--zx-space-unit) * 8);
|
|
113
|
+
--zx-space-8: calc(var(--zx-space-unit) * 10);
|
|
65
114
|
|
|
66
|
-
/*
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
115
|
+
/*
|
|
116
|
+
* Radius — one base, proportional steps, so a theme that scales `--zx-radius` keeps the
|
|
117
|
+
* relationship between a menu item, a control, and the panel around them. At the default base
|
|
118
|
+
* the steps are 2 / 3 / 4 / 6px. `-full` is for shapes whose roundness is the meaning: badges,
|
|
119
|
+
* avatars, toggles, progress tracks.
|
|
120
|
+
*/
|
|
121
|
+
--zx-radius: 4px;
|
|
122
|
+
--zx-radius-sm: calc(var(--zx-radius) * .5);
|
|
123
|
+
--zx-radius-md: calc(var(--zx-radius) * .75);
|
|
70
124
|
--zx-radius-lg: var(--zx-radius);
|
|
71
|
-
--zx-radius-xl: calc(var(--zx-radius)
|
|
125
|
+
--zx-radius-xl: calc(var(--zx-radius) * 1.5);
|
|
72
126
|
--zx-radius-full: 999px;
|
|
73
127
|
|
|
74
128
|
--zx-font-sans: Inter, "Inter Variable", ui-sans-serif, system-ui, -apple-system,
|
|
@@ -81,12 +135,52 @@
|
|
|
81
135
|
--zx-text-lg: 16px;
|
|
82
136
|
--zx-text-xl: 18px;
|
|
83
137
|
--zx-text-2xl: 24px;
|
|
138
|
+
--zx-text-3xl: 30px;
|
|
139
|
+
|
|
140
|
+
/*
|
|
141
|
+
* Weight and tracking. Interface text sits at the mid weights — medium for labels and rows,
|
|
142
|
+
* semibold for headings and the current item; heavier is for titles and figures only. UI text
|
|
143
|
+
* runs slightly tight (the root sets it), titles a little tighter.
|
|
144
|
+
*/
|
|
145
|
+
--zx-weight-medium: 500;
|
|
146
|
+
--zx-weight-semibold: 600;
|
|
147
|
+
--zx-tracking-tight: -0.01em;
|
|
148
|
+
--zx-tracking-title: -0.015em;
|
|
84
149
|
|
|
85
150
|
--zx-shadow-1: 0 1px 2px 0 rgb(9 9 11 / 5%);
|
|
86
151
|
--zx-shadow-2: 0 1px 3px 0 rgb(9 9 11 / 10%), 0 1px 2px -1px rgb(9 9 11 / 10%);
|
|
87
152
|
--zx-shadow-3: 0 10px 15px -3px rgb(9 9 11 / 10%), 0 4px 6px -4px rgb(9 9 11 / 10%);
|
|
88
153
|
|
|
154
|
+
/*
|
|
155
|
+
* Motion. Two durations and three named curves: `--zx-ease` for state changes (hover, colour,
|
|
156
|
+
* a fade), `--zx-ease-spring` for things that pop in — a small overshoot of about 3%, never a
|
|
157
|
+
* bounce — and `--zx-ease-drawer` for panels that slide: a decisive ease-out that covers most of
|
|
158
|
+
* the distance at once and settles, so a drawer feels like it arrives rather than drifts.
|
|
159
|
+
*/
|
|
89
160
|
--zx-dur-fast: 120ms;
|
|
90
161
|
--zx-dur-base: 180ms;
|
|
91
162
|
--zx-ease: cubic-bezier(.2, .6, .3, 1);
|
|
163
|
+
--zx-ease-spring: cubic-bezier(.34, 1.32, .64, 1);
|
|
164
|
+
--zx-ease-drawer: cubic-bezier(.32, .72, 0, 1);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/*
|
|
168
|
+
* Motion as a setting. `data-zx-motion="reduced"` on any element — usually `<html>`, from an
|
|
169
|
+
* application's own preference — stops movement inside it: every duration becomes 0ms here, and
|
|
170
|
+
* `base.css` stops the CSS animations and transitions that do not read a token. The operating
|
|
171
|
+
* system's reduced-motion preference does the same for the whole page. There is deliberately no
|
|
172
|
+
* value that turns motion back on: a person who asked their system for less motion gets less,
|
|
173
|
+
* whatever an application or a region says. `src/core/motion.js` answers the same question for
|
|
174
|
+
* script (`prefersReducedMotion`, `watchMotion`).
|
|
175
|
+
*/
|
|
176
|
+
[data-zx-motion="reduced"] {
|
|
177
|
+
--zx-dur-fast: 0ms;
|
|
178
|
+
--zx-dur-base: 0ms;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
@media (prefers-reduced-motion: reduce) {
|
|
182
|
+
:root {
|
|
183
|
+
--zx-dur-fast: 0ms;
|
|
184
|
+
--zx-dur-base: 0ms;
|
|
185
|
+
}
|
|
92
186
|
}
|