@codenhub/styles 0.1.0 → 0.1.1

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.
Files changed (45) hide show
  1. package/README.md +7 -69
  2. package/dist/aesthetics/chunky-tile.css +1 -1
  3. package/dist/aesthetics/index.css +1 -1
  4. package/dist/components.css +1 -1
  5. package/dist/index.css +1 -1
  6. package/dist/native.css +1 -1
  7. package/dist/theme.css +1 -1
  8. package/dist/tw/aesthetics/chunky-tile.css +4 -2
  9. package/dist/tw/box.css +21 -0
  10. package/dist/tw/components/button.css +23 -3
  11. package/dist/tw/components/form.css +0 -2
  12. package/dist/tw/components/index.css +16 -6
  13. package/dist/tw/components/surface.css +29 -5
  14. package/dist/tw/elevation.css +14 -7
  15. package/dist/tw/index.css +20 -5
  16. package/dist/tw/intent.css +20 -0
  17. package/dist/tw/native.css +4 -20
  18. package/dist/tw/reset.css +20 -33
  19. package/dist/tw/theme.css +12 -7
  20. package/dist/tw/utilities/content.css +14 -2
  21. package/docs/accessibility.md +58 -48
  22. package/docs/changelog/0.1.0.md +37 -0
  23. package/docs/changelog/0.1.1.md +10 -0
  24. package/docs/changelog/index.md +10 -0
  25. package/docs/concepts.md +20 -46
  26. package/docs/index.md +18 -45
  27. package/docs/integrating/astro.md +13 -7
  28. package/docs/integrating/index.md +25 -16
  29. package/docs/integrating/nextjs.md +31 -8
  30. package/docs/integrating/svelte.md +14 -8
  31. package/docs/integrating/tailwind.md +31 -15
  32. package/docs/integrating/vue.md +13 -7
  33. package/docs/setup.md +35 -55
  34. package/docs/usage/aesthetics.md +30 -107
  35. package/docs/usage/buttons.md +19 -35
  36. package/docs/usage/composing.md +25 -100
  37. package/docs/usage/content-and-layout.md +56 -81
  38. package/docs/usage/customizing.md +25 -90
  39. package/docs/usage/feedback.md +11 -49
  40. package/docs/usage/forms.md +16 -58
  41. package/docs/usage/index.md +9 -17
  42. package/docs/usage/theming.md +25 -81
  43. package/docs/usage/tooltips.md +15 -21
  44. package/llms-full.txt +1060 -1506
  45. package/package.json +121 -44
@@ -1,15 +1,18 @@
1
1
  ---
2
2
  title: Tailwind CSS v4
3
3
  description: Using the /tw source entrypoints in a Tailwind CSS v4 project.
4
+ order: 1
4
5
  ---
5
6
 
6
7
  # Tailwind CSS v4
7
8
 
8
- A project that already runs Tailwind CSS v4 can process this package's
9
- source instead of its compiled output. `/tw` entrypoints publish copied,
10
- uncompiled source from `dist/tw`; your own Tailwind build compiles it
11
- alongside your app, so its `@theme`, `@utility`, and `@apply` directives
12
- resolve together with yours.
9
+ A project that already runs Tailwind CSS v4 can process this package's source instead of its compiled output, so both sets of classes compile through the same Tailwind build.
10
+
11
+ ## Why source instead of compiled
12
+
13
+ `/tw` entrypoints publish copied, uncompiled source from `dist/tw`; your own Tailwind build compiles it alongside your app, so its `@theme`, `@utility`, and `@apply` directives resolve together with yours. The compiled entrypoints (`@codenhub/styles`) still work in a Tailwind project, but then two separate CSS pipelines run side by side instead of one — use `/tw` unless a specific reason rules it out.
14
+
15
+ ## Import the source entrypoint
13
16
 
14
17
  ```css
15
18
  @import "tailwindcss";
@@ -18,13 +21,11 @@ resolve together with yours.
18
21
  @source "./src";
19
22
  ```
20
23
 
21
- `@source` tells Tailwind's build where to scan for the utility and component
22
- class names actually used in your markup, so it can generate only what is
23
- referenced. Point it at your app's source, not at this package — `/tw`
24
- already ships every class definition it publishes.
24
+ Tailwind CSS v4 scans your project automatically — most projects need nothing beyond the two imports above. `@source` paths resolve relative to the CSS file that declares them, not your project root, so `./src` here means "the `src/` next to this stylesheet"; adjust it to match where your own global stylesheet actually lives. Add `@source` only for markup Tailwind's automatic scan won't reach on its own: a path excluded by default (`.gitignore`d, or inside `node_modules` — an external component library, for instance) or, in a monorepo, one outside this file's own directory tree. Point it at your app's markup, not at this package — `/tw` already ships every class definition it publishes, so scanning it too only slows the build without adding classes.
25
25
 
26
- Add aesthetics from the source entrypoint the same way as the compiled one,
27
- after the base import:
26
+ ## Add aesthetics
27
+
28
+ Add an aesthetic from the source entrypoint the same way as the compiled one, after the base import:
28
29
 
29
30
  ```css
30
31
  @import "tailwindcss";
@@ -34,7 +35,22 @@ after the base import:
34
35
  @source "./src";
35
36
  ```
36
37
 
37
- Import a focused `/tw/*` entrypoint instead of the combined one — such as
38
- `/tw/button` or `/tw/form` — when a build only needs one component family;
39
- see the full [import path table](../setup.md#import-paths) for what each one
40
- composes. Tailwind CSS 4 or newer is required for every `/tw` entrypoint.
38
+ ## Using a focused entrypoint
39
+
40
+ Import a focused `/tw/*` entrypoint instead of the combined one — such as `/tw/button` or `/tw/form` — when a build only needs one component family; see the full [import path table](../setup.md#import-paths) for what each one composes.
41
+
42
+ ## Troubleshooting
43
+
44
+ **Classes resolve to no styling**
45
+
46
+ - **What happened:** components use documented classes like `.btn.primary`, but no styling appears even though `@import "@codenhub/styles/tw"` is in the stylesheet.
47
+ - **Why:** this is rarely `@source` itself — Tailwind already scans your project automatically. The more common cause is markup living somewhere that automatic scan excludes by default: a `.gitignore`d path, or a component pulled from `node_modules`. Tailwind may not see a class used only there and skips generating a rule for it.
48
+ - **Fix:** add an explicit `@source` pointing at that directory, resolved relative to this stylesheet — matching the [example above](#import-the-source-entrypoint).
49
+
50
+ **Duplicate token and reset rules**
51
+
52
+ - **What happened:** the built stylesheet is larger than expected, and browser devtools show the same custom properties or reset rules defined twice.
53
+ - **Why:** importing both a compiled entrypoint (`@codenhub/styles`) and a `/tw` entrypoint (`@codenhub/styles/tw`) in the same build compiles the same tokens and reset from two independent sources; Tailwind's build has no way to know they describe the same package.
54
+ - **Fix:** pick one path per project — `/tw` entrypoints for a project running Tailwind CSS v4, compiled entrypoints everywhere else.
55
+
56
+ Tailwind CSS 4 or newer is required for every `/tw` entrypoint.
@@ -1,11 +1,14 @@
1
1
  ---
2
2
  title: Vue
3
3
  description: Loading the stylesheet in a Vue / Vite app.
4
+ order: 3
4
5
  ---
5
6
 
6
7
  # Vue
7
8
 
8
- Import the package once, from the app's entry file, before the app mounts:
9
+ Vue places no restriction on where CSS is imported from, but importing it once, from the app's entry file, keeps the reset and tokens from loading more than once and guarantees they're in place before any component renders.
10
+
11
+ ## Import the stylesheet
9
12
 
10
13
  ```ts
11
14
  // main.ts
@@ -16,10 +19,13 @@ import App from "./App.vue";
16
19
  createApp(App).mount("#app");
17
20
  ```
18
21
 
19
- Apply `.dark` or `.light` on the root element to force a theme instead of
20
- following the system preference; see
21
- [Setup → Configuration](../setup.md#configuration).
22
+ Running Tailwind CSS v4? Import `@codenhub/styles/tw` from a CSS entry file instead of `main.ts`, using the `@tailwindcss/vite` plugin — see [Tailwind CSS v4](./tailwind.md).
23
+
24
+ ## Force a theme
25
+
26
+ Apply `.dark` or `.light` on the root element to force a theme instead of following the system preference; see [Setup → Configuration](../setup.md#configuration).
27
+
28
+ ## See also
22
29
 
23
- A project running Tailwind CSS v4 imports `@codenhub/styles/tw` from a CSS
24
- entry file instead of `main.ts`, using the `@tailwindcss/vite` plugin; see
25
- [Tailwind CSS v4](./tailwind.md).
30
+ - [Setup → Import paths](../setup.md#import-paths): every entrypoint this package publishes.
31
+ - [Usage](../usage/index.md): component classes to compose once the stylesheet is loaded.
package/docs/setup.md CHANGED
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  title: Setup
3
3
  description: Install the package, pick an entrypoint, and render a first component.
4
+ order: 1
4
5
  ---
5
6
 
6
7
  # Setup
@@ -13,8 +14,7 @@ pnpm add @codenhub/styles
13
14
 
14
15
  ## Quick start
15
16
 
16
- Import the compiled stylesheet for the complete token, reset, utility, and
17
- component-class surface, then compose helper classes in markup:
17
+ Import the compiled stylesheet for the complete token, reset, utility, and component-class surface, then compose helper classes in markup:
18
18
 
19
19
  ```css
20
20
  @import "@codenhub/styles";
@@ -28,13 +28,9 @@ component-class surface, then compose helper classes in markup:
28
28
  </main>
29
29
  ```
30
30
 
31
- The full stylesheet applies global reset and focus-visible rules, but does not
32
- apply the optional classless native-element mappings, and does not include
33
- aesthetics. Import focused entrypoints when global rules are not appropriate;
34
- see [Import paths](#import-paths) below.
31
+ The full stylesheet applies global reset and focus-visible rules, but does not apply the optional classless native-element mappings, and does not include aesthetics. Import focused entrypoints when global rules are not appropriate; see [Import paths](#import-paths) below.
35
32
 
36
- Aesthetics are opt-in. Import the combined aesthetics stylesheet, or one
37
- aesthetic on its own, after the base stylesheet so its rules win:
33
+ Aesthetics are opt-in. Import the combined aesthetics stylesheet, or one aesthetic on its own, after the base stylesheet so its rules win:
38
34
 
39
35
  ```css
40
36
  @import "@codenhub/styles";
@@ -47,14 +43,11 @@ aesthetic on its own, after the base stylesheet so its rules win:
47
43
  </section>
48
44
  ```
49
45
 
50
- A project already running Tailwind CSS v4 imports the source entrypoint
51
- instead; see [Integrating → Tailwind CSS v4](./integrating/tailwind.md).
46
+ A project already running Tailwind CSS v4 imports the source entrypoint instead; see [Integrating → Tailwind CSS v4](./integrating/tailwind.md).
52
47
 
53
48
  ## Configuration
54
49
 
55
- The root follows the operating-system color-scheme preference. Apply `.light`
56
- or `.dark` to the root or any ancestor to force token values for that subtree.
57
- `.theme-light`, `.theme-dark`, and `data-theme="light|dark"` are aliases.
50
+ The root follows the operating-system color-scheme preference. Apply `.light` or `.dark` to the root or any ancestor to force token values for that subtree. `.theme-light`, `.theme-dark`, and `data-theme="light|dark"` are aliases.
58
51
 
59
52
  ```html
60
53
  <html class="dark">
@@ -64,53 +57,40 @@ or `.dark` to the root or any ancestor to force token values for that subtree.
64
57
  </html>
65
58
  ```
66
59
 
67
- See [Concepts → Theme selection](./concepts.md#theme-selection) for how
68
- selectors resolve and [Usage → Theming](./usage/theming.md) for the full color
69
- token reference.
60
+ See [Concepts → Theme selection](./concepts.md#theme-selection) for how selectors resolve and [Usage → Theming](./usage/theming.md) for the full color token reference.
70
61
 
71
62
  ## Import paths
72
63
 
73
- Compiled entrypoints are ready-to-import CSS and require only tooling that can
74
- resolve package CSS imports. `/tw` entrypoints publish copied, uncompiled
75
- source from `dist/tw`; a Tailwind v4 build must still process their `@theme`,
76
- `@utility`, `@apply`, and related directives. Focused source component
77
- entrypoints include theme tokens so their classes can work independently.
78
-
79
- | Import path | Composition and effects |
80
- | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
81
- | `@codenhub/styles` | Compiled complete surface: Tailwind base/theme output, tokens, typography, utilities, components, and reset. Applies global reset, root theme, and focus rules. |
82
- | `@codenhub/styles/theme` | Compiled Tailwind theme variables, Codenhub tokens, and the presentation classes. Sets root theme properties and system/explicit theme selectors; no reset or component classes. |
83
- | `@codenhub/styles/components` | Compiled theme tokens, typography utilities, and every component class. Includes static reduced-motion loader masks; no reset, layout/content utilities, or native mappings. |
84
- | `@codenhub/styles/native` | Compiled complete surface plus classless mappings for headings, text, content elements, form controls, and buttons. Applies the reset and broad element selectors. |
85
- | `@codenhub/styles/aesthetics` | Compiled `.neobrutalism`, `.glass`, `.pixel`, and `.chunky-tile` classes. Adds no tokens or components of its own; import after the base stylesheet. |
86
- | `@codenhub/styles/aesthetics/*` | One compiled aesthetic: `/neobrutalism`, `/glass`, `/pixel`, or `/chunky-tile`. Same rules and ordering as the combined file. |
87
- | `@codenhub/styles/tw` | Source equivalent of the complete stylesheet. Imports Tailwind itself, theme, typography, utilities, components, and reset; applies the same global rules. |
88
- | `@codenhub/styles/tw/theme` | Source theme, tokens, and presentation classes. Imports Tailwind's theme layer; emits root/system/explicit theme selectors and defines the package's custom `dark:` variant. |
89
- | `@codenhub/styles/tw/components` | Published Tailwind source for theme, typography, buttons, feedback, forms, loaders, surfaces, and tooltips, including static reduced-motion loader masks. No reset, layout/content utilities, or native mappings. |
90
- | `@codenhub/styles/tw/surface` | Source theme plus `.surface`, `.card`, and `.panel`. |
91
- | `@codenhub/styles/tw/button` | Published Tailwind source for theme, activity indicators, and `.btn`; includes static reduced-motion masks because buttons compose `.loader-mask` for loading state. |
92
- | `@codenhub/styles/tw/form` | Source theme plus field, public `text-control`, input, textarea, select, checkbox, radio, and switch utilities. |
93
- | `@codenhub/styles/tw/feedback` | Source theme plus alert, badge, skeleton, and progress utilities and their keyframes. |
94
- | `@codenhub/styles/tw/loader` | Published Tailwind source for activity indicators and loaders, including static reduced-motion masks. It has no theme or reset side effects and uses `currentColor`. |
95
- | `@codenhub/styles/tw/tooltip` | Source theme plus tooltip utilities. |
96
- | `@codenhub/styles/tw/reset` | Source theme, typography utilities, and global reset/accessibility rules. It changes root/body/elements and selection, motion, focus, scrollbar, and forced colors. |
97
- | `@codenhub/styles/tw/native` | Source complete surface plus reset and classless native-element mappings; broadest global effects. |
98
- | `@codenhub/styles/tw/typography` | Source theme plus typography utilities; sets theme selectors but no reset or classless mappings. |
99
- | `@codenhub/styles/tw/utilities` | Source theme and typography composition plus layout and content utilities; safelists the package utility names. |
100
- | `@codenhub/styles/tw/aesthetics` | Source aesthetics, combined. `/tw/aesthetics/neobrutalism`, `/glass`, `/pixel`, and `/chunky-tile` publish one apiece. Plain CSS with no theme or reset side effects. |
101
-
102
- Avoid importing overlapping entrypoints in the same build unless duplicate
103
- generated CSS is acceptable; pick the narrowest entrypoint that covers what a
104
- page needs.
64
+ Compiled entrypoints are ready-to-import CSS and require only tooling that can resolve package CSS imports. `/tw` entrypoints publish copied, uncompiled source from `dist/tw`; a Tailwind v4 build must still process their `@theme`, `@utility`, `@apply`, and related directives. Focused source component entrypoints include theme tokens so their classes can work independently.
65
+
66
+ | Import path | Composition and effects |
67
+ | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
68
+ | `@codenhub/styles` | Compiled complete surface: Tailwind base/theme output, tokens, typography, utilities, components, and reset. Applies global reset, root theme, and focus rules. |
69
+ | `@codenhub/styles/theme` | Compiled Tailwind theme variables, Codenhub tokens, and the presentation classes. Sets root theme properties and system/explicit theme selectors; no reset or component classes. |
70
+ | `@codenhub/styles/components` | Compiled theme tokens, typography utilities, and every component class. Includes static reduced-motion loader masks; no reset, layout/content utilities, or native mappings. |
71
+ | `@codenhub/styles/native` | Compiled complete surface plus classless mappings for headings, text, content elements, form controls, and buttons. Applies the reset and broad element selectors. |
72
+ | `@codenhub/styles/aesthetics` | Compiled `.neobrutalism`, `.glass`, `.pixel`, and `.chunky-tile` classes. Adds no tokens or components of its own; import after the base stylesheet. |
73
+ | `@codenhub/styles/aesthetics/*` | One compiled aesthetic: `/neobrutalism`, `/glass`, `/pixel`, or `/chunky-tile`. Same rules and ordering as the combined file. |
74
+ | `@codenhub/styles/tw` | Source equivalent of the complete stylesheet. Imports Tailwind itself, theme, typography, utilities, components, and reset; applies the same global rules. |
75
+ | `@codenhub/styles/tw/theme` | Source theme, tokens, and presentation classes. Imports Tailwind's theme layer; emits root/system/explicit theme selectors and defines the package's custom `dark:` variant. |
76
+ | `@codenhub/styles/tw/components` | Published Tailwind source for theme, typography, buttons, feedback, forms, loaders, surfaces, and tooltips, including static reduced-motion loader masks. No reset, layout/content utilities, or native mappings. |
77
+ | `@codenhub/styles/tw/surface` | Source theme plus `.surface`, `.card`, and `.panel`. |
78
+ | `@codenhub/styles/tw/button` | Published Tailwind source for theme and `.btn`, including its `.loading` state's mask application. Pair it with `/tw/loader` for `--loader-art` — the spinner artwork and its reduced-motion fallback — to resolve. |
79
+ | `@codenhub/styles/tw/form` | Source theme plus field, public `text-control`, input, textarea, select, checkbox, radio, and switch utilities. |
80
+ | `@codenhub/styles/tw/feedback` | Source theme plus alert, badge, skeleton, and progress utilities and their keyframes. |
81
+ | `@codenhub/styles/tw/loader` | Published Tailwind source for activity indicators and loaders, including static reduced-motion masks. It has no theme or reset side effects and uses `currentColor`. |
82
+ | `@codenhub/styles/tw/tooltip` | Source theme plus tooltip utilities. |
83
+ | `@codenhub/styles/tw/reset` | Source theme, typography utilities, and global reset/accessibility rules. It changes root/body/elements and selection, motion, focus, scrollbar, and forced colors. |
84
+ | `@codenhub/styles/tw/native` | Source complete surface plus reset and classless native-element mappings; broadest global effects. |
85
+ | `@codenhub/styles/tw/typography` | Source theme plus typography utilities; sets theme selectors but no reset or classless mappings. |
86
+ | `@codenhub/styles/tw/utilities` | Source theme and typography composition plus layout and content utilities; safelists the package utility names. |
87
+ | `@codenhub/styles/tw/aesthetics` | Source aesthetics, combined. `/tw/aesthetics/neobrutalism`, `/glass`, `/pixel`, and `/chunky-tile` publish one apiece. Plain CSS with no theme or reset side effects. |
88
+
89
+ Avoid importing overlapping entrypoints in the same build unless duplicate generated CSS is acceptable; pick the narrowest entrypoint that covers what a page needs.
105
90
 
106
91
  ## Requirements
107
92
 
108
93
  - Consumer tooling must resolve package CSS imports.
109
- - Chrome 123, Safari 17.5, or Firefox 121 and newer. Color tokens are declared
110
- with `light-dark()` and selected by `color-scheme` (Firefox 120), and
111
- `.input-group` propagates a nested control's invalid and disabled state with
112
- `:has()` (Firefox 121).
94
+ - Chrome 123, Safari 17.5, or Firefox 121 and newer. Color tokens are declared with `light-dark()` and selected by `color-scheme` (Firefox 120), and `.input-group` propagates a nested control's invalid and disabled state with `:has()` (Firefox 121).
113
95
  - Tailwind CSS 4 or newer is required only for `/tw` source entrypoints.
114
- - The package has no JavaScript runtime. Apps must provide semantic HTML,
115
- ARIA, keyboard behavior, focus management, validation, and announcements;
116
- see [Accessibility](./accessibility.md).
96
+ - The package has no JavaScript runtime. Apps must provide semantic HTML, ARIA, keyboard behavior, focus management, validation, and announcements; see [Accessibility](./accessibility.md).
@@ -1,22 +1,19 @@
1
1
  ---
2
2
  title: Aesthetics
3
3
  description: The four shipped aesthetics in depth, including their documented exceptions.
4
+ order: 4
4
5
  ---
5
6
 
6
7
  # Aesthetics
7
8
 
8
- An aesthetic decides what a component is _made of_: its radius, border
9
- thickness, shadow, and shape. Aesthetics ship from opt-in entrypoints, so
10
- importing the stylesheet is what makes the classes available:
9
+ An aesthetic decides what a component is _made of_: its radius, border thickness, shadow, and shape. Aesthetics ship from opt-in entrypoints, so importing the stylesheet is what makes the classes available:
11
10
 
12
11
  ```css
13
12
  @import "@codenhub/styles";
14
13
  @import "@codenhub/styles/aesthetics";
15
14
  ```
16
15
 
17
- Import them after the base stylesheet. `.neobrutalism` and `.pixel` replace
18
- the neutral border color, and they do so at zero specificity, so source order
19
- is what lets them win.
16
+ Import them after the base stylesheet. `.neobrutalism` and `.pixel` replace the neutral border color, and they do so at zero specificity, so source order is what lets them win.
20
17
 
21
18
  Like presentation, an aesthetic class cascades to any subtree:
22
19
 
@@ -34,33 +31,19 @@ Like presentation, an aesthetic class cascades to any subtree:
34
31
  | `.pixel` | Corners cut by one grid unit, a chunky outline drawn as an inset ring, and the consumer-supplied `--font-pixel` over monospace. |
35
32
  | `.chunky-tile` | Rounded slabs seated on a darker shade of themselves, with a press that moves the element down into its own bar. |
36
33
 
37
- Aesthetics compose with every supported fill and edge pair. `.ghost.edgeless`
38
- intentionally removes the visible material traits from components whose
39
- aesthetic is expressed only through their fill, edge, or elevation.
34
+ Aesthetics compose with every supported fill and edge pair. `.ghost.edgeless` intentionally removes the visible material traits from components whose aesthetic is expressed only through their fill, edge, or elevation.
40
35
 
41
- An explicit presentation on the element still wins over the aesthetic's
42
- defaults. The aesthetic supplies edge thickness; presentation only decides
43
- whether that edge is drawn.
36
+ An explicit presentation on the element still wins over the aesthetic's defaults. The aesthetic supplies edge thickness; presentation only decides whether that edge is drawn.
44
37
 
45
- An aesthetic directly on a component likewise wins over an inherited
46
- aesthetic. This includes tooltip pseudo-elements: `.tooltip.glass` gets the
47
- complete glass bubble under a pixel ancestor, and `.tooltip.pixel` gets the
48
- complete stepped bubble under a glass ancestor.
38
+ An aesthetic directly on a component likewise wins over an inherited aesthetic. This includes tooltip pseudo-elements: `.tooltip.glass` gets the complete glass bubble under a pixel ancestor, and `.tooltip.pixel` gets the complete stepped bubble under a glass ancestor.
49
39
 
50
- Each aesthetic that scales from one number publishes it as a knob — see
51
- [Customizing → Aesthetic tokens](./customizing.md#aesthetic-tokens) for how
52
- knobs resolve and where they can be set. This page covers what each
53
- aesthetic looks like and where it makes documented exceptions.
40
+ Each aesthetic that scales from one number publishes it as a knob — see [Customizing → Aesthetic tokens](./customizing.md#aesthetic-tokens) for how knobs resolve and where they can be set. This page covers what each aesthetic looks like and where it makes documented exceptions.
54
41
 
55
42
  ## Neobrutalism
56
43
 
57
- The shadow is cast in the component's own intent, so a success button throws
58
- a green shadow and a destructive card a red one. With no intent, both the
59
- outline and the shadow use the ink, which follows the theme rather than the
60
- palette.
44
+ The shadow is cast in the component's own intent, so a success button throws a green shadow and a destructive card a red one. With no intent, both the outline and the shadow use the ink, which follows the theme rather than the palette.
61
45
 
62
- `--neo-offset` is the knob: the shadow offset and the distance the press
63
- travels are the same number, so scaling the look scales both at once.
46
+ `--neo-offset` is the knob: the shadow offset and the distance the press travels are the same number, so scaling the look scales both at once.
64
47
 
65
48
  ```html
66
49
  <section class="neobrutalism" style="--neo-offset: 6px">
@@ -70,26 +53,15 @@ travels are the same number, so scaling the look scales both at once.
70
53
 
71
54
  **Exceptions:**
72
55
 
73
- - Content chips are left alone. A `.kbd`, `.code`, or `.pre` is content
74
- rather than structure, and an ink edge on one reads as a defect: a key cap
75
- keeps the quiet border color and a code chip keeps no border at all.
76
- - Only `.btn` and `.card.interactive` respond to hover and press. A card
77
- becomes a control when it opts in with `.interactive`; a plain card, an
78
- alert, or a panel is a container and stays put.
79
- - An alert rests on the slab under this aesthetic and nowhere else. Here the
80
- slab is a second ink line rather than depth, and an alert is the only
81
- container the package rests flat, so without it a neobrutalist alert is
82
- the one box on the page that reads as unfinished. It is a resting default,
83
- so `.flat` still takes it off and `.floating` still doubles it.
56
+ - Content chips are left alone. A `.kbd`, `.code`, or `.pre` is content rather than structure, and an ink edge on one reads as a defect: a key cap keeps the quiet border color and a code chip keeps no border at all.
57
+ - Only `.btn` and an opted-in `.card` respond to hover and press. A card opts in with `.interactive`, or with one of its halves — `.hoverable` for the hover response alone, `.pressable` for the press alone; a plain card, an alert, or a panel is a container and stays put.
58
+ - An alert rests on the slab under this aesthetic and nowhere else. Here the slab is a second ink line rather than depth, and an alert is the only container the package rests flat, so without it a neobrutalist alert is the one box on the page that reads as unfinished. It is a resting default, so `.flat` still takes it off and `.floating` still doubles it.
84
59
 
85
60
  ## Glass
86
61
 
87
- `.glass` needs something behind it to blur. On a flat page background it
88
- renders as a plain translucent panel.
62
+ `.glass` needs something behind it to blur. On a flat page background it renders as a plain translucent panel.
89
63
 
90
- `--glass-radius` and `--glass-radius-surface` are the corners, at `0.75rem`
91
- and `1rem`. Glass is rounder than the base geometry because a translucent
92
- panel with a tight corner reads as a cut-out rather than as a pane.
64
+ `--glass-radius` and `--glass-radius-surface` are the corners, at `0.75rem` and `1rem`. Glass is rounder than the base geometry because a translucent panel with a tight corner reads as a cut-out rather than as a pane.
93
65
 
94
66
  ```html
95
67
  <section class="glass" style="--glass-radius-surface: 1.5rem">
@@ -99,18 +71,12 @@ panel with a tight corner reads as a cut-out rather than as a pane.
99
71
 
100
72
  **Exceptions:**
101
73
 
102
- - The blur applies to `.card`, `.panel`, `.alert`, and the tooltip bubble
103
- only. Controls stay solid and sit on the glass: a blur under every control
104
- of a dense cluster costs a composited layer apiece and reads as noise.
105
- Controls still take the aesthetic's radius, border, and shadow.
106
- - Under `prefers-reduced-transparency: reduce`, glass surfaces drop the blur
107
- and become opaque.
74
+ - The blur applies to `.card`, `.panel`, `.alert`, and the tooltip bubble only. Controls stay solid and sit on the glass: a blur under every control of a dense cluster costs a composited layer apiece and reads as noise. Controls still take the aesthetic's radius, border, and shadow.
75
+ - Under `prefers-reduced-transparency: reduce`, glass surfaces drop the blur and become opaque.
108
76
 
109
77
  ## Pixel
110
78
 
111
- `--pixel-unit` is one pixel of the imaginary low-resolution grid, `4px` by
112
- default. One square unit is cut from each corner and the outline is one unit
113
- thick, so the cut and what covers it are the same size.
79
+ `--pixel-unit` is one pixel of the imaginary low-resolution grid, `4px` by default. One square unit is cut from each corner and the outline is one unit thick, so the cut and what covers it are the same size.
114
80
 
115
81
  ```html
116
82
  <section class="pixel" style="--pixel-unit: 6px">
@@ -120,44 +86,16 @@ thick, so the cut and what covers it are the same size.
120
86
 
121
87
  **Exceptions:**
122
88
 
123
- - Corners are one unit or nothing. Chips square instead of stepping —
124
- badges, key caps, code, checkboxes, and switches all read
125
- `--ui-clip-tight`, which this aesthetic sets to none, because one unit off
126
- each corner of a 24px badge is a bite rather than a corner. Tables,
127
- progress bars, and skeletons square too, each for its own reason: a
128
- table's `overflow: hidden` fights the clip and the corners square off
129
- where the two meet, and progress and skeleton never read a clip at all —
130
- a squaring aesthetic reaches them through `border-radius` alone. `.pre` is
131
- the one exception that steps: it carries no clip override, so it inherits
132
- the same polygon a button or a card gets, and with no border by default
133
- the cut shows with no ring around it.
134
- - The outline is an inset ring, because a clip removes a real border — and
135
- the focus ring, for the same reason, is a second inset layer rather than
136
- an outline. Both are the element's own edge rather than a shadow, so the
137
- border answers `.edged` and `.edgeless` the way a border does: a
138
- `.edgeless` badge and a `.solid` button draw none, a `.edged` card draws
139
- one, and a field keeps one whatever a container asks for.
140
- - The tooltip trigger and `.radio` are hardcoded past the clip rather than
141
- reached by it. `.tooltip-icon` forces `clip-path: none`, since a stepped
142
- badge would clip its own bubble away with it. `.radio` forces the same,
143
- because the circle is the only thing telling it from a checkbox at a
144
- glance, and a stepped polygon would square it.
145
- - `--font-pixel` is yours to supply. The package ships no font binary, so the
146
- aesthetic has no network side effect and falls back to the monospace
147
- stack.
89
+ - Corners are one unit or nothing. Chips square instead of stepping — badges, key caps, code, checkboxes, and switches all read `--ui-clip-tight`, which this aesthetic sets to none, because one unit off each corner of a 24px badge is a bite rather than a corner. Tables, progress bars, and skeletons square too, each for its own reason: a table's `overflow: hidden` fights the clip and the corners square off where the two meet, and progress and skeleton never read a clip at all — a squaring aesthetic reaches them through `border-radius` alone. `.pre` is the one exception that steps: it carries no clip override, so it inherits the same polygon a button or a card gets, and with no border by default the cut shows with no ring around it.
90
+ - The outline is an inset ring, because a clip removes a real border — and the focus ring, for the same reason, is a second inset layer rather than an outline. Both are the element's own edge rather than a shadow, so the border answers `.edged` and `.edgeless` the way a border does: a `.edgeless` badge and a `.solid` button draw none, a `.edged` card draws one, and a field keeps one whatever a container asks for.
91
+ - The tooltip trigger and `.radio` are hardcoded past the clip rather than reached by it. `.tooltip-icon` forces `clip-path: none`, since a stepped badge would clip its own bubble away with it. `.radio` forces the same, because the circle is the only thing telling it from a checkbox at a glance, and a stepped polygon would square it.
92
+ - `--font-pixel` is yours to supply. The package ships no font binary, so the aesthetic has no network side effect and falls back to the monospace stack.
148
93
 
149
94
  ## Chunky tile
150
95
 
151
- Rounded slabs sitting on a darker shade of themselves, pressed flat on
152
- click. The look mobile learning and game apps use; it is named for what it
153
- is made of rather than for any one product.
96
+ Rounded slabs sitting on a darker shade of themselves, pressed flat on click. The look mobile learning and game apps use; it is named for what it is made of rather than for any one product.
154
97
 
155
- `--tile-lift` is how deep the bar is and how far a press travels, `4px` by
156
- default. One number drives both, so the top edge drops by exactly the bar's
157
- depth and the bottom edge does not move. `--tile-radius` is the corner,
158
- `0.75rem`, and it is one value rather than a control/surface pair on
159
- purpose — the shared corner is what makes a button and the card it sits in
160
- read as the same object.
98
+ `--tile-lift` is how deep the bar is and how far a press travels, `4px` by default. One number drives both, so the top edge drops by exactly the bar's depth and the bottom edge does not move. `--tile-radius` is the corner, `0.75rem`, and it is one value rather than a control/surface pair on purpose — the shared corner is what makes a button and the card it sits in read as the same object.
161
99
 
162
100
  ```html
163
101
  <section class="chunky-tile" style="--tile-lift: 6px; --tile-radius: 0.5rem">
@@ -165,33 +103,18 @@ read as the same object.
165
103
  </section>
166
104
  ```
167
105
 
168
- The bar is a darker shade of the element's own colour rather than a shadow
169
- under it, so it follows every intent: a success button sits on a dark green
170
- edge, a destructive one on a dark red edge, and a plain card on a grey edge
171
- that matches the line it already draws. Measured on the light palette,
172
- `.btn.success` is `#007a55` on `#004c34`. On a dark page a near-black
173
- surface cannot go darker, so its bar lands lighter and reads as a rim.
106
+ The bar is a darker shade of the element's own colour rather than a shadow under it, so it follows every intent: a success button sits on a dark green edge, a destructive one on a dark red edge, and a plain card on a grey edge that matches the line it already draws. Measured on the light palette, `.btn.success` is `#007a55` on `#004c34`. On a dark page a near-black surface cannot go darker, so its bar lands lighter and reads as a rim.
174
107
 
175
108
  **Exceptions:**
176
109
 
177
- - Only what the registry rests above zero sits on a bar — buttons and cards.
178
- A badge, chip, field, or tooltip is flat until it asks for depth with
179
- `.raised`, and `.flat` takes the bar off anything:
110
+ - Only what the registry rests above zero sits on a bar — buttons and cards. A badge, chip, field, or tooltip is flat until it asks for depth with `.raised`, and `.flat` takes the bar off anything:
180
111
 
181
112
  ```html
182
113
  <div class="card soft edgeless info flat">Promo panel, deliberately flat</div>
183
114
  ```
184
115
 
185
- - `--font-rounded` is yours to supply. A heavy rounded grotesque is most of
186
- this look and the package ships no font binary, so with nothing supplied
187
- the page's own stack is used.
188
- - Action labels are drawn heavier and slightly tracked. Casing is left
189
- alone: how a label is worded is the application's decision, so if you want
190
- uppercase buttons, write that rule in your own stylesheet.
191
- - `.card.interactive` presses like a `.btn`, so a chunky answer tile drops
192
- onto its bar on click. A plain `.card` stays put.
193
- - The shipped `.primary` is a near-black monochrome, which leaves a primary
194
- button's bar almost invisible against its own plate; give `.primary` a hue
195
- if it is the call to action.
196
- - Depth in this aesthetic is the bar, never a blurred drop shadow. Anything
197
- the registry rests flat sits flush on the page.
116
+ - `--font-rounded` is yours to supply. A heavy rounded grotesque is most of this look and the package ships no font binary, so with nothing supplied the page's own stack is used.
117
+ - Action labels are drawn heavier and slightly tracked. Casing is left alone: how a label is worded is the application's decision, so if you want uppercase buttons, write that rule in your own stylesheet.
118
+ - `.card.interactive` presses like a `.btn`, so a chunky answer tile drops onto its bar on click; `.card.pressable` gets the same press on its own. A plain `.card` stays put.
119
+ - The shipped `.primary` is a near-black monochrome, which leaves a primary button's bar almost invisible against its own plate; give `.primary` a hue if it is the call to action.
120
+ - Depth in this aesthetic is the bar, never a blurred drop shadow. Anything the registry rests flat sits flush on the page.
@@ -1,18 +1,14 @@
1
1
  ---
2
2
  title: Buttons
3
3
  description: Button classes, intents, sizes, and states.
4
+ order: 5
4
5
  ---
5
6
 
6
7
  # Buttons
7
8
 
8
- Use `.btn` with one optional intent class, one optional fill class, one
9
- optional edge class, optional size class, and optional state. See
10
- [Composing](./composing.md) for how the intent, presentation, and aesthetic
11
- axes combine on any component.
9
+ Use `.btn` with one optional intent class, one optional fill class, one optional edge class, optional size class, and optional state. See [Composing](./composing.md) for how the intent, presentation, and aesthetic axes combine on any component.
12
10
 
13
- Intent classes map color tokens into button tone slots.
14
- [Presentation](./composing.md#presentation) decides how much of that intent
15
- reaches background, text, border, and hover.
11
+ Intent classes map color tokens into button tone slots. [Presentation](./composing.md#presentation) decides how much of that intent reaches background, text, border, and hover.
16
12
 
17
13
  Intent classes:
18
14
 
@@ -26,29 +22,23 @@ Intent classes:
26
22
  | `.destructive`, `.danger`, `.error` | Destructive or error action. |
27
23
  | `.info` | Informational action. |
28
24
 
29
- Every component that supports intent accepts the same list and reads the
30
- same [intent tokens](./theming.md#intent-tokens), so a custom intent class
31
- works everywhere without touching a component.
25
+ Every component that supports intent accepts the same list and reads the same [intent tokens](./theming.md#intent-tokens), so a custom intent class works everywhere without touching a component.
32
26
 
33
- `.neutral` is the only intent that does not fill all the way. Its color is
34
- the page's own text color, so a full fill of it would be a black or white
35
- slab — the loudest element on the page, for the intent that means nothing in
36
- particular. It stops at `--intent-fill-max`, which is why a `.solid` neutral
37
- is a quiet plate a step past `.soft` rather than a block of ink. Set the slot
38
- on your own intent classes; see [Theming → Intent tokens](./theming.md#intent-tokens).
27
+ `.neutral` is the only intent that does not fill all the way. Its color is the page's own text color, so a full fill of it would be a black or white slab — the loudest element on the page, for the intent that means nothing in particular. It stops at `--intent-fill-max`, which is why a `.solid` neutral is a quiet plate a step past `.soft` rather than a block of ink. Set the slot on your own intent classes; see [Theming → Intent tokens](./theming.md#intent-tokens).
39
28
 
40
29
  Size and shape classes:
41
30
 
42
- | Class | Purpose |
43
- | ---------------------------------------------------------------------- | ----------------------------------------------------------- |
44
- | `.pill` | Fully rounded button corners (`border-radius: 9999px`). |
45
- | `.sm` | Smaller button. |
46
- | `.lg` | Larger button. |
47
- | `.p-sm`, `.compact` | Compact padding modifier (`px-2.5 py-1`). |
48
- | `.p-lg`, `.spacious` | Spacious padding modifier (`px-6 py-3`). |
49
- | `.icon` | Square icon button. Use an accessible name in HTML. |
50
- | `.loading` | Loading state. Hides text and shows CSS activity indicator. |
51
- | `.disabled`, `[disabled]`, `[aria-disabled="true"]`, `[data-disabled]` | Disabled styling. |
31
+ | Class | Purpose |
32
+ | ---------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
33
+ | `.pill` | Fully rounded button corners (`border-radius: 9999px`). |
34
+ | `.sm` | Smaller button. |
35
+ | `.lg` | Larger button. |
36
+ | `.p-xs`, `.dense` | Tightest padding modifier (`px-2 py-0.5`; icon `p-0.5`). Also drops the `--control-height` minimum so a chip-sized button fits a table cell or a dense toolbar; every other size and padding class keeps that floor. An icon-only button at this tier gives up its `min-width` too, so size the glyph yourself. |
37
+ | `.p-sm`, `.compact` | Compact padding modifier (`px-2.5 py-1`; icon `p-1`). |
38
+ | `.p-lg`, `.spacious` | Spacious padding modifier (`px-6 py-3`; icon `p-3`). |
39
+ | `.icon` | Square icon button. Use an accessible name in HTML. |
40
+ | `.loading` | Loading state. Hides text and shows CSS activity indicator. |
41
+ | `.disabled`, `[disabled]`, `[aria-disabled="true"]`, `[data-disabled]` | Disabled styling. |
52
42
 
53
43
  Examples:
54
44
 
@@ -61,14 +51,8 @@ Examples:
61
51
  <button class="btn primary loading" disabled>Saving</button>
62
52
  ```
63
53
 
64
- `.loading` is a state, not a color or presentation class. Prefer combining
65
- it with disabled behavior so users cannot trigger duplicate work. Loading
66
- buttons keep only opacity and transform transitions active so spinner and
67
- surface colors stay synchronized when theme tokens change.
54
+ `.loading` is a state, not a color or presentation class. Prefer combining it with disabled behavior so users cannot trigger duplicate work. Loading buttons keep only opacity and transform transitions active so spinner and surface colors stay synchronized when theme tokens change.
68
55
 
69
- On the base look a press scales the button down a little
70
- (`--ui-active-transform`, `scale(0.97)`). [Aesthetics](./aesthetics.md) swap
71
- in their own press gesture, and `prefers-reduced-motion` turns it off.
56
+ On the base look a press scales the button down a little (`--ui-active-transform`, `scale(0.97)`). [Aesthetics](./aesthetics.md) swap in their own press gesture, and `prefers-reduced-motion` turns it off.
72
57
 
73
- Use `<button>` for actions or an accessible link for navigation; see
74
- [Accessibility](../accessibility.md).
58
+ Use `<button>` for actions or an accessible link for navigation; see [Accessibility](../accessibility.md).