labellife-design-tool 0.1.0 → 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/README.md CHANGED
@@ -14,6 +14,7 @@ Professional canvas editor built with React, TypeScript, and Konva.js. A powerfu
14
14
  - 📥 **Template Import** - Import JSON templates with user input collection
15
15
  - 🌐 **i18n Support** - Internationalization support (English, Dutch)
16
16
  - ⚙️ **Configurable** - Customize features, panels, and behavior
17
+ - 🧩 **Modular Architecture** - Exclude panels, add custom panels, control features
17
18
 
18
19
  ## Installation
19
20
 
@@ -88,6 +89,333 @@ function MyEditor() {
88
89
  }
89
90
  ```
90
91
 
92
+ ### Modular Configuration (v0.2.0+)
93
+
94
+ The library supports a modular architecture that allows you to customize panels, features, and tools.
95
+
96
+ #### Exclude Panels
97
+
98
+ Hide panels you don't need:
99
+
100
+ ```tsx
101
+ import { CanvasEditor } from 'labellife-design-tool';
102
+
103
+ <CanvasEditor
104
+ name="Editor"
105
+ config={{
106
+ panels: {
107
+ disable: ['variables', 'export', 'background'], // Hide these panels
108
+ },
109
+ }}
110
+ />
111
+ ```
112
+
113
+ #### Enable Only Specific Panels
114
+
115
+ Show only the panels you need:
116
+
117
+ ```tsx
118
+ <CanvasEditor
119
+ name="Minimal Editor"
120
+ config={{
121
+ panels: {
122
+ enable: ['elements', 'text', 'image'], // Only show these three
123
+ },
124
+ }}
125
+ />
126
+ ```
127
+
128
+ #### Reorder Panels
129
+
130
+ Customize the panel order:
131
+
132
+ ```tsx
133
+ <CanvasEditor
134
+ name="Custom Order"
135
+ config={{
136
+ panels: {
137
+ order: ['text', 'elements', 'image', 'design'], // Custom order
138
+ },
139
+ }}
140
+ />
141
+ ```
142
+
143
+ #### Feature Flags
144
+
145
+ Control which features are available:
146
+
147
+ ```tsx
148
+ <CanvasEditor
149
+ name="No Unsplash"
150
+ config={{
151
+ features: {
152
+ unsplash: false, // Disable Unsplash integration
153
+ imageUpload: true, // Keep image upload enabled
154
+ textTools: true, // Keep text tools enabled
155
+ shapeTools: false, // Disable shape tools
156
+ },
157
+ }}
158
+ />
159
+ ```
160
+
161
+ #### Tool Configuration
162
+
163
+ Control which tools are available:
164
+
165
+ ```tsx
166
+ <CanvasEditor
167
+ name="Limited Tools"
168
+ config={{
169
+ tools: {
170
+ disable: ['line'], // Disable line tool
171
+ // Or enable only specific tools:
172
+ // enable: ['select', 'text'],
173
+ },
174
+ }}
175
+ />
176
+ ```
177
+
178
+ ### Adding Custom Panels
179
+
180
+ You can add your own custom panels to extend the editor's functionality.
181
+
182
+ #### Step 1: Create Your Custom Panel Component
183
+
184
+ ```tsx
185
+ import React from 'react';
186
+ import { PanelProps } from 'labellife-design-tool';
187
+ import { Settings } from 'lucide-react';
188
+
189
+ // Your custom panel component receives PanelProps
190
+ const MyCustomPanel: React.FC<PanelProps> = ({
191
+ design, // Current design state
192
+ currentPage, // Current page
193
+ selectedElement, // Currently selected element (or null)
194
+ selectedIds, // Array of selected element IDs
195
+ setDesign, // Function to update the design
196
+ updateElement, // Function to update an element
197
+ deleteElement, // Optional: Function to delete an element
198
+ }) => {
199
+ return (
200
+ <div className="p-4">
201
+ <h3 className="text-white font-semibold mb-4 flex items-center gap-2">
202
+ <Settings className="w-5 h-5" />
203
+ Custom Settings
204
+ </h3>
205
+
206
+ <div className="space-y-4">
207
+ {/* Display current design info */}
208
+ <div className="bg-gray-700 p-3 rounded">
209
+ <p className="text-sm text-gray-300">
210
+ Design: {design.name}
211
+ </p>
212
+ <p className="text-sm text-gray-300">
213
+ Pages: {design.pages.length}
214
+ </p>
215
+ <p className="text-sm text-gray-300">
216
+ Selected: {selectedElement?.name || 'None'}
217
+ </p>
218
+ </div>
219
+
220
+ {/* Custom actions */}
221
+ <button
222
+ onClick={() => {
223
+ setDesign({
224
+ ...design,
225
+ name: `Updated at ${new Date().toLocaleTimeString()}`,
226
+ });
227
+ }}
228
+ className="w-full bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700"
229
+ >
230
+ Update Design Name
231
+ </button>
232
+
233
+ {/* Update selected element */}
234
+ {selectedElement && (
235
+ <button
236
+ onClick={() => {
237
+ updateElement(selectedElement.id, {
238
+ opacity: selectedElement.opacity === 1 ? 0.5 : 1,
239
+ });
240
+ }}
241
+ className="w-full bg-green-600 text-white px-4 py-2 rounded hover:bg-green-700"
242
+ >
243
+ Toggle Opacity
244
+ </button>
245
+ )}
246
+ </div>
247
+ </div>
248
+ );
249
+ };
250
+ ```
251
+
252
+ #### Step 2: Configure and Add Your Custom Panel
253
+
254
+ ```tsx
255
+ import { CanvasEditor, CustomPanelConfig } from 'labellife-design-tool';
256
+ import { Settings } from 'lucide-react';
257
+ import { MyCustomPanel } from './MyCustomPanel';
258
+
259
+ // Define your custom panel configuration
260
+ const customPanel: CustomPanelConfig = {
261
+ id: 'my-custom-panel', // Unique ID (must not conflict with built-in panels)
262
+ title: 'Custom Settings', // Title shown in the panel header
263
+ icon: Settings, // Optional: Icon component (from lucide-react or custom)
264
+ component: MyCustomPanel, // Your panel component
265
+
266
+ // Positioning options (choose one):
267
+ position: 'after', // 'before' | 'after' | number
268
+ afterPanel: 'text', // Insert after 'text' panel
269
+ // Or use:
270
+ // beforePanel: 'design', // Insert before 'design' panel
271
+ // position: 2, // Insert at index 2
272
+ };
273
+
274
+ // Use it in your editor
275
+ function App() {
276
+ return (
277
+ <CanvasEditor
278
+ name="My Editor"
279
+ config={{
280
+ panels: {
281
+ custom: [customPanel], // Add your custom panel
282
+ },
283
+ }}
284
+ />
285
+ );
286
+ }
287
+ ```
288
+
289
+ #### Panel Positioning Options
290
+
291
+ You can control where your custom panel appears:
292
+
293
+ ```tsx
294
+ // Position after a specific panel
295
+ {
296
+ id: 'panel-after',
297
+ position: 'after',
298
+ afterPanel: 'text' // Appears after 'text' panel
299
+ }
300
+
301
+ // Position before a specific panel
302
+ {
303
+ id: 'panel-before',
304
+ position: 'before',
305
+ beforePanel: 'design' // Appears before 'design' panel
306
+ }
307
+
308
+ // Position at a specific index
309
+ {
310
+ id: 'panel-index',
311
+ position: 2 // Appears at index 2 (0-based)
312
+ }
313
+
314
+ // Default: Add to end (no position specified)
315
+ {
316
+ id: 'panel-end'
317
+ }
318
+ ```
319
+
320
+ #### Complete Example: Custom Panel with Multiple Features
321
+
322
+ ```tsx
323
+ import React from 'react';
324
+ import { CanvasEditor, CustomPanelConfig, PanelProps } from 'labellife-design-tool';
325
+ import { Palette, Layers } from 'lucide-react';
326
+
327
+ // Custom panel that manages design colors
328
+ const ColorPalettePanel: React.FC<PanelProps> = ({
329
+ design,
330
+ setDesign,
331
+ }) => {
332
+ const colors = ['#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#FF00FF'];
333
+
334
+ return (
335
+ <div className="p-4">
336
+ <h3 className="text-white font-semibold mb-4">Color Palette</h3>
337
+ <div className="grid grid-cols-5 gap-2">
338
+ {colors.map((color) => (
339
+ <button
340
+ key={color}
341
+ onClick={() => {
342
+ setDesign({
343
+ ...design,
344
+ colors: [...(design.colors || []), color],
345
+ });
346
+ }}
347
+ className="w-10 h-10 rounded"
348
+ style={{ backgroundColor: color }}
349
+ title={color}
350
+ />
351
+ ))}
352
+ </div>
353
+ </div>
354
+ );
355
+ };
356
+
357
+ // Custom panel configuration
358
+ const colorPalettePanel: CustomPanelConfig = {
359
+ id: 'color-palette',
360
+ title: 'Colors',
361
+ icon: Palette,
362
+ component: ColorPalettePanel,
363
+ position: 'after',
364
+ afterPanel: 'design',
365
+ };
366
+
367
+ // Use multiple custom panels
368
+ function App() {
369
+ return (
370
+ <CanvasEditor
371
+ name="Custom Editor"
372
+ config={{
373
+ panels: {
374
+ custom: [colorPalettePanel], // Add custom panel
375
+ disable: ['variables'], // Hide variables panel
376
+ order: ['elements', 'text', 'color-palette', 'image'], // Custom order
377
+ },
378
+ }}
379
+ />
380
+ );
381
+ }
382
+ ```
383
+
384
+ #### Available Panel Props
385
+
386
+ Your custom panel component receives these props:
387
+
388
+ ```tsx
389
+ interface PanelProps {
390
+ // Core editor state
391
+ design: CanvasDesign; // Current design
392
+ currentPage: Page; // Current page
393
+ selectedElement: CanvasElement | null; // Selected element
394
+ selectedIds: string[]; // Array of selected IDs
395
+
396
+ // Core editor actions
397
+ setDesign: (design: CanvasDesign) => void;
398
+ updateElement: (id: string, attrs: Partial<CanvasElement>) => void;
399
+ deleteElement?: (id: string) => void;
400
+
401
+ // Additional props (panel-specific)
402
+ [key: string]: any;
403
+ }
404
+ ```
405
+
406
+ #### Built-in Panel IDs
407
+
408
+ Available built-in panel IDs you can reference:
409
+ - `'elements'` - Elements/Shapes panel
410
+ - `'text'` - Text panel
411
+ - `'image'` - Images panel
412
+ - `'design'` - Design panel
413
+ - `'background'` - Background panel
414
+ - `'variables'` - Variables panel (if enabled)
415
+ - `'export'` - Export panel (if enabled)
416
+
417
+ For more advanced examples and API documentation, see [MODULAR_USAGE_GUIDE.md](./MODULAR_USAGE_GUIDE.md).
418
+
91
419
  ## Development
92
420
 
93
421
  To run the development server:
@@ -1 +1 @@
1
- {"version":3,"file":"CanvasEditor.d.ts","sourceRoot":"","sources":["../../src/CanvasEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAkFxE,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAExC,QAAA,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CA68B7D,CAAC;AAEF,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"CanvasEditor.d.ts","sourceRoot":"","sources":["../../src/CanvasEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AA+ExE,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAExC,QAAA,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAk8B7D,CAAC;AAEF,eAAe,YAAY,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { ToolType, ActivePanelId } from "../types";
2
+ import { ToolType, ActivePanelId, PanelConfig } from "../types";
3
3
  import { Config } from "../types/Config";
4
4
  export interface LeftMenuProps {
5
5
  tool: ToolType;
@@ -7,6 +7,7 @@ export interface LeftMenuProps {
7
7
  onSetTool: (tool: ToolType) => void;
8
8
  onSetActivePanel: (panel: ActivePanelId) => void;
9
9
  config?: Config;
10
+ panels?: PanelConfig[];
10
11
  }
11
12
  export declare const LeftMenu: React.FC<LeftMenuProps>;
12
13
  export default LeftMenu;
@@ -1 +1 @@
1
- {"version":3,"file":"LeftMenu.d.ts","sourceRoot":"","sources":["../../../src/components/LeftMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAWzC,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,CAAC;IACf,WAAW,EAAE,aAAa,CAAC;IAC3B,SAAS,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IACpC,gBAAgB,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAqH5C,CAAC;AAEF,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"LeftMenu.d.ts","sourceRoot":"","sources":["../../../src/components/LeftMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAsBzC,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,CAAC;IACf,WAAW,EAAE,aAAa,CAAC;IAC3B,SAAS,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IACpC,gBAAgB,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;CACxB;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAwJ5C,CAAC;AAEF,eAAe,QAAQ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"AppName.d.ts","sourceRoot":"","sources":["../../../../src/components/header/AppName.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,QAAA,MAAM,OAAO,EAAE,KAAK,CAAC,EAGpB,CAAC;AAEF,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"AppName.d.ts","sourceRoot":"","sources":["../../../../src/components/header/AppName.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,QAAA,MAAM,OAAO,EAAE,KAAK,CAAC,EAGpB,CAAC;AAEF,eAAe,OAAO,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ExportButton.d.ts","sourceRoot":"","sources":["../../../../src/components/header/ExportButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,UAAU,iBAAiB;IACzB,gBAAgB,EAAE,CAAC,KAAK,EAAE,aAAa,GAAG,QAAQ,KAAK,IAAI,CAAC;CAC7D;AAED,QAAA,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAW7C,CAAC;AAEF,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"ExportButton.d.ts","sourceRoot":"","sources":["../../../../src/components/header/ExportButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,UAAU,iBAAiB;IACzB,gBAAgB,EAAE,CAAC,KAAK,EAAE,aAAa,GAAG,QAAQ,KAAK,IAAI,CAAC;CAC7D;AAED,QAAA,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAW7C,CAAC;AAEF,eAAe,YAAY,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"HistoryControls.d.ts","sourceRoot":"","sources":["../../../../src/components/header/HistoryControls.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,oBAAoB;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,QAAA,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA2BnD,CAAC;AAEF,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"HistoryControls.d.ts","sourceRoot":"","sources":["../../../../src/components/header/HistoryControls.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,UAAU,oBAAoB;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,QAAA,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA2BnD,CAAC;AAEF,eAAe,eAAe,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ZoomControls.d.ts","sourceRoot":"","sources":["../../../../src/components/header/ZoomControls.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB;AAED,QAAA,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAmC7C,CAAC;AAEF,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"ZoomControls.d.ts","sourceRoot":"","sources":["../../../../src/components/header/ZoomControls.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB;AAED,QAAA,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAmC7C,CAAC;AAEF,eAAe,YAAY,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Scoped i18n instance for LabelLife Design Tool
3
+ * Uses namespace 'labellife-editor' to avoid conflicts with consumer's i18n
4
+ */
5
+ declare const EDITOR_NAMESPACE = "labellife-editor";
6
+ declare const editorI18n: import("node_modules/i18next").i18n;
7
+ export default editorI18n;
8
+ export { EDITOR_NAMESPACE };
9
+ //# sourceMappingURL=i18n.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../../src/i18n.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,QAAA,MAAM,gBAAgB,qBAAqB,CAAC;AAG5C,QAAA,MAAM,UAAU,qCAAwB,CAAC;AA+BzC,eAAe,UAAU,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
@@ -14,6 +14,8 @@
14
14
  --color-red-700: oklch(50.5% 0.213 27.518);
15
15
  --color-green-400: oklch(79.2% 0.209 151.711);
16
16
  --color-green-500: oklch(72.3% 0.219 149.579);
17
+ --color-green-600: oklch(62.7% 0.194 149.214);
18
+ --color-green-700: oklch(52.7% 0.154 150.069);
17
19
  --color-blue-400: oklch(70.7% 0.165 254.624);
18
20
  --color-blue-500: oklch(62.3% 0.214 259.815);
19
21
  --color-blue-600: oklch(54.6% 0.245 262.881);
@@ -183,9 +185,6 @@
183
185
  ::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field {
184
186
  padding-block: 0;
185
187
  }
186
- ::-webkit-calendar-picker-indicator {
187
- line-height: 1;
188
- }
189
188
  :-moz-ui-invalid {
190
189
  box-shadow: none;
191
190
  }
@@ -218,6 +217,12 @@
218
217
  .inset-0 {
219
218
  inset: calc(var(--spacing) * 0);
220
219
  }
220
+ .-top-1\.5 {
221
+ top: calc(var(--spacing) * -1.5);
222
+ }
223
+ .-right-1\.5 {
224
+ right: calc(var(--spacing) * -1.5);
225
+ }
221
226
  .bottom-4 {
222
227
  bottom: calc(var(--spacing) * 4);
223
228
  }
@@ -317,6 +322,9 @@
317
322
  .h-8 {
318
323
  height: calc(var(--spacing) * 8);
319
324
  }
325
+ .h-10 {
326
+ height: calc(var(--spacing) * 10);
327
+ }
320
328
  .h-12 {
321
329
  height: calc(var(--spacing) * 12);
322
330
  }
@@ -350,6 +358,9 @@
350
358
  .w-8 {
351
359
  width: calc(var(--spacing) * 8);
352
360
  }
361
+ .w-10 {
362
+ width: calc(var(--spacing) * 10);
363
+ }
353
364
  .w-12 {
354
365
  width: calc(var(--spacing) * 12);
355
366
  }
@@ -582,6 +593,12 @@
582
593
  background-color: color-mix(in oklab, var(--color-green-500) 10%, transparent);
583
594
  }
584
595
  }
596
+ .bg-green-600 {
597
+ background-color: var(--color-green-600);
598
+ }
599
+ .bg-red-500 {
600
+ background-color: var(--color-red-500);
601
+ }
585
602
  .bg-red-600 {
586
603
  background-color: var(--color-red-600);
587
604
  }
@@ -668,6 +685,10 @@
668
685
  font-size: var(--text-xs);
669
686
  line-height: var(--tw-leading, var(--text-xs--line-height));
670
687
  }
688
+ .leading-none {
689
+ --tw-leading: 1;
690
+ line-height: 1;
691
+ }
671
692
  .font-bold {
672
693
  --tw-font-weight: var(--font-weight-bold);
673
694
  font-weight: var(--font-weight-bold);
@@ -723,6 +744,10 @@
723
744
  --tw-shadow: 0 25px 50px -12px var(--tw-shadow-color, rgb(0 0 0 / 0.25));
724
745
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
725
746
  }
747
+ .shadow-sm {
748
+ --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
749
+ box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
750
+ }
726
751
  .outline {
727
752
  outline-style: var(--tw-outline-style);
728
753
  outline-width: 1px;
@@ -822,6 +847,13 @@
822
847
  }
823
848
  }
824
849
  }
850
+ .hover\:bg-green-700 {
851
+ &:hover {
852
+ @media (hover: hover) {
853
+ background-color: var(--color-green-700);
854
+ }
855
+ }
856
+ }
825
857
  .hover\:bg-red-600 {
826
858
  &:hover {
827
859
  @media (hover: hover) {
@@ -850,6 +882,14 @@
850
882
  }
851
883
  }
852
884
  }
885
+ .hover\:shadow {
886
+ &:hover {
887
+ @media (hover: hover) {
888
+ --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
889
+ box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
890
+ }
891
+ }
892
+ }
853
893
  .focus\:border-blue-500 {
854
894
  &:focus {
855
895
  border-color: var(--color-blue-500);
@@ -913,6 +953,10 @@
913
953
  inherits: false;
914
954
  initial-value: solid;
915
955
  }
956
+ @property --tw-leading {
957
+ syntax: "*";
958
+ inherits: false;
959
+ }
916
960
  @property --tw-font-weight {
917
961
  syntax: "*";
918
962
  inherits: false;
@@ -1070,6 +1114,7 @@
1070
1114
  --tw-space-y-reverse: 0;
1071
1115
  --tw-space-x-reverse: 0;
1072
1116
  --tw-border-style: solid;
1117
+ --tw-leading: initial;
1073
1118
  --tw-font-weight: initial;
1074
1119
  --tw-shadow: 0 0 #0000;
1075
1120
  --tw-shadow-color: initial;