@lepid-labs/styles 1.0.0 → 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.
- package/css.d.ts +8 -0
- package/luminous-precision/base.css +6 -2
- package/luminous-precision/components/badge.css +25 -0
- package/luminous-precision/components/button-group.css +130 -0
- package/luminous-precision/components/button-hold.css +112 -0
- package/luminous-precision/components/icon-button.css +71 -0
- package/luminous-precision/components/layout.css +348 -0
- package/luminous-precision/components/page.css +85 -0
- package/luminous-precision/components/pre.css +75 -0
- package/luminous-precision/components/shell.css +165 -0
- package/luminous-precision/components/status-card.css +159 -0
- package/luminous-precision/components/stepper.css +108 -0
- package/luminous-precision/components/table.css +20 -0
- package/luminous-precision/components/tabs.css +42 -0
- package/luminous-precision/design.md +64 -4
- package/luminous-precision/index.css +8 -0
- package/luminous-precision/tokens.css +6 -0
- package/neon-butterfly/base.css +6 -2
- package/neon-butterfly/components/badge.css +25 -0
- package/neon-butterfly/components/button-group.css +128 -0
- package/neon-butterfly/components/button-hold.css +112 -0
- package/neon-butterfly/components/icon-button.css +66 -0
- package/neon-butterfly/components/layout.css +348 -0
- package/neon-butterfly/components/page.css +85 -0
- package/neon-butterfly/components/pre.css +75 -0
- package/neon-butterfly/components/shell.css +196 -0
- package/neon-butterfly/components/status-card.css +156 -0
- package/neon-butterfly/components/stepper.css +107 -0
- package/neon-butterfly/components/table.css +20 -0
- package/neon-butterfly/components/tabs.css +42 -0
- package/neon-butterfly/design.md +60 -4
- package/neon-butterfly/index.css +8 -0
- package/neon-butterfly/tokens.css +6 -0
- package/package.json +58 -15
- package/summer-cloud/base.css +6 -2
- package/summer-cloud/components/badge.css +26 -0
- package/summer-cloud/components/button-group.css +131 -0
- package/summer-cloud/components/button-hold.css +132 -0
- package/summer-cloud/components/icon-button.css +76 -0
- package/summer-cloud/components/layout.css +348 -0
- package/summer-cloud/components/page.css +85 -0
- package/summer-cloud/components/pre.css +74 -0
- package/summer-cloud/components/shell.css +197 -0
- package/summer-cloud/components/status-card.css +158 -0
- package/summer-cloud/components/stepper.css +101 -0
- package/summer-cloud/components/table.css +20 -0
- package/summer-cloud/components/tabs.css +42 -0
- package/summer-cloud/design.md +64 -2
- package/summer-cloud/index.css +8 -0
- package/summer-cloud/tokens.css +6 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/* neon-butterfly — shell chrome: unfilled bars (hairlines over the circuit
|
|
2
|
+
* background), uppercase mono labels under lime "//" headings, the current page in lilac with a pulsing glow border and a
|
|
3
|
+
* neon-lime chevron. Structure is in layout.css. */
|
|
4
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__skip {
|
|
5
|
+
padding: var(--ld-space-2) var(--ld-space-3);
|
|
6
|
+
background: var(--ld-surface);
|
|
7
|
+
border: 1px solid var(--ld-primary-border);
|
|
8
|
+
border-radius: var(--ld-radius);
|
|
9
|
+
color: var(--ld-primary);
|
|
10
|
+
font-size: var(--ld-text-sm);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__header {
|
|
14
|
+
/* no fill: the shell background runs under the bar; the blur keeps
|
|
15
|
+
* content scrolling beneath it legible */
|
|
16
|
+
background: transparent;
|
|
17
|
+
border-bottom: 1px solid var(--ld-border);
|
|
18
|
+
backdrop-filter: blur(var(--ld-blur));
|
|
19
|
+
}
|
|
20
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__toggle {
|
|
21
|
+
background: none;
|
|
22
|
+
border: 1px solid var(--ld-border);
|
|
23
|
+
border-radius: var(--ld-radius);
|
|
24
|
+
color: var(--ld-faint);
|
|
25
|
+
transition: color var(--ld-transition), border-color var(--ld-transition);
|
|
26
|
+
}
|
|
27
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__toggle:hover,
|
|
28
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__toggle:focus-visible {
|
|
29
|
+
color: var(--ld-accent);
|
|
30
|
+
border-color: var(--ld-accent);
|
|
31
|
+
box-shadow: 0 0 8px var(--ld-accent-glow);
|
|
32
|
+
outline: none;
|
|
33
|
+
}
|
|
34
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__brand {
|
|
35
|
+
color: var(--ld-primary);
|
|
36
|
+
font-weight: var(--ld-font-weight-bold);
|
|
37
|
+
text-transform: uppercase;
|
|
38
|
+
letter-spacing: var(--ld-tracking-wide);
|
|
39
|
+
text-shadow: 0 0 10px var(--ld-primary-glow);
|
|
40
|
+
}
|
|
41
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__brand svg,
|
|
42
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__brand img {
|
|
43
|
+
filter: drop-shadow(0 0 6px var(--ld-primary-glow));
|
|
44
|
+
}
|
|
45
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-topnav__item {
|
|
46
|
+
padding: var(--ld-space-2) var(--ld-space-3);
|
|
47
|
+
border: 1px solid transparent;
|
|
48
|
+
border-radius: var(--ld-radius);
|
|
49
|
+
color: var(--ld-faint);
|
|
50
|
+
font-size: 12px;
|
|
51
|
+
font-weight: var(--ld-font-weight-bold);
|
|
52
|
+
text-transform: uppercase;
|
|
53
|
+
letter-spacing: var(--ld-tracking-wide);
|
|
54
|
+
transition: color var(--ld-transition), border-color var(--ld-transition);
|
|
55
|
+
}
|
|
56
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-topnav__item:hover,
|
|
57
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-topnav__item:focus-visible {
|
|
58
|
+
color: var(--ld-on-surface);
|
|
59
|
+
border-color: var(--ld-border);
|
|
60
|
+
outline: none;
|
|
61
|
+
}
|
|
62
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-topnav__item--active,
|
|
63
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-topnav__item[aria-current="page"] {
|
|
64
|
+
color: var(--ld-primary);
|
|
65
|
+
border-color: var(--ld-primary-border);
|
|
66
|
+
text-shadow: 0 0 8px var(--ld-primary-glow);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__nav {
|
|
70
|
+
background: transparent; /* the shell background shows through; a hairline divides */
|
|
71
|
+
border-right: 1px solid var(--ld-border);
|
|
72
|
+
}
|
|
73
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__scrim {
|
|
74
|
+
background: rgba(11, 19, 38, 0.6);
|
|
75
|
+
backdrop-filter: blur(2px);
|
|
76
|
+
}
|
|
77
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__heading {
|
|
78
|
+
color: var(--ld-faint);
|
|
79
|
+
font-size: 11px;
|
|
80
|
+
font-weight: var(--ld-font-weight-bold);
|
|
81
|
+
text-transform: uppercase;
|
|
82
|
+
letter-spacing: var(--ld-tracking-wide);
|
|
83
|
+
}
|
|
84
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__heading::before {
|
|
85
|
+
content: "// ";
|
|
86
|
+
color: var(--ld-accent);
|
|
87
|
+
}
|
|
88
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__item {
|
|
89
|
+
border: 1px solid transparent;
|
|
90
|
+
border-radius: var(--ld-radius);
|
|
91
|
+
color: var(--ld-on-surface);
|
|
92
|
+
font-size: 13px;
|
|
93
|
+
font-weight: var(--ld-font-weight-bold);
|
|
94
|
+
text-transform: uppercase;
|
|
95
|
+
letter-spacing: 0.06em;
|
|
96
|
+
transition: color var(--ld-transition), border-color var(--ld-transition), transform var(--ld-transition);
|
|
97
|
+
}
|
|
98
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__icon {
|
|
99
|
+
color: var(--ld-faint);
|
|
100
|
+
transition: color var(--ld-transition);
|
|
101
|
+
}
|
|
102
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__item:hover,
|
|
103
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__item:focus-visible {
|
|
104
|
+
border-color: var(--ld-primary-border);
|
|
105
|
+
color: var(--ld-primary);
|
|
106
|
+
transform: translateX(3px);
|
|
107
|
+
outline: none;
|
|
108
|
+
}
|
|
109
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__item:hover .ld-sidenav__icon,
|
|
110
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__item:focus-visible .ld-sidenav__icon {
|
|
111
|
+
color: var(--ld-accent);
|
|
112
|
+
filter: drop-shadow(0 0 4px var(--ld-accent-glow));
|
|
113
|
+
}
|
|
114
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__item--active,
|
|
115
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__item[aria-current="page"] {
|
|
116
|
+
background: var(--ld-surface);
|
|
117
|
+
border-color: var(--ld-primary-border);
|
|
118
|
+
color: var(--ld-primary);
|
|
119
|
+
animation: ld-nb-shell-glow 2.4s infinite;
|
|
120
|
+
}
|
|
121
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__item--active .ld-sidenav__icon,
|
|
122
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__item[aria-current="page"] .ld-sidenav__icon {
|
|
123
|
+
color: var(--ld-accent);
|
|
124
|
+
filter: drop-shadow(0 0 4px var(--ld-accent-glow));
|
|
125
|
+
}
|
|
126
|
+
@keyframes ld-nb-shell-glow {
|
|
127
|
+
0%, 100% { box-shadow: 0 0 4px rgba(210, 187, 255, 0.15); }
|
|
128
|
+
50% { box-shadow: 0 0 14px var(--ld-primary-glow); }
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__footer {
|
|
132
|
+
border-top: 1px solid var(--ld-border);
|
|
133
|
+
color: var(--ld-faint);
|
|
134
|
+
font-size: 12px;
|
|
135
|
+
text-transform: uppercase;
|
|
136
|
+
letter-spacing: var(--ld-tracking-wide);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-page__eyebrow {
|
|
140
|
+
color: var(--ld-accent);
|
|
141
|
+
font-size: 12px;
|
|
142
|
+
font-weight: var(--ld-font-weight-bold);
|
|
143
|
+
text-transform: uppercase;
|
|
144
|
+
letter-spacing: var(--ld-tracking-wide);
|
|
145
|
+
text-shadow: 0 0 6px var(--ld-accent-glow);
|
|
146
|
+
}
|
|
147
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-page__title {
|
|
148
|
+
font-size: clamp(1.25rem, 1rem + 1vw, 1.75rem);
|
|
149
|
+
font-weight: var(--ld-font-weight-bold);
|
|
150
|
+
text-transform: uppercase;
|
|
151
|
+
letter-spacing: var(--ld-tracking-wide);
|
|
152
|
+
}
|
|
153
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-page__subtitle {
|
|
154
|
+
color: var(--ld-faint);
|
|
155
|
+
font-size: var(--ld-text-sm);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
@media (width <= 48rem) {
|
|
159
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__nav {
|
|
160
|
+
background: color-mix(in srgb, var(--ld-bg) 94%, transparent);
|
|
161
|
+
box-shadow: 12px 0 40px rgba(0, 0, 0, 0.5);
|
|
162
|
+
}
|
|
163
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell--tabbar .ld-shell__nav {
|
|
164
|
+
border-right: none;
|
|
165
|
+
border-top: 1px solid var(--ld-border);
|
|
166
|
+
box-shadow: 0 -8px 30px rgba(0, 0, 0, 0.45);
|
|
167
|
+
}
|
|
168
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell--tabbar .ld-sidenav__item {
|
|
169
|
+
transform: none;
|
|
170
|
+
font-size: 10px;
|
|
171
|
+
}
|
|
172
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell--tabbar .ld-sidenav__item--active,
|
|
173
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell--tabbar .ld-sidenav__item[aria-current="page"] {
|
|
174
|
+
background: none;
|
|
175
|
+
border-color: transparent;
|
|
176
|
+
animation: none;
|
|
177
|
+
text-shadow: 0 0 8px var(--ld-primary-glow);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
@media (prefers-reduced-motion: reduce) {
|
|
182
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell__toggle,
|
|
183
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-topnav__item,
|
|
184
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__item {
|
|
185
|
+
transition: none;
|
|
186
|
+
}
|
|
187
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__item:hover,
|
|
188
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__item:focus-visible {
|
|
189
|
+
transform: none;
|
|
190
|
+
}
|
|
191
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__item--active,
|
|
192
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-sidenav__item[aria-current="page"] {
|
|
193
|
+
animation: none;
|
|
194
|
+
box-shadow: 0 0 10px var(--ld-primary-glow);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/* neon-butterfly — status card: a dense dashboard card whose left edge, ring, and
|
|
2
|
+
* flash carry state (generalized from pulse's repo card).
|
|
3
|
+
* .ld-status-card--<tone> left edge in the semantic color
|
|
4
|
+
* [data-ld-attention="<tone>"] outline + glow ring calling for action
|
|
5
|
+
* [data-ld-changed] replays the change flash while present */
|
|
6
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card {
|
|
7
|
+
--ld-status-attention: var(--ld-warning);
|
|
8
|
+
position: relative;
|
|
9
|
+
display: flex;
|
|
10
|
+
flex-direction: column;
|
|
11
|
+
padding: 0;
|
|
12
|
+
background: var(--ld-surface-glass);
|
|
13
|
+
border: 1px solid var(--ld-border);
|
|
14
|
+
border-left: 3px solid transparent;
|
|
15
|
+
border-radius: var(--ld-radius);
|
|
16
|
+
backdrop-filter: blur(var(--ld-blur));
|
|
17
|
+
-webkit-backdrop-filter: blur(var(--ld-blur));
|
|
18
|
+
color: var(--ld-on-surface);
|
|
19
|
+
overflow: hidden;
|
|
20
|
+
transition: background var(--ld-transition), box-shadow var(--ld-transition);
|
|
21
|
+
}
|
|
22
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card:hover { box-shadow: 0 0 12px var(--ld-primary-glow); }
|
|
23
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card--info { border-left-color: var(--ld-info); }
|
|
24
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card--success { border-left-color: var(--ld-success); }
|
|
25
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card--warning { border-left-color: var(--ld-warning); }
|
|
26
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card--danger { border-left-color: var(--ld-danger); }
|
|
27
|
+
|
|
28
|
+
/* attention ring — the tone rides on the attribute value */
|
|
29
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card[data-ld-attention] {
|
|
30
|
+
outline: 1px solid color-mix(in srgb, var(--ld-status-attention) 70%, transparent);
|
|
31
|
+
box-shadow: 0 0 14px color-mix(in srgb, var(--ld-status-attention) 35%, transparent);
|
|
32
|
+
}
|
|
33
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card[data-ld-attention]:hover {
|
|
34
|
+
box-shadow: 0 0 18px color-mix(in srgb, var(--ld-status-attention) 55%, transparent);
|
|
35
|
+
}
|
|
36
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card[data-ld-attention="info"] { --ld-status-attention: var(--ld-info); }
|
|
37
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card[data-ld-attention="success"] { --ld-status-attention: var(--ld-success); }
|
|
38
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card[data-ld-attention="danger"] { --ld-status-attention: var(--ld-danger); }
|
|
39
|
+
|
|
40
|
+
/* change flash — fades from a primary tint back to the resting glass */
|
|
41
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card[data-ld-changed] { animation: ld-nb-status-flash 30s ease-out forwards; }
|
|
42
|
+
@keyframes ld-nb-status-flash {
|
|
43
|
+
from { background: color-mix(in srgb, var(--ld-primary) 20%, var(--ld-surface)); }
|
|
44
|
+
to { background: var(--ld-surface-glass); }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card__watermark {
|
|
48
|
+
position: absolute;
|
|
49
|
+
top: 0;
|
|
50
|
+
left: -0.25rem;
|
|
51
|
+
width: 2rem;
|
|
52
|
+
height: 2rem;
|
|
53
|
+
color: var(--ld-on-surface);
|
|
54
|
+
opacity: 0.12;
|
|
55
|
+
pointer-events: none;
|
|
56
|
+
rotate: -25deg;
|
|
57
|
+
}
|
|
58
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card__watermark > svg { width: 100%; height: 100%; }
|
|
59
|
+
|
|
60
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card__head {
|
|
61
|
+
display: flex;
|
|
62
|
+
align-items: center;
|
|
63
|
+
justify-content: space-between;
|
|
64
|
+
gap: var(--ld-space-2);
|
|
65
|
+
padding: 0.625rem 0.75rem 0.5rem 0.875rem;
|
|
66
|
+
}
|
|
67
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card__title {
|
|
68
|
+
min-width: 0;
|
|
69
|
+
overflow: hidden;
|
|
70
|
+
font-size: var(--ld-text-sm);
|
|
71
|
+
font-weight: var(--ld-font-weight-bold);
|
|
72
|
+
white-space: nowrap;
|
|
73
|
+
text-overflow: ellipsis;
|
|
74
|
+
color: inherit;
|
|
75
|
+
text-decoration: none;
|
|
76
|
+
transition: color var(--ld-transition);
|
|
77
|
+
}
|
|
78
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card__title[href]:hover { color: var(--ld-primary); }
|
|
79
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card__prefix { color: var(--ld-faint); }
|
|
80
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card__prefix::after { content: " // "; opacity: 0.5; }
|
|
81
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card__meta {
|
|
82
|
+
display: flex;
|
|
83
|
+
align-items: center;
|
|
84
|
+
gap: 0.375rem;
|
|
85
|
+
flex-shrink: 0;
|
|
86
|
+
}
|
|
87
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card__note {
|
|
88
|
+
font-size: 11px;
|
|
89
|
+
color: var(--ld-faint);
|
|
90
|
+
white-space: nowrap;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card__rows {
|
|
94
|
+
list-style: none;
|
|
95
|
+
margin: 0;
|
|
96
|
+
padding: 0;
|
|
97
|
+
border-top: 1px solid var(--ld-border);
|
|
98
|
+
}
|
|
99
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card__row {
|
|
100
|
+
display: grid;
|
|
101
|
+
grid-template-columns: auto 1fr auto;
|
|
102
|
+
align-items: baseline;
|
|
103
|
+
gap: 0.375rem;
|
|
104
|
+
padding: 0.3rem 0.75rem 0.3rem 0.875rem;
|
|
105
|
+
font-size: 12px;
|
|
106
|
+
color: inherit;
|
|
107
|
+
text-decoration: none;
|
|
108
|
+
transition: background 0.1s;
|
|
109
|
+
}
|
|
110
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card__row[href]:hover { background: color-mix(in srgb, var(--ld-primary) 8%, transparent); }
|
|
111
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card__row-lead {
|
|
112
|
+
min-width: 1.5rem;
|
|
113
|
+
font-size: 11px;
|
|
114
|
+
font-weight: var(--ld-font-weight-bold);
|
|
115
|
+
color: var(--ld-faint);
|
|
116
|
+
text-align: right;
|
|
117
|
+
font-variant-numeric: tabular-nums;
|
|
118
|
+
}
|
|
119
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card__row-main {
|
|
120
|
+
min-width: 0;
|
|
121
|
+
overflow: hidden;
|
|
122
|
+
white-space: nowrap;
|
|
123
|
+
text-overflow: ellipsis;
|
|
124
|
+
color: var(--ld-on-surface);
|
|
125
|
+
}
|
|
126
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card__row-trail {
|
|
127
|
+
display: flex;
|
|
128
|
+
align-items: center;
|
|
129
|
+
gap: var(--ld-space-1);
|
|
130
|
+
flex-shrink: 0;
|
|
131
|
+
font-size: 10px;
|
|
132
|
+
color: var(--ld-faint);
|
|
133
|
+
}
|
|
134
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card__footer {
|
|
135
|
+
display: block;
|
|
136
|
+
padding: 0.3rem 0.875rem;
|
|
137
|
+
border-top: 1px solid var(--ld-border);
|
|
138
|
+
font-size: 11px;
|
|
139
|
+
color: var(--ld-faint);
|
|
140
|
+
text-decoration: none;
|
|
141
|
+
transition: color var(--ld-transition);
|
|
142
|
+
}
|
|
143
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card__footer[href]:hover { color: var(--ld-accent); }
|
|
144
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card__empty {
|
|
145
|
+
margin: 0;
|
|
146
|
+
padding: 0.375rem 0.875rem 0.5rem;
|
|
147
|
+
border-top: 1px solid var(--ld-border);
|
|
148
|
+
font-size: 12px;
|
|
149
|
+
color: var(--ld-faint);
|
|
150
|
+
opacity: 0.7;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
@media (prefers-reduced-motion: reduce) {
|
|
154
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card { transition: none; }
|
|
155
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-status-card[data-ld-changed] { animation: none; }
|
|
156
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/* neon-butterfly — stepper: a milestone rail with labelled step nodes. Lilac
|
|
2
|
+
* rail and complete nodes; the current node is the lime activity signal.
|
|
3
|
+
* .ld-stepper__step--complete solid lilac node, navy icon
|
|
4
|
+
* .ld-stepper__step--current surface node, 2px lime border, lime glow
|
|
5
|
+
* .ld-stepper__step--upcoming surface node, hairline border, faint icon
|
|
6
|
+
* The fill follows the state modifiers — no progress value to compute. */
|
|
7
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-stepper {
|
|
8
|
+
display: flex;
|
|
9
|
+
align-items: flex-start;
|
|
10
|
+
list-style: none;
|
|
11
|
+
margin: 0;
|
|
12
|
+
padding: 0;
|
|
13
|
+
}
|
|
14
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-stepper__step {
|
|
15
|
+
position: relative;
|
|
16
|
+
flex: 1 1 0;
|
|
17
|
+
min-width: 0;
|
|
18
|
+
display: flex;
|
|
19
|
+
flex-direction: column;
|
|
20
|
+
align-items: center;
|
|
21
|
+
gap: var(--ld-space-2);
|
|
22
|
+
text-align: center;
|
|
23
|
+
}
|
|
24
|
+
/* rail segment: from this node's centre to the next node's centre; the track is
|
|
25
|
+
* ::before, the fill ::after. Segments meet under the nodes, so the rail reads
|
|
26
|
+
* as one bar and the fill ends exactly at the current node. */
|
|
27
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-stepper__step::before,
|
|
28
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-stepper__step::after {
|
|
29
|
+
content: "";
|
|
30
|
+
position: absolute;
|
|
31
|
+
top: 0.75rem;
|
|
32
|
+
left: 50%;
|
|
33
|
+
width: 100%;
|
|
34
|
+
height: 0.5rem;
|
|
35
|
+
border-radius: 1rem;
|
|
36
|
+
}
|
|
37
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-stepper__step:last-child::before,
|
|
38
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-stepper__step:last-child::after { display: none; }
|
|
39
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-stepper__step::before {
|
|
40
|
+
background: var(--ld-surface);
|
|
41
|
+
box-shadow: inset 0 0 0 1px var(--ld-border);
|
|
42
|
+
}
|
|
43
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-stepper__step::after {
|
|
44
|
+
width: 0;
|
|
45
|
+
background: var(--ld-primary);
|
|
46
|
+
box-shadow: 0 0 8px var(--ld-primary-glow);
|
|
47
|
+
transition: width var(--ld-transition);
|
|
48
|
+
}
|
|
49
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-stepper__step--complete::after { width: 100%; }
|
|
50
|
+
|
|
51
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-stepper__node {
|
|
52
|
+
position: relative;
|
|
53
|
+
z-index: 1;
|
|
54
|
+
display: inline-flex;
|
|
55
|
+
align-items: center;
|
|
56
|
+
justify-content: center;
|
|
57
|
+
width: 2rem;
|
|
58
|
+
height: 2rem;
|
|
59
|
+
border-radius: 50%;
|
|
60
|
+
box-sizing: border-box;
|
|
61
|
+
font-family: var(--ld-font-mono);
|
|
62
|
+
font-size: 12px;
|
|
63
|
+
font-weight: var(--ld-font-weight-bold);
|
|
64
|
+
line-height: 1;
|
|
65
|
+
transition: background var(--ld-transition), color var(--ld-transition), box-shadow var(--ld-transition);
|
|
66
|
+
}
|
|
67
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-stepper__node > svg { width: 1rem; height: 1rem; }
|
|
68
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-stepper__step--complete .ld-stepper__node {
|
|
69
|
+
background: var(--ld-primary);
|
|
70
|
+
color: var(--ld-on-primary);
|
|
71
|
+
box-shadow: 0 0 8px var(--ld-primary-glow);
|
|
72
|
+
}
|
|
73
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-stepper__step--current .ld-stepper__node {
|
|
74
|
+
background: var(--ld-surface);
|
|
75
|
+
border: 2px solid var(--ld-accent);
|
|
76
|
+
color: var(--ld-accent);
|
|
77
|
+
box-shadow: 0 0 12px var(--ld-accent-glow);
|
|
78
|
+
}
|
|
79
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-stepper__step--upcoming .ld-stepper__node {
|
|
80
|
+
background: var(--ld-surface);
|
|
81
|
+
border: 1px solid var(--ld-border);
|
|
82
|
+
color: var(--ld-faint);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* label voice: uppercase tracked mono, like every other label here */
|
|
86
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-stepper__label {
|
|
87
|
+
font-family: var(--ld-font-mono);
|
|
88
|
+
font-size: 11px;
|
|
89
|
+
font-weight: var(--ld-font-weight-bold);
|
|
90
|
+
text-transform: uppercase;
|
|
91
|
+
letter-spacing: 0.1em;
|
|
92
|
+
line-height: 1.3;
|
|
93
|
+
color: var(--ld-faint);
|
|
94
|
+
transition: color var(--ld-transition), text-shadow var(--ld-transition);
|
|
95
|
+
}
|
|
96
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-stepper__step--complete .ld-stepper__label { color: var(--ld-on-surface); }
|
|
97
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-stepper__step--current .ld-stepper__label {
|
|
98
|
+
color: var(--ld-accent);
|
|
99
|
+
text-shadow: 0 0 8px var(--ld-accent-glow);
|
|
100
|
+
}
|
|
101
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-stepper__step--upcoming .ld-stepper__label { color: var(--ld-faint); }
|
|
102
|
+
|
|
103
|
+
@media (prefers-reduced-motion: reduce) {
|
|
104
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-stepper__step::after,
|
|
105
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-stepper__node,
|
|
106
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-stepper__label { transition: none; }
|
|
107
|
+
}
|
|
@@ -25,3 +25,23 @@
|
|
|
25
25
|
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-table tbody tr:hover {
|
|
26
26
|
background: var(--ld-surface-glass);
|
|
27
27
|
}
|
|
28
|
+
|
|
29
|
+
/* Interactive rows (.ld-table--interactive): the cursor is the affordance —
|
|
30
|
+
* plain tables hover too. Focus is an outline so it
|
|
31
|
+
* composes with the selected state (aria-selected="true"), which sits last
|
|
32
|
+
* so it outranks hover. */
|
|
33
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-table--interactive tbody tr {
|
|
34
|
+
cursor: pointer;
|
|
35
|
+
}
|
|
36
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-table--interactive tbody tr:focus-visible {
|
|
37
|
+
outline: 1px solid var(--ld-primary-border);
|
|
38
|
+
outline-offset: -1px;
|
|
39
|
+
background: var(--ld-surface-glass);
|
|
40
|
+
}
|
|
41
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-table--interactive tbody tr:active {
|
|
42
|
+
background: rgba(210, 187, 255, 0.08);
|
|
43
|
+
}
|
|
44
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-table--interactive tbody tr[aria-selected="true"] {
|
|
45
|
+
background: rgba(210, 187, 255, 0.12);
|
|
46
|
+
box-shadow: inset 2px 0 0 0 var(--ld-primary), inset 0 0 10px rgba(210, 187, 255, 0.25);
|
|
47
|
+
}
|
|
@@ -31,3 +31,45 @@
|
|
|
31
31
|
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-tabpanel {
|
|
32
32
|
padding: var(--ld-space-3) 0;
|
|
33
33
|
}
|
|
34
|
+
|
|
35
|
+
/* Sliding indicator: one lit bar on the tablist, pinned to the active tab by
|
|
36
|
+
* anchor positioning, takes over the underline. Its inline edges transition
|
|
37
|
+
* separately — with data-ld-dir ("forward" | "back", set by the Tabs
|
|
38
|
+
* component) the edge nearer the target leads and the far edge trails, so the
|
|
39
|
+
* light reaches for the tab; without it the bar just slides. Browsers without
|
|
40
|
+
* anchor positioning keep the static underline above. */
|
|
41
|
+
@supports (anchor-name: --ld-a) and (anchor-scope: --ld-a) {
|
|
42
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-tabs {
|
|
43
|
+
position: relative;
|
|
44
|
+
anchor-scope: --ld-tab-active;
|
|
45
|
+
}
|
|
46
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-tabs :is(.ld-tab--active, .ld-tab[aria-selected="true"]) {
|
|
47
|
+
anchor-name: --ld-tab-active;
|
|
48
|
+
border-bottom-color: transparent;
|
|
49
|
+
}
|
|
50
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-tabs:where(:has(.ld-tab--active, .ld-tab[aria-selected="true"]))::after {
|
|
51
|
+
content: "";
|
|
52
|
+
position: absolute;
|
|
53
|
+
position-anchor: --ld-tab-active;
|
|
54
|
+
inset-block-end: anchor(bottom);
|
|
55
|
+
inset-inline: anchor(start) anchor(end);
|
|
56
|
+
block-size: 2px;
|
|
57
|
+
background: var(--ld-primary);
|
|
58
|
+
box-shadow: 0 0 10px var(--ld-primary-glow), 0 0 2px var(--ld-primary);
|
|
59
|
+
pointer-events: none;
|
|
60
|
+
transition: inset-inline-start var(--ld-slide-lead), inset-inline-end var(--ld-slide-lead);
|
|
61
|
+
}
|
|
62
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-tabs[data-ld-dir="forward"]::after {
|
|
63
|
+
transition: inset-inline-start var(--ld-slide-trail), inset-inline-end var(--ld-slide-lead);
|
|
64
|
+
}
|
|
65
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-tabs[data-ld-dir="back"]::after {
|
|
66
|
+
transition: inset-inline-start var(--ld-slide-lead), inset-inline-end var(--ld-slide-trail);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@media (prefers-reduced-motion: reduce) {
|
|
71
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-tabs::after,
|
|
72
|
+
:where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-tabs[data-ld-dir]::after {
|
|
73
|
+
transition: none;
|
|
74
|
+
}
|
|
75
|
+
}
|
package/neon-butterfly/design.md
CHANGED
|
@@ -50,22 +50,78 @@ appear only on interaction or state. Never use pure white or pure black.
|
|
|
50
50
|
Class prefix `ld-`. Variants use BEM-ish modifiers (`ld-btn--accent`).
|
|
51
51
|
|
|
52
52
|
- **Card** `.ld-card` — frosted glass panel.
|
|
53
|
+
- **Status card** `.ld-status-card` — dense dashboard card (from pulse's repo
|
|
54
|
+
card): 3px left edge takes a semantic `--<tone>`, `data-ld-attention="<tone>"`
|
|
55
|
+
adds an outline + glow ring, `data-ld-changed` replays a 30s tint flash.
|
|
56
|
+
Parts: `__watermark`, `__head`, `__prefix`, `__title`, `__meta`, `__note`,
|
|
57
|
+
`__rows`, `__row` (`-lead`/`-main`/`-trail`), `__footer`, `__empty`.
|
|
53
58
|
- **NavLink** `.ld-link` — the switchboard link: `>` chevron turns lime on hover.
|
|
54
59
|
- **Button** `.ld-btn` — `--primary`, `--accent`, `--danger` variants; `--sm`
|
|
55
60
|
compact size (badge-scaled) for inline/table-row actions.
|
|
61
|
+
- **Hold button** `.ld-btn--hold` (+ `__ring`, `__body`, `__label`, `__hint`,
|
|
62
|
+
`__meter`) — hold-to-confirm: a 3px conic ring around the icon well fills
|
|
63
|
+
as `--ld-hold` goes 0→1. `--danger` paints it **lime** — this theme reads
|
|
64
|
+
the ring as an activity signal, not a warning; `--primary` lilac,
|
|
65
|
+
`--accent` lime. `data-ld-hold="fired"` lights the border and glows
|
|
66
|
+
(dropped under reduced motion; the fill stays). Window:
|
|
67
|
+
`--ld-hold-duration` 250 ms — terminal-quick.
|
|
68
|
+
- **Button group** `.ld-btn-group` (+ `--block`) — one long track with
|
|
69
|
+
`.ld-btn` segments lined up inside; the track owns the chrome and the
|
|
70
|
+
segments drop theirs. Glass track, hairline border, faint mono labels.
|
|
71
|
+
The pressed segment (`aria-pressed="true"` / `.ld-btn--active`) takes the
|
|
72
|
+
lilac edge and a lilac text glow; no hover pulse inside the track.
|
|
73
|
+
With one pressed segment the chrome is a single sliding pill: the edge
|
|
74
|
+
nearer the new segment leads, the far edge trails on a spring that squashes ~7% and settles
|
|
75
|
+
(`--ld-slide-lead` / `--ld-slide-trail`, direction from `data-ld-dir`).
|
|
76
|
+
Variants tint the label only; `--block` fills the row with equal-width
|
|
77
|
+
segments. Use `role="group"` + `aria-label`.
|
|
78
|
+
- **Icon button** `.ld-icon-btn` (+ `--active`, `--danger`) — chromeless
|
|
79
|
+
2rem square for icon-only actions (`<button>` or `<a>`; always
|
|
80
|
+
`aria-label`). Faint glyph that turns lilac on hover; active
|
|
81
|
+
(`--active`, `aria-pressed="true"`, `aria-current="page"`) is lilac with a
|
|
82
|
+
soft glow. `--danger` turns the glyph red on hover. Child `svg` 1.25em.
|
|
56
83
|
- **Form** `.ld-input`, `.ld-textarea`, `.ld-select`, `.ld-label`, `.ld-field`,
|
|
57
84
|
`.ld-checkbox`, `.ld-radio`, `.ld-switch`, `.ld-choice` — checked states glow lime.
|
|
58
|
-
- **Badge** `.ld-badge` + semantic modifiers
|
|
85
|
+
- **Badge** `.ld-badge` + semantic modifiers; `--sm` is the 9px dashboard
|
|
86
|
+
pill, `--pulse` the one solid amber call to action with a breathing glow.
|
|
59
87
|
- **Alert** `.ld-alert` — left accent bar carries the semantic color.
|
|
60
88
|
- **Dialog** `.ld-dialog` — native `<dialog>`, lilac border + glow, blurred backdrop.
|
|
61
|
-
- **Tabs** `.ld-tabs`/`.ld-tab`/`.ld-tabpanel` — active tab underlined in lilac with text glow.
|
|
62
|
-
- **Table** `.ld-table` — lilac header rule, glass row hover.
|
|
89
|
+
- **Tabs** `.ld-tabs`/`.ld-tab`/`.ld-tabpanel` — active tab underlined in lilac with text glow; the underline is one lit bar that stretches to the new tab and snaps back (same slide tokens).
|
|
90
|
+
- **Table** `.ld-table` — lilac header rule, glass row hover. `.ld-table--interactive` adds the pointer, a lilac focus outline, and a selected row (`aria-selected`) with a lilac left bar and inner glow.
|
|
63
91
|
- **Progress** `.ld-progress`, **Spinner** `.ld-spinner` — glowing lilac indicators.
|
|
92
|
+
- **App shell** `.ld-shell` (+ `__skip`, `__header`, `__toggle`, `__brand`,
|
|
93
|
+
`__actions`, `__nav`, `__scrim`, `__main`, `__footer`; `.ld-topnav`/`__item`;
|
|
94
|
+
`.ld-sidenav` + `__section`, `__heading`, `__item`, `__icon`, `__label`,
|
|
95
|
+
`__badge`, `__footer`) — brand uppercase lilac with a glow text-shadow; section headings prefixed with a lime `//`. Items are uppercase mono; hover nudges right with a lilac border and lights the icon lime; the current page is a lilac-bordered pane with a slow pulsing glow and a lime icon. The header and nav are unfilled — hairline
|
|
96
|
+
borders over the page background (`.ld-bg`), which the shell paints; the
|
|
97
|
+
header blurs what scrolls under it. The drawer and tab bar take a fill. Structure (`components/layout.css`) is shared by every theme:
|
|
98
|
+
collapsed rail on `data-ld-nav-collapsed`, drawer on `data-ld-nav-open`
|
|
99
|
+
below 48rem, `--tabbar` docks the nav at the bottom. The header
|
|
100
|
+
always spans the full width above the nav.
|
|
101
|
+
- **Page layouts** `.ld-page` (`--narrow`/`--wide`/`--full`, `__header`,
|
|
102
|
+
`__eyebrow`, `__title`, `__subtitle`, `__actions`), `.ld-grid`,
|
|
103
|
+
`.ld-split`, `.ld-aside-layout`, `.ld-center` — structure only
|
|
104
|
+
(`components/page.css`, shared by every theme); the page
|
|
105
|
+
title uses the display face.
|
|
106
|
+
- **Stepper** `.ld-stepper` (+ `__step`, `__node`, `__label`) — milestone
|
|
107
|
+
rail: glowing lilac fill on a surface track, 2rem nodes, uppercase mono
|
|
108
|
+
labels. `__step--complete` is a solid lilac node; `--current` is the
|
|
109
|
+
activity signal — 2px lime border, lime icon and glow, lime label;
|
|
110
|
+
`--upcoming` a hairline surface node in faint. The rail is per-step
|
|
111
|
+
(`::before` track, `::after` fill), so the fill follows the modifiers and
|
|
112
|
+
`aria-current="step"` marks the active node.
|
|
64
113
|
- **Muted text** `.ld-muted` — faint secondary/empty-state text;
|
|
65
114
|
`color: var(--ld-faint)` only, no italic — this theme's mono/uppercase
|
|
66
115
|
terminal voice never reaches for a literary flourish.
|
|
67
116
|
- **Pre / log block** `.ld-pre` — command/log `<pre>`; sunken background,
|
|
68
|
-
hairline border, radius, small mono, horizontal scroll.
|
|
117
|
+
hairline border, radius, small mono, horizontal scroll. `.ld-pre--log`
|
|
118
|
+
bounds it (`--ld-log-max-height`, 420px), scrolls both ways, wraps long
|
|
119
|
+
lines, and adds faint 4px scanlines.
|
|
120
|
+
- **Copy control** `.ld-pre-copy` — an `.ld-icon-btn` pinned top-right in
|
|
121
|
+
a `.ld-pre-wrap`; fades in on hover/focus-within, always shown on touch
|
|
122
|
+
(`hover: none`). `data-ld-copy="copied"` swaps the copy glyph for a
|
|
123
|
+
success-tinted check; `"failed"` tints it danger. Status goes to a
|
|
124
|
+
visually hidden `aria-live` `.ld-pre-copy-status`.
|
|
69
125
|
|
|
70
126
|
## Code syntax
|
|
71
127
|
|
package/neon-butterfly/index.css
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
/* neon-butterfly — full theme entry point */
|
|
2
2
|
@import "./tokens.css";
|
|
3
3
|
@import "./base.css";
|
|
4
|
+
@import "./components/layout.css";
|
|
5
|
+
@import "./components/shell.css";
|
|
6
|
+
@import "./components/page.css";
|
|
4
7
|
@import "./components/card.css";
|
|
8
|
+
@import "./components/status-card.css";
|
|
5
9
|
@import "./components/link.css";
|
|
6
10
|
@import "./components/button.css";
|
|
11
|
+
@import "./components/button-hold.css";
|
|
12
|
+
@import "./components/button-group.css";
|
|
13
|
+
@import "./components/icon-button.css";
|
|
7
14
|
@import "./components/form.css";
|
|
8
15
|
@import "./components/badge.css";
|
|
9
16
|
@import "./components/alert.css";
|
|
@@ -11,5 +18,6 @@
|
|
|
11
18
|
@import "./components/tabs.css";
|
|
12
19
|
@import "./components/table.css";
|
|
13
20
|
@import "./components/progress.css";
|
|
21
|
+
@import "./components/stepper.css";
|
|
14
22
|
@import "./components/muted.css";
|
|
15
23
|
@import "./components/pre.css";
|
|
@@ -62,6 +62,12 @@
|
|
|
62
62
|
--ld-radius-lg: 0.5rem; /* one radius everywhere is the look */
|
|
63
63
|
--ld-blur: 12px;
|
|
64
64
|
--ld-transition: 0.3s;
|
|
65
|
+
--ld-hold-duration: 250ms; /* (extra) hold-to-confirm commitment window */
|
|
66
|
+
/* (extra) sliding indicator — tabs underline, button-group pill. The edge
|
|
67
|
+
* nearer the target leads; the far edge trails on a spring that overshoots
|
|
68
|
+
* inward, so the light stretches across the gap and snaps back to shape. */
|
|
69
|
+
--ld-slide-lead: 0.22s cubic-bezier(0.2, 0.9, 0.3, 1);
|
|
70
|
+
--ld-slide-trail: 0.55s linear(0, 0.066, 0.22, 0.407, 0.591, 0.75, 0.876, 0.966, 1.024, 1.055, 1.067, 1.066, 1.057, 1.045, 1.032, 1.021, 1.011, 1.004, 1, 0.997, 0.996, 0.995, 0.996, 0.997, 1);
|
|
65
71
|
|
|
66
72
|
/* spacing */
|
|
67
73
|
--ld-space-1: 0.25rem;
|