mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 14:11:09 -05:00
- Implemented park card component with image, status badge, favorite button, and quick stats overlay. - Developed ride card component featuring thrill level badge, status badge, favorite button, and detailed stats. - Created advanced search page with filters for parks and rides, including location, type, status, and thrill level. - Added dynamic quick search functionality with results display. - Enhanced user experience with JavaScript for filter toggling, range slider updates, and view switching. - Included custom CSS for improved styling of checkboxes and search results layout.
12 KiB
12 KiB
ThrillWiki Design System
Last Updated: 2025-01-15
Overview
A comprehensive design system for ThrillWiki that combines modern aesthetics with exceptional user experience. Built on Tailwind CSS, HTMX, and AlpineJS to create a cohesive, accessible, and performant interface.
Design Philosophy
Core Principles
- Thrill-Focused: Every design element should evoke excitement and adventure
- Data-Rich: Present complex theme park information in digestible, beautiful ways
- Progressive Enhancement: Works beautifully without JavaScript, enhanced with it
- Accessibility First: WCAG 2.1 AA compliance throughout
- Performance Obsessed: Sub-2s load times, smooth 60fps animations
Visual Identity
- Theme: Modern theme park adventure with premium feel
- Mood: Exciting, trustworthy, sophisticated, fun
- Target: Theme park enthusiasts, families, travel planners
Color System
Primary Palette
/* Thrill Colors - Excitement & Adventure */
--thrill-primary: #6366f1; /* Indigo 500 - Primary brand */
--thrill-primary-dark: #4f46e5; /* Indigo 600 - Hover states */
--thrill-primary-light: #818cf8; /* Indigo 400 - Light accents */
/* Adventure Colors - Energy & Fun */
--thrill-secondary: #f59e0b; /* Amber 500 - Secondary actions */
--thrill-secondary-dark: #d97706; /* Amber 600 - Hover states */
--thrill-secondary-light: #fbbf24; /* Amber 400 - Light accents */
/* Status Colors - Clear Communication */
--thrill-success: #10b981; /* Emerald 500 - Operating parks */
--thrill-warning: #f59e0b; /* Amber 500 - Construction */
--thrill-danger: #ef4444; /* Red 500 - Closed permanently */
--thrill-info: #3b82f6; /* Blue 500 - Information */
Neutral Palette
/* Light Mode */
--neutral-50: #f8fafc;
--neutral-100: #f1f5f9;
--neutral-200: #e2e8f0;
--neutral-300: #cbd5e1;
--neutral-400: #94a3b8;
--neutral-500: #64748b;
--neutral-600: #475569;
--neutral-700: #334155;
--neutral-800: #1e293b;
--neutral-900: #0f172a;
/* Dark Mode */
--dark-50: #0f172a;
--dark-100: #1e293b;
--dark-200: #334155;
--dark-300: #475569;
--dark-400: #64748b;
--dark-500: #94a3b8;
--dark-600: #cbd5e1;
--dark-700: #e2e8f0;
--dark-800: #f1f5f9;
--dark-900: #f8fafc;
Gradient System
/* Hero Gradients */
--gradient-hero: linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #ec4899 100%);
--gradient-hero-dark: linear-gradient(135deg, #4338ca 0%, #7c3aed 50%, #db2777 100%);
/* Background Gradients */
--gradient-bg-light: linear-gradient(135deg, #f8fafc 0%, #e0e7ff 50%, #ede9fe 100%);
--gradient-bg-dark: linear-gradient(135deg, #0f172a 0%, #1e1b4b 50%, #581c87 100%);
/* Card Gradients */
--gradient-card: linear-gradient(145deg, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0.05) 100%);
--gradient-card-hover: linear-gradient(145deg, rgba(255,255,255,0.15) 0%, rgba(255,255,255,0.08) 100%);
Typography
Font Stack
/* Primary Font - Poppins */
--font-primary: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
/* Weights */
--font-light: 300;
--font-regular: 400;
--font-medium: 500;
--font-semibold: 600;
--font-bold: 700;
--font-extrabold: 800;
Type Scale
/* Display - Hero sections */
--text-display-xl: 4.5rem; /* 72px */
--text-display-lg: 3.75rem; /* 60px */
--text-display-md: 3rem; /* 48px */
--text-display-sm: 2.25rem; /* 36px */
/* Headings */
--text-h1: 2rem; /* 32px */
--text-h2: 1.75rem; /* 28px */
--text-h3: 1.5rem; /* 24px */
--text-h4: 1.25rem; /* 20px */
--text-h5: 1.125rem; /* 18px */
--text-h6: 1rem; /* 16px */
/* Body */
--text-lg: 1.125rem; /* 18px */
--text-base: 1rem; /* 16px */
--text-sm: 0.875rem; /* 14px */
--text-xs: 0.75rem; /* 12px */
Spacing System
Base Scale (4px grid)
--space-0: 0;
--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 */
--space-20: 5rem; /* 80px */
--space-24: 6rem; /* 96px */
--space-32: 8rem; /* 128px */
Component Library
Buttons
Primary Button
.btn-primary {
@apply px-6 py-3 bg-gradient-to-r from-thrill-primary to-thrill-primary-dark;
@apply text-white font-semibold rounded-xl shadow-lg;
@apply hover:shadow-xl hover:scale-105 active:scale-95;
@apply transition-all duration-200 ease-out;
@apply focus:outline-none focus:ring-4 focus:ring-thrill-primary/30;
}
Secondary Button
.btn-secondary {
@apply px-6 py-3 bg-white dark:bg-neutral-800;
@apply text-thrill-primary dark:text-thrill-primary-light;
@apply font-semibold rounded-xl shadow-md border border-thrill-primary/20;
@apply hover:bg-thrill-primary/5 hover:shadow-lg hover:scale-105;
@apply active:scale-95 transition-all duration-200 ease-out;
@apply focus:outline-none focus:ring-4 focus:ring-thrill-primary/30;
}
Ghost Button
.btn-ghost {
@apply px-4 py-2 text-neutral-600 dark:text-neutral-400;
@apply font-medium rounded-lg hover:bg-neutral-100 dark:hover:bg-neutral-800;
@apply hover:text-neutral-900 dark:hover:text-neutral-100;
@apply transition-all duration-150 ease-out;
@apply focus:outline-none focus:ring-2 focus:ring-neutral-300 dark:focus:ring-neutral-600;
}
Cards
Base Card
.card {
@apply bg-white/80 dark:bg-neutral-800/80 backdrop-blur-lg;
@apply border border-neutral-200/50 dark:border-neutral-700/50;
@apply rounded-2xl shadow-lg hover:shadow-xl;
@apply transition-all duration-300 ease-out;
@apply hover:scale-[1.02] hover:-translate-y-1;
}
Feature Card
.card-feature {
@apply card p-8 relative overflow-hidden;
@apply before:absolute before:inset-0 before:bg-gradient-card;
@apply hover:before:bg-gradient-card-hover;
@apply before:transition-all before:duration-300;
}
Park Card
.card-park {
@apply card group cursor-pointer;
@apply hover:ring-2 hover:ring-thrill-primary/30;
}
.card-park-image {
@apply aspect-video w-full object-cover rounded-t-2xl;
@apply group-hover:scale-105 transition-transform duration-500 ease-out;
}
.card-park-content {
@apply p-6 space-y-4;
}
Forms
Input Fields
.form-input {
@apply w-full px-4 py-3 bg-white dark:bg-neutral-800;
@apply border border-neutral-300 dark:border-neutral-600;
@apply rounded-xl shadow-sm focus:shadow-md;
@apply text-neutral-900 dark:text-neutral-100;
@apply placeholder-neutral-500 dark:placeholder-neutral-400;
@apply focus:outline-none focus:ring-2 focus:ring-thrill-primary/50;
@apply focus:border-thrill-primary dark:focus:border-thrill-primary-light;
@apply transition-all duration-200 ease-out;
}
Labels
.form-label {
@apply block text-sm font-semibold text-neutral-700 dark:text-neutral-300;
@apply mb-2;
}
Error States
.form-error {
@apply text-sm text-thrill-danger mt-1;
}
.form-input-error {
@apply border-thrill-danger focus:ring-thrill-danger/50;
@apply focus:border-thrill-danger;
}
Status Badges
Operating
.badge-operating {
@apply inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold;
@apply bg-thrill-success/10 text-thrill-success;
@apply border border-thrill-success/20;
}
Construction
.badge-construction {
@apply inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold;
@apply bg-thrill-warning/10 text-thrill-warning;
@apply border border-thrill-warning/20;
}
Closed
.badge-closed {
@apply inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold;
@apply bg-thrill-danger/10 text-thrill-danger;
@apply border border-thrill-danger/20;
}
Animation System
Micro-Interactions
/* Hover Lift */
.hover-lift {
@apply transition-all duration-300 ease-out;
@apply hover:scale-105 hover:-translate-y-1 hover:shadow-xl;
}
/* Pulse Animation */
.pulse-glow {
@apply animate-pulse;
animation: pulse-glow 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
@keyframes pulse-glow {
0%, 100% { box-shadow: 0 0 0 0 rgba(99, 102, 241, 0.4); }
50% { box-shadow: 0 0 0 10px rgba(99, 102, 241, 0); }
}
/* Slide In Animations */
.slide-in-up {
animation: slideInUp 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
@keyframes slideInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
HTMX Transitions
/* View Transitions for HTMX */
.htmx-transition {
view-transition-name: main-content;
}
::view-transition-old(main-content) {
animation: 300ms cubic-bezier(0.4, 0, 1, 1) both fade-out,
600ms cubic-bezier(0.4, 0, 0.2, 1) both slide-to-left;
}
::view-transition-new(main-content) {
animation: 400ms cubic-bezier(0, 0, 0.2, 1) 100ms both fade-in,
600ms cubic-bezier(0.4, 0, 0.2, 1) both slide-from-right;
}
@keyframes fade-in { from { opacity: 0; } }
@keyframes fade-out { to { opacity: 0; } }
@keyframes slide-from-right { from { transform: translateX(30px); } }
@keyframes slide-to-left { to { transform: translateX(-30px); } }
Layout System
Container Sizes
.container-xs { max-width: 480px; }
.container-sm { max-width: 640px; }
.container-md { max-width: 768px; }
.container-lg { max-width: 1024px; }
.container-xl { max-width: 1280px; }
.container-2xl { max-width: 1536px; }
Grid System
/* Auto-fit grids for responsive cards */
.grid-auto-fit-xs { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.grid-auto-fit-sm { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.grid-auto-fit-md { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.grid-auto-fit-lg { grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); }
Responsive Design
Breakpoints
/* Mobile First Approach */
sm: 640px /* Small devices */
md: 768px /* Medium devices */
lg: 1024px /* Large devices */
xl: 1280px /* Extra large devices */
2xl: 1536px /* 2X Extra large devices */
Container Queries
/* Component-based responsive design */
@container (min-width: 320px) { /* Small container */ }
@container (min-width: 480px) { /* Medium container */ }
@container (min-width: 640px) { /* Large container */ }
Accessibility
Focus States
.focus-visible {
@apply focus:outline-none focus-visible:ring-2 focus-visible:ring-thrill-primary;
@apply focus-visible:ring-offset-2 focus-visible:ring-offset-white;
@apply dark:focus-visible:ring-offset-neutral-900;
}
Screen Reader Support
.sr-only {
@apply absolute w-px h-px p-0 -m-px overflow-hidden;
@apply whitespace-nowrap border-0;
clip: rect(0, 0, 0, 0);
}
.sr-only-focusable:focus {
@apply static w-auto h-auto p-1 m-0 overflow-visible;
@apply whitespace-normal;
clip: auto;
}
Performance Guidelines
Critical CSS
- Inline critical styles for above-the-fold content
- Defer non-critical CSS loading
- Use CSS containment for performance isolation
Animation Performance
- Prefer
transformandopacityfor animations - Use
will-changesparingly and remove after animation - Implement
prefers-reduced-motionsupport
Loading States
.loading-skeleton {
@apply bg-gradient-to-r from-neutral-200 via-neutral-100 to-neutral-200;
@apply dark:from-neutral-700 dark:via-neutral-600 dark:to-neutral-700;
@apply animate-pulse;
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
}
@keyframes shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
Implementation Notes
CSS Custom Properties
- Use CSS custom properties for theme values
- Implement proper fallbacks for older browsers
- Leverage cascade for theme switching
Component Architecture
- Build components with composition in mind
- Use CSS classes for styling, not inline styles
- Implement proper component variants
Testing Strategy
- Test across all supported browsers
- Validate accessibility with screen readers
- Performance test on low-end devices
- Verify responsive behavior at all breakpoints