@leftium/nimble.css 0.1.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/LICENSE +21 -0
- package/README.md +128 -0
- package/dist/nimble-base.css +286 -0
- package/dist/nimble-base.min.css +1 -0
- package/dist/nimble-reset.css +120 -0
- package/dist/nimble-reset.min.css +1 -0
- package/dist/nimble-utilities.css +40 -0
- package/dist/nimble-utilities.min.css +1 -0
- package/dist/nimble.css +618 -0
- package/dist/nimble.min.css +1 -0
- package/package.json +40 -0
- package/src/_buttons.scss +123 -0
- package/src/_code.scss +37 -0
- package/src/_colors.scss +124 -0
- package/src/_config.scss +53 -0
- package/src/_details.scss +29 -0
- package/src/_dialog.scss +26 -0
- package/src/_document.scss +41 -0
- package/src/_forms.scss +130 -0
- package/src/_layers-base.scss +1 -0
- package/src/_layers-reset.scss +1 -0
- package/src/_layers-utilities.scss +1 -0
- package/src/_layers.scss +6 -0
- package/src/_links.scss +29 -0
- package/src/_media.scss +26 -0
- package/src/_print.scss +41 -0
- package/src/_reset.scss +183 -0
- package/src/_tables.scss +34 -0
- package/src/_typography.scss +135 -0
- package/src/_utilities.scss +73 -0
- package/src/nimble-base.scss +11 -0
- package/src/nimble-reset.scss +8 -0
- package/src/nimble-utilities.scss +8 -0
- package/src/nimble.scss +30 -0
package/src/_reset.scss
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
// ==========================================================================
|
|
2
|
+
// nimble.css — Reset
|
|
3
|
+
// Trimmed sanitize.css (v13.0.0) wrapped in @layer nimble.reset
|
|
4
|
+
// All selectors use :where() for zero specificity (spec §3.2)
|
|
5
|
+
// ==========================================================================
|
|
6
|
+
|
|
7
|
+
@use 'config' as *;
|
|
8
|
+
|
|
9
|
+
@layer nimble.reset {
|
|
10
|
+
|
|
11
|
+
// --- Document ---
|
|
12
|
+
|
|
13
|
+
:where(*),
|
|
14
|
+
:where(*::before),
|
|
15
|
+
:where(*::after) {
|
|
16
|
+
box-sizing: border-box;
|
|
17
|
+
background-repeat: no-repeat;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
:where(html) {
|
|
21
|
+
// Correct the line height in all browsers
|
|
22
|
+
line-height: 1.5;
|
|
23
|
+
// Prevent adjustments of font size after orientation changes in iOS
|
|
24
|
+
-webkit-text-size-adjust: 100%;
|
|
25
|
+
// Use a better default tab size
|
|
26
|
+
tab-size: 4;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
:where(body) {
|
|
30
|
+
margin: 0;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// --- Sections ---
|
|
34
|
+
|
|
35
|
+
:where(h1) {
|
|
36
|
+
font-size: 2em;
|
|
37
|
+
margin-block: 0.67em;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// --- Grouping content ---
|
|
41
|
+
|
|
42
|
+
:where(hr) {
|
|
43
|
+
height: 0;
|
|
44
|
+
color: inherit; // Correct hr color in Firefox
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
:where(nav) :where(ol, ul) {
|
|
48
|
+
list-style-type: none;
|
|
49
|
+
padding: 0;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
:where(pre) {
|
|
53
|
+
font-family: monospace, monospace; // Correct font sizing
|
|
54
|
+
font-size: 1em;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// --- Text-level semantics ---
|
|
58
|
+
|
|
59
|
+
:where(abbr[title]) {
|
|
60
|
+
text-decoration: underline dotted;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
:where(b, strong) {
|
|
64
|
+
font-weight: bolder;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
:where(code, kbd, samp) {
|
|
68
|
+
font-family: monospace, monospace; // Correct font sizing
|
|
69
|
+
font-size: 1em;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
:where(small) {
|
|
73
|
+
font-size: 80%;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
:where(sub, sup) {
|
|
77
|
+
font-size: 75%;
|
|
78
|
+
line-height: 0;
|
|
79
|
+
position: relative;
|
|
80
|
+
vertical-align: baseline;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
:where(sub) {
|
|
84
|
+
bottom: -0.25em;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
:where(sup) {
|
|
88
|
+
top: -0.5em;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// --- Embedded content ---
|
|
92
|
+
|
|
93
|
+
:where(iframe) {
|
|
94
|
+
border-style: none;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// --- Tabular data ---
|
|
98
|
+
|
|
99
|
+
:where(table) {
|
|
100
|
+
border-collapse: collapse;
|
|
101
|
+
border-color: currentColor; // Correct border-color in Chrome/Edge/Safari
|
|
102
|
+
text-indent: 0; // Remove text indentation in Chrome/Edge/Safari
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// --- Forms ---
|
|
106
|
+
|
|
107
|
+
:where(button, input, select, textarea) {
|
|
108
|
+
font: inherit; // Use the same font as the document
|
|
109
|
+
letter-spacing: inherit;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
:where(button, [type="button"], [type="reset"], [type="submit"]) {
|
|
113
|
+
-webkit-appearance: button; // Correct clickable type in iOS/Safari
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
:where(fieldset) {
|
|
117
|
+
border: 1px solid #a0a0a0;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
:where(progress) {
|
|
121
|
+
vertical-align: baseline;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
:where(textarea) {
|
|
125
|
+
resize: vertical; // Only vertical resize by default
|
|
126
|
+
overflow: auto; // Remove default scrollbar in IE
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
:where([type="search"]) {
|
|
130
|
+
-webkit-appearance: textfield; // Correct appearance in Chrome/Safari
|
|
131
|
+
outline-offset: -2px;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
:where(::-webkit-search-decoration) {
|
|
135
|
+
-webkit-appearance: none; // Remove inner padding in Chrome/Safari on macOS
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
:where(::-webkit-inner-spin-button),
|
|
139
|
+
:where(::-webkit-outer-spin-button) {
|
|
140
|
+
height: auto; // Correct height in Chrome
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
:where(::-webkit-file-upload-button) {
|
|
144
|
+
-webkit-appearance: button; // Correct clickable type in iOS/Safari
|
|
145
|
+
font: inherit;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// --- Interactive ---
|
|
149
|
+
|
|
150
|
+
:where(summary) {
|
|
151
|
+
display: list-item; // Correct display in Chrome
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// --- Accessibility ---
|
|
155
|
+
|
|
156
|
+
// Remove delay from tapping on clickable elements
|
|
157
|
+
:where(a, area, button, input, label, select, summary, textarea, [tabindex]) {
|
|
158
|
+
touch-action: manipulation;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Change the cursor for busy elements
|
|
162
|
+
:where([aria-busy="true"]) {
|
|
163
|
+
cursor: progress;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Change the cursor for disabled/not-editable elements
|
|
167
|
+
:where([aria-disabled="true"], [disabled]) {
|
|
168
|
+
cursor: not-allowed;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Remove animations/transitions for users who prefer reduced motion
|
|
172
|
+
@media (prefers-reduced-motion: reduce) {
|
|
173
|
+
:where(*),
|
|
174
|
+
:where(*::before),
|
|
175
|
+
:where(*::after) {
|
|
176
|
+
animation-duration: 0.01ms !important;
|
|
177
|
+
animation-iteration-count: 1 !important;
|
|
178
|
+
transition-duration: 0.01ms !important;
|
|
179
|
+
scroll-behavior: auto !important;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
}
|
package/src/_tables.scss
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// ==========================================================================
|
|
2
|
+
// nimble.css — Tables
|
|
3
|
+
// Spec §9.4
|
|
4
|
+
// ==========================================================================
|
|
5
|
+
|
|
6
|
+
@use 'sass:string';
|
|
7
|
+
@use 'config' as *;
|
|
8
|
+
|
|
9
|
+
@layer nimble.base {
|
|
10
|
+
|
|
11
|
+
:where(table) {
|
|
12
|
+
width: 100%;
|
|
13
|
+
border-collapse: collapse;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
:where(th, td) {
|
|
17
|
+
padding: 0.5em 0.75em;
|
|
18
|
+
border-bottom: 1px solid #{string.unquote('color-mix(in oklch, var(#{$prefix}border), transparent 40%)')};
|
|
19
|
+
text-align: start;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
:where(thead th, thead td) {
|
|
23
|
+
font-weight: 600;
|
|
24
|
+
border-bottom-width: 2px;
|
|
25
|
+
background-color: var(#{$prefix}surface-2);
|
|
26
|
+
text-wrap: balance;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Responsive tables: horizontal scroll when inside figure
|
|
30
|
+
:where(figure:has(table)) {
|
|
31
|
+
overflow-x: auto;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// ==========================================================================
|
|
2
|
+
// nimble.css — Typography
|
|
3
|
+
// Headings, vertical rhythm, blockquote, hr, mark, lists
|
|
4
|
+
// ==========================================================================
|
|
5
|
+
|
|
6
|
+
@use 'sass:map';
|
|
7
|
+
@use 'sass:string';
|
|
8
|
+
@use 'config' as *;
|
|
9
|
+
|
|
10
|
+
// Heading scale: size and line-height
|
|
11
|
+
// Spec §8.3
|
|
12
|
+
$_heading-scale: (
|
|
13
|
+
h1: (size: 2rem, lh: 1.1),
|
|
14
|
+
h2: (size: 1.75rem, lh: 1.15),
|
|
15
|
+
h3: (size: 1.5rem, lh: 1.2),
|
|
16
|
+
h4: (size: 1.25rem, lh: 1.3),
|
|
17
|
+
h5: (size: 1.125rem, lh: 1.4),
|
|
18
|
+
h6: (size: 1rem, lh: 1.5),
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
// Phone breakpoint heading overrides
|
|
22
|
+
// Spec §8.3
|
|
23
|
+
$_heading-phone: (
|
|
24
|
+
h1: 1.75rem,
|
|
25
|
+
h2: 1.5rem,
|
|
26
|
+
h3: 1.3rem,
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
@layer nimble.base {
|
|
30
|
+
|
|
31
|
+
// ----- Headings -----
|
|
32
|
+
|
|
33
|
+
@each $tag, $vals in $_heading-scale {
|
|
34
|
+
#{$tag} {
|
|
35
|
+
font-size: map.get($vals, size);
|
|
36
|
+
line-height: map.get($vals, lh);
|
|
37
|
+
margin-top: 0;
|
|
38
|
+
margin-bottom: var(#{$prefix}spacing);
|
|
39
|
+
font-weight: 700;
|
|
40
|
+
text-wrap: balance;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Phone breakpoint: scale down h1-h3
|
|
45
|
+
@media (max-width: #{$breakpoint-phone}) {
|
|
46
|
+
@each $tag, $size in $_heading-phone {
|
|
47
|
+
#{$tag} {
|
|
48
|
+
font-size: #{$size};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// ----- Vertical rhythm -----
|
|
54
|
+
// Block elements: no top margin, consistent bottom margin
|
|
55
|
+
// Spec §8.4
|
|
56
|
+
|
|
57
|
+
p, ul, ol, dl, blockquote, pre, table, figure, form, fieldset {
|
|
58
|
+
margin-top: 0;
|
|
59
|
+
margin-bottom: var(#{$prefix}spacing);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Extra top margin on headings that follow block content
|
|
63
|
+
:where(p, ul, ol, dl, blockquote, pre, table, figure, form) + :is(h1, h2, h3, h4, h5, h6) {
|
|
64
|
+
margin-top: calc(var(#{$prefix}spacing) * 2);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ----- Lists -----
|
|
68
|
+
|
|
69
|
+
ul, ol {
|
|
70
|
+
padding-inline-start: 1.5em;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
li {
|
|
74
|
+
margin-bottom: 0.25em;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Remove bottom margin on nested lists
|
|
78
|
+
:where(li) > :where(ul, ol) {
|
|
79
|
+
margin-bottom: 0;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
dt {
|
|
83
|
+
font-weight: 600;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
dd {
|
|
87
|
+
margin-inline-start: 1.5em;
|
|
88
|
+
margin-bottom: 0.5em;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// ----- Blockquote -----
|
|
92
|
+
// Spec §9.6
|
|
93
|
+
|
|
94
|
+
blockquote {
|
|
95
|
+
margin-block: var(#{$prefix}spacing);
|
|
96
|
+
margin-inline: 0;
|
|
97
|
+
padding: 0.25em var(#{$prefix}spacing);
|
|
98
|
+
border-inline-start: 0.25rem solid var(#{$prefix}border);
|
|
99
|
+
font-style: italic;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
:where(blockquote) footer,
|
|
103
|
+
:where(blockquote) cite {
|
|
104
|
+
font-style: normal;
|
|
105
|
+
font-size: 0.9em;
|
|
106
|
+
color: var(#{$prefix}text-2);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// ----- Horizontal Rule -----
|
|
110
|
+
// Spec §9.9
|
|
111
|
+
|
|
112
|
+
hr {
|
|
113
|
+
border: none;
|
|
114
|
+
height: 1px;
|
|
115
|
+
background-color: color-mix(in oklch, var(#{$prefix}border), transparent 40%);
|
|
116
|
+
margin: calc(var(#{$prefix}spacing) * 2) 0;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// ----- Mark -----
|
|
120
|
+
// Spec §9.10
|
|
121
|
+
|
|
122
|
+
mark {
|
|
123
|
+
padding: 0.1em 0.25em;
|
|
124
|
+
background-color: #{string.unquote('light-dark(#fde68a, oklch(0.55 0.12 85))')};
|
|
125
|
+
color: #{string.unquote('light-dark(inherit, oklch(0.95 0.01 85))')};
|
|
126
|
+
border-radius: 2px;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ----- Address -----
|
|
130
|
+
|
|
131
|
+
address {
|
|
132
|
+
font-style: normal;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// ==========================================================================
|
|
2
|
+
// nimble.css — Utilities
|
|
3
|
+
// Spec §10: .container, .fluid, .full-bleed, .wide, .striped,
|
|
4
|
+
// .visually-hidden, .overflow-auto
|
|
5
|
+
// ==========================================================================
|
|
6
|
+
|
|
7
|
+
@use 'sass:string';
|
|
8
|
+
@use 'config' as *;
|
|
9
|
+
|
|
10
|
+
@if $enable-utilities {
|
|
11
|
+
|
|
12
|
+
@layer nimble.utilities {
|
|
13
|
+
|
|
14
|
+
// ----- Layout -----
|
|
15
|
+
|
|
16
|
+
// Centered content container (useful inside fluid layout)
|
|
17
|
+
.container {
|
|
18
|
+
max-width: var(#{$prefix}content-width);
|
|
19
|
+
margin-inline: auto;
|
|
20
|
+
padding-inline: var(#{$prefix}spacing);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Full viewport width with padding (opt-in on body or wrapper)
|
|
24
|
+
.fluid {
|
|
25
|
+
display: block;
|
|
26
|
+
max-width: none;
|
|
27
|
+
padding-inline: var(#{$prefix}spacing);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Break out of centered container to full width
|
|
31
|
+
.full-bleed {
|
|
32
|
+
grid-column: 1 / -1;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Break out to wide max-width
|
|
36
|
+
.wide {
|
|
37
|
+
grid-column: 1 / -1;
|
|
38
|
+
width: 100%;
|
|
39
|
+
max-width: #{$wide-width};
|
|
40
|
+
margin-inline: auto;
|
|
41
|
+
padding-inline: var(#{$prefix}spacing);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// ----- Tables -----
|
|
45
|
+
|
|
46
|
+
// Striped table rows
|
|
47
|
+
.striped :where(tbody tr:nth-child(even)) {
|
|
48
|
+
background-color: var(#{$prefix}surface-2);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// ----- Visibility -----
|
|
52
|
+
|
|
53
|
+
// Accessible hidden (screen readers only)
|
|
54
|
+
.visually-hidden {
|
|
55
|
+
position: absolute;
|
|
56
|
+
width: 1px;
|
|
57
|
+
height: 1px;
|
|
58
|
+
padding: 0;
|
|
59
|
+
margin: -1px;
|
|
60
|
+
overflow: hidden;
|
|
61
|
+
clip-path: inset(50%);
|
|
62
|
+
white-space: nowrap;
|
|
63
|
+
border: 0;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Scrollable container
|
|
67
|
+
.overflow-auto {
|
|
68
|
+
overflow: auto;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// ==========================================================================
|
|
2
|
+
// nimble.css — Base Sub-bundle
|
|
3
|
+
// Reset + colors + document + typography — the classless core
|
|
4
|
+
// ==========================================================================
|
|
5
|
+
|
|
6
|
+
@use 'config' as *;
|
|
7
|
+
@use 'layers-base';
|
|
8
|
+
@use 'reset';
|
|
9
|
+
@use 'colors';
|
|
10
|
+
@use 'document';
|
|
11
|
+
@use 'typography';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// ==========================================================================
|
|
2
|
+
// nimble.css — Reset Sub-bundle
|
|
3
|
+
// Standalone modern CSS reset
|
|
4
|
+
// ==========================================================================
|
|
5
|
+
|
|
6
|
+
@use 'config' as *;
|
|
7
|
+
@use 'layers-reset';
|
|
8
|
+
@use 'reset';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// ==========================================================================
|
|
2
|
+
// nimble.css — Utilities Sub-bundle
|
|
3
|
+
// Standalone utility classes (requires colors to be loaded separately)
|
|
4
|
+
// ==========================================================================
|
|
5
|
+
|
|
6
|
+
@use 'config' as *;
|
|
7
|
+
@use 'layers-utilities';
|
|
8
|
+
@use 'utilities';
|
package/src/nimble.scss
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// ==========================================================================
|
|
2
|
+
// nimble.css — Entry Point
|
|
3
|
+
// A minimal class/classless CSS library
|
|
4
|
+
// ==========================================================================
|
|
5
|
+
|
|
6
|
+
@use 'config' as *;
|
|
7
|
+
|
|
8
|
+
// Layer order declaration — emitted first in CSS output.
|
|
9
|
+
// Lower layers lose to higher layers in cascade.
|
|
10
|
+
@use 'layers';
|
|
11
|
+
|
|
12
|
+
// Phase 2: Core
|
|
13
|
+
@use 'reset';
|
|
14
|
+
@use 'colors';
|
|
15
|
+
@use 'document';
|
|
16
|
+
@use 'typography';
|
|
17
|
+
|
|
18
|
+
// Phase 3: Elements
|
|
19
|
+
@use 'links';
|
|
20
|
+
@use 'buttons';
|
|
21
|
+
@use 'forms';
|
|
22
|
+
@use 'tables';
|
|
23
|
+
@use 'code';
|
|
24
|
+
@use 'media';
|
|
25
|
+
@use 'details';
|
|
26
|
+
@use 'dialog';
|
|
27
|
+
@use 'print';
|
|
28
|
+
|
|
29
|
+
// Phase 4: Utilities
|
|
30
|
+
@use 'utilities';
|