@lepid-labs/styles 1.0.1 → 1.0.2

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.
@@ -0,0 +1,348 @@
1
+ /* neon-butterfly — layout: the app shell's grid, sticky parts, rail, drawer and tab
2
+ * bar. Structure only, identical in every theme (the chrome lives in
3
+ * shell.css; the page layouts that go inside main live in page.css).
4
+ *
5
+ * .ld-shell is a grid of named areas; any of __header, __nav, __footer may be
6
+ * left out and its track collapses to nothing, so there are no "has header"
7
+ * modifiers. The shell paints the theme's page background (base.css lists it
8
+ * beside .ld-bg). Nav state is two presence attributes on the root:
9
+ * data-ld-nav-collapsed (wide: icon rail) and data-ld-nav-open (narrow:
10
+ * drawer shown). The header always spans the full width above the nav, so
11
+ * its toggle and brand never move as the nav collapses or hides. Below 48rem
12
+ * the nav leaves the grid and becomes a drawer — or, with .ld-shell--tabbar,
13
+ * a bottom tab bar. 48rem is SHELL_NARROW_QUERY
14
+ * in the React package; keep the two in step.
15
+ */
16
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell {
17
+ --ld-shell-header-h: 3.5rem;
18
+ --ld-shell-nav-w: 15rem;
19
+ --ld-shell-rail-w: 4.25rem;
20
+ --ld-shell-top: 0px; /* sticky offset below the header, when there is one */
21
+ display: grid;
22
+ grid-template-columns: auto minmax(0, 1fr);
23
+ grid-template-rows: auto 1fr auto;
24
+ grid-template-areas:
25
+ "header header"
26
+ "nav main"
27
+ "nav footer";
28
+ min-block-size: 100dvh;
29
+ }
30
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell:has(> .ld-shell__header) {
31
+ --ld-shell-top: var(--ld-shell-header-h);
32
+ }
33
+
34
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__skip {
35
+ position: absolute;
36
+ inset-inline-start: var(--ld-space-2);
37
+ inset-block-start: -10rem;
38
+ z-index: 50;
39
+ }
40
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__skip:focus {
41
+ inset-block-start: var(--ld-space-2);
42
+ }
43
+
44
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__header {
45
+ grid-area: header;
46
+ position: sticky;
47
+ inset-block-start: 0;
48
+ z-index: 20;
49
+ display: flex;
50
+ align-items: center;
51
+ gap: var(--ld-space-3);
52
+ block-size: var(--ld-shell-header-h);
53
+ padding-inline: var(--ld-space-3);
54
+ min-inline-size: 0;
55
+ }
56
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__toggle {
57
+ flex: none;
58
+ display: inline-grid;
59
+ place-items: center;
60
+ inline-size: 2.25rem;
61
+ block-size: 2.25rem;
62
+ padding: 0;
63
+ cursor: pointer;
64
+ }
65
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__toggle svg {
66
+ inline-size: 1.25rem;
67
+ block-size: 1.25rem;
68
+ }
69
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell:not(:has(> .ld-shell__nav)) .ld-shell__toggle {
70
+ display: none;
71
+ }
72
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__brand {
73
+ flex: none;
74
+ display: inline-flex;
75
+ align-items: center;
76
+ gap: var(--ld-space-2);
77
+ text-decoration: none;
78
+ white-space: nowrap;
79
+ }
80
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__brand svg,
81
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__brand img {
82
+ inline-size: 1.75rem;
83
+ block-size: 1.75rem;
84
+ }
85
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-topnav {
86
+ display: flex;
87
+ align-items: center;
88
+ gap: var(--ld-space-1);
89
+ min-inline-size: 0;
90
+ overflow-x: auto;
91
+ scrollbar-width: none;
92
+ }
93
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-topnav__item {
94
+ flex: none;
95
+ white-space: nowrap;
96
+ text-decoration: none;
97
+ }
98
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__actions {
99
+ flex: none;
100
+ display: flex;
101
+ align-items: center;
102
+ gap: var(--ld-space-2);
103
+ margin-inline-start: auto;
104
+ }
105
+
106
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__nav {
107
+ grid-area: nav;
108
+ position: sticky;
109
+ inset-block-start: var(--ld-shell-top);
110
+ align-self: start;
111
+ z-index: 10;
112
+ inline-size: var(--ld-shell-nav-w);
113
+ block-size: calc(100dvh - var(--ld-shell-top));
114
+ overflow: hidden auto;
115
+ overscroll-behavior: contain;
116
+ transition: inline-size var(--ld-transition);
117
+ }
118
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__scrim {
119
+ display: none;
120
+ }
121
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__main {
122
+ grid-area: main;
123
+ display: flex;
124
+ flex-direction: column;
125
+ min-inline-size: 0;
126
+ padding: var(--ld-space-4) var(--ld-space-5);
127
+ }
128
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__main:focus {
129
+ outline: none; /* focus target of the skip link, not an interactive control */
130
+ }
131
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__footer {
132
+ grid-area: footer;
133
+ display: flex;
134
+ flex-wrap: wrap;
135
+ align-items: center;
136
+ justify-content: space-between;
137
+ gap: var(--ld-space-2) var(--ld-space-4);
138
+ padding: var(--ld-space-3) var(--ld-space-5);
139
+ }
140
+
141
+ /* Side nav: sections of icon + label items, an optional footer pinned low. */
142
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav {
143
+ display: flex;
144
+ flex-direction: column;
145
+ gap: var(--ld-space-3);
146
+ min-block-size: 100%;
147
+ padding: var(--ld-space-3) var(--ld-space-2);
148
+ }
149
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__section {
150
+ display: flex;
151
+ flex-direction: column;
152
+ gap: 2px;
153
+ }
154
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__heading {
155
+ margin: 0;
156
+ padding: var(--ld-space-1) var(--ld-space-3);
157
+ white-space: nowrap;
158
+ overflow: hidden;
159
+ }
160
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__item {
161
+ display: flex;
162
+ align-items: center;
163
+ gap: var(--ld-space-3);
164
+ min-block-size: 2.5rem;
165
+ padding: var(--ld-space-2) var(--ld-space-3);
166
+ text-decoration: none;
167
+ white-space: nowrap;
168
+ }
169
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__icon {
170
+ flex: none;
171
+ display: inline-grid;
172
+ place-items: center;
173
+ inline-size: 1.25rem;
174
+ block-size: 1.25rem;
175
+ }
176
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__icon svg {
177
+ inline-size: 100%;
178
+ block-size: 100%;
179
+ }
180
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__label {
181
+ flex: 1;
182
+ min-inline-size: 0;
183
+ overflow: hidden;
184
+ text-overflow: ellipsis;
185
+ }
186
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__badge {
187
+ flex: none;
188
+ margin-inline-start: auto;
189
+ }
190
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__footer {
191
+ display: flex;
192
+ flex-direction: column;
193
+ gap: 2px;
194
+ margin-block-start: auto;
195
+ }
196
+ /* A brand inside the nav (for shells without a header). */
197
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav > .ld-shell__brand {
198
+ padding: var(--ld-space-1) var(--ld-space-3) var(--ld-space-2);
199
+ }
200
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__footer > .ld-shell__toggle {
201
+ margin-inline-start: var(--ld-space-2);
202
+ }
203
+
204
+ /* Wide: the collapsed nav is an icon rail. Labels, headings and badges stay
205
+ * in the accessibility tree, only visually clipped; headings become rules. */
206
+ @media (width > 48rem) {
207
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell[data-ld-nav-collapsed] .ld-shell__nav {
208
+ inline-size: var(--ld-shell-rail-w);
209
+ }
210
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell[data-ld-nav-collapsed] .ld-sidenav__item {
211
+ justify-content: center;
212
+ padding-inline: 0;
213
+ }
214
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell[data-ld-nav-collapsed] :is(.ld-sidenav__label, .ld-sidenav__badge),
215
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell[data-ld-nav-collapsed] .ld-sidenav__heading {
216
+ position: absolute;
217
+ inline-size: 1px;
218
+ block-size: 1px;
219
+ padding: 0;
220
+ overflow: hidden;
221
+ clip-path: inset(50%);
222
+ }
223
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell[data-ld-nav-collapsed] .ld-sidenav > .ld-shell__brand {
224
+ justify-content: center;
225
+ padding-inline: 0;
226
+ }
227
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell[data-ld-nav-collapsed] .ld-sidenav > .ld-shell__brand > :not(svg, img) {
228
+ display: none;
229
+ }
230
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell[data-ld-nav-collapsed] .ld-sidenav__footer > .ld-shell__toggle {
231
+ margin-inline: auto;
232
+ }
233
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell[data-ld-nav-collapsed] .ld-sidenav__section + .ld-sidenav__section {
234
+ border-block-start: 1px solid var(--ld-border);
235
+ padding-block-start: var(--ld-space-3);
236
+ }
237
+ }
238
+
239
+ /* Narrow: the nav leaves the grid. Default is an off-canvas drawer under the
240
+ * header (visibility keeps a closed drawer out of the tab order). */
241
+ @media (width <= 48rem) {
242
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell {
243
+ grid-template-columns: minmax(0, 1fr);
244
+ grid-template-areas:
245
+ "header"
246
+ "main"
247
+ "footer";
248
+ }
249
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__header {
250
+ padding-inline: var(--ld-space-2);
251
+ gap: var(--ld-space-2);
252
+ }
253
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__main {
254
+ padding: var(--ld-space-3);
255
+ }
256
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__footer {
257
+ padding: var(--ld-space-3);
258
+ }
259
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__nav {
260
+ position: fixed;
261
+ inset-block: var(--ld-shell-top) 0;
262
+ inset-inline-start: 0;
263
+ align-self: stretch; /* fixed boxes honour align-self; "start" would shrink-wrap the drawer */
264
+ z-index: 40;
265
+ inline-size: min(var(--ld-shell-nav-w) + 3rem, 85vw);
266
+ block-size: auto;
267
+ transform: translateX(-100%);
268
+ visibility: hidden;
269
+ transition: transform var(--ld-transition), visibility 0s linear var(--ld-transition);
270
+ }
271
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell[data-ld-nav-open] .ld-shell__nav {
272
+ transform: none;
273
+ visibility: visible;
274
+ transition: transform var(--ld-transition);
275
+ }
276
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell[data-ld-nav-open] .ld-shell__scrim {
277
+ display: block;
278
+ position: fixed;
279
+ inset: var(--ld-shell-top) 0 0;
280
+ z-index: 30;
281
+ }
282
+
283
+ /* Tab bar: the nav docks at the bottom; sections flatten into one row. */
284
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell--tabbar .ld-shell__toggle {
285
+ display: none;
286
+ }
287
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell--tabbar .ld-shell__nav {
288
+ inset-block: auto 0;
289
+ inset-inline: 0;
290
+ inline-size: auto;
291
+ transform: none;
292
+ visibility: visible;
293
+ overflow: visible;
294
+ padding-block-end: env(safe-area-inset-bottom, 0px);
295
+ transition: none;
296
+ }
297
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell--tabbar .ld-shell__scrim {
298
+ display: none;
299
+ }
300
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell--tabbar .ld-sidenav {
301
+ flex-direction: row;
302
+ gap: 0;
303
+ min-block-size: 0;
304
+ padding: var(--ld-space-1);
305
+ }
306
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell--tabbar :is(.ld-sidenav__section, .ld-sidenav__footer) {
307
+ display: contents;
308
+ }
309
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell--tabbar .ld-sidenav > .ld-shell__brand {
310
+ display: none;
311
+ }
312
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell--tabbar .ld-sidenav__heading {
313
+ display: none;
314
+ }
315
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell--tabbar .ld-sidenav__item {
316
+ position: relative;
317
+ flex: 1 1 0;
318
+ flex-direction: column;
319
+ justify-content: center;
320
+ gap: 2px;
321
+ min-inline-size: 0;
322
+ padding: var(--ld-space-1);
323
+ font-size: 0.6875rem;
324
+ }
325
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell--tabbar .ld-sidenav__label {
326
+ flex: none;
327
+ max-inline-size: 100%;
328
+ }
329
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell--tabbar .ld-sidenav__badge {
330
+ position: absolute;
331
+ inset-block-start: 0;
332
+ inset-inline-start: calc(50% + 0.5rem);
333
+ margin: 0;
334
+ }
335
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell--tabbar .ld-shell__footer {
336
+ padding-block-end: calc(4.5rem + env(safe-area-inset-bottom, 0px));
337
+ }
338
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell--tabbar:not(:has(> .ld-shell__footer)) .ld-shell__main {
339
+ padding-block-end: calc(4.5rem + env(safe-area-inset-bottom, 0px));
340
+ }
341
+ }
342
+
343
+ @media (prefers-reduced-motion: reduce) {
344
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__nav,
345
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell[data-ld-nav-open] .ld-shell__nav {
346
+ transition: none;
347
+ }
348
+ }
@@ -0,0 +1,85 @@
1
+ /* neon-butterfly — page layouts: what goes inside .ld-shell__main (or any
2
+ * container). Structure only, identical in every theme; shell.css dresses the
3
+ * page header's type. */
4
+ /* A page column: width-capped, centered, with a header row. */
5
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-page {
6
+ display: grid;
7
+ align-content: start;
8
+ gap: var(--ld-space-4);
9
+ inline-size: 100%;
10
+ max-inline-size: var(--ld-page-max, 72rem);
11
+ margin-inline: auto;
12
+ }
13
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-page--narrow { --ld-page-max: 48rem; }
14
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-page--wide { --ld-page-max: 96rem; }
15
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-page--full { --ld-page-max: none; }
16
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-page__header {
17
+ display: flex;
18
+ flex-wrap: wrap;
19
+ align-items: flex-end;
20
+ justify-content: space-between;
21
+ gap: var(--ld-space-3);
22
+ }
23
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-page__heading {
24
+ display: grid;
25
+ gap: var(--ld-space-1);
26
+ min-inline-size: 0;
27
+ }
28
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-page__title,
29
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-page__subtitle,
30
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-page__eyebrow {
31
+ margin: 0;
32
+ }
33
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-page__actions {
34
+ display: flex;
35
+ flex-wrap: wrap;
36
+ gap: var(--ld-space-2);
37
+ }
38
+
39
+ /* Dashboard grid: as many columns of at least --ld-grid-min as fit. */
40
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-grid {
41
+ display: grid;
42
+ grid-template-columns: repeat(auto-fill, minmax(min(var(--ld-grid-min, 18rem), 100%), 1fr));
43
+ gap: var(--ld-space-3);
44
+ align-items: start;
45
+ }
46
+
47
+ /* List + detail, and content + aside: two panes that stack by themselves once
48
+ * the wide pane would drop below 60% of the row — no breakpoint, so they work
49
+ * at any shell width. */
50
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-split,
51
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-aside-layout {
52
+ display: flex;
53
+ flex-wrap: wrap;
54
+ align-items: flex-start;
55
+ gap: var(--ld-space-4);
56
+ }
57
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-split__list {
58
+ flex: 1 1 var(--ld-split-list, 20rem);
59
+ display: grid;
60
+ gap: var(--ld-space-2);
61
+ min-inline-size: 0;
62
+ }
63
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-split__detail,
64
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-aside-layout__main {
65
+ flex: 999 1 0;
66
+ min-inline-size: 60%;
67
+ }
68
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-aside-layout__aside {
69
+ flex: 1 1 var(--ld-aside-w, 16rem);
70
+ position: sticky;
71
+ inset-block-start: calc(var(--ld-shell-top, 0px) + var(--ld-space-3));
72
+ min-inline-size: 0;
73
+ }
74
+
75
+ /* Centered: one narrow column in the middle of the remaining height — sign
76
+ * in, empty states, a single form. Fills .ld-shell__main (a flex column). */
77
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-center {
78
+ flex: 1;
79
+ display: grid;
80
+ place-items: center;
81
+ min-block-size: 100%;
82
+ }
83
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-center > * {
84
+ inline-size: min(100%, var(--ld-center-max, 26rem));
85
+ }
@@ -11,3 +11,78 @@
11
11
  font-size: var(--ld-text-sm);
12
12
  overflow-x: auto;
13
13
  }
14
+
15
+ /* Log / terminal variant (.ld-pre--log): bounded, scrolls both ways, wraps
16
+ * long lines, and carries faint 4px scanlines. Height comes from
17
+ * --ld-log-max-height (the React LogBlock's maxHeight sets it inline). */
18
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-pre--log {
19
+ max-height: var(--ld-log-max-height, 420px);
20
+ overflow: auto;
21
+ line-height: 1.45;
22
+ white-space: pre-wrap;
23
+ overflow-wrap: anywhere;
24
+ background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0.02) 1px, transparent 1px);
25
+ background-size: 100% 4px;
26
+ }
27
+
28
+ /* Copy control (.ld-pre-wrap + .ld-pre-copy): an .ld-icon-btn pinned to the
29
+ * block's top-right corner. Hidden until the wrap is hovered or holds focus
30
+ * (so it stays keyboard-reachable), always shown where there's no hover
31
+ * (touch). The host script sets data-ld-copy="copied" | "failed" on the
32
+ * button for ~1.5s: copied swaps the copy glyph for the check. Status text for
33
+ * screen readers goes in the visually hidden aria-live .ld-pre-copy-status. */
34
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-pre-wrap {
35
+ position: relative;
36
+ }
37
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-pre-wrap > .ld-pre {
38
+ padding-right: calc(2rem + var(--ld-space-3));
39
+ }
40
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-pre-copy {
41
+ position: absolute;
42
+ top: var(--ld-space-1);
43
+ right: var(--ld-space-1);
44
+ background: var(--ld-surface-sunken);
45
+ opacity: 0;
46
+ transition: opacity var(--ld-transition), color var(--ld-transition), box-shadow var(--ld-transition);
47
+ }
48
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-pre-wrap:hover .ld-pre-copy,
49
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-pre-wrap:focus-within .ld-pre-copy,
50
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-pre-wrap .ld-pre-copy[data-ld-copy] {
51
+ opacity: 1;
52
+ }
53
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-pre-wrap .ld-pre-copy[data-ld-copy="copied"] {
54
+ color: var(--ld-success);
55
+ }
56
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-pre-wrap .ld-pre-copy[data-ld-copy="failed"] {
57
+ color: var(--ld-danger);
58
+ }
59
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-pre-copy__check,
60
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-pre-copy[data-ld-copy="copied"] .ld-pre-copy__icon {
61
+ display: none;
62
+ }
63
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-pre-copy[data-ld-copy="copied"] .ld-pre-copy__check {
64
+ display: block;
65
+ }
66
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-pre-copy-status {
67
+ position: absolute;
68
+ width: 1px;
69
+ height: 1px;
70
+ margin: -1px;
71
+ padding: 0;
72
+ overflow: hidden;
73
+ clip-path: inset(50%);
74
+ white-space: nowrap;
75
+ border: 0;
76
+ }
77
+
78
+ @media (hover: none) {
79
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-pre-copy {
80
+ opacity: 1;
81
+ }
82
+ }
83
+
84
+ @media (prefers-reduced-motion: reduce) {
85
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-pre-copy {
86
+ transition: none;
87
+ }
88
+ }