@livenetworks/ashlar 2.1.12 → 2.2.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 +25 -2
- package/components/COMPONENTS.md +29 -25
- package/components/ln-api-connector/ln-api-connector.schema.json +105 -105
- package/components/ln-chart/ln-chart-dev.scss +0 -4
- package/components/ln-core/README.md +16 -60
- package/components/ln-core/index.js +1 -1
- package/components/ln-core/ln-core.schema.json +120 -120
- package/components/ln-core/query.js +113 -113
- package/components/ln-core/reactive.js +0 -59
- package/components/ln-data-coordinator/README.md +2 -0
- package/components/ln-data-coordinator/ln-data-coordinator.js +1 -1
- package/components/ln-data-coordinator/ln-data-coordinator.schema.json +196 -196
- package/components/ln-data-coordinator/src/ln-data-coordinator.js +457 -432
- package/components/ln-data-store/ln-data-store.schema.json +92 -92
- package/components/ln-date/ln-date.js +1 -1
- package/components/ln-date/src/ln-date.js +1 -1
- package/components/ln-debug/ln-debug.js +1 -1
- package/components/ln-debug/ln-debug.schema.json +28 -28
- package/components/ln-debug/src/generated-attributes.js +304 -302
- package/components/ln-dropdown/ln-dropdown.schema.json +90 -90
- package/components/ln-external-links/README.md +19 -19
- package/components/ln-external-links/ln-external-links.js +1 -1
- package/components/ln-external-links/ln-external-links.schema.json +9 -0
- package/components/ln-external-links/ln-external-links.scss +12 -0
- package/components/ln-external-links/src/ln-external-links.js +3 -2
- package/components/ln-filter/README.md +2 -1
- package/components/ln-filter/ln-filter.js +1 -1
- package/components/ln-filter/ln-filter.schema.json +157 -169
- package/components/ln-filter/src/ln-filter.js +4 -4
- package/components/ln-form/ln-form.schema.json +57 -57
- package/components/ln-key/ln-key.js +1 -1
- package/components/ln-key/ln-key.schema.json +8 -0
- package/components/ln-key/src/ln-key.js +8 -5
- package/components/ln-obfuscator/ln-obfuscator.js +1 -1
- package/components/ln-obfuscator/ln-obfuscator.schema.json +6 -0
- package/components/ln-obfuscator/src/ln-obfuscator.js +2 -2
- package/components/ln-options/ln-options.schema.json +47 -47
- package/components/ln-popover/ln-popover.schema.json +82 -82
- package/components/ln-progress/ln-progress.schema.json +0 -13
- package/components/ln-search/ln-search.schema.json +111 -111
- package/components/ln-sort/README.md +1 -0
- package/components/ln-sort/ln-sort.js +1 -1
- package/components/ln-sort/ln-sort.schema.json +100 -112
- package/components/ln-sort/src/sort-model.js +1 -6
- package/components/ln-sortable/ln-sortable.schema.json +38 -38
- package/components/ln-sortable/ln-sortable.scss +25 -25
- package/components/ln-table/README.md +8 -1
- package/components/ln-table/ln-table.js +1 -1
- package/components/ln-table/ln-table.schema.json +195 -195
- package/components/ln-table/src/ln-table.js +43 -7
- package/components/ln-table-coordinator/ln-table-coordinator.js +1 -1
- package/components/ln-table-coordinator/ln-table-coordinator.schema.json +18 -0
- package/components/ln-table-coordinator/src/ln-table-coordinator.js +104 -2
- package/components/ln-toast/README.md +1 -1
- package/components/ln-toast/ln-toast.js +1 -1
- package/components/ln-toast/ln-toast.schema.json +6 -0
- package/components/ln-toast/src/ln-toast.js +1 -1
- package/components/ln-validate/README.md +6 -6
- package/components/ln-validate/ln-validate-dev.scss +0 -5
- package/components/ln-validate/ln-validate.js +1 -1
- package/components/ln-validate/ln-validate.schema.json +0 -6
- package/components/ln-validate/src/ln-validate.js +48 -29
- package/ln-ashlar.html-data.json +1824 -1814
- package/package.json +15 -5
- package/theme/README.md +74 -0
- package/theme/base/_global.scss +2 -2
- package/theme/base/_reset.scss +11 -0
- package/theme/components/_app-shell.scss +0 -8
- package/theme/components/_form.scss +6 -6
- package/theme/components/_ln-table.scss +6 -3
- package/theme/components/_scrollbar.scss +5 -4
- package/theme/components/_sortable.scss +19 -19
- package/theme/components/_stat-card.scss +1 -0
- package/theme/components/_table.scss +11 -35
- package/theme/config/_density.scss +110 -65
- package/theme/config/_palette.scss +71 -49
- package/theme/config/_theme.scss +27 -31
- package/theme/config/_tokens.scss +28 -26
- package/theme/config/mixins/_app-shell.scss +17 -21
- package/theme/config/mixins/_avatar.scss +2 -2
- package/theme/config/mixins/_btn.scss +4 -2
- package/theme/config/mixins/_card.scss +88 -71
- package/theme/config/mixins/_colors.scss +2 -1
- package/theme/config/mixins/_display.scss +12 -0
- package/theme/config/mixins/_footer.scss +3 -1
- package/theme/config/mixins/_form.scss +74 -55
- package/theme/config/mixins/_layout.scss +9 -0
- package/theme/config/mixins/_ln-table.scss +22 -15
- package/theme/config/mixins/_modal.scss +3 -0
- package/theme/config/mixins/_nav.scss +31 -8
- package/theme/config/mixins/_sidebar.scss +2 -1
- package/theme/config/mixins/_spacing.scss +4 -4
- package/theme/config/mixins/_stat-card.scss +33 -2
- package/theme/config/mixins/_status-badge.scss +1 -0
- package/theme/config/mixins/_table.scss +87 -69
- package/theme/config/mixins/_tabs.scss +31 -0
- package/theme/config/mixins/_toast.scss +0 -1
- package/theme/designs/relaxed/_card.scss +12 -0
- package/theme/designs/relaxed/_layout.scss +24 -0
- package/theme/ln-ashlar-core.scss +1 -0
- package/theme/ln-ashlar-dev.scss +0 -1
- package/theme/ln-ashlar-relaxed.scss +67 -0
- package/theme/tailwind/components.css +2198 -0
- package/theme/tailwind/entry.css +3 -0
- package/theme/tailwind/theme.css +23 -0
- package/theme/utilities/_utilities.scss +1 -11
- package/web-types.json +2351 -2337
- package/components/ln-progress/ln-progress-dev.scss +0 -8
|
@@ -11,64 +11,51 @@
|
|
|
11
11
|
--color-secondary-light: 160 84% 94%;
|
|
12
12
|
--color-secondary-lighter: 160 84% 97%;
|
|
13
13
|
|
|
14
|
-
// Status colors
|
|
15
|
-
|
|
14
|
+
// Status colors — solid tones sit below the 7:1 text/fill target;
|
|
15
|
+
// ratios are against white (D2: design values kept exact).
|
|
16
|
+
--color-success: 142 72% 29%; // 5.07:1
|
|
16
17
|
--color-success-light: 142 71% 94%;
|
|
17
18
|
--color-success-lighter: 142 71% 97%;
|
|
18
19
|
|
|
19
|
-
--color-error: 0
|
|
20
|
+
--color-error: 0 72% 51%; // 4.80:1
|
|
20
21
|
--color-error-light: 0 84% 94%;
|
|
21
22
|
--color-error-lighter: 0 84% 97%;
|
|
22
23
|
|
|
23
|
-
--color-warning:
|
|
24
|
+
--color-warning: 26 90% 37%; // 5.04:1
|
|
24
25
|
--color-warning-light: 38 92% 94%;
|
|
25
26
|
--color-warning-lighter: 38 92% 97%;
|
|
26
27
|
|
|
27
|
-
--color-info:
|
|
28
|
+
--color-info: 221 83% 53%; // 5.20:1
|
|
28
29
|
--color-info-light: 199 89% 94%;
|
|
29
30
|
--color-info-lighter: 199 89% 97%;
|
|
30
31
|
|
|
31
|
-
// Neutral scale
|
|
32
|
-
--color-neutral-50: 210
|
|
33
|
-
--color-neutral-100:
|
|
34
|
-
--color-neutral-150:
|
|
35
|
-
--color-neutral-175:
|
|
36
|
-
--color-neutral-200:
|
|
37
|
-
--color-neutral-300:
|
|
38
|
-
--color-neutral-400:
|
|
39
|
-
--color-neutral-500:
|
|
40
|
-
--color-neutral-600: 215
|
|
41
|
-
--color-neutral-700:
|
|
42
|
-
--color-neutral-800:
|
|
32
|
+
// Neutral scale — cool slate greys
|
|
33
|
+
--color-neutral-50: 210 40% 98%;
|
|
34
|
+
--color-neutral-100: 210 40% 96%;
|
|
35
|
+
--color-neutral-150: 214 35% 93%;
|
|
36
|
+
--color-neutral-175: 214 33% 92%;
|
|
37
|
+
--color-neutral-200: 214 32% 91%;
|
|
38
|
+
--color-neutral-300: 213 27% 84%;
|
|
39
|
+
--color-neutral-400: 215 20% 65%;
|
|
40
|
+
--color-neutral-500: 215 16% 47%;
|
|
41
|
+
--color-neutral-600: 215 19% 35%;
|
|
42
|
+
--color-neutral-700: 215 25% 27%;
|
|
43
|
+
--color-neutral-800: 217 33% 17%;
|
|
43
44
|
--color-neutral-900: 222 47% 11%;
|
|
44
45
|
|
|
45
46
|
// Base canvas background
|
|
46
47
|
--color-white: 0 0% 100%;
|
|
47
48
|
|
|
48
|
-
// Shadows —
|
|
49
|
+
// Shadows — soft, diffuse, single layer. Resting surfaces are defined by
|
|
50
|
+
// their border; depth is reserved for floating layers.
|
|
49
51
|
--shadow-none: none;
|
|
50
52
|
|
|
51
|
-
--shadow-xs:
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
--shadow-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
--shadow-md:
|
|
59
|
-
0 4px 6px -1px hsl(220 40% 10% / 0.08),
|
|
60
|
-
0 2px 4px -2px hsl(220 40% 10% / 0.05);
|
|
61
|
-
|
|
62
|
-
--shadow-lg:
|
|
63
|
-
0 10px 15px -3px hsl(220 40% 10% / 0.08),
|
|
64
|
-
0 4px 6px -4px hsl(220 40% 10% / 0.04);
|
|
65
|
-
|
|
66
|
-
--shadow-xl:
|
|
67
|
-
0 20px 25px -5px hsl(220 40% 10% / 0.09),
|
|
68
|
-
0 8px 10px -6px hsl(220 40% 10% / 0.04);
|
|
69
|
-
|
|
70
|
-
--shadow-2xl:
|
|
71
|
-
0 25px 50px -12px hsl(220 40% 10% / 0.18);
|
|
53
|
+
--shadow-xs: 0 1px 2px hsl(215 40% 20% / 0.04);
|
|
54
|
+
--shadow-sm: 0 2px 6px hsl(215 40% 20% / 0.05);
|
|
55
|
+
--shadow-md: 0 4px 16px -4px hsl(215 40% 20% / 0.10);
|
|
56
|
+
--shadow-lg: 0 12px 32px -8px hsl(215 40% 20% / 0.14);
|
|
57
|
+
--shadow-xl: 0 24px 48px -12px hsl(215 40% 20% / 0.18);
|
|
58
|
+
--shadow-2xl: 0 32px 64px -16px hsl(215 40% 20% / 0.22);
|
|
72
59
|
|
|
73
60
|
--shadow-inner:
|
|
74
61
|
inset 0 2px 4px 0 hsl(220 40% 15% / 0.06);
|
|
@@ -79,24 +66,29 @@
|
|
|
79
66
|
// Value vocabulary — what bg/fg/border/shadow values exist
|
|
80
67
|
--bg-base: hsl(var(--color-white));
|
|
81
68
|
--bg-elevated: var(--bg-base);
|
|
82
|
-
--bg-sunken: hsl(var(--color-neutral-
|
|
83
|
-
--bg-recessed: hsl(var(--color-neutral-
|
|
69
|
+
--bg-sunken: hsl(var(--color-neutral-50)); // quiet chrome (thead, tracks)
|
|
70
|
+
--bg-recessed: hsl(var(--color-neutral-100)); // page canvas
|
|
84
71
|
|
|
85
72
|
--bg-hover: hsl(var(--color-neutral-100));
|
|
86
73
|
--bg-active: hsl(var(--color-neutral-150));
|
|
87
74
|
|
|
88
|
-
//
|
|
89
|
-
|
|
90
|
-
--fg-
|
|
91
|
-
--fg-
|
|
92
|
-
--fg-subtle: hsl(var(--color-neutral-700));
|
|
75
|
+
// fg-muted and fg-subtle are below the 7:1 target (D2: design values kept).
|
|
76
|
+
--fg-default: hsl(var(--color-neutral-800));
|
|
77
|
+
--fg-muted: hsl(213 20% 40%); // 6.07:1 on white
|
|
78
|
+
--fg-subtle: hsl(var(--color-neutral-500)); // 4.72:1 on white, 4.30:1 on the canvas
|
|
93
79
|
|
|
94
80
|
--border-subtle: hsl(var(--color-neutral-200));
|
|
95
81
|
--border-strong: hsl(var(--color-neutral-300));
|
|
82
|
+
--border-strong-hover: hsl(var(--color-neutral-500)); // 4.72:1 on white; one ramp step darker than --border-ui
|
|
96
83
|
|
|
97
84
|
// Interactive boundaries only (input/select/checkbox). 1.4.11 wants 3:1
|
|
98
85
|
// for these; --border-subtle/-strong stay decorative and exempt.
|
|
99
|
-
|
|
86
|
+
// Solved literal: slate-300 is 1.48:1, slate-400 is 2.57:1.
|
|
87
|
+
--border-ui: hsl(215 20% 58%); // 3.24:1 on white
|
|
88
|
+
|
|
89
|
+
// Lightness step for accent hover/active (relative colour syntax,
|
|
90
|
+
// unitless). Light surfaces darken; dark values flip the sign.
|
|
91
|
+
--accent-hover-shift: -8;
|
|
100
92
|
|
|
101
93
|
--color-scrim: hsl(var(--color-neutral-900) / 0.5);
|
|
102
94
|
|
|
@@ -143,14 +135,23 @@
|
|
|
143
135
|
|
|
144
136
|
--border-subtle: hsl(var(--color-neutral-175));
|
|
145
137
|
--border-strong: hsl(var(--color-neutral-300));
|
|
138
|
+
--border-strong-hover: hsl(var(--color-neutral-400));
|
|
146
139
|
|
|
147
140
|
--border-ui: hsl(var(--color-neutral-400));
|
|
148
141
|
|
|
142
|
+
// Dark surfaces lighten on hover.
|
|
143
|
+
--accent-hover-shift: 8;
|
|
144
|
+
|
|
149
145
|
// Scrims — anchored to black, not the ramp: dark --color-neutral-900 is
|
|
150
146
|
// near-white, so binding either to it would need an index flip.
|
|
151
147
|
--color-scrim: hsl(0 0% 0% / 0.6);
|
|
152
148
|
--app-scrim-bg: hsl(0 0% 0% / 0.4);
|
|
153
149
|
|
|
150
|
+
// Status tones — brighter on dark surfaces
|
|
151
|
+
--color-success: 142 69% 48%;
|
|
152
|
+
--color-warning: 38 92% 55%;
|
|
153
|
+
--color-info: 213 94% 68%;
|
|
154
|
+
|
|
154
155
|
// Status tint layers — re-tuned for dark surfaces
|
|
155
156
|
--color-success-light: 142 50% 18%;
|
|
156
157
|
--color-success-lighter: 142 40% 13%;
|
|
@@ -159,7 +160,7 @@
|
|
|
159
160
|
--color-info-light: 217 55% 22%;
|
|
160
161
|
--color-info-lighter: 217 45% 15%;
|
|
161
162
|
|
|
162
|
-
--color-error: 0
|
|
163
|
+
--color-error: 0 91% 71%; // Lighter red for text contrast in dark mode
|
|
163
164
|
--color-error-light: 0 50% 20%;
|
|
164
165
|
--color-error-lighter: 0 40% 14%;
|
|
165
166
|
|
|
@@ -215,7 +216,7 @@
|
|
|
215
216
|
// stylesheet load order, which is brand.css's whole guarantee.
|
|
216
217
|
// ---------------------------------------------------------------------------
|
|
217
218
|
:where(:root) {
|
|
218
|
-
--brand-primary:
|
|
219
|
+
--brand-primary: 201 96% 32%; // 5.94:1 on white (D2: design value kept)
|
|
219
220
|
--brand-secondary: 160 84% 36%;
|
|
220
221
|
}
|
|
221
222
|
|
|
@@ -239,6 +240,8 @@
|
|
|
239
240
|
--color-border: var(--border-subtle);
|
|
240
241
|
--shadow: var(--shadow-resting);
|
|
241
242
|
--radius: var(--radius-md);
|
|
243
|
+
// Indirection so a skin that zeroes --radius-lg (glass) reaches panels.
|
|
244
|
+
--panel-radius: var(--radius-lg);
|
|
242
245
|
|
|
243
246
|
// accent — tints computed against the LOCAL --bg-base, so one
|
|
244
247
|
// formula serves both themes. The two override slots are
|
|
@@ -272,3 +275,22 @@
|
|
|
272
275
|
--btn-fg-hover: var(--color-fg);
|
|
273
276
|
--btn-border-hover: var(--border-strong);
|
|
274
277
|
}
|
|
278
|
+
|
|
279
|
+
// ---------------------------------------------------------------------------
|
|
280
|
+
// Default dark lift — brighter accent with an ink label on dark surfaces.
|
|
281
|
+
// Zero specificity; [data-theme] subtrees are excluded so an ancestor theme's
|
|
282
|
+
// declaration is not clobbered (Declaration-Site Invariant).
|
|
283
|
+
// ---------------------------------------------------------------------------
|
|
284
|
+
:where([data-mode="dark"]:not([data-theme], [data-theme] *)) {
|
|
285
|
+
--brand-primary: 199 89% 64%; // 8.79:1 vs ink
|
|
286
|
+
--color-accent-fg: hsl(var(--color-ink));
|
|
287
|
+
--check-mark: var(--check-mark-on-dark);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
@media (prefers-color-scheme: dark) {
|
|
291
|
+
:where(:root:not([data-mode="light"]):not([data-theme])) {
|
|
292
|
+
--brand-primary: 199 89% 64%;
|
|
293
|
+
--color-accent-fg: hsl(var(--color-ink));
|
|
294
|
+
--check-mark: var(--check-mark-on-dark);
|
|
295
|
+
}
|
|
296
|
+
}
|
package/theme/config/_theme.scss
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
// :root:not([data-mode="light"]) ← opt-out of auto
|
|
17
17
|
// <html data-skin="glass"> ← structural preset (flat, borderless)
|
|
18
18
|
// <html data-theme="ocean"> ← brand palette preset
|
|
19
|
+
// <aside data-mode="dark" data-theme="navy"> ← dark navy brand region
|
|
19
20
|
//
|
|
20
21
|
// See docs-mcp/css/theming.md for the full guide.
|
|
21
22
|
// ==========================================================================
|
|
@@ -153,6 +154,28 @@
|
|
|
153
154
|
}
|
|
154
155
|
}
|
|
155
156
|
|
|
157
|
+
// Brand region — a dark-navy surface island, e.g. a sidebar. Always paired
|
|
158
|
+
// with data-mode="dark": the ramp re-seats the dark vocabulary on navy.
|
|
159
|
+
// <aside data-mode="dark" data-theme="navy">
|
|
160
|
+
[data-theme="navy"] {
|
|
161
|
+
&[data-mode="dark"],
|
|
162
|
+
:where([data-mode="dark"]) & {
|
|
163
|
+
--color-neutral-50: 213 74% 8%;
|
|
164
|
+
--color-neutral-100: 213 74% 11%;
|
|
165
|
+
--color-neutral-150: 213 55% 15%;
|
|
166
|
+
--color-neutral-175: 213 50% 17%;
|
|
167
|
+
--color-neutral-200: 213 45% 20%;
|
|
168
|
+
--color-neutral-300: 213 35% 28%;
|
|
169
|
+
--color-neutral-400: 213 30% 40%; // 2.82:1 on navy-100, under the 3:1 ui target
|
|
170
|
+
--color-neutral-600: 215 20% 65%; // 6.80:1 on navy-100 (fg-subtle)
|
|
171
|
+
--color-neutral-700: 213 27% 84%; // 11.79:1
|
|
172
|
+
--color-neutral-900: 210 40% 98%; // 16.70:1
|
|
173
|
+
--brand-primary: 199 89% 64%; // 8.59:1 on navy-100
|
|
174
|
+
--color-accent-fg: hsl(var(--color-ink));
|
|
175
|
+
--check-mark: var(--check-mark-on-dark);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
156
179
|
// ---------------------------------------------------------------------------
|
|
157
180
|
// Named skins — structural/physics presets. Polarity-agnostic. Activation:
|
|
158
181
|
// <html data-skin="glass">
|
|
@@ -185,9 +208,10 @@
|
|
|
185
208
|
--btn-bg-hover: var(--bg-hover);
|
|
186
209
|
--btn-border: var(--color-accent);
|
|
187
210
|
// --color-accent-hover is declared only below <html> (a, mixin bodies);
|
|
188
|
-
// invalid at computed-value time here — derive locally.
|
|
189
|
-
// @mixin btn's own accent-hover so neutral
|
|
190
|
-
|
|
211
|
+
// invalid at computed-value time here — derive locally. Follows
|
|
212
|
+
// --accent-hover-shift like @mixin btn's own accent-hover, so neutral
|
|
213
|
+
// and accent buttons agree.
|
|
214
|
+
--btn-border-hover: hsl(from var(--color-accent) h s calc(l + var(--accent-hover-shift)));
|
|
191
215
|
|
|
192
216
|
// ── Accent buttons — translucent fill via consumer-scope rebind
|
|
193
217
|
// Rebind --btn-* on the button itself (not at skin :root) so
|
|
@@ -263,31 +287,3 @@
|
|
|
263
287
|
--btn-border-hover: hsl(var(--color-primary));
|
|
264
288
|
}
|
|
265
289
|
}
|
|
266
|
-
|
|
267
|
-
[data-skin="soft"] {
|
|
268
|
-
// Soft — playful, maximum radius, heavily shadow-based, no borders.
|
|
269
|
-
--radius-xs: 0.5rem;
|
|
270
|
-
--radius-sm: 0.75rem;
|
|
271
|
-
--radius-md: 1rem;
|
|
272
|
-
--radius-lg: 1.5rem;
|
|
273
|
-
--radius-xl: 2rem;
|
|
274
|
-
--radius-2xl: 2.5rem;
|
|
275
|
-
|
|
276
|
-
// Override shadows to be much larger and softer (volumetric look)
|
|
277
|
-
--shadow-sm: 0 8px 16px -2px rgba(0, 0, 0, 0.08);
|
|
278
|
-
--shadow-md: 0 12px 24px -4px rgba(0, 0, 0, 0.12);
|
|
279
|
-
--shadow-lg: 0 24px 48px -4px rgba(0, 0, 0, 0.16);
|
|
280
|
-
|
|
281
|
-
// Floating elements are more pronounced
|
|
282
|
-
--shadow-resting: var(--shadow-sm);
|
|
283
|
-
--shadow-floating: var(--shadow-lg);
|
|
284
|
-
|
|
285
|
-
// Remove default subtle borders (cards, panels) so they rely solely on shadows
|
|
286
|
-
--border-subtle: transparent;
|
|
287
|
-
|
|
288
|
-
// ── Buttons — pill shapes, floating, no borders
|
|
289
|
-
--btn-border: transparent;
|
|
290
|
-
--btn-border-hover: transparent;
|
|
291
|
-
--btn-bg: var(--bg-elevated);
|
|
292
|
-
--btn-bg-hover: var(--bg-hover);
|
|
293
|
-
}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
@use 'mixins/breakpoints' as *;
|
|
2
|
-
|
|
3
1
|
// ==========================================================================
|
|
4
2
|
// Design Tokens — ln-ashlar
|
|
5
3
|
// ==========================================================================
|
|
@@ -53,23 +51,24 @@
|
|
|
53
51
|
--max-w-form: 32rem;
|
|
54
52
|
--max-w-content: 48rem;
|
|
55
53
|
--max-w-container: 80rem;
|
|
54
|
+
--grid-item-min-width: 14rem; // intrinsic minimum for auto-fit card grids
|
|
56
55
|
|
|
57
56
|
// -----------------------------------------------------------------------
|
|
58
57
|
// Border Radius
|
|
59
58
|
// -----------------------------------------------------------------------
|
|
60
59
|
--radius-none: 0;
|
|
61
|
-
--radius-xs: 0.
|
|
62
|
-
--radius-sm: 0.
|
|
63
|
-
--radius-md: 0.
|
|
64
|
-
--radius-lg:
|
|
65
|
-
--radius-xl:
|
|
66
|
-
--radius-2xl:
|
|
60
|
+
--radius-xs: 0.25rem; // 4px
|
|
61
|
+
--radius-sm: 0.375rem; // 6px
|
|
62
|
+
--radius-md: 0.625rem; // 10px — controls (--radius)
|
|
63
|
+
--radius-lg: 1rem; // 16px — panels, modals
|
|
64
|
+
--radius-xl: 1.375rem; // 22px
|
|
65
|
+
--radius-2xl: 1.75rem; // 28px
|
|
67
66
|
--radius-full: 9999px;
|
|
68
67
|
|
|
69
68
|
// -----------------------------------------------------------------------
|
|
70
69
|
// Transitions — durations
|
|
71
70
|
// -----------------------------------------------------------------------
|
|
72
|
-
--transition-base: 0.
|
|
71
|
+
--transition-base: 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
|
73
72
|
--transition-fast: 0.15s cubic-bezier(0.4, 0, 0.2, 1);
|
|
74
73
|
--transition-slow: 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
75
74
|
|
|
@@ -85,7 +84,9 @@
|
|
|
85
84
|
// -----------------------------------------------------------------------
|
|
86
85
|
// Typography
|
|
87
86
|
// -----------------------------------------------------------------------
|
|
88
|
-
|
|
87
|
+
// Plus Jakarta Sans is not bundled — the page loads it, or the stack
|
|
88
|
+
// falls back to Inter / system UI.
|
|
89
|
+
--font-sans: 'Plus Jakarta Sans', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
89
90
|
--font-mono: 'JetBrains Mono', ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace;
|
|
90
91
|
--font-features: "cv02", "cv03", "cv04", "cv11", "tnum";
|
|
91
92
|
|
|
@@ -214,6 +215,21 @@
|
|
|
214
215
|
--btn-padding-x: var(--size-sm-up);
|
|
215
216
|
--btn-padding-y: var(--size-xs-up);
|
|
216
217
|
|
|
218
|
+
// Control size contract — buttons, text inputs, selects and pills share
|
|
219
|
+
// one line box and one vertical padding per density tier:
|
|
220
|
+
// height = --control-line-height + 2 × padding-y + 2 × border
|
|
221
|
+
// compact 22 + 2×6 + 2 = 36px · comfortable 44px · spacious 54px
|
|
222
|
+
// Density rebinds all three in _density.scss.
|
|
223
|
+
--control-line-height: 1.375rem; // 22px
|
|
224
|
+
--input-padding-y: var(--btn-padding-y);
|
|
225
|
+
|
|
226
|
+
// Card and table padding — structural rhythm, density-reactive via
|
|
227
|
+
// _density.scss (compact values here).
|
|
228
|
+
--card-padding-y: var(--size-sm-up); // 12px
|
|
229
|
+
--card-padding-x: var(--size-md); // 16px
|
|
230
|
+
--table-cell-padding-y: var(--size-sm); // 8px
|
|
231
|
+
--table-cell-padding-x: var(--size-md); // 16px
|
|
232
|
+
|
|
217
233
|
// -- Typography — primitives -----------------------------------------
|
|
218
234
|
// Mixins read these two primitives ONLY (via @include typography(role),
|
|
219
235
|
// which rebinds them per role on the consuming element's scope — mirror
|
|
@@ -267,19 +283,5 @@
|
|
|
267
283
|
// spacing — that is --gap.
|
|
268
284
|
}
|
|
269
285
|
|
|
270
|
-
//
|
|
271
|
-
//
|
|
272
|
-
// Not the same as `[data-density]` (that's a user opt-in).
|
|
273
|
-
// This is viewport-driven structural compression: content dominates chrome
|
|
274
|
-
// at narrow widths. Components reading --padding-x/--padding-y/--gap
|
|
275
|
-
// react via the cascade.
|
|
276
|
-
//
|
|
277
|
-
// Interaction with [data-density]: stacks. Compact density + mobile viewport =
|
|
278
|
-
// both apply; the underlying --padding-y tightens further from the mobile rebind.
|
|
279
|
-
// ---------------------------------------------------------------------------
|
|
280
|
-
@include mq-down(md) {
|
|
281
|
-
:root {
|
|
282
|
-
--padding-y: var(--size-xs); // 6px → 4px
|
|
283
|
-
--gap: var(--size-xs-up); // 6px → 6px (already tight)
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
+
// Mobile rhythm (viewport-driven tightening) lives at the end of
|
|
287
|
+
// _density.scss so it stacks on top of every density tier.
|
|
@@ -125,13 +125,13 @@
|
|
|
125
125
|
|
|
126
126
|
// Equalize height across icon-only and text-only siblings AND
|
|
127
127
|
// search-icon labels. Geometric — locks the border-box chrome to
|
|
128
|
-
// the
|
|
128
|
+
// the shared control line box (--control-line-height) plus rebound --padding-y and
|
|
129
129
|
// border-width on both edges. Buttons rebind --padding-y below;
|
|
130
130
|
// search labels read --padding-y from @mixin form-input-icon-group
|
|
131
131
|
// (same var(--size-xs) value), so the formula resolves identically
|
|
132
132
|
// for both. Border-box is the project default (scss/base/_reset.scss).
|
|
133
133
|
:is(button, label) {
|
|
134
|
-
min-height: calc(
|
|
134
|
+
min-height: calc(var(--control-line-height) + 2 * var(--padding-y) + 2 * var(--border-width));
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
button {
|
|
@@ -190,20 +190,12 @@
|
|
|
190
190
|
height: calc(100dvh - var(--app-header-height));
|
|
191
191
|
overflow: hidden;
|
|
192
192
|
|
|
193
|
-
//
|
|
194
|
-
//
|
|
195
|
-
//
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
padding-left: var(--app-sidebar-width);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// On mobile the sidebar overlays (scrim covers content) —
|
|
203
|
-
// no content shift.
|
|
204
|
-
@include mq-down(md) {
|
|
205
|
-
&:has(.app-sidebar[data-ln-toggle="open"]) {
|
|
206
|
-
padding-left: 0;
|
|
193
|
+
// Open drawer on desktop: reserve its width on the parent so content
|
|
194
|
+
// and footer shift together (padding, not child margin — no overflow).
|
|
195
|
+
// On mobile the drawer overlays the content instead.
|
|
196
|
+
@include mq-up(md) {
|
|
197
|
+
&:has(> aside[data-ln-toggle="open"]) {
|
|
198
|
+
padding-left: var(--app-sidebar-width);
|
|
207
199
|
}
|
|
208
200
|
}
|
|
209
201
|
|
|
@@ -222,10 +214,13 @@
|
|
|
222
214
|
// `> *:first-child` / `> *:last-child` margins below — those
|
|
223
215
|
// margins scroll past with the content, leaving sticky to pin
|
|
224
216
|
// against the actual section edges.
|
|
225
|
-
padding-inline: var(--
|
|
217
|
+
padding-inline: clamp(var(--size-md), 3vw, var(--size-xl));
|
|
226
218
|
@include overflow-auto;
|
|
227
219
|
@include w-full;
|
|
228
|
-
@include stack(var(--
|
|
220
|
+
@include stack(var(--size-lg));
|
|
221
|
+
// The stack gap owns vertical rhythm here — section-cards drop
|
|
222
|
+
// their own bottom margin so the two do not add up.
|
|
223
|
+
--panel-margin-block: 0;
|
|
229
224
|
@include transition;
|
|
230
225
|
|
|
231
226
|
// Children keep intrinsic height — wrapper's overflow-auto
|
|
@@ -243,11 +238,11 @@
|
|
|
243
238
|
// descendants (sticky top:0 toolbar/thead, sticky bottom:0 footer)
|
|
244
239
|
// to the inside of the padding edge.
|
|
245
240
|
> *:first-child {
|
|
246
|
-
margin-block-start: var(--
|
|
241
|
+
margin-block-start: clamp(var(--size-md), 3vw, var(--size-xl));
|
|
247
242
|
}
|
|
248
243
|
|
|
249
244
|
> *:last-child {
|
|
250
|
-
margin-block-end: var(--
|
|
245
|
+
margin-block-end: clamp(var(--size-md), 3vw, var(--size-xl));
|
|
251
246
|
}
|
|
252
247
|
}
|
|
253
248
|
}
|
|
@@ -309,6 +304,7 @@
|
|
|
309
304
|
max-width: var(--max-w-container);
|
|
310
305
|
@include mx(auto);
|
|
311
306
|
@include w-full;
|
|
312
|
-
@include stack(var(--
|
|
307
|
+
@include stack(var(--size-lg));
|
|
308
|
+
--panel-margin-block: 0;
|
|
313
309
|
}
|
|
314
310
|
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
// Initials fallback — <abbr class="avatar">SO</abbr>
|
|
69
|
-
&:not(:has(img
|
|
69
|
+
&:not(:has(img, span)) {
|
|
70
70
|
@include _avatar-media;
|
|
71
71
|
@include flex-center;
|
|
72
72
|
@include text-sm;
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
// ─── Sizes ─────────────────────────────────────────────
|
|
98
98
|
@mixin _avatar-size($size, $font-size, $line-height) {
|
|
99
99
|
img { @include size($size); }
|
|
100
|
-
&:not(:has(img
|
|
100
|
+
&:not(:has(img, span)) {
|
|
101
101
|
@include size($size);
|
|
102
102
|
font-size: $font-size;
|
|
103
103
|
line-height: $line-height;
|
|
@@ -37,6 +37,8 @@
|
|
|
37
37
|
--padding-x: var(--btn-padding-x, var(--size-md));
|
|
38
38
|
padding: var(--padding-y) var(--padding-x);
|
|
39
39
|
@include text-sm;
|
|
40
|
+
// Shared control line box — aligns with inputs/selects (see _tokens.scss).
|
|
41
|
+
line-height: var(--control-line-height);
|
|
40
42
|
@include font-medium;
|
|
41
43
|
border-radius: var(--radius);
|
|
42
44
|
white-space: nowrap;
|
|
@@ -69,14 +71,14 @@
|
|
|
69
71
|
@mixin btn {
|
|
70
72
|
// Accent variant — rebinds the --btn-* token surface to accent values.
|
|
71
73
|
--color-accent: hsl(var(--color-primary));
|
|
72
|
-
--color-accent-hover: hsl(from var(--color-accent) h s calc(l -
|
|
74
|
+
--color-accent-hover: hsl(from var(--color-accent) h s calc(l + var(--accent-hover-shift)));
|
|
73
75
|
|
|
74
76
|
--btn-bg: var(--color-accent-bg, var(--color-accent));
|
|
75
77
|
--btn-fg: var(--color-accent-bg-fg, var(--color-accent-fg));
|
|
76
78
|
--btn-border: hsl(from var(--color-accent) h s calc(l - 4));
|
|
77
79
|
--btn-bg-hover: var(--color-accent-bg-hover, var(--color-accent-hover));
|
|
78
80
|
--btn-fg-hover: var(--color-accent-bg-fg, var(--color-accent-fg));
|
|
79
|
-
--btn-border-hover: hsl(from var(--color-accent) h s calc(l -
|
|
81
|
+
--btn-border-hover: hsl(from var(--color-accent) h s calc(l + var(--accent-hover-shift)));
|
|
80
82
|
}
|
|
81
83
|
|
|
82
84
|
@mixin btn-soft {
|