@codenhub/styles 0.4.0 → 0.5.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.md +1 -1
- 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 +1 -1
- package/dist/aesthetics/neobrutalism.css +1 -1
- package/dist/aesthetics/pixel.css +1 -1
- package/dist/aesthetics/sketch.css +1 -0
- package/dist/components.css +1 -1
- package/dist/index.css +1 -1
- package/dist/native.css +1 -1
- package/dist/palette.css +1 -1
- package/dist/theme.css +1 -1
- package/dist/tw/aesthetics/chunky-tile.css +142 -126
- package/dist/tw/aesthetics/cyber.css +132 -95
- package/dist/tw/aesthetics/glass.css +97 -56
- package/dist/tw/aesthetics/index.css +1 -0
- package/dist/tw/aesthetics/neobrutalism.css +99 -52
- package/dist/tw/aesthetics/pixel.css +127 -87
- package/dist/tw/aesthetics/sketch.css +326 -0
- package/dist/tw/box.css +100 -35
- package/dist/tw/components/button.css +40 -22
- package/dist/tw/components/feedback.css +29 -14
- package/dist/tw/components/form.css +151 -155
- package/dist/tw/components/index.css +15 -3
- package/dist/tw/components/loader.css +34 -25
- package/dist/tw/components/surface.css +28 -71
- package/dist/tw/components/tooltip.css +20 -10
- package/dist/tw/corner.css +26 -0
- package/dist/tw/elevation.css +8 -9
- package/dist/tw/intent.css +17 -9
- package/dist/tw/native.css +45 -39
- package/dist/tw/palette.css +452 -446
- package/dist/tw/presentation.css +9 -4
- package/dist/tw/surface.css +62 -0
- package/dist/tw/theme.css +106 -75
- package/dist/tw/utilities/content.css +25 -16
- package/dist/tw/utilities/layout.css +2 -2
- package/docs/accessibility.md +16 -16
- package/docs/changelog/0.5.0.md +38 -0
- package/docs/changelog/index.md +1 -0
- package/docs/index.md +3 -3
- package/docs/setup.md +23 -3
- package/docs/usage/aesthetics.md +56 -13
- package/docs/usage/buttons.md +13 -13
- package/docs/usage/composing.md +11 -11
- package/docs/usage/content-and-layout.md +13 -13
- package/docs/usage/customizing.md +90 -52
- package/docs/usage/feedback.md +1 -1
- package/docs/usage/forms.md +11 -11
- package/docs/usage/theming.md +1 -1
- package/llms-full.txt +274 -136
- package/package.json +12 -2
|
@@ -1,113 +1,150 @@
|
|
|
1
1
|
/* Cyber: bevelled corners, a thin bright edge, and a glow in the component's own
|
|
2
|
-
colour. See docs/internal/
|
|
2
|
+
colour. See docs/internal/model.md#cyber for the decision.
|
|
3
3
|
|
|
4
4
|
Tier 1 only. The bevel is `corner-shape`, not `clip-path`: a clip removes
|
|
5
5
|
every outer shadow, so a clipped chamfer has nothing left to glow, and an
|
|
6
6
|
inset ring cannot follow a diagonal cut the way `.pixel`'s follows its square
|
|
7
7
|
one. `corner-shape` draws the corner itself, and the border, the glow, and the
|
|
8
8
|
focus outline all follow it. Load after the base stylesheet. */
|
|
9
|
-
.cyber {
|
|
10
|
-
/* Knobs, read with a fallback so an ancestor can set them (R8; see
|
|
11
|
-
model.md#rules-for-aesthetics). One cut size for controls and surfaces
|
|
12
|
-
alike, so a button and the card around it read as the same material; the
|
|
13
|
-
two shapes then place that cut on opposite diagonals, so they read as
|
|
14
|
-
different things. A shape knob takes any `border-radius` value -- the
|
|
15
|
-
documented presets are a hexagon, a parallelogram, and a single notch --
|
|
16
|
-
and the cut knob scales the default pair without restating it.
|
|
17
|
-
|
|
18
|
-
The cut is a ceiling, not a size: the default pair caps it at a quarter of
|
|
19
|
-
the element's own box, so a 40px button or a card takes the full cut and a
|
|
20
|
-
19px icon button about 5px rather than having its corners eaten. Nothing in
|
|
21
|
-
the model scales a corner with a component's size -- `.sm` and `.dense`
|
|
22
|
-
change padding and height, never the radius -- and a radius percentage is
|
|
23
|
-
the one length that already knows the box. Horizontal percentages resolve
|
|
24
|
-
against the width and vertical ones against the height, so on a small wide
|
|
25
|
-
button the cut runs slightly shallower than 45 degrees; at those sizes that
|
|
26
|
-
is not visible. A shape set through the knob is taken as written. */
|
|
27
|
-
--_cyber-cut: var(--cyber-cut, 0.625rem);
|
|
28
|
-
--_cyber-glow: var(--cyber-glow, 8px);
|
|
29
|
-
--_cyber-shape: var(--cyber-shape, min(var(--_cyber-cut), 25%) 0 / min(var(--_cyber-cut), 25%) 0);
|
|
30
|
-
--_cyber-shape-surface: var(--cyber-shape-surface, 0 min(var(--_cyber-cut), 25%) / 0 min(var(--_cyber-cut), 25%));
|
|
31
|
-
|
|
32
|
-
/* The neutral line. A neon hue is the look's signature, but hue is intent's
|
|
33
|
-
(R1), so the default follows the theme the way neobrutalism's and pixel's
|
|
34
|
-
ink does, and `--cyber-ink` lets an application choose a neon neutral
|
|
35
|
-
without the aesthetic imposing one on every palette. A named intent keeps
|
|
36
|
-
its own edge colour. */
|
|
37
|
-
--ui-ink: var(--cyber-ink, light-dark(var(--color-neutral-950), var(--color-neutral-50)));
|
|
38
|
-
|
|
39
|
-
/* Controls cut top-left and bottom-right, surfaces top-right and bottom-left.
|
|
40
|
-
Anything fully round -- a badge, a switch, the progress track, the tooltip
|
|
41
|
-
icon, and through their own full radius a radio and a `.btn.pill` -- cuts
|
|
42
|
-
all the way to points: a diamond, or a hexagon on something wider than it
|
|
43
|
-
is tall. Chips square outright, which is what tells the checkbox from the
|
|
44
|
-
radio beside it. */
|
|
45
|
-
--ui-corner-shape: bevel;
|
|
46
|
-
--ui-radius: var(--_cyber-shape);
|
|
47
|
-
--ui-radius-surface: var(--_cyber-shape-surface);
|
|
48
|
-
--ui-radius-pill: calc(infinity * 1px);
|
|
49
|
-
--ui-radius-tight: 0;
|
|
50
|
-
--ui-border-width: 1px;
|
|
51
|
-
--ui-border-max: 100px;
|
|
52
|
-
|
|
53
|
-
/* The glow: the component's own ink, blurred, with no offset. `box` mixes
|
|
54
|
-
depth as `color-mix(in oklab, var(--intent-border) var(--ui-shadow-ink),
|
|
55
|
-
var(--elevation-color))`, so a transparent depth colour turns 40% ink into
|
|
56
|
-
the intent colour at 40% alpha rather than into a darker shade of it.
|
|
57
|
-
Elevation scales the blur like every shadow, so the glow lights what rests
|
|
58
|
-
above zero -- buttons and cards -- and anything raised, and leaves fields
|
|
59
|
-
and chips crisp. */
|
|
60
|
-
--elevation-color: transparent;
|
|
61
|
-
--ui-shadow-ink: 40%;
|
|
62
|
-
--ui-shadow-x: 0px;
|
|
63
|
-
--ui-shadow-y: 0px;
|
|
64
|
-
--ui-shadow-blur: var(--_cyber-glow);
|
|
65
|
-
--ui-shadow-spread: 0px;
|
|
66
|
-
|
|
67
|
-
/* The glow holds still under the pointer and under a press; the press is the
|
|
68
|
-
base scale, restated because a region nested inside another aesthetic must
|
|
69
|
-
not inherit that one's travel. Reduced motion drops it below. */
|
|
70
|
-
--ui-hover-transform: none;
|
|
71
|
-
--ui-active-shadow-x: 0px;
|
|
72
|
-
--ui-active-shadow-y: 0px;
|
|
73
|
-
--ui-active-transform: scale(0.97);
|
|
74
|
-
|
|
75
|
-
/* Nothing here clips, blurs, thins its fill, or draws its edge as a ring, and
|
|
76
|
-
an aesthetic nested inside one that does has to say so rather than inherit
|
|
77
|
-
it. */
|
|
78
|
-
--ui-clip: none;
|
|
79
|
-
--ui-clip-tight: none;
|
|
80
|
-
--ui-shadow-inset: ;
|
|
81
|
-
--ui-shadow-edge: initial;
|
|
82
|
-
--ui-backdrop: none;
|
|
83
|
-
--ui-bg-alpha: 1;
|
|
84
|
-
|
|
85
|
-
/* Consumer-supplied, the way `.pixel` reads `--font-pixel`. The package ships
|
|
86
|
-
no font binary; the monospace stack is the closest technical face every
|
|
87
|
-
platform already has. */
|
|
88
|
-
font-family: var(--font-cyber, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
|
|
89
|
-
}
|
|
90
9
|
|
|
91
|
-
/*
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
@
|
|
10
|
+
/* The layer map, stated before anything uses a layer -- see `theme.css`. The
|
|
11
|
+
aesthetic's token class sits in `components`, below every utility, so a
|
|
12
|
+
consumer's own utility or unlayered CSS beats it; the solo class stays
|
|
13
|
+
unlayered, because it has to beat a foreign component's unlayered CSS. See
|
|
14
|
+
docs/internal/model.md#cascade-layers. */
|
|
15
|
+
@layer theme, base, components, utilities;
|
|
16
|
+
|
|
17
|
+
@layer components {
|
|
97
18
|
.cyber {
|
|
98
|
-
|
|
99
|
-
|
|
19
|
+
/* Knobs, read with a fallback so an ancestor can set them (R8; see
|
|
20
|
+
model.md#rules-for-aesthetics). One cut size for controls and surfaces
|
|
21
|
+
alike, so a button and the card around it read as the same material; the
|
|
22
|
+
two shapes then place that cut on opposite diagonals, so they read as
|
|
23
|
+
different things. A shape knob takes any `border-radius` value -- the
|
|
24
|
+
documented presets are a hexagon, a parallelogram, and a single notch --
|
|
25
|
+
and the cut knob sizes the default pair without restating it.
|
|
26
|
+
|
|
27
|
+
The cut is the corner length at scale 1, and `box` multiplies it by the
|
|
28
|
+
size step, so a `.p-xs` icon button takes half the cut and a `.lg` button
|
|
29
|
+
a quarter more -- always a true 45 degrees, because it stays a length. It
|
|
30
|
+
used to be capped at a quarter of the element's box, a percentage, which
|
|
31
|
+
ran shallower than 45 degrees on a small wide button; the step retired
|
|
32
|
+
the cap. A shape set through a knob is taken as written, unscaled: it is
|
|
33
|
+
read as `--ui-radius`, which `box` honours over the computed corner, and
|
|
34
|
+
left unset the reference makes the token guaranteed-invalid so the
|
|
35
|
+
computed corner draws. */
|
|
36
|
+
--_cyber-cut: var(--cyber-cut, 0.625rem);
|
|
37
|
+
--_cyber-glow: var(--cyber-glow, 8px);
|
|
38
|
+
|
|
39
|
+
/* The neutral line. A neon hue is the look's signature, but hue is intent's
|
|
40
|
+
(R1), so the default follows the theme the way neobrutalism's and pixel's
|
|
41
|
+
ink does, and `--cyber-ink` lets an application choose a neon neutral
|
|
42
|
+
without the aesthetic imposing one on every palette. A named intent keeps
|
|
43
|
+
its own edge colour. */
|
|
44
|
+
--ui-ink: var(--cyber-ink, light-dark(var(--color-neutral-950), var(--color-neutral-50)));
|
|
45
|
+
|
|
46
|
+
/* Controls cut top-left and bottom-right, through the four corner switches
|
|
47
|
+
every component reads; surfaces cut top-right and bottom-left, which the
|
|
48
|
+
switches cannot say at the same time, so their shape is written whole and
|
|
49
|
+
does not scale -- a card is large enough that the full cut is right at
|
|
50
|
+
every padding. Anything fully round -- a badge, a switch, the progress
|
|
51
|
+
track, the tooltip icon, and through their own full radius a radio and a
|
|
52
|
+
`.btn.pill` -- cuts all the way to points: a diamond, or a hexagon on
|
|
53
|
+
something wider than it is tall. Chips square outright, which is what
|
|
54
|
+
tells the checkbox from the radio beside it. */
|
|
55
|
+
--ui-corner-shape: bevel;
|
|
56
|
+
--ui-corner: var(--_cyber-cut);
|
|
57
|
+
--ui-corner-surface: var(--_cyber-cut);
|
|
58
|
+
--ui-corner-tl: 1;
|
|
59
|
+
--ui-corner-tr: 0;
|
|
60
|
+
--ui-corner-br: 1;
|
|
61
|
+
--ui-corner-bl: 0;
|
|
62
|
+
--ui-radius: var(--cyber-shape);
|
|
63
|
+
--ui-radius-surface: var(--cyber-shape-surface, 0 var(--_cyber-cut) / 0 var(--_cyber-cut));
|
|
64
|
+
--ui-radius-pill: calc(infinity * 1px);
|
|
65
|
+
--ui-radius-tight: 0;
|
|
66
|
+
--ui-border-width: 1px;
|
|
67
|
+
--ui-border-max: 100px;
|
|
68
|
+
--ui-line-style: initial;
|
|
69
|
+
--ui-rule-style: initial;
|
|
70
|
+
|
|
71
|
+
/* The glow is light, not depth, so it is the halo: the component's own intent
|
|
72
|
+
colour at 40%, blurred, with no offset. Elevation does not scale it, so
|
|
73
|
+
every component glows -- fields and chips included -- and `.flat` does
|
|
74
|
+
not put it out. There is no depth, and the transparent depth colour keeps
|
|
75
|
+
`.raised` and `.floating` from drawing any. */
|
|
76
|
+
--elevation-color: transparent;
|
|
77
|
+
--ui-shadow-ink: 0%;
|
|
78
|
+
--ui-shadow-x: 0px;
|
|
79
|
+
--ui-shadow-y: 0px;
|
|
80
|
+
--ui-shadow-blur: 0px;
|
|
81
|
+
--ui-shadow-spread: 0px;
|
|
82
|
+
--ui-halo-blur: var(--_cyber-glow);
|
|
83
|
+
--ui-halo-spread: 0px;
|
|
84
|
+
--ui-halo-ink: 40%;
|
|
85
|
+
|
|
86
|
+
/* The glow holds still under the pointer and under a press; the press is the
|
|
87
|
+
base scale, restated because a region nested inside another aesthetic must
|
|
88
|
+
not inherit that one's travel. Reduced motion drops it below. */
|
|
89
|
+
--ui-hover-transform: none;
|
|
90
|
+
--ui-active-shadow-x: 0px;
|
|
91
|
+
--ui-active-shadow-y: 0px;
|
|
92
|
+
--ui-active-transform: scale(0.97);
|
|
93
|
+
--ui-active-translate-x: initial;
|
|
94
|
+
--ui-active-translate-y: initial;
|
|
95
|
+
|
|
96
|
+
/* Nothing here clips, blurs, thins its fill, or draws its edge as a ring, and
|
|
97
|
+
an aesthetic nested inside one that does has to say so rather than inherit
|
|
98
|
+
it. */
|
|
99
|
+
--ui-clip: none;
|
|
100
|
+
--ui-clip-tight: none;
|
|
101
|
+
--ui-shadow-inset: ;
|
|
102
|
+
--ui-shadow-edge: initial;
|
|
103
|
+
--ui-backdrop: none;
|
|
104
|
+
--ui-surface-ground: initial;
|
|
105
|
+
--ui-surface-shadow: initial;
|
|
106
|
+
--ui-surface-image: initial;
|
|
107
|
+
--ui-bg-alpha: 1;
|
|
108
|
+
|
|
109
|
+
/* Consumer-supplied, the way `.pixel` reads `--font-pixel`. The package ships
|
|
110
|
+
no font binary; the monospace stack is the closest technical face every
|
|
111
|
+
platform already has. */
|
|
112
|
+
font-family: var(--font-cyber, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
|
|
113
|
+
|
|
114
|
+
/* The control ink glass and chunky tile name, cleared so a region nested
|
|
115
|
+
inside either draws its controls in this aesthetic's own ink. */
|
|
116
|
+
--ui-control-ink: initial;
|
|
117
|
+
|
|
118
|
+
/* Chunky tile's heavier label, cleared so a region nested inside it keeps
|
|
119
|
+
the button's and the badge's own label. */
|
|
120
|
+
--ui-label-weight: initial;
|
|
121
|
+
--ui-label-tracking: initial;
|
|
122
|
+
--ui-label-case: initial;
|
|
123
|
+
--ui-label-shadow: initial;
|
|
100
124
|
}
|
|
101
|
-
}
|
|
102
125
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
126
|
+
/* Firefox and Safari do not draw `corner-shape` yet, and there the radius would
|
|
127
|
+
round the corners instead. A rounded cyber element reads as a different
|
|
128
|
+
aesthetic; a square one reads as the same aesthetic simplified. What is fully
|
|
129
|
+
round stays round rather than square: a square radio is a checkbox, and a
|
|
130
|
+
pill is the nearest a diamond gets without a bevel. */
|
|
131
|
+
@supports not (corner-shape: bevel) {
|
|
132
|
+
.cyber {
|
|
133
|
+
--ui-corner: 0;
|
|
134
|
+
--ui-radius: 0;
|
|
135
|
+
--ui-radius-surface: 0;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
@media (prefers-reduced-motion: reduce) {
|
|
140
|
+
.cyber {
|
|
141
|
+
--ui-active-transform: none;
|
|
142
|
+
}
|
|
106
143
|
}
|
|
107
144
|
}
|
|
108
145
|
|
|
109
146
|
/* Solo: the same look painted onto the one element carrying the class, for an
|
|
110
|
-
element the package does not style. See docs/internal/solo-
|
|
147
|
+
element the package does not style. See docs/internal/model.md#solo-classes and
|
|
111
148
|
the note on `.glass-solo`: own knobs and foundation tokens with literal
|
|
112
149
|
fallbacks, never a shared `--ui-*`, `--intent-*`, or `--elevation-color`
|
|
113
150
|
token, unlayered, and not for this package's own components. */
|
|
@@ -7,74 +7,115 @@
|
|
|
7
7
|
panels, alerts and tooltips while controls stay solid. An active blur costs a
|
|
8
8
|
compositing layer apiece, and one under every control of a dense cluster reads
|
|
9
9
|
as noise. */
|
|
10
|
-
.glass {
|
|
11
|
-
/* Knobs read with a fallback so an ancestor can set them -- declared here they
|
|
12
|
-
outrank `:root` (R8; see model.md#rules-for-aesthetics). Glass is softer
|
|
13
|
-
than the base geometry because a translucent tight corner reads as a
|
|
14
|
-
cut-out; a control/surface pair rather than one value, because they do not
|
|
15
|
-
scale together and 12/16 keeps a button looking at home inside a card. */
|
|
16
|
-
--ui-radius: var(--glass-radius, 0.75rem);
|
|
17
|
-
--ui-radius-surface: var(--glass-radius-surface, 1rem);
|
|
18
|
-
--ui-border-width: 1px;
|
|
19
|
-
--ui-border-max: 100px;
|
|
20
10
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
11
|
+
/* The layer map, stated before anything uses a layer -- see `theme.css`. The
|
|
12
|
+
aesthetic's token class sits in `components`, below every utility, so a
|
|
13
|
+
consumer's own utility or unlayered CSS beats it; the solo class stays
|
|
14
|
+
unlayered, because it has to beat a foreign component's unlayered CSS. See
|
|
15
|
+
docs/internal/model.md#cascade-layers. */
|
|
16
|
+
@layer theme, base, components, utilities;
|
|
24
17
|
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
@layer components {
|
|
19
|
+
.glass {
|
|
20
|
+
/* Knobs read with a fallback so an ancestor can set them -- declared here they
|
|
21
|
+
outrank `:root` (R8; see model.md#rules-for-aesthetics). Glass is softer
|
|
22
|
+
than the base geometry because a translucent tight corner reads as a
|
|
23
|
+
cut-out; a control/surface pair rather than one value, because they do not
|
|
24
|
+
scale together and 12/16 keeps a button looking at home inside a card. */
|
|
25
|
+
--ui-corner: var(--glass-radius, 0.75rem);
|
|
26
|
+
--ui-corner-surface: var(--glass-radius-surface, 1rem);
|
|
27
|
+
--ui-border-width: 1px;
|
|
28
|
+
--ui-border-max: 100px;
|
|
29
|
+
--ui-line-style: initial;
|
|
30
|
+
--ui-rule-style: initial;
|
|
27
31
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
and nothing shows through. */
|
|
40
|
-
--ui-surface-ground: color-mix(in srgb, var(--color-background) 45%, transparent);
|
|
32
|
+
/* Glass catches light from above whatever is under it, so the edge is a light
|
|
33
|
+
hairline in both themes rather than a theme-following ink. */
|
|
34
|
+
--ui-ink: light-dark(rgb(255 255 255 / 0.65), rgb(255 255 255 / 0.22));
|
|
35
|
+
/* A control's boundary is not a pane's edge. The hairline erases an
|
|
36
|
+
unchecked checkbox on a light page (1.33:1 inside a glass card) and leaves
|
|
37
|
+
a field with nothing marking where typing goes, so controls take the
|
|
38
|
+
theme's ink at 55% instead: translucent, so it tints whatever is behind
|
|
39
|
+
the pane rather than drawing a flat grey, and 6.31:1 on a checkbox, 2.31:1
|
|
40
|
+
on a field's 60% resting line, in light. See
|
|
41
|
+
docs/internal/model.md#presentation. */
|
|
42
|
+
--ui-control-ink: light-dark(rgb(0 0 0 / 0.55), rgb(255 255 255 / 0.55));
|
|
41
43
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
complete-value slot -- which is also what keeps it off buttons and chips --
|
|
46
|
-
and the registry records that `.flat` does not reach it. */
|
|
47
|
-
--ui-surface-shadow: 0 1px 2px -1px var(--elevation-color), 0 18px 40px -16px var(--elevation-color);
|
|
44
|
+
--ui-bg-alpha: 0.8;
|
|
45
|
+
--ui-backdrop: blur(14px) saturate(1.6);
|
|
46
|
+
--ui-surface-image: initial;
|
|
48
47
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
48
|
+
/* R6. Controls carry no shadow of their own -- the depth in this aesthetic is
|
|
49
|
+
the blur, and a drop shadow under a translucent button reads as grime. All
|
|
50
|
+
general parts are explicitly zero so inherited or future geometry cannot
|
|
51
|
+
leak onto controls. `--ui-surface-shadow` below replaces the shadow of
|
|
52
|
+
surfaces only. */
|
|
53
|
+
--ui-shadow-x: 0px;
|
|
54
|
+
--ui-shadow-y: 0px;
|
|
55
|
+
--ui-shadow-blur: 0px;
|
|
56
|
+
--ui-shadow-spread: 0px;
|
|
57
|
+
/* No halo, cleared so a region nested inside another
|
|
58
|
+
aesthetic does not inherit one. */
|
|
59
|
+
--ui-halo-blur: initial;
|
|
60
|
+
--ui-halo-spread: initial;
|
|
61
|
+
--ui-halo-ink: initial;
|
|
62
|
+
/* `--ui-bg-alpha` multiplies the fill, and a surface's default fill is 0%:
|
|
63
|
+
without a translucent ground the blur ends up behind an opaque background
|
|
64
|
+
and nothing shows through. */
|
|
65
|
+
--ui-surface-ground: color-mix(in srgb, var(--color-background) 45%, transparent);
|
|
63
66
|
|
|
64
|
-
/*
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
--ui-
|
|
70
|
-
|
|
67
|
+
/* Two layers pulling in with negative spread, so the shadow tucks under the
|
|
68
|
+
surface instead of haloing onto the backdrop. It is the one shipped aesthetic
|
|
69
|
+
that cannot be described with the parts, so it takes `surface`'s
|
|
70
|
+
complete-value slot -- which is also what keeps it off buttons and chips --
|
|
71
|
+
and the registry records that `.flat` does not reach it. */
|
|
72
|
+
--ui-surface-shadow: 0 1px 2px -1px var(--elevation-color), 0 18px 40px -16px var(--elevation-color);
|
|
73
|
+
|
|
74
|
+
--ui-clip: none;
|
|
75
|
+
--ui-clip-tight: none;
|
|
76
|
+
/* Round corners, said explicitly, and the pill and chip corners cleared back
|
|
77
|
+
to `--ui-corner`: a region nested inside `.cyber` would otherwise inherit
|
|
78
|
+
its bevel, its diagonal, its diamond pills, and its square chips. */
|
|
79
|
+
--ui-corner-shape: round;
|
|
80
|
+
--ui-radius-pill: initial;
|
|
81
|
+
--ui-radius-tight: initial;
|
|
82
|
+
--ui-radius: initial;
|
|
83
|
+
--ui-radius-surface: initial;
|
|
84
|
+
--ui-corner-tl: initial;
|
|
85
|
+
--ui-corner-tr: initial;
|
|
86
|
+
--ui-corner-br: initial;
|
|
87
|
+
--ui-corner-bl: initial;
|
|
88
|
+
/* Nothing here draws its edge as a ring, and an aesthetic nested inside pixel
|
|
89
|
+
has to say so rather than inherit it. */
|
|
90
|
+
--ui-shadow-edge: initial;
|
|
91
|
+
--ui-hover-transform: none;
|
|
92
|
+
--ui-active-transform: none;
|
|
93
|
+
--ui-active-translate-x: initial;
|
|
94
|
+
--ui-active-translate-y: initial;
|
|
95
|
+
|
|
96
|
+
/* Chunky tile's heavier label, cleared so a region nested inside it keeps
|
|
97
|
+
the button's and the badge's own label. */
|
|
98
|
+
--ui-label-weight: initial;
|
|
99
|
+
--ui-label-tracking: initial;
|
|
100
|
+
--ui-label-case: initial;
|
|
101
|
+
--ui-label-shadow: initial;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/* Transparency is the whole aesthetic, so the honest degradation is an opaque
|
|
105
|
+
surface rather than a softer blur. */
|
|
106
|
+
@media (prefers-reduced-transparency: reduce) {
|
|
107
|
+
.glass {
|
|
108
|
+
--ui-bg-alpha: 1;
|
|
109
|
+
--ui-backdrop: none;
|
|
110
|
+
--ui-surface-ground: var(--color-background);
|
|
111
|
+
}
|
|
71
112
|
}
|
|
72
113
|
}
|
|
73
114
|
|
|
74
115
|
/* Solo: the same look painted onto the one element carrying the class, for an
|
|
75
116
|
element the package does not style -- a toast from another library, a plain
|
|
76
117
|
`<div>` on a page that never loaded the base stylesheet. See
|
|
77
|
-
docs/internal/solo-
|
|
118
|
+
docs/internal/model.md#solo-classes.
|
|
78
119
|
|
|
79
120
|
It reads the aesthetic's own knobs and the theme's foundation tokens, each
|
|
80
121
|
with its shipped literal as the fallback, and never a `--ui-*`, `--intent-*`,
|
|
@@ -3,59 +3,100 @@
|
|
|
3
3
|
named -- the ink reaches everything through the intent reset, the shadow is
|
|
4
4
|
colourless geometry each component colours against its own intent. Load after
|
|
5
5
|
the base stylesheet; source order decides against the zero-specificity reset. */
|
|
6
|
-
.neobrutalism {
|
|
7
|
-
/* Read with a fallback, not declared, so an ancestor (`:root`, where an app
|
|
8
|
-
themes) can set `--neo-offset`; the private carries the resolved value to
|
|
9
|
-
the six places below. See model.md#rules-for-aesthetics (R8). */
|
|
10
|
-
--_neo-offset: var(--neo-offset, 4px);
|
|
11
6
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
7
|
+
/* The layer map, stated before anything uses a layer -- see `theme.css`. The
|
|
8
|
+
aesthetic's token class sits in `components`, below every utility, so a
|
|
9
|
+
consumer's own utility or unlayered CSS beats it; the solo class stays
|
|
10
|
+
unlayered, because it has to beat a foreign component's unlayered CSS. See
|
|
11
|
+
docs/internal/model.md#cascade-layers. */
|
|
12
|
+
@layer theme, base, components, utilities;
|
|
13
|
+
|
|
14
|
+
@layer components {
|
|
15
|
+
.neobrutalism {
|
|
16
|
+
/* Read with a fallback, not declared, so an ancestor (`:root`, where an app
|
|
17
|
+
themes) can set `--neo-offset`; the private carries the resolved value to
|
|
18
|
+
the six places below. See model.md#rules-for-aesthetics (R8). */
|
|
19
|
+
--_neo-offset: var(--neo-offset, 4px);
|
|
20
|
+
|
|
21
|
+
/* Pure black reads as ink on a light page and disappears on a dark one, so the
|
|
22
|
+
ink follows the theme rather than the palette. A thick border in the neutral
|
|
23
|
+
border grey is a thick grey box, not a brutalist one. */
|
|
24
|
+
--ui-ink: light-dark(var(--color-neutral-950), var(--color-neutral-50));
|
|
25
|
+
|
|
26
|
+
--ui-corner: 0;
|
|
27
|
+
--ui-corner-surface: 0;
|
|
28
|
+
--ui-border-width: 2px;
|
|
29
|
+
--ui-border-max: 100px;
|
|
30
|
+
--ui-line-style: initial;
|
|
31
|
+
--ui-rule-style: initial;
|
|
16
32
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
33
|
+
/* Hard, unblurred, and offset. Scaled by each component's own elevation, so
|
|
34
|
+
the registry decides which components sit on a slab and `.flat` takes one
|
|
35
|
+
off without this file knowing which component it landed on. */
|
|
36
|
+
/* The slab is ink, not shade: a hard offset of the element's own line colour
|
|
37
|
+
is the whole look, so this aesthetic asks for the intent instead of the
|
|
38
|
+
neutral depth colour every other shadow uses. */
|
|
39
|
+
--ui-shadow-ink: 100%;
|
|
40
|
+
--ui-shadow-x: var(--_neo-offset);
|
|
41
|
+
--ui-shadow-y: var(--_neo-offset);
|
|
42
|
+
--ui-shadow-blur: 0px;
|
|
43
|
+
--ui-shadow-spread: 0px;
|
|
44
|
+
/* No halo, cleared so a region nested inside another
|
|
45
|
+
aesthetic does not inherit one. */
|
|
46
|
+
--ui-halo-blur: initial;
|
|
47
|
+
--ui-halo-spread: initial;
|
|
48
|
+
--ui-halo-ink: initial;
|
|
21
49
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
--ui-shadow-spread: 0px;
|
|
50
|
+
/* The press: travel the offset, shrink the shadow to nothing, so the element
|
|
51
|
+
lands flat where its slab was. A translation `box` scales with the slab, so
|
|
52
|
+
the two stay the same length at every size and elevation. Hover keeps the slab still under the pointer;
|
|
53
|
+
`box-hover`'s derived fill tint is the whole hover response. One token pair,
|
|
54
|
+
no `:hover` list, R3 intact. */
|
|
55
|
+
--ui-active-shadow-x: 0px;
|
|
56
|
+
--ui-active-shadow-y: 0px;
|
|
57
|
+
--ui-active-transform: none;
|
|
58
|
+
--ui-active-translate-x: var(--_neo-offset);
|
|
59
|
+
--ui-active-translate-y: var(--_neo-offset);
|
|
33
60
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
61
|
+
/* Nothing here clips or blurs, and an aesthetic nested inside another has to
|
|
62
|
+
say so rather than inherit it. */
|
|
63
|
+
--ui-clip: none;
|
|
64
|
+
--ui-clip-tight: none;
|
|
65
|
+
/* Round corners, said explicitly, and the pill and chip corners cleared back
|
|
66
|
+
to `--ui-corner`: a region nested inside `.cyber` would otherwise inherit
|
|
67
|
+
its bevel, its diagonal, its diamond pills, and its square chips. */
|
|
68
|
+
--ui-corner-shape: round;
|
|
69
|
+
--ui-radius-pill: initial;
|
|
70
|
+
--ui-radius-tight: initial;
|
|
71
|
+
--ui-radius: initial;
|
|
72
|
+
--ui-radius-surface: initial;
|
|
73
|
+
--ui-corner-tl: initial;
|
|
74
|
+
--ui-corner-tr: initial;
|
|
75
|
+
--ui-corner-br: initial;
|
|
76
|
+
--ui-corner-bl: initial;
|
|
77
|
+
--ui-shadow-inset: ;
|
|
78
|
+
/* The slab is depth cast in ink, not this element's line, so an `.edgeless`
|
|
79
|
+
button keeps it. Cleared rather than omitted, because a neobrutalist region
|
|
80
|
+
nested inside a pixel one would otherwise inherit pixel's answer and lose the
|
|
81
|
+
slab on everything the edge axis rests at zero. */
|
|
82
|
+
--ui-shadow-edge: initial;
|
|
83
|
+
--ui-backdrop: none;
|
|
84
|
+
--ui-surface-ground: initial;
|
|
85
|
+
--ui-surface-shadow: initial;
|
|
86
|
+
--ui-bg-alpha: 1;
|
|
87
|
+
--ui-surface-image: initial;
|
|
41
88
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
/* The slab is depth cast in ink, not this element's line, so an `.edgeless`
|
|
54
|
-
button keeps it. Cleared rather than omitted, because a neobrutalist region
|
|
55
|
-
nested inside a pixel one would otherwise inherit pixel's answer and lose the
|
|
56
|
-
slab on everything the edge axis rests at zero. */
|
|
57
|
-
--ui-shadow-edge: initial;
|
|
58
|
-
--ui-backdrop: none;
|
|
89
|
+
/* The control ink glass and chunky tile name, cleared so a region nested
|
|
90
|
+
inside either draws its controls in this aesthetic's own ink. */
|
|
91
|
+
--ui-control-ink: initial;
|
|
92
|
+
|
|
93
|
+
/* Chunky tile's heavier label, cleared so a region nested inside it keeps
|
|
94
|
+
the button's and the badge's own label. */
|
|
95
|
+
--ui-label-weight: initial;
|
|
96
|
+
--ui-label-tracking: initial;
|
|
97
|
+
--ui-label-case: initial;
|
|
98
|
+
--ui-label-shadow: initial;
|
|
99
|
+
}
|
|
59
100
|
}
|
|
60
101
|
|
|
61
102
|
/* The one R3 exception, recorded in the registry as `selectors`. The slab here
|
|
@@ -63,13 +104,19 @@
|
|
|
63
104
|
registry rests flat -- looks unfinished without it. It writes the component's
|
|
64
105
|
resting default rather than the modifier, so `.flat`/`.raised`/`.floating`
|
|
65
106
|
still win on the element; a token would name the component through a longer
|
|
66
|
-
route. `--_d-elevation` inheriting is inert -- it equals `box`'s own fallback.
|
|
67
|
-
|
|
68
|
-
|
|
107
|
+
route. `--_d-elevation` inheriting is inert -- it equals `box`'s own fallback.
|
|
108
|
+
|
|
109
|
+
In `utilities`, not with the token class: it has to beat `@utility alert`'s
|
|
110
|
+
own `--_d-elevation: 0`, which it does there at 0-2-0, and it writes only a
|
|
111
|
+
private nothing a consumer sets. */
|
|
112
|
+
@layer utilities {
|
|
113
|
+
.neobrutalism .alert {
|
|
114
|
+
--_d-elevation: 1;
|
|
115
|
+
}
|
|
69
116
|
}
|
|
70
117
|
|
|
71
118
|
/* Solo: the same look painted onto the one element carrying the class, for an
|
|
72
|
-
element the package does not style. See docs/internal/solo-
|
|
119
|
+
element the package does not style. See docs/internal/model.md#solo-classes and
|
|
73
120
|
the note on `.glass-solo`: own knobs and foundation tokens with literal
|
|
74
121
|
fallbacks, never a shared `--ui-*`, `--intent-*`, or `--elevation-color`
|
|
75
122
|
token, unlayered, and not for this package's own components. */
|