@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.
@@ -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
+ }
@@ -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';
@@ -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';