@skalar-saas/design-system 0.1.136 → 0.1.137

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,6 @@
1
1
  {
2
2
  "name": "@skalar-saas/design-system",
3
- "version": "0.1.136",
3
+ "version": "0.1.137",
4
4
  "type": "module",
5
5
  "description": "Skalar Design System - UI component library",
6
6
  "author": "Skalar Team",
@@ -28,10 +28,12 @@
28
28
  "require": "./dist/index.js"
29
29
  },
30
30
  "./styles": "./dist/design-system.css",
31
+ "./theme": "./src/styles/theme.css",
31
32
  "./preset": "./tailwind.preset.js"
32
33
  },
33
34
  "files": [
34
35
  "dist",
36
+ "src/styles/theme.css",
35
37
  "tailwind.preset.js",
36
38
  "README.md"
37
39
  ],
package/src/README.md ADDED
@@ -0,0 +1,110 @@
1
+ # Shared Icons
2
+
3
+ This directory contains reusable SVG icon components for the project.
4
+
5
+ ## Structure
6
+
7
+ ```
8
+ src/shared/icons/
9
+ ├── ChatIcon.tsx # Individual icon component
10
+ ├── AICommentaryIcon.tsx # Individual icon component
11
+ ├── index.ts # Barrel export
12
+ └── README.md # This file
13
+ ```
14
+
15
+ ## Source Files
16
+
17
+ All SVG source files are located in `/public/icons/`.
18
+
19
+ ## Usage
20
+
21
+ ### Importing Icons
22
+
23
+ ```tsx
24
+ // Import single icon
25
+ import { ChatIcon } from '@/shared/icons';
26
+
27
+ // Import multiple icons
28
+ import { ChatIcon, AICommentaryIcon } from '@/shared/icons';
29
+ ```
30
+
31
+ ### Using in Components
32
+
33
+ ```tsx
34
+ // Default size (20px)
35
+ <ChatIcon />
36
+
37
+ // Custom size
38
+ <ChatIcon size={24} />
39
+
40
+ // With custom class
41
+ <ChatIcon className="text-blue-500" />
42
+ ```
43
+
44
+ ## Adding a New Icon
45
+
46
+ 1. **Save the SVG** to `/public/icons/` with a descriptive name (e.g., `iconsax-new-icon.svg`)
47
+
48
+ 2. **Create the component file** in this directory:
49
+ ```tsx
50
+ // NewIcon.tsx
51
+ import React from 'react';
52
+
53
+ export interface NewIconProps {
54
+ size?: number;
55
+ className?: string;
56
+ }
57
+
58
+ export const NewIcon = ({ size = 20, className }: NewIconProps) => (
59
+ <svg
60
+ width={size}
61
+ height={size}
62
+ viewBox="0 0 20 20"
63
+ fill="none"
64
+ xmlns="http://www.w3.org/2000/svg"
65
+ className={className}
66
+ >
67
+ {/* SVG paths here - use fill="currentColor" for theme compatibility */}
68
+ </svg>
69
+ );
70
+ ```
71
+
72
+ 3. **Export in index.ts**:
73
+ ```tsx
74
+ export { NewIcon } from './NewIcon';
75
+ export type { NewIconProps } from './NewIcon';
76
+ ```
77
+
78
+ ## Naming Convention
79
+
80
+ - Component name: PascalCase (e.g., `ChatIcon`, `AICommentaryIcon`)
81
+ - File name: Same as component name (e.g., `ChatIcon.tsx`)
82
+ - SVG source: kebab-case in `/public/icons/` (e.g., `iconsax-chat.svg`)
83
+
84
+ ## Best Practices
85
+
86
+ 1. **Use `currentColor`** for fill/stroke to inherit text color from parent
87
+ 2. **Accept `size` prop** for flexible sizing (default: 20px)
88
+ 3. **Accept `className` prop** for styling flexibility
89
+ 4. **Preserve viewBox** from original SVG for correct scaling
90
+ 5. **Export TypeScript types** alongside components
91
+ 6. **Document the icon** with JSDoc comments
92
+
93
+ ## Theme Compatibility
94
+
95
+ All icons use `fill="currentColor"` to automatically adapt to the theme's text color. This allows icons to change color based on:
96
+ - Parent component text color
97
+ - Hover states
98
+ - Active/inactive states
99
+ - Dark/light mode (when implemented)
100
+
101
+ Example:
102
+ ```tsx
103
+ <div className="text-blue-500">
104
+ <ChatIcon /> {/* Will be blue */}
105
+ </div>
106
+
107
+ <div className="text-red-500 hover:text-red-700">
108
+ <ChatIcon /> {/* Will be red, darker on hover */}
109
+ </div>
110
+ ```
@@ -0,0 +1,81 @@
1
+ # CSS Files - IMPORTANT
2
+
3
+ ## 📁 Files Overview
4
+
5
+ ### `globals.css` - PRODUCTION (DO NOT MODIFY)
6
+ - **Purpose**: Used in production builds (npm package)
7
+ - **Status**: Legacy file, will be replaced eventually
8
+ - **Rule**: ⛔ **NEVER MODIFY THIS FILE**
9
+
10
+ ### `globals_new.css` - DEVELOPMENT (CORRECT TOKENS)
11
+ - **Purpose**: New token system based on Figma design
12
+ - **Status**: Active development, used in Storybook
13
+ - **Contains**: Clean semantic tokens (36 tokens per theme)
14
+ - **Rule**: ✅ This is the source of truth for new components
15
+ - **Rule**: ⚠️ Only modify if updating tokens from Figma
16
+
17
+ ### `globals_old_backup.css` - BACKUP
18
+ - **Purpose**: Backup of old globals.css
19
+ - **Rule**: ⛔ DO NOT MODIFY OR DELETE
20
+
21
+ ## 🔧 Usage
22
+
23
+ ### Storybook (Development)
24
+ Uses `globals_new.css` - configured in `.storybook/preview.ts`
25
+
26
+ ### Production Build (npm)
27
+ Uses `globals.css` - configured in build process
28
+
29
+ ## 🎨 Token System
30
+
31
+ The `globals_new.css` file contains:
32
+ - **36 semantic tokens** for light theme
33
+ - **36 semantic tokens** for dark theme
34
+ - Based directly on Figma design
35
+ - No invented color scales (primary-50, primary-100, etc.)
36
+
37
+ ### Token Categories:
38
+ - Primitive colors: `--black`, `--white`
39
+ - Surfaces: `--surface-bg`, `--surface-1` to `--surface-4`
40
+ - Text emphasis: `--text-disabled`, `--placeholder`, `--low-em`, `--med-em`, `--high-em`
41
+ - Brand: `--brand-primary-main`, `--brand-secondary-main`, etc.
42
+ - Status colors: Warning, Success, Info, Danger (with `-em`, `-main`, `-accent-*` variants)
43
+ - Spacing: `--spacing-0` to `--spacing-26`
44
+
45
+ ## 🚨 Critical Rules
46
+
47
+ 1. **NEVER modify `globals.css`** - It's used in production
48
+ 2. **Only modify `globals_new.css` if:**
49
+ - Updating tokens from Figma design
50
+ - Adding new tokens approved by design team
51
+ 3. **When migrating components:**
52
+ - Update component to use new semantic tokens
53
+ - Test in both light and dark modes
54
+ - DO NOT modify the CSS files
55
+
56
+ ## 📋 Migration Process
57
+
58
+ 1. Components use `globals.css` (old) in production
59
+ 2. New components are built with `globals_new.css` tokens
60
+ 3. Old components are gradually migrated to new tokens
61
+ 4. When all components are migrated: `globals_new.css` → `globals.css`
62
+ 5. Delete `globals_old_backup.css`
63
+
64
+ ## 💡 Quick Reference
65
+
66
+ **Need to add a new component?**
67
+ → Use tokens from `globals_new.css`
68
+
69
+ **Found a component with old tokens (primary-900, gray-500, etc.)?**
70
+ → Migrate it to use semantic tokens (success-main, surface-3, etc.)
71
+
72
+ **Want to change a color?**
73
+ → DON'T! Check with design team first, update Figma, then update `globals_new.css`
74
+
75
+ **Storybook showing wrong colors?**
76
+ → Check that `.storybook/preview.ts` imports `globals_new.css`
77
+
78
+ ---
79
+
80
+ **Last updated**: Nov 2025
81
+ **Token system version**: 1.0 (Figma-based semantic tokens)
@@ -0,0 +1,536 @@
1
+ /**
2
+ * =========================================
3
+ * SKALAR DESIGN SYSTEM - NEW TOKEN SYSTEM
4
+ * =========================================
5
+ *
6
+ * Importable theme: token definitions (:root / .dark) + @theme mapping.
7
+ * Sin `@import "tailwindcss"` a propósito, para que un consumidor pueda
8
+ * importar este archivo DESPUÉS de su propio `@import "tailwindcss"` sin
9
+ * duplicarlo. El build del DS lo importa vía globals.css.
10
+ */
11
+
12
+ /* ========================================= */
13
+ /* BASE TOKENS - LIGHT THEME (DEFAULT) */
14
+ /* ========================================= */
15
+
16
+ :root {
17
+ /* Fonts */
18
+ --font-inter: 'Inter', sans-serif;
19
+ --font-space-grotesk: 'Space Grotesk', sans-serif;
20
+
21
+ /* ========================================= */
22
+ /* PRIMITIVE COLORS */
23
+ /* ========================================= */
24
+
25
+ --black: #000;
26
+ --white: #FFF;
27
+ --black-uniform: #000;
28
+ --white-uniform: #FFF;
29
+
30
+ /* ========================================= */
31
+ /* SURFACE TOKENS */
32
+ /* Use for backgrounds, cards, containers */
33
+ /* ========================================= */
34
+
35
+ --surface-bg: #F9F9FA;
36
+ --surface-1: #F0F1F5;
37
+ --surface-2: #E8EBF0;
38
+ --surface-3: #D8DDE5;
39
+ --surface-4: #CACFDB;
40
+
41
+ /* ========================================= */
42
+ /* TEXT EMPHASIS TOKENS */
43
+ /* Use for text colors based on hierarchy */
44
+ /* ========================================= */
45
+
46
+ --disabled: #BFC6D4;
47
+ --placeholder: #667085;
48
+ --low-em: #5A606B;
49
+ --med-em: #2F343C;
50
+ --high-em: #22262E;
51
+
52
+ /* ========================================= */
53
+ /* BRAND TOKENS */
54
+ /* Primary brand colors */
55
+ /* ========================================= */
56
+
57
+ --brand-primary-main: #0A0F15;
58
+ --brand-primary-main-special: #0A0F15;
59
+
60
+ --brand-primary-accent-special: #191E25;
61
+ --brand-primary-accent-3: #262C35;
62
+
63
+ --brand-secondary-main: #2563EB;
64
+ --brand-secondary-accent-3: #3B76F6;
65
+
66
+ /* ========================================= */
67
+ /* SEMANTIC STATUS TOKENS - WARNING */
68
+ /* ========================================= */
69
+
70
+ --warning-em: #FB6E0A;
71
+ --warning-main: #FC9E0B;
72
+ --warning-accent-3: #FDC82C;
73
+ --warning-accent-1: #FEDE82;
74
+ --warning-accent-0: #FFF8E1;
75
+
76
+ /* ========================================= */
77
+ /* SEMANTIC STATUS TOKENS - SUCCESS */
78
+ /* ========================================= */
79
+
80
+ --success-em: #054F31;
81
+ --success-main: #039855;
82
+ --success-accent-3: #32D583;
83
+ --success-accent-2: #A6F4C5;
84
+ --success-accent-1: #ECFDF3;
85
+
86
+ /* ========================================= */
87
+ /* SEMANTIC STATUS TOKENS - INFO */
88
+ /* ========================================= */
89
+
90
+ --info-em: #3362C2;
91
+ --info-main: #3A85E8;
92
+ --info-accent-3: #50A3F9;
93
+ --info-accent-2: #94C9FC;
94
+ --info-accent-1: #E4F2FE;
95
+
96
+ /* ========================================= */
97
+ /* SEMANTIC STATUS TOKENS - DANGER */
98
+ /* ========================================= */
99
+
100
+ --danger-em: #DE2424;
101
+ --danger-main: #F03D3D;
102
+ --danger-accent-3: #FF7373;
103
+ --danger-accent-2: #FFE0E0;
104
+ --danger-accent-1: #FEF2F2;
105
+
106
+ /* ========================================= */
107
+ /* SPACING SYSTEM */
108
+ /* ========================================= */
109
+
110
+ --spacing-0: 0px;
111
+ --spacing-1: 2px;
112
+ --spacing-2: 4px;
113
+ --spacing-3: 6px;
114
+ --spacing-4: 8px;
115
+ --spacing-5: 10px;
116
+ --spacing-6: 12px;
117
+ --spacing-7: 14px;
118
+ --spacing-8: 16px;
119
+ --spacing-9: 20px;
120
+ --spacing-10: 24px;
121
+ --spacing-11: 28px;
122
+ --spacing-12: 32px;
123
+ --spacing-13: 40px;
124
+ --spacing-14: 48px;
125
+ --spacing-15: 64px;
126
+ --spacing-16: 80px;
127
+ --spacing-17: 96px;
128
+ --spacing-18: 128px;
129
+ --spacing-19: 180px;
130
+ --spacing-20: 192px;
131
+ --spacing-21: 224px;
132
+ --spacing-22: 256px;
133
+ --spacing-23: 320px;
134
+ --spacing-24: 384px;
135
+ --spacing-25: 480px;
136
+ --spacing-26: 560px;
137
+
138
+ /* ========================================= */
139
+ /* SHADOW SYSTEM */
140
+ /* Use for elevations and depth */
141
+ /* ========================================= */
142
+
143
+ --shadow-e1: 0px 4px 12px -2px rgba(0, 0, 0, 0.08);
144
+ --shadow-e2: 0px 8px 24px -4px rgba(0, 0, 0, 0.12);
145
+ --shadow-e3: 0px 12px 32px -6px rgba(0, 0, 0, 0.16);
146
+
147
+ /* ========================================= */
148
+ /* LAYOUT SYSTEM */
149
+ /* Container, Sidebar, and Navbar tokens */
150
+ /* ========================================= */
151
+
152
+ /* Container Max Widths */
153
+ --layout-container-max-width: 1400px;
154
+ --layout-container-narrow: 896px;
155
+ --layout-container-medium: 1152px;
156
+ --layout-container-wide: 1600px;
157
+
158
+ /* Container Padding (responsive) */
159
+ --layout-container-padding-mobile: 16px;
160
+ --layout-container-padding-tablet: 24px;
161
+ --layout-container-padding-desktop: 32px;
162
+ --layout-container-padding-desktop-lg: 48px;
163
+
164
+ /* Sidebar Dimensions */
165
+ --layout-sidebar-width: 280px;
166
+ --layout-sidebar-collapsed: 64px;
167
+ --layout-sidebar-navigation: 240px;
168
+
169
+ /* Navbar Dimensions */
170
+ --layout-navbar-header-height: 60px;
171
+ --layout-navbar-tabs-height: 48px;
172
+ --layout-navbar-total-height: 108px;
173
+
174
+ }
175
+
176
+ /* ========================================= */
177
+ /* DARK MODE THEME */
178
+ /* ========================================= */
179
+
180
+ .dark {
181
+ /* Primitive colors - INVERTED */
182
+ --black: #FFF;
183
+ --white: #000;
184
+
185
+ /* Surface tokens - Dark backgrounds */
186
+ --surface-bg: #0A0A0A;
187
+ --surface-1: #131313;
188
+ --surface-2: #1F1F1F;
189
+ --surface-3: #292929;
190
+ --surface-4: #333333;
191
+
192
+ /* Text emphasis - Lighter for dark backgrounds */
193
+ --disabled: #565656;
194
+ --placeholder: #C4C4C4;
195
+ --low-em: #7E7E7E;
196
+ --med-em: #C3C3C3;
197
+ --high-em: #FFF;
198
+
199
+ /* Brand tokens - Adjusted for dark mode */
200
+ --brand-primary-main: #3B414C;
201
+ --brand-primary-main-special: #1F1F1F;
202
+
203
+ --brand-primary-accent-special: #333333;
204
+ --brand-primary-accent-3: #262C35;
205
+
206
+ --brand-secondary-main: #2563EB;
207
+ --brand-secondary-accent-3: #3B76F6;
208
+
209
+ /* Warning tokens - Dark mode variants */
210
+ --warning-em: #FED350;
211
+ --warning-main: #FDBE12;
212
+ --warning-accent-3: #FDB10C;
213
+ --warning-accent-1: #FEDE82;
214
+ --warning-accent-0: #3A2A06;
215
+
216
+ /* Success tokens - Dark mode variants */
217
+ --success-em: #6CE9A6;
218
+ --success-main: #12B76A;
219
+ --success-accent-3: #039855;
220
+ --success-accent-2: #054F31;
221
+ --success-accent-1: #053321;
222
+
223
+ /* Info tokens - Dark mode variants */
224
+ --info-em: #6CB3FA;
225
+ --info-main: #3C93F7;
226
+ --info-accent-3: #3A85E8;
227
+ --info-accent-2: #2C43A3;
228
+ --info-accent-1: #3560C2;
229
+
230
+ /* Danger tokens - Dark mode variants */
231
+ --danger-em: #FFA9A9;
232
+ --danger-main: #F03D3D;
233
+ --danger-accent-3: #DE2424;
234
+ --danger-accent-2: #3F1E1E;
235
+ --danger-accent-1: #371C1C;
236
+
237
+ /* Canvas tokens - Dark mode */
238
+ --canvas-container-bg: #0a0a0a;
239
+ --canvas-bg: #111111;
240
+ --canvas-grid-bg: #0f0f0f;
241
+ --canvas-grid-line: #2a2a2a;
242
+ --canvas-grid-center-line: #181818;
243
+ }
244
+
245
+ /* ========================================= */
246
+ /* TAILWIND THEME INTEGRATION */
247
+ /* ========================================= */
248
+
249
+ @theme inline {
250
+ /* Font families */
251
+ --font-family-inter: var(--font-inter);
252
+ --font-family-space-grotesk: var(--font-space-grotesk);
253
+
254
+ /* Primitive colors */
255
+ --color-black: var(--black);
256
+ --color-white: var(--white);
257
+
258
+ --color-black-uniform: var(--black-uniform);
259
+ --color-white-uniform: var(--white-uniform);
260
+
261
+
262
+ /* Surface colors */
263
+ --color-surface-bg: var(--surface-bg);
264
+ --color-surface-1: var(--surface-1);
265
+ --color-surface-2: var(--surface-2);
266
+ --color-surface-3: var(--surface-3);
267
+ --color-surface-4: var(--surface-4);
268
+
269
+ /* Text emphasis */
270
+ --color-disabled: var(--disabled);
271
+ --color-placeholder: var(--placeholder);
272
+ --color-low-em: var(--low-em);
273
+ --color-med-em: var(--med-em);
274
+ --color-high-em: var(--high-em);
275
+
276
+ /* Brand colors */
277
+ --color-brand-primary-main: var(--brand-primary-main);
278
+ --color-brand-primary-main-special: var(--brand-primary-main-special);
279
+ --color-brand-primary-accent-special: var(--brand-primary-accent-special);
280
+ --color-brand-primary-accent-3: var(--brand-primary-accent-3);
281
+ --color-brand-secondary-main: var(--brand-secondary-main);
282
+ --color-brand-secondary-accent-3: var(--brand-secondary-accent-3);
283
+
284
+ /* Warning colors */
285
+ --color-warning-em: var(--warning-em);
286
+ --color-warning-main: var(--warning-main);
287
+ --color-warning-accent-3: var(--warning-accent-3);
288
+ --color-warning-accent-1: var(--warning-accent-1);
289
+ --color-warning-accent-0: var(--warning-accent-0);
290
+
291
+ /* Success colors */
292
+ --color-success-em: var(--success-em);
293
+ --color-success-main: var(--success-main);
294
+ --color-success-accent-3: var(--success-accent-3);
295
+ --color-success-accent-2: var(--success-accent-2);
296
+ --color-success-accent-1: var(--success-accent-1);
297
+
298
+ /* Info colors */
299
+ --color-info-em: var(--info-em);
300
+ --color-info-main: var(--info-main);
301
+ --color-info-accent-3: var(--info-accent-3);
302
+ --color-info-accent-2: var(--info-accent-2);
303
+ --color-info-accent-1: var(--info-accent-1);
304
+
305
+ /* Danger colors */
306
+ --color-danger-em: var(--danger-em);
307
+ --color-danger-main: var(--danger-main);
308
+ --color-danger-accent-3: var(--danger-accent-3);
309
+ --color-danger-accent-2: var(--danger-accent-2);
310
+ --color-danger-accent-1: var(--danger-accent-1);
311
+
312
+ /* Spacing */
313
+ --spacing-0: 0px;
314
+ --spacing-1: 2px;
315
+ --spacing-2: 4px;
316
+ --spacing-3: 6px;
317
+ --spacing-4: 8px;
318
+ --spacing-5: 10px;
319
+ --spacing-6: 12px;
320
+ --spacing-7: 14px;
321
+ --spacing-8: 16px;
322
+ --spacing-9: 20px;
323
+ --spacing-10: 24px;
324
+ --spacing-11: 28px;
325
+ --spacing-12: 32px;
326
+ --spacing-13: 40px;
327
+ --spacing-14: 48px;
328
+ --spacing-15: 64px;
329
+ --spacing-16: 80px;
330
+ --spacing-17: 96px;
331
+ --spacing-18: 128px;
332
+ --spacing-19: 180px;
333
+ --spacing-20: 192px;
334
+ --spacing-21: 224px;
335
+ --spacing-22: 256px;
336
+ --spacing-23: 320px;
337
+ --spacing-24: 384px;
338
+ --spacing-25: 480px;
339
+ --spacing-26: 560px;
340
+
341
+ /* Border Radius */
342
+ --radius-0: 0px;
343
+ --radius-1: 2px;
344
+ --radius-2: 4px;
345
+ --radius-3: 6px;
346
+ --radius-4: 8px;
347
+ --radius-5: 10px;
348
+ --radius-6: 12px;
349
+ --radius-7: 14px;
350
+ --radius-8: 16px;
351
+ --radius-9: 20px;
352
+ --radius-10: 24px;
353
+ --radius-11: 28px;
354
+ --radius-12: 32px;
355
+ --radius-13: 40px;
356
+ --radius-14: 48px;
357
+ --radius-15: 64px;
358
+ --radius-16: 80px;
359
+ --radius-17: 96px;
360
+ --radius-18: 128px;
361
+ --radius-19: 180px;
362
+ --radius-20: 192px;
363
+ --radius-21: 224px;
364
+ --radius-22: 256px;
365
+ --radius-23: 320px;
366
+ --radius-24: 384px;
367
+ --radius-25: 480px;
368
+ --radius-26: 560px;
369
+
370
+ /* Shadows */
371
+ --shadow-e1: var(--shadow-e1);
372
+ --shadow-e2: var(--shadow-e2);
373
+ --shadow-e3: var(--shadow-e3);
374
+
375
+ /* ========================================= */
376
+ /* LAYOUT SYSTEM */
377
+ /* ========================================= */
378
+
379
+ /* Container Max Widths */
380
+ --max-width-container: var(--layout-container-max-width);
381
+ --max-width-container-narrow: var(--layout-container-narrow);
382
+ --max-width-container-medium: var(--layout-container-medium);
383
+ --max-width-container-wide: var(--layout-container-wide);
384
+
385
+ /* Container Padding */
386
+ --padding-container-mobile: var(--layout-container-padding-mobile);
387
+ --padding-container-tablet: var(--layout-container-padding-tablet);
388
+ --padding-container-desktop: var(--layout-container-padding-desktop);
389
+ --padding-container-desktop-lg: var(--layout-container-padding-desktop-lg);
390
+
391
+ /* Sidebar Widths */
392
+ --width-sidebar: var(--layout-sidebar-width);
393
+ --width-sidebar-collapsed: var(--layout-sidebar-collapsed);
394
+ --width-sidebar-nav: var(--layout-sidebar-navigation);
395
+
396
+ /* Navbar Heights */
397
+ --height-navbar: var(--layout-navbar-total-height);
398
+ --height-navbar-header: var(--layout-navbar-header-height);
399
+ --height-navbar-tabs: var(--layout-navbar-tabs-height);
400
+
401
+ }
402
+
403
+ /* ========================================= */
404
+ /* BASE STYLES */
405
+ /* ========================================= */
406
+
407
+ body {
408
+ background: var(--surface-bg);
409
+ color: var(--high-em);
410
+ font-family: var(--font-inter), system-ui, sans-serif;
411
+ }
412
+
413
+ /* ========================================= */
414
+ /* ANIMATIONS */
415
+ /* ========================================= */
416
+
417
+ @keyframes typing-dot {
418
+ 0%,
419
+ 60%,
420
+ 100% {
421
+ opacity: 0.3;
422
+ transform: translateY(0) scale(0.8);
423
+ }
424
+ 30% {
425
+ opacity: 1;
426
+ transform: translateY(-4px) scale(1);
427
+ }
428
+ }
429
+
430
+ @layer utilities {
431
+ .ds-scrollbar {
432
+ scrollbar-width: thin;
433
+ scrollbar-color: var(--surface-3) var(--surface-1);
434
+ }
435
+
436
+ .ds-scrollbar::-webkit-scrollbar {
437
+ width: 7px;
438
+ height: 7px;
439
+ }
440
+
441
+ .ds-scrollbar::-webkit-scrollbar-track {
442
+ background: var(--surface-1);
443
+ }
444
+
445
+ .ds-scrollbar::-webkit-scrollbar-thumb {
446
+ background: var(--surface-3);
447
+ border-radius: 999px;
448
+ }
449
+
450
+ .ds-scrollbar::-webkit-scrollbar-thumb:hover {
451
+ background: var(--surface-4);
452
+ }
453
+
454
+ .animate-typing-dot {
455
+ animation: typing-dot 1.4s infinite ease-in-out;
456
+ }
457
+
458
+ /* Responsive flex direction utilities with proper specificity */
459
+ .flex-col-to-row {
460
+ flex-direction: column;
461
+ @media (min-width: 1024px) {
462
+ flex-direction: row;
463
+ }
464
+ }
465
+
466
+ .flex-col-to-row-md {
467
+ flex-direction: column;
468
+ @media (min-width: 768px) {
469
+ flex-direction: row;
470
+ }
471
+ }
472
+
473
+ /* Panel Layout animations - LEFT side */
474
+ .animate-panel-enter {
475
+ animation: panel-enter 0.15s cubic-bezier(0.25, 0.46, 0.45, 0.94);
476
+ }
477
+
478
+ .animate-panel-exit {
479
+ animation: panel-exit 0.1s cubic-bezier(0.55, 0.055, 0.675, 0.19) forwards;
480
+ }
481
+
482
+ /* Panel Layout animations - RIGHT side */
483
+ .animate-panel-enter-right {
484
+ animation: panel-enter-right 0.15s cubic-bezier(0.25, 0.46, 0.45, 0.94);
485
+ }
486
+
487
+ .animate-panel-exit-right {
488
+ animation: panel-exit-right 0.1s cubic-bezier(0.55, 0.055, 0.675, 0.19) forwards;
489
+ }
490
+ }
491
+
492
+ /* Panel enter/exit animations - LEFT side */
493
+ @keyframes panel-enter {
494
+ from {
495
+ opacity: 0;
496
+ transform: translateX(-10px);
497
+ }
498
+ to {
499
+ opacity: 1;
500
+ transform: translateX(0);
501
+ }
502
+ }
503
+
504
+ @keyframes panel-exit {
505
+ from {
506
+ opacity: 1;
507
+ transform: translateX(0);
508
+ }
509
+ to {
510
+ opacity: 0;
511
+ transform: translateX(-10px);
512
+ }
513
+ }
514
+
515
+ /* Panel enter/exit animations - RIGHT side */
516
+ @keyframes panel-enter-right {
517
+ from {
518
+ opacity: 0;
519
+ transform: translateX(10px);
520
+ }
521
+ to {
522
+ opacity: 1;
523
+ transform: translateX(0);
524
+ }
525
+ }
526
+
527
+ @keyframes panel-exit-right {
528
+ from {
529
+ opacity: 1;
530
+ transform: translateX(0);
531
+ }
532
+ to {
533
+ opacity: 0;
534
+ transform: translateX(10px);
535
+ }
536
+ }