@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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lepid-labs/styles",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Shared design-system styles: tokens, base styles, and component classes per theme.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -19,22 +19,65 @@
|
|
|
19
19
|
"summer-cloud",
|
|
20
20
|
"luminous-precision",
|
|
21
21
|
"all.css",
|
|
22
|
-
"manifest.json"
|
|
22
|
+
"manifest.json",
|
|
23
|
+
"css.d.ts"
|
|
23
24
|
],
|
|
24
25
|
"exports": {
|
|
25
|
-
"./all":
|
|
26
|
+
"./all": {
|
|
27
|
+
"types": "./css.d.ts",
|
|
28
|
+
"default": "./all.css"
|
|
29
|
+
},
|
|
26
30
|
"./manifest": "./manifest.json",
|
|
27
|
-
"./neon-butterfly":
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
"./
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"./
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
"./neon-butterfly": {
|
|
32
|
+
"types": "./css.d.ts",
|
|
33
|
+
"default": "./neon-butterfly/index.css"
|
|
34
|
+
},
|
|
35
|
+
"./neon-butterfly/tokens": {
|
|
36
|
+
"types": "./css.d.ts",
|
|
37
|
+
"default": "./neon-butterfly/tokens.css"
|
|
38
|
+
},
|
|
39
|
+
"./neon-butterfly/base": {
|
|
40
|
+
"types": "./css.d.ts",
|
|
41
|
+
"default": "./neon-butterfly/base.css"
|
|
42
|
+
},
|
|
43
|
+
"./neon-butterfly/components/*": {
|
|
44
|
+
"types": "./css.d.ts",
|
|
45
|
+
"default": "./neon-butterfly/components/*.css"
|
|
46
|
+
},
|
|
47
|
+
"./summer-cloud": {
|
|
48
|
+
"types": "./css.d.ts",
|
|
49
|
+
"default": "./summer-cloud/index.css"
|
|
50
|
+
},
|
|
51
|
+
"./summer-cloud/tokens": {
|
|
52
|
+
"types": "./css.d.ts",
|
|
53
|
+
"default": "./summer-cloud/tokens.css"
|
|
54
|
+
},
|
|
55
|
+
"./summer-cloud/base": {
|
|
56
|
+
"types": "./css.d.ts",
|
|
57
|
+
"default": "./summer-cloud/base.css"
|
|
58
|
+
},
|
|
59
|
+
"./summer-cloud/components/*": {
|
|
60
|
+
"types": "./css.d.ts",
|
|
61
|
+
"default": "./summer-cloud/components/*.css"
|
|
62
|
+
},
|
|
63
|
+
"./luminous-precision": {
|
|
64
|
+
"types": "./css.d.ts",
|
|
65
|
+
"default": "./luminous-precision/index.css"
|
|
66
|
+
},
|
|
67
|
+
"./luminous-precision/tokens": {
|
|
68
|
+
"types": "./css.d.ts",
|
|
69
|
+
"default": "./luminous-precision/tokens.css"
|
|
70
|
+
},
|
|
71
|
+
"./luminous-precision/base": {
|
|
72
|
+
"types": "./css.d.ts",
|
|
73
|
+
"default": "./luminous-precision/base.css"
|
|
74
|
+
},
|
|
75
|
+
"./luminous-precision/components/*": {
|
|
76
|
+
"types": "./css.d.ts",
|
|
77
|
+
"default": "./luminous-precision/components/*.css"
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"devDependencies": {
|
|
81
|
+
"typescript": "^5.7.0"
|
|
39
82
|
}
|
|
40
83
|
}
|
package/summer-cloud/base.css
CHANGED
|
@@ -35,8 +35,12 @@
|
|
|
35
35
|
|
|
36
36
|
/* Opt-in page background: the sky gradient. Flat --ld-bg is also correct, but
|
|
37
37
|
* the gradient is the signature — the theme reads as "airy" only against it.
|
|
38
|
-
* Apply to <body>, or to the attributed container itself.
|
|
39
|
-
|
|
38
|
+
* Apply to <body>, or to the attributed container itself. An app shell
|
|
39
|
+
* (.ld-shell) always paints it, and so does the <body> around one, so the
|
|
40
|
+
* page stays covered past the shell (overscroll, short pages). */
|
|
41
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-bg,
|
|
42
|
+
:where(html[data-ld-style="summer-cloud"]) body:has(.ld-shell),
|
|
43
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-shell {
|
|
40
44
|
background: linear-gradient(135deg, var(--ld-sky-start) 0%, var(--ld-sky-end) 100%);
|
|
41
45
|
background-attachment: fixed;
|
|
42
46
|
}
|
|
@@ -21,6 +21,32 @@
|
|
|
21
21
|
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-badge--warning { background: var(--ld-warning); border-color: transparent; color: #241a00; }
|
|
22
22
|
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-badge--danger { background: var(--ld-danger); border-color: transparent; color: #4a0000; }
|
|
23
23
|
|
|
24
|
+
/* Compact size — dashboard pills inside .ld-status-card__meta and row trails. */
|
|
25
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-badge--sm {
|
|
26
|
+
padding: 0.125rem 0.375rem;
|
|
27
|
+
gap: 2px;
|
|
28
|
+
font-size: 9px;
|
|
29
|
+
letter-spacing: 0.06em;
|
|
30
|
+
}
|
|
31
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-badge[href] { text-decoration: none; }
|
|
32
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-badge[href]:hover { filter: brightness(1.1); }
|
|
33
|
+
|
|
34
|
+
/* Pulse — the one solid, glowing call to action (work is waiting on you). */
|
|
35
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-badge--pulse {
|
|
36
|
+
background: var(--ld-warning);
|
|
37
|
+
border-color: transparent;
|
|
38
|
+
color: #241a00;
|
|
39
|
+
box-shadow: 0 0 8px color-mix(in srgb, var(--ld-warning) 60%, transparent);
|
|
40
|
+
animation: ld-sc-badge-pulse 2s ease-in-out infinite;
|
|
41
|
+
}
|
|
42
|
+
@keyframes ld-sc-badge-pulse {
|
|
43
|
+
0%, 100% { box-shadow: 0 0 6px color-mix(in srgb, var(--ld-warning) 50%, transparent); }
|
|
44
|
+
50% { box-shadow: 0 0 16px color-mix(in srgb, var(--ld-warning) 90%, transparent); }
|
|
45
|
+
}
|
|
46
|
+
@media (prefers-reduced-motion: reduce) {
|
|
47
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-badge--pulse { animation: none; }
|
|
48
|
+
}
|
|
49
|
+
|
|
24
50
|
/* Chip — the filter variant: outlined until selected. */
|
|
25
51
|
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-chip {
|
|
26
52
|
display: inline-flex;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/* summer-cloud — button group: a long glass pill; segments are pills inside
|
|
2
|
+
* it and the pressed one floats up as a white chip with violet text. */
|
|
3
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group {
|
|
4
|
+
display: inline-flex;
|
|
5
|
+
align-items: stretch;
|
|
6
|
+
gap: var(--ld-space-1);
|
|
7
|
+
max-width: 100%;
|
|
8
|
+
padding: var(--ld-space-1);
|
|
9
|
+
background: rgba(255, 255, 255, 0.4);
|
|
10
|
+
border: 1px solid var(--ld-border);
|
|
11
|
+
border-radius: var(--ld-radius-pill);
|
|
12
|
+
}
|
|
13
|
+
/* --block: fill the row, equal-width segments */
|
|
14
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group--block {
|
|
15
|
+
display: flex;
|
|
16
|
+
}
|
|
17
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group--block > .ld-btn {
|
|
18
|
+
flex: 1 1 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* segments: the pill is the chrome, so the button drops its own */
|
|
22
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group > .ld-btn {
|
|
23
|
+
padding-block: var(--ld-space-2);
|
|
24
|
+
background: transparent;
|
|
25
|
+
border-color: transparent;
|
|
26
|
+
box-shadow: none;
|
|
27
|
+
color: var(--ld-faint);
|
|
28
|
+
font-weight: var(--ld-font-weight-medium);
|
|
29
|
+
white-space: nowrap;
|
|
30
|
+
}
|
|
31
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group > .ld-btn--sm {
|
|
32
|
+
padding-block: 0.25rem;
|
|
33
|
+
}
|
|
34
|
+
/* variants tint the label only — a solid fill would break the pill */
|
|
35
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group > .ld-btn--primary {
|
|
36
|
+
color: var(--ld-primary);
|
|
37
|
+
}
|
|
38
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group > .ld-btn--accent {
|
|
39
|
+
color: var(--ld-accent-deep);
|
|
40
|
+
}
|
|
41
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group > .ld-btn--danger {
|
|
42
|
+
color: var(--ld-danger-deep);
|
|
43
|
+
}
|
|
44
|
+
/* no hover scale inside the pill — neighbours would overlap; the press stays */
|
|
45
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group > .ld-btn:hover,
|
|
46
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group > .ld-btn:focus-visible {
|
|
47
|
+
background: var(--ld-sky-tint);
|
|
48
|
+
border-color: transparent;
|
|
49
|
+
box-shadow: none;
|
|
50
|
+
color: var(--ld-primary);
|
|
51
|
+
transform: none;
|
|
52
|
+
}
|
|
53
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group > .ld-btn--accent:hover,
|
|
54
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group > .ld-btn--accent:focus-visible {
|
|
55
|
+
color: var(--ld-accent-deep);
|
|
56
|
+
}
|
|
57
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group > .ld-btn--danger:hover,
|
|
58
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group > .ld-btn--danger:focus-visible {
|
|
59
|
+
color: var(--ld-danger-deep);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/* pressed segment (toggle / segmented use): the floating white chip */
|
|
63
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group > .ld-btn--active,
|
|
64
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group > .ld-btn[aria-pressed="true"] {
|
|
65
|
+
background: var(--ld-surface);
|
|
66
|
+
color: var(--ld-primary);
|
|
67
|
+
font-weight: var(--ld-font-weight-bold);
|
|
68
|
+
box-shadow: 0 2px 8px var(--ld-primary-border);
|
|
69
|
+
}
|
|
70
|
+
/* after the pressed rule so the focus ring survives on the pressed segment */
|
|
71
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group > .ld-btn:focus-visible {
|
|
72
|
+
box-shadow: 0 0 0 4px var(--ld-accent-glow);
|
|
73
|
+
}
|
|
74
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group > .ld-btn:active {
|
|
75
|
+
transform: scale(0.97);
|
|
76
|
+
}
|
|
77
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group > .ld-btn:disabled {
|
|
78
|
+
background: transparent;
|
|
79
|
+
color: var(--ld-faint);
|
|
80
|
+
transform: none;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/* Sliding pill: with exactly one pressed segment, its chrome moves to one
|
|
84
|
+
* chip on the track, pinned to the segment by anchor positioning, so a
|
|
85
|
+
* change of selection travels instead of blinking. Its inline edges transition
|
|
86
|
+
* separately — with data-ld-dir ("forward" | "back", set by ButtonGroup) the
|
|
87
|
+
* edge nearer the target leads and the far edge trails, stretching the pill
|
|
88
|
+
* across the gap; without it the pill just slides. Several pressed segments
|
|
89
|
+
* (multi-toggle), or no anchor positioning, keep the per-segment chrome above. */
|
|
90
|
+
@supports (anchor-name: --ld-a) and (anchor-scope: --ld-a) {
|
|
91
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group {
|
|
92
|
+
position: relative;
|
|
93
|
+
isolation: isolate;
|
|
94
|
+
anchor-scope: --ld-btn-group-active;
|
|
95
|
+
}
|
|
96
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group:not(:has(> :is(.ld-btn--active, .ld-btn[aria-pressed="true"]) ~ :is(.ld-btn--active, .ld-btn[aria-pressed="true"]))) > :is(.ld-btn--active, .ld-btn[aria-pressed="true"]) {
|
|
97
|
+
anchor-name: --ld-btn-group-active;
|
|
98
|
+
background: transparent;
|
|
99
|
+
box-shadow: none;
|
|
100
|
+
}
|
|
101
|
+
/* same weight as the rule above, so the focus ring survives on the pressed segment */
|
|
102
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group:not(:has(> :is(.ld-btn--active, .ld-btn[aria-pressed="true"]) ~ :is(.ld-btn--active, .ld-btn[aria-pressed="true"]))) > :is(.ld-btn--active, .ld-btn[aria-pressed="true"]):focus-visible {
|
|
103
|
+
box-shadow: 0 0 0 4px var(--ld-accent-glow);
|
|
104
|
+
}
|
|
105
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group:where(:has(> :is(.ld-btn--active, .ld-btn[aria-pressed="true"])):not(:has(> :is(.ld-btn--active, .ld-btn[aria-pressed="true"]) ~ :is(.ld-btn--active, .ld-btn[aria-pressed="true"]))))::before {
|
|
106
|
+
content: "";
|
|
107
|
+
position: absolute;
|
|
108
|
+
z-index: -1;
|
|
109
|
+
position-anchor: --ld-btn-group-active;
|
|
110
|
+
inset-block: anchor(top) anchor(bottom);
|
|
111
|
+
inset-inline: anchor(start) anchor(end);
|
|
112
|
+
background: var(--ld-surface);
|
|
113
|
+
border-radius: var(--ld-radius-pill);
|
|
114
|
+
box-shadow: 0 2px 8px var(--ld-primary-border);
|
|
115
|
+
pointer-events: none;
|
|
116
|
+
transition: inset-inline-start var(--ld-slide-lead), inset-inline-end var(--ld-slide-lead);
|
|
117
|
+
}
|
|
118
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group[data-ld-dir="forward"]::before {
|
|
119
|
+
transition: inset-inline-start var(--ld-slide-trail), inset-inline-end var(--ld-slide-lead);
|
|
120
|
+
}
|
|
121
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group[data-ld-dir="back"]::before {
|
|
122
|
+
transition: inset-inline-start var(--ld-slide-lead), inset-inline-end var(--ld-slide-trail);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
@media (prefers-reduced-motion: reduce) {
|
|
127
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group::before,
|
|
128
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn-group[data-ld-dir]::before {
|
|
129
|
+
transition: none;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/* summer-cloud — hold-to-confirm button: violet ring on a bouncy glass pill
|
|
2
|
+
*
|
|
3
|
+
* Contract: .ld-btn--hold composes with .ld-btn and any variant. The consumer
|
|
4
|
+
* writes one number, --ld-hold in [0, 1]; the ring fill is pure CSS.
|
|
5
|
+
* data-ld-hold="holding" | "fired" carries the behavioural state.
|
|
6
|
+
*/
|
|
7
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn--hold {
|
|
8
|
+
--ld-hold: 0;
|
|
9
|
+
--ld-hold-color: var(--ld-on-surface); /* neutral on its own */
|
|
10
|
+
position: relative;
|
|
11
|
+
gap: var(--ld-space-3);
|
|
12
|
+
padding: var(--ld-space-2) var(--ld-space-3) var(--ld-space-2) var(--ld-space-2);
|
|
13
|
+
text-align: left;
|
|
14
|
+
user-select: none;
|
|
15
|
+
-webkit-user-select: none;
|
|
16
|
+
touch-action: none; /* a touch hold must not turn into a scroll */
|
|
17
|
+
}
|
|
18
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn--hold.ld-btn--primary {
|
|
19
|
+
--ld-hold-color: var(--ld-primary);
|
|
20
|
+
}
|
|
21
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn--hold.ld-btn--accent {
|
|
22
|
+
--ld-hold-color: var(--ld-accent);
|
|
23
|
+
}
|
|
24
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn--hold.ld-btn--danger {
|
|
25
|
+
--ld-hold-color: var(--ld-primary);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* On the hold composition the ring and hint carry the danger state, so the
|
|
29
|
+
* pill stays glass: a violet ring on the solid red CTA would fight it, and the
|
|
30
|
+
* ring track would vanish. Deep red text keeps the intent legible. */
|
|
31
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn--hold.ld-btn--danger,
|
|
32
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn--hold.ld-btn--danger:hover,
|
|
33
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn--hold.ld-btn--danger:focus-visible {
|
|
34
|
+
background: rgba(255, 255, 255, 0.5);
|
|
35
|
+
border-color: var(--ld-outline);
|
|
36
|
+
color: var(--ld-danger-deep);
|
|
37
|
+
box-shadow: none;
|
|
38
|
+
}
|
|
39
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn--hold.ld-btn--danger:focus-visible {
|
|
40
|
+
box-shadow: 0 0 0 4px var(--ld-accent-glow);
|
|
41
|
+
}
|
|
42
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn--hold:active {
|
|
43
|
+
transform: none; /* the ring is the press feedback */
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* ring: the icon well, wrapped by a conic fill masked to a 3px stroke */
|
|
47
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn__ring {
|
|
48
|
+
position: relative;
|
|
49
|
+
display: inline-grid;
|
|
50
|
+
place-items: center;
|
|
51
|
+
flex: none;
|
|
52
|
+
width: 2.25rem;
|
|
53
|
+
height: 2.25rem;
|
|
54
|
+
border-radius: 50%;
|
|
55
|
+
background: var(--ld-surface-sunken);
|
|
56
|
+
color: var(--ld-hold-color);
|
|
57
|
+
}
|
|
58
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn__ring::before {
|
|
59
|
+
content: "";
|
|
60
|
+
position: absolute;
|
|
61
|
+
inset: 0;
|
|
62
|
+
border-radius: 50%;
|
|
63
|
+
background: conic-gradient(var(--ld-hold-color) calc(var(--ld-hold) * 360deg), var(--ld-outline) 0);
|
|
64
|
+
-webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2.5px));
|
|
65
|
+
mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2.5px));
|
|
66
|
+
}
|
|
67
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn__ring > svg {
|
|
68
|
+
width: 1rem;
|
|
69
|
+
height: 1rem;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn__body {
|
|
73
|
+
display: flex;
|
|
74
|
+
flex-direction: column;
|
|
75
|
+
align-items: flex-start;
|
|
76
|
+
gap: 0.125rem;
|
|
77
|
+
line-height: 1.2;
|
|
78
|
+
}
|
|
79
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn__label {
|
|
80
|
+
font-weight: var(--ld-font-weight-bold);
|
|
81
|
+
}
|
|
82
|
+
/* the hint and meter restate the ring, so state is never color-only */
|
|
83
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn__hint {
|
|
84
|
+
font-size: 11px;
|
|
85
|
+
font-weight: var(--ld-font-weight);
|
|
86
|
+
letter-spacing: normal;
|
|
87
|
+
text-transform: none;
|
|
88
|
+
color: var(--ld-faint);
|
|
89
|
+
}
|
|
90
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn__meter {
|
|
91
|
+
margin-left: auto;
|
|
92
|
+
min-width: 3.5ch;
|
|
93
|
+
text-align: right;
|
|
94
|
+
font-family: var(--ld-font-mono);
|
|
95
|
+
font-variant-numeric: tabular-nums;
|
|
96
|
+
font-size: 12px;
|
|
97
|
+
color: var(--ld-faint);
|
|
98
|
+
}
|
|
99
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn--hold[data-ld-hold="holding"] .ld-btn__meter {
|
|
100
|
+
color: var(--ld-hold-color);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* fired: the post-commit flash */
|
|
104
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn--hold[data-ld-hold="fired"] {
|
|
105
|
+
animation: ld-sc-hold-fired 0.5s var(--ld-ease-bounce);
|
|
106
|
+
}
|
|
107
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn--hold[data-ld-hold="fired"] .ld-btn__ring {
|
|
108
|
+
box-shadow: 0 0 16px color-mix(in srgb, var(--ld-hold-color) 55%, transparent);
|
|
109
|
+
}
|
|
110
|
+
@keyframes ld-sc-hold-fired {
|
|
111
|
+
0% {
|
|
112
|
+
transform: scale(1);
|
|
113
|
+
}
|
|
114
|
+
40% {
|
|
115
|
+
transform: scale(1.06);
|
|
116
|
+
}
|
|
117
|
+
100% {
|
|
118
|
+
transform: scale(1);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/* reduced motion: the ring still fills (it is the state, not decoration);
|
|
123
|
+
* only the flash and glow go */
|
|
124
|
+
@media (prefers-reduced-motion: reduce) {
|
|
125
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn--hold[data-ld-hold="fired"] {
|
|
126
|
+
animation: none;
|
|
127
|
+
box-shadow: none;
|
|
128
|
+
}
|
|
129
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-btn--hold[data-ld-hold="fired"] .ld-btn__ring {
|
|
130
|
+
box-shadow: none;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/* summer-cloud — icon button: round chromeless pill that fills sky-white and bounces on hover.
|
|
2
|
+
* Icon-only control (<button> or <a>): give it an accessible name (aria-label).
|
|
3
|
+
* Active/current: .ld-icon-btn--active, [aria-pressed="true"], [aria-current="page"]. */
|
|
4
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-icon-btn {
|
|
5
|
+
display: inline-flex;
|
|
6
|
+
align-items: center;
|
|
7
|
+
justify-content: center;
|
|
8
|
+
flex: none;
|
|
9
|
+
width: 2rem;
|
|
10
|
+
height: 2rem;
|
|
11
|
+
padding: 0;
|
|
12
|
+
background: none;
|
|
13
|
+
border: none;
|
|
14
|
+
border-radius: var(--ld-radius-pill);
|
|
15
|
+
color: var(--ld-faint);
|
|
16
|
+
font: inherit;
|
|
17
|
+
line-height: 1;
|
|
18
|
+
text-decoration: none;
|
|
19
|
+
cursor: pointer;
|
|
20
|
+
transition: background var(--ld-transition), color var(--ld-transition), box-shadow 0.2s ease, transform 0.2s var(--ld-ease-bounce);
|
|
21
|
+
}
|
|
22
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-icon-btn > svg {
|
|
23
|
+
width: 1.25em;
|
|
24
|
+
height: 1.25em;
|
|
25
|
+
flex: none;
|
|
26
|
+
}
|
|
27
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-icon-btn:hover,
|
|
28
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-icon-btn:focus-visible {
|
|
29
|
+
background: var(--ld-sky-tint);
|
|
30
|
+
color: var(--ld-primary);
|
|
31
|
+
transform: scale(1.06);
|
|
32
|
+
outline: none;
|
|
33
|
+
}
|
|
34
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-icon-btn:focus-visible {
|
|
35
|
+
box-shadow: 0 0 0 4px var(--ld-accent-glow);
|
|
36
|
+
}
|
|
37
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-icon-btn:active:not(:disabled) {
|
|
38
|
+
transform: scale(0.92);
|
|
39
|
+
}
|
|
40
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-icon-btn--active,
|
|
41
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-icon-btn[aria-pressed="true"],
|
|
42
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-icon-btn[aria-current="page"] {
|
|
43
|
+
background: var(--ld-sky-tint);
|
|
44
|
+
color: var(--ld-primary);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* danger: destructive action (delete, remove) — faint at rest, red on hover */
|
|
48
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-icon-btn--danger:hover,
|
|
49
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-icon-btn--danger:focus-visible {
|
|
50
|
+
color: var(--ld-danger-deep);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/* disabled: dimmed and inert — hover never lights it; [aria-disabled] covers <a> */
|
|
54
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-icon-btn:disabled,
|
|
55
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-icon-btn[aria-disabled="true"] {
|
|
56
|
+
opacity: 0.4;
|
|
57
|
+
color: var(--ld-faint);
|
|
58
|
+
background: none;
|
|
59
|
+
box-shadow: none;
|
|
60
|
+
transform: none;
|
|
61
|
+
cursor: not-allowed;
|
|
62
|
+
}
|
|
63
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-icon-btn[aria-disabled="true"] {
|
|
64
|
+
pointer-events: none;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@media (prefers-reduced-motion: reduce) {
|
|
68
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-icon-btn {
|
|
69
|
+
transition: none;
|
|
70
|
+
}
|
|
71
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-icon-btn:hover,
|
|
72
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-icon-btn:focus-visible,
|
|
73
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-icon-btn:active:not(:disabled) {
|
|
74
|
+
transform: none;
|
|
75
|
+
}
|
|
76
|
+
}
|