@codenhub/styles 0.5.0 → 0.7.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.
Files changed (119) hide show
  1. package/NOTICE +18 -16
  2. package/README.es.md +61 -0
  3. package/README.md +27 -22
  4. package/README.pt-BR.md +61 -0
  5. package/dist/aesthetics/chunky-tile.css +1 -1
  6. package/dist/aesthetics/cyber.css +1 -1
  7. package/dist/aesthetics/glass.css +1 -1
  8. package/dist/aesthetics/index.css +2 -2
  9. package/dist/aesthetics/neobrutalism.css +1 -1
  10. package/dist/aesthetics/pixel.css +1 -1
  11. package/dist/aesthetics/sketch.css +1 -1
  12. package/dist/components.css +2 -2
  13. package/dist/index.css +2 -2
  14. package/dist/native.css +2 -2
  15. package/dist/palette.css +1 -1
  16. package/dist/theme.css +2 -2
  17. package/dist/tw/aesthetics/chunky-tile.css +120 -62
  18. package/dist/tw/aesthetics/cyber.css +102 -40
  19. package/dist/tw/aesthetics/glass.css +371 -19
  20. package/dist/tw/aesthetics/index.css +2 -1
  21. package/dist/tw/aesthetics/neobrutalism.css +121 -33
  22. package/dist/tw/aesthetics/pixel.css +111 -16
  23. package/dist/tw/aesthetics/sketch.css +100 -28
  24. package/dist/tw/box.css +69 -28
  25. package/dist/tw/components/button.css +35 -14
  26. package/dist/tw/components/feedback.css +61 -58
  27. package/dist/tw/components/form.css +255 -142
  28. package/dist/tw/components/index.css +4 -9
  29. package/dist/tw/components/surface.css +80 -68
  30. package/dist/tw/components/tooltip.css +75 -41
  31. package/dist/tw/elevation.css +14 -22
  32. package/dist/tw/index.css +15 -19
  33. package/dist/tw/intent.css +35 -27
  34. package/dist/tw/native.css +22 -12
  35. package/dist/tw/palette.css +14 -11
  36. package/dist/tw/presentation.css +16 -30
  37. package/dist/tw/reset.css +36 -43
  38. package/dist/tw/surface.css +11 -12
  39. package/dist/tw/theme.css +87 -103
  40. package/dist/tw/utilities/content.css +311 -200
  41. package/dist/tw/utilities/layout.css +41 -37
  42. package/docs/accessibility.md +104 -58
  43. package/docs/changelog/0.1.1.md +1 -0
  44. package/docs/changelog/0.2.0.md +1 -0
  45. package/docs/changelog/0.3.0.md +1 -0
  46. package/docs/changelog/0.4.0.md +1 -0
  47. package/docs/changelog/0.5.0.md +8 -3
  48. package/docs/changelog/0.6.0.md +53 -0
  49. package/docs/changelog/0.7.0.md +50 -0
  50. package/docs/changelog/index.md +2 -0
  51. package/docs/concepts.md +188 -46
  52. package/docs/es/accessibility.md +150 -0
  53. package/docs/es/concepts.md +212 -0
  54. package/docs/es/index.md +104 -0
  55. package/docs/es/integrating/astro.md +35 -0
  56. package/docs/es/integrating/index.md +47 -0
  57. package/docs/es/integrating/nextjs.md +67 -0
  58. package/docs/es/integrating/svelte.md +45 -0
  59. package/docs/es/integrating/tailwind.md +78 -0
  60. package/docs/es/integrating/vue.md +31 -0
  61. package/docs/es/integrating/without-a-bundler.md +115 -0
  62. package/docs/es/setup.md +180 -0
  63. package/docs/es/usage/aesthetics.md +276 -0
  64. package/docs/es/usage/buttons.md +131 -0
  65. package/docs/es/usage/composing.md +164 -0
  66. package/docs/es/usage/content-and-layout.md +215 -0
  67. package/docs/es/usage/customizing.md +298 -0
  68. package/docs/es/usage/feedback.md +153 -0
  69. package/docs/es/usage/forms.md +231 -0
  70. package/docs/es/usage/index.md +29 -0
  71. package/docs/es/usage/solo.md +84 -0
  72. package/docs/es/usage/theming.md +296 -0
  73. package/docs/es/usage/tooltips.md +127 -0
  74. package/docs/index.md +89 -21
  75. package/docs/integrating/astro.md +3 -4
  76. package/docs/integrating/index.md +18 -13
  77. package/docs/integrating/nextjs.md +4 -5
  78. package/docs/integrating/svelte.md +5 -4
  79. package/docs/integrating/tailwind.md +29 -8
  80. package/docs/integrating/vue.md +3 -4
  81. package/docs/integrating/without-a-bundler.md +114 -0
  82. package/docs/pt-BR/accessibility.md +150 -0
  83. package/docs/pt-BR/concepts.md +212 -0
  84. package/docs/pt-BR/index.md +104 -0
  85. package/docs/pt-BR/integrating/astro.md +35 -0
  86. package/docs/pt-BR/integrating/index.md +47 -0
  87. package/docs/pt-BR/integrating/nextjs.md +67 -0
  88. package/docs/pt-BR/integrating/svelte.md +45 -0
  89. package/docs/pt-BR/integrating/tailwind.md +78 -0
  90. package/docs/pt-BR/integrating/vue.md +31 -0
  91. package/docs/pt-BR/integrating/without-a-bundler.md +115 -0
  92. package/docs/pt-BR/setup.md +180 -0
  93. package/docs/pt-BR/usage/aesthetics.md +276 -0
  94. package/docs/pt-BR/usage/buttons.md +131 -0
  95. package/docs/pt-BR/usage/composing.md +164 -0
  96. package/docs/pt-BR/usage/content-and-layout.md +215 -0
  97. package/docs/pt-BR/usage/customizing.md +298 -0
  98. package/docs/pt-BR/usage/feedback.md +153 -0
  99. package/docs/pt-BR/usage/forms.md +231 -0
  100. package/docs/pt-BR/usage/index.md +29 -0
  101. package/docs/pt-BR/usage/solo.md +84 -0
  102. package/docs/pt-BR/usage/theming.md +296 -0
  103. package/docs/pt-BR/usage/tooltips.md +127 -0
  104. package/docs/setup.md +134 -91
  105. package/docs/usage/aesthetics.md +102 -65
  106. package/docs/usage/buttons.md +108 -40
  107. package/docs/usage/composing.md +105 -92
  108. package/docs/usage/content-and-layout.md +159 -127
  109. package/docs/usage/customizing.md +112 -43
  110. package/docs/usage/feedback.md +135 -70
  111. package/docs/usage/forms.md +184 -99
  112. package/docs/usage/index.md +18 -14
  113. package/docs/usage/solo.md +83 -0
  114. package/docs/usage/theming.md +260 -119
  115. package/docs/usage/tooltips.md +103 -42
  116. package/llms-full.txt +2465 -1272
  117. package/llms.txt +25 -17
  118. package/package.json +28 -35
  119. package/dist/tw/components/loader.css +0 -117
@@ -1,150 +1,163 @@
1
1
  ---
2
2
  title: Composing
3
- description: Combining intent, presentation, and aesthetic on a component, and the axis-support matrix.
4
- order: 1
3
+ description: Lookup for how intent, presentation, aesthetic, and elevation combine, every component's default look, and which classes each component reads.
4
+ order: 8
5
5
  ---
6
6
 
7
- # Composing the three axes
7
+ # Composing
8
8
 
9
- See [Concepts](../concepts.md#the-three-axes) for what each axis means. This page covers how they combine in markup, what the presentation classes mean in depth, which components support which axis, and elevation.
9
+ This is a lookup page. [Building a screen](../concepts.md) introduces intent, presentation, and aesthetic; this page has the complete rules for combining them, the default look of every component, which classes each component reads, and elevation.
10
10
 
11
- ## Combining axes
11
+ ## Combining classes
12
12
 
13
13
  ```html
14
14
  <div class="soft">
15
15
  <button class="btn primary">Soft primary button</button>
16
16
  <span class="badge success">Soft success badge</span>
17
- <button class="btn primary ghost edged">Outlined; the element wins</button>
17
+ <button class="btn primary ghost edged">Outlined: the class on the element wins</button>
18
18
  </div>
19
19
  ```
20
20
 
21
- A declaration on the element always beats one inherited from a container, so a container sets the default look for its subtree and any element opts out.
22
-
23
- Intent classes do not cascade. `.primary` and its siblings stay on the element that shows the intent, because a container silently recoloring every descendant is a trap rather than a feature — see [Theming → Intent tokens](./theming.md#intent-tokens). Use `.neutral` to opt an element back out of an inherited intent context. Presentation and [material tokens](./customizing.md#material-tokens) do cascade, so a container can set the look of its whole subtree while any element overrides it.
21
+ - **Presentation passes down.** `.solid`, `.soft`, `.ghost`, `.edged`, and `.edgeless` work on the component or on any container, and a class on the element beats one inherited from a container. A container sets the look of everything inside it, and any element can choose its own.
22
+ - **Aesthetics and [material tokens](./customizing.md#material-tokens) pass down** the same way.
23
+ - **Intent does not pass down.** `.primary` and the other intent classes color only the element they are on. A container that silently recolored everything inside it would turn a red danger-zone card's neutral Cancel button red. `.neutral` names the default; use it where an element would otherwise take an intent, such as a table row inside a `.success` table. See [Theming → Intent tokens](./theming.md#intent-tokens).
24
+ - **Elevation does not pass down.** `.raised` lifts only the element it is on; see [Elevation](#elevation).
25
+
26
+ ## Component defaults
27
+
28
+ With no presentation class on it or around it, each component has its own look. "Resting elevation" is how much depth it takes when an [aesthetic](./aesthetics.md) draws depth; with no aesthetic, nothing has a shadow.
29
+
30
+ | Component | Fill | Edge | Resting elevation |
31
+ | -------------------------------- | ----------- | -------- | ----------------- |
32
+ | `.btn` | `.solid` | edgeless | 1 |
33
+ | `.card` | `.ghost` | edged | 1 |
34
+ | `.panel` | `.soft` | edgeless | 0 |
35
+ | `.alert` | `.soft` | edged | 0 |
36
+ | `.badge` | `.soft` | edgeless | 0 |
37
+ | `.ipt`, `.textarea`, `.select` | `.ghost` | edged | 0 |
38
+ | `.input-group` | `.ghost` | edged | 0 |
39
+ | `.checkbox`, `.radio`, `.switch` | `.soft` | edged | 0 |
40
+ | `.kbd` | `.soft` | edged | 0 |
41
+ | `.code`, `.pre` | `.soft` | edgeless | 0 |
42
+ | `.data-table` | `.soft` | edgeless | 0 |
43
+ | `.progress` (the track) | `.soft` | edgeless | 0 |
44
+ | `.tooltip-bubble` | `.solid` | edged | 0 |
45
+ | `.quote` | `.ghost` | edged | 0 |
46
+ | `.skeleton`, `.divider` | Intent only | None | 0 |
47
+
48
+ A neutral `.solid` fills only to 20%; see [Theming → Intent tokens](./theming.md#intent-tokens). The neutral exceptions to these fills are in [Presentation](#presentation).
24
49
 
25
50
  ## Presentation
26
51
 
27
- Presentation has two independent axes. `.solid`, `.soft`, and `.ghost` decide how much intent fills a component; `.edged` and `.edgeless` decide whether it draws a boundary. They set [presentation tokens](./customizing.md#presentation-tokens) and nothing else, so they work on the component itself or on any ancestor.
28
-
29
- | Class | Look |
30
- | ----------- | ---------------------------------------------------------- |
31
- | `.solid` | Intent-colored fill with contrast text. |
32
- | `.soft` | Lightly tinted fill with intent-colored text. |
33
- | `.ghost` | No fill at rest, with intent-colored text. |
34
- | `.edged` | Intent-colored boundary at the aesthetic's material width. |
35
- | `.edgeless` | No boundary. |
36
-
37
- Values each class ships:
38
-
39
- | Class | `--ui-fill` | `--ui-fg-on-fill` | `--ui-border` |
40
- | ----------- | ----------- | ----------------- | ------------- |
41
- | `.solid` | `100%` | `100%` | |
42
- | `.soft` | `12%` | `0%` | |
43
- | `.ghost` | `0%` | `0%` | |
44
- | `.edged` | | | `100%` |
45
- | `.edgeless` | | | `0%` |
52
+ Presentation is two separate choices. `.solid`, `.soft`, and `.ghost` set how much of the intent color fills a component. `.edged` and `.edgeless` set whether it draws a border. They set [presentation tokens](./customizing.md#presentation-tokens) and nothing else.
46
53
 
47
- `.card`, `.panel`, `.alert`, `.kbd`, `.code`, and `.pre` override `.soft`'s fill at rest to `0%` for the no-named-intent case only, and reveal it on `.card`'s own `:hover`/`.interactive`/`.hoverable` -- the one place a component remaps what a presentation class resolves to for part of its intent range, the same way text controls cap it at `6%` cascaded. A named intent on any of the six keeps the ordinary `12%`. `.badge` reads the identical intent/presentation classes but keeps its 12% wash at rest even with no named intent, since it has no border to fall back on and would otherwise disappear rather than read quieter. See [Content and layout → Surfaces](./content-and-layout.md#surfaces) and [Feedback](./feedback.md).
48
-
49
- The combinations mean exactly what they spell:
54
+ | Class | Look | `--ui-fill` | `--ui-fg-on-fill` | `--ui-border` |
55
+ | ----------- | --------------------------------------------------------- | ----------- | ----------------- | ------------- |
56
+ | `.solid` | Filled with the intent color, with contrast text. | `100%` | `100%` | |
57
+ | `.soft` | A light tint, with intent-colored text. | `12%` | `0%` | |
58
+ | `.ghost` | No fill at rest, with intent-colored text. | `0%` | `0%` | |
59
+ | `.edged` | An intent-colored border, as thick as the aesthetic sets. | | | `100%` |
60
+ | `.edgeless` | No border. | | | `0%` |
50
61
 
51
62
  ```html
52
63
  <button class="btn primary">Solid, the button default</button>
53
- <button class="btn soft edged">Tinted with a border</button>
64
+ <button class="btn soft edged">Tinted, with a border</button>
54
65
  <button class="btn primary ghost edged">Outline</button>
55
- <button class="btn ghost">Ghost; picks up a tint on hover</button>
56
- <input class="ipt soft edgeless" />
57
- <!-- A field sunk into the page -->
66
+ <button class="btn ghost">Ghost: picks up a tint on hover</button>
67
+ <input class="ipt soft edgeless" aria-label="Search" />
58
68
  ```
59
69
 
60
- A fill class never decides an edge and an edge class never decides a fill. Use `.solid.edgeless` for a filled box with no line; `.solid.edged` renders the same box, because the line fades out as the fill fills in.
70
+ A fill class never sets the border, and a border class never sets the fill. `.solid.edged` looks the same as `.solid.edgeless`, because the border fades out as the fill fills in.
61
71
 
62
- The edge is the silhouette and nothing else. Rules _inside_ a component that has an inside are a separate switch — see [Content and layout → Table rules](./content-and-layout.md#table-rules) — because tying them to this axis made them arrive by implication rather than by request.
72
+ The border is the outline of the component and nothing else. Lines inside a component, such as the rules between table rows, are a separate switch; see [Content and layout → Table rules](./content-and-layout.md#table-rules).
63
73
 
64
- With no presentation class in scope, each component keeps its own default: buttons are filled, alerts and badges are tinted, surfaces and controls are neutral and bordered.
74
+ ### Neutral surfaces rest untinted
65
75
 
66
- | Component | Reads |
67
- | ----------------------------------------------- | ----------------------------------------------------------------------------------------------- |
68
- | `.btn`, `.alert`, `.badge`, `.card`, `.panel` | Fill, text, border, and border width. |
69
- | `.kbd` | Fill, text, border, and border width. |
70
- | `.data-table` | Header fill and text, border, border width. |
71
- | `.ipt`, `.textarea`, `.select`, `.text-control` | Border, border width, and a capped fill. |
72
- | `.input-group` | Border, border width, and a capped fill. |
73
- | `.checkbox`, `.radio` | A capped fill, checked and unchecked. |
74
- | `.switch` | Border, border width, and a capped fill. |
75
- | `.quote` | Fill, text, border, and width. |
76
- | `.code`, `.pre`, `.tooltip-bubble` | Fill, text, border, and material. |
77
- | `.progress` | Track fill, border, and border width; the value fill is always the intent color, full strength. |
78
- | `.loader`, `.skeleton`, `.divider` | Intent only, not presentation. |
76
+ A neutral `.card.soft`, `.panel`, and `.alert` show no tint at rest. They use the quiet background tone one step off the page instead (`--color-foreground`), because a gray tint on every neutral box looks dirty rather than quiet.
79
77
 
80
- A text control caps a **cascaded** fill at `6%`, keeping typed text legible when a `.solid` container reaches a field nobody classed. A fill class written on the control itself names its own cap instead, because that is a consumer describing what they want: `.soft` takes `12%` and `.solid` takes `20%`.
78
+ - A `.card.soft` with `.interactive` or `.hoverable` shows the tint on hover. A plain `.card.soft` and a `.panel` have no hover state.
79
+ - With one of the six built-in intents, all three keep the ordinary 12% tint, and a card deepens it on hover. An intent you defined yourself is treated as neutral here; see [Theming → Your own intent](./theming.md#your-own-intent).
80
+ - A `.badge` keeps its 12% tint even when neutral. It has no border, so without the tint it would disappear into the text around it.
81
81
 
82
- | On a text control | fill |
83
- | ----------------- | ---- |
84
- | `.ghost` | 0% |
85
- | cascaded `.solid` | 6% |
86
- | `.soft` | 12% |
87
- | `.solid` | 20% |
82
+ `.kbd`, `.code`, and `.pre` work differently. They rest on their intent's subtle tone, `--intent-subtle`, which is `--color-surface` for neutral, and a built-in intent adds 12% of its color over it. An intent you defined yourself shows its own `--intent-subtle` tint without that extra 12%.
88
83
 
89
- A toggle's cap does not have that split: it is `40%` whether the presentation class is on the checkbox/radio/switch itself or cascaded from a container, the same value for all three. That is where an unchecked `.ghost` (0%), `.soft`/default (12%), and `.solid` (the cap) read as three distinct plates instead of shades of the same wash. Being checked pins the fill to `100%` instead, whatever the presentation class asks — a checkbox, a radio, and a switch each have one "on" look, and presentation only shapes them unchecked. See [Forms](./forms.md) for the full toggle reference.
84
+ ### Text controls and toggles
90
85
 
91
- The same split governs the edge: a cascaded `.edgeless` is floored and the element's own is honoured — except on `.checkbox` and `.radio`, which never drop their line at all, and on `.switch.ghost`, which keeps its line specifically against its own `.edgeless`: `.ghost` already asks for zero fill, so removing the line too would leave nothing marking the track but the knob. `.switch.ghost.edgeless` renders the same as `.switch.ghost.edged` rather than as a distinct, boundary-less look. See [Forms](./forms.md) for the full toggle and text control reference.
86
+ - **Text controls** cap their fill so typed text stays readable: at most 6% from a container, 12% for their own `.soft`, and 20% for their own `.solid`. They ignore an `.edgeless` from a container and honor their own. See [Forms → Fill and border on text controls](./forms.md#fill-and-border-on-text-controls).
87
+ - **Toggles** cap their unchecked fill at 40% and fill to 100% once checked. `.checkbox` and `.radio` always draw their border, and so does `.switch.ghost`. See [Forms → Checked and unchecked colors](./forms.md#checked-and-unchecked-colors).
92
88
 
93
- A tooltip bubble is filled, over a tinted ground. An intent fills it with that intent's own color: `.tooltip-bubble.primary` is the primary color, black on a light page and white on a dark one, and `.tooltip-bubble.destructive` is a red bubble.
89
+ ### Tooltip bubbles
94
90
 
95
- With no intent the bubble is `--color-tooltip`, the one plate in the package chosen per theme rather than derived from an intent. Composed like everything else it was `20%` of the page's ink over the surface tone, which steps _lighter_ than the surface on a dark page and _darker_ on a light one — so the dark bubble read as lifted and the light one as a mid-grey slab two steps darker than every card on the screen. The token states each direction instead: near-white over a light page, a mid grey over a dark one. `--color-tooltip-contrast` is its ink.
91
+ A tooltip bubble is always filled and opaque, and draws a thin border that only its own `.edgeless` removes. With no intent it uses `--color-tooltip`; an intent fills it with that intent's color. [Tooltips → How the bubble looks](./tooltips.md#how-the-bubble-looks) has the colors.
96
92
 
97
- Near-white is only 1.04:1 against a light page, so the bubble draws a hairline as well, and floors it: a container's `.solid` or `.edgeless` cannot take the boundary away from a bubble nobody classed, while `.tooltip-bubble.edgeless` still can. The ground keeps the bubble opaque at every fill, so a cascaded presentation leaves it readable over whatever it floats above. It reads the material tokens too, so an [aesthetic](./aesthetics.md) in scope shapes the bubble like any other component. See [Tooltips](./tooltips.md) for the full tooltip reference.
93
+ ### Progress tracks
98
94
 
99
- ## Component axis reference
95
+ `.progress` reads both choices on its track. The filled part is always the intent color at full strength. `.solid` is not supported on the track, because the track and the filled part would be the same color. `.ghost.edgeless` renders but leaves the track with no visible frame; `.ghost.edged` draws an outline around it.
96
+
97
+ ### Unsupported combinations
100
98
 
101
- This table is the authoritative axis map for demonstrated components. "Shape" means the component reads applicable radius, border-width, shadow, hover, or clip/edge material tokens; an aesthetic may intentionally affect only the materials that component draws.
99
+ | Component | Class | What happens |
100
+ | ----------------------- | ----------- | -------------------------------------------------------------------------------------------- |
101
+ | `.kbd`, `.code`, `.pre` | `.ghost` | The chip still draws its tinted background, because that background is what makes it a chip. |
102
+ | `.progress` | `.solid` | The track and the filled part are the same color, so the value cannot be seen. |
103
+ | `.checkbox`, `.radio` | `.edgeless` | Ignored: the border is always drawn. |
102
104
 
103
- Presentation is two independent axes, so they get a column each. A `Yes` means the class changes what the component computes, which `tests/browser/axes.spec.ts` asserts against `registry.json` in both directions: an axis marked `Yes` must move, and an axis marked `No` must not.
105
+ ## Component axis reference
106
+
107
+ Which classes change each component. "Material" is what an [aesthetic](./aesthetics.md) can change on it: "Shape" means corner, border width, shadow, hover, and outline; the narrower entries list what applies.
104
108
 
105
- | Components | Intent | Fill | Edge | Aesthetic material |
109
+ | Components | Intent | Fill | Edge | Material |
106
110
  | --------------------------------------------------------- | ------ | ---- | ---- | ------------------ |
107
111
  | `.btn`, `.alert`, `.badge`, `.card`, `.panel` | Yes | Yes | Yes | Shape |
108
- | `.loader` | Yes | No | No | No |
109
- | `.kbd`, `.data-table` | Yes | Yes | Yes | Radius and edge |
112
+ | `.kbd`, `.data-table` | Yes | Yes | Yes | Corner and edge |
110
113
  | `.quote` | Yes | Yes | Yes | Edge width |
111
114
  | `.divider`, `.skeleton` | Yes | No | No | No |
112
115
  | `.ipt`, `.textarea`, `.select`, `.text-control` | Yes | Yes | Yes | Shape |
113
116
  | `.input-group` | Yes | Yes | Yes | Shape |
114
117
  | `.surface` | Yes | Yes | Yes | Shape |
115
- | `.checkbox`, `.radio` | Yes | Yes | No | Radius and edge |
116
- | `.switch` | Yes | Yes | Yes | Radius and edge |
117
- | `.progress` | Yes | Yes | Yes | Radius and edge |
118
- | `.code`, `.pre` | Yes | Yes | Yes | Radius and clip |
119
- | `.tooltip-bubble` | Yes | Yes | Yes | Shape and overlay |
118
+ | `.checkbox`, `.radio` | Yes | Yes | No | Corner and edge |
119
+ | `.switch` | Yes | Yes | Yes | Corner and edge |
120
+ | `.progress` | Yes | Yes | Yes | Corner and edge |
121
+ | `.code`, `.pre` | Yes | Yes | Yes | Corner and outline |
122
+ | `.tooltip-bubble` | Yes | Yes | Yes | Shape and blur |
120
123
  | `.table-wrap`, `.quote-inline`, layout and text utilities | No | No | No | No |
121
124
 
122
- `.checkbox` and `.radio` are the only components that read one axis and not the other. Their line is the only thing marking an unchecked box, so it is drawn whatever the edge class says, from a container or from the element itself. `.edgeless` on either is unsupported rather than merely discouraged.
125
+ "Yes" means the class changes the component, and "No" means it does not; the package's tests check both. What each component does with a class:
123
126
 
124
- `.progress` reads both axes on its track; the value fill, the moving bar itself, is always the intent color at full strength and never changes. `.solid` is unsupported on the track: at full fill the track and the value fill compose the same color, and the one thing the component exists to show — how much is filled versus not — disappears. `.ghost.edgeless` renders (no fill, no border) but is not recommended: `.ghost.edged` — an outline capsule around the moving fill — keeps a visible frame at rest, while pairing `.ghost` with `.edgeless` leaves the track with none.
127
+ | Component | Reads |
128
+ | ----------------------------------------------- | -------------------------------------------------------------------------------------- |
129
+ | `.btn`, `.alert`, `.badge`, `.card`, `.panel` | Fill, text color, border, and border width. |
130
+ | `.kbd` | Fill, text color, border, and border width. |
131
+ | `.data-table` | Header fill and text color, border, and border width. |
132
+ | `.ipt`, `.textarea`, `.select`, `.text-control` | Border, border width, and a capped fill. |
133
+ | `.input-group` | Border, border width, and a capped fill. |
134
+ | `.checkbox`, `.radio` | A capped fill, checked and unchecked. |
135
+ | `.switch` | Border, border width, and a capped fill. |
136
+ | `.quote` | Fill, text color, border, and border width. |
137
+ | `.code`, `.pre`, `.tooltip-bubble` | Fill, text color, border, and material. |
138
+ | `.progress` | Track fill, border, and border width. The filled part is always the full intent color. |
139
+ | `.skeleton`, `.divider` | Intent only. |
125
140
 
126
- Every other text control floors a _cascaded_ `.edgeless` and honours its own: a `.edgeless` toolbar will not erase the line of a field nobody classed, while `.ipt.edgeless` is a consumer describing what they want and gets it.
127
-
128
- State and modifier classes such as `.interactive`, `.hoverable`, `.pressable`, `.invalid`, `.p-sm`, and `.vertical` sit above this map and are documented with their component.
141
+ State and modifier classes such as `.interactive`, `.hoverable`, `.pressable`, `.p-sm`, and `.vertical` are documented with their component. An invalid control is marked with `aria-invalid="true"`, not a class; see [Forms](./forms.md#show-a-validation-error).
129
142
 
130
143
  ## Elevation
131
144
 
132
- Depth is a modifier, not an axis. Nothing is raised until an [aesthetic](./aesthetics.md) draws depth or one of these classes asks for it.
133
-
134
- | Class | Depth |
135
- | ----------- | ------------------------------------------------------------------------ |
136
- | `.flat` | Removes part-based elevation; glass surfaces keep their complete shadow. |
137
- | `.raised` | One unit of the depth in scope. Cards, tiles, popovers that sit close. |
138
- | `.floating` | Twice it, for menus and popovers. |
145
+ Elevation is how much depth a component takes. Nothing has a shadow until an [aesthetic](./aesthetics.md) draws depth or one of these classes asks for it.
139
146
 
140
- These are a different thing from the raw `--elevation-*` shadow tokens in [Theming](./theming.md#foundation-tokens), which are fixed shadows for elements you style yourself.
141
-
142
- Each is one unitless multiplier over whatever shadow geometry is in scope, so the same class reads as a soft blur on a plain page and as a hard offset slab under `.neobrutalism` — the aesthetic decides what depth looks like, the class decides how much of it this element takes.
147
+ | Class | Depth |
148
+ | ----------- | ------------------------------------------------------------------------------------ |
149
+ | `.flat` | None. Glass surfaces keep their shadow, because it is part of what glass is made of. |
150
+ | `.raised` | One step of the depth in scope: cards and tiles that sit close to the page. |
151
+ | `.floating` | Two steps: menus and popovers. |
143
152
 
144
153
  ```html
145
154
  <article class="card raised">Lifted</article>
146
- <div class="floating panel">A menu surface</div>
147
- <article class="card flat">Flat, whatever the page or container says</article>
155
+ <div class="floating panel">A menu</div>
156
+ <article class="card flat">Flat, whatever the aesthetic says</article>
148
157
  ```
149
158
 
150
- The multiplier does not inherit: an elevation class lifts or flattens the element it is written on only, and an unclassed element inside it takes no depth of its own. Give each element that needs depth its own elevation class. Spread is deliberately left out of the multiplication, because an aesthetic that draws its edge as an inset ring spends spread on it and scaling that would erase the edge.
159
+ Each class multiplies the shadow of the aesthetic in scope. The same `.raised` is a soft blur on a plain page and a hard offset shadow under `.neobrutalism`: the aesthetic decides what depth looks like, and the class decides how much of it this element takes.
160
+
161
+ The class does not pass down. It lifts or flattens only the element it is on, and an element inside it takes no depth from it. Give each element that needs depth its own class. The spread of a shadow is not multiplied, because an aesthetic that draws its border as an inner shadow uses the spread for that border.
162
+
163
+ These classes are separate from the `--elevation-*` shadow tokens in [Theming → Foundation tokens](./theming.md#foundation-tokens), which are fixed shadows for elements you style yourself.