@lepid-labs/styles 1.0.0 → 1.0.1
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/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/status-card.css +159 -0
- package/luminous-precision/components/stepper.css +108 -0
- package/luminous-precision/components/tabs.css +42 -0
- package/luminous-precision/design.md +33 -2
- package/luminous-precision/index.css +4 -0
- package/luminous-precision/tokens.css +6 -0
- 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/status-card.css +156 -0
- package/neon-butterfly/components/stepper.css +107 -0
- package/neon-butterfly/components/tabs.css +42 -0
- package/neon-butterfly/design.md +32 -2
- package/neon-butterfly/index.css +4 -0
- package/neon-butterfly/tokens.css +6 -0
- package/package.json +58 -15
- 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/status-card.css +158 -0
- package/summer-cloud/components/stepper.css +101 -0
- package/summer-cloud/components/tabs.css +42 -0
- package/summer-cloud/design.md +35 -1
- package/summer-cloud/index.css +4 -0
- package/summer-cloud/tokens.css +6 -0
package/neon-butterfly/index.css
CHANGED
|
@@ -2,8 +2,11 @@
|
|
|
2
2
|
@import "./tokens.css";
|
|
3
3
|
@import "./base.css";
|
|
4
4
|
@import "./components/card.css";
|
|
5
|
+
@import "./components/status-card.css";
|
|
5
6
|
@import "./components/link.css";
|
|
6
7
|
@import "./components/button.css";
|
|
8
|
+
@import "./components/button-hold.css";
|
|
9
|
+
@import "./components/button-group.css";
|
|
7
10
|
@import "./components/form.css";
|
|
8
11
|
@import "./components/badge.css";
|
|
9
12
|
@import "./components/alert.css";
|
|
@@ -11,5 +14,6 @@
|
|
|
11
14
|
@import "./components/tabs.css";
|
|
12
15
|
@import "./components/table.css";
|
|
13
16
|
@import "./components/progress.css";
|
|
17
|
+
@import "./components/stepper.css";
|
|
14
18
|
@import "./components/muted.css";
|
|
15
19
|
@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;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lepid-labs/styles",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
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
|
}
|
|
@@ -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,158 @@
|
|
|
1
|
+
/* summer-cloud — 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="summer-cloud"], [data-ld-style="summer-cloud"] *).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-high);
|
|
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
|
+
box-shadow: var(--ld-shadow-soft);
|
|
19
|
+
color: var(--ld-on-surface);
|
|
20
|
+
overflow: hidden;
|
|
21
|
+
transition: background var(--ld-transition), box-shadow var(--ld-transition);
|
|
22
|
+
}
|
|
23
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card:hover { box-shadow: var(--ld-shadow-raised); }
|
|
24
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card--info { border-left-color: var(--ld-info); }
|
|
25
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card--success { border-left-color: var(--ld-success); }
|
|
26
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card--warning { border-left-color: var(--ld-warning); }
|
|
27
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card--danger { border-left-color: var(--ld-danger); }
|
|
28
|
+
|
|
29
|
+
/* attention ring — the tone rides on the attribute value */
|
|
30
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card[data-ld-attention] {
|
|
31
|
+
outline: 1px solid color-mix(in srgb, var(--ld-status-attention) 70%, transparent);
|
|
32
|
+
box-shadow: 0 0 14px color-mix(in srgb, var(--ld-status-attention) 35%, transparent);
|
|
33
|
+
}
|
|
34
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card[data-ld-attention]:hover {
|
|
35
|
+
box-shadow: 0 0 18px color-mix(in srgb, var(--ld-status-attention) 55%, transparent);
|
|
36
|
+
}
|
|
37
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card[data-ld-attention="info"] { --ld-status-attention: var(--ld-info); }
|
|
38
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card[data-ld-attention="success"] { --ld-status-attention: var(--ld-success); }
|
|
39
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card[data-ld-attention="danger"] { --ld-status-attention: var(--ld-danger); }
|
|
40
|
+
|
|
41
|
+
/* change flash — fades from a primary tint back to the resting glass */
|
|
42
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card[data-ld-changed] { animation: ld-sc-status-flash 30s ease-out forwards; }
|
|
43
|
+
@keyframes ld-sc-status-flash {
|
|
44
|
+
from { background: color-mix(in srgb, var(--ld-primary) 14%, var(--ld-surface)); }
|
|
45
|
+
to { background: var(--ld-surface-glass-high); }
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card__watermark {
|
|
49
|
+
position: absolute;
|
|
50
|
+
top: 0;
|
|
51
|
+
left: -0.25rem;
|
|
52
|
+
width: 2rem;
|
|
53
|
+
height: 2rem;
|
|
54
|
+
color: var(--ld-on-surface);
|
|
55
|
+
opacity: 0.1;
|
|
56
|
+
pointer-events: none;
|
|
57
|
+
rotate: -25deg;
|
|
58
|
+
}
|
|
59
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card__watermark > svg { width: 100%; height: 100%; }
|
|
60
|
+
|
|
61
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card__head {
|
|
62
|
+
display: flex;
|
|
63
|
+
align-items: center;
|
|
64
|
+
justify-content: space-between;
|
|
65
|
+
gap: var(--ld-space-2);
|
|
66
|
+
padding: 0.625rem 0.75rem 0.5rem 0.875rem;
|
|
67
|
+
}
|
|
68
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card__title {
|
|
69
|
+
min-width: 0;
|
|
70
|
+
overflow: hidden;
|
|
71
|
+
font-family: var(--ld-font-display);
|
|
72
|
+
font-size: var(--ld-text-sm);
|
|
73
|
+
font-weight: var(--ld-font-weight-bold);
|
|
74
|
+
white-space: nowrap;
|
|
75
|
+
text-overflow: ellipsis;
|
|
76
|
+
color: inherit;
|
|
77
|
+
text-decoration: none;
|
|
78
|
+
transition: color var(--ld-transition);
|
|
79
|
+
}
|
|
80
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card__title[href]:hover { color: var(--ld-primary); }
|
|
81
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card__prefix { color: var(--ld-faint); }
|
|
82
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card__prefix::after { content: " / "; opacity: 0.5; }
|
|
83
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card__meta {
|
|
84
|
+
display: flex;
|
|
85
|
+
align-items: center;
|
|
86
|
+
gap: 0.375rem;
|
|
87
|
+
flex-shrink: 0;
|
|
88
|
+
}
|
|
89
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card__note {
|
|
90
|
+
font-size: 11px;
|
|
91
|
+
color: var(--ld-faint);
|
|
92
|
+
white-space: nowrap;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card__rows {
|
|
96
|
+
list-style: none;
|
|
97
|
+
margin: 0;
|
|
98
|
+
padding: 0;
|
|
99
|
+
border-top: 1px solid var(--ld-border);
|
|
100
|
+
}
|
|
101
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card__row {
|
|
102
|
+
display: grid;
|
|
103
|
+
grid-template-columns: auto 1fr auto;
|
|
104
|
+
align-items: baseline;
|
|
105
|
+
gap: 0.375rem;
|
|
106
|
+
padding: 0.3rem 0.75rem 0.3rem 0.875rem;
|
|
107
|
+
font-size: 12px;
|
|
108
|
+
color: inherit;
|
|
109
|
+
text-decoration: none;
|
|
110
|
+
transition: background 0.1s;
|
|
111
|
+
}
|
|
112
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card__row[href]:hover { background: var(--ld-sky-tint); }
|
|
113
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card__row-lead {
|
|
114
|
+
min-width: 1.5rem;
|
|
115
|
+
font-size: 11px;
|
|
116
|
+
font-weight: var(--ld-font-weight-bold);
|
|
117
|
+
color: var(--ld-faint);
|
|
118
|
+
text-align: right;
|
|
119
|
+
font-variant-numeric: tabular-nums;
|
|
120
|
+
}
|
|
121
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card__row-main {
|
|
122
|
+
min-width: 0;
|
|
123
|
+
overflow: hidden;
|
|
124
|
+
white-space: nowrap;
|
|
125
|
+
text-overflow: ellipsis;
|
|
126
|
+
color: var(--ld-on-surface);
|
|
127
|
+
}
|
|
128
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card__row-trail {
|
|
129
|
+
display: flex;
|
|
130
|
+
align-items: center;
|
|
131
|
+
gap: var(--ld-space-1);
|
|
132
|
+
flex-shrink: 0;
|
|
133
|
+
font-size: 10px;
|
|
134
|
+
color: var(--ld-faint);
|
|
135
|
+
}
|
|
136
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card__footer {
|
|
137
|
+
display: block;
|
|
138
|
+
padding: 0.3rem 0.875rem;
|
|
139
|
+
border-top: 1px solid var(--ld-border);
|
|
140
|
+
font-size: 11px;
|
|
141
|
+
color: var(--ld-faint);
|
|
142
|
+
text-decoration: none;
|
|
143
|
+
transition: color var(--ld-transition);
|
|
144
|
+
}
|
|
145
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card__footer[href]:hover { color: var(--ld-primary); }
|
|
146
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card__empty {
|
|
147
|
+
margin: 0;
|
|
148
|
+
padding: 0.375rem 0.875rem 0.5rem;
|
|
149
|
+
border-top: 1px solid var(--ld-border);
|
|
150
|
+
font-size: 12px;
|
|
151
|
+
color: var(--ld-faint);
|
|
152
|
+
opacity: 0.7;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
@media (prefers-reduced-motion: reduce) {
|
|
156
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card { transition: none; }
|
|
157
|
+
:where([data-ld-style="summer-cloud"], [data-ld-style="summer-cloud"] *).ld-status-card[data-ld-changed] { animation: none; }
|
|
158
|
+
}
|