elvish-css 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 +21 -0
- package/README.md +518 -0
- package/dist/elvish.css +2194 -0
- package/dist/elvish.d.ts +78 -0
- package/dist/elvish.esm.js +2185 -0
- package/dist/elvish.iife.js +2169 -0
- package/dist/elvish.min.css +9 -0
- package/dist/elvish.umd.js +2173 -0
- package/elvish.css +28 -0
- package/elvish.js +81 -0
- package/global/global.css +16 -0
- package/global/modern.css +305 -0
- package/global/reset.css +507 -0
- package/global/tokens.css +154 -0
- package/global/transitions.css +288 -0
- package/global/transitions.js +289 -0
- package/global/utilities.css +151 -0
- package/package.json +61 -0
- package/primitives/adleithian/adleithian.css +16 -0
- package/primitives/adleithian/adleithian.js +63 -0
- package/primitives/bau/bau.css +86 -0
- package/primitives/bau/bau.js +127 -0
- package/primitives/enedh/enedh.css +38 -0
- package/primitives/enedh/enedh.js +110 -0
- package/primitives/esgal/esgal.css +39 -0
- package/primitives/esgal/esgal.js +115 -0
- package/primitives/fano/fano.css +28 -0
- package/primitives/fano/fano.js +108 -0
- package/primitives/gant-thala/gant-thala.css +32 -0
- package/primitives/gant-thala/gant-thala.js +69 -0
- package/primitives/glan-tholl/glan-tholl.css +71 -0
- package/primitives/glan-tholl/glan-tholl.js +147 -0
- package/primitives/glan-veleg/glan-veleg.css +45 -0
- package/primitives/glan-veleg/glan-veleg.js +138 -0
- package/primitives/gonath/gonath.css +57 -0
- package/primitives/gonath/gonath.js +113 -0
- package/primitives/gwistindor/gwistindor.css +52 -0
- package/primitives/gwistindor/gwistindor.js +96 -0
- package/primitives/hath/hath.css +39 -0
- package/primitives/hath/hath.js +107 -0
- package/primitives/him/him.css +43 -0
- package/primitives/him/him.js +169 -0
- package/primitives/miriant/miriant.css +75 -0
- package/primitives/miriant/miriant.js +158 -0
- package/primitives/thann/thann.css +57 -0
- package/primitives/thann/thann.js +96 -0
- package/primitives/tiniath/tiniath.css +16 -0
- package/primitives/tiniath/tiniath.js +88 -0
- package/primitives/vircantie/vircantie.css +24 -0
- package/primitives/vircantie/vircantie.js +83 -0
package/global/reset.css
ADDED
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Elvish - Modern Reset & Axioms
|
|
3
|
+
*
|
|
4
|
+
* A synthesis of Andy Bell's "More Modern CSS Reset" and Elvish's original reset.
|
|
5
|
+
* Optimized for Chrome/Edge with graceful degradation for Safari/Firefox.
|
|
6
|
+
*
|
|
7
|
+
* Sources:
|
|
8
|
+
* - [AB] Andy Bell's "A (More) Modern CSS Reset"
|
|
9
|
+
* - [EL] Elvish original reset
|
|
10
|
+
* - [NEW] New additions for modern browsers
|
|
11
|
+
*
|
|
12
|
+
* Debug Mode:
|
|
13
|
+
* Add .mellon or .debug to <body> or any element to reveal layout structure.
|
|
14
|
+
* "Mellon" is Sindarin for "friend" - the password to enter Moria.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/* ==========================================================================
|
|
18
|
+
BOX SIZING [AB + EL]
|
|
19
|
+
Both resets agree. Universal consensus.
|
|
20
|
+
========================================================================== */
|
|
21
|
+
|
|
22
|
+
*,
|
|
23
|
+
*::before,
|
|
24
|
+
*::after {
|
|
25
|
+
box-sizing: border-box;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* ==========================================================================
|
|
29
|
+
BORDER & BACKGROUND DEFAULTS [EL + NEW]
|
|
30
|
+
|
|
31
|
+
Layout-focused philosophy: visual styling is opt-in, not opt-out.
|
|
32
|
+
- Borders: style is solid (for easy `border-width: 1px`), but width is 0
|
|
33
|
+
- Backgrounds: transparent by default
|
|
34
|
+
- This means elements are "invisible" until explicitly styled
|
|
35
|
+
========================================================================== */
|
|
36
|
+
|
|
37
|
+
*,
|
|
38
|
+
*::before,
|
|
39
|
+
*::after {
|
|
40
|
+
/* Border: ready to use, but invisible by default */
|
|
41
|
+
border-style: solid;
|
|
42
|
+
border-width: 0;
|
|
43
|
+
|
|
44
|
+
/* Background: transparent until explicitly set */
|
|
45
|
+
background-color: transparent;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* Root elements get the actual background */
|
|
49
|
+
html {
|
|
50
|
+
background-color: var(--color-surface);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/* ==========================================================================
|
|
54
|
+
MARGIN RESET [AB - expanded]
|
|
55
|
+
|
|
56
|
+
DISCARDED from Elvish: `* { margin: 0 }` is too aggressive.
|
|
57
|
+
It breaks nested lists, fieldset legends, and third-party components.
|
|
58
|
+
|
|
59
|
+
Andy Bell's surgical approach is safer - only reset elements that commonly
|
|
60
|
+
have problematic default margins. Expanded to include pre, h5, h6.
|
|
61
|
+
========================================================================== */
|
|
62
|
+
|
|
63
|
+
body,
|
|
64
|
+
h1, h2, h3, h4, h5, h6,
|
|
65
|
+
p,
|
|
66
|
+
figure,
|
|
67
|
+
blockquote,
|
|
68
|
+
dl, dd,
|
|
69
|
+
pre,
|
|
70
|
+
fieldset {
|
|
71
|
+
margin: 0;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* ==========================================================================
|
|
75
|
+
MEASURE AXIOM [EL]
|
|
76
|
+
|
|
77
|
+
Not in Andy Bell's reset - this is Elvish's core philosophy.
|
|
78
|
+
|
|
79
|
+
No line of text should exceed a comfortable reading length.
|
|
80
|
+
Exception-based: everything gets the constraint, then we remove it
|
|
81
|
+
from elements that need to contain multiple adjacent boxes.
|
|
82
|
+
========================================================================== */
|
|
83
|
+
|
|
84
|
+
* {
|
|
85
|
+
max-inline-size: var(--measure);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
html,
|
|
89
|
+
body,
|
|
90
|
+
div,
|
|
91
|
+
section,
|
|
92
|
+
article,
|
|
93
|
+
aside,
|
|
94
|
+
header,
|
|
95
|
+
footer,
|
|
96
|
+
nav,
|
|
97
|
+
main,
|
|
98
|
+
form,
|
|
99
|
+
fieldset,
|
|
100
|
+
figure,
|
|
101
|
+
figcaption,
|
|
102
|
+
picture,
|
|
103
|
+
video,
|
|
104
|
+
canvas,
|
|
105
|
+
iframe,
|
|
106
|
+
details,
|
|
107
|
+
summary,
|
|
108
|
+
dialog,
|
|
109
|
+
menu,
|
|
110
|
+
hgroup,
|
|
111
|
+
address,
|
|
112
|
+
/* Custom elements - Elvish layout primitives (Sindarin names) */
|
|
113
|
+
i-hath, /* Stack */
|
|
114
|
+
i-bau, /* Box */
|
|
115
|
+
i-enedh, /* Center (horizontal) */
|
|
116
|
+
i-tiniath, /* Cluster */
|
|
117
|
+
i-glan-veleg, /* Sidebar */
|
|
118
|
+
i-gwistindor, /* Switcher */
|
|
119
|
+
i-esgal, /* Cover (vertical center) */
|
|
120
|
+
i-vircantie, /* Grid */
|
|
121
|
+
i-gant-thala, /* Frame (aspect) */
|
|
122
|
+
i-glan-tholl, /* Reel (side-scrolling) */
|
|
123
|
+
i-fano, /* Imposter (overlay) */
|
|
124
|
+
i-thann, /* Icon */
|
|
125
|
+
i-adleithian, /* Container */
|
|
126
|
+
i-him, /* Sticky */
|
|
127
|
+
i-miriant, /* Grid-placed */
|
|
128
|
+
i-gonath { /* Masonry */
|
|
129
|
+
max-inline-size: none;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* ==========================================================================
|
|
133
|
+
ROOT DEFAULTS [AB + EL + NEW]
|
|
134
|
+
========================================================================== */
|
|
135
|
+
|
|
136
|
+
html {
|
|
137
|
+
/* [EL] Font settings via design tokens */
|
|
138
|
+
font-family: var(--font-plain);
|
|
139
|
+
font-size: 100%; /* Respects user preferences */
|
|
140
|
+
line-height: var(--line-height);
|
|
141
|
+
|
|
142
|
+
/* [EL] Colors */
|
|
143
|
+
color: var(--color-text);
|
|
144
|
+
/* background-color set above in BORDER & BACKGROUND DEFAULTS */
|
|
145
|
+
|
|
146
|
+
/* [NEW] Text rendering - prioritize legibility */
|
|
147
|
+
text-rendering: optimizeLegibility;
|
|
148
|
+
-webkit-font-smoothing: antialiased;
|
|
149
|
+
-moz-osx-font-smoothing: grayscale;
|
|
150
|
+
|
|
151
|
+
/* [NEW] Prevent text size inflation on mobile */
|
|
152
|
+
-webkit-text-size-adjust: 100%;
|
|
153
|
+
text-size-adjust: 100%;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/* [AB] Smooth scrolling ONLY when using keyboard navigation */
|
|
157
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
158
|
+
html:focus-within {
|
|
159
|
+
scroll-behavior: smooth;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/* ==========================================================================
|
|
164
|
+
BODY DEFAULTS [EL + NEW]
|
|
165
|
+
========================================================================== */
|
|
166
|
+
|
|
167
|
+
body {
|
|
168
|
+
/* [EL] Full viewport height - dvh accounts for mobile browser chrome */
|
|
169
|
+
min-block-size: 100vh;
|
|
170
|
+
min-block-size: 100dvh;
|
|
171
|
+
|
|
172
|
+
/* [NEW] Prevent horizontal overflow from animations, etc. */
|
|
173
|
+
overflow-x: clip;
|
|
174
|
+
|
|
175
|
+
/* Body gets the surface background */
|
|
176
|
+
background-color: var(--color-surface);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/* ==========================================================================
|
|
180
|
+
TYPOGRAPHY [EL + NEW]
|
|
181
|
+
========================================================================== */
|
|
182
|
+
|
|
183
|
+
h1, h2, h3, h4, h5, h6 {
|
|
184
|
+
/* [EL] Tighter line height for headings */
|
|
185
|
+
line-height: var(--line-height-tight);
|
|
186
|
+
|
|
187
|
+
/* [NEW] Balanced wrapping for headings (Chrome 114+, Safari 17.5+) */
|
|
188
|
+
text-wrap: balance;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/* [EL] Modular scale sizing */
|
|
192
|
+
h1 { font-size: var(--s4); }
|
|
193
|
+
h2 { font-size: var(--s3); }
|
|
194
|
+
h3 { font-size: var(--s2); }
|
|
195
|
+
h4 { font-size: var(--s1); }
|
|
196
|
+
h5 { font-size: var(--s0); }
|
|
197
|
+
h6 { font-size: var(--s-1); }
|
|
198
|
+
|
|
199
|
+
/* [NEW] Pretty wrapping for prose (Chrome 117+) */
|
|
200
|
+
p {
|
|
201
|
+
text-wrap: pretty;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/* ==========================================================================
|
|
205
|
+
LINKS [AB + EL]
|
|
206
|
+
========================================================================== */
|
|
207
|
+
|
|
208
|
+
a {
|
|
209
|
+
/* [EL] Inherit color - style via classes or context */
|
|
210
|
+
color: currentColor;
|
|
211
|
+
|
|
212
|
+
/* [AB] Better underline rendering - skips descenders (g, y, p) */
|
|
213
|
+
text-decoration-skip-ink: auto;
|
|
214
|
+
|
|
215
|
+
/* [NEW] Modern underline offset for readability */
|
|
216
|
+
text-underline-offset: 0.2em;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/* [EL] Remove underline on hover */
|
|
220
|
+
a:hover {
|
|
221
|
+
text-decoration: none;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/* [NEW] Focus styles for keyboard navigation */
|
|
225
|
+
a:focus-visible {
|
|
226
|
+
outline: 2px solid var(--color-accent, currentColor);
|
|
227
|
+
outline-offset: 2px;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/* ==========================================================================
|
|
231
|
+
MEDIA [EL - expanded from AB]
|
|
232
|
+
========================================================================== */
|
|
233
|
+
|
|
234
|
+
img,
|
|
235
|
+
picture,
|
|
236
|
+
video,
|
|
237
|
+
canvas,
|
|
238
|
+
svg {
|
|
239
|
+
display: block;
|
|
240
|
+
max-inline-size: 100%;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
img,
|
|
244
|
+
picture,
|
|
245
|
+
video {
|
|
246
|
+
/* [EL] Maintain aspect ratio */
|
|
247
|
+
block-size: auto;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/* [NEW] Style for alt text when image fails to load */
|
|
251
|
+
img {
|
|
252
|
+
font-style: italic;
|
|
253
|
+
vertical-align: middle;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/* ==========================================================================
|
|
257
|
+
FORM ELEMENTS [AB + EL]
|
|
258
|
+
========================================================================== */
|
|
259
|
+
|
|
260
|
+
input,
|
|
261
|
+
button,
|
|
262
|
+
textarea,
|
|
263
|
+
select {
|
|
264
|
+
/* [AB + EL] Inherit font from parent */
|
|
265
|
+
font: inherit;
|
|
266
|
+
/* [EL] Inherit color too */
|
|
267
|
+
color: inherit;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/* [EL] Indicate buttons are clickable */
|
|
271
|
+
button,
|
|
272
|
+
[role="button"] {
|
|
273
|
+
cursor: pointer;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/* [NEW] Textarea should not resize horizontally */
|
|
277
|
+
textarea {
|
|
278
|
+
resize: vertical;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/* ==========================================================================
|
|
282
|
+
LISTS [EL - modified]
|
|
283
|
+
========================================================================== */
|
|
284
|
+
|
|
285
|
+
ul,
|
|
286
|
+
ol {
|
|
287
|
+
list-style: none;
|
|
288
|
+
padding: 0;
|
|
289
|
+
margin: 0;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/* [NEW] Restore list styles when explicitly marked for semantics */
|
|
293
|
+
ul[role="list"],
|
|
294
|
+
ol[role="list"],
|
|
295
|
+
ul.list,
|
|
296
|
+
ol.list {
|
|
297
|
+
list-style: revert;
|
|
298
|
+
padding-inline-start: 1em;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/* ==========================================================================
|
|
302
|
+
TABLES [EL]
|
|
303
|
+
========================================================================== */
|
|
304
|
+
|
|
305
|
+
table {
|
|
306
|
+
border-collapse: collapse;
|
|
307
|
+
border-spacing: 0;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/* [NEW] Inherit text alignment */
|
|
311
|
+
th {
|
|
312
|
+
text-align: inherit;
|
|
313
|
+
font-weight: inherit;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/* ==========================================================================
|
|
317
|
+
CODE [EL]
|
|
318
|
+
========================================================================== */
|
|
319
|
+
|
|
320
|
+
pre,
|
|
321
|
+
code,
|
|
322
|
+
kbd,
|
|
323
|
+
samp {
|
|
324
|
+
font-family: var(--font-mono);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
pre {
|
|
328
|
+
overflow-x: auto;
|
|
329
|
+
white-space: pre;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/* ==========================================================================
|
|
333
|
+
MISC ELEMENTS [EL + NEW]
|
|
334
|
+
========================================================================== */
|
|
335
|
+
|
|
336
|
+
/* [EL] Horizontal rule */
|
|
337
|
+
hr {
|
|
338
|
+
border-width: var(--border-thin, 1px) 0 0 0;
|
|
339
|
+
color: inherit;
|
|
340
|
+
block-size: 0;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/* [NEW] Abbreviations with title should indicate expandability */
|
|
344
|
+
abbr[title] {
|
|
345
|
+
text-decoration: underline dotted;
|
|
346
|
+
cursor: help;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/* [NEW] Summary cursor */
|
|
350
|
+
summary {
|
|
351
|
+
cursor: pointer;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/* ==========================================================================
|
|
355
|
+
SELECTION [NEW]
|
|
356
|
+
========================================================================== */
|
|
357
|
+
|
|
358
|
+
::selection {
|
|
359
|
+
background-color: var(--color-accent, highlight);
|
|
360
|
+
color: var(--color-accent-text, highlighttext);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/* ==========================================================================
|
|
364
|
+
FOCUS STATES [NEW]
|
|
365
|
+
========================================================================== */
|
|
366
|
+
|
|
367
|
+
/* Remove default focus outline */
|
|
368
|
+
:focus {
|
|
369
|
+
outline: none;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/* Visible focus for keyboard navigation only */
|
|
373
|
+
:focus-visible {
|
|
374
|
+
outline: 2px solid var(--color-accent, currentColor);
|
|
375
|
+
outline-offset: 2px;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/* ==========================================================================
|
|
379
|
+
REDUCED MOTION [AB - expanded]
|
|
380
|
+
========================================================================== */
|
|
381
|
+
|
|
382
|
+
@media (prefers-reduced-motion: reduce) {
|
|
383
|
+
*,
|
|
384
|
+
*::before,
|
|
385
|
+
*::after {
|
|
386
|
+
/* [AB] Kill all animations */
|
|
387
|
+
animation-duration: 0.01ms !important;
|
|
388
|
+
animation-iteration-count: 1 !important;
|
|
389
|
+
|
|
390
|
+
/* [AB] Kill all transitions */
|
|
391
|
+
transition-duration: 0.01ms !important;
|
|
392
|
+
|
|
393
|
+
/* [AB] Kill smooth scrolling */
|
|
394
|
+
scroll-behavior: auto !important;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/* [NEW] Also target View Transitions */
|
|
398
|
+
::view-transition-group(*),
|
|
399
|
+
::view-transition-old(*),
|
|
400
|
+
::view-transition-new(*) {
|
|
401
|
+
animation: none !important;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/* ==========================================================================
|
|
406
|
+
DEBUG MODE - "MELLON" [NEW]
|
|
407
|
+
|
|
408
|
+
Add .mellon or .debug to <body> or any element to reveal layout structure.
|
|
409
|
+
"Mellon" is Sindarin for "friend" - the password to enter Moria.
|
|
410
|
+
|
|
411
|
+
Features:
|
|
412
|
+
- Dashed outlines show element boundaries (uses outline, not border)
|
|
413
|
+
- Each nesting level gets a different hue (rainbow effect)
|
|
414
|
+
- Optional .tint modifier adds subtle background colors
|
|
415
|
+
- Zero specificity via :where() - easily overridden by real styles
|
|
416
|
+
|
|
417
|
+
Usage:
|
|
418
|
+
<body class="mellon"> - Debug entire page
|
|
419
|
+
<body class="mellon tint"> - Debug with background tints
|
|
420
|
+
<div class="debug"> - Debug specific section
|
|
421
|
+
========================================================================== */
|
|
422
|
+
|
|
423
|
+
/* Debug color tokens */
|
|
424
|
+
:root {
|
|
425
|
+
--debug-stroke: 1px;
|
|
426
|
+
--debug-style: dashed;
|
|
427
|
+
--debug-saturation: 0.25;
|
|
428
|
+
--debug-lightness: 55%;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/* Calculate hue based on depth (golden angle ≈ 137.5° for optimal distribution) */
|
|
432
|
+
:where(.mellon, .debug),
|
|
433
|
+
:where(.mellon, .debug) :where(*) {
|
|
434
|
+
--debug-hue: 0;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
:where(.mellon, .debug) > :where(*) { --debug-hue: 137; }
|
|
438
|
+
:where(.mellon, .debug) > :where(*) > :where(*) { --debug-hue: 275; }
|
|
439
|
+
:where(.mellon, .debug) > :where(*) > :where(*) > :where(*) { --debug-hue: 52; }
|
|
440
|
+
:where(.mellon, .debug) > :where(*) > :where(*) > :where(*) > :where(*) { --debug-hue: 190; }
|
|
441
|
+
:where(.mellon, .debug) > :where(*) > :where(*) > :where(*) > :where(*) > :where(*) { --debug-hue: 327; }
|
|
442
|
+
:where(.mellon, .debug) > :where(*) > :where(*) > :where(*) > :where(*) > :where(*) > :where(*) { --debug-hue: 105; }
|
|
443
|
+
|
|
444
|
+
/* Show outlines in debug mode */
|
|
445
|
+
:where(.mellon, .debug),
|
|
446
|
+
:where(.mellon, .debug) :where(*) {
|
|
447
|
+
outline: var(--debug-stroke) var(--debug-style)
|
|
448
|
+
oklch(var(--debug-lightness) var(--debug-saturation) var(--debug-hue, 0)) !important;
|
|
449
|
+
outline-offset: -1px;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/* Highlight Elvish primitives more prominently */
|
|
453
|
+
:where(.mellon, .debug) :where(
|
|
454
|
+
i-hath, i-bau, i-enedh, i-tiniath, i-glan-veleg, i-gwistindor,
|
|
455
|
+
i-esgal, i-vircantie, i-gant-thala, i-glan-tholl, i-fano, i-thann,
|
|
456
|
+
i-adleithian, i-him, i-miriant, i-gonath
|
|
457
|
+
) {
|
|
458
|
+
--debug-stroke: 2px;
|
|
459
|
+
--debug-style: solid;
|
|
460
|
+
--debug-saturation: 0.4;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/* Optional: Background tint mode */
|
|
464
|
+
:where(.mellon.tint, .debug.tint),
|
|
465
|
+
:where(.mellon.tint, .debug.tint) :where(*) {
|
|
466
|
+
background-color: oklch(
|
|
467
|
+
var(--debug-lightness)
|
|
468
|
+
calc(var(--debug-saturation) * 0.4)
|
|
469
|
+
var(--debug-hue, 0)
|
|
470
|
+
/ 0.1
|
|
471
|
+
) !important;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/* ==========================================================================
|
|
475
|
+
UTILITIES [EL + NEW]
|
|
476
|
+
========================================================================== */
|
|
477
|
+
|
|
478
|
+
/* [EL] Hidden but accessible to screen readers */
|
|
479
|
+
.visually-hidden,
|
|
480
|
+
.sr-only {
|
|
481
|
+
position: absolute;
|
|
482
|
+
inline-size: 1px;
|
|
483
|
+
block-size: 1px;
|
|
484
|
+
padding: 0;
|
|
485
|
+
margin: -1px;
|
|
486
|
+
overflow: hidden;
|
|
487
|
+
clip: rect(0, 0, 0, 0);
|
|
488
|
+
clip-path: inset(50%);
|
|
489
|
+
white-space: nowrap;
|
|
490
|
+
border: 0;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
/* [NEW] Skip link pattern for accessibility */
|
|
494
|
+
.skip-link {
|
|
495
|
+
position: absolute;
|
|
496
|
+
inset-inline-start: 0;
|
|
497
|
+
inset-block-start: 0;
|
|
498
|
+
padding: var(--s-1, 0.5rem) var(--s0, 1rem);
|
|
499
|
+
background: var(--color-accent, highlight);
|
|
500
|
+
color: var(--color-accent-text, highlighttext);
|
|
501
|
+
transform: translateY(-100%);
|
|
502
|
+
z-index: 9999;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
.skip-link:focus {
|
|
506
|
+
transform: translateY(0);
|
|
507
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Elvish - Design Tokens
|
|
3
|
+
*
|
|
4
|
+
* Modular scale and design tokens for consistent spacing,
|
|
5
|
+
* typography, and colors throughout the system.
|
|
6
|
+
*
|
|
7
|
+
* Uses modern CSS features:
|
|
8
|
+
* - light-dark() for automatic theme switching
|
|
9
|
+
* - Relative color syntax (oklch) for derived colors
|
|
10
|
+
*
|
|
11
|
+
* RATIO MODES:
|
|
12
|
+
* - golden (φ = 1.618): Classical, dramatic, organic - best for CTAs & impact
|
|
13
|
+
* - silver (√2 = 1.414): Subtle, modern, ISO paper ratios - best for dense content
|
|
14
|
+
* - fifth (1.5): Musical, balanced middle-ground
|
|
15
|
+
*
|
|
16
|
+
* To change: set --ratio-mode on :root or any container
|
|
17
|
+
* :root { --ratio-mode: silver; }
|
|
18
|
+
* .documentation { --ratio-mode: silver; }
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
:root {
|
|
22
|
+
/* ===== COLOR SCHEME ===== */
|
|
23
|
+
color-scheme: light dark;
|
|
24
|
+
|
|
25
|
+
/* ===== RATIO PRESETS ===== */
|
|
26
|
+
--ratio-golden: 1.618; /* φ - Golden Ratio */
|
|
27
|
+
--ratio-silver: 1.414; /* √2 - Silver/Lichtenberg Ratio */
|
|
28
|
+
--ratio-fifth: 1.5; /* Perfect Fifth (musical) */
|
|
29
|
+
|
|
30
|
+
/* ===== ACTIVE RATIO ===== */
|
|
31
|
+
/* Default: Perfect Fifth for balanced harmony */
|
|
32
|
+
--ratio: var(--ratio-fifth);
|
|
33
|
+
|
|
34
|
+
/* ===== MODULAR SCALE ===== */
|
|
35
|
+
/*
|
|
36
|
+
* Golden Ratio scale at 16px base:
|
|
37
|
+
* s-2: 6px | s-1: 10px | s0: 16px (base)
|
|
38
|
+
* s1: 26px | s2: 42px | s3: 68px
|
|
39
|
+
* s4: 110px | s5: 178px
|
|
40
|
+
*/
|
|
41
|
+
--s-5: calc(var(--s-4) / var(--ratio));
|
|
42
|
+
--s-4: calc(var(--s-3) / var(--ratio));
|
|
43
|
+
--s-3: calc(var(--s-2) / var(--ratio));
|
|
44
|
+
--s-2: calc(var(--s-1) / var(--ratio));
|
|
45
|
+
--s-1: calc(var(--s0) / var(--ratio));
|
|
46
|
+
--s0: 1rem;
|
|
47
|
+
--s1: calc(var(--s0) * var(--ratio));
|
|
48
|
+
--s2: calc(var(--s1) * var(--ratio));
|
|
49
|
+
--s3: calc(var(--s2) * var(--ratio));
|
|
50
|
+
--s4: calc(var(--s3) * var(--ratio));
|
|
51
|
+
--s5: calc(var(--s4) * var(--ratio));
|
|
52
|
+
|
|
53
|
+
/* ===== MEASURE (Text) ===== */
|
|
54
|
+
/* Maximum line length for readable text - varies by ratio */
|
|
55
|
+
--measure: 70ch; /* Default for Fifth; Golden=60ch, Silver=80ch */
|
|
56
|
+
|
|
57
|
+
/* ===== LAYOUT THRESHOLDS ===== */
|
|
58
|
+
/*
|
|
59
|
+
* These are for LAYOUT decisions, not text readability.
|
|
60
|
+
* Use rem (not ch) because layout is about physical space, not characters.
|
|
61
|
+
*/
|
|
62
|
+
--layout-threshold-sm: 30rem; /* ~480px - phone landscape */
|
|
63
|
+
--layout-threshold-md: 45rem; /* ~720px - tablet portrait */
|
|
64
|
+
--layout-threshold-lg: 60rem; /* ~960px - tablet landscape */
|
|
65
|
+
--layout-threshold-xl: 75rem; /* ~1200px - small desktop */
|
|
66
|
+
|
|
67
|
+
/* ===== BRAND COLOR (Single source of truth) ===== */
|
|
68
|
+
/* Teal: rgba(0, 233, 188, 1) converted to OKLCH */
|
|
69
|
+
--brand: oklch(83% 0.17 168);
|
|
70
|
+
|
|
71
|
+
/* ===== DERIVED COLORS (Relative Color Syntax) ===== */
|
|
72
|
+
/* Lighten/darken by adjusting L (lightness) */
|
|
73
|
+
--brand-lighter: oklch(from var(--brand) calc(l + 0.3) c h);
|
|
74
|
+
--brand-light: oklch(from var(--brand) calc(l + 0.15) c h);
|
|
75
|
+
--brand-dark: oklch(from var(--brand) calc(l - 0.1) c h);
|
|
76
|
+
--brand-darker: oklch(from var(--brand) calc(l - 0.2) c h);
|
|
77
|
+
|
|
78
|
+
/* Desaturate by reducing C (chroma) */
|
|
79
|
+
--brand-muted: oklch(from var(--brand) l calc(c * 0.5) h);
|
|
80
|
+
--brand-subtle: oklch(from var(--brand) l calc(c * 0.25) h);
|
|
81
|
+
|
|
82
|
+
/* Transparency variants */
|
|
83
|
+
--brand-ghost: oklch(from var(--brand) l c h / 0.1);
|
|
84
|
+
--brand-overlay: oklch(from var(--brand) l c h / 0.85);
|
|
85
|
+
|
|
86
|
+
/* Complementary/Analogous via hue shift */
|
|
87
|
+
--brand-complement: oklch(from var(--brand) l c calc(h + 180));
|
|
88
|
+
--brand-analogous-1: oklch(from var(--brand) l c calc(h + 30));
|
|
89
|
+
--brand-analogous-2: oklch(from var(--brand) l c calc(h - 30));
|
|
90
|
+
|
|
91
|
+
/* ===== SEMANTIC COLORS (light-dark auto-switching) ===== */
|
|
92
|
+
--color-surface: light-dark(#ffffff, #1a1a2e);
|
|
93
|
+
--color-surface-raised: light-dark(#f8f9fa, #252538);
|
|
94
|
+
--color-surface-sunken: light-dark(#e9ecef, #12121c);
|
|
95
|
+
|
|
96
|
+
--color-text: light-dark(#1a1a2e, #f0f0f5);
|
|
97
|
+
--color-text-muted: light-dark(#6c757d, #9ca3af);
|
|
98
|
+
--color-text-subtle: light-dark(#adb5bd, #6b7280);
|
|
99
|
+
|
|
100
|
+
--color-border: light-dark(#dee2e6, #374151);
|
|
101
|
+
--color-border-strong: light-dark(#adb5bd, #4b5563);
|
|
102
|
+
|
|
103
|
+
/* Accent adapts to theme */
|
|
104
|
+
--color-accent: light-dark(
|
|
105
|
+
oklch(from var(--brand) calc(l - 0.05) c h),
|
|
106
|
+
oklch(from var(--brand) calc(l + 0.1) c h)
|
|
107
|
+
);
|
|
108
|
+
--color-accent-hover: light-dark(
|
|
109
|
+
oklch(from var(--brand) calc(l - 0.15) c h),
|
|
110
|
+
oklch(from var(--brand) calc(l + 0.2) c h)
|
|
111
|
+
);
|
|
112
|
+
--color-accent-text: light-dark(#ffffff, #1a1a2e);
|
|
113
|
+
|
|
114
|
+
/* Status colors */
|
|
115
|
+
--color-success: light-dark(oklch(55% 0.17 145), oklch(65% 0.17 145));
|
|
116
|
+
--color-warning: light-dark(oklch(70% 0.15 85), oklch(75% 0.15 85));
|
|
117
|
+
--color-danger: light-dark(oklch(55% 0.2 25), oklch(65% 0.2 25));
|
|
118
|
+
--color-info: light-dark(oklch(55% 0.15 230), oklch(65% 0.15 230));
|
|
119
|
+
|
|
120
|
+
/* Legacy aliases for backward compatibility */
|
|
121
|
+
--color-dark: var(--color-text);
|
|
122
|
+
--color-light: var(--color-surface);
|
|
123
|
+
--color-mid: var(--color-text-muted);
|
|
124
|
+
|
|
125
|
+
/* ===== BORDERS ===== */
|
|
126
|
+
--border-thin: 1px;
|
|
127
|
+
--border-thick: 3px;
|
|
128
|
+
|
|
129
|
+
/* ===== FONTS ===== */
|
|
130
|
+
--font-plain: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
131
|
+
--font-mono: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, monospace;
|
|
132
|
+
|
|
133
|
+
/* ===== LINE HEIGHT ===== */
|
|
134
|
+
--line-height: 1.5;
|
|
135
|
+
--line-height-tight: 1.2;
|
|
136
|
+
--line-height-loose: 1.8;
|
|
137
|
+
|
|
138
|
+
/* ===== TIMING ===== */
|
|
139
|
+
--duration-instant: 100ms;
|
|
140
|
+
--duration-fast: 200ms;
|
|
141
|
+
--duration-normal: 300ms;
|
|
142
|
+
--duration-slow: 500ms;
|
|
143
|
+
|
|
144
|
+
/* ===== EASING ===== */
|
|
145
|
+
--ease-out: cubic-bezier(0, 0, 0.2, 1);
|
|
146
|
+
--ease-in: cubic-bezier(0.4, 0, 1, 1);
|
|
147
|
+
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
|
|
148
|
+
--ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
149
|
+
|
|
150
|
+
/* Legacy transition shortcuts */
|
|
151
|
+
--transition-fast: var(--duration-fast) var(--ease-out);
|
|
152
|
+
--transition-medium: var(--duration-normal) var(--ease-out);
|
|
153
|
+
--transition-slow: var(--duration-slow) var(--ease-out);
|
|
154
|
+
}
|