@leftium/nimble.css 0.11.0 → 0.13.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 +9 -8
- package/dist/nimble-base.css +10 -12
- package/dist/nimble-base.min.css +1 -1
- package/dist/nimble-core.css +700 -651
- package/dist/nimble-core.min.css +1 -1
- package/dist/nimble-progress.css +0 -65
- package/dist/nimble-progress.min.css +1 -1
- package/dist/nimble.css +784 -800
- package/dist/nimble.min.css +1 -1
- package/no-nimble.js +111 -0
- package/package.json +4 -2
- package/src/_buttons.scss +20 -14
- package/src/_code.scss +2 -2
- package/src/_config.scss +5 -5
- package/src/_details.scss +9 -8
- package/src/_dialog.scss +23 -2
- package/src/_document.scss +11 -10
- package/src/_forms.scss +37 -23
- package/src/_grid-columns.scss +24 -23
- package/src/_layout-utilities.scss +43 -3
- package/src/_links.scss +1 -1
- package/src/_media.scss +2 -2
- package/src/_meter.scss +2 -2
- package/src/_print.scss +1 -1
- package/src/_progress.scss +4 -73
- package/src/_reset.scss +2 -2
- package/src/_select.scss +3 -2
- package/src/_tables.scss +3 -2
- package/src/_typography.scss +34 -33
- package/src/nimble-core.scss +8 -0
- package/src/nimble.scss +8 -0
package/src/_forms.scss
CHANGED
|
@@ -13,14 +13,15 @@
|
|
|
13
13
|
select, textarea) {
|
|
14
14
|
--_input-bg: color-mix(in oklch, var(#{$prefix}surface-1), var(#{$prefix}surface-2) 20%);
|
|
15
15
|
|
|
16
|
-
padding: 0.5em 0.75em;
|
|
16
|
+
padding: 0.5em 0.75em; // 0.5em: OP ~size-2; 0.75em: no OP match
|
|
17
|
+
// OP normalize: padding-block: --size-1, padding-inline: --size-2
|
|
17
18
|
min-height: calc(1em * 1.5 + 1em + 2px); // line-height + vertical padding + border
|
|
18
19
|
background-color: var(--_input-bg);
|
|
19
20
|
border: 1px solid var(#{$prefix}border);
|
|
20
21
|
border-radius: var(#{$prefix}radius);
|
|
21
22
|
color: var(#{$prefix}text);
|
|
22
23
|
font: inherit;
|
|
23
|
-
font-size: 1rem; // >=16px prevents iOS Safari auto-zoom on focus
|
|
24
|
+
font-size: 1rem; // OP --size-3; >=16px prevents iOS Safari auto-zoom on focus
|
|
24
25
|
transition: border-color 0.2s, box-shadow 0.2s;
|
|
25
26
|
}
|
|
26
27
|
|
|
@@ -31,6 +32,12 @@
|
|
|
31
32
|
margin-bottom: var(#{$prefix}spacing);
|
|
32
33
|
}
|
|
33
34
|
|
|
35
|
+
// When an input is the last visible child of a block that already has
|
|
36
|
+
// margin-bottom (e.g. <p>), kill the input's margin to avoid doubling.
|
|
37
|
+
:where(p, div) > :where(input, select, textarea):nth-last-child(1 of :not(datalist, script, style)) {
|
|
38
|
+
margin-bottom: 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
34
41
|
// ----- Focus -----
|
|
35
42
|
|
|
36
43
|
:where(input, select, textarea):focus-visible {
|
|
@@ -45,7 +52,7 @@
|
|
|
45
52
|
display: block;
|
|
46
53
|
margin-top: calc(var(#{$prefix}spacing) * -0.75); // pull up under the input
|
|
47
54
|
margin-bottom: var(#{$prefix}spacing);
|
|
48
|
-
font-size: 0.875em;
|
|
55
|
+
font-size: 0.875em; // no OP match (7/8)
|
|
49
56
|
color: color-mix(in oklch, var(#{$prefix}text), transparent 40%);
|
|
50
57
|
}
|
|
51
58
|
|
|
@@ -72,17 +79,17 @@
|
|
|
72
79
|
|
|
73
80
|
:where(label) {
|
|
74
81
|
display: block;
|
|
75
|
-
margin-bottom: 0.25em;
|
|
82
|
+
margin-bottom: 0.25em; // OP ~size-1 (em-relative)
|
|
76
83
|
}
|
|
77
84
|
|
|
78
85
|
:where(label:has(+ input, + select, + textarea)) {
|
|
79
|
-
font-weight: 600;
|
|
86
|
+
font-weight: 600; // OP --font-weight-6
|
|
80
87
|
}
|
|
81
88
|
|
|
82
89
|
// file and range are short/inline controls — increase the label gap to match
|
|
83
90
|
// the visual weight of the spacing above and beside them.
|
|
84
91
|
:where(label:has(+ [type="file"], + [type="range"])) {
|
|
85
|
-
margin-bottom: 0.5em;
|
|
92
|
+
margin-bottom: 0.5em; // OP ~size-2 (em-relative)
|
|
86
93
|
}
|
|
87
94
|
|
|
88
95
|
// ----- Fieldset -----
|
|
@@ -95,9 +102,16 @@
|
|
|
95
102
|
max-width: 100%;
|
|
96
103
|
}
|
|
97
104
|
|
|
105
|
+
// Kill last-child bottom margin so it doesn't stack with fieldset padding.
|
|
106
|
+
// Uses :nth-last-child(of ...) to skip invisible elements (datalist, script).
|
|
107
|
+
:where(fieldset) > :nth-last-child(1 of :not(datalist, script, style)),
|
|
108
|
+
:where(fieldset) > :nth-last-child(1 of :not(datalist, script, style)) > :nth-last-child(1 of :not(datalist, script, style)) {
|
|
109
|
+
margin-bottom: 0;
|
|
110
|
+
}
|
|
111
|
+
|
|
98
112
|
:where(legend) {
|
|
99
|
-
font-weight: 600;
|
|
100
|
-
padding-inline: 0.25em;
|
|
113
|
+
font-weight: 600; // OP --font-weight-6
|
|
114
|
+
padding-inline: 0.25em; // OP ~size-1 (em-relative)
|
|
101
115
|
}
|
|
102
116
|
|
|
103
117
|
// ----- Checkbox & Radio -----
|
|
@@ -105,16 +119,16 @@
|
|
|
105
119
|
|
|
106
120
|
:where([type="checkbox"], [type="radio"]) {
|
|
107
121
|
accent-color: var(#{$prefix}primary);
|
|
108
|
-
width: 1.125em;
|
|
109
|
-
height: 1.125em;
|
|
122
|
+
width: 1.125em; // no OP match (OP normalize: --size-3 = 1rem)
|
|
123
|
+
height: 1.125em; // no OP match (OP normalize: --size-3 = 1rem)
|
|
110
124
|
margin: 0; // Remove browser default margin so flex labels align flush left
|
|
111
125
|
}
|
|
112
126
|
|
|
113
127
|
:where(label:has([type="checkbox"], [type="radio"])) {
|
|
114
128
|
display: flex;
|
|
115
129
|
align-items: center;
|
|
116
|
-
gap: 0.35em;
|
|
117
|
-
margin-bottom: 0.5em;
|
|
130
|
+
gap: 0.35em; // no OP match (near ~size-1)
|
|
131
|
+
margin-bottom: 0.5em; // OP ~size-2 (em-relative)
|
|
118
132
|
}
|
|
119
133
|
|
|
120
134
|
// Last checkbox/radio label in a group drops its bottom margin
|
|
@@ -126,8 +140,8 @@
|
|
|
126
140
|
// ----- Search (pill shape) -----
|
|
127
141
|
|
|
128
142
|
:where([type="search"]) {
|
|
129
|
-
border-radius: 5rem;
|
|
130
|
-
padding-inline: 1.25em;
|
|
143
|
+
border-radius: 5rem; // OP --size-10 (pill)
|
|
144
|
+
padding-inline: 1.25em; // OP ~size-4 (em-relative)
|
|
131
145
|
}
|
|
132
146
|
|
|
133
147
|
// ----- Range -----
|
|
@@ -157,9 +171,9 @@
|
|
|
157
171
|
}
|
|
158
172
|
|
|
159
173
|
:where([type="file"])::file-selector-button {
|
|
160
|
-
padding: 0.5em 1em;
|
|
161
|
-
margin-right: 0.75em;
|
|
162
|
-
margin-inline-end: 0.75em;
|
|
174
|
+
padding: 0.5em 1em; // OP ~size-2 ~size-3 (em-relative)
|
|
175
|
+
margin-right: 0.75em; // no OP match (between ~size-2/~size-3)
|
|
176
|
+
margin-inline-end: 0.75em; // no OP match (between ~size-2/~size-3)
|
|
163
177
|
background-color: var(#{$prefix}primary);
|
|
164
178
|
color: var(#{$prefix}primary-contrast);
|
|
165
179
|
border: 1px solid var(#{$prefix}primary);
|
|
@@ -178,7 +192,7 @@
|
|
|
178
192
|
// Natural width so picker icon stays near content (excluded from full-width rule above).
|
|
179
193
|
// appearance: none is applied outside @layer (see below) to fix iOS Safari sizing.
|
|
180
194
|
:where([type="date"], [type="month"], [type="week"], [type="time"], [type="datetime-local"]) {
|
|
181
|
-
min-width: 10em; //
|
|
195
|
+
min-width: 10em; // no OP match; prevent collapse when empty (e.g. time with no value)
|
|
182
196
|
margin-bottom: var(#{$prefix}spacing);
|
|
183
197
|
}
|
|
184
198
|
|
|
@@ -188,7 +202,7 @@
|
|
|
188
202
|
--_color-size: calc(1em * 1.5 + 1em + 2px); // Match text input height
|
|
189
203
|
margin-bottom: var(#{$prefix}spacing);
|
|
190
204
|
|
|
191
|
-
--_color-pad: 0.25em;
|
|
205
|
+
--_color-pad: 0.25em; // OP ~size-1 (em-relative)
|
|
192
206
|
|
|
193
207
|
height: var(--_color-size);
|
|
194
208
|
width: calc((var(--_color-size) - 2 * var(--_color-pad)) * 1.618 + 2 * var(--_color-pad)); // Golden ratio inner swatch
|
|
@@ -216,14 +230,14 @@
|
|
|
216
230
|
:where(label:has([type="checkbox"][role="switch"])) {
|
|
217
231
|
display: flex;
|
|
218
232
|
align-items: center;
|
|
219
|
-
gap: 0.5em;
|
|
233
|
+
gap: 0.5em; // OP ~size-2 (em-relative)
|
|
220
234
|
}
|
|
221
235
|
|
|
222
236
|
:where([type="checkbox"][role="switch"]) {
|
|
223
237
|
appearance: none;
|
|
224
|
-
width: 2.5em;
|
|
225
|
-
height: 1.25em;
|
|
226
|
-
border-radius: 1em;
|
|
238
|
+
width: 2.5em; // no OP match (custom switch width)
|
|
239
|
+
height: 1.25em; // OP ~size-4 (em-relative)
|
|
240
|
+
border-radius: 1em; // OP ~size-3 (pill, em-relative)
|
|
227
241
|
background-color: var(#{$prefix}border);
|
|
228
242
|
position: relative;
|
|
229
243
|
cursor: pointer;
|
package/src/_grid-columns.scss
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// ==========================================================================
|
|
2
2
|
// nimble.css — Grid Column Assignment
|
|
3
|
-
// Assigns body's direct children to the centered content column (column
|
|
4
|
-
//
|
|
3
|
+
// Assigns body's direct children to the centered content column (column 2).
|
|
4
|
+
// 3-column grid: 1fr | content | 1fr
|
|
5
5
|
// Global (not scoped) so the body grid layout always applies.
|
|
6
6
|
// ==========================================================================
|
|
7
7
|
|
|
@@ -11,40 +11,41 @@
|
|
|
11
11
|
@layer nimble.base {
|
|
12
12
|
|
|
13
13
|
body > * {
|
|
14
|
-
grid-column:
|
|
14
|
+
grid-column: 2;
|
|
15
15
|
min-width: 0; // Allow grid children to shrink below intrinsic content width
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
|
|
18
19
|
// Fix for frameworks (SvelteKit, etc.) that insert a
|
|
19
20
|
// <div style="display: contents"> wrapper between <body> and content.
|
|
20
21
|
// display: contents removes the element from the box tree for layout,
|
|
21
22
|
// but NOT for CSS selector matching — so body > * misses the actual
|
|
22
23
|
// content elements. This rule mirrors the body > * rule above.
|
|
23
24
|
body > [style*='display: contents'] > * {
|
|
24
|
-
grid-column:
|
|
25
|
+
grid-column: 2;
|
|
25
26
|
min-width: 0;
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
// Content shadow: absolutely-positioned pseudo spanning full body height.
|
|
29
|
-
// Width
|
|
30
|
-
//
|
|
31
|
-
//
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
30
|
+
// Width = content column + shadow gap on each side, creating a visual
|
|
31
|
+
// separation between the shadow edge and the content.
|
|
32
|
+
// The clamp() formula handles visibility: shadow shows at full width when
|
|
33
|
+
// there's at least 2*gap of space on each side between shadow edge and
|
|
34
|
+
// viewport edge, otherwise snaps to 0. No breakpoint needed.
|
|
35
|
+
body::before {
|
|
36
|
+
content: '';
|
|
37
|
+
position: absolute;
|
|
38
|
+
top: 0;
|
|
39
|
+
bottom: 0;
|
|
40
|
+
left: 50%;
|
|
41
|
+
transform: translateX(-50%);
|
|
42
|
+
width: clamp(0px,
|
|
43
|
+
#{string.unquote('calc((100% - 2 * var(#{$prefix}spacing) - var(#{$prefix}content-width) - 4 * var(#{$prefix}content-shadow-gap)) * 9999)')},
|
|
44
|
+
#{string.unquote('calc(var(#{$prefix}content-width) + 2 * var(#{$prefix}content-shadow-gap))')}
|
|
45
|
+
);
|
|
46
|
+
box-shadow: var(#{$prefix}content-shadow);
|
|
47
|
+
pointer-events: none;
|
|
48
|
+
z-index: -1;
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
}
|
|
@@ -2,8 +2,15 @@
|
|
|
2
2
|
// nimble.css — Layout Utilities
|
|
3
3
|
// Global layout classes that interact with the body grid.
|
|
4
4
|
// Always available, including on .no-nimble elements.
|
|
5
|
+
//
|
|
6
|
+
// Breakout hierarchy (narrow → wide):
|
|
7
|
+
// (default) — content column (--nc-content-width)
|
|
8
|
+
// .bleed-edge — content + shadow gap on each side (shadow boundary)
|
|
9
|
+
// .bleed-wide — up to $wide-width (1200px), centered
|
|
10
|
+
// .bleed-full — full viewport width
|
|
5
11
|
// ==========================================================================
|
|
6
12
|
|
|
13
|
+
@use 'sass:string';
|
|
7
14
|
@use 'config' as *;
|
|
8
15
|
|
|
9
16
|
@if $enable-utilities {
|
|
@@ -24,17 +31,27 @@
|
|
|
24
31
|
padding-inline: var(#{$prefix}spacing);
|
|
25
32
|
}
|
|
26
33
|
|
|
27
|
-
// Break out
|
|
34
|
+
// Break out to shadow/paper edge (content + gap on each side).
|
|
35
|
+
// Uses the same shadow-visibility condition as the body::before pseudo:
|
|
36
|
+
// when the shadow is visible, caps at content-width + 2*gap (shadow boundary);
|
|
37
|
+
// when the shadow is hidden (narrow viewport), goes full width.
|
|
28
38
|
// position: relative creates a stacking context so background
|
|
29
39
|
// covers adjacent siblings' content shadows.
|
|
30
|
-
.
|
|
40
|
+
.bleed-edge {
|
|
31
41
|
grid-column: 1 / -1;
|
|
42
|
+
width: 100%;
|
|
43
|
+
max-width: clamp(
|
|
44
|
+
#{string.unquote('calc(var(#{$prefix}content-width) + 2 * var(#{$prefix}content-shadow-gap))')},
|
|
45
|
+
#{string.unquote('calc((100% - 2 * var(#{$prefix}spacing) - var(#{$prefix}content-width) - 4 * var(#{$prefix}content-shadow-gap)) * -9999)')},
|
|
46
|
+
100%
|
|
47
|
+
);
|
|
48
|
+
margin-inline: auto;
|
|
32
49
|
box-shadow: none;
|
|
33
50
|
position: relative;
|
|
34
51
|
}
|
|
35
52
|
|
|
36
53
|
// Break out to wide max-width
|
|
37
|
-
.wide {
|
|
54
|
+
.bleed-wide {
|
|
38
55
|
grid-column: 1 / -1;
|
|
39
56
|
box-shadow: none;
|
|
40
57
|
width: 100%;
|
|
@@ -43,6 +60,29 @@
|
|
|
43
60
|
padding-inline: var(#{$prefix}spacing);
|
|
44
61
|
}
|
|
45
62
|
|
|
63
|
+
// Break out of centered container to full viewport width.
|
|
64
|
+
// position: relative creates a stacking context so background
|
|
65
|
+
// covers adjacent siblings' content shadows.
|
|
66
|
+
.bleed-full {
|
|
67
|
+
grid-column: 1 / -1;
|
|
68
|
+
box-shadow: none;
|
|
69
|
+
position: relative;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Responsive equal-column grid
|
|
73
|
+
// Mobile: single column. Above phone breakpoint: auto-fit columns.
|
|
74
|
+
// margin-bottom matches vertical rhythm of p, ul, etc.
|
|
75
|
+
.grid {
|
|
76
|
+
display: grid;
|
|
77
|
+
grid-template-columns: 1fr;
|
|
78
|
+
gap: var(#{$prefix}spacing);
|
|
79
|
+
margin-bottom: var(#{$prefix}spacing);
|
|
80
|
+
|
|
81
|
+
@media (min-width: #{$breakpoint-phone}) {
|
|
82
|
+
grid-template-columns: repeat(auto-fit, minmax(0%, 1fr));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
46
86
|
}
|
|
47
87
|
|
|
48
88
|
}
|
package/src/_links.scss
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
:where(a:not([role="button"])) {
|
|
12
12
|
color: var(#{$prefix}primary);
|
|
13
13
|
text-decoration: underline;
|
|
14
|
-
text-underline-offset: 0.15em;
|
|
14
|
+
text-underline-offset: 0.15em; // no OP match; OP normalize: 1px (2px Firefox)
|
|
15
15
|
text-decoration-color: #{string.unquote('color-mix(in oklch, var(#{$prefix}primary), transparent 50%)')};
|
|
16
16
|
transition: color 0.2s, text-decoration-color 0.2s;
|
|
17
17
|
}
|
package/src/_media.scss
CHANGED
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
:where(figcaption) {
|
|
21
|
-
font-size: 0.9em;
|
|
21
|
+
font-size: 0.9em; // no OP match; OP normalize: --font-size-1 (1rem)
|
|
22
22
|
color: color-mix(in oklch, var(#{$prefix}text), transparent 40%);
|
|
23
|
-
margin-top: 0.5em;
|
|
23
|
+
margin-top: 0.5em; // OP ~size-2 (em-relative)
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
}
|
package/src/_meter.scss
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
-moz-appearance: none;
|
|
17
17
|
appearance: none;
|
|
18
18
|
width: 100%;
|
|
19
|
-
height: 0.5rem;
|
|
19
|
+
height: 0.5rem; // OP --size-2
|
|
20
20
|
overflow: hidden;
|
|
21
21
|
border: 0;
|
|
22
22
|
border-radius: var(#{$prefix}radius);
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
border-radius: var(#{$prefix}radius);
|
|
33
33
|
background-color: var(#{$prefix}surface-3);
|
|
34
34
|
border: 0;
|
|
35
|
-
height: 0.5rem;
|
|
35
|
+
height: 0.5rem; // OP --size-2
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
// WebKit: value bars for each semantic state
|
package/src/_print.scss
CHANGED
package/src/_progress.scss
CHANGED
|
@@ -8,81 +8,12 @@
|
|
|
8
8
|
|
|
9
9
|
@layer nimble.base {
|
|
10
10
|
|
|
11
|
+
// Native system progress bars on all platforms.
|
|
12
|
+
// Custom styling via appearance: none is broken on iOS Safari (partial
|
|
13
|
+
// stripping of native chrome) and cannot be scoped away from WebKit/Blink
|
|
14
|
+
// via CSS alone. Native bars look fine everywhere.
|
|
11
15
|
:where(progress) {
|
|
12
|
-
-webkit-appearance: none;
|
|
13
|
-
appearance: none;
|
|
14
|
-
position: relative;
|
|
15
16
|
width: 100%;
|
|
16
|
-
height: 0.5rem;
|
|
17
|
-
overflow: hidden;
|
|
18
|
-
border: 0;
|
|
19
|
-
border-radius: var(#{$prefix}radius);
|
|
20
|
-
background-color: var(#{$prefix}surface-3);
|
|
21
|
-
color: var(#{$prefix}primary); // Firefox uses color for the bar
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
:where(progress)::-webkit-progress-bar {
|
|
25
|
-
border-radius: var(#{$prefix}radius);
|
|
26
|
-
background-color: var(#{$prefix}surface-3);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
:where(progress)::-webkit-progress-value {
|
|
30
|
-
background-color: var(#{$prefix}primary);
|
|
31
|
-
border-radius: var(#{$prefix}radius);
|
|
32
|
-
transition: inline-size 0.3s ease;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
:where(progress)::-moz-progress-bar {
|
|
36
|
-
background-color: var(#{$prefix}primary);
|
|
37
|
-
border-radius: var(#{$prefix}radius);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Indeterminate: evenly-spaced blue bands travel continuously rightward.
|
|
41
|
-
// Gradient is 200% wide with two identical 10%-wide bands at 15% and 65%.
|
|
42
|
-
// They're 50% apart — exactly one visible width (100/200 = 50% of gradient).
|
|
43
|
-
// Animating position by -200% = one full gradient width → seamless loop.
|
|
44
|
-
:where(progress):not([value]) {
|
|
45
|
-
--nc-progress-track:
|
|
46
|
-
linear-gradient(to right,
|
|
47
|
-
var(#{$prefix}surface-3) 0%,
|
|
48
|
-
var(#{$prefix}primary) 25%,
|
|
49
|
-
var(#{$prefix}primary) 25%,
|
|
50
|
-
var(#{$prefix}surface-3) 50%,
|
|
51
|
-
var(#{$prefix}surface-3) 50%,
|
|
52
|
-
var(#{$prefix}primary) 75%,
|
|
53
|
-
var(#{$prefix}primary) 75%,
|
|
54
|
-
var(#{$prefix}surface-3) 100%);
|
|
55
|
-
--nc-progress-track-size: 200% 100%;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
@media (prefers-reduced-motion: no-preference) {
|
|
59
|
-
@supports selector(progress::after) {
|
|
60
|
-
:where(progress):not([value])::after {
|
|
61
|
-
content: "";
|
|
62
|
-
position: absolute;
|
|
63
|
-
inset: 0;
|
|
64
|
-
background: var(--nc-progress-track);
|
|
65
|
-
background-size: var(--nc-progress-track-size);
|
|
66
|
-
animation: nc-progress-indeterminate 12s linear infinite;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
:where(progress):not([value])::-webkit-progress-bar {
|
|
71
|
-
background: var(--nc-progress-track);
|
|
72
|
-
background-size: var(--nc-progress-track-size);
|
|
73
|
-
animation: nc-progress-indeterminate 12s linear infinite;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
:where(progress):not([value])::-moz-progress-bar {
|
|
77
|
-
background: var(--nc-progress-track);
|
|
78
|
-
background-size: var(--nc-progress-track-size);
|
|
79
|
-
animation: nc-progress-indeterminate 12s linear infinite;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
@keyframes nc-progress-indeterminate {
|
|
84
|
-
from { background-position: 0% 0%; }
|
|
85
|
-
to { background-position: -200% 0%; }
|
|
86
17
|
}
|
|
87
18
|
|
|
88
19
|
}
|
package/src/_reset.scss
CHANGED
package/src/_select.scss
CHANGED
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
border: 1px solid var(#{$prefix}border);
|
|
33
33
|
border-radius: var(#{$prefix}radius);
|
|
34
34
|
background-color: var(#{$prefix}surface-1);
|
|
35
|
-
padding: 0.25em;
|
|
35
|
+
padding: 0.25em; // OP ~size-1 (em-relative)
|
|
36
36
|
// Fade in/out animation
|
|
37
37
|
opacity: 0;
|
|
38
38
|
transition: opacity 0.2s, overlay 0.2s allow-discrete, display 0.2s allow-discrete;
|
|
@@ -50,7 +50,8 @@
|
|
|
50
50
|
|
|
51
51
|
// Options inside the picker
|
|
52
52
|
:where(select) option {
|
|
53
|
-
padding: 0.5em 0.75em;
|
|
53
|
+
padding: 0.5em 0.75em; // 0.5em: OP ~size-2; 0.75em: no OP match
|
|
54
|
+
// OP normalize: select uses 0.75ch block, --size-relative-4 inline
|
|
54
55
|
border-radius: var(#{$prefix}radius);
|
|
55
56
|
transition: background-color 0.15s;
|
|
56
57
|
}
|
package/src/_tables.scss
CHANGED
|
@@ -14,13 +14,14 @@
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
:where(th, td) {
|
|
17
|
-
padding: 0.5em 0.75em;
|
|
17
|
+
padding: 0.5em 0.75em; // 0.5em: OP ~size-2; 0.75em: no OP match
|
|
18
|
+
// OP normalize: --size-2 (0.5rem) both axes
|
|
18
19
|
border-bottom: 1px solid #{string.unquote('color-mix(in oklch, var(#{$prefix}border), transparent 40%)')};
|
|
19
20
|
text-align: start;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
:where(thead th, thead td) {
|
|
23
|
-
font-weight: 600;
|
|
24
|
+
font-weight: 600; // OP --font-weight-6
|
|
24
25
|
border-bottom-width: 2px;
|
|
25
26
|
background-color: var(#{$prefix}surface-2);
|
|
26
27
|
text-wrap: balance;
|
package/src/_typography.scss
CHANGED
|
@@ -12,22 +12,19 @@
|
|
|
12
12
|
// h2–h6 always carry top margin so they breathe above any preceding content,
|
|
13
13
|
// regardless of DOM nesting (first-child of section, etc.).
|
|
14
14
|
// Spec §8.3
|
|
15
|
+
// OP normalize uses --font-lineheight-1 (1.25) for ALL headings + --font-weight-9 (900).
|
|
16
|
+
// nimble uses a graduated lh scale + weight 700 (--font-weight-7).
|
|
17
|
+
// OP normalize heading sizes: h1=3.5rem h2=2.5rem h3=2rem h4=1.5rem h5=1.25rem h6=1.1rem
|
|
15
18
|
$_heading-scale: (
|
|
16
|
-
h1: (size: 2rem, lh: 1.1, mt: 0),
|
|
17
|
-
h2: (size: 1.75rem, lh: 1.15, mt: 2rem),
|
|
18
|
-
h3: (size: 1.5rem, lh: 1.2, mt: 1.5rem),
|
|
19
|
-
h4: (size: 1.25rem, lh: 1.3, mt: 1.5rem),
|
|
20
|
-
h5: (size: 1.125rem, lh: 1.4, mt: 1.5rem),
|
|
21
|
-
h6: (size: 1rem, lh: 1.5, mt: 1.5rem),
|
|
19
|
+
h1: (size: 2rem, lh: 1.1, mt: 0), // OP --font-size-5/--size-7; lh: --font-lineheight-0
|
|
20
|
+
h2: (size: 1.75rem, lh: 1.15, mt: 2rem), // OP --size-6; lh: no OP match (near lh-0); mt: --size-7
|
|
21
|
+
h3: (size: 1.5rem, lh: 1.2, mt: 1.5rem), // OP --font-size-4/--size-5; lh: no OP match (near lh-1); mt: --size-5
|
|
22
|
+
h4: (size: 1.25rem, lh: 1.3, mt: 1.5rem), // OP --font-size-3/--size-4; lh: no OP match (near lh-1); mt: --size-5
|
|
23
|
+
h5: (size: 1.125rem, lh: 1.4, mt: 1.5rem), // no OP match (OP --font-size-2: 1.1rem); lh: no OP match; mt: --size-5
|
|
24
|
+
h6: (size: 1rem, lh: 1.5, mt: 1.5rem), // OP --font-size-1/--size-3; lh: --font-lineheight-3; mt: --size-5
|
|
22
25
|
);
|
|
23
26
|
|
|
24
|
-
|
|
25
|
-
// Spec §8.3
|
|
26
|
-
$_heading-phone: (
|
|
27
|
-
h1: 1.75rem,
|
|
28
|
-
h2: 1.5rem,
|
|
29
|
-
h3: 1.3rem,
|
|
30
|
-
);
|
|
27
|
+
|
|
31
28
|
|
|
32
29
|
@layer nimble.base {
|
|
33
30
|
|
|
@@ -38,21 +35,12 @@ $_heading-phone: (
|
|
|
38
35
|
font-size: map.get($vals, size);
|
|
39
36
|
line-height: map.get($vals, lh);
|
|
40
37
|
margin-top: map.get($vals, mt);
|
|
41
|
-
margin-bottom: var(#{$prefix}spacing);
|
|
42
|
-
font-weight: 700;
|
|
38
|
+
margin-bottom: var(#{$prefix}spacing); // OP --size-3
|
|
39
|
+
font-weight: 700; // OP --font-weight-7 (OP normalize uses weight-9: 900)
|
|
43
40
|
text-wrap: balance;
|
|
44
41
|
}
|
|
45
42
|
}
|
|
46
43
|
|
|
47
|
-
// Phone breakpoint: scale down h1-h3
|
|
48
|
-
@media (max-width: #{$breakpoint-phone}) {
|
|
49
|
-
@each $tag, $size in $_heading-phone {
|
|
50
|
-
#{$tag} {
|
|
51
|
-
font-size: #{$size};
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
44
|
// ----- Vertical rhythm -----
|
|
57
45
|
// Block elements: no top margin, consistent bottom margin
|
|
58
46
|
// Spec §8.4
|
|
@@ -62,16 +50,29 @@ $_heading-phone: (
|
|
|
62
50
|
margin-bottom: var(#{$prefix}spacing);
|
|
63
51
|
}
|
|
64
52
|
|
|
53
|
+
// Prevent double spacing at page edges: body has padding-block,
|
|
54
|
+
// so strip margins that would stack with it.
|
|
55
|
+
// Must live inside @scope so it beats the scoped margin rules above.
|
|
56
|
+
// Uses :nth-child/:nth-last-child(of ...) to skip <script>/<style>.
|
|
57
|
+
body > :first-child,
|
|
58
|
+
body > :first-child > :first-child {
|
|
59
|
+
margin-top: 0;
|
|
60
|
+
}
|
|
61
|
+
body > :nth-last-child(1 of :not(script, style, dialog)),
|
|
62
|
+
body > :nth-last-child(1 of :not(script, style, dialog)) > :last-child {
|
|
63
|
+
margin-bottom: 0;
|
|
64
|
+
}
|
|
65
|
+
|
|
65
66
|
|
|
66
67
|
|
|
67
68
|
// ----- Lists -----
|
|
68
69
|
|
|
69
70
|
ul, ol {
|
|
70
|
-
padding-inline-start: 1.5em;
|
|
71
|
+
padding-inline-start: 1.5em; // OP ~size-5 (em-relative); OP normalize: --size-8 (3rem)
|
|
71
72
|
}
|
|
72
73
|
|
|
73
74
|
:where(li) {
|
|
74
|
-
margin-bottom: 0.25em;
|
|
75
|
+
margin-bottom: 0.25em; // OP ~size-1 (em-relative)
|
|
75
76
|
}
|
|
76
77
|
|
|
77
78
|
// Remove bottom margin on nested lists
|
|
@@ -80,12 +81,12 @@ $_heading-phone: (
|
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
dt {
|
|
83
|
-
font-weight: 600;
|
|
84
|
+
font-weight: 600; // OP --font-weight-6 (OP normalize uses weight-7: 700)
|
|
84
85
|
}
|
|
85
86
|
|
|
86
87
|
dd {
|
|
87
|
-
margin-inline-start: 1.5em;
|
|
88
|
-
margin-bottom: 0.5em;
|
|
88
|
+
margin-inline-start: 1.5em; // OP ~size-5 (em-relative)
|
|
89
|
+
margin-bottom: 0.5em; // OP ~size-2 (em-relative)
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
// ----- Blockquote -----
|
|
@@ -94,15 +95,15 @@ $_heading-phone: (
|
|
|
94
95
|
blockquote {
|
|
95
96
|
margin-block: var(#{$prefix}spacing);
|
|
96
97
|
margin-inline: 0;
|
|
97
|
-
padding: 0.25em var(#{$prefix}spacing);
|
|
98
|
-
border-inline-start: 0.25rem solid var(#{$prefix}border);
|
|
98
|
+
padding: 0.25em var(#{$prefix}spacing); // OP ~size-1 (em-relative), --size-3
|
|
99
|
+
border-inline-start: 0.25rem solid var(#{$prefix}border); // OP --size-1
|
|
99
100
|
font-style: italic;
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
:where(blockquote) footer,
|
|
103
104
|
:where(blockquote) cite {
|
|
104
105
|
font-style: normal;
|
|
105
|
-
font-size: 0.9em;
|
|
106
|
+
font-size: 0.9em; // no OP match (near ~size-3)
|
|
106
107
|
color: color-mix(in oklch, var(#{$prefix}text), transparent 40%);
|
|
107
108
|
}
|
|
108
109
|
|
|
@@ -120,7 +121,7 @@ $_heading-phone: (
|
|
|
120
121
|
// Spec §9.10
|
|
121
122
|
|
|
122
123
|
mark {
|
|
123
|
-
padding: 0.1em 0.25em;
|
|
124
|
+
padding: 0.1em 0.25em; // 0.1em: no OP match (micro); 0.25em: OP ~size-1
|
|
124
125
|
background-color: #{string.unquote('light-dark(#fde68a, oklch(0.55 0.12 85))')};
|
|
125
126
|
color: #{string.unquote('light-dark(inherit, oklch(0.95 0.01 85))')};
|
|
126
127
|
border-radius: 2px;
|
package/src/nimble-core.scss
CHANGED
|
@@ -18,6 +18,14 @@
|
|
|
18
18
|
@use 'layout-utilities';
|
|
19
19
|
@use 'print';
|
|
20
20
|
|
|
21
|
+
// Sentinel markers — no-nimble.js uses these to find where scopeable rules begin
|
|
22
|
+
@layer nimble.base {
|
|
23
|
+
:root { --nimble-scope-start: 1 }
|
|
24
|
+
}
|
|
25
|
+
@layer nimble.utilities {
|
|
26
|
+
:root { --nimble-scope-start: 1 }
|
|
27
|
+
}
|
|
28
|
+
|
|
21
29
|
// Component-level styles — optionally scoped
|
|
22
30
|
@if $exclude-selector {
|
|
23
31
|
@scope (:root) to (#{$exclude-selector}) {
|
package/src/nimble.scss
CHANGED
|
@@ -19,6 +19,14 @@
|
|
|
19
19
|
@use 'layout-utilities';
|
|
20
20
|
@use 'print';
|
|
21
21
|
|
|
22
|
+
// Sentinel markers — no-nimble.js uses these to find where scopeable rules begin
|
|
23
|
+
@layer nimble.base {
|
|
24
|
+
:root { --nimble-scope-start: 1 }
|
|
25
|
+
}
|
|
26
|
+
@layer nimble.utilities {
|
|
27
|
+
:root { --nimble-scope-start: 1 }
|
|
28
|
+
}
|
|
29
|
+
|
|
22
30
|
// Component-level styles — optionally scoped
|
|
23
31
|
@if $exclude-selector {
|
|
24
32
|
@scope (:root) to (#{$exclude-selector}) {
|