@ponchia/ui 0.8.1 → 0.10.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.
Files changed (85) hide show
  1. package/CHANGELOG.md +149 -3
  2. package/MIGRATIONS.json +117 -27
  3. package/README.md +19 -11
  4. package/behaviors/index.d.ts +0 -2
  5. package/behaviors/index.d.ts.map +1 -1
  6. package/behaviors/index.js +0 -2
  7. package/behaviors/popover.js +4 -4
  8. package/classes/classes.json +48 -10
  9. package/classes/index.d.ts +16 -3
  10. package/classes/index.js +28 -3
  11. package/classes/vscode.css-custom-data.json +10 -10
  12. package/css/app.css +52 -30
  13. package/css/base.css +10 -14
  14. package/css/content.css +23 -21
  15. package/css/core.css +1 -0
  16. package/css/disclosure.css +17 -17
  17. package/css/feedback.css +15 -15
  18. package/css/forms.css +8 -7
  19. package/css/navigation.css +3 -3
  20. package/css/overlay.css +37 -39
  21. package/css/primitives.css +48 -28
  22. package/css/report.css +66 -42
  23. package/css/row.css +154 -0
  24. package/css/state.css +95 -6
  25. package/css/table.css +3 -3
  26. package/css/tokens.css +10 -10
  27. package/css/workbench.css +22 -10
  28. package/dist/bronto.css +1 -1
  29. package/dist/css/app.css +1 -1
  30. package/dist/css/base.css +1 -1
  31. package/dist/css/content.css +1 -1
  32. package/dist/css/disclosure.css +1 -1
  33. package/dist/css/feedback.css +1 -1
  34. package/dist/css/forms.css +1 -1
  35. package/dist/css/navigation.css +1 -1
  36. package/dist/css/overlay.css +1 -1
  37. package/dist/css/primitives.css +1 -1
  38. package/dist/css/report-kit.css +1 -1
  39. package/dist/css/report.css +1 -1
  40. package/dist/css/row.css +1 -0
  41. package/dist/css/state.css +1 -1
  42. package/dist/css/table.css +1 -1
  43. package/dist/css/tokens.css +1 -1
  44. package/dist/css/workbench.css +1 -1
  45. package/docs/adr/0004-prune-unused-adapters.md +5 -1
  46. package/docs/adr/0005-productive-tools-and-editorial-reports.md +58 -0
  47. package/docs/adr/0006-trusted-publishing.md +92 -0
  48. package/docs/architecture.md +16 -23
  49. package/docs/command.md +1 -2
  50. package/docs/compositions.md +110 -0
  51. package/docs/frontier-primitives.md +1 -2
  52. package/docs/migrations/0.8-to-0.9.md +66 -0
  53. package/docs/migrations/0.9-to-0.10.md +47 -0
  54. package/docs/package-contract.md +13 -13
  55. package/docs/reference.md +43 -18
  56. package/docs/reporting.md +15 -9
  57. package/docs/stability.md +20 -55
  58. package/docs/state.md +47 -0
  59. package/docs/theming.md +16 -0
  60. package/docs/usage.md +60 -30
  61. package/llms.txt +7 -18
  62. package/package.json +15 -54
  63. package/tokens/figma.variables.json +20 -20
  64. package/tokens/index.js +10 -10
  65. package/tokens/index.json +20 -20
  66. package/tokens/resolved.json +10 -10
  67. package/tokens/tokens.dtcg.json +20 -20
  68. package/behaviors/modal.d.ts +0 -45
  69. package/behaviors/modal.d.ts.map +0 -1
  70. package/behaviors/modal.js +0 -373
  71. package/qwik/index.d.ts +0 -48
  72. package/qwik/index.d.ts.map +0 -1
  73. package/qwik/index.js +0 -227
  74. package/react/index.d.ts +0 -45
  75. package/react/index.d.ts.map +0 -1
  76. package/react/index.js +0 -165
  77. package/solid/index.d.ts +0 -75
  78. package/solid/index.d.ts.map +0 -1
  79. package/solid/index.js +0 -172
  80. package/svelte/index.d.ts +0 -114
  81. package/svelte/index.d.ts.map +0 -1
  82. package/svelte/index.js +0 -197
  83. package/vue/index.d.ts +0 -116
  84. package/vue/index.d.ts.map +0 -1
  85. package/vue/index.js +0 -266
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$comment": "@ponchia/ui class vocabulary as language-neutral data — validate emitted markup without executing the ESM cls map or parsing the .d.ts. Generated from classes/index.js — do not edit by hand; run `npm run classes:json:build`. Drift-checked in CI. `groups[].base` is null for a parts-only namespace (no standalone base class — do NOT emit it). A modifier whose name contains `__` (e.g. `ui-spark__bar--pos`) attaches to THAT part, not the base host. `states` is the author-applied `is-*` hooks (runtime/behavior-managed hooks are excluded); `behaviorAttributes` are the `data-bronto-*` wiring hooks the optional behaviors delegate on; `requiredAria` is the role/aria a generator must emit per component. `states` + `customProperties` are documented in docs/reference.md and ship outside `cls` by design.",
3
3
  "counts": {
4
- "classes": 669,
5
- "groups": 183
4
+ "classes": 683,
5
+ "groups": 186
6
6
  },
7
7
  "groups": {
8
8
  "ui-accordion": {
@@ -295,7 +295,8 @@
295
295
  "ui-chip": {
296
296
  "base": "ui-chip",
297
297
  "modifiers": [
298
- "ui-chip--accent"
298
+ "ui-chip--accent",
299
+ "ui-chip--dense"
299
300
  ],
300
301
  "parts": []
301
302
  },
@@ -830,7 +831,10 @@
830
831
  },
831
832
  "ui-menu": {
832
833
  "base": "ui-menu",
833
- "modifiers": [],
834
+ "modifiers": [
835
+ "ui-menu--at-pointer",
836
+ "ui-menu--dropdown"
837
+ ],
834
838
  "parts": [
835
839
  "ui-menu__item",
836
840
  "ui-menu__label",
@@ -1074,6 +1078,18 @@
1074
1078
  "modifiers": [],
1075
1079
  "parts": []
1076
1080
  },
1081
+ "ui-row": {
1082
+ "base": "ui-row",
1083
+ "modifiers": [
1084
+ "ui-row--ruled",
1085
+ "ui-row--stacked"
1086
+ ],
1087
+ "parts": [
1088
+ "ui-row__mark",
1089
+ "ui-row__meta",
1090
+ "ui-row__title"
1091
+ ]
1092
+ },
1077
1093
  "ui-screen-only": {
1078
1094
  "base": "ui-screen-only",
1079
1095
  "modifiers": [],
@@ -1152,6 +1168,11 @@
1152
1168
  "ui-severity-row__title"
1153
1169
  ]
1154
1170
  },
1171
+ "ui-severity-tone": {
1172
+ "base": "ui-severity-tone",
1173
+ "modifiers": [],
1174
+ "parts": []
1175
+ },
1155
1176
  "ui-shortcut": {
1156
1177
  "base": "ui-shortcut",
1157
1178
  "modifiers": [],
@@ -1442,6 +1463,15 @@
1442
1463
  "ui-timeline__time"
1443
1464
  ]
1444
1465
  },
1466
+ "ui-timestrip": {
1467
+ "base": "ui-timestrip",
1468
+ "modifiers": [],
1469
+ "parts": [
1470
+ "ui-timestrip__axis",
1471
+ "ui-timestrip__event",
1472
+ "ui-timestrip__now"
1473
+ ]
1474
+ },
1445
1475
  "ui-toast": {
1446
1476
  "base": "ui-toast",
1447
1477
  "modifiers": [
@@ -1682,6 +1712,7 @@
1682
1712
  "ui-check",
1683
1713
  "ui-chip",
1684
1714
  "ui-chip--accent",
1715
+ "ui-chip--dense",
1685
1716
  "ui-citation",
1686
1717
  "ui-citation--chip",
1687
1718
  "ui-claim",
@@ -1924,6 +1955,8 @@
1924
1955
  "ui-mark--warning",
1925
1956
  "ui-matrix",
1926
1957
  "ui-menu",
1958
+ "ui-menu--at-pointer",
1959
+ "ui-menu--dropdown",
1927
1960
  "ui-menu-host",
1928
1961
  "ui-menu__item",
1929
1962
  "ui-menu__label",
@@ -2039,6 +2072,12 @@
2039
2072
  "ui-report__title",
2040
2073
  "ui-report__toc",
2041
2074
  "ui-reveal",
2075
+ "ui-row",
2076
+ "ui-row--ruled",
2077
+ "ui-row--stacked",
2078
+ "ui-row__mark",
2079
+ "ui-row__meta",
2080
+ "ui-row__title",
2042
2081
  "ui-screen-only",
2043
2082
  "ui-scroll-progress",
2044
2083
  "ui-scroll-reveal",
@@ -2063,6 +2102,7 @@
2063
2102
  "ui-severity-row",
2064
2103
  "ui-severity-row__meta",
2065
2104
  "ui-severity-row__title",
2105
+ "ui-severity-tone",
2066
2106
  "ui-shortcut",
2067
2107
  "ui-shortcut__sep",
2068
2108
  "ui-sidebar",
@@ -2171,6 +2211,10 @@
2171
2211
  "ui-timeline",
2172
2212
  "ui-timeline__item",
2173
2213
  "ui-timeline__time",
2214
+ "ui-timestrip",
2215
+ "ui-timestrip__axis",
2216
+ "ui-timestrip__event",
2217
+ "ui-timestrip__now",
2174
2218
  "ui-toast",
2175
2219
  "ui-toast--accent",
2176
2220
  "ui-toast--danger",
@@ -2801,12 +2845,6 @@
2801
2845
  "behavior": "initDialog",
2802
2846
  "note": "opt into backdrop light-dismiss (click the backdrop to close)"
2803
2847
  },
2804
- {
2805
- "name": "data-bronto-modal",
2806
- "on": "a controlled (non-<dialog>) .ui-modal overlay",
2807
- "behavior": "initModal",
2808
- "note": "inert focus-trap, focus-return, and Escape close signal for a consumer-owned .is-open modal; needs an accessible name"
2809
- },
2810
2848
  {
2811
2849
  "name": "data-bronto-menu",
2812
2850
  "on": "a native <details> dropdown",
@@ -51,10 +51,17 @@ export declare const cls: {
51
51
  readonly badgeDot: 'ui-badge--dot';
52
52
  readonly chip: 'ui-chip';
53
53
  readonly chipAccent: 'ui-chip--accent';
54
+ readonly chipDense: 'ui-chip--dense';
54
55
  readonly link: 'ui-link';
55
56
  readonly linkArrow: 'ui-link--arrow';
56
57
  readonly linkCta: 'ui-link--cta';
57
58
  readonly keyValue: 'ui-key-value';
59
+ readonly row: 'ui-row';
60
+ readonly rowTitle: 'ui-row__title';
61
+ readonly rowMeta: 'ui-row__meta';
62
+ readonly rowMark: 'ui-row__mark';
63
+ readonly rowStacked: 'ui-row--stacked';
64
+ readonly rowRuled: 'ui-row--ruled';
58
65
  readonly emptyState: 'ui-empty-state';
59
66
  readonly emptyStateInvite: 'ui-empty-state--invite';
60
67
  readonly emptyStateGlyph: 'ui-empty-state__glyph';
@@ -164,6 +171,8 @@ export declare const cls: {
164
171
  readonly modalDrawer: 'ui-modal--drawer';
165
172
  readonly menuHost: 'ui-menu-host';
166
173
  readonly menu: 'ui-menu';
174
+ readonly menuDropdown: 'ui-menu--dropdown';
175
+ readonly menuAtPointer: 'ui-menu--at-pointer';
167
176
  readonly menuLabel: 'ui-menu__label';
168
177
  readonly menuItem: 'ui-menu__item';
169
178
  readonly menuSep: 'ui-menu__sep';
@@ -571,6 +580,11 @@ export declare const cls: {
571
580
  readonly severityRow: 'ui-severity-row';
572
581
  readonly severityRowTitle: 'ui-severity-row__title';
573
582
  readonly severityRowMeta: 'ui-severity-row__meta';
583
+ readonly severityTone: 'ui-severity-tone';
584
+ readonly timestrip: 'ui-timestrip';
585
+ readonly timestripAxis: 'ui-timestrip__axis';
586
+ readonly timestripNow: 'ui-timestrip__now';
587
+ readonly timestripEvent: 'ui-timestrip__event';
574
588
  readonly generated: 'ui-generated';
575
589
  readonly generatedLabel: 'ui-generated__label';
576
590
  readonly originLabel: 'ui-origin-label';
@@ -734,6 +748,7 @@ export interface ClaimOpts {
734
748
  }
735
749
  export interface ChipOpts {
736
750
  accent?: boolean;
751
+ dense?: boolean;
737
752
  }
738
753
  export interface LinkOpts {
739
754
  arrow?: boolean;
@@ -786,8 +801,6 @@ export interface DotbarOpts {
786
801
  }
787
802
  export interface ModalOpts {
788
803
  drawer?: boolean;
789
- /** Controlled non-dialog usage — adds only the is-open state; pair with initModal for focus management. */
790
- open?: boolean;
791
804
  }
792
805
  export interface TabOpts {
793
806
  active?: boolean;
@@ -1006,7 +1019,7 @@ export type SeverityLevel = (typeof SEVERITY_LEVELS)[number];
1006
1019
  * `'unknown'`, which paints the neutral tone. */
1007
1020
  export declare function severity(
1008
1021
  level: SeverityLevel | (string & {}) | null | undefined,
1009
- opts?: { part?: 'chip' | 'dot' | 'row' },
1022
+ opts?: { part?: 'chip' | 'dot' | 'row' | 'tone' },
1010
1023
  ): { class: string; 'data-level': string };
1011
1024
 
1012
1025
  /** Min/max for the value-bearing fills; defaults to 0–100. */
package/classes/index.js CHANGED
@@ -55,10 +55,17 @@ export const cls = Object.freeze({
55
55
  badgeDot: 'ui-badge--dot',
56
56
  chip: 'ui-chip',
57
57
  chipAccent: 'ui-chip--accent',
58
+ chipDense: 'ui-chip--dense',
58
59
  link: 'ui-link',
59
60
  linkArrow: 'ui-link--arrow',
60
61
  linkCta: 'ui-link--cta',
61
62
  keyValue: 'ui-key-value',
63
+ row: 'ui-row',
64
+ rowTitle: 'ui-row__title',
65
+ rowMeta: 'ui-row__meta',
66
+ rowMark: 'ui-row__mark',
67
+ rowStacked: 'ui-row--stacked',
68
+ rowRuled: 'ui-row--ruled',
62
69
  emptyState: 'ui-empty-state',
63
70
  emptyStateInvite: 'ui-empty-state--invite',
64
71
  emptyStateGlyph: 'ui-empty-state__glyph',
@@ -173,6 +180,8 @@ export const cls = Object.freeze({
173
180
  modalDrawer: 'ui-modal--drawer',
174
181
  menuHost: 'ui-menu-host',
175
182
  menu: 'ui-menu',
183
+ menuDropdown: 'ui-menu--dropdown',
184
+ menuAtPointer: 'ui-menu--at-pointer',
176
185
  menuLabel: 'ui-menu__label',
177
186
  menuItem: 'ui-menu__item',
178
187
  menuSep: 'ui-menu__sep',
@@ -609,6 +618,14 @@ export const cls = Object.freeze({
609
618
  severityRow: 'ui-severity-row',
610
619
  severityRowTitle: 'ui-severity-row__title',
611
620
  severityRowMeta: 'ui-severity-row__meta',
621
+ // The tone as a value, for a mark Bronto does not ship (an SVG shape, a
622
+ // gradient stop): it paints nothing and only resolves `--severity-tone`.
623
+ severityTone: 'ui-severity-tone',
624
+ // timestrip — WHEN, beside the ladder's HOW BAD (css/state.css)
625
+ timestrip: 'ui-timestrip',
626
+ timestripAxis: 'ui-timestrip__axis',
627
+ timestripNow: 'ui-timestrip__now',
628
+ timestripEvent: 'ui-timestrip__event',
612
629
  // generated content / AI-trust surfaces (css/generated.css)
613
630
  generated: 'ui-generated',
614
631
  generatedLabel: 'ui-generated__label',
@@ -977,7 +994,7 @@ export const ui = {
977
994
  compare: ({ cols } = {}) => j(cls.compare, cols === 2 && cls.compare2up),
978
995
  reportFinding: ({ severity } = {}) => j(cls.reportFinding, reportFindingSeverity(severity)),
979
996
  claim: ({ status } = {}) => j(cls.claim, claimStatus(status)),
980
- chip: ({ accent } = {}) => j(cls.chip, accent && cls.chipAccent),
997
+ chip: ({ accent, dense } = {}) => j(cls.chip, accent && cls.chipAccent, dense && cls.chipDense),
981
998
  link: ({ arrow, cta } = {}) => j(cls.link, arrow && cls.linkArrow, cta && cls.linkCta),
982
999
  dot: ({ tone, live } = {}) => j(cls.dot, dotTone(tone), live && cls.dotLive),
983
1000
  dotgrid: ({ accent, dense } = {}) =>
@@ -1002,7 +1019,7 @@ export const ui = {
1002
1019
  dotspinner: ({ size } = {}) =>
1003
1020
  j(cls.dotspinner, size === 'sm' && cls.dotspinnerSm, size === 'lg' && cls.dotspinnerLg),
1004
1021
  dotbar: ({ indeterminate } = {}) => j(cls.dotbar, indeterminate && cls.dotbarIndeterminate),
1005
- modal: ({ drawer, open } = {}) => j(cls.modal, drawer && cls.modalDrawer, open && 'is-open'),
1022
+ modal: ({ drawer } = {}) => j(cls.modal, drawer && cls.modalDrawer),
1006
1023
  tab: ({ active } = {}) => j(cls.tab, active && 'is-active'),
1007
1024
  avatar: ({ size } = {}) =>
1008
1025
  j(cls.avatar, size === 'sm' && cls.avatarSm, size === 'lg' && cls.avatarLg),
@@ -1149,8 +1166,16 @@ export const SEVERITY_LEVELS = Object.freeze(['critical', 'error', 'warning', 'n
1149
1166
  /** `data-level` + the severity class, bundled so the attribute that carries the
1150
1167
  * meaning cannot be forgotten — the class alone paints the neutral tone and
1151
1168
  * silently loses the level. Unknown/absent levels resolve to `unknown`. */
1169
+ const SEVERITY_PARTS = {
1170
+ chip: 'severity',
1171
+ dot: 'severityDot',
1172
+ row: 'severityRow',
1173
+ // Paints nothing; resolves the tone for a mark Bronto does not ship.
1174
+ tone: 'severityTone',
1175
+ };
1176
+
1152
1177
  export const severity = (level, { part = 'chip' } = {}) => ({
1153
- class: part === 'dot' ? cls.severityDot : part === 'row' ? cls.severityRow : cls.severity,
1178
+ class: cls[SEVERITY_PARTS[part] ?? 'severity'],
1154
1179
  'data-level': SEVERITY_LEVELS.includes(level) ? level : 'unknown',
1155
1180
  });
1156
1181
 
@@ -239,11 +239,11 @@
239
239
  },
240
240
  {
241
241
  "name": "--radius-lg",
242
- "description": "Global scale token. Value: `3px`"
242
+ "description": "Global scale token. Value: `6px`"
243
243
  },
244
244
  {
245
245
  "name": "--radius-md",
246
- "description": "Global scale token. Value: `2px`"
246
+ "description": "Global scale token. Value: `4px`"
247
247
  },
248
248
  {
249
249
  "name": "--radius-pill",
@@ -251,11 +251,11 @@
251
251
  },
252
252
  {
253
253
  "name": "--radius-sm",
254
- "description": "Global scale token. Value: `1px`"
254
+ "description": "Global scale token. Value: `2px`"
255
255
  },
256
256
  {
257
257
  "name": "--radius-xl",
258
- "description": "Global scale token. Value: `4px`"
258
+ "description": "Global scale token. Value: `8px`"
259
259
  },
260
260
  {
261
261
  "name": "--safe-area-bottom",
@@ -371,11 +371,11 @@
371
371
  },
372
372
  {
373
373
  "name": "--text-2xs",
374
- "description": "Global scale token. Value: `0.72rem`"
374
+ "description": "Global scale token. Value: `0.75rem`"
375
375
  },
376
376
  {
377
377
  "name": "--text-base",
378
- "description": "Global scale token. Value: `0.95rem`"
378
+ "description": "Global scale token. Value: `1rem`"
379
379
  },
380
380
  {
381
381
  "name": "--text-dim",
@@ -383,11 +383,11 @@
383
383
  },
384
384
  {
385
385
  "name": "--text-lg",
386
- "description": "Global scale token. Value: `1.15rem`"
386
+ "description": "Global scale token. Value: `1.125rem`"
387
387
  },
388
388
  {
389
389
  "name": "--text-sm",
390
- "description": "Global scale token. Value: `0.86rem`"
390
+ "description": "Global scale token. Value: `0.875rem`"
391
391
  },
392
392
  {
393
393
  "name": "--text-soft",
@@ -395,11 +395,11 @@
395
395
  },
396
396
  {
397
397
  "name": "--text-xl",
398
- "description": "Global scale token. Value: `1.45rem`"
398
+ "description": "Global scale token. Value: `1.5rem`"
399
399
  },
400
400
  {
401
401
  "name": "--text-xs",
402
- "description": "Global scale token. Value: `0.76rem`"
402
+ "description": "Global scale token. Value: `0.8125rem`"
403
403
  },
404
404
  {
405
405
  "name": "--tracking-wide",
package/css/app.css CHANGED
@@ -64,12 +64,12 @@
64
64
 
65
65
  .ui-app-nav__section {
66
66
  color: var(--text-dim);
67
- font-family: var(--mono);
67
+ font-family: var(--sans);
68
68
  font-size: var(--text-2xs);
69
- letter-spacing: var(--tracking-wide);
69
+ letter-spacing: 0;
70
70
  margin: var(--space-sm) 0 0.3rem;
71
71
  padding: 0 0.5rem;
72
- text-transform: uppercase;
72
+ text-transform: none;
73
73
  }
74
74
 
75
75
  .ui-app-nav a {
@@ -77,7 +77,7 @@
77
77
  border-inline-start: 2px solid transparent;
78
78
  color: var(--text-soft);
79
79
  display: flex;
80
- font-family: var(--mono);
80
+ font-family: var(--sans);
81
81
  font-size: var(--text-sm);
82
82
  gap: 0.55rem;
83
83
  padding: 0.5rem 0.6rem;
@@ -148,7 +148,7 @@
148
148
  .ui-app-rail__foot {
149
149
  border-block-start: 1px solid var(--line);
150
150
  color: var(--text-dim);
151
- font-family: var(--mono);
151
+ font-family: var(--sans);
152
152
  font-size: var(--text-2xs);
153
153
  margin-block-start: auto;
154
154
  padding-block-start: var(--space-sm);
@@ -163,9 +163,15 @@
163
163
  display: flex;
164
164
  gap: var(--space-xs);
165
165
  margin-block-start: auto;
166
+ min-inline-size: 0;
167
+ overflow-wrap: anywhere;
166
168
  padding-block-start: var(--space-sm);
167
169
  }
168
170
 
171
+ .ui-app-rail__account > * {
172
+ min-inline-size: 0;
173
+ }
174
+
169
175
  .ui-app-rail__account + .ui-app-rail__foot {
170
176
  margin-block-start: 0;
171
177
  }
@@ -204,17 +210,17 @@
204
210
 
205
211
  .ui-app-topbar__title {
206
212
  color: var(--text);
207
- font-family: var(--display);
208
- font-size: 1.1rem;
209
- font-weight: var(--display-weight);
210
- letter-spacing: var(--tracking-wide);
213
+ font-family: var(--sans);
214
+ font-size: 1.25rem;
215
+ font-weight: 650;
216
+ letter-spacing: 0;
211
217
  margin: 0;
212
- text-transform: uppercase;
218
+ text-transform: none;
213
219
  }
214
220
 
215
221
  .ui-app-content {
216
222
  display: grid;
217
- gap: var(--space-lg);
223
+ gap: var(--space-xl);
218
224
  padding: var(--space-lg);
219
225
  }
220
226
 
@@ -222,14 +228,12 @@
222
228
 
223
229
  .ui-app-toolbar {
224
230
  align-items: center;
225
- background: var(--panel);
226
- border: 1px solid var(--line);
227
- border-radius: var(--radius-md);
231
+ border-block-end: 1px solid var(--line);
228
232
  display: flex;
229
233
  flex-wrap: wrap;
230
234
  gap: 0.7rem;
231
235
  justify-content: space-between;
232
- padding: 0.7rem 0.85rem;
236
+ padding-block-end: var(--space-md);
233
237
  }
234
238
 
235
239
  .ui-app-toolbar__group {
@@ -242,29 +246,43 @@
242
246
  /* --- Panel --- */
243
247
 
244
248
  .ui-app-panel {
245
- background: var(--panel);
246
- border: 1px solid var(--line);
247
- border-radius: var(--radius-md);
248
249
  display: grid;
249
- gap: 0.85rem;
250
- padding: var(--space-md);
250
+ gap: var(--space-md);
251
+ min-inline-size: 0;
251
252
  }
252
253
 
253
254
  .ui-app-panel__head {
254
255
  align-items: flex-start;
255
256
  display: flex;
257
+ flex-wrap: wrap;
256
258
  gap: 0.7rem;
257
259
  justify-content: space-between;
258
260
  }
259
261
 
260
262
  .ui-app-panel__title {
261
263
  color: var(--text);
262
- font-family: var(--display);
263
- font-size: 0.95rem;
264
- font-weight: var(--display-weight);
265
- letter-spacing: var(--tracking-wide);
264
+ font-family: var(--sans);
265
+ font-size: 1.125rem;
266
+ font-weight: 650;
267
+ letter-spacing: 0;
266
268
  margin: 0;
267
- text-transform: uppercase;
269
+ text-transform: none;
270
+ }
271
+
272
+ /* A service overview needs a compact scan, including on a phone. Keep the
273
+ generic stat tile available elsewhere; avoid framing every metric twice. */
274
+ .ui-app-panel > .ui-statgrid,
275
+ .ui-app-panel > .ui-app-metrics {
276
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 6rem), 1fr));
277
+ }
278
+
279
+ .ui-app-panel > .ui-statgrid > .ui-stat,
280
+ .ui-app-panel > .ui-app-metrics > .ui-app-metric {
281
+ background: none;
282
+ border: 0;
283
+ border-block-start: 1px solid var(--line);
284
+ border-radius: 0;
285
+ padding: var(--space-md) 0;
268
286
  }
269
287
 
270
288
  .ui-app-panel__head p {
@@ -285,7 +303,7 @@
285
303
  permanent admin-shell alias (grouped on the canonical rules there —
286
304
  identical output). Nothing app-specific left to define here. */
287
305
 
288
- /* --- Mobile rail: collapses to a horizontal scrolling strip --- */
306
+ /* --- Mobile rail: navigation wraps instead of hiding destinations offscreen. --- */
289
307
 
290
308
  @media (max-width: 880px) {
291
309
  .ui-app-shell {
@@ -300,10 +318,10 @@
300
318
  }
301
319
 
302
320
  .ui-app-rail {
303
- flex-direction: row;
321
+ flex-flow: row wrap;
304
322
  block-size: auto;
305
- overflow-x: auto;
306
- position: sticky;
323
+ overflow: visible;
324
+ position: static;
307
325
  inset-block-start: 0;
308
326
  z-index: calc(var(--z-raised) + 1);
309
327
  }
@@ -321,7 +339,9 @@
321
339
  }
322
340
 
323
341
  .ui-app-nav {
324
- grid-auto-flow: column;
342
+ display: flex;
343
+ flex: 1 0 100%;
344
+ flex-wrap: wrap;
325
345
  gap: 0.15rem;
326
346
  }
327
347
 
@@ -330,6 +350,8 @@
330
350
  }
331
351
 
332
352
  .ui-app-nav a {
353
+ flex: 1 1 auto;
354
+ justify-content: center;
333
355
  border-inline-start: 0;
334
356
  border-block-end: 2px solid transparent;
335
357
  white-space: nowrap;
package/css/base.css CHANGED
@@ -1,5 +1,5 @@
1
1
  /* ==========================================================================
2
- base — reset + element defaults, Nothing-flat
2
+ base — reset + readable element defaults
3
3
  ========================================================================== */
4
4
 
5
5
  *,
@@ -13,9 +13,8 @@ html {
13
13
  color: var(--text);
14
14
  font-family: var(--sans);
15
15
 
16
- /* = 15px at the 16px default, but rem honours a user's browser font-size
17
- preference (which a px root would ignore). */
18
- font-size: 0.9375rem;
16
+ /* Preserve the browser's preferred reading size. Compact controls use tokens. */
17
+ font-size: 1rem;
19
18
  line-height: 1.55;
20
19
  scroll-behavior: smooth;
21
20
  text-rendering: optimizeLegibility;
@@ -74,27 +73,25 @@ li {
74
73
  line-height: 1.65;
75
74
  }
76
75
 
77
- /* Headings ride the dot-matrix display face. */
76
+ /* Everyday headings are readable text. .ui-display owns the brand face. */
78
77
  h1,
79
78
  h2,
80
79
  h3,
81
80
  h4 {
82
81
  color: var(--text);
83
- font-family: var(--display);
84
- font-weight: 700;
85
- letter-spacing: 0.01em;
86
- line-height: 1.06;
82
+ font-family: var(--sans);
83
+ font-weight: 650;
84
+ letter-spacing: -0.02em;
85
+ line-height: 1.2;
87
86
  margin: 0;
88
- text-transform: uppercase;
89
87
  }
90
88
 
91
89
  h1 {
92
- font-size: clamp(2.6rem, 6vw, 4.6rem);
93
- letter-spacing: 0.02em;
90
+ font-size: clamp(2rem, 4vw, 3rem);
94
91
  }
95
92
 
96
93
  h2 {
97
- font-size: clamp(1.7rem, 3.4vw, 2.4rem);
94
+ font-size: clamp(1.5rem, 3vw, 2rem);
98
95
  }
99
96
 
100
97
  h3 {
@@ -103,7 +100,6 @@ h3 {
103
100
 
104
101
  h4 {
105
102
  font-size: 1rem;
106
- letter-spacing: var(--tracking-wide);
107
103
  }
108
104
 
109
105
  strong,