@codenhub/styles 0.0.4 → 0.1.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 (71) hide show
  1. package/LICENSE +201 -201
  2. package/NOTICE +27 -0
  3. package/README.md +60 -92
  4. package/dist/aesthetics/chunky-tile.css +1 -0
  5. package/dist/aesthetics/glass.css +1 -0
  6. package/dist/aesthetics/index.css +2 -0
  7. package/dist/aesthetics/neobrutalism.css +1 -0
  8. package/dist/aesthetics/pixel.css +1 -0
  9. package/dist/components.css +2 -2
  10. package/dist/index.css +2 -2
  11. package/dist/native.css +2 -0
  12. package/dist/theme.css +2 -2
  13. package/dist/tw/aesthetics/chunky-tile.css +107 -0
  14. package/dist/tw/aesthetics/glass.css +66 -0
  15. package/dist/tw/aesthetics/index.css +9 -0
  16. package/dist/tw/aesthetics/neobrutalism.css +63 -0
  17. package/dist/tw/aesthetics/pixel.css +88 -0
  18. package/dist/tw/box.css +185 -0
  19. package/dist/tw/components/button.css +88 -0
  20. package/dist/tw/components/feedback.css +163 -0
  21. package/dist/tw/components/form.css +601 -0
  22. package/dist/tw/components/index.css +18 -0
  23. package/dist/tw/components/loader.css +122 -0
  24. package/dist/tw/components/surface.css +98 -0
  25. package/dist/tw/components/tooltip.css +132 -0
  26. package/dist/tw/elevation.css +39 -0
  27. package/dist/tw/index.css +12 -0
  28. package/dist/tw/intent.css +189 -0
  29. package/dist/tw/native.css +203 -0
  30. package/dist/tw/presentation.css +77 -0
  31. package/dist/tw/reset.css +142 -0
  32. package/dist/tw/theme.css +218 -0
  33. package/dist/tw/typography.css +34 -0
  34. package/dist/tw/utilities/content.css +349 -0
  35. package/dist/tw/utilities/index.css +6 -0
  36. package/dist/tw/utilities/layout.css +107 -0
  37. package/docs/accessibility.md +82 -0
  38. package/docs/concepts.md +94 -0
  39. package/docs/index.md +62 -0
  40. package/docs/integrating/astro.md +29 -0
  41. package/docs/integrating/index.md +32 -0
  42. package/docs/integrating/nextjs.md +44 -0
  43. package/docs/integrating/svelte.md +37 -0
  44. package/docs/integrating/tailwind.md +40 -0
  45. package/docs/integrating/vue.md +25 -0
  46. package/docs/setup.md +116 -0
  47. package/docs/usage/aesthetics.md +197 -0
  48. package/docs/usage/buttons.md +74 -0
  49. package/docs/usage/composing.md +218 -0
  50. package/docs/usage/content-and-layout.md +200 -0
  51. package/docs/usage/customizing.md +213 -0
  52. package/docs/usage/feedback.md +117 -0
  53. package/docs/usage/forms.md +177 -0
  54. package/docs/usage/index.md +32 -0
  55. package/docs/usage/theming.md +210 -0
  56. package/docs/usage/tooltips.md +45 -0
  57. package/llms-full.txt +2122 -0
  58. package/llms.txt +26 -0
  59. package/package.json +95 -29
  60. package/src/components/button.css +0 -155
  61. package/src/components/feedback.css +0 -214
  62. package/src/components/form.css +0 -303
  63. package/src/components/index.css +0 -9
  64. package/src/components/loader.css +0 -56
  65. package/src/components/surface.css +0 -6
  66. package/src/components/tooltip.css +0 -60
  67. package/src/index.css +0 -7
  68. package/src/overrides.css +0 -76
  69. package/src/theme.css +0 -234
  70. package/src/typography.css +0 -30
  71. package/src/utilities.css +0 -40
@@ -0,0 +1,88 @@
1
+ @reference "tailwindcss";
2
+ @import "../theme.css";
3
+ @reference "./loader.css";
4
+ @reference "../box.css";
5
+
6
+ /* A filled, edgeless, raised box you can press. `box` paints it; everything
7
+ here is what makes it a button rather than some other box.
8
+
9
+ The resting values are the published default: a button with no presentation
10
+ class is solid and edgeless, and that is a decision written on three lines
11
+ rather than a `var()` fallback buried in an expression. */
12
+ @utility btn {
13
+ --_d-fill: 100%;
14
+ --_d-fg-on-fill: 100%;
15
+ --_d-border: 0%;
16
+ --_d-elevation: 1;
17
+
18
+ @apply box box-hover box-active relative inline-flex w-fit cursor-pointer items-center justify-center gap-2 px-4 py-2 font-semibold whitespace-nowrap no-underline select-none;
19
+
20
+ min-height: var(--control-height);
21
+
22
+ &.sm {
23
+ @apply min-h-8 px-3 py-1 text-sm;
24
+ }
25
+
26
+ &.lg {
27
+ @apply min-h-12 px-5 py-2.5 text-[1.0625rem];
28
+ }
29
+
30
+ &.icon {
31
+ @apply aspect-square p-2;
32
+
33
+ min-width: var(--control-height);
34
+ }
35
+
36
+ /* `.p-sm`/`.p-lg` are the canonical names, matching the `sm`/`md`/`lg`
37
+ vocabulary the elevation modifier uses; `.compact`/`.spacious` are
38
+ first-class aliases, not a deprecation shim -- the same pattern
39
+ `.destructive`/`.danger`/`.error` uses on the intent axis. Bare `sm`/`lg`
40
+ are already the size modifier's class names, so `p-` prefixes here to
41
+ avoid colliding with a button's own size. */
42
+ &.p-sm,
43
+ &.compact {
44
+ @apply px-2.5 py-1;
45
+
46
+ &.icon {
47
+ @apply p-1;
48
+ }
49
+ }
50
+
51
+ &.p-lg,
52
+ &.spacious {
53
+ @apply px-6 py-3;
54
+
55
+ &.icon {
56
+ @apply p-3;
57
+ }
58
+ }
59
+
60
+ &.pill {
61
+ @apply rounded-full;
62
+ }
63
+
64
+ &.loading {
65
+ /* `text-transparent!` forces the label invisible whatever the intent
66
+ resolved to, so the spinner is the only thing left to read. */
67
+ @apply pointer-events-none text-transparent!;
68
+
69
+ & > * {
70
+ opacity: 0 !important;
71
+ }
72
+
73
+ /* The spinner takes the label's colour, which `box` already resolved
74
+ against this button's own intent and presentation. It reads `--_fg`
75
+ rather than `currentColor`: the rule above forces `color` to transparent
76
+ to hide the label, and a spinner painted in `currentColor` inherits that
77
+ and paints nothing at all. */
78
+ &::after {
79
+ @apply loader-mask absolute block size-4 -translate-x-1/2 -translate-y-1/2;
80
+
81
+ background-color: var(--_fg);
82
+
83
+ top: calc(50% + var(--border-width));
84
+ left: calc(50% + var(--border-width));
85
+ content: "";
86
+ }
87
+ }
88
+ }
@@ -0,0 +1,163 @@
1
+ @reference "tailwindcss";
2
+ @import "../theme.css";
3
+ @reference "../box.css";
4
+ @reference "./surface.css";
5
+
6
+ @keyframes anim-skeleton {
7
+ 0% {
8
+ background-position: 200% 0;
9
+ }
10
+
11
+ 100% {
12
+ background-position: -200% 0;
13
+ }
14
+ }
15
+
16
+ @keyframes anim-progress-indeterminate {
17
+ 0% {
18
+ inset-inline-start: -33%;
19
+ width: 33%;
20
+ }
21
+ 50% {
22
+ width: 40%;
23
+ }
24
+ 100% {
25
+ inset-inline-start: 100%;
26
+ width: 33%;
27
+ }
28
+ }
29
+
30
+ /* A soft, edged surface, so an aesthetic that blurs surfaces blurs this too: an
31
+ alert is a container carrying a message, not a control. */
32
+ @utility alert {
33
+ @apply surface flex p-4 leading-5;
34
+
35
+ --_d-fill: 12%;
36
+ --_d-fg-on-fill: 0%;
37
+ --_d-border: 100%;
38
+ --_d-elevation: 0;
39
+
40
+ &.icon {
41
+ @apply relative ps-11;
42
+
43
+ &::before {
44
+ @apply absolute start-4 top-4 block size-5 bg-current;
45
+
46
+ content: "";
47
+ mask-image: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'/><path d='M12 16v-4'/><path d='M12 8h.01'/></svg>");
48
+ -webkit-mask-image: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'/><path d='M12 16v-4'/><path d='M12 8h.01'/></svg>");
49
+ mask-size: contain;
50
+ -webkit-mask-size: contain;
51
+ mask-repeat: no-repeat;
52
+ -webkit-mask-repeat: no-repeat;
53
+ mask-position: center;
54
+ -webkit-mask-position: center;
55
+ }
56
+
57
+ &.success::before {
58
+ mask-image: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'/><path d='m9 12 2 2 4-4'/></svg>");
59
+ -webkit-mask-image: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'/><path d='m9 12 2 2 4-4'/></svg>");
60
+ }
61
+
62
+ &.warning::before {
63
+ mask-image: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z'/><path d='M12 9v4'/><path d='M12 17h.01'/></svg>");
64
+ -webkit-mask-image: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z'/><path d='M12 9v4'/><path d='M12 17h.01'/></svg>");
65
+ }
66
+
67
+ &.destructive::before,
68
+ &.danger::before,
69
+ &.error::before {
70
+ mask-image: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'/><path d='m15 9-6 6'/><path d='m9 9 6 6'/></svg>");
71
+ -webkit-mask-image: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'/><path d='m15 9-6 6'/><path d='m9 9 6 6'/></svg>");
72
+ }
73
+
74
+ &.info::before {
75
+ mask-image: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'/><path d='M12 16v-4'/><path d='M12 8h.01'/></svg>");
76
+ -webkit-mask-image: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'/><path d='M12 16v-4'/><path d='M12 8h.01'/></svg>");
77
+ }
78
+ }
79
+ }
80
+
81
+ /* A soft, edgeless chip. Small enough that the structural silhouette would be
82
+ most of its height, so it takes the tight one where an aesthetic ships a pair. */
83
+ @utility badge {
84
+ --_d-fill: 12%;
85
+ --_d-fg-on-fill: 0%;
86
+ --_d-border: 0%;
87
+ --_d-elevation: 0;
88
+
89
+ @apply box inline-flex min-h-6 w-fit items-center gap-1 px-2.5 text-xs font-bold;
90
+
91
+ /* Pill by default, but an aesthetic that declares no radius has to mean it, so
92
+ the round corner is this component's fallback rather than a hardcoded value. */
93
+ border-radius: var(--ui-radius, calc(infinity * 1px));
94
+ clip-path: var(--ui-clip-tight, var(--ui-clip, none));
95
+ }
96
+
97
+ /* An indicator reads intent and no presentation token at all. It is a stand-in
98
+ for content rather than a box with a look of its own, so there is nothing for
99
+ a container's `.solid` or `.edgeless` to say about it -- which is also what
100
+ removes the visibility floor that used to fight `--ui-fill` for control of the
101
+ base tone, and the transparent border that only ever appeared if something up
102
+ the tree asked for an edge. */
103
+ @utility skeleton {
104
+ --skeleton-base: color-mix(in oklab, var(--intent-color) 6%, var(--intent-subtle));
105
+ --skeleton-sheen: color-mix(in oklab, var(--intent-color) 10%, var(--color-foreground));
106
+
107
+ @apply min-h-4 w-full;
108
+
109
+ animation: anim-skeleton calc(var(--motion-duration-slow) * 4) linear infinite;
110
+ background: linear-gradient(90deg, var(--skeleton-base), var(--skeleton-sheen), var(--skeleton-base));
111
+ background-size: 200% 100%;
112
+ border-radius: var(--ui-radius, var(--radius-control));
113
+ }
114
+
115
+ /* The same: intent only. The track is 10px tall, which is most of a border under
116
+ any aesthetic thick enough to have an opinion, so the bar draws no edge and the
117
+ ceilings that used to keep one survivable are gone with it. */
118
+ @utility progress {
119
+ --progress-color: var(--intent-color);
120
+ --progress-surface: color-mix(in srgb, var(--intent-subtle) 60%, transparent);
121
+
122
+ @apply relative h-2.5 w-full overflow-hidden bg-(--progress-surface);
123
+ /* Round by default; an aesthetic that declares no radius squares the track and
124
+ its fill together. */
125
+ border-radius: var(--ui-radius, calc(infinity * 1px));
126
+
127
+ &::after {
128
+ content: "";
129
+ @apply absolute start-0 top-0 bottom-0 block h-full transition-[width] duration-(--motion-duration-slow) ease-(--motion-ease);
130
+
131
+ border-radius: var(--ui-radius, calc(infinity * 1px));
132
+ background-color: var(--progress-color);
133
+ width: var(--progress-value, 0%);
134
+ z-index: 2;
135
+ }
136
+
137
+ &.active::before {
138
+ content: "";
139
+ @apply absolute inset-0 block h-full;
140
+ animation: anim-skeleton calc(var(--motion-duration-slow) * 4) linear infinite;
141
+ background: linear-gradient(
142
+ 90deg,
143
+ transparent,
144
+ color-mix(in srgb, var(--progress-color) 15%, transparent),
145
+ transparent
146
+ );
147
+ background-size: 200% 100%;
148
+ z-index: 1;
149
+ }
150
+
151
+ &.indeterminate::after {
152
+ width: 33%;
153
+ animation: anim-progress-indeterminate 1.5s infinite ease-in-out;
154
+ /* No logical form exists for transform-origin, so the inline-start edge
155
+ is named directly and mirrored under :dir(rtl) to match the
156
+ inset-inline-start positioning above. */
157
+ transform-origin: left;
158
+
159
+ :dir(rtl) & {
160
+ transform-origin: right;
161
+ }
162
+ }
163
+ }