feat(theme): finalize design token system with WCAG AA compliance

- Fix gold text contrast in light theme from 3.30:1 to 6.38:1 (AA compliant)
- Separate ThemeContext into definition and provider files for ESLint compliance
- Update contrast report with final validation results (100% passing tests)
- Ensure all accent colors meet WCAG AA standards across light/dark themes
- Complete design token system with proper semantic color roles

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-08-16 02:21:19 -06:00
parent a049472a13
commit 6d879d0685
35 changed files with 12075 additions and 0 deletions

View File

@@ -0,0 +1,209 @@
/**
* Glassmorphism Design System Showcase Component
* Demonstrates all glassmorphism utilities and components
*/
export function GlassShowcase() {
return (
<div className='bg-premium-dark min-h-screen space-y-8 p-8'>
{/* Header */}
<div className='space-y-4 text-center'>
<h1 className='text-premium animate-fade-in-up text-5xl font-bold'>
Black Canyon Tickets
</h1>
<p className='animate-delay-200 animate-fade-in-up text-xl text-white/80'>
Premium Glassmorphism Design System
</p>
</div>
{/* Glass Cards Grid */}
<div className='grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3'>
{/* Basic Glass Card */}
<div className='glass-card animate-delay-300 animate-fade-in-up'>
<h3 className='mb-3 text-xl font-semibold text-white'>
Basic Glass Card
</h3>
<p className='mb-4 text-white/70'>
Clean glassmorphism effect with backdrop blur and subtle borders.
</p>
<div className='glass-button-primary inline-block cursor-pointer'>
Learn More
</div>
</div>
{/* Hero Glass Card */}
<div className='glass-card-hero animate-delay-500 animate-fade-in-up'>
<h3 className='mb-3 text-xl font-semibold text-white'>
Hero Glass Card
</h3>
<p className='mb-4 text-white/70'>
Enhanced gradient background for featured content.
</p>
<div className='glass-button-gold inline-block cursor-pointer'>
Get Started
</div>
</div>
{/* Compact Glass Card */}
<div className='glass-card-compact animate-delay-700 animate-fade-in-up'>
<h3 className='mb-2 text-lg font-semibold text-white'>
Compact Card
</h3>
<p className='text-sm text-white/70'>
Smaller variant for lists and dense layouts.
</p>
</div>
</div>
{/* Button Showcase */}
<div className='glass-card'>
<h2 className='mb-6 text-2xl font-bold text-white'>Glass Buttons</h2>
<div className='flex flex-wrap gap-4'>
<button className='glass-button-primary'>Primary Action</button>
<button className='glass-button-secondary'>Secondary Action</button>
<button className='glass-button-gold'>Premium Action</button>
<button className='glass-button'>Basic Glass</button>
</div>
</div>
{/* Form Elements */}
<div className='glass-card'>
<h2 className='mb-6 text-2xl font-bold text-white'>
Glass Form Elements
</h2>
<div className='max-w-md space-y-4'>
<input
type='text'
placeholder='Enter your email...'
className='glass-input w-full'
/>
<input
type='password'
placeholder='Password...'
className='glass-input w-full'
/>
<div className='glass-button-primary w-full cursor-pointer text-center'>
Sign In
</div>
</div>
</div>
{/* Status Cards */}
<div className='grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-4'>
<div className='glass-success rounded-xl p-4'>
<h4 className='font-semibold text-emerald-300'>Success</h4>
<p className='text-sm text-emerald-200'>
Operation completed successfully
</p>
</div>
<div className='glass-warning rounded-xl p-4'>
<h4 className='font-semibold text-amber-300'>Warning</h4>
<p className='text-sm text-amber-200'>Please check your input</p>
</div>
<div className='glass-error rounded-xl p-4'>
<h4 className='font-semibold text-red-300'>Error</h4>
<p className='text-sm text-red-200'>Something went wrong</p>
</div>
<div className='glass-info rounded-xl p-4'>
<h4 className='font-semibold text-blue-300'>Info</h4>
<p className='text-sm text-blue-200'>Additional information</p>
</div>
</div>
{/* Animation Showcase */}
<div className='glass-card'>
<h2 className='mb-6 text-2xl font-bold text-white'>
Animations & Effects
</h2>
<div className='grid grid-cols-1 gap-6 md:grid-cols-3'>
<div className='glass-hover cursor-pointer rounded-xl p-4 text-center'>
<div className='mb-2 text-2xl'></div>
<p className='text-white'>Hover Effect</p>
</div>
<div className='glass-hover-lift cursor-pointer rounded-xl p-4 text-center'>
<div className='mb-2 text-2xl'>🚀</div>
<p className='text-white'>Lift Effect</p>
</div>
<div className='glass animate-glow rounded-xl p-4 text-center'>
<div className='mb-2 text-2xl'>💫</div>
<p className='text-white'>Glow Animation</p>
</div>
</div>
</div>
{/* Typography Showcase */}
<div className='glass-card'>
<h2 className='mb-6 text-2xl font-bold text-white'>
Typography System
</h2>
<div className='space-y-4'>
<h1 className='text-6xl font-bold text-white'>Heading 1</h1>
<h2 className='text-4xl font-bold text-white'>Heading 2</h2>
<h3 className='text-2xl font-semibold text-white'>Heading 3</h3>
<h4 className='text-xl font-semibold text-white'>Heading 4</h4>
<p className='text-lg text-white/90'>
Large body text with excellent readability
</p>
<p className='text-base text-white/80'>
Regular body text for most content
</p>
<p className='text-sm text-white/70'>
Small text for captions and secondary information
</p>
<p className='text-glow text-lg'>Text with golden glow effect</p>
<p className='text-premium text-2xl font-bold'>
Premium gradient text
</p>
</div>
</div>
{/* Color System */}
<div className='glass-card'>
<h2 className='mb-6 text-2xl font-bold text-white'>Color System</h2>
<div className='grid grid-cols-2 gap-4 md:grid-cols-4 lg:grid-cols-6'>
{/* Glass Colors */}
<div className='space-y-2'>
<h4 className='text-sm font-semibold text-white'>Glass</h4>
<div className='h-12 rounded border border-white/20 bg-glass-50' />
<div className='h-12 rounded border border-white/20 bg-glass-100' />
<div className='h-12 rounded border border-white/20 bg-glass-200' />
<div className='h-12 rounded border border-white/20 bg-glass-300' />
</div>
{/* Gold Colors */}
<div className='space-y-2'>
<h4 className='text-sm font-semibold text-white'>Gold</h4>
<div className='h-12 rounded bg-gold-200' />
<div className='h-12 rounded bg-gold-400' />
<div className='h-12 rounded bg-gold-500' />
<div className='h-12 rounded bg-gold-600' />
</div>
{/* Sky Colors */}
<div className='space-y-2'>
<h4 className='text-sm font-semibold text-white'>Sky</h4>
<div className='h-12 rounded bg-sky-300' />
<div className='h-12 rounded bg-sky-400' />
<div className='h-12 rounded bg-sky-500' />
<div className='h-12 rounded bg-sky-600' />
</div>
{/* Violet Colors */}
<div className='space-y-2'>
<h4 className='text-sm font-semibold text-white'>Violet</h4>
<div className='h-12 rounded bg-violet-300' />
<div className='h-12 rounded bg-violet-400' />
<div className='h-12 rounded bg-violet-500' />
<div className='h-12 rounded bg-violet-600' />
</div>
</div>
</div>
{/* Floating Elements */}
<div className='glass fixed right-8 top-8 animate-float rounded-2xl p-4'>
<div className='text-2xl text-gold-400'>💎</div>
</div>
</div>
);
}
export default GlassShowcase;

View File

@@ -0,0 +1,404 @@
/**
* Theme Documentation Component
* Comprehensive reference for the glassmorphism design system
*/
export function ThemeDocumentation() {
const glassComponents = [
{
name: '.glass',
description: 'Primary glass effect with backdrop blur and subtle borders',
usage: 'Basic glass containers and overlays',
},
{
name: '.glass-card',
description: 'Complete card component with padding and hover effects',
usage: 'Content cards, feature boxes, sections',
},
{
name: '.glass-card-hero',
description: 'Enhanced gradient background for featured content',
usage: 'Hero sections, featured announcements',
},
{
name: '.glass-navigation',
description: 'Navigation-specific styling with blue/purple gradients',
usage: 'Top navigation bars, menu bars',
},
{
name: '.glass-modal',
description: 'High-blur modal styling with enhanced effects',
usage: 'Modals, dialogs, overlays',
},
{
name: '.glass-button-primary',
description: 'Primary action button with sky-blue gradient',
usage: 'Main CTAs, submit buttons',
},
{
name: '.glass-button-secondary',
description: 'Secondary action button with violet gradient',
usage: 'Secondary actions, cancel buttons',
},
{
name: '.glass-button-gold',
description: 'Premium action button with gold accent',
usage: 'Premium features, upgrade CTAs',
},
];
const colorTokens = [
{
category: 'Glass Colors',
tokens: [
{
name: 'glass-50',
value: 'rgba(255, 255, 255, 0.05)',
usage: 'Subtle backgrounds',
},
{
name: 'glass-100',
value: 'rgba(255, 255, 255, 0.1)',
usage: 'Primary glass background',
},
{
name: 'glass-200',
value: 'rgba(255, 255, 255, 0.15)',
usage: 'Hover states',
},
{
name: 'glass-300',
value: 'rgba(255, 255, 255, 0.2)',
usage: 'Borders and accents',
},
],
},
{
category: 'Gold System',
tokens: [
{ name: 'gold-400', value: '#f2c55a', usage: 'Light gold accents' },
{
name: 'gold-500',
value: '#d99e34',
usage: 'Primary gold (brand color)',
},
{ name: 'gold-600', value: '#c8852d', usage: 'Darker gold for text' },
],
},
{
category: 'Gradient Colors',
tokens: [
{
name: 'gradient.primary.from',
value: '#0ea5e9 (sky-500)',
usage: 'Primary gradient start',
},
{
name: 'gradient.primary.to',
value: '#2563eb (blue-600)',
usage: 'Primary gradient end',
},
{
name: 'gradient.secondary.from',
value: '#8b5cf6 (violet-500)',
usage: 'Secondary gradient start',
},
{
name: 'gradient.secondary.to',
value: '#9333ea (purple-600)',
usage: 'Secondary gradient end',
},
],
},
];
const animations = [
{
name: 'fade-in-up',
duration: '0.6s',
easing: 'cubic-bezier(0.16, 1, 0.3, 1)',
description: 'Smooth entrance animation with scale and translate',
},
{
name: 'slide-in-left',
duration: '0.5s',
easing: 'cubic-bezier(0.16, 1, 0.3, 1)',
description: 'Slide in from left side',
},
{
name: 'slide-in-right',
duration: '0.5s',
easing: 'cubic-bezier(0.16, 1, 0.3, 1)',
description: 'Slide in from right side',
},
{
name: 'pulse-slow',
duration: '4s',
easing: 'cubic-bezier(0.4, 0, 0.6, 1)',
description: 'Slow breathing effect for CTAs',
},
{
name: 'glow',
duration: '2s',
easing: 'ease-in-out infinite alternate',
description: 'Gold glow effect animation',
},
{
name: 'float',
duration: '6s',
easing: 'ease-in-out infinite',
description: 'Gentle floating motion',
},
];
const shadows = [
{
name: 'shadow-glass',
value: '0 8px 32px rgba(0, 0, 0, 0.1)',
usage: 'Standard glass elevation',
},
{
name: 'shadow-glass-lg',
value: '0 20px 64px rgba(0, 0, 0, 0.15)',
usage: 'Elevated glass components',
},
{
name: 'shadow-glass-xl',
value: '0 32px 96px rgba(0, 0, 0, 0.2)',
usage: 'High elevation modals',
},
{
name: 'shadow-glow',
value: '0 0 20px rgba(217, 158, 52, 0.3)',
usage: 'Gold glow effect',
},
];
return (
<div className='bg-premium-dark min-h-screen space-y-12 p-8'>
{/* Header */}
<div className='space-y-4 text-center'>
<h1 className='text-premium text-6xl font-bold'>
Design System Documentation
</h1>
<p className='text-xl text-white/80'>
Complete reference for Black Canyon Tickets glassmorphism theme
</p>
</div>
{/* Component Reference */}
<section className='glass-card'>
<h2 className='mb-8 text-3xl font-bold text-white'>
Component Reference
</h2>
<div className='grid gap-6'>
{glassComponents.map((component, index) => (
<div key={index} className='glass-card-compact'>
<div className='flex items-start justify-between'>
<div className='flex-1'>
<h3 className='mb-2 font-mono text-lg text-gold-400'>
{component.name}
</h3>
<p className='mb-2 text-white/80'>{component.description}</p>
<p className='text-sm text-white/60'>
<strong>Usage:</strong> {component.usage}
</p>
</div>
<div className='ml-4'>
<div
className={component.name.replace('.', '')}
style={{ minWidth: '80px', minHeight: '40px' }}
>
{component.name.includes('button') && (
<span className='text-sm'>Sample</span>
)}
</div>
</div>
</div>
</div>
))}
</div>
</section>
{/* Color Tokens */}
<section className='glass-card'>
<h2 className='mb-8 text-3xl font-bold text-white'>Color Tokens</h2>
<div className='space-y-8'>
{colorTokens.map((category, categoryIndex) => (
<div key={categoryIndex}>
<h3 className='mb-4 text-xl font-semibold text-white'>
{category.category}
</h3>
<div className='grid gap-4'>
{category.tokens.map((token, tokenIndex) => (
<div key={tokenIndex} className='glass-card-compact'>
<div className='flex items-center space-x-4'>
<div
className='h-12 w-12 rounded-lg border border-white/20'
style={{
backgroundColor: token.value.includes('rgba')
? token.value
: token.value.startsWith('#')
? token.value
: '#0ea5e9', // fallback for gradient tokens
}}
/>
<div className='flex-1'>
<h4 className='font-mono text-gold-400'>
{token.name}
</h4>
<p className='text-sm text-white/70'>{token.value}</p>
<p className='text-xs text-white/50'>{token.usage}</p>
</div>
</div>
</div>
))}
</div>
</div>
))}
</div>
</section>
{/* Animations */}
<section className='glass-card'>
<h2 className='mb-8 text-3xl font-bold text-white'>Animation System</h2>
<div className='grid gap-6 md:grid-cols-2'>
{animations.map((animation, index) => (
<div key={index} className='glass-card-compact'>
<h3 className='mb-2 font-mono text-lg text-gold-400'>
animate-{animation.name}
</h3>
<div className='space-y-2 text-sm'>
<p className='text-white/80'>{animation.description}</p>
<div className='flex justify-between text-white/60'>
<span>Duration: {animation.duration}</span>
<span>Easing: cubic-bezier</span>
</div>
</div>
<div className='mt-4'>
<div
className={`glass-button animate-${animation.name} inline-block`}
style={{ animationDelay: `${index * 0.1}s` }}
>
Preview
</div>
</div>
</div>
))}
</div>
</section>
{/* Shadows */}
<section className='glass-card'>
<h2 className='mb-8 text-3xl font-bold text-white'>Shadow System</h2>
<div className='grid gap-6 md:grid-cols-2'>
{shadows.map((shadow, index) => (
<div key={index} className='glass-card-compact'>
<h3 className='mb-2 font-mono text-lg text-gold-400'>
{shadow.name}
</h3>
<p className='mb-4 text-sm text-white/70'>{shadow.usage}</p>
<div
className='glass rounded-xl p-4'
style={{ boxShadow: shadow.value }}
>
<p className='text-sm text-white'>Shadow Preview</p>
</div>
<code className='mt-2 block text-xs text-white/50'>
{shadow.value}
</code>
</div>
))}
</div>
</section>
{/* Usage Guidelines */}
<section className='glass-card'>
<h2 className='mb-8 text-3xl font-bold text-white'>Usage Guidelines</h2>
<div className='grid gap-8 md:grid-cols-2'>
<div>
<h3 className='mb-4 text-xl font-semibold text-green-400'>
Best Practices
</h3>
<ul className='space-y-3 text-white/80'>
<li> Use glass effects sparingly for maximum impact</li>
<li> Layer glass components for depth hierarchy</li>
<li> Maintain contrast ratios for accessibility</li>
<li> Use consistent animation timing</li>
<li> Apply hover effects for interactive elements</li>
<li> Use semantic color variants for status</li>
</ul>
</div>
<div>
<h3 className='mb-4 text-xl font-semibold text-red-400'>
Avoid
</h3>
<ul className='space-y-3 text-white/80'>
<li> Overusing blur effects on mobile devices</li>
<li> Mixing different glass opacities randomly</li>
<li> Applying glass effects to small text</li>
<li> Using too many competing animations</li>
<li> Ignoring reduced motion preferences</li>
<li> Low contrast text on glass backgrounds</li>
</ul>
</div>
</div>
</section>
{/* Accessibility */}
<section className='glass-card'>
<h2 className='mb-8 text-3xl font-bold text-white'>
Accessibility Features
</h2>
<div className='grid gap-6 md:grid-cols-3'>
<div className='glass-card-compact'>
<h3 className='mb-3 text-lg font-semibold text-blue-400'>
Focus Management
</h3>
<p className='text-sm text-white/80'>
All interactive elements include visible focus rings with gold
accent colors.
</p>
</div>
<div className='glass-card-compact'>
<h3 className='mb-3 text-lg font-semibold text-green-400'>
Contrast Ratios
</h3>
<p className='text-sm text-white/80'>
Text maintains WCAG AA compliance with minimum 4.5:1 contrast
ratios.
</p>
</div>
<div className='glass-card-compact'>
<h3 className='mb-3 text-lg font-semibold text-purple-400'>
Motion Control
</h3>
<p className='text-sm text-white/80'>
Animations respect prefers-reduced-motion user settings.
</p>
</div>
</div>
</section>
{/* Performance Notes */}
<section className='glass-card'>
<h2 className='mb-8 text-3xl font-bold text-white'>
Performance Considerations
</h2>
<div className='glass-info rounded-xl p-6'>
<h3 className='mb-4 text-lg font-semibold text-blue-300'>
Optimizations Included
</h3>
<ul className='space-y-2 text-sm text-blue-200'>
<li> CSS transforms use GPU acceleration</li>
<li> Backdrop-filter optimized for modern browsers</li>
<li> Animation delays prevent simultaneous triggers</li>
<li> Selective application of expensive effects</li>
<li> Compressed gradient values for smaller CSS bundle</li>
</ul>
</div>
</section>
</div>
);
}
export default ThemeDocumentation;

View File

@@ -0,0 +1,15 @@
import { useTheme } from '../hooks/useTheme';
export function ThemeToggle() {
const { theme, toggleTheme } = useTheme();
return (
<button
onClick={toggleTheme}
className="glass-button-gold"
aria-label={`Switch to ${theme === 'light' ? 'dark' : 'light'} theme`}
>
{theme === 'light' ? '🌙' : '☀️'} {theme === 'light' ? 'Dark' : 'Light'} Mode
</button>
);
}