@charstudios/pallet 0.3.0 → 0.3.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.
@@ -1,9 +1,10 @@
1
1
  /*
2
2
  * Toon variant skin.
3
3
  *
4
- * Cel-shaded / neo-brutalist: moderate radius, no soft shadows, and a thick
5
- * bottom "lip" whose color is auto-derived from each surface's fill
6
- * (`--toon-fill`) via color-mix slightly darker than the background.
4
+ * Cel-shaded / neo-brutalist lips for real shadcn *surfaces* only
5
+ * (cards, buttons, inputs, overlays, …). Layout shells, sidebar chrome,
6
+ * menu rows, and other structural slots stay flat so apps do not look like
7
+ * every div is a chunky tile.
7
8
  */
8
9
 
9
10
  @layer pallet-variants {
@@ -12,19 +13,17 @@
12
13
  --toon-radius-sm: var(--radius-md);
13
14
  --toon-outline: 1.5px;
14
15
  --toon-lip: 3.5px;
15
- /* Default fill used when a slot does not override --toon-fill */
16
16
  --toon-fill: var(--card);
17
17
  }
18
18
 
19
- /* Shared toon chunk: outline + thick auto-darkened bottom border, no shadow.
20
- Lip/edge colors read --toon-fill on the element itself so overrides work. */
19
+ /* ── Surfaces that get the toon chunk (outline + thick lip) ───────────── */
21
20
  [data-pallet-variant="toon"] :is(
21
+ /* Controls */
22
22
  [data-slot="button"],
23
23
  [data-slot="input"],
24
24
  [data-slot="textarea"],
25
25
  [data-slot="select-trigger"],
26
26
  [data-slot="native-select"],
27
- [data-slot="native-select-wrapper"],
28
27
  [data-slot="combobox-trigger"],
29
28
  [data-slot="combobox-chip"],
30
29
  [data-slot="combobox-chip-input"],
@@ -32,23 +31,22 @@
32
31
  [data-slot="input-otp"],
33
32
  [data-slot="input-otp-slot"],
34
33
  [data-slot="input-group"],
35
- [data-slot="input-group-control"],
34
+ [data-slot="input-group-button"],
36
35
  [data-slot="sidebar-input"],
37
36
  [data-slot="toggle"],
38
- [data-slot="toggle-group"],
39
37
  [data-slot="toggle-group-item"],
40
38
  [data-slot="pagination-link"],
41
- [data-slot="button-group"],
42
- [data-slot="input-group-button"],
43
39
  [data-slot="carousel-previous"],
44
40
  [data-slot="carousel-next"],
45
- [data-slot="sidebar-trigger"],
46
- [data-slot="sidebar-menu-button"],
47
- [data-slot="sidebar-menu-sub-button"],
48
- [data-slot="sidebar-group-action"],
49
- [data-slot="sidebar-menu-action"],
41
+ /* Chrome */
50
42
  [data-slot="badge"],
51
43
  [data-slot="kbd"],
44
+ [data-slot="checkbox"],
45
+ [data-slot="radio-group-item"],
46
+ [data-slot="switch"],
47
+ [data-slot="slider-track"],
48
+ [data-slot="progress"],
49
+ /* Panels */
52
50
  [data-slot="card"],
53
51
  [data-slot="alert"],
54
52
  [data-slot="accordion-item"],
@@ -56,21 +54,8 @@
56
54
  [data-slot="tabs-trigger"],
57
55
  [data-slot="table-container"],
58
56
  [data-slot="item"],
59
- [data-slot="item-group"],
60
- [data-slot="empty"],
61
- [data-slot="field-set"],
62
- [data-slot="sidebar"],
63
- [data-slot="sidebar-container"],
64
- [data-slot="sidebar-inner"],
65
- [data-slot="sidebar-group"],
66
- [data-slot="carousel"],
67
- [data-slot="chart"],
68
- [data-slot="menubar"],
69
- [data-slot="navigation-menu-viewport"],
70
- [data-slot="breadcrumb"],
71
- [data-slot="pagination"],
72
- [data-slot="scroll-area"],
73
57
  [data-slot="calendar"],
58
+ /* Overlays / menus */
74
59
  [data-slot="popover-content"],
75
60
  [data-slot="dropdown-menu-content"],
76
61
  [data-slot="dropdown-menu-sub-content"],
@@ -94,27 +79,21 @@
94
79
  border-style: solid;
95
80
  border-width: var(--toon-outline);
96
81
  border-bottom-width: var(--toon-lip);
97
- border-color: color-mix(in oklch, var(--toon-fill) 42%, var(--foreground));
98
- border-bottom-color: color-mix(in oklch, var(--toon-fill) 68%, black);
82
+ border-color: color-mix(in oklch, var(--toon-fill) 68%, black);
99
83
  border-radius: var(--toon-radius);
100
84
  box-shadow: none !important;
101
85
  filter: none;
102
86
  text-shadow: none;
103
87
  }
104
88
 
105
- /* ── Fill tokens (lip color is derived from these) ─────────────────────── */
89
+ /* ── Fill tokens ──────────────────────────────────────────────────────── */
106
90
  [data-pallet-variant="toon"] :is(
107
91
  [data-slot="card"],
108
92
  [data-slot="alert"],
109
93
  [data-slot="item"],
110
- [data-slot="item-group"],
111
- [data-slot="empty"],
112
94
  [data-slot="accordion-item"],
113
95
  [data-slot="table-container"],
114
- [data-slot="field-set"],
115
- [data-slot="calendar"],
116
- [data-slot="chart"],
117
- [data-slot="carousel"]
96
+ [data-slot="calendar"]
118
97
  ) {
119
98
  --toon-fill: var(--card);
120
99
  }
@@ -148,18 +127,17 @@
148
127
  [data-slot="textarea"],
149
128
  [data-slot="select-trigger"],
150
129
  [data-slot="native-select"],
151
- [data-slot="native-select-wrapper"],
152
130
  [data-slot="combobox-trigger"],
153
131
  [data-slot="combobox-chip-input"],
154
132
  [data-slot="command-input"],
155
133
  [data-slot="input-otp"],
156
134
  [data-slot="input-otp-slot"],
157
135
  [data-slot="input-group"],
158
- [data-slot="input-group-control"],
159
- [data-slot="sidebar-input"]
136
+ [data-slot="sidebar-input"],
137
+ [data-slot="checkbox"],
138
+ [data-slot="radio-group-item"]
160
139
  ) {
161
140
  --toon-fill: var(--background);
162
- background-color: var(--background);
163
141
  }
164
142
 
165
143
  [data-pallet-variant="toon"] :is(
@@ -169,28 +147,54 @@
169
147
  [data-slot="carousel-next"],
170
148
  [data-slot="pagination-link"]
171
149
  ) {
172
- /* Default / primary-looking controls — lip darkens the primary fill */
173
150
  --toon-fill: var(--primary);
174
151
  }
175
152
 
176
- /* Non-primary button variants: lip tracks the light surface fill instead */
177
153
  [data-pallet-variant="toon"] [data-slot="button"]:is(
178
154
  [data-variant="outline"],
179
155
  [data-variant="secondary"],
180
- [data-variant="ghost"],
181
- [class*="bg-secondary"],
182
- [class*="bg-background"]
156
+ [class*="variant-outline"],
157
+ [class*="variant-secondary"]
183
158
  ) {
184
159
  --toon-fill: var(--background);
185
160
  }
186
161
 
187
162
  [data-pallet-variant="toon"] [data-slot="button"]:is(
188
163
  [data-variant="destructive"],
164
+ [class*="variant-destructive"],
189
165
  [class*="bg-destructive"]
190
166
  ) {
191
167
  --toon-fill: var(--destructive);
192
168
  }
193
169
 
170
+ /* Ghost: borderless until hover / focus */
171
+ [data-pallet-variant="toon"] [data-slot="button"]:is(
172
+ [data-variant="ghost"],
173
+ [class*="variant-ghost"]
174
+ ) {
175
+ --toon-fill: var(--accent);
176
+ border-color: transparent !important;
177
+ box-shadow: none !important;
178
+ transform: none;
179
+ }
180
+
181
+ [data-pallet-variant="toon"] [data-slot="button"]:is(
182
+ [data-variant="ghost"],
183
+ [class*="variant-ghost"]
184
+ ):is(:hover, :focus-visible) {
185
+ border-color: color-mix(in oklch, var(--toon-fill) 68%, black) !important;
186
+ }
187
+
188
+ /* Link: never a toon chunk */
189
+ [data-pallet-variant="toon"] [data-slot="button"]:is(
190
+ [data-variant="link"],
191
+ [class*="variant-link"]
192
+ ) {
193
+ border: none !important;
194
+ box-shadow: none !important;
195
+ transform: none;
196
+ }
197
+
194
198
  [data-pallet-variant="toon"] :is(
195
199
  [data-slot="toggle"],
196
200
  [data-slot="toggle-group-item"],
@@ -204,29 +208,6 @@
204
208
  }
205
209
 
206
210
  [data-pallet-variant="toon"] :is(
207
- [data-slot="sidebar"],
208
- [data-slot="sidebar-container"],
209
- [data-slot="sidebar-inner"],
210
- [data-slot="sidebar-group"],
211
- [data-slot="menubar"],
212
- [data-slot="navigation-menu-viewport"]
213
- ) {
214
- --toon-fill: var(--sidebar);
215
- }
216
-
217
- [data-pallet-variant="toon"] :is(
218
- [data-slot="sidebar-menu-button"],
219
- [data-slot="sidebar-menu-sub-button"],
220
- [data-slot="sidebar-trigger"],
221
- [data-slot="sidebar-group-action"],
222
- [data-slot="sidebar-menu-action"]
223
- ) {
224
- --toon-fill: var(--sidebar);
225
- }
226
-
227
- /* Active / on states: lip tracks the primary fill */
228
- [data-pallet-variant="toon"] :is(
229
- [data-slot="sidebar-menu-button"],
230
211
  [data-slot="tabs-trigger"],
231
212
  [data-slot="toggle"],
232
213
  [data-slot="toggle-group-item"],
@@ -235,37 +216,18 @@
235
216
  --toon-fill: var(--primary);
236
217
  }
237
218
 
238
- /* ── Sizing tweaks ─────────────────────────────────────────────────────── */
219
+ /* ── Size tweaks ──────────────────────────────────────────────────────── */
239
220
  [data-pallet-variant="toon"] :is(
240
221
  [data-slot="badge"],
241
222
  [data-slot="kbd"],
242
- [data-slot="avatar-badge"],
243
223
  [data-slot="checkbox"],
224
+ [data-slot="radio-group-item"],
244
225
  [data-slot="input-otp-slot"]
245
226
  ) {
246
227
  border-radius: var(--toon-radius-sm);
247
228
  --toon-lip: 2.5px;
248
229
  }
249
230
 
250
- [data-pallet-variant="toon"] :is(
251
- [data-slot="checkbox"],
252
- [data-slot="radio-group-item"],
253
- [data-slot="switch"],
254
- [data-slot="slider-track"],
255
- [data-slot="progress"],
256
- [data-slot="avatar"],
257
- [data-slot="avatar-fallback"]
258
- ) {
259
- --toon-fill: var(--background);
260
- border-style: solid;
261
- border-width: var(--toon-outline);
262
- border-bottom-width: var(--toon-lip);
263
- border-color: color-mix(in oklch, var(--toon-fill) 42%, var(--foreground));
264
- border-bottom-color: color-mix(in oklch, var(--toon-fill) 68%, black);
265
- border-radius: var(--toon-radius-sm);
266
- box-shadow: none !important;
267
- }
268
-
269
231
  [data-pallet-variant="toon"] [data-slot="switch"],
270
232
  [data-pallet-variant="toon"] [data-slot="slider-track"],
271
233
  [data-pallet-variant="toon"] [data-slot="progress"] {
@@ -275,28 +237,26 @@
275
237
 
276
238
  [data-pallet-variant="toon"] [data-slot="switch"][data-state="checked"] {
277
239
  --toon-fill: var(--primary);
278
- border-color: color-mix(in oklch, var(--toon-fill) 42%, var(--foreground));
279
- border-bottom-color: color-mix(in oklch, var(--toon-fill) 68%, black);
240
+ border-color: color-mix(in oklch, var(--toon-fill) 68%, black);
280
241
  }
281
242
 
282
243
  [data-pallet-variant="toon"] [data-slot="textarea"] {
283
244
  border-radius: var(--radius-xl);
284
245
  }
285
246
 
286
- /* Press: sink the lip slightly for a tactile toon feel */
287
247
  [data-pallet-variant="toon"] :is(
288
248
  [data-slot="button"],
289
249
  [data-slot="toggle"],
290
250
  [data-slot="toggle-group-item"],
291
251
  [data-slot="pagination-link"],
292
- [data-slot="sidebar-menu-button"],
293
252
  [data-slot="carousel-previous"],
294
253
  [data-slot="carousel-next"]
295
- ):active {
254
+ ):active:not([data-variant="ghost"]):not([data-variant="link"]):not([class*="variant-ghost"]):not([class*="variant-link"]) {
296
255
  transform: translateY(1px);
297
256
  border-bottom-width: 2px;
298
257
  }
299
258
 
259
+ /* Menu rows: radius only — no chunk borders (avoids tiled lists) */
300
260
  [data-pallet-variant="toon"] :is(
301
261
  [data-slot="dropdown-menu-item"],
302
262
  [data-slot="dropdown-menu-checkbox-item"],
@@ -313,6 +273,91 @@
313
273
  box-shadow: none !important;
314
274
  }
315
275
 
276
+ /* ── Sidebar: panel is square; nav rows stay flat (not individual tiles) ─ */
277
+ [data-pallet-variant="toon"] :is(
278
+ [data-slot="sidebar"],
279
+ [data-slot="sidebar-container"],
280
+ [data-slot="sidebar-inner"],
281
+ [data-slot="sidebar-wrapper"],
282
+ [data-slot="sidebar-gap"],
283
+ [data-slot="sidebar-header"],
284
+ [data-slot="sidebar-footer"],
285
+ [data-slot="sidebar-content"],
286
+ [data-slot="sidebar-group"],
287
+ [data-slot="sidebar-group-content"],
288
+ [data-slot="sidebar-group-label"],
289
+ [data-slot="sidebar-menu"],
290
+ [data-slot="sidebar-menu-item"],
291
+ [data-slot="sidebar-menu-sub"],
292
+ [data-slot="sidebar-menu-sub-item"],
293
+ [data-slot="sidebar-inset"],
294
+ [data-slot="sidebar-rail"]
295
+ ) {
296
+ border-radius: 0 !important;
297
+ box-shadow: none !important;
298
+ }
299
+
300
+ /* Outer sidebar shell: hard edge, no rounded lip tile */
301
+ [data-pallet-variant="toon"] :is(
302
+ [data-slot="sidebar"],
303
+ [data-slot="sidebar-container"],
304
+ [data-slot="sidebar-inner"]
305
+ ) {
306
+ border: none;
307
+ border-right: var(--toon-outline) solid
308
+ color-mix(in oklch, var(--sidebar) 68%, black);
309
+ border-bottom: none;
310
+ }
311
+
312
+ /* Nav buttons / actions: flat rows, soft radius, no chunk lip */
313
+ [data-pallet-variant="toon"] :is(
314
+ [data-slot="sidebar-menu-button"],
315
+ [data-slot="sidebar-menu-sub-button"],
316
+ [data-slot="sidebar-menu-action"],
317
+ [data-slot="sidebar-group-action"],
318
+ [data-slot="sidebar-trigger"]
319
+ ) {
320
+ border: none !important;
321
+ border-radius: var(--toon-radius-sm) !important;
322
+ box-shadow: none !important;
323
+ transform: none;
324
+ }
325
+
326
+ [data-pallet-variant="toon"] :is(
327
+ [data-slot="sidebar-menu-button"],
328
+ [data-slot="sidebar-menu-sub-button"]
329
+ ):is([data-active="true"], [data-state="active"]) {
330
+ background-color: color-mix(in oklch, var(--sidebar-accent) 85%, var(--primary));
331
+ color: var(--sidebar-accent-foreground);
332
+ }
333
+
334
+ /* Structural slots that must never pick up chunk styling */
335
+ [data-pallet-variant="toon"] :is(
336
+ [data-slot="button-group"],
337
+ [data-slot="toggle-group"],
338
+ [data-slot="field"],
339
+ [data-slot="field-set"],
340
+ [data-slot="field-group"],
341
+ [data-slot="item-group"],
342
+ [data-slot="empty"],
343
+ [data-slot="carousel"],
344
+ [data-slot="chart"],
345
+ [data-slot="breadcrumb"],
346
+ [data-slot="pagination"],
347
+ [data-slot="scroll-area"],
348
+ [data-slot="scroll-area-viewport"],
349
+ [data-slot="menubar"],
350
+ [data-slot="navigation-menu"],
351
+ [data-slot="navigation-menu-viewport"],
352
+ [data-slot="tabs"],
353
+ [data-slot="table"],
354
+ [data-slot="avatar"],
355
+ [data-slot="avatar-fallback"],
356
+ [data-slot="skeleton"]
357
+ ) {
358
+ box-shadow: none !important;
359
+ }
360
+
316
361
  [data-pallet-variant="toon"] :is(
317
362
  [data-slot="dialog-overlay"],
318
363
  [data-slot="alert-dialog-overlay"],
package/package.json CHANGED
@@ -1,79 +1,79 @@
1
- {
2
- "name": "@charstudios/pallet",
3
- "version": "0.3.0",
4
- "description": "Runtime, hook-driven theming layer for shadcn/ui apps. Full control over colors, fonts, roundness, elevation, spacing and motion, with swappable visual variants.",
5
- "type": "module",
6
- "license": "MIT",
7
- "author": "Char Studios",
8
- "repository": {
9
- "type": "git",
10
- "url": "git+https://github.com/Char-Studios/Pallet.git"
11
- },
12
- "bugs": {
13
- "url": "https://github.com/Char-Studios/Pallet/issues"
14
- },
15
- "homepage": "https://github.com/Char-Studios/Pallet#readme",
16
- "keywords": [
17
- "shadcn",
18
- "theme",
19
- "theming",
20
- "design-system",
21
- "tailwind",
22
- "react",
23
- "nextjs",
24
- "css-variables",
25
- "tokens"
26
- ],
27
- "sideEffects": [
28
- "**/*.css"
29
- ],
30
- "files": [
31
- "dist"
32
- ],
33
- "exports": {
34
- ".": {
35
- "types": "./dist/index.d.ts",
36
- "import": "./dist/index.js"
37
- },
38
- "./server": {
39
- "types": "./dist/server.d.ts",
40
- "import": "./dist/server.js"
41
- },
42
- "./presets": {
43
- "types": "./dist/presets/index.d.ts",
44
- "import": "./dist/presets/index.js"
45
- },
46
- "./styles": "./dist/styles/index.css",
47
- "./styles/flat": "./dist/styles/variant-flat.css",
48
- "./styles/toon": "./dist/styles/variant-toon.css",
49
- "./styles/frosted": "./dist/styles/variant-frosted.css",
50
- "./styles/base": "./dist/styles/base.css"
51
- },
52
- "main": "./dist/index.js",
53
- "module": "./dist/index.js",
54
- "types": "./dist/index.d.ts",
55
- "scripts": {
56
- "build": "tsup",
57
- "dev": "tsup --watch",
58
- "typecheck": "tsc --noEmit",
59
- "prepublishOnly": "npm run build"
60
- },
61
- "peerDependencies": {
62
- "react": ">=18",
63
- "react-dom": ">=18"
64
- },
65
- "devDependencies": {
66
- "@types/react": "^19",
67
- "@types/react-dom": "^19",
68
- "react": "^19",
69
- "react-dom": "^19",
70
- "tsup": "^8.5.0",
71
- "typescript": "^5.6.0"
72
- },
73
- "publishConfig": {
74
- "access": "public"
75
- },
76
- "engines": {
77
- "node": ">=18"
78
- }
79
- }
1
+ {
2
+ "name": "@charstudios/pallet",
3
+ "version": "0.3.1",
4
+ "description": "Runtime, hook-driven theming layer for shadcn/ui apps. Full control over colors, fonts, roundness, elevation, spacing and motion, with swappable visual variants.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "Char Studios",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/Char-Studios/Pallet.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/Char-Studios/Pallet/issues"
14
+ },
15
+ "homepage": "https://github.com/Char-Studios/Pallet#readme",
16
+ "keywords": [
17
+ "shadcn",
18
+ "theme",
19
+ "theming",
20
+ "design-system",
21
+ "tailwind",
22
+ "react",
23
+ "nextjs",
24
+ "css-variables",
25
+ "tokens"
26
+ ],
27
+ "sideEffects": [
28
+ "**/*.css"
29
+ ],
30
+ "files": [
31
+ "dist"
32
+ ],
33
+ "exports": {
34
+ ".": {
35
+ "types": "./dist/index.d.ts",
36
+ "import": "./dist/index.js"
37
+ },
38
+ "./server": {
39
+ "types": "./dist/server.d.ts",
40
+ "import": "./dist/server.js"
41
+ },
42
+ "./presets": {
43
+ "types": "./dist/presets/index.d.ts",
44
+ "import": "./dist/presets/index.js"
45
+ },
46
+ "./styles": "./dist/styles/index.css",
47
+ "./styles/flat": "./dist/styles/variant-flat.css",
48
+ "./styles/toon": "./dist/styles/variant-toon.css",
49
+ "./styles/frosted": "./dist/styles/variant-frosted.css",
50
+ "./styles/base": "./dist/styles/base.css"
51
+ },
52
+ "main": "./dist/index.js",
53
+ "module": "./dist/index.js",
54
+ "types": "./dist/index.d.ts",
55
+ "scripts": {
56
+ "build": "tsup",
57
+ "dev": "tsup --watch",
58
+ "typecheck": "tsc --noEmit",
59
+ "prepublishOnly": "npm run build"
60
+ },
61
+ "peerDependencies": {
62
+ "react": ">=18",
63
+ "react-dom": ">=18"
64
+ },
65
+ "devDependencies": {
66
+ "@types/react": "^19",
67
+ "@types/react-dom": "^19",
68
+ "react": "^19",
69
+ "react-dom": "^19",
70
+ "tsup": "^8.5.0",
71
+ "typescript": "^5.6.0"
72
+ },
73
+ "publishConfig": {
74
+ "access": "public"
75
+ },
76
+ "engines": {
77
+ "node": ">=18"
78
+ }
79
+ }