@codenhub/styles 0.5.0 → 0.6.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 (59) hide show
  1. package/README.md +7 -7
  2. package/dist/aesthetics/chunky-tile.css +1 -1
  3. package/dist/aesthetics/cyber.css +1 -1
  4. package/dist/aesthetics/glass.css +1 -1
  5. package/dist/aesthetics/index.css +1 -1
  6. package/dist/aesthetics/neobrutalism.css +1 -1
  7. package/dist/aesthetics/pixel.css +1 -1
  8. package/dist/aesthetics/sketch.css +1 -1
  9. package/dist/components.css +1 -1
  10. package/dist/index.css +1 -1
  11. package/dist/native.css +1 -1
  12. package/dist/palette.css +1 -1
  13. package/dist/theme.css +1 -1
  14. package/dist/tw/aesthetics/chunky-tile.css +39 -39
  15. package/dist/tw/aesthetics/cyber.css +16 -11
  16. package/dist/tw/aesthetics/glass.css +235 -10
  17. package/dist/tw/aesthetics/index.css +2 -1
  18. package/dist/tw/aesthetics/neobrutalism.css +23 -11
  19. package/dist/tw/aesthetics/pixel.css +18 -8
  20. package/dist/tw/aesthetics/sketch.css +14 -7
  21. package/dist/tw/box.css +49 -27
  22. package/dist/tw/components/button.css +35 -14
  23. package/dist/tw/components/feedback.css +59 -56
  24. package/dist/tw/components/form.css +200 -126
  25. package/dist/tw/components/index.css +3 -7
  26. package/dist/tw/components/loader.css +4 -5
  27. package/dist/tw/components/surface.css +71 -68
  28. package/dist/tw/components/tooltip.css +75 -41
  29. package/dist/tw/elevation.css +14 -22
  30. package/dist/tw/index.css +15 -19
  31. package/dist/tw/intent.css +31 -24
  32. package/dist/tw/native.css +15 -5
  33. package/dist/tw/palette.css +8 -5
  34. package/dist/tw/presentation.css +16 -30
  35. package/dist/tw/reset.css +21 -28
  36. package/dist/tw/surface.css +11 -12
  37. package/dist/tw/theme.css +58 -86
  38. package/dist/tw/utilities/content.css +268 -199
  39. package/dist/tw/utilities/layout.css +15 -25
  40. package/docs/accessibility.md +50 -33
  41. package/docs/changelog/0.6.0.md +52 -0
  42. package/docs/changelog/index.md +1 -0
  43. package/docs/concepts.md +6 -6
  44. package/docs/index.md +9 -0
  45. package/docs/integrating/nextjs.md +1 -1
  46. package/docs/integrating/tailwind.md +14 -6
  47. package/docs/setup.md +6 -6
  48. package/docs/usage/aesthetics.md +35 -8
  49. package/docs/usage/buttons.md +1 -1
  50. package/docs/usage/composing.md +1 -1
  51. package/docs/usage/content-and-layout.md +12 -11
  52. package/docs/usage/customizing.md +8 -9
  53. package/docs/usage/feedback.md +5 -3
  54. package/docs/usage/forms.md +51 -35
  55. package/docs/usage/theming.md +39 -40
  56. package/docs/usage/tooltips.md +37 -17
  57. package/llms-full.txt +331 -183
  58. package/llms.txt +6 -0
  59. package/package.json +5 -5
@@ -17,6 +17,18 @@
17
17
  @apply box box-hover box-active relative inline-flex w-fit cursor-pointer items-center justify-center gap-2 px-4 py-2 whitespace-nowrap no-underline select-none;
18
18
 
19
19
  min-height: var(--control-height);
20
+ /* The vertical padding gives back the line `box` draws, so a default button
21
+ is exactly `--control-height` tall like `.ipt` beside it, under any
22
+ aesthetic's line width. At the default 16px/1.5 text the label and the
23
+ padding fill it; the size and padding modifiers set their own. */
24
+ padding-block: calc(0.5rem - var(--_width));
25
+ /* The surrounding font, not the user agent's smaller button one, on every
26
+ entry: `/components` carries no reset to say so, and a `.btn` link and a
27
+ `.btn` button have to print the same label. `.sm` and `.lg` set their own
28
+ size over this. */
29
+ font-family: inherit;
30
+ font-size: inherit;
31
+ line-height: inherit;
20
32
  /* The label is material, shared with `.badge`: weight, tracking, case, and a
21
33
  text shadow, set by an aesthetic as tokens (`.chunky-tile`'s heavier,
22
34
  tracked label), and a consumer's own `font-*`, `tracking-*`, `uppercase`, or
@@ -50,20 +62,29 @@
50
62
  min-width: var(--control-height);
51
63
  }
52
64
 
53
- /* Bare `sm`/`lg` are already the size modifier's class names, so `p-`
54
- prefixes here to avoid colliding with a button's own size. `.p-xs` is the
55
- tightest step, below `.p-sm`: a chip-sized button in a toolbar or a table
56
- cell.
57
-
58
- `.icon` drops both floors -- `min-width` from its own base rule below and
59
- `min-height` from `--control-height` -- at every padding tier, labeled
60
- buttons keep the height floor everywhere but `.p-xs`. `.icon`
61
- already asks to be square: `aspect-square` ties its width to whatever
62
- height it lands on, so a height floor that survives keeps the button
63
- bigger than its own glyph regardless of how tight the padding asked to be
64
- -- the one combination `.p-xs` used to get right and the other two tiers
65
- did not, leaving a `.icon.p-sm` floating in a box far bigger than it
66
- needed and a `.icon.p-lg` doing the same one step further out. */
65
+ /* The size steps for an icon button, square at each: `.sm`'s 2rem, with the
66
+ padding giving back the line width the way the default button's does, and
67
+ `.lg`'s 3rem. Each names its width as well as its height, because WebKit
68
+ does not let `aspect-ratio` widen a box past its `min-width`. */
69
+ &.icon.sm {
70
+ min-width: 2rem;
71
+ padding: calc(0.375rem - var(--_width));
72
+ }
73
+
74
+ &.icon.lg {
75
+ min-width: 3rem;
76
+ }
77
+
78
+ /* Bare `sm`/`lg` are the size modifier's class names, so `p-` prefixes here.
79
+ `.p-xs` is the tightest step, below `.p-sm`: a chip-sized button in a
80
+ toolbar or a table cell.
81
+
82
+ `.icon` drops both floors -- `min-width` from its own base rule above and
83
+ `min-height` from `--control-height` -- at every padding tier; labeled
84
+ buttons keep the height floor everywhere but `.p-xs`. `.icon` is already
85
+ square: `aspect-square` ties its width to whatever height it lands on, so a
86
+ surviving height floor would keep the button bigger than its own glyph
87
+ however tight the padding asked to be. */
67
88
  &.p-xs {
68
89
  @apply px-2 py-0.5;
69
90
 
@@ -38,50 +38,45 @@
38
38
  --_d-elevation: 0;
39
39
 
40
40
  /* Same carve-out as `.panel`'s, and for the same reason: a neutral alert
41
- mixes 12% of near-black ink onto the page, measured `217, 217, 217`
42
- against `250, 250, 250` -- the identical slab `.panel` read before its
43
- own fix, not a status-signaling problem, since this is scoped to no
44
- named intent. A named intent keeps its ordinary wash; untinting
45
- `.alert.soft.destructive` too would silence the status it exists to
46
- carry rather than quiet it, which is why an earlier, unconditional
47
- version of this fix was rejected for `.alert` specifically. This
48
- version never reaches that case: `:not(...)` names every intent class,
49
- plus `.solid`/`.ghost` so an explicit presentation on the element is
50
- never clamped to a cap it did not ask for.
51
-
52
- Grounds on `--color-foreground` through `--_d-surface-ground`, exactly
53
- like `.panel` and a resting `.card.soft`, so glass's ground and a
54
- consumer's `--ui-surface-ground` still win over it -- an
55
- alert has no hover state to reveal a tint into either, so this is
56
- permanent rather than revealed. Unlike a neutral panel or badge, an
57
- alert cannot lose its visual identity from this: `--_d-border: 100%`
58
- above holds regardless of fill, so a neutral alert still reads as a
59
- framed box, just a quiet one instead of a grey slab. */
41
+ mixes 12% of near-black ink onto the page (`217, 217, 217` against `250,
42
+ 250, 250`), a slab rather than a status signal. Scoped to no named intent:
43
+ a named intent keeps its ordinary wash, because untinting
44
+ `.alert.soft.destructive` would silence the status it exists to carry
45
+ rather than quiet it. `:not(...)` names every intent class, plus
46
+ `.solid`/`.ghost` so an explicit presentation on the element is never
47
+ clamped to a cap it did not ask for.
48
+
49
+ Grounds on `--color-foreground` through `--_d-surface-ground`, exactly like
50
+ `.panel` and a resting `.card.soft`, so glass's ground and a consumer's
51
+ `--ui-surface-ground` still win over it. An alert has no hover state to
52
+ reveal a tint into either, so this is permanent. A neutral alert keeps its
53
+ identity: `--_d-border: 100%` above holds regardless of fill, so it still
54
+ reads as a framed box, just a quiet one instead of a grey slab. */
60
55
  &:not(.primary, .secondary, .success, .warning, .destructive, .info, .solid, .ghost) {
61
56
  --_fill-cap: 0%;
62
57
  --_d-surface-ground: var(--color-foreground);
63
58
  }
64
59
  }
65
60
 
66
- /* No icon is shipped: the five hardcoded per-intent masks this used to paint on
67
- a `::before` are gone, the same way the per-input-type icon was removed from
68
- `.input-group` -- see `docs/internal/model.md#input-group-owns-the-box-the-control-inside-gives-it-up`.
69
- `.alert` is
70
- already `flex`, so an icon dropped in as a real child is spaced by `gap-3`
71
- with nothing to trigger: `.alert-icon` only fixes its size and alignment, not
72
- whether one is present. Any icon element works, the same contract
73
- `.input-group` documents -- an inline `<svg>`, an `<img>`, or a class from an
74
- icon set such as `@codenhub/icons`. */
61
+ /* No icon is shipped. `.alert` is already `flex`, so an icon dropped in as a
62
+ real child is spaced by `gap-3`: `.alert-icon` only fixes its size and
63
+ alignment, not whether one is present. Any icon element works, the same
64
+ contract `.input-group` documents -- an inline `<svg>`, an `<img>`, or a
65
+ class from an icon set such as `@codenhub/icons`. See
66
+ `docs/internal/model.md#input-group-owns-the-box-the-control-inside-gives-it-up`. */
75
67
  @utility alert-icon {
76
68
  @apply inline-flex flex-none items-center justify-center;
77
69
 
78
- /* `!important`: an icon-set glyph (`@codenhub/icons` among them) carries its
79
- own `width`/`height` on a selector this utility cannot outrank -- an
80
- attribute selector reads more specific than one class regardless of
81
- stylesheet order. Sizing what you drop in is this utility's one job, so it
82
- has to win over the glyph's own opinion. */
83
- width: 1.25rem !important;
84
- height: 1.25rem !important;
70
+ /* A `@codenhub/icons` glyph sizes itself in an unlayered rule, which no
71
+ layered rule outranks whatever its specificity, but it reads its size from
72
+ `--ic-size`, so the size goes there as well as on the box for any other
73
+ icon. No `!important`: that would shut out the consumer's own resize too.
74
+ An icon set with another prefix, or one that sizes unlayered with no knob,
75
+ keeps its own size. */
76
+ --ic-size: 1.25rem;
77
+
78
+ width: 1.25rem;
79
+ height: 1.25rem;
85
80
  }
86
81
 
87
82
  /* A soft, edgeless chip. Small enough that the structural silhouette would be
@@ -111,10 +106,7 @@
111
106
 
112
107
  /* An indicator reads intent and no presentation token at all. It is a stand-in
113
108
  for content rather than a box with a look of its own, so there is nothing for
114
- a container's `.solid` or `.edgeless` to say about it -- which is also what
115
- removes the visibility floor that used to fight `--ui-fill` for control of the
116
- base tone, and the transparent border that only ever appeared if something up
117
- the tree asked for an edge. */
109
+ a container's `.solid` or `.edgeless` to say about it. */
118
110
  @utility skeleton {
119
111
  --skeleton-base: color-mix(in oklab, var(--intent-color) 6%, var(--intent-subtle));
120
112
  --skeleton-sheen: color-mix(in oklab, var(--intent-color) 10%, var(--color-foreground));
@@ -133,6 +125,12 @@
133
125
  calc(var(--_corner) * var(--ui-corner-br, 1)) calc(var(--_corner) * var(--ui-corner-bl, 1))
134
126
  );
135
127
  corner-shape: var(--ui-corner-shape, round);
128
+
129
+ /* Reduced motion stops the shimmer here, for the entries without the reset;
130
+ see `box.css`. The gradient stays, so the placeholder still reads. */
131
+ @media (prefers-reduced-motion: reduce) {
132
+ animation: none;
133
+ }
136
134
  }
137
135
 
138
136
  /* The track is a box, the fill is not: `box.css`'s formula composes the frame,
@@ -161,17 +159,16 @@
161
159
  not `.pre`/`.code`/`.kbd`'s opaque `--intent-subtle` ground. */
162
160
  --_progress-surface: color-mix(in oklab, var(--intent-color) var(--_progress-fill), transparent);
163
161
  /* One `color-mix()`, not `box`/`.quote`'s two chained through a `--_line`
164
- step: a WebKit build measurably destabilizes composing dozens of tracks
165
- each carrying a three-level color-mix chain into the same page -- fine
166
- at ten, a reproducible ~30-minute CI hang at forty, isolated by removing
167
- one variable at a time (element count, then border at all, then chain
168
- depth) until only chain depth reproduced it. `box`/`.quote`'s extra step
169
- blends the line toward the fill first so a heavily filled box does not
170
- draw a ring of a different colour around its own plate -- a real risk up
171
- to `.solid`'s 100% fill. `.progress` never reaches that: `.solid` is
172
- unsupported here (`registry.json`), so the fill this reads never exceeds
173
- `.soft`'s 12%, and mixing straight from `--intent-border` at that fill
174
- is indistinguishable from blending through the surface first. */
162
+ step: a WebKit build destabilizes when composing dozens of tracks each
163
+ carrying a three-level color-mix chain into one page (fine at ten, a
164
+ ~30-minute CI hang at forty; only chain depth reproduces it).
165
+ `box`/`.quote`'s extra step blends the line toward the fill first so a
166
+ heavily filled box does not draw a ring of a different colour around its
167
+ own plate -- a real risk up to `.solid`'s 100% fill. `.progress` never
168
+ reaches that: `.solid` is unsupported here (`registry.json`), so the fill
169
+ this reads never exceeds `.soft`'s 12%, and mixing straight from
170
+ `--intent-border` at that fill is indistinguishable from blending through
171
+ the surface first. */
175
172
  --_progress-edge: color-mix(in oklab, var(--intent-border) var(--ui-border, var(--_d-border)), transparent);
176
173
 
177
174
  @apply relative h-2.5 w-full overflow-hidden;
@@ -213,13 +210,19 @@
213
210
  &.indeterminate::after {
214
211
  width: 33%;
215
212
  animation: anim-progress-indeterminate 1.5s infinite ease-in-out;
216
- /* No logical form exists for transform-origin, so the inline-start edge
217
- is named directly and mirrored under :dir(rtl) to match the
218
- inset-inline-start positioning above. */
219
- transform-origin: left;
213
+ }
214
+
215
+ /* Reduced motion, for the entries without the reset; see `box.css`. The
216
+ value moves without sliding, and the shimmer and the indeterminate sweep
217
+ stop where the reset would stop them: the fill rests at the start. */
218
+ @media (prefers-reduced-motion: reduce) {
219
+ &::after {
220
+ transition-duration: 0.01ms;
221
+ }
220
222
 
221
- :dir(rtl) & {
222
- transform-origin: right;
223
+ &.active::before,
224
+ &.indeterminate::after {
225
+ animation: none;
223
226
  }
224
227
  }
225
228
  }