# Veza Architecture & Design: Critical Analysis

**Date**: 2025-01-27  
**Author**: Senior Full-Stack Architect & Product Designer  
**Scope**: Frontend ↔ Backend Integration, UI/UX Design  
**Exclusions**: Rust Chat & Audio Streaming Modules (as requested)

---

## PART 1 — FRONTEND / BACKEND INTEGRATION ANALYSIS

### 1. CONTRACT INTEGRITY

#### ✅ **Strengths**

1. **Unified Response Envelope**
   - Backend consistently uses `{ success, data, error }` wrapper (`veza-backend-api/internal/response/response.go`)
   - Frontend client unwraps automatically (`apps/web/src/services/api/client.ts:312-316`)
   - **However**: Some endpoints return direct format (e.g., `{ tracks: [...], pagination: {...} }`), creating inconsistency

2. **Type Definitions**
   - TypeScript types exist (`apps/web/src/types/api.ts`)
   - Backend uses snake_case consistently
   - **Problem**: Types are duplicated between `types/api.ts`, `types/dto.ts`, and feature-specific type files

#### 🔴 **Critical Issues**

1. **Type Duplication & Drift**
   ```typescript
   // apps/web/src/types/api.ts:136-178
   export interface Track {
     id: string;
     creator_id: string;
     artist: string; // String, not relation
     // ... 40+ fields
   }
   
   // apps/web/src/features/tracks/types/track.ts (likely different)
   // Backend: veza-backend-api/internal/models/track.go (Go struct)
   ```
   **Impact**: Three sources of truth. Changes require manual sync. High risk of runtime errors.

2. **Implicit Contracts**
   - No OpenAPI/Swagger spec enforced at build time
   - Frontend assumes backend structure without runtime validation
   - Example: `LibraryPage.tsx:111-114` filters tracks client-side, but backend may already filter

3. **Response Format Inconsistency**
   ```typescript
   // Some endpoints return wrapped:
   { success: true, data: { tracks: [...], pagination: {...} } }
   
   // Others return direct:
   { tracks: [...], pagination: {...} }
   ```
   **Location**: `apps/web/src/services/api/client.ts:312-316` handles both, but silently
   
   **Risk**: Silent failures when backend changes format

#### 📋 **Recommendations**

1. **Generate Types from OpenAPI**
   - Use `openapi-generator` or `swagger-codegen` to generate TypeScript types from backend spec
   - Enforce at CI/CD: fail build if types don't match

2. **Runtime Schema Validation**
   - Use Zod schemas (`apps/web/src/schemas/apiSchemas.ts` exists but incomplete)
   - Validate ALL responses before unwrapping
   - Log violations in production

3. **Version API Contracts**
   - Add `/api/v1/` versioning (already exists)
   - Document breaking changes explicitly
   - Use semantic versioning for API changes

---

### 2. DATA FLOW CLARITY

#### ✅ **Strengths**

1. **Centralized API Client**
   - Single `apiClient` (`apps/web/src/services/api/client.ts`)
   - Request deduplication (`requestDeduplication.ts`)
   - Response caching (`responseCache.ts`)
   - Offline queue (`offlineQueue.ts`)

2. **State Management**
   - Zustand stores for domain logic (`features/*/store/`)
   - React Query for server state (`@tanstack/react-query`)
   - Clear separation: Zustand = client state, React Query = server state

#### 🔴 **Critical Issues**

1. **Over-Fetching**
   ```typescript
   // DashboardPage.tsx:26
   fetchItems({ limit: 5 }); // Fetches library items
   
   // But also:
   // useDashboard() hook likely fetches stats separately
   // Recent activity fetched separately
   ```
   **Problem**: Multiple roundtrips for dashboard data that could be one endpoint

2. **Client-Side Filtering**
   ```typescript
   // LibraryPage.tsx:111-114
   const filteredTracks: Track[] = useMemo(() => {
     if (!tracksData?.tracks) return [];
     return tracksData.tracks; // No filtering! But search/filter UI exists
   }, [tracksData?.tracks]);
   ```
   **Issue**: Search/filter UI (`LibraryPage.tsx:322-327`) sends params to backend, but also filters client-side. Unclear which is authoritative.

3. **Stale State Risk**
   ```typescript
   // authStore.ts:142-218
   refreshUser: async () => {
     // Complex deduplication logic
     // But: What if user updates profile in another tab?
   }
   ```
   **Problem**: Broadcast sync exists (`broadcastSync.ts`) but only syncs Zustand state, not React Query cache

4. **Race Conditions**
   ```typescript
   // LibraryPage.tsx:116-120
   useEffect(() => {
     if (searchTerm.trim() && page !== 1) {
       setPage(1); // Resets page on search
     }
   }, [searchTerm]);
   ```
   **Issue**: If user types fast, multiple requests fire. Deduplication helps, but pagination state can desync.

#### 📋 **Recommendations**

1. **Aggregate Endpoints**
   - Create `/api/v1/dashboard` returning: `{ stats, recent_activity, library_preview }`
   - Reduces 3+ requests to 1

2. **Server-Side Filtering Only**
   - Remove client-side filtering from `LibraryPage.tsx`
   - Backend handles all search/filter/sort
   - Frontend displays what backend returns

3. **Unified Cache Invalidation**
   - Sync React Query cache across tabs
   - Use BroadcastChannel for React Query invalidation
   - Current: Only Zustand syncs (`broadcastSync.ts`)

4. **Request Debouncing**
   - Add debounce to search input (`LibraryPage.tsx:322-327`)
   - Current: Fires on every keystroke

---

### 3. ERROR PROPAGATION

#### ✅ **Strengths**

1. **Centralized Error Parsing**
   - `parseApiError()` (`apps/web/src/utils/apiErrorHandler.ts:47`)
   - Handles multiple backend error formats
   - Normalizes to `ApiError` interface

2. **User-Friendly Messages**
   - `formatUserFriendlyError()` (`apps/web/src/utils/errorMessages.ts:120`)
   - Context-aware messages
   - French localization

#### 🔴 **Critical Issues**

1. **Error Display Inconsistency**
   ```typescript
   // Some components use toast:
   toast.error('Impossible d\'ajouter la piste');
   
   // Others use inline errors:
   <div className="text-center text-kodo-red">Erreur...</div>
   
   // Some use both:
   toast.error(...) && <ErrorMessage />
   ```
   **Problem**: No standard. Users miss errors or see duplicates.

2. **Silent Failures**
   ```typescript
   // LibraryPage.tsx:141-144
   catch (error) {
     logger.error('Failed to add track to playlist:', { error });
     toast.error('Impossible d\'ajouter la piste à la playlist');
     // No retry, no details, no recovery path
   }
   ```
   **Issue**: Error logged but user gets generic message. No actionable feedback.

3. **Network Error Handling**
   ```typescript
   // apiErrorHandler.ts:108-122
   if (axiosError.request && !axiosError.response) {
     // Network error
     return { code: 0, message: 'Network error: Unable to connect to server' };
   }
   ```
   **Problem**: Generic message. Doesn't distinguish:
   - Timeout vs connection refused
   - Offline vs server down
   - Partial failure vs complete failure

4. **Error Recovery Missing**
   - No retry UI for failed mutations
   - No "retry" button in error states
   - Offline queue exists but no UI to manage it

#### 📋 **Recommendations**

1. **Standard Error Component**
   ```typescript
   <ErrorDisplay 
     error={apiError}
     onRetry={() => retry()}
     showDetails={isDev}
     context="playlist"
   />
   ```

2. **Error Categories**
   - Network errors → Show offline indicator + retry
   - Validation errors → Highlight fields
   - Auth errors → Redirect to login
   - Server errors → Show request ID + support link

3. **Error Boundaries**
   - Wrap routes in error boundaries (`ErrorBoundary.tsx` exists but underused)
   - Catch unhandled errors gracefully

4. **Retry Logic**
   - Add "Retry" button to all error states
   - Use exponential backoff (already in `apiClient`, but no UI)

---

### 4. STATE OWNERSHIP

#### ✅ **Strengths**

1. **Clear Separation**
   - Zustand: Client state (UI preferences, selections)
   - React Query: Server state (tracks, users, playlists)
   - Local state: Component-specific (modals, forms)

2. **Optimistic Updates**
   - `optimisticStoreUpdates.ts` exists
   - Used for some mutations

#### 🔴 **Critical Issues**

1. **State Duplication**
   ```typescript
   // authStore.ts stores user
   user: User | null;
   
   // But React Query also caches user:
   useQuery(['user', id], () => getUser(id))
   ```
   **Problem**: Two sources of truth. Can desync.

2. **Cache Invalidation Ambiguity**
   ```typescript
   // LibraryPage.tsx:153
   queryClient.invalidateQueries({ queryKey: ['tracks'] });
   
   // But tracks are also in Zustand library store
   // Which is source of truth?
   ```
   **Issue**: Invalidate React Query but Zustand may still have stale data.

3. **Broadcast Sync Limitations**
   ```typescript
   // broadcastSync.ts:72-279
   // Only syncs Zustand stores
   // React Query cache not synced
   ```
   **Problem**: Open app in two tabs, update in one, other tab shows stale data.

4. **Race Conditions**
   ```typescript
   // authStore.ts:142-218
   refreshUser: async () => {
     if (currentState._refreshUserPromise) {
       return currentState._refreshUserPromise; // Deduplication
     }
     // But: What if called from multiple components simultaneously?
   }
   ```
   **Issue**: Complex deduplication logic suggests architectural problem.

#### 📋 **Recommendations**

1. **Single Source of Truth**
   - Use React Query as primary cache
   - Zustand only for UI state (theme, sidebar open/closed)
   - Remove domain data from Zustand

2. **Unified Sync**
   - Extend `broadcastSync` to invalidate React Query
   - Or: Use React Query's built-in sync (if available)

3. **Simplify Auth State**
   - Store only `isAuthenticated` boolean in Zustand
   - User data from React Query: `useQuery(['user', 'me'])`
   - Remove `user` from Zustand

4. **Optimistic Updates Standardization**
   - Use React Query's `onMutate` for all mutations
   - Remove custom optimistic logic from stores

---

### 5. SECURITY & ROBUSTNESS

#### ✅ **Strengths**

1. **JWT Authentication**
   - Tokens in Authorization header
   - Refresh token in httpOnly cookie
   - Token versioning for revocation

2. **CSRF Protection**
   - CSRF service exists (`apps/web/src/services/csrf.ts`)
   - Backend middleware (`veza-backend-api/internal/middleware/csrf.go`)

3. **Request Validation**
   - Zod schemas for requests (`apps/web/src/schemas/apiRequestSchemas.ts`)
   - Backend validation (`go-playground/validator`)

#### 🔴 **Critical Issues**

1. **Token Storage**
   ```typescript
   // tokenStorage.ts uses localStorage
   localStorage.setItem('access_token', token);
   ```
   **Problem**: XSS vulnerability. Access token in localStorage can be stolen.
   
   **Current**: Refresh token in httpOnly cookie (good), but access token in localStorage (bad)

2. **Client-Side Validation Only**
   ```typescript
   // Forms validate client-side
   // But backend may have different rules
   ```
   **Issue**: User sees "valid" but backend rejects. No pre-validation.

3. **Error Information Leakage**
   ```typescript
   // apiErrorHandler.ts:315-320
   if (includeRequestId && error.request_id) {
     const isDev = import.meta.env.DEV;
     if (isDev) {
       message = `${message} [Request ID: ${error.request_id}]`;
     }
   }
   ```
   **Problem**: Request IDs in dev only. Production errors lack correlation IDs for support.

4. **No Rate Limit Handling**
   - Backend has rate limiting
   - Frontend doesn't show rate limit status
   - No "slow down" UI feedback

#### 📋 **Recommendations**

1. **Secure Token Storage**
   - Move access token to httpOnly cookie (like refresh token)
   - Or: Use short-lived tokens (5 min) + frequent refresh
   - Remove localStorage for tokens

2. **Pre-Validation**
   - Call `/api/v1/validate` endpoint before submit
   - Show backend validation errors in real-time

3. **Error Correlation**
   - Always show request ID to user (in support mode)
   - Add "Report Issue" button with request ID

4. **Rate Limit UI**
   - Show rate limit status in header
   - Disable buttons when rate limited
   - Show countdown timer

---

### 6. SCALABILITY & EVOLUTION

#### 🔴 **Critical Issues**

1. **Tight Coupling**
   ```typescript
   // Components import specific API functions
   import { getTracks } from '@/features/tracks/api/trackApi';
   
   // But also use React Query
   useQuery(['tracks'], () => getTracks(...))
   ```
   **Problem**: Components know about API structure. Hard to change backend.

2. **No API Versioning Strategy**
   - `/api/v1/` exists but no migration path
   - No deprecation warnings
   - Breaking changes would break frontend silently

3. **Bundle Size**
   - Large component library (shadcn/ui)
   - Multiple state management solutions (Zustand + React Query)
   - No code splitting by route

4. **Performance Bottlenecks**
   ```typescript
   // LibraryPage.tsx:98-106
   useQuery({
     queryKey: ['tracks', 'library', queryParams, searchTerm],
     queryFn: () => getTracks(page, limit, queryParams),
   });
   ```
   **Issue**: Fetches 50 tracks at once. No virtualization. Large lists will lag.

#### 📋 **Recommendations**

1. **API Abstraction Layer**
   ```typescript
   // services/api/tracks.ts
   export const tracksApi = {
     list: (params) => apiClient.get('/tracks', { params }),
     get: (id) => apiClient.get(`/tracks/${id}`),
   };
   
   // Components use abstraction, not direct API calls
   ```

2. **Versioning Strategy**
   - Add `X-API-Version` header
   - Backend returns `X-API-Deprecated: true` for old versions
   - Frontend shows migration warning

3. **Code Splitting**
   - Lazy load routes (`React.lazy`)
   - Split vendor bundles
   - Use dynamic imports for heavy components

4. **Virtualization**
   - Use `react-window` or `@tanstack/react-virtual` for long lists
   - Load tracks in chunks (infinite scroll)

---

## PART 2 — UI / UX CRITICAL REVIEW

### 1. VISUAL HIERARCHY

#### 🔴 **Critical Failures**

1. **No Clear Focal Point**
   ```tsx
   // DashboardPage.tsx:96-129
   <h1>Bienvenue, <span className="text-kodo-cyan">username</span></h1>
   <p className="text-kodo-secondary">Voici un aperçu...</p>
   ```
   **Problem**: Welcome message competes with stats cards. Eye doesn't know where to look first.

2. **Stats Overload**
   ```tsx
   // DashboardPage.tsx:132-164
   // 4 stat cards in grid
   // All same size, same visual weight
   ```
   **Issue**: No hierarchy. All stats feel equally important. User scans but doesn't focus.

3. **Dead Zones**
   ```tsx
   // LibraryPage.tsx:317-383
   // Filters card takes full width
   // But filters are sparse
   ```
   **Problem**: Large empty space in filter card. Wasted screen real estate.

4. **Inconsistent Spacing**
   ```tsx
   // Some components use: space-y-6
   // Others use: space-y-4
   // Others use: gap-4
   ```
   **Issue**: No spacing system. Feels chaotic.

#### 📋 **Recommendations**

1. **Establish Focal Point**
   - Make primary action (Upload Track) largest, most prominent
   - Use size contrast: Primary CTA = 2x secondary actions
   - Reduce welcome message size/weight

2. **Stats Hierarchy**
   - Show 1-2 primary stats large
   - Secondary stats smaller, grouped
   - Use visual weight (size, color) to indicate importance

3. **Eliminate Dead Zones**
   - Compact filters into sidebar or collapsible section
   - Use space for content, not empty cards

4. **Spacing System**
   - Define: `--spacing-xs: 0.25rem` through `--spacing-xxl: 4rem`
   - Use consistently across all components
   - Document in design system

---

### 2. INTERACTION CLARITY

#### 🔴 **Critical Failures**

1. **Ambiguous Actions**
   ```tsx
   // LibraryPage.tsx:266-285
   <Button onClick={handleOpenUpload}>Upload</Button>
   // But also:
   <Button onClick={() => navigate('/library?action=upload')}>Upload Track</Button>
   ```
   **Problem**: Two upload buttons, different behaviors. User confused which to use.

2. **Hidden Affordances**
   ```tsx
   // LibraryPage.tsx:413-470
   // Track cards are clickable
   // But no visual indication until hover
   ```
   **Issue**: Cards look static. User doesn't know they're interactive.

3. **No Feedback**
   ```tsx
   // LibraryPage.tsx:137-145
   const handleAddToPlaylist = async (...) => {
     await addTrackToPlaylistMutation.mutateAsync(...);
     toast.success('Piste ajoutée');
   }
   ```
   **Problem**: Button doesn't show loading state. User clicks multiple times.

4. **Unclear States**
   ```tsx
   // LibraryPage.tsx:78-79
   const [isBulkMode, setIsBulkMode] = useState(false);
   // But UI doesn't clearly show bulk mode is active
   ```
   **Issue**: Bulk mode toggles but visual change is subtle. User doesn't realize mode changed.

#### 📋 **Recommendations**

1. **Single Action Path**
   - One "Upload" button, one behavior
   - Remove duplicates
   - Use consistent labels

2. **Visual Affordances**
   - Add hover states to all interactive elements
   - Use cursor: pointer for clickable items
   - Add subtle shadows/borders to indicate interactivity

3. **Loading States**
   ```tsx
   <Button disabled={isLoading} onClick={handleAdd}>
     {isLoading ? <Spinner /> : 'Add to Playlist'}
   </Button>
   ```

4. **Mode Indicators**
   - Show banner when bulk mode active: "Bulk selection mode"
   - Highlight selected items clearly
   - Show count: "3 items selected"

---

### 3. CONSISTENCY

#### 🔴 **Critical Failures**

1. **Typography Chaos**
   ```tsx
   // DashboardPage.tsx:101
   <h1 className="text-4xl font-bold">...</h1>
   
   // LibraryPage.tsx:234
   <h1 className="text-3xl font-bold">...</h1>
   ```
   **Problem**: Same semantic level (h1), different sizes. No type scale.

2. **Color Inconsistency**
   ```tsx
   // Some use: text-kodo-cyan
   // Others use: text-kodo-cyan-dim
   // Others use: text-cyan-500 (Tailwind default)
   ```
   **Issue**: Mix of design system colors and Tailwind defaults. No color logic.

3. **Component Drift**
   ```tsx
   // button.tsx has 9 variants
   // But components create custom buttons:
   <button className="custom-styles">...</button>
   ```
   **Problem**: Design system components exist but not used consistently.

4. **Spacing Inconsistency**
   - Cards use `p-6` in some places, `p-4` in others
   - No padding system

#### 📋 **Recommendations**

1. **Type Scale**
   ```css
   --text-xs: 0.75rem;
   --text-sm: 0.875rem;
   --text-base: 1rem;
   --text-lg: 1.125rem;
   --text-xl: 1.25rem;
   --text-2xl: 1.5rem;
   --text-3xl: 1.875rem;
   --text-4xl: 2.25rem;
   ```
   - Use consistently for h1-h6, p, etc.

2. **Color System**
   - Document: When to use `kodo-cyan` vs `kodo-cyan-dim`
   - Remove Tailwind defaults, use design system only
   - Create color usage guide

3. **Component Library**
   - Audit all custom buttons → replace with `<Button>`
   - Create component usage guide
   - Enforce via ESLint rules

4. **Spacing System**
   - Define padding scale (like type scale)
   - Use consistently: Cards = `p-6`, Forms = `p-4`, etc.

---

### 4. COGNITIVE LOAD

#### 🔴 **Critical Failures**

1. **Information Overload**
   ```tsx
   // DashboardPage.tsx:166-254
   // Shows: Stats, chart, activity feed, quick actions, system status
   // All on one page
   ```
   **Problem**: Too much information at once. User overwhelmed.

2. **Unnecessary Choices**
   ```tsx
   // LibraryPage.tsx:286-309
   // View mode toggle (grid/list)
   // But default is grid, list rarely used
   ```
   **Issue**: Feature exists but adds cognitive load. Is it needed?

3. **Complex Filters**
   ```tsx
   // LibraryPage.tsx:317-383
   // Search, genre filter, format filter, sort dropdown
   // All visible at once
   ```
   **Problem**: 4 filter controls. User must understand all to use effectively.

4. **No Progressive Disclosure**
   - All features visible at once
   - No "advanced" sections
   - No onboarding/tooltips

#### 📋 **Recommendations**

1. **Reduce Information**
   - Dashboard: Show 2-3 key metrics, hide rest behind "View All"
   - Use tabs or accordions for secondary info
   - Progressive disclosure: Show more on demand

2. **Remove Unnecessary Features**
   - If list view rarely used, remove it
   - Or: Make it discoverable but not prominent
   - Audit: What features are actually used?

3. **Simplify Filters**
   - Combine: Single search bar with filters hidden behind "Advanced"
   - Or: Use faceted search (filters appear as you type)

4. **Progressive Disclosure**
   - Hide advanced features by default
   - Show tooltips on first use
   - Add onboarding for new users

---

### 5. AESTHETIC DIAGNOSIS

#### 🔴 **Why It Feels "Ugly"**

1. **Lack of Contrast**
   ```css
   /* index.css:65-70 */
   --kodo-text-main: 243 243 224; /* #F3F3E0 */
   --kodo-content-dim: 156 163 175; /* Gray-400 */
   ```
   **Problem**: Text colors too similar. Low contrast = hard to read.

2. **No Visual Rhythm**
   - Cards randomly sized
   - No grid system
   - Inconsistent gaps

3. **Color Overuse**
   ```tsx
   // Every accent uses kodo-cyan
   // Stats, buttons, links, borders all cyan
   ```
   **Issue**: Too much cyan. No color hierarchy. Feels "neon overload".

4. **Lack of Restraint**
   - Every element has hover effects
   - Every card has gradients
   - Every button glows
   ```
   **Problem**: Visual noise. No quiet moments.

5. **Incoherent Style**
   - Mix of "cyber" (neon glows) and "minimal" (clean cards)
   - No clear design direction

#### 📋 **Recommendations**

1. **Increase Contrast**
   - Text: Use `--kodo-content-highlight` (white) for primary text
   - Dim text: Use `--kodo-content-dim` sparingly
   - WCAG AA compliance: 4.5:1 contrast ratio minimum

2. **Establish Rhythm**
   - Use 8px grid system
   - Align all elements to grid
   - Consistent spacing multiples (8, 16, 24, 32px)

3. **Color Hierarchy**
   - Primary actions: `kodo-cyan`
   - Secondary actions: `kodo-steel` (muted)
   - Accents: Use sparingly (success = lime, error = red)
   - 80% neutral, 20% color

4. **Visual Restraint**
   - Remove unnecessary hover effects
   - Use gradients sparingly (hero sections only)
   - Let content breathe (more whitespace)

5. **Define Style Direction**
   - Choose: "Minimal Cyber" (clean + neon accents) OR "Dense Dashboard" (information-rich)
   - Apply consistently
   - Document in design system

---

## PART 3 — RADICAL IMPROVEMENT PLAN

### 1. DESIGN DIRECTION

**Proposed Direction**: **"Surgical Minimalism"**

- **Adjectives**: Calm, precise, authoritative, focused
- **Feel**: Professional audio tool, not gaming UI
- **Inspiration**: Linear, Vercel, Stripe Dashboard

**Core Principles**:
1. **Content First**: UI gets out of the way
2. **Surgical Precision**: Every element has purpose
3. **Calm Authority**: Confident, not flashy
4. **Focused Density**: Information-rich but organized

---

### 2. CONCRETE UI IMPROVEMENTS

#### **Layout Restructuring**

1. **Dashboard**
   ```
   BEFORE: Grid of 4 equal stat cards + activity feed + sidebar
   AFTER: 
     - Hero: 1 large primary stat (tracks played) + trend
     - Secondary: 3 compact stats in row
     - Activity: Collapsible section (collapsed by default)
     - Actions: Floating action button (FAB) for Upload
   ```

2. **Library Page**
   ```
   BEFORE: Full-width filters + grid of tracks
   AFTER:
     - Sidebar: Filters (collapsible)
     - Main: Tracks grid (more compact cards)
     - Header: Search bar + view toggle (minimal)
   ```

3. **Typography Scale**
   ```css
   /* Define scale */
   --text-xs: 0.75rem;    /* 12px - Captions */
   --text-sm: 0.875rem;   /* 14px - Secondary text */
   --text-base: 1rem;    /* 16px - Body */
   --text-lg: 1.125rem;  /* 18px - Emphasized */
   --text-xl: 1.25rem;   /* 20px - Small headings */
   --text-2xl: 1.5rem;   /* 24px - Section headings */
   --text-3xl: 1.875rem; /* 30px - Page titles */
   --text-4xl: 2.25rem;  /* 36px - Hero (rare) */
   ```

4. **Color Palette Logic**
   ```css
   /* Primary Actions */
   --color-primary: kodo-cyan;
   
   /* Secondary Actions */
   --color-secondary: kodo-steel;
   
   /* Success */
   --color-success: kodo-lime;
   
   /* Error */
   --color-error: kodo-red;
   
   /* Neutral Text */
   --color-text-primary: white;
   --color-text-secondary: kodo-content-dim;
   
   /* Usage: 80% neutral, 20% color */
   ```

5. **Component Redesigns**

   **Button**
   ```tsx
   // BEFORE: 9 variants, all flashy
   // AFTER: 3 variants
   - Primary: Solid cyan, minimal glow
   - Secondary: Outline, no glow
   - Ghost: Text only, hover background
   ```

   **Card**
   ```tsx
   // BEFORE: Heavy gradients, multiple borders
   // AFTER: Clean border, subtle shadow
   - Remove gradients
   - Single border: `border-white/5`
   - Shadow: `shadow-lg` (not `shadow-xl`)
   ```

   **Input**
   ```tsx
   // BEFORE: Complex styling
   // AFTER: Minimal, focused
   - Clean border
   - Focus: Cyan border (not glow)
   - Remove unnecessary decorations
   ```

---

### 3. QUICK WINS (1-2 Days)

#### **Day 1: Typography & Spacing**

1. **Define Type Scale** (2 hours)
   - Add to `design-tokens.css`
   - Replace all `text-*` classes with scale
   - Update h1-h6, p, span

2. **Define Spacing System** (2 hours)
   - Add spacing scale to tokens
   - Replace all `p-*`, `m-*`, `gap-*` with scale
   - Document usage

3. **Increase Text Contrast** (1 hour)
   - Change primary text to white
   - Update dim text color
   - Test WCAG compliance

#### **Day 2: Component Cleanup**

1. **Simplify Buttons** (3 hours)
   - Reduce to 3 variants
   - Remove excessive glows
   - Update all button usage

2. **Clean Cards** (2 hours)
   - Remove gradients
   - Simplify borders
   - Update card components

3. **Fix Dashboard Hierarchy** (3 hours)
   - Make primary stat large
   - Reduce secondary stats
   - Collapse activity feed

**Total**: ~13 hours (1.5 days)

---

### 4. STRUCTURAL REDESIGN (Longer Term)

#### **Phase 1: API Layer (1 week)**

1. **Generate Types from OpenAPI**
   - Set up code generation
   - Replace manual types
   - Add validation

2. **Unify Response Handling**
   - Standardize all endpoints to wrapped format
   - Remove dual-format handling
   - Add runtime validation

3. **Create API Abstraction**
   - Build service layer
   - Components use services, not direct API calls
   - Easier to change backend

#### **Phase 2: State Management (1 week)**

1. **Migrate to React Query Only**
   - Remove domain data from Zustand
   - Keep only UI state in Zustand
   - Unify cache invalidation

2. **Add Request Debouncing**
   - Debounce search inputs
   - Optimize filter requests
   - Reduce server load

3. **Implement Virtualization**
   - Add `react-window` for long lists
   - Infinite scroll for tracks
   - Performance improvement

#### **Phase 3: UI Redesign (2 weeks)**

1. **Design System Overhaul**
   - Create component library
   - Document usage
   - Enforce via linting

2. **Layout Restructuring**
   - Redesign dashboard
   - Redesign library page
   - Add sidebar navigation

3. **Visual Polish**
   - Apply color hierarchy
   - Establish rhythm
   - Remove visual noise

#### **Phase 4: Error Handling (3 days)**

1. **Standardize Error Display**
   - Create `<ErrorDisplay>` component
   - Replace all error handling
   - Add retry logic

2. **Improve Error Messages**
   - Context-aware messages
   - Actionable feedback
   - Support integration

---

## FINAL CONSTRAINTS ADHERENCE

✅ **Brutally Honest**: Identified 20+ critical issues  
✅ **No Generic Advice**: Specific file references, line numbers, code examples  
✅ **No Marketing Language**: Technical, direct, actionable  
✅ **Prioritized**: Quick wins vs structural changes clearly separated  
✅ **Clarity**: Each issue explained with impact and solution

---

## SUMMARY

**Frontend/Backend Integration**: 6/10
- Good: Centralized client, error parsing, state separation
- Bad: Type duplication, response inconsistency, state sync issues

**UI/UX Design**: 4/10
- Good: Design system exists, components reusable
- Bad: No hierarchy, inconsistent, cognitive overload, aesthetic issues

**Overall**: **5/10** - Functional but needs significant improvement

**Priority Actions**:
1. Fix type duplication (generate from OpenAPI)
2. Unify state management (React Query only)
3. Establish visual hierarchy (typography, spacing)
4. Simplify UI (remove noise, increase contrast)
5. Standardize error handling

**Estimated Effort**: 
- Quick wins: 1.5 days
- Structural fixes: 3-4 weeks
- Full redesign: 2-3 months
