@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.
Files changed (221) hide show
  1. package/LICENSE +641 -641
  2. package/components/COMPONENTS.md +1116 -1116
  3. package/components/index.js +81 -81
  4. package/components/ln-accordion/ln-accordion-dev.scss +8 -8
  5. package/components/ln-accordion/ln-accordion.js +1 -1
  6. package/components/ln-accordion/ln-accordion.schema.json +30 -30
  7. package/components/ln-accordion/src/ln-accordion.js +1 -0
  8. package/components/ln-ajax/ln-ajax-dev.scss +8 -8
  9. package/components/ln-ajax/ln-ajax.js +1 -1
  10. package/components/ln-ajax/ln-ajax.schema.json +30 -30
  11. package/components/ln-api-connector/ln-api-connector.js +1 -1
  12. package/components/ln-api-connector/ln-api-connector.schema.json +96 -96
  13. package/components/ln-api-connector/src/ln-api-connector.js +1 -0
  14. package/components/ln-api-queue/ln-api-queue.js +1 -1
  15. package/components/ln-api-queue/ln-api-queue.schema.json +34 -34
  16. package/components/ln-api-queue/src/ln-api-queue.js +3 -13
  17. package/components/ln-autoresize/ln-autoresize-dev.scss +8 -8
  18. package/components/ln-autoresize/ln-autoresize.js +1 -1
  19. package/components/ln-autoresize/ln-autoresize.schema.json +22 -22
  20. package/components/ln-autosave/ln-autosave-dev.scss +13 -13
  21. package/components/ln-autosave/ln-autosave.js +1 -1
  22. package/components/ln-autosave/ln-autosave.schema.json +48 -48
  23. package/components/ln-autosave/src/autosave-model.js +34 -34
  24. package/components/ln-chart/ln-chart.js +1 -1
  25. package/components/ln-chart/ln-chart.schema.json +146 -146
  26. package/components/ln-chart/src/chart-model.js +154 -154
  27. package/components/ln-circular-progress/ln-circular-progress.js +1 -1
  28. package/components/ln-circular-progress/ln-circular-progress.schema.json +42 -42
  29. package/components/ln-confirm/ln-confirm-dev.scss +24 -24
  30. package/components/ln-confirm/ln-confirm.js +1 -1
  31. package/components/ln-confirm/ln-confirm.schema.json +66 -66
  32. package/components/ln-confirm/src/ln-confirm.js +178 -178
  33. package/components/ln-core/crypto.js +286 -265
  34. package/components/ln-core/dom.js +115 -115
  35. package/components/ln-core/form.js +136 -136
  36. package/components/ln-core/helpers.js +33 -33
  37. package/components/ln-core/http.js +48 -48
  38. package/components/ln-core/index.js +1 -1
  39. package/components/ln-core/ln-core.schema.json +109 -109
  40. package/components/ln-core/locale.js +55 -55
  41. package/components/ln-core/matching.js +78 -78
  42. package/components/ln-core/number.js +125 -125
  43. package/components/ln-core/template.js +206 -206
  44. package/components/ln-couchdb-connector/README.md +4 -0
  45. package/components/ln-couchdb-connector/ln-couchdb-connector.js +1 -1
  46. package/components/ln-couchdb-connector/ln-couchdb-connector.schema.json +50 -50
  47. package/components/ln-couchdb-connector/src/ln-couchdb-connector.js +19 -1
  48. package/components/ln-data-coordinator/README.md +9 -38
  49. package/components/ln-data-coordinator/ln-data-coordinator-dev.scss +8 -8
  50. package/components/ln-data-coordinator/ln-data-coordinator.js +1 -1
  51. package/components/ln-data-coordinator/ln-data-coordinator.schema.json +16 -16
  52. package/components/ln-data-coordinator/src/data-read-policy.js +0 -7
  53. package/components/ln-data-coordinator/src/ln-data-coordinator.js +428 -1299
  54. package/components/ln-data-store/README.md +3 -2
  55. package/components/ln-data-store/ln-data-store-dev.scss +13 -13
  56. package/components/ln-data-store/ln-data-store.js +1 -1
  57. package/components/ln-data-store/ln-data-store.schema.json +84 -84
  58. package/components/ln-data-store/src/data-store-model.js +184 -155
  59. package/components/ln-data-store/src/ln-data-store.js +58 -11
  60. package/components/ln-date/README.md +4 -0
  61. package/components/ln-date/ln-date.js +1 -1
  62. package/components/ln-date/ln-date.schema.json +92 -92
  63. package/components/ln-date/src/date-model.js +186 -186
  64. package/components/ln-date/src/ln-date.js +3 -3
  65. package/components/ln-debug/ln-debug.js +1 -1
  66. package/components/ln-debug/ln-debug.schema.json +28 -28
  67. package/components/ln-debug/src/console-sink.js +19 -19
  68. package/components/ln-debug/src/gate.js +95 -95
  69. package/components/ln-debug/src/generated-attributes.js +2 -2
  70. package/components/ln-dropdown/ln-dropdown-dev.scss +13 -13
  71. package/components/ln-dropdown/ln-dropdown.js +1 -1
  72. package/components/ln-dropdown/ln-dropdown.schema.json +90 -90
  73. package/components/ln-editor/ln-editor.js +1 -1
  74. package/components/ln-editor/ln-editor.schema.json +58 -58
  75. package/components/ln-external-links/ln-external-links.js +1 -1
  76. package/components/ln-external-links/ln-external-links.schema.json +18 -18
  77. package/components/ln-fill/ln-fill.js +1 -1
  78. package/components/ln-fill/ln-fill.schema.json +23 -23
  79. package/components/ln-filter/ln-filter.js +1 -1
  80. package/components/ln-filter/ln-filter.schema.json +153 -153
  81. package/components/ln-filter/src/filter-model.js +185 -185
  82. package/components/ln-form/ln-form-dev.scss +8 -8
  83. package/components/ln-form/ln-form.js +1 -1
  84. package/components/ln-form/ln-form.schema.json +45 -45
  85. package/components/ln-http/ln-http.js +1 -1
  86. package/components/ln-http/ln-http.schema.json +6 -6
  87. package/components/ln-icon/ln-icon.schema.json +6 -6
  88. package/components/ln-include/ln-include.js +1 -1
  89. package/components/ln-include/ln-include.schema.json +23 -23
  90. package/components/ln-key/ln-key-dev.scss +18 -18
  91. package/components/ln-key/ln-key.js +1 -1
  92. package/components/ln-key/ln-key.schema.json +56 -56
  93. package/components/ln-key/src/ln-key.js +10 -10
  94. package/components/ln-link/ln-link-dev.scss +8 -8
  95. package/components/ln-link/ln-link.js +1 -1
  96. package/components/ln-link/ln-link.schema.json +22 -22
  97. package/components/ln-list/README.md +152 -152
  98. package/components/ln-list/ln-list-dev.scss +8 -8
  99. package/components/ln-list/ln-list.js +1 -1
  100. package/components/ln-list/ln-list.schema.json +166 -166
  101. package/components/ln-list/src/ln-list.js +4 -4
  102. package/components/ln-modal/README.md +4 -6
  103. package/components/ln-modal/ln-modal.js +1 -1
  104. package/components/ln-modal/ln-modal.schema.json +65 -65
  105. package/components/ln-modal/src/ln-modal.js +28 -8
  106. package/components/ln-nav/ln-nav.js +1 -1
  107. package/components/ln-nav/ln-nav.schema.json +25 -25
  108. package/components/ln-number/ln-number.js +1 -1
  109. package/components/ln-number/ln-number.schema.json +63 -63
  110. package/components/ln-number/src/number-model.js +31 -31
  111. package/components/ln-obfuscator/README.md +60 -60
  112. package/components/ln-obfuscator/ln-obfuscator.js +1 -1
  113. package/components/ln-obfuscator/ln-obfuscator.schema.json +49 -49
  114. package/components/ln-obfuscator/src/ln-obfuscator.js +159 -159
  115. package/components/ln-obfuscator/src/obfuscator-model.js +250 -250
  116. package/components/ln-options/ln-options.js +1 -1
  117. package/components/ln-options/ln-options.schema.json +41 -41
  118. package/components/ln-options/src/ln-options.js +1 -0
  119. package/components/ln-persist/README.md +151 -151
  120. package/components/ln-persist/ln-persist.js +1 -1
  121. package/components/ln-persist/ln-persist.schema.json +28 -28
  122. package/components/ln-persist/src/ln-persist.js +83 -83
  123. package/components/ln-picklist/README.md +230 -230
  124. package/components/ln-picklist/ln-picklist-dev.scss +22 -22
  125. package/components/ln-picklist/ln-picklist.js +1 -1
  126. package/components/ln-picklist/ln-picklist.schema.json +49 -49
  127. package/components/ln-picklist/src/ln-picklist.js +228 -228
  128. package/components/ln-popover/README.md +4 -0
  129. package/components/ln-popover/ln-popover-dev.scss +13 -13
  130. package/components/ln-popover/ln-popover.js +1 -1
  131. package/components/ln-popover/ln-popover.schema.json +82 -82
  132. package/components/ln-popover/src/ln-popover.js +9 -0
  133. package/components/ln-progress/ln-progress-dev.scss +8 -8
  134. package/components/ln-progress/ln-progress.js +1 -1
  135. package/components/ln-progress/ln-progress.schema.json +40 -40
  136. package/components/ln-router/ln-router.js +1 -1
  137. package/components/ln-router/ln-router.schema.json +76 -76
  138. package/components/ln-scroll/README.md +45 -45
  139. package/components/ln-scroll/ln-scroll.js +1 -1
  140. package/components/ln-scroll/ln-scroll.schema.json +85 -85
  141. package/components/ln-scroll/src/ln-scroll.js +150 -150
  142. package/components/ln-search/README.md +188 -188
  143. package/components/ln-search/ln-search.js +1 -1
  144. package/components/ln-search/ln-search.schema.json +103 -103
  145. package/components/ln-slug/ln-slug.js +1 -1
  146. package/components/ln-slug/ln-slug.schema.json +23 -23
  147. package/components/ln-sort/ln-sort.js +1 -1
  148. package/components/ln-sort/ln-sort.schema.json +104 -104
  149. package/components/ln-sort/src/ln-sort.js +321 -321
  150. package/components/ln-sort/src/sort-model.js +117 -117
  151. package/components/ln-sortable/ln-sortable-dev.scss +13 -13
  152. package/components/ln-sortable/ln-sortable.js +1 -1
  153. package/components/ln-sortable/ln-sortable.schema.json +36 -36
  154. package/components/ln-stat/ln-stat-dev.scss +8 -8
  155. package/components/ln-stat/ln-stat.js +1 -1
  156. package/components/ln-stat/ln-stat.schema.json +32 -32
  157. package/components/ln-stat/src/stat-model.js +28 -28
  158. package/components/ln-table/ln-table.js +1 -1
  159. package/components/ln-table/ln-table.schema.json +211 -211
  160. package/components/ln-table/src/ln-table.js +2 -0
  161. package/components/ln-table/src/table-model.js +98 -98
  162. package/components/ln-table-coordinator/ln-table-coordinator.js +1 -1
  163. package/components/ln-table-coordinator/ln-table-coordinator.schema.json +93 -93
  164. package/components/ln-table-coordinator/src/ln-table-coordinator.js +3 -3
  165. package/components/ln-tabs/README.md +2 -2
  166. package/components/ln-tabs/ln-tabs.js +1 -1
  167. package/components/ln-tabs/ln-tabs.schema.json +75 -75
  168. package/components/ln-tabs/src/ln-tabs.js +208 -207
  169. package/components/ln-tabs/src/tabs-model.js +82 -82
  170. package/components/ln-time/ln-time-dev.scss +13 -13
  171. package/components/ln-time/ln-time.js +1 -1
  172. package/components/ln-time/ln-time.schema.json +38 -38
  173. package/components/ln-toast/ln-toast.js +1 -1
  174. package/components/ln-toast/ln-toast.schema.json +65 -65
  175. package/components/ln-toggle/ln-toggle.js +1 -1
  176. package/components/ln-toggle/ln-toggle.schema.json +52 -52
  177. package/components/ln-tooltip/ln-tooltip.js +1 -1
  178. package/components/ln-tooltip/ln-tooltip.schema.json +86 -86
  179. package/components/ln-translations/ln-translations.js +1 -1
  180. package/components/ln-translations/ln-translations.schema.json +120 -120
  181. package/components/ln-ui-coordinator/README.md +62 -62
  182. package/components/ln-ui-coordinator/ln-ui-coordinator.js +1 -1
  183. package/components/ln-ui-coordinator/ln-ui-coordinator.schema.json +28 -28
  184. package/components/ln-ui-coordinator/src/ln-ui-coordinator.js +140 -140
  185. package/components/ln-upload/ln-upload.js +1 -1
  186. package/components/ln-upload/ln-upload.schema.json +193 -193
  187. package/components/ln-upload/src/upload-model.js +78 -78
  188. package/components/ln-validate/ln-validate.js +1 -1
  189. package/components/ln-validate/ln-validate.schema.json +50 -50
  190. package/components/ln-validate/src/validate-model.js +64 -64
  191. package/components/ln-websocket-connector/README.md +166 -166
  192. package/components/ln-websocket-connector/ln-websocket-connector.js +1 -1
  193. package/components/ln-websocket-connector/ln-websocket-connector.schema.json +29 -29
  194. package/components/ln-websocket-connector/src/ln-websocket-connector.js +283 -279
  195. package/ln-ashlar.html-data.json +7 -8
  196. package/package.json +84 -84
  197. package/theme/brand.css +73 -73
  198. package/theme/components/_confirm.scss +6 -6
  199. package/theme/components/_picklist.scss +3 -3
  200. package/theme/config/_palette.scss +274 -274
  201. package/theme/config/_theme.scss +292 -292
  202. package/theme/config/_tokens.scss +285 -285
  203. package/theme/config/mixins/_index.scss +62 -62
  204. package/theme/config/mixins/_picklist.scss +66 -66
  205. package/theme/ln-ashlar-dev.scss +66 -66
  206. package/theme/ln-ashlar-landing.scss +56 -56
  207. package/theme/ln-ashlar-theme.scss +63 -63
  208. package/theme/presentation/_bento.scss +151 -151
  209. package/theme/presentation/_cta.scss +111 -111
  210. package/theme/presentation/_effects.scss +216 -216
  211. package/theme/presentation/_features.scss +108 -108
  212. package/theme/presentation/_footer.scss +129 -129
  213. package/theme/presentation/_hero.scss +158 -158
  214. package/theme/presentation/_layout.scss +170 -170
  215. package/theme/presentation/_navbar.scss +140 -140
  216. package/theme/presentation/_pricing.scss +262 -262
  217. package/theme/presentation/_stats.scss +87 -87
  218. package/theme/presentation/_testimonials.scss +124 -124
  219. package/theme/presentation/_tokens.scss +39 -39
  220. package/theme/presentation/_typography.scss +163 -163
  221. package/web-types.json +12 -12
@@ -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
  }