@floegence/floe-webapp-core 0.1.15 → 0.1.17

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 (92) hide show
  1. package/dist/app/ActivityAppsMain.d.ts +23 -0
  2. package/dist/app/index.d.ts +1 -0
  3. package/dist/components/layout/KeepAliveStack.d.ts +16 -0
  4. package/dist/components/layout/index.d.ts +1 -0
  5. package/dist/context/ViewActivationContext.d.ts +12 -0
  6. package/dist/context/index.d.ts +1 -0
  7. package/dist/floe.css +442 -0
  8. package/dist/index.js +250 -243
  9. package/dist/index10.js +126 -90
  10. package/dist/index11.js +91 -97
  11. package/dist/index12.js +100 -100
  12. package/dist/index13.js +107 -78
  13. package/dist/index14.js +80 -119
  14. package/dist/index15.js +108 -91
  15. package/dist/index16.js +93 -118
  16. package/dist/index17.js +120 -141
  17. package/dist/index18.js +148 -37
  18. package/dist/index19.js +36 -56
  19. package/dist/index2.js +6 -6
  20. package/dist/index20.js +47 -65
  21. package/dist/index21.js +73 -156
  22. package/dist/index22.js +147 -311
  23. package/dist/index23.js +311 -121
  24. package/dist/index24.js +126 -41
  25. package/dist/index25.js +47 -142
  26. package/dist/index26.js +138 -250
  27. package/dist/index27.js +236 -177
  28. package/dist/index28.js +187 -80
  29. package/dist/index29.js +87 -37
  30. package/dist/index3.js +2 -2
  31. package/dist/index30.js +37 -66
  32. package/dist/index31.js +69 -278
  33. package/dist/index32.js +278 -152
  34. package/dist/index33.js +147 -24
  35. package/dist/index34.js +26 -45
  36. package/dist/index35.js +45 -10
  37. package/dist/index36.js +10 -27
  38. package/dist/index37.js +27 -145
  39. package/dist/index38.js +140 -105
  40. package/dist/index39.js +109 -89
  41. package/dist/index4.js +1 -1
  42. package/dist/index40.js +79 -97
  43. package/dist/index41.js +85 -61
  44. package/dist/index42.js +81 -173
  45. package/dist/index43.js +177 -65
  46. package/dist/index44.js +56 -61
  47. package/dist/index45.js +70 -38
  48. package/dist/index46.js +39 -48
  49. package/dist/index47.js +40 -30
  50. package/dist/index48.js +37 -24
  51. package/dist/index49.js +42 -166
  52. package/dist/index5.js +4 -4
  53. package/dist/index50.js +22 -37
  54. package/dist/index51.js +167 -60
  55. package/dist/index52.js +31 -87
  56. package/dist/index53.js +63 -114
  57. package/dist/index54.js +88 -130
  58. package/dist/index55.js +114 -36
  59. package/dist/index56.js +130 -411
  60. package/dist/index57.js +38 -37
  61. package/dist/index58.js +418 -12
  62. package/dist/index59.js +38 -10
  63. package/dist/index6.js +2 -2
  64. package/dist/index60.js +19 -16
  65. package/dist/index61.js +12 -9
  66. package/dist/index62.js +10 -8
  67. package/dist/index63.js +15 -57
  68. package/dist/index64.js +10 -5
  69. package/dist/index65.js +8 -3
  70. package/dist/index66.js +56 -43
  71. package/dist/index67.js +5 -26
  72. package/dist/index68.js +3 -32
  73. package/dist/index69.js +44 -90
  74. package/dist/index7.js +1 -1
  75. package/dist/index70.js +23 -19
  76. package/dist/index71.js +28 -42
  77. package/dist/index72.js +92 -15
  78. package/dist/index73.js +22 -35
  79. package/dist/index74.js +45 -63
  80. package/dist/index75.js +14 -84
  81. package/dist/index76.js +35 -14
  82. package/dist/index77.js +59 -2258
  83. package/dist/index78.js +84 -7
  84. package/dist/index79.js +17 -0
  85. package/dist/index8.js +2 -2
  86. package/dist/index80.js +2266 -0
  87. package/dist/index81.js +10 -0
  88. package/dist/index9.js +1 -1
  89. package/dist/tailwind.css +9 -0
  90. package/dist/themes/dark.css +75 -0
  91. package/dist/themes/light.css +79 -0
  92. package/package.json +5 -3
@@ -0,0 +1,23 @@
1
+ import { type Accessor } from 'solid-js';
2
+ import { type FloeComponent } from '../context/ComponentRegistry';
3
+ import { type KeepAliveStackProps, type KeepAliveView } from '../components/layout/KeepAliveStack';
4
+ export interface ActivityAppsMainProps<TProtocol = unknown> {
5
+ class?: string;
6
+ /** Override the active id (default: LayoutContext.sidebarActiveTab). */
7
+ activeId?: Accessor<string>;
8
+ /**
9
+ * Explicit view list (advanced).
10
+ * When provided, the registry is not required.
11
+ */
12
+ views?: KeepAliveView[];
13
+ /**
14
+ * Registry-driven filter (default: sidebar.fullScreen === true).
15
+ * Only used when `views` is not provided.
16
+ */
17
+ include?: (component: FloeComponent<TProtocol>) => boolean;
18
+ /** Forwarded to KeepAliveStack (default: true). */
19
+ lazyMount?: KeepAliveStackProps['lazyMount'];
20
+ /** Forwarded to KeepAliveStack (default: true). */
21
+ keepMounted?: KeepAliveStackProps['keepMounted'];
22
+ }
23
+ export declare function ActivityAppsMain<TProtocol = unknown>(props: ActivityAppsMainProps<TProtocol>): import("solid-js").JSX.Element;
@@ -1,2 +1,3 @@
1
1
  export { FloeProvider, type FloeProviderProps } from './FloeProvider';
2
2
  export { FloeApp, type FloeAppProps } from './FloeApp';
3
+ export { ActivityAppsMain, type ActivityAppsMainProps } from './ActivityAppsMain';
@@ -0,0 +1,16 @@
1
+ import { type JSX } from 'solid-js';
2
+ export interface KeepAliveView {
3
+ id: string;
4
+ render: () => JSX.Element;
5
+ class?: string;
6
+ }
7
+ export interface KeepAliveStackProps {
8
+ views: KeepAliveView[];
9
+ activeId: string;
10
+ class?: string;
11
+ /** When true, a view is mounted only after its first activation (default: true). */
12
+ lazyMount?: boolean;
13
+ /** When true, mounted views stay mounted after deactivation (default: true). */
14
+ keepMounted?: boolean;
15
+ }
16
+ export declare function KeepAliveStack(props: KeepAliveStackProps): JSX.Element;
@@ -6,4 +6,5 @@ export { BottomBar, BottomBarItem, StatusIndicator, type BottomBarProps, type Bo
6
6
  export { MobileTabBar, type MobileTabBarItem, type MobileTabBarProps } from './MobileTabBar';
7
7
  export { ResizeHandle, type ResizeHandleProps } from './ResizeHandle';
8
8
  export { Panel, PanelHeader, PanelContent, type PanelProps, type PanelHeaderProps, type PanelContentProps } from './Panel';
9
+ export { KeepAliveStack, type KeepAliveStackProps, type KeepAliveView } from './KeepAliveStack';
9
10
  export * from '../deck';
@@ -0,0 +1,12 @@
1
+ import { type Accessor, type JSX } from 'solid-js';
2
+ export interface ViewActivationContextValue {
3
+ id: string;
4
+ active: Accessor<boolean>;
5
+ activationSeq: Accessor<number>;
6
+ }
7
+ export interface ViewActivationProviderProps {
8
+ value: ViewActivationContextValue;
9
+ children: JSX.Element;
10
+ }
11
+ export declare function ViewActivationProvider(props: ViewActivationProviderProps): JSX.Element;
12
+ export declare function useViewActivation(): ViewActivationContextValue;
@@ -8,3 +8,4 @@ export { ComponentRegistryProvider, useComponentRegistry, useComponentContextFac
8
8
  export { WidgetRegistryProvider, useWidgetRegistry, createWidgetRegistry, type WidgetDefinition, type WidgetProps, type WidgetRegistryValue, } from './WidgetRegistry';
9
9
  export { DeckProvider, useDeck, createDeckService, type DeckWidget, type DeckLayout, type DragState, type ResizeState, type DeckContextValue, } from './DeckContext';
10
10
  export { WidgetStateProvider, useWidgetStateContext, useWidgetState, useCurrentWidgetId, type WidgetStateContextValue, type WidgetStateProviderProps, } from './WidgetStateContext';
11
+ export { ViewActivationProvider, useViewActivation, type ViewActivationContextValue, type ViewActivationProviderProps } from './ViewActivationContext';
package/dist/floe.css ADDED
@@ -0,0 +1,442 @@
1
+ /*
2
+ * Floe design tokens + base styles + custom utilities.
3
+ *
4
+ * This file is Tailwind v4 input CSS (it uses @theme/@layer) and is consumed by:
5
+ * - `@floegence/floe-webapp-core/styles` (precompiled bundle via `globals.css`)
6
+ * - `@floegence/floe-webapp-core/tailwind` (downstream Tailwind integration entry)
7
+ *
8
+ * It intentionally does NOT include:
9
+ * - `@import 'tailwindcss'` (owned by the application / precompiled entry)
10
+ * - any `@source` directives (owned by the entry that imports this file)
11
+ */
12
+
13
+
14
+ /* Import theme definitions - they define the CSS variables */
15
+ @import './themes/light.css';
16
+ @import './themes/dark.css';
17
+
18
+ /*
19
+ * TailwindCSS v4 requires @theme for utilities. However, CSS variable
20
+ * references don't work properly for background/text color utilities.
21
+ * Instead, we use @utility to define custom utilities that reference
22
+ * CSS variables at runtime.
23
+ */
24
+
25
+ /* Border radius - these work fine with var() */
26
+ @theme {
27
+ --radius-sm: calc(var(--radius) - 4px);
28
+ --radius-md: calc(var(--radius) - 2px);
29
+ --radius-lg: var(--radius);
30
+ --radius-xl: calc(var(--radius) + 4px);
31
+ }
32
+
33
+ /* Custom color utilities using CSS variables */
34
+ @layer utilities {
35
+ /* Background colors */
36
+ .bg-background { background-color: var(--background); }
37
+ .bg-foreground { background-color: var(--foreground); }
38
+ .bg-primary { background-color: var(--primary); }
39
+ .bg-primary-foreground { background-color: var(--primary-foreground); }
40
+ .bg-secondary { background-color: var(--secondary); }
41
+ .bg-secondary-foreground { background-color: var(--secondary-foreground); }
42
+ .bg-muted { background-color: var(--muted); }
43
+ .bg-muted-foreground { background-color: var(--muted-foreground); }
44
+ .bg-accent { background-color: var(--accent); }
45
+ .bg-accent-foreground { background-color: var(--accent-foreground); }
46
+ .bg-card { background-color: var(--card); }
47
+ .bg-card-foreground { background-color: var(--card-foreground); }
48
+ .bg-popover { background-color: var(--popover); }
49
+ .bg-popover-foreground { background-color: var(--popover-foreground); }
50
+ .bg-border { background-color: var(--border); }
51
+ .bg-input { background-color: var(--input); }
52
+ .bg-ring { background-color: var(--ring); }
53
+ .bg-success { background-color: var(--success); }
54
+ .bg-success-foreground { background-color: var(--success-foreground); }
55
+ .bg-warning { background-color: var(--warning); }
56
+ .bg-warning-foreground { background-color: var(--warning-foreground); }
57
+ .bg-error { background-color: var(--error); }
58
+ .bg-error-foreground { background-color: var(--error-foreground); }
59
+ /* Alias: destructive == error (VSCode-style danger actions) */
60
+ .bg-destructive { background-color: var(--error); }
61
+ .bg-destructive-foreground { background-color: var(--error-foreground); }
62
+ .bg-info { background-color: var(--info); }
63
+ .bg-info-foreground { background-color: var(--info-foreground); }
64
+ .bg-sidebar { background-color: var(--sidebar); }
65
+ .bg-sidebar-foreground { background-color: var(--sidebar-foreground); }
66
+ .bg-sidebar-primary { background-color: var(--sidebar-primary); }
67
+ .bg-sidebar-primary-foreground { background-color: var(--sidebar-primary-foreground); }
68
+ .bg-sidebar-accent { background-color: var(--sidebar-accent); }
69
+ .bg-sidebar-accent-foreground { background-color: var(--sidebar-accent-foreground); }
70
+ .bg-sidebar-border { background-color: var(--sidebar-border); }
71
+ .bg-sidebar-ring { background-color: var(--sidebar-ring); }
72
+ .bg-activity-bar { background-color: var(--activity-bar); }
73
+ .bg-activity-bar-foreground { background-color: var(--activity-bar-foreground); }
74
+ .bg-activity-bar-foreground-active { background-color: var(--activity-bar-foreground-active); }
75
+ .bg-activity-bar-badge { background-color: var(--activity-bar-badge); }
76
+ .bg-activity-bar-badge-foreground { background-color: var(--activity-bar-badge-foreground); }
77
+ .bg-terminal-background { background-color: var(--terminal-background); }
78
+ .bg-terminal-foreground { background-color: var(--terminal-foreground); }
79
+
80
+ /* Text colors */
81
+ .text-background { color: var(--background); }
82
+ .text-foreground { color: var(--foreground); }
83
+ .text-primary { color: var(--primary); }
84
+ .text-primary-foreground { color: var(--primary-foreground); }
85
+ .text-secondary { color: var(--secondary); }
86
+ .text-secondary-foreground { color: var(--secondary-foreground); }
87
+ .text-muted { color: var(--muted); }
88
+ .text-muted-foreground { color: var(--muted-foreground); }
89
+ .text-accent { color: var(--accent); }
90
+ .text-accent-foreground { color: var(--accent-foreground); }
91
+ .text-card { color: var(--card); }
92
+ .text-card-foreground { color: var(--card-foreground); }
93
+ .text-popover { color: var(--popover); }
94
+ .text-popover-foreground { color: var(--popover-foreground); }
95
+ .text-border { color: var(--border); }
96
+ .text-input { color: var(--input); }
97
+ .text-ring { color: var(--ring); }
98
+ .text-success { color: var(--success); }
99
+ .text-success-foreground { color: var(--success-foreground); }
100
+ .text-warning { color: var(--warning); }
101
+ .text-warning-foreground { color: var(--warning-foreground); }
102
+ .text-error { color: var(--error); }
103
+ .text-error-foreground { color: var(--error-foreground); }
104
+ /* Alias: destructive == error */
105
+ .text-destructive { color: var(--error); }
106
+ .text-destructive-foreground { color: var(--error-foreground); }
107
+ .text-info { color: var(--info); }
108
+ .text-info-foreground { color: var(--info-foreground); }
109
+ .text-sidebar { color: var(--sidebar); }
110
+ .text-sidebar-foreground { color: var(--sidebar-foreground); }
111
+ .text-sidebar-primary { color: var(--sidebar-primary); }
112
+ .text-sidebar-primary-foreground { color: var(--sidebar-primary-foreground); }
113
+ .text-sidebar-accent { color: var(--sidebar-accent); }
114
+ .text-sidebar-accent-foreground { color: var(--sidebar-accent-foreground); }
115
+ .text-sidebar-border { color: var(--sidebar-border); }
116
+ .text-sidebar-ring { color: var(--sidebar-ring); }
117
+ .text-activity-bar { color: var(--activity-bar); }
118
+ .text-activity-bar-foreground { color: var(--activity-bar-foreground); }
119
+ .text-activity-bar-foreground-active { color: var(--activity-bar-foreground-active); }
120
+ .text-activity-bar-badge { color: var(--activity-bar-badge); }
121
+ .text-activity-bar-badge-foreground { color: var(--activity-bar-badge-foreground); }
122
+ .text-terminal-background { color: var(--terminal-background); }
123
+ .text-terminal-foreground { color: var(--terminal-foreground); }
124
+
125
+ /* Border colors */
126
+ .border-border { border-color: var(--border); }
127
+ .border-input { border-color: var(--input); }
128
+ .border-ring { border-color: var(--ring); }
129
+ .border-primary { border-color: var(--primary); }
130
+ .border-secondary { border-color: var(--secondary); }
131
+ .border-muted { border-color: var(--muted); }
132
+ .border-accent { border-color: var(--accent); }
133
+ .border-sidebar-border { border-color: var(--sidebar-border); }
134
+
135
+ /* Ring colors */
136
+ .ring-ring { --tw-ring-color: var(--ring); }
137
+ .ring-primary { --tw-ring-color: var(--primary); }
138
+ .ring-sidebar-ring { --tw-ring-color: var(--sidebar-ring); }
139
+
140
+ /* Hover states for primary */
141
+ .hover\:bg-primary\/90:hover { background-color: color-mix(in srgb, var(--primary) 90%, transparent); }
142
+ .hover\:bg-secondary\/80:hover { background-color: color-mix(in srgb, var(--secondary) 80%, transparent); }
143
+ .hover\:bg-accent:hover { background-color: var(--accent); }
144
+ .hover\:bg-accent\/50:hover { background-color: color-mix(in srgb, var(--accent) 50%, transparent); }
145
+ .hover\:bg-muted:hover { background-color: var(--muted); }
146
+ .hover\:text-accent-foreground:hover { color: var(--accent-foreground); }
147
+ .hover\:bg-error\/90:hover { background-color: color-mix(in srgb, var(--error) 90%, transparent); }
148
+ .hover\:bg-destructive\/10:hover { background-color: color-mix(in srgb, var(--error) 10%, transparent); }
149
+ .hover\:text-destructive:hover { color: var(--error); }
150
+
151
+ /* Opacity variants for overlays */
152
+ .bg-background\/60 { background-color: color-mix(in srgb, var(--background) 60%, transparent); }
153
+ .bg-background\/80 { background-color: color-mix(in srgb, var(--background) 80%, transparent); }
154
+ .bg-muted\/40 { background-color: color-mix(in srgb, var(--muted) 40%, transparent); }
155
+ .bg-muted\/50 { background-color: color-mix(in srgb, var(--muted) 50%, transparent); }
156
+ .bg-muted\/70 { background-color: color-mix(in srgb, var(--muted) 70%, transparent); }
157
+ .bg-muted\/80 { background-color: color-mix(in srgb, var(--muted) 80%, transparent); }
158
+ .bg-muted-foreground\/30 { background-color: color-mix(in srgb, var(--muted-foreground) 30%, transparent); }
159
+ .bg-primary\/70 { background-color: color-mix(in srgb, var(--primary) 70%, transparent); }
160
+ .bg-accent\/40 { background-color: color-mix(in srgb, var(--accent) 40%, transparent); }
161
+ .bg-accent\/80 { background-color: color-mix(in srgb, var(--accent) 80%, transparent); }
162
+ .text-muted-foreground\/70 { color: color-mix(in srgb, var(--muted-foreground) 70%, transparent); }
163
+ .placeholder\:text-muted-foreground\/60::placeholder { color: color-mix(in srgb, var(--muted-foreground) 60%, transparent); }
164
+
165
+ /* Additional hover states */
166
+ .hover\:bg-primary\/50:hover { background-color: color-mix(in srgb, var(--primary) 50%, transparent); }
167
+ .hover\:bg-muted\/70:hover { background-color: color-mix(in srgb, var(--muted) 70%, transparent); }
168
+ .hover\:bg-muted\/80:hover { background-color: color-mix(in srgb, var(--muted) 80%, transparent); }
169
+ .hover\:bg-accent\/40:hover { background-color: color-mix(in srgb, var(--accent) 40%, transparent); }
170
+ .hover\:bg-sidebar-accent\/80:hover { background-color: color-mix(in srgb, var(--sidebar-accent) 80%, transparent); }
171
+ .hover\:border-border\/50:hover { border-color: color-mix(in srgb, var(--border) 50%, transparent); }
172
+ .border-border\/50 { border-color: color-mix(in srgb, var(--border) 50%, transparent); }
173
+
174
+ /* Gradient utilities with CSS variables */
175
+ .from-primary {
176
+ --tw-gradient-from: var(--primary);
177
+ --tw-gradient-to: transparent;
178
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
179
+ }
180
+ .to-primary\/70 {
181
+ --tw-gradient-to: color-mix(in srgb, var(--primary) 70%, transparent);
182
+ }
183
+ }
184
+
185
+ /* Base styles */
186
+ @layer base {
187
+ * {
188
+ border-color: var(--border);
189
+ scrollbar-width: thin;
190
+ scrollbar-color: var(--muted) transparent;
191
+ }
192
+
193
+ *::-webkit-scrollbar {
194
+ width: 0.5rem;
195
+ height: 0.5rem;
196
+ }
197
+
198
+ *::-webkit-scrollbar-track {
199
+ background: transparent;
200
+ }
201
+
202
+ *::-webkit-scrollbar-thumb {
203
+ background: var(--muted);
204
+ border-radius: 9999px;
205
+ }
206
+
207
+ *::-webkit-scrollbar-thumb:hover {
208
+ background: color-mix(in srgb, var(--muted-foreground) 50%, transparent);
209
+ }
210
+
211
+ html {
212
+ height: 100%;
213
+ -webkit-font-smoothing: antialiased;
214
+ -moz-osx-font-smoothing: grayscale;
215
+ font-feature-settings: 'cv02', 'cv03', 'cv04', 'cv11';
216
+ /* Prevent the viewport from rubber-banding; scroll should be inside app panels. */
217
+ overscroll-behavior: none;
218
+ }
219
+
220
+ body {
221
+ height: 100%;
222
+ overflow: hidden;
223
+ overscroll-behavior: none;
224
+ background-color: var(--background);
225
+ color: var(--foreground);
226
+ font-family:
227
+ 'Inter',
228
+ -apple-system,
229
+ BlinkMacSystemFont,
230
+ 'Segoe UI',
231
+ Roboto,
232
+ sans-serif;
233
+ }
234
+
235
+ #root {
236
+ height: 100%;
237
+ }
238
+
239
+ /* Monospace for code and terminal */
240
+ code,
241
+ pre,
242
+ .font-mono {
243
+ font-family:
244
+ 'JetBrains Mono',
245
+ 'Fira Code',
246
+ 'SF Mono',
247
+ Menlo,
248
+ Monaco,
249
+ Consolas,
250
+ monospace;
251
+ }
252
+
253
+ /* Focus styles */
254
+ :focus-visible {
255
+ outline: none;
256
+ box-shadow: 0 0 0 2px var(--background), 0 0 0 4px var(--ring);
257
+ }
258
+
259
+ :focus:not(:focus-visible) {
260
+ outline: none;
261
+ }
262
+
263
+ /* Selection */
264
+ ::selection {
265
+ background: color-mix(in srgb, var(--primary) 20%, transparent);
266
+ color: var(--foreground);
267
+ }
268
+ }
269
+
270
+ /* Animation utilities */
271
+ @layer utilities {
272
+ .animate-in {
273
+ animation: animate-in 200ms ease-out;
274
+ }
275
+
276
+ .animate-out {
277
+ animation: animate-out 150ms ease-in;
278
+ }
279
+
280
+ .slide-in-from-top {
281
+ --tw-enter-translate-y: -100%;
282
+ }
283
+
284
+ .slide-in-from-bottom {
285
+ --tw-enter-translate-y: 100%;
286
+ }
287
+
288
+ .slide-in-from-left {
289
+ --tw-enter-translate-x: -100%;
290
+ }
291
+
292
+ .slide-in-from-right {
293
+ --tw-enter-translate-x: 100%;
294
+ }
295
+
296
+ .slide-in-from-top-2 {
297
+ --tw-enter-translate-y: -0.5rem;
298
+ }
299
+
300
+ .slide-in-from-top-4 {
301
+ --tw-enter-translate-y: -1rem;
302
+ }
303
+
304
+ .fade-in {
305
+ --tw-enter-opacity: 0;
306
+ }
307
+
308
+ .zoom-in-95 {
309
+ --tw-enter-scale: 0.95;
310
+ }
311
+
312
+ .scrollbar-hide {
313
+ -ms-overflow-style: none;
314
+ scrollbar-width: none;
315
+ }
316
+
317
+ .scrollbar-hide::-webkit-scrollbar {
318
+ display: none;
319
+ }
320
+ }
321
+
322
+ @keyframes animate-in {
323
+ from {
324
+ opacity: var(--tw-enter-opacity, 1);
325
+ transform: translate(
326
+ var(--tw-enter-translate-x, 0),
327
+ var(--tw-enter-translate-y, 0)
328
+ )
329
+ scale(var(--tw-enter-scale, 1));
330
+ }
331
+ }
332
+
333
+ @keyframes animate-out {
334
+ to {
335
+ opacity: var(--tw-exit-opacity, 0);
336
+ transform: translate(
337
+ var(--tw-exit-translate-x, 0),
338
+ var(--tw-exit-translate-y, 0)
339
+ )
340
+ scale(var(--tw-exit-scale, 1));
341
+ }
342
+ }
343
+
344
+ /* Loading animation keyframes */
345
+ @keyframes snake-move {
346
+ 0%,
347
+ 100% {
348
+ transform: scale(0.8);
349
+ opacity: 0.3;
350
+ }
351
+ 50% {
352
+ transform: scale(1);
353
+ opacity: 1;
354
+ }
355
+ }
356
+
357
+ /* Safe area insets for mobile */
358
+ @layer utilities {
359
+ .safe-bottom {
360
+ padding-bottom: env(safe-area-inset-bottom, 0);
361
+ }
362
+
363
+ .safe-top {
364
+ padding-top: env(safe-area-inset-top, 0);
365
+ }
366
+
367
+ .safe-left {
368
+ padding-left: env(safe-area-inset-left, 0);
369
+ }
370
+
371
+ .safe-right {
372
+ padding-right: env(safe-area-inset-right, 0);
373
+ }
374
+ }
375
+
376
+ /* Advanced Card animations */
377
+ @keyframes gradient-shift {
378
+ 0% {
379
+ background-position: 0% 50%;
380
+ }
381
+ 50% {
382
+ background-position: 100% 50%;
383
+ }
384
+ 100% {
385
+ background-position: 0% 50%;
386
+ }
387
+ }
388
+
389
+ @keyframes shimmer {
390
+ 0% {
391
+ transform: translateX(-100%);
392
+ }
393
+ 100% {
394
+ transform: translateX(100%);
395
+ }
396
+ }
397
+
398
+ @keyframes spin {
399
+ from {
400
+ transform: rotate(0deg);
401
+ }
402
+ to {
403
+ transform: rotate(360deg);
404
+ }
405
+ }
406
+
407
+ @keyframes morph {
408
+ 0%, 100% {
409
+ border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%;
410
+ transform: translate(0, 0) rotate(0deg);
411
+ }
412
+ 25% {
413
+ border-radius: 30% 60% 70% 40% / 50% 60% 30% 60%;
414
+ transform: translate(10%, 10%) rotate(90deg);
415
+ }
416
+ 50% {
417
+ border-radius: 50% 60% 30% 60% / 30% 60% 70% 40%;
418
+ transform: translate(0, 20%) rotate(180deg);
419
+ }
420
+ 75% {
421
+ border-radius: 60% 40% 60% 30% / 60% 30% 40% 70%;
422
+ transform: translate(-10%, 10%) rotate(270deg);
423
+ }
424
+ }
425
+
426
+ @keyframes float {
427
+ 0%, 100% {
428
+ transform: translateY(0);
429
+ }
430
+ 50% {
431
+ transform: translateY(-10px);
432
+ }
433
+ }
434
+
435
+ @keyframes glow-pulse {
436
+ 0%, 100% {
437
+ box-shadow: 0 0 5px var(--primary), 0 0 20px var(--primary);
438
+ }
439
+ 50% {
440
+ box-shadow: 0 0 20px var(--primary), 0 0 40px var(--primary);
441
+ }
442
+ }