diff --git a/DESIGN_SYSTEM.md b/DESIGN_SYSTEM.md new file mode 100644 index 0000000..308e73a --- /dev/null +++ b/DESIGN_SYSTEM.md @@ -0,0 +1,539 @@ +# RepoDructor - Design System & Architecture Guide + +## 🎨 Design Philosophy + +RepoDructor follows a **Glassmorphism** design philosophy with **Aurora-inspired** lighting effects. The application emphasizes transparency, depth, and visual hierarchy through carefully crafted blur effects, subtle borders, and dynamic lighting. + +### Core Design Principles + +1. **Transparency & Depth**: All UI elements use glassmorphism with varying levels of transparency +2. **Dynamic Lighting**: Aurora orbs and particles provide ambient lighting that responds to music playback +3. **Smooth Animations**: Every interaction includes fluid transitions and micro-animations +4. **Responsive Design**: Mobile-first approach with adaptive layouts +5. **Accessibility**: Support for reduced motion and high contrast preferences + +--- + +## 🏗️ Architecture Overview + +### Component Structure + +``` +components/ +├── Base Components +│ ├── BaseButton.client.vue # Foundation button component +│ └── IconButton.client.vue # Extends BaseButton for icon buttons +├── UI Components +│ ├── ThemeToggle.client.vue # Dark/light theme switcher +│ ├── PlaybackControls.client.vue # Shuffle/repeat controls +│ ├── TrackListItem.client.vue # Individual track display +│ ├── TrackList.client.vue # Track collection container +│ └── MusicControls.client.vue # Main playback controls (fixed bottom) +├── Layout Components +│ ├── MainContainer.client.vue # App layout wrapper +│ └── AuroraBackground.client.vue # Dynamic background effects +└── pages/ + └── index.vue # Main application page +``` + +### Component Hierarchy + +``` +index.vue +├── AuroraBackground.client.vue +├── MainContainer.client.vue +│ ├── Header (built-in) +│ │ ├── PlaybackControls.client.vue +│ │ │ ├── IconButton.client.vue (shuffle) +│ │ │ └── IconButton.client.vue (repeat) +│ │ └── ThemeToggle.client.vue +│ └── TrackList.client.vue +│ └── TrackListItem.client.vue (multiple) +└── MusicControls.client.vue + └── IconButton.client.vue (multiple) +``` + +--- + +## 🎯 Component Design Patterns + +### Base Components + +#### BaseButton.client.vue +**Purpose**: Foundation for all interactive buttons +**Variants**: `default`, `icon`, `primary` +**Key Features**: +- Glassmorphism background with blur effects +- Hover animations with shimmer effect +- Active state management +- Accessibility support + +```vue + + + +``` + +#### IconButton.client.vue +**Purpose**: Specialized button for icons with badges +**Sizes**: `small`, `normal`, `large` +**Icon Support**: String (emojis), Object/Function (Lucide Vue components) +**Key Features**: +- Extends BaseButton with icon-specific styling +- Support for both emoji strings and SVG components +- Badge support for notifications +- Icon-specific hover animations +- Responsive sizing with dynamic icon scaling + +### UI Components + +#### ThemeToggle.client.vue +**Purpose**: Dark/light theme switcher +**Key Features**: +- Smooth rotation animation on toggle +- Radial glow effect on hover +- Persists preference in localStorage +- Updates document theme attribute + +#### PlaybackControls.client.vue +**Purpose**: Shuffle and repeat mode controls +**Key Features**: +- Icon-specific hover animations (wiggle for shuffle, spin for repeat) +- Active state with glow effects +- LocalStorage persistence +- Emits change events to parent + +#### TrackListItem.client.vue +**Purpose**: Individual track display with interaction +**Key Features**: +- Ripple effect on click +- Hover lift animation +- Active state with gradient background +- Loading state with spinner +- Waveform visualization for active playing tracks + +#### TrackList.client.vue +**Purpose**: Container for track collection +**Key Features**: +- Staggered animations for child items +- Scrollable container with custom scrollbar +- Empty state and loading state handling +- Glassmorphism container styling + +#### MusicControls.client.vue +**Purpose**: Main music playback controls (fixed at bottom) +**Key Features**: +- Collapsible interface with compact and expanded states +- Track information display with animated status indicators +- Navigation controls with Lucide SVG icons (SkipBack, Play/Pause, SkipForward) +- Progress bar with interactive seek functionality +- Volume control with visual feedback and mute toggle +- Compact collapse button positioned in top-right corner +- Dynamic bottom positioning (closer when expanded, standard when collapsed) +- Responsive layout that adapts to screen size + +### Layout Components + +#### MainContainer.client.vue +**Purpose**: Application layout wrapper +**Key Features**: +- Header with app branding and controls +- Responsive content area +- Consistent spacing and margins +- Glassmorphism header styling + +#### AuroraBackground.client.vue +**Purpose**: Dynamic background effects +**Key Features**: +- Multiple floating orbs with different colors +- Interactive orbs that respond to music playback +- Particle system with floating elements +- Gradient overlays +- Performance optimized animations + +--- + +## 🎨 Design Tokens + +### Color System + +```css +/* Light Mode */ +--bg-primary: #f8fafc; +--bg-secondary: rgba(255, 255, 255, 0.8); +--bg-glass: rgba(255, 255, 255, 0.25); +--text-primary: #1e293b; +--text-secondary: #64748b; +--accent-primary: #3b82f6; +--accent-secondary: #8b5cf6; +--border-glass: rgba(255, 255, 255, 0.18); + +/* Dark Mode */ +--bg-primary: #0f172a; +--bg-secondary: rgba(15, 23, 42, 0.8); +--bg-glass: rgba(15, 23, 42, 0.3); +--text-primary: #f1f5f9; +--text-secondary: #94a3b8; +--accent-primary: #60a5fa; +--accent-secondary: #a78bfa; +--border-glass: rgba(255, 255, 255, 0.125); + +/* Aurora Colors */ +--aurora-1: #ff6b6b; +--aurora-2: #4ecdc4; +--aurora-3: #45b7d1; +--aurora-4: #f9ca24; +--aurora-5: #6c5ce7; +``` + +### Typography + +```css +font-family: 'Inter', sans-serif; + +/* Sizes */ +--text-xs: 0.75rem; +--text-sm: 0.875rem; +--text-base: 1rem; +--text-lg: 1.125rem; +--text-xl: 1.25rem; +--text-2xl: 1.5rem; + +/* Weights */ +--font-light: 300; +--font-normal: 400; +--font-medium: 500; +--font-semibold: 600; +--font-bold: 700; +``` + +### Spacing + +```css +--space-1: 0.25rem; /* 4px */ +--space-2: 0.5rem; /* 8px */ +--space-3: 0.75rem; /* 12px */ +--space-4: 1rem; /* 16px */ +--space-5: 1.25rem; /* 20px */ +--space-6: 1.5rem; /* 24px */ +--space-8: 2rem; /* 32px */ +--space-10: 2.5rem; /* 40px */ +``` + +### Border Radius + +```css +--radius-sm: 8px; +--radius-md: 12px; +--radius-lg: 16px; +--radius-xl: 20px; +--radius-full: 50%; +``` + +--- + +## ✨ Animation System + +### Core Animation Classes + +Located in `assets/css/animations.css`: + +```css +/* Utility Classes */ +.animate-fade-in /* Fade in effect */ +.animate-slide-in-up /* Slide up with fade */ +.animate-bounce-in /* Bounce entrance */ +.animate-scale-in /* Scale entrance */ +.animate-glow /* Continuous glow effect */ +.animate-pulse-glow /* Pulsing glow */ + +/* Hover Effects */ +.hover-lift /* Lift on hover */ +.hover-scale /* Scale on hover */ +.hover-glow /* Glow on hover */ + +/* Interactive Effects */ +.ripple /* Click ripple effect */ +.stagger-children /* Staggered child animations */ +``` + +### Performance Considerations + +```css +/* Reduced Motion Support */ +@media (prefers-reduced-motion: reduce) { + * { + animation-duration: 0.01ms !important; + transition-duration: 0.01ms !important; + } +} + +/* Hardware Acceleration */ +.aurora-orb, +.interactive-orb, +.particle { + will-change: transform; + transform: translateZ(0); +} +``` + +--- + +## 🎨 Icon System + +### Icon Library: Lucide Vue + +RepoDructor uses **Lucide Vue** as the primary icon system for consistent, scalable iconography that matches the glassmorphism aesthetic. + +### Icon Implementation + +```vue + + + +``` + +### Icon Categories + +**Playback Controls:** +- `Play`, `Pause` - Primary playback states +- `SkipForward`, `SkipBack` - Navigation controls +- `Shuffle` - Random playback mode +- `Repeat`, `Repeat1` - Repeat modes + +**Audio Controls:** +- `Volume2`, `Volume1`, `VolumeX` - Volume states +- `Music` - General music representation + +**Interface Controls:** +- `Sun`, `Moon` - Theme toggle states +- `ChevronUp`, `ChevronDown` - Collapse/expand actions + +### Icon Sizing + +Icons automatically scale based on context: +- **Small buttons**: 18px +- **Normal buttons**: 20px +- **Large buttons**: 28px +- **Custom sizing**: Use `:size` prop + +### Benefits + +- **Consistent**: Unified design language across all icons +- **Scalable**: Vector-based for perfect rendering at any size +- **Local**: No external dependencies or network requests +- **Accessible**: Proper semantic meaning and ARIA support +- **Themeable**: Inherit colors from CSS custom properties + +--- + +## 📱 Responsive Design + +### Breakpoints + +```css +/* Mobile First Approach */ +@media (max-width: 768px) /* Tablet and below */ +@media (max-width: 480px) /* Mobile */ + +/* Special Mobile Considerations */ +@media (max-width: 768px) { + .music-controls { + /* Fixed positioning with safe areas */ + bottom: calc(20px + env(safe-area-inset-bottom)); + left: 20px; + right: 20px; + } +} +``` + +### Layout Patterns + +1. **Desktop**: Horizontal layouts with fixed controls at bottom +2. **Tablet**: Slightly compressed with smaller gaps +3. **Mobile**: Vertical stacking with reorganized control layouts + +--- + +## 🎵 Audio Integration Patterns + +### State Management + +```javascript +// Core audio states +const isPlaying = ref(false) +const currentTrack = ref(null) +const currentTime = ref(0) +const duration = ref(0) +const volume = ref(0.7) + +// Playback modes +const isShuffled = useLocalStorage('shuffle', false) +const repeatMode = useLocalStorage('repeat', 'none') +``` + +### Event Handling + +```javascript +// Component communication pattern +const emit = defineEmits(['track-selected', 'shuffle-changed']) + +// Handle track selection +const handleTrackClick = (track, index) => { + emit('track-selected', { track, index }) +} +``` + +--- + +## 🔧 Development Guidelines + +### Component Creation + +1. **Always use `.client.vue` suffix** for client-side components +2. **Follow the composition API pattern** with ` + + \ No newline at end of file diff --git a/components/BaseButton.client.vue b/components/BaseButton.client.vue new file mode 100644 index 0000000..6827b36 --- /dev/null +++ b/components/BaseButton.client.vue @@ -0,0 +1,186 @@ + + + + + \ No newline at end of file diff --git a/components/IconButton.client.vue b/components/IconButton.client.vue new file mode 100644 index 0000000..c6343e9 --- /dev/null +++ b/components/IconButton.client.vue @@ -0,0 +1,138 @@ + + + + + \ No newline at end of file diff --git a/components/MainContainer.client.vue b/components/MainContainer.client.vue new file mode 100644 index 0000000..f9c4e3c --- /dev/null +++ b/components/MainContainer.client.vue @@ -0,0 +1,278 @@ + + + + + \ No newline at end of file diff --git a/components/MusicControls.client.vue b/components/MusicControls.client.vue new file mode 100644 index 0000000..a30e9ba --- /dev/null +++ b/components/MusicControls.client.vue @@ -0,0 +1,667 @@ + + + + + \ No newline at end of file diff --git a/components/PlaybackControls.client.vue b/components/PlaybackControls.client.vue new file mode 100644 index 0000000..2096b78 --- /dev/null +++ b/components/PlaybackControls.client.vue @@ -0,0 +1,104 @@ + + + + + \ No newline at end of file diff --git a/components/ThemeToggle.client.vue b/components/ThemeToggle.client.vue new file mode 100644 index 0000000..3df3393 --- /dev/null +++ b/components/ThemeToggle.client.vue @@ -0,0 +1,59 @@ + + + + + \ No newline at end of file diff --git a/components/TrackList.client.vue b/components/TrackList.client.vue new file mode 100644 index 0000000..8d31e48 --- /dev/null +++ b/components/TrackList.client.vue @@ -0,0 +1,280 @@ + + + + + \ No newline at end of file diff --git a/components/TrackListItem.client.vue b/components/TrackListItem.client.vue new file mode 100644 index 0000000..e59dbb7 --- /dev/null +++ b/components/TrackListItem.client.vue @@ -0,0 +1,257 @@ + + + + + \ No newline at end of file diff --git a/msucia.png b/msucia.png new file mode 100644 index 0000000..b317eb5 Binary files /dev/null and b/msucia.png differ diff --git a/nuxt.config.ts b/nuxt.config.ts index ab30855..2896027 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -3,6 +3,8 @@ import { defineNuxtConfig } from 'nuxt/config' export default defineNuxtConfig({ compatibilityDate: '2025-08-02', + // Disable SSR completely to avoid hydration issues with client-side audio APIs + ssr: false, devtools: { enabled: true, vscode: {}, @@ -76,7 +78,7 @@ export default defineNuxtConfig({ periodicSyncForUpdates: 20 }, devOptions: { - enabled: true, + enabled: false, type: 'module', navigateFallback: '/' }, diff --git a/package-lock.json b/package-lock.json index 1aba774..d645d81 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,8 @@ "dependencies": { "@vite-pwa/nuxt": "^1.0.4", "@vueuse/core": "^10.5.0", - "@vueuse/nuxt": "^10.5.0" + "@vueuse/nuxt": "^10.5.0", + "lucide-vue-next": "^0.536.0" }, "devDependencies": { "@nuxt/devtools": "latest", @@ -9933,6 +9934,15 @@ "yallist": "^3.0.2" } }, + "node_modules/lucide-vue-next": { + "version": "0.536.0", + "resolved": "https://registry.npmjs.org/lucide-vue-next/-/lucide-vue-next-0.536.0.tgz", + "integrity": "sha512-ypauLrs4PymzxBKvEiuyo1HqOqjPdBdAtATCSPs4hLgqEA0JAEINWfQbGoLEkaEixT7gsTeSK5TAvOhAcaHfCA==", + "license": "ISC", + "peerDependencies": { + "vue": ">=3.0.1" + } + }, "node_modules/luxon": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.1.tgz", diff --git a/package.json b/package.json index 6732b3b..07ea84c 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "dependencies": { "@vite-pwa/nuxt": "^1.0.4", "@vueuse/core": "^10.5.0", - "@vueuse/nuxt": "^10.5.0" + "@vueuse/nuxt": "^10.5.0", + "lucide-vue-next": "^0.536.0" } } diff --git a/pages/index.vue b/pages/index.vue index 2c1ee50..e796c17 100644 --- a/pages/index.vue +++ b/pages/index.vue @@ -1,124 +1,43 @@