monacousa-portal/Design/README.md

480 lines
12 KiB
Markdown
Raw Normal View History

# MonacoUSA Portal Design System Implementation Guide
## 🎨 Overview
This comprehensive guide outlines the complete visual redesign of the MonacoUSA Portal, transitioning from a standard Vuetify implementation to a premium, custom design system featuring Monaco's signature red and white color scheme with modern glass morphism effects.
## 📋 Table of Contents
1. [Design Philosophy](#design-philosophy)
2. [Technical Stack](#technical-stack)
3. [Migration Strategy](#migration-strategy)
4. [Component Architecture](#component-architecture)
5. [Implementation Roadmap](#implementation-roadmap)
6. [Performance Guidelines](#performance-guidelines)
7. [Accessibility Standards](#accessibility-standards)
## Design Philosophy
### Core Principles
- **Premium Feel**: Every interaction should feel smooth and sophisticated
- **Brand Identity**: Monaco's red (#dc2626) as the primary accent color
- **Modern Aesthetics**: Glass morphism, subtle animations, and floating elements
- **User Experience**: Intuitive navigation with clear visual hierarchy
- **Performance**: Animations that enhance, not hinder, user experience
### Visual Language
- **Glass Morphism**: Semi-transparent surfaces with backdrop blur
- **Gradient Accents**: Dynamic gradients from Monaco red to deeper shades
- **Floating Elements**: Subtle shadows and depth for interactive components
- **Micro-animations**: Smooth transitions on hover, click, and state changes
- **Consistent Spacing**: 8px grid system for alignment and padding
## Technical Stack
### Current Setup
- **Framework**: Nuxt 3.8.2
- **UI Library**: Vuetify 3.4.7 (to be replaced)
- **Icons**: Material Design Icons (transitioning to Lucide)
- **Authentication**: Keycloak integration
- **Styling**: SCSS with scoped components
### New Additions
- **Animation Libraries**:
- VueUse Motion (preferred for Vue integration)
- GSAP (for complex animations)
- Anime.js (lightweight alternative)
- **Icons**: Lucide Icons (modern, customizable)
- **Utilities**: Tailwind CSS (for rapid prototyping)
- **State Management**: Pinia (already implemented)
## Migration Strategy
### Phase 1: Foundation (Week 1-2)
1. Set up new style architecture
2. Create base component library
3. Implement color system and typography
4. Set up animation utilities
### Phase 2: Core Components (Week 3-4)
1. Replace navigation components
2. Implement custom dropdowns and selects
3. Create button variants
4. Build card components
### Phase 3: Page Templates (Week 5-6)
1. Dashboard layouts
2. Data tables with glass effects
3. Form components
4. Modal and dialog systems
### Phase 4: Polish & Optimization (Week 7-8)
1. Performance tuning
2. Accessibility audit
3. Cross-browser testing
4. Documentation completion
## Component Architecture
### File Structure
```
components/
├── ui/ # Base UI components
│ ├── MonacoButton.vue
│ ├── GlassCard.vue
│ ├── AnimatedDropdown.vue
│ └── FloatingInput.vue
├── layout/ # Layout components
│ ├── DashboardSidebar.vue
│ ├── AppHeader.vue
│ └── PageContainer.vue
├── features/ # Feature-specific components
│ ├── MemberCard.vue
│ ├── EventCalendar.vue
│ └── DuesTracker.vue
└── shared/ # Shared utilities
├── LoadingSpinner.vue
├── ErrorBoundary.vue
└── TransitionWrapper.vue
```
### Component Guidelines
#### Naming Convention
- PascalCase for component files
- Prefix with "Monaco" for custom branded components
- Use descriptive names (e.g., `GlassDropdownMenu` not `Dropdown`)
#### Props & Events
```vue
<script setup lang="ts">
interface Props {
variant?: 'primary' | 'glass' | 'gradient'
size?: 'sm' | 'md' | 'lg'
animated?: boolean
}
const props = withDefaults(defineProps<Props>(), {
variant: 'primary',
size: 'md',
animated: true
})
const emit = defineEmits<{
click: [event: MouseEvent]
hover: [state: boolean]
}>()
</script>
```
#### Composition API Pattern
```vue
<script setup lang="ts">
import { useMonacoTheme } from '~/composables/useMonacoTheme'
import { useGlassEffect } from '~/composables/useGlassEffect'
const { primaryColor, gradients } = useMonacoTheme()
const { glassStyle, blurAmount } = useGlassEffect()
</script>
```
## Implementation Roadmap
### Week 1: Setup & Foundation
- [ ] Configure animation libraries
- [ ] Set up SCSS architecture
- [ ] Create color system utilities
- [ ] Implement base glass morphism styles
- [ ] Set up Lucide icons integration
### Week 2: Core Components
- [ ] Custom dropdown components
- [ ] Button system with variants
- [ ] Card components with glass effects
- [ ] Form inputs with floating labels
- [ ] Navigation components
### Week 3: Dashboard Implementation
- [ ] Member dashboard layout
- [ ] Board dashboard enhancements
- [ ] Admin panel structure
- [ ] Widget components
- [ ] Chart integrations
### Week 4: Advanced Features
- [ ] Event calendar with animations
- [ ] Member management interface
- [ ] Dues payment flow
- [ ] Profile components
- [ ] Settings panels
### Week 5: Responsive Design
- [ ] Mobile navigation
- [ ] Tablet optimizations
- [ ] Touch interactions
- [ ] Gesture support
- [ ] PWA enhancements
### Week 6: Testing & Optimization
- [ ] Performance profiling
- [ ] Bundle optimization
- [ ] Lazy loading implementation
- [ ] Animation performance tuning
- [ ] Memory leak detection
## Performance Guidelines
### Animation Performance
```scss
// Use transform and opacity for animations
.animated-element {
will-change: transform, opacity;
transform: translateZ(0); // Enable hardware acceleration
}
// Avoid animating expensive properties
// BAD: width, height, padding, margin
// GOOD: transform, opacity, filter
```
### Component Optimization
```vue
<!-- Use v-show for frequently toggled elements -->
<div v-show="isVisible" class="glass-panel">
<!-- Content -->
</div>
<!-- Use v-if for conditionally rendered heavy components -->
<HeavyComponent v-if="shouldRender" />
<!-- Implement lazy loading for routes -->
<script setup>
const MemberDashboard = defineAsyncComponent(() =>
import('~/components/dashboards/MemberDashboard.vue')
)
</script>
```
### Bundle Size Management
- Tree-shake unused Vuetify components
- Lazy load animation libraries
- Use dynamic imports for heavy features
- Implement code splitting by route
- Optimize images with next-gen formats
## Accessibility Standards
### WCAG 2.1 Compliance
- **Color Contrast**: Ensure 4.5:1 ratio for normal text
- **Focus Indicators**: Clear visual focus states
- **Keyboard Navigation**: Full keyboard support
- **Screen Readers**: Proper ARIA labels
- **Motion Sensitivity**: Respect prefers-reduced-motion
### Implementation Examples
```vue
<template>
<button
:aria-label="ariaLabel"
:aria-pressed="isPressed"
@click="handleClick"
@keydown.enter="handleClick"
@keydown.space.prevent="handleClick"
class="monaco-button"
:class="{ 'reduced-motion': prefersReducedMotion }"
>
<slot />
</button>
</template>
<script setup>
const prefersReducedMotion = useMediaQuery('(prefers-reduced-motion: reduce)')
</script>
<style scoped>
.monaco-button {
transition: all 0.3s ease;
}
.monaco-button.reduced-motion {
transition: none;
}
</style>
```
## Style Guidelines
### Color System
```scss
// Primary Colors
$monaco-red: #dc2626;
$monaco-red-dark: #b91c1c;
$monaco-red-light: #ef4444;
$monaco-white: #ffffff;
// Gradients
$monaco-gradient: linear-gradient(135deg, $monaco-red 0%, $monaco-red-dark 100%);
$monaco-gradient-reverse: linear-gradient(135deg, $monaco-red-light 0%, $monaco-red 100%);
// Glass Effects
$glass-bg: rgba(255, 255, 255, 0.7);
$glass-border: rgba(255, 255, 255, 0.3);
$glass-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
$glass-blur: 20px;
```
### Typography Scale
```scss
// Font Family
$font-primary: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
$font-mono: 'Fira Code', 'Monaco', monospace;
// Font Sizes
$text-xs: 0.75rem; // 12px
$text-sm: 0.875rem; // 14px
$text-base: 1rem; // 16px
$text-lg: 1.125rem; // 18px
$text-xl: 1.25rem; // 20px
$text-2xl: 1.5rem; // 24px
$text-3xl: 1.875rem; // 30px
$text-4xl: 2.25rem; // 36px
```
### Spacing System
```scss
// Based on 8px grid
$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
$space-12: 3rem; // 48px
$space-16: 4rem; // 64px
```
## Component Examples
### Glass Card Component
```vue
<template>
<div class="glass-card" :class="[sizeClass, variantClass]">
<div v-if="hasHeader" class="glass-card-header">
<slot name="header" />
</div>
<div class="glass-card-body">
<slot />
</div>
<div v-if="hasFooter" class="glass-card-footer">
<slot name="footer" />
</div>
</div>
</template>
<script setup lang="ts">
interface Props {
size?: 'sm' | 'md' | 'lg'
variant?: 'light' | 'dark' | 'colored'
}
const props = withDefaults(defineProps<Props>(), {
size: 'md',
variant: 'light'
})
const slots = useSlots()
const hasHeader = computed(() => !!slots.header)
const hasFooter = computed(() => !!slots.footer)
const sizeClass = computed(() => `glass-card--${props.size}`)
const variantClass = computed(() => `glass-card--${props.variant}`)
</script>
<style scoped lang="scss">
.glass-card {
background: rgba(255, 255, 255, 0.7);
backdrop-filter: blur(20px);
border-radius: 16px;
border: 1px solid rgba(255, 255, 255, 0.3);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
overflow: hidden;
transition: all 0.3s ease;
&:hover {
transform: translateY(-2px);
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
}
&--dark {
background: rgba(0, 0, 0, 0.7);
border-color: rgba(255, 255, 255, 0.1);
}
&--colored {
background: linear-gradient(135deg,
rgba(220, 38, 38, 0.1) 0%,
rgba(185, 28, 28, 0.1) 100%);
}
}
</style>
```
## Testing Strategy
### Unit Testing
```typescript
// components/__tests__/MonacoButton.spec.ts
import { mount } from '@vue/test-utils'
import MonacoButton from '~/components/ui/MonacoButton.vue'
describe('MonacoButton', () => {
it('renders with correct variant class', () => {
const wrapper = mount(MonacoButton, {
props: { variant: 'gradient' }
})
expect(wrapper.classes()).toContain('monaco-button--gradient')
})
it('emits click event', async () => {
const wrapper = mount(MonacoButton)
await wrapper.trigger('click')
expect(wrapper.emitted('click')).toHaveLength(1)
})
})
```
### E2E Testing
```typescript
// e2e/dashboard.spec.ts
import { test, expect } from '@playwright/test'
test('dashboard loads with glass morphism effects', async ({ page }) => {
await page.goto('/dashboard')
const glassCard = page.locator('.glass-card').first()
await expect(glassCard).toBeVisible()
const styles = await glassCard.evaluate(el =>
window.getComputedStyle(el)
)
expect(styles.backdropFilter).toContain('blur')
})
```
## Deployment Checklist
### Pre-deployment
- [ ] Run full test suite
- [ ] Check bundle size (<500KB initial)
- [ ] Validate accessibility scores
- [ ] Test on all target browsers
- [ ] Optimize images and assets
- [ ] Review security headers
### Performance Metrics
- First Contentful Paint: <1.5s
- Time to Interactive: <3s
- Cumulative Layout Shift: <0.1
- First Input Delay: <100ms
- Lighthouse Score: >90
### Browser Support
- Chrome 90+
- Firefox 88+
- Safari 14+
- Edge 90+
- Mobile Safari 14+
- Chrome Mobile 90+
## Resources
### Documentation
- [Vue 3 Composition API](https://vuejs.org/guide/extras/composition-api-faq.html)
- [Nuxt 3 Documentation](https://nuxt.com/docs)
- [VueUse Motion](https://motion.vueuse.org/)
- [GSAP Documentation](https://greensock.com/docs/)
- [Lucide Icons](https://lucide.dev/)
### Design Inspiration
- [Glass Morphism Examples](https://glassmorphism.com/)
- [Monaco Brand Guidelines](internal-link)
- [Material Design 3](https://m3.material.io/)
### Tools
- [Contrast Checker](https://webaim.org/resources/contrastchecker/)
- [Bundle Analyzer](https://github.com/nuxt/devtools)
- [Lighthouse CI](https://github.com/GoogleChrome/lighthouse-ci)
## Support
For questions or assistance with implementation:
- Technical Lead: [Contact Info]
- Design Team: [Contact Info]
- Documentation: This guide and `/Design` folder
---
*Last Updated: December 2024*
*Version: 1.0.0*