@crazy-staff/ui 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,82 @@
1
1
  {
2
2
  "name": "@crazy-staff/ui",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.2.0",
4
+ "description": "The design system of crazy-staff: React components on Base UI, Tailwind CSS 4 and tailwind-variants.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/crazy-staff/crazy-ui.git",
9
+ "directory": "packages/ui"
10
+ },
11
+ "type": "module",
12
+ "sideEffects": [
13
+ "**/*.css"
14
+ ],
15
+ "files": [
16
+ "dist",
17
+ "src/styles/theme.css",
18
+ "README.md",
19
+ "LICENSE",
20
+ "CHANGELOG.md"
21
+ ],
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/index.d.ts",
25
+ "import": "./dist/index.js"
26
+ },
27
+ "./theme.css": "./src/styles/theme.css",
28
+ "./package.json": "./package.json"
29
+ },
30
+ "publishConfig": {
31
+ "access": "public"
32
+ },
33
+ "scripts": {
34
+ "build": "tsdown",
35
+ "typecheck": "tsc --noEmit",
36
+ "test": "vitest run"
37
+ },
38
+ "peerDependencies": {
39
+ "react": "^19.0.0",
40
+ "react-dom": "^19.0.0",
41
+ "tailwindcss": "^4.0.0"
42
+ },
43
+ "dependencies": {
44
+ "@base-ui/react": "1.9.0",
45
+ "@tanstack/charts": "1.5.0",
46
+ "@tanstack/react-charts": "1.5.0",
47
+ "@tanstack/react-table": "9.3.1",
48
+ "clsx": "^2.1.1",
49
+ "embla-carousel-react": "8.6.0",
50
+ "hyperellipse": "1.0.5",
51
+ "lucide-react": "^1.72.0",
52
+ "motion": "^14.13.0",
53
+ "react-resizable-panels": "^4.21.0",
54
+ "shiki": "4.6.0",
55
+ "tailwind-merge": "^3.7.0",
56
+ "tailwind-variants": "^4.0.2"
57
+ },
58
+ "devDependencies": {
59
+ "@testing-library/jest-dom": "^7.0.1",
60
+ "@testing-library/react": "^16.3.3",
61
+ "@testing-library/user-event": "^14.6.10",
62
+ "@types/react": "^19.3.0",
63
+ "@types/react-dom": "^19.3.0",
64
+ "@vitejs/plugin-react": "^6.3.0",
65
+ "jsdom": "^31.0.1",
66
+ "react": "^19.3.1",
67
+ "react-dom": "^19.3.1",
68
+ "tailwindcss": "^4.3.5",
69
+ "tsdown": "^0.23.7",
70
+ "typescript": "7.0.2",
71
+ "vitest": "^5.1.0"
72
+ },
73
+ "homepage": "https://github.com/crazy-staff/crazy-ui#readme",
74
+ "keywords": [
75
+ "react",
76
+ "design-system",
77
+ "components",
78
+ "base-ui",
79
+ "tailwindcss",
80
+ "crazy-staff"
81
+ ]
82
+ }
@@ -0,0 +1,247 @@
1
+ /*
2
+ * crazy-ui theme
3
+ *
4
+ * Every visual decision is a CSS variable with the `--cui-` prefix. Apps override any of them
5
+ * (colours, radii, shadows, fonts, density, motion) on `:root`, on `.dark`, or on any subtree.
6
+ * Tailwind utilities read the variables through `@theme inline`, so overrides on a subtree work
7
+ * without rebuilding CSS: `bg-accent`, `rounded-control`, `shadow-card`, `h-control`, `font-heading`.
8
+ *
9
+ * Look (design round 1, owner's pick): our own twist on fumadocs.dev — its neutral palette (as in
10
+ * crazy-hub) with the Crazy purple, a little softer and rounder. Corners are superellipses (CSS
11
+ * `corner-shape`, polyfilled by `registerSquircles()` in Firefox and Safari) and the radius
12
+ * shrinks with the element: chips < small controls < controls < cards < panels.
13
+ *
14
+ * Usage in an app stylesheet:
15
+ * @import 'tailwindcss';
16
+ * @import '@crazy-staff/ui/theme.css';
17
+ * @source '../node_modules/@crazy-staff/ui/dist';
18
+ * and once on the client: `registerSquircles()` from '@crazy-staff/ui'.
19
+ */
20
+
21
+ /* Components never use `dark:`; dark mode only swaps token values. */
22
+
23
+ @theme inline {
24
+ --color-background: var(--cui-background);
25
+ --color-foreground: var(--cui-foreground);
26
+ --color-frame: var(--cui-frame);
27
+ --color-surface: var(--cui-surface);
28
+ --color-surface-2: var(--cui-surface-2);
29
+ --color-popover: var(--cui-popover);
30
+ --color-hover: var(--cui-hover);
31
+ --color-muted: var(--cui-muted);
32
+ --color-border: var(--cui-border);
33
+ --color-border-strong: var(--cui-border-strong);
34
+ --color-input: var(--cui-input);
35
+ --color-input-border: var(--cui-input-border);
36
+ --color-ring: var(--cui-ring);
37
+ --color-accent: var(--cui-accent);
38
+ --color-accent-foreground: var(--cui-accent-foreground);
39
+ --color-accent-soft: var(--cui-accent-soft);
40
+ --color-accent-soft-foreground: var(--cui-accent-soft-foreground);
41
+ --color-danger: var(--cui-danger);
42
+ --color-danger-foreground: var(--cui-danger-foreground);
43
+ --color-success: var(--cui-success);
44
+ --color-warning: var(--cui-warning);
45
+
46
+ /* `--corner-scale` is 1 where `corner-shape` is native and while the polyfill measures;
47
+ before the polyfill runs it shrinks squircle radii so they don't flash too round. */
48
+ --radius-chip: calc(var(--cui-radius-chip) * var(--corner-scale, 1));
49
+ --radius-control-sm: calc(var(--cui-radius-control-sm) * var(--corner-scale, 1));
50
+ --radius-control: calc(var(--cui-radius-control) * var(--corner-scale, 1));
51
+ --radius-control-lg: calc(var(--cui-radius-control-lg) * var(--corner-scale, 1));
52
+ --radius-item: calc(var(--cui-radius-item) * var(--corner-scale, 1));
53
+ --radius-card: calc(var(--cui-radius-card) * var(--corner-scale, 1));
54
+ --radius-panel: calc(var(--cui-radius-panel) * var(--corner-scale, 1));
55
+ --radius-switch: var(--cui-radius-switch);
56
+
57
+ --shadow-control: var(--cui-shadow-control);
58
+ --shadow-button: var(--cui-shadow-button);
59
+ --shadow-glow: var(--cui-shadow-glow);
60
+ --shadow-card: var(--cui-shadow-card);
61
+ --shadow-card-hover: var(--cui-shadow-card-hover);
62
+ --shadow-overlay: var(--cui-shadow-overlay);
63
+
64
+ --font-sans: var(--cui-font-sans);
65
+ --font-mono: var(--cui-font-mono);
66
+ --font-heading: var(--cui-font-heading);
67
+
68
+ --spacing-control: var(--cui-control-height);
69
+ --spacing-control-sm: calc(var(--cui-control-height) * 0.78);
70
+ --spacing-control-lg: calc(var(--cui-control-height) * 1.2);
71
+
72
+ --ease-ui: var(--cui-ease);
73
+ --ease-spring: var(--cui-ease-spring);
74
+ }
75
+
76
+ /* Squircle corners. The custom property is what the polyfill looks for. */
77
+ @utility squircle {
78
+ --corner-shape: var(--cui-corner-shape);
79
+ corner-shape: var(--cui-corner-shape);
80
+ }
81
+ @supports not (corner-shape: squircle) {
82
+ .squircle {
83
+ --corner-scale: 0.75;
84
+ }
85
+ }
86
+ /* Polyfilled squircles are painted from a snapshot of the computed style: animating the painted
87
+ properties would snapshot a half-way colour. Keep motion on transform, colour and opacity. */
88
+ [data-squircle-fallback] .squircle {
89
+ transition-property: color, opacity, transform, translate, scale;
90
+ }
91
+
92
+ /* Rows of a new page slide in from the side of the move (Data Table). `--row-from` sets the side. */
93
+ @theme {
94
+ --animate-row-in: cui-row-in var(--cui-duration-normal) var(--cui-ease) both;
95
+ @keyframes cui-row-in {
96
+ from {
97
+ opacity: 0;
98
+ translate: var(--row-from, 0) 0;
99
+ filter: blur(2px);
100
+ }
101
+ }
102
+ }
103
+
104
+ /* Everything clickable shows the hand (Tailwind 4 no longer does it for buttons). */
105
+ @layer base {
106
+ :where(button, select, summary, [role='button'], [role='tab'], [role='radio'], [role='checkbox'], [role='switch'], [role='option'], [role='menuitem'], [role='menuitemcheckbox'], [role='menuitemradio']):not(:disabled, [aria-disabled='true'], [data-disabled]),
107
+ :where(label):has(input:not(:disabled), [role='checkbox'], [role='radio'], [role='switch']) {
108
+ cursor: pointer;
109
+ }
110
+ }
111
+
112
+ /* Shapes that glide or resize (hover blocks, active fills, indicators): the native corner-shape
113
+ only, because the polyfill can't follow an animation. Where it's unsupported they get a plain
114
+ radius scaled to look like the polyfilled squircles around them. */
115
+ @utility squircle-motion {
116
+ corner-shape: var(--cui-corner-shape);
117
+ }
118
+ @supports not (corner-shape: squircle) {
119
+ .squircle-motion {
120
+ --corner-scale: 0.75;
121
+ }
122
+ }
123
+
124
+ /* The accent glow used behind heroes and page tops. */
125
+ @utility glow {
126
+ background-image:
127
+ radial-gradient(60% 90% at 12% 0%, var(--cui-glow), transparent 70%),
128
+ radial-gradient(45% 70% at 88% 0%, var(--cui-glow-2), transparent 70%);
129
+ }
130
+
131
+ :root,
132
+ .light {
133
+ color-scheme: light;
134
+
135
+ /* colour — crazy-hub light palette */
136
+ --cui-frame: hsl(0 0% 91.5%);
137
+ --cui-background: hsl(0 0% 95%);
138
+ --cui-foreground: hsl(0 0% 3.9%);
139
+ --cui-surface: hsl(0 0% 95%);
140
+ --cui-surface-2: hsl(0 0% 90%);
141
+ --cui-popover: hsl(0 0% 96%);
142
+ --cui-hover: hsl(0 0% 82% / 0.5);
143
+ --cui-muted: hsl(0 0% 40%);
144
+ /* borders are opaque: transparent greys read as shadcn / old Material */
145
+ --cui-border: hsl(0 0% 86%);
146
+ --cui-border-strong: hsl(0 0% 80%);
147
+ --cui-input: hsl(0 0% 95%);
148
+ --cui-input-border: hsl(0 0% 82%);
149
+ /* light mirrors dark: a lavender fill with dark ink, a deeper purple for accent text */
150
+ --cui-accent: hsl(250 75% 72%);
151
+ --cui-accent-foreground: hsl(250 30% 10%);
152
+ --cui-accent-soft: hsl(250 70% 62% / 0.12);
153
+ --cui-accent-soft-foreground: hsl(250 45% 46%);
154
+ --cui-ring: hsl(250 70% 62% / 0.35);
155
+ --cui-danger: hsl(0 60% 47%);
156
+ --cui-danger-foreground: hsl(0 0% 98%);
157
+ --cui-success: hsl(150 45% 32%);
158
+ --cui-warning: hsl(32 70% 37%);
159
+ --cui-glow: hsl(250 75% 68% / 0.2);
160
+ --cui-glow-2: hsl(250 75% 68% / 0.09);
161
+
162
+ /* shape — the smaller the element, the smaller the radius */
163
+ /* halfway between a circle (1) and a squircle (2): rounder than squircle, still smooth */
164
+ --cui-corner-shape: superellipse(1.5);
165
+ --cui-radius-chip: 0.5rem;
166
+ --cui-radius-control-sm: 0.75rem;
167
+ --cui-radius-control: 1rem;
168
+ --cui-radius-control-lg: 1.125rem;
169
+ --cui-radius-item: 0.875rem;
170
+ --cui-radius-card: 1.5rem;
171
+ --cui-radius-panel: 1.75rem;
172
+ --cui-radius-switch: 9999px;
173
+ --cui-border-width: 1px;
174
+
175
+ /* elevation — quiet; the accent glow on buttons is opt-in (`glow` prop) */
176
+ --cui-shadow-control: 0 1px 2px hsl(0 0% 0% / 0.05);
177
+ --cui-shadow-button: none;
178
+ --cui-shadow-glow: 0 6px 18px -6px hsl(250 75% 60% / 0.45);
179
+ --cui-shadow-card: 0 1px 2px hsl(0 0% 0% / 0.04);
180
+ --cui-shadow-card-hover: 0 18px 48px -24px hsl(250 40% 35% / 0.22);
181
+ --cui-shadow-overlay: 0 12px 36px hsl(0 0% 0% / 0.14);
182
+
183
+ /* type */
184
+ --cui-font-sans: 'Inter Variable', ui-sans-serif, system-ui, sans-serif;
185
+ --cui-font-mono: 'Geist Mono Variable', ui-monospace, SFMono-Regular, Menlo, monospace;
186
+ --cui-font-heading: var(--cui-font-sans);
187
+ --cui-heading-weight: 600;
188
+ --cui-heading-tracking: -0.015em;
189
+ --cui-control-weight: 500;
190
+
191
+ /* density: scale every control height with one number */
192
+ --cui-density: 1.05;
193
+ --cui-control-height: calc(2.25rem * var(--cui-density));
194
+
195
+ /* motion */
196
+ --cui-duration-fast: 150ms;
197
+ --cui-duration-normal: 250ms;
198
+ --cui-ease: cubic-bezier(0.22, 1, 0.36, 1);
199
+ --cui-ease-spring: cubic-bezier(0.34, 1.3, 0.64, 1);
200
+ --cui-press-scale: 0.985;
201
+ --cui-card-lift: 2px;
202
+ }
203
+
204
+ .dark,
205
+ [data-theme='dark'] {
206
+ color-scheme: dark;
207
+
208
+ /* crazy-hub dark palette */
209
+ --cui-frame: hsl(0 0% 9.8%);
210
+ --cui-background: hsl(0 0% 7.04%);
211
+ --cui-foreground: hsl(0 0% 92%);
212
+ --cui-surface: hsl(0 0% 9.8%);
213
+ --cui-surface-2: hsl(0 0% 12.9%);
214
+ --cui-popover: hsl(0 0% 11.6%);
215
+ --cui-hover: hsl(0 0% 40.9% / 0.3);
216
+ --cui-muted: hsl(0 0% 62%);
217
+ --cui-border: hsl(0 0% 13.5%);
218
+ --cui-border-strong: hsl(0 0% 17.5%);
219
+ --cui-input: hsl(0 0% 9.8%);
220
+ --cui-input-border: hsl(0 0% 18%);
221
+ --cui-accent: hsl(250 100% 80%);
222
+ --cui-accent-foreground: hsl(250 30% 10%);
223
+ --cui-accent-soft: hsl(250 100% 80% / 0.1);
224
+ --cui-accent-soft-foreground: hsl(250 100% 80%);
225
+ --cui-ring: hsl(250 100% 80% / 0.4);
226
+ --cui-danger: hsl(0 70% 68%);
227
+ --cui-danger-foreground: hsl(0 0% 5%);
228
+ --cui-success: hsl(150 40% 58%);
229
+ --cui-warning: hsl(40 70% 60%);
230
+ --cui-glow: hsl(250 100% 80% / 0.2);
231
+ --cui-glow-2: hsl(250 100% 80% / 0.06);
232
+
233
+ --cui-shadow-control: 0 1px 2px hsl(0 0% 0% / 0.4);
234
+ --cui-shadow-glow: 0 6px 20px -6px hsl(250 100% 75% / 0.4);
235
+ --cui-shadow-card: 0 1px 2px hsl(0 0% 0% / 0.3);
236
+ --cui-shadow-card-hover: 0 20px 56px -28px hsl(250 80% 70% / 0.25);
237
+ --cui-shadow-overlay: 0 12px 36px hsl(0 0% 0% / 0.6);
238
+ }
239
+
240
+ @media (prefers-reduced-motion: reduce) {
241
+ :root {
242
+ --cui-duration-fast: 0ms;
243
+ --cui-duration-normal: 0ms;
244
+ --cui-press-scale: 1;
245
+ --cui-card-lift: 0px;
246
+ }
247
+ }