@livenetworks/ashlar 2.0.6 → 2.0.8
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/LICENSE +641 -641
- package/components/COMPONENTS.md +1116 -1116
- package/components/index.js +81 -81
- package/components/ln-accordion/ln-accordion-dev.scss +8 -8
- package/components/ln-accordion/ln-accordion.js +1 -1
- package/components/ln-accordion/ln-accordion.schema.json +30 -30
- package/components/ln-accordion/src/ln-accordion.js +1 -0
- package/components/ln-ajax/ln-ajax-dev.scss +8 -8
- package/components/ln-ajax/ln-ajax.js +1 -1
- package/components/ln-ajax/ln-ajax.schema.json +30 -30
- package/components/ln-api-connector/ln-api-connector.js +1 -1
- package/components/ln-api-connector/ln-api-connector.schema.json +96 -96
- package/components/ln-api-connector/src/ln-api-connector.js +1 -0
- package/components/ln-api-queue/ln-api-queue.js +1 -1
- package/components/ln-api-queue/ln-api-queue.schema.json +34 -34
- package/components/ln-api-queue/src/ln-api-queue.js +3 -13
- package/components/ln-autoresize/ln-autoresize-dev.scss +8 -8
- package/components/ln-autoresize/ln-autoresize.js +1 -1
- package/components/ln-autoresize/ln-autoresize.schema.json +22 -22
- package/components/ln-autosave/ln-autosave-dev.scss +13 -13
- package/components/ln-autosave/ln-autosave.js +1 -1
- package/components/ln-autosave/ln-autosave.schema.json +48 -48
- package/components/ln-autosave/src/autosave-model.js +34 -34
- package/components/ln-chart/ln-chart.js +1 -1
- package/components/ln-chart/ln-chart.schema.json +146 -146
- package/components/ln-chart/src/chart-model.js +154 -154
- package/components/ln-circular-progress/ln-circular-progress.js +1 -1
- package/components/ln-circular-progress/ln-circular-progress.schema.json +42 -42
- package/components/ln-confirm/ln-confirm-dev.scss +24 -24
- package/components/ln-confirm/ln-confirm.js +1 -1
- package/components/ln-confirm/ln-confirm.schema.json +66 -66
- package/components/ln-confirm/src/ln-confirm.js +178 -178
- package/components/ln-core/crypto.js +286 -265
- package/components/ln-core/dom.js +115 -115
- package/components/ln-core/form.js +136 -136
- package/components/ln-core/helpers.js +33 -33
- package/components/ln-core/http.js +48 -48
- package/components/ln-core/index.js +1 -1
- package/components/ln-core/ln-core.schema.json +109 -109
- package/components/ln-core/locale.js +55 -55
- package/components/ln-core/matching.js +78 -78
- package/components/ln-core/number.js +125 -125
- package/components/ln-core/template.js +206 -206
- package/components/ln-couchdb-connector/README.md +4 -0
- package/components/ln-couchdb-connector/ln-couchdb-connector.js +1 -1
- package/components/ln-couchdb-connector/ln-couchdb-connector.schema.json +50 -50
- package/components/ln-couchdb-connector/src/ln-couchdb-connector.js +19 -1
- package/components/ln-data-coordinator/README.md +9 -38
- package/components/ln-data-coordinator/ln-data-coordinator-dev.scss +8 -8
- package/components/ln-data-coordinator/ln-data-coordinator.js +1 -1
- package/components/ln-data-coordinator/ln-data-coordinator.schema.json +16 -16
- package/components/ln-data-coordinator/src/data-read-policy.js +0 -7
- package/components/ln-data-coordinator/src/ln-data-coordinator.js +428 -1299
- package/components/ln-data-store/README.md +3 -2
- package/components/ln-data-store/ln-data-store-dev.scss +13 -13
- package/components/ln-data-store/ln-data-store.js +1 -1
- package/components/ln-data-store/ln-data-store.schema.json +84 -84
- package/components/ln-data-store/src/data-store-model.js +184 -155
- package/components/ln-data-store/src/ln-data-store.js +58 -11
- package/components/ln-date/README.md +4 -0
- package/components/ln-date/ln-date.js +1 -1
- package/components/ln-date/ln-date.schema.json +92 -92
- package/components/ln-date/src/date-model.js +186 -186
- package/components/ln-date/src/ln-date.js +3 -3
- package/components/ln-debug/ln-debug.js +1 -1
- package/components/ln-debug/ln-debug.schema.json +28 -28
- package/components/ln-debug/src/console-sink.js +19 -19
- package/components/ln-debug/src/gate.js +95 -95
- package/components/ln-debug/src/generated-attributes.js +2 -2
- package/components/ln-dropdown/ln-dropdown-dev.scss +13 -13
- package/components/ln-dropdown/ln-dropdown.js +1 -1
- package/components/ln-dropdown/ln-dropdown.schema.json +90 -90
- package/components/ln-editor/ln-editor.js +1 -1
- package/components/ln-editor/ln-editor.schema.json +58 -58
- package/components/ln-external-links/ln-external-links.js +1 -1
- package/components/ln-external-links/ln-external-links.schema.json +18 -18
- package/components/ln-fill/ln-fill.js +1 -1
- package/components/ln-fill/ln-fill.schema.json +23 -23
- package/components/ln-filter/ln-filter.js +1 -1
- package/components/ln-filter/ln-filter.schema.json +153 -153
- package/components/ln-filter/src/filter-model.js +185 -185
- package/components/ln-form/ln-form-dev.scss +8 -8
- package/components/ln-form/ln-form.js +1 -1
- package/components/ln-form/ln-form.schema.json +45 -45
- package/components/ln-http/ln-http.js +1 -1
- package/components/ln-http/ln-http.schema.json +6 -6
- package/components/ln-icon/ln-icon.schema.json +6 -6
- package/components/ln-include/ln-include.js +1 -1
- package/components/ln-include/ln-include.schema.json +23 -23
- package/components/ln-key/ln-key-dev.scss +18 -18
- package/components/ln-key/ln-key.js +1 -1
- package/components/ln-key/ln-key.schema.json +56 -56
- package/components/ln-key/src/ln-key.js +10 -10
- package/components/ln-link/ln-link-dev.scss +8 -8
- package/components/ln-link/ln-link.js +1 -1
- package/components/ln-link/ln-link.schema.json +22 -22
- package/components/ln-list/README.md +152 -152
- package/components/ln-list/ln-list-dev.scss +8 -8
- package/components/ln-list/ln-list.js +1 -1
- package/components/ln-list/ln-list.schema.json +166 -166
- package/components/ln-list/src/ln-list.js +4 -4
- package/components/ln-modal/README.md +4 -6
- package/components/ln-modal/ln-modal.js +1 -1
- package/components/ln-modal/ln-modal.schema.json +65 -65
- package/components/ln-modal/src/ln-modal.js +28 -8
- package/components/ln-nav/ln-nav.js +1 -1
- package/components/ln-nav/ln-nav.schema.json +25 -25
- package/components/ln-number/ln-number.js +1 -1
- package/components/ln-number/ln-number.schema.json +63 -63
- package/components/ln-number/src/number-model.js +31 -31
- package/components/ln-obfuscator/README.md +60 -60
- package/components/ln-obfuscator/ln-obfuscator.js +1 -1
- package/components/ln-obfuscator/ln-obfuscator.schema.json +49 -49
- package/components/ln-obfuscator/src/ln-obfuscator.js +159 -159
- package/components/ln-obfuscator/src/obfuscator-model.js +250 -250
- package/components/ln-options/ln-options.js +1 -1
- package/components/ln-options/ln-options.schema.json +41 -41
- package/components/ln-options/src/ln-options.js +1 -0
- package/components/ln-persist/README.md +151 -151
- package/components/ln-persist/ln-persist.js +1 -1
- package/components/ln-persist/ln-persist.schema.json +28 -28
- package/components/ln-persist/src/ln-persist.js +83 -83
- package/components/ln-picklist/README.md +230 -230
- package/components/ln-picklist/ln-picklist-dev.scss +22 -22
- package/components/ln-picklist/ln-picklist.js +1 -1
- package/components/ln-picklist/ln-picklist.schema.json +49 -49
- package/components/ln-picklist/src/ln-picklist.js +228 -228
- package/components/ln-popover/README.md +4 -0
- package/components/ln-popover/ln-popover-dev.scss +13 -13
- package/components/ln-popover/ln-popover.js +1 -1
- package/components/ln-popover/ln-popover.schema.json +82 -82
- package/components/ln-popover/src/ln-popover.js +9 -0
- package/components/ln-progress/ln-progress-dev.scss +8 -8
- package/components/ln-progress/ln-progress.js +1 -1
- package/components/ln-progress/ln-progress.schema.json +40 -40
- package/components/ln-router/ln-router.js +1 -1
- package/components/ln-router/ln-router.schema.json +76 -76
- package/components/ln-scroll/README.md +45 -45
- package/components/ln-scroll/ln-scroll.js +1 -1
- package/components/ln-scroll/ln-scroll.schema.json +85 -85
- package/components/ln-scroll/src/ln-scroll.js +150 -150
- package/components/ln-search/README.md +188 -188
- package/components/ln-search/ln-search.js +1 -1
- package/components/ln-search/ln-search.schema.json +103 -103
- package/components/ln-slug/ln-slug.js +1 -1
- package/components/ln-slug/ln-slug.schema.json +23 -23
- package/components/ln-sort/ln-sort.js +1 -1
- package/components/ln-sort/ln-sort.schema.json +104 -104
- package/components/ln-sort/src/ln-sort.js +321 -321
- package/components/ln-sort/src/sort-model.js +117 -117
- package/components/ln-sortable/ln-sortable-dev.scss +13 -13
- package/components/ln-sortable/ln-sortable.js +1 -1
- package/components/ln-sortable/ln-sortable.schema.json +36 -36
- package/components/ln-stat/ln-stat-dev.scss +8 -8
- package/components/ln-stat/ln-stat.js +1 -1
- package/components/ln-stat/ln-stat.schema.json +32 -32
- package/components/ln-stat/src/stat-model.js +28 -28
- package/components/ln-table/ln-table.js +1 -1
- package/components/ln-table/ln-table.schema.json +211 -211
- package/components/ln-table/src/ln-table.js +2 -0
- package/components/ln-table/src/table-model.js +98 -98
- package/components/ln-table-coordinator/ln-table-coordinator.js +1 -1
- package/components/ln-table-coordinator/ln-table-coordinator.schema.json +93 -93
- package/components/ln-table-coordinator/src/ln-table-coordinator.js +3 -3
- package/components/ln-tabs/README.md +2 -2
- package/components/ln-tabs/ln-tabs.js +1 -1
- package/components/ln-tabs/ln-tabs.schema.json +75 -75
- package/components/ln-tabs/src/ln-tabs.js +208 -207
- package/components/ln-tabs/src/tabs-model.js +82 -82
- package/components/ln-time/ln-time-dev.scss +13 -13
- package/components/ln-time/ln-time.js +1 -1
- package/components/ln-time/ln-time.schema.json +38 -38
- package/components/ln-toast/ln-toast.js +1 -1
- package/components/ln-toast/ln-toast.schema.json +65 -65
- package/components/ln-toggle/ln-toggle.js +1 -1
- package/components/ln-toggle/ln-toggle.schema.json +52 -52
- package/components/ln-tooltip/ln-tooltip.js +1 -1
- package/components/ln-tooltip/ln-tooltip.schema.json +86 -86
- package/components/ln-translations/ln-translations.js +1 -1
- package/components/ln-translations/ln-translations.schema.json +120 -120
- package/components/ln-ui-coordinator/README.md +62 -62
- package/components/ln-ui-coordinator/ln-ui-coordinator.js +1 -1
- package/components/ln-ui-coordinator/ln-ui-coordinator.schema.json +28 -28
- package/components/ln-ui-coordinator/src/ln-ui-coordinator.js +140 -140
- package/components/ln-upload/ln-upload.js +1 -1
- package/components/ln-upload/ln-upload.schema.json +193 -193
- package/components/ln-upload/src/upload-model.js +78 -78
- package/components/ln-validate/ln-validate.js +1 -1
- package/components/ln-validate/ln-validate.schema.json +50 -50
- package/components/ln-validate/src/validate-model.js +64 -64
- package/components/ln-websocket-connector/README.md +166 -166
- package/components/ln-websocket-connector/ln-websocket-connector.js +1 -1
- package/components/ln-websocket-connector/ln-websocket-connector.schema.json +29 -29
- package/components/ln-websocket-connector/src/ln-websocket-connector.js +283 -279
- package/ln-ashlar.html-data.json +7 -8
- package/package.json +84 -84
- package/theme/brand.css +73 -73
- package/theme/components/_confirm.scss +6 -6
- package/theme/components/_picklist.scss +3 -3
- package/theme/config/_palette.scss +274 -274
- package/theme/config/_theme.scss +292 -292
- package/theme/config/_tokens.scss +285 -285
- package/theme/config/mixins/_index.scss +62 -62
- package/theme/config/mixins/_picklist.scss +66 -66
- package/theme/ln-ashlar-dev.scss +66 -66
- package/theme/ln-ashlar-landing.scss +56 -56
- package/theme/ln-ashlar-theme.scss +63 -63
- package/theme/presentation/_bento.scss +151 -151
- package/theme/presentation/_cta.scss +111 -111
- package/theme/presentation/_effects.scss +216 -216
- package/theme/presentation/_features.scss +108 -108
- package/theme/presentation/_footer.scss +129 -129
- package/theme/presentation/_hero.scss +158 -158
- package/theme/presentation/_layout.scss +170 -170
- package/theme/presentation/_navbar.scss +140 -140
- package/theme/presentation/_pricing.scss +262 -262
- package/theme/presentation/_stats.scss +87 -87
- package/theme/presentation/_testimonials.scss +124 -124
- package/theme/presentation/_tokens.scss +39 -39
- package/theme/presentation/_typography.scss +163 -163
- package/web-types.json +12 -12
package/theme/config/_theme.scss
CHANGED
|
@@ -1,293 +1,293 @@
|
|
|
1
|
-
@use 'palette' as *;
|
|
2
|
-
|
|
3
|
-
// ==========================================================================
|
|
4
|
-
// Theme — ln-ashlar
|
|
5
|
-
// ==========================================================================
|
|
6
|
-
// Three orthogonal activation axes:
|
|
7
|
-
// data-skin — structure/physics (radius, shadow, button chrome, nav/menu
|
|
8
|
-
// rebinds). Polarity-agnostic.
|
|
9
|
-
// data-mode — polarity only (bg/fg base values + native color-scheme).
|
|
10
|
-
// data-theme — brand palette only (color values).
|
|
11
|
-
//
|
|
12
|
-
// Activation paths:
|
|
13
|
-
// <html data-mode="dark"> ← explicit dark polarity
|
|
14
|
-
// <element data-mode="dark"> ← scoped dark polarity island
|
|
15
|
-
// @media (prefers-color-scheme: dark) ← system preference (auto)
|
|
16
|
-
// :root:not([data-mode="light"]) ← opt-out of auto
|
|
17
|
-
// <html data-skin="glass"> ← structural preset (flat, borderless)
|
|
18
|
-
// <html data-theme="ocean"> ← brand palette preset
|
|
19
|
-
//
|
|
20
|
-
// See docs-mcp/css/theming.md for the full guide.
|
|
21
|
-
// ==========================================================================
|
|
22
|
-
|
|
23
|
-
// ---------------------------------------------------------------------------
|
|
24
|
-
// Activation — ashlar values at zero specificity, derivations at every scope
|
|
25
|
-
// ---------------------------------------------------------------------------
|
|
26
|
-
|
|
27
|
-
// Ashlar values — zero specificity, a client file always outranks them
|
|
28
|
-
:where(:root),
|
|
29
|
-
:where([data-mode="light"]) {
|
|
30
|
-
@include ln-values-light;
|
|
31
|
-
color-scheme: light;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
:where([data-mode="dark"]) {
|
|
35
|
-
@include ln-values-dark;
|
|
36
|
-
color-scheme: dark;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
@media (prefers-color-scheme: dark) {
|
|
40
|
-
:where(:root:not([data-mode="light"])) {
|
|
41
|
-
@include ln-values-dark;
|
|
42
|
-
color-scheme: dark;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Derivations — library-owned, normal specificity, every colour-bearing scope.
|
|
47
|
-
// data-skin is deliberately absent: it declares no colour values, so the chain
|
|
48
|
-
// there could only reproduce the inherited result — while clobbering the
|
|
49
|
-
// preset --btn-* / tint overrides of any ancestor theme.
|
|
50
|
-
:root,
|
|
51
|
-
[data-theme],
|
|
52
|
-
[data-mode] {
|
|
53
|
-
@include ln-color-chain;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
:where([data-mode]) {
|
|
57
|
-
color: var(--color-fg);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
:where([data-mode]:not(html):not(body)) {
|
|
61
|
-
background-color: var(--color-bg);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// ---------------------------------------------------------------------------
|
|
65
|
-
// Named presets — demo theme picker. Brand palette only. Activation:
|
|
66
|
-
// <html data-theme="ocean"> <html data-theme="sunset"> etc.
|
|
67
|
-
// ---------------------------------------------------------------------------
|
|
68
|
-
|
|
69
|
-
// Lightness is solved, not authored: each fill sits at the AAA (7:1) limit
|
|
70
|
-
// for its hue against whichever foreground pole is nearer. Dark lifts cross
|
|
71
|
-
// the white/ink boundary, so they pair themselves — see --color-ink.
|
|
72
|
-
[data-theme="ocean"] {
|
|
73
|
-
--brand-primary: 190 80% 24%; // 7.40 on white
|
|
74
|
-
|
|
75
|
-
&[data-mode="dark"],
|
|
76
|
-
:where([data-mode="dark"]) & {
|
|
77
|
-
--brand-primary: 190 80% 46%; // 7.24 on ink
|
|
78
|
-
--color-accent-fg: hsl(var(--color-ink));
|
|
79
|
-
--check-mark: var(--check-mark-on-dark);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
[data-theme="sunset"] {
|
|
84
|
-
--brand-primary: 10 80% 36%; // 7.10 on white
|
|
85
|
-
|
|
86
|
-
&[data-mode="dark"],
|
|
87
|
-
:where([data-mode="dark"]) & {
|
|
88
|
-
--brand-primary: 10 80% 69%; // 7.09 on ink
|
|
89
|
-
--color-accent-fg: hsl(var(--color-ink));
|
|
90
|
-
--check-mark: var(--check-mark-on-dark);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
[data-theme="midnight"] {
|
|
95
|
-
// Pure palette — no polarity opinion, but both lightnesses are now solved,
|
|
96
|
-
// so the unpaired light case reads at AAA instead of being "accepted".
|
|
97
|
-
--brand-primary: 265 70% 50%; // 7.05 on white
|
|
98
|
-
|
|
99
|
-
&[data-mode="dark"],
|
|
100
|
-
:where([data-mode="dark"]) & {
|
|
101
|
-
--brand-primary: 265 70% 75%; // 7.15 on ink
|
|
102
|
-
--color-accent-fg: hsl(var(--color-ink));
|
|
103
|
-
--check-mark: var(--check-mark-on-dark);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
[data-theme="glass"] {
|
|
108
|
-
// Electric blue accent — luminescent on dark navy glass
|
|
109
|
-
// No &[data-mode="dark"] lift block (unlike ocean/sunset/midnight): glass
|
|
110
|
-
// was authored dark-first, so it solves straight to the ink pole in both
|
|
111
|
-
// polarities — a lift here would blow out on dark.
|
|
112
|
-
--brand-primary: 218 95% 71%; // 7.04 on ink
|
|
113
|
-
--check-mark: var(--check-mark-on-dark);
|
|
114
|
-
--color-accent-fg: hsl(var(--color-ink));
|
|
115
|
-
|
|
116
|
-
// Active-nav wash — Glass computes a stronger 24% tint mix against
|
|
117
|
-
// local --bg-base for contrast on the deep dark surface.
|
|
118
|
-
// Side-effect: dropdown active items + upload drop-zone also pick up the
|
|
119
|
-
// slightly darker tint — improvement, not regression.
|
|
120
|
-
--color-accent-tint: color-mix(in srgb, hsl(var(--color-primary)) 24%, var(--bg-base));
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
[data-theme="aurora"] {
|
|
124
|
-
--brand-primary: 158 80% 30%;
|
|
125
|
-
|
|
126
|
-
&[data-mode="dark"],
|
|
127
|
-
:where([data-mode="dark"]) & {
|
|
128
|
-
--brand-primary: 158 80% 55%;
|
|
129
|
-
--color-accent-fg: hsl(var(--color-ink));
|
|
130
|
-
--check-mark: var(--check-mark-on-dark);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
[data-theme="violet"] {
|
|
135
|
-
--brand-primary: 255 75% 48%;
|
|
136
|
-
|
|
137
|
-
&[data-mode="dark"],
|
|
138
|
-
:where([data-mode="dark"]) & {
|
|
139
|
-
--brand-primary: 255 85% 72%;
|
|
140
|
-
--color-accent-fg: hsl(var(--color-ink));
|
|
141
|
-
--check-mark: var(--check-mark-on-dark);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
[data-theme="cyber"] {
|
|
146
|
-
--brand-primary: 198 95% 38%;
|
|
147
|
-
|
|
148
|
-
&[data-mode="dark"],
|
|
149
|
-
:where([data-mode="dark"]) & {
|
|
150
|
-
--brand-primary: 198 95% 58%;
|
|
151
|
-
--color-accent-fg: hsl(var(--color-ink));
|
|
152
|
-
--check-mark: var(--check-mark-on-dark);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// ---------------------------------------------------------------------------
|
|
157
|
-
// Named skins — structural/physics presets. Polarity-agnostic. Activation:
|
|
158
|
-
// <html data-skin="glass">
|
|
159
|
-
// ---------------------------------------------------------------------------
|
|
160
|
-
|
|
161
|
-
[data-skin="glass"] {
|
|
162
|
-
// Flat — zero radius everywhere
|
|
163
|
-
--radius-xs: 0;
|
|
164
|
-
--radius-sm: 0;
|
|
165
|
-
--radius-md: 0;
|
|
166
|
-
--radius-lg: 0;
|
|
167
|
-
--radius-xl: 0;
|
|
168
|
-
--radius-2xl: 0;
|
|
169
|
-
--radius-full: 0;
|
|
170
|
-
|
|
171
|
-
// Flat — no elevation shadows. --shadow-inner kept for recessed
|
|
172
|
-
// surfaces (code blocks, progress tracks) which read it as a depth
|
|
173
|
-
// affordance rather than elevation.
|
|
174
|
-
--shadow-xs: none;
|
|
175
|
-
--shadow-sm: none;
|
|
176
|
-
--shadow-md: none;
|
|
177
|
-
--shadow-lg: none;
|
|
178
|
-
--shadow-xl: none;
|
|
179
|
-
--shadow-2xl: none;
|
|
180
|
-
|
|
181
|
-
// ── Buttons — neutral chrome via --btn-* rebind, accent variant via
|
|
182
|
-
// cross-cutting --color-accent-bg-* companion tokens. Skin rebinds
|
|
183
|
-
// at :root only; library owns structure. (See docs/architecture/reference.md ## Theme Architecture for exact mechanics)
|
|
184
|
-
--btn-bg: var(--bg-elevated);
|
|
185
|
-
--btn-bg-hover: var(--bg-hover);
|
|
186
|
-
--btn-border: var(--color-accent);
|
|
187
|
-
// --color-accent-hover is declared only below <html> (a, mixin bodies);
|
|
188
|
-
// invalid at computed-value time here — derive locally. l - 6 matches
|
|
189
|
-
// @mixin btn's own accent-hover so neutral and accent buttons agree.
|
|
190
|
-
--btn-border-hover: hsl(from var(--color-accent) h s calc(l - 6));
|
|
191
|
-
|
|
192
|
-
// ── Accent buttons — translucent fill via consumer-scope rebind
|
|
193
|
-
// Rebind --btn-* on the button itself (not at skin :root) so
|
|
194
|
-
// var(--color-primary) inside the values resolves on the button's
|
|
195
|
-
// cascade — letting .success / .error / .warning / .info status
|
|
196
|
-
// overrides reach the fill and text color. Token-only rebinds; no
|
|
197
|
-
// background/color/border-color declarations, no &:hover blocks
|
|
198
|
-
// (button-base already handles state via --btn-*-hover).
|
|
199
|
-
button[type="submit"],
|
|
200
|
-
.btn {
|
|
201
|
-
--btn-bg: hsl(var(--color-primary) / 0.2);
|
|
202
|
-
--btn-fg: hsl(var(--color-primary));
|
|
203
|
-
--btn-bg-hover: hsl(var(--color-primary) / 0.3);
|
|
204
|
-
--btn-fg-hover: hsl(var(--color-primary));
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// ── Nav surface — palette-only rebind ──────────────────────────
|
|
208
|
-
// @mixin nav reads --nav-link-border-color* via fallback (defaults:
|
|
209
|
-
// transparent). Glass rebinds them so hover/active draw an accent
|
|
210
|
-
// ring. --nav-list-bleed shifts the ul to the sidebar's vertical
|
|
211
|
-
// borders so dividers reach edge-to-edge; @mixin nav reads it with
|
|
212
|
-
// `0` fallback so default theme is unaffected.
|
|
213
|
-
--nav-link-border-color-hover: var(--color-accent);
|
|
214
|
-
--nav-link-border-color-active: var(--color-accent);
|
|
215
|
-
// Resolves against the ROOT --padding-x, not a sidebar-local one — valid
|
|
216
|
-
// today because nothing between :root and the nav rebinds it, but latent.
|
|
217
|
-
--nav-list-bleed: calc(-1 * var(--padding-x));
|
|
218
|
-
|
|
219
|
-
// ── Dropdown / menu-items dividers ─────────────────────────────
|
|
220
|
-
// @mixin menu-items reads SOFT --border-block-start on `li + li`
|
|
221
|
-
// and `hr` with `none` fallback. Glass rebinds the slot in scope
|
|
222
|
-
// so the divider appears for both. Scoped (not skin :root)
|
|
223
|
-
// because --border-block-start is read by ~10 other mixins
|
|
224
|
-
// (cards, tables, accordions) where the divider should NOT appear.
|
|
225
|
-
[data-ln-dropdown-menu],
|
|
226
|
-
.menu-items {
|
|
227
|
-
--border-block-start: var(--border-width) solid var(--color-border);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
[data-skin="outline"] {
|
|
232
|
-
// Outline — no elevation shadows, structural borders only.
|
|
233
|
-
--shadow-xs: none;
|
|
234
|
-
--shadow-sm: none;
|
|
235
|
-
--shadow-md: none;
|
|
236
|
-
--shadow-lg: none;
|
|
237
|
-
--shadow-xl: none;
|
|
238
|
-
--shadow-2xl: none;
|
|
239
|
-
|
|
240
|
-
// Retain the inner shadow for recessed tracks.
|
|
241
|
-
--shadow-resting: none;
|
|
242
|
-
--shadow-floating: none;
|
|
243
|
-
|
|
244
|
-
// Make the borders stand out more since there are no shadows
|
|
245
|
-
// Resolves once at <html> against whichever polarity is active there —
|
|
246
|
-
// a nested [data-mode] island under this skin inherits root neutral-300.
|
|
247
|
-
--border-subtle: hsl(var(--color-neutral-300));
|
|
248
|
-
|
|
249
|
-
// ── Buttons — neutral chrome
|
|
250
|
-
--btn-bg: transparent;
|
|
251
|
-
--btn-bg-hover: var(--bg-hover);
|
|
252
|
-
// Give buttons a visible border instead of filling them
|
|
253
|
-
--btn-border: var(--border-strong);
|
|
254
|
-
|
|
255
|
-
// ── Accent buttons — transparent fill, colored border
|
|
256
|
-
button[type="submit"],
|
|
257
|
-
.btn {
|
|
258
|
-
--btn-bg: transparent;
|
|
259
|
-
--btn-fg: hsl(var(--color-primary));
|
|
260
|
-
--btn-border: hsl(var(--color-primary));
|
|
261
|
-
--btn-bg-hover: hsl(var(--color-primary) / 0.1);
|
|
262
|
-
--btn-fg-hover: hsl(var(--color-primary));
|
|
263
|
-
--btn-border-hover: hsl(var(--color-primary));
|
|
264
|
-
}
|
|
265
|
-
}
|
|
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);
|
|
1
|
+
@use 'palette' as *;
|
|
2
|
+
|
|
3
|
+
// ==========================================================================
|
|
4
|
+
// Theme — ln-ashlar
|
|
5
|
+
// ==========================================================================
|
|
6
|
+
// Three orthogonal activation axes:
|
|
7
|
+
// data-skin — structure/physics (radius, shadow, button chrome, nav/menu
|
|
8
|
+
// rebinds). Polarity-agnostic.
|
|
9
|
+
// data-mode — polarity only (bg/fg base values + native color-scheme).
|
|
10
|
+
// data-theme — brand palette only (color values).
|
|
11
|
+
//
|
|
12
|
+
// Activation paths:
|
|
13
|
+
// <html data-mode="dark"> ← explicit dark polarity
|
|
14
|
+
// <element data-mode="dark"> ← scoped dark polarity island
|
|
15
|
+
// @media (prefers-color-scheme: dark) ← system preference (auto)
|
|
16
|
+
// :root:not([data-mode="light"]) ← opt-out of auto
|
|
17
|
+
// <html data-skin="glass"> ← structural preset (flat, borderless)
|
|
18
|
+
// <html data-theme="ocean"> ← brand palette preset
|
|
19
|
+
//
|
|
20
|
+
// See docs-mcp/css/theming.md for the full guide.
|
|
21
|
+
// ==========================================================================
|
|
22
|
+
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// Activation — ashlar values at zero specificity, derivations at every scope
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
|
|
27
|
+
// Ashlar values — zero specificity, a client file always outranks them
|
|
28
|
+
:where(:root),
|
|
29
|
+
:where([data-mode="light"]) {
|
|
30
|
+
@include ln-values-light;
|
|
31
|
+
color-scheme: light;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
:where([data-mode="dark"]) {
|
|
35
|
+
@include ln-values-dark;
|
|
36
|
+
color-scheme: dark;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@media (prefers-color-scheme: dark) {
|
|
40
|
+
:where(:root:not([data-mode="light"])) {
|
|
41
|
+
@include ln-values-dark;
|
|
42
|
+
color-scheme: dark;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Derivations — library-owned, normal specificity, every colour-bearing scope.
|
|
47
|
+
// data-skin is deliberately absent: it declares no colour values, so the chain
|
|
48
|
+
// there could only reproduce the inherited result — while clobbering the
|
|
49
|
+
// preset --btn-* / tint overrides of any ancestor theme.
|
|
50
|
+
:root,
|
|
51
|
+
[data-theme],
|
|
52
|
+
[data-mode] {
|
|
53
|
+
@include ln-color-chain;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
:where([data-mode]) {
|
|
57
|
+
color: var(--color-fg);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
:where([data-mode]:not(html):not(body)) {
|
|
61
|
+
background-color: var(--color-bg);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
// Named presets — demo theme picker. Brand palette only. Activation:
|
|
66
|
+
// <html data-theme="ocean"> <html data-theme="sunset"> etc.
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
|
|
69
|
+
// Lightness is solved, not authored: each fill sits at the AAA (7:1) limit
|
|
70
|
+
// for its hue against whichever foreground pole is nearer. Dark lifts cross
|
|
71
|
+
// the white/ink boundary, so they pair themselves — see --color-ink.
|
|
72
|
+
[data-theme="ocean"] {
|
|
73
|
+
--brand-primary: 190 80% 24%; // 7.40 on white
|
|
74
|
+
|
|
75
|
+
&[data-mode="dark"],
|
|
76
|
+
:where([data-mode="dark"]) & {
|
|
77
|
+
--brand-primary: 190 80% 46%; // 7.24 on ink
|
|
78
|
+
--color-accent-fg: hsl(var(--color-ink));
|
|
79
|
+
--check-mark: var(--check-mark-on-dark);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
[data-theme="sunset"] {
|
|
84
|
+
--brand-primary: 10 80% 36%; // 7.10 on white
|
|
85
|
+
|
|
86
|
+
&[data-mode="dark"],
|
|
87
|
+
:where([data-mode="dark"]) & {
|
|
88
|
+
--brand-primary: 10 80% 69%; // 7.09 on ink
|
|
89
|
+
--color-accent-fg: hsl(var(--color-ink));
|
|
90
|
+
--check-mark: var(--check-mark-on-dark);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
[data-theme="midnight"] {
|
|
95
|
+
// Pure palette — no polarity opinion, but both lightnesses are now solved,
|
|
96
|
+
// so the unpaired light case reads at AAA instead of being "accepted".
|
|
97
|
+
--brand-primary: 265 70% 50%; // 7.05 on white
|
|
98
|
+
|
|
99
|
+
&[data-mode="dark"],
|
|
100
|
+
:where([data-mode="dark"]) & {
|
|
101
|
+
--brand-primary: 265 70% 75%; // 7.15 on ink
|
|
102
|
+
--color-accent-fg: hsl(var(--color-ink));
|
|
103
|
+
--check-mark: var(--check-mark-on-dark);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
[data-theme="glass"] {
|
|
108
|
+
// Electric blue accent — luminescent on dark navy glass
|
|
109
|
+
// No &[data-mode="dark"] lift block (unlike ocean/sunset/midnight): glass
|
|
110
|
+
// was authored dark-first, so it solves straight to the ink pole in both
|
|
111
|
+
// polarities — a lift here would blow out on dark.
|
|
112
|
+
--brand-primary: 218 95% 71%; // 7.04 on ink
|
|
113
|
+
--check-mark: var(--check-mark-on-dark);
|
|
114
|
+
--color-accent-fg: hsl(var(--color-ink));
|
|
115
|
+
|
|
116
|
+
// Active-nav wash — Glass computes a stronger 24% tint mix against
|
|
117
|
+
// local --bg-base for contrast on the deep dark surface.
|
|
118
|
+
// Side-effect: dropdown active items + upload drop-zone also pick up the
|
|
119
|
+
// slightly darker tint — improvement, not regression.
|
|
120
|
+
--color-accent-tint: color-mix(in srgb, hsl(var(--color-primary)) 24%, var(--bg-base));
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
[data-theme="aurora"] {
|
|
124
|
+
--brand-primary: 158 80% 30%;
|
|
125
|
+
|
|
126
|
+
&[data-mode="dark"],
|
|
127
|
+
:where([data-mode="dark"]) & {
|
|
128
|
+
--brand-primary: 158 80% 55%;
|
|
129
|
+
--color-accent-fg: hsl(var(--color-ink));
|
|
130
|
+
--check-mark: var(--check-mark-on-dark);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
[data-theme="violet"] {
|
|
135
|
+
--brand-primary: 255 75% 48%;
|
|
136
|
+
|
|
137
|
+
&[data-mode="dark"],
|
|
138
|
+
:where([data-mode="dark"]) & {
|
|
139
|
+
--brand-primary: 255 85% 72%;
|
|
140
|
+
--color-accent-fg: hsl(var(--color-ink));
|
|
141
|
+
--check-mark: var(--check-mark-on-dark);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
[data-theme="cyber"] {
|
|
146
|
+
--brand-primary: 198 95% 38%;
|
|
147
|
+
|
|
148
|
+
&[data-mode="dark"],
|
|
149
|
+
:where([data-mode="dark"]) & {
|
|
150
|
+
--brand-primary: 198 95% 58%;
|
|
151
|
+
--color-accent-fg: hsl(var(--color-ink));
|
|
152
|
+
--check-mark: var(--check-mark-on-dark);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// ---------------------------------------------------------------------------
|
|
157
|
+
// Named skins — structural/physics presets. Polarity-agnostic. Activation:
|
|
158
|
+
// <html data-skin="glass">
|
|
159
|
+
// ---------------------------------------------------------------------------
|
|
160
|
+
|
|
161
|
+
[data-skin="glass"] {
|
|
162
|
+
// Flat — zero radius everywhere
|
|
163
|
+
--radius-xs: 0;
|
|
164
|
+
--radius-sm: 0;
|
|
165
|
+
--radius-md: 0;
|
|
166
|
+
--radius-lg: 0;
|
|
167
|
+
--radius-xl: 0;
|
|
168
|
+
--radius-2xl: 0;
|
|
169
|
+
--radius-full: 0;
|
|
170
|
+
|
|
171
|
+
// Flat — no elevation shadows. --shadow-inner kept for recessed
|
|
172
|
+
// surfaces (code blocks, progress tracks) which read it as a depth
|
|
173
|
+
// affordance rather than elevation.
|
|
174
|
+
--shadow-xs: none;
|
|
175
|
+
--shadow-sm: none;
|
|
176
|
+
--shadow-md: none;
|
|
177
|
+
--shadow-lg: none;
|
|
178
|
+
--shadow-xl: none;
|
|
179
|
+
--shadow-2xl: none;
|
|
180
|
+
|
|
181
|
+
// ── Buttons — neutral chrome via --btn-* rebind, accent variant via
|
|
182
|
+
// cross-cutting --color-accent-bg-* companion tokens. Skin rebinds
|
|
183
|
+
// at :root only; library owns structure. (See docs/architecture/reference.md ## Theme Architecture for exact mechanics)
|
|
184
|
+
--btn-bg: var(--bg-elevated);
|
|
185
|
+
--btn-bg-hover: var(--bg-hover);
|
|
186
|
+
--btn-border: var(--color-accent);
|
|
187
|
+
// --color-accent-hover is declared only below <html> (a, mixin bodies);
|
|
188
|
+
// invalid at computed-value time here — derive locally. l - 6 matches
|
|
189
|
+
// @mixin btn's own accent-hover so neutral and accent buttons agree.
|
|
190
|
+
--btn-border-hover: hsl(from var(--color-accent) h s calc(l - 6));
|
|
191
|
+
|
|
192
|
+
// ── Accent buttons — translucent fill via consumer-scope rebind
|
|
193
|
+
// Rebind --btn-* on the button itself (not at skin :root) so
|
|
194
|
+
// var(--color-primary) inside the values resolves on the button's
|
|
195
|
+
// cascade — letting .success / .error / .warning / .info status
|
|
196
|
+
// overrides reach the fill and text color. Token-only rebinds; no
|
|
197
|
+
// background/color/border-color declarations, no &:hover blocks
|
|
198
|
+
// (button-base already handles state via --btn-*-hover).
|
|
199
|
+
button[type="submit"],
|
|
200
|
+
.btn {
|
|
201
|
+
--btn-bg: hsl(var(--color-primary) / 0.2);
|
|
202
|
+
--btn-fg: hsl(var(--color-primary));
|
|
203
|
+
--btn-bg-hover: hsl(var(--color-primary) / 0.3);
|
|
204
|
+
--btn-fg-hover: hsl(var(--color-primary));
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// ── Nav surface — palette-only rebind ──────────────────────────
|
|
208
|
+
// @mixin nav reads --nav-link-border-color* via fallback (defaults:
|
|
209
|
+
// transparent). Glass rebinds them so hover/active draw an accent
|
|
210
|
+
// ring. --nav-list-bleed shifts the ul to the sidebar's vertical
|
|
211
|
+
// borders so dividers reach edge-to-edge; @mixin nav reads it with
|
|
212
|
+
// `0` fallback so default theme is unaffected.
|
|
213
|
+
--nav-link-border-color-hover: var(--color-accent);
|
|
214
|
+
--nav-link-border-color-active: var(--color-accent);
|
|
215
|
+
// Resolves against the ROOT --padding-x, not a sidebar-local one — valid
|
|
216
|
+
// today because nothing between :root and the nav rebinds it, but latent.
|
|
217
|
+
--nav-list-bleed: calc(-1 * var(--padding-x));
|
|
218
|
+
|
|
219
|
+
// ── Dropdown / menu-items dividers ─────────────────────────────
|
|
220
|
+
// @mixin menu-items reads SOFT --border-block-start on `li + li`
|
|
221
|
+
// and `hr` with `none` fallback. Glass rebinds the slot in scope
|
|
222
|
+
// so the divider appears for both. Scoped (not skin :root)
|
|
223
|
+
// because --border-block-start is read by ~10 other mixins
|
|
224
|
+
// (cards, tables, accordions) where the divider should NOT appear.
|
|
225
|
+
[data-ln-dropdown-menu],
|
|
226
|
+
.menu-items {
|
|
227
|
+
--border-block-start: var(--border-width) solid var(--color-border);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
[data-skin="outline"] {
|
|
232
|
+
// Outline — no elevation shadows, structural borders only.
|
|
233
|
+
--shadow-xs: none;
|
|
234
|
+
--shadow-sm: none;
|
|
235
|
+
--shadow-md: none;
|
|
236
|
+
--shadow-lg: none;
|
|
237
|
+
--shadow-xl: none;
|
|
238
|
+
--shadow-2xl: none;
|
|
239
|
+
|
|
240
|
+
// Retain the inner shadow for recessed tracks.
|
|
241
|
+
--shadow-resting: none;
|
|
242
|
+
--shadow-floating: none;
|
|
243
|
+
|
|
244
|
+
// Make the borders stand out more since there are no shadows
|
|
245
|
+
// Resolves once at <html> against whichever polarity is active there —
|
|
246
|
+
// a nested [data-mode] island under this skin inherits root neutral-300.
|
|
247
|
+
--border-subtle: hsl(var(--color-neutral-300));
|
|
248
|
+
|
|
249
|
+
// ── Buttons — neutral chrome
|
|
250
|
+
--btn-bg: transparent;
|
|
251
|
+
--btn-bg-hover: var(--bg-hover);
|
|
252
|
+
// Give buttons a visible border instead of filling them
|
|
253
|
+
--btn-border: var(--border-strong);
|
|
254
|
+
|
|
255
|
+
// ── Accent buttons — transparent fill, colored border
|
|
256
|
+
button[type="submit"],
|
|
257
|
+
.btn {
|
|
258
|
+
--btn-bg: transparent;
|
|
259
|
+
--btn-fg: hsl(var(--color-primary));
|
|
260
|
+
--btn-border: hsl(var(--color-primary));
|
|
261
|
+
--btn-bg-hover: hsl(var(--color-primary) / 0.1);
|
|
262
|
+
--btn-fg-hover: hsl(var(--color-primary));
|
|
263
|
+
--btn-border-hover: hsl(var(--color-primary));
|
|
264
|
+
}
|
|
265
|
+
}
|
|
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
293
|
}
|