# UX Implementation Guide > **Purpose:** Comprehensive guide for UX implementation across ByteLyst products using common platform UI packages, design tokens, and Cipher design system integration. > **Target Audience:** Product teams implementing UX improvements and testing infrastructure. --- ## Overview This guide documents the complete UX implementation approach for the trading dashboard, which can be replicated across all ByteLyst products. The approach covers: - **Common Platform UI Integration** - Leveraging `@bytelyst/ui` shared primitives - **Design Token Usage** - Using `@bytelyst/design-tokens` for consistent styling - **Component Normalization** - Replacing one-off components with shared primitives - **Accessibility Improvements** - Keyboard navigation, ARIA labels, focus management - **Responsive Design** - Viewport matrix testing, shell breakpoints - **Testing Infrastructure** - Playwright E2E tests, Storybook, AI-friendly reports - **Cipher Design System** - Visual hierarchy, spacing, typography principles --- ## Part 1: Common Platform UI Integration ### Local Package Resolution **Critical:** Use local common platform packages by default, not Gitea registry. **File:** `.pnpmfile.cjs` ```javascript // .pnpmfile.cjs // Default to local common platform packages function readPackage(pkg, context) { if (!context.workspace) return pkg; // Default to common-plat (local packages) const packageSource = process.env.BYTELYST_PACKAGE_SOURCE || 'common-plat'; if (packageSource === 'common-plat') { // Resolve @bytelyst/* packages from local common platform if (pkg.name.startsWith('@bytelyst/')) { pkg.dependencies = pkg.dependencies || {}; pkg.dependencies[pkg.name] = 'workspace:*'; } } return pkg; } module.exports = { name: 'bytelyst-package-source', hooks: { readPackage, }, }; ``` **File:** `.npmrc` ```ini # Remove repo-level GITEA_NPM_TOKEN interpolation # Gitea registry auth should live in user-level ~/.npmrc or CI secrets # Only when BYTELYST_PACKAGE_SOURCE=gitea is explicitly used ``` **Commit Reference:** `f2216ad` - chore(pnpm): prefer local bytelyst packages ### Environment Variables ```bash # Default: Use local common platform packages BYTELYST_PACKAGE_SOURCE=common-plat # Optional: Use Gitea registry (requires auth) BYTELYST_PACKAGE_SOURCE=gitea # GITEA_NPM_TOKEN should be in ~/.npmrc or CI secrets ``` ### Verification Commands ```bash # Verify local package resolution pnpm install @bytelyst/ui @bytelyst/design-tokens # Verify packages resolve from local common platform pnpm list @bytelyst/ui # Should show: @bytelyst/ui -> link:../learning_ai_common_plat/packages/ui ``` ### Benefits of Local Package Resolution 1. **Faster Development** - No network calls to registry during development 2. **Immediate Updates** - Changes to common platform are immediately available 3. **No Registry Dependency** - Works offline and without Gitea access 4. **Consistent Builds** - Same packages across all environments 5. **Simpler CI** - No need for registry auth in CI by default ### Product Adapter Pattern Create a product adapter to normalize imports and extend shared primitives with product-specific variants: **File:** `web/src/components/ui/Primitives.tsx` ```typescript import * as React from 'react'; import { Badge as CommonBadge, Button as CommonButton, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldTitle, Input as CommonInput, Select as CommonSelect, Textarea as CommonTextarea, type BadgeProps as CommonBadgeProps, type ButtonProps as CommonButtonProps, type InputProps as CommonInputProps, type SelectProps as CommonSelectProps, type TextareaProps as CommonTextareaProps, } from '@bytelyst/ui'; // Re-export all shared primitives export { ActionMenu, AlertBanner, DataList, DataTable, Drawer, EmptyState, EntityCard, FieldGrid, FilterBar, FormSection, MetricCard, Modal, PageHeader, Panel, Skeleton, Timeline, Toolbar, // ... all other @bytelyst/ui components } from '@bytelyst/ui'; // Define product-specific variants type ProductButtonVariant = NonNullable | 'link'; type ProductButtonSize = NonNullable | 'icon'; type ProductFieldVariant = 'surface' | 'muted'; type ProductFieldSize = 'sm' | 'md'; type ProductBadgeVariant = NonNullable | 'danger'; type ProductStatusTone = 'success' | 'warning' | 'error' | 'info' | 'neutral'; // Extend interfaces with product-specific props export interface ButtonProps extends Omit { variant?: ProductButtonVariant; size?: ProductButtonSize; } export interface IconButtonProps extends Omit { icon: React.ReactNode; label: string; } export interface InputProps extends CommonInputProps { controlSize?: ProductFieldSize; variant?: ProductFieldVariant; } // Product status mapping for badges export type ProductStatus = | 'active' | 'approved' | 'blocked' | 'buy' | 'cancelled' | 'connected' | 'danger' | 'degraded' | 'disabled' | 'error' | 'failed' | 'idle' | 'info' | 'live' | 'neutral' | 'off' | 'ok' | 'paper' | 'pending' | 'rejected' | 'sell' | 'success' | 'synced' | 'warning'; const productStatusTone: Record = { active: 'success', approved: 'success', blocked: 'error', buy: 'success', cancelled: 'neutral', connected: 'success', danger: 'error', degraded: 'warning', disabled: 'neutral', error: 'error', failed: 'error', idle: 'neutral', info: 'info', live: 'warning', neutral: 'neutral', off: 'neutral', ok: 'success', paper: 'info', pending: 'warning', rejected: 'error', sell: 'error', success: 'success', synced: 'success', warning: 'warning', }; // Helper function to map product status to tone export function statusToneFor(status: ProductStatus | string | null | undefined): ProductStatusTone { if (!status) return 'neutral'; const normalized = status.trim().toLowerCase().replace(/[\s_]+/g, '-') as ProductStatus; return productStatusTone[normalized] ?? 'neutral'; } // Product-specific component implementations export const Button = React.forwardRef( ({ variant = 'primary', size = 'md', className, ...props }, ref) => ( ), ); export const IconButton = React.forwardRef( ({ icon, label, variant = 'ghost', size = 'icon', className, ...props }, ref) => ( ), ); export const Input = React.forwardRef( ({ controlSize = 'md', variant = 'surface', className, ...props }, ref) => ( ), ); export function ProductStatusBadge({ status, children, }: { status: ProductStatus | string | null | undefined; children?: React.ReactNode; }) { return ( {children ?? status ?? 'Unknown'} ); } ``` **Benefits of Product Adapter Pattern:** - Centralized import point for all UI components - Product-specific variants without modifying common platform - Consistent styling across the application - Easy to migrate to new common platform versions - Type-safe extensions with TypeScript --- ## Part 2: Design Token Usage ### CSS Variable Integration Use design tokens from `@bytelyst/design-tokens` via CSS custom properties: ```css /* Surface colors */ background: var(--bl-surface-card); background: var(--bl-surface-muted); background: var(--bl-surface-overlay); /* Text colors */ color: var(--bl-text-primary); color: var(--bl-text-secondary); color: var(--bl-text-muted); /* Border colors */ border-color: var(--bl-border); border-color: var(--bl-border-muted); /* Input styling */ background: var(--bl-input); color: var(--bl-text-primary); border-color: var(--bl-border); /* Focus states */ border-color: var(--bl-focus-ring); box-shadow: 0 0 0 2px var(--bl-focus-ring-muted); /* Semantic colors */ color: var(--bl-accent); background: var(--bl-success); background: var(--bl-warning); background: var(--bl-error); /* Spacing */ padding: var(--bl-spacing-sm); padding: var(--bl-spacing-md); padding: var(--bl-spacing-lg); padding: var(--bl-spacing-xl); /* Border radius */ border-radius: var(--bl-radius-control); border-radius: var(--bl-radius-md); border-radius: var(--bl-radius-lg); /* Typography */ font-size: var(--bl-text-sm); font-size: var(--bl-text-base); font-size: var(--bl-text-lg); font-weight: var(--bl-font-medium); font-weight: var(--bl-font-semibold); ``` ### Component Token Patterns **Example: Badge Component** ```typescript // Using design tokens for badge styling const badgeStyles = { success: { background: 'var(--bl-success-light)', color: 'var(--bl-success-dark)', borderColor: 'var(--bl-success)', }, warning: { background: 'var(--bl-warning-light)', color: 'var(--bl-warning-dark)', borderColor: 'var(--bl-warning)', }, error: { background: 'var(--bl-error-light)', color: 'var(--bl-error-dark)', borderColor: 'var(--bl-error)', }, }; ``` ### Token Migration Checklist When migrating to design tokens: 1. **Identify hardcoded colors** - Search for hex codes and named colors 2. **Map to semantic tokens** - Use semantic names (success, warning, error) not literal colors 3. **Replace with CSS variables** - Use `var(--bl-*)` syntax 4. **Test across themes** - Ensure tokens work in light/dark modes 5. **Audit for missed tokens** - Use `audit:ui` to find remaining hardcoded values --- ## Part 3: Component Normalization ### Badge Normalization **Before:** One-off CSS classes for different badge styles ```css /* Old approach - one-off classes */ .stat-chip { background: #f0f0f0; padding: 4px 8px; border-radius: 4px; font-size: 12px; } .saved-setup-id-chip { background: #e0e0e0; padding: 6px 12px; border-radius: 6px; } .health-pill { background: #d0d0d0; padding: 5px 10px; border-radius: 20px; } ``` **After:** Shared Badge component from product adapter ```typescript import { Badge, ProductStatusBadge } from '../components/ui/Primitives'; // Replace .stat-chip with Badge Active // Replace .saved-setup-id-chip with Badge Setup #123 // Replace .health-pill with ProductStatusBadge ``` **Commit:** `94ce743` - refactor(ui): replace one-off visual language with shared Badge components ### Alert Banner Unification **Before:** Different alert implementations across components ```typescript // HistoryTab.tsx - custom alert
⚠️ Warning message
// PositionsTab.tsx - different alert
!
Warning text
``` **After:** Shared AlertBanner component ```typescript import { AlertBanner } from '../components/ui/Primitives'; // Both components now use shared AlertBanner Warning message Error message ``` **Commit:** `d4846b7` - refactor(ui): unify operational alert banners ### Table Controls Standardization **Before:** Custom table controls with inconsistent styling ```typescript // Different button styles across tables ``` **After:** Standardized Button component ```typescript import { Button, IconButton } from '../components/ui/Primitives'; // Consistent button styles } label="Run" /> ``` **Commits:** - `3951767` - refactor(ui): standardize operations table badges - `fd64fec` - refactor(ui): refine positions table controls - `bfd7d3b` - refactor(ui): align history filters controls ### Control Normalization Pattern **Step 1:** Identify one-off controls ```bash # Search for custom CSS classes grep -r "className.*chip" web/src/ grep -r "className.*btn" web/src/ grep -r "className.*pill" web/src/ ``` **Step 2:** Map to shared primitives - Chips → Badge - Custom buttons → Button - Custom inputs → Input - Custom selects → Select - Custom alerts → AlertBanner **Step 3:** Replace component by component ```typescript // Before
Text
// After Text ``` **Step 4:** Remove old CSS ```css /* Delete one-off CSS classes */ .custom-chip { /* delete */ } .custom-btn { /* delete */ } ``` **Step 5:** Verify with audit ```bash pnpm run audit:ui ``` --- ## Part 4: Accessibility Improvements ### Keyboard Navigation **Focus Management** ```typescript // Ensure interactive elements are focusable ``` **Keyboard Toggles** ```typescript // Commit: a65d726 - test(ui): cover profile rule keyboard toggles
{ if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); toggle(); } }} aria-pressed={isActive} > Toggle Option
``` **Commit:** `3c52593` - fix(ui): improve profile rule keyboard access ### ARIA Labels **Button Labels** ```typescript // Icon buttons need explicit labels } label="Edit item" aria-label="Edit item" /> ``` **Status Indicators** ```typescript // Status badges need descriptive labels Active ``` **Form Labels** ```typescript // All inputs need associated labels Email Enter your email address ``` ### Focus Indicators **Visible Focus States** ```css /* Ensure focus is visible */ *:focus-visible { outline: 2px solid var(--bl-focus-ring); outline-offset: 2px; } /* Or use design token */ *:focus-visible { outline: 2px solid var(--bl-focus-ring); box-shadow: 0 0 0 2px var(--bl-focus-ring-muted); } ``` **Focus Order** ```typescript // Ensure logical tab order
// Use tabIndex to control order if needed ``` --- ## Part 5: Responsive Design ### Shell Breakpoints **Responsive Shell Testing** ```typescript // Commit: c51544a - test(ui): lock responsive shell breakpoints const breakpoints = { mobile: 'max-width: 560px', tablet: 'max-width: 768px', desktop: 'min-width: 769px', }; // Shell adapts at these breakpoints @media (max-width: 560px) { .dashboard-main { margin-left: 0; } .dashboard-right-panel { display: none; } .trading-sidebar { position: fixed; bottom: 0; width: 100%; height: 60px; } } ``` ### Viewport Matrix Testing **Test all routes across viewports** ```typescript // Commit: 79f0021 - test(ui): add comprehensive Playwright E2E test suite const routes = ['/', '/portfolio', '/research', '/plans', '/markets']; const viewports = [ { name: 'Desktop', width: 1200, height: 800 }, { name: 'Tablet', width: 768, height: 1024 }, { name: 'Mobile', width: 375, height: 667 }, ]; routes.forEach((route) => { viewports.forEach((viewport) => { test(`${route} - ${viewport.name} viewport`, async ({ page }) => { await page.setViewportSize({ width: viewport.width, height: viewport.height }); await page.goto(route); // Check for horizontal overflow const bodyWidth = await page.evaluate(() => document.body.scrollWidth); expect(bodyWidth).toBeLessThanOrEqual(viewport.width + 10); // Check main content visibility const mainContent = page.locator('main'); await expect(mainContent).toBeVisible(); }); }); }); ``` ### Mobile-First Patterns **Responsive Components** ```typescript // Use responsive design tokens
Content
``` **Conditional Rendering** ```typescript // Show/hide based on viewport const isMobile = useMediaQuery('(max-width: 560px)'); {isMobile ? ( ) : ( )} ``` --- ## Part 6: Testing Infrastructure ### Playwright Setup **Install Dependencies** ```bash cd web pnpm add -D @playwright/test pnpm exec playwright install chromium ``` **Create Playwright Config** Create `web/playwright.config.ts`: ```typescript import { defineConfig, devices } from '@playwright/test'; export default defineConfig({ testDir: './e2e', fullyParallel: true, forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, workers: process.env.CI ? 1 : undefined, reporter: 'html', use: { baseURL: 'http://localhost:3050', trace: 'on-first-retry', screenshot: 'only-on-failure', }, projects: [ { name: 'chromium', use: { ...devices['Desktop Chrome'] } }, { name: 'firefox', use: { ...devices['Desktop Firefox'] } }, { name: 'webkit', use: { ...devices['Desktop Safari'] } }, { name: 'Mobile Chrome', use: { ...devices['Pixel 5'] } }, { name: 'Mobile Safari', use: { ...devices['iPhone 12'] } }, { name: 'Desktop Chrome HiDPI', use: { ...devices['Desktop Chrome HiDPI'] } }, ], }); ``` **Commit:** `8db23bd` - test(ui): add Playwright and Storybook testing infrastructure ### Test Suite Structure Create tests in `web/e2e/` directory: ``` web/e2e/ ├── viewport-matrix.spec.ts # Viewport compliance ├── horizontal-overflow.spec.ts # Overflow detection ├── alert-positioning.spec.ts # Critical alerts positioning ├── assistant-positioning.spec.ts # Assistant widget positioning ├── destructive-actions.spec.ts # Destructive actions confirmation ├── feedback.spec.ts # Save/delete/update feedback ├── page-states.spec.ts # Loading/empty/error/success states ├── form-validation.spec.ts # Form validation └── keyboard-navigation.spec.ts # Keyboard navigation ``` **Commit:** `79f0021` - test(ui): add comprehensive Playwright E2E test suite ### Test Runner Script Create `scripts/tests/run-e2e.sh` with server lifecycle management: ```bash #!/bin/bash set -e # Colors for visual output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' PURPLE='\033[0;35m' CYAN='\033[0;36m' BOLD='\033[1m' NC='\033[0m' SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" WEB_DIR="$PROJECT_ROOT/web" REPORTS_DIR="$SCRIPT_DIR/reports" TIMESTAMP=$(date +%Y%m%d_%H%M%S) PORT=3050 cd "$WEB_DIR" # Function to kill any process on the specified port kill_port() { local port=$1 local pid=$(lsof -ti:$port 2>/dev/null || echo "") if [ -n "$pid" ]; then kill -9 $pid 2>/dev/null || true sleep 2 fi } # Function to wait for server to be ready wait_for_server() { local max_attempts=30 local attempt=0 while [ $attempt -lt $max_attempts ]; do if curl -s http://localhost:$PORT > /dev/null 2>&1; then return 0 fi attempt=$((attempt + 1)) sleep 2 done return 1 } # Kill existing server, start fresh, run tests, cleanup kill_port $PORT pnpm dev --port $PORT --strict-port > "$REPORTS_DIR/server-$TIMESTAMP.log" 2>&1 & SERVER_PID=$! if ! wait_for_server; then kill_port $PORT exit 1 fi pnpm exec playwright test \ --reporter=json \ --reporter=list \ --output="$REPORTS_DIR/results-$TIMESTAMP.json" \ 2>&1 | tee "$REPORTS_DIR/test-output-$TIMESTAMP.log" TEST_EXIT_CODE=$? kill $SERVER_PID 2>/dev/null || true kill_port $PORT exit $TEST_EXIT_CODE ``` **Commits:** - `a572293` - test(ui): enhance E2E test runner with AI-friendly detailed reports - `df7c57e` - feat(test): add automatic server lifecycle management to run-e2e.sh - `2bd38e1` - ui(test): enhance script output with visual formatting and colors ### AI-Friendly Report Generation The test runner generates three types of reports: 1. **JSON Report** - Full machine-readable data 2. **Markdown Report** - Human-readable summary 3. **AI Summary** - Optimized for AI agents with actionable next steps **AI Summary Format:** ```json { "timestamp": "20260509_135006", "test_status": "passed", "test_exit_code": 0, "tests_total": 333, "tests_passed": 333, "tests_failed": 0, "duration_seconds": 447, "health_check": { "status": "healthy", "app_running": true, "app_url": "http://localhost:3050" }, "for_ai_agents": { "quick_summary": "passed - 333/333 tests passed in 447s", "if_failed_check": "scripts/tests/reports/test-output-20260509_135006.log", "html_report": "web/playwright-report/index.html", "next_action": "Review HTML report for performance optimization" } } ``` ### Storybook Setup **Install Storybook** ```bash cd web pnpm add -D @storybook/react @storybook/addon-essentials @storybook/addon-interactions ``` **Create Storybook Config** Create `web/.storybook/main.ts`: ```typescript import type { StorybookConfig } from '@storybook/react-vite'; const config: StorybookConfig = { stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'], addons: [ '@storybook/addon-essentials', '@storybook/addon-interactions', ], framework: { name: '@storybook/react-vite', options: {}, }, docs: { autodocs: 'tag', }, }; export default config; ``` **Commit:** `8db23bd` - test(ui): add Playwright and Storybook testing infrastructure --- ## Part 7: Cipher Design System Integration ### Design Principles Follow Cipher design system principles for consistent UX across products: #### 1. Visual Hierarchy **Size and Weight** ```typescript // Use design tokens for consistent hierarchy

Primary Heading

Secondary Heading

Body text

``` #### 2. Spacing System **Consistent Spacing** ```typescript // Use design token spacing
Content
``` #### 3. Typography **Font Scales** ```typescript // Use design token font sizes const textStyles = { xs: 'var(--bl-text-xs)', sm: 'var(--bl-text-sm)', base: 'var(--bl-text-base)', lg: 'var(--bl-text-lg)', xl: 'var(--bl-text-xl)', '2xl': 'var(--bl-text-2xl)', };

Body text

``` #### 4. Color System **Semantic Colors** ```typescript // Use semantic color tokens, not literal colors const statusColors = { success: 'var(--bl-success)', warning: 'var(--bl-warning)', error: 'var(--bl-error)', info: 'var(--bl-info)', };
Success message
``` #### 5. Accessibility **WCAG AA Compliance** ```typescript // Ensure contrast ratios meet WCAG AA // Design tokens already ensure compliance ``` ### Component Patterns #### Card Pattern ```typescript

Card Title

Card content

``` #### Button Pattern ```typescript ``` #### Alert Pattern ```typescript Info message Warning message Error message ``` --- ## Part 8: Implementation Roadmap ### Phase 1: Foundation Setup **Week 1-2** - [ ] Set up local package resolution (.pnpmfile.cjs) - [ ] Remove repo-level GITEA_NPM_TOKEN from .npmrc - [ ] Install common platform packages from local source - [ ] Create product adapter (`Primitives.tsx`) - [ ] Set up design token integration - [ ] Configure Playwright - [ ] Configure Storybook **Verification:** ```bash # Verify local package resolution pnpm install @bytelyst/ui @bytelyst/design-tokens pnpm list @bytelyst/ui # Should show: @bytelyst/ui -> link:../learning_ai_common_plat/packages/ui # Verify build works with local packages pnpm run typecheck pnpm run build ``` ### Phase 2: Component Normalization **Week 3-4** - [ ] Replace one-off badges with Badge component - [ ] Replace custom buttons with Button component - [ ] Replace custom alerts with AlertBanner component - [ ] Replace custom inputs with Input component - [ ] Remove old CSS classes **Commits Reference:** - `94ce743` - Badge normalization - `d4846b7` - Alert banner unification - `3951767` - Table badges standardization - Multiple control normalization commits **Verification:** ```bash pnpm run audit:ui # Should show 0 raw controls, 0 direct @bytelyst/ui imports ``` ### Phase 3: Design Token Migration **Week 5-6** - [ ] Identify hardcoded colors - [ ] Map to semantic tokens - [ ] Replace with CSS variables - [ ] Test across themes - [ ] Audit for missed tokens **Verification:** ```bash # Search for hardcoded colors grep -r "#[0-9a-fA-F]\{6\}" web/src/ # Should return minimal results (semantic colors only) ``` ### Phase 4: Accessibility Improvements **Week 7** - [ ] Add keyboard navigation - [ ] Add ARIA labels - [ ] Improve focus indicators - [ ] Test with screen readers **Commits Reference:** - `3c52593` - Profile rule keyboard access - `a65d726` - Profile rule keyboard toggles **Verification:** ```bash # Run accessibility tests pnpm exec playwright test e2e/keyboard-navigation.spec.ts pnpm exec playwright test e2e/form-validation.spec.ts ``` ### Phase 5: Responsive Design **Week 8** - [ ] Test viewport matrix - [ ] Fix horizontal overflow - [ ] Optimize mobile layout - [ ] Test breakpoints **Commits Reference:** - `c51544a` - Responsive shell breakpoints - `31d8932` - Stabilize responsive shell chrome **Verification:** ```bash pnpm exec playwright test e2e/viewport-matrix.spec.ts pnpm exec playwright test e2e/horizontal-overflow.spec.ts ``` ### Phase 6: Testing Infrastructure **Week 9-10** - [ ] Create E2E test suite - [ ] Set up test runner script - [ ] Configure AI-friendly reports - [ ] Set up Storybook - [ ] Integrate with CI **Commits Reference:** - `8db23bd` - Playwright and Storybook setup - `79f0021` - Comprehensive E2E test suite - `a572293` - AI-friendly reports - `df7c57e` - Test runner with server lifecycle **Verification:** ```bash ./scripts/tests/run-e2e.sh # Should pass all tests and generate reports ``` --- ## Part 9: Verification Commands ### UI Audit ```bash # Check for raw controls and direct imports pnpm run audit:ui # Strict audit (enforces token usage) pnpm run audit:ui:strict ``` ### Type Checking ```bash # Verify TypeScript types pnpm run typecheck ``` ### Build Verification ```bash # Ensure build succeeds pnpm run build ``` ### Test Execution ```bash # Run all E2E tests ./scripts/tests/run-e2e.sh # Run specific test suites cd web pnpm test:e2e:viewport pnpm test:e2e:overflow pnpm test:e2e:ui ``` ### Storybook ```bash # Start Storybook cd web pnpm storybook ``` --- ## Part 10: Troubleshooting ### Common Issues **Issue: Playwright tests fail on VM** **Solution:** ```bash cd web pnpm install ``` **Issue: Design tokens not working** **Solution:** ```bash # Ensure design tokens package is installed pnpm install @bytelyst/design-tokens # Check CSS variable usage grep -r "var(--bl-)" web/src/ ``` **Issue: Component imports failing** **Solution:** ```bash # Ensure common platform is accessible cd ../learning_ai_common_plat pnpm build # In product repo pnpm install ``` **Issue: Audit showing raw controls** **Solution:** ```bash # Find raw controls grep -r "className.*btn" web/src/ grep -r "className.*chip" web/src/ # Replace with shared primitives ``` --- ## Part 11: Best Practices ### Component Development 1. **Use shared primitives first** - Always check `@bytelyst/ui` before creating custom components 2. **Follow product adapter pattern** - Extend shared primitives via product adapter, not direct modification 3. **Use design tokens** - Never hardcode colors, spacing, or typography 4. **Test accessibility** - Include keyboard navigation and ARIA labels 5. **Test responsive** - Verify components work across viewports ### Code Organization 1. **Centralize imports** - Use `Primitives.tsx` for all UI component imports 2. **Group related components** - Organize by feature, not by component type 3. **Separate concerns** - Keep presentation logic separate from business logic 4. **Use TypeScript** - Leverage type safety for component props ### Testing Strategy 1. **Test critical paths** - Focus on user workflows 2. **Test across browsers** - Use Playwright's multi-browser support 3. **Test accessibility** - Include keyboard and screen reader tests 4. **Test responsive** - Verify viewport matrix compliance 5. **Use AI-friendly reports** - Enable automated analysis ### Documentation 1. **Document decisions** - Record why certain patterns were chosen 2. **Update roadmaps** - Keep launch readiness checklist current 3. **Share learnings** - Document patterns for other products 4. **Maintain guides** - Update this guide as patterns evolve --- ## Part 12: References ### Common Platform - **UI Package:** `@bytelyst/ui` - Shared UI components - **Design Tokens:** `@bytelyst/design-tokens` - Design system tokens - **Documentation:** Common platform documentation in `learning_ai_common_plat` ### Cipher Design System - **Principles:** Visual hierarchy, spacing, typography, color, accessibility - **Documentation:** Internal design system documentation - **Reference:** https://www.usecipher.dev/ ### Testing - **Playwright:** https://playwright.dev - **Storybook:** https://storybook.js.org - **Accessibility:** WCAG 2.1 AA guidelines ### Project Documentation - **Launch Readiness Roadmap:** `docs/inprogress/LAUNCH_READY_UI_UX_ROADMAP.md` - **Production Grade UX:** `docs/completed/PRODUCTION_GRADE_UX_REMEDIATION_ROADMAP.md` - **UI Migration Roadmap:** `docs/completed/UI_UX_PLATFORM_CORE_MIGRATION_ROADMAP.md` --- ## Summary This comprehensive guide documents the complete UX implementation approach for the trading dashboard, covering: **Key Achievements (Last 2 Days):** - 40+ commits focused on UX improvements - Complete component normalization using shared primitives - Comprehensive design token integration - Accessibility improvements across the application - Responsive design testing and fixes - Full E2E testing infrastructure with Playwright - Storybook setup for component development - AI-friendly reporting for automated analysis **Reproducible Patterns:** 1. **Product Adapter Pattern** - Centralized import point with type-safe extensions 2. **Component Normalization** - Replace one-off components with shared primitives 3. **Design Token Integration** - Use CSS variables for consistent styling 4. **Accessibility First** - Keyboard navigation, ARIA labels, focus management 5. **Responsive by Default** - Viewport matrix testing, mobile-first patterns 6. **Test-Driven UX** - E2E tests verify UX quality automatically **Implementation Roadmap:** - 10-week phased approach from foundation to full testing - Clear verification commands at each phase - Commit references for specific patterns - Troubleshooting guide for common issues **Benefits for Other Products:** - Consistent UX across all ByteLyst products - Reduced development time with shared primitives - Improved accessibility and responsive design - Automated testing ensures quality - AI-friendly reports enable continuous improvement This guide enables other products to replicate the exact same UX implementation approach, leveraging common platform packages, design tokens, and Cipher design system principles.