@djangocfg/ui-nextjs 2.1.82 → 2.1.83

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 (33) hide show
  1. package/package.json +4 -4
  2. package/src/tools/AudioPlayer/@refactoring3/00-IMPLEMENTATION-ROADMAP.md +1146 -0
  3. package/src/tools/AudioPlayer/@refactoring3/01-WAVESURFER-STREAMING-ANALYSIS.md +611 -0
  4. package/src/tools/AudioPlayer/@refactoring3/02-MEDIA-VIEWER-ANALYSIS.md +560 -0
  5. package/src/tools/AudioPlayer/@refactoring3/03-HYBRID-ARCHITECTURE-PROPOSAL.md +769 -0
  6. package/src/tools/AudioPlayer/@refactoring3/04-CRACKLING-ISSUE-DIAGNOSIS.md +373 -0
  7. package/src/tools/AudioPlayer/README.md +177 -205
  8. package/src/tools/AudioPlayer/components/AudioPlayer.tsx +9 -4
  9. package/src/tools/AudioPlayer/components/HybridAudioPlayer.tsx +251 -0
  10. package/src/tools/AudioPlayer/components/HybridSimplePlayer.tsx +291 -0
  11. package/src/tools/AudioPlayer/components/HybridWaveform.tsx +279 -0
  12. package/src/tools/AudioPlayer/components/SimpleAudioPlayer.tsx +16 -26
  13. package/src/tools/AudioPlayer/components/index.ts +6 -1
  14. package/src/tools/AudioPlayer/context/AudioProvider.tsx +8 -3
  15. package/src/tools/AudioPlayer/context/HybridAudioProvider.tsx +121 -0
  16. package/src/tools/AudioPlayer/context/index.ts +14 -2
  17. package/src/tools/AudioPlayer/hooks/index.ts +11 -0
  18. package/src/tools/AudioPlayer/hooks/useHybridAudio.ts +387 -0
  19. package/src/tools/AudioPlayer/hooks/useHybridAudioAnalysis.ts +95 -0
  20. package/src/tools/AudioPlayer/hooks/useSharedWebAudio.ts +6 -3
  21. package/src/tools/AudioPlayer/index.ts +31 -0
  22. package/src/tools/AudioPlayer/progressive/ProgressiveAudioPlayer.tsx +8 -0
  23. package/src/tools/index.ts +22 -0
  24. package/src/tools/AudioPlayer/@refactoring/00-PLAN.md +0 -148
  25. package/src/tools/AudioPlayer/@refactoring/01-TYPES.md +0 -301
  26. package/src/tools/AudioPlayer/@refactoring/02-HOOKS.md +0 -281
  27. package/src/tools/AudioPlayer/@refactoring/03-CONTEXT.md +0 -328
  28. package/src/tools/AudioPlayer/@refactoring/04-COMPONENTS.md +0 -251
  29. package/src/tools/AudioPlayer/@refactoring/05-EFFECTS.md +0 -427
  30. package/src/tools/AudioPlayer/@refactoring/06-UTILS-AND-INDEX.md +0 -193
  31. package/src/tools/AudioPlayer/@refactoring/07-EXECUTION-CHECKLIST.md +0 -146
  32. package/src/tools/AudioPlayer/@refactoring2/ISSUE_ANALYSIS.md +0 -187
  33. package/src/tools/AudioPlayer/@refactoring2/PLAN.md +0 -372
@@ -1,251 +0,0 @@
1
- # Phase 5: Components Reorganization
2
-
3
- ## Overview
4
-
5
- Move all components to `components/` folder and split `AudioReactiveCover` into subcomponents.
6
-
7
- ---
8
-
9
- ## Files to Move (with import updates)
10
-
11
- | Current | New Location | Changes |
12
- |---------|--------------|---------|
13
- | `AudioPlayer.tsx` | `components/AudioPlayer.tsx` | Update imports |
14
- | `AudioEqualizer.tsx` | `components/AudioEqualizer.tsx` | Update imports |
15
- | `SimpleAudioPlayer.tsx` | `components/SimpleAudioPlayer.tsx` | Update imports |
16
- | `AudioShortcutsPopover.tsx` | `components/ShortcutsPopover.tsx` | Rename + update imports |
17
- | `VisualizationToggle.tsx` | `components/VisualizationToggle.tsx` | Update imports |
18
-
19
- ---
20
-
21
- ## `AudioReactiveCover` Split
22
-
23
- Current: 390 lines with 4 inline effect components.
24
-
25
- ### `components/ReactiveCover/index.tsx`
26
-
27
- Main component (~100 lines).
28
-
29
- ```typescript
30
- 'use client';
31
-
32
- import { type ReactNode } from 'react';
33
- import { cn } from '@djangocfg/ui-nextjs';
34
- import { useAudioElement } from '../../context';
35
- import {
36
- getEffectConfig,
37
- prepareEffectColors,
38
- EFFECT_ANIMATIONS,
39
- } from '../../effects';
40
- import type { EffectVariant, EffectIntensity, EffectColorScheme } from '../../types';
41
-
42
- import { GlowEffect } from './GlowEffect';
43
- import { OrbsEffect } from './OrbsEffect';
44
- import { SpotlightEffect } from './SpotlightEffect';
45
- import { MeshEffect } from './MeshEffect';
46
-
47
- // ... Props and constants ...
48
-
49
- export function AudioReactiveCover({
50
- children,
51
- size = 'lg',
52
- variant = 'spotlight',
53
- intensity = 'medium',
54
- colorScheme = 'primary',
55
- onClick,
56
- className,
57
- }: AudioReactiveCoverProps) {
58
- const { isPlaying, audioLevels: levels } = useAudioElement();
59
-
60
- const sizeConfig = SIZES[size];
61
- const effectConfig = getEffectConfig(intensity);
62
- const { colors, hueShift } = prepareEffectColors(colorScheme, levels);
63
- const containerScale = 1 + levels.overall * effectConfig.scale;
64
-
65
- return (
66
- <div
67
- className={cn('relative', sizeConfig.container, className)}
68
- style={{
69
- transform: `scale(${containerScale})`,
70
- transition: 'transform 0.1s ease-out',
71
- }}
72
- >
73
- {variant === 'glow' && (
74
- <GlowEffect
75
- levels={levels}
76
- config={effectConfig}
77
- colors={colors}
78
- hueShift={hueShift}
79
- isPlaying={isPlaying}
80
- />
81
- )}
82
-
83
- {variant === 'orbs' && (
84
- <OrbsEffect
85
- levels={levels}
86
- config={effectConfig}
87
- colors={colors}
88
- baseSize={sizeConfig.orbBase}
89
- isPlaying={isPlaying}
90
- />
91
- )}
92
-
93
- {variant === 'spotlight' && (
94
- <SpotlightEffect
95
- levels={levels}
96
- config={effectConfig}
97
- colors={colors}
98
- isPlaying={isPlaying}
99
- />
100
- )}
101
-
102
- {variant === 'mesh' && (
103
- <MeshEffect
104
- levels={levels}
105
- config={effectConfig}
106
- colors={colors}
107
- isPlaying={isPlaying}
108
- />
109
- )}
110
-
111
- {/* Content */}
112
- <div
113
- className="relative w-full h-full rounded-lg overflow-hidden shadow-2xl z-10 bg-background cursor-pointer"
114
- onClick={onClick}
115
- role={onClick ? 'button' : undefined}
116
- tabIndex={onClick ? 0 : undefined}
117
- onKeyDown={onClick ? (e) => e.key === 'Enter' && onClick() : undefined}
118
- >
119
- {children}
120
- </div>
121
-
122
- <style dangerouslySetInnerHTML={{ __html: EFFECT_ANIMATIONS }} />
123
- </div>
124
- );
125
- }
126
- ```
127
-
128
- ### `components/ReactiveCover/GlowEffect.tsx`
129
-
130
- ```typescript
131
- 'use client';
132
-
133
- import { cn } from '@djangocfg/ui-nextjs';
134
- import { calculateGlowLayers } from '../../effects';
135
- import type { AudioLevels, EffectConfig } from '../../types';
136
-
137
- interface GlowEffectProps {
138
- levels: AudioLevels;
139
- config: EffectConfig;
140
- colors: string[];
141
- hueShift: number;
142
- isPlaying: boolean;
143
- }
144
-
145
- export function GlowEffect({ levels, config, colors, hueShift, isPlaying }: GlowEffectProps) {
146
- const layers = calculateGlowLayers(levels, config, colors);
147
- const showPulseRings = levels.bass > 0.5;
148
- const showSparkle = levels.high > 0.4;
149
-
150
- return (
151
- <>
152
- {/* Main glow layers */}
153
- {layers.map((layer, i) => (
154
- <div
155
- key={i}
156
- className={cn('absolute rounded-2xl -z-10', layer.blur)}
157
- style={{
158
- inset: `-${layer.inset}px`,
159
- background: layer.background,
160
- opacity: isPlaying ? layer.opacity : 0,
161
- transform: i < 2 ? `scaleY(${layer.scale})` : `scale(${layer.scale})`,
162
- animation: isPlaying && layer.animation ? layer.animation : 'none',
163
- transition: 'opacity 0.3s',
164
- }}
165
- />
166
- ))}
167
-
168
- {/* Rotating color sweep */}
169
- <div
170
- className="absolute rounded-2xl blur-xl overflow-hidden -z-10"
171
- style={{
172
- inset: '-75px',
173
- opacity: isPlaying ? 0.6 : 0,
174
- transition: 'opacity 0.5s',
175
- }}
176
- >
177
- <div
178
- className="absolute inset-0"
179
- style={{
180
- background: `conic-gradient(
181
- from ${hueShift}deg at 50% 50%,
182
- hsl(${colors[0]} / 0.4) 0deg,
183
- hsl(${colors[1] || colors[0]} / 0.3) 90deg,
184
- hsl(${colors[2] || colors[0]} / 0.3) 180deg,
185
- hsl(${colors[3] || colors[0]} / 0.3) 270deg,
186
- hsl(${colors[0]} / 0.4) 360deg
187
- )`,
188
- animation: isPlaying ? 'glow-rotate 6s linear infinite' : 'none',
189
- }}
190
- />
191
- </div>
192
-
193
- {/* Pulse rings on bass hits */}
194
- {showPulseRings && (
195
- <>
196
- <div
197
- className="absolute -inset-6 rounded-xl border-2 animate-ping -z-10"
198
- style={{
199
- borderColor: `hsl(${colors[0]} / 0.4)`,
200
- animationDuration: '1s',
201
- }}
202
- />
203
- <div
204
- className="absolute -inset-12 rounded-2xl border animate-ping -z-10"
205
- style={{
206
- borderColor: `hsl(${colors[1] || colors[0]} / 0.3)`,
207
- animationDuration: '1.5s',
208
- animationDelay: '0.2s',
209
- }}
210
- />
211
- </>
212
- )}
213
-
214
- {/* Sparkle on high frequencies */}
215
- {showSparkle && (
216
- <div
217
- className="absolute -inset-18 rounded-3xl -z-10"
218
- style={{
219
- background: `radial-gradient(circle at 50% 30%, hsl(${colors[2] || colors[0]} / 0.5) 0%, transparent 30%)`,
220
- animation: 'sparkle-move 0.5s ease-out',
221
- }}
222
- />
223
- )}
224
- </>
225
- );
226
- }
227
- ```
228
-
229
- ### Similar split for:
230
- - `components/ReactiveCover/OrbsEffect.tsx`
231
- - `components/ReactiveCover/SpotlightEffect.tsx`
232
- - `components/ReactiveCover/MeshEffect.tsx`
233
-
234
- ---
235
-
236
- ## `components/index.ts`
237
-
238
- ```typescript
239
- // Main components
240
- export { AudioPlayer } from './AudioPlayer';
241
- export { AudioEqualizer } from './AudioEqualizer';
242
- export { SimpleAudioPlayer } from './SimpleAudioPlayer';
243
- export type { SimpleAudioPlayerProps } from './SimpleAudioPlayer';
244
-
245
- // ReactiveCover
246
- export { AudioReactiveCover } from './ReactiveCover';
247
-
248
- // UI components
249
- export { ShortcutsPopover as AudioShortcutsPopover } from './ShortcutsPopover';
250
- export { VisualizationToggle } from './VisualizationToggle';
251
- ```
@@ -1,427 +0,0 @@
1
- # Phase 6: Effects Refactoring
2
-
3
- ## Source: `effects/index.ts` (413 lines)
4
-
5
- Split into 3 files by concern.
6
-
7
- ---
8
-
9
- ## `effects/constants.ts`
10
-
11
- Configuration constants (~60 lines).
12
-
13
- ```typescript
14
- import type { EffectIntensity, EffectColorScheme, EffectConfig } from '../types';
15
-
16
- // =============================================================================
17
- // INTENSITY CONFIGURATION
18
- // =============================================================================
19
-
20
- export const INTENSITY_CONFIG: Record<EffectIntensity, EffectConfig> = {
21
- subtle: { opacity: 0.3, scale: 0.02, blur: 'blur-2xl' },
22
- medium: { opacity: 0.5, scale: 0.04, blur: 'blur-xl' },
23
- strong: { opacity: 0.7, scale: 0.06, blur: 'blur-lg' },
24
- };
25
-
26
- // =============================================================================
27
- // COLOR SCHEMES
28
- // =============================================================================
29
-
30
- export const COLOR_SCHEMES: Record<EffectColorScheme, string[]> = {
31
- primary: ['217 91% 60%'],
32
- vibrant: ['217 91% 60%', '142 76% 36%', '262 83% 58%', '25 95% 53%'],
33
- cool: ['217 91% 60%', '262 83% 58%', '199 89% 48%'],
34
- warm: ['25 95% 53%', '0 84% 60%', '38 92% 50%'],
35
- };
36
-
37
- // Default multi-color palette
38
- export const DEFAULT_GLOW_COLORS = [
39
- '217 91% 60%', // Blue
40
- '262 83% 58%', // Purple
41
- '330 81% 60%', // Pink
42
- '25 95% 53%', // Orange
43
- ];
44
-
45
- // =============================================================================
46
- // HELPERS
47
- // =============================================================================
48
-
49
- export function getEffectConfig(intensity: EffectIntensity): EffectConfig {
50
- return INTENSITY_CONFIG[intensity];
51
- }
52
-
53
- export function getColors(colorScheme: EffectColorScheme): string[] {
54
- return COLOR_SCHEMES[colorScheme];
55
- }
56
- ```
57
-
58
- ---
59
-
60
- ## `effects/calculations.ts`
61
-
62
- Effect calculation functions (~250 lines).
63
-
64
- ```typescript
65
- import type {
66
- AudioLevels,
67
- EffectConfig,
68
- EffectColors,
69
- EffectLayer,
70
- Orb,
71
- MeshGradient,
72
- SpotlightData,
73
- EffectColorScheme,
74
- } from '../types';
75
- import { COLOR_SCHEMES, DEFAULT_GLOW_COLORS } from './constants';
76
-
77
- // =============================================================================
78
- // PREPARE EFFECT COLORS
79
- // =============================================================================
80
-
81
- export function prepareEffectColors(
82
- colorScheme: EffectColorScheme,
83
- levels: AudioLevels
84
- ): EffectColors {
85
- const baseColors = COLOR_SCHEMES[colorScheme];
86
- const colors = baseColors.length > 1 ? baseColors : DEFAULT_GLOW_COLORS;
87
- const hueShift = Math.floor(
88
- (levels.bass * 30) + (levels.mid * 20) + (levels.high * 10)
89
- );
90
-
91
- return { colors, hueShift };
92
- }
93
-
94
- // =============================================================================
95
- // GLOW LAYERS
96
- // =============================================================================
97
-
98
- export function calculateGlowLayers(
99
- levels: AudioLevels,
100
- config: EffectConfig,
101
- colors: string[]
102
- ): EffectLayer[] {
103
- const { bass, mid, high } = levels;
104
-
105
- return [
106
- // Layer 1: Bass glow - bottom
107
- {
108
- inset: 60 + bass * 90,
109
- opacity: 1,
110
- scale: 1 + bass * 0.5,
111
- background: `radial-gradient(ellipse 80% 60% at 50% 100%, hsl(${colors[0]} / ${0.4 + bass * 0.4}) 0%, transparent 70%)`,
112
- blur: 'blur-3xl',
113
- },
114
- // Layer 2: Mid glow - top
115
- {
116
- inset: 45 + mid * 75,
117
- opacity: 1,
118
- scale: 1 + mid * 0.4,
119
- background: `radial-gradient(ellipse 70% 50% at 50% 0%, hsl(${colors[1] || colors[0]} / ${0.3 + mid * 0.5}) 0%, transparent 70%)`,
120
- blur: 'blur-2xl',
121
- },
122
- // Layer 3: High glow - left
123
- {
124
- inset: 30 + high * 60,
125
- opacity: 1,
126
- scale: 1 + high * 0.3,
127
- background: `radial-gradient(ellipse 50% 80% at 0% 50%, hsl(${colors[2] || colors[0]} / ${0.3 + high * 0.4}) 0%, transparent 60%)`,
128
- blur: 'blur-2xl',
129
- },
130
- // Layer 4: High glow - right
131
- {
132
- inset: 30 + high * 60,
133
- opacity: 1,
134
- scale: 1 + high * 0.3,
135
- background: `radial-gradient(ellipse 50% 80% at 100% 50%, hsl(${colors[3] || colors[0]} / ${0.3 + high * 0.4}) 0%, transparent 60%)`,
136
- blur: 'blur-2xl',
137
- },
138
- // Layer 5: Center pulsing glow
139
- {
140
- inset: 24 + bass * 45,
141
- opacity: 1,
142
- scale: 1 + bass * 0.2,
143
- background: `radial-gradient(circle at 50% 50%, hsl(${colors[0]} / ${0.2 + bass * 0.3}) 0%, hsl(${colors[1] || colors[0]} / ${0.1 + mid * 0.2}) 40%, transparent 70%)`,
144
- blur: 'blur-xl',
145
- animation: 'glow-breathe 2s ease-in-out infinite',
146
- },
147
- ];
148
- }
149
-
150
- // =============================================================================
151
- // ORBS
152
- // =============================================================================
153
-
154
- export function calculateOrbs(
155
- levels: AudioLevels,
156
- config: EffectConfig,
157
- colors: string[],
158
- baseSize: number = 50
159
- ): Orb[] {
160
- const { bass, mid, high, overall } = levels;
161
- const size = baseSize * 3;
162
-
163
- const bassMove = bass * 30;
164
- const midMove = mid * 25;
165
- const highMove = high * 20;
166
-
167
- return [
168
- {
169
- x: -40 + bassMove,
170
- y: -40 - bassMove * 0.5,
171
- size: size * (1 + bass * 1.2),
172
- color: colors[0],
173
- opacity: 0.5 + bass * 0.5,
174
- scale: 1 + bass * 0.6,
175
- },
176
- {
177
- x: 130 - midMove * 0.5,
178
- y: -30 + midMove,
179
- size: size * (0.9 + mid * 1.0),
180
- color: colors[1] || colors[0],
181
- opacity: 0.5 + mid * 0.5,
182
- scale: 1 + mid * 0.5,
183
- },
184
- {
185
- x: 140 + highMove * 0.3,
186
- y: 120 - highMove,
187
- size: size * (0.8 + high * 0.8),
188
- color: colors[2] || colors[0],
189
- opacity: 0.4 + high * 0.6,
190
- scale: 1 + high * 0.45,
191
- },
192
- {
193
- x: -30 - midMove * 0.4,
194
- y: 130 + midMove * 0.3,
195
- size: size * (0.9 + mid * 0.9),
196
- color: colors[3] || colors[0],
197
- opacity: 0.45 + mid * 0.55,
198
- scale: 1 + mid * 0.5,
199
- },
200
- {
201
- x: 50,
202
- y: 50,
203
- size: size * (0.6 + overall * 1.5),
204
- color: colors[0],
205
- opacity: 0.3 + overall * 0.5,
206
- scale: 1 + overall * 0.7,
207
- },
208
- ];
209
- }
210
-
211
- // =============================================================================
212
- // MESH GRADIENTS
213
- // =============================================================================
214
-
215
- export function calculateMeshGradients(
216
- levels: AudioLevels,
217
- config: EffectConfig,
218
- colors: string[]
219
- ): MeshGradient[] {
220
- const { bass, mid, high, overall } = levels;
221
-
222
- const bassOffset = bass * 40;
223
- const midOffset = mid * 30;
224
- const highOffset = high * 25;
225
-
226
- return [
227
- {
228
- width: `${200 + bass * 150}%`,
229
- height: `${200 + bass * 150}%`,
230
- top: `${-80 + bassOffset}%`,
231
- right: `${-80 - bassOffset}%`,
232
- color: colors[0],
233
- opacity: 0.4 + bass * 0.6,
234
- scale: 1 + bass * 0.5,
235
- rotation: bass * 45,
236
- blur: 'blur-2xl',
237
- },
238
- {
239
- width: `${180 + mid * 120}%`,
240
- height: `${180 + mid * 120}%`,
241
- bottom: `${-60 + midOffset}%`,
242
- left: `${-60 - midOffset}%`,
243
- color: colors[1] || colors[0],
244
- opacity: 0.4 + mid * 0.6,
245
- scale: 1 + mid * 0.4,
246
- rotation: -mid * 40,
247
- blur: 'blur-2xl',
248
- },
249
- {
250
- width: `${140 + high * 100}%`,
251
- height: `${140 + high * 100}%`,
252
- top: `${70 - highOffset}%`,
253
- right: `${-50 + highOffset}%`,
254
- color: colors[2] || colors[0],
255
- opacity: 0.35 + high * 0.65,
256
- scale: 1 + high * 0.35,
257
- rotation: high * 35,
258
- blur: 'blur-xl',
259
- },
260
- {
261
- width: `${160 + bass * 140}%`,
262
- height: `${160 + bass * 140}%`,
263
- top: `${-60 - bassOffset * 0.8}%`,
264
- left: `${-60 + bassOffset * 0.8}%`,
265
- color: colors[3] || colors[1] || colors[0],
266
- opacity: 0.35 + bass * 0.65,
267
- scale: 1 + bass * 0.55,
268
- rotation: -bass * 50,
269
- blur: 'blur-2xl',
270
- },
271
- {
272
- width: `${80 + overall * 150}%`,
273
- height: `${80 + overall * 150}%`,
274
- top: '50%',
275
- left: '50%',
276
- color: colors[0],
277
- opacity: 0.3 + overall * 0.5,
278
- scale: 1 + overall * 0.4,
279
- rotation: 0,
280
- isCenter: true,
281
- blur: 'blur-3xl',
282
- },
283
- ];
284
- }
285
-
286
- // =============================================================================
287
- // SPOTLIGHT
288
- // =============================================================================
289
-
290
- export function calculateSpotlight(
291
- levels: AudioLevels,
292
- config: EffectConfig,
293
- colors: string[],
294
- rotation: number
295
- ): SpotlightData {
296
- const { bass, mid, high, overall } = levels;
297
-
298
- return {
299
- rotation: rotation + mid * 180,
300
- inset: 12 + bass * 30,
301
- colors: colors.map((c, i) => ({
302
- color: c,
303
- opacity: i === 0 ? 0.3 + bass * 0.7 : i === 1 ? 0.3 + mid * 0.7 : 0.3 + high * 0.7,
304
- })),
305
- pulseInset: 24 + bass * 50,
306
- pulseOpacity: 0.3 + bass * 0.7,
307
- pulseScale: 1 + bass * 0.4,
308
- ringOpacity: 0.2 + overall * 0.6,
309
- ringScale: 1 + overall * 0.3,
310
- };
311
- }
312
- ```
313
-
314
- ---
315
-
316
- ## `effects/animations.ts`
317
-
318
- CSS keyframes (~80 lines).
319
-
320
- ```typescript
321
- /**
322
- * CSS keyframes for audio-reactive effects.
323
- * Injected once via <style> tag.
324
- */
325
- export const EFFECT_ANIMATIONS = `
326
- @keyframes spotlight-spin {
327
- 0% { transform: rotate(0deg); }
328
- 100% { transform: rotate(360deg); }
329
- }
330
-
331
- @keyframes orb-float-1 {
332
- 0%, 100% { transform: translate(-50%, -50%) translateY(0); }
333
- 50% { transform: translate(-50%, -50%) translateY(-15px); }
334
- }
335
-
336
- @keyframes orb-float-2 {
337
- 0%, 100% { transform: translate(-50%, -50%) translateX(0); }
338
- 50% { transform: translate(-50%, -50%) translateX(15px); }
339
- }
340
-
341
- @keyframes orb-float-3 {
342
- 0%, 100% { transform: translate(-50%, -50%) translate(0, 0); }
343
- 33% { transform: translate(-50%, -50%) translate(10px, -10px); }
344
- 66% { transform: translate(-50%, -50%) translate(-10px, 10px); }
345
- }
346
-
347
- @keyframes orb-float-4 {
348
- 0%, 100% { transform: translate(-50%, -50%) translate(0, 0); }
349
- 50% { transform: translate(-50%, -50%) translate(-15px, -10px); }
350
- }
351
-
352
- @keyframes mesh-float-1 {
353
- 0%, 100% { transform: translate(0, 0) scale(1); }
354
- 25% { transform: translate(-5%, 10%) scale(1.05); }
355
- 50% { transform: translate(5%, 5%) scale(0.95); }
356
- 75% { transform: translate(-3%, -5%) scale(1.02); }
357
- }
358
-
359
- @keyframes mesh-float-2 {
360
- 0%, 100% { transform: translate(0, 0) scale(1); }
361
- 33% { transform: translate(8%, -8%) scale(1.08); }
362
- 66% { transform: translate(-6%, 6%) scale(0.92); }
363
- }
364
-
365
- @keyframes mesh-float-3 {
366
- 0%, 100% { transform: translate(0, 0) scale(1); }
367
- 50% { transform: translate(10%, 10%) scale(1.1); }
368
- }
369
-
370
- @keyframes mesh-float-4 {
371
- 0%, 100% { transform: translate(0, 0) scale(1) rotate(0deg); }
372
- 25% { transform: translate(10%, -5%) scale(1.1) rotate(5deg); }
373
- 50% { transform: translate(-5%, 10%) scale(0.95) rotate(-5deg); }
374
- 75% { transform: translate(-10%, -10%) scale(1.05) rotate(3deg); }
375
- }
376
-
377
- @keyframes mesh-pulse {
378
- 0%, 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.3; }
379
- 50% { transform: translate(-50%, -50%) scale(1.2); opacity: 0.5; }
380
- }
381
-
382
- @keyframes glow-breathe {
383
- 0%, 100% { opacity: 0.6; transform: scale(1); }
384
- 50% { opacity: 1; transform: scale(1.05); }
385
- }
386
-
387
- @keyframes glow-rotate {
388
- 0% { transform: rotate(0deg); }
389
- 100% { transform: rotate(360deg); }
390
- }
391
-
392
- @keyframes sparkle-move {
393
- 0% { opacity: 0; transform: scale(0.8); }
394
- 50% { opacity: 1; }
395
- 100% { opacity: 0; transform: scale(1.2); }
396
- }
397
- `;
398
- ```
399
-
400
- ---
401
-
402
- ## `effects/index.ts`
403
-
404
- Re-export all.
405
-
406
- ```typescript
407
- // Constants
408
- export {
409
- INTENSITY_CONFIG,
410
- COLOR_SCHEMES,
411
- DEFAULT_GLOW_COLORS,
412
- getEffectConfig,
413
- getColors,
414
- } from './constants';
415
-
416
- // Calculations
417
- export {
418
- prepareEffectColors,
419
- calculateGlowLayers,
420
- calculateOrbs,
421
- calculateMeshGradients,
422
- calculateSpotlight,
423
- } from './calculations';
424
-
425
- // Animations
426
- export { EFFECT_ANIMATIONS } from './animations';
427
- ```