@giana/cryptic-reset 1.0.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Georgiana Blantin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # Cryptic Reset
2
+
3
+ A highly opinionated CSS reset for personal projects, featuring responsive text sizing; OKLCH-based color formulas; line-height-based layout spacing; automatic formatting of minor HTML elements and more.
package/css/base.css ADDED
@@ -0,0 +1,487 @@
1
+ /*
2
+ * Custom properties used
3
+ * Be sure to set these to customize the reset otherwise the defaults will be used
4
+ * Variables marked with ✨ are prioritized for customization, the rest should work as-is
5
+ *
6
+ * // Text
7
+ * --font-family-default: sans-serif ✨
8
+ * --font-family-heading: var(--font-family-default, sans-serif) ✨
9
+ * --font-family-monospace: monospace
10
+ * --font-size-default: 1em
11
+ * --line-height-default: 1.5
12
+ *
13
+ * // Spacing / rhythm
14
+ * --margin-heading-start: var(--spacing, 1.5rem) * 2
15
+ * --margin-heading-end: var(--spacing, 1.5rem)
16
+ * --min-tap-size: 48px
17
+ * --spacing: 1.5rem
18
+ *
19
+ * // Colors ✨
20
+ * --color-background: white
21
+ * --color-text: black
22
+ * --color-link: blue
23
+ * --color-link-hover: var(--color-link, blue)
24
+ *
25
+ * --color-highlight-background: highlight
26
+ * --color-highlight-text: highlighttext
27
+ * --color-scrollbar-thumb: var(--color-background, white)
28
+ * --color-scrollbar-track: var(--color-text, black)
29
+ *
30
+ * --color-form-elements: var(--border-color, blue)
31
+ * --color-button-background: transparent
32
+ * --color-button-text: currentColor
33
+ * --color-button-border: currentColor
34
+ * --color-button-border-hover: blue
35
+ * --color-input-background: transparent
36
+ * --color-input-text: currentColor
37
+ * --color-input-border: currentColor
38
+ * --color-input-border-hover: blue
39
+ *
40
+ * // Buttons
41
+ * --border-width-button: 1px ✨
42
+ * --height-button: calc(var(--spacing, 1.5rem) * 2)
43
+ * --padding-block-button: calc((var(--height) - 1lh) / 2 - var(--border-width) * 2)
44
+ * --padding-inline-button: var(--padding-block-button)
45
+ *
46
+ * // Inputs
47
+ * --border-width-input: 1px ✨
48
+ * --height-input: calc(var(--spacing, 1.5rem) * 2)
49
+ * --padding-block-input: 0
50
+ * --padding-inline-input: var(--spacing, 1.5rem)
51
+ *
52
+ * // Form elements
53
+ * --height-textarea: calc(var(--spacing, 1.5rem) * 6)
54
+ * --padding-block-textarea: calc(var(--spacing, 1.5rem) / 2)
55
+ *
56
+ * // Misc
57
+ * --hr-height: 2px
58
+ * --scroll-offset: var(--spacing, 1.5rem)
59
+ *
60
+ */
61
+
62
+ @layer base {
63
+ :root {
64
+ box-sizing: border-box;
65
+ interpolate-size: allow-keywords;
66
+ color-scheme: light dark;
67
+ }
68
+
69
+ @view-transition {
70
+ navigation: auto;
71
+ }
72
+
73
+ *,
74
+ ::before,
75
+ ::after {
76
+ background-repeat: no-repeat;
77
+ box-decoration-break: clone;
78
+ box-sizing: inherit;
79
+ outline-offset: 0.25em;
80
+ paint-order: stroke;
81
+ transition-behavior: allow-discrete;
82
+ }
83
+
84
+ /* Prevent text-shadows making highlighted text unreadable */
85
+ ::selection {
86
+ background-color: var(--color-highlight-background, highlight);
87
+ color: var(--color-highlight-text, highlighttext);
88
+ text-shadow: none !important;
89
+ }
90
+
91
+ html {
92
+ -moz-text-size-adjust: 100%;
93
+ -webkit-text-size-adjust: 100%;
94
+ text-size-adjust: 100%;
95
+
96
+ background-color: var(--color-background, white);
97
+ height: 100%;
98
+ overflow-x: clip;
99
+
100
+ /* Removed for `prefers-reduced-motion` in overwrites.css */
101
+ scroll-behavior: smooth;
102
+ scrollbar-gutter: stable;
103
+ }
104
+
105
+ /* Custom scrollbar styles for non-document elements */
106
+ :where(:not(html)) {
107
+ scrollbar-color: var(--color-scrollbar-thumb, var(--color-background, white))
108
+ var(--color-scrollbar-track, var(--color-text, black));
109
+ scrollbar-width: thin;
110
+ }
111
+
112
+ body {
113
+ background-color: var(--color-background, white);
114
+ color: var(--color-text, black);
115
+ font-family: var(--font-family-default, sans-serif);
116
+ font-size: var(--font-size-default, 1em);
117
+ font-size-adjust: ex-height from-font;
118
+ font-synthesis-weight: none;
119
+ font-synthesis-style: none;
120
+ font-synthesis-small-caps: auto;
121
+ hanging-punctuation: first allow-end last;
122
+ hyphens: auto;
123
+ hyphenate-limit-chars: auto 4 3;
124
+ line-height: var(--line-height-default, 1.5);
125
+ min-height: 100%;
126
+ margin: 0;
127
+ overflow-wrap: break-word;
128
+ text-rendering: optimizeLegibility;
129
+ }
130
+
131
+ main {
132
+ outline: 0;
133
+ }
134
+
135
+ :target {
136
+ scroll-margin-block-start: var(
137
+ --scroll-offset,
138
+ var(--section-spacing-y, var(--spacing, 1.5rem))
139
+ );
140
+ }
141
+
142
+ /* Reset spacing and add bottom margin for basic elements */
143
+ ol,
144
+ ul,
145
+ dl,
146
+ dd,
147
+ p,
148
+ blockquote,
149
+ pre,
150
+ table,
151
+ figure,
152
+ form,
153
+ fieldset,
154
+ details {
155
+ padding: 0;
156
+ margin: 0;
157
+ margin-block-end: var(--spacing, 1.5rem);
158
+ }
159
+
160
+ /* Indent nested lists */
161
+ ol,
162
+ ul {
163
+ & ol,
164
+ & ul {
165
+ padding-inline-start: var(--spacing, 1.5rem);
166
+ }
167
+ }
168
+
169
+ dt {
170
+ font-weight: bold;
171
+ }
172
+
173
+ dd {
174
+ margin: 0;
175
+ padding-inline-start: var(--spacing, 1.5rem);
176
+ }
177
+
178
+ /* Limit width of objects with intrinsic size */
179
+ img,
180
+ picture,
181
+ object,
182
+ video,
183
+ embed,
184
+ iframe {
185
+ max-width: 100%;
186
+ height: auto;
187
+ }
188
+
189
+ audio,
190
+ canvas {
191
+ max-width: 100%;
192
+ }
193
+
194
+ video {
195
+ object-fit: cover;
196
+ }
197
+
198
+ a {
199
+ color: var(--color-link, blue);
200
+ transition-duration: var(--transition-duration--sm, 0.25s);
201
+ transition-property: background, border, color, box-shadow, filter, opacity, transform;
202
+
203
+ &:where(:not([class])) {
204
+ text-underline-offset: 0.25em;
205
+ text-decoration-thickness: 1px;
206
+ text-decoration-skip-ink: auto;
207
+ }
208
+
209
+ &:hover,
210
+ &:focus {
211
+ color: var(--color-link-hover, var(--color-link, blue));
212
+ }
213
+
214
+ &:focus-visible {
215
+ outline: 2px dashed var(--color-link-hover, var(--color-link, blue));
216
+ }
217
+ }
218
+
219
+ h1,
220
+ .h1,
221
+ h2,
222
+ .h2,
223
+ h3,
224
+ .h3,
225
+ h4,
226
+ .h4,
227
+ h5,
228
+ .h5,
229
+ h6,
230
+ .h6 {
231
+ font-family: var(--font-family-heading, var(--font-family-default, 1rem));
232
+ font-size: var(--font-size);
233
+ font-weight: 400;
234
+ line-height: var(--line-height);
235
+ margin-block-start: var(--margin-heading-start, var(--spacing-xl, 3rem));
236
+ margin-block-end: var(--margin-heading-end, var(--spacing, 1.5rem));
237
+ text-box: trim-both cap alphabetic;
238
+ }
239
+
240
+ h1,
241
+ .h1,
242
+ h2,
243
+ .h2,
244
+ h3,
245
+ .h3 {
246
+ --line-height: var(--line-height-heading, 1.25);
247
+
248
+ text-wrap: balance;
249
+ }
250
+
251
+ h5,
252
+ .h5,
253
+ h6,
254
+ .h6 {
255
+ font-weight: 700;
256
+ }
257
+
258
+ p {
259
+ text-box-edge: cap alphabetic;
260
+ text-wrap: pretty;
261
+
262
+ &:where(:first-child) {
263
+ text-box-trim: trim-start;
264
+ }
265
+
266
+ &:where(:last-child) {
267
+ text-box-trim: trim-end;
268
+ }
269
+
270
+ &:where(:only-child) {
271
+ text-box-trim: trim-both;
272
+ }
273
+ }
274
+
275
+ strong,
276
+ b {
277
+ font-weight: bolder;
278
+ }
279
+
280
+ small {
281
+ font-size: var(--font-size, 0.875rem);
282
+ }
283
+
284
+ pre {
285
+ max-width: 100%;
286
+ white-space: pre-wrap;
287
+ overflow-x: auto;
288
+ }
289
+
290
+ code:where(:not(pre *)),
291
+ pre:where(:has(code)) {
292
+ background-color: var(--color-text);
293
+ border-radius: 3px;
294
+ color: var(--color-background);
295
+ font-family: var(--font-family-monospace, monospace);
296
+ }
297
+
298
+ pre:where(:has(code)) {
299
+ padding: var(--spacing);
300
+ }
301
+
302
+ /* Sensible defaults for tables */
303
+ table {
304
+ border-color: inherit;
305
+ border-collapse: collapse;
306
+ table-layout: fixed;
307
+ text-indent: 0;
308
+ max-width: 100%;
309
+ }
310
+
311
+ th,
312
+ td {
313
+ padding: 0;
314
+ }
315
+
316
+ hr {
317
+ border: 0;
318
+ clear: both;
319
+ margin: 0;
320
+
321
+ border-block-end: var(--hr-height, 2px) solid;
322
+
323
+ /* Pull up by half-height to center */
324
+ margin-block-start: calc(var(--hr-height, 2px) / -2);
325
+
326
+ /* Reset rhythm by compensating for height */
327
+ margin-block-end: calc(var(--spacing, 1.5rem) - var(--hr-height, 2px) / 2);
328
+ }
329
+
330
+ svg {
331
+ display: inline-block;
332
+ fill: currentColor;
333
+ vertical-align: middle;
334
+ }
335
+
336
+ /* Assume dimensionless SVGs are icons and set sensible defaults */
337
+ svg:where(:not([width]):not([height])) {
338
+ width: 2ex;
339
+ height: 2ex;
340
+ }
341
+
342
+ /* Format lists inside nav elements and footer <ul>s as nav lists */
343
+ nav :where(ol),
344
+ nav :where(ul),
345
+ footer :where(ul:has(a)) {
346
+ display: flex;
347
+ align-items: center;
348
+ gap: var(--spacing, 1.5rem);
349
+ flex-wrap: wrap;
350
+
351
+ & li,
352
+ & a {
353
+ display: block;
354
+ }
355
+ }
356
+
357
+ /* Fix... bug? where children of details inherit content-box */
358
+ details {
359
+ display: block;
360
+
361
+ & * {
362
+ box-sizing: border-box;
363
+ }
364
+ }
365
+
366
+ ::details-content {
367
+ transition-behavior: allow-discrete;
368
+ }
369
+
370
+ /* Input resets */
371
+ input,
372
+ textarea,
373
+ button {
374
+ color: inherit;
375
+ font: inherit;
376
+ line-height: inherit;
377
+ margin: 0;
378
+ vertical-align: middle;
379
+
380
+ &:focus {
381
+ outline: none;
382
+ }
383
+
384
+ &:focus-visible {
385
+ outline: 2px dashed var(--border-color-hover, blue);
386
+ }
387
+ }
388
+
389
+ /* All button-style elements */
390
+ button,
391
+ [type="button"],
392
+ [type="reset"],
393
+ [type="submit"],
394
+ .button {
395
+ --background-color: var(--color-button-background, transparent);
396
+ --border-width: var(--border-width-button, 1px);
397
+ --border-color: var(--color-button-border, currentColor);
398
+ --border-color-hover: var(--color-button-border-hover, blue);
399
+ --text-color: var(--color-button-text, currentColor);
400
+ --height: max(var(--min-tap-size, 48px), var(--height-button, var(--spacing-xl, 4rem)));
401
+ --padding-block: var(
402
+ --padding-block-button,
403
+ calc((var(--height) - 1lh) / 2 - var(--border-width) * 2)
404
+ );
405
+ --padding-inline: var(--padding-inline-button, var(--padding-block));
406
+ --width: fit-content;
407
+
408
+ cursor: pointer;
409
+ line-height: var(--button-line-height, var(--line-height, 1.5));
410
+ }
411
+
412
+ /* All text-style elements */
413
+ [type="text"],
414
+ [type="email"],
415
+ [type="password"],
416
+ [type="number"],
417
+ [type="url"],
418
+ [type="tel"],
419
+ [type="search"],
420
+ textarea {
421
+ --background-color: var(--color-input-background, transparent);
422
+ --border-width: var(--border-width-input, 1px);
423
+ --border-color: var(--color-input-border, currentColor);
424
+ --border-color-hover: var(--color-input-border-hover, blue);
425
+ --text-color: var(--color-input-text, currentColor);
426
+ --height: max(var(--min-tap-size, 48px), var(--height-input, var(--spacing-xl, 4rem)));
427
+ --padding-block: var(--padding-block-input, 0);
428
+ --padding-inline: var(--padding-inline-input, var(--spacing-sm, 0.5rem));
429
+ --width: 30ch;
430
+ }
431
+
432
+ textarea {
433
+ --padding-block: var(--padding-block-textarea, var(--spacing-sm, 0.5rem));
434
+ --height: max(var(--min-tap-size, 48px), var(--height-textarea, var(--spacing-4xl, 6rem)));
435
+ --width: 60ch;
436
+ }
437
+
438
+ ::placeholder {
439
+ color: currentColor;
440
+ opacity: 0.65;
441
+ }
442
+
443
+ /* Common styles for button-style and text-style elements */
444
+ button,
445
+ [type="button"],
446
+ [type="reset"],
447
+ [type="submit"],
448
+ [type="text"],
449
+ [type="email"],
450
+ [type="password"],
451
+ [type="number"],
452
+ [type="url"],
453
+ [type="tel"],
454
+ [type="search"],
455
+ textarea,
456
+ .button {
457
+ background: var(--background-color);
458
+ border: var(--border-width) solid var(--border-color);
459
+ color: var(--text-color);
460
+ min-height: var(--height);
461
+ min-width: min(100%, var(--width));
462
+ padding-block: var(--padding-block);
463
+ padding-inline: var(--padding-inline);
464
+ text-decoration: none;
465
+ transition-duration: var(--transition-duration--sm, 0.25s);
466
+ transition-property: background, border, color, box-shadow, opacity, transform;
467
+
468
+ &:hover,
469
+ &:focus {
470
+ border-color: var(--border-color-hover);
471
+ }
472
+ }
473
+
474
+ /* Accent color for other form elements */
475
+ [type="checkbox"],
476
+ [type="radio"],
477
+ [type="range"],
478
+ progress {
479
+ accent-color: var(--color-form-elements, var(--border-color, blue));
480
+ height: 1em;
481
+ }
482
+
483
+ /* Make label display:block when followed by textarea */
484
+ label:where(:has(+ textarea)) {
485
+ display: block;
486
+ }
487
+ }
package/css/color.css ADDED
@@ -0,0 +1,101 @@
1
+ @layer color {
2
+ :root {
3
+ /*
4
+ * Color tools for working with OKLCH
5
+ *
6
+ * `Softest` and `strongest` refer to how strong the contrast is depending on color mode.
7
+ * `Soft` are lighter colors in light mode and darker colors in dark mode.
8
+ * `Strong` are darker colors in light mode and lighter colors in dark mode.
9
+ *
10
+ */
11
+
12
+ /* Arbitrary, visually-selected values */
13
+ --_lightness-softest: 0.975;
14
+ --_lightness-strongest: 0.20;
15
+
16
+ --_chroma-softest: 0.02;
17
+ --_chroma-strongest: 0.08;
18
+
19
+ --_hue-cool: 300; /* Blue toward purple */
20
+ --_hue-warm: 70; /* Orange */
21
+
22
+ --_hue-softest: var(--_hue-warm);
23
+ --_hue-strongest: var(--_hue-cool);
24
+
25
+ /* Reverse formula for dark mode */
26
+ /* @media (prefers-color-scheme: dark) {
27
+ --_lightness-softest: 0.15;
28
+ --_lightness-strongest: 0.975;
29
+
30
+ --_chroma-softest: 0.07;
31
+ --_chroma-strongest: 0.01;
32
+
33
+ --_hue-softest: var(--_hue-cool);
34
+ --_hue-strongest: var(--_hue-warm);
35
+ } */
36
+ }
37
+
38
+ @function --shift-hue(
39
+ --color <color>,
40
+ --amount <percentage>,
41
+ --direction <string>
42
+ )
43
+ returns <color> {
44
+ --new-hue:
45
+ if(style(--direction: "softer"): var(--_hue-softest);
46
+ else: var(--_hue-strongest));
47
+
48
+ --new-color: oklch(from var(--color) l c var(--new-hue));
49
+
50
+ result: color-mix(in oklch, var(--color), var(--new-color) var(--amount));
51
+ }
52
+
53
+ @function --shift-brightness(
54
+ --color <color>,
55
+ --amount <integer>,
56
+ --direction <string>,
57
+ --scale <number>: 5
58
+ )
59
+ returns <color> {
60
+ --_lightness-shift:
61
+ if(style(--direction: "softer"): var(--_lightness-softest);
62
+ else: var(--_lightness-strongest));
63
+ --_chroma-shift:
64
+ if(style(--direction: "softer"): var(--_chroma-softest);
65
+ else: var(--_chroma-strongest));
66
+
67
+ --_amount-c-soft: calc(var(--amount) - (var(--amount) * -0.05));
68
+ --_amount-c-strong: calc(var(--amount) + (var(--amount) * 0.25));
69
+ --_amount-l-soft: var(--amount);
70
+ --_amount-l-strong: calc(var(--amount) + (var(--amount) * 0.075));
71
+
72
+ --_amount-c:
73
+ if(style(--direction: "softer"): var(--_amount-c-soft);
74
+ else: var(--_amount-c-strong));
75
+ --_amount-l:
76
+ if(style(--direction: "softer"): var(--_amount-l-soft);
77
+ else: var(--_amount-l-strong));
78
+
79
+ --_lightness: calc((var(--_lightness-shift) - l) / var(--scale) * var(--_amount-l) + l);
80
+ --_chroma: calc((min(c, var(--_chroma-shift)) - c) / var(--scale) * var(--_amount-c) + c);
81
+
82
+ result: oklch(from var(--color) var(--_lightness) var(--_chroma) h);
83
+ }
84
+
85
+ @function --shift-color(
86
+ --color <color>,
87
+ --amount <integer>,
88
+ --direction <string>,
89
+ --scale <number>: 5
90
+ )
91
+ returns <color> {
92
+ --_amount_percentage: calc(100% - (var(--amount) * 10%));
93
+
94
+ --_hue-shifted-color: --shift-hue(var(--color), 100%, var(--direction));
95
+ --_hue-brightness-color: --shift-brightness(var(--_hue-shifted-color), var(--amount), var(--direction), var(--scale));
96
+
97
+ --_brightness-shifted-color: --shift-brightness(var(--color), var(--amount), var(--direction), var(--scale));
98
+
99
+ result: color-mix(in oklch, var(--_brightness-shifted-color) var(--_amount_percentage), var(--_hue-brightness-color));
100
+ }
101
+ }
@@ -0,0 +1,226 @@
1
+ /*
2
+ * Custom properties used
3
+ *
4
+ * // Buttons
5
+ * --button-icon-size: 2ex
6
+ * --button-icon-space: 1ch
7
+ *
8
+ * // Form elements
9
+ * --form-inner-spacing: calc(var(--spacing, 1.5rem) / 2)
10
+ *
11
+ */
12
+
13
+ @layer components {
14
+ button,
15
+ [type="button"],
16
+ [type="reset"],
17
+ [type="submit"],
18
+ .button {
19
+ --width: calc(var(--height) * 3.5);
20
+
21
+ display: inline-flex;
22
+ gap: var(--button-icon-space, 1ch);
23
+ align-items: center;
24
+ justify-content: center;
25
+
26
+ /* Icons inside buttons */
27
+ & svg,
28
+ & img,
29
+ & i {
30
+ width: var(--button-icon-size, 2ex);
31
+ height: var(--button-icon-size, 2ex);
32
+ }
33
+
34
+ /* Icon-only buttons */
35
+ /* Note: only-child does not count raw text nodes */
36
+ &:where(:has(svg:only-child, img:only-child, i:only-child)) {
37
+ --width: var(--height);
38
+ }
39
+ }
40
+
41
+ form {
42
+ display: flex;
43
+ flex-direction: column;
44
+ align-items: baseline;
45
+ gap: var(--form-inner-spacing, var(--spacing-sm, 0.5rem));
46
+
47
+ container-name: form;
48
+ container-type: inline-size;
49
+ margin-block-end: var(--spacing);
50
+ width: 100%;
51
+
52
+ /* Make all form elements full width of form */
53
+ &:where(*:not(button, [type="submit"], [type="reset"], [type="button"])) {
54
+ --width: 100%;
55
+ }
56
+ }
57
+
58
+ label {
59
+ font-weight: bolder;
60
+ }
61
+
62
+ :where(form > div),
63
+ :where(label:not(:has([type="radio"] + , [type="checkbox"] + ))) {
64
+ display: block;
65
+ width: 100%;
66
+ }
67
+
68
+ /* Compensate for flex-gap where label is directly followed by its form element */
69
+ :where(form > label + input),
70
+ :where(form > label + textarea) {
71
+ margin-block-start: calc(var(--form-inner-spacing, var(--spacing-sm, 0.5rem)) * -1);
72
+ }
73
+
74
+ /* Add asterisk to labels of required fields */
75
+ label:has([required], + [required]) {
76
+ &::after {
77
+ content: " * ";
78
+ }
79
+ }
80
+
81
+ fieldset {
82
+ --border-width: 1px;
83
+ --border-color: var(--color-form-elements, var(--color-primary));
84
+
85
+ border: var(--border-width) solid var(--border-color);
86
+ margin-block-start: calc(var(--border-width) * -1);
87
+ padding: var(--form-inner-spacing, var(--spacing-sm, 0.5rem));
88
+ }
89
+
90
+ legend {
91
+ color: var(--color-form-elements, var(--color-primary));
92
+ font-weight: 400;
93
+ }
94
+
95
+ select {
96
+ appearance: base-select;
97
+ }
98
+
99
+ details,
100
+ summary,
101
+ ::details-content {
102
+ transition-duration: 0.5s;
103
+ }
104
+
105
+ details {
106
+ border: 1px solid var(--color-form-elements, var(--color-primary));
107
+
108
+ & + :where(details) {
109
+ border-top: 0;
110
+ }
111
+
112
+ & > :where(:not(summary)) {
113
+ padding: var(--spacing);
114
+ }
115
+ }
116
+
117
+ summary {
118
+ border-block-end: 0 solid var(--color-form-elements, var(--color-primary));
119
+ cursor: pointer;
120
+ display: flex;
121
+ justify-content: space-between;
122
+ align-items: center;
123
+ padding-block: var(--spacing-sm, 0.5rem);
124
+ padding-inline: var(--spacing);
125
+
126
+ &::after {
127
+ content: '⌵';
128
+ transition-duration: 0.25s;
129
+ }
130
+
131
+ [open] &::after {
132
+ rotate: 180deg;
133
+ }
134
+ }
135
+
136
+ summary::marker {
137
+ display: none;
138
+ }
139
+
140
+ [open] summary {
141
+ border-block-end-width: 1px;
142
+ }
143
+
144
+ ::details-content {
145
+ height: 0;
146
+ overflow: clip;
147
+ }
148
+
149
+ [open]::details-content {
150
+ height: auto;
151
+ }
152
+
153
+ /* Default styles for dialogs, popovers, and backdrops */
154
+ [popover],
155
+ dialog {
156
+ border: 0;
157
+ margin: 0;
158
+ max-width: calc(100% - var(--spacing, 1.5rem));
159
+ max-height: calc(100% - var(--spacing, 1.5rem));
160
+ padding: 0;
161
+ }
162
+
163
+ /* Position popover at the bottom of the anchor, extending horizontally */
164
+ [popover] {
165
+ position-area: block-end span-all;
166
+ position-try-fallbacks: flip-block;
167
+ }
168
+
169
+ ::backdrop {
170
+ background-color: var(--color-background, black);
171
+ }
172
+
173
+ /* Default animations for dialogs, popovers, and backdrops */
174
+ /* Transition-to on close */
175
+ [popover],
176
+ dialog,
177
+ ::backdrop {
178
+ opacity: 0;
179
+ transition-duration: 0.5s;
180
+ }
181
+
182
+ /* Improve styling for popover hints */
183
+ [popover="hint"] {
184
+ text-align: center;
185
+ text-wrap: balance;
186
+ transition-duration: 0.25s;
187
+ }
188
+
189
+ /* When visible */
190
+ [popover]:popover-open,
191
+ dialog[open] {
192
+ opacity: 1;
193
+ }
194
+
195
+ /* Show backdrop only on dialog */
196
+ [open]::backdrop {
197
+ opacity: 0.8;
198
+ }
199
+
200
+ /* Transition-from on open */
201
+ @starting-style {
202
+ [popover]:popover-open,
203
+ [popover]:popover-open::backdrop,
204
+ dialog[open],
205
+ [open]::backdrop {
206
+ opacity: 0;
207
+ }
208
+ }
209
+ }
210
+
211
+ @layer overwrites {
212
+ /* Compensate for form spacing to maintain rhythm */
213
+ /* I am so deeply sorry for this selector */
214
+ form:where(:has(label:last-of-type:nth-of-type(odd)):has(*:last-child:nth-child(odd))),
215
+ form:where(:has(label:last-of-type:nth-of-type(even)):has(*:last-child:nth-child(even))) {
216
+ margin-block-end: calc(
217
+ var(--spacing) +
218
+ var(--form-inner-spacing, var(--spacing-sm, 0.5rem))
219
+ );
220
+ }
221
+
222
+ /* Center dialog on page */
223
+ dialog {
224
+ margin: auto;
225
+ }
226
+ }
package/css/layout.css ADDED
@@ -0,0 +1,112 @@
1
+ /*
2
+ * Custom properties used
3
+ * Be sure to set these to customize the reset otherwise the defaults will be used
4
+ * Variables marked with ✨ are prioritized for customization, the rest should work as-is
5
+ *
6
+ * //Sizing
7
+ * --section-spacing-x: [media-query dependent];
8
+ * --section-spacing-y: [media-query dependent];
9
+ * --max-content-width: 100rem ✨
10
+ *
11
+ */
12
+
13
+ /*---------- Page elements ----------*/
14
+
15
+ @layer layout {
16
+ body {
17
+ /* Creates section spacing variable for section-like elements */
18
+ --section-spacing-x: var(--spacing-lg);
19
+ --section-spacing-y: var(--spacing-xl);
20
+
21
+ @media (min-width: 40rem) {
22
+ --section-spacing-x: var(--spacing-xl);
23
+ --section-spacing-y: var(--spacing-xl);
24
+ }
25
+
26
+ @media (min-width: 60rem) {
27
+ --section-spacing-x: var(--spacing-2xl);
28
+ --section-spacing-y: var(--spacing-2xl);
29
+ }
30
+
31
+ @media (min-width: 80rem) {
32
+ --section-spacing-x: var(--spacing-3xl);
33
+ --section-spacing-y: var(--spacing-3xl);
34
+ }
35
+ }
36
+
37
+ /* Makes main span full height of page */
38
+ body,
39
+ main {
40
+ display: flex;
41
+ flex-direction: column;
42
+ }
43
+
44
+ /* Lets main's children span full height of page if desired */
45
+ main,
46
+ main > :where(section:only-child),
47
+ main > :where(article:only-child) {
48
+ flex: 1;
49
+ }
50
+
51
+ header,
52
+ main,
53
+ section,
54
+ article,
55
+ footer {
56
+ clear: both;
57
+ max-width: 100%;
58
+ position: relative;
59
+ }
60
+
61
+ header,
62
+ section,
63
+ article,
64
+ footer {
65
+ /* Limit width of an element while maintaining padding and centering */
66
+ padding-inline: max(var(--section-spacing-x), calc(50% - var(--max-content-width, 100rem) / 2));
67
+ }
68
+
69
+ /* Add default alignment for header and footer elements */
70
+ header,
71
+ footer {
72
+ display: flex;
73
+ align-items: center;
74
+ justify-content: center;
75
+ gap: var(--spacing, 1.5rem);
76
+ padding-block: var(--spacing, 1.5rem);
77
+
78
+ /* If header/footer contains more than one item */
79
+ &:where(:has(> :nth-child(2))) {
80
+ justify-content: space-between;
81
+ }
82
+
83
+ & > * {
84
+ margin-block-end: 0;
85
+ }
86
+ }
87
+
88
+ header {
89
+ & a,
90
+ & img {
91
+ display: block;
92
+ }
93
+ }
94
+
95
+ section,
96
+ article {
97
+ padding-block: var(--section-spacing-y);
98
+ }
99
+
100
+ /* Add default alignment for footer elements */
101
+ footer {
102
+ flex-direction: column;
103
+ text-align: center;
104
+
105
+ & p,
106
+ & ul,
107
+ & ol {
108
+ font-size: var(--font-size, 0.875rem);
109
+ justify-content: center;
110
+ }
111
+ }
112
+ }
@@ -0,0 +1,62 @@
1
+ @layer overwrites {
2
+ @media screen and (prefers-reduced-motion: reduce) {
3
+ /* Removes smooth-scrolling on user preference */
4
+ html {
5
+ scroll-behavior: auto;
6
+ }
7
+
8
+ /* Removes all transitions and animations */
9
+ * {
10
+ animation-duration: 0.001ms !important;
11
+ transition-duration: 0.001ms !important;
12
+ }
13
+ }
14
+
15
+ /* Removes bottom margin from last child of any element */
16
+ /* TODO: Upgrade to margin-trim whenever it's widespread */
17
+ :where(*:last-child) {
18
+ margin-block-end: 0;
19
+ }
20
+
21
+ :where(h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6) {
22
+ /* Removes margin from first child heading and headings preceeded by other headings */
23
+ &:first-child,
24
+ &:where(h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6) + & {
25
+ margin-block-start: 0;
26
+ }
27
+
28
+ /* Remove margin-bottom from heading selectors followed by other heading selectors */
29
+ &:has(+ :where(h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6)) {
30
+ margin-block-end: 0;
31
+ }
32
+ }
33
+
34
+ /* Remove styling from links containing images */
35
+ :where(a:has(img)) {
36
+ border-width: 0;
37
+ text-decoration: none;
38
+
39
+ &::before,
40
+ &::after {
41
+ content: none;
42
+ }
43
+ }
44
+
45
+ /* Hides elements */
46
+ [hidden] {
47
+ display: none;
48
+ }
49
+
50
+ /* Hides elements visually, leaves accessible to screenreaders */
51
+ /* .sr-only is always hidden, .visually hidden unhides when focused */
52
+ .sr-only,
53
+ .visually-hidden:not(:focus, :active, :focus-within) {
54
+ clip: rect(0 0 0 0);
55
+ clip-path: inset(50%);
56
+ overflow: hidden;
57
+ position: absolute;
58
+ white-space: nowrap;
59
+ width: 1px;
60
+ height: 1px;
61
+ }
62
+ }
package/css/rhythm.css ADDED
@@ -0,0 +1,247 @@
1
+ /*
2
+ * Custom properties used
3
+ * Be sure to set these to customize the reset otherwise the defaults will be used
4
+ * Variables marked with ✨ are prioritized for customization, the rest should work as-is
5
+ *
6
+ * // Text ✨
7
+ * --font-size-min: 16
8
+ * --font-size-max: 20
9
+ * --line-height-min: 1.25
10
+ * --line-height-max: 1.5
11
+ * --rhythm-scale-min: 1.25;
12
+ * --rhythm-scale-max: 1.5;
13
+ * --font-size-min-allowed: 12px;
14
+ *
15
+ * // Spacing ✨
16
+ * --spacing-scale: 1.5;
17
+ *
18
+ * // Screen sizes
19
+ * --font-size-min-viewport: 420
20
+ * --font-size-max-viewport: 1600
21
+ *
22
+ * // Variables created
23
+ * These are created on individual elements and set via --font-size-min/max and --line-height-min/max
24
+ * or by setting --rhythm-multiplier to scale text up or down based on base font-size
25
+ *
26
+ * font-size: var(--font-size);
27
+ * line-height: var(--line-height);
28
+ *
29
+ * // Variables created on body
30
+ * --RHYTHM_UNITS (CONST) - Body font-size = 1rem
31
+ * --RHYTHM (CONST) - Body line-height = 1rlh
32
+ * --spacing[-<size>] - Calculated by body line-height & spacing-scale
33
+ *
34
+ */
35
+
36
+ @layer rhythm {
37
+ @layer apply-first {
38
+ /*
39
+ Responsive typography with vertical rhythm
40
+ */
41
+
42
+ /* Global rhythm scale values ✨ */
43
+ /*
44
+ Useful text scales
45
+ Golden Ratio: 1.618
46
+ Minor Sixth: 1.6
47
+ Perfect Fifth: 1.5
48
+ Augmented Fourth: 1.414
49
+ Perfect Fourth: 1.333
50
+ Major Third: 1.25
51
+ Minor Third: 1.2
52
+ Major Second: 1.125
53
+ Minor Second: 1.067
54
+ */
55
+ :root {
56
+ --rhythm-scale-min: 1.25;
57
+ --rhythm-scale-max: 1.5;
58
+ --spacing-scale: var(--rhythm-scale-max);
59
+
60
+ /* Prevents font size from going below this value when using scales */
61
+ /* Set to 0 to disable */
62
+ --font-size-min-allowed: 12px;
63
+ }
64
+
65
+ /* Attach to common text-based elements */
66
+ body,
67
+ h1,
68
+ h2,
69
+ h3,
70
+ h4,
71
+ h5,
72
+ h6,
73
+ p,
74
+ a,
75
+ span,
76
+ sub,
77
+ sup,
78
+ button,
79
+ input,
80
+ label,
81
+ textarea,
82
+ select,
83
+ small,
84
+ figcaption,
85
+ caption,
86
+ table,
87
+ ul,
88
+ ol,
89
+ .rfs {
90
+ /* Step 1: Establish individual responsive font-size */
91
+
92
+ /*
93
+ Min and max font sizes to screen sizes
94
+ That is, font size will be 16px at 320px screen width and 20px at 1440px screen width
95
+ These values can be customized on each element to automatically update the formula
96
+ */
97
+ --font-size-min: 16;
98
+ --font-size-max: 20;
99
+ --font-size-min-viewport: 420;
100
+ --font-size-max-viewport: 1600;
101
+
102
+ /* Changing the --rhythm-multiplier variable will scale the text based on base calculated font size */
103
+ --rhythm-multiplier: 0;
104
+
105
+ --_font-size-min: calc(var(--font-size-min) * pow(var(--rhythm-scale-min), var(--rhythm-multiplier)));
106
+ --_font-size-max: calc(var(--font-size-max) * pow(var(--rhythm-scale-max), var(--rhythm-multiplier)));
107
+
108
+ /*
109
+ Converting from px to rem automatically for convenience and accessibility
110
+ If you want to set font-sizes in rem units from the start, you can set --font-size-units to 1rem
111
+ Default 1rem = 16px, so 1px = 0.0625rem
112
+ */
113
+ --font-size-units: calc(0.0625rem);
114
+ --viewport-units: 100vw;
115
+
116
+ /* Math. Don't worry about it. And don't touch. */
117
+
118
+ /* The vws */
119
+ --_font-size-step: calc(
120
+ (var(--_font-size-max) - var(--_font-size-min)) /
121
+ (var(--font-size-max-viewport) - var(--font-size-min-viewport))
122
+ );
123
+
124
+ /* The rems */
125
+ --_font-size-base-value: calc(
126
+ var(--_font-size-min) -
127
+ var(--font-size-min-viewport) *
128
+ var(--_font-size-step)
129
+ );
130
+
131
+ /*
132
+ Create font-size custom prop on selected elements
133
+ Selected elements can now use the --font-size prop
134
+
135
+ What's more, we can tweak the values established above such as
136
+ --font-size-min and --font-size-max, and the formula will update automatically
137
+ The same applies to the viewport units --font-size-min-viewport and --font-size-max-viewport
138
+ We can even set a custom --font-size prop on any element, and it will override the default
139
+ */
140
+
141
+ /* Using min() and max() inside the clamp, so we can reverse the order of the values if needed */
142
+ /* eg, a smaller font-size-max and a larger font-size-min */
143
+ --_font-size: clamp(
144
+ min(var(--_font-size-min), var(--_font-size-max)) *
145
+ var(--font-size-units),
146
+ var(--_font-size-base-value) *
147
+ var(--font-size-units) +
148
+ var(--_font-size-step) *
149
+ var(--viewport-units),
150
+ max(var(--_font-size-max), var(--_font-size-min)) *
151
+ var(--font-size-units)
152
+ );
153
+
154
+ --font-size: max(var(--font-size-min-allowed), var(--_font-size));
155
+
156
+ /* Using ems to lock current line-height to current font-size */
157
+ --line-height-units: 1em;
158
+
159
+ /* Min and max line-height */
160
+ --line-height-min: 1.25;
161
+ --line-height-max: 1.5;
162
+
163
+ /* Same viewport boundaries as font-size, using font-size values to convert from pixels */
164
+ --line-height-min-viewport: calc(var(--font-size-min-viewport) / var(--_font-size-min));
165
+ --line-height-max-viewport: calc(var(--font-size-max-viewport) / var(--_font-size-max));
166
+
167
+ /* You know the drill. No touchy. */
168
+
169
+ /* The vws */
170
+ --_line-height-step: calc(
171
+ (var(--line-height-max) - var(--line-height-min)) /
172
+ (var(--line-height-max-viewport) - var(--line-height-min-viewport))
173
+ );
174
+
175
+ /* The ems */
176
+ --_line-height-base-value: calc(
177
+ var(--line-height-min) -
178
+ var(--line-height-min-viewport) *
179
+ var(--_line-height-step)
180
+ );
181
+
182
+ /*
183
+ Just like with --font-size, all elements will now have access to responsive line-height
184
+ And we can tweak the values established above such as --line-height-min and --line-height-max
185
+ */
186
+ --line-height: clamp(
187
+ min(var(--line-height-min), var(--line-height-max)) *
188
+ var(--line-height-units),
189
+ var(--_line-height-base-value) *
190
+ var(--line-height-units) +
191
+ var(--_line-height-step) *
192
+ var(--viewport-units),
193
+ max(var(--line-height-max), var(--line-height-min)) *
194
+ var(--line-height-units)
195
+ );
196
+ }
197
+
198
+ body {
199
+ /* We can now set font-size and line-height to their respective props */
200
+ font-size: var(--font-size);
201
+ line-height: var(--line-height);
202
+
203
+ /*
204
+ Notice that we are starting our type rhythm from the body element
205
+ The HTML element is untouched, meaning our root units remain at defaults
206
+ The reason for this is so we can use the root units to easily calculate sizes
207
+ If we start our rhythm from the root element and try to calculate sizes from there,
208
+ such as setting a paragraph at 16px or a heading at 4rem, we'll find that we have to
209
+ do a lot of math to get the right values. Such math is beyond my delicate constitution.
210
+
211
+ This is our new rem-unit and can be used whenever needed to refer to body font-size
212
+ NOTE: Please treat this as a CONST and do not edit or overwrite
213
+ */
214
+ --RHYTHM_UNITS: var(--font-size);
215
+
216
+ /*
217
+ Create rhythm by locking to body line-height
218
+ This is our new rlh unit and can be used anywhere to refer to body line-height
219
+ NOTE: Please treat this as a CONST and do not edit or overwrite
220
+ */
221
+ --RHYTHM: clamp(
222
+ min(var(--line-height-min), var(--line-height-max)) *
223
+ var(--RHYTHM_UNITS),
224
+ var(--_line-height-base-value) *
225
+ var(--RHYTHM_UNITS) +
226
+ var(--_line-height-step) *
227
+ var(--viewport-units),
228
+ max(var(--line-height-max), var(--line-height-min)) *
229
+ var(--RHYTHM_UNITS)
230
+ );
231
+
232
+ /* Here, a safe prop you can overwrite and play with as needed */
233
+ --spacing: var(--RHYTHM);
234
+
235
+ /* Might as well */
236
+ --spacing-xs: calc(var(--spacing) * pow(var(--spacing-scale), -4));
237
+ --spacing-sm: calc(var(--spacing) * pow(var(--spacing-scale), -2));
238
+ --spacing-md: var(--spacing);
239
+ --spacing-lg: calc(var(--spacing) * pow(var(--spacing-scale), 1));
240
+ --spacing-xl: calc(var(--spacing) * pow(var(--spacing-scale), 2));
241
+ --spacing-2xl: calc(var(--spacing) * pow(var(--spacing-scale), 3));
242
+ --spacing-3xl: calc(var(--spacing) * pow(var(--spacing-scale), 4));
243
+ --spacing-4xl: calc(var(--spacing) * pow(var(--spacing-scale), 5));
244
+ --spacing-5xl: calc(var(--spacing) * pow(var(--spacing-scale), 6));
245
+ }
246
+ }
247
+ }
package/package.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@giana/cryptic-reset",
3
+ "version": "1.0.0",
4
+ "description": "An opinionated reset/starter for personal CSS projects",
5
+ "main": "reset.css",
6
+ "style": "reset.css",
7
+ "author": "Giana Blantin <giana@blantin.com> (https://giana.im)",
8
+ "license": "MIT",
9
+ "files": [
10
+ "reset.css",
11
+ "css/"
12
+ ],
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/gianablantin/cryptic-reset.git"
16
+ },
17
+ "devDependencies": {
18
+ "@biomejs/biome": "2.4.3"
19
+ }
20
+ }
package/reset.css ADDED
@@ -0,0 +1,8 @@
1
+ @layer color, base, rhythm.apply-first, rhythm, layout, components, utilities, overwrites, default;
2
+
3
+ @import "css/color.css";
4
+ @import "css/base.css";
5
+ @import "css/rhythm.css";
6
+ @import "css/layout.css";
7
+ @import "css/components.css";
8
+ @import "css/overwrites.css";