@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,187 @@
|
|
|
1
|
+
/* A filled, edgeless, raised box you can press. `box` paints it; everything
|
|
2
|
+
here is what makes it a button rather than some other box.
|
|
3
|
+
|
|
4
|
+
The resting values are the published default: a button with no presentation
|
|
5
|
+
class is solid and edgeless, and that is a decision written on three lines
|
|
6
|
+
rather than a `var()` fallback buried in an expression. */
|
|
7
|
+
@utility btn {
|
|
8
|
+
/* The neutral reset, carried so `@apply btn` gets it: the reset in
|
|
9
|
+
`intent.css` names `.btn`, which a consumer's `.my-btn` is not, so an
|
|
10
|
+
applied one inside a `.card.success` took the card's intent. In
|
|
11
|
+
`families`, beside the intent classes, so one applied with it wins; never
|
|
12
|
+
on `.btn` itself, which keeps the reset in `components`. See
|
|
13
|
+
docs/internal/model.md#what-apply-carries. */
|
|
14
|
+
@layer families {
|
|
15
|
+
:where(&:not(.btn, .primary, .secondary, .success, .warning, .destructive, .info)) {
|
|
16
|
+
--intent-color: var(--color-text);
|
|
17
|
+
--intent-contrast: var(--color-text-contrast);
|
|
18
|
+
--intent-hover: var(--color-text-hover);
|
|
19
|
+
--intent-strong: var(--color-text-strong);
|
|
20
|
+
--intent-subtle: var(--color-surface);
|
|
21
|
+
--intent-border: var(--ui-ink, var(--color-border));
|
|
22
|
+
--intent-fill-max: 20%;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/* The modifier flags, restated so a container's do not reach this button:
|
|
27
|
+
a `.card.p-xs` would otherwise shrink every button inside it. At zero
|
|
28
|
+
specificity in `families`, beside the flag utilities, so one on the
|
|
29
|
+
element wins, applied or as a class. See `modifiers.css`. */
|
|
30
|
+
@layer families {
|
|
31
|
+
:where(&:not(.icon)) {
|
|
32
|
+
--_m-icon: initial;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
:where(&:not(.pill)) {
|
|
36
|
+
--_m-pill: initial;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
:where(&:not(.p-xs)) {
|
|
40
|
+
--_m-p-xs: initial;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
:where(&:not(.p-sm)) {
|
|
44
|
+
--_m-p-sm: initial;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
:where(&:not(.p-lg)) {
|
|
48
|
+
--_m-p-lg: initial;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@apply box box-hover box-active relative inline-flex w-fit cursor-pointer items-center justify-center gap-2 px-4 py-2 whitespace-nowrap no-underline select-none;
|
|
53
|
+
|
|
54
|
+
/* After `@apply box`: `box` states its own resting defaults, and the later
|
|
55
|
+
declaration wins. */
|
|
56
|
+
--_d-fill: 100%;
|
|
57
|
+
--_d-fg-on-fill: 100%;
|
|
58
|
+
--_d-border: 0%;
|
|
59
|
+
--_d-elevation: 1;
|
|
60
|
+
--_d-holds-ink: ;
|
|
61
|
+
|
|
62
|
+
/* With no fill, the neutral line is the region's unfilled ink when the
|
|
63
|
+
aesthetic names one -- glass does, for a `.ghost.edged` button. See `--_bare-ink` in
|
|
64
|
+
`box.css`. Unset, the reference is invalid and `box` keeps its line. */
|
|
65
|
+
--_bare-ink: var(--_unfilled-ink);
|
|
66
|
+
|
|
67
|
+
/* The default step's vertical padding gives back the line `box` draws, so a
|
|
68
|
+
default button is exactly `--control-height` tall like `.ipt` beside it,
|
|
69
|
+
under any aesthetic's line width; at the default 16px/1.5 text the label
|
|
70
|
+
and the padding fill it. The surrounding font, not the user agent's
|
|
71
|
+
smaller button one, on every entry: `/components` carries no reset to say
|
|
72
|
+
so, and a `.btn` link and a `.btn` button have to print the same label.
|
|
73
|
+
Both are the fallbacks of the size steps below. */
|
|
74
|
+
font-family: inherit;
|
|
75
|
+
/* The label is material, shared with `.badge`: weight, tracking, case, and a
|
|
76
|
+
text shadow, set by an aesthetic as tokens (`.chunky-tile`'s heavier,
|
|
77
|
+
tracked label), and a consumer's own `font-*`, `tracking-*`, `uppercase`, or
|
|
78
|
+
text-shadow utility still beats the aesthetic. Tracking, case, and shadow
|
|
79
|
+
fall back to `normal` and `none`, the label's own values, so none of them
|
|
80
|
+
inherits: body copy's wider tracking is set on `body`, and a button that
|
|
81
|
+
took it, or a container's, printed a tracked label nothing asked for. The
|
|
82
|
+
user agent already stops case and shadow inheriting into a button, and
|
|
83
|
+
`/native` maps `<button>` and the button inputs here. The shadow is written
|
|
84
|
+
without a colour, so it takes the label's own and cannot lower its
|
|
85
|
+
contrast. See docs/internal/model.md#cascade-layers. */
|
|
86
|
+
font-weight: var(--ui-label-weight, var(--font-weight-semibold));
|
|
87
|
+
letter-spacing: var(--ui-label-tracking, normal);
|
|
88
|
+
text-transform: var(--ui-label-case, none);
|
|
89
|
+
text-shadow: var(--ui-label-shadow, none);
|
|
90
|
+
|
|
91
|
+
/* The size steps. `sm` and `lg` raise a flag (`size.css`) and each line
|
|
92
|
+
below computes only while its flag is up, so the declarations that read
|
|
93
|
+
them fall back to the default step. Written in the component's own body,
|
|
94
|
+
not as `&.sm`, so `@apply btn sm` carries the step and a consumer's
|
|
95
|
+
`min-h-*` or `px-*` beats it as it beats the default. `--_scale-size`
|
|
96
|
+
is the step `box` scales the corner and the depth by. */
|
|
97
|
+
--_sm-h: var(--_size-sm) 2rem;
|
|
98
|
+
--_lg-h: var(--_size-lg) 3rem;
|
|
99
|
+
--_sm-px: var(--_size-sm) 0.75rem;
|
|
100
|
+
--_lg-px: var(--_size-lg) 1.25rem;
|
|
101
|
+
--_sm-py: var(--_size-sm) 0.25rem;
|
|
102
|
+
--_lg-py: var(--_size-lg) 0.625rem;
|
|
103
|
+
--_sm-text: var(--_size-sm) var(--text-sm);
|
|
104
|
+
--_lg-text: var(--_size-lg) 1.0625rem;
|
|
105
|
+
--_sm-leading: var(--_size-sm) var(--tw-leading, var(--text-sm--line-height));
|
|
106
|
+
--_sm-scale: var(--_size-sm) 0.75;
|
|
107
|
+
--_lg-scale: var(--_size-lg) 1.25;
|
|
108
|
+
--_scale-size: var(--_sm-scale, var(--_lg-scale));
|
|
109
|
+
|
|
110
|
+
/* The modifiers: `icon`, `pill`, and the padding steps. Each raises a flag
|
|
111
|
+
(`modifiers.css`) and the lines below compute only while theirs is up, as
|
|
112
|
+
the size steps above do, so `@apply btn icon` carries the shape. A line
|
|
113
|
+
that names two flags needs both.
|
|
114
|
+
|
|
115
|
+
Bare `sm`/`lg` are the size modifier's names, so the padding steps take
|
|
116
|
+
a `p-` prefix. `p-xs` is the tightest, below `p-sm`: a chip-sized
|
|
117
|
+
button in a toolbar or a table cell. */
|
|
118
|
+
--_icon-pad: var(--_m-icon) var(--_sm-icon-pad, 0.5rem);
|
|
119
|
+
--_sm-icon-pad: var(--_size-sm) calc(0.375rem - var(--_width));
|
|
120
|
+
--_xs-px: var(--_m-p-xs) --spacing(2);
|
|
121
|
+
--_xs-py: var(--_m-p-xs) --spacing(0.5);
|
|
122
|
+
--_psm-px: var(--_m-p-sm) --spacing(2.5);
|
|
123
|
+
--_psm-py: var(--_m-p-sm) --spacing(1);
|
|
124
|
+
--_plg-px: var(--_m-p-lg) --spacing(6);
|
|
125
|
+
--_plg-py: var(--_m-p-lg) --spacing(3);
|
|
126
|
+
/* An icon button's padding step is the same on every side. */
|
|
127
|
+
--_xs-icon-px: var(--_m-icon) var(--_xs-py);
|
|
128
|
+
--_psm-icon-px: var(--_m-icon) var(--_psm-py);
|
|
129
|
+
--_plg-icon-px: var(--_m-icon) var(--_plg-py);
|
|
130
|
+
--_xs-scale: var(--_m-p-xs) 0.5;
|
|
131
|
+
--_psm-scale: var(--_m-p-sm) 0.75;
|
|
132
|
+
--_plg-scale: var(--_m-p-lg) 1.25;
|
|
133
|
+
--_scale-pad: var(--_plg-scale, var(--_psm-scale, var(--_xs-scale)));
|
|
134
|
+
|
|
135
|
+
/* The size floor. `p-xs` is the one padding step that drops it for a
|
|
136
|
+
labeled button: at that tier the button is a chip in a toolbar or a table
|
|
137
|
+
cell, where `--control-height` is taller than the row it sits in; every
|
|
138
|
+
other size and padding class keeps the floor, so a plain button stays a
|
|
139
|
+
comfortable target.
|
|
140
|
+
|
|
141
|
+
An icon button drops both floors at every padding tier. It is already
|
|
142
|
+
square -- `aspect-ratio` ties its width to whatever height it lands on
|
|
143
|
+
-- so a surviving floor would keep the button bigger than its own glyph
|
|
144
|
+
however tight the padding asked to be. */
|
|
145
|
+
--_floor: var(--_sm-h, var(--_lg-h, var(--control-height)));
|
|
146
|
+
--_xs-floor: var(--_m-p-xs) 0px;
|
|
147
|
+
--_psm-icon-floor: var(--_m-icon) var(--_m-p-sm) 0px;
|
|
148
|
+
--_plg-icon-floor: var(--_m-icon) var(--_m-p-lg) 0px;
|
|
149
|
+
--_icon-floor: var(--_m-icon) var(--_xs-floor, var(--_psm-icon-floor, var(--_plg-icon-floor, var(--_floor))));
|
|
150
|
+
|
|
151
|
+
min-height: var(--_xs-floor, var(--_psm-icon-floor, var(--_plg-icon-floor, var(--_floor))));
|
|
152
|
+
/* Square at each size step. The width is named as well as the height,
|
|
153
|
+
because WebKit does not let `aspect-ratio` widen a box past its
|
|
154
|
+
`min-width`. */
|
|
155
|
+
min-width: var(--_icon-floor, auto);
|
|
156
|
+
--_icon-ratio: var(--_m-icon) 1 / 1;
|
|
157
|
+
aspect-ratio: var(--_icon-ratio, auto);
|
|
158
|
+
padding-inline: var(
|
|
159
|
+
--_plg-icon-px,
|
|
160
|
+
var(
|
|
161
|
+
--_psm-icon-px,
|
|
162
|
+
var(
|
|
163
|
+
--_xs-icon-px,
|
|
164
|
+
var(--_plg-px, var(--_psm-px, var(--_xs-px, var(--_icon-pad, var(--_sm-px, var(--_lg-px, 1rem))))))
|
|
165
|
+
)
|
|
166
|
+
)
|
|
167
|
+
);
|
|
168
|
+
padding-block: var(
|
|
169
|
+
--_plg-py,
|
|
170
|
+
var(--_psm-py, var(--_xs-py, var(--_icon-pad, var(--_sm-py, var(--_lg-py, calc(0.5rem - var(--_width)))))))
|
|
171
|
+
);
|
|
172
|
+
font-size: var(--_sm-text, var(--_lg-text, inherit));
|
|
173
|
+
line-height: var(--_sm-leading, inherit);
|
|
174
|
+
|
|
175
|
+
/* A pill takes the round material ahead of the box radius, which is
|
|
176
|
+
`box`'s own formula restated. Sketch gives the token the button's own box
|
|
177
|
+
outline; a bevel still cuts the full radius to points under cyber. */
|
|
178
|
+
--_pill-radius: var(--_m-pill) var(--ui-radius-pill, calc(infinity * 1px));
|
|
179
|
+
border-radius: var(
|
|
180
|
+
--_pill-radius,
|
|
181
|
+
var(
|
|
182
|
+
--ui-radius,
|
|
183
|
+
calc(var(--_corner) * var(--ui-corner-tl, 1)) calc(var(--_corner) * var(--ui-corner-tr, 1))
|
|
184
|
+
calc(var(--_corner) * var(--ui-corner-br, 1)) calc(var(--_corner) * var(--ui-corner-bl, 1))
|
|
185
|
+
)
|
|
186
|
+
);
|
|
187
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
@reference "tailwindcss";
|
|
2
|
+
@import "../theme.css";
|
|
3
|
+
@reference "../surface.css";
|
|
4
|
+
|
|
5
|
+
/* The focused entry: what the rules in `feedback.rules.css` need to compile on their
|
|
6
|
+
own, then the rules. An aggregate entry imports the rules file directly and
|
|
7
|
+
supplies those needs once -- Tailwind stacks a `@utility` each time a file
|
|
8
|
+
that defines it is imported or referenced, so a second route to `box.css`
|
|
9
|
+
doubles every `@apply box`. See docs/internal/model.md (One route to each
|
|
10
|
+
utility). */
|
|
11
|
+
@import "./feedback.rules.css";
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
@reference "tailwindcss";
|
|
2
|
-
@import "../theme.css";
|
|
3
|
-
@reference "../box.css";
|
|
4
|
-
@reference "../surface.css";
|
|
5
|
-
|
|
6
1
|
@keyframes anim-skeleton {
|
|
7
2
|
0% {
|
|
8
3
|
background-position: 200% 0;
|
|
@@ -39,12 +34,11 @@
|
|
|
39
34
|
|
|
40
35
|
/* Same carve-out as `.panel`'s, and for the same reason: a neutral alert
|
|
41
36
|
mixes 12% of near-black ink onto the page (`217, 217, 217` against `250,
|
|
42
|
-
250, 250`), a slab rather than a status signal.
|
|
43
|
-
|
|
44
|
-
`.
|
|
45
|
-
|
|
46
|
-
`.
|
|
47
|
-
clamped to a cap it did not ask for.
|
|
37
|
+
250, 250`), a slab rather than a status signal. Only a quiet neutral tint
|
|
38
|
+
is untinted, through `surface`'s `--_quiet`, stepped from the resolved
|
|
39
|
+
fill so a container's `.ghost` or `.solid` renders the alert as the
|
|
40
|
+
alert's own `.ghost` or `.solid` would. A named intent keeps its ordinary wash, because untinting
|
|
41
|
+
`.alert.soft.destructive` would silence the status it exists to carry.
|
|
48
42
|
|
|
49
43
|
Grounds on `--color-foreground` through `--_d-surface-ground`, exactly like
|
|
50
44
|
`.panel` and a resting `.card.soft`, so glass's ground and a consumer's
|
|
@@ -52,10 +46,8 @@
|
|
|
52
46
|
reveal a tint into either, so this is permanent. A neutral alert keeps its
|
|
53
47
|
identity: `--_d-border: 100%` above holds regardless of fill, so it still
|
|
54
48
|
reads as a framed box, just a quiet one instead of a grey slab. */
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
--_d-surface-ground: var(--color-foreground);
|
|
58
|
-
}
|
|
49
|
+
--_fill-cap: calc(100% - var(--_quiet));
|
|
50
|
+
--_d-surface-ground: color-mix(in oklab, var(--color-foreground) var(--_quiet), var(--color-background));
|
|
59
51
|
}
|
|
60
52
|
|
|
61
53
|
/* No icon is shipped. `.alert` is already `flex`, so an icon dropped in as a
|
|
@@ -82,17 +74,38 @@
|
|
|
82
74
|
/* A soft, edgeless chip. Small enough that the structural silhouette would be
|
|
83
75
|
most of its height, so it takes the tight one where an aesthetic ships a pair. */
|
|
84
76
|
@utility badge {
|
|
77
|
+
/* The neutral reset, carried so `@apply badge` gets it, as `btn` carries its own. */
|
|
78
|
+
@layer families {
|
|
79
|
+
:where(&:not(.badge, .primary, .secondary, .success, .warning, .destructive, .info)) {
|
|
80
|
+
--intent-color: var(--color-text);
|
|
81
|
+
--intent-contrast: var(--color-text-contrast);
|
|
82
|
+
--intent-hover: var(--color-text-hover);
|
|
83
|
+
--intent-strong: var(--color-text-strong);
|
|
84
|
+
--intent-subtle: var(--color-surface);
|
|
85
|
+
--intent-border: var(--ui-ink, var(--color-border));
|
|
86
|
+
--intent-fill-max: 20%;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@apply box inline-flex min-h-6 w-fit items-center gap-1 px-2.5 text-xs;
|
|
91
|
+
|
|
92
|
+
/* After `@apply box`: `box` states its own resting defaults, and the later
|
|
93
|
+
declaration wins. */
|
|
85
94
|
--_d-fill: 12%;
|
|
86
95
|
--_d-fg-on-fill: 0%;
|
|
87
96
|
--_d-border: 0%;
|
|
88
97
|
--_d-elevation: 0;
|
|
89
98
|
|
|
90
|
-
|
|
99
|
+
/* With no fill, the neutral line is the region's unfilled ink when the
|
|
100
|
+
aesthetic names one -- glass does, for a `.ghost.edged` badge. See `--_bare-ink` in
|
|
101
|
+
`box.css`. Unset, the reference is invalid and `box` keeps its line. */
|
|
102
|
+
--_bare-ink: var(--_unfilled-ink);
|
|
91
103
|
|
|
92
|
-
/* The label material `.btn` reads. Unset, tracking
|
|
93
|
-
|
|
104
|
+
/* The label material `.btn` reads. Unset, tracking is `normal`, as `.btn`'s
|
|
105
|
+
is, so neither body copy's tracking nor a container's reaches the label;
|
|
106
|
+
case and shadow inherit, as a badge's text always has. */
|
|
94
107
|
font-weight: var(--ui-label-weight, var(--font-weight-bold));
|
|
95
|
-
letter-spacing: var(--ui-label-tracking);
|
|
108
|
+
letter-spacing: var(--ui-label-tracking, normal);
|
|
96
109
|
text-transform: var(--ui-label-case);
|
|
97
110
|
text-shadow: var(--ui-label-shadow);
|
|
98
111
|
|
|
@@ -108,6 +121,22 @@
|
|
|
108
121
|
for content rather than a box with a look of its own, so there is nothing for
|
|
109
122
|
a container's `.solid` or `.edgeless` to say about it. */
|
|
110
123
|
@utility skeleton {
|
|
124
|
+
/* The indicator reset, carried so `@apply skeleton` gets it, as `btn` carries
|
|
125
|
+
its own: the neutral slots, with the two an indicator takes from the
|
|
126
|
+
colour it sits in. Without it an applied one read an undefined
|
|
127
|
+
`--intent-border`. */
|
|
128
|
+
@layer families {
|
|
129
|
+
:where(&:not(.skeleton, .primary, .secondary, .success, .warning, .destructive, .info)) {
|
|
130
|
+
--intent-color: currentColor;
|
|
131
|
+
--intent-contrast: var(--color-text-contrast);
|
|
132
|
+
--intent-hover: var(--color-text-hover);
|
|
133
|
+
--intent-strong: var(--color-text-strong);
|
|
134
|
+
--intent-subtle: var(--color-surface);
|
|
135
|
+
--intent-border: currentColor;
|
|
136
|
+
--intent-fill-max: 20%;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
111
140
|
--skeleton-base: color-mix(in oklab, var(--intent-color) 6%, var(--intent-subtle));
|
|
112
141
|
--skeleton-sheen: color-mix(in oklab, var(--intent-color) 10%, var(--color-foreground));
|
|
113
142
|
|
|
@@ -131,19 +160,71 @@
|
|
|
131
160
|
@media (prefers-reduced-motion: reduce) {
|
|
132
161
|
animation: none;
|
|
133
162
|
}
|
|
163
|
+
|
|
164
|
+
/* Forced colours remove background images, and the gradient is all a
|
|
165
|
+
skeleton is: it vanished. A system-colour outline keeps the placeholder's
|
|
166
|
+
shape on the page. A border, inside the box, so nothing moves. */
|
|
167
|
+
@media (forced-colors: active) {
|
|
168
|
+
box-sizing: border-box;
|
|
169
|
+
border: 1px solid CanvasText;
|
|
170
|
+
animation: none;
|
|
171
|
+
}
|
|
134
172
|
}
|
|
135
173
|
|
|
136
174
|
/* The track is a box, the fill is not: `box.css`'s formula composes the frame,
|
|
137
175
|
the value fill stays `--intent-color` at full strength with no presentation,
|
|
138
|
-
same contract as `.
|
|
176
|
+
same contract as `.skeleton`. `.progress` cannot `@apply box`
|
|
139
177
|
(the fill is a `::after`, not the element's own background), so it hand-
|
|
140
178
|
reimplements the formula the way `.quote` does -- see
|
|
141
179
|
docs/internal/model.md#components-that-do-not-take-the-whole-of-box for the
|
|
142
|
-
decision and why the other
|
|
180
|
+
decision and why the other two indicators do not get the same treatment. */
|
|
143
181
|
@utility progress {
|
|
182
|
+
/* The indicator reset, carried so `@apply progress` gets it, as `btn` carries
|
|
183
|
+
its own: the neutral slots, with the two an indicator takes from the
|
|
184
|
+
colour it sits in. Without it an applied one read an undefined
|
|
185
|
+
`--intent-border`. */
|
|
186
|
+
@layer families {
|
|
187
|
+
:where(&:not(.progress, .primary, .secondary, .success, .warning, .destructive, .info)) {
|
|
188
|
+
--intent-color: currentColor;
|
|
189
|
+
--intent-contrast: var(--color-text-contrast);
|
|
190
|
+
--intent-hover: var(--color-text-hover);
|
|
191
|
+
--intent-strong: var(--color-text-strong);
|
|
192
|
+
--intent-subtle: var(--color-surface);
|
|
193
|
+
--intent-border: currentColor;
|
|
194
|
+
--intent-fill-max: 20%;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
@layer families {
|
|
199
|
+
:where(&:not(.active)) {
|
|
200
|
+
--_m-active: initial;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
:where(&:not(.indeterminate)) {
|
|
204
|
+
--_m-indeterminate: initial;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/* The two states. Each raises a flag (`modifiers.css`); the pseudo-elements
|
|
209
|
+
below read these lines, which inherit to them as the flags do. */
|
|
210
|
+
--_active-content: var(--_m-active) "";
|
|
211
|
+
--_active-shimmer: var(--_m-active) anim-skeleton calc(var(--motion-duration-slow) * 4) linear infinite;
|
|
212
|
+
--_indeterminate-width: var(--_m-indeterminate) 33%;
|
|
213
|
+
--_indeterminate-sweep: var(--_m-indeterminate) anim-progress-indeterminate 1.5s infinite ease-in-out;
|
|
214
|
+
|
|
215
|
+
/* Printed as drawn. A browser leaves backgrounds off paper by default, and
|
|
216
|
+
the bar is nothing but two backgrounds: the track and the value. */
|
|
217
|
+
print-color-adjust: exact;
|
|
218
|
+
|
|
144
219
|
--_d-fill: 12%;
|
|
145
220
|
--_d-fg-on-fill: 0%;
|
|
146
221
|
--_d-border: 0%;
|
|
222
|
+
/* The track is a 12% tint, 1.2:1 against the page. With more contrast asked
|
|
223
|
+
for it is outlined, so where the bar ends is not left to the tint. An edge
|
|
224
|
+
class still decides: `--ui-border` is read before this. */
|
|
225
|
+
@media (prefers-contrast: more) {
|
|
226
|
+
--_d-border: 100%;
|
|
227
|
+
}
|
|
147
228
|
--_d-elevation: 0;
|
|
148
229
|
/* `--progress-color`/`--progress-surface`/`--progress-edge` are the Tier 1
|
|
149
230
|
override path an aesthetic or consumer reaches `.progress` through (see
|
|
@@ -189,14 +270,19 @@
|
|
|
189
270
|
border-radius: var(--ui-radius-pill, var(--ui-radius, var(--ui-corner, calc(infinity * 1px))));
|
|
190
271
|
corner-shape: var(--ui-corner-shape, round);
|
|
191
272
|
background-color: var(--progress-color, var(--intent-color));
|
|
192
|
-
width: var(--progress-value, 0%);
|
|
273
|
+
width: var(--_indeterminate-width, var(--progress-value, 0%));
|
|
274
|
+
animation: var(--_indeterminate-sweep, none);
|
|
193
275
|
z-index: 2;
|
|
194
276
|
}
|
|
195
277
|
|
|
196
|
-
|
|
197
|
-
|
|
278
|
+
/* The shimmer, which generates no box unless `active`. Its animation is
|
|
279
|
+
gated with it: WebKit 26 lists an animation on a pseudo-element that
|
|
280
|
+
generates no box in `getAnimations()`, and an endless one there never
|
|
281
|
+
settles (`structure.spec.ts`, "reaches every line a component draws"). */
|
|
282
|
+
&::before {
|
|
283
|
+
content: var(--_active-content, none);
|
|
198
284
|
@apply absolute inset-0 block h-full;
|
|
199
|
-
animation:
|
|
285
|
+
animation: var(--_active-shimmer, none);
|
|
200
286
|
background: linear-gradient(
|
|
201
287
|
90deg,
|
|
202
288
|
transparent,
|
|
@@ -207,11 +293,6 @@
|
|
|
207
293
|
z-index: 1;
|
|
208
294
|
}
|
|
209
295
|
|
|
210
|
-
&.indeterminate::after {
|
|
211
|
-
width: 33%;
|
|
212
|
-
animation: anim-progress-indeterminate 1.5s infinite ease-in-out;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
296
|
/* Reduced motion, for the entries without the reset; see `box.css`. The
|
|
216
297
|
value moves without sliding, and the shimmer and the indeterminate sweep
|
|
217
298
|
stop where the reset would stop them: the fill rests at the start. */
|
|
@@ -220,9 +301,32 @@
|
|
|
220
301
|
transition-duration: 0.01ms;
|
|
221
302
|
}
|
|
222
303
|
|
|
223
|
-
|
|
224
|
-
|
|
304
|
+
&::before,
|
|
305
|
+
&::after {
|
|
225
306
|
animation: none;
|
|
226
307
|
}
|
|
227
308
|
}
|
|
228
309
|
}
|
|
310
|
+
|
|
311
|
+
/* Forced colours repaint every background as Canvas, the value fill on a
|
|
312
|
+
Canvas track included, so a half-full bar read as an empty one. The bar opts
|
|
313
|
+
out, as the toggles do in `form.css`, and names system colours for every
|
|
314
|
+
part: the value in CanvasText, the track in Canvas, and a CanvasText
|
|
315
|
+
boundary at the track's own width, because a `.soft.edgeless` track has no
|
|
316
|
+
visible line and the extent of the bar is half of what it says. The shimmer
|
|
317
|
+
is decoration in the intent colour, so it goes. */
|
|
318
|
+
@media (forced-colors: active) {
|
|
319
|
+
.progress {
|
|
320
|
+
forced-color-adjust: none;
|
|
321
|
+
background-color: Canvas;
|
|
322
|
+
border-color: CanvasText;
|
|
323
|
+
|
|
324
|
+
&::after {
|
|
325
|
+
background-color: CanvasText;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
&::before {
|
|
329
|
+
display: none;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
@reference "tailwindcss";
|
|
2
|
+
@import "../theme.css";
|
|
3
|
+
@reference "../box.css";
|
|
4
|
+
|
|
5
|
+
/* The focused entry: what the rules in `form.rules.css` need to compile on their
|
|
6
|
+
own, then the rules. An aggregate entry imports the rules file directly and
|
|
7
|
+
supplies those needs once -- Tailwind stacks a `@utility` each time a file
|
|
8
|
+
that defines it is imported or referenced, so a second route to `box.css`
|
|
9
|
+
doubles every `@apply box`. See docs/internal/model.md (One route to each
|
|
10
|
+
utility). */
|
|
11
|
+
@import "./form.rules.css";
|