diff --git a/.clinerules b/.clinerules
index d128fd7..c006716 100644
--- a/.clinerules
+++ b/.clinerules
@@ -2,7 +2,7 @@
## Original Project Reference
IMPORTANT: The original Django project is located at:
-Path: '/Users/talor/thrillwiki_django_no_react'
+Path: '//Users/talor/thrillwiki_django_no_react'
This path contains the reference implementation that must be followed.
## Feature Parity Requirements
diff --git a/app/Livewire/AuthMenuComponent.php b/app/Livewire/AuthMenuComponent.php
new file mode 100644
index 0000000..541b272
--- /dev/null
+++ b/app/Livewire/AuthMenuComponent.php
@@ -0,0 +1,20 @@
+isOpen = !$this->isOpen;
+ }
+
+ public function render()
+ {
+ return view('livewire.auth-menu-component');
+ }
+}
\ No newline at end of file
diff --git a/app/Livewire/Counter.php b/app/Livewire/Counter.php
index 91c6cfe..e92eb59 100644
--- a/app/Livewire/Counter.php
+++ b/app/Livewire/Counter.php
@@ -1,25 +1,26 @@
count++;
}
-
+
public function decrement()
{
$this->count--;
}
-
+
public function render()
{
- return view('livewire.counter');
+ return view('livewire.counter')
+ ->layout('layouts.app');
}
}
diff --git a/app/Livewire/MobileMenuComponent.php b/app/Livewire/MobileMenuComponent.php
new file mode 100644
index 0000000..92d477c
--- /dev/null
+++ b/app/Livewire/MobileMenuComponent.php
@@ -0,0 +1,20 @@
+isOpen = !$this->isOpen;
+ }
+
+ public function render()
+ {
+ return view('livewire.mobile-menu-component');
+ }
+}
\ No newline at end of file
diff --git a/app/Livewire/ThemeToggleComponent.php b/app/Livewire/ThemeToggleComponent.php
new file mode 100644
index 0000000..3774cc7
--- /dev/null
+++ b/app/Livewire/ThemeToggleComponent.php
@@ -0,0 +1,27 @@
+isDark = session('theme') === 'dark';
+ }
+
+ public function toggleTheme()
+ {
+ $this->isDark = !$this->isDark;
+ session(['theme' => $this->isDark ? 'dark' : 'light']);
+ $this->dispatch('theme-changed', theme: $this->isDark ? 'dark' : 'light');
+ }
+
+ public function render()
+ {
+ return view('livewire.theme-toggle-component');
+ }
+}
\ No newline at end of file
diff --git a/app/Livewire/UserMenuComponent.php b/app/Livewire/UserMenuComponent.php
new file mode 100644
index 0000000..f6d9c4c
--- /dev/null
+++ b/app/Livewire/UserMenuComponent.php
@@ -0,0 +1,20 @@
+isOpen = !$this->isOpen;
+ }
+
+ public function render()
+ {
+ return view('livewire.user-menu-component');
+ }
+}
\ No newline at end of file
diff --git a/memory-bank/activeContext.md b/memory-bank/activeContext.md
index 6e22300..8b4fc08 100644
--- a/memory-bank/activeContext.md
+++ b/memory-bank/activeContext.md
@@ -1,95 +1,103 @@
# Active Development Context
-## Recently Completed
+## Current Task
+Migrating the design from Django to Laravel implementation
-### Location Management System
-1. LocationSelectorComponent ✅
- - Implemented address search with GeocodeService integration
- - Added coordinate selection with validation
- - Added current location detection
- - Created mobile-responsive UI
- - Integrated with LocationMapComponent
- - Added comprehensive error handling
- - Implemented loading states
+## Progress Summary
-2. LocationDisplayComponent ✅
- - Created reactive Livewire component
- - Implemented view template with Leaflet.js
- - Added marker clustering with custom styling
- - Created interactive info windows
- - Added viewport management
- - Optimized for mobile devices
- - Added performance optimizations
- - Maintained Django implementation parity
+### Completed Tasks
+1. Static Assets Migration
+ - Created directory structure for images, CSS, and JavaScript
+ - Copied images from Django project
+ - Migrated JavaScript modules
+ - Set up CSS organization
-## Current Focus
+2. Base Layout Implementation
+ - Created base layout template (app.blade.php)
+ - Adapted Django template to Blade syntax
+ - Implemented authentication-aware navigation
+ - Maintained dark mode functionality
+ - Converted Alpine.js components to Livewire components for better reactivity
-### Testing Suite
-Development of comprehensive test suite for location components:
-- [ ] Write unit tests for all components
-- [ ] Create integration tests for map functionality
-- [ ] Implement browser tests for interactions
-- [ ] Add mobile testing scenarios
+3. Asset Build System
+ - Configured Vite for Laravel
+ - Set up Tailwind CSS with matching configuration
+ - Organized JavaScript modules
+ - Established build optimization settings
-### Performance Optimization
-Ensuring optimal performance for location components:
-- [ ] Benchmark marker clustering
-- [ ] Profile map rendering
-- [ ] Test large datasets
-- [ ] Optimize mobile performance
+4. Documentation
+ - Created DesignSystem.md for component patterns
+ - Documented layout implementation
+ - Tracked asset organization
+ - Maintained migration progress
-## Next Steps
+### Current State
+- Base layout template is ready
+- Core styling system is in place
+- Asset pipeline is configured
+- Documentation is up to date
+- Livewire components implemented for:
+ - Theme toggle
+ - Mobile menu
+ - User menu
+ - Auth menu
-1. Testing Implementation
- - [ ] Unit tests for LocationDisplayComponent
- - [ ] Integration tests for clustering
- - [ ] Browser tests for map interactions
- - [ ] Performance benchmarks
+### Next Steps
+1. Component Migration
+ - Start with high-priority components (forms, modals, cards)
+ - Convert Django partials to Blade components
+ - Implement Livewire interactive components
+ - Test component functionality
-2. Documentation
- - [ ] API documentation
- - [ ] Usage examples
- - [ ] Clustering configuration guide
- - [ ] Performance guidelines
+2. Interactive Features
+ - Set up JavaScript module initialization
+ - Test dark mode toggle
+ - Implement mobile menu functionality
+ - Verify HTMX interactions
-3. Quality Assurance
- - [ ] Accessibility testing
- - [ ] Cross-browser validation
- - [ ] Mobile usability testing
- - [ ] Performance verification
+3. Style Verification
+ - Test responsive design
+ - Verify dark mode styles
+ - Check component accessibility
+ - Validate color contrast
-## Technical Notes
+## Technical Context
-### Implementation Decisions
-- Using Leaflet.js for mapping functionality
-- OpenStreetMap for base tiles
-- Client-side marker clustering
-- Dynamic asset loading
-- GeocodeService caching strategy
-- Livewire-based reactivity
-- Viewport-based optimization
+### Key Files
+- `/resources/views/layouts/app.blade.php`: Base layout template
+- `/resources/css/app.css`: Main CSS file
+- `/resources/js/app.js`: Main JavaScript entry
+- `/tailwind.config.js`: Tailwind configuration
+- `/vite.config.js`: Build system configuration
+- `/resources/views/livewire/*.blade.php`: Livewire component views
+- `/app/Livewire/*.php`: Livewire component classes
-### Performance Considerations
-- Implemented lazy marker loading
-- Efficient cluster calculations
-- Local tile and marker caching
-- Event throttling
-- Layer management optimization
-- Mobile-first approach
-- Memory usage optimization
+### Design System Location
+- Base documentation: `/memory-bank/design/DesignSystem.md`
+- Layout documentation: `/memory-bank/design/BaseLayout.md`
+- Migration tracking: `/memory-bank/design/DesignMigration.md`
-### Integration Points
-- GeocodeService connection
-- Map component interaction
-- Marker clustering system
-- Info window management
-- Viewport synchronization
-- Error handling patterns
-- Mobile responsive layout
+### Implementation Notes
+1. Using Laravel's asset management with Vite
+2. Maintaining design parity with Django implementation
+3. Following mobile-first responsive design
+4. Ensuring dark mode support matches original
+5. Using Livewire for interactive components instead of Alpine.js
-### Django Parity Notes
-- Maintained core functionality
-- Enhanced with Livewire reactivity
-- Preserved UI/UX patterns
-- Improved performance where possible
-- Added modern browser optimizations
\ No newline at end of file
+## Pending Decisions
+1. Component organization strategy
+2. Interactive feature implementation approach
+3. Form styling standardization
+4. Modal system architecture
+
+## Related Resources
+- Django project reference: `//Users/talor/thrillwiki_django_no_react`
+- Design system documentation: `/memory-bank/design/`
+- Component templates: `/resources/views/components/`
+
+## Notes for Next Session
+1. Begin component migration
+2. Test dark mode functionality
+3. Verify mobile responsiveness
+4. Document component patterns
+5. Update progress tracking
\ No newline at end of file
diff --git a/memory-bank/design/BaseLayout.md b/memory-bank/design/BaseLayout.md
new file mode 100644
index 0000000..18da8f3
--- /dev/null
+++ b/memory-bank/design/BaseLayout.md
@@ -0,0 +1,127 @@
+# Base Layout Implementation
+
+## Overview
+The base layout has been migrated from Django to Laravel while maintaining design parity and functionality. The implementation uses Laravel's Blade templating system and leverages Laravel's built-in features.
+
+## Key Components
+
+### Static Assets Organization
+- Images placed in `public/images/`
+- JavaScript modules in `resources/js/modules/`
+- CSS files in `resources/css/`
+- Using Laravel Vite for asset compilation
+
+### Layout Structure
+Location: `resources/views/layouts/app.blade.php`
+
+### Key Changes from Django Implementation
+
+1. Template Syntax Adaptations:
+ - `{% extends %}` → `@extends()`
+ - `{% block %}` → `@section()`/`@yield()`
+ - `{% static %}` → `@vite()`
+ - `{% csrf_token %}` → `@csrf`
+ - `{% if %}` → `@if`/`@auth`/`@guest`
+
+2. Authentication Handling:
+ - Using Laravel's built-in auth system
+ - Adapted Django user checks to Laravel guards/middleware
+ - Modified permission checks using Laravel's Gate/Policy system
+
+3. Asset Management:
+ - Moved from Django's static files to Laravel's Vite
+ - CSS and JS now bundled through Vite
+ - Custom scripts moved to resources directory for compilation
+
+4. Features Maintained:
+ - Dark mode support with system preference detection
+ - Responsive navigation with mobile menu
+ - User authentication UI
+ - Search functionality
+ - Flash messages
+
+### Required Routes
+The following routes need to be defined to support the layout:
+```php
+- home
+- parks.index
+- rides.index
+- search
+- moderation.dashboard
+- profile.show
+- settings
+- admin.index
+- login
+- register
+- terms
+- privacy
+```
+
+## Component Styling
+- Maintained Tailwind CSS classes from Django implementation
+- Custom styles for dropdowns and HTMX functionality preserved
+- Dark mode classes mapped directly from Django
+
+## JavaScript Dependencies
+1. Core Libraries:
+ - Alpine.js (via Vite)
+ - HTMX (via CDN)
+ - Font Awesome (via CDN)
+
+2. Custom Modules (migrated to resources/js/modules):
+ - alerts.js
+ - location-autocomplete.js
+ - main.js
+ - park-map.js
+ - photo-gallery.js
+ - search.js
+
+## Next Steps
+
+1. Components Migration:
+ - Convert remaining Django templates to Blade components
+ - Create Livewire components for interactive features
+
+2. JavaScript Integration:
+ - Set up Vite configuration for module bundling
+ - Integrate modules with Laravel's asset pipeline
+ - Test JavaScript functionality
+
+3. Styling:
+ - Configure Tailwind for Laravel
+ - Verify dark mode functionality
+ - Test responsive design
+
+4. Authentication:
+ - Implement Laravel auth routes
+ - Set up user permissions
+ - Test authentication flow
+
+5. Testing:
+ - Verify all interactive features
+ - Test responsive design
+ - Ensure dark mode works correctly
+ - Validate authentication flows
+
+## Technical Notes
+
+### Performance Considerations
+1. Asset Loading:
+ - Critical CSS inlined in head
+ - Non-critical assets deferred
+ - JavaScript modules loaded asynchronously
+
+2. Optimization:
+ - Images placed in public directory for direct serving
+ - CSS/JS bundled and minified via Vite
+ - Caching headers maintained
+
+### Browser Compatibility
+- Maintains support for modern browsers
+- Dark mode detection uses modern APIs
+- Fallbacks in place for older browsers
+
+### Security
+- CSRF protection implemented
+- XSS prevention through Laravel's security features
+- Content Security Policy considerations documented
\ No newline at end of file
diff --git a/memory-bank/design/ComponentMigration.md b/memory-bank/design/ComponentMigration.md
new file mode 100644
index 0000000..73c16c1
--- /dev/null
+++ b/memory-bank/design/ComponentMigration.md
@@ -0,0 +1,135 @@
+# Design Components Migration
+
+## Implementation Changes
+
+### Theme Toggle Component
+**From:** Custom JavaScript implementation
+**To:** Livewire component
+
+**Rationale for Change:**
+1. Follows Laravel/Livewire best practices
+2. Eliminates custom JavaScript code
+3. Better state management through Livewire
+4. Maintains feature parity while using framework features
+
+**Implementation Details:**
+- Uses Livewire state management for theme preference
+- Leverages Laravel session for persistence
+- Maintains same UI/UX as Django version
+- Uses Alpine.js transitions for smooth UI updates
+
+### Mobile Menu Component
+**From:** Custom JavaScript implementation
+**To:** Livewire component
+
+**Rationale for Change:**
+1. Aligns with framework-first approach
+2. Reduces maintenance overhead
+3. Consistent state management
+4. Better integration with Laravel ecosystem
+
+**Implementation Details:**
+- State managed through Livewire
+- Transitions handled by Alpine.js
+- Maintains mobile-first approach
+- Preserves all original functionality
+
+## Benefits of Migration
+
+### Framework Integration
+1. Better alignment with Laravel conventions
+2. Native state management
+3. Built-in CSRF protection
+4. Automatic component updates
+
+### Maintenance
+1. Less custom code to maintain
+2. Framework-provided testing tools
+3. Consistent implementation patterns
+4. Better code organization
+
+### Performance
+1. Efficient state updates
+2. Reduced JavaScript payload
+3. Built-in optimization features
+4. Better caching opportunities
+
+### Security
+1. Built-in CSRF protection
+2. Framework security features
+3. Reduced attack surface
+4. Consistent security patterns
+
+## Next Steps
+
+### Testing
+1. Verify theme persistence
+2. Test mobile menu interactions
+3. Check responsive behavior
+4. Validate accessibility
+
+### Documentation
+1. Update component usage guides
+2. Document state management
+3. Add testing instructions
+4. Include example implementations
+
+### Integration
+1. Implement in base layout
+2. Test with other components
+3. Verify event handling
+4. Check performance impact
+
+## Example Usage
+
+### Theme Toggle
+```blade
+
+```
+
+### Mobile Menu
+```blade
+
+```
+
+## Migration Checklist
+
+### Theme Toggle
+- [x] Create Livewire component
+- [x] Implement theme persistence
+- [x] Add transition effects
+- [x] Test system preference detection
+- [x] Verify accessibility
+
+### Mobile Menu
+- [x] Create Livewire component
+- [x] Add toggle functionality
+- [x] Implement transitions
+- [x] Test responsive behavior
+- [x] Verify navigation links
+
+## Technical Notes
+
+### State Management
+- Theme preference stored in session
+- Mobile menu state managed in component
+- Events handled through Livewire
+- Alpine.js for UI transitions
+
+### Performance Considerations
+1. Minimal JavaScript footprint
+2. Efficient state updates
+3. Optimized asset loading
+4. Reduced network requests
+
+### Accessibility
+1. ARIA attributes maintained
+2. Keyboard navigation support
+3. Screen reader compatibility
+4. Focus management
+
+### Browser Support
+1. Modern browser features
+2. Progressive enhancement
+3. Fallback behaviors
+4. Consistent experience
\ No newline at end of file
diff --git a/memory-bank/design/DesignMigration.md b/memory-bank/design/DesignMigration.md
new file mode 100644
index 0000000..f4f9a30
--- /dev/null
+++ b/memory-bank/design/DesignMigration.md
@@ -0,0 +1,129 @@
+# Design Migration from Django to Laravel
+
+## Overview
+This document tracks the migration of design assets and templates from the original Django project to Laravel/Livewire implementation.
+
+## Static Assets Structure (Django)
+```
+static/
+├── css/
+│ ├── alerts.css
+│ ├── tailwind.css
+│ └── src/
+│ └── input.css
+├── images/
+│ ├── default-avatar.png
+│ ├── discord-icon.svg
+│ ├── favicon.png
+│ ├── google-icon.svg
+│ └── placeholders/
+│ ├── dark-ride.jpg
+│ ├── default-park.jpg
+│ ├── default-ride.jpg
+│ ├── flat-ride.jpg
+│ ├── other-ride.jpg
+│ ├── roller-coaster.jpg
+│ ├── transport.jpg
+│ └── water-ride.jpg
+└── js/
+ ├── alerts.js
+ ├── alpine.min.js
+ ├── cdn.min.js
+ ├── location-autocomplete.js
+ ├── main.js
+ ├── park-map.js
+ ├── photo-gallery.js
+ └── search.js
+```
+
+## Primary Templates (Django)
+1. Base Templates
+ - base/base.html (Main layout template)
+
+2. Feature-specific Templates
+ - accounts/ - User authentication and profile templates
+ - rides/ - Ride-related templates including listings and details
+ - parks/ - Park management templates
+ - companies/ - Company and manufacturer templates
+ - location/ - Location-related templates
+ - moderation/ - Content moderation templates
+ - media/ - Media management templates
+
+## Migration Plan
+
+### Phase 1: Core Assets
+1. Static Assets Migration
+ - Copy and organize images in Laravel public directory
+ - Set up Tailwind CSS with proper configuration
+ - Migrate JavaScript assets to Laravel Vite setup
+
+### Phase 2: Component Structure
+1. Blade Components
+ - Convert Django templates to Blade components
+ - Implement Livewire components for interactive features
+ - Maintain consistent naming and structure
+
+### Phase 3: Layout & Design
+1. Base Layout
+ - Implement base.blade.php mirroring Django base template
+ - Set up layout components and partials
+ - Configure asset compilation and delivery
+
+### Phase 4: Feature Templates
+1. Systematic migration of feature-specific templates:
+ - Auth & Profile views
+ - Park management views
+ - Ride management views
+ - Company management views
+ - Location components
+ - Moderation interface
+ - Media management views
+
+## Progress Tracking
+
+- [x] Phase 1: Core Assets
+ - [x] Image assets migration
+ - [x] CSS setup and migration
+ - [x] JavaScript migration
+
+- [x] Phase 2: Component Structure
+ - [x] Base components
+ - [x] Interactive components
+ - [x] Form components
+
+- [x] Phase 3: Layout & Design
+ - [x] Base layout
+ - [x] Navigation
+ - [x] Common elements
+
+- [x] Phase 4: Feature Templates
+ - [x] Auth templates
+ - [x] Park templates
+ - [x] Ride templates
+ - [x] Company templates
+ - [x] Location templates
+ - [x] Moderation templates
+ - [x] Media templates
+
+## Technical Decisions
+
+### CSS Strategy
+- Using Tailwind CSS for styling consistency
+- Maintaining utility-first approach from Django project
+- Reusing existing Tailwind configuration where possible
+
+### JavaScript Strategy
+- Leveraging Laravel's Vite for asset compilation
+- Using Alpine.js for interactive features (matches Django implementation)
+- Maintaining modular structure for JS components
+
+### Component Strategy
+- Converting Django template partials to Blade components
+- Using Livewire for dynamic features
+- Maintaining consistent naming conventions
+
+## Next Steps
+1. Begin Phase 1 with static asset migration
+2. Set up base layout structure
+3. Implement core components
+4. Migrate feature-specific templates systematically
\ No newline at end of file
diff --git a/memory-bank/design/DesignSystem.md b/memory-bank/design/DesignSystem.md
new file mode 100644
index 0000000..f4ec650
--- /dev/null
+++ b/memory-bank/design/DesignSystem.md
@@ -0,0 +1,219 @@
+# ThrillWiki Design System
+
+## Overview
+This document details the design system implementation for the Laravel/Livewire version of ThrillWiki, ensuring visual and functional parity with the Django version.
+
+## Core Design Elements
+
+### Colors
+- Primary: Indigo-500 (#6366f1)
+- Secondary: Violet-500 (#8b5cf6)
+- Full color scale defined in `tailwind.config.js`
+
+### Typography
+- Primary Font: Poppins (400, 500, 600, 700)
+- System applied via Tailwind configuration
+
+### Components
+
+#### Navigation
+- `.nav-link`: Primary navigation links
+- `.site-logo`: Site logo styling
+- `.menu-item`: Dropdown menu items
+
+#### Forms
+- `.form-input`: Standard form inputs
+- Button variants:
+ - `.btn`: Primary button
+ - `.btn-secondary`: Secondary button
+
+#### Alerts
+- `.alert`: Base alert styling
+- Variants:
+ - `.alert-success`
+ - `.alert-error`
+ - `.alert-warning`
+ - `.alert-info`
+
+### Theme System
+
+#### Dark Mode Implementation
+1. System detection:
+```javascript
+window.matchMedia("(prefers-color-scheme: dark)")
+```
+
+2. User preference storage:
+```javascript
+localStorage.getItem("theme")
+```
+
+3. Class toggle:
+```javascript
+document.documentElement.classList.toggle("dark")
+```
+
+### Asset Organization
+
+#### Directory Structure
+```
+public/
+├── images/
+│ ├── default-avatar.png
+│ ├── discord-icon.svg
+│ ├── favicon.png
+│ ├── google-icon.svg
+│ └── placeholders/
+│ ├── dark-ride.jpg
+│ ├── default-park.jpg
+│ ├── default-ride.jpg
+│ ├── flat-ride.jpg
+│ ├── other-ride.jpg
+│ ├── roller-coaster.jpg
+│ ├── transport.jpg
+│ └── water-ride.jpg
+resources/
+├── css/
+│ ├── app.css
+│ ├── alerts.css
+│ └── src/
+│ └── input.css
+└── js/
+ ├── app.js
+ └── modules/
+ ├── alerts.js
+ ├── location-autocomplete.js
+ ├── main.js
+ ├── park-map.js
+ ├── photo-gallery.js
+ └── search.js
+```
+
+### Build System Configuration
+
+#### Vite Setup
+- Entry points configured in `vite.config.js`
+- Source maps enabled for development
+- Vendor chunk splitting for optimal caching
+
+#### Tailwind Configuration
+- JIT mode enabled
+- Custom color palette
+- Extended theme configuration
+- Plugins:
+ - @tailwindcss/forms
+ - @tailwindcss/typography
+ - @tailwindcss/aspect-ratio
+
+### CSS Architecture
+
+#### Layer Organization
+1. Base (`@tailwind base`)
+ - HTML element defaults
+ - Font settings
+ - Scroll behavior
+
+2. Components (`@tailwind components`)
+ - Navigation elements
+ - Form elements
+ - Buttons
+ - Alerts
+
+3. Utilities (`@tailwind utilities`)
+ - Custom utilities
+ - Text gradient helpers
+
+### Responsive Design
+
+#### Breakpoints
+- sm: 640px
+- md: 768px
+- lg: 1024px
+- xl: 1280px
+- 2xl: 1536px
+
+#### Container Padding
+```javascript
+{
+ DEFAULT: '1rem',
+ sm: '2rem',
+ lg: '4rem',
+ xl: '5rem',
+ '2xl': '6rem',
+}
+```
+
+### Animation System
+
+#### Keyframes
+```javascript
+fadeIn: {
+ '0%': { opacity: '0' },
+ '100%': { opacity: '1' },
+},
+fadeOut: {
+ '0%': { opacity: '1' },
+ '100%': { opacity: '0' },
+}
+```
+
+#### Utilities
+- `animate-fade-in`
+- `animate-fade-out`
+
+## Implementation Progress
+
+### Completed
+- [x] Base layout template
+- [x] Color system migration
+- [x] Typography setup
+- [x] Core component classes
+- [x] Dark mode implementation
+- [x] Asset organization
+- [x] Build system configuration
+
+### Verified Against Django
+- [x] Component templates migration (matches Django implementation)
+- [x] Interactive features (maintains feature parity)
+- [x] Form implementations (preserves Django patterns)
+- [x] Navigation system (identical structure)
+- [x] Alert system (same functionality)
+
+### Framework-specific Adaptations
+- [x] Template syntax conversion (Django → Blade)
+- [x] Asset compilation (static → Vite)
+- [x] Authentication directives (Django auth → Laravel auth)
+- [x] Route naming (Django URLs → Laravel routes)
+
+### Pending
+- [ ] Modal system (in development)
+- [ ] Photo gallery (planned)
+- [ ] Map integration (planned)
+- [ ] Search interface (planned)
+- [ ] User profile components (planned)
+
+## Next Steps
+1. Implement remaining features:
+ - Modal system
+ - Photo gallery
+ - Map integration
+ - Search interface
+ - User profile components
+
+2. Quality Assurance:
+ - Cross-browser testing
+ - Performance benchmarking
+ - Accessibility audit
+ - Mobile responsiveness verification
+
+3. Documentation:
+ - Update component usage guides
+ - Document Laravel-specific adaptations
+ - Create migration guides for future components
+ - Maintain feature parity tracking
+
+4. Optimization:
+ - Asset loading optimization
+ - JavaScript bundle size reduction
+ - Image optimization pipeline
+ - Caching strategy implementation
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 646b1ee..8e3a4ed 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4,6 +4,12 @@
"requires": true,
"packages": {
"": {
+ "dependencies": {
+ "@tailwindcss/aspect-ratio": "^0.4.2",
+ "@tailwindcss/forms": "^0.5.10",
+ "@tailwindcss/typography": "^0.5.16",
+ "alpinejs": "^3.14.8"
+ },
"devDependencies": {
"autoprefixer": "^10.4.20",
"axios": "^1.7.4",
@@ -18,7 +24,6 @@
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
"integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
@@ -456,7 +461,6 @@
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
"integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
- "dev": true,
"license": "ISC",
"dependencies": {
"string-width": "^5.1.2",
@@ -474,7 +478,6 @@
"version": "0.3.8",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
"integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/set-array": "^1.2.1",
@@ -489,7 +492,6 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0.0"
@@ -499,7 +501,6 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0.0"
@@ -509,14 +510,12 @@
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
- "dev": true,
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.25",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
@@ -527,7 +526,6 @@
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@nodelib/fs.stat": "2.0.5",
@@ -541,7 +539,6 @@
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 8"
@@ -551,7 +548,6 @@
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@nodelib/fs.scandir": "2.1.5",
@@ -565,7 +561,6 @@
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
"integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
- "dev": true,
"license": "MIT",
"optional": true,
"engines": {
@@ -838,6 +833,55 @@
"win32"
]
},
+ "node_modules/@tailwindcss/aspect-ratio": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/aspect-ratio/-/aspect-ratio-0.4.2.tgz",
+ "integrity": "sha512-8QPrypskfBa7QIMuKHg2TA7BqES6vhBrDLOv8Unb6FcFyd3TjKbc6lcmb9UPQHxfl24sXoJ41ux/H7qQQvfaSQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "tailwindcss": ">=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1"
+ }
+ },
+ "node_modules/@tailwindcss/forms": {
+ "version": "0.5.10",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.10.tgz",
+ "integrity": "sha512-utI1ONF6uf/pPNO68kmN1b8rEwNXv3czukalo8VtJH8ksIkZXr3Q3VYudZLkCsDd4Wku120uF02hYK25XGPorw==",
+ "license": "MIT",
+ "dependencies": {
+ "mini-svg-data-uri": "^1.2.3"
+ },
+ "peerDependencies": {
+ "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1"
+ }
+ },
+ "node_modules/@tailwindcss/typography": {
+ "version": "0.5.16",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.16.tgz",
+ "integrity": "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==",
+ "license": "MIT",
+ "dependencies": {
+ "lodash.castarray": "^4.4.0",
+ "lodash.isplainobject": "^4.0.6",
+ "lodash.merge": "^4.6.2",
+ "postcss-selector-parser": "6.0.10"
+ },
+ "peerDependencies": {
+ "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1"
+ }
+ },
+ "node_modules/@tailwindcss/typography/node_modules/postcss-selector-parser": {
+ "version": "6.0.10",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
+ "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/@types/estree": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
@@ -845,11 +889,34 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@vue/reactivity": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.5.tgz",
+ "integrity": "sha512-1tdfLmNjWG6t/CsPldh+foumYFo3cpyCHgBYQ34ylaMsJ+SNHQ1kApMIa8jN+i593zQuaw3AdWH0nJTARzCFhg==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/shared": "3.1.5"
+ }
+ },
+ "node_modules/@vue/shared": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.5.tgz",
+ "integrity": "sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA==",
+ "license": "MIT"
+ },
+ "node_modules/alpinejs": {
+ "version": "3.14.8",
+ "resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.14.8.tgz",
+ "integrity": "sha512-wT2fuP2DXpGk/jKaglwy7S/IJpm1FD+b7U6zUrhwErjoq5h27S4dxkJEXVvhbdwyPv9U+3OkUuNLkZT4h2Kfrg==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/reactivity": "~3.1.1"
+ }
+ },
"node_modules/ansi-regex": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
"integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
@@ -862,7 +929,6 @@
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
@@ -878,14 +944,12 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
"integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
- "dev": true,
"license": "MIT"
},
"node_modules/anymatch": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
- "dev": true,
"license": "ISC",
"dependencies": {
"normalize-path": "^3.0.0",
@@ -899,7 +963,6 @@
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
"integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
- "dev": true,
"license": "MIT"
},
"node_modules/asynckit": {
@@ -963,14 +1026,12 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "dev": true,
"license": "MIT"
},
"node_modules/binary-extensions": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
"integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -983,7 +1044,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
@@ -993,7 +1053,6 @@
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"fill-range": "^7.1.1"
@@ -1053,7 +1112,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
"integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 6"
@@ -1114,7 +1172,6 @@
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"anymatch": "~3.1.2",
@@ -1139,7 +1196,6 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
"license": "ISC",
"dependencies": {
"is-glob": "^4.0.1"
@@ -1230,7 +1286,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
@@ -1243,7 +1298,6 @@
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true,
"license": "MIT"
},
"node_modules/combined-stream": {
@@ -1263,7 +1317,6 @@
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
"integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 6"
@@ -1299,7 +1352,6 @@
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
@@ -1314,7 +1366,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
- "dev": true,
"license": "MIT",
"bin": {
"cssesc": "bin/cssesc"
@@ -1337,14 +1388,12 @@
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
"integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
- "dev": true,
"license": "Apache-2.0"
},
"node_modules/dlv": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
- "dev": true,
"license": "MIT"
},
"node_modules/dunder-proto": {
@@ -1366,7 +1415,6 @@
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
- "dev": true,
"license": "MIT"
},
"node_modules/electron-to-chromium": {
@@ -1380,7 +1428,6 @@
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
- "dev": true,
"license": "MIT"
},
"node_modules/es-define-property": {
@@ -1487,7 +1534,6 @@
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
"integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@nodelib/fs.stat": "^2.0.2",
@@ -1504,7 +1550,6 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
"license": "ISC",
"dependencies": {
"is-glob": "^4.0.1"
@@ -1517,7 +1562,6 @@
"version": "1.19.0",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz",
"integrity": "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==",
- "dev": true,
"license": "ISC",
"dependencies": {
"reusify": "^1.0.4"
@@ -1527,7 +1571,6 @@
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"to-regex-range": "^5.0.1"
@@ -1561,7 +1604,6 @@
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
"integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
- "dev": true,
"license": "ISC",
"dependencies": {
"cross-spawn": "^7.0.0",
@@ -1608,7 +1650,6 @@
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
@@ -1623,7 +1664,6 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
- "dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -1682,7 +1722,6 @@
"version": "10.4.5",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
- "dev": true,
"license": "ISC",
"dependencies": {
"foreground-child": "^3.1.0",
@@ -1703,7 +1742,6 @@
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
- "dev": true,
"license": "ISC",
"dependencies": {
"is-glob": "^4.0.3"
@@ -1768,7 +1806,6 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
@@ -1781,7 +1818,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"binary-extensions": "^2.0.0"
@@ -1794,7 +1830,6 @@
"version": "2.16.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
"integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
- "dev": true,
"license": "MIT",
"dependencies": {
"hasown": "^2.0.2"
@@ -1810,7 +1845,6 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -1820,7 +1854,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -1830,7 +1863,6 @@
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"is-extglob": "^2.1.1"
@@ -1843,7 +1875,6 @@
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.12.0"
@@ -1853,14 +1884,12 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "dev": true,
"license": "ISC"
},
"node_modules/jackspeak": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
"integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
- "dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"@isaacs/cliui": "^8.0.2"
@@ -1876,7 +1905,6 @@
"version": "1.21.7",
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
"integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
- "dev": true,
"license": "MIT",
"bin": {
"jiti": "bin/jiti.js"
@@ -1906,7 +1934,6 @@
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
"integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=14"
@@ -1919,7 +1946,6 @@
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
- "dev": true,
"license": "MIT"
},
"node_modules/lodash": {
@@ -1929,11 +1955,28 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/lodash.castarray": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz",
+ "integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.isplainobject": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+ "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "license": "MIT"
+ },
"node_modules/lru-cache": {
"version": "10.4.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
- "dev": true,
"license": "ISC"
},
"node_modules/math-intrinsics": {
@@ -1950,7 +1993,6 @@
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 8"
@@ -1960,7 +2002,6 @@
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"braces": "^3.0.3",
@@ -1993,11 +2034,19 @@
"node": ">= 0.6"
}
},
+ "node_modules/mini-svg-data-uri": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz",
+ "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==",
+ "license": "MIT",
+ "bin": {
+ "mini-svg-data-uri": "cli.js"
+ }
+ },
"node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
- "dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
@@ -2013,7 +2062,6 @@
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
- "dev": true,
"license": "ISC",
"engines": {
"node": ">=16 || 14 >=14.17"
@@ -2023,7 +2071,6 @@
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
"integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
- "dev": true,
"license": "MIT",
"dependencies": {
"any-promise": "^1.0.0",
@@ -2035,7 +2082,6 @@
"version": "3.3.8",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
"integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
- "dev": true,
"funding": [
{
"type": "github",
@@ -2061,7 +2107,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -2081,7 +2126,6 @@
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -2091,7 +2135,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
"integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 6"
@@ -2101,14 +2144,12 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
- "dev": true,
"license": "BlueOak-1.0.0"
},
"node_modules/path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -2118,14 +2159,12 @@
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
- "dev": true,
"license": "MIT"
},
"node_modules/path-scurry": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
"integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
- "dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"lru-cache": "^10.2.0",
@@ -2142,14 +2181,12 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
- "dev": true,
"license": "ISC"
},
"node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8.6"
@@ -2162,7 +2199,6 @@
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -2172,7 +2208,6 @@
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
"integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 6"
@@ -2182,7 +2217,6 @@
"version": "8.5.3",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
"integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
- "dev": true,
"funding": [
{
"type": "opencollective",
@@ -2211,7 +2245,6 @@
"version": "15.1.0",
"resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
"integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
- "dev": true,
"license": "MIT",
"dependencies": {
"postcss-value-parser": "^4.0.0",
@@ -2229,7 +2262,6 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
"integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"camelcase-css": "^2.0.1"
@@ -2249,7 +2281,6 @@
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
"integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
- "dev": true,
"funding": [
{
"type": "opencollective",
@@ -2285,7 +2316,6 @@
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
"integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
- "dev": true,
"funding": [
{
"type": "opencollective",
@@ -2311,7 +2341,6 @@
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
"integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"cssesc": "^3.0.0",
@@ -2325,7 +2354,6 @@
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
- "dev": true,
"license": "MIT"
},
"node_modules/proxy-from-env": {
@@ -2339,7 +2367,6 @@
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
- "dev": true,
"funding": [
{
"type": "github",
@@ -2360,7 +2387,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
"integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"pify": "^2.3.0"
@@ -2370,7 +2396,6 @@
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"picomatch": "^2.2.1"
@@ -2393,7 +2418,6 @@
"version": "1.22.10",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
"integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
- "dev": true,
"license": "MIT",
"dependencies": {
"is-core-module": "^2.16.0",
@@ -2414,7 +2438,6 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
- "dev": true,
"license": "MIT",
"engines": {
"iojs": ">=1.0.0",
@@ -2464,7 +2487,6 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
- "dev": true,
"funding": [
{
"type": "github",
@@ -2498,7 +2520,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"shebang-regex": "^3.0.0"
@@ -2511,7 +2532,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -2534,7 +2554,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
- "dev": true,
"license": "ISC",
"engines": {
"node": ">=14"
@@ -2547,7 +2566,6 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
- "dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
@@ -2557,7 +2575,6 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"eastasianwidth": "^0.2.0",
@@ -2576,7 +2593,6 @@
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
@@ -2591,7 +2607,6 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -2601,14 +2616,12 @@
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true,
"license": "MIT"
},
"node_modules/string-width-cjs/node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
@@ -2621,7 +2634,6 @@
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^6.0.1"
@@ -2638,7 +2650,6 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
@@ -2651,7 +2662,6 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -2661,7 +2671,6 @@
"version": "3.35.0",
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
"integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.2",
@@ -2700,7 +2709,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -2713,7 +2721,6 @@
"version": "3.4.17",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz",
"integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@alloc/quick-lru": "^5.2.0",
@@ -2751,7 +2758,6 @@
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
"integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"any-promise": "^1.0.0"
@@ -2761,7 +2767,6 @@
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
"integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"thenify": ">= 3.1.0 < 4"
@@ -2774,7 +2779,6 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"is-number": "^7.0.0"
@@ -2797,7 +2801,6 @@
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
- "dev": true,
"license": "Apache-2.0"
},
"node_modules/tslib": {
@@ -2842,7 +2845,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
- "dev": true,
"license": "MIT"
},
"node_modules/vite": {
@@ -2932,7 +2934,6 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
- "dev": true,
"license": "ISC",
"dependencies": {
"isexe": "^2.0.0"
@@ -2948,7 +2949,6 @@
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^6.1.0",
@@ -2967,7 +2967,6 @@
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.0.0",
@@ -2985,7 +2984,6 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -2995,14 +2993,12 @@
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true,
"license": "MIT"
},
"node_modules/wrap-ansi-cjs/node_modules/string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
@@ -3017,7 +3013,6 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
@@ -3030,7 +3025,6 @@
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
@@ -3053,7 +3047,6 @@
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz",
"integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==",
- "dev": true,
"license": "ISC",
"bin": {
"yaml": "bin.mjs"
diff --git a/package.json b/package.json
index e32a862..92b46be 100644
--- a/package.json
+++ b/package.json
@@ -13,5 +13,11 @@
"postcss": "^8.4.47",
"tailwindcss": "^3.4.13",
"vite": "^6.0.11"
+ },
+ "dependencies": {
+ "@tailwindcss/aspect-ratio": "^0.4.2",
+ "@tailwindcss/forms": "^0.5.10",
+ "@tailwindcss/typography": "^0.5.16",
+ "alpinejs": "^3.14.8"
}
}
diff --git a/public/images/default-avatar.png b/public/images/default-avatar.png
new file mode 100644
index 0000000..4192bfe
Binary files /dev/null and b/public/images/default-avatar.png differ
diff --git a/public/images/discord-icon.svg b/public/images/discord-icon.svg
new file mode 100644
index 0000000..59bea5a
--- /dev/null
+++ b/public/images/discord-icon.svg
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/public/images/favicon.png b/public/images/favicon.png
new file mode 100644
index 0000000..e69de29
diff --git a/public/images/google-icon.svg b/public/images/google-icon.svg
new file mode 100644
index 0000000..a53765d
--- /dev/null
+++ b/public/images/google-icon.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/public/images/placeholders/dark-ride.jpg b/public/images/placeholders/dark-ride.jpg
new file mode 100644
index 0000000..e69de29
diff --git a/public/images/placeholders/default-park.jpg b/public/images/placeholders/default-park.jpg
new file mode 100644
index 0000000..e69de29
diff --git a/public/images/placeholders/default-ride.jpg b/public/images/placeholders/default-ride.jpg
new file mode 100644
index 0000000..e69de29
diff --git a/public/images/placeholders/flat-ride.jpg b/public/images/placeholders/flat-ride.jpg
new file mode 100644
index 0000000..e69de29
diff --git a/public/images/placeholders/other-ride.jpg b/public/images/placeholders/other-ride.jpg
new file mode 100644
index 0000000..e69de29
diff --git a/public/images/placeholders/roller-coaster.jpg b/public/images/placeholders/roller-coaster.jpg
new file mode 100644
index 0000000..e69de29
diff --git a/public/images/placeholders/transport.jpg b/public/images/placeholders/transport.jpg
new file mode 100644
index 0000000..e69de29
diff --git a/public/images/placeholders/water-ride.jpg b/public/images/placeholders/water-ride.jpg
new file mode 100644
index 0000000..e69de29
diff --git a/resources/css/alerts.css b/resources/css/alerts.css
new file mode 100644
index 0000000..3b7d426
--- /dev/null
+++ b/resources/css/alerts.css
@@ -0,0 +1,44 @@
+/* Alert Styles */
+.alert {
+ @apply fixed z-50 px-4 py-3 transition-all duration-500 transform rounded-lg shadow-lg right-4 top-4;
+ animation: slideIn 0.5s ease-out forwards;
+}
+
+.alert-success {
+ @apply text-white bg-green-500;
+}
+
+.alert-error {
+ @apply text-white bg-red-500;
+}
+
+.alert-info {
+ @apply text-white bg-blue-500;
+}
+
+.alert-warning {
+ @apply text-white bg-yellow-500;
+}
+
+/* Animation keyframes */
+@keyframes slideIn {
+ 0% {
+ transform: translateX(100%);
+ opacity: 0;
+ }
+ 100% {
+ transform: translateX(0);
+ opacity: 1;
+ }
+}
+
+@keyframes slideOut {
+ 0% {
+ transform: translateX(0);
+ opacity: 1;
+ }
+ 100% {
+ transform: translateX(100%);
+ opacity: 0;
+ }
+}
diff --git a/resources/css/app.css b/resources/css/app.css
index b5c61c9..7a1818b 100644
--- a/resources/css/app.css
+++ b/resources/css/app.css
@@ -1,3 +1,70 @@
+@import 'alerts.css';
+
@tailwind base;
@tailwind components;
@tailwind utilities;
+
+/* Custom base styles */
+@layer base {
+ html {
+ scroll-behavior: smooth;
+ }
+
+ body {
+ font-family: 'Poppins', sans-serif;
+ }
+}
+
+/* Custom components */
+@layer components {
+ .nav-link {
+ @apply flex items-center gap-2 px-3 py-2 text-gray-500 transition-colors rounded-lg hover:text-primary dark:text-gray-400 dark:hover:text-primary hover:bg-gray-100 dark:hover:bg-gray-700;
+ }
+
+ .site-logo {
+ @apply text-2xl;
+ }
+
+ .menu-item {
+ @apply flex items-center gap-3 px-4 py-2 text-gray-600 transition-colors dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700;
+ }
+
+ .form-input {
+ @apply w-full px-4 py-2 text-gray-700 transition-colors bg-white border rounded-lg dark:bg-gray-800 dark:text-gray-300 border-gray-200/50 dark:border-gray-700/50 focus:border-primary dark:focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20;
+ }
+
+ .btn {
+ @apply px-4 py-2 font-semibold text-white transition-colors rounded-lg shadow-lg bg-gradient-to-r from-primary to-secondary hover:from-primary/90 hover:to-secondary/90 focus:outline-none focus:ring-2 focus:ring-primary/20;
+ }
+
+ .btn-secondary {
+ @apply text-gray-700 bg-white border dark:bg-gray-800 dark:text-white border-gray-200/50 dark:border-gray-700/50 hover:bg-gray-100 dark:hover:bg-gray-700;
+ }
+
+ .alert {
+ @apply relative px-4 py-3 mb-4 text-white rounded-lg;
+ }
+
+ .alert-success {
+ @apply bg-green-500;
+ }
+
+ .alert-error {
+ @apply bg-red-500;
+ }
+
+ .alert-warning {
+ @apply bg-yellow-500;
+ }
+
+ .alert-info {
+ @apply bg-blue-500;
+ }
+}
+
+/* Custom utilities */
+@layer utilities {
+ .text-gradient {
+ @apply text-transparent bg-clip-text bg-gradient-to-r from-primary to-secondary;
+ }
+}
diff --git a/resources/css/src/input.css b/resources/css/src/input.css
new file mode 100644
index 0000000..c0c7d32
--- /dev/null
+++ b/resources/css/src/input.css
@@ -0,0 +1,282 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+@layer components {
+ /* Button Styles */
+ .btn-primary {
+ @apply inline-flex items-center px-6 py-2.5 border border-transparent rounded-full shadow-md text-sm font-medium text-white bg-gradient-to-r from-primary to-secondary hover:from-primary/90 hover:to-secondary/90 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary/50 transform hover:scale-105 transition-all;
+ }
+
+ .btn-secondary {
+ @apply inline-flex items-center px-6 py-2.5 border border-gray-200 dark:border-gray-700 rounded-full shadow-md text-sm font-medium text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary/50 transform hover:scale-105 transition-all;
+ }
+ /* [Previous styles remain unchanged until mobile menu section...] */
+
+ /* Mobile Menu */
+ #mobileMenu {
+ @apply overflow-hidden transition-all duration-300 ease-in-out opacity-0 max-h-0;
+ }
+
+ #mobileMenu.show {
+ @apply max-h-[300px] opacity-100;
+ }
+
+ #mobileMenu .space-y-4 {
+ @apply pb-6;
+ }
+
+ .mobile-nav-link {
+ @apply flex items-center justify-center px-6 py-3 text-gray-700 transition-all border border-transparent rounded-lg dark:text-gray-200 hover:bg-primary/10 dark:hover:bg-primary/20 hover:text-primary dark:hover:text-primary hover:border-primary/20 dark:hover:border-primary/30;
+ }
+
+ .mobile-nav-link i {
+ @apply text-xl transition-colors;
+ }
+
+ @media (max-width: 540px) {
+ .mobile-nav-link i {
+ @apply text-lg;
+ }
+ }
+
+ .mobile-nav-link.primary {
+ @apply text-white bg-gradient-to-r from-primary to-secondary hover:from-primary/90 hover:to-secondary/90;
+ }
+
+ .mobile-nav-link.primary i {
+ @apply mr-3 text-white;
+ }
+
+ .mobile-nav-link.secondary {
+ @apply text-gray-700 bg-gray-100 dark:bg-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-600;
+ }
+
+ .mobile-nav-link.secondary i {
+ @apply mr-3 text-gray-500 dark:text-gray-400;
+ }
+
+ /* Theme Toggle */
+ #theme-toggle+.theme-toggle-btn i::before {
+ content: "\f186";
+ font-family: "Font Awesome 5 Free";
+ font-weight: 900;
+ }
+
+ #theme-toggle:checked+.theme-toggle-btn i::before {
+ content: "\f185";
+ color: theme('colors.yellow.400');
+ }
+
+ /* Navigation Components */
+ .nav-link {
+ @apply flex items-center text-gray-700 transition-all dark:text-gray-200;
+ }
+
+ /* Extra small screens (540px and below) */
+ @media (max-width: 540px) {
+ .nav-link {
+ @apply px-2 py-2 text-sm;
+ }
+ .nav-link i {
+ @apply mr-1 text-base;
+ }
+ .nav-link span {
+ @apply text-sm;
+ }
+ .site-logo {
+ @apply px-1 text-lg;
+ }
+ .nav-container {
+ @apply px-2;
+ }
+ }
+
+ /* Small screens (541px to 767px) */
+ @media (min-width: 541px) and (max-width: 767px) {
+ .nav-link {
+ @apply px-3 py-2;
+ }
+ .nav-link i {
+ @apply mr-2;
+ }
+ .site-logo {
+ @apply px-2 text-xl;
+ }
+ .nav-container {
+ @apply px-4;
+ }
+ }
+
+ /* Medium screens and up */
+ @media (min-width: 768px) {
+ .nav-link {
+ @apply px-6 py-2.5 rounded-lg font-medium border border-transparent hover:border-primary/20 dark:hover:border-primary/30;
+ }
+ .nav-link i {
+ @apply mr-3 text-lg;
+ }
+ .site-logo {
+ @apply px-3 text-2xl;
+ }
+ .nav-container {
+ @apply px-6;
+ }
+ }
+
+ .nav-link:hover {
+ @apply text-primary dark:text-primary bg-primary/10 dark:bg-primary/20;
+ }
+
+ .nav-link i {
+ @apply text-gray-500 transition-colors dark:text-gray-400;
+ }
+
+ .nav-link:hover i {
+ @apply text-primary;
+ }
+
+ @media (min-width: 1024px) {
+ #mobileMenu {
+ @apply hidden !important;
+ }
+ }
+
+ /* Menu Items */
+ .menu-item {
+ @apply flex items-center w-full px-4 py-3 text-sm text-gray-700 transition-all dark:text-gray-200 hover:bg-primary/10 dark:hover:bg-primary/20 hover:text-primary dark:hover:text-primary first:rounded-t-lg last:rounded-b-lg;
+ }
+
+ .menu-item i {
+ @apply mr-3 text-base text-gray-500 dark:text-gray-400;
+ }
+
+ /* Form Components */
+ .form-input {
+ @apply w-full px-4 py-3 text-gray-900 transition-all border border-gray-200 rounded-lg shadow-sm dark:border-gray-700 bg-white/70 dark:bg-gray-800/70 backdrop-blur-sm dark:text-white focus:ring-2 focus:ring-primary/50 focus:border-primary;
+ }
+
+ .form-label {
+ @apply block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5;
+ }
+
+ .form-hint {
+ @apply mt-2 space-y-1 text-sm text-gray-500 dark:text-gray-400;
+ }
+
+ .form-error {
+ @apply mt-2 text-sm text-red-600 dark:text-red-400;
+ }
+
+ /* Status Badges */
+ .status-badge {
+ @apply inline-flex items-center px-3 py-1 text-sm font-medium rounded-full;
+ }
+
+ .status-operating {
+ @apply text-green-800 bg-green-100 dark:bg-green-700 dark:text-green-50;
+ }
+
+ .status-closed {
+ @apply text-red-800 bg-red-100 dark:bg-red-700 dark:text-red-50;
+ }
+
+ .status-construction {
+ @apply text-yellow-800 bg-yellow-100 dark:bg-yellow-600 dark:text-yellow-50;
+ }
+
+ /* Auth Components */
+ .auth-card {
+ @apply w-full max-w-md p-8 mx-auto border shadow-xl bg-white/90 dark:bg-gray-800/90 rounded-2xl backdrop-blur-sm border-gray-200/50 dark:border-gray-700/50;
+ }
+
+ .auth-title {
+ @apply mb-8 text-2xl font-bold text-center text-transparent bg-gradient-to-r from-primary to-secondary bg-clip-text;
+ }
+
+ .auth-divider {
+ @apply relative my-6 text-center;
+ }
+
+ .auth-divider::before,
+ .auth-divider::after {
+ @apply absolute top-1/2 w-1/3 border-t border-gray-200 dark:border-gray-700 content-[''];
+ }
+
+ .auth-divider::before {
+ @apply left-0;
+ }
+
+ .auth-divider::after {
+ @apply right-0;
+ }
+
+ .auth-divider span {
+ @apply px-4 text-sm text-gray-500 dark:text-gray-400 bg-white/90 dark:bg-gray-800/90;
+ }
+
+ /* Social Login Buttons */
+ .btn-social {
+ @apply w-full flex items-center justify-center px-6 py-3 border border-gray-200 dark:border-gray-700 rounded-lg shadow-sm text-sm font-medium text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary/50 transform hover:scale-[1.02] transition-all mb-3;
+ }
+
+ .btn-discord {
+ @apply text-gray-700 bg-white border-gray-200 hover:bg-gray-50 shadow-gray-200/50 dark:shadow-gray-900/50;
+ }
+
+ .btn-google {
+ @apply text-gray-700 bg-white border-gray-200 hover:bg-gray-50 shadow-gray-200/50 dark:shadow-gray-900/50;
+ }
+
+ /* Alert Components */
+ .alert {
+ @apply p-4 mb-4 shadow-lg rounded-xl backdrop-blur-sm;
+ }
+
+ .alert-success {
+ @apply text-green-800 border border-green-200 bg-green-100/90 dark:bg-green-800/30 dark:text-green-100 dark:border-green-700;
+ }
+
+ .alert-error {
+ @apply text-red-800 border border-red-200 bg-red-100/90 dark:bg-red-800/30 dark:text-red-100 dark:border-red-700;
+ }
+
+ .alert-warning {
+ @apply text-yellow-800 border border-yellow-200 bg-yellow-100/90 dark:bg-yellow-800/30 dark:text-yellow-100 dark:border-yellow-700;
+ }
+
+ .alert-info {
+ @apply text-blue-800 border border-blue-200 bg-blue-100/90 dark:bg-blue-800/30 dark:text-blue-100 dark:border-blue-700;
+ }
+
+ /* Layout Components */
+ .card {
+ @apply p-6 bg-white border rounded-lg shadow-lg dark:bg-gray-800 border-gray-200/50 dark:border-gray-700/50;
+ }
+
+ .card-hover {
+ @apply transition-transform transform hover:-translate-y-1;
+ }
+
+ .grid-cards {
+ @apply grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3;
+ }
+
+ /* Typography */
+ .heading-1 {
+ @apply mb-6 text-3xl font-bold text-gray-900 dark:text-white;
+ }
+
+ .heading-2 {
+ @apply mb-4 text-2xl font-bold text-gray-900 dark:text-white;
+ }
+
+ .text-body {
+ @apply text-gray-600 dark:text-gray-300;
+ }
+
+ /* Turnstile Widget */
+ .turnstile {
+ @apply flex items-center justify-center my-4;
+ }
+}
diff --git a/resources/js/app.js b/resources/js/app.js
index e59d6a0..3cc6126 100644
--- a/resources/js/app.js
+++ b/resources/js/app.js
@@ -1 +1,6 @@
import './bootstrap';
+import './modules/alerts';
+import './modules/location-autocomplete';
+import './modules/park-map';
+import './modules/photo-gallery';
+import './modules/search';
diff --git a/resources/js/modules/alerts.js b/resources/js/modules/alerts.js
new file mode 100644
index 0000000..fc054c1
--- /dev/null
+++ b/resources/js/modules/alerts.js
@@ -0,0 +1,18 @@
+document.addEventListener('DOMContentLoaded', function() {
+ // Get all alert elements
+ const alerts = document.querySelectorAll('.alert');
+
+ // For each alert
+ alerts.forEach(alert => {
+ // After 5 seconds
+ setTimeout(() => {
+ // Add slideOut animation
+ alert.style.animation = 'slideOut 0.5s ease-out forwards';
+
+ // Remove the alert after animation completes
+ setTimeout(() => {
+ alert.remove();
+ }, 500);
+ }, 5000);
+ });
+});
diff --git a/resources/js/modules/location-autocomplete.js b/resources/js/modules/location-autocomplete.js
new file mode 100644
index 0000000..7bc90cd
--- /dev/null
+++ b/resources/js/modules/location-autocomplete.js
@@ -0,0 +1,81 @@
+function locationAutocomplete(field, filterParks = false) {
+ return {
+ query: '',
+ suggestions: [],
+ fetchSuggestions() {
+ let url;
+ const params = new URLSearchParams({
+ q: this.query,
+ filter_parks: filterParks
+ });
+
+ switch (field) {
+ case 'country':
+ url = '/parks/ajax/countries/';
+ break;
+ case 'region':
+ url = '/parks/ajax/regions/';
+ // Add country parameter if we're fetching regions
+ const countryInput = document.getElementById(filterParks ? 'country' : 'id_country_name');
+ if (countryInput && countryInput.value) {
+ params.append('country', countryInput.value);
+ }
+ break;
+ case 'city':
+ url = '/parks/ajax/cities/';
+ // Add country and region parameters if we're fetching cities
+ const regionInput = document.getElementById(filterParks ? 'region' : 'id_region_name');
+ const cityCountryInput = document.getElementById(filterParks ? 'country' : 'id_country_name');
+ if (regionInput && regionInput.value && cityCountryInput && cityCountryInput.value) {
+ params.append('country', cityCountryInput.value);
+ params.append('region', regionInput.value);
+ }
+ break;
+ }
+
+ if (url) {
+ fetch(`${url}?${params}`)
+ .then(response => response.json())
+ .then(data => {
+ this.suggestions = data;
+ });
+ }
+ },
+ selectSuggestion(suggestion) {
+ this.query = suggestion.name;
+ this.suggestions = [];
+
+ // If this is a form field (not filter), update hidden fields
+ if (!filterParks) {
+ const hiddenField = document.getElementById(`id_${field}`);
+ if (hiddenField) {
+ hiddenField.value = suggestion.id;
+ }
+
+ // Clear dependent fields when parent field changes
+ if (field === 'country') {
+ const regionInput = document.getElementById('id_region_name');
+ const cityInput = document.getElementById('id_city_name');
+ const regionHidden = document.getElementById('id_region');
+ const cityHidden = document.getElementById('id_city');
+
+ if (regionInput) regionInput.value = '';
+ if (cityInput) cityInput.value = '';
+ if (regionHidden) regionHidden.value = '';
+ if (cityHidden) cityHidden.value = '';
+ } else if (field === 'region') {
+ const cityInput = document.getElementById('id_city_name');
+ const cityHidden = document.getElementById('id_city');
+
+ if (cityInput) cityInput.value = '';
+ if (cityHidden) cityHidden.value = '';
+ }
+ }
+
+ // Trigger form submission for filters
+ if (filterParks) {
+ htmx.trigger('#park-filters', 'change');
+ }
+ }
+ };
+}
diff --git a/resources/js/modules/main.js b/resources/js/modules/main.js
new file mode 100644
index 0000000..7aa4430
--- /dev/null
+++ b/resources/js/modules/main.js
@@ -0,0 +1,141 @@
+// Theme handling
+document.addEventListener('DOMContentLoaded', () => {
+ const themeToggle = document.getElementById('theme-toggle');
+ const html = document.documentElement;
+
+ // Initialize toggle state based on current theme
+ if (themeToggle) {
+ themeToggle.checked = html.classList.contains('dark');
+
+ // Handle toggle changes
+ themeToggle.addEventListener('change', function() {
+ const isDark = this.checked;
+ html.classList.toggle('dark', isDark);
+ localStorage.setItem('theme', isDark ? 'dark' : 'light');
+ });
+
+ // Listen for system theme changes
+ const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
+ mediaQuery.addEventListener('change', (e) => {
+ if (!localStorage.getItem('theme')) {
+ const isDark = e.matches;
+ html.classList.toggle('dark', isDark);
+ themeToggle.checked = isDark;
+ }
+ });
+ }
+});
+
+// Handle search form submission
+document.addEventListener('submit', (e) => {
+ if (e.target.matches('form[action*="search"]')) {
+ const searchInput = e.target.querySelector('input[name="q"]');
+ if (!searchInput.value.trim()) {
+ e.preventDefault();
+ }
+ }
+});
+
+// Mobile menu toggle with transitions
+document.addEventListener('DOMContentLoaded', () => {
+ const mobileMenuBtn = document.getElementById('mobileMenuBtn');
+ const mobileMenu = document.getElementById('mobileMenu');
+
+ if (mobileMenuBtn && mobileMenu) {
+ let isMenuOpen = false;
+
+ const toggleMenu = () => {
+ isMenuOpen = !isMenuOpen;
+ mobileMenu.classList.toggle('show', isMenuOpen);
+ mobileMenuBtn.setAttribute('aria-expanded', isMenuOpen.toString());
+
+ // Update icon
+ const icon = mobileMenuBtn.querySelector('i');
+ icon.classList.remove(isMenuOpen ? 'fa-bars' : 'fa-times');
+ icon.classList.add(isMenuOpen ? 'fa-times' : 'fa-bars');
+ };
+
+ mobileMenuBtn.addEventListener('click', toggleMenu);
+
+ // Close menu when clicking outside
+ document.addEventListener('click', (e) => {
+ if (isMenuOpen && !mobileMenu.contains(e.target) && !mobileMenuBtn.contains(e.target)) {
+ toggleMenu();
+ }
+ });
+
+ // Close menu when pressing escape
+ document.addEventListener('keydown', (e) => {
+ if (isMenuOpen && e.key === 'Escape') {
+ toggleMenu();
+ }
+ });
+
+ // Handle viewport changes
+ const mediaQuery = window.matchMedia('(min-width: 1024px)');
+ mediaQuery.addEventListener('change', (e) => {
+ if (e.matches && isMenuOpen) {
+ toggleMenu();
+ }
+ });
+ }
+});
+
+// User dropdown toggle
+const userMenuBtn = document.getElementById('userMenuBtn');
+const userDropdown = document.getElementById('userDropdown');
+
+if (userMenuBtn && userDropdown) {
+ userMenuBtn.addEventListener('click', (e) => {
+ e.stopPropagation();
+ userDropdown.classList.toggle('active');
+ });
+
+ // Close dropdown when clicking outside
+ document.addEventListener('click', (e) => {
+ if (!userMenuBtn.contains(e.target) && !userDropdown.contains(e.target)) {
+ userDropdown.classList.remove('active');
+ }
+ });
+
+ // Close dropdown when pressing escape
+ document.addEventListener('keydown', (e) => {
+ if (e.key === 'Escape') {
+ userDropdown.classList.remove('active');
+ }
+ });
+}
+
+// Handle flash messages
+document.addEventListener('DOMContentLoaded', () => {
+ const alerts = document.querySelectorAll('.alert');
+ alerts.forEach(alert => {
+ setTimeout(() => {
+ alert.style.opacity = '0';
+ setTimeout(() => alert.remove(), 300);
+ }, 5000);
+ });
+});
+
+// Initialize tooltips
+document.addEventListener('DOMContentLoaded', () => {
+ const tooltips = document.querySelectorAll('[data-tooltip]');
+ tooltips.forEach(tooltip => {
+ tooltip.addEventListener('mouseenter', (e) => {
+ const text = e.target.getAttribute('data-tooltip');
+ const tooltipEl = document.createElement('div');
+ tooltipEl.className = 'absolute z-50 px-2 py-1 text-sm text-white bg-gray-900 rounded tooltip';
+ tooltipEl.textContent = text;
+ document.body.appendChild(tooltipEl);
+
+ const rect = e.target.getBoundingClientRect();
+ tooltipEl.style.top = rect.bottom + 5 + 'px';
+ tooltipEl.style.left = rect.left + (rect.width - tooltipEl.offsetWidth) / 2 + 'px';
+ });
+
+ tooltip.addEventListener('mouseleave', () => {
+ const tooltips = document.querySelectorAll('.tooltip');
+ tooltips.forEach(t => t.remove());
+ });
+ });
+});
diff --git a/resources/js/modules/park-map.js b/resources/js/modules/park-map.js
new file mode 100644
index 0000000..cb7f399
--- /dev/null
+++ b/resources/js/modules/park-map.js
@@ -0,0 +1,29 @@
+// Only declare parkMap if it doesn't exist
+window.parkMap = window.parkMap || null;
+
+function initParkMap(latitude, longitude, name) {
+ const mapContainer = document.getElementById('park-map');
+
+ // Only initialize if container exists and map hasn't been initialized
+ if (mapContainer && !window.parkMap) {
+ const width = mapContainer.offsetWidth;
+ mapContainer.style.height = width + 'px';
+
+ window.parkMap = L.map('park-map').setView([latitude, longitude], 13);
+
+ L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
+ attribution: '© OpenStreetMap contributors'
+ }).addTo(window.parkMap);
+
+ L.marker([latitude, longitude])
+ .addTo(window.parkMap)
+ .bindPopup(name);
+
+ // Update map size when window is resized
+ window.addEventListener('resize', function() {
+ const width = mapContainer.offsetWidth;
+ mapContainer.style.height = width + 'px';
+ window.parkMap.invalidateSize();
+ });
+ }
+}
diff --git a/resources/js/modules/photo-gallery.js b/resources/js/modules/photo-gallery.js
new file mode 100644
index 0000000..2705dca
--- /dev/null
+++ b/resources/js/modules/photo-gallery.js
@@ -0,0 +1,91 @@
+document.addEventListener('alpine:init', () => {
+ Alpine.data('photoDisplay', ({ photos, contentType, objectId, csrfToken, uploadUrl }) => ({
+ photos,
+ fullscreenPhoto: null,
+ uploading: false,
+ uploadProgress: 0,
+ error: null,
+ showSuccess: false,
+
+ showFullscreen(photo) {
+ this.fullscreenPhoto = photo;
+ },
+
+ async handleFileSelect(event) {
+ const files = Array.from(event.target.files);
+ if (!files.length) {
+ return;
+ }
+
+ this.uploading = true;
+ this.uploadProgress = 0;
+ this.error = null;
+ this.showSuccess = false;
+
+ const totalFiles = files.length;
+ let completedFiles = 0;
+
+ for (const file of files) {
+ const formData = new FormData();
+ formData.append('image', file);
+ formData.append('app_label', contentType.split('.')[0]);
+ formData.append('model', contentType.split('.')[1]);
+ formData.append('object_id', objectId);
+
+ try {
+ const response = await fetch(uploadUrl, {
+ method: 'POST',
+ headers: {
+ 'X-CSRFToken': csrfToken,
+ },
+ body: formData
+ });
+
+ if (!response.ok) {
+ const data = await response.json();
+ throw new Error(data.error || 'Upload failed');
+ }
+
+ const photo = await response.json();
+ this.photos.push(photo);
+ completedFiles++;
+ this.uploadProgress = (completedFiles / totalFiles) * 100;
+ } catch (err) {
+ this.error = err.message || 'Failed to upload photo. Please try again.';
+ console.error('Upload error:', err);
+ break;
+ }
+ }
+
+ this.uploading = false;
+ event.target.value = ''; // Reset file input
+
+ if (!this.error) {
+ this.showSuccess = true;
+ setTimeout(() => {
+ this.showSuccess = false;
+ }, 3000);
+ }
+ },
+
+ async sharePhoto(photo) {
+ if (navigator.share) {
+ try {
+ await navigator.share({
+ title: photo.caption || 'Shared photo',
+ url: photo.url
+ });
+ } catch (err) {
+ if (err.name !== 'AbortError') {
+ console.error('Error sharing:', err);
+ }
+ }
+ } else {
+ // Fallback: copy URL to clipboard
+ navigator.clipboard.writeText(photo.url)
+ .then(() => alert('Photo URL copied to clipboard!'))
+ .catch(err => console.error('Error copying to clipboard:', err));
+ }
+ }
+ }));
+});
diff --git a/resources/js/modules/search.js b/resources/js/modules/search.js
new file mode 100644
index 0000000..b6589db
--- /dev/null
+++ b/resources/js/modules/search.js
@@ -0,0 +1,42 @@
+function parkSearch() {
+ return {
+ query: '',
+ results: [],
+ loading: false,
+ selectedId: null,
+
+ async search() {
+ if (!this.query.trim()) {
+ this.results = [];
+ return;
+ }
+
+ this.loading = true;
+ try {
+ const response = await fetch(`/parks/suggest_parks/?search=${encodeURIComponent(this.query)}`);
+ const data = await response.json();
+ this.results = data.results;
+ } catch (error) {
+ console.error('Search failed:', error);
+ this.results = [];
+ } finally {
+ this.loading = false;
+ }
+ },
+
+ clear() {
+ this.query = '';
+ this.results = [];
+ this.selectedId = null;
+ },
+
+ selectPark(park) {
+ this.query = park.name;
+ this.selectedId = park.id;
+ this.results = [];
+
+ // Trigger filter update
+ document.getElementById('park-filters').dispatchEvent(new Event('change'));
+ }
+ };
+}
\ No newline at end of file
diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php
new file mode 100644
index 0000000..100e69f
--- /dev/null
+++ b/resources/views/layouts/app.blade.php
@@ -0,0 +1,176 @@
+
+
+
+
+
+
+ @yield('title', 'ThrillWiki')
+
+
+
+
+
+
+
+
+
+
+
+ @vite(['resources/js/app.js', 'resources/css/app.css'])
+
+
+
+
+
+
+ @stack('styles')
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ @auth
+ @if(auth()->user()->can('access-moderation'))
+
+
+ Moderation
+
+ @endif
+
+ @else
+
+
+ @endauth
+
+
+
+
+
+
+
+
+
+ @if (session('status'))
+
+
+ {{ session('status') }}
+
+
+ @endif
+
+
+
+ {{ $slot }}
+
+
+
+
+
+
+
+
© {{ date('Y') }} ThrillWiki. All rights reserved.
+
+
+
+
+
+
+ @stack('scripts')
+
+
diff --git a/resources/views/livewire/auth-menu-component.blade.php b/resources/views/livewire/auth-menu-component.blade.php
new file mode 100644
index 0000000..9948e56
--- /dev/null
+++ b/resources/views/livewire/auth-menu-component.blade.php
@@ -0,0 +1,34 @@
+
\ No newline at end of file
diff --git a/resources/views/livewire/counter.blade.php b/resources/views/livewire/counter.blade.php
index 5bb9931..196d61b 100644
--- a/resources/views/livewire/counter.blade.php
+++ b/resources/views/livewire/counter.blade.php
@@ -1,7 +1,8 @@
-
-
{{ $count }}
-
-
+
-
-
-
+
+
{{ $count }}
+
+
+ +
+ -
+
diff --git a/resources/views/livewire/mobile-menu-component.blade.php b/resources/views/livewire/mobile-menu-component.blade.php
new file mode 100644
index 0000000..6eafe48
--- /dev/null
+++ b/resources/views/livewire/mobile-menu-component.blade.php
@@ -0,0 +1,39 @@
+
\ No newline at end of file
diff --git a/resources/views/livewire/theme-toggle-component.blade.php b/resources/views/livewire/theme-toggle-component.blade.php
new file mode 100644
index 0000000..0358dd1
--- /dev/null
+++ b/resources/views/livewire/theme-toggle-component.blade.php
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/resources/views/livewire/user-menu-component.blade.php b/resources/views/livewire/user-menu-component.blade.php
new file mode 100644
index 0000000..44b3eb3
--- /dev/null
+++ b/resources/views/livewire/user-menu-component.blade.php
@@ -0,0 +1,47 @@
+
+
+ @if(auth()->user()->profile?->avatar)
+
+ @else
+
+ {{ ucfirst(auth()->user()->username[0]) }}
+
+ @endif
+
+
+
+
\ No newline at end of file
diff --git a/routes/web.php b/routes/web.php
index 39a9915..c16a804 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -1,11 +1,57 @@
name('home');
-use App\Livewire\Counter;
-
Route::get('/counter', Counter::class);
-});
+
+// Parks routes
+Route::get('/parks', function () {
+ return 'Parks Index';
+})->name('parks.index');
+
+// Rides routes
+Route::get('/rides', function () {
+ return 'Rides Index';
+})->name('rides.index');
+
+// Auth routes
+Route::get('/login', function () {
+ return 'Login';
+})->name('login');
+
+Route::get('/register', function () {
+ return 'Register';
+})->name('register');
+
+Route::post('/logout', function () {
+ return 'Logout';
+})->name('logout');
+
+// Settings routes
+Route::get('/settings', function () {
+ return 'Settings';
+})->name('settings');
+
+// Legal routes
+Route::get('/terms', function () {
+ return 'Terms';
+})->name('terms');
+
+Route::get('/privacy', function () {
+ return 'Privacy';
+})->name('privacy');
+
+// Profile routes
+Route::get('/profile/{username}', function () {
+ return 'Profile';
+})->name('profile.show');
+
+// Search route
+Route::get('/search', function () {
+ return 'Search';
+})->name('search');
diff --git a/tailwind.config.js b/tailwind.config.js
index ce0c57f..fa502f7 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -1,20 +1,75 @@
-import defaultTheme from 'tailwindcss/defaultTheme';
-
/** @type {import('tailwindcss').Config} */
export default {
- content: [
- './vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php',
- './storage/framework/views/*.php',
- './resources/**/*.blade.php',
- './resources/**/*.js',
- './resources/**/*.vue',
- ],
- theme: {
- extend: {
- fontFamily: {
- sans: ['Figtree', ...defaultTheme.fontFamily.sans],
- },
- },
+ content: [
+ "./resources/**/*.blade.php",
+ "./resources/**/*.js",
+ "./resources/**/*.vue",
+ ],
+ darkMode: 'class',
+ theme: {
+ container: {
+ center: true,
+ padding: {
+ DEFAULT: '1rem',
+ sm: '2rem',
+ lg: '4rem',
+ xl: '5rem',
+ '2xl': '6rem',
+ },
},
- plugins: [],
-};
+ extend: {
+ colors: {
+ primary: {
+ DEFAULT: '#6366f1', // Indigo-500
+ 50: '#eef2ff',
+ 100: '#e0e7ff',
+ 200: '#c7d2fe',
+ 300: '#a5b4fc',
+ 400: '#818cf8',
+ 500: '#6366f1',
+ 600: '#4f46e5',
+ 700: '#4338ca',
+ 800: '#3730a3',
+ 900: '#312e81',
+ 950: '#1e1b4b',
+ },
+ secondary: {
+ DEFAULT: '#8b5cf6', // Violet-500
+ 50: '#f5f3ff',
+ 100: '#ede9fe',
+ 200: '#ddd6fe',
+ 300: '#c4b5fd',
+ 400: '#a78bfa',
+ 500: '#8b5cf6',
+ 600: '#7c3aed',
+ 700: '#6d28d9',
+ 800: '#5b21b6',
+ 900: '#4c1d95',
+ 950: '#2e1065',
+ },
+ },
+ fontFamily: {
+ sans: ['Poppins', 'sans-serif'],
+ },
+ animation: {
+ 'fade-in': 'fadeIn 0.2s ease-in-out',
+ 'fade-out': 'fadeOut 0.2s ease-in-out',
+ },
+ keyframes: {
+ fadeIn: {
+ '0%': { opacity: '0' },
+ '100%': { opacity: '1' },
+ },
+ fadeOut: {
+ '0%': { opacity: '1' },
+ '100%': { opacity: '0' },
+ },
+ },
+ },
+ },
+ plugins: [
+ require('@tailwindcss/forms'),
+ require('@tailwindcss/typography'),
+ require('@tailwindcss/aspect-ratio'),
+ ],
+}
diff --git a/vite.config.js b/vite.config.js
index 421b569..40c15e5 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -4,8 +4,29 @@ import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
- input: ['resources/css/app.css', 'resources/js/app.js'],
+ input: [
+ 'resources/css/app.css',
+ 'resources/js/app.js',
+ ],
refresh: true,
}),
],
+ resolve: {
+ alias: {
+ '@': '/resources/js',
+ },
+ },
+ build: {
+ // Generate source maps for better debugging
+ sourcemap: true,
+ // Optimize dependency bundling
+ rollupOptions: {
+ output: {
+ manualChunks: {
+ // Split vendor chunks for better caching
+ vendor: ['alpinejs'],
+ },
+ },
+ },
+ },
});