@godxjp/ui 18.4.0 → 18.6.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/README.md +16 -1
- package/dist/app/theme-axes.d.ts +11 -3
- package/dist/app/theme-axes.js +2 -1
- package/dist/components/charts/chart-frame.d.ts +17 -3
- package/dist/components/charts/chart-frame.js +7 -1
- package/dist/components/charts/chart-summary.d.ts +21 -0
- package/dist/components/charts/chart-summary.js +32 -5
- package/dist/components/charts/compact-bar-trend.d.ts +30 -0
- package/dist/components/charts/compact-bar-trend.js +74 -0
- package/dist/components/charts/index.d.ts +6 -0
- package/dist/components/charts/index.js +2 -0
- package/dist/components/data-display/badge.d.ts +8 -0
- package/dist/components/data-display/badge.js +7 -1
- package/dist/components/data-display/data-table.d.ts +40 -4
- package/dist/components/data-display/data-table.js +69 -2
- package/dist/components/data-display/empty-state.js +1 -1
- package/dist/components/data-display/index.d.ts +4 -2
- package/dist/components/data-display/index.js +10 -1
- package/dist/components/data-display/list-row.d.ts +41 -4
- package/dist/components/data-display/list-row.js +23 -3
- package/dist/components/data-display/qr-code.d.ts +1 -1
- package/dist/components/data-display/service-launcher-card.d.ts +40 -0
- package/dist/components/data-display/service-launcher-card.js +97 -0
- package/dist/components/data-display/table.d.ts +47 -2
- package/dist/components/data-display/table.js +29 -4
- package/dist/components/data-entry/command-palette.d.ts +37 -0
- package/dist/components/data-entry/command-palette.js +125 -0
- package/dist/components/data-entry/command.d.ts +10 -10
- package/dist/components/data-entry/index.d.ts +3 -0
- package/dist/components/data-entry/index.js +2 -0
- package/dist/components/data-entry/input-otp.d.ts +1 -0
- package/dist/components/feedback/dialog.d.ts +16 -1
- package/dist/components/feedback/dialog.js +46 -33
- package/dist/components/feedback/index.d.ts +5 -2
- package/dist/components/feedback/index.js +8 -2
- package/dist/components/feedback/sheet.d.ts +26 -4
- package/dist/components/feedback/sheet.js +54 -7
- package/dist/components/feedback/two-factor-setup.d.ts +31 -0
- package/dist/components/feedback/two-factor-setup.js +97 -0
- package/dist/components/general/index.d.ts +1 -1
- package/dist/components/general/logo.d.ts +49 -9
- package/dist/components/general/logo.js +67 -14
- package/dist/components/layout/app-shell.d.ts +1 -1
- package/dist/components/layout/app-shell.js +55 -30
- package/dist/components/layout/auth-account-summary.d.ts +5 -0
- package/dist/components/layout/auth-account-summary.js +31 -0
- package/dist/components/layout/auth-divider.d.ts +7 -0
- package/dist/components/layout/auth-divider.js +21 -0
- package/dist/components/layout/auth-footer.d.ts +5 -0
- package/dist/components/layout/auth-footer.js +24 -0
- package/dist/components/layout/auth-identity.d.ts +5 -0
- package/dist/components/layout/auth-identity.js +17 -0
- package/dist/components/layout/auth-shell.d.ts +9 -1
- package/dist/components/layout/auth-shell.js +25 -6
- package/dist/components/layout/auth-stack.d.ts +4 -0
- package/dist/components/layout/auth-stack.js +8 -0
- package/dist/components/layout/centered-shell.d.ts +5 -2
- package/dist/components/layout/centered-shell.js +29 -19
- package/dist/components/layout/error-surface.d.ts +35 -0
- package/dist/components/layout/error-surface.js +155 -0
- package/dist/components/layout/flex.d.ts +1 -1
- package/dist/components/layout/flex.js +4 -0
- package/dist/components/layout/index.d.ts +23 -3
- package/dist/components/layout/index.js +21 -2
- package/dist/components/layout/legal-document-shell.d.ts +34 -0
- package/dist/components/layout/legal-document-shell.js +186 -0
- package/dist/components/layout/master-detail.d.ts +24 -0
- package/dist/components/layout/master-detail.js +48 -0
- package/dist/components/layout/org-switcher.d.ts +9 -0
- package/dist/components/layout/org-switcher.js +218 -0
- package/dist/components/layout/page-container.d.ts +1 -1
- package/dist/components/layout/page-container.js +7 -2
- package/dist/components/layout/sidebar-link.d.ts +43 -0
- package/dist/components/layout/sidebar-link.js +13 -0
- package/dist/components/layout/sidebar.d.ts +42 -5
- package/dist/components/layout/sidebar.js +170 -85
- package/dist/components/navigation/app-setting-picker.js +17 -6
- package/dist/components/navigation/filter-bar.d.ts +12 -3
- package/dist/components/navigation/filter-bar.js +8 -2
- package/dist/components/navigation/index.d.ts +2 -2
- package/dist/components/navigation/index.js +3 -1
- package/dist/components/navigation/steps.js +38 -19
- package/dist/components/navigation/tabs-scroll.d.ts +70 -0
- package/dist/components/navigation/tabs-scroll.js +76 -0
- package/dist/components/navigation/tabs.js +47 -23
- package/dist/components/ui/avatar.d.ts +2 -1
- package/dist/components/ui/avatar.js +2 -1
- package/dist/components/ui/input-otp.d.ts +4 -1
- package/dist/components/ui/input-otp.js +2 -1
- package/dist/components/ui/toggle-group.d.ts +7 -4
- package/dist/components/ui/toggle-group.js +32 -21
- package/dist/email/brand-mark.d.ts +108 -0
- package/dist/email/brand-mark.js +88 -0
- package/dist/email/color.d.ts +53 -0
- package/dist/email/color.js +37 -0
- package/dist/email/geometry.d.ts +120 -0
- package/dist/email/geometry.js +90 -0
- package/dist/email/index.d.ts +83 -0
- package/dist/email/index.js +82 -0
- package/dist/email/inline-style.d.ts +27 -0
- package/dist/email/inline-style.js +26 -0
- package/dist/email/tokens.generated.d.ts +167 -0
- package/dist/email/tokens.generated.js +162 -0
- package/dist/email/urgency.d.ts +22 -0
- package/dist/email/urgency.js +14 -0
- package/dist/i18n/messages/en.json +36 -3
- package/dist/i18n/messages/ja.json +36 -3
- package/dist/i18n/messages/vi.json +36 -3
- package/dist/inertia/index.d.ts +50 -0
- package/dist/inertia/index.js +5 -0
- package/dist/props/components/app.prop.d.ts +11 -1
- package/dist/props/components/charts.prop.d.ts +40 -1
- package/dist/props/components/data-display.prop.d.ts +75 -1
- package/dist/props/components/data-entry.prop.d.ts +6 -0
- package/dist/props/components/feedback.prop.d.ts +10 -0
- package/dist/props/components/index.d.ts +3 -3
- package/dist/props/components/layout.prop.d.ts +560 -10
- package/dist/props/components/layout.prop.js +1 -0
- package/dist/props/components/navigation.prop.d.ts +24 -2
- package/dist/props/registry.d.ts +433 -8
- package/dist/props/registry.js +527 -9
- package/dist/props/vocabulary/data.prop.d.ts +27 -0
- package/dist/props/vocabulary/index.d.ts +3 -3
- package/dist/props/vocabulary/interaction.prop.d.ts +10 -1
- package/dist/props/vocabulary/layout.prop.d.ts +49 -0
- package/dist/styles/base.css +8 -2
- package/dist/styles/card-layout.css +161 -7
- package/dist/styles/chart-layout.css +97 -0
- package/dist/styles/control.css +76 -2
- package/dist/styles/data-display-layout.css +78 -6
- package/dist/styles/dialog-layout.css +105 -4
- package/dist/styles/fonts.css +15 -4
- package/dist/styles/index.css +11 -3
- package/dist/styles/layout.css +466 -1
- package/dist/styles/logo-layout.css +95 -0
- package/dist/styles/navigation-layout.css +152 -0
- package/dist/styles/shell-layout.css +790 -40
- package/dist/styles/table-layout.css +164 -1
- package/dist/theme/dxs.canonical.css +77 -0
- package/dist/tokens/axes.css +40 -0
- package/dist/tokens/base.css +6 -0
- package/dist/tokens/components/card.css +48 -0
- package/dist/tokens/components/chart.css +47 -0
- package/dist/tokens/components/control.css +16 -0
- package/dist/tokens/components/data-display.css +13 -0
- package/dist/tokens/components/email.css +93 -0
- package/dist/tokens/components/error-surface.css +36 -0
- package/dist/tokens/components/feedback.css +17 -0
- package/dist/tokens/components/legal-document.css +67 -0
- package/dist/tokens/components/list-row.css +43 -2
- package/dist/tokens/components/logo.css +74 -0
- package/dist/tokens/components/navigation.css +28 -0
- package/dist/tokens/components/sheet.css +19 -0
- package/dist/tokens/components/shell.css +210 -0
- package/dist/tokens/components/sidebar.css +33 -0
- package/dist/tokens/components/table.css +45 -0
- package/dist/tokens/foundation.css +31 -2
- package/dist/tokens/semantic/layout.css +69 -2
- package/package.json +22 -5
|
@@ -74,12 +74,17 @@
|
|
|
74
74
|
gap: var(--space-inline-sm);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
/* The footer owns its own inset on BOTH axes (gh#236) — it is a self-contained slot that is
|
|
78
|
+
* usually dropped straight into a flush container, so relying on an ancestor for inline/block-end
|
|
79
|
+
* padding left the label and the page-size Select flush against the container edge and its
|
|
80
|
+
* closing border. Logical properties only (RTL-safe); both axes are tunable tokens (#45). */
|
|
77
81
|
.ui-data-table-pagination {
|
|
78
82
|
display: flex;
|
|
79
83
|
align-items: center;
|
|
80
84
|
justify-content: flex-end;
|
|
81
85
|
gap: var(--space-inline-sm);
|
|
82
|
-
padding-
|
|
86
|
+
padding-block: var(--table-pagination-padding-y, var(--space-stack-sm));
|
|
87
|
+
padding-inline: var(--table-pagination-padding-x, var(--table-cell-space-x));
|
|
83
88
|
}
|
|
84
89
|
|
|
85
90
|
/* Numbered footer may wrap only between its two semantic groups. The supported JA/EN/VI locale
|
|
@@ -115,10 +120,22 @@
|
|
|
115
120
|
|
|
116
121
|
.ui-data-table-surface {
|
|
117
122
|
overflow: hidden;
|
|
123
|
+
/* Narrow-viewport legibility floor — a TOKEN, not the old `min-w-[640px]` literal (gh#253,
|
|
124
|
+
* rule #45). Cleared at the `sm` step below, and opted out of entirely by the collection
|
|
125
|
+
* preset, which owns its width through the column-priority measures. */
|
|
126
|
+
min-inline-size: var(--table-surface-min-inline-size);
|
|
118
127
|
border: 1px solid hsl(var(--border));
|
|
119
128
|
border-radius: var(--radius-md);
|
|
120
129
|
}
|
|
121
130
|
|
|
131
|
+
/* `preset="action-collection"` (gh#253) — the priority measures fit the table to its container at
|
|
132
|
+
* every width, so the desktop floor would re-introduce exactly the horizontal scroll the preset
|
|
133
|
+
* removes. Attribute-scoped: `preset="default"` emits NO attribute, so an untouched DataTable
|
|
134
|
+
* never matches this rule (the inert-default contract, gh#231). */
|
|
135
|
+
.ui-data-table-surface[data-preset="action-collection"] {
|
|
136
|
+
min-inline-size: 0;
|
|
137
|
+
}
|
|
138
|
+
|
|
122
139
|
/* Zebra striping (opt-in via the `striped` prop). Selected rows keep their
|
|
123
140
|
* own emphasis, so they are excluded from the stripe. */
|
|
124
141
|
.ui-data-table-surface[data-striped] tbody tr:nth-child(even):not([data-state="selected"]) {
|
|
@@ -187,6 +204,12 @@
|
|
|
187
204
|
.ui-data-table-scroll::after {
|
|
188
205
|
inset-inline-end: 0;
|
|
189
206
|
}
|
|
207
|
+
|
|
208
|
+
/* From `sm` up the viewport is already wider than the floor, so it is released and the surface
|
|
209
|
+
* simply fills its container (this is the `sm:min-w-0` half of the old utility pair). */
|
|
210
|
+
.ui-data-table-surface {
|
|
211
|
+
min-inline-size: 0;
|
|
212
|
+
}
|
|
190
213
|
}
|
|
191
214
|
|
|
192
215
|
/* ── Pinned (sticky) inline-end column ────────────────────────────────
|
|
@@ -233,3 +256,143 @@
|
|
|
233
256
|
);
|
|
234
257
|
}
|
|
235
258
|
}
|
|
259
|
+
|
|
260
|
+
@layer components {
|
|
261
|
+
/* ── Table · `preset="action-collection"` (gh#253) ───────────────────────────────────────────
|
|
262
|
+
* The canonical dense approval / action queue: requester · target · reason · requested date ·
|
|
263
|
+
* row actions, all five discoverable in the initial 390px frame, WITHOUT a consumer width, a
|
|
264
|
+
* hidden column or a page-local breakpoint.
|
|
265
|
+
*
|
|
266
|
+
* It keeps the REAL table: no `display` change, no role rewriting, no card transformation — so
|
|
267
|
+
* `<table>/<thead>/<tr>/<th>/<td>` semantics, header association, `aria-sort` and screen-reader
|
|
268
|
+
* table navigation survive exactly as they are at 1440. What the preset replaces is the SIZING
|
|
269
|
+
* model: the desktop INTRINSIC column widths (a `white-space: nowrap` reason column is what
|
|
270
|
+
* makes a five-column queue 1511px wide and forces the horizontal scroll gh#253 reports) give
|
|
271
|
+
* way to `table-layout: fixed` plus token-owned column-PRIORITY measures, and cells wrap.
|
|
272
|
+
*
|
|
273
|
+
* The collapse step is measured against the TABLE'S OWN container, not the viewport (a table in
|
|
274
|
+
* a master rail must collapse before the page does), so it is a container query. Below the step
|
|
275
|
+
* only the MEASURES and the type/padding tier change — the structure is identical. */
|
|
276
|
+
.ui-table-collection {
|
|
277
|
+
container: ui-table-collection / inline-size;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.ui-table-collection [data-slot="table"] {
|
|
281
|
+
table-layout: fixed;
|
|
282
|
+
inline-size: 100%;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
.ui-table-collection :is([data-slot="table-head"], [data-slot="table-cell"]) {
|
|
286
|
+
/* The column measure comes from `priority`; an unmarked column takes what is left (`auto`),
|
|
287
|
+
* which is the free-text column. */
|
|
288
|
+
inline-size: var(--table-action-collection-column-width, auto);
|
|
289
|
+
overflow-wrap: anywhere;
|
|
290
|
+
white-space: normal;
|
|
291
|
+
vertical-align: top;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
.ui-table-collection [data-priority="primary"] {
|
|
295
|
+
--table-action-collection-column-width: var(--table-action-collection-primary-width);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
.ui-table-collection [data-priority="secondary"] {
|
|
299
|
+
--table-action-collection-column-width: var(--table-action-collection-secondary-width);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.ui-table-collection [data-priority="meta"] {
|
|
303
|
+
--table-action-collection-column-width: var(--table-action-collection-meta-width);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.ui-table-collection [data-priority="actions"] {
|
|
307
|
+
--table-action-collection-column-width: var(--table-action-collection-actions-width);
|
|
308
|
+
text-align: end;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/* Below the step the SOURCE measures are re-pointed to their compact tier (and the type / row
|
|
312
|
+
* density with them); nothing else moves. One block per canonical step — a media/container
|
|
313
|
+
* query cannot read a `var()`, so the tokenized scale is written out (sm 40rem · md 48rem ·
|
|
314
|
+
* lg 64rem · xl 80rem, the same steps as `--master-detail-collapse-below`). */
|
|
315
|
+
@container ui-table-collection (width < 40rem) {
|
|
316
|
+
[data-collapse-below="sm"] [data-slot="table"] {
|
|
317
|
+
--table-action-collection-primary-width: var(--table-action-collection-primary-width-compact);
|
|
318
|
+
--table-action-collection-secondary-width: var(
|
|
319
|
+
--table-action-collection-secondary-width-compact
|
|
320
|
+
);
|
|
321
|
+
--table-action-collection-meta-width: var(--table-action-collection-meta-width-compact);
|
|
322
|
+
--table-action-collection-actions-width: var(--table-action-collection-actions-width-compact);
|
|
323
|
+
--table-row-height: var(--table-action-collection-row-height-compact);
|
|
324
|
+
--table-cell-space-x: var(--table-action-collection-cell-space-x-compact);
|
|
325
|
+
--table-cell-padding-y: var(--table-action-collection-cell-padding-y-compact);
|
|
326
|
+
font-size: var(--table-action-collection-font-size-compact);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/* A nowrap child (a Badge pill, a chip) would otherwise bleed into the next column at the
|
|
330
|
+
* compact measure — inside a collapsed action cell everything wraps. */
|
|
331
|
+
[data-collapse-below="sm"] [data-slot="table-cell"] * {
|
|
332
|
+
white-space: normal;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
@container ui-table-collection (width < 48rem) {
|
|
337
|
+
[data-collapse-below="md"] [data-slot="table"] {
|
|
338
|
+
--table-action-collection-primary-width: var(--table-action-collection-primary-width-compact);
|
|
339
|
+
--table-action-collection-secondary-width: var(
|
|
340
|
+
--table-action-collection-secondary-width-compact
|
|
341
|
+
);
|
|
342
|
+
--table-action-collection-meta-width: var(--table-action-collection-meta-width-compact);
|
|
343
|
+
--table-action-collection-actions-width: var(--table-action-collection-actions-width-compact);
|
|
344
|
+
--table-row-height: var(--table-action-collection-row-height-compact);
|
|
345
|
+
--table-cell-space-x: var(--table-action-collection-cell-space-x-compact);
|
|
346
|
+
--table-cell-padding-y: var(--table-action-collection-cell-padding-y-compact);
|
|
347
|
+
font-size: var(--table-action-collection-font-size-compact);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/* A nowrap child (a Badge pill, a chip) would otherwise bleed into the next column at the
|
|
351
|
+
* compact measure — inside a collapsed action cell everything wraps. */
|
|
352
|
+
[data-collapse-below="md"] [data-slot="table-cell"] * {
|
|
353
|
+
white-space: normal;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
@container ui-table-collection (width < 64rem) {
|
|
358
|
+
[data-collapse-below="lg"] [data-slot="table"] {
|
|
359
|
+
--table-action-collection-primary-width: var(--table-action-collection-primary-width-compact);
|
|
360
|
+
--table-action-collection-secondary-width: var(
|
|
361
|
+
--table-action-collection-secondary-width-compact
|
|
362
|
+
);
|
|
363
|
+
--table-action-collection-meta-width: var(--table-action-collection-meta-width-compact);
|
|
364
|
+
--table-action-collection-actions-width: var(--table-action-collection-actions-width-compact);
|
|
365
|
+
--table-row-height: var(--table-action-collection-row-height-compact);
|
|
366
|
+
--table-cell-space-x: var(--table-action-collection-cell-space-x-compact);
|
|
367
|
+
--table-cell-padding-y: var(--table-action-collection-cell-padding-y-compact);
|
|
368
|
+
font-size: var(--table-action-collection-font-size-compact);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/* A nowrap child (a Badge pill, a chip) would otherwise bleed into the next column at the
|
|
372
|
+
* compact measure — inside a collapsed action cell everything wraps. */
|
|
373
|
+
[data-collapse-below="lg"] [data-slot="table-cell"] * {
|
|
374
|
+
white-space: normal;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
@container ui-table-collection (width < 80rem) {
|
|
379
|
+
[data-collapse-below="xl"] [data-slot="table"] {
|
|
380
|
+
--table-action-collection-primary-width: var(--table-action-collection-primary-width-compact);
|
|
381
|
+
--table-action-collection-secondary-width: var(
|
|
382
|
+
--table-action-collection-secondary-width-compact
|
|
383
|
+
);
|
|
384
|
+
--table-action-collection-meta-width: var(--table-action-collection-meta-width-compact);
|
|
385
|
+
--table-action-collection-actions-width: var(--table-action-collection-actions-width-compact);
|
|
386
|
+
--table-row-height: var(--table-action-collection-row-height-compact);
|
|
387
|
+
--table-cell-space-x: var(--table-action-collection-cell-space-x-compact);
|
|
388
|
+
--table-cell-padding-y: var(--table-action-collection-cell-padding-y-compact);
|
|
389
|
+
font-size: var(--table-action-collection-font-size-compact);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/* A nowrap child (a Badge pill, a chip) would otherwise bleed into the next column at the
|
|
393
|
+
* compact measure — inside a collapsed action cell everything wraps. */
|
|
394
|
+
[data-collapse-below="xl"] [data-slot="table-cell"] * {
|
|
395
|
+
white-space: normal;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/* ───────────────────────────────────────────────────────────────────────────
|
|
2
|
+
* THE CANONICAL DXS THEME — gh#214
|
|
3
|
+
*
|
|
4
|
+
* The one stylesheet a DXS surface imports INSTEAD of `@godxjp/ui/styles`. It
|
|
5
|
+
* makes the canonical contract the DEFAULT for every surface in the app, so no
|
|
6
|
+
* page ever needs local CSS for auth geometry, density, page insets, the brand
|
|
7
|
+
* logo colour, the auth divider, or the legal footer.
|
|
8
|
+
*
|
|
9
|
+
* import "@godxjp/ui/theme/dxs.canonical.css"; // instead of @godxjp/ui/styles
|
|
10
|
+
*
|
|
11
|
+
* Prefer the RUNTIME route when the app already mounts the provider — it is the
|
|
12
|
+
* same contract, switchable at runtime and persisted with the other axes:
|
|
13
|
+
*
|
|
14
|
+
* <AppProvider brand="dxs"> … </AppProvider> // writes <html data-brand="dxs">
|
|
15
|
+
*
|
|
16
|
+
* NOT A NEW BRAND. Every value below is canonical evidence already encoded in
|
|
17
|
+
* this package — the shipped GodX Navy primary ramp, and the
|
|
18
|
+
* `--auth-shell-canonical-*` measures declared in
|
|
19
|
+
* `src/tokens/components/shell.css`. This file only re-points the generic knob
|
|
20
|
+
* at the canonical one; it invents no colour and no geometry.
|
|
21
|
+
*
|
|
22
|
+
* SOURCE OF TRUTH: `src/tokens/axes.css` · `:root[data-brand="dxs"]`. This file
|
|
23
|
+
* mirrors that block at `:root` for stylesheet-only apps (no provider). They are
|
|
24
|
+
* asserted identical by `src/tokens/__tests__/dxs-canonical-theme.test.ts` — add
|
|
25
|
+
* a knob to BOTH or to neither.
|
|
26
|
+
*
|
|
27
|
+
* OVERRIDING: declare your own root block AFTER this import; at equal
|
|
28
|
+
* specificity the later declaration wins. Token overrides only — never component
|
|
29
|
+
* CSS or Tailwind utilities in a theme file.
|
|
30
|
+
* ─────────────────────────────────────────────────────────────────────────── */
|
|
31
|
+
|
|
32
|
+
@import "@godxjp/ui/styles";
|
|
33
|
+
|
|
34
|
+
:root {
|
|
35
|
+
/* ── Brand palette — the shipped GodX Navy ramp (identical to the `brand`
|
|
36
|
+
* axis preset). The emerald IDENTITY mark is deliberately NOT here:
|
|
37
|
+
* `--logo-godx-color` / `--logo-wordmark-color` default to the `--brand`
|
|
38
|
+
* IDENTITY role at their call sites and never read `--primary` (nor the
|
|
39
|
+
* `--success` status green — gh#250), so a re-themed action colour can
|
|
40
|
+
* never recolour the GoDX mark or wordmark. */
|
|
41
|
+
--primary: 211 73% 15%;
|
|
42
|
+
--primary-foreground: 0 0% 100%;
|
|
43
|
+
--ring: 24 99% 46%;
|
|
44
|
+
--accent: 24 99% 95%;
|
|
45
|
+
--accent-foreground: 24 99% 28%;
|
|
46
|
+
|
|
47
|
+
/* ── Canonical auth surface — 36px controls, 22.5rem card measure, 16px page
|
|
48
|
+
* inset (15px below 30rem, see the media query below). This is what
|
|
49
|
+
* `AuthShell variant="canonical"` applies per-instance, made the default
|
|
50
|
+
* for every auth surface in the app. `variant="canonical"` still owns the
|
|
51
|
+
* COMPACT CARD density (`[data-density="compact"]` is element-scoped and
|
|
52
|
+
* cannot be reached from a token), so keep passing it for the full
|
|
53
|
+
* canonical card rhythm. */
|
|
54
|
+
--auth-shell-control-height: var(--auth-shell-canonical-control-height);
|
|
55
|
+
--auth-shell-heading-size: var(--auth-shell-canonical-heading-size);
|
|
56
|
+
--auth-shell-card-max-width: var(--auth-shell-canonical-card-max-width);
|
|
57
|
+
--auth-shell-main-padding: var(--auth-shell-canonical-main-padding);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* Canonical 15px mobile page inset. */
|
|
61
|
+
@media (max-width: 30rem) {
|
|
62
|
+
:root {
|
|
63
|
+
--auth-shell-main-padding: var(--auth-shell-canonical-main-padding-mobile);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* ── TODO (no canonical in-repo source yet — do NOT guess) ───────────────────
|
|
68
|
+
* · AppShell rail width / collapsed rail width / responsive breakpoint are
|
|
69
|
+
* still CSS literals, not tokens (gh#213), so there is nothing for a theme to
|
|
70
|
+
* bind. Add the bindings here once `--app-shell-sidebar-width` /
|
|
71
|
+
* `--app-shell-rail-width` / the breakpoint knob ship.
|
|
72
|
+
* · Standalone `.ui-topbar` height/gap/inset knobs do not exist yet (gh#213).
|
|
73
|
+
* · A real DXS wordmark ASSET (logotype artwork) has not been supplied by
|
|
74
|
+
* design. `<Logo wordmark="GoDX" />` typesets the name in the design-system
|
|
75
|
+
* display face via `--logo-wordmark-font-family`; swap in the real logotype
|
|
76
|
+
* (an inline `<svg>` passed as `wordmark`) when it exists.
|
|
77
|
+
* ─────────────────────────────────────────────────────────────────────────── */
|
package/dist/tokens/axes.css
CHANGED
|
@@ -57,3 +57,43 @@
|
|
|
57
57
|
--accent: 215 25% 94%;
|
|
58
58
|
--accent-foreground: 215 25% 20%;
|
|
59
59
|
}
|
|
60
|
+
|
|
61
|
+
/* ── THE CANONICAL DXS PRESET (gh#214) ──────────────────────────────────────
|
|
62
|
+
* `dxs` is the one brand value that is NOT just a primary tint: it binds the
|
|
63
|
+
* canonical DXS SURFACE CONTRACT that every hosted-identity screen shares, so a
|
|
64
|
+
* service selects it once (`<AppProvider brand="dxs">`, or import
|
|
65
|
+
* `@godxjp/ui/theme/dxs.canonical.css`) and needs ZERO page CSS for auth
|
|
66
|
+
* geometry, density, insets, logo colour, divider or footer.
|
|
67
|
+
*
|
|
68
|
+
* SINGLE SOURCE OF TRUTH — every value below is already canonical evidence in
|
|
69
|
+
* this package: the palette is the shipped GodX Navy ramp (identical to
|
|
70
|
+
* `data-brand="brand"`), and the auth knobs simply re-point the generic
|
|
71
|
+
* AuthShell tokens at the `--auth-shell-canonical-*` values declared in
|
|
72
|
+
* `tokens/components/shell.css`. Nothing here is a new brand colour.
|
|
73
|
+
* `src/theme/dxs.canonical.css` mirrors this block for stylesheet-only apps;
|
|
74
|
+
* `src/tokens/__tests__/dxs-canonical-theme.test.ts` fails if the two drift.
|
|
75
|
+
*
|
|
76
|
+
* The GoDX identity mark needs no binding: `--logo-godx-color` /
|
|
77
|
+
* `--logo-wordmark-color` already default to the `--brand` IDENTITY role (the
|
|
78
|
+
* canonical emerald) at their call sites, and never reference `--primary` — nor
|
|
79
|
+
* the `--success` status green they wrongly borrowed before gh#250. */
|
|
80
|
+
:root[data-brand="dxs"] {
|
|
81
|
+
--primary: 211 73% 15%;
|
|
82
|
+
--primary-foreground: 0 0% 100%;
|
|
83
|
+
--ring: 24 99% 46%;
|
|
84
|
+
--accent: 24 99% 95%;
|
|
85
|
+
--accent-foreground: 24 99% 28%;
|
|
86
|
+
|
|
87
|
+
/* Canonical auth surface — 36px controls, 22.5rem card measure, 16px page
|
|
88
|
+
* inset (15px below 30rem, see the media query). Matches AuthShell
|
|
89
|
+
* `variant="canonical"`, which still owns the compact CARD density knob. */
|
|
90
|
+
--auth-shell-control-height: var(--auth-shell-canonical-control-height);
|
|
91
|
+
--auth-shell-heading-size: var(--auth-shell-canonical-heading-size);
|
|
92
|
+
--auth-shell-card-max-width: var(--auth-shell-canonical-card-max-width);
|
|
93
|
+
--auth-shell-main-padding: var(--auth-shell-canonical-main-padding);
|
|
94
|
+
}
|
|
95
|
+
@media (max-width: 30rem) {
|
|
96
|
+
:root[data-brand="dxs"] {
|
|
97
|
+
--auth-shell-main-padding: var(--auth-shell-canonical-main-padding-mobile);
|
|
98
|
+
}
|
|
99
|
+
}
|
package/dist/tokens/base.css
CHANGED
|
@@ -9,13 +9,19 @@
|
|
|
9
9
|
@import "./components/control.css";
|
|
10
10
|
@import "./components/form.css";
|
|
11
11
|
@import "./components/card.css";
|
|
12
|
+
@import "./components/chart.css";
|
|
12
13
|
@import "./components/descriptions.css";
|
|
13
14
|
@import "./components/table.css";
|
|
14
15
|
@import "./components/feedback.css";
|
|
16
|
+
@import "./components/sheet.css";
|
|
15
17
|
@import "./components/badge.css";
|
|
16
18
|
@import "./components/navigation.css";
|
|
17
19
|
@import "./components/data-display.css";
|
|
18
20
|
@import "./components/list-row.css";
|
|
19
21
|
@import "./components/logo.css";
|
|
22
|
+
@import "./components/email.css";
|
|
20
23
|
@import "./components/data-entry.css";
|
|
21
24
|
@import "./components/shell.css";
|
|
25
|
+
@import "./components/sidebar.css";
|
|
26
|
+
@import "./components/legal-document.css";
|
|
27
|
+
@import "./components/error-surface.css";
|
|
@@ -4,11 +4,28 @@
|
|
|
4
4
|
/* Horizontal inset of every slot (header / content / footer) + the resting top/bottom
|
|
5
5
|
* shell padding. This is the column the title, body and footer all align to. */
|
|
6
6
|
--card-space-inset: var(--space-section-active);
|
|
7
|
+
/* BLOCK-axis (top/bottom) shell padding of the slotted card rhythm — a plain header's top, a
|
|
8
|
+
* `solo` body's top, and the terminal slot's bottom (gh#232). Split off --card-space-inset so a
|
|
9
|
+
* shell (AuthShell compact) can retune the card's height WITHOUT moving the inline column.
|
|
10
|
+
* Declared `initial` — NOT `var(--card-space-inset)` — so the default resolves at the CALL SITE:
|
|
11
|
+
* a :root binding would freeze at the :root inset and `[data-density="tight"|"cozy"]` (which
|
|
12
|
+
* override --card-space-inset on the card element) would stop reaching it. See docs/TOKENS.md ·
|
|
13
|
+
* "Role-mirror knobs MUST be `initial`" — the same call-site rule applies to derived knobs. */
|
|
14
|
+
--card-space-shell-y: initial; /* default = var(--card-space-inset) */
|
|
7
15
|
/* Vertical padding of a BANDED header band (top = bottom). Drives --card-space-divided-y. */
|
|
8
16
|
--card-space-header-y: var(--space-stack-sm);
|
|
9
17
|
/* Gap between the header and the body, and the body's own top padding — the breathing
|
|
10
18
|
* room under a title before content begins. */
|
|
11
19
|
--card-space-body-y: var(--space-section-active);
|
|
20
|
+
/* Symmetric block padding for a SOLO content slot, so a composed shell can tune block and
|
|
21
|
+
* inline spacing independently without targeting CardContent.
|
|
22
|
+
* Declared `initial` for the SAME reason as --card-space-shell-y above: written as
|
|
23
|
+
* `var(--card-space-inset)` here it would freeze at the :root inset, and a card carrying
|
|
24
|
+
* [data-density="tight"|"cozy"] (which override --card-space-inset ON THE CARD) would keep the
|
|
25
|
+
* :root value. The default now resolves at the call site through the chain
|
|
26
|
+
* solo-y → shell-y → inset, so a solo body follows the general block knob when only that is
|
|
27
|
+
* set, and an explicit solo-y still wins. */
|
|
28
|
+
--card-space-solo-y: initial; /* default = var(--card-space-shell-y, var(--card-space-inset)) */
|
|
12
29
|
/* Vertical padding of a SEPARATED footer band (top = bottom). Drives --card-space-divided-y. */
|
|
13
30
|
--card-space-footer-y: var(--space-stack-sm);
|
|
14
31
|
/* DIVIDED-section vertical padding (rule #44/#45). A header/footer that carries a divider
|
|
@@ -75,4 +92,35 @@
|
|
|
75
92
|
--stat-card-icon-background: initial;
|
|
76
93
|
--stat-card-icon-foreground: initial;
|
|
77
94
|
--stat-card-delta-font-size: var(--font-size-xs);
|
|
95
|
+
/* ── ServiceLauncherCard (gh#219) ───────────────────────────────────────────────────
|
|
96
|
+
* Internal rhythm of a launcher tile: one gap knob drives the vertical stack AND the
|
|
97
|
+
* icon↔title↔status row, so a service theme retunes the whole tile density once. */
|
|
98
|
+
--card-service-launcher-space-gap: var(--space-stack-sm);
|
|
99
|
+
/* Semantic icon surface. `--control-height-lg` is the 36px control tier the hi-fi calls for —
|
|
100
|
+
* a tier token, never a literal, so the medallion tracks --scaling with its sibling controls. */
|
|
101
|
+
--card-service-launcher-icon-size: var(--control-height-lg);
|
|
102
|
+
--card-service-launcher-icon-glyph-size: var(--space-5);
|
|
103
|
+
--card-service-launcher-icon-radius: var(--radius-md);
|
|
104
|
+
/* Available-service medallion tint. `initial` (role-mirror rule, docs/TOKENS.md) so the role
|
|
105
|
+
* defaults resolve at the CALL SITE and a scoped [data-tenant]/.dark override reaches them.
|
|
106
|
+
* Defaults = hsl(var(--accent)) fill · hsl(var(--primary)) glyph. */
|
|
107
|
+
--card-service-launcher-icon-background: initial;
|
|
108
|
+
--card-service-launcher-icon-foreground: initial;
|
|
109
|
+
/* Unavailable medallion tint — applied when the consumer supplies `disabledReason`, so an
|
|
110
|
+
* un-launchable service never reads as brand-live. `initial` for the same role-mirror reason.
|
|
111
|
+
* Defaults = hsl(var(--muted)) fill · hsl(var(--muted-foreground)) glyph. */
|
|
112
|
+
--card-service-launcher-unavailable-icon-background: initial;
|
|
113
|
+
--card-service-launcher-unavailable-icon-foreground: initial;
|
|
114
|
+
/* Description prose — also drives the disabled-reason line and the catalog-CTA caption. */
|
|
115
|
+
--card-service-launcher-description-font-size: var(--font-size-xs);
|
|
116
|
+
--card-service-launcher-description-line-height: var(--line-height-body);
|
|
117
|
+
/* Mono metadata line (hostname · plan) — tighter leading than prose by design. */
|
|
118
|
+
--card-service-launcher-metadata-font-size: var(--font-size-xs);
|
|
119
|
+
--card-service-launcher-metadata-line-height: var(--line-height-normal);
|
|
120
|
+
/* Dashed catalog/add companion tile: kept tall enough to sit level with a populated launcher
|
|
121
|
+
* tile in the same grid row. Four control tiers ≈ medallion + title + description + action. */
|
|
122
|
+
--card-service-launcher-cta-min-height: calc(var(--control-height-lg) * 4);
|
|
123
|
+
/* Skeleton bar widths — shape-matched placeholders for the title and status badge. */
|
|
124
|
+
--card-service-launcher-skeleton-title-width: var(--space-12);
|
|
125
|
+
--card-service-launcher-skeleton-status-width: var(--space-10);
|
|
78
126
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/* Chart component tokens — the dependency-free `CompactBarTrend` primitive
|
|
2
|
+
* (`@godxjp/ui/charts`). Every piece of its geometry and every fill is a public knob so a
|
|
3
|
+
* service theme can match its own design grid WITHOUT page-local CSS or inline heights
|
|
4
|
+
* (cardinal rules #44/#45). The recharts-backed charts draw their own SVG and only use the
|
|
5
|
+
* foundation `--chart-1..6` palette. */
|
|
6
|
+
|
|
7
|
+
:root {
|
|
8
|
+
/* ── Plot height tiers (size = xs|sm|md|lg) ───────────────────────────────────────────
|
|
9
|
+
* `xs` is the canonical dashboard-summary-card density: a seven-day trend that sits under
|
|
10
|
+
* a KPI headline without stealing its vertical rhythm. A service retunes the whole scale
|
|
11
|
+
* here; a screen picks a step with the `size` prop. */
|
|
12
|
+
--chart-trend-plot-height-xs: 3.5rem;
|
|
13
|
+
--chart-trend-plot-height-sm: 5rem;
|
|
14
|
+
--chart-trend-plot-height-md: 7.5rem;
|
|
15
|
+
--chart-trend-plot-height-lg: 10rem;
|
|
16
|
+
/* Active tier — chart-layout.css re-points this per `data-size`; overriding it directly
|
|
17
|
+
* pins one height for every trend regardless of `size`. */
|
|
18
|
+
--chart-trend-plot-height: var(--chart-trend-plot-height-xs);
|
|
19
|
+
|
|
20
|
+
/* ── Bar marks ────────────────────────────────────────────────────────────────────────
|
|
21
|
+
* Thin marks, a surface gap between neighbours and a rounded data-end anchored to the
|
|
22
|
+
* baseline (the data-visualization mark spec). */
|
|
23
|
+
--chart-trend-bar-gap: var(--space-2);
|
|
24
|
+
--chart-trend-bar-radius: var(--radius-sm);
|
|
25
|
+
/* Ceiling on a single mark so a 3-point trend does not render slabs. */
|
|
26
|
+
--chart-trend-bar-max-width: 1.5rem;
|
|
27
|
+
/* Floor so a zero/absent value still reads as a plotted category rather than a hole. */
|
|
28
|
+
--chart-trend-bar-min-height: 2px;
|
|
29
|
+
/* Muted mark fill — role-mirror knob, declared `initial` so the role default re-resolves
|
|
30
|
+
* at the CALL SITE under `.dark` / `[data-tenant]` (docs/TOKENS.md · "Role-mirror knobs
|
|
31
|
+
* MUST be `initial`"). Default = hsl(var(--muted-foreground) / 0.75), which clears the
|
|
32
|
+
* 3:1 non-text contrast floor (WCAG 1.4.11) against the card surface. */
|
|
33
|
+
--chart-trend-bar-background: initial;
|
|
34
|
+
/* Opacity applied to the muted-fill role default. */
|
|
35
|
+
--chart-trend-bar-background-alpha: 0.75;
|
|
36
|
+
/* Emphasized ("current") mark fill — role-mirror knob. Default = hsl(var(--primary)). */
|
|
37
|
+
--chart-trend-bar-emphasis-background: initial;
|
|
38
|
+
|
|
39
|
+
/* ── Baseline + category ticks ────────────────────────────────────────────────────────
|
|
40
|
+
* Chrome defaults QUIET (rule #44): no baseline rule at rest. A service opts in with
|
|
41
|
+
* `--chart-trend-baseline-border: 1px solid hsl(var(--border));`. */
|
|
42
|
+
--chart-trend-baseline-border: initial;
|
|
43
|
+
--chart-trend-tick-gap: var(--space-1);
|
|
44
|
+
--chart-trend-tick-font-size: var(--font-size-xs);
|
|
45
|
+
/* Gap between the plot block and the optional activity footer slot. */
|
|
46
|
+
--chart-trend-footer-gap: var(--space-2);
|
|
47
|
+
}
|
|
@@ -58,6 +58,16 @@
|
|
|
58
58
|
--slider-track-height: 0.375rem;
|
|
59
59
|
--slider-thumb-size: 1rem;
|
|
60
60
|
|
|
61
|
+
/* InputOTP slot box (gh#233). Its own knob so an auth surface can widen the 6-slot challenge row
|
|
62
|
+
* to fill a wide panel WITHOUT re-scoping --control-height (which would resize every other
|
|
63
|
+
* control in the same card). Declared `initial` — the tier-mirror form of the role-mirror rule in
|
|
64
|
+
* docs/TOKENS.md: the default must resolve at the CALL SITE (`var(--otp-slot-size,
|
|
65
|
+
* var(--control-height))`), because `--otp-slot-size: var(--control-height)` here would FREEZE at
|
|
66
|
+
* the :root tier (32px) and an OTP row inside `.ui-auth-shell[data-variant="canonical"]`, which
|
|
67
|
+
* re-scopes --control-height to 36px, would silently shrink. Verified in Chromium: 36px before
|
|
68
|
+
* and after. A service opts in with a NAMED tier (`var(--control-height-lg)`), never a calc. */
|
|
69
|
+
--otp-slot-size: initial; /* default = var(--control-height) at the call site */
|
|
70
|
+
|
|
61
71
|
/* Checked/on/active fills — `initial` so the --primary default re-resolves at the call site
|
|
62
72
|
* under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped
|
|
63
73
|
* [data-tenant] override of --primary never reaches it). A service retints the "selected" state
|
|
@@ -75,6 +85,12 @@
|
|
|
75
85
|
--command-group-padding: var(--space-1);
|
|
76
86
|
--command-item-padding-y: var(--space-2);
|
|
77
87
|
--command-item-padding-x: var(--space-2);
|
|
88
|
+
--command-palette-width: 35rem;
|
|
89
|
+
--command-palette-inset-top: calc(var(--space-6) * 4);
|
|
90
|
+
--command-palette-viewport-inset: var(--space-3);
|
|
91
|
+
--command-palette-hint-padding-y: var(--space-2);
|
|
92
|
+
--command-palette-hint-padding-x: var(--space-4);
|
|
93
|
+
--command-palette-hint-gap: var(--space-4);
|
|
78
94
|
--search-input-edge-inset: var(--space-3);
|
|
79
95
|
--search-input-start-padding: calc(
|
|
80
96
|
var(--search-input-edge-inset) + var(--control-icon-size) + var(--control-gap)
|
|
@@ -15,6 +15,19 @@
|
|
|
15
15
|
Painted as an overlay so a service sets --avatar-tint: hsl(var(--primary) / 0.08). */
|
|
16
16
|
--avatar-tint: transparent;
|
|
17
17
|
|
|
18
|
+
/* Entity-header mark — `<Avatar shape="square">` (gh#249): the compact rounded SQUARE an
|
|
19
|
+
organization/service header uses, as opposed to the round person avatar. Every value is a knob
|
|
20
|
+
(rule #45) so a service matches the mark to its own grid without a className override.
|
|
21
|
+
--avatar-square-background / --avatar-square-foreground are role-mirror knobs: `initial` so the
|
|
22
|
+
--primary / --primary-foreground defaults re-resolve at the CALL SITE under a scoped
|
|
23
|
+
[data-tenant]/.dark theme (a :root binding to a role var would freeze at the :root value).
|
|
24
|
+
Defaults = --radius-lg corners · --control-height box (same as the circle avatar, so swapping
|
|
25
|
+
shape never reflows a header) · hsl(var(--primary)) fill · hsl(var(--primary-foreground)) glyph. */
|
|
26
|
+
--avatar-square-radius: var(--radius-lg);
|
|
27
|
+
--avatar-square-size: var(--control-height);
|
|
28
|
+
--avatar-square-background: initial;
|
|
29
|
+
--avatar-square-foreground: initial;
|
|
30
|
+
|
|
18
31
|
/* Progress track + fill — `initial` so the role defaults re-resolve under a scoped theme.
|
|
19
32
|
Track reads --secondary, fill reads --success; a service re-tones once.
|
|
20
33
|
Defaults = hsl(var(--secondary)) track · hsl(var(--success)) fill. */
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/* EMAIL component tokens — the geometry/typography half of the transactional-email contract
|
|
2
|
+
* (`@godxjp/ui/email`). HTML email cannot read CSS custom properties: Outlook/Gmail strip <style>
|
|
3
|
+
* blocks and require LITERAL inline values, so a Blade/Twig/MJML template can never `var()` these.
|
|
4
|
+
* They still live in the component tier because this is the ONE source a maintainer edits — the
|
|
5
|
+
* `@godxjp/ui/email` export is GENERATED from this file plus the colour roles in foundation.css
|
|
6
|
+
* (scripts/gen-email-tokens.mjs), so an email template and a web screen can never drift apart.
|
|
7
|
+
*
|
|
8
|
+
* Every value is a LITERAL px/number (never rem, never calc, never var): email clients resolve
|
|
9
|
+
* neither the cascade nor relative units reliably, and the export must serialise to a plain hex/px
|
|
10
|
+
* string. Where a value mirrors a web token the comment names it, so a retune stays traceable.
|
|
11
|
+
*
|
|
12
|
+
* Colours are deliberately NOT redeclared here — they derive from the semantic roles
|
|
13
|
+
* (--card/--background/--foreground/--muted/--border/--primary/--ring/--brand) and are converted
|
|
14
|
+
* HSL→hex at module load, so a re-themed role re-tints the email with zero copy-paste.
|
|
15
|
+
* The identity mark reads --brand, NOT --success: --success is the wakatake status green, and the
|
|
16
|
+
* two are deliberately distinct roles (gh#250).
|
|
17
|
+
*/
|
|
18
|
+
:root {
|
|
19
|
+
/* ── Shell — the 480px transactional-email geometry ─────────────────────────────────────── */
|
|
20
|
+
--email-shell-width: 480px; /* canonical transactional card width */
|
|
21
|
+
--email-shell-padding: 32px; /* card inset — mirrors --space-8 (2rem) */
|
|
22
|
+
--email-shell-page-padding: 24px; /* gutter between the client viewport and the card (--space-6) */
|
|
23
|
+
--email-shell-border-width: 1px; /* card edge — mirrors the 1px --border hairline */
|
|
24
|
+
--email-card-radius: 10px; /* mirrors --card-radius (--radius-xl = 6px × φ ≈ 10px) */
|
|
25
|
+
--email-card-reference-height: 407px; /* canonical invitation reference measures 480×407 */
|
|
26
|
+
--email-stack-gap: 24px; /* block rhythm — mirrors --space-stack-lg (1.5rem) */
|
|
27
|
+
--email-stack-gap-sm: 12px; /* tight rhythm — mirrors --space-3 (0.75rem) */
|
|
28
|
+
|
|
29
|
+
/* ── Brand-mark lockup — the canonical GoDX capsule + wordmark (see EMAIL_BRAND_MARK) ────── */
|
|
30
|
+
/* The mark ARTWORK is the same 32×32 capsule + glyph `<Logo mark="godx" />` paints; only the
|
|
31
|
+
* RENDERED BOX differs. The canonical SCR-302 header sets it at 22px next to a 13px/700 "GoDX"
|
|
32
|
+
* wordmark, which is smaller than the web --logo-godx-size (2rem) — an email header carries the
|
|
33
|
+
* identity, not the navigation, so the lockup sits quieter (gh#250). */
|
|
34
|
+
--email-mark-width: 22px; /* canonical SCR-302 header lockup mark box */
|
|
35
|
+
--email-mark-height: 22px;
|
|
36
|
+
--email-mark-gap: 8px; /* mark ↔ wordmark — mirrors --logo-wordmark-gap (--space-2) */
|
|
37
|
+
--email-wordmark-font-size: 13px; /* canonical wordmark size (≈ --font-size-xs 12.5px) */
|
|
38
|
+
--email-wordmark-font-weight: 700; /* mirrors --logo-wordmark-font-weight */
|
|
39
|
+
|
|
40
|
+
/* ── Typography — literal px so no client has to resolve the rem scale ──────────────────── */
|
|
41
|
+
/* The DXS canonical face is M PLUS 2 (see src/styles/fonts.css). Email clients honour NO
|
|
42
|
+
* @font-face, so the stack ships the face NAME first and degrades through the platform JP faces
|
|
43
|
+
* to a generic — a client with M PLUS 2 installed (or a webmail that already loaded it) renders
|
|
44
|
+
* the canonical face, everything else lands on Hiragino (macOS/iOS) → Yu Gothic (Windows) →
|
|
45
|
+
* Noto Sans JP → Meiryo → the system UI face → Arial → sans-serif. Family names are SINGLE-quoted
|
|
46
|
+
* on export (the generator normalises) because an inline `style="…"` attribute is double-quoted;
|
|
47
|
+
* only ASCII aliases are listed, since a non-ASCII family name does not survive every transfer
|
|
48
|
+
* encoding. */
|
|
49
|
+
--email-font-family-sans:
|
|
50
|
+
"M PLUS 2", "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Yu Gothic Medium", YuGothic,
|
|
51
|
+
"Noto Sans JP", Meiryo, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, Arial,
|
|
52
|
+
sans-serif;
|
|
53
|
+
/* Tabular/reference strings — invoice ids, masked card numbers, ISO dates, amounts — are set in
|
|
54
|
+
* the mono face in the canonical card. Mirrors --font-family-mono. */
|
|
55
|
+
--email-font-family-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
56
|
+
--email-body-font-size: 14px; /* mirrors --font-size-base (0.875rem) */
|
|
57
|
+
/* 1.9, NOT the web --line-height-body (1.7) — the canonical email card runs its JP body copy
|
|
58
|
+
* looser than a screen, because a mail client gives the reader no density control. */
|
|
59
|
+
--email-body-line-height: 1.9;
|
|
60
|
+
--email-body-font-weight: 400; /* mirrors --font-weight-normal */
|
|
61
|
+
--email-heading-font-size: 17px; /* canonical card title (≈ --heading-h2, base × φ^¼² ≈ 17.6px) */
|
|
62
|
+
--email-heading-line-height: 1.7; /* the title shares the card's body leading, not a tight ramp */
|
|
63
|
+
--email-heading-font-weight: 500; /* mirrors --font-weight-medium — an email title is calm, not bold */
|
|
64
|
+
|
|
65
|
+
/* ── Primary CTA — the one action button ────────────────────────────────────────────────── */
|
|
66
|
+
--email-cta-height: 36px; /* mirrors --control-height-lg (2.25rem) — the canonical CTA box */
|
|
67
|
+
--email-cta-line-height: 36px; /* equal to the height: bulletproof vertical centring in Outlook */
|
|
68
|
+
--email-cta-padding-x: 16px; /* mirrors --space-4 */
|
|
69
|
+
--email-cta-radius: 6px; /* mirrors the --radius base (0.375rem) */
|
|
70
|
+
--email-cta-font-size: 14px; /* mirrors --font-size-base */
|
|
71
|
+
--email-cta-font-weight: 500; /* mirrors --font-weight-medium */
|
|
72
|
+
|
|
73
|
+
/* ── Legal footer ───────────────────────────────────────────────────────────────────────── */
|
|
74
|
+
--email-footer-font-size: 11px; /* mirrors --font-size-2xs (base ÷ φ^¼² ≈ 11.1px) */
|
|
75
|
+
--email-footer-line-height: 1.8; /* the legal band runs looser than the web --line-height-normal */
|
|
76
|
+
--email-footer-link-gap: 12px; /* horizontal separation between footer links (--space-3) */
|
|
77
|
+
--email-footer-padding-top: 20px; /* space above the legal band */
|
|
78
|
+
--email-footer-border-width: 1px; /* the hairline above the legal band */
|
|
79
|
+
|
|
80
|
+
/* ── Focus affordance (webmail preview panes that DO honour :focus) ─────────────────────── */
|
|
81
|
+
--email-focus-border-width: 2px; /* mirrors --focus-ring-width */
|
|
82
|
+
|
|
83
|
+
/* ── Mobile reflow — applied under the narrow media query and by inline fallbacks ───────── */
|
|
84
|
+
--email-mobile-max-width: 520px; /* the reflow breakpoint (card width + both gutters) */
|
|
85
|
+
--email-mobile-width: 100%; /* the card goes fluid below the breakpoint */
|
|
86
|
+
--email-mobile-padding: 20px; /* reduced card inset — mirrors --space-5 */
|
|
87
|
+
--email-mobile-page-padding: 12px; /* reduced viewport gutter — mirrors --space-3 */
|
|
88
|
+
/* One step below the 17px desktop title. The canonical 390px reference raster is unusable (it is
|
|
89
|
+
* 435px wide and already clips the card — dxs-platform/platform#496), so this is the library's
|
|
90
|
+
* documented contract rather than a measured canonical value. */
|
|
91
|
+
--email-mobile-heading-font-size: 16px;
|
|
92
|
+
--email-mobile-cta-width: 100%; /* the CTA goes full-bleed so the tap target spans the card */
|
|
93
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/* ErrorSurface — the 403 / 404 / 500 / 503 exception surface (gh#221, gh#251).
|
|
2
|
+
*
|
|
3
|
+
* Package-owned geometry: a service retunes the surface here (or in its own theme.css) instead of
|
|
4
|
+
* forking `.ui-error-surface` or adding a `className` to the component. Chrome defaults are QUIET
|
|
5
|
+
* (cardinal rule #44): the metadata block ships with no divider — a service opts IN.
|
|
6
|
+
*/
|
|
7
|
+
:root {
|
|
8
|
+
/* Measure of the surface block. Caps the status code + body + metadata column so a long ja/vi
|
|
9
|
+
* headline wraps at a readable width in BOTH shells, including the application shell where
|
|
10
|
+
* PageContainer is much wider than the copy wants to be. */
|
|
11
|
+
--error-surface-max-width: 32rem;
|
|
12
|
+
|
|
13
|
+
/* Rhythm between the status code, the EmptyState body, the metadata list and the progress meter. */
|
|
14
|
+
--error-surface-gap: var(--space-3);
|
|
15
|
+
|
|
16
|
+
/* Block padding of the surface inside the shell it is placed in. Desktop (1440/1024) default; the
|
|
17
|
+
* 390 step steps it down so a phone loses no vertical space (see styles/shell-layout.css). */
|
|
18
|
+
--error-surface-padding-block: var(--space-10);
|
|
19
|
+
--error-surface-padding-block-compact: var(--space-6);
|
|
20
|
+
|
|
21
|
+
/* Brand slot (a Logo) above the status code, system mode only. */
|
|
22
|
+
--error-surface-brand-gap: var(--space-2);
|
|
23
|
+
|
|
24
|
+
/* Metadata description list: row rhythm and the label↔value gap inside one row. */
|
|
25
|
+
--error-surface-meta-gap: var(--space-1);
|
|
26
|
+
--error-surface-meta-row-gap: var(--space-2);
|
|
27
|
+
|
|
28
|
+
/* Chrome, default quiet (#44). A service opts in with
|
|
29
|
+
* `--error-surface-meta-border: 1px solid hsl(var(--border));`. */
|
|
30
|
+
--error-surface-meta-border: none;
|
|
31
|
+
--error-surface-meta-padding-block: 0;
|
|
32
|
+
|
|
33
|
+
/* Width of the maintenance progress meter — narrower than the measure, so it reads as metadata
|
|
34
|
+
* rather than as the primary content of the page. */
|
|
35
|
+
--error-surface-progress-max-width: 18rem;
|
|
36
|
+
}
|