Files
thrillwiki_django_no_react/cline_docs/designSystem.md
pacnpal b1c369c1bb Add park and ride card components with advanced search functionality
- 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.
2025-09-24 23:10:48 -04:00

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

  1. Thrill-Focused: Every design element should evoke excitement and adventure
  2. Data-Rich: Present complex theme park information in digestible, beautiful ways
  3. Progressive Enhancement: Works beautifully without JavaScript, enhanced with it
  4. Accessibility First: WCAG 2.1 AA compliance throughout
  5. 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 transform and opacity for animations
  • Use will-change sparingly and remove after animation
  • Implement prefers-reduced-motion support

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