@livenetworks/ashlar 1.5.1 → 1.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 +189 -177
- package/js/COMPONENTS.md +55 -49
- package/js/index.js +22 -5
- package/js/ln-accordion/README.md +186 -137
- package/js/ln-accordion/ln-accordion.js +1 -1
- package/js/ln-ajax/README.md +73 -4
- package/js/ln-ajax/ln-ajax.js +1 -1
- package/js/ln-ajax/src/ln-ajax.js +13 -13
- package/js/ln-api-connector/README.md +261 -150
- package/js/ln-api-connector/ln-api-connector.js +1 -1
- package/js/ln-api-connector/src/ln-api-connector.js +368 -265
- package/js/ln-api-queue/README.md +219 -0
- package/js/ln-api-queue/ln-api-queue.js +1 -0
- package/js/ln-api-queue/src/ln-api-queue.js +320 -0
- package/js/ln-api-queue/src/queue-storage.js +455 -0
- package/js/ln-autoresize/README.md +47 -0
- package/js/ln-autoresize/ln-autoresize.js +1 -1
- package/js/ln-autosave/README.md +33 -1
- package/js/ln-autosave/ln-autosave.js +1 -1
- package/js/ln-autosave/src/ln-autosave.js +4 -4
- package/js/ln-circular-progress/README.md +27 -13
- package/js/ln-circular-progress/ln-circular-progress.js +1 -1
- package/js/ln-circular-progress/src/ln-circular-progress.js +18 -5
- package/js/ln-confirm/README.md +162 -86
- package/js/ln-confirm/_ln-confirm.scss +11 -0
- package/js/ln-confirm/ln-confirm.js +1 -1
- package/js/ln-confirm/src/ln-confirm.js +77 -41
- package/js/ln-core/README.md +896 -0
- package/js/ln-core/hash.js +92 -0
- package/js/ln-core/helpers.js +337 -8
- package/js/ln-core/index.js +4 -2
- package/js/ln-core/persist.js +29 -3
- package/js/ln-core/positioning.js +1 -35
- package/js/ln-core/window-cache.js +213 -0
- package/js/ln-couchdb-connector/README.md +177 -156
- package/js/ln-couchdb-connector/ln-couchdb-connector.js +1 -1
- package/js/ln-couchdb-connector/src/ln-couchdb-connector.js +398 -348
- package/js/ln-data-coordinator/README.md +536 -165
- package/js/ln-data-coordinator/ln-data-coordinator.js +1 -1
- package/js/ln-data-coordinator/src/data-read-policy.js +18 -0
- package/js/ln-data-coordinator/src/ln-data-coordinator.js +1042 -249
- package/js/ln-data-coordinator/src/mutation-receipts.js +46 -0
- package/js/ln-data-store/README.md +241 -94
- package/js/ln-data-store/ln-data-store.js +1 -1
- package/js/ln-data-store/src/ln-data-store.js +694 -699
- package/js/ln-date/README.md +39 -1
- package/js/ln-date/ln-date-dev.scss +14 -0
- package/js/ln-date/ln-date.js +1 -1
- package/js/ln-date/src/ln-date.js +236 -178
- package/js/ln-debug/README.md +58 -0
- package/js/ln-debug/ln-debug.js +1 -0
- package/js/ln-debug/src/ln-debug.js +19 -0
- package/js/ln-dropdown/README.md +31 -8
- package/js/ln-dropdown/ln-dropdown.js +1 -1
- package/js/ln-dropdown/src/ln-dropdown.js +30 -13
- package/js/ln-editor/README.md +274 -0
- package/js/ln-editor/ln-editor.js +1 -0
- package/js/ln-editor/ln-editor.scss +43 -0
- package/js/ln-editor/src/ln-editor.js +619 -0
- package/js/ln-external-links/README.md +44 -5
- package/js/ln-external-links/ln-external-links.js +1 -1
- package/js/ln-fill/README.md +199 -0
- package/js/ln-fill/ln-fill.js +1 -0
- package/js/ln-fill/src/ln-fill.js +87 -0
- package/js/ln-filter/README.md +92 -2
- package/js/ln-filter/ln-filter-dev.scss +8 -0
- package/js/ln-filter/ln-filter.js +1 -1
- package/js/ln-filter/src/ln-filter.js +22 -7
- package/js/ln-form/README.md +212 -49
- package/js/ln-form/ln-form.js +1 -1
- package/js/ln-form/src/ln-form.js +99 -199
- package/js/ln-http/README.md +125 -89
- package/js/ln-http/ln-http.js +1 -1
- package/js/ln-http/src/ln-http.js +32 -13
- package/js/ln-icon/README.md +130 -0
- package/js/ln-icon/ln-icon.js +1 -0
- package/js/{ln-icons/src/ln-icons.js → ln-icon/src/ln-icon.js} +20 -15
- package/js/ln-link/README.md +47 -9
- package/js/ln-link/ln-link.js +1 -1
- package/js/ln-link/src/ln-link.js +22 -6
- package/js/ln-list/README.md +129 -0
- package/js/ln-list/ln-list.js +1 -0
- package/js/ln-list/ln-list.scss +28 -0
- package/js/ln-list/src/ln-list.js +1216 -0
- package/js/ln-modal/README.md +185 -154
- package/js/ln-modal/ln-modal-dev.scss +13 -0
- package/js/ln-modal/ln-modal.js +1 -1
- package/js/ln-modal/ln-modal.scss +28 -4
- package/js/ln-modal/src/ln-modal.js +137 -201
- package/js/ln-modal-coordinator/README.md +99 -0
- package/js/ln-modal-coordinator/ln-modal-coordinator-dev.scss +8 -0
- package/js/ln-modal-coordinator/ln-modal-coordinator.js +1 -0
- package/js/ln-modal-coordinator/src/ln-modal-coordinator.js +345 -0
- package/js/ln-nav/README.md +46 -3
- package/js/ln-nav/ln-nav.js +1 -1
- package/js/ln-nav/src/ln-nav.js +92 -127
- package/js/ln-number/README.md +28 -1
- package/js/ln-number/ln-number-dev.scss +13 -0
- package/js/ln-number/ln-number.js +1 -1
- package/js/ln-number/src/ln-number.js +443 -350
- package/js/ln-options/README.md +66 -0
- package/js/ln-options/ln-options.js +1 -0
- package/js/ln-options/src/ln-options.js +74 -0
- package/js/ln-popover/README.md +40 -5
- package/js/ln-popover/ln-popover.js +1 -1
- package/js/ln-popover/src/ln-popover.js +38 -11
- package/js/ln-progress/README.md +413 -442
- package/js/ln-progress/ln-progress.js +1 -1
- package/js/ln-progress/src/ln-progress.js +98 -150
- package/js/ln-router/README.md +432 -0
- package/js/ln-router/ln-router.js +1 -0
- package/js/ln-router/src/ln-router.js +539 -0
- package/js/ln-search/README.md +158 -83
- package/js/ln-search/ln-search-dev.scss +8 -0
- package/js/ln-search/ln-search.js +1 -1
- package/js/ln-search/src/ln-search.js +12 -9
- package/js/ln-slug/README.md +110 -0
- package/js/ln-slug/ln-slug.js +1 -0
- package/js/ln-slug/src/ln-slug.js +74 -0
- package/js/ln-sort/README.md +170 -0
- package/js/ln-sort/ln-sort-dev.scss +8 -0
- package/js/ln-sort/ln-sort.js +1 -0
- package/js/ln-sort/src/ln-sort.js +178 -0
- package/js/ln-sortable/README.md +133 -95
- package/js/ln-sortable/ln-sortable.js +1 -1
- package/js/ln-stat/README.md +55 -0
- package/js/ln-stat/ln-stat.js +1 -0
- package/js/ln-stat/src/ln-stat.js +55 -0
- package/js/ln-table/README.md +285 -101
- package/js/ln-table/ln-table-dev.scss +17 -0
- package/js/ln-table/ln-table.js +1 -1
- package/js/ln-table/ln-table.scss +1 -1
- package/js/ln-table/src/ln-table.js +1493 -473
- package/js/ln-table-coordinator/README.md +73 -0
- package/js/ln-table-coordinator/ln-table-coordinator.js +1 -0
- package/js/ln-table-coordinator/src/ln-table-coordinator.js +160 -0
- package/js/ln-tabs/README.md +221 -137
- package/js/ln-tabs/ln-tabs-dev.scss +18 -0
- package/js/ln-tabs/ln-tabs.js +1 -1
- package/js/ln-tabs/src/ln-tabs.js +41 -24
- package/js/ln-time/README.md +14 -0
- package/js/ln-time/ln-time.js +1 -1
- package/js/ln-time/src/ln-time.js +223 -192
- package/js/ln-toast/README.md +178 -122
- package/js/ln-toast/ln-toast.js +1 -15
- package/js/ln-toast/src/ln-toast.js +232 -210
- package/js/ln-toast/template.html +16 -12
- package/js/ln-toggle/README.md +61 -2
- package/js/ln-toggle/ln-toggle-dev.scss +13 -0
- package/js/ln-toggle/ln-toggle.js +1 -1
- package/js/ln-toggle/src/ln-toggle.js +56 -43
- package/js/ln-tooltip/README.md +95 -58
- package/js/ln-tooltip/ln-tooltip-dev.scss +9 -0
- package/js/ln-tooltip/ln-tooltip.js +1 -1
- package/js/ln-tooltip/src/ln-tooltip.js +45 -6
- package/js/ln-translations/README.md +118 -96
- package/js/ln-translations/ln-translations.js +1 -1
- package/js/ln-translations/src/ln-translations.js +10 -5
- package/js/ln-upload/README.md +85 -10
- package/js/ln-upload/ln-upload.js +1 -1
- package/js/ln-upload/src/ln-upload.js +26 -10
- package/js/ln-validate/README.md +72 -0
- package/js/ln-validate/ln-validate-dev.scss +15 -0
- package/js/ln-validate/ln-validate.js +1 -1
- package/js/ln-validate/src/ln-validate.js +64 -0
- package/package.json +61 -56
- package/scss/base/_global.scss +2 -2
- package/scss/base/_typography.scss +1 -2
- package/scss/components/_date.scss +1 -0
- package/scss/components/_dropdown.scss +0 -5
- package/scss/components/_editor.scss +5 -0
- package/scss/components/_filter.scss +26 -25
- package/scss/components/_form.scss +7 -0
- package/scss/components/_ln-table.scss +13 -3
- package/scss/components/_sort.scss +10 -0
- package/scss/components/_table.scss +36 -23
- package/scss/components/_toast.scss +68 -41
- package/scss/components/_toggle.scss +16 -0
- package/scss/config/_density.scss +205 -117
- package/scss/config/_icons.scss +10 -9
- package/scss/config/_tokens.scss +69 -47
- package/scss/config/mixins/_accordion.scss +2 -7
- package/scss/config/mixins/_alert.scss +4 -4
- package/scss/config/mixins/_breadcrumbs.scss +2 -2
- package/scss/config/mixins/_btn.scss +1 -1
- package/scss/config/mixins/_card.scss +89 -14
- package/scss/config/mixins/_collapsible.scss +3 -0
- package/scss/config/mixins/_colors.scss +1 -1
- package/scss/config/mixins/_diagnostics.scss +11 -0
- package/scss/config/mixins/_display.scss +1 -0
- package/scss/config/mixins/_dropdown.scss +3 -5
- package/scss/config/mixins/_editor.scss +124 -0
- package/scss/config/mixins/_empty-state.scss +7 -0
- package/scss/config/mixins/_filter.scss +3 -5
- package/scss/config/mixins/_footer.scss +1 -2
- package/scss/config/mixins/_form.scss +207 -21
- package/scss/config/mixins/_index.scss +2 -0
- package/scss/config/mixins/_ln-table.scss +41 -2
- package/scss/config/mixins/_modal.scss +149 -66
- package/scss/config/mixins/_nav.scss +3 -4
- package/scss/config/mixins/_popover.scss +39 -0
- package/scss/config/mixins/_sidebar.scss +1 -1
- package/scss/config/mixins/_sort.scss +42 -0
- package/scss/config/mixins/_table.scss +85 -60
- package/scss/config/mixins/_toast.scss +179 -152
- package/scss/config/mixins/_tooltip.scss +17 -7
- package/scss/config/mixins/_typography.scss +4 -2
- package/scss/ln-ashlar-dev.scss +27 -9
- package/scss/ln-ashlar.scss +7 -1
- package/js/ln-data-table/README.md +0 -110
- package/js/ln-data-table/ln-data-table.js +0 -1
- package/js/ln-data-table/ln-data-table.scss +0 -10
- package/js/ln-data-table/src/ln-data-table.js +0 -1087
- package/js/ln-icons/README.md +0 -88
- package/js/ln-icons/ln-icons.js +0 -1
- package/js/ln-table/ln-table-sort.js +0 -1
- package/js/ln-table/src/ln-table-sort.js +0 -156
package/scss/config/_tokens.scss
CHANGED
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
// -----------------------------------------------------------------------
|
|
21
21
|
// Colors — Primary
|
|
22
22
|
// -----------------------------------------------------------------------
|
|
23
|
-
--color-primary:
|
|
24
|
-
--color-primary-light:
|
|
25
|
-
--color-primary-lighter:
|
|
23
|
+
--color-primary: 232 75% 52%;
|
|
24
|
+
--color-primary-light: 232 75% 93%;
|
|
25
|
+
--color-primary-lighter: 232 75% 97%;
|
|
26
26
|
|
|
27
27
|
// -----------------------------------------------------------------------
|
|
28
28
|
// Colors — Secondary (brand accent — surface/element color, NOT text)
|
|
@@ -59,17 +59,17 @@
|
|
|
59
59
|
// during dark-mode audits -- semantic tokens inherit dark adjustments
|
|
60
60
|
// automatically, direct-neutral references do not.
|
|
61
61
|
//
|
|
62
|
-
--color-neutral-50:
|
|
63
|
-
--color-neutral-100:
|
|
64
|
-
--color-neutral-150:
|
|
65
|
-
--color-neutral-200:
|
|
66
|
-
--color-neutral-300:
|
|
67
|
-
--color-neutral-400:
|
|
68
|
-
--color-neutral-500:
|
|
69
|
-
--color-neutral-600:
|
|
70
|
-
--color-neutral-700:
|
|
71
|
-
--color-neutral-800:
|
|
72
|
-
--color-neutral-900:
|
|
62
|
+
--color-neutral-50: 220 20% 98%;
|
|
63
|
+
--color-neutral-100: 220 16% 96%;
|
|
64
|
+
--color-neutral-150: 220 14% 93%;
|
|
65
|
+
--color-neutral-200: 220 13% 91%;
|
|
66
|
+
--color-neutral-300: 220 13% 83%;
|
|
67
|
+
--color-neutral-400: 218 11% 65%;
|
|
68
|
+
--color-neutral-500: 220 9% 46%;
|
|
69
|
+
--color-neutral-600: 220 11% 34%;
|
|
70
|
+
--color-neutral-700: 220 14% 24%;
|
|
71
|
+
--color-neutral-800: 220 20% 15%;
|
|
72
|
+
--color-neutral-900: 221 39% 11%;
|
|
73
73
|
|
|
74
74
|
// -----------------------------------------------------------------------
|
|
75
75
|
// Colors — Backgrounds
|
|
@@ -100,6 +100,8 @@
|
|
|
100
100
|
--size-xl: 2rem; // 32px
|
|
101
101
|
--size-2xl: 3rem; // 48px
|
|
102
102
|
--size-3xl: 4rem; // 64px
|
|
103
|
+
--size-4xl: 6rem;
|
|
104
|
+
--size-5xl: 8rem;
|
|
103
105
|
|
|
104
106
|
// -----------------------------------------------------------------------
|
|
105
107
|
// Border Width
|
|
@@ -184,7 +186,7 @@
|
|
|
184
186
|
// Typography
|
|
185
187
|
// -----------------------------------------------------------------------
|
|
186
188
|
--font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
187
|
-
--font-mono: ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace;
|
|
189
|
+
--font-mono: 'JetBrains Mono', ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace;
|
|
188
190
|
|
|
189
191
|
--text-xs: 0.75rem; // 12px
|
|
190
192
|
--text-sm: 0.875rem; // 14px
|
|
@@ -194,25 +196,28 @@
|
|
|
194
196
|
--text-2xl: 1.5rem; // 24px
|
|
195
197
|
|
|
196
198
|
// -----------------------------------------------------------------------
|
|
197
|
-
// Typography — semantic role tokens (v1.1)
|
|
199
|
+
// Typography — semantic role tokens (v1.1) — VOCABULARY
|
|
198
200
|
// -----------------------------------------------------------------------
|
|
199
201
|
// Public API surface — full scale exposed; internal usage may skip levels.
|
|
202
|
+
// Vocabulary: density + themes rebind these; mixins read the
|
|
203
|
+
// --font-size/--line-height primitives via @include typography(role),
|
|
204
|
+
// never these tokens directly.
|
|
200
205
|
--text-display-lg: 3.75rem; --lh-display-lg: 1.1;
|
|
201
206
|
--text-display-md: 3rem; --lh-display-md: 1.1;
|
|
202
|
-
--text-display-sm:
|
|
207
|
+
--text-display-sm: 1.875rem; --lh-display-sm: 1.1;
|
|
203
208
|
|
|
204
|
-
--text-heading-lg: 1.
|
|
205
|
-
--text-heading-md: 1.
|
|
206
|
-
--text-heading-sm: 1.
|
|
209
|
+
--text-heading-lg: 1.75rem; --lh-heading-lg: 1.15;
|
|
210
|
+
--text-heading-md: 1.25rem; --lh-heading-md: 1.2;
|
|
211
|
+
--text-heading-sm: 1.125rem; --lh-heading-sm: 1.25;
|
|
207
212
|
|
|
208
|
-
--text-title-md:
|
|
209
|
-
--text-title-sm:
|
|
213
|
+
--text-title-md: 1rem; --lh-title-md: 1.3;
|
|
214
|
+
--text-title-sm: 0.875rem; --lh-title-sm: 1.3;
|
|
210
215
|
|
|
211
216
|
--text-body-lg: 1.125rem; --lh-body-lg: 1.6;
|
|
212
|
-
--text-body-md:
|
|
213
|
-
--text-body-sm: 0.
|
|
217
|
+
--text-body-md: 0.875rem; --lh-body-md: 1.5; // 14px / 1.5 — DocuFlow body
|
|
218
|
+
--text-body-sm: 0.8125rem; --lh-body-sm: 1.45; // 13px
|
|
214
219
|
|
|
215
|
-
--text-label-md: 0.
|
|
220
|
+
--text-label-md: 0.8125rem; --lh-label-md: 1.4; // 13px
|
|
216
221
|
--text-label-sm: 0.75rem; --lh-label-sm: 1.4;
|
|
217
222
|
|
|
218
223
|
--text-caption: 0.75rem; --lh-caption: 1.4;
|
|
@@ -241,17 +246,21 @@
|
|
|
241
246
|
// -----------------------------------------------------------------------
|
|
242
247
|
// App shell — intrinsic dimensions (not spacing rhythm)
|
|
243
248
|
// -----------------------------------------------------------------------
|
|
244
|
-
--app-header-height: 3.
|
|
245
|
-
--app-sidebar-width:
|
|
249
|
+
--app-header-height: 3.25rem; // 52px — DocuFlow topbar height
|
|
250
|
+
--app-sidebar-width: 14.5rem; // 232px — DocuFlow sidebar width
|
|
246
251
|
--app-scrim-bg: hsl(var(--color-neutral-900) / 0.4);
|
|
247
252
|
|
|
248
253
|
// -----------------------------------------------------------------------
|
|
249
254
|
// Logical tokens — the public contract mixins read
|
|
250
255
|
// -----------------------------------------------------------------------
|
|
251
|
-
// Rule: mixin bodies reference ONLY these tokens
|
|
252
|
-
// --
|
|
253
|
-
//
|
|
254
|
-
//
|
|
256
|
+
// Rule: mixin bodies reference ONLY these tokens. Typography mixins read
|
|
257
|
+
// --font-size/--line-height ONLY (via @include typography(role), which
|
|
258
|
+
// rebinds the primitive per role on the consuming element's scope).
|
|
259
|
+
// --text-*/--lh-* role scale is VOCABULARY: density + themes rebind it,
|
|
260
|
+
// mixins never read it directly. --radius-*/--shadow-*/--transition-*/
|
|
261
|
+
// --easing-* role scales remain directly readable (not yet primitived).
|
|
262
|
+
// Back-end scales (--size-*, --color-neutral-*) are re-bound here and in
|
|
263
|
+
// context scopes (density, theme, region overrides) — never read directly
|
|
255
264
|
// inside a component mixin.
|
|
256
265
|
//
|
|
257
266
|
// See .claude/plans/refactor-logical-tokens-architecture.md for the
|
|
@@ -260,8 +269,8 @@
|
|
|
260
269
|
|
|
261
270
|
// -- Structure & rhythm -----------------------------------------------
|
|
262
271
|
--padding-x: var(--size-sm-up);
|
|
263
|
-
--padding-y: var(--size-
|
|
264
|
-
--gap: var(--size-
|
|
272
|
+
--padding-y: var(--size-xs-up); // 6px — dense base (DocuFlow 7px rounds to 6px)
|
|
273
|
+
--gap: var(--size-xs-up); // 6px — dense base
|
|
265
274
|
--radius: var(--radius-md);
|
|
266
275
|
|
|
267
276
|
// -----------------------------------------------------------------------
|
|
@@ -350,10 +359,24 @@
|
|
|
350
359
|
--btn-border-hover: var(--border-strong-hover);
|
|
351
360
|
|
|
352
361
|
// Button padding tokens
|
|
353
|
-
--btn-padding-x: var(--size-
|
|
354
|
-
--btn-padding-y: var(--size-
|
|
355
|
-
|
|
356
|
-
//
|
|
362
|
+
--btn-padding-x: var(--size-sm-up);
|
|
363
|
+
--btn-padding-y: var(--size-xs-up);
|
|
364
|
+
|
|
365
|
+
// Card padding tokens — roomier than base rhythm; density-reactive via _density.scss
|
|
366
|
+
--card-padding-y: var(--size-sm-up); // 12px dense base
|
|
367
|
+
--card-padding-x: var(--size-md); // 16px dense base
|
|
368
|
+
|
|
369
|
+
// Table cell padding tokens — roomier than base rhythm; density-reactive via _density.scss
|
|
370
|
+
--table-cell-padding-y: var(--size-sm); // 8px dense base (DocuFlow th: 9px / td: 10px)
|
|
371
|
+
--table-cell-padding-x: var(--size-md); // 16px dense base
|
|
372
|
+
|
|
373
|
+
// -- Typography — primitives -----------------------------------------
|
|
374
|
+
// Mixins read these two primitives ONLY (via @include typography(role),
|
|
375
|
+
// which rebinds them per role on the consuming element's scope — mirror
|
|
376
|
+
// of how @mixin card rebinds --color-bg). The --text-{role}/--lh-{role}
|
|
377
|
+
// role scale (lines ~202-220) is VOCABULARY: density + themes rebind it,
|
|
378
|
+
// mixins never read it directly. These :root values are the default for
|
|
379
|
+
// text that does not pass through a typography mixin.
|
|
357
380
|
--font-size: var(--text-body-md);
|
|
358
381
|
--line-height: var(--lh-body-md);
|
|
359
382
|
|
|
@@ -389,10 +412,10 @@
|
|
|
389
412
|
// margin-bottom: var(--margin-block);
|
|
390
413
|
// }
|
|
391
414
|
//
|
|
392
|
-
//
|
|
393
|
-
// the
|
|
394
|
-
//
|
|
395
|
-
//
|
|
415
|
+
// NOTE: [data-density] scopes rebind type roles, logical
|
|
416
|
+
// --padding-y/--gap, and control sizing — NOT the --size-* scale.
|
|
417
|
+
// So --margin-block (reading --size-*) is constant across density
|
|
418
|
+
// tiers for now; making structural margins reactive is a Phase 3 item.
|
|
396
419
|
//
|
|
397
420
|
// --margin-inline is the horizontal companion. Used for
|
|
398
421
|
// element-pushing structural offsets (icon→text gap inside a
|
|
@@ -402,18 +425,17 @@
|
|
|
402
425
|
|
|
403
426
|
// ---------------------------------------------------------------------------
|
|
404
427
|
// Mobile rhythm — logical tokens tighten at ≤ md viewport.
|
|
405
|
-
// Not the same as
|
|
428
|
+
// Not the same as `[data-density]` (that's a user opt-in).
|
|
406
429
|
// This is viewport-driven structural compression: content dominates chrome
|
|
407
430
|
// at narrow widths. Components reading --padding-x/--padding-y/--gap
|
|
408
431
|
// react via the cascade.
|
|
409
432
|
//
|
|
410
|
-
// Interaction with
|
|
411
|
-
// both apply; the underlying --
|
|
412
|
-
// .density-compact so logical tokens resolve to the tightest value.
|
|
433
|
+
// Interaction with [data-density]: stacks. Compact density + mobile viewport =
|
|
434
|
+
// both apply; the underlying --padding-y tightens further from the mobile rebind.
|
|
413
435
|
// ---------------------------------------------------------------------------
|
|
414
436
|
@include mq-down(md) {
|
|
415
437
|
:root {
|
|
416
|
-
--padding-y: var(--size-xs); //
|
|
417
|
-
--gap: var(--size-xs-up); //
|
|
438
|
+
--padding-y: var(--size-xs); // 6px → 4px
|
|
439
|
+
--gap: var(--size-xs-up); // 6px → 6px (already tight)
|
|
418
440
|
}
|
|
419
441
|
}
|
|
@@ -41,12 +41,7 @@
|
|
|
41
41
|
@include cursor-pointer;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
//
|
|
45
|
-
.
|
|
46
|
-
--padding-y: var(--size-sm-up);
|
|
47
|
-
--padding-x: var(--size-md);
|
|
48
|
-
padding: var(--padding-y) var(--padding-x);
|
|
49
|
-
margin: 0;
|
|
50
|
-
}
|
|
44
|
+
// Body spacing now comes from the universal `.collapsible-body > *`
|
|
45
|
+
// rule in components/_toggle.scss (applies to every collapsible).
|
|
51
46
|
}
|
|
52
47
|
}
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
//
|
|
16
16
|
// HTML:
|
|
17
17
|
// <div class="alert" role="alert">
|
|
18
|
-
// <svg class="ln-icon" aria-hidden="true"><use href="#ln-info-circle"></use></svg>
|
|
18
|
+
// <svg class="ln-icon" aria-hidden="true"><use href="#ln-icon-info-circle"></use></svg>
|
|
19
19
|
// <p>Message text.</p>
|
|
20
20
|
// <button type="button" aria-label="Dismiss">
|
|
21
|
-
// <svg class="ln-icon" aria-hidden="true"><use href="#ln-x"></use></svg>
|
|
21
|
+
// <svg class="ln-icon" aria-hidden="true"><use href="#ln-icon-x"></use></svg>
|
|
22
22
|
// </button>
|
|
23
23
|
// </div>
|
|
24
24
|
|
|
@@ -63,12 +63,12 @@
|
|
|
63
63
|
// HTML (dismissible via ln-toggle, dismissed state persists across reloads):
|
|
64
64
|
// <div class="alert banner" role="status" aria-live="polite"
|
|
65
65
|
// data-ln-toggle="open" data-ln-persist id="trial-notice">
|
|
66
|
-
// <svg class="ln-icon" aria-hidden="true"><use href="#ln-info-circle"></use></svg>
|
|
66
|
+
// <svg class="ln-icon" aria-hidden="true"><use href="#ln-icon-info-circle"></use></svg>
|
|
67
67
|
// <p>Trial expires in 3 days.</p>
|
|
68
68
|
// <button type="button" aria-label="Dismiss"
|
|
69
69
|
// data-ln-toggle-for="trial-notice"
|
|
70
70
|
// data-ln-toggle-action="close">
|
|
71
|
-
// <svg class="ln-icon" aria-hidden="true"><use href="#ln-x"></use></svg>
|
|
71
|
+
// <svg class="ln-icon" aria-hidden="true"><use href="#ln-icon-x"></use></svg>
|
|
72
72
|
// </button>
|
|
73
73
|
// </div>
|
|
74
74
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
@use 'borders' as *;
|
|
3
3
|
@use 'focus' as *;
|
|
4
4
|
@use 'interaction' as *;
|
|
5
|
+
@use 'typography' as *;
|
|
5
6
|
|
|
6
7
|
// ─── Breadcrumbs ────────────────────────────────────────────────────────────
|
|
7
8
|
// CSS-only navigation trail. No JS involvement.
|
|
@@ -37,8 +38,7 @@
|
|
|
37
38
|
@include flex;
|
|
38
39
|
@include items-center;
|
|
39
40
|
gap: var(--gap);
|
|
40
|
-
|
|
41
|
-
line-height: var(--lh-body-sm);
|
|
41
|
+
@include typography(body-sm);
|
|
42
42
|
margin: 0;
|
|
43
43
|
|
|
44
44
|
+ li::before {
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
// --color-accent / --color-accent-fg) sidestep that: the default
|
|
49
49
|
// theme leaves them unset (mixin falls back to solid + white), Glass
|
|
50
50
|
// rebinds them at theme :root to flip the accent button to
|
|
51
|
-
// translucent. Solid-accent consumers (toast-
|
|
51
|
+
// translucent. Solid-accent consumers (toast-icon, pill-checked,
|
|
52
52
|
// stepper active/complete) read --color-accent / --color-accent-fg
|
|
53
53
|
// directly and are unaffected by Glass's rebind because Glass leaves
|
|
54
54
|
// --color-accent-fg alone. See CLAUDE.md ## Theme Architecture for
|
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
// Card & Section — composite mixins
|
|
12
12
|
|
|
13
13
|
@mixin card {
|
|
14
|
+
--color-bg: var(--nested-card-bg, var(--bg-base));
|
|
15
|
+
--shadow: var(--nested-card-shadow, var(--shadow-resting));
|
|
16
|
+
|
|
14
17
|
background: var(--color-bg);
|
|
15
18
|
@include border;
|
|
16
19
|
@include w-full;
|
|
@@ -18,12 +21,28 @@
|
|
|
18
21
|
border-radius: var(--radius);
|
|
19
22
|
@include overflow-hidden;
|
|
20
23
|
@include transition;
|
|
21
|
-
--shadow: var(--shadow-resting);
|
|
22
24
|
box-shadow: var(--shadow);
|
|
23
25
|
|
|
24
26
|
&:hover {
|
|
25
|
-
--color-border: var(--
|
|
26
|
-
--shadow: var(--shadow-floating);
|
|
27
|
+
--color-border: color-mix(in srgb, var(--color-accent) 35%, transparent);
|
|
28
|
+
--shadow: var(--nested-card-shadow-hover, var(--shadow-floating));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Nesting ladder: when nested inside a section-card or another card,
|
|
32
|
+
// climb to elevated surface to preserve visual depth.
|
|
33
|
+
.section-card &,
|
|
34
|
+
.section &,
|
|
35
|
+
.card & {
|
|
36
|
+
--color-bg: var(--bg-elevated);
|
|
37
|
+
--shadow: var(--shadow-floating);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Bulletproof nesting support for custom/semantic selectors:
|
|
41
|
+
// sets the elevated background variables on all descendants.
|
|
42
|
+
& * {
|
|
43
|
+
--nested-card-bg: var(--bg-elevated);
|
|
44
|
+
--nested-card-shadow: var(--shadow-floating);
|
|
45
|
+
--nested-card-shadow-hover: var(--shadow-floating);
|
|
27
46
|
}
|
|
28
47
|
|
|
29
48
|
// Direct-child selectors only — nested <header>/<main>/<footer>
|
|
@@ -47,13 +66,22 @@
|
|
|
47
66
|
@include flex-1;
|
|
48
67
|
text-decoration: none;
|
|
49
68
|
color: inherit;
|
|
69
|
+
|
|
70
|
+
> header { @include panel-header; }
|
|
71
|
+
> main { @include panel-body; }
|
|
72
|
+
> footer { @include panel-footer; }
|
|
73
|
+
|
|
74
|
+
> main {
|
|
75
|
+
@include flex-1;
|
|
76
|
+
gap: var(--gap);
|
|
77
|
+
}
|
|
50
78
|
}
|
|
51
79
|
|
|
52
80
|
// Tile-header h3: when a card carries a title inside > main
|
|
53
81
|
// without a <header> wrapper, the global h3 cascade (heading-sm)
|
|
54
82
|
// is too large for tile context. Tighten to tile-title sizing.
|
|
55
83
|
> main h3 {
|
|
56
|
-
|
|
84
|
+
@include typography(body-sm);
|
|
57
85
|
@include font-semibold;
|
|
58
86
|
color: inherit;
|
|
59
87
|
margin: 0;
|
|
@@ -64,15 +92,15 @@
|
|
|
64
92
|
@include flex;
|
|
65
93
|
@include items-center;
|
|
66
94
|
@include justify-between;
|
|
67
|
-
padding: var(--padding-y) var(--padding-x);
|
|
95
|
+
padding: var(--card-padding-y) var(--card-padding-x);
|
|
68
96
|
@include border-b;
|
|
69
97
|
--color-bg: var(--bg-sunken);
|
|
70
98
|
background: var(--color-bg);
|
|
71
99
|
@include transition;
|
|
100
|
+
margin-bottom: 0;
|
|
72
101
|
|
|
73
|
-
h3 {
|
|
74
|
-
|
|
75
|
-
line-height: var(--lh-body-sm);
|
|
102
|
+
:is(h1, h2, h3, h4, h5, h6) {
|
|
103
|
+
@include typography(body-sm);
|
|
76
104
|
@include font-medium;
|
|
77
105
|
color: var(--color-fg);
|
|
78
106
|
margin: 0;
|
|
@@ -110,7 +138,48 @@
|
|
|
110
138
|
}
|
|
111
139
|
|
|
112
140
|
@mixin panel-body {
|
|
113
|
-
padding: var(--padding-y) var(--padding-x);
|
|
141
|
+
padding: var(--card-padding-y) var(--card-padding-x);
|
|
142
|
+
|
|
143
|
+
ul, ol {
|
|
144
|
+
padding-left: 1.5em;
|
|
145
|
+
margin-bottom: var(--size-md);
|
|
146
|
+
|
|
147
|
+
li {
|
|
148
|
+
margin-bottom: var(--size-xs);
|
|
149
|
+
line-height: 1.7;
|
|
150
|
+
list-style: inherit;
|
|
151
|
+
|
|
152
|
+
&:last-child {
|
|
153
|
+
margin-bottom: 0;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
ul {
|
|
159
|
+
list-style-type: disc;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
ol {
|
|
163
|
+
list-style-type: decimal;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
&:has(> table),
|
|
167
|
+
&:has(> .table-container) {
|
|
168
|
+
overflow-x: auto;
|
|
169
|
+
max-width: 100%;
|
|
170
|
+
-webkit-overflow-scrolling: touch;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// ln-table brings its own chrome and sticky thead/footer — `clip` keeps
|
|
174
|
+
// this cell from becoming the scroll container that would trap them.
|
|
175
|
+
&:has(> [data-ln-table]) {
|
|
176
|
+
overflow-x: clip;
|
|
177
|
+
max-width: 100%;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
table {
|
|
181
|
+
min-width: var(--table-min-width, 600px);
|
|
182
|
+
}
|
|
114
183
|
|
|
115
184
|
// Auto-flush: ONLY when the table (or .table-container) is the
|
|
116
185
|
// sole child of main — i.e. the card is a pure table card.
|
|
@@ -122,11 +191,13 @@
|
|
|
122
191
|
// then <table>), :only-child doesn't match, padding stays,
|
|
123
192
|
// and the table keeps its own inset.
|
|
124
193
|
&:has(> table:only-child),
|
|
125
|
-
&:has(> .table-container:only-child)
|
|
194
|
+
&:has(> .table-container:only-child),
|
|
195
|
+
&:has(> [data-ln-table]:only-child) {
|
|
126
196
|
padding: 0;
|
|
127
197
|
|
|
128
198
|
> table,
|
|
129
|
-
> .table-container > table
|
|
199
|
+
> .table-container > table,
|
|
200
|
+
> [data-ln-table] > table {
|
|
130
201
|
border-radius: 0;
|
|
131
202
|
box-shadow: none;
|
|
132
203
|
margin-bottom: 0;
|
|
@@ -135,8 +206,10 @@
|
|
|
135
206
|
}
|
|
136
207
|
|
|
137
208
|
@mixin panel-footer {
|
|
138
|
-
padding: var(--padding-y) var(--padding-x);
|
|
209
|
+
padding: var(--card-padding-y) var(--card-padding-x);
|
|
139
210
|
@include border-t;
|
|
211
|
+
--color-bg: var(--bg-sunken);
|
|
212
|
+
background: var(--color-bg);
|
|
140
213
|
@include flex;
|
|
141
214
|
@include justify-end;
|
|
142
215
|
gap: var(--gap);
|
|
@@ -146,7 +219,7 @@
|
|
|
146
219
|
--margin-block: var(--size-xl);
|
|
147
220
|
margin-bottom: var(--margin-block);
|
|
148
221
|
|
|
149
|
-
header {
|
|
222
|
+
> header {
|
|
150
223
|
@include flex;
|
|
151
224
|
@include items-center;
|
|
152
225
|
@include justify-between;
|
|
@@ -277,7 +350,9 @@
|
|
|
277
350
|
border-inline-end: var(--border-inline-end, var(--border-width) solid var(--color-border));
|
|
278
351
|
border-radius: var(--radius);
|
|
279
352
|
box-shadow: var(--shadow);
|
|
280
|
-
z-index:
|
|
353
|
+
// z-index is the caller's responsibility: top-layer consumers (dropdown,
|
|
354
|
+
// popover, tooltip portal) don't need one; standalone consumers do —
|
|
355
|
+
// see [data-ln-table] .column-filter-dropdown in components/_filter.scss.
|
|
281
356
|
}
|
|
282
357
|
|
|
283
358
|
// ─── Card field list (label/value rows) ────────────────
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
// --color-accent vocabulary to a status family (success / warning /
|
|
20
20
|
// error / info / secondary). Used by .success / .warning / .error /
|
|
21
21
|
// .info / .secondary classes in _utilities.scss. Cascading both families
|
|
22
|
-
// ensures every downstream consumer (btn, toast-
|
|
22
|
+
// ensures every downstream consumer (btn, toast-icon, card-accent,
|
|
23
23
|
// alert, badge, etc.) picks up the status color through inherited
|
|
24
24
|
// custom-property values — no per-mixin redeclare required.
|
|
25
25
|
@mixin semantic-color($family) {
|
|
@@ -35,3 +35,14 @@
|
|
|
35
35
|
margin-inline-start: var(--size-xs, 0.5rem);
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
+
|
|
39
|
+
// Replaced-element DOM diagnostic error (img, video, iframe, etc.)
|
|
40
|
+
// Replaced elements do NOT render ::before/::after generated content, so this
|
|
41
|
+
// mixin uses a visible outline + translucent wash instead of a text label.
|
|
42
|
+
// The human-readable reason is carried by surrounding copy (e.g. a demo
|
|
43
|
+
// section header), not by a pseudo-element.
|
|
44
|
+
@mixin dev-replaced-error {
|
|
45
|
+
outline: 2px dashed hsl(var(--color-error));
|
|
46
|
+
outline-offset: var(--size-xs);
|
|
47
|
+
background: color-mix(in srgb, hsl(var(--color-error)) 15%, transparent);
|
|
48
|
+
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
@mixin block { display: block; }
|
|
6
6
|
@mixin inline-block { display: inline-block; }
|
|
7
7
|
@mixin hidden { display: none; }
|
|
8
|
+
@mixin invisible { visibility: hidden; }
|
|
8
9
|
|
|
9
10
|
@mixin flex-col { display: flex; flex-direction: column; }
|
|
10
11
|
@mixin flex-row { display: flex; flex-direction: row; }
|
|
@@ -130,11 +130,9 @@
|
|
|
130
130
|
|
|
131
131
|
@mixin dropdown-menu {
|
|
132
132
|
@include floating-panel;
|
|
133
|
-
@include
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
--margin-block: var(--size-xs);
|
|
137
|
-
margin-top: var(--margin-block);
|
|
133
|
+
@include fixed;
|
|
134
|
+
inset: auto;
|
|
135
|
+
margin: 0;
|
|
138
136
|
--padding-y: var(--size-xs);
|
|
139
137
|
padding-block: var(--padding-y);
|
|
140
138
|
min-width: 10rem;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
@use 'spacing' as *;
|
|
2
|
+
@use 'display' as *;
|
|
3
|
+
@use 'typography' as *;
|
|
4
|
+
@use 'colors' as *;
|
|
5
|
+
@use 'borders' as *;
|
|
6
|
+
@use 'transitions' as *;
|
|
7
|
+
@use 'motion' as *;
|
|
8
|
+
@use 'focus' as *;
|
|
9
|
+
@use 'prose' as *;
|
|
10
|
+
|
|
11
|
+
// ─── Editor ────────────────────────────────────────────────────
|
|
12
|
+
// Lightweight WYSIWYG editor wrapper: toolbar + contentEditable
|
|
13
|
+
// surface. The editing surface reuses @include prose for content
|
|
14
|
+
// formatting so authored content matches rendered output.
|
|
15
|
+
//
|
|
16
|
+
// Structure:
|
|
17
|
+
// [data-ln-editor]
|
|
18
|
+
// > [role="toolbar"] toolbar (authored container)
|
|
19
|
+
// > ul > li > button formatting actions (grouped)
|
|
20
|
+
// > .ln-editor__surface contentEditable div (JS-created)
|
|
21
|
+
// > textarea hidden source (form submission)
|
|
22
|
+
|
|
23
|
+
@mixin editor {
|
|
24
|
+
@include border;
|
|
25
|
+
border-radius: var(--radius);
|
|
26
|
+
overflow: hidden;
|
|
27
|
+
--color-bg: var(--bg-base);
|
|
28
|
+
background: var(--color-bg);
|
|
29
|
+
|
|
30
|
+
// ─── Toolbar ───────────────────────────────────────────────
|
|
31
|
+
> [role="toolbar"] {
|
|
32
|
+
@include flex;
|
|
33
|
+
@include flex-wrap;
|
|
34
|
+
@include items-center;
|
|
35
|
+
--gap: var(--size-2xs);
|
|
36
|
+
gap: var(--gap);
|
|
37
|
+
--padding-y: var(--size-xs);
|
|
38
|
+
--padding-x: var(--size-sm);
|
|
39
|
+
padding: var(--padding-y) var(--padding-x);
|
|
40
|
+
--color-bg: var(--bg-sunken);
|
|
41
|
+
background: var(--color-bg);
|
|
42
|
+
border-bottom: var(--border-width) solid var(--color-border);
|
|
43
|
+
|
|
44
|
+
// Button groups — each <ul> is a visual group
|
|
45
|
+
> ul {
|
|
46
|
+
@include flex;
|
|
47
|
+
@include items-center;
|
|
48
|
+
--gap: var(--size-2xs);
|
|
49
|
+
gap: var(--gap);
|
|
50
|
+
list-style: none;
|
|
51
|
+
padding: 0;
|
|
52
|
+
margin: 0;
|
|
53
|
+
|
|
54
|
+
// Visual separator between groups (not on last)
|
|
55
|
+
&:not(:last-child) {
|
|
56
|
+
--padding-x: var(--size-xs);
|
|
57
|
+
padding-right: var(--padding-x);
|
|
58
|
+
border-right: var(--border-width) solid var(--color-border);
|
|
59
|
+
--margin-inline: var(--size-xs);
|
|
60
|
+
margin-right: var(--margin-inline);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Toolbar buttons — compact, neutral
|
|
65
|
+
button {
|
|
66
|
+
--padding-y: var(--size-2xs);
|
|
67
|
+
--padding-x: var(--size-xs);
|
|
68
|
+
padding: var(--padding-y) var(--padding-x);
|
|
69
|
+
border-radius: var(--radius-sm);
|
|
70
|
+
background: transparent;
|
|
71
|
+
color: var(--color-fg);
|
|
72
|
+
@include transition-colors;
|
|
73
|
+
|
|
74
|
+
&:hover {
|
|
75
|
+
--color-bg: var(--bg-base);
|
|
76
|
+
background: var(--color-bg);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Active formatting state (JS toggles this class)
|
|
80
|
+
&.ln-editor-active {
|
|
81
|
+
--color-bg: var(--bg-base);
|
|
82
|
+
background: var(--color-bg);
|
|
83
|
+
color: var(--color-accent);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// ─── Editing Surface ───────────────────────────────────────
|
|
89
|
+
> .ln-editor__surface {
|
|
90
|
+
@include prose;
|
|
91
|
+
max-width: none; // Override prose's max-width constraint
|
|
92
|
+
--padding-y: var(--size-md);
|
|
93
|
+
--padding-x: var(--size-md);
|
|
94
|
+
padding: var(--padding-y) var(--padding-x);
|
|
95
|
+
min-height: 8rem;
|
|
96
|
+
outline: none;
|
|
97
|
+
cursor: text;
|
|
98
|
+
|
|
99
|
+
// Counter the global reset (`ul li, ol li { list-style: none }`).
|
|
100
|
+
// The reset kills markers on <li> directly; prose only sets
|
|
101
|
+
// list-style on the <ul>/<ol> container. Restore inheritance
|
|
102
|
+
// so the container's disc/decimal flows through to each item.
|
|
103
|
+
ul li { list-style: disc; }
|
|
104
|
+
ol li { list-style: decimal; }
|
|
105
|
+
|
|
106
|
+
// Empty placeholder via CSS
|
|
107
|
+
&:empty::before {
|
|
108
|
+
content: attr(data-placeholder);
|
|
109
|
+
--color-fg: var(--fg-subtle);
|
|
110
|
+
color: var(--color-fg);
|
|
111
|
+
pointer-events: none;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Focus state on the whole editor when editing
|
|
116
|
+
&:focus-within {
|
|
117
|
+
border-color: var(--color-accent);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// ─── Hidden textarea (source for form submission) ──────────
|
|
121
|
+
> textarea[data-ln-editor-source] {
|
|
122
|
+
display: none;
|
|
123
|
+
}
|
|
124
|
+
}
|