|
Build And Push Image / docker (push) Failing after 1m11s
Details
- Added VueUse Motion for animations with custom presets - Created base UI component library with glass morphism effects: * GlassCard - Flexible card component with 4 variants * MonacoButton - Multi-variant button system * FloatingInput - Modern input with floating labels * StatsCard - Dashboard statistics display * AnimatedNumber - Smooth number animations * Icon system - Modular icon components - Created comprehensive page mockups: * Dashboard mockup with stats, activity feed, and widgets * Events page with filtering, search, and calendar - Established Monaco brand design system (red #dc2626) - Configured spring animations and glass effects 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| components/dropdowns | ||
| mockups | ||
| README.md | ||
| design-system.md | ||
README.md
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
- Design Philosophy
- Technical Stack
- Migration Strategy
- Component Architecture
- Implementation Roadmap
- Performance Guidelines
- 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)
- Set up new style architecture
- Create base component library
- Implement color system and typography
- Set up animation utilities
Phase 2: Core Components (Week 3-4)
- Replace navigation components
- Implement custom dropdowns and selects
- Create button variants
- Build card components
Phase 3: Page Templates (Week 5-6)
- Dashboard layouts
- Data tables with glass effects
- Form components
- Modal and dialog systems
Phase 4: Polish & Optimization (Week 7-8)
- Performance tuning
- Accessibility audit
- Cross-browser testing
- 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.,
GlassDropdownMenunotDropdown)
Props & Events
<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
<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
// 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
<!-- 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
<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
// 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
// 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
// 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
<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
// 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
// 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
Design Inspiration
Tools
Support
For questions or assistance with implementation:
- Technical Lead: [Contact Info]
- Design Team: [Contact Info]
- Documentation: This guide and
/Designfolder
Last Updated: December 2024 Version: 1.0.0