@codenhub/styles 0.6.0 → 0.8.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/NOTICE +18 -16
- package/README.es.md +62 -0
- package/README.md +28 -22
- package/README.pt-BR.md +62 -0
- package/dist/aesthetics/chunky-tile.css +1 -1
- package/dist/aesthetics/cyber.css +1 -1
- package/dist/aesthetics/glass.css +1 -1
- package/dist/aesthetics/index.css +2 -2
- package/dist/aesthetics/neobrutalism.css +1 -1
- package/dist/aesthetics/pixel.css +1 -1
- package/dist/aesthetics/sketch.css +1 -1
- package/dist/cli.js +189 -0
- package/dist/components.css +2 -2
- package/dist/index.css +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/native.css +2 -2
- package/dist/palette.css +1 -1
- package/dist/theme.css +2 -2
- package/docs/accessibility.md +108 -60
- package/docs/changelog/0.1.1.md +1 -0
- package/docs/changelog/0.2.0.md +1 -0
- package/docs/changelog/0.3.0.md +1 -0
- package/docs/changelog/0.4.0.md +1 -0
- package/docs/changelog/0.5.0.md +8 -3
- package/docs/changelog/0.6.0.md +2 -1
- package/docs/changelog/0.7.0.md +50 -0
- package/docs/changelog/0.8.0.md +70 -0
- package/docs/changelog/index.md +2 -0
- package/docs/concepts.md +188 -46
- package/docs/es/accessibility.md +169 -0
- package/docs/es/concepts.md +212 -0
- package/docs/es/index.md +105 -0
- package/docs/es/integrating/astro.md +35 -0
- package/docs/es/integrating/index.md +75 -0
- package/docs/es/integrating/nextjs.md +67 -0
- package/docs/es/integrating/svelte.md +45 -0
- package/docs/es/integrating/tailwind.md +148 -0
- package/docs/es/integrating/vue.md +31 -0
- package/docs/es/integrating/without-a-bundler.md +238 -0
- package/docs/es/setup.md +188 -0
- package/docs/es/usage/aesthetics.md +282 -0
- package/docs/es/usage/buttons.md +135 -0
- package/docs/es/usage/composing.md +168 -0
- package/docs/es/usage/content-and-layout.md +219 -0
- package/docs/es/usage/customizing.md +304 -0
- package/docs/es/usage/feedback.md +157 -0
- package/docs/es/usage/forms.md +256 -0
- package/docs/es/usage/index.md +33 -0
- package/docs/es/usage/presets.md +92 -0
- package/docs/es/usage/solo.md +86 -0
- package/docs/es/usage/theming.md +309 -0
- package/docs/es/usage/tooltips.md +127 -0
- package/docs/index.md +86 -26
- package/docs/integrating/astro.md +3 -4
- package/docs/integrating/index.md +46 -13
- package/docs/integrating/nextjs.md +3 -4
- package/docs/integrating/svelte.md +5 -4
- package/docs/integrating/tailwind.md +89 -6
- package/docs/integrating/vue.md +3 -4
- package/docs/integrating/without-a-bundler.md +237 -0
- package/docs/pt-BR/accessibility.md +169 -0
- package/docs/pt-BR/concepts.md +212 -0
- package/docs/pt-BR/index.md +105 -0
- package/docs/pt-BR/integrating/astro.md +35 -0
- package/docs/pt-BR/integrating/index.md +75 -0
- package/docs/pt-BR/integrating/nextjs.md +67 -0
- package/docs/pt-BR/integrating/svelte.md +45 -0
- package/docs/pt-BR/integrating/tailwind.md +148 -0
- package/docs/pt-BR/integrating/vue.md +31 -0
- package/docs/pt-BR/integrating/without-a-bundler.md +238 -0
- package/docs/pt-BR/setup.md +188 -0
- package/docs/pt-BR/usage/aesthetics.md +282 -0
- package/docs/pt-BR/usage/buttons.md +135 -0
- package/docs/pt-BR/usage/composing.md +168 -0
- package/docs/pt-BR/usage/content-and-layout.md +219 -0
- package/docs/pt-BR/usage/customizing.md +304 -0
- package/docs/pt-BR/usage/feedback.md +157 -0
- package/docs/pt-BR/usage/forms.md +256 -0
- package/docs/pt-BR/usage/index.md +33 -0
- package/docs/pt-BR/usage/presets.md +92 -0
- package/docs/pt-BR/usage/solo.md +86 -0
- package/docs/pt-BR/usage/theming.md +309 -0
- package/docs/pt-BR/usage/tooltips.md +127 -0
- package/docs/setup.md +142 -91
- package/docs/usage/aesthetics.md +89 -73
- package/docs/usage/buttons.md +112 -40
- package/docs/usage/composing.md +109 -92
- package/docs/usage/content-and-layout.md +160 -125
- package/docs/usage/customizing.md +117 -41
- package/docs/usage/feedback.md +138 -71
- package/docs/usage/forms.md +201 -107
- package/docs/usage/index.md +22 -14
- package/docs/usage/presets.md +91 -0
- package/docs/usage/solo.md +85 -0
- package/docs/usage/theming.md +273 -118
- package/docs/usage/tooltips.md +90 -49
- package/llms-full.txt +2820 -1298
- package/llms.txt +24 -22
- package/package.json +134 -91
- package/{dist/tw → tw}/aesthetics/chunky-tile.css +107 -29
- package/{dist/tw → tw}/aesthetics/cyber.css +88 -40
- package/{dist/tw → tw}/aesthetics/glass.css +257 -61
- package/{dist/tw → tw}/aesthetics/neobrutalism.css +113 -20
- package/{dist/tw → tw}/aesthetics/pixel.css +93 -8
- package/tw/aesthetics/sketch.css +417 -0
- package/{dist/tw → tw}/box.css +105 -9
- package/tw/components/button.css +11 -0
- package/tw/components/button.rules.css +187 -0
- package/tw/components/feedback.css +11 -0
- package/{dist/tw/components/feedback.css → tw/components/feedback.rules.css} +136 -32
- package/tw/components/form.css +11 -0
- package/{dist/tw/components/form.css → tw/components/form.rules.css} +577 -125
- package/tw/components/index.css +16 -0
- package/tw/components/rules.css +41 -0
- package/tw/components/surface.css +11 -0
- package/tw/components/surface.rules.css +222 -0
- package/tw/components/tooltip.css +11 -0
- package/{dist/tw/components/tooltip.css → tw/components/tooltip.rules.css} +43 -27
- package/{dist/tw → tw}/corner.css +18 -12
- package/{dist/tw → tw}/elevation.css +23 -17
- package/{dist/tw → tw}/index.css +12 -10
- package/tw/index.d.ts +1 -0
- package/tw/intent.css +312 -0
- package/tw/modifiers.css +127 -0
- package/tw/native.css +320 -0
- package/tw/presentation.css +139 -0
- package/tw/reset.css +10 -0
- package/{dist/tw/reset.css → tw/reset.rules.css} +21 -22
- package/tw/size.css +34 -0
- package/tw/surface.css +9 -0
- package/tw/surface.rules.css +212 -0
- package/{dist/tw → tw}/theme.css +121 -45
- package/tw/typography.css +8 -0
- package/{dist/tw/typography.css → tw/typography.rules.css} +0 -3
- package/{dist/tw → tw}/utilities/content.css +212 -50
- package/tw/utilities/index.css +11 -0
- package/tw/utilities/layout.css +208 -0
- package/tw/utilities/rules.css +8 -0
- package/dist/tw/aesthetics/sketch.css +0 -333
- package/dist/tw/components/button.css +0 -139
- package/dist/tw/components/index.css +0 -36
- package/dist/tw/components/loader.css +0 -116
- package/dist/tw/components/surface.css +0 -175
- package/dist/tw/intent.css +0 -228
- package/dist/tw/native.css +0 -203
- package/dist/tw/palette.css +0 -460
- package/dist/tw/presentation.css +0 -68
- package/dist/tw/surface.css +0 -61
- package/dist/tw/utilities/index.css +0 -6
- package/dist/tw/utilities/layout.css +0 -130
- /package/{dist/tw → tw}/aesthetics/index.css +0 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/* What every surface shares. Two slots exist here and nowhere else, and that is
|
|
2
|
+
how an aesthetic reaches surfaces without naming one: only a surface resolves
|
|
3
|
+
`--ui-backdrop`, so glass blurs cards and panels while controls stay solid,
|
|
4
|
+
and only a surface resolves `--ui-surface-shadow`, so a two-layer drop shadow
|
|
5
|
+
does not land under every button on the page.
|
|
6
|
+
|
|
7
|
+
A primitive beside `box`, and like `box` it imports neither the theme nor
|
|
8
|
+
Tailwind: `feedback.css` and `tooltip.css` `@reference` it, and a referenced
|
|
9
|
+
file that reaches the theme strips its tokens from every entry that pulls it
|
|
10
|
+
in. See docs/internal/model.md (Which files import the theme). */
|
|
11
|
+
@utility surface {
|
|
12
|
+
@apply box block;
|
|
13
|
+
|
|
14
|
+
/* Bare and edged. `box` reads these three with no fallback, so `surface` --
|
|
15
|
+
typeable on its own -- owes all three; `card` restates its own. No shadow
|
|
16
|
+
geometry: depth is asked for (`.raised`/`.floating`, an aesthetic, the
|
|
17
|
+
registry elevation) rather than carried, so a plain card is flat. */
|
|
18
|
+
--_d-fill: 0%;
|
|
19
|
+
--_d-fg-on-fill: 0%;
|
|
20
|
+
--_d-border: 100%;
|
|
21
|
+
|
|
22
|
+
/* A surface rests on a ground of its own, so no ink from above passes
|
|
23
|
+
through it: what is inside sits on this plate. It hands its own down
|
|
24
|
+
only where its fill is a plate (`--_own-hold`, which `box` steps and
|
|
25
|
+
which does not inherit). Unfilled, it hands down none, so a neutral
|
|
26
|
+
button in a soft success alert keeps the page's ink, not the alert's. */
|
|
27
|
+
--_held-ink: var(--_fg-own);
|
|
28
|
+
--_held-on: var(--_own-hold);
|
|
29
|
+
|
|
30
|
+
/* The neutral reset, carried so `@apply surface` gets it: the reset in
|
|
31
|
+
`intent.css` names `.surface`, which a consumer's `.my-surface` is not, so
|
|
32
|
+
a surface inside a `.card.success` took the card's intent. Only for an
|
|
33
|
+
element that carries neither an intent class nor one of the package's own
|
|
34
|
+
surface classes; those keep the reset in `components`, where a consumer's
|
|
35
|
+
own intent class beats it, and `.tooltip-bubble` keeps its own no-intent
|
|
36
|
+
plate. Zero specificity, so every rule that writes an intent slot on the
|
|
37
|
+
element wins over it. The values track `.neutral`'s. */
|
|
38
|
+
/* In `families`, beside the intent classes: applied with an intent --
|
|
39
|
+
`@apply surface info` -- the reset and the intent land in one layer, where the
|
|
40
|
+
intent's 0-1-0 beats this. Left in the rule's own layer it would beat
|
|
41
|
+
every intent applied with it. */
|
|
42
|
+
@layer families {
|
|
43
|
+
:where(
|
|
44
|
+
&:not(
|
|
45
|
+
.surface,
|
|
46
|
+
.card,
|
|
47
|
+
.panel,
|
|
48
|
+
.alert,
|
|
49
|
+
.tooltip-bubble,
|
|
50
|
+
.primary,
|
|
51
|
+
.secondary,
|
|
52
|
+
.success,
|
|
53
|
+
.warning,
|
|
54
|
+
.destructive,
|
|
55
|
+
.info
|
|
56
|
+
)
|
|
57
|
+
) {
|
|
58
|
+
--intent-color: var(--color-text);
|
|
59
|
+
--intent-contrast: var(--color-text-contrast);
|
|
60
|
+
--intent-hover: var(--color-text-hover);
|
|
61
|
+
--intent-strong: var(--color-text-strong);
|
|
62
|
+
--intent-subtle: var(--color-surface);
|
|
63
|
+
--intent-border: var(--ui-ink, var(--color-border));
|
|
64
|
+
--intent-fill-max: 20%;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/* The public token first, so an aesthetic (glass's translucent ground) or a
|
|
69
|
+
consumer names the ground outright; then the component's own quiet default,
|
|
70
|
+
which `.card.soft`, a neutral `.panel`, and a neutral `.alert` write as a
|
|
71
|
+
private rather than as the public token. Written as the public token, their
|
|
72
|
+
own declaration would beat glass's inherited one in a glass region, and
|
|
73
|
+
beat glass on the same element too (`.card.soft.glass` would go opaque).
|
|
74
|
+
Restated `initial` here so a quiet ground cannot inherit into a surface
|
|
75
|
+
nested inside one, the way `box` restates `--_d-ground`. See
|
|
76
|
+
docs/internal/model.md#cascade-layers. */
|
|
77
|
+
--_d-surface-ground: initial;
|
|
78
|
+
--_d-ground: var(--ui-surface-ground, var(--_d-surface-ground, var(--color-background)));
|
|
79
|
+
|
|
80
|
+
/* Whether this surface rests on a quiet neutral tint, as 0% or 100%: a
|
|
81
|
+
neutral intent (its fill cap is below 100%) and a resolved fill above
|
|
82
|
+
nothing and below that cap -- `.soft`, a panel's or an alert's default.
|
|
83
|
+
12% of the page's near-black ink reads as a grey slab rather than a step,
|
|
84
|
+
so `.card`, `.panel`, and `.alert` read this to rest such a fill on the
|
|
85
|
+
quiet foreground instead. Stepped from the resolved fill rather than
|
|
86
|
+
keyed on a class on the element, because presentation cascades: a
|
|
87
|
+
container's `.soft` and the surface's own are one request and have to
|
|
88
|
+
render one plate. Stepped rather than divided, as `box`'s `--_plate` is,
|
|
89
|
+
because the percentages cannot be divided in every engine yet. Only the
|
|
90
|
+
components that reinterpret the tint apply it; `surface` alone keeps the
|
|
91
|
+
plain tint. */
|
|
92
|
+
--_quiet: min(
|
|
93
|
+
clamp(0%, calc((100% - var(--intent-fill-max, 100%)) * 1000), 100%),
|
|
94
|
+
clamp(0%, calc(var(--ui-fill, var(--_d-fill)) * 1000), 100%),
|
|
95
|
+
clamp(0%, calc((var(--intent-fill-max, 100%) - var(--ui-fill, var(--_d-fill))) * 1000), 100%)
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
/* The complete-shadow slot for a shadow that is not one layer (glass tucks two
|
|
99
|
+
under with negative spread). Only `surface` reads it -- through `--ui-shadow`
|
|
100
|
+
it would land an 18px drop under every button and chip -- like the backdrop. */
|
|
101
|
+
--_shadow: var(--ui-surface-shadow, var(--_shadow-parts)) var(--_halo-layer,);
|
|
102
|
+
|
|
103
|
+
/* The surface pair of `box`'s corner: the aesthetic's surface length, scaled
|
|
104
|
+
by the padding step and patterned by the same four corner switches. */
|
|
105
|
+
--_corner-surface: calc(var(--ui-corner-surface, var(--radius-surface)) * var(--_scale));
|
|
106
|
+
border-radius: var(
|
|
107
|
+
--ui-radius-surface,
|
|
108
|
+
calc(var(--_corner-surface) * var(--ui-corner-tl, 1)) calc(var(--_corner-surface) * var(--ui-corner-tr, 1))
|
|
109
|
+
calc(var(--_corner-surface) * var(--ui-corner-br, 1)) calc(var(--_corner-surface) * var(--ui-corner-bl, 1))
|
|
110
|
+
);
|
|
111
|
+
/* No silhouette clip, whatever the aesthetic's `--ui-clip`: a clip cuts
|
|
112
|
+
everything inside the element, and a surface is the box that holds other
|
|
113
|
+
things. Under `.pixel` a tooltip in a card computed visible and was never
|
|
114
|
+
painted, and a child's shadow and focus outline were cut with it. A
|
|
115
|
+
surface is square there, with the ring, as a table is. */
|
|
116
|
+
clip-path: none;
|
|
117
|
+
/* The painted layer: a pattern, a texture, or a gradient an aesthetic lays
|
|
118
|
+
over the plate. Surfaces only, like the backdrop, so a control's label and
|
|
119
|
+
`.select`'s chevron never sit on one. The aesthetic that sets it owns the
|
|
120
|
+
contrast of the text over it, and a consumer's own `background-image` still
|
|
121
|
+
beats this declaration. */
|
|
122
|
+
background-image: var(--ui-surface-image, none);
|
|
123
|
+
/* Prefixed property first, deliberately: written second the minifier folds the
|
|
124
|
+
pair into the prefixed one alone, and the standard property never reaches
|
|
125
|
+
`dist/` -- which drops the blur in Firefox (the one engine with
|
|
126
|
+
`backdrop-filter` and not the `-webkit-` alias). Measured on the built CSS.
|
|
127
|
+
|
|
128
|
+
Cleared under liquid glass, which draws the blur on a layer below instead:
|
|
129
|
+
a surface with a backdrop filter of its own is a backdrop root, and a layer
|
|
130
|
+
inside one sees only the surface. */
|
|
131
|
+
--_layers-clear: var(--_glass-liquid-on) none;
|
|
132
|
+
-webkit-backdrop-filter: var(--_layers-clear, var(--ui-backdrop, none));
|
|
133
|
+
backdrop-filter: var(--_layers-clear, var(--ui-backdrop, none));
|
|
134
|
+
|
|
135
|
+
/* Liquid glass's two layers, a blur under the content and a lens with its rim
|
|
136
|
+
and sheen above it. A pseudo-element is not a value a token reaches, so
|
|
137
|
+
they are drawn here, where `@apply surface` carries them, and glass hands
|
|
138
|
+
them its values: `--_glass-liquid-on` is the space-toggle flag the nearest
|
|
139
|
+
liquid region in a glass scope sets on and every other region sets off,
|
|
140
|
+
and the blur, lens, rim, and sheen are its privates. With no liquid region
|
|
141
|
+
in scope every declaration below is a no-op, so the surface names no
|
|
142
|
+
aesthetic's class and changes nothing without one.
|
|
143
|
+
|
|
144
|
+
Zero specificity, so anything that writes these on the element beats them:
|
|
145
|
+
the tooltip bubble's own `absolute`, a consumer's `relative` or `before:`
|
|
146
|
+
utility. Off, the anchor, the isolation, and the content revert to the
|
|
147
|
+
layer below, so a surface outside a liquid region keeps every positioning
|
|
148
|
+
and pseudo-element rule written for it in another layer; the layers' other
|
|
149
|
+
declarations compute to `unset`, which is what an undeclared one is. Both
|
|
150
|
+
slots are spent where the flag is on, so a host there carries no
|
|
151
|
+
`::before` or `::after` of its own. See
|
|
152
|
+
docs/internal/model.md#glass-liquid. */
|
|
153
|
+
:where(&) {
|
|
154
|
+
--_layers-anchor: var(--_glass-liquid-on) relative;
|
|
155
|
+
--_layers-isolation: var(--_glass-liquid-on) isolate;
|
|
156
|
+
|
|
157
|
+
position: var(--_layers-anchor, revert-layer);
|
|
158
|
+
isolation: var(--_layers-isolation, revert-layer);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
:where(&)::before,
|
|
162
|
+
:where(&)::after {
|
|
163
|
+
--_layers-content: var(--_glass-liquid-on) "";
|
|
164
|
+
|
|
165
|
+
position: var(--_glass-liquid-on) absolute;
|
|
166
|
+
inset: var(--_glass-liquid-on) 0;
|
|
167
|
+
z-index: var(--_glass-liquid-on) -1;
|
|
168
|
+
border-radius: var(--_glass-liquid-on) inherit;
|
|
169
|
+
corner-shape: var(--_glass-liquid-on) inherit;
|
|
170
|
+
content: var(--_layers-content, revert-layer);
|
|
171
|
+
pointer-events: var(--_glass-liquid-on) none;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/* Prefixed first, for the reason above. */
|
|
175
|
+
:where(&)::before {
|
|
176
|
+
-webkit-backdrop-filter: var(--_glass-liquid-on) var(--_glass-liquid-blur);
|
|
177
|
+
backdrop-filter: var(--_glass-liquid-on) var(--_glass-liquid-blur);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
:where(&)::after {
|
|
181
|
+
backdrop-filter: var(--_glass-liquid-on) var(--_glass-liquid-lens);
|
|
182
|
+
background-image: var(--_glass-liquid-on) var(--_glass-liquid-sheen);
|
|
183
|
+
box-shadow: var(--_glass-liquid-on) var(--_glass-liquid-rim);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/* A `<dialog>`: hidden while closed, centred once open. The user agent
|
|
187
|
+
promises both, at user-agent origin, which loses to any author rule at
|
|
188
|
+
all: `display: block` above beats the first, so a closed dialog rendered,
|
|
189
|
+
and a margin reset beats the second, so an open one pinned to the
|
|
190
|
+
top-left. Carried here so `@apply surface` keeps both; the package's own
|
|
191
|
+
surfaces also keep the unlayered hide in `components/surface.css`.
|
|
192
|
+
|
|
193
|
+
The hide outranks a display utility on specificity, 0-2-1 against 0-1-0,
|
|
194
|
+
so a closed `.my-sheet.flex` stays closed; written unlayered, the
|
|
195
|
+
consumer's own applied rule beats every layered one. The centring is a
|
|
196
|
+
default at zero specificity, so a consumer's margin -- a utility, or their
|
|
197
|
+
own CSS in the same layer -- still places the dialog. */
|
|
198
|
+
&:is(dialog):not([open]) {
|
|
199
|
+
display: none;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/* A closed popover, for the same reason: the user agent's
|
|
203
|
+
`[popover]:not(:popover-open)` hide loses to `display: block` above, so a
|
|
204
|
+
`.card.floating` menu rendered before it was ever shown. */
|
|
205
|
+
&[popover]:not(:popover-open) {
|
|
206
|
+
display: none;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
:where(&:is(dialog)[open]) {
|
|
210
|
+
margin: auto;
|
|
211
|
+
}
|
|
212
|
+
}
|
package/{dist/tw → tw}/theme.css
RENAMED
|
@@ -2,27 +2,43 @@
|
|
|
2
2
|
orders layers by the first time it meets each name, so a sheet that opened
|
|
3
3
|
`components` first would rank it below `theme` and `base`; stating Tailwind's
|
|
4
4
|
own order here, and at the top of every entrypoint, makes every load order
|
|
5
|
-
rank the same.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
rank the same. Intent, presentation, elevation, corner, and size are
|
|
6
|
+
`@utility` rules whose bodies sit in `utilities.families`, a sublayer that
|
|
7
|
+
loses to every rule written straight into `utilities` -- a component's, or
|
|
8
|
+
a consumer's own utility -- so `@apply` and the variants reach them and an
|
|
9
|
+
override still beats them. The intent floor and resets, and every
|
|
10
|
+
aesthetic's token class, stay in `components`. Components are `@utility`
|
|
11
|
+
rules in `utilities`. See docs/internal/model.md#cascade-layers. */
|
|
9
12
|
@layer theme, base, components, utilities;
|
|
10
13
|
|
|
11
14
|
@import "tailwindcss/theme.css" layer(theme);
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
@import "./
|
|
15
|
+
/* Unlayered imports: a `@utility` has to be top-level, and each of these files
|
|
16
|
+
places its own rules -- the class families in `utilities.families`, the
|
|
17
|
+
intent floor and resets in `components`. */
|
|
18
|
+
@import "./intent.css";
|
|
19
|
+
@import "./presentation.css";
|
|
20
|
+
@import "./elevation.css";
|
|
21
|
+
@import "./corner.css";
|
|
22
|
+
@import "./size.css";
|
|
23
|
+
@import "./modifiers.css";
|
|
16
24
|
/* Everything that is not `src/` -- see the note in `index.css`. Keeps a
|
|
17
25
|
`--color-*` reference in a docs example from shipping as a real theme entry. */
|
|
18
26
|
|
|
19
27
|
/* Color tokens are declared once with `light-dark()`, which resolves at the
|
|
20
28
|
point of use against the consuming element's computed `color-scheme`. Theme
|
|
21
|
-
selectors below therefore set `color-scheme
|
|
29
|
+
selectors below therefore set `color-scheme`, and the region's own `color`
|
|
30
|
+
so its text re-resolves too. Verified
|
|
22
31
|
across Chromium, Firefox, and WebKit, including resolution through
|
|
23
32
|
`color-mix()` and through Tailwind's `@theme`, which emits theme values as
|
|
24
|
-
unregistered custom properties rather than `@property` registrations.
|
|
25
|
-
|
|
33
|
+
unregistered custom properties rather than `@property` registrations.
|
|
34
|
+
|
|
35
|
+
`static`, because every token here is documented as public. Tailwind keeps a
|
|
36
|
+
plain `@theme` value only where it sees the entry read it, and `/theme`
|
|
37
|
+
carries no reset or component to read `--color-background`,
|
|
38
|
+
`--color-foreground`, `--color-text-secondary`, or `--font-default`, so it
|
|
39
|
+
shipped without them. `exports.test.ts` holds every compiled entry to the
|
|
40
|
+
tokens `docs/usage/theming.md` lists. */
|
|
41
|
+
@theme static {
|
|
26
42
|
--font-default: "Segoe UI", system-ui, sans-serif;
|
|
27
43
|
|
|
28
44
|
--color-primary: light-dark(var(--color-neutral-950), var(--color-neutral-50));
|
|
@@ -38,8 +54,15 @@
|
|
|
38
54
|
/* Neutral-400 in light: the heaviest grey that still leaves a field legible
|
|
39
55
|
(2.48:1 against the page). A lighter line lands within a few RGB units of a
|
|
40
56
|
`.card.soft.edged`'s own fill and reads as no boundary. Dark's neutral-700
|
|
41
|
-
already separates (27 units).
|
|
42
|
-
|
|
57
|
+
already separates (27 units).
|
|
58
|
+
|
|
59
|
+
`--_contrast-border` is set only under `prefers-contrast: more`, below.
|
|
60
|
+
Read here rather than restating the token there, so a consumer who sets
|
|
61
|
+
`--color-border` replaces both and keeps their colour. */
|
|
62
|
+
--color-border: var(--_contrast-border, light-dark(var(--color-neutral-400), var(--color-neutral-700)));
|
|
63
|
+
/* Nothing in the package draws a border that darkens on hover; it is a
|
|
64
|
+
public override point for a consumer's own. */
|
|
65
|
+
--color-border-hover: light-dark(var(--color-neutral-600), var(--color-neutral-500));
|
|
43
66
|
|
|
44
67
|
/* A text control's line is the only thing identifying it: the box is
|
|
45
68
|
transparent at rest, so nothing else marks where typing goes.
|
|
@@ -120,22 +143,13 @@
|
|
|
120
143
|
--color-info-hover: light-dark(#4b36e9, #5e4ff9);
|
|
121
144
|
--color-info-subtle: light-dark(var(--color-indigo-100), var(--color-indigo-900));
|
|
122
145
|
--color-info-strong: light-dark(var(--color-indigo-800), var(--color-indigo-300));
|
|
123
|
-
|
|
124
|
-
--breakpoint-xs: 30rem;
|
|
125
146
|
}
|
|
126
147
|
|
|
127
|
-
/*
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
in that table, but nothing in this package draws a border that darkens on
|
|
133
|
-
hover, so nothing here ever references it, and Tailwind quietly dropped it
|
|
134
|
-
from every compiled stylesheet. `static` forces it to compile regardless,
|
|
135
|
-
so the token a consumer's docs promise is the token their `var()` actually
|
|
136
|
-
resolves. */
|
|
137
|
-
@theme static {
|
|
138
|
-
--color-border-hover: light-dark(var(--color-neutral-600), var(--color-neutral-500));
|
|
148
|
+
/* Not `static`: a breakpoint is a variant for a `/tw` consumer's own build and
|
|
149
|
+
means nothing as a custom property, since a media query cannot read `var()`.
|
|
150
|
+
Tailwind keeps the variable only where an `xs:` utility uses it. */
|
|
151
|
+
@theme {
|
|
152
|
+
--breakpoint-xs: 30rem;
|
|
139
153
|
}
|
|
140
154
|
|
|
141
155
|
/* The foundation tokens and the colour-scheme selectors, in `theme` so every
|
|
@@ -171,13 +185,25 @@
|
|
|
171
185
|
instead of inferring it by omitting a shadow declaration. These are raw
|
|
172
186
|
shadows for elements a consumer styles; the elevation modifier classes
|
|
173
187
|
(`.flat`/`.raised`/`.floating` in elevation.css) multiply an aesthetic's
|
|
174
|
-
shadow parts instead, and are not read from here.
|
|
188
|
+
shadow parts instead, and are not read from here.
|
|
189
|
+
|
|
190
|
+
They resolve `--elevation-color` here, once, so a container's own
|
|
191
|
+
`--elevation-color` does not reach them. Declaring them on every element
|
|
192
|
+
instead would re-resolve it, and would also redeclare them under a
|
|
193
|
+
container that sets its own `--elevation-sm`, which no descendant would
|
|
194
|
+
then see. A consumer's override wins over a colour that follows the
|
|
195
|
+
container; docs/usage/theming.md#foundation-tokens says so. */
|
|
175
196
|
--elevation-none: none;
|
|
176
197
|
--elevation-sm: 0 1px 2px var(--elevation-color), 0 1px 3px var(--elevation-color);
|
|
177
198
|
--elevation-md: 0 4px 6px -1px var(--elevation-color), 0 2px 4px -2px var(--elevation-color);
|
|
178
199
|
--elevation-lg: 0 20px 25px -5px var(--elevation-color), 0 8px 10px -6px var(--elevation-color);
|
|
179
200
|
|
|
180
|
-
|
|
201
|
+
/* `--focus-ring` is not declared: its default is the brand colour
|
|
202
|
+
at 64%, and declared here it resolved against `:root`'s
|
|
203
|
+
`--color-primary` and inherited, so a region that set its own brand
|
|
204
|
+
colour filled a primary button in it and ringed it in the page's. Every
|
|
205
|
+
reader falls back to the mix on the focused element instead, and a
|
|
206
|
+
consumer's `--focus-ring` on any ancestor still inherits. */
|
|
181
207
|
/* `--focus-ring-offset` is not declared: its default is the negative of the
|
|
182
208
|
line width of whatever is focused, which only the focused element knows,
|
|
183
209
|
so the outline computes it there -- see `reset.css`. Declared here it
|
|
@@ -200,28 +226,29 @@
|
|
|
200
226
|
/* The base look answers a press with a small scale-in. `box-active` applies it on
|
|
201
227
|
`.btn` and `.card.interactive`; every aesthetic sets its own
|
|
202
228
|
`--ui-active-transform` on its class, in `components`, so those win over
|
|
203
|
-
this whichever sheet loads first. Reduced motion
|
|
204
|
-
|
|
229
|
+
this whichever sheet loads first. Reduced motion keeps it and drops only
|
|
230
|
+
its motion, in `box`. */
|
|
205
231
|
:root {
|
|
206
232
|
--ui-active-transform: scale(0.97);
|
|
207
233
|
}
|
|
208
234
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
235
|
+
/* A forced theme re-resolves the region's own text as well as its scheme.
|
|
236
|
+
`color` inherits as a computed colour, already resolved against the scheme
|
|
237
|
+
above, so a `<p>` in an `<aside class="dark">` on a light page kept the
|
|
238
|
+
light theme's near-black. No background: a region that wants the theme's
|
|
239
|
+
ground says so. In `theme`, so every utility and component still wins. */
|
|
215
240
|
.light,
|
|
216
241
|
.theme-light,
|
|
217
242
|
[data-theme="light"] {
|
|
218
243
|
color-scheme: light;
|
|
244
|
+
color: var(--color-text);
|
|
219
245
|
}
|
|
220
246
|
|
|
221
247
|
.dark,
|
|
222
248
|
.theme-dark,
|
|
223
249
|
[data-theme="dark"] {
|
|
224
250
|
color-scheme: dark;
|
|
251
|
+
color: var(--color-text);
|
|
225
252
|
}
|
|
226
253
|
}
|
|
227
254
|
|
|
@@ -231,13 +258,14 @@
|
|
|
231
258
|
The second arm follows the OS preference. `--color-*` tokens resolve through
|
|
232
259
|
`light-dark()` against the computed `color-scheme`, so with no explicit
|
|
233
260
|
selector `:root`'s `color-scheme: light dark` already follows it -- see
|
|
234
|
-
`
|
|
235
|
-
but it can match "OS prefers dark, and not under a
|
|
236
|
-
a plain descendant exclusion:
|
|
237
|
-
only when no ancestor (or the
|
|
238
|
-
|
|
239
|
-
where `light-dark()` would
|
|
240
|
-
|
|
261
|
+
`docs/usage/theming.md#light-and-dark`. A selector list cannot query
|
|
262
|
+
computed style, but it can match "OS prefers dark, and not under a
|
|
263
|
+
forced-light subtree" with a plain descendant exclusion:
|
|
264
|
+
`:not(:where(.light, .light *, ...))` matches only when no ancestor (or the
|
|
265
|
+
element itself) carries one of the three light spellings. The exclusion
|
|
266
|
+
cannot see a subtree forced light by other means, where `light-dark()` would
|
|
267
|
+
still honor it; that is out of contract, since those three spellings are the
|
|
268
|
+
only supported way to force a theme.
|
|
241
269
|
|
|
242
270
|
Each arm is independent, so an explicit selector wins over the OS preference
|
|
243
271
|
at any depth. It does not win over an explicit selector of the opposite
|
|
@@ -256,13 +284,61 @@
|
|
|
256
284
|
}
|
|
257
285
|
}
|
|
258
286
|
|
|
287
|
+
/* Paper is the light ground. A browser leaves backgrounds off a printed page
|
|
288
|
+
unless told otherwise, so a dark page printed its near-white text on no
|
|
289
|
+
ground at all. Every token resolves through `light-dark()`, so printing in
|
|
290
|
+
the light scheme re-resolves all of them, a forced-dark region's included.
|
|
291
|
+
In `theme`, after the selectors above and at their specificity, so it beats
|
|
292
|
+
them and a consumer's utility still beats it. It does not reach a `dark:`
|
|
293
|
+
utility, which keys on the class and not on the scheme. */
|
|
294
|
+
@layer theme {
|
|
295
|
+
@media print {
|
|
296
|
+
:root,
|
|
297
|
+
.dark,
|
|
298
|
+
.theme-dark,
|
|
299
|
+
[data-theme="dark"] {
|
|
300
|
+
color-scheme: light;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/* More contrast, asked for by the reader. The quiet surface line is 2.48:1
|
|
306
|
+
against the light page and 1.91:1 against the dark one by choice; here it
|
|
307
|
+
takes a grey two steps heavier, neutral-600 in light and neutral-400 in
|
|
308
|
+
dark. The control grey between them is not enough: `box` fades a line by the
|
|
309
|
+
fill under it, and on a neutral `.badge.soft.edged` neutral-500 lands at
|
|
310
|
+
2.9:1 against its own tint. One token, so every neutral line that reads it
|
|
311
|
+
follows: surfaces, dividers, table rules, a neutral button's edge.
|
|
312
|
+
`--color-border` reads this slot first, so a consumer's own value for the
|
|
313
|
+
token replaces both and still wins.
|
|
314
|
+
See docs/accessibility.md. */
|
|
315
|
+
@layer theme {
|
|
316
|
+
@media (prefers-contrast: more) {
|
|
317
|
+
:root,
|
|
318
|
+
:host {
|
|
319
|
+
--_contrast-border: light-dark(var(--color-neutral-600), var(--color-neutral-400));
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
259
324
|
/* Forced colours draw the plain version of every structural part: a solid line
|
|
260
325
|
and nothing an aesthetic layers on top. Unlayered, so it beats every layered
|
|
261
326
|
declaration of these tokens -- an aesthetic's and a consumer's utility alike --
|
|
262
327
|
the way the other `forced-colors` blocks do. See
|
|
263
|
-
docs/internal/model.md#material-tokens.
|
|
328
|
+
docs/internal/model.md#material-tokens.
|
|
329
|
+
|
|
330
|
+
The border comes back and the clip goes. Forced colours remove every box
|
|
331
|
+
shadow, so an aesthetic that draws its edge as an inset ring and takes the
|
|
332
|
+
border out with `--ui-border-max` (`.pixel`) left buttons, fields, and cards
|
|
333
|
+
with no boundary at all. With the ceiling lifted the border is drawn at the
|
|
334
|
+
aesthetic's own width and the system colours it; with no clip the corners
|
|
335
|
+
it would cut are whole and the focus outline shows. */
|
|
264
336
|
@media (forced-colors: active) {
|
|
265
337
|
* {
|
|
338
|
+
--ui-border-max: initial;
|
|
339
|
+
--ui-clip: none;
|
|
340
|
+
--ui-clip-tight: none;
|
|
341
|
+
--ui-shadow-edge: initial;
|
|
266
342
|
--ui-line-style: solid;
|
|
267
343
|
--ui-rule-style: solid;
|
|
268
344
|
--ui-halo-ink: initial;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
@reference "tailwindcss";
|
|
2
|
+
@import "./theme.css";
|
|
3
|
+
|
|
4
|
+
/* The focused entry: Tailwind and the theme, which the rules need to compile
|
|
5
|
+
on their own, then the rules. An aggregate entry imports the rules file and
|
|
6
|
+
brings the theme itself, once. See docs/internal/model.md (One route to each
|
|
7
|
+
utility). */
|
|
8
|
+
@import "./typography.rules.css";
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
@reference "tailwindcss";
|
|
2
|
-
@import "./theme.css";
|
|
3
|
-
|
|
4
1
|
/* `text-6xl` and up bundle `line-height: 1`, which sets a heading's line box to
|
|
5
2
|
the font size exactly: descenders reach the box edge and a wrapped heading's
|
|
6
3
|
lines collide. The two largest steps set an explicit leading that still
|