diff --git a/history_tracking/apps.py b/history_tracking/apps.py index cf058912..f7f856e2 100644 --- a/history_tracking/apps.py +++ b/history_tracking/apps.py @@ -7,14 +7,20 @@ class HistoryTrackingConfig(AppConfig): name = "history_tracking" def ready(self): + from django.apps import apps from .mixins import HistoricalChangeMixin - from .models import Park - models_with_history = [Park] - - for model in models_with_history: - # Check if mixin is already applied - if HistoricalChangeMixin not in model.history.model.__bases__: - model.history.model.__bases__ = ( - HistoricalChangeMixin, - ) + model.history.model.__bases__ + # Get the Park model + try: + Park = apps.get_model('parks', 'Park') + ParkArea = apps.get_model('parks', 'ParkArea') + + # Apply mixin to historical models + if HistoricalChangeMixin not in Park.history.model.__bases__: + Park.history.model.__bases__ = (HistoricalChangeMixin,) + Park.history.model.__bases__ + + if HistoricalChangeMixin not in ParkArea.history.model.__bases__: + ParkArea.history.model.__bases__ = (HistoricalChangeMixin,) + ParkArea.history.model.__bases__ + except LookupError: + # Models might not be loaded yet + pass diff --git a/history_tracking/mixins.py b/history_tracking/mixins.py index fd81e158..8bee4203 100644 --- a/history_tracking/mixins.py +++ b/history_tracking/mixins.py @@ -2,6 +2,17 @@ class HistoricalChangeMixin: + @property + def prev_record(self): + """Get the previous record for this instance""" + try: + return type(self).objects.filter( + history_date__lt=self.history_date, + id=self.id + ).order_by('-history_date').first() + except (AttributeError, TypeError): + return None + @property def diff_against_previous(self): prev_record = self.prev_record @@ -15,9 +26,14 @@ class HistoricalChangeMixin: "history_id", "history_type", "history_user_id", + "history_change_reason", + "history_type", ] and not field.startswith("_"): - old_value = getattr(prev_record, field) - new_value = getattr(self, field) - if old_value != new_value: - changes[field] = {"old": old_value, "new": new_value} + try: + old_value = getattr(prev_record, field) + new_value = getattr(self, field) + if old_value != new_value: + changes[field] = {"old": old_value, "new": new_value} + except AttributeError: + continue return changes diff --git a/history_tracking/models.py b/history_tracking/models.py index 8fc5524b..eccb2a17 100644 --- a/history_tracking/models.py +++ b/history_tracking/models.py @@ -4,14 +4,11 @@ from simple_history.models import HistoricalRecords from .mixins import HistoricalChangeMixin -class Park(models.Model): - name = models.CharField(max_length=200) - # ... other fields ... - history = HistoricalRecords() +class HistoricalModel(models.Model): + """Abstract base class for models with history tracking""" + class Meta: + abstract = True @property def _history_model(self): return self.history.model - - -# Apply the mixin diff --git a/moderation/mixins.py b/moderation/mixins.py index 80d53de9..4209e570 100644 --- a/moderation/mixins.py +++ b/moderation/mixins.py @@ -202,8 +202,8 @@ class HistoryMixin: context = super().get_context_data(**kwargs) obj = self.get_object() - # Get historical records - context['history'] = obj.history.all().select_related('history_user') + # Get historical records ordered by date + context['history'] = obj.history.all().select_related('history_user').order_by('-history_date') # Get related edit submissions content_type = ContentType.objects.get_for_model(obj) diff --git a/parks/__pycache__/admin.cpython-312.pyc b/parks/__pycache__/admin.cpython-312.pyc index 0a4f4378..3a3bcbc9 100644 Binary files a/parks/__pycache__/admin.cpython-312.pyc and b/parks/__pycache__/admin.cpython-312.pyc differ diff --git a/parks/__pycache__/apps.cpython-312.pyc b/parks/__pycache__/apps.cpython-312.pyc index 318dd6a0..a17e4a50 100644 Binary files a/parks/__pycache__/apps.cpython-312.pyc and b/parks/__pycache__/apps.cpython-312.pyc differ diff --git a/parks/__pycache__/models.cpython-312.pyc b/parks/__pycache__/models.cpython-312.pyc index e2a426ed..3a561457 100644 Binary files a/parks/__pycache__/models.cpython-312.pyc and b/parks/__pycache__/models.cpython-312.pyc differ diff --git a/parks/__pycache__/signals.cpython-312.pyc b/parks/__pycache__/signals.cpython-312.pyc index 19f2d06d..ff678b54 100644 Binary files a/parks/__pycache__/signals.cpython-312.pyc and b/parks/__pycache__/signals.cpython-312.pyc differ diff --git a/parks/admin.py b/parks/admin.py index a161f3ec..21f73e03 100644 --- a/parks/admin.py +++ b/parks/admin.py @@ -33,27 +33,3 @@ class ParkAreaAdmin(SimpleHistoryAdmin): # Register the models with their admin classes admin.site.register(Park, ParkAdmin) admin.site.register(ParkArea, ParkAreaAdmin) - -# Register the historical records for direct editing -from simple_history.models import HistoricalRecords -from .models import Park - -class HistoricalParkAdmin(admin.ModelAdmin): - list_display = ('name', 'formatted_location', 'status', 'history_date', 'history_user', 'history_type') - list_filter = ('status', 'history_type') - search_fields = ('name', 'description') - readonly_fields = ('history_date', 'history_type', 'history_id') - - def formatted_location(self, obj): - """Display formatted location string""" - return obj.instance.formatted_location - formatted_location.short_description = 'Location' - - def has_add_permission(self, request): - return False # Prevent adding new historical records directly - - def has_delete_permission(self, request, obj=None): - return False # Prevent deleting historical records - -# Register the historical model -admin.site.register(Park.history.model, HistoricalParkAdmin) diff --git a/parks/apps.py b/parks/apps.py index 35fe03cd..8971f27f 100644 --- a/parks/apps.py +++ b/parks/apps.py @@ -5,4 +5,4 @@ class ParksConfig(AppConfig): name = 'parks' def ready(self): - import parks.signals # noqa + import parks.signals # Register signals diff --git a/parks/management/commands/update_park_counts.py b/parks/management/commands/update_park_counts.py new file mode 100644 index 00000000..8929cbd6 --- /dev/null +++ b/parks/management/commands/update_park_counts.py @@ -0,0 +1,34 @@ +from django.core.management.base import BaseCommand +from django.db.models import Count, Q +from parks.models import Park + +class Command(BaseCommand): + help = 'Update total_rides and total_roller_coasters counts for all parks' + + def handle(self, *args, **options): + parks = Park.objects.all() + operating_rides = Q(status='OPERATING') + updated = 0 + + for park in parks: + # Count total operating rides + total_rides = park.rides.filter(operating_rides).count() + + # Count total operating roller coasters + total_coasters = park.rides.filter( + operating_rides, + category='RC' + ).count() + + # Update park counts + Park.objects.filter(id=park.id).update( + total_rides=total_rides, + total_roller_coasters=total_coasters + ) + updated += 1 + + self.stdout.write( + self.style.SUCCESS( + f'Successfully updated counts for {updated} parks' + ) + ) diff --git a/parks/migrations/0007_remove_historicalparkarea_history_user_and_more.py b/parks/migrations/0007_remove_historicalparkarea_history_user_and_more.py new file mode 100644 index 00000000..39204c41 --- /dev/null +++ b/parks/migrations/0007_remove_historicalparkarea_history_user_and_more.py @@ -0,0 +1,27 @@ +# Generated by Django 5.1.2 on 2024-11-03 20:26 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("parks", "0006_alter_historicalpark_latitude_and_more"), + ] + + operations = [ + migrations.RemoveField( + model_name="historicalparkarea", + name="history_user", + ), + migrations.RemoveField( + model_name="historicalparkarea", + name="park", + ), + migrations.DeleteModel( + name="HistoricalPark", + ), + migrations.DeleteModel( + name="HistoricalParkArea", + ), + ] diff --git a/parks/migrations/0008_historicalpark_historicalparkarea.py b/parks/migrations/0008_historicalpark_historicalparkarea.py new file mode 100644 index 00000000..ccbaa5ca --- /dev/null +++ b/parks/migrations/0008_historicalpark_historicalparkarea.py @@ -0,0 +1,212 @@ +# Generated by Django 5.1.2 on 2024-11-03 20:38 + +import django.core.validators +import django.db.models.deletion +import history_tracking.mixins +import parks.models +import simple_history.models +from decimal import Decimal +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("companies", "0004_add_total_parks"), + ("parks", "0007_remove_historicalparkarea_history_user_and_more"), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name="HistoricalPark", + fields=[ + ( + "id", + models.BigIntegerField( + auto_created=True, blank=True, db_index=True, verbose_name="ID" + ), + ), + ("name", models.CharField(max_length=255)), + ("slug", models.SlugField(max_length=255)), + ("description", models.TextField(blank=True)), + ( + "status", + models.CharField( + choices=[ + ("OPERATING", "Operating"), + ("CLOSED_TEMP", "Temporarily Closed"), + ("CLOSED_PERM", "Permanently Closed"), + ("UNDER_CONSTRUCTION", "Under Construction"), + ("DEMOLISHED", "Demolished"), + ("RELOCATED", "Relocated"), + ], + default="OPERATING", + max_length=20, + ), + ), + ( + "latitude", + models.DecimalField( + blank=True, + decimal_places=6, + help_text="Latitude coordinate (-90 to 90)", + max_digits=9, + null=True, + validators=[ + django.core.validators.MinValueValidator(Decimal("-90")), + django.core.validators.MaxValueValidator(Decimal("90")), + parks.models.validate_latitude_digits, + ], + ), + ), + ( + "longitude", + models.DecimalField( + blank=True, + decimal_places=6, + help_text="Longitude coordinate (-180 to 180)", + max_digits=10, + null=True, + validators=[ + django.core.validators.MinValueValidator(Decimal("-180")), + django.core.validators.MaxValueValidator(Decimal("180")), + parks.models.validate_longitude_digits, + ], + ), + ), + ("street_address", models.CharField(blank=True, max_length=255)), + ("city", models.CharField(blank=True, max_length=255)), + ("state", models.CharField(blank=True, max_length=255)), + ("country", models.CharField(blank=True, max_length=255)), + ("postal_code", models.CharField(blank=True, max_length=20)), + ("opening_date", models.DateField(blank=True, null=True)), + ("closing_date", models.DateField(blank=True, null=True)), + ("operating_season", models.CharField(blank=True, max_length=255)), + ( + "size_acres", + models.DecimalField( + blank=True, decimal_places=2, max_digits=10, null=True + ), + ), + ("website", models.URLField(blank=True)), + ( + "average_rating", + models.DecimalField( + blank=True, decimal_places=2, max_digits=3, null=True + ), + ), + ("total_rides", models.IntegerField(blank=True, null=True)), + ("total_roller_coasters", models.IntegerField(blank=True, null=True)), + ( + "created_at", + models.DateTimeField(blank=True, editable=False, null=True), + ), + ("updated_at", models.DateTimeField(blank=True, editable=False)), + ("history_id", models.AutoField(primary_key=True, serialize=False)), + ("history_date", models.DateTimeField(db_index=True)), + ("history_change_reason", models.CharField(max_length=100, null=True)), + ( + "history_type", + models.CharField( + choices=[("+", "Created"), ("~", "Changed"), ("-", "Deleted")], + max_length=1, + ), + ), + ( + "history_user", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "owner", + models.ForeignKey( + blank=True, + db_constraint=False, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + related_name="+", + to="companies.company", + ), + ), + ], + options={ + "verbose_name": "historical park", + "verbose_name_plural": "historical parks", + "ordering": ("-history_date", "-history_id"), + "get_latest_by": ("history_date", "history_id"), + }, + bases=( + history_tracking.mixins.HistoricalChangeMixin, + simple_history.models.HistoricalChanges, + models.Model, + ), + ), + migrations.CreateModel( + name="HistoricalParkArea", + fields=[ + ( + "id", + models.BigIntegerField( + auto_created=True, blank=True, db_index=True, verbose_name="ID" + ), + ), + ("name", models.CharField(max_length=255)), + ("slug", models.SlugField(max_length=255)), + ("description", models.TextField(blank=True)), + ("opening_date", models.DateField(blank=True, null=True)), + ("closing_date", models.DateField(blank=True, null=True)), + ( + "created_at", + models.DateTimeField(blank=True, editable=False, null=True), + ), + ("updated_at", models.DateTimeField(blank=True, editable=False)), + ("history_id", models.AutoField(primary_key=True, serialize=False)), + ("history_date", models.DateTimeField(db_index=True)), + ("history_change_reason", models.CharField(max_length=100, null=True)), + ( + "history_type", + models.CharField( + choices=[("+", "Created"), ("~", "Changed"), ("-", "Deleted")], + max_length=1, + ), + ), + ( + "history_user", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "park", + models.ForeignKey( + blank=True, + db_constraint=False, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + related_name="+", + to="parks.park", + ), + ), + ], + options={ + "verbose_name": "historical park area", + "verbose_name_plural": "historical park areas", + "ordering": ("-history_date", "-history_id"), + "get_latest_by": ("history_date", "history_id"), + }, + bases=( + history_tracking.mixins.HistoricalChangeMixin, + simple_history.models.HistoricalChanges, + models.Model, + ), + ), + ] diff --git a/parks/models.py b/parks/models.py index b3f1f95c..ef4396e5 100644 --- a/parks/models.py +++ b/parks/models.py @@ -9,6 +9,7 @@ from simple_history.models import HistoricalRecords from companies.models import Company from media.models import Photo +from history_tracking.models import HistoricalModel def normalize_coordinate(value, max_digits, decimal_places): @@ -53,7 +54,7 @@ def validate_longitude_digits(value): return validate_coordinate_digits(value, 10, 6) -class Park(models.Model): +class Park(HistoricalModel): STATUS_CHOICES = [ ("OPERATING", "Operating"), ("CLOSED_TEMP", "Temporarily Closed"), @@ -176,7 +177,7 @@ class Park(models.Model): raise cls.DoesNotExist() -class ParkArea(models.Model): +class ParkArea(HistoricalModel): park = models.ForeignKey(Park, on_delete=models.CASCADE, related_name="areas") name = models.CharField(max_length=255) slug = models.SlugField(max_length=255) diff --git a/parks/signals.py b/parks/signals.py index e69de29b..b7500852 100644 --- a/parks/signals.py +++ b/parks/signals.py @@ -0,0 +1,35 @@ +from django.db.models.signals import post_save, post_delete +from django.dispatch import receiver +from django.db.models import Count, Q + +from rides.models import Ride +from .models import Park + +def update_park_ride_counts(park): + """Update total_rides and total_roller_coasters for a park""" + operating_rides = Q(status='OPERATING') + + # Count total operating rides + total_rides = park.rides.filter(operating_rides).count() + + # Count total operating roller coasters + total_coasters = park.rides.filter( + operating_rides, + category='RC' + ).count() + + # Update park counts + Park.objects.filter(id=park.id).update( + total_rides=total_rides, + total_roller_coasters=total_coasters + ) + +@receiver(post_save, sender=Ride) +def ride_saved(sender, instance, **kwargs): + """Update park counts when a ride is saved""" + update_park_ride_counts(instance.park) + +@receiver(post_delete, sender=Ride) +def ride_deleted(sender, instance, **kwargs): + """Update park counts when a ride is deleted""" + update_park_ride_counts(instance.park) diff --git a/static/css/tailwind.css b/static/css/tailwind.css index a27ec1c5..c546209c 100644 --- a/static/css/tailwind.css +++ b/static/css/tailwind.css @@ -2237,6 +2237,22 @@ select { grid-column: 1 / -1; } +.col-span-4 { + grid-column: span 4 / span 4; +} + +.col-span-8 { + grid-column: span 8 / span 8; +} + +.col-span-9 { + grid-column: span 9 / span 9; +} + +.col-span-1 { + grid-column: span 1 / span 1; +} + .mx-1 { margin-left: 0.25rem; margin-right: 0.25rem; @@ -2337,6 +2353,14 @@ select { margin-top: auto; } +.mt-0\.5 { + margin-top: 0.125rem; +} + +.mt-8 { + margin-top: 2rem; +} + .block { display: block; } @@ -2405,6 +2429,10 @@ select { height: 100%; } +.h-\[340px\] { + height: 340px; +} + .max-h-60 { max-height: 15rem; } @@ -2421,6 +2449,10 @@ select { min-height: 100vh; } +.min-h-0 { + min-height: 0px; +} + .w-16 { width: 4rem; } @@ -2547,6 +2579,14 @@ select { resize: both; } +.auto-rows-fr { + grid-auto-rows: minmax(0, 1fr); +} + +.auto-rows-min { + grid-auto-rows: min-content; +} + .grid-cols-1 { grid-template-columns: repeat(1, minmax(0, 1fr)); } @@ -2559,6 +2599,14 @@ select { grid-template-columns: repeat(4, minmax(0, 1fr)); } +.grid-cols-3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); +} + +.grid-cols-12 { + grid-template-columns: repeat(12, minmax(0, 1fr)); +} + .flex-col { flex-direction: column; } @@ -2603,6 +2651,37 @@ select { gap: 1.5rem; } +.gap-3 { + gap: 0.75rem; +} + +.gap-8 { + gap: 2rem; +} + +.gap-x-8 { + -moz-column-gap: 2rem; + column-gap: 2rem; +} + +.gap-y-6 { + row-gap: 1.5rem; +} + +.gap-x-6 { + -moz-column-gap: 1.5rem; + column-gap: 1.5rem; +} + +.gap-y-4 { + row-gap: 1rem; +} + +.gap-x-4 { + -moz-column-gap: 1rem; + column-gap: 1rem; +} + .space-x-2 > :not([hidden]) ~ :not([hidden]) { --tw-space-x-reverse: 0; margin-right: calc(0.5rem * var(--tw-space-x-reverse)); @@ -3156,6 +3235,11 @@ select { color: rgb(133 77 14 / var(--tw-text-opacity)); } +.text-green-600 { + --tw-text-opacity: 1; + color: rgb(22 163 74 / var(--tw-text-opacity)); +} + .opacity-0 { opacity: 0; } @@ -3316,6 +3400,12 @@ select { transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } +.hover\:scale-\[1\.02\]:hover { + --tw-scale-x: 1.02; + --tw-scale-y: 1.02; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + .hover\:border-gray-300:hover { --tw-border-opacity: 1; border-color: rgb(209 213 219 / var(--tw-border-opacity)); @@ -3670,6 +3760,11 @@ select { color: rgb(254 252 232 / var(--tw-text-opacity)); } +.dark\:text-green-400:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(74 222 128 / var(--tw-text-opacity)); +} + .dark\:ring-1:is(.dark *) { --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); @@ -3744,10 +3839,22 @@ select { } @media (min-width: 640px) { + .sm\:col-span-2 { + grid-column: span 2 / span 2; + } + + .sm\:col-span-4 { + grid-column: span 4 / span 4; + } + .sm\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } + .sm\:grid-cols-6 { + grid-template-columns: repeat(6, minmax(0, 1fr)); + } + .sm\:space-x-4 > :not([hidden]) ~ :not([hidden]) { --tw-space-x-reverse: 0; margin-right: calc(1rem * var(--tw-space-x-reverse)); @@ -3762,6 +3869,26 @@ select { } @media (min-width: 768px) { + .md\:col-span-2 { + grid-column: span 2 / span 2; + } + + .md\:col-span-3 { + grid-column: span 3 / span 3; + } + + .md\:col-span-9 { + grid-column: span 9 / span 9; + } + + .md\:col-span-4 { + grid-column: span 4 / span 4; + } + + .md\:col-span-8 { + grid-column: span 8 / span 8; + } + .md\:mt-0 { margin-top: 0px; } @@ -3778,6 +3905,14 @@ select { grid-template-columns: repeat(4, minmax(0, 1fr)); } + .md\:grid-cols-8 { + grid-template-columns: repeat(8, minmax(0, 1fr)); + } + + .md\:grid-cols-12 { + grid-template-columns: repeat(12, minmax(0, 1fr)); + } + .md\:flex-row { flex-direction: row; } @@ -3786,6 +3921,10 @@ select { align-items: center; } + .md\:justify-between { + justify-content: space-between; + } + .md\:text-2xl { font-size: 1.5rem; line-height: 2rem; @@ -3806,6 +3945,22 @@ select { grid-column: span 2 / span 2; } + .lg\:col-span-4 { + grid-column: span 4 / span 4; + } + + .lg\:col-span-8 { + grid-column: span 8 / span 8; + } + + .lg\:col-span-3 { + grid-column: span 3 / span 3; + } + + .lg\:col-span-5 { + grid-column: span 5 / span 5; + } + .lg\:mb-0 { margin-bottom: 0px; } @@ -3814,6 +3969,14 @@ select { margin-right: 1.5rem; } + .lg\:ml-8 { + margin-left: 2rem; + } + + .lg\:mt-0 { + margin-top: 0px; + } + .lg\:flex { display: flex; } @@ -3826,6 +3989,10 @@ select { width: 33.333333%; } + .lg\:w-1\/2 { + width: 50%; + } + .lg\:flex-1 { flex: 1 1 0%; } @@ -3838,6 +4005,18 @@ select { grid-template-columns: repeat(4, minmax(0, 1fr)); } + .lg\:grid-cols-12 { + grid-template-columns: repeat(12, minmax(0, 1fr)); + } + + .lg\:grid-cols-5 { + grid-template-columns: repeat(5, minmax(0, 1fr)); + } + + .lg\:grid-cols-6 { + grid-template-columns: repeat(6, minmax(0, 1fr)); + } + .lg\:flex-row { flex-direction: row; } @@ -3855,3 +4034,9 @@ select { line-height: 1; } } + +@media (min-width: 1280px) { + .xl\:grid-cols-4 { + grid-template-columns: repeat(4, minmax(0, 1fr)); + } +} diff --git a/static/js/park-map.js b/static/js/park-map.js new file mode 100644 index 00000000..cb7f399e --- /dev/null +++ b/static/js/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/staticfiles/css/alerts.css b/staticfiles/css/alerts.css new file mode 100644 index 00000000..3b7d4260 --- /dev/null +++ b/staticfiles/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/staticfiles/css/src/input.css b/staticfiles/css/src/input.css new file mode 100644 index 00000000..c0c7d323 --- /dev/null +++ b/staticfiles/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/staticfiles/css/tailwind.css b/staticfiles/css/tailwind.css new file mode 100644 index 00000000..97a1eb47 --- /dev/null +++ b/staticfiles/css/tailwind.css @@ -0,0 +1,3867 @@ +/* +! tailwindcss v3.4.11 | MIT License | https://tailwindcss.com +*/ + +/* +1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) +2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) +*/ + +*, +::before, +::after { + box-sizing: border-box; + /* 1 */ + border-width: 0; + /* 2 */ + border-style: solid; + /* 2 */ + border-color: #e5e7eb; + /* 2 */ +} + +::before, +::after { + --tw-content: ''; +} + +/* +1. Use a consistent sensible line-height in all browsers. +2. Prevent adjustments of font size after orientation changes in iOS. +3. Use a more readable tab size. +4. Use the user's configured `sans` font-family by default. +5. Use the user's configured `sans` font-feature-settings by default. +6. Use the user's configured `sans` font-variation-settings by default. +7. Disable tap highlights on iOS +*/ + +html, +:host { + line-height: 1.5; + /* 1 */ + -webkit-text-size-adjust: 100%; + /* 2 */ + -moz-tab-size: 4; + /* 3 */ + -o-tab-size: 4; + tab-size: 4; + /* 3 */ + font-family: Poppins, sans-serif; + /* 4 */ + font-feature-settings: normal; + /* 5 */ + font-variation-settings: normal; + /* 6 */ + -webkit-tap-highlight-color: transparent; + /* 7 */ +} + +/* +1. Remove the margin in all browsers. +2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. +*/ + +body { + margin: 0; + /* 1 */ + line-height: inherit; + /* 2 */ +} + +/* +1. Add the correct height in Firefox. +2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) +3. Ensure horizontal rules are visible by default. +*/ + +hr { + height: 0; + /* 1 */ + color: inherit; + /* 2 */ + border-top-width: 1px; + /* 3 */ +} + +/* +Add the correct text decoration in Chrome, Edge, and Safari. +*/ + +abbr:where([title]) { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; +} + +/* +Remove the default font size and weight for headings. +*/ + +h1, +h2, +h3, +h4, +h5, +h6 { + font-size: inherit; + font-weight: inherit; +} + +/* +Reset links to optimize for opt-in styling instead of opt-out. +*/ + +a { + color: inherit; + text-decoration: inherit; +} + +/* +Add the correct font weight in Edge and Safari. +*/ + +b, +strong { + font-weight: bolder; +} + +/* +1. Use the user's configured `mono` font-family by default. +2. Use the user's configured `mono` font-feature-settings by default. +3. Use the user's configured `mono` font-variation-settings by default. +4. Correct the odd `em` font sizing in all browsers. +*/ + +code, +kbd, +samp, +pre { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + /* 1 */ + font-feature-settings: normal; + /* 2 */ + font-variation-settings: normal; + /* 3 */ + font-size: 1em; + /* 4 */ +} + +/* +Add the correct font size in all browsers. +*/ + +small { + font-size: 80%; +} + +/* +Prevent `sub` and `sup` elements from affecting the line height in all browsers. +*/ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* +1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) +2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) +3. Remove gaps between table borders by default. +*/ + +table { + text-indent: 0; + /* 1 */ + border-color: inherit; + /* 2 */ + border-collapse: collapse; + /* 3 */ +} + +/* +1. Change the font styles in all browsers. +2. Remove the margin in Firefox and Safari. +3. Remove default padding in all browsers. +*/ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; + /* 1 */ + font-feature-settings: inherit; + /* 1 */ + font-variation-settings: inherit; + /* 1 */ + font-size: 100%; + /* 1 */ + font-weight: inherit; + /* 1 */ + line-height: inherit; + /* 1 */ + letter-spacing: inherit; + /* 1 */ + color: inherit; + /* 1 */ + margin: 0; + /* 2 */ + padding: 0; + /* 3 */ +} + +/* +Remove the inheritance of text transform in Edge and Firefox. +*/ + +button, +select { + text-transform: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Remove default button styles. +*/ + +button, +input:where([type='button']), +input:where([type='reset']), +input:where([type='submit']) { + -webkit-appearance: button; + /* 1 */ + background-color: transparent; + /* 2 */ + background-image: none; + /* 2 */ +} + +/* +Use the modern Firefox focus style for all focusable elements. +*/ + +:-moz-focusring { + outline: auto; +} + +/* +Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-[AWS-SECRET-REMOVED]d494c9be1/layout/style/res/forms.css#L728-L737) +*/ + +:-moz-ui-invalid { + box-shadow: none; +} + +/* +Add the correct vertical alignment in Chrome and Firefox. +*/ + +progress { + vertical-align: baseline; +} + +/* +Correct the cursor style of increment and decrement buttons in Safari. +*/ + +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; +} + +/* +1. Correct the odd appearance in Chrome and Safari. +2. Correct the outline style in Safari. +*/ + +[type='search'] { + -webkit-appearance: textfield; + /* 1 */ + outline-offset: -2px; + /* 2 */ +} + +/* +Remove the inner padding in Chrome and Safari on macOS. +*/ + +::-webkit-search-decoration { + -webkit-appearance: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Change font properties to `inherit` in Safari. +*/ + +::-webkit-file-upload-button { + -webkit-appearance: button; + /* 1 */ + font: inherit; + /* 2 */ +} + +/* +Add the correct display in Chrome and Safari. +*/ + +summary { + display: list-item; +} + +/* +Removes the default spacing and border for appropriate elements. +*/ + +blockquote, +dl, +dd, +h1, +h2, +h3, +h4, +h5, +h6, +hr, +figure, +p, +pre { + margin: 0; +} + +fieldset { + margin: 0; + padding: 0; +} + +legend { + padding: 0; +} + +ol, +ul, +menu { + list-style: none; + margin: 0; + padding: 0; +} + +/* +Reset default styling for dialogs. +*/ + +dialog { + padding: 0; +} + +/* +Prevent resizing textareas horizontally by default. +*/ + +textarea { + resize: vertical; +} + +/* +1. Reset the default placeholder opacity in Firefox. (https://github.[AWS-SECRET-REMOVED]) +2. Set the default placeholder color to the user's configured gray 400 color. +*/ + +input::-moz-placeholder, textarea::-moz-placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +input::placeholder, +textarea::placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +/* +Set the default cursor for buttons. +*/ + +button, +[role="button"] { + cursor: pointer; +} + +/* +Make sure disabled buttons don't get the pointer cursor. +*/ + +:disabled { + cursor: default; +} + +/* +1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) +2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) + This can trigger a poorly considered lint error in some tools but is included by design. +*/ + +img, +svg, +video, +canvas, +audio, +iframe, +embed, +object { + display: block; + /* 1 */ + vertical-align: middle; + /* 2 */ +} + +/* +Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) +*/ + +img, +video { + max-width: 100%; + height: auto; +} + +/* Make elements with the HTML hidden attribute stay hidden by default */ + +[hidden] { + display: none; +} + +[type='text'],input:where(:not([type])),[type='email'],[type='url'],[type='password'],[type='number'],[type='date'],[type='datetime-local'],[type='month'],[type='search'],[type='tel'],[type='time'],[type='week'],[multiple],textarea,select { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background-color: #fff; + border-color: #6b7280; + border-width: 1px; + border-radius: 0px; + padding-top: 0.5rem; + padding-right: 0.75rem; + padding-bottom: 0.5rem; + padding-left: 0.75rem; + font-size: 1rem; + line-height: 1.5rem; + --tw-shadow: 0 0 #0000; +} + +[type='text']:focus, input:where(:not([type])):focus, [type='email']:focus, [type='url']:focus, [type='password']:focus, [type='number']:focus, [type='date']:focus, [type='datetime-local']:focus, [type='month']:focus, [type='search']:focus, [type='tel']:focus, [type='time']:focus, [type='week']:focus, [multiple]:focus, textarea:focus, select:focus { + outline: 2px solid transparent; + outline-offset: 2px; + --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: #2563eb; + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + border-color: #2563eb; +} + +input::-moz-placeholder, textarea::-moz-placeholder { + color: #6b7280; + opacity: 1; +} + +input::placeholder,textarea::placeholder { + color: #6b7280; + opacity: 1; +} + +::-webkit-datetime-edit-fields-wrapper { + padding: 0; +} + +::-webkit-date-and-time-value { + min-height: 1.5em; + text-align: inherit; +} + +::-webkit-datetime-edit { + display: inline-flex; +} + +::-webkit-datetime-edit,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-meridiem-field { + padding-top: 0; + padding-bottom: 0; +} + +select { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e"); + background-position: right 0.5rem center; + background-repeat: no-repeat; + background-size: 1.5em 1.5em; + padding-right: 2.5rem; + -webkit-print-color-adjust: exact; + print-color-adjust: exact; +} + +[multiple],[size]:where(select:not([size="1"])) { + background-image: initial; + background-position: initial; + background-repeat: unset; + background-size: initial; + padding-right: 0.75rem; + -webkit-print-color-adjust: unset; + print-color-adjust: unset; +} + +[type='checkbox'],[type='radio'] { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + padding: 0; + -webkit-print-color-adjust: exact; + print-color-adjust: exact; + display: inline-block; + vertical-align: middle; + background-origin: border-box; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + flex-shrink: 0; + height: 1rem; + width: 1rem; + color: #2563eb; + background-color: #fff; + border-color: #6b7280; + border-width: 1px; + --tw-shadow: 0 0 #0000; +} + +[type='checkbox'] { + border-radius: 0px; +} + +[type='radio'] { + border-radius: 100%; +} + +[type='checkbox']:focus,[type='radio']:focus { + outline: 2px solid transparent; + outline-offset: 2px; + --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: #fff; + --tw-ring-color: #2563eb; + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); +} + +[type='checkbox']:checked,[type='radio']:checked { + border-color: transparent; + background-color: currentColor; + background-size: 100% 100%; + background-position: center; + background-repeat: no-repeat; +} + +[type='checkbox']:checked { + background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e"); +} + +@media (forced-colors: active) { + [type='checkbox']:checked { + -webkit-appearance: auto; + -moz-appearance: auto; + appearance: auto; + } +} + +[type='radio']:checked { + background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e"); +} + +@media (forced-colors: active) { + [type='radio']:checked { + -webkit-appearance: auto; + -moz-appearance: auto; + appearance: auto; + } +} + +[type='checkbox']:checked:hover,[type='checkbox']:checked:focus,[type='radio']:checked:hover,[type='radio']:checked:focus { + border-color: transparent; + background-color: currentColor; +} + +[type='checkbox']:indeterminate { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e"); + border-color: transparent; + background-color: currentColor; + background-size: 100% 100%; + background-position: center; + background-repeat: no-repeat; +} + +@media (forced-colors: active) { + [type='checkbox']:indeterminate { + -webkit-appearance: auto; + -moz-appearance: auto; + appearance: auto; + } +} + +[type='checkbox']:indeterminate:hover,[type='checkbox']:indeterminate:focus { + border-color: transparent; + background-color: currentColor; +} + +[type='file'] { + background: unset; + border-color: inherit; + border-width: 0; + border-radius: 0; + padding: 0; + font-size: unset; + line-height: inherit; +} + +[type='file']:focus { + outline: 1px solid ButtonText; + outline: 1px auto -webkit-focus-ring-color; +} + +*, ::before, ::after { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; + --tw-contain-size: ; + --tw-contain-layout: ; + --tw-contain-paint: ; + --tw-contain-style: ; +} + +::backdrop { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; + --tw-contain-size: ; + --tw-contain-layout: ; + --tw-contain-paint: ; + --tw-contain-style: ; +} + +.container { + width: 100%; +} + +@media (min-width: 640px) { + .container { + max-width: 640px; + } +} + +@media (min-width: 768px) { + .container { + max-width: 768px; + } +} + +@media (min-width: 1024px) { + .container { + max-width: 1024px; + } +} + +@media (min-width: 1280px) { + .container { + max-width: 1280px; + } +} + +@media (min-width: 1536px) { + .container { + max-width: 1536px; + } +} + +.prose { + color: var(--tw-prose-body); + max-width: 65ch; +} + +.prose :where(p):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 1.25em; + margin-bottom: 1.25em; +} + +.prose :where([class~="lead"]):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: var(--tw-prose-lead); + font-size: 1.25em; + line-height: 1.6; + margin-top: 1.2em; + margin-bottom: 1.2em; +} + +.prose :where(a):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: var(--tw-prose-links); + text-decoration: underline; + font-weight: 500; +} + +.prose :where(strong):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: var(--tw-prose-bold); + font-weight: 600; +} + +.prose :where(a strong):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: inherit; +} + +.prose :where(blockquote strong):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: inherit; +} + +.prose :where(thead th strong):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: inherit; +} + +.prose :where(ol):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + list-style-type: decimal; + margin-top: 1.25em; + margin-bottom: 1.25em; + padding-inline-start: 1.625em; +} + +.prose :where(ol[type="A"]):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + list-style-type: upper-alpha; +} + +.prose :where(ol[type="a"]):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + list-style-type: lower-alpha; +} + +.prose :where(ol[type="A" s]):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + list-style-type: upper-alpha; +} + +.prose :where(ol[type="a" s]):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + list-style-type: lower-alpha; +} + +.prose :where(ol[type="I"]):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + list-style-type: upper-roman; +} + +.prose :where(ol[type="i"]):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + list-style-type: lower-roman; +} + +.prose :where(ol[type="I" s]):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + list-style-type: upper-roman; +} + +.prose :where(ol[type="i" s]):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + list-style-type: lower-roman; +} + +.prose :where(ol[type="1"]):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + list-style-type: decimal; +} + +.prose :where(ul):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + list-style-type: disc; + margin-top: 1.25em; + margin-bottom: 1.25em; + padding-inline-start: 1.625em; +} + +.prose :where(ol > li):not(:where([class~="not-prose"],[class~="not-prose"] *))::marker { + font-weight: 400; + color: var(--tw-prose-counters); +} + +.prose :where(ul > li):not(:where([class~="not-prose"],[class~="not-prose"] *))::marker { + color: var(--tw-prose-bullets); +} + +.prose :where(dt):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: var(--tw-prose-headings); + font-weight: 600; + margin-top: 1.25em; +} + +.prose :where(hr):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + border-color: var(--tw-prose-hr); + border-top-width: 1px; + margin-top: 3em; + margin-bottom: 3em; +} + +.prose :where(blockquote):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + font-weight: 500; + font-style: italic; + color: var(--tw-prose-quotes); + border-inline-start-width: 0.25rem; + border-inline-start-color: var(--tw-prose-quote-borders); + quotes: "\201C""\201D""\2018""\2019"; + margin-top: 1.6em; + margin-bottom: 1.6em; + padding-inline-start: 1em; +} + +.prose :where(blockquote p:first-of-type):not(:where([class~="not-prose"],[class~="not-prose"] *))::before { + content: open-quote; +} + +.prose :where(blockquote p:last-of-type):not(:where([class~="not-prose"],[class~="not-prose"] *))::after { + content: close-quote; +} + +.prose :where(h1):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: var(--tw-prose-headings); + font-weight: 800; + font-size: 2.25em; + margin-top: 0; + margin-bottom: 0.8888889em; + line-height: 1.1111111; +} + +.prose :where(h1 strong):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + font-weight: 900; + color: inherit; +} + +.prose :where(h2):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: var(--tw-prose-headings); + font-weight: 700; + font-size: 1.5em; + margin-top: 2em; + margin-bottom: 1em; + line-height: 1.3333333; +} + +.prose :where(h2 strong):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + font-weight: 800; + color: inherit; +} + +.prose :where(h3):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: var(--tw-prose-headings); + font-weight: 600; + font-size: 1.25em; + margin-top: 1.6em; + margin-bottom: 0.6em; + line-height: 1.6; +} + +.prose :where(h3 strong):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + font-weight: 700; + color: inherit; +} + +.prose :where(h4):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: var(--tw-prose-headings); + font-weight: 600; + margin-top: 1.5em; + margin-bottom: 0.5em; + line-height: 1.5; +} + +.prose :where(h4 strong):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + font-weight: 700; + color: inherit; +} + +.prose :where(img):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 2em; + margin-bottom: 2em; +} + +.prose :where(picture):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + display: block; + margin-top: 2em; + margin-bottom: 2em; +} + +.prose :where(video):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 2em; + margin-bottom: 2em; +} + +.prose :where(kbd):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + font-weight: 500; + font-family: inherit; + color: var(--tw-prose-kbd); + box-shadow: 0 0 0 1px rgb(var(--tw-prose-kbd-shadows) / 10%), 0 3px 0 rgb(var(--tw-prose-kbd-shadows) / 10%); + font-size: 0.875em; + border-radius: 0.3125rem; + padding-top: 0.1875em; + padding-inline-end: 0.375em; + padding-bottom: 0.1875em; + padding-inline-start: 0.375em; +} + +.prose :where(code):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: var(--tw-prose-code); + font-weight: 600; + font-size: 0.875em; +} + +.prose :where(code):not(:where([class~="not-prose"],[class~="not-prose"] *))::before { + content: "`"; +} + +.prose :where(code):not(:where([class~="not-prose"],[class~="not-prose"] *))::after { + content: "`"; +} + +.prose :where(a code):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: inherit; +} + +.prose :where(h1 code):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: inherit; +} + +.prose :where(h2 code):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: inherit; + font-size: 0.875em; +} + +.prose :where(h3 code):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: inherit; + font-size: 0.9em; +} + +.prose :where(h4 code):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: inherit; +} + +.prose :where(blockquote code):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: inherit; +} + +.prose :where(thead th code):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: inherit; +} + +.prose :where(pre):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: var(--tw-prose-pre-code); + background-color: var(--tw-prose-pre-bg); + overflow-x: auto; + font-weight: 400; + font-size: 0.875em; + line-height: 1.7142857; + margin-top: 1.7142857em; + margin-bottom: 1.7142857em; + border-radius: 0.375rem; + padding-top: 0.8571429em; + padding-inline-end: 1.1428571em; + padding-bottom: 0.8571429em; + padding-inline-start: 1.1428571em; +} + +.prose :where(pre code):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + background-color: transparent; + border-width: 0; + border-radius: 0; + padding: 0; + font-weight: inherit; + color: inherit; + font-size: inherit; + font-family: inherit; + line-height: inherit; +} + +.prose :where(pre code):not(:where([class~="not-prose"],[class~="not-prose"] *))::before { + content: none; +} + +.prose :where(pre code):not(:where([class~="not-prose"],[class~="not-prose"] *))::after { + content: none; +} + +.prose :where(table):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + width: 100%; + table-layout: auto; + margin-top: 2em; + margin-bottom: 2em; + font-size: 0.875em; + line-height: 1.7142857; +} + +.prose :where(thead):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + border-bottom-width: 1px; + border-bottom-color: var(--tw-prose-th-borders); +} + +.prose :where(thead th):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: var(--tw-prose-headings); + font-weight: 600; + vertical-align: bottom; + padding-inline-end: 0.5714286em; + padding-bottom: 0.5714286em; + padding-inline-start: 0.5714286em; +} + +.prose :where(tbody tr):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + border-bottom-width: 1px; + border-bottom-color: var(--tw-prose-td-borders); +} + +.prose :where(tbody tr:last-child):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + border-bottom-width: 0; +} + +.prose :where(tbody td):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + vertical-align: baseline; +} + +.prose :where(tfoot):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + border-top-width: 1px; + border-top-color: var(--tw-prose-th-borders); +} + +.prose :where(tfoot td):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + vertical-align: top; +} + +.prose :where(th, td):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + text-align: start; +} + +.prose :where(figure > *):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 0; + margin-bottom: 0; +} + +.prose :where(figcaption):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: var(--tw-prose-captions); + font-size: 0.875em; + line-height: 1.4285714; + margin-top: 0.8571429em; +} + +.prose { + --tw-prose-body: #374151; + --tw-prose-headings: #111827; + --tw-prose-lead: #4b5563; + --tw-prose-links: #111827; + --tw-prose-bold: #111827; + --tw-prose-counters: #6b7280; + --tw-prose-bullets: #d1d5db; + --tw-prose-hr: #e5e7eb; + --tw-prose-quotes: #111827; + --tw-prose-quote-borders: #e5e7eb; + --tw-prose-captions: #6b7280; + --tw-prose-kbd: #111827; + --tw-prose-kbd-shadows: 17 24 39; + --tw-prose-code: #111827; + --tw-prose-pre-code: #e5e7eb; + --tw-prose-pre-bg: #1f2937; + --tw-prose-th-borders: #d1d5db; + --tw-prose-td-borders: #e5e7eb; + --tw-prose-invert-body: #d1d5db; + --tw-prose-invert-headings: #fff; + --tw-prose-invert-lead: #9ca3af; + --tw-prose-invert-links: #fff; + --tw-prose-invert-bold: #fff; + --tw-prose-invert-counters: #9ca3af; + --tw-prose-invert-bullets: #4b5563; + --tw-prose-invert-hr: #374151; + --tw-prose-invert-quotes: #f3f4f6; + --tw-prose-invert-quote-borders: #374151; + --tw-prose-invert-captions: #9ca3af; + --tw-prose-invert-kbd: #fff; + --tw-prose-invert-kbd-shadows: 255 255 255; + --tw-prose-invert-code: #fff; + --tw-prose-invert-pre-code: #d1d5db; + --tw-prose-invert-pre-bg: rgb(0 0 0 / 50%); + --tw-prose-invert-th-borders: #4b5563; + --tw-prose-invert-td-borders: #374151; + font-size: 1rem; + line-height: 1.75; +} + +.prose :where(picture > img):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 0; + margin-bottom: 0; +} + +.prose :where(li):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 0.5em; + margin-bottom: 0.5em; +} + +.prose :where(ol > li):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + padding-inline-start: 0.375em; +} + +.prose :where(ul > li):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + padding-inline-start: 0.375em; +} + +.prose :where(.prose > ul > li p):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 0.75em; + margin-bottom: 0.75em; +} + +.prose :where(.prose > ul > li > p:first-child):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 1.25em; +} + +.prose :where(.prose > ul > li > p:last-child):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-bottom: 1.25em; +} + +.prose :where(.prose > ol > li > p:first-child):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 1.25em; +} + +.prose :where(.prose > ol > li > p:last-child):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-bottom: 1.25em; +} + +.prose :where(ul ul, ul ol, ol ul, ol ol):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 0.75em; + margin-bottom: 0.75em; +} + +.prose :where(dl):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 1.25em; + margin-bottom: 1.25em; +} + +.prose :where(dd):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 0.5em; + padding-inline-start: 1.625em; +} + +.prose :where(hr + *):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 0; +} + +.prose :where(h2 + *):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 0; +} + +.prose :where(h3 + *):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 0; +} + +.prose :where(h4 + *):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 0; +} + +.prose :where(thead th:first-child):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + padding-inline-start: 0; +} + +.prose :where(thead th:last-child):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + padding-inline-end: 0; +} + +.prose :where(tbody td, tfoot td):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + padding-top: 0.5714286em; + padding-inline-end: 0.5714286em; + padding-bottom: 0.5714286em; + padding-inline-start: 0.5714286em; +} + +.prose :where(tbody td:first-child, tfoot td:first-child):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + padding-inline-start: 0; +} + +.prose :where(tbody td:last-child, tfoot td:last-child):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + padding-inline-end: 0; +} + +.prose :where(figure):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 2em; + margin-bottom: 2em; +} + +.prose :where(.prose > :first-child):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 0; +} + +.prose :where(.prose > :last-child):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-bottom: 0; +} + +.form-input,.form-textarea,.form-select,.form-multiselect { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background-color: #fff; + border-color: #6b7280; + border-width: 1px; + border-radius: 0px; + padding-top: 0.5rem; + padding-right: 0.75rem; + padding-bottom: 0.5rem; + padding-left: 0.75rem; + font-size: 1rem; + line-height: 1.5rem; + --tw-shadow: 0 0 #0000; +} + +.form-input:focus, .form-textarea:focus, .form-select:focus, .form-multiselect:focus { + outline: 2px solid transparent; + outline-offset: 2px; + --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: #2563eb; + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + border-color: #2563eb; +} + +.form-input::-moz-placeholder, .form-textarea::-moz-placeholder { + color: #6b7280; + opacity: 1; +} + +.form-input::placeholder,.form-textarea::placeholder { + color: #6b7280; + opacity: 1; +} + +.form-input::-webkit-datetime-edit-fields-wrapper { + padding: 0; +} + +.form-input::-webkit-date-and-time-value { + min-height: 1.5em; + text-align: inherit; +} + +.form-input::-webkit-datetime-edit { + display: inline-flex; +} + +.form-input::-webkit-datetime-edit,.form-input::-webkit-datetime-edit-year-field,.form-input::-webkit-datetime-edit-month-field,.form-input::-webkit-datetime-edit-day-field,.form-input::-webkit-datetime-edit-hour-field,.form-input::-webkit-datetime-edit-minute-field,.form-input::-webkit-datetime-edit-second-field,.form-input::-webkit-datetime-edit-millisecond-field,.form-input::-webkit-datetime-edit-meridiem-field { + padding-top: 0; + padding-bottom: 0; +} + +.form-select { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e"); + background-position: right 0.5rem center; + background-repeat: no-repeat; + background-size: 1.5em 1.5em; + padding-right: 2.5rem; + -webkit-print-color-adjust: exact; + print-color-adjust: exact; +} + +.form-select:where([size]:not([size="1"])) { + background-image: initial; + background-position: initial; + background-repeat: unset; + background-size: initial; + padding-right: 0.75rem; + -webkit-print-color-adjust: unset; + print-color-adjust: unset; +} + +.aspect-h-9 { + --tw-aspect-h: 9; +} + +.aspect-w-16 { + position: relative; + padding-bottom: calc(var(--tw-aspect-h) / var(--tw-aspect-w) * 100%); + --tw-aspect-w: 16; +} + +.aspect-w-16 > * { + position: absolute; + height: 100%; + width: 100%; + top: 0; + right: 0; + bottom: 0; + left: 0; +} + +/* Button Styles */ + +.btn-primary { + display: inline-flex; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + align-items: center; + border-radius: 9999px; + border-width: 1px; + border-color: transparent; + background-image: linear-gradient(to right, var(--tw-gradient-stops)); + --tw-gradient-from: #4f46e5 var(--tw-gradient-from-position); + --tw-gradient-to: rgb(79 70 229 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); + --tw-gradient-to: #e11d48 var(--tw-gradient-to-position); + padding-left: 1.5rem; + padding-right: 1.5rem; + padding-top: 0.625rem; + padding-bottom: 0.625rem; + font-size: 0.875rem; + line-height: 1.25rem; + font-weight: 500; + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); + --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + transition-property: all; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.btn-primary:hover { + --tw-scale-x: 1.05; + --tw-scale-y: 1.05; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + --tw-gradient-from: rgb(79 70 229 / 0.9) var(--tw-gradient-from-position); + --tw-gradient-to: rgb(79 70 229 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); + --tw-gradient-to: rgb(225 29 72 / 0.9) var(--tw-gradient-to-position); +} + +.btn-primary:focus { + outline: 2px solid transparent; + outline-offset: 2px; + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-color: rgb(79 70 229 / 0.5); + --tw-ring-offset-width: 2px; +} + +.btn-secondary { + display: inline-flex; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + align-items: center; + border-radius: 9999px; + border-width: 1px; + --tw-border-opacity: 1; + border-color: rgb(229 231 235 / var(--tw-border-opacity)); + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)); + padding-left: 1.5rem; + padding-right: 1.5rem; + padding-top: 0.625rem; + padding-bottom: 0.625rem; + font-size: 0.875rem; + line-height: 1.25rem; + font-weight: 500; + --tw-text-opacity: 1; + color: rgb(55 65 81 / var(--tw-text-opacity)); + --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + transition-property: all; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.btn-secondary:hover { + --tw-scale-x: 1.05; + --tw-scale-y: 1.05; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + --tw-bg-opacity: 1; + background-color: rgb(249 250 251 / var(--tw-bg-opacity)); +} + +.btn-secondary:focus { + outline: 2px solid transparent; + outline-offset: 2px; + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-color: rgb(79 70 229 / 0.5); + --tw-ring-offset-width: 2px; +} + +.btn-secondary:is(.dark *) { + --tw-border-opacity: 1; + border-color: rgb(55 65 81 / var(--tw-border-opacity)); + --tw-bg-opacity: 1; + background-color: rgb(31 41 55 / var(--tw-bg-opacity)); + --tw-text-opacity: 1; + color: rgb(229 231 235 / var(--tw-text-opacity)); +} + +.btn-secondary:hover:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(55 65 81 / var(--tw-bg-opacity)); +} + +/* [Previous styles remain unchanged until mobile menu section...] */ + +/* Mobile Menu */ + +#mobileMenu { + max-height: 0px; + overflow: hidden; + opacity: 0; + transition-property: all; + transition-duration: 300ms; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} + +#mobileMenu.show { + max-height: 300px; + opacity: 1; +} + +#mobileMenu .space-y-4 { + padding-bottom: 1.5rem; +} + +.mobile-nav-link.primary { + background-image: linear-gradient(to right, var(--tw-gradient-stops)); + --tw-gradient-from: #4f46e5 var(--tw-gradient-from-position); + --tw-gradient-to: rgb(79 70 229 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); + --tw-gradient-to: #e11d48 var(--tw-gradient-to-position); + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); +} + +.mobile-nav-link.primary:hover { + --tw-gradient-from: rgb(79 70 229 / 0.9) var(--tw-gradient-from-position); + --tw-gradient-to: rgb(79 70 229 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); + --tw-gradient-to: rgb(225 29 72 / 0.9) var(--tw-gradient-to-position); +} + +.mobile-nav-link.primary i { + margin-right: 0.75rem; + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); +} + +/* 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: #facc15; +} + +/* Navigation Components */ + +.nav-link { + display: flex; + align-items: center; + --tw-text-opacity: 1; + color: rgb(55 65 81 / var(--tw-text-opacity)); + transition-property: all; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.nav-link:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(229 231 235 / var(--tw-text-opacity)); +} + +/* Extra small screens (540px and below) */ + +@media (max-width: 540px) { + .nav-link { + padding-left: 0.5rem; + padding-right: 0.5rem; + padding-top: 0.5rem; + padding-bottom: 0.5rem; + font-size: 0.875rem; + line-height: 1.25rem; + } + + .nav-link i { + margin-right: 0.25rem; + font-size: 1rem; + line-height: 1.5rem; + } + + .nav-link span { + font-size: 0.875rem; + line-height: 1.25rem; + } + + .site-logo { + padding-left: 0.25rem; + padding-right: 0.25rem; + font-size: 1.125rem; + line-height: 1.75rem; + } + + .nav-container { + padding-left: 0.5rem; + padding-right: 0.5rem; + } +} + +/* Small screens (541px to 767px) */ + +@media (min-width: 541px) and (max-width: 767px) { + .nav-link { + padding-left: 0.75rem; + padding-right: 0.75rem; + padding-top: 0.5rem; + padding-bottom: 0.5rem; + } + + .nav-link i { + margin-right: 0.5rem; + } + + .site-logo { + padding-left: 0.5rem; + padding-right: 0.5rem; + font-size: 1.25rem; + line-height: 1.75rem; + } + + .nav-container { + padding-left: 1rem; + padding-right: 1rem; + } +} + +/* Medium screens and up */ + +@media (min-width: 768px) { + .nav-link { + border-radius: 0.5rem; + border-width: 1px; + border-color: transparent; + padding-left: 1.5rem; + padding-right: 1.5rem; + padding-top: 0.625rem; + padding-bottom: 0.625rem; + font-weight: 500; + } + + .nav-link:hover { + border-color: rgb(79 70 229 / 0.2); + } + + .nav-link:hover:is(.dark *) { + border-color: rgb(79 70 229 / 0.3); + } + + .nav-link i { + margin-right: 0.75rem; + font-size: 1.125rem; + line-height: 1.75rem; + } + + .site-logo { + padding-left: 0.75rem; + padding-right: 0.75rem; + font-size: 1.5rem; + line-height: 2rem; + } + + .nav-container { + padding-left: 1.5rem; + padding-right: 1.5rem; + } +} + +.nav-link:hover { + background-color: rgb(79 70 229 / 0.1); + --tw-text-opacity: 1; + color: rgb(79 70 229 / var(--tw-text-opacity)); +} + +.nav-link:hover:is(.dark *) { + background-color: rgb(79 70 229 / 0.2); + --tw-text-opacity: 1; + color: rgb(79 70 229 / var(--tw-text-opacity)); +} + +.nav-link i { + --tw-text-opacity: 1; + color: rgb(107 114 128 / var(--tw-text-opacity)); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.nav-link i:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(156 163 175 / var(--tw-text-opacity)); +} + +.nav-link:hover i { + --tw-text-opacity: 1; + color: rgb(79 70 229 / var(--tw-text-opacity)); +} + +@media (min-width: 1024px) { + #mobileMenu { + display: none !important; + } +} + +/* Menu Items */ + +.menu-item { + display: flex; + width: 100%; + align-items: center; + padding-left: 1rem; + padding-right: 1rem; + padding-top: 0.75rem; + padding-bottom: 0.75rem; + font-size: 0.875rem; + line-height: 1.25rem; + --tw-text-opacity: 1; + color: rgb(55 65 81 / var(--tw-text-opacity)); + transition-property: all; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.menu-item:first-child { + border-top-left-radius: 0.5rem; + border-top-right-radius: 0.5rem; +} + +.menu-item:last-child { + border-bottom-right-radius: 0.5rem; + border-bottom-left-radius: 0.5rem; +} + +.menu-item:hover { + background-color: rgb(79 70 229 / 0.1); + --tw-text-opacity: 1; + color: rgb(79 70 229 / var(--tw-text-opacity)); +} + +.menu-item:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(229 231 235 / var(--tw-text-opacity)); +} + +.menu-item:hover:is(.dark *) { + background-color: rgb(79 70 229 / 0.2); + --tw-text-opacity: 1; + color: rgb(79 70 229 / var(--tw-text-opacity)); +} + +.menu-item i { + margin-right: 0.75rem; + font-size: 1rem; + line-height: 1.5rem; + --tw-text-opacity: 1; + color: rgb(107 114 128 / var(--tw-text-opacity)); +} + +.menu-item i:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(156 163 175 / var(--tw-text-opacity)); +} + +/* Form Components */ + +.form-input { + width: 100%; + border-radius: 0.5rem; + border-width: 1px; + --tw-border-opacity: 1; + border-color: rgb(229 231 235 / var(--tw-border-opacity)); + background-color: rgb(255 255 255 / 0.7); + padding-left: 1rem; + padding-right: 1rem; + padding-top: 0.75rem; + padding-bottom: 0.75rem; + --tw-text-opacity: 1; + color: rgb(17 24 39 / var(--tw-text-opacity)); + --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); + --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + --tw-backdrop-blur: blur(4px); + -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + transition-property: all; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.form-input:focus { + --tw-border-opacity: 1; + border-color: rgb(79 70 229 / var(--tw-border-opacity)); + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-color: rgb(79 70 229 / 0.5); +} + +.form-input:is(.dark *) { + --tw-border-opacity: 1; + border-color: rgb(55 65 81 / var(--tw-border-opacity)); + background-color: rgb(31 41 55 / 0.7); + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); +} + +.form-label { + margin-bottom: 0.375rem; + display: block; + font-size: 0.875rem; + line-height: 1.25rem; + font-weight: 500; + --tw-text-opacity: 1; + color: rgb(55 65 81 / var(--tw-text-opacity)); +} + +.form-label:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(209 213 219 / var(--tw-text-opacity)); +} + +.form-error { + margin-top: 0.5rem; + font-size: 0.875rem; + line-height: 1.25rem; + --tw-text-opacity: 1; + color: rgb(220 38 38 / var(--tw-text-opacity)); +} + +.form-error:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(248 113 113 / var(--tw-text-opacity)); +} + +/* Status Badges */ + +.status-badge { + display: inline-flex; + align-items: center; + border-radius: 9999px; + padding-left: 0.75rem; + padding-right: 0.75rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + font-size: 0.875rem; + line-height: 1.25rem; + font-weight: 500; +} + +.status-operating { + --tw-bg-opacity: 1; + background-color: rgb(220 252 231 / var(--tw-bg-opacity)); + --tw-text-opacity: 1; + color: rgb(22 101 52 / var(--tw-text-opacity)); +} + +.status-operating:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(21 128 61 / var(--tw-bg-opacity)); + --tw-text-opacity: 1; + color: rgb(240 253 244 / var(--tw-text-opacity)); +} + +.status-closed { + --tw-bg-opacity: 1; + background-color: rgb(254 226 226 / var(--tw-bg-opacity)); + --tw-text-opacity: 1; + color: rgb(153 27 27 / var(--tw-text-opacity)); +} + +.status-closed:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(185 28 28 / var(--tw-bg-opacity)); + --tw-text-opacity: 1; + color: rgb(254 242 242 / var(--tw-text-opacity)); +} + +.status-construction { + --tw-bg-opacity: 1; + background-color: rgb(254 249 195 / var(--tw-bg-opacity)); + --tw-text-opacity: 1; + color: rgb(133 77 14 / var(--tw-text-opacity)); +} + +.status-construction:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(202 138 4 / var(--tw-bg-opacity)); + --tw-text-opacity: 1; + color: rgb(254 252 232 / var(--tw-text-opacity)); +} + +/* Auth Components */ + +.auth-card { + margin-left: auto; + margin-right: auto; + width: 100%; + max-width: 28rem; + border-radius: 1rem; + border-width: 1px; + border-color: rgb(229 231 235 / 0.5); + background-color: rgb(255 255 255 / 0.9); + padding: 2rem; + --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + --tw-backdrop-blur: blur(4px); + -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); +} + +.auth-card:is(.dark *) { + border-color: rgb(55 65 81 / 0.5); + background-color: rgb(31 41 55 / 0.9); +} + +.auth-title { + margin-bottom: 2rem; + background-image: linear-gradient(to right, var(--tw-gradient-stops)); + --tw-gradient-from: #4f46e5 var(--tw-gradient-from-position); + --tw-gradient-to: rgb(79 70 229 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); + --tw-gradient-to: #e11d48 var(--tw-gradient-to-position); + -webkit-background-clip: text; + background-clip: text; + text-align: center; + font-size: 1.5rem; + line-height: 2rem; + font-weight: 700; + color: transparent; +} + +.auth-divider { + position: relative; + margin-top: 1.5rem; + margin-bottom: 1.5rem; + text-align: center; +} + +.auth-divider::before, + .auth-divider::after { + position: absolute; + top: 50%; + width: 33.333333%; + border-top-width: 1px; + --tw-border-opacity: 1; + border-color: rgb(229 231 235 / var(--tw-border-opacity)); + --tw-content: ''; + content: var(--tw-content); +} + +.auth-divider:is(.dark *)::before, + .auth-divider:is(.dark *)::after { + --tw-border-opacity: 1; + border-color: rgb(55 65 81 / var(--tw-border-opacity)); +} + +.auth-divider::before { + left: 0px; +} + +.auth-divider::after { + right: 0px; +} + +.auth-divider span { + background-color: rgb(255 255 255 / 0.9); + padding-left: 1rem; + padding-right: 1rem; + font-size: 0.875rem; + line-height: 1.25rem; + --tw-text-opacity: 1; + color: rgb(107 114 128 / var(--tw-text-opacity)); +} + +.auth-divider span:is(.dark *) { + background-color: rgb(31 41 55 / 0.9); + --tw-text-opacity: 1; + color: rgb(156 163 175 / var(--tw-text-opacity)); +} + +/* Social Login Buttons */ + +.btn-social { + margin-bottom: 0.75rem; + display: flex; + width: 100%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + align-items: center; + justify-content: center; + border-radius: 0.5rem; + border-width: 1px; + --tw-border-opacity: 1; + border-color: rgb(229 231 235 / var(--tw-border-opacity)); + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)); + padding-left: 1.5rem; + padding-right: 1.5rem; + padding-top: 0.75rem; + padding-bottom: 0.75rem; + font-size: 0.875rem; + line-height: 1.25rem; + font-weight: 500; + --tw-text-opacity: 1; + color: rgb(55 65 81 / var(--tw-text-opacity)); + --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); + --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + transition-property: all; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.btn-social:hover { + --tw-scale-x: 1.02; + --tw-scale-y: 1.02; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + --tw-bg-opacity: 1; + background-color: rgb(249 250 251 / var(--tw-bg-opacity)); +} + +.btn-social:focus { + outline: 2px solid transparent; + outline-offset: 2px; + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-color: rgb(79 70 229 / 0.5); + --tw-ring-offset-width: 2px; +} + +.btn-social:is(.dark *) { + --tw-border-opacity: 1; + border-color: rgb(55 65 81 / var(--tw-border-opacity)); + --tw-bg-opacity: 1; + background-color: rgb(31 41 55 / var(--tw-bg-opacity)); + --tw-text-opacity: 1; + color: rgb(229 231 235 / var(--tw-text-opacity)); +} + +.btn-social:hover:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(55 65 81 / var(--tw-bg-opacity)); +} + +.btn-discord { + --tw-border-opacity: 1; + border-color: rgb(229 231 235 / var(--tw-border-opacity)); + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)); + --tw-text-opacity: 1; + color: rgb(55 65 81 / var(--tw-text-opacity)); + --tw-shadow-color: rgb(229 231 235 / 0.5); + --tw-shadow: var(--tw-shadow-colored); +} + +.btn-discord:hover { + --tw-bg-opacity: 1; + background-color: rgb(249 250 251 / var(--tw-bg-opacity)); +} + +.btn-discord:is(.dark *) { + --tw-shadow-color: rgb(17 24 39 / 0.5); + --tw-shadow: var(--tw-shadow-colored); +} + +.btn-google { + --tw-border-opacity: 1; + border-color: rgb(229 231 235 / var(--tw-border-opacity)); + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)); + --tw-text-opacity: 1; + color: rgb(55 65 81 / var(--tw-text-opacity)); + --tw-shadow-color: rgb(229 231 235 / 0.5); + --tw-shadow: var(--tw-shadow-colored); +} + +.btn-google:hover { + --tw-bg-opacity: 1; + background-color: rgb(249 250 251 / var(--tw-bg-opacity)); +} + +.btn-google:is(.dark *) { + --tw-shadow-color: rgb(17 24 39 / 0.5); + --tw-shadow: var(--tw-shadow-colored); +} + +/* Alert Components */ + +.alert { + margin-bottom: 1rem; + border-radius: 0.75rem; + padding: 1rem; + --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + --tw-backdrop-blur: blur(4px); + -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); +} + +.alert-error { + border-width: 1px; + --tw-border-opacity: 1; + border-color: rgb(254 202 202 / var(--tw-border-opacity)); + background-color: rgb(254 226 226 / 0.9); + --tw-text-opacity: 1; + color: rgb(153 27 27 / var(--tw-text-opacity)); +} + +.alert-error:is(.dark *) { + --tw-border-opacity: 1; + border-color: rgb(185 28 28 / var(--tw-border-opacity)); + background-color: rgb(153 27 27 / 0.3); + --tw-text-opacity: 1; + color: rgb(254 226 226 / var(--tw-text-opacity)); +} + +/* Layout Components */ + +.card { + border-radius: 0.5rem; + border-width: 1px; + border-color: rgb(229 231 235 / 0.5); + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)); + padding: 1.5rem; + --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.card:is(.dark *) { + border-color: rgb(55 65 81 / 0.5); + --tw-bg-opacity: 1; + background-color: rgb(31 41 55 / var(--tw-bg-opacity)); +} + +/* Typography */ + +/* Turnstile Widget */ + +.turnstile { + margin-top: 1rem; + margin-bottom: 1rem; + display: flex; + align-items: center; + justify-content: center; +} + +.static { + position: static; +} + +.fixed { + position: fixed; +} + +.absolute { + position: absolute; +} + +.relative { + position: relative; +} + +.sticky { + position: sticky; +} + +.inset-0 { + inset: 0px; +} + +.bottom-0 { + bottom: 0px; +} + +.bottom-4 { + bottom: 1rem; +} + +.left-0 { + left: 0px; +} + +.right-0 { + right: 0px; +} + +.right-4 { + right: 1rem; +} + +.top-0 { + top: 0px; +} + +.top-4 { + top: 1rem; +} + +.z-20 { + z-index: 20; +} + +.z-40 { + z-index: 40; +} + +.z-50 { + z-index: 50; +} + +.z-\[60\] { + z-index: 60; +} + +.col-span-2 { + grid-column: span 2 / span 2; +} + +.col-span-3 { + grid-column: span 3 / span 3; +} + +.col-span-full { + grid-column: 1 / -1; +} + +.mx-1 { + margin-left: 0.25rem; + margin-right: 0.25rem; +} + +.mx-4 { + margin-left: 1rem; + margin-right: 1rem; +} + +.mx-8 { + margin-left: 2rem; + margin-right: 2rem; +} + +.mx-auto { + margin-left: auto; + margin-right: auto; +} + +.-mb-px { + margin-bottom: -1px; +} + +.mb-1 { + margin-bottom: 0.25rem; +} + +.mb-12 { + margin-bottom: 3rem; +} + +.mb-2 { + margin-bottom: 0.5rem; +} + +.mb-3 { + margin-bottom: 0.75rem; +} + +.mb-4 { + margin-bottom: 1rem; +} + +.mb-6 { + margin-bottom: 1.5rem; +} + +.mb-8 { + margin-bottom: 2rem; +} + +.ml-1 { + margin-left: 0.25rem; +} + +.ml-2 { + margin-left: 0.5rem; +} + +.ml-6 { + margin-left: 1.5rem; +} + +.mr-1 { + margin-right: 0.25rem; +} + +.mr-2 { + margin-right: 0.5rem; +} + +.mr-3 { + margin-right: 0.75rem; +} + +.mt-1 { + margin-top: 0.25rem; +} + +.mt-2 { + margin-top: 0.5rem; +} + +.mt-3 { + margin-top: 0.75rem; +} + +.mt-4 { + margin-top: 1rem; +} + +.mt-6 { + margin-top: 1.5rem; +} + +.mt-auto { + margin-top: auto; +} + +.block { + display: block; +} + +.inline-block { + display: inline-block; +} + +.flex { + display: flex; +} + +.inline-flex { + display: inline-flex; +} + +.table { + display: table; +} + +.grid { + display: grid; +} + +.hidden { + display: none; +} + +.h-16 { + height: 4rem; +} + +.h-2 { + height: 0.5rem; +} + +.h-2\.5 { + height: 0.625rem; +} + +.h-24 { + height: 6rem; +} + +.h-4 { + height: 1rem; +} + +.h-48 { + height: 12rem; +} + +.h-5 { + height: 1.25rem; +} + +.h-8 { + height: 2rem; +} + +.h-\[300px\] { + height: 300px; +} + +.h-full { + height: 100%; +} + +.max-h-60 { + max-height: 15rem; +} + +.max-h-\[90vh\] { + max-height: 90vh; +} + +.min-h-\[calc\(100vh-16rem\)\] { + min-height: calc(100vh - 16rem); +} + +.min-h-screen { + min-height: 100vh; +} + +.w-16 { + width: 4rem; +} + +.w-24 { + width: 6rem; +} + +.w-32 { + width: 8rem; +} + +.w-4 { + width: 1rem; +} + +.w-5 { + width: 1.25rem; +} + +.w-64 { + width: 16rem; +} + +.w-8 { + width: 2rem; +} + +.w-auto { + width: auto; +} + +.w-fit { + width: -moz-fit-content; + width: fit-content; +} + +.w-full { + width: 100%; +} + +.max-w-2xl { + max-width: 42rem; +} + +.max-w-3xl { + max-width: 48rem; +} + +.max-w-4xl { + max-width: 56rem; +} + +.max-w-7xl { + max-width: 80rem; +} + +.max-w-lg { + max-width: 32rem; +} + +.max-w-md { + max-width: 28rem; +} + +.max-w-none { + max-width: none; +} + +.flex-1 { + flex: 1 1 0%; +} + +.flex-grow { + flex-grow: 1; +} + +.-translate-y-2 { + --tw-translate-y: -0.5rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.-translate-y-full { + --tw-translate-y: -100%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.translate-y-0 { + --tw-translate-y: 0px; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.scale-100 { + --tw-scale-x: 1; + --tw-scale-y: 1; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.scale-95 { + --tw-scale-x: .95; + --tw-scale-y: .95; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.transform { + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} + +.animate-spin { + animation: spin 1s linear infinite; +} + +.cursor-pointer { + cursor: pointer; +} + +.resize { + resize: both; +} + +.grid-cols-1 { + grid-template-columns: repeat(1, minmax(0, 1fr)); +} + +.grid-cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); +} + +.grid-cols-4 { + grid-template-columns: repeat(4, minmax(0, 1fr)); +} + +.flex-col { + flex-direction: column; +} + +.flex-wrap { + flex-wrap: wrap; +} + +.items-start { + align-items: flex-start; +} + +.items-end { + align-items: flex-end; +} + +.items-center { + align-items: center; +} + +.justify-end { + justify-content: flex-end; +} + +.justify-center { + justify-content: center; +} + +.justify-between { + justify-content: space-between; +} + +.gap-2 { + gap: 0.5rem; +} + +.gap-4 { + gap: 1rem; +} + +.gap-6 { + gap: 1.5rem; +} + +.space-x-2 > :not([hidden]) ~ :not([hidden]) { + --tw-space-x-reverse: 0; + margin-right: calc(0.5rem * var(--tw-space-x-reverse)); + margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse))); +} + +.space-x-4 > :not([hidden]) ~ :not([hidden]) { + --tw-space-x-reverse: 0; + margin-right: calc(1rem * var(--tw-space-x-reverse)); + margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse))); +} + +.space-y-1 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.25rem * var(--tw-space-y-reverse)); +} + +.space-y-2 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.5rem * var(--tw-space-y-reverse)); +} + +.space-y-3 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.75rem * var(--tw-space-y-reverse)); +} + +.space-y-4 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(1rem * var(--tw-space-y-reverse)); +} + +.space-y-6 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(1.5rem * var(--tw-space-y-reverse)); +} + +.overflow-auto { + overflow: auto; +} + +.overflow-hidden { + overflow: hidden; +} + +.rounded { + border-radius: 0.25rem; +} + +.rounded-full { + border-radius: 9999px; +} + +.rounded-lg { + border-radius: 0.5rem; +} + +.rounded-md { + border-radius: 0.375rem; +} + +.rounded-l-lg { + border-top-left-radius: 0.5rem; + border-bottom-left-radius: 0.5rem; +} + +.rounded-r-lg { + border-top-right-radius: 0.5rem; + border-bottom-right-radius: 0.5rem; +} + +.rounded-t-lg { + border-top-left-radius: 0.5rem; + border-top-right-radius: 0.5rem; +} + +.border { + border-width: 1px; +} + +.border-2 { + border-width: 2px; +} + +.border-4 { + border-width: 4px; +} + +.border-b { + border-bottom-width: 1px; +} + +.border-b-2 { + border-bottom-width: 2px; +} + +.border-t { + border-top-width: 1px; +} + +.border-dashed { + border-style: dashed; +} + +.border-blue-500 { + --tw-border-opacity: 1; + border-color: rgb(59 130 246 / var(--tw-border-opacity)); +} + +.border-blue-600 { + --tw-border-opacity: 1; + border-color: rgb(37 99 235 / var(--tw-border-opacity)); +} + +.border-gray-200 { + --tw-border-opacity: 1; + border-color: rgb(229 231 235 / var(--tw-border-opacity)); +} + +.border-gray-200\/50 { + border-color: rgb(229 231 235 / 0.5); +} + +.border-gray-300 { + --tw-border-opacity: 1; + border-color: rgb(209 213 219 / var(--tw-border-opacity)); +} + +.border-green-500 { + --tw-border-opacity: 1; + border-color: rgb(34 197 94 / var(--tw-border-opacity)); +} + +.border-red-400 { + --tw-border-opacity: 1; + border-color: rgb(248 113 113 / var(--tw-border-opacity)); +} + +.border-red-500 { + --tw-border-opacity: 1; + border-color: rgb(239 68 68 / var(--tw-border-opacity)); +} + +.border-transparent { + border-color: transparent; +} + +.border-t-transparent { + border-top-color: transparent; +} + +.bg-black { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / var(--tw-bg-opacity)); +} + +.bg-black\/50 { + background-color: rgb(0 0 0 / 0.5); +} + +.bg-blue-100 { + --tw-bg-opacity: 1; + background-color: rgb(219 234 254 / var(--tw-bg-opacity)); +} + +.bg-blue-50 { + --tw-bg-opacity: 1; + background-color: rgb(239 246 255 / var(--tw-bg-opacity)); +} + +.bg-blue-500 { + --tw-bg-opacity: 1; + background-color: rgb(59 130 246 / var(--tw-bg-opacity)); +} + +.bg-blue-600 { + --tw-bg-opacity: 1; + background-color: rgb(37 99 235 / var(--tw-bg-opacity)); +} + +.bg-gray-200 { + --tw-bg-opacity: 1; + background-color: rgb(229 231 235 / var(--tw-bg-opacity)); +} + +.bg-gray-50 { + --tw-bg-opacity: 1; + background-color: rgb(249 250 251 / var(--tw-bg-opacity)); +} + +.bg-green-100 { + --tw-bg-opacity: 1; + background-color: rgb(220 252 231 / var(--tw-bg-opacity)); +} + +.bg-green-500 { + --tw-bg-opacity: 1; + background-color: rgb(34 197 94 / var(--tw-bg-opacity)); +} + +.bg-green-600 { + --tw-bg-opacity: 1; + background-color: rgb(22 163 74 / var(--tw-bg-opacity)); +} + +.bg-red-100 { + --tw-bg-opacity: 1; + background-color: rgb(254 226 226 / var(--tw-bg-opacity)); +} + +.bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); +} + +.bg-red-600 { + --tw-bg-opacity: 1; + background-color: rgb(220 38 38 / var(--tw-bg-opacity)); +} + +.bg-white { + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)); +} + +.bg-white\/10 { + background-color: rgb(255 255 255 / 0.1); +} + +.bg-white\/90 { + background-color: rgb(255 255 255 / 0.9); +} + +.bg-yellow-100 { + --tw-bg-opacity: 1; + background-color: rgb(254 249 195 / var(--tw-bg-opacity)); +} + +.bg-yellow-500 { + --tw-bg-opacity: 1; + background-color: rgb(234 179 8 / var(--tw-bg-opacity)); +} + +.bg-yellow-600 { + --tw-bg-opacity: 1; + background-color: rgb(202 138 4 / var(--tw-bg-opacity)); +} + +.bg-opacity-50 { + --tw-bg-opacity: 0.5; +} + +.bg-opacity-90 { + --tw-bg-opacity: 0.9; +} + +.bg-gradient-to-br { + background-image: linear-gradient(to bottom right, var(--tw-gradient-stops)); +} + +.bg-gradient-to-r { + background-image: linear-gradient(to right, var(--tw-gradient-stops)); +} + +.from-primary { + --tw-gradient-from: #4f46e5 var(--tw-gradient-from-position); + --tw-gradient-to: rgb(79 70 229 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); +} + +.from-white { + --tw-gradient-from: #fff var(--tw-gradient-from-position); + --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); +} + +.via-blue-50 { + --tw-gradient-to: rgb(239 246 255 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), #eff6ff var(--tw-gradient-via-position), var(--tw-gradient-to); +} + +.to-indigo-50 { + --tw-gradient-to: #eef2ff var(--tw-gradient-to-position); +} + +.to-secondary { + --tw-gradient-to: #e11d48 var(--tw-gradient-to-position); +} + +.bg-clip-text { + -webkit-background-clip: text; + background-clip: text; +} + +.object-cover { + -o-object-fit: cover; + object-fit: cover; +} + +.p-2 { + padding: 0.5rem; +} + +.p-3 { + padding: 0.75rem; +} + +.p-4 { + padding: 1rem; +} + +.p-6 { + padding: 1.5rem; +} + +.p-8 { + padding: 2rem; +} + +.px-2 { + padding-left: 0.5rem; + padding-right: 0.5rem; +} + +.px-3 { + padding-left: 0.75rem; + padding-right: 0.75rem; +} + +.px-4 { + padding-left: 1rem; + padding-right: 1rem; +} + +.px-6 { + padding-left: 1.5rem; + padding-right: 1.5rem; +} + +.px-8 { + padding-left: 2rem; + padding-right: 2rem; +} + +.py-1 { + padding-top: 0.25rem; + padding-bottom: 0.25rem; +} + +.py-12 { + padding-top: 3rem; + padding-bottom: 3rem; +} + +.py-16 { + padding-top: 4rem; + padding-bottom: 4rem; +} + +.py-2 { + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} + +.py-3 { + padding-top: 0.75rem; + padding-bottom: 0.75rem; +} + +.py-4 { + padding-top: 1rem; + padding-bottom: 1rem; +} + +.py-6 { + padding-top: 1.5rem; + padding-bottom: 1.5rem; +} + +.py-8 { + padding-top: 2rem; + padding-bottom: 2rem; +} + +.pb-4 { + padding-bottom: 1rem; +} + +.text-center { + text-align: center; +} + +.text-2xl { + font-size: 1.5rem; + line-height: 2rem; +} + +.text-3xl { + font-size: 1.875rem; + line-height: 2.25rem; +} + +.text-4xl { + font-size: 2.25rem; + line-height: 2.5rem; +} + +.text-lg { + font-size: 1.125rem; + line-height: 1.75rem; +} + +.text-sm { + font-size: 0.875rem; + line-height: 1.25rem; +} + +.text-xl { + font-size: 1.25rem; + line-height: 1.75rem; +} + +.text-xs { + font-size: 0.75rem; + line-height: 1rem; +} + +.font-bold { + font-weight: 700; +} + +.font-medium { + font-weight: 500; +} + +.font-semibold { + font-weight: 600; +} + +.text-blue-500 { + --tw-text-opacity: 1; + color: rgb(59 130 246 / var(--tw-text-opacity)); +} + +.text-blue-600 { + --tw-text-opacity: 1; + color: rgb(37 99 235 / var(--tw-text-opacity)); +} + +.text-blue-700 { + --tw-text-opacity: 1; + color: rgb(29 78 216 / var(--tw-text-opacity)); +} + +.text-blue-800 { + --tw-text-opacity: 1; + color: rgb(30 64 175 / var(--tw-text-opacity)); +} + +.text-gray-300 { + --tw-text-opacity: 1; + color: rgb(209 213 219 / var(--tw-text-opacity)); +} + +.text-gray-400 { + --tw-text-opacity: 1; + color: rgb(156 163 175 / var(--tw-text-opacity)); +} + +.text-gray-500 { + --tw-text-opacity: 1; + color: rgb(107 114 128 / var(--tw-text-opacity)); +} + +.text-gray-600 { + --tw-text-opacity: 1; + color: rgb(75 85 99 / var(--tw-text-opacity)); +} + +.text-gray-700 { + --tw-text-opacity: 1; + color: rgb(55 65 81 / var(--tw-text-opacity)); +} + +.text-gray-900 { + --tw-text-opacity: 1; + color: rgb(17 24 39 / var(--tw-text-opacity)); +} + +.text-green-800 { + --tw-text-opacity: 1; + color: rgb(22 101 52 / var(--tw-text-opacity)); +} + +.text-primary { + --tw-text-opacity: 1; + color: rgb(79 70 229 / var(--tw-text-opacity)); +} + +.text-red-500 { + --tw-text-opacity: 1; + color: rgb(239 68 68 / var(--tw-text-opacity)); +} + +.text-red-600 { + --tw-text-opacity: 1; + color: rgb(220 38 38 / var(--tw-text-opacity)); +} + +.text-red-700 { + --tw-text-opacity: 1; + color: rgb(185 28 28 / var(--tw-text-opacity)); +} + +.text-red-800 { + --tw-text-opacity: 1; + color: rgb(153 27 27 / var(--tw-text-opacity)); +} + +.text-transparent { + color: transparent; +} + +.text-white { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); +} + +.text-yellow-400 { + --tw-text-opacity: 1; + color: rgb(250 204 21 / var(--tw-text-opacity)); +} + +.text-yellow-500 { + --tw-text-opacity: 1; + color: rgb(234 179 8 / var(--tw-text-opacity)); +} + +.text-yellow-600 { + --tw-text-opacity: 1; + color: rgb(202 138 4 / var(--tw-text-opacity)); +} + +.text-yellow-800 { + --tw-text-opacity: 1; + color: rgb(133 77 14 / var(--tw-text-opacity)); +} + +.text-green-600 { + --tw-text-opacity: 1; + color: rgb(22 163 74 / var(--tw-text-opacity)); +} + +.opacity-0 { + opacity: 0; +} + +.opacity-100 { + opacity: 1; +} + +.shadow { + --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-lg { + --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-md { + --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-sm { + --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); + --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-xl { + --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.ring-2 { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); +} + +.ring-blue-500 { + --tw-ring-opacity: 1; + --tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity)); +} + +.ring-primary\/20 { + --tw-ring-color: rgb(79 70 229 / 0.2); +} + +.filter { + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); +} + +.backdrop-blur-lg { + --tw-backdrop-blur: blur(16px); + -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); +} + +.transition { + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.transition-all { + transition-property: all; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.transition-colors { + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.transition-opacity { + transition-property: opacity; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.transition-transform { + transition-property: transform; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.duration-100 { + transition-duration: 100ms; +} + +.duration-200 { + transition-duration: 200ms; +} + +.duration-300 { + transition-duration: 300ms; +} + +.duration-75 { + transition-duration: 75ms; +} + +.ease-in { + transition-timing-function: cubic-bezier(0.4, 0, 1, 1); +} + +.ease-out { + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); +} + +.dark\:prose-invert:is(.dark *) { + --tw-prose-body: var(--tw-prose-invert-body); + --tw-prose-headings: var(--tw-prose-invert-headings); + --tw-prose-lead: var(--tw-prose-invert-lead); + --tw-prose-links: var(--tw-prose-invert-links); + --tw-prose-bold: var(--tw-prose-invert-bold); + --tw-prose-counters: var(--tw-prose-invert-counters); + --tw-prose-bullets: var(--tw-prose-invert-bullets); + --tw-prose-hr: var(--tw-prose-invert-hr); + --tw-prose-quotes: var(--tw-prose-invert-quotes); + --tw-prose-quote-borders: var(--tw-prose-invert-quote-borders); + --tw-prose-captions: var(--tw-prose-invert-captions); + --tw-prose-kbd: var(--tw-prose-invert-kbd); + --tw-prose-kbd-shadows: var(--tw-prose-invert-kbd-shadows); + --tw-prose-code: var(--tw-prose-invert-code); + --tw-prose-pre-code: var(--tw-prose-invert-pre-code); + --tw-prose-pre-bg: var(--tw-prose-invert-pre-bg); + --tw-prose-th-borders: var(--tw-prose-invert-th-borders); + --tw-prose-td-borders: var(--tw-prose-invert-td-borders); +} + +.last\:mb-0:last-child { + margin-bottom: 0px; +} + +.hover\:-translate-y-1:hover { + --tw-translate-y: -0.25rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.hover\:translate-x-2:hover { + --tw-translate-x: 0.5rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.hover\:scale-105:hover { + --tw-scale-x: 1.05; + --tw-scale-y: 1.05; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.hover\:border-gray-300:hover { + --tw-border-opacity: 1; + border-color: rgb(209 213 219 / var(--tw-border-opacity)); +} + +.hover\:bg-blue-700:hover { + --tw-bg-opacity: 1; + background-color: rgb(29 78 216 / var(--tw-bg-opacity)); +} + +.hover\:bg-gray-100:hover { + --tw-bg-opacity: 1; + background-color: rgb(243 244 246 / var(--tw-bg-opacity)); +} + +.hover\:bg-gray-300:hover { + --tw-bg-opacity: 1; + background-color: rgb(209 213 219 / var(--tw-bg-opacity)); +} + +.hover\:bg-gray-50:hover { + --tw-bg-opacity: 1; + background-color: rgb(249 250 251 / var(--tw-bg-opacity)); +} + +.hover\:bg-green-700:hover { + --tw-bg-opacity: 1; + background-color: rgb(21 128 61 / var(--tw-bg-opacity)); +} + +.hover\:bg-red-50:hover { + --tw-bg-opacity: 1; + background-color: rgb(254 242 242 / var(--tw-bg-opacity)); +} + +.hover\:bg-red-700:hover { + --tw-bg-opacity: 1; + background-color: rgb(185 28 28 / var(--tw-bg-opacity)); +} + +.hover\:bg-white\/20:hover { + background-color: rgb(255 255 255 / 0.2); +} + +.hover\:bg-yellow-600:hover { + --tw-bg-opacity: 1; + background-color: rgb(202 138 4 / var(--tw-bg-opacity)); +} + +.hover\:text-blue-500:hover { + --tw-text-opacity: 1; + color: rgb(59 130 246 / var(--tw-text-opacity)); +} + +.hover\:text-blue-600:hover { + --tw-text-opacity: 1; + color: rgb(37 99 235 / var(--tw-text-opacity)); +} + +.hover\:text-blue-700:hover { + --tw-text-opacity: 1; + color: rgb(29 78 216 / var(--tw-text-opacity)); +} + +.hover\:text-gray-300:hover { + --tw-text-opacity: 1; + color: rgb(209 213 219 / var(--tw-text-opacity)); +} + +.hover\:text-gray-600:hover { + --tw-text-opacity: 1; + color: rgb(75 85 99 / var(--tw-text-opacity)); +} + +.hover\:text-gray-700:hover { + --tw-text-opacity: 1; + color: rgb(55 65 81 / var(--tw-text-opacity)); +} + +.hover\:text-primary:hover { + --tw-text-opacity: 1; + color: rgb(79 70 229 / var(--tw-text-opacity)); +} + +.hover\:text-primary\/80:hover { + color: rgb(79 70 229 / 0.8); +} + +.hover\:underline:hover { + text-decoration-line: underline; +} + +.focus\:border-blue-500:focus { + --tw-border-opacity: 1; + border-color: rgb(59 130 246 / var(--tw-border-opacity)); +} + +.focus\:underline:focus { + text-decoration-line: underline; +} + +.focus\:outline-none:focus { + outline: 2px solid transparent; + outline-offset: 2px; +} + +.focus\:ring-2:focus { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); +} + +.focus\:ring-blue-500:focus { + --tw-ring-opacity: 1; + --tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity)); +} + +.focus\:ring-primary\/50:focus { + --tw-ring-color: rgb(79 70 229 / 0.5); +} + +.focus\:ring-offset-2:focus { + --tw-ring-offset-width: 2px; +} + +.group:hover .group-hover\:scale-105 { + --tw-scale-x: 1.05; + --tw-scale-y: 1.05; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.group:hover .group-hover\:opacity-100 { + opacity: 1; +} + +.dark\:border-gray-600:is(.dark *) { + --tw-border-opacity: 1; + border-color: rgb(75 85 99 / var(--tw-border-opacity)); +} + +.dark\:border-gray-700:is(.dark *) { + --tw-border-opacity: 1; + border-color: rgb(55 65 81 / var(--tw-border-opacity)); +} + +.dark\:border-gray-700\/50:is(.dark *) { + border-color: rgb(55 65 81 / 0.5); +} + +.dark\:bg-blue-400\/30:is(.dark *) { + background-color: rgb(96 165 250 / 0.3); +} + +.dark\:bg-blue-500:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(59 130 246 / var(--tw-bg-opacity)); +} + +.dark\:bg-blue-700:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(29 78 216 / var(--tw-bg-opacity)); +} + +.dark\:bg-blue-900:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(30 58 138 / var(--tw-bg-opacity)); +} + +.dark\:bg-blue-900\/50:is(.dark *) { + background-color: rgb(30 58 138 / 0.5); +} + +.dark\:bg-gray-600:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(75 85 99 / var(--tw-bg-opacity)); +} + +.dark\:bg-gray-700:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(55 65 81 / var(--tw-bg-opacity)); +} + +.dark\:bg-gray-700\/50:is(.dark *) { + background-color: rgb(55 65 81 / 0.5); +} + +.dark\:bg-gray-800:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(31 41 55 / var(--tw-bg-opacity)); +} + +.dark\:bg-gray-800\/90:is(.dark *) { + background-color: rgb(31 41 55 / 0.9); +} + +.dark\:bg-green-200:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(187 247 208 / var(--tw-bg-opacity)); +} + +.dark\:bg-green-500:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(34 197 94 / var(--tw-bg-opacity)); +} + +.dark\:bg-green-900:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(20 83 45 / var(--tw-bg-opacity)); +} + +.dark\:bg-red-200:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(254 202 202 / var(--tw-bg-opacity)); +} + +.dark\:bg-red-500:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); +} + +.dark\:bg-red-900:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(127 29 29 / var(--tw-bg-opacity)); +} + +.dark\:bg-yellow-400\/30:is(.dark *) { + background-color: rgb(250 204 21 / 0.3); +} + +.dark\:bg-yellow-600:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(202 138 4 / var(--tw-bg-opacity)); +} + +.dark\:bg-yellow-900:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(113 63 18 / var(--tw-bg-opacity)); +} + +.dark\:from-gray-950:is(.dark *) { + --tw-gradient-from: #030712 var(--tw-gradient-from-position); + --tw-gradient-to: rgb(3 7 18 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); +} + +.dark\:via-indigo-950:is(.dark *) { + --tw-gradient-to: rgb(30 27 75 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), #1e1b4b var(--tw-gradient-via-position), var(--tw-gradient-to); +} + +.dark\:to-purple-950:is(.dark *) { + --tw-gradient-to: #3b0764 var(--tw-gradient-to-position); +} + +.dark\:text-blue-200:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(191 219 254 / var(--tw-text-opacity)); +} + +.dark\:text-blue-400:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(96 165 250 / var(--tw-text-opacity)); +} + +.dark\:text-blue-50:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(239 246 255 / var(--tw-text-opacity)); +} + +.dark\:text-blue-500:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(59 130 246 / var(--tw-text-opacity)); +} + +.dark\:text-gray-200:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(229 231 235 / var(--tw-text-opacity)); +} + +.dark\:text-gray-300:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(209 213 219 / var(--tw-text-opacity)); +} + +.dark\:text-gray-400:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(156 163 175 / var(--tw-text-opacity)); +} + +.dark\:text-gray-500:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(107 114 128 / var(--tw-text-opacity)); +} + +.dark\:text-gray-600:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(75 85 99 / var(--tw-text-opacity)); +} + +.dark\:text-green-200:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(187 247 208 / var(--tw-text-opacity)); +} + +.dark\:text-green-900:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(20 83 45 / var(--tw-text-opacity)); +} + +.dark\:text-red-200:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(254 202 202 / var(--tw-text-opacity)); +} + +.dark\:text-red-400:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(248 113 113 / var(--tw-text-opacity)); +} + +.dark\:text-red-800:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(153 27 27 / var(--tw-text-opacity)); +} + +.dark\:text-red-900:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(127 29 29 / var(--tw-text-opacity)); +} + +.dark\:text-white:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); +} + +.dark\:text-yellow-200:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(254 240 138 / var(--tw-text-opacity)); +} + +.dark\:text-yellow-300:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(253 224 71 / var(--tw-text-opacity)); +} + +.dark\:text-yellow-400:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(250 204 21 / var(--tw-text-opacity)); +} + +.dark\:text-yellow-50:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(254 252 232 / var(--tw-text-opacity)); +} + +.dark\:text-green-400:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(74 222 128 / var(--tw-text-opacity)); +} + +.dark\:ring-1:is(.dark *) { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); +} + +.dark\:ring-blue-400\/30:is(.dark *) { + --tw-ring-color: rgb(96 165 250 / 0.3); +} + +.dark\:ring-yellow-400\/30:is(.dark *) { + --tw-ring-color: rgb(250 204 21 / 0.3); +} + +.dark\:hover\:bg-blue-600:hover:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(37 99 235 / var(--tw-bg-opacity)); +} + +.dark\:hover\:bg-blue-800:hover:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(30 64 175 / var(--tw-bg-opacity)); +} + +.dark\:hover\:bg-gray-500:hover:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(107 114 128 / var(--tw-bg-opacity)); +} + +.dark\:hover\:bg-gray-600:hover:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(75 85 99 / var(--tw-bg-opacity)); +} + +.dark\:hover\:bg-gray-700:hover:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(55 65 81 / var(--tw-bg-opacity)); +} + +.dark\:hover\:bg-green-600:hover:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(22 163 74 / var(--tw-bg-opacity)); +} + +.dark\:hover\:bg-red-600:hover:is(.dark *) { + --tw-bg-opacity: 1; + background-color: rgb(220 38 38 / var(--tw-bg-opacity)); +} + +.dark\:hover\:bg-red-900\/20:hover:is(.dark *) { + background-color: rgb(127 29 29 / 0.2); +} + +.dark\:hover\:text-blue-300:hover:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(147 197 253 / var(--tw-text-opacity)); +} + +.dark\:hover\:text-blue-400:hover:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(96 165 250 / var(--tw-text-opacity)); +} + +.dark\:hover\:text-gray-300:hover:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(209 213 219 / var(--tw-text-opacity)); +} + +.dark\:hover\:text-primary:hover:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(79 70 229 / var(--tw-text-opacity)); +} + +@media (min-width: 640px) { + .sm\:grid-cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .sm\:space-x-4 > :not([hidden]) ~ :not([hidden]) { + --tw-space-x-reverse: 0; + margin-right: calc(1rem * var(--tw-space-x-reverse)); + margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse))); + } + + .sm\:space-x-6 > :not([hidden]) ~ :not([hidden]) { + --tw-space-x-reverse: 0; + margin-right: calc(1.5rem * var(--tw-space-x-reverse)); + margin-left: calc(1.5rem * calc(1 - var(--tw-space-x-reverse))); + } +} + +@media (min-width: 768px) { + .md\:mt-0 { + margin-top: 0px; + } + + .md\:grid-cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .md\:grid-cols-3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + + .md\:grid-cols-4 { + grid-template-columns: repeat(4, minmax(0, 1fr)); + } + + .md\:flex-row { + flex-direction: row; + } + + .md\:items-center { + align-items: center; + } + + .md\:text-2xl { + font-size: 1.5rem; + line-height: 2rem; + } + + .md\:text-5xl { + font-size: 3rem; + line-height: 1; + } +} + +@media (min-width: 1024px) { + .lg\:col-span-1 { + grid-column: span 1 / span 1; + } + + .lg\:col-span-2 { + grid-column: span 2 / span 2; + } + + .lg\:mb-0 { + margin-bottom: 0px; + } + + .lg\:mr-6 { + margin-right: 1.5rem; + } + + .lg\:flex { + display: flex; + } + + .lg\:hidden { + display: none; + } + + .lg\:w-1\/3 { + width: 33.333333%; + } + + .lg\:flex-1 { + flex: 1 1 0%; + } + + .lg\:grid-cols-3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + + .lg\:grid-cols-4 { + grid-template-columns: repeat(4, minmax(0, 1fr)); + } + + .lg\:flex-row { + flex-direction: row; + } + + .lg\:items-start { + align-items: flex-start; + } + + .lg\:justify-between { + justify-content: space-between; + } + + .lg\:text-6xl { + font-size: 3.75rem; + line-height: 1; + } +} diff --git a/staticfiles/images/placeholders/dark-ride.jpg b/staticfiles/images/placeholders/dark-ride.jpg new file mode 100644 index 00000000..e69de29b diff --git a/staticfiles/images/placeholders/default-park.jpg b/staticfiles/images/placeholders/default-park.jpg new file mode 100644 index 00000000..e69de29b diff --git a/staticfiles/images/placeholders/default-ride.jpg b/staticfiles/images/placeholders/default-ride.jpg new file mode 100644 index 00000000..e69de29b diff --git a/staticfiles/images/placeholders/flat-ride.jpg b/staticfiles/images/placeholders/flat-ride.jpg new file mode 100644 index 00000000..e69de29b diff --git a/staticfiles/images/placeholders/other-ride.jpg b/staticfiles/images/placeholders/other-ride.jpg new file mode 100644 index 00000000..e69de29b diff --git a/staticfiles/images/placeholders/roller-coaster.jpg b/staticfiles/images/placeholders/roller-coaster.jpg new file mode 100644 index 00000000..e69de29b diff --git a/staticfiles/images/placeholders/transport.jpg b/staticfiles/images/placeholders/transport.jpg new file mode 100644 index 00000000..e69de29b diff --git a/staticfiles/images/placeholders/water-ride.jpg b/staticfiles/images/placeholders/water-ride.jpg new file mode 100644 index 00000000..e69de29b diff --git a/staticfiles/js/alerts.js b/staticfiles/js/alerts.js new file mode 100644 index 00000000..fc054c16 --- /dev/null +++ b/staticfiles/js/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/staticfiles/js/alpine.min.js b/staticfiles/js/alpine.min.js new file mode 100644 index 00000000..a7120970 --- /dev/null +++ b/staticfiles/js/alpine.min.js @@ -0,0 +1,5 @@ +(()=>{var tt=!1,rt=!1,V=[],nt=-1;function Vt(e){Sn(e)}function Sn(e){V.includes(e)||V.push(e),An()}function Ee(e){let t=V.indexOf(e);t!==-1&&t>nt&&V.splice(t,1)}function An(){!rt&&!tt&&(tt=!0,queueMicrotask(On))}function On(){tt=!1,rt=!0;for(let e=0;ee.effect(t,{scheduler:r=>{it?Vt(r):r()}}),ot=e.raw}function st(e){k=e}function Wt(e){let t=()=>{};return[n=>{let i=k(n);return e._x_effects||(e._x_effects=new Set,e._x_runEffects=()=>{e._x_effects.forEach(o=>o())}),e._x_effects.add(i),t=()=>{i!==void 0&&(e._x_effects.delete(i),$(i))},i},()=>{t()}]}function q(e,t,r={}){e.dispatchEvent(new CustomEvent(t,{detail:r,bubbles:!0,composed:!0,cancelable:!0}))}function O(e,t){if(typeof ShadowRoot=="function"&&e instanceof ShadowRoot){Array.from(e.children).forEach(i=>O(i,t));return}let r=!1;if(t(e,()=>r=!0),r)return;let n=e.firstElementChild;for(;n;)O(n,t,!1),n=n.nextElementSibling}function v(e,...t){console.warn(`Alpine Warning: ${e}`,...t)}var Gt=!1;function Jt(){Gt&&v("Alpine has already been initialized on this page. Calling Alpine.start() more than once can cause problems."),Gt=!0,document.body||v("Unable to initialize. Trying to load Alpine before `` is available. Did you forget to add `defer` in Alpine's ` +
- -
-
-
-
-
-

{{ park.name }}

- {% if park.city or park.state or park.country %} - {% spaceless %} -

- {% if park.city %}{{ park.city }}{% endif %}{% if park.city and park.state %}, {% endif %}{% if park.state %}{{ park.state }}{% endif %}{% if park.country and park.state or park.city %}, {% endif %}{% if park.country %}{{ park.country }}{% endif %} -

- {% endspaceless %} - {% endif %} -
- {% if user.is_authenticated %} -
- - Edit - - {% if perms.media.add_photo %} - - {% endif %} -
- {% endif %} -
-
- - {{ park.get_status_display }} - - {% if park.average_rating %} - - - {{ park.average_rating|floatformat:1 }}/10 - - {% endif %} + + {% if user.is_authenticated %} +
+ + Edit + + {% if perms.media.add_photo %} + + {% endif %} +
+ {% endif %} + + +
+ +
+

{{ park.name }}

+ + {% if park.formatted_location %} +
+ +

{{ park.formatted_location }}

+
+ {% endif %} + +
+ + {{ park.get_status_display }} + + {% if park.average_rating %} + + + {{ park.average_rating|floatformat:1 }}/10 + + {% endif %} +
+
+ + +
+ +
+ + {% if park.total_rides %} + +
Total Rides
+
{{ park.total_rides }}
+
+ {% endif %} + + + {% if park.total_roller_coasters %} +
+
Total Roller Coasters
+
{{ park.total_roller_coasters }}
+ {% endif %}
- -
-
- {% if park.owner %} -
-
Owner/Operator
-
- - {{ park.owner.name }} - -
-
- {% endif %} - {% if park.opening_date %} -
-
Opening Date
-
{{ park.opening_date }}
-
- {% endif %} - {% if park.operating_season %} -
-
Operating Season
-
{{ park.operating_season }}
-
- {% endif %} - {% if park.size_acres %} -
-
Size
-
{{ park.size_acres }} acres
-
- {% endif %} - {% if park.total_rides %} -
-
Total Rides
-
{{ park.total_rides }}
-
- {% endif %} - {% if park.total_roller_coasters %} -
-
Roller Coasters
-
{{ park.total_roller_coasters }}
-
- {% endif %} - {% if park.website %} -
-
Website
-
- - Official Website - -
-
- {% endif %} -
+ +
+ {% if park.owner %} +
+ +
Owner/Operator
+
+ + {{ park.owner.name }} + +
+
+ {% endif %} + + {% if park.opening_date %} +
+ +
Opening Date
+
{{ park.opening_date }}
+
+ {% endif %} + + {% if park.operating_season %} +
+ +
Operating Season
+
{{ park.operating_season }}
+
+ {% endif %} + + {% if park.size_acres %} +
+ +
Size
+
{{ park.size_acres }} acres
+
+ {% endif %} + + {% if park.website %} +
+ +
Website
+
+ + Official Website + + +
+
+ {% endif %}
- {% if park.photos.exists %}
@@ -171,7 +204,7 @@ {% if park.latitude and park.longitude %}

Location

-
+
{% endif %} @@ -189,10 +222,14 @@
{% for field, changes in record.diff_against_previous.items %} -
- {{ field }}: - {{ changes.old }} → {{ changes.new }} -
+ {% if field != "updated_at" %} +
+ {{ field|title }}: + {{ changes.old }} + + {{ changes.new }} +
+ {% endif %} {% endfor %}
@@ -203,12 +240,18 @@
-
{% if perms.media.add_photo %} -
@@ -227,37 +270,13 @@ {% if park.latitude and park.longitude %} {% block extra_js %} + {% endblock %} {% endif %} -{% block extra_head %} -{% if park.latitude and park.longitude %} - -{% endif %} -{% endblock %} {% endblock %}