@codenhub/styles 0.7.0 → 0.9.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/README.es.md +9 -8
- package/README.md +8 -7
- package/README.pt-BR.md +9 -8
- 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 +358 -0
- package/dist/components.css +50 -2
- package/dist/index.css +50 -2
- package/dist/index.d.ts +1 -0
- package/dist/native.css +50 -2
- package/dist/palette.css +1 -1
- package/dist/purge/classes.json +1 -0
- package/dist/purge/index.css +50 -0
- package/dist/theme.css +2 -2
- package/docs/accessibility.md +46 -27
- package/docs/changelog/0.8.0.md +70 -0
- package/docs/changelog/0.9.0.md +40 -0
- package/docs/changelog/index.md +2 -0
- package/docs/es/accessibility.md +47 -28
- package/docs/es/index.md +4 -3
- package/docs/es/integrating/index.md +38 -10
- package/docs/es/integrating/tailwind.md +79 -8
- package/docs/es/integrating/without-a-bundler.md +157 -5
- package/docs/es/setup.md +43 -34
- package/docs/es/usage/aesthetics.md +20 -14
- package/docs/es/usage/buttons.md +6 -2
- package/docs/es/usage/composing.md +6 -2
- package/docs/es/usage/content-and-layout.md +10 -4
- package/docs/es/usage/customizing.md +46 -26
- package/docs/es/usage/feedback.md +5 -1
- package/docs/es/usage/forms.md +30 -5
- package/docs/es/usage/index.md +7 -3
- package/docs/es/usage/presets.md +92 -0
- package/docs/es/usage/solo.md +4 -2
- package/docs/es/usage/theming.md +29 -16
- package/docs/es/usage/tooltips.md +2 -2
- package/docs/index.md +3 -2
- package/docs/integrating/index.md +38 -10
- package/docs/integrating/tailwind.md +78 -7
- package/docs/integrating/without-a-bundler.md +156 -4
- package/docs/pt-BR/accessibility.md +47 -28
- package/docs/pt-BR/index.md +4 -3
- package/docs/pt-BR/integrating/index.md +38 -10
- package/docs/pt-BR/integrating/tailwind.md +79 -8
- package/docs/pt-BR/integrating/without-a-bundler.md +157 -5
- package/docs/pt-BR/setup.md +43 -34
- package/docs/pt-BR/usage/aesthetics.md +20 -14
- package/docs/pt-BR/usage/buttons.md +6 -2
- package/docs/pt-BR/usage/composing.md +6 -2
- package/docs/pt-BR/usage/content-and-layout.md +10 -4
- package/docs/pt-BR/usage/customizing.md +46 -26
- package/docs/pt-BR/usage/feedback.md +5 -1
- package/docs/pt-BR/usage/forms.md +30 -5
- package/docs/pt-BR/usage/index.md +7 -3
- package/docs/pt-BR/usage/presets.md +92 -0
- package/docs/pt-BR/usage/solo.md +4 -2
- package/docs/pt-BR/usage/theming.md +22 -9
- package/docs/pt-BR/usage/tooltips.md +2 -2
- package/docs/setup.md +31 -22
- package/docs/usage/aesthetics.md +19 -13
- package/docs/usage/buttons.md +5 -1
- package/docs/usage/composing.md +5 -1
- package/docs/usage/content-and-layout.md +9 -3
- package/docs/usage/customizing.md +45 -25
- package/docs/usage/feedback.md +4 -0
- package/docs/usage/forms.md +29 -4
- package/docs/usage/index.md +6 -2
- package/docs/usage/presets.md +91 -0
- package/docs/usage/solo.md +3 -1
- package/docs/usage/theming.md +21 -8
- package/docs/usage/tooltips.md +1 -1
- package/llms-full.txt +695 -134
- package/llms.txt +3 -2
- package/package.json +117 -65
- package/{dist/tw → tw}/aesthetics/chunky-tile.css +43 -20
- package/{dist/tw → tw}/aesthetics/cyber.css +19 -25
- package/{dist/tw → tw}/aesthetics/glass.css +110 -36
- package/{dist/tw → tw}/aesthetics/neobrutalism.css +41 -21
- package/{dist/tw → tw}/aesthetics/pixel.css +3 -0
- package/tw/aesthetics/sketch.css +435 -0
- package/{dist/tw → tw}/box.css +109 -26
- 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} +156 -33
- package/tw/components/form.css +11 -0
- package/{dist/tw/components/form.css → tw/components/form.rules.css} +584 -141
- 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 +225 -0
- package/tw/components/tooltip.css +11 -0
- package/{dist/tw/components/tooltip.css → tw/components/tooltip.rules.css} +82 -61
- package/{dist/tw → tw}/corner.css +18 -12
- package/{dist/tw → tw}/elevation.css +27 -21
- package/{dist/tw → tw}/index.css +11 -9
- package/tw/index.d.ts +1 -0
- package/tw/intent.css +312 -0
- package/tw/modifiers.css +127 -0
- package/tw/native.css +323 -0
- package/tw/presentation.css +139 -0
- package/tw/reset.css +10 -0
- package/{dist/tw/reset.css → tw/reset.rules.css} +7 -8
- 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 +93 -29
- package/tw/typography.css +8 -0
- package/{dist/tw/typography.css → tw/typography.rules.css} +0 -3
- package/{dist/tw → tw}/utilities/content.css +248 -108
- package/tw/utilities/index.css +11 -0
- package/tw/utilities/layout.css +210 -0
- package/tw/utilities/rules.css +8 -0
- package/dist/tw/aesthetics/sketch.css +0 -398
- package/dist/tw/components/button.css +0 -139
- package/dist/tw/components/index.css +0 -35
- package/dist/tw/components/surface.css +0 -184
- package/dist/tw/intent.css +0 -229
- 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 -144
- /package/{dist/tw → tw}/aesthetics/index.css +0 -0
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
@reference "tailwindcss";
|
|
2
|
-
@import "../theme.css";
|
|
3
|
-
@reference "../box.css";
|
|
4
|
-
|
|
5
|
-
/* A filled, edgeless, raised box you can press. `box` paints it; everything
|
|
6
|
-
here is what makes it a button rather than some other box.
|
|
7
|
-
|
|
8
|
-
The resting values are the published default: a button with no presentation
|
|
9
|
-
class is solid and edgeless, and that is a decision written on three lines
|
|
10
|
-
rather than a `var()` fallback buried in an expression. */
|
|
11
|
-
@utility btn {
|
|
12
|
-
--_d-fill: 100%;
|
|
13
|
-
--_d-fg-on-fill: 100%;
|
|
14
|
-
--_d-border: 0%;
|
|
15
|
-
--_d-elevation: 1;
|
|
16
|
-
|
|
17
|
-
@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;
|
|
18
|
-
|
|
19
|
-
min-height: var(--control-height);
|
|
20
|
-
/* The vertical padding gives back the line `box` draws, so a default button
|
|
21
|
-
is exactly `--control-height` tall like `.ipt` beside it, under any
|
|
22
|
-
aesthetic's line width. At the default 16px/1.5 text the label and the
|
|
23
|
-
padding fill it; the size and padding modifiers set their own. */
|
|
24
|
-
padding-block: calc(0.5rem - var(--_width));
|
|
25
|
-
/* The surrounding font, not the user agent's smaller button one, on every
|
|
26
|
-
entry: `/components` carries no reset to say so, and a `.btn` link and a
|
|
27
|
-
`.btn` button have to print the same label. `.sm` and `.lg` set their own
|
|
28
|
-
size over this. */
|
|
29
|
-
font-family: inherit;
|
|
30
|
-
font-size: inherit;
|
|
31
|
-
line-height: inherit;
|
|
32
|
-
/* The label is material, shared with `.badge`: weight, tracking, case, and a
|
|
33
|
-
text shadow, set by an aesthetic as tokens (`.chunky-tile`'s heavier,
|
|
34
|
-
tracked label), and a consumer's own `font-*`, `tracking-*`, `uppercase`, or
|
|
35
|
-
text-shadow utility still beats the aesthetic. Tracking has no fallback on
|
|
36
|
-
purpose: undefined, the declaration is invalid at computed-value time and
|
|
37
|
-
`letter-spacing` inherits, which is what it did before the slot existed.
|
|
38
|
-
Case and shadow fall back to `none`, which is what a button already does:
|
|
39
|
-
the user agent stops both inheriting into one. The shadow is written
|
|
40
|
-
without a colour, so it takes the label's own and cannot lower its
|
|
41
|
-
contrast. See docs/internal/model.md#cascade-layers. */
|
|
42
|
-
font-weight: var(--ui-label-weight, var(--font-weight-semibold));
|
|
43
|
-
letter-spacing: var(--ui-label-tracking);
|
|
44
|
-
text-transform: var(--ui-label-case, none);
|
|
45
|
-
text-shadow: var(--ui-label-shadow, none);
|
|
46
|
-
|
|
47
|
-
&.sm {
|
|
48
|
-
@apply min-h-8 px-3 py-1 text-sm;
|
|
49
|
-
|
|
50
|
-
--_scale-size: 0.75;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
&.lg {
|
|
54
|
-
@apply min-h-12 px-5 py-2.5 text-[1.0625rem];
|
|
55
|
-
|
|
56
|
-
--_scale-size: 1.25;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
&.icon {
|
|
60
|
-
@apply aspect-square p-2;
|
|
61
|
-
|
|
62
|
-
min-width: var(--control-height);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/* The size steps for an icon button, square at each: `.sm`'s 2rem, with the
|
|
66
|
-
padding giving back the line width the way the default button's does, and
|
|
67
|
-
`.lg`'s 3rem. Each names its width as well as its height, because WebKit
|
|
68
|
-
does not let `aspect-ratio` widen a box past its `min-width`. */
|
|
69
|
-
&.icon.sm {
|
|
70
|
-
min-width: 2rem;
|
|
71
|
-
padding: calc(0.375rem - var(--_width));
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
&.icon.lg {
|
|
75
|
-
min-width: 3rem;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/* Bare `sm`/`lg` are the size modifier's class names, so `p-` prefixes here.
|
|
79
|
-
`.p-xs` is the tightest step, below `.p-sm`: a chip-sized button in a
|
|
80
|
-
toolbar or a table cell.
|
|
81
|
-
|
|
82
|
-
`.icon` drops both floors -- `min-width` from its own base rule above and
|
|
83
|
-
`min-height` from `--control-height` -- at every padding tier; labeled
|
|
84
|
-
buttons keep the height floor everywhere but `.p-xs`. `.icon` is already
|
|
85
|
-
square: `aspect-square` ties its width to whatever height it lands on, so a
|
|
86
|
-
surviving height floor would keep the button bigger than its own glyph
|
|
87
|
-
however tight the padding asked to be. */
|
|
88
|
-
&.p-xs {
|
|
89
|
-
@apply px-2 py-0.5;
|
|
90
|
-
|
|
91
|
-
--_scale-pad: 0.5;
|
|
92
|
-
|
|
93
|
-
/* The one padding step that also drops the size floor for a labeled
|
|
94
|
-
button. At this tier the button is a chip in a toolbar or a table
|
|
95
|
-
cell, where `--control-height` is taller than the row it sits in;
|
|
96
|
-
every other size and padding class keeps the floor, so a plain button
|
|
97
|
-
stays a comfortable target. */
|
|
98
|
-
min-height: 0;
|
|
99
|
-
|
|
100
|
-
&.icon {
|
|
101
|
-
@apply p-0.5;
|
|
102
|
-
|
|
103
|
-
min-width: 0;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
&.p-sm {
|
|
108
|
-
@apply px-2.5 py-1;
|
|
109
|
-
|
|
110
|
-
--_scale-pad: 0.75;
|
|
111
|
-
|
|
112
|
-
&.icon {
|
|
113
|
-
@apply p-1;
|
|
114
|
-
|
|
115
|
-
min-width: 0;
|
|
116
|
-
min-height: 0;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
&.p-lg {
|
|
121
|
-
@apply px-6 py-3;
|
|
122
|
-
|
|
123
|
-
--_scale-pad: 1.25;
|
|
124
|
-
|
|
125
|
-
&.icon {
|
|
126
|
-
@apply p-3;
|
|
127
|
-
|
|
128
|
-
min-width: 0;
|
|
129
|
-
min-height: 0;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/* A pill normally takes the round material ahead of the box radius. Sketch
|
|
134
|
-
gives this token the button's own box outline; a bevel still cuts the full
|
|
135
|
-
radius to points under cyber. */
|
|
136
|
-
&.pill {
|
|
137
|
-
border-radius: var(--ui-radius-pill, calc(infinity * 1px));
|
|
138
|
-
}
|
|
139
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/* The layer map, stated before any import uses a layer -- see `theme.css`.
|
|
2
|
-
Tailwind's utilities are imported into `utilities` the way
|
|
3
|
-
`tailwindcss/index.css` does it, so every component lands there on this
|
|
4
|
-
entrypoint and on `/native` too, exactly where `.` already puts them. Without
|
|
5
|
-
`layer(utilities)` the CLI emitted them unlayered here, and they beat every
|
|
6
|
-
consumer rule on these two entries alone. */
|
|
7
|
-
@layer theme, base, components, utilities;
|
|
8
|
-
|
|
9
|
-
/* The theme before `@reference "tailwindcss"`, as `native.css` has it:
|
|
10
|
-
Tailwind writes the theme's variables at the first `@theme` it meets, and
|
|
11
|
-
after the reference that is Tailwind's own reference-only one. See
|
|
12
|
-
docs/internal/model.md (Which files import the theme). */
|
|
13
|
-
@import "../theme.css";
|
|
14
|
-
@reference "tailwindcss";
|
|
15
|
-
@import "tailwindcss/utilities.css" layer(utilities);
|
|
16
|
-
/* Everything that is not `src/` -- see the note in `index.css`. Keeps a class
|
|
17
|
-
name in a docs code fence from shipping as a real rule in `dist/components.css`. */
|
|
18
|
-
@import "../typography.css";
|
|
19
|
-
@import "../box.css";
|
|
20
|
-
@import "./button.css";
|
|
21
|
-
@import "./feedback.css";
|
|
22
|
-
@import "./form.css";
|
|
23
|
-
@import "./surface.css";
|
|
24
|
-
@import "./tooltip.css";
|
|
25
|
-
|
|
26
|
-
/* The composition utilities -- `box`, `box-hover`, `box-active`,
|
|
27
|
-
`text-control`, `surface`, `input-group` -- are `@utility` rules whose bodies
|
|
28
|
-
the content scan will not emit on its own. `box` and friends appear only as
|
|
29
|
-
`@utility` blocks and `@apply` targets; `text-control`, `surface` and
|
|
30
|
-
`input-group` appear only inside `:is()`/`:where()` argument lists in
|
|
31
|
-
`intent.css` and `form.css`, never as a selector of their own. Safelisting
|
|
32
|
-
all six makes the emission deliberate; the composition-body check in
|
|
33
|
-
`exports.test.ts` fails the build if one is dropped. `text-control` and
|
|
34
|
-
`surface` are also documented as consumer-usable on their own. */
|
|
35
|
-
@source inline("box box-hover box-active text-control surface input-group unadorned text-display text-title-lg text-title text-title-sm text-label-lg text-label text-body btn field label hint ipt icon textarea select checkbox radio switch alert alert-icon badge skeleton progress tooltip tooltip-bubble tooltip-icon card panel interactive flush neutral solid soft ghost edged edgeless flat raised floating");
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
@reference "tailwindcss";
|
|
2
|
-
@import "../theme.css";
|
|
3
|
-
@import "../surface.css";
|
|
4
|
-
@reference "../box.css";
|
|
5
|
-
|
|
6
|
-
/* A ghost, edged container that takes one unit when depth is supplied. */
|
|
7
|
-
@utility card {
|
|
8
|
-
@apply surface p-(--surface-padding,1.25rem);
|
|
9
|
-
|
|
10
|
-
/* After the `@apply`, not before: `surface` inlines its own resting geometry
|
|
11
|
-
at that point, so defaults written above it would be overridden by the very
|
|
12
|
-
utility they are meant to specialise. */
|
|
13
|
-
--_d-fill: 0%;
|
|
14
|
-
--_d-fg-on-fill: 0%;
|
|
15
|
-
--_d-border: 100%;
|
|
16
|
-
--_d-elevation: 1;
|
|
17
|
-
|
|
18
|
-
&.p-xs {
|
|
19
|
-
--surface-padding: 0.5rem;
|
|
20
|
-
--_scale-pad: 0.5;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
&.p-sm {
|
|
24
|
-
--surface-padding: 0.75rem;
|
|
25
|
-
--_scale-pad: 0.75;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
&.p-lg {
|
|
29
|
-
--surface-padding: 2rem;
|
|
30
|
-
--_scale-pad: 1.25;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
&.flush {
|
|
34
|
-
--surface-padding: 0;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/* `.soft` rests untinted for no named intent instead of mixing its 12%: 12%
|
|
38
|
-
of `--color-text` onto any of `--color-background`, `--color-foreground`,
|
|
39
|
-
or `--color-surface` lands within a few units of the others (a near-black
|
|
40
|
-
ink dominates the result), so swapping the ground token alone does not read
|
|
41
|
-
as quieter. A resting no-intent `.card.soft` is `--color-foreground` with
|
|
42
|
-
no ink mixed in -- a plain step up from the page that marks a different
|
|
43
|
-
container without drawing attention to it.
|
|
44
|
-
|
|
45
|
-
A named intent keeps its ordinary 12% wash: 12% of an actual hue does not
|
|
46
|
-
read as a slab the way 12% of near-black ink does (`.card.soft.destructive`
|
|
47
|
-
is a gentle `249, 225, 225`), and untinting it would silence it rather than
|
|
48
|
-
quiet it. `:not(...)` names every intent class for that reason; `.panel`'s
|
|
49
|
-
carve-out below is scoped the same way.
|
|
50
|
-
|
|
51
|
-
`--_fill-cap: 0%` (box.css's override slot, not `--ui-fill` directly -- see
|
|
52
|
-
the comment there) composed with `box-hover`'s formula (`min(100%, resting
|
|
53
|
-
+ 14%)`) reveals the intent on hover with no second fill declaration for
|
|
54
|
-
the no-intent case: resting at 0% means hover lands at exactly the hover
|
|
55
|
-
step, 14%, in `--intent-hover`. The ground steps to `--color-surface` at
|
|
56
|
-
the same moment, through `--_d-surface-ground`, the default `surface` reads
|
|
57
|
-
beneath the public `--ui-surface-ground`, so a consumer's override, or
|
|
58
|
-
glass's ground, wins over both states. Scoped to `.interactive` and
|
|
59
|
-
`.hoverable`, the two classes that opt a card into `box-hover`: a plain
|
|
60
|
-
`.card.soft` has no hover state to reveal into and stays at the quiet rest.
|
|
61
|
-
A named intent needs neither special case: it rests tinted, so the generic
|
|
62
|
-
`box-hover` formula deepens it on hover (12% to 26%). */
|
|
63
|
-
&.soft:not(.primary, .secondary, .success, .warning, .destructive, .info) {
|
|
64
|
-
--_fill-cap: 0%;
|
|
65
|
-
--_d-surface-ground: var(--color-foreground);
|
|
66
|
-
|
|
67
|
-
&.interactive:hover,
|
|
68
|
-
&.hoverable:hover {
|
|
69
|
-
--_d-surface-ground: var(--color-surface);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/* Opt-in, because a card is only sometimes a control. Applications still owe
|
|
74
|
-
it a real interactive element and an accessible name. Hover and press are
|
|
75
|
-
the derived ones every other pressable box gets; there is nothing
|
|
76
|
-
card-specific about either.
|
|
77
|
-
|
|
78
|
-
`.interactive` is the whole opt-in and stays that way; `.hoverable` and
|
|
79
|
-
`.pressable` are its halves, for a card that answers one gesture and not
|
|
80
|
-
the other. A card with its own nested controls takes `.hoverable` for the
|
|
81
|
-
hover warmth without the press-scale that reads as "you activated the
|
|
82
|
-
card" when the click really landed on a nested button. `.hoverable` alone
|
|
83
|
-
does not set the pointer cursor: that travels with being a click target,
|
|
84
|
-
i.e. with `.pressable` / `.interactive`. */
|
|
85
|
-
&.interactive,
|
|
86
|
-
&.hoverable {
|
|
87
|
-
@apply box-hover;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
&.interactive,
|
|
91
|
-
&.pressable {
|
|
92
|
-
@apply box-active cursor-pointer;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/* A panel is the flush, unelevated sibling: sidebars, toolbars, and wells that
|
|
97
|
-
sit flat against the layout rather than floating above it. Soft and edgeless
|
|
98
|
-
is what makes it read as a well without drawing a line to say so. */
|
|
99
|
-
@utility panel {
|
|
100
|
-
@apply surface p-(--surface-padding,1rem);
|
|
101
|
-
|
|
102
|
-
--_d-fill: 12%;
|
|
103
|
-
--_d-fg-on-fill: 0%;
|
|
104
|
-
--_d-border: 0%;
|
|
105
|
-
--_d-elevation: 0;
|
|
106
|
-
|
|
107
|
-
&.p-xs {
|
|
108
|
-
--surface-padding: 0.25rem;
|
|
109
|
-
--_scale-pad: 0.5;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
&.p-sm {
|
|
113
|
-
--surface-padding: 0.5rem;
|
|
114
|
-
--_scale-pad: 0.75;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
&.p-lg {
|
|
118
|
-
--surface-padding: 1.5rem;
|
|
119
|
-
--_scale-pad: 1.25;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
&.flush {
|
|
123
|
-
--surface-padding: 0;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/* Neutral panels are the common case -- layout wells, sidebars, toolbars with
|
|
127
|
-
no named intent -- and 12% of `--color-text` (near-black) mixed onto the
|
|
128
|
-
page is far more assertive than 12% of a hue (`217, 217, 217` against a
|
|
129
|
-
`250, 250, 250` page): the same "neutral ink reads louder" effect
|
|
130
|
-
`.card.soft` answers, and the reason `--intent-fill-max` stops neutral's
|
|
131
|
-
fill short everywhere else.
|
|
132
|
-
|
|
133
|
-
Scoped to no named intent rather than untinted unconditionally, as
|
|
134
|
-
`data-table` is: a panel is not interactive, so there is no hover to reveal
|
|
135
|
-
a colored intent into, and it is edgeless by default, so the fill is the
|
|
136
|
-
only channel a `.primary` bulk-actions bar or a `.destructive` danger-zone
|
|
137
|
-
panel has to say what it is (a resting `.panel.destructive` is a gentle
|
|
138
|
-
`249, 225, 225` wash). `.card.soft` carries the same scoping. `:not(...)`
|
|
139
|
-
names every intent class, plus `.solid`/`.ghost` so an explicit
|
|
140
|
-
presentation on the element is never clamped to a cap it did not ask for --
|
|
141
|
-
the guard `data-table`'s `:not(.solid, .ghost)` also uses.
|
|
142
|
-
|
|
143
|
-
Grounds on `--color-foreground` through `--_d-surface-ground`, the default
|
|
144
|
-
`.card.soft` rests on, so a bare `.panel` rests at exactly the plate a
|
|
145
|
-
`.card.soft` does, and a consumer's `--ui-surface-ground` or glass's
|
|
146
|
-
translucent ground wins over it: a neutral panel under `.glass` is glass.
|
|
147
|
-
Permanent rather than hover-revealed: neither a panel nor `data-table` has
|
|
148
|
-
an interaction state to reveal a tint into. */
|
|
149
|
-
&:not(.primary, .secondary, .success, .warning, .destructive, .info, .solid, .ghost) {
|
|
150
|
-
--_fill-cap: 0%;
|
|
151
|
-
--_d-surface-ground: var(--color-foreground);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/* The user agent already promises both of these for a native `<dialog>` --
|
|
156
|
-
`dialog:not([open]) { display: none }` and a centred `margin: auto` on the
|
|
157
|
-
open box -- but both are user-agent origin, which loses to any author rule
|
|
158
|
-
at all. `.card`'s own `display: block` beats the first outright, so a
|
|
159
|
-
`<dialog class="card">` rendered open with no `open` attribute and no
|
|
160
|
-
`.showModal()` call, and a margin reset beats the second, so an opened one
|
|
161
|
-
pinned to the top-left. The registry has no dialog component, and these
|
|
162
|
-
three are the containers a consumer reaches for.
|
|
163
|
-
|
|
164
|
-
Here rather than in the reset, so every entrypoint that ships `.card` ships
|
|
165
|
-
the fix, `/components` included, and scoped to the package's own containers,
|
|
166
|
-
so a dialog the package does not style keeps whatever margin its author
|
|
167
|
-
gives it.
|
|
168
|
-
|
|
169
|
-
The two halves sit in different places. Hiding a closed dialog is
|
|
170
|
-
behaviour, so it is unlayered and beats any layered rule whatever its
|
|
171
|
-
specificity. Centring an open one is a default, so it is in `utilities` at
|
|
172
|
-
zero specificity: it beats a reset in `base`, and a consumer's own margin
|
|
173
|
-
-- a utility, or unlayered CSS -- beats it. Unlayered at 0-2-1 it overruled
|
|
174
|
-
`mt-8` and `.my-dialog { margin-top: 2rem }` alike, and a dialog could not
|
|
175
|
-
be placed. */
|
|
176
|
-
dialog:is(.card, .panel, .surface):not([open]) {
|
|
177
|
-
display: none;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
@layer utilities {
|
|
181
|
-
:where(dialog:is(.card, .panel, .surface)[open]) {
|
|
182
|
-
margin: auto;
|
|
183
|
-
}
|
|
184
|
-
}
|
package/dist/tw/intent.css
DELETED
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
/* Imported into the `components` layer by `theme.css`, below every utility, so
|
|
2
|
-
a consumer's own utility or unlayered CSS beats these classes. See
|
|
3
|
-
docs/internal/model.md#cascade-layers. */
|
|
4
|
-
|
|
5
|
-
/* An intent maps one colour family onto seven shared slots and nothing else.
|
|
6
|
-
It does not cascade: the reset at the bottom redeclares the neutral defaults
|
|
7
|
-
at every component's own root, so a `.success` container cannot recolour a
|
|
8
|
-
nested destructive button while `.btn.success` still wins. Every intent writes
|
|
9
|
-
every slot, `--intent-fill-max` included -- omitting it inherits the reset's
|
|
10
|
-
neutral cap, and `tests/integration/registry.test.ts` fails the build on one
|
|
11
|
-
that does. Neutral maps `--intent-subtle` to `--color-surface` (the tone
|
|
12
|
-
tooltips, key caps, code and table heads sit on) and `--intent-border` to
|
|
13
|
-
`--ui-ink` (how an aesthetic restates the neutral line without naming one). */
|
|
14
|
-
|
|
15
|
-
/* The same neutral values, at the root. This is the floor: an element that
|
|
16
|
-
carries no intent class and matches none of the resets below -- a component
|
|
17
|
-
`@apply`-ed onto a selector the package does not name, a bare `<code>` with
|
|
18
|
-
no native stylesheet loaded -- still composes against a real colour instead
|
|
19
|
-
of an undefined one that collapses its `color-mix()` to nothing. It is not
|
|
20
|
-
the barrier. `.neutral` and both resets below still write these slots on the
|
|
21
|
-
element itself, which is a matching rule and so beats this inherited value --
|
|
22
|
-
that is what stops a `.success` container's intent reaching a component
|
|
23
|
-
nested under it. An intent class on the element beats both. Values track
|
|
24
|
-
`.neutral` slot for slot; `registry.test.ts` fails the build on drift. */
|
|
25
|
-
:root {
|
|
26
|
-
--intent-color: var(--color-text);
|
|
27
|
-
--intent-contrast: var(--color-text-contrast);
|
|
28
|
-
--intent-hover: var(--color-text-hover);
|
|
29
|
-
--intent-strong: var(--color-text-strong);
|
|
30
|
-
--intent-subtle: var(--color-surface);
|
|
31
|
-
--intent-border: var(--ui-ink, var(--color-border));
|
|
32
|
-
--intent-fill-max: 20%;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/* Neutral stops its fill short: its colour is the page's ink, so a full fill is
|
|
36
|
-
a slab and `.neutral.solid` would be pixel-for-pixel `.primary.solid`. 20% is
|
|
37
|
-
chosen against `.soft`'s 12% -- a step past the tint, not a repeat.
|
|
38
|
-
`--intent-contrast` stays the page colour; a `.neutral.solid` badge's ink is
|
|
39
|
-
`box`'s question, answered by the same `--ui-fg-on-fill` cap. Pointing this
|
|
40
|
-
slot at `--color-text` renders a checked neutral checkbox black-on-black. */
|
|
41
|
-
.neutral {
|
|
42
|
-
--intent-color: var(--color-text);
|
|
43
|
-
--intent-contrast: var(--color-text-contrast);
|
|
44
|
-
--intent-hover: var(--color-text-hover);
|
|
45
|
-
--intent-strong: var(--color-text-strong);
|
|
46
|
-
--intent-subtle: var(--color-surface);
|
|
47
|
-
--intent-border: var(--ui-ink, var(--color-border));
|
|
48
|
-
--intent-fill-max: 20%;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
.primary {
|
|
52
|
-
--intent-color: var(--color-primary);
|
|
53
|
-
--intent-contrast: var(--color-primary-contrast);
|
|
54
|
-
--intent-hover: var(--color-primary-hover);
|
|
55
|
-
--intent-strong: var(--color-primary-strong);
|
|
56
|
-
--intent-subtle: var(--color-primary-subtle);
|
|
57
|
-
--intent-border: var(--color-primary);
|
|
58
|
-
--intent-fill-max: 100%;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
.secondary {
|
|
62
|
-
--intent-color: var(--color-accent);
|
|
63
|
-
--intent-contrast: var(--color-accent-contrast);
|
|
64
|
-
--intent-hover: var(--color-accent-hover);
|
|
65
|
-
--intent-strong: var(--color-accent-strong);
|
|
66
|
-
--intent-subtle: var(--color-accent-subtle);
|
|
67
|
-
--intent-border: var(--color-accent);
|
|
68
|
-
--intent-fill-max: 100%;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
.success {
|
|
72
|
-
--intent-color: var(--color-success);
|
|
73
|
-
--intent-contrast: var(--color-success-contrast);
|
|
74
|
-
--intent-hover: var(--color-success-hover);
|
|
75
|
-
--intent-strong: var(--color-success-strong);
|
|
76
|
-
--intent-subtle: var(--color-success-subtle);
|
|
77
|
-
--intent-border: var(--color-success);
|
|
78
|
-
--intent-fill-max: 100%;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
.warning {
|
|
82
|
-
--intent-color: var(--color-warning);
|
|
83
|
-
--intent-contrast: var(--color-warning-contrast);
|
|
84
|
-
--intent-hover: var(--color-warning-hover);
|
|
85
|
-
--intent-strong: var(--color-warning-strong);
|
|
86
|
-
--intent-subtle: var(--color-warning-subtle);
|
|
87
|
-
--intent-border: var(--color-warning);
|
|
88
|
-
--intent-fill-max: 100%;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
.destructive {
|
|
92
|
-
--intent-color: var(--color-destructive);
|
|
93
|
-
--intent-contrast: var(--color-destructive-contrast);
|
|
94
|
-
--intent-hover: var(--color-destructive-hover);
|
|
95
|
-
--intent-strong: var(--color-destructive-strong);
|
|
96
|
-
--intent-subtle: var(--color-destructive-subtle);
|
|
97
|
-
--intent-border: var(--color-destructive);
|
|
98
|
-
--intent-fill-max: 100%;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
.info {
|
|
102
|
-
--intent-color: var(--color-info);
|
|
103
|
-
--intent-contrast: var(--color-info-contrast);
|
|
104
|
-
--intent-hover: var(--color-info-hover);
|
|
105
|
-
--intent-strong: var(--color-info-strong);
|
|
106
|
-
--intent-subtle: var(--color-info-subtle);
|
|
107
|
-
--intent-border: var(--color-info);
|
|
108
|
-
--intent-fill-max: 100%;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/* Every component resolves the neutral defaults at its own root, at zero
|
|
112
|
-
specificity, so an intent class on the element wins while an inherited value
|
|
113
|
-
loses -- the one rule that lets every component drop its per-intent branches.
|
|
114
|
-
This list and the one in `native.css` are the package's only hand-maintained
|
|
115
|
-
selector lists; `tests/integration/registry.test.ts` fails the build on a
|
|
116
|
-
registry component missing from either. `.text-control` and `.surface` are on
|
|
117
|
-
it though they are not components: both are documented as typeable on their
|
|
118
|
-
own, and a bare `<div class="surface">` with no intent resolved computes a
|
|
119
|
-
transparent background and a zero-width border -- `box` collapses. */
|
|
120
|
-
:where(
|
|
121
|
-
.btn,
|
|
122
|
-
.ipt,
|
|
123
|
-
.text-control,
|
|
124
|
-
.surface,
|
|
125
|
-
.textarea,
|
|
126
|
-
.select,
|
|
127
|
-
.input-group,
|
|
128
|
-
.checkbox,
|
|
129
|
-
.radio,
|
|
130
|
-
.switch,
|
|
131
|
-
.card,
|
|
132
|
-
.panel,
|
|
133
|
-
.alert,
|
|
134
|
-
.data-table,
|
|
135
|
-
.pre,
|
|
136
|
-
.quote,
|
|
137
|
-
.tooltip-bubble,
|
|
138
|
-
.tooltip-icon,
|
|
139
|
-
.badge,
|
|
140
|
-
.kbd,
|
|
141
|
-
.code,
|
|
142
|
-
.skeleton,
|
|
143
|
-
.progress,
|
|
144
|
-
.divider
|
|
145
|
-
) {
|
|
146
|
-
--intent-color: var(--color-text);
|
|
147
|
-
--intent-contrast: var(--color-text-contrast);
|
|
148
|
-
--intent-hover: var(--color-text-hover);
|
|
149
|
-
--intent-strong: var(--color-text-strong);
|
|
150
|
-
--intent-subtle: var(--color-surface);
|
|
151
|
-
--intent-border: var(--ui-ink, var(--color-border));
|
|
152
|
-
--intent-fill-max: 20%;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/* The six text controls take a heavier line than everything else that rests on
|
|
156
|
-
the shared neutral. A card, a table or a divider sits on a filled surface or
|
|
157
|
-
separates content that identifies itself; a text control at rest is a
|
|
158
|
-
transparent box whose only mark is its border, and WCAG 1.4.11 asks that
|
|
159
|
-
border for 3:1. `--color-border` gives it 1.42:1.
|
|
160
|
-
|
|
161
|
-
Declared here at zero specificity for the same reason the indicators below
|
|
162
|
-
are: written inside `@utility text-control` it would land in `utilities`,
|
|
163
|
-
above every intent class in `components`, and overrule `.primary` on the
|
|
164
|
-
element. Written as a plain class list it would carry 0-1-0 and, being later
|
|
165
|
-
in the stylesheet, beat `.primary` the same way. Either would make every
|
|
166
|
-
colored control draw a grey line; `:where()` keeps it under both.
|
|
167
|
-
|
|
168
|
-
An aesthetic reaches this line through `--ui-control-ink` first, then its
|
|
169
|
-
`--ui-ink`: the theme keeps a control border apart from a surface border, and
|
|
170
|
-
an aesthetic whose neutral line suits a pane but not a control's boundary --
|
|
171
|
-
`.glass`'s white hairline, `.chunky-tile`'s tile grey -- names a control line
|
|
172
|
-
of its own. See docs/internal/model.md#presentation.
|
|
173
|
-
|
|
174
|
-
The second selector is the tooltip bubble's below, for the same reason:
|
|
175
|
-
`.neutral` carries 0-1-0 and beat `:where()`, so a `.neutral` field under
|
|
176
|
-
`.glass` drew the pane's hairline while an unclassed one drew the control
|
|
177
|
-
line, and writing the intent out changed the box. */
|
|
178
|
-
:where(.text-control, .ipt, .textarea, .select, .input-group, .checkbox, .radio, .switch),
|
|
179
|
-
:is(.text-control, .ipt, .textarea, .select, .input-group, .checkbox, .radio, .switch).neutral {
|
|
180
|
-
--intent-border: var(--ui-control-ink, var(--ui-ink, var(--color-control-border)));
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/* A table's lines -- its frame, head rule, and row rules -- are drawn on a
|
|
184
|
-
plate, not at a pane's edge against the backdrop, so an aesthetic whose
|
|
185
|
-
neutral line is a highlight names a rule line of its own: glass's white
|
|
186
|
-
hairline vanishes on the table's light plate. Neutral only, and `.neutral`
|
|
187
|
-
included, the way the control line above is, and a `.neutral` row in a
|
|
188
|
-
table of another intent, which draws its rules as a neutral table does. */
|
|
189
|
-
:where(.data-table),
|
|
190
|
-
.data-table.neutral,
|
|
191
|
-
.data-table tr.neutral {
|
|
192
|
-
--intent-border: var(--ui-rule-ink, var(--ui-ink, var(--color-border)));
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/* The bubble a tooltip draws is the one plate in the package that is chosen
|
|
196
|
-
rather than composed, so it resolves the no-intent case onto its own pair
|
|
197
|
-
instead of the shared neutral -- see `--color-tooltip` in `theme.css`.
|
|
198
|
-
|
|
199
|
-
The cap goes with it. Neutral stops its fill at 20% because its colour is the
|
|
200
|
-
page's ink; `--color-tooltip` is a plate rather than an ink, so a full fill
|
|
201
|
-
of it is the plate and there is nothing to stop short of. `--intent-subtle`
|
|
202
|
-
stays the surface token, the tone every other unclassed component sits on.
|
|
203
|
-
`.tooltip-icon` is a separate element that never fills past `0%`, so the
|
|
204
|
-
generic neutral reset above is enough for it.
|
|
205
|
-
|
|
206
|
-
Two selectors, so `none` and `neutral` agree. `:where()` loses to any intent
|
|
207
|
-
class, so `.tooltip-bubble.primary` still floods with primary;
|
|
208
|
-
`.tooltip-bubble.neutral` carries 0-2-0 and beats `.neutral`, so writing the
|
|
209
|
-
intent out gives the same bubble as writing nothing. */
|
|
210
|
-
:where(.tooltip-bubble),
|
|
211
|
-
.tooltip-bubble.neutral {
|
|
212
|
-
--intent-color: var(--color-tooltip);
|
|
213
|
-
--intent-contrast: var(--color-tooltip-contrast);
|
|
214
|
-
--intent-hover: var(--color-tooltip);
|
|
215
|
-
--intent-strong: var(--color-tooltip-contrast);
|
|
216
|
-
--intent-subtle: var(--color-surface);
|
|
217
|
-
--intent-border: var(--ui-ink, var(--color-border));
|
|
218
|
-
--intent-fill-max: 100%;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/* Indicators take the color they sit in rather than the shared neutral, so a
|
|
222
|
-
skeleton inside filled or colored content still matches it. It has to be
|
|
223
|
-
declared here at zero specificity: written in the component's own block it
|
|
224
|
-
would carry 0-1-0 and, being later in the stylesheet, beat `.success` --
|
|
225
|
-
which silently makes every indicator ignore every intent class. */
|
|
226
|
-
:where(.skeleton, .progress, .divider) {
|
|
227
|
-
--intent-color: currentColor;
|
|
228
|
-
--intent-border: currentColor;
|
|
229
|
-
}
|