@apliteni/apliteni-ui 0.35.0 → 0.37.0
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/README.md +7 -0
- package/package.json +1 -1
- package/react/README.md +5 -0
- package/react/dist/index.css +4 -2
- package/react/dist/index.js +2 -1
- package/src/components/dropdown.js +2 -1
- package/src/styles/back.css +3 -3
- package/src/styles/badge.css +16 -16
- package/src/styles/base.css +6 -6
- package/src/styles/button.css +13 -13
- package/src/styles/callout.css +22 -22
- package/src/styles/card.css +6 -6
- package/src/styles/code.css +6 -6
- package/src/styles/command-palette.css +22 -22
- package/src/styles/confirm.css +3 -3
- package/src/styles/drawer.css +7 -7
- package/src/styles/dropdown.css +25 -23
- package/src/styles/empty.css +2 -2
- package/src/styles/feedback.css +14 -14
- package/src/styles/footer.css +5 -5
- package/src/styles/input.css +15 -15
- package/src/styles/layout.css +27 -27
- package/src/styles/loading.css +3 -3
- package/src/styles/motion.css +1 -1
- package/src/styles/nav.css +28 -28
- package/src/styles/pagination.css +6 -6
- package/src/styles/segmented.css +4 -4
- package/src/styles/stat.css +6 -6
- package/src/styles/success.css +7 -7
- package/src/styles/table.css +7 -7
- package/src/styles/tabs.css +4 -4
- package/src/styles/tooltip.css +3 -3
- package/src/styles/topbar.css +17 -17
- package/src/tokens/tokens.css +49 -7
package/README.md
CHANGED
|
@@ -151,6 +151,13 @@ Each accent re-points only the accent family (`--accent`, `--purple*`, `--glow-p
|
|
|
151
151
|
stay put — so **every accent works in both themes** and every component follows with no
|
|
152
152
|
component-level change.
|
|
153
153
|
|
|
154
|
+
Focus uses a surface-coloured gap, a solid band and a decorative glow. Tune
|
|
155
|
+
`--ring-width`, `--ring-color`, `--ring-gap-width` and `--ring-gap` at the root;
|
|
156
|
+
`--ring` remains the composed shadow. Kit surfaces recompose it to match their
|
|
157
|
+
background, so an ancestor's custom `--ring` must also be applied on those surfaces.
|
|
158
|
+
The page shell inherits root overrides; it does not introduce another composition.
|
|
159
|
+
See [the focus-ring contract](docs/specification.md#the-focus-ring).
|
|
160
|
+
|
|
154
161
|
Both attributes are overrides, not requirements: with neither present the kit paints dark
|
|
155
162
|
Nebula, and `data-accent` alone paints that accent on the dark theme. An absent `data-theme`
|
|
156
163
|
is *not* "follow the system" — the kit ships no `prefers-color-scheme` rule, so a host that
|
package/package.json
CHANGED
package/react/README.md
CHANGED
|
@@ -101,6 +101,11 @@ each other on the same page.
|
|
|
101
101
|
|
|
102
102
|
## Dropdown
|
|
103
103
|
|
|
104
|
+
Use `badge: { text: 'Archivado', tone: 'state' }` for off, unset, disabled or archived
|
|
105
|
+
states, including translated labels. Explicit `tone: 'neutral'` uses body ink. When tone
|
|
106
|
+
is omitted, exact English off/unset/disabled/archive/archived labels fall back to state
|
|
107
|
+
ink and Live to live ink; other labels use body ink. This also applies to vanilla `dropdown()`.
|
|
108
|
+
|
|
104
109
|
`Dropdown` renders the kit's `dropdown()` markup, class for class, and carries
|
|
105
110
|
`wireDropdown()`'s keyboard: the arrows open it onto the first row or the selected one and
|
|
106
111
|
then walk the ring, stepping over a disabled row and wrapping at both ends; Home and End go
|
package/react/dist/index.css
CHANGED
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
.rx-modal {
|
|
45
45
|
width: min(480px, 92vw);
|
|
46
46
|
background: var(--bg-elevated);
|
|
47
|
+
--ring-gap: var(--bg-elevated);
|
|
47
48
|
border: 1px solid var(--border-strong);
|
|
48
49
|
box-shadow: inset 0 0 0 1px var(--elev-edge, var(--border)), var(--elev-drop);
|
|
49
50
|
border-radius: var(--radius-xl);
|
|
@@ -92,10 +93,11 @@
|
|
|
92
93
|
color: inherit;
|
|
93
94
|
}
|
|
94
95
|
.rx-sort:focus-visible {
|
|
95
|
-
outline: 2px solid
|
|
96
|
-
|
|
96
|
+
outline: 2px solid transparent;
|
|
97
|
+
box-shadow: var(--ring);
|
|
97
98
|
border-radius: 4px;
|
|
98
99
|
}
|
|
99
100
|
.rx-caret {
|
|
100
101
|
margin-left: 2px;
|
|
102
|
+
color: var(--muted);
|
|
101
103
|
}
|
package/react/dist/index.js
CHANGED
|
@@ -1064,7 +1064,8 @@ var Glyph2 = ({ name, className, hidden }) => /* @__PURE__ */ jsx12(
|
|
|
1064
1064
|
function RowBadge({ badge }) {
|
|
1065
1065
|
const text2 = typeof badge === "string" ? badge : badge.text;
|
|
1066
1066
|
const given = typeof badge === "string" ? "" : badge.tone || "";
|
|
1067
|
-
|
|
1067
|
+
let tone = given || (/^live$/i.test(String(text2)) ? "live" : "neutral");
|
|
1068
|
+
if (!given && tone === "neutral" && /^(?:off|unset|disabled|archive|archived)$/i.test(text2)) tone = "state";
|
|
1068
1069
|
return /* @__PURE__ */ jsx12("span", { className: `ui-dropdown__badge is-${tone}`, children: text2 });
|
|
1069
1070
|
}
|
|
1070
1071
|
var keyOf = (it) => it.value != null ? `v:${it.value}` : `l:${it.label}`;
|
|
@@ -22,7 +22,8 @@ function ddBadge(badge) {
|
|
|
22
22
|
if (!badge) return '';
|
|
23
23
|
const text = typeof badge === 'string' ? badge : badge.text;
|
|
24
24
|
let tone = typeof badge === 'string' ? '' : (badge.tone || '');
|
|
25
|
-
if (!tone) tone = /^live$/i.test(text) ? 'live'
|
|
25
|
+
if (!tone) tone = /^live$/i.test(text) ? 'live'
|
|
26
|
+
: /^(?:off|unset|disabled|archive|archived)$/i.test(text) ? 'state' : 'neutral';
|
|
26
27
|
return `<span class="${cx('ui-dropdown__badge', `is-${tone}`)}">${esc(text)}</span>`;
|
|
27
28
|
}
|
|
28
29
|
|
package/src/styles/back.css
CHANGED
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
and outranks a bare class: it would paint this in the host's link colour.
|
|
31
31
|
(0,2,0) wins without !important — the argument `.ui-nav .ui-nav__item` makes
|
|
32
32
|
in nav.css. */
|
|
33
|
-
.ui-back[href] { color: var(--
|
|
34
|
-
.ui-back[href]:hover { color: var(--strong); background: var(--surface-2); }
|
|
35
|
-
.ui-back:focus-visible { outline:
|
|
33
|
+
.ui-back[href] { color: var(--text); }
|
|
34
|
+
.ui-back[href]:hover { color: var(--strong); background: var(--surface-2); /* ring-gap: inherit — control paint; its focus indicator uses the containing surface. */ }
|
|
35
|
+
.ui-back:focus-visible { outline: 2px solid transparent; box-shadow: var(--ring); }
|
|
36
36
|
|
|
37
37
|
/* 16px, with the stroke raised to match: the glyph set draws at 1.7 on a 24-unit
|
|
38
38
|
box, which is 1.13 CSS px at this size and under the kit's 1.5 for a stroked
|
package/src/styles/badge.css
CHANGED
|
@@ -14,30 +14,30 @@
|
|
|
14
14
|
font-weight: var(--weight-semibold);
|
|
15
15
|
padding: 3px 9px;
|
|
16
16
|
border-radius: var(--radius-pill);
|
|
17
|
-
color: var(--
|
|
18
|
-
background: var(--surface-2);
|
|
17
|
+
color: var(--text);
|
|
18
|
+
background: var(--surface-2); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */
|
|
19
19
|
white-space: nowrap;
|
|
20
20
|
}
|
|
21
21
|
/* Status chips take the --chip-* pairs, so the light app's solid fills live in
|
|
22
22
|
tokens.css rather than in a theme override down here: on white the glow-tints
|
|
23
23
|
wash out and the ink has to deepen to clear AA, and that is a token decision. */
|
|
24
|
-
.ui-badge--live { color: var(--chip-success-ink); background: var(--chip-success-fill); }
|
|
25
|
-
.ui-badge--soon { color: var(--purple-mid); background: var(--glow-purple); }
|
|
26
|
-
.ui-badge--info { color: var(--chip-info-ink); background: var(--chip-info-fill); }
|
|
24
|
+
.ui-badge--live { color: var(--chip-success-ink); background: var(--chip-success-fill); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */ }
|
|
25
|
+
.ui-badge--soon { color: var(--purple-mid); background: var(--glow-purple); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */ }
|
|
26
|
+
.ui-badge--info { color: var(--chip-info-ink); background: var(--chip-info-fill); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */ }
|
|
27
27
|
.ui-badge--warn { color: var(--chip-warn-ink); background: var(--chip-warn-fill); }
|
|
28
|
-
.ui-badge--danger { color: var(--chip-danger-ink); background: var(--chip-danger-fill); }
|
|
29
|
-
.ui-badge--archive { color: var(--muted); background: var(--surface); }
|
|
28
|
+
.ui-badge--danger { color: var(--chip-danger-ink); background: var(--chip-danger-fill); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */ }
|
|
29
|
+
.ui-badge--archive { /* muted-ink: state — archived record */ color: var(--muted); background: var(--surface); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */ }
|
|
30
30
|
|
|
31
31
|
/* Semantic status variants — for record/row status in data tables
|
|
32
32
|
(paid / verified / pending / failed …). Same chip, mapped to meaning. */
|
|
33
|
-
.ui-badge--success { color: var(--chip-success-ink); background: var(--chip-success-fill); }
|
|
33
|
+
.ui-badge--success { color: var(--chip-success-ink); background: var(--chip-success-fill); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */ }
|
|
34
34
|
.ui-badge--pending { color: var(--chip-warn-ink); background: var(--chip-warn-fill); }
|
|
35
|
-
.ui-badge--neutral { color: var(--
|
|
35
|
+
.ui-badge--neutral { color: var(--text); background: var(--surface-2); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */ }
|
|
36
36
|
|
|
37
37
|
/* The two neutral chips are the exception: their light fill is already in the
|
|
38
|
-
surface scale (--surface-3), and
|
|
39
|
-
:root[data-theme="light"] .ui-badge--neutral
|
|
40
|
-
:root[data-theme="light"] .ui-badge--archive { color: var(--muted); background: var(--surface-3); }
|
|
38
|
+
surface scale (--surface-3), and only archive uses muted state ink. */
|
|
39
|
+
:root[data-theme="light"] .ui-badge--neutral { background: var(--surface-3); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */ }
|
|
40
|
+
:root[data-theme="light"] .ui-badge--archive { /* muted-ink: state — archived record */ color: var(--muted); background: var(--surface-3); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */ }
|
|
41
41
|
|
|
42
42
|
/* Pill: same shape, sentence case, a touch larger — a metadata chip */
|
|
43
43
|
.ui-pill {
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
gap: 7px;
|
|
47
47
|
/* rank: chip */
|
|
48
48
|
font-size: var(--text-xs);
|
|
49
|
-
color: var(--
|
|
50
|
-
background: var(--surface-2);
|
|
49
|
+
color: var(--text);
|
|
50
|
+
background: var(--surface-2); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */
|
|
51
51
|
border-radius: var(--radius-pill);
|
|
52
52
|
padding: 4px 11px;
|
|
53
53
|
font-weight: var(--weight-semibold);
|
|
@@ -55,8 +55,8 @@
|
|
|
55
55
|
/* The live pill is the same status paint as the live badge, so it takes the
|
|
56
56
|
same pair. On its own it was --green on --glow-green, which is 3.97:1 over
|
|
57
57
|
white — under AA, while the badge beside it cleared at 4.64:1. See issue #131. */
|
|
58
|
-
.ui-pill--live { color: var(--chip-success-ink); background: var(--chip-success-fill); }
|
|
59
|
-
.ui-pill--soon { color: var(--purple-mid); background: var(--glow-purple); }
|
|
58
|
+
.ui-pill--live { color: var(--chip-success-ink); background: var(--chip-success-fill); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */ }
|
|
59
|
+
.ui-pill--soon { color: var(--purple-mid); background: var(--glow-purple); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */ }
|
|
60
60
|
|
|
61
61
|
/* Status dot */
|
|
62
62
|
.ui-dot {
|
package/src/styles/base.css
CHANGED
|
@@ -15,7 +15,7 @@ html {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
body {
|
|
18
|
-
background: var(--bg);
|
|
18
|
+
background: var(--bg); /* ring-gap: inherit — page background inherits root overrides. */
|
|
19
19
|
color: var(--text);
|
|
20
20
|
font-family: var(--font-sans);
|
|
21
21
|
font-weight: var(--weight-normal);
|
|
@@ -27,7 +27,7 @@ body {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
::selection {
|
|
30
|
-
background: color-mix(in srgb, var(--accent) 30%, transparent);
|
|
30
|
+
background: color-mix(in srgb, var(--accent) 30%, transparent); /* ring-gap: inherit — selection paint is not a focus container. */
|
|
31
31
|
color: var(--strong);
|
|
32
32
|
}
|
|
33
33
|
|
|
@@ -87,7 +87,7 @@ strong {
|
|
|
87
87
|
|
|
88
88
|
/* Spotlight — a soft radial from the top-centre (auth cards, focused heroes). */
|
|
89
89
|
.ui-bg-spotlight::before {
|
|
90
|
-
background: radial-gradient(620px 340px at 50% -12%, var(--glow-purple), transparent 70%);
|
|
90
|
+
background: radial-gradient(620px 340px at 50% -12%, var(--glow-purple), transparent 70%); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */
|
|
91
91
|
}
|
|
92
92
|
/* Grid — a faint token-coloured grid, masked to fade at the edges. */
|
|
93
93
|
.ui-bg-grid::before {
|
|
@@ -107,7 +107,7 @@ strong {
|
|
|
107
107
|
}
|
|
108
108
|
/* Accent wash — a gentle top-down tint in the current accent. */
|
|
109
109
|
.ui-bg-wash::before {
|
|
110
|
-
background: linear-gradient(180deg, var(--glow-purple), transparent 45%);
|
|
110
|
+
background: linear-gradient(180deg, var(--glow-purple), transparent 45%); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
/* Layout helpers used by the example apps */
|
|
@@ -120,7 +120,7 @@ strong {
|
|
|
120
120
|
/* rank: label */
|
|
121
121
|
font-size: var(--text-sm);
|
|
122
122
|
font-weight: var(--weight-medium);
|
|
123
|
-
color: var(--
|
|
123
|
+
color: var(--text);
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
/* Sensible default size for inline icons that a parent rule doesn't size.
|
|
@@ -142,6 +142,6 @@ svg:where(:not([width]):not([height])) {
|
|
|
142
142
|
.ui-input:focus-visible,
|
|
143
143
|
.ui-seg button:focus-visible,
|
|
144
144
|
.ui-switch:focus-visible {
|
|
145
|
-
outline:
|
|
145
|
+
outline: 2px solid transparent;
|
|
146
146
|
box-shadow: var(--ring);
|
|
147
147
|
}
|
package/src/styles/button.css
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
padding: var(--btn-pad-y) var(--btn-pad-x);
|
|
21
21
|
cursor: pointer;
|
|
22
22
|
border: 1px solid var(--border);
|
|
23
|
-
background: var(--surface-2);
|
|
23
|
+
background: var(--surface-2); /* ring-gap: inherit — control paint; its focus indicator uses the containing surface. */
|
|
24
24
|
color: var(--text);
|
|
25
25
|
white-space: nowrap;
|
|
26
26
|
transition: background var(--dur-fast) var(--ease),
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
|
|
33
33
|
.ui-btn:hover {
|
|
34
34
|
border-color: var(--accent);
|
|
35
|
-
background: color-mix(in srgb, var(--accent) 14%, var(--surface-2));
|
|
35
|
+
background: color-mix(in srgb, var(--accent) 14%, var(--surface-2)); /* ring-gap: inherit — control paint; its focus indicator uses the containing surface. */
|
|
36
36
|
color: var(--strong);
|
|
37
37
|
}
|
|
38
38
|
.ui-btn:active { transform: translateY(1px); }
|
|
@@ -56,19 +56,19 @@
|
|
|
56
56
|
.ui-btn--ghost {
|
|
57
57
|
background: transparent;
|
|
58
58
|
border-color: transparent;
|
|
59
|
-
color: var(--
|
|
59
|
+
color: var(--text);
|
|
60
60
|
}
|
|
61
61
|
.ui-btn--ghost:hover {
|
|
62
|
-
background: var(--surface-2);
|
|
62
|
+
background: var(--surface-2); /* ring-gap: inherit — control paint; its focus indicator uses the containing surface. */
|
|
63
63
|
border-color: transparent;
|
|
64
64
|
color: var(--strong);
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
.ui-btn--danger { color: var(--
|
|
67
|
+
.ui-btn--danger { color: var(--text); }
|
|
68
68
|
.ui-btn--danger:hover {
|
|
69
69
|
color: var(--pink);
|
|
70
70
|
border-color: var(--pink);
|
|
71
|
-
background: color-mix(in srgb, var(--pink) 10%, transparent);
|
|
71
|
+
background: color-mix(in srgb, var(--pink) 10%, transparent); /* ring-gap: inherit — control paint; its focus indicator uses the containing surface. */
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
/* -- Sizes -------------------------------------------------------------- */
|
|
@@ -93,9 +93,9 @@
|
|
|
93
93
|
makes this read as inert; the quiet ink is the rest. #220 */
|
|
94
94
|
.ui-btn:disabled,
|
|
95
95
|
.ui-btn[aria-disabled="true"] {
|
|
96
|
-
background: var(--disabled-surface);
|
|
96
|
+
background: var(--disabled-surface); /* ring-gap: inherit — control paint; its focus indicator uses the containing surface. */
|
|
97
97
|
border-color: var(--disabled-border);
|
|
98
|
-
color: var(--disabled-ink);
|
|
98
|
+
/* muted-ink: state — unavailable control */ color: var(--disabled-ink);
|
|
99
99
|
cursor: not-allowed;
|
|
100
100
|
pointer-events: none;
|
|
101
101
|
}
|
|
@@ -104,12 +104,12 @@
|
|
|
104
104
|
.ui-btn--ghost[aria-disabled="true"] {
|
|
105
105
|
background: transparent;
|
|
106
106
|
border-color: transparent;
|
|
107
|
-
color: var(--disabled-ink-bare);
|
|
107
|
+
/* muted-ink: state — unavailable control */ color: var(--disabled-ink-bare);
|
|
108
108
|
}
|
|
109
109
|
/* With no box, the ink is read on whatever is behind it, so the ghost takes an ink
|
|
110
110
|
set for the dullest ground: in dark 7.49 / 6.31 / 7.00 / 5.44 on --bg / --surface /
|
|
111
|
-
--surface-2 / --surface-3, in light 5.70 / 6.17 / 5.20 / 5.39. The enabled ghost
|
|
112
|
-
|
|
111
|
+
--surface-2 / --surface-3, in light 5.70 / 6.17 / 5.20 / 5.39. The enabled ghost now uses body
|
|
112
|
+
ink, keeping its words readable without changing the disabled pair. #273 cut this ink to rescue two
|
|
113
113
|
dark pairs from under #220's floor; #295 re-picked --muted against the elevation
|
|
114
114
|
ladder and lifted both clear, so it is the margin now rather than the rescue.
|
|
115
115
|
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
left: 10px; right: 10px; bottom: 5px;
|
|
138
138
|
height: 3px;
|
|
139
139
|
border-radius: 999px;
|
|
140
|
-
background: color-mix(in srgb, var(--accent) 22%, transparent);
|
|
140
|
+
background: color-mix(in srgb, var(--accent) 22%, transparent); /* ring-gap: inherit — decorative paint has no nested focus target. */
|
|
141
141
|
overflow: hidden;
|
|
142
142
|
/* Clean entrance: grow + fade in on state change, once. */
|
|
143
143
|
transform-origin: center;
|
|
@@ -156,7 +156,7 @@
|
|
|
156
156
|
/* On the filled primary the surface IS the accent, so shimmer in the contrast
|
|
157
157
|
colour instead — otherwise the bars vanish into the button. */
|
|
158
158
|
.ui-btn--primary .ui-btn__bars {
|
|
159
|
-
background: color-mix(in srgb, var(--accent-contrast) 26%, transparent);
|
|
159
|
+
background: color-mix(in srgb, var(--accent-contrast) 26%, transparent); /* ring-gap: inherit — decorative paint has no nested focus target. */
|
|
160
160
|
}
|
|
161
161
|
.ui-btn--primary .ui-btn__bars i {
|
|
162
162
|
background: linear-gradient(90deg,
|
package/src/styles/callout.css
CHANGED
|
@@ -7,23 +7,23 @@
|
|
|
7
7
|
gap: 12px;
|
|
8
8
|
padding: 15px 17px;
|
|
9
9
|
border-radius: var(--radius-md);
|
|
10
|
-
background: var(--surface-2);
|
|
10
|
+
background: var(--surface-2); --ring-gap: var(--surface-2);
|
|
11
11
|
font-size: calc(var(--text-sm) + 0.5px);
|
|
12
12
|
line-height: 1.55;
|
|
13
|
-
color: var(--
|
|
13
|
+
color: var(--text);
|
|
14
14
|
}
|
|
15
|
-
.ui-callout__icon { width: 18px; height: 18px; flex: none; margin-top: 1px; color: var(--muted); }
|
|
15
|
+
.ui-callout__icon { width: 18px; height: 18px; flex: none; margin-top: 1px; /* muted-ink: glyph — nonverbal callout icon */ color: var(--muted); }
|
|
16
16
|
.ui-callout__icon svg { width: 100%; height: 100%; stroke: currentColor; fill: none; stroke-width: 2.1; } /* 2.1 of a 24 box drawn at 18px = 1.58 CSS px, which is what buys the 3:1 graphic bar rather than the 4.5:1 text one. docs/specification.md#icons-and-glyphs */
|
|
17
17
|
.ui-callout b { color: var(--text); font-weight: var(--weight-semibold); }
|
|
18
18
|
.ui-callout code { font-family: var(--font-mono); font-size: 0.92em; color: var(--text); }
|
|
19
19
|
|
|
20
|
-
.ui-callout--info { background: var(--glow-cyan); }
|
|
20
|
+
.ui-callout--info { --ring-gap: inherit; background: var(--glow-cyan); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */ }
|
|
21
21
|
.ui-callout--info .ui-callout__icon { color: var(--chip-info-ink); } /* the chip inks, not the raw signals: in light the raw signal cleared the graphic bar by a tenth on its own wash and read as a smudge, and a stroke is read the way text is. The two are the same value in dark by construction, so only light moves. #206 */
|
|
22
|
-
.ui-callout--success { background: var(--glow-green); }
|
|
22
|
+
.ui-callout--success { --ring-gap: inherit; background: var(--glow-green); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */ }
|
|
23
23
|
.ui-callout--success .ui-callout__icon { color: var(--chip-success-ink); }
|
|
24
|
-
.ui-callout--warn { background: color-mix(in srgb, var(--amber) 13%, transparent); }
|
|
24
|
+
.ui-callout--warn { --ring-gap: inherit; background: color-mix(in srgb, var(--amber) 13%, transparent); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */ }
|
|
25
25
|
.ui-callout--warn .ui-callout__icon { color: var(--chip-warn-ink); }
|
|
26
|
-
.ui-callout--danger { background: var(--glow-pink); }
|
|
26
|
+
.ui-callout--danger { --ring-gap: inherit; background: var(--glow-pink); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */ }
|
|
27
27
|
.ui-callout--danger .ui-callout__icon { color: var(--chip-danger-ink); }
|
|
28
28
|
|
|
29
29
|
/* ----------------------------------------------------------------------------
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
.ui-toast--danger { --toast-accent: var(--pink); --toast-action-ink: var(--chip-danger-ink); --toast-glow: var(--glow-pink); --toast-on: var(--danger-contrast); --toast-solid: var(--signal-solid-danger); }
|
|
62
62
|
.ui-toast--warn { --toast-accent: var(--amber); --toast-action-ink: var(--chip-warn-ink); --toast-glow: color-mix(in srgb, var(--amber) 14%, transparent); --toast-on: var(--signal-contrast); --toast-solid: var(--signal-solid-warn); }
|
|
63
63
|
.ui-toast--info { --toast-accent: var(--cyan); --toast-action-ink: var(--chip-info-ink); --toast-glow: var(--glow-cyan); --toast-on: var(--signal-contrast); --toast-solid: var(--signal-solid-info); }
|
|
64
|
-
.ui-toast--neutral { --toast-accent: var(--muted); --toast-action-ink: var(--
|
|
64
|
+
.ui-toast--neutral { --toast-accent: var(--muted); --toast-action-ink: var(--text); --toast-glow: var(--surface-2); --toast-on: var(--signal-solid-ink); --toast-solid: var(--signal-solid-neutral); }
|
|
65
65
|
|
|
66
66
|
/* left status marker (soft + outline; solid is already a full fill) */
|
|
67
67
|
.ui-toast--soft::before,
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
.ui-toast__icon svg { width: 13px; height: 13px; stroke: currentColor; fill: none; stroke-width: 2.8; } /* 2.8 of a 24 box drawn at 13px = 1.52 CSS px. The circle has no room for a bigger glyph, so the weight comes out of the stroke. docs/specification.md#icons-and-glyphs */
|
|
75
75
|
.ui-toast__body { flex: 1; min-width: 0; }
|
|
76
76
|
.ui-toast__title { font-weight: var(--weight-medium); color: var(--strong); }
|
|
77
|
-
.ui-toast__text { color: var(--
|
|
77
|
+
.ui-toast__text { color: var(--text); }
|
|
78
78
|
|
|
79
79
|
/* trailing action ("Undo" / "Retry") — status-coloured TEXT, so it takes the
|
|
80
80
|
text-grade ink rather than the accent.
|
|
@@ -85,9 +85,9 @@
|
|
|
85
85
|
the ink is dark and darkens it where the ink is bright — the hovered pair is
|
|
86
86
|
at or above the resting pair in both. */
|
|
87
87
|
.ui-toast__action { flex: none; align-self: center; background: none; border: 0; padding: 4px 9px; border-radius: var(--radius-xs); font: inherit; font-weight: var(--weight-medium); color: var(--toast-action-ink); cursor: pointer; }
|
|
88
|
-
.ui-toast__action:hover { background: color-mix(in srgb, var(--bg) 55%, transparent); }
|
|
88
|
+
.ui-toast__action:hover { background: color-mix(in srgb, var(--bg) 55%, transparent); /* ring-gap: inherit — control paint; its focus indicator uses the containing surface. */ }
|
|
89
89
|
|
|
90
|
-
.ui-toast__close { flex: none; align-self: flex-start; background: none; border: 0; color: var(--muted); cursor: pointer; padding: 2px; display: grid; place-items: center; position: relative; font: inherit; }
|
|
90
|
+
.ui-toast__close { flex: none; align-self: flex-start; background: none; border: 0; /* muted-ink: glyph — dismiss icon */ color: var(--muted); cursor: pointer; padding: 2px; display: grid; place-items: center; position: relative; font: inherit; }
|
|
91
91
|
.ui-toast__close svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 2.5; }
|
|
92
92
|
/* The target, not the ink. WCAG 2.5.8 measures what a pointer can land on, and
|
|
93
93
|
the drawn button is 19x19 — a 15px glyph in 2px of padding. Growing the box
|
|
@@ -117,7 +117,7 @@
|
|
|
117
117
|
/* style: soft — tinted surface. The shadow used to be its edge, so it takes the
|
|
118
118
|
status-tinted hairline the outline style carries, at half the weight. #295 */
|
|
119
119
|
.ui-toast--soft {
|
|
120
|
-
background: var(--toast-glow);
|
|
120
|
+
background: var(--toast-glow); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */
|
|
121
121
|
border: 1px solid color-mix(in srgb, var(--toast-accent) 22%, transparent);
|
|
122
122
|
--elev-edge: color-mix(in srgb, var(--toast-accent) 11%, transparent);
|
|
123
123
|
}
|
|
@@ -130,8 +130,8 @@
|
|
|
130
130
|
clear each other — and four of the ten status x theme combinations did not.
|
|
131
131
|
Gated for all ten in stories/signal-contrast.test.js. See #149. */
|
|
132
132
|
.ui-toast--solid {
|
|
133
|
-
--toast-ink: var(--signal-solid-ink);
|
|
134
|
-
background: var(--toast-solid);
|
|
133
|
+
--toast-ink: var(--signal-solid-ink); --ring-color: var(--toast-ink);
|
|
134
|
+
background: var(--toast-solid); --ring-gap: var(--toast-solid);
|
|
135
135
|
color: var(--toast-ink);
|
|
136
136
|
/* No inner line: a solid toast has no outer one either. It keeps the drop. */
|
|
137
137
|
--elev-edge: transparent;
|
|
@@ -142,19 +142,19 @@
|
|
|
142
142
|
(--chip-success-ink in light). The opacity: 0.82 this replaced measured 4.19
|
|
143
143
|
there, and 2.25 on the dark danger fill — the pair was correct and the
|
|
144
144
|
dilution then spent it. */
|
|
145
|
-
.ui-toast--solid .ui-toast__text { color:
|
|
146
|
-
.ui-toast--solid .ui-toast__icon { background: color-mix(in srgb, var(--toast-ink) 22%, transparent); color: var(--toast-ink); }
|
|
145
|
+
.ui-toast--solid .ui-toast__text { color: var(--toast-ink); }
|
|
146
|
+
.ui-toast--solid .ui-toast__icon { background: color-mix(in srgb, var(--toast-ink) 22%, transparent); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */ color: var(--toast-ink); }
|
|
147
147
|
.ui-toast--solid .ui-toast__action { color: var(--toast-ink); }
|
|
148
148
|
/* Hover darkens the FILL rather than lightening the ink. Washing the ink over
|
|
149
149
|
itself was the one surface #149 did not reach, and it worked against the pair
|
|
150
150
|
it was drawn from: it pulled the fill towards the ink it has to clear. */
|
|
151
|
-
.ui-toast--solid .ui-toast__action:hover { background: color-mix(in srgb, var(--signal-contrast) 14%, transparent); }
|
|
152
|
-
.ui-toast--solid .ui-toast__close { color: color-mix(in srgb, var(--toast-ink) 68%, transparent); }
|
|
151
|
+
.ui-toast--solid .ui-toast__action:hover { background: color-mix(in srgb, var(--signal-contrast) 14%, transparent); /* ring-gap: inherit — control paint; its focus indicator uses the containing surface. */ }
|
|
152
|
+
.ui-toast--solid .ui-toast__close { /* muted-ink: glyph — dismiss icon on solid toast */ color: color-mix(in srgb, var(--toast-ink) 68%, transparent); }
|
|
153
153
|
.ui-toast--solid .ui-toast__close:hover { color: var(--toast-ink); }
|
|
154
|
-
.ui-toast--solid .ui-toast__timer { background: color-mix(in srgb, var(--toast-ink) 55%, transparent); }
|
|
154
|
+
.ui-toast--solid .ui-toast__timer { background: color-mix(in srgb, var(--toast-ink) 55%, transparent); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */ }
|
|
155
155
|
|
|
156
156
|
/* style: outline — elevated card with a status-tinted border */
|
|
157
|
-
.ui-toast--outline { background: var(--bg-elevated); border: 1px solid color-mix(in srgb, var(--toast-accent) 40%, transparent); --elev-edge: color-mix(in srgb, var(--toast-accent) 20%, transparent); }
|
|
157
|
+
.ui-toast--outline { background: var(--bg-elevated); --ring-gap: var(--bg-elevated); border: 1px solid color-mix(in srgb, var(--toast-accent) 40%, transparent); --elev-edge: color-mix(in srgb, var(--toast-accent) 20%, transparent); }
|
|
158
158
|
|
|
159
159
|
/* compact — single line, no body text */
|
|
160
160
|
.ui-toast--compact { align-items: center; padding-top: 10px; padding-bottom: 10px; }
|
|
@@ -178,7 +178,7 @@
|
|
|
178
178
|
border-radius: var(--radius-lg);
|
|
179
179
|
padding: 30px;
|
|
180
180
|
text-align: center;
|
|
181
|
-
background: var(--glow-green);
|
|
181
|
+
background: var(--glow-green); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */
|
|
182
182
|
}
|
|
183
183
|
.ui-success__check {
|
|
184
184
|
width: 48px; height: 48px;
|
|
@@ -191,4 +191,4 @@
|
|
|
191
191
|
}
|
|
192
192
|
.ui-success__check svg { width: 22px; height: 22px; stroke: currentColor; fill: none; stroke-width: 2.4; }
|
|
193
193
|
.ui-success__title { color: var(--strong); font-size: var(--text-lg); font-weight: var(--weight-semibold); margin-bottom: 5px; }
|
|
194
|
-
.ui-success__sub { color: var(--
|
|
194
|
+
.ui-success__sub { color: var(--text); font-size: var(--text-base); }
|
package/src/styles/card.css
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
/* Flat since #284 and edged in both themes since #295: the surface is the step, the
|
|
7
7
|
line is what makes it legible. why: docs/specification.md#elevation */
|
|
8
8
|
.ui-card {
|
|
9
|
-
background: var(--surface);
|
|
9
|
+
background: var(--surface); --ring-gap: var(--surface);
|
|
10
10
|
border: 1px solid var(--border);
|
|
11
11
|
border-radius: var(--radius-xl);
|
|
12
12
|
padding: var(--space-6) 26px;
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
/* An accent-tinted card, e.g. a highlighted plan / success surface. The accent edge is
|
|
29
29
|
the card's own hairline re-coloured: an inset ring over it would draw two. #295 */
|
|
30
30
|
.ui-card--accent {
|
|
31
|
-
background: color-mix(in srgb, var(--accent) 9%, var(--surface));
|
|
31
|
+
background: color-mix(in srgb, var(--accent) 9%, var(--surface)); --ring-gap: color-mix(in srgb, var(--accent) 9%, var(--surface));
|
|
32
32
|
border-color: color-mix(in srgb, var(--accent) 22%, transparent);
|
|
33
33
|
}
|
|
34
34
|
.ui-card--live {
|
|
35
|
-
background: color-mix(in srgb, var(--green) 10%, var(--surface));
|
|
35
|
+
background: color-mix(in srgb, var(--green) 10%, var(--surface)); --ring-gap: color-mix(in srgb, var(--green) 10%, var(--surface));
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
/* Interactive card (link / button semantics) */
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
margin: 0 0 5px;
|
|
65
65
|
}
|
|
66
66
|
.ui-card__sub {
|
|
67
|
-
color: var(--
|
|
67
|
+
color: var(--text);
|
|
68
68
|
font-size: var(--text-base);
|
|
69
69
|
line-height: var(--leading-snug);
|
|
70
70
|
margin-bottom: var(--space-5);
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
}
|
|
81
81
|
.ui-card__row + .ui-card__row { border-top: 1px solid var(--border); }
|
|
82
82
|
.ui-card__row .lab { color: var(--strong); font-size: var(--text-md); font-weight: var(--weight-medium); }
|
|
83
|
-
.ui-card__row .hint { color: var(--
|
|
83
|
+
.ui-card__row .hint { color: var(--text); font-size: calc(var(--text-sm) + 0.5px); margin-top: 3px; }
|
|
84
84
|
|
|
85
85
|
/* Icon chip that leads a card header */
|
|
86
86
|
.ui-card__icon {
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
border-radius: var(--radius-md);
|
|
90
90
|
display: grid;
|
|
91
91
|
place-items: center;
|
|
92
|
-
background: var(--glow-purple);
|
|
92
|
+
background: var(--glow-purple); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */
|
|
93
93
|
color: var(--accent);
|
|
94
94
|
flex: none;
|
|
95
95
|
}
|
package/src/styles/code.css
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* ========================================================================== */
|
|
5
5
|
|
|
6
6
|
.ui-snippet {
|
|
7
|
-
background: var(--surface-2);
|
|
7
|
+
background: var(--surface-2); --ring-gap: var(--surface-2);
|
|
8
8
|
border-radius: var(--radius-md);
|
|
9
9
|
overflow: hidden;
|
|
10
10
|
}
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
/* rank: label */
|
|
19
19
|
font-size: var(--text-sm);
|
|
20
20
|
font-weight: var(--weight-medium);
|
|
21
|
-
color: var(--
|
|
21
|
+
color: var(--text);
|
|
22
22
|
}
|
|
23
23
|
.ui-snippet pre {
|
|
24
24
|
margin: 0;
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
.ui-snippet__copy {
|
|
34
34
|
background: none;
|
|
35
35
|
border: 0;
|
|
36
|
-
color: var(--
|
|
36
|
+
color: var(--text);
|
|
37
37
|
cursor: pointer;
|
|
38
38
|
font-family: var(--font-sans);
|
|
39
39
|
font-size: calc(var(--text-xs) + 1px);
|
|
@@ -57,11 +57,11 @@
|
|
|
57
57
|
.ui-snippet pre .f { color: var(--cyan); }
|
|
58
58
|
.ui-snippet pre .s { color: var(--green); }
|
|
59
59
|
.ui-snippet pre .u { color: var(--cyan); }
|
|
60
|
-
.ui-snippet pre .c { color: var(--
|
|
60
|
+
.ui-snippet pre .c { color: var(--text); font-style: italic; }
|
|
61
61
|
|
|
62
62
|
/* Reveal: a live secret/token, tinted green */
|
|
63
63
|
.ui-snippet--reveal {
|
|
64
|
-
background: color-mix(in srgb, var(--green) 10%, var(--surface));
|
|
64
|
+
background: color-mix(in srgb, var(--green) 10%, var(--surface)); --ring-gap: color-mix(in srgb, var(--green) 10%, var(--surface));
|
|
65
65
|
}
|
|
66
66
|
.ui-snippet--reveal .ui-snippet__bar span { color: var(--green); }
|
|
67
67
|
.ui-snippet--reveal pre { color: var(--green); word-break: break-all; white-space: pre-wrap; }
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
.ui-code {
|
|
71
71
|
font-family: var(--font-mono);
|
|
72
72
|
font-size: 0.9em;
|
|
73
|
-
background: var(--surface-2);
|
|
73
|
+
background: var(--surface-2); --ring-gap: var(--surface-2);
|
|
74
74
|
padding: 2px 6px;
|
|
75
75
|
border-radius: var(--radius-xs);
|
|
76
76
|
color: var(--text);
|