diff --git a/assets/mobile.css b/assets/mobile.css
index 4a31874..7d7d2dd 100644
--- a/assets/mobile.css
+++ b/assets/mobile.css
@@ -73,6 +73,14 @@
--color-ice: #14b8e8;
--color-ice-ink: #04212c;
+ /* Referee sign-up accent -- deliberately distinct from game/training/other's
+ club-red/info-blue/warn-amber (mobile/_calendar_row.html) so a "needs a
+ referee" row stands out from the member's own RSVP rows at a glance. */
+ --color-referee: #7c4dff;
+ --color-referee-bg: #f1ecff;
+ --color-referee-border: #d9caff;
+ --color-referee-text: #5b2fd6;
+
--color-row-sel: #fff7f8;
--color-row-focus: #f4f9ff;
--color-row-warn: #fffdf6;
@@ -393,6 +401,12 @@
border: 1px solid #dde1e7;
}
+ .pill-referee {
+ background: var(--color-referee-bg);
+ color: var(--color-referee-text);
+ border: 1px solid var(--color-referee-border);
+ }
+
/* --- Person switcher chips (Home's own -- see mobile/templates/mobile/home.html) --- */
.person-chip {
diff --git a/events/admin.py b/events/admin.py
index 80f2e9b..40552a0 100644
--- a/events/admin.py
+++ b/events/admin.py
@@ -2,7 +2,7 @@ from django import forms
from django.contrib import admin
from django.utils.translation import gettext_lazy as _
-from .models import Attendance, Competition, Event, EventReferee, EventSeries, Lineup, LineupSelection, Location, Opponent
+from .models import Attendance, Competition, Event, EventReferee, EventSeries, Lineup, LineupSelection, Location, Opponent, RefereeSignup
@admin.register(Opponent)
@@ -138,3 +138,11 @@ class EventRefereeAdmin(admin.ModelAdmin):
@admin.display(description=_("total payable"))
def total_payable(self, obj):
return obj.total_payable
+
+
+@admin.register(RefereeSignup)
+class RefereeSignupAdmin(admin.ModelAdmin):
+ list_display = ["event", "member", "status", "responded_at"]
+ list_filter = ["status"]
+ search_fields = ["event__title", "member__first_name", "member__last_name"]
+ raw_id_fields = ["event", "member"]
diff --git a/events/migrations/0026_refereesignup.py b/events/migrations/0026_refereesignup.py
new file mode 100644
index 0000000..cfc895c
--- /dev/null
+++ b/events/migrations/0026_refereesignup.py
@@ -0,0 +1,34 @@
+# Generated by Django 6.0.6 on 2026-08-22 14:32
+
+import django.db.models.deletion
+import uuid
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('events', '0025_remove_lineupunit_lineup_lineupselection_and_more'),
+ ('members', '0006_parentclaim_submitted_by_user'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='RefereeSignup',
+ fields=[
+ ('created', models.DateTimeField(auto_now_add=True, verbose_name='created')),
+ ('modified', models.DateTimeField(auto_now=True, verbose_name='modified')),
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
+ ('status', models.CharField(choices=[('invited', 'invited'), ('accepted', 'accepted'), ('declined', 'declined')], default='invited', max_length=20, verbose_name='status')),
+ ('responded_at', models.DateTimeField(blank=True, null=True, verbose_name='responded at')),
+ ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='referee_signups', to='events.event', verbose_name='event')),
+ ('member', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='referee_signups', to='members.member', verbose_name='member')),
+ ],
+ options={
+ 'verbose_name': 'referee sign-up',
+ 'verbose_name_plural': 'referee sign-ups',
+ 'ordering': ['event', 'member__last_name', 'member__first_name'],
+ 'constraints': [models.UniqueConstraint(fields=('event', 'member'), name='unique_referee_signup_per_event_per_member')],
+ },
+ ),
+ ]
diff --git a/events/models.py b/events/models.py
index 8ccd8c9..0551a36 100644
--- a/events/models.py
+++ b/events/models.py
@@ -304,6 +304,42 @@ class EventReferee(UUIDModel):
return (self.fee or Decimal("0")) + self.km_total
+class RefereeSignup(UUIDModel):
+ """One eligible referee's invite/response for one home game -- the
+ self-service counterpart to admin assignment (EventReferee). Created
+ automatically (events.services.referees.sync_referee_invites, wired from
+ events/signals.py) the moment a home game needs a club-arranged referee,
+ for every currently-eligible member (teams.RefereeProfile). Accepting
+ (events.services.referees.accept_referee_signup) creates a real
+ EventReferee row via the same capacity-checked assign_referee every admin
+ assignment goes through (assigned_by=None marks it self-service) -- this
+ table only ever tracks the invite/response, never payment/capacity, so
+ the desktop referee-management screen stays the single source of truth
+ for who's actually refereeing.
+ """
+
+ class Status(models.TextChoices):
+ INVITED = "invited", _("invited")
+ ACCEPTED = "accepted", _("accepted")
+ DECLINED = "declined", _("declined")
+
+ event = models.ForeignKey(Event, on_delete=models.CASCADE, related_name="referee_signups", verbose_name=_("event"))
+ member = models.ForeignKey(Member, on_delete=models.CASCADE, related_name="referee_signups", verbose_name=_("member"))
+ status = models.CharField(_("status"), max_length=20, choices=Status.choices, default=Status.INVITED)
+ responded_at = models.DateTimeField(_("responded at"), null=True, blank=True)
+
+ class Meta:
+ verbose_name = _("referee sign-up")
+ verbose_name_plural = _("referee sign-ups")
+ ordering = ["event", "member__last_name", "member__first_name"]
+ constraints = [
+ models.UniqueConstraint(fields=["event", "member"], name="unique_referee_signup_per_event_per_member"),
+ ]
+
+ def __str__(self):
+ return f"{self.event} - {self.member} ({self.status})"
+
+
class Competition(models.Model):
"""A competition has a name with a specific URL to fetch data from. These are managed centrally."""
diff --git a/events/services/referees.py b/events/services/referees.py
index 659ffd7..13a406a 100644
--- a/events/services/referees.py
+++ b/events/services/referees.py
@@ -27,9 +27,10 @@ from django.db import transaction
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
-from events.models import ASSUMED_EVENT_DURATION, Event, EventReferee
+from events.models import ASSUMED_EVENT_DURATION, Event, EventReferee, RefereeSignup
from events.services.attendance import effective_members
from members.models import Member
+from notifications.services import notify_members
from teams.models import RefereeLevel, Team
@@ -147,3 +148,56 @@ def set_referee_fee(referee, *, fee=None, km=None, km_rate=None):
referee.km_rate = km_rate
referee.save(update_fields=["fee", "km", "km_rate"])
return referee
+
+
+def sync_referee_invites(event):
+ """Invites every currently-eligible, not-yet-invited referee to `event` --
+ the referee-facing counterpart to events.sync_event_attendances, wired
+ from the same signal points (events/signals.py's post_save(Event) and
+ the Event.teams m2m). Idempotent: only creates rows for members with no
+ RefereeSignup at all yet for this event, so an unrelated edit (or a
+ second team added later) never re-notifies someone who already
+ responded -- or re-invites someone who already said no."""
+ if not needs_referee_management(event):
+ return []
+
+ already_invited_ids = set(RefereeSignup.objects.filter(event=event).values_list("member_id", flat=True))
+ new_members = [member for member in eligible_referees(event) if member.pk not in already_invited_ids]
+ if not new_members:
+ return []
+
+ RefereeSignup.objects.bulk_create([RefereeSignup(event=event, member=member) for member in new_members])
+ body = _("%(event)s needs a referee -- can you take it?") % {"event": event.title}
+ notify_members(new_members, club=event.club, title=_("Referee needed"), body=body, source=event)
+ return new_members
+
+
+@transaction.atomic
+def accept_referee_signup(signup):
+ """Confirms `signup`'s member as an actual referee for the game --
+ routed through the exact same assign_referee every admin assignment
+ uses (assigned_by=None marks it self-service), so capacity is enforced
+ once, in one place, and the desktop referee-management screen sees the
+ new assignment with no separate sync step. Raises RefereeAssignmentError
+ unchanged if the game's already full -- `signup` is left INVITED so the
+ referee can retry if a slot frees up."""
+ assign_referee(signup.event, signup.member, assigned_by=None)
+ signup.status = RefereeSignup.Status.ACCEPTED
+ signup.responded_at = timezone.now()
+ signup.save(update_fields=["status", "responded_at"])
+ return signup
+
+
+@transaction.atomic
+def decline_referee_signup(signup):
+ """Declines `signup`. If they'd already accepted, also removes their
+ self-service EventReferee row (assigned_by is None -- never touches an
+ admin-made assignment for the same member/event, though assign_referee's
+ own "already assigned" guard makes that pairing impossible anyway) so
+ the desktop screen stops counting someone who's since said they can't
+ make it after all."""
+ EventReferee.objects.filter(event=signup.event, member=signup.member, assigned_by__isnull=True).delete()
+ signup.status = RefereeSignup.Status.DECLINED
+ signup.responded_at = timezone.now()
+ signup.save(update_fields=["status", "responded_at"])
+ return signup
diff --git a/events/signals.py b/events/signals.py
index 05e5468..b8ef3d7 100644
--- a/events/signals.py
+++ b/events/signals.py
@@ -21,6 +21,7 @@ from django.utils.translation import gettext_lazy as _
from club.models import ClubMembership
from events.models import Event, EventSeries
from events.services import sync_event_attendances
+from events.services.referees import sync_referee_invites
from members.models import Group, GroupMembership
from teams.models import Team, TeamMembership
@@ -50,6 +51,7 @@ def validate_groups_same_club(sender, instance, action, reverse, pk_set, **kwarg
@receiver(post_save, sender=Event)
def sync_on_event_save(sender, instance, **kwargs):
sync_event_attendances(instance)
+ sync_referee_invites(instance)
@receiver(m2m_changed, sender=Event.teams.through)
@@ -68,6 +70,18 @@ def sync_on_audience_change(sender, instance, action, reverse, model, pk_set, **
sync_event_attendances(event)
+@receiver(m2m_changed, sender=Event.teams.through)
+def sync_referee_invites_on_teams_change(sender, instance, action, reverse, **kwargs):
+ # Referee eligibility only depends on `teams` (needs_referee_management),
+ # not groups/invited/excluded_members -- a separate, narrower receiver
+ # rather than folding into sync_on_audience_change above, which is about
+ # attendance specifically. reverse (team.scheduled_events.add(...)) isn't
+ # a used path -- see validate_teams_same_club's own comment.
+ if action not in M2M_SYNC_ACTIONS or reverse or not isinstance(instance, Event):
+ return
+ sync_referee_invites(instance)
+
+
@receiver(post_save, sender=TeamMembership)
@receiver(post_delete, sender=TeamMembership)
def sync_on_roster_change(sender, instance, **kwargs):
diff --git a/events/tests.py b/events/tests.py
index d386dad..ffde616 100644
--- a/events/tests.py
+++ b/events/tests.py
@@ -19,7 +19,7 @@ from notifications.models import Notification
from teams.models import Position, RefereeLevel, RefereeProfile, StaffAssignment, Team, TeamMembership
from .admin import EventAdminForm
-from .models import Attendance, Competition, Event, EventReferee, EventSeries, Lineup, LineupSelection, Location, Opponent
+from .models import Attendance, Competition, Event, EventReferee, EventSeries, Lineup, LineupSelection, Location, Opponent, RefereeSignup
from .services import (
cancel_occurrence,
detach_occurrence,
@@ -36,7 +36,19 @@ from .services import (
from .services.calendar import add_months, month_bounds, month_grid, season_grid, week_bounds, week_grid
from .services.lineup import notify_dropout, publish_lineup, selected_members_by_position, toggle_selection
from .services.rbihf_import import RBIHFImportError, apply_plan, build_plan, extract_team_id, parse_fixtures, suggested_location, suggested_opponent
-from .services.referees import RefereeAssignmentError, add_external_referee, assign_referee, conflicting_events, eligible_referees, needs_referee_management, remove_referee, set_referee_fee
+from .services.referees import (
+ RefereeAssignmentError,
+ accept_referee_signup,
+ add_external_referee,
+ assign_referee,
+ conflicting_events,
+ decline_referee_signup,
+ eligible_referees,
+ needs_referee_management,
+ remove_referee,
+ set_referee_fee,
+ sync_referee_invites,
+)
from .tasks import send_deadline_reminders
@@ -1488,6 +1500,109 @@ class RefereeServiceTests(EventsTestBase):
self.assertEqual(assignment.total_payable, Decimal("25.00"))
+class RefereeSignupServiceTests(EventsTestBase):
+ """events.services.referees.sync_referee_invites/accept_referee_signup/
+ decline_referee_signup -- the self-service sign-up flow, layered on top
+ of the same assign_referee/eligible_referees the admin flow uses."""
+
+ @classmethod
+ def setUpTestData(cls):
+ super().setUpTestData()
+ cls.home_ground = Location.objects.create(club=cls.club, name="Home Ground", address="1 St", city="Town", zip_code="1000", country="BE", is_home=True)
+ cls.level = RefereeLevel.objects.create(club=cls.club, name="Regional")
+ cls.level.teams.add(cls.team)
+ cls.referee = Member.objects.create(first_name="Ref", last_name="Eree")
+ cls.referee_profile = RefereeProfile.objects.create(member=cls.referee, level=cls.level, valid_until=timezone.localdate() + timedelta(days=30))
+
+ def make_home_game(self, **kwargs):
+ kwargs.setdefault("kind", Event.EventKind.GAME)
+ kwargs.setdefault("location", self.home_ground)
+ event = self.make_event(**kwargs)
+ event.teams.add(self.team)
+ return event
+
+ def test_creating_a_home_game_invites_eligible_referees(self):
+ # sync_referee_invites is wired from events/signals.py's post_save(Event)
+ # -- make_home_game's own .save() (via make_event) already triggers it.
+ game = self.make_home_game()
+
+ self.assertTrue(RefereeSignup.objects.filter(event=game, member=self.referee, status=RefereeSignup.Status.INVITED).exists())
+
+ def test_creating_a_home_game_notifies_eligible_referees(self):
+ self.make_home_game()
+
+ self.assertTrue(Notification.objects.filter(member=self.referee, title="Referee needed").exists())
+
+ def test_sync_does_not_reinvite_someone_who_already_responded(self):
+ game = self.make_home_game()
+ signup = RefereeSignup.objects.get(event=game, member=self.referee)
+ signup.status = RefereeSignup.Status.DECLINED
+ signup.responded_at = timezone.now()
+ signup.save()
+
+ sync_referee_invites(game)
+
+ signup.refresh_from_db()
+ self.assertEqual(signup.status, RefereeSignup.Status.DECLINED)
+
+ def test_sync_is_a_noop_for_an_away_game(self):
+ away_ground = Location.objects.create(club=self.club, name="Away Ground", address="2 St", city="Town", zip_code="1000", country="BE")
+ game = self.make_home_game(location=away_ground)
+
+ self.assertFalse(RefereeSignup.objects.filter(event=game).exists())
+
+ def test_accept_creates_a_real_event_referee_assignment(self):
+ game = self.make_home_game()
+ signup = RefereeSignup.objects.get(event=game, member=self.referee)
+
+ accept_referee_signup(signup)
+
+ assignment = EventReferee.objects.get(event=game, member=self.referee)
+ self.assertIsNone(assignment.assigned_by)
+ signup.refresh_from_db()
+ self.assertEqual(signup.status, RefereeSignup.Status.ACCEPTED)
+ self.assertIsNotNone(signup.responded_at)
+
+ def test_accept_raises_when_the_game_is_already_full(self):
+ game = self.make_home_game(max_referees=1)
+ add_external_referee(game, "Guest Referee", assigned_by=None)
+ signup = RefereeSignup.objects.get(event=game, member=self.referee)
+
+ with self.assertRaises(RefereeAssignmentError):
+ accept_referee_signup(signup)
+
+ signup.refresh_from_db()
+ self.assertEqual(signup.status, RefereeSignup.Status.INVITED)
+
+ def test_decline_marks_the_signup_declined(self):
+ game = self.make_home_game()
+ signup = RefereeSignup.objects.get(event=game, member=self.referee)
+
+ decline_referee_signup(signup)
+
+ signup.refresh_from_db()
+ self.assertEqual(signup.status, RefereeSignup.Status.DECLINED)
+ self.assertIsNotNone(signup.responded_at)
+
+ def test_decline_after_accepting_removes_the_self_service_assignment(self):
+ game = self.make_home_game()
+ signup = RefereeSignup.objects.get(event=game, member=self.referee)
+ accept_referee_signup(signup)
+
+ decline_referee_signup(signup)
+
+ self.assertFalse(EventReferee.objects.filter(event=game, member=self.referee).exists())
+
+ def test_decline_never_removes_an_admin_made_assignment_for_the_same_member(self):
+ game = self.make_home_game()
+ signup = RefereeSignup.objects.get(event=game, member=self.referee)
+ EventReferee.objects.create(event=game, member=self.referee, assigned_by=self.alice)
+
+ decline_referee_signup(signup)
+
+ self.assertTrue(EventReferee.objects.filter(event=game, member=self.referee, assigned_by=self.alice).exists())
+
+
class CalendarGridTests(EventsTestBase):
"""events.services.calendar -- date-range math and grid layout behind the
Events page's Week/Month/Season views."""
diff --git a/management/templates/management/_referee_assignment_panel.html b/management/templates/management/_referee_assignment_panel.html
index a82d2f6..4bd3a8f 100644
--- a/management/templates/management/_referee_assignment_panel.html
+++ b/management/templates/management/_referee_assignment_panel.html
@@ -3,8 +3,16 @@
Shared by the event detail page and the referee management dashboard --
context: event, referees (EventReferee rows -- fee/km/km_rate read straight
off the model instance, no separate form object needed), referee_candidates,
- referees_full, can_manage_referees, and an optional next_url to return to
- after a POST (defaults to the event detail page when blank).
+ referees_full, pending_signups (RefereeSignup rows still INVITED -- the
+ self-service counterpart, events.services.referees.sync_referee_invites/
+ accept_referee_signup), can_manage_referees, and an optional next_url to
+ return to after a POST (defaults to the event detail page when blank).
+
+ A referee row with no assigned_by (events.services.referees.
+ accept_referee_signup passes assigned_by=None) is one who signed
+ themselves up rather than one an admin picked -- flagged "Self sign-up"
+ instead of "Assigned by ..." so that stays visible here without a
+ separate screen.
The fee is entered right here, inline, rather than behind a "Fee" button
that opened a second (and on the dashboard, nested-inside-a-dialog) modal
@@ -33,7 +41,11 @@
{% if referee.is_external %}{% trans "External" %}{% endif %}
{% if can_manage_referees and not referee.fee %}{% trans "Fee not set" %}{% endif %}
- {% if referee.assigned_by %}{% blocktrans with name=referee.assigned_by %}Assigned by {{ name }}{% endblocktrans %}{% endif %}
+ {% if referee.assigned_by %}
+ {% blocktrans with name=referee.assigned_by %}Assigned by {{ name }}{% endblocktrans %}
+ {% elif not referee.is_external %}
+ {% trans "Self sign-up" %}
+ {% endif %}
{% if can_manage_referees %}
@@ -76,6 +88,13 @@
{% endfor %}
+{% if pending_signups %}
+
+ {% blocktrans count counter=pending_signups|length %}Invited, no response yet: {% plural %}Invited, no response yet: {% endblocktrans %}
+ {% for signup in pending_signups %}{{ signup.member }}{% if not forloop.last %}, {% endif %}{% endfor %}
+
+{% endif %}
+
{% if can_manage_referees and not referees_full %}
{% trans "Add a referee" %}
diff --git a/management/templates/management/referee_management.html b/management/templates/management/referee_management.html
index 08de4ed..2eb9a11 100644
--- a/management/templates/management/referee_management.html
+++ b/management/templates/management/referee_management.html
@@ -90,7 +90,7 @@
{% if game.opponent %}{% trans "vs" %} {{ game.opponent }}{% endif %}
{{ game.start|date:"j M Y H:i" }}
- {% include "management/_referee_assignment_panel.html" with event=game referees=game.referee_rows referee_candidates=game.referee_candidates referees_full=game.referees_full can_manage_referees=True next_url=request.get_full_path %}
+ {% include "management/_referee_assignment_panel.html" with event=game referees=game.referee_rows referee_candidates=game.referee_candidates referees_full=game.referees_full pending_signups=game.pending_signups can_manage_referees=True next_url=request.get_full_path %}
diff --git a/management/tests.py b/management/tests.py
index 9933ddd..ec3d2f2 100644
--- a/management/tests.py
+++ b/management/tests.py
@@ -23,7 +23,7 @@ from billing.services.dues import record_payment, subscribe
from club.models import Club, ClubMembership, ClubRole, DuesInvoice, FeePayment, MemberRequirementStatus, OnboardingRequirement, Season, Sponsor
from club.services.invoicing import DuesInvoicePDFError
from club.services.onboarding import mark_complete
-from events.models import Attendance, Competition, Event, EventReferee, EventSeries, Location, Opponent
+from events.models import Attendance, Competition, Event, EventReferee, EventSeries, Location, Opponent, RefereeSignup
from events.services.rbihf_import import RBIHFImportError
from events.services.recurrence import detach_occurrence, generate_occurrences
from management.bulk_import import TEMPLATE_COLUMNS
@@ -6554,6 +6554,39 @@ class RefereeManagementDashboardTests(ManagementTestBase):
self.assertRedirects(response, reverse("management:event_detail", args=[game.pk]))
+ def test_shows_a_pending_self_service_invite(self):
+ # make_game()'s own event.teams.add(...) already triggers
+ # events.services.referees.sync_referee_invites via events/signals.py --
+ # self.referee (eligible for self.team) gets invited automatically.
+ game = self.make_game()
+ self.client.force_login(self.admin_user)
+
+ response = self.club_get("referee_management")
+
+ self.assertTrue(RefereeSignup.objects.filter(event=game, member=self.referee, status=RefereeSignup.Status.INVITED).exists())
+ self.assertContains(response, "Invited, no response yet")
+ self.assertContains(response, str(self.referee))
+
+ def test_no_pending_invite_shown_once_the_game_is_full(self):
+ game = self.make_game(max_referees=1)
+ EventReferee.objects.create(event=game, member=self.referee, assigned_by=self.admin_member)
+ other_referee = Member.objects.create(first_name="Other", last_name="Ref")
+ RefereeSignup.objects.create(event=game, member=other_referee, status=RefereeSignup.Status.INVITED)
+ self.client.force_login(self.admin_user)
+
+ response = self.club_get("referee_management")
+
+ self.assertNotContains(response, "Invited, no response yet")
+
+ def test_self_signed_up_referee_is_flagged_distinctly_from_an_admin_assignment(self):
+ game = self.make_game()
+ EventReferee.objects.create(event=game, member=self.referee, assigned_by=None)
+ self.client.force_login(self.admin_user)
+
+ response = self.club_get("referee_management")
+
+ self.assertContains(response, "Self sign-up")
+
class FeatureGatedSectionsTests(ManagementTestBase):
"""The Shop and Forms sections are still stubs (StubListMixin) and, on top
diff --git a/management/views.py b/management/views.py
index 149aee1..1c41ae7 100644
--- a/management/views.py
+++ b/management/views.py
@@ -35,7 +35,7 @@ from club.services.onboarding import annotate_onboarding_status, approve_all_cle
from controlpanel.messages import notify
from controlpanel.mixins import RedirectOnInvalidMixin
from controlpanel.services.statistics import club_attention, club_charts, club_statistics, unrostered_members
-from events.models import Attendance, Event, EventReferee, EventSeries, Location, Opponent
+from events.models import Attendance, Event, EventReferee, EventSeries, Location, Opponent, RefereeSignup
from events.services.attendance import member_attendance_counts, member_attendance_sparkline, player_attendance_rankings, players_who_missed_recent_practices, team_attendance_rate, team_no_shows
from events.services.calendar import add_months, month_bounds, month_grid, season_grid, week_bounds, week_grid
from events.services.competitions import CompetitionFetchError, fetch_game_info
@@ -2501,6 +2501,7 @@ class EventDetailView(ClubStaffRequiredMixin, DetailView):
referees = []
referee_candidates = []
referees_full = False
+ pending_signups = []
if referee_management_needed:
referees = list(event.referees.select_related("member", "assigned_by").order_by("member__last_name", "member__first_name"))
referees_full = len(referees) >= event.max_referees
@@ -2510,6 +2511,8 @@ class EventDetailView(ClubStaffRequiredMixin, DetailView):
candidate.has_conflict = bool(conflicts)
candidate.conflict_titles = ", ".join(conflict.title for conflict in conflicts)
referee_candidates.append(candidate)
+ if can_manage_referees:
+ pending_signups = list(event.referee_signups.filter(status=RefereeSignup.Status.INVITED).select_related("member"))
return super().get_context_data(
can_manage=can_manage,
@@ -2521,6 +2524,7 @@ class EventDetailView(ClubStaffRequiredMixin, DetailView):
referees=referees,
referee_candidates=referee_candidates,
referees_full=referees_full,
+ pending_signups=pending_signups,
**kwargs,
)
@@ -2745,6 +2749,7 @@ class RefereeManagementDashboardView(MemberAdminRequiredMixin, TemplateView):
game.referees_full = len(game.referee_rows) >= game.max_referees
game.referee_candidates = []
game.fees_pending = any(not referee.fee for referee in game.referee_rows)
+ game.pending_signups = list(game.referee_signups.filter(status=RefereeSignup.Status.INVITED).select_related("member")) if not game.referees_full else []
if not game.referee_rows:
kpi_no_referee += 1
elif not game.referees_full:
diff --git a/mobile/templates/mobile/_calendar_referee_row.html b/mobile/templates/mobile/_calendar_referee_row.html
new file mode 100644
index 0000000..1decaf9
--- /dev/null
+++ b/mobile/templates/mobile/_calendar_referee_row.html
@@ -0,0 +1,50 @@
+{% load i18n lucide %}
+{% comment %}
+ One referee sign-up row on M3's Calendar -- a home game the signed-in
+ account is eligible (and, once responded, confirmed) to referee for.
+ Merged into the same chronological list as the account's own RSVP rows
+ (mobile/_calendar_row.html), but in the referee accent (assets/mobile.
+ css's --color-referee/.pill-referee) so it reads as a different kind of
+ commitment at a glance -- and scoped to self.me only (mobile/views.py's
+ CalendarView), never managed_people, since a referee is an adult acting
+ on their own behalf, not something a parent does for a child.
+
+ Expects ``row`` ({event, referee_signup}) in scope. Accept/Decline are
+ two small forms, not a single multi-button one, so hx-boost="false" can
+ sit on each without a formaction/htmx-boost mismatch (see event_detail.
+ html's own top-of-file comment for that failure mode).
+{% endcomment %}
+
+
+
{{ row.event.start|date:"D" }}
+
+
+
+
+
+ {% lucide "flag" size=13 stroke_width=2.4 class="shrink-0 text-referee" %}
+ {% trans "Referee" %} · {{ row.event.title }}
+
+
+ {{ row.event.start|date:"H:i" }}
+ {% for team in row.event.teams.all %}· {{ team.name }}{% endfor %}
+ {% if row.event.location %}· {{ row.event.location.name }}{% endif %}
+
+
+ {% if row.referee_signup.status == "accepted" %}
+
{% trans "Confirmed" %}
+ {% else %}
+
+
+
+
+ {% endif %}
+
diff --git a/mobile/templates/mobile/calendar.html b/mobile/templates/mobile/calendar.html
index ed9a2c4..0e0fc41 100644
--- a/mobile/templates/mobile/calendar.html
+++ b/mobile/templates/mobile/calendar.html
@@ -7,7 +7,10 @@
everything further out grouped by calendar month (see CalendarView's own
docstring -- later_months is a list of {month_start, rows}). No person
switcher and no club-wide toggle here -- always every event
- self.managed_people is invited to, full stop. A real, working ?kind=
+ self.managed_people is invited to, plus (merged into the same
+ chronological list, own accent colour) any home game self.me is
+ eligible to referee -- see mobile/_calendar_referee_row.html. A real,
+ working ?kind=
filter (All/Games/Practices) stands in for the design mock's "Games only"
pill; its List/Month toggle isn't reproduced -- that's a second view
mode, not a filter. -mx-4 (on the row groups only, not this filter row)
@@ -60,7 +63,7 @@
{% for row in this_week %}
- {% include "mobile/_calendar_row.html" %}
+ {% if row.referee_signup %}{% include "mobile/_calendar_referee_row.html" %}{% else %}{% include "mobile/_calendar_row.html" %}{% endif %}
{% endfor %}
@@ -71,7 +74,7 @@
{% for row in next_week %}
- {% include "mobile/_calendar_row.html" %}
+ {% if row.referee_signup %}{% include "mobile/_calendar_referee_row.html" %}{% else %}{% include "mobile/_calendar_row.html" %}{% endif %}
{% endfor %}
@@ -82,7 +85,7 @@
{% for row in month.rows %}
- {% include "mobile/_calendar_row.html" %}
+ {% if row.referee_signup %}{% include "mobile/_calendar_referee_row.html" %}{% else %}{% include "mobile/_calendar_row.html" %}{% endif %}
{% endfor %}
diff --git a/mobile/tests.py b/mobile/tests.py
index ec3f04e..cdefda7 100644
--- a/mobile/tests.py
+++ b/mobile/tests.py
@@ -9,11 +9,11 @@ from django.utils import timezone, translation
from icalendar import Calendar as ICalCalendar
from club.models import Club, ClubMembership, DuesInvoice, MemberRequirementStatus, OnboardingRequirement, Season, Sponsor
-from events.models import Attendance, Event, Lineup, LineupSelection
+from events.models import Attendance, Event, EventReferee, Lineup, LineupSelection, Location, RefereeSignup
from members.models import Family, FamilyMembership, Member
from news.models import News
from notifications.models import Notification
-from teams.models import Position, StaffAssignment, Team, TeamMembership
+from teams.models import Position, RefereeLevel, RefereeProfile, StaffAssignment, Team, TeamMembership
from .models import CalendarFeedToken, PushSubscription
from .services.icons import render_fallback_icon
@@ -1008,6 +1008,145 @@ class CalendarViewTests(TestCase):
self.assertIn(event, self._events_in_context(response))
+@override_settings(ROSTERCHIEF_BASE_DOMAIN="rosterchief.app", ALLOWED_HOSTS=["rosterchief.app", "ajax-united.rosterchief.app", "testserver"])
+class CalendarRefereeSignupTests(TestCase):
+ """M3's Calendar merges in the signed-in account's own referee sign-ups
+ (self.me only, never managed_people) -- see mobile/_calendar_referee_row.
+ html and CalendarView's own docstring."""
+
+ @classmethod
+ def setUpTestData(cls):
+ cls.club = make_club()
+ today = timezone.localdate()
+ cls.season = Season.objects.create(club=cls.club, start_date=today - datetime.timedelta(days=30), end_date=today + datetime.timedelta(days=300))
+ cls.user = User.objects.create_user(email="ref@example.com", password="pw-secret-123")
+ cls.member = Member.objects.create(first_name="Ref", last_name="Eree", email="ref@example.com", user=cls.user)
+ ClubMembership.objects.create(club=cls.club, member=cls.member, season=cls.season)
+
+ cls.home_ground = Location.objects.create(club=cls.club, name="Home Rink", address="1 St", city="Town", zip_code="1000", country="BE", is_home=True)
+ cls.team = Team.objects.create(club=cls.club, name="U16", short_name="U16")
+ cls.level = RefereeLevel.objects.create(club=cls.club, name="Regional")
+ cls.level.teams.add(cls.team)
+ RefereeProfile.objects.create(member=cls.member, level=cls.level, valid_until=today + datetime.timedelta(days=30))
+
+ cls.game = Event.objects.create(club=cls.club, title="Home game", kind=Event.EventKind.GAME, location=cls.home_ground, start=timezone.now() + datetime.timedelta(days=1))
+ cls.game.teams.add(cls.team) # triggers sync_referee_invites via events/signals.py
+
+ def _get(self, **params):
+ url = reverse("mobile:calendar")
+ if params:
+ url += "?" + "&".join(f"{key}={value}" for key, value in params.items())
+ return self.client.get(url, HTTP_HOST="ajax-united.rosterchief.app")
+
+ def test_invited_game_shows_up_on_the_calendar(self):
+ self.client.force_login(self.user)
+
+ response = self._get()
+
+ self.assertContains(response, "Referee")
+ self.assertContains(response, "I'll ref")
+
+ def test_declined_signup_is_not_shown(self):
+ signup = RefereeSignup.objects.get(event=self.game, member=self.member)
+ signup.status = RefereeSignup.Status.DECLINED
+ signup.save()
+ self.client.force_login(self.user)
+
+ response = self._get()
+
+ self.assertNotContains(response, "I'll ref")
+
+ def test_accepted_signup_shows_a_confirmed_pill_with_no_actions(self):
+ signup = RefereeSignup.objects.get(event=self.game, member=self.member)
+ signup.status = RefereeSignup.Status.ACCEPTED
+ signup.save()
+ self.client.force_login(self.user)
+
+ response = self._get()
+
+ self.assertContains(response, "Confirmed")
+ self.assertNotContains(response, "I'll ref")
+
+ def test_training_filter_excludes_referee_rows(self):
+ self.client.force_login(self.user)
+
+ response = self._get(kind="training")
+
+ self.assertNotContains(response, "I'll ref")
+
+
+@override_settings(ROSTERCHIEF_BASE_DOMAIN="rosterchief.app", ALLOWED_HOSTS=["rosterchief.app", "ajax-united.rosterchief.app", "testserver"])
+class RefereeSignupRespondViewTests(TestCase):
+ """mobile:referee_signup_respond -- Accept/Decline from the Calendar."""
+
+ @classmethod
+ def setUpTestData(cls):
+ cls.club = make_club()
+ today = timezone.localdate()
+ cls.season = Season.objects.create(club=cls.club, start_date=today - datetime.timedelta(days=30), end_date=today + datetime.timedelta(days=300))
+ cls.user = User.objects.create_user(email="ref@example.com", password="pw-secret-123")
+ cls.member = Member.objects.create(first_name="Ref", last_name="Eree", email="ref@example.com", user=cls.user)
+ ClubMembership.objects.create(club=cls.club, member=cls.member, season=cls.season)
+
+ cls.home_ground = Location.objects.create(club=cls.club, name="Home Rink", address="1 St", city="Town", zip_code="1000", country="BE", is_home=True)
+ cls.team = Team.objects.create(club=cls.club, name="U16", short_name="U16")
+ cls.level = RefereeLevel.objects.create(club=cls.club, name="Regional")
+ cls.level.teams.add(cls.team)
+ RefereeProfile.objects.create(member=cls.member, level=cls.level, valid_until=today + datetime.timedelta(days=30))
+
+ cls.game = Event.objects.create(club=cls.club, title="Home game", kind=Event.EventKind.GAME, location=cls.home_ground, start=timezone.now() + datetime.timedelta(days=1))
+ cls.game.teams.add(cls.team)
+
+ def _post(self, response_value):
+ signup = RefereeSignup.objects.get(event=self.game, member=self.member)
+ return self.client.post(reverse("mobile:referee_signup_respond", kwargs={"signup_id": signup.pk}), {"response": response_value}, HTTP_HOST="ajax-united.rosterchief.app")
+
+ def test_requires_login(self):
+ response = self._post("accept")
+
+ self.assertEqual(response.status_code, 302)
+
+ def test_accept_creates_a_real_assignment(self):
+ self.client.force_login(self.user)
+
+ response = self._post("accept")
+
+ self.assertRedirects(response, reverse("mobile:calendar"), fetch_redirect_response=False)
+ self.assertTrue(EventReferee.objects.filter(event=self.game, member=self.member).exists())
+ signup = RefereeSignup.objects.get(event=self.game, member=self.member)
+ self.assertEqual(signup.status, RefereeSignup.Status.ACCEPTED)
+
+ def test_accept_shows_an_error_when_the_game_is_already_full(self):
+ self.game.max_referees = 0
+ self.game.save(update_fields=["max_referees"])
+ self.client.force_login(self.user)
+
+ response = self._post("accept")
+
+ self.assertRedirects(response, reverse("mobile:calendar"), fetch_redirect_response=False)
+ self.assertFalse(EventReferee.objects.filter(event=self.game, member=self.member).exists())
+ signup = RefereeSignup.objects.get(event=self.game, member=self.member)
+ self.assertEqual(signup.status, RefereeSignup.Status.INVITED)
+
+ def test_decline_marks_the_signup_declined(self):
+ self.client.force_login(self.user)
+
+ response = self._post("decline")
+
+ self.assertRedirects(response, reverse("mobile:calendar"), fetch_redirect_response=False)
+ signup = RefereeSignup.objects.get(event=self.game, member=self.member)
+ self.assertEqual(signup.status, RefereeSignup.Status.DECLINED)
+
+ def test_cannot_respond_to_someone_elses_signup(self):
+ stranger_user = User.objects.create_user(email="stranger@example.com", password="pw-secret-123")
+ Member.objects.create(first_name="Not", last_name="You", email="stranger@example.com", user=stranger_user)
+ self.client.force_login(stranger_user)
+
+ response = self._post("accept")
+
+ self.assertEqual(response.status_code, 404)
+
+
@override_settings(ROSTERCHIEF_BASE_DOMAIN="rosterchief.app", ALLOWED_HOSTS=["rosterchief.app", "ajax-united.rosterchief.app", "testserver"])
class EventDetailScreenTests(TestCase):
"""M2 -- design_handoff_rosterchief_platform/README.md's M2 section,
diff --git a/mobile/urls.py b/mobile/urls.py
index 3e29881..ed44013 100644
--- a/mobile/urls.py
+++ b/mobile/urls.py
@@ -14,6 +14,7 @@ urlpatterns = [
# Member mode (M1-M7).
path("", views.HomeView.as_view(), name="home"),
path("calendar/", views.CalendarView.as_view(), name="calendar"),
+ path("referee-signups//respond/", views.RefereeSignupRespondView.as_view(), name="referee_signup_respond"),
path("events//", views.EventDetailView.as_view(), name="event_detail"),
path("news/", views.NewsListView.as_view(), name="news_list"),
path("news//", views.NewsDetailView.as_view(), name="news_detail"),
diff --git a/mobile/views.py b/mobile/views.py
index a17fc16..447d264 100644
--- a/mobile/views.py
+++ b/mobile/views.py
@@ -27,9 +27,10 @@ from club.services.fees import open_dues_rows
from club.services.onboarding import checklist_for
from club.services.sponsors import active_sponsors
from controlpanel.messages import notify
-from events.models import Attendance, Event, Lineup
+from events.models import Attendance, Event, Lineup, RefereeSignup
from events.services.calendar import week_bounds
from events.services.lineup import notify_dropout, selected_members_by_position
+from events.services.referees import RefereeAssignmentError, accept_referee_signup, decline_referee_signup
from members.models import FamilyMembership, Member
from members.views import ClubScopedPublicMixin
from news.models import News
@@ -348,6 +349,31 @@ class CalendarView(PersonScopeMixin, LoginRequiredMixin, TemplateView):
for attendance in attendances
]
+ # Referee sign-ups are scoped to self.me only, never managed_people --
+ # a referee is an adult with their own account, not something a
+ # parent does on a child's behalf, unlike every RSVP row above.
+ # Merged into the same chronological list (own dict shape, no
+ # pill_class/member) rather than a separate section, so it reads on
+ # the actual day it falls on -- distinct styling is what sets it
+ # apart (mobile/_calendar_referee_row.html), not a different place
+ # on the screen. Declined invites are dropped; accepted ones stay
+ # visible as a confirmed commitment.
+ if self.me is not None and kind_filter != "training":
+ signups = (
+ RefereeSignup.objects.filter(
+ member=self.me,
+ event__club=self.request.club,
+ event__cancelled=False,
+ event__start__gte=now,
+ status__in=[RefereeSignup.Status.INVITED, RefereeSignup.Status.ACCEPTED],
+ )
+ .select_related("event", "event__location", "event__opponent")
+ .prefetch_related("event__teams")
+ )
+ rows += [{"event": signup.event, "referee_signup": signup} for signup in signups]
+
+ rows.sort(key=lambda row: row["event"].start)
+
this_week, next_week, later_rows = [], [], []
for row in rows:
event_date = timezone.localtime(row["event"].start).date()
@@ -368,6 +394,33 @@ class CalendarView(PersonScopeMixin, LoginRequiredMixin, TemplateView):
return super().get_context_data(this_week=this_week, next_week=next_week, later_months=later_months, kind_filter=kind_filter if kind_filter in self.KIND_FILTERS else "", **kwargs)
+class RefereeSignupRespondView(PersonScopeMixin, LoginRequiredMixin, View):
+ """Accept/decline a referee invite from a Calendar row
+ (mobile/_calendar_referee_row.html) -- routes through
+ events.services.referees.accept_referee_signup/decline_referee_signup,
+ so capacity is enforced in the one place the desktop admin flow already
+ enforces it, and the referee-management screen sees the result with no
+ separate sync step."""
+
+ def post(self, request, *args, **kwargs):
+ signup = get_object_or_404(RefereeSignup, pk=kwargs["signup_id"], member=self.me, event__club=request.club)
+ response = request.POST.get("response")
+
+ if response == "accept":
+ try:
+ accept_referee_signup(signup)
+ notify(request, f"s|{_('Referee sign-up confirmed')}|{_('Thanks for signing up -- see you there.')}")
+ except RefereeAssignmentError as exc:
+ notify(request, f"e|{_('Could not sign you up')}|{exc}")
+ elif response == "decline":
+ decline_referee_signup(signup)
+ notify(request, f"s|{_('Declined')}|{_('No problem -- thanks for letting us know.')}")
+ else:
+ return HttpResponseBadRequest(_("Unknown response."))
+
+ return HttpResponseRedirect(reverse("mobile:calendar"))
+
+
class EventDetailView(PersonScopeMixin, LoginRequiredMixin, TemplateView):
"""M2 -- design_handoff_rosterchief_platform/README.md's M2 section:
"answer for several". A hero header (no event photos in this codebase --
diff --git a/static/css/mobile.css b/static/css/mobile.css
index 3bf119f..3bbd39f 100644
--- a/static/css/mobile.css
+++ b/static/css/mobile.css
@@ -1,2 +1,2 @@
/*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */
-@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial}}}@layer theme{:root,:host{--font-sans:"Barlow", ui-sans-serif, system-ui, sans-serif;--font-mono:"IBM Plex Mono", ui-monospace, SFMono-Regular, monospace;--color-sky-500:oklch(68.5% .169 237.323);--color-gray-500:oklch(55.1% .027 264.364);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-md:28rem;--container-xl:36rem;--container-2xl:42rem;--container-3xl:48rem;--container-6xl:72rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5 / 2.25);--text-5xl:3rem;--text-5xl--line-height:1;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--tracking-wide:.025em;--tracking-wider:.05em;--leading-tight:1.25;--leading-relaxed:1.625;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--ease-out:cubic-bezier(0, 0, .2, 1);--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--font-display:"Barlow Condensed", ui-sans-serif, system-ui, sans-serif;--color-ink:#0b1220;--color-navy:var(--tenant-navy,#101e36);--color-steel:#1b2b47;--color-hairline:#1e2b42;--color-paper:#f4f5f7;--color-line:#e3e6eb;--color-rule:#eef0f3;--color-edge:#d6dae1;--color-stroke:#c9cfd8;--color-muted:#6c7787;--color-dim:#8b95a4;--color-slate:#3a4658;--color-on-dark:#93a0b4;--color-on-dark-dim:#7c8aa0;--color-on-dark-faint:#5c6b85;--color-club:var(--tenant-club,#e4002b);--color-club-dark:var(--tenant-club-dark,#b00021);--color-club-content:var(--tenant-club-content,#fff);--color-ok:#14a05a;--color-ok-bg:#e6f6ee;--color-ok-border:#bfe7d3;--color-ok-text:#0c7a43;--color-warn:#f0a22e;--color-warn-bg:#fff5e4;--color-warn-border:#f6e0b8;--color-warn-text:#9a6410;--color-warn-deep:#7a4e08;--color-danger-bg:#fdecec;--color-danger-border:#f5c9ce;--color-info:#14b8e8;--color-info-bg:#eaf7fc;--color-info-border:#c3e7f4;--color-info-text:#0a6f91;--color-ice:#14b8e8;--color-ice-ink:#04212c;--color-row-sel:#fff7f8;--color-row-focus:#f4f9ff;--color-subhead:#f8f9fa;--radius-box:.875rem}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}body{background:var(--color-paper);color:var(--color-slate);font-family:var(--font-sans);padding-top:env(safe-area-inset-top);padding-bottom:env(safe-area-inset-bottom)}[x-cloak]{display:none!important}}@layer components{.app-header{padding:max(env(safe-area-inset-top), 14px) 16px 14px;background:var(--color-navy);color:#fff;flex-shrink:0}.app-crest{object-fit:cover;border-radius:999px;flex-shrink:0;width:32px;height:32px}.app-crest-fallback{background:var(--color-club);color:var(--color-club-content);font-family:var(--font-display);justify-content:center;align-items:center;font-size:.75rem;font-weight:800;display:flex}.scrollbar-hide{scrollbar-width:none;-ms-overflow-style:none}.scrollbar-hide::-webkit-scrollbar{display:none}.role-switcher{background:var(--color-steel);border-radius:999px;gap:4px;margin-top:10px;padding:4px;display:flex}.role-switcher-item{height:36px;font-family:var(--font-display);letter-spacing:.1em;text-transform:uppercase;color:var(--color-on-dark);border-radius:999px;flex:1;justify-content:center;align-items:center;font-size:.875rem;font-weight:800;display:flex}.role-switcher-item-active{color:var(--color-ink);background:#fff}.role-switcher-item-active-ice{background:var(--color-ice);color:var(--color-ice-ink)}.tab-bar{border-top:1px solid var(--color-line);padding:8px 8px max(env(safe-area-inset-bottom), 26px);background:#fff;flex-shrink:0;display:flex}.tab-bar-item{height:48px;color:var(--color-dim);flex-direction:column;flex:1;justify-content:center;align-items:center;gap:3px;display:flex}.tab-bar-item-active{color:var(--color-club)}.tab-bar-label{font-family:var(--font-display);letter-spacing:.08em;text-transform:uppercase;font-size:.75rem;font-weight:700}.btn{height:46px;font-family:var(--font-display);letter-spacing:.1em;text-transform:uppercase;cursor:pointer;white-space:nowrap;border:none;border-radius:.5rem;justify-content:center;align-items:center;gap:.5rem;padding-inline:1.25rem;font-size:1rem;font-weight:800;display:inline-flex}.btn:disabled{opacity:.45;cursor:not-allowed}.btn-primary{background:var(--color-club);color:#fff}.btn-dark{background:var(--color-ink);color:#fff}.btn-positive{background:var(--color-ok);color:#fff}.btn-secondary{border:1.5px solid var(--color-stroke);color:var(--color-ink);background:#fff}.btn-ghost-on-dark{color:#fff;background:#ffffff26}.pill{font-family:var(--font-display);letter-spacing:.1em;text-transform:uppercase;border-radius:999px;align-items:center;padding:5px 10px;font-size:.75rem;font-weight:700;display:inline-flex}.pill-ok{background:var(--color-ok-bg);color:var(--color-ok-text);border:1px solid var(--color-ok-border)}.pill-danger{background:var(--color-danger-bg);color:var(--color-club-dark);border:1px solid var(--color-danger-border)}.pill-warn{background:var(--color-warn-bg);color:var(--color-warn-text);border:1px solid var(--color-warn-border)}.pill-info{background:var(--color-info-bg);color:var(--color-info-text);border:1px solid var(--color-info-border)}.pill-neutral{background:var(--color-rule);color:#4a5566;border:1px solid #dde1e7}.person-chip{border:1.5px solid var(--color-line);color:var(--color-muted);background:#fff;border-radius:999px;flex-shrink:0;align-items:center;gap:6px;padding:4px 10px 4px 4px;display:flex}.person-chip-active{border-color:var(--color-ink);color:var(--color-ink)}.person-chip-avatar{background:var(--color-stroke);color:#fff;width:22px;height:22px;font-family:var(--font-display);border-radius:999px;flex-shrink:0;justify-content:center;align-items:center;font-size:.6875rem;font-weight:800;display:flex}.person-chip-active .person-chip-avatar{background:var(--color-club)}.person-chip-label{font-family:var(--font-display);letter-spacing:.06em;text-transform:uppercase;font-size:.8125rem;font-weight:700}.m-card{border:1px solid var(--color-line);border-radius:var(--radius-box);background:#fff}.m-card-dark{background:var(--color-ink);color:#fff;border-radius:var(--radius-box)}.coach-header{padding:max(env(safe-area-inset-top), 14px) 16px 14px;background:var(--color-ink);color:#fff;flex-shrink:0}.coach-sheet{background:var(--color-paper);flex:1;overflow-y:auto}.coach-tab-bar{background:var(--color-ink);border-top:1px solid var(--color-hairline);padding:8px 8px max(env(safe-area-inset-bottom), 26px);flex-shrink:0;display:flex;position:relative}.coach-tab-bar-item{height:48px;color:var(--color-on-dark);flex-direction:column;flex:1;justify-content:center;align-items:center;gap:3px;display:flex}.coach-tab-bar-item-active{color:var(--color-ice)}.coach-tab-bar-add{flex:1;justify-content:center;align-items:flex-start;display:flex}.coach-tab-bar-add-button{background:var(--color-ice);width:48px;height:48px;color:var(--color-ice-ink);border:4px solid var(--color-ink);border-radius:999px;justify-content:center;align-items:center;margin-top:-20px;display:flex;box-shadow:0 2px 10px #00000059}}@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:0}.inset-x-3{inset-inline:calc(var(--spacing) * 3)}.-top-1{top:calc(var(--spacing) * -1)}.top-0{top:0}.top-1\.5{top:calc(var(--spacing) * 1.5)}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing) * 2)}.top-\[3px\]{top:3px}.top-full{top:100%}.-right-1{right:calc(var(--spacing) * -1)}.right-0{right:0}.right-2{right:calc(var(--spacing) * 2)}.right-\[3px\]{right:3px}.bottom-full{bottom:100%}.left-0{left:0}.left-1\.5{left:calc(var(--spacing) * 1.5)}.left-2\.5{left:calc(var(--spacing) * 2.5)}.left-3{left:calc(var(--spacing) * 3)}.left-\[3px\]{left:3px}.isolate{isolation:isolate}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.col-span-2{grid-column:span 2/span 2}.col-span-full{grid-column:1/-1}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.-mx-4{margin-inline:calc(var(--spacing) * -4)}.mx-4{margin-inline:calc(var(--spacing) * 4)}.mx-auto{margin-inline:auto}.my-1{margin-block:var(--spacing)}.my-2{margin-block:calc(var(--spacing) * 2)}.my-3{margin-block:calc(var(--spacing) * 3)}.my-4{margin-block:calc(var(--spacing) * 4)}.my-6{margin-block:calc(var(--spacing) * 6)}.ms-auto{margin-inline-start:auto}.-mt-0\.5{margin-top:calc(var(--spacing) * -.5)}.-mt-1{margin-top:calc(var(--spacing) * -1)}.-mt-4{margin-top:calc(var(--spacing) * -4)}.-mt-5{margin-top:calc(var(--spacing) * -5)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-2\.5{margin-top:calc(var(--spacing) * 2.5)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-3\.5{margin-top:calc(var(--spacing) * 3.5)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mt-8{margin-top:calc(var(--spacing) * 8)}.mt-10{margin-top:calc(var(--spacing) * 10)}.mt-auto{margin-top:auto}.mr-1{margin-right:var(--spacing)}.mb-1{margin-bottom:var(--spacing)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-2\.5{margin-bottom:calc(var(--spacing) * 2.5)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-3\.5{margin-bottom:calc(var(--spacing) * 3.5)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.mb-10{margin-bottom:calc(var(--spacing) * 10)}.mb-auto{margin-bottom:auto}.-ml-2\.5{margin-left:calc(var(--spacing) * -2.5)}.ml-1{margin-left:var(--spacing)}.ml-2{margin-left:calc(var(--spacing) * 2)}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.aspect-square{aspect-ratio:1}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-8\.5{height:calc(var(--spacing) * 8.5)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-11{height:calc(var(--spacing) * 11)}.h-12{height:calc(var(--spacing) * 12)}.h-14{height:calc(var(--spacing) * 14)}.h-16{height:calc(var(--spacing) * 16)}.h-24{height:calc(var(--spacing) * 24)}.h-44{height:calc(var(--spacing) * 44)}.h-48{height:calc(var(--spacing) * 48)}.h-72{height:calc(var(--spacing) * 72)}.h-\[3px\]{height:3px}.h-\[7px\]{height:7px}.h-\[19px\]{height:19px}.h-\[22px\]{height:22px}.h-\[30px\]{height:30px}.h-\[34px\]{height:34px}.h-\[38px\]{height:38px}.h-\[52px\]{height:52px}.h-\[54px\]{height:54px}.h-\[68px\]{height:68px}.h-\[104px\]{height:104px}.h-\[180px\]{height:180px}.h-\[190px\]{height:190px}.h-\[220px\]{height:220px}.h-\[330px\]{height:330px}.h-\[560px\]{height:560px}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-60{max-height:calc(var(--spacing) * 60)}.max-h-96{max-height:calc(var(--spacing) * 96)}.max-h-full{max-height:100%}.min-h-6{min-height:calc(var(--spacing) * 6)}.min-h-11{min-height:calc(var(--spacing) * 11)}.min-h-screen{min-height:100vh}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-9\.5{width:calc(var(--spacing) * 9.5)}.w-10{width:calc(var(--spacing) * 10)}.w-11{width:calc(var(--spacing) * 11)}.w-12{width:calc(var(--spacing) * 12)}.w-14{width:calc(var(--spacing) * 14)}.w-16{width:calc(var(--spacing) * 16)}.w-20{width:calc(var(--spacing) * 20)}.w-23{width:calc(var(--spacing) * 23)}.w-24{width:calc(var(--spacing) * 24)}.w-28{width:calc(var(--spacing) * 28)}.w-40{width:calc(var(--spacing) * 40)}.w-44{width:calc(var(--spacing) * 44)}.w-48{width:calc(var(--spacing) * 48)}.w-56{width:calc(var(--spacing) * 56)}.w-60{width:calc(var(--spacing) * 60)}.w-64{width:calc(var(--spacing) * 64)}.w-72{width:calc(var(--spacing) * 72)}.w-80{width:calc(var(--spacing) * 80)}.w-\[3px\]{width:3px}.w-\[7px\]{width:7px}.w-\[36rem\]{width:36rem}.w-\[68px\]{width:68px}.w-\[236px\]{width:236px}.w-\[460px\]{width:460px}.w-auto{width:auto}.w-fit{width:fit-content}.w-full{width:100%}.w-px{width:1px}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-6xl{max-width:var(--container-6xl)}.max-w-40{max-width:calc(var(--spacing) * 40)}.max-w-\[35\%\]{max-width:35%}.max-w-\[91vw\]{max-width:91vw}.max-w-\[1440px\]{max-width:1440px}.max-w-full{max-width:100%}.max-w-md{max-width:var(--container-md)}.max-w-none{max-width:none}.max-w-xl{max-width:var(--container-xl)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:0}.min-w-4{min-width:calc(var(--spacing) * 4)}.min-w-40{min-width:calc(var(--spacing) * 40)}.min-w-\[19px\]{min-width:19px}.min-w-\[220px\]{min-width:220px}.flex-1{flex:1}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.border-collapse{border-collapse:collapse}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.cursor-pointer{cursor:pointer}.resize{resize:both}.scrollbar-gutter-stable{scrollbar-gutter:stable}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.list-none{list-style-type:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.flex-nowrap{flex-wrap:nowrap}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-start{justify-content:flex-start}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-3\.5{gap:calc(var(--spacing) * 3.5)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-10{gap:calc(var(--spacing) * 10)}.gap-px{gap:1px}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-y-2{row-gap:calc(var(--spacing) * 2)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-rule>:not(:last-child)){border-color:var(--color-rule)}.self-start{align-self:flex-start}.self-stretch{align-self:stretch}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-\[10px\]{border-radius:10px}.rounded-\[14px\]{border-radius:14px}.rounded-box{border-radius:var(--radius-box)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-\[1\.5px\]{border-style:var(--tw-border-style);border-width:1.5px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.border-l-\[3px\]{border-left-style:var(--tw-border-style);border-left-width:3px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-\[\#2C3B56\]{border-color:#2c3b56}.border-\[\#DDE1E7\]{border-color:#dde1e7}.border-club{border-color:var(--color-club)}.border-danger-border{border-color:var(--color-danger-border)}.border-edge{border-color:var(--color-edge)}.border-ice{border-color:var(--color-ice)}.border-info{border-color:var(--color-info)}.border-info-border{border-color:var(--color-info-border)}.border-ink{border-color:var(--color-ink)}.border-line{border-color:var(--color-line)}.border-on-dark-faint{border-color:var(--color-on-dark-faint)}.border-rule{border-color:var(--color-rule)}.border-stroke{border-color:var(--color-stroke)}.border-warn{border-color:var(--color-warn)}.border-warn-border{border-color:var(--color-warn-border)}.border-white\/20{border-color:#fff3}@supports (color:color-mix(in lab, red, red)){.border-white\/20{border-color:color-mix(in oklab, var(--color-white) 20%, transparent)}}.border-white\/30{border-color:#ffffff4d}@supports (color:color-mix(in lab, red, red)){.border-white\/30{border-color:color-mix(in oklab, var(--color-white) 30%, transparent)}}.border-l-club{border-left-color:var(--color-club)}.border-l-club-dark{border-left-color:var(--color-club-dark)}.border-l-info{border-left-color:var(--color-info)}.border-l-transparent{border-left-color:#0000}.border-l-warn{border-left-color:var(--color-warn)}.bg-\[var\(--club\)\]{background-color:var(--club)}.bg-black\/20{background-color:#0003}@supports (color:color-mix(in lab, red, red)){.bg-black\/20{background-color:color-mix(in oklab, var(--color-black) 20%, transparent)}}.bg-club{background-color:var(--color-club)}.bg-danger-bg{background-color:var(--color-danger-bg)}.bg-edge{background-color:var(--color-edge)}.bg-hairline{background-color:var(--color-hairline)}.bg-ice{background-color:var(--color-ice)}.bg-info{background-color:var(--color-info)}.bg-info-bg{background-color:var(--color-info-bg)}.bg-ink{background-color:var(--color-ink)}.bg-line{background-color:var(--color-line)}.bg-navy{background-color:var(--color-navy)}.bg-ok{background-color:var(--color-ok)}.bg-paper{background-color:var(--color-paper)}.bg-row-focus{background-color:var(--color-row-focus)}.bg-row-sel{background-color:var(--color-row-sel)}.bg-rule{background-color:var(--color-rule)}.bg-steel{background-color:var(--color-steel)}.bg-steel\/60{background-color:#1b2b4799}@supports (color:color-mix(in lab, red, red)){.bg-steel\/60{background-color:color-mix(in oklab, var(--color-steel) 60%, transparent)}}.bg-subhead{background-color:var(--color-subhead)}.bg-warn{background-color:var(--color-warn)}.bg-warn-bg{background-color:var(--color-warn-bg)}.bg-white{background-color:var(--color-white)}.bg-white\/10{background-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.bg-white\/10{background-color:color-mix(in oklab, var(--color-white) 10%, transparent)}}.bg-white\/15{background-color:#ffffff26}@supports (color:color-mix(in lab, red, red)){.bg-white\/15{background-color:color-mix(in oklab, var(--color-white) 15%, transparent)}}.stroke-2{stroke-width:2px}.object-contain{object-fit:contain}.object-cover{object-fit:cover}.p-1{padding:var(--spacing)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-3\.5{padding:calc(var(--spacing) * 3.5)}.p-4{padding:calc(var(--spacing) * 4)}.p-4\.5{padding:calc(var(--spacing) * 4.5)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-10{padding:calc(var(--spacing) * 10)}.p-\[18px\]{padding:18px}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-4\.5{padding-inline:calc(var(--spacing) * 4.5)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-7{padding-inline:calc(var(--spacing) * 7)}.px-8{padding-inline:calc(var(--spacing) * 8)}.px-\[3px\]{padding-inline:3px}.px-\[18px\]{padding-inline:18px}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-5{padding-block:calc(var(--spacing) * 5)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-10{padding-block:calc(var(--spacing) * 10)}.py-14{padding-block:calc(var(--spacing) * 14)}.py-\[5px\]{padding-block:5px}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-3\.5{padding-top:calc(var(--spacing) * 3.5)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pb-0{padding-bottom:0}.pb-0\.5{padding-bottom:calc(var(--spacing) * .5)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pb-6{padding-bottom:calc(var(--spacing) * 6)}.pb-\[22px\]{padding-bottom:22px}.pb-\[26px\]{padding-bottom:26px}.pl-2\.5{padding-left:calc(var(--spacing) * 2.5)}.pl-8{padding-left:calc(var(--spacing) * 8)}.pl-9{padding-left:calc(var(--spacing) * 9)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.align-middle{vertical-align:middle}.font-display{font-family:var(--font-display)}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[13px\]{font-size:13px}.text-\[15px\]{font-size:15px}.text-\[17px\]{font-size:17px}.text-\[19px\]{font-size:19px}.text-\[22px\]{font-size:22px}.text-\[34px\]{font-size:34px}.text-\[56px\]{font-size:56px}.leading-\[\.94\]{--tw-leading:.94;line-height:.94}.leading-\[\.95\]{--tw-leading:.95;line-height:.95}.leading-\[\.96\]{--tw-leading:.96;line-height:.96}.leading-\[\.98\]{--tw-leading:.98;line-height:.98}.leading-\[1\.05\]{--tw-leading:1.05;line-height:1.05}.leading-\[1\.5\]{--tw-leading:1.5;line-height:1.5}.leading-\[1\.6\]{--tw-leading:1.6;line-height:1.6}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-extrabold{--tw-font-weight:var(--font-weight-extrabold);font-weight:var(--font-weight-extrabold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[\.1em\]{--tw-tracking:.1em;letter-spacing:.1em}.tracking-\[\.04em\]{--tw-tracking:.04em;letter-spacing:.04em}.tracking-\[\.06em\]{--tw-tracking:.06em;letter-spacing:.06em}.tracking-\[\.08em\]{--tw-tracking:.08em;letter-spacing:.08em}.tracking-\[\.12em\]{--tw-tracking:.12em;letter-spacing:.12em}.tracking-\[\.14em\]{--tw-tracking:.14em;letter-spacing:.14em}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[\#4A5566\]{color:#4a5566}.text-club{color:var(--color-club)}.text-club-content{color:var(--color-club-content)}.text-club-dark{color:var(--color-club-dark)}.text-dim{color:var(--color-dim)}.text-edge{color:var(--color-edge)}.text-gray-500{color:var(--color-gray-500)}.text-ice{color:var(--color-ice)}.text-ice-ink{color:var(--color-ice-ink)}.text-info{color:var(--color-info)}.text-info-text{color:var(--color-info-text)}.text-ink{color:var(--color-ink)}.text-muted{color:var(--color-muted)}.text-ok{color:var(--color-ok)}.text-ok-text{color:var(--color-ok-text)}.text-on-dark{color:var(--color-on-dark)}.text-on-dark-dim{color:var(--color-on-dark-dim)}.text-on-dark-faint{color:var(--color-on-dark-faint)}.text-sky-500{color:var(--color-sky-500)}.text-slate{color:var(--color-slate)}.text-warn{color:var(--color-warn)}.text-warn-deep{color:var(--color-warn-deep)}.text-warn-text{color:var(--color-warn-text)}.text-white{color:var(--color-white)}.text-white\/80{color:#fffc}@supports (color:color-mix(in lab, red, red)){.text-white\/80{color:color-mix(in oklab, var(--color-white) 80%, transparent)}}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.line-through{text-decoration-line:line-through}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.accent-ink{accent-color:var(--color-ink)}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-80{opacity:.8}.opacity-\[\.72\]{opacity:.72}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[-24px_0_60px_rgba\(11\,18\,32\,\.2\)\]{--tw-shadow:-24px 0 60px var(--tw-shadow-color,#0b122033);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_24px_60px_rgba\(11\,18\,32\,\.18\)\]{--tw-shadow:0 24px 60px var(--tw-shadow-color,#0b12202e);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[inset_3px_0_0_var\(--color-info\)\]{--tw-shadow:inset 3px 0 0 var(--tw-shadow-color,var(--color-info));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-offset-2{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);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,)}.grayscale{--tw-grayscale:grayscale(100%);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,)}.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-filter{-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,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.placeholder\:text-dim::placeholder{color:var(--color-dim)}.placeholder\:text-on-dark::placeholder{color:var(--color-on-dark)}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.empty\:hidden:empty{display:none}@media (hover:hover){.hover\:border-white:hover{border-color:var(--color-white)}.hover\:bg-ink:hover{background-color:var(--color-ink)}.hover\:bg-rule:hover{background-color:var(--color-rule)}.hover\:bg-steel:hover{background-color:var(--color-steel)}.hover\:bg-subhead:hover{background-color:var(--color-subhead)}.hover\:bg-white\/25:hover{background-color:#ffffff40}@supports (color:color-mix(in lab, red, red)){.hover\:bg-white\/25:hover{background-color:color-mix(in oklab, var(--color-white) 25%, transparent)}}.hover\:text-ink:hover{color:var(--color-ink)}.hover\:text-white:hover{color:var(--color-white)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}}.focus\:border-ink:focus{border-color:var(--color-ink)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.has-checked\:border-ink:has(:checked){border-color:var(--color-ink)}.has-checked\:bg-ink:has(:checked){background-color:var(--color-ink)}.has-checked\:text-white:has(:checked){color:var(--color-white)}@media (min-width:40rem){.sm\:col-span-2{grid-column:span 2/span 2}.sm\:block{display:block}.sm\:hidden{display:none}.sm\:inline{display:inline}.sm\:h-16{height:calc(var(--spacing) * 16)}.sm\:w-16{width:calc(var(--spacing) * 16)}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.sm\:gap-3{gap:calc(var(--spacing) * 3)}.sm\:px-6{padding-inline:calc(var(--spacing) * 6)}.sm\:text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.sm\:text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}}@media (min-width:48rem){.md\:col-span-2{grid-column:span 2/span 2}.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\:text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}}@media (min-width:64rem){.lg\:flex{display:flex}.lg\:w-fit{width:fit-content}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}}@media (min-width:80rem){.xl\:sticky{position:sticky}.xl\:top-4{top:calc(var(--spacing) * 4)}.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.xl\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.xl\:grid-cols-\[1\.2fr_1fr\]{grid-template-columns:1.2fr 1fr}.xl\:grid-cols-\[1\.6fr_1fr\]{grid-template-columns:1.6fr 1fr}.xl\:grid-cols-\[1\.35fr_1fr\]{grid-template-columns:1.35fr 1fr}.xl\:self-start{align-self:flex-start}}.\[\&\:\:-webkit-details-marker\]\:hidden::-webkit-details-marker{display:none}}@font-face{font-family:Barlow;font-style:normal;font-weight:400;font-display:swap;src:url(../fonts/barlow-latin-400-normal.woff2)format("woff2");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow;font-style:normal;font-weight:500;font-display:swap;src:url(../fonts/barlow-latin-500-normal.woff2)format("woff2");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow;font-style:normal;font-weight:600;font-display:swap;src:url(../fonts/barlow-latin-600-normal.woff2)format("woff2");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow;font-style:normal;font-weight:700;font-display:swap;src:url(../fonts/barlow-latin-700-normal.woff2)format("woff2");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow Condensed;font-style:normal;font-weight:600;font-display:swap;src:url(../fonts/barlow-condensed-latin-600-normal.woff2)format("woff2");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow Condensed;font-style:normal;font-weight:700;font-display:swap;src:url(../fonts/barlow-condensed-latin-700-normal.woff2)format("woff2");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow Condensed;font-style:normal;font-weight:800;font-display:swap;src:url(../fonts/barlow-condensed-latin-800-normal.woff2)format("woff2");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:IBM Plex Mono;font-style:normal;font-weight:400;font-display:swap;src:url(../fonts/ibm-plex-mono-latin-400-normal.woff2)format("woff2");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:IBM Plex Mono;font-style:normal;font-weight:500;font-display:swap;src:url(../fonts/ibm-plex-mono-latin-500-normal.woff2)format("woff2");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@keyframes pulse{50%{opacity:.5}}
\ No newline at end of file
+@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial}}}@layer theme{:root,:host{--font-sans:"Barlow", ui-sans-serif, system-ui, sans-serif;--font-mono:"IBM Plex Mono", ui-monospace, SFMono-Regular, monospace;--color-sky-500:oklch(68.5% .169 237.323);--color-gray-500:oklch(55.1% .027 264.364);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-md:28rem;--container-xl:36rem;--container-2xl:42rem;--container-3xl:48rem;--container-6xl:72rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5 / 2.25);--text-5xl:3rem;--text-5xl--line-height:1;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--tracking-wide:.025em;--tracking-wider:.05em;--leading-tight:1.25;--leading-relaxed:1.625;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--ease-out:cubic-bezier(0, 0, .2, 1);--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--font-display:"Barlow Condensed", ui-sans-serif, system-ui, sans-serif;--color-ink:#0b1220;--color-navy:var(--tenant-navy,#101e36);--color-steel:#1b2b47;--color-hairline:#1e2b42;--color-paper:#f4f5f7;--color-line:#e3e6eb;--color-rule:#eef0f3;--color-edge:#d6dae1;--color-stroke:#c9cfd8;--color-muted:#6c7787;--color-dim:#8b95a4;--color-slate:#3a4658;--color-on-dark:#93a0b4;--color-on-dark-dim:#7c8aa0;--color-on-dark-faint:#5c6b85;--color-club:var(--tenant-club,#e4002b);--color-club-dark:var(--tenant-club-dark,#b00021);--color-club-content:var(--tenant-club-content,#fff);--color-ok:#14a05a;--color-ok-bg:#e6f6ee;--color-ok-border:#bfe7d3;--color-ok-text:#0c7a43;--color-warn:#f0a22e;--color-warn-bg:#fff5e4;--color-warn-border:#f6e0b8;--color-warn-text:#9a6410;--color-warn-deep:#7a4e08;--color-danger-bg:#fdecec;--color-danger-border:#f5c9ce;--color-info:#14b8e8;--color-info-bg:#eaf7fc;--color-info-border:#c3e7f4;--color-info-text:#0a6f91;--color-ice:#14b8e8;--color-ice-ink:#04212c;--color-referee:#7c4dff;--color-referee-bg:#f1ecff;--color-referee-border:#d9caff;--color-referee-text:#5b2fd6;--color-row-sel:#fff7f8;--color-row-focus:#f4f9ff;--color-subhead:#f8f9fa;--radius-box:.875rem}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}body{background:var(--color-paper);color:var(--color-slate);font-family:var(--font-sans);padding-top:env(safe-area-inset-top);padding-bottom:env(safe-area-inset-bottom)}[x-cloak]{display:none!important}}@layer components{.app-header{padding:max(env(safe-area-inset-top), 14px) 16px 14px;background:var(--color-navy);color:#fff;flex-shrink:0}.app-crest{object-fit:cover;border-radius:999px;flex-shrink:0;width:32px;height:32px}.app-crest-fallback{background:var(--color-club);color:var(--color-club-content);font-family:var(--font-display);justify-content:center;align-items:center;font-size:.75rem;font-weight:800;display:flex}.scrollbar-hide{scrollbar-width:none;-ms-overflow-style:none}.scrollbar-hide::-webkit-scrollbar{display:none}.role-switcher{background:var(--color-steel);border-radius:999px;gap:4px;margin-top:10px;padding:4px;display:flex}.role-switcher-item{height:36px;font-family:var(--font-display);letter-spacing:.1em;text-transform:uppercase;color:var(--color-on-dark);border-radius:999px;flex:1;justify-content:center;align-items:center;font-size:.875rem;font-weight:800;display:flex}.role-switcher-item-active{color:var(--color-ink);background:#fff}.role-switcher-item-active-ice{background:var(--color-ice);color:var(--color-ice-ink)}.tab-bar{border-top:1px solid var(--color-line);padding:8px 8px max(env(safe-area-inset-bottom), 26px);background:#fff;flex-shrink:0;display:flex}.tab-bar-item{height:48px;color:var(--color-dim);flex-direction:column;flex:1;justify-content:center;align-items:center;gap:3px;display:flex}.tab-bar-item-active{color:var(--color-club)}.tab-bar-label{font-family:var(--font-display);letter-spacing:.08em;text-transform:uppercase;font-size:.75rem;font-weight:700}.btn{height:46px;font-family:var(--font-display);letter-spacing:.1em;text-transform:uppercase;cursor:pointer;white-space:nowrap;border:none;border-radius:.5rem;justify-content:center;align-items:center;gap:.5rem;padding-inline:1.25rem;font-size:1rem;font-weight:800;display:inline-flex}.btn:disabled{opacity:.45;cursor:not-allowed}.btn-primary{background:var(--color-club);color:#fff}.btn-dark{background:var(--color-ink);color:#fff}.btn-positive{background:var(--color-ok);color:#fff}.btn-secondary{border:1.5px solid var(--color-stroke);color:var(--color-ink);background:#fff}.btn-ghost-on-dark{color:#fff;background:#ffffff26}.pill{font-family:var(--font-display);letter-spacing:.1em;text-transform:uppercase;border-radius:999px;align-items:center;padding:5px 10px;font-size:.75rem;font-weight:700;display:inline-flex}.pill-ok{background:var(--color-ok-bg);color:var(--color-ok-text);border:1px solid var(--color-ok-border)}.pill-danger{background:var(--color-danger-bg);color:var(--color-club-dark);border:1px solid var(--color-danger-border)}.pill-warn{background:var(--color-warn-bg);color:var(--color-warn-text);border:1px solid var(--color-warn-border)}.pill-info{background:var(--color-info-bg);color:var(--color-info-text);border:1px solid var(--color-info-border)}.pill-neutral{background:var(--color-rule);color:#4a5566;border:1px solid #dde1e7}.pill-referee{background:var(--color-referee-bg);color:var(--color-referee-text);border:1px solid var(--color-referee-border)}.person-chip{border:1.5px solid var(--color-line);color:var(--color-muted);background:#fff;border-radius:999px;flex-shrink:0;align-items:center;gap:6px;padding:4px 10px 4px 4px;display:flex}.person-chip-active{border-color:var(--color-ink);color:var(--color-ink)}.person-chip-avatar{background:var(--color-stroke);color:#fff;width:22px;height:22px;font-family:var(--font-display);border-radius:999px;flex-shrink:0;justify-content:center;align-items:center;font-size:.6875rem;font-weight:800;display:flex}.person-chip-active .person-chip-avatar{background:var(--color-club)}.person-chip-label{font-family:var(--font-display);letter-spacing:.06em;text-transform:uppercase;font-size:.8125rem;font-weight:700}.m-card{border:1px solid var(--color-line);border-radius:var(--radius-box);background:#fff}.m-card-dark{background:var(--color-ink);color:#fff;border-radius:var(--radius-box)}.coach-header{padding:max(env(safe-area-inset-top), 14px) 16px 14px;background:var(--color-ink);color:#fff;flex-shrink:0}.coach-sheet{background:var(--color-paper);flex:1;overflow-y:auto}.coach-tab-bar{background:var(--color-ink);border-top:1px solid var(--color-hairline);padding:8px 8px max(env(safe-area-inset-bottom), 26px);flex-shrink:0;display:flex;position:relative}.coach-tab-bar-item{height:48px;color:var(--color-on-dark);flex-direction:column;flex:1;justify-content:center;align-items:center;gap:3px;display:flex}.coach-tab-bar-item-active{color:var(--color-ice)}.coach-tab-bar-add{flex:1;justify-content:center;align-items:flex-start;display:flex}.coach-tab-bar-add-button{background:var(--color-ice);width:48px;height:48px;color:var(--color-ice-ink);border:4px solid var(--color-ink);border-radius:999px;justify-content:center;align-items:center;margin-top:-20px;display:flex;box-shadow:0 2px 10px #00000059}}@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:0}.inset-x-3{inset-inline:calc(var(--spacing) * 3)}.-top-1{top:calc(var(--spacing) * -1)}.top-0{top:0}.top-1\.5{top:calc(var(--spacing) * 1.5)}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing) * 2)}.top-\[3px\]{top:3px}.top-full{top:100%}.-right-1{right:calc(var(--spacing) * -1)}.right-0{right:0}.right-2{right:calc(var(--spacing) * 2)}.right-\[3px\]{right:3px}.bottom-full{bottom:100%}.left-0{left:0}.left-1\.5{left:calc(var(--spacing) * 1.5)}.left-2\.5{left:calc(var(--spacing) * 2.5)}.left-3{left:calc(var(--spacing) * 3)}.left-\[3px\]{left:3px}.isolate{isolation:isolate}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.col-span-2{grid-column:span 2/span 2}.col-span-full{grid-column:1/-1}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.-mx-4{margin-inline:calc(var(--spacing) * -4)}.mx-4{margin-inline:calc(var(--spacing) * 4)}.mx-auto{margin-inline:auto}.my-1{margin-block:var(--spacing)}.my-2{margin-block:calc(var(--spacing) * 2)}.my-3{margin-block:calc(var(--spacing) * 3)}.my-4{margin-block:calc(var(--spacing) * 4)}.my-6{margin-block:calc(var(--spacing) * 6)}.ms-auto{margin-inline-start:auto}.-mt-0\.5{margin-top:calc(var(--spacing) * -.5)}.-mt-1{margin-top:calc(var(--spacing) * -1)}.-mt-4{margin-top:calc(var(--spacing) * -4)}.-mt-5{margin-top:calc(var(--spacing) * -5)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-2\.5{margin-top:calc(var(--spacing) * 2.5)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-3\.5{margin-top:calc(var(--spacing) * 3.5)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mt-8{margin-top:calc(var(--spacing) * 8)}.mt-10{margin-top:calc(var(--spacing) * 10)}.mt-auto{margin-top:auto}.mr-1{margin-right:var(--spacing)}.mb-1{margin-bottom:var(--spacing)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-2\.5{margin-bottom:calc(var(--spacing) * 2.5)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-3\.5{margin-bottom:calc(var(--spacing) * 3.5)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.mb-10{margin-bottom:calc(var(--spacing) * 10)}.mb-auto{margin-bottom:auto}.-ml-2\.5{margin-left:calc(var(--spacing) * -2.5)}.ml-1{margin-left:var(--spacing)}.ml-2{margin-left:calc(var(--spacing) * 2)}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.aspect-square{aspect-ratio:1}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-8\.5{height:calc(var(--spacing) * 8.5)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-11{height:calc(var(--spacing) * 11)}.h-12{height:calc(var(--spacing) * 12)}.h-14{height:calc(var(--spacing) * 14)}.h-16{height:calc(var(--spacing) * 16)}.h-24{height:calc(var(--spacing) * 24)}.h-44{height:calc(var(--spacing) * 44)}.h-48{height:calc(var(--spacing) * 48)}.h-72{height:calc(var(--spacing) * 72)}.h-\[3px\]{height:3px}.h-\[7px\]{height:7px}.h-\[19px\]{height:19px}.h-\[22px\]{height:22px}.h-\[30px\]{height:30px}.h-\[34px\]{height:34px}.h-\[38px\]{height:38px}.h-\[52px\]{height:52px}.h-\[54px\]{height:54px}.h-\[68px\]{height:68px}.h-\[104px\]{height:104px}.h-\[180px\]{height:180px}.h-\[190px\]{height:190px}.h-\[220px\]{height:220px}.h-\[330px\]{height:330px}.h-\[560px\]{height:560px}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-60{max-height:calc(var(--spacing) * 60)}.max-h-96{max-height:calc(var(--spacing) * 96)}.max-h-full{max-height:100%}.min-h-6{min-height:calc(var(--spacing) * 6)}.min-h-11{min-height:calc(var(--spacing) * 11)}.min-h-screen{min-height:100vh}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-9\.5{width:calc(var(--spacing) * 9.5)}.w-10{width:calc(var(--spacing) * 10)}.w-11{width:calc(var(--spacing) * 11)}.w-12{width:calc(var(--spacing) * 12)}.w-14{width:calc(var(--spacing) * 14)}.w-16{width:calc(var(--spacing) * 16)}.w-20{width:calc(var(--spacing) * 20)}.w-23{width:calc(var(--spacing) * 23)}.w-24{width:calc(var(--spacing) * 24)}.w-28{width:calc(var(--spacing) * 28)}.w-40{width:calc(var(--spacing) * 40)}.w-44{width:calc(var(--spacing) * 44)}.w-48{width:calc(var(--spacing) * 48)}.w-56{width:calc(var(--spacing) * 56)}.w-60{width:calc(var(--spacing) * 60)}.w-64{width:calc(var(--spacing) * 64)}.w-72{width:calc(var(--spacing) * 72)}.w-80{width:calc(var(--spacing) * 80)}.w-\[3px\]{width:3px}.w-\[7px\]{width:7px}.w-\[36rem\]{width:36rem}.w-\[68px\]{width:68px}.w-\[236px\]{width:236px}.w-\[460px\]{width:460px}.w-auto{width:auto}.w-fit{width:fit-content}.w-full{width:100%}.w-px{width:1px}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-6xl{max-width:var(--container-6xl)}.max-w-40{max-width:calc(var(--spacing) * 40)}.max-w-\[35\%\]{max-width:35%}.max-w-\[91vw\]{max-width:91vw}.max-w-\[1440px\]{max-width:1440px}.max-w-full{max-width:100%}.max-w-md{max-width:var(--container-md)}.max-w-none{max-width:none}.max-w-xl{max-width:var(--container-xl)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:0}.min-w-4{min-width:calc(var(--spacing) * 4)}.min-w-40{min-width:calc(var(--spacing) * 40)}.min-w-\[19px\]{min-width:19px}.min-w-\[220px\]{min-width:220px}.flex-1{flex:1}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.border-collapse{border-collapse:collapse}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.cursor-pointer{cursor:pointer}.resize{resize:both}.scrollbar-gutter-stable{scrollbar-gutter:stable}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.list-none{list-style-type:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.flex-nowrap{flex-wrap:nowrap}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-start{justify-content:flex-start}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-3\.5{gap:calc(var(--spacing) * 3.5)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-10{gap:calc(var(--spacing) * 10)}.gap-px{gap:1px}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-y-2{row-gap:calc(var(--spacing) * 2)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-rule>:not(:last-child)){border-color:var(--color-rule)}.self-start{align-self:flex-start}.self-stretch{align-self:stretch}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-\[10px\]{border-radius:10px}.rounded-\[14px\]{border-radius:14px}.rounded-box{border-radius:var(--radius-box)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-\[1\.5px\]{border-style:var(--tw-border-style);border-width:1.5px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.border-l-\[3px\]{border-left-style:var(--tw-border-style);border-left-width:3px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-\[\#2C3B56\]{border-color:#2c3b56}.border-\[\#DDE1E7\]{border-color:#dde1e7}.border-club{border-color:var(--color-club)}.border-danger-border{border-color:var(--color-danger-border)}.border-edge{border-color:var(--color-edge)}.border-ice{border-color:var(--color-ice)}.border-info{border-color:var(--color-info)}.border-info-border{border-color:var(--color-info-border)}.border-ink{border-color:var(--color-ink)}.border-line{border-color:var(--color-line)}.border-on-dark-faint{border-color:var(--color-on-dark-faint)}.border-rule{border-color:var(--color-rule)}.border-stroke{border-color:var(--color-stroke)}.border-warn{border-color:var(--color-warn)}.border-warn-border{border-color:var(--color-warn-border)}.border-white\/20{border-color:#fff3}@supports (color:color-mix(in lab, red, red)){.border-white\/20{border-color:color-mix(in oklab, var(--color-white) 20%, transparent)}}.border-white\/30{border-color:#ffffff4d}@supports (color:color-mix(in lab, red, red)){.border-white\/30{border-color:color-mix(in oklab, var(--color-white) 30%, transparent)}}.border-l-club{border-left-color:var(--color-club)}.border-l-club-dark{border-left-color:var(--color-club-dark)}.border-l-info{border-left-color:var(--color-info)}.border-l-transparent{border-left-color:#0000}.border-l-warn{border-left-color:var(--color-warn)}.bg-\[var\(--club\)\]{background-color:var(--club)}.bg-black\/20{background-color:#0003}@supports (color:color-mix(in lab, red, red)){.bg-black\/20{background-color:color-mix(in oklab, var(--color-black) 20%, transparent)}}.bg-club{background-color:var(--color-club)}.bg-danger-bg{background-color:var(--color-danger-bg)}.bg-edge{background-color:var(--color-edge)}.bg-hairline{background-color:var(--color-hairline)}.bg-ice{background-color:var(--color-ice)}.bg-info{background-color:var(--color-info)}.bg-info-bg{background-color:var(--color-info-bg)}.bg-ink{background-color:var(--color-ink)}.bg-line{background-color:var(--color-line)}.bg-navy{background-color:var(--color-navy)}.bg-ok{background-color:var(--color-ok)}.bg-paper{background-color:var(--color-paper)}.bg-row-focus{background-color:var(--color-row-focus)}.bg-row-sel{background-color:var(--color-row-sel)}.bg-rule{background-color:var(--color-rule)}.bg-steel{background-color:var(--color-steel)}.bg-steel\/60{background-color:#1b2b4799}@supports (color:color-mix(in lab, red, red)){.bg-steel\/60{background-color:color-mix(in oklab, var(--color-steel) 60%, transparent)}}.bg-subhead{background-color:var(--color-subhead)}.bg-warn{background-color:var(--color-warn)}.bg-warn-bg{background-color:var(--color-warn-bg)}.bg-white{background-color:var(--color-white)}.bg-white\/10{background-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.bg-white\/10{background-color:color-mix(in oklab, var(--color-white) 10%, transparent)}}.bg-white\/15{background-color:#ffffff26}@supports (color:color-mix(in lab, red, red)){.bg-white\/15{background-color:color-mix(in oklab, var(--color-white) 15%, transparent)}}.stroke-2{stroke-width:2px}.object-contain{object-fit:contain}.object-cover{object-fit:cover}.p-1{padding:var(--spacing)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-3\.5{padding:calc(var(--spacing) * 3.5)}.p-4{padding:calc(var(--spacing) * 4)}.p-4\.5{padding:calc(var(--spacing) * 4.5)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-10{padding:calc(var(--spacing) * 10)}.p-\[18px\]{padding:18px}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-4\.5{padding-inline:calc(var(--spacing) * 4.5)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-7{padding-inline:calc(var(--spacing) * 7)}.px-8{padding-inline:calc(var(--spacing) * 8)}.px-\[3px\]{padding-inline:3px}.px-\[18px\]{padding-inline:18px}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-5{padding-block:calc(var(--spacing) * 5)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-10{padding-block:calc(var(--spacing) * 10)}.py-14{padding-block:calc(var(--spacing) * 14)}.py-\[5px\]{padding-block:5px}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-3\.5{padding-top:calc(var(--spacing) * 3.5)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pb-0{padding-bottom:0}.pb-0\.5{padding-bottom:calc(var(--spacing) * .5)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pb-6{padding-bottom:calc(var(--spacing) * 6)}.pb-\[22px\]{padding-bottom:22px}.pb-\[26px\]{padding-bottom:26px}.pl-2\.5{padding-left:calc(var(--spacing) * 2.5)}.pl-8{padding-left:calc(var(--spacing) * 8)}.pl-9{padding-left:calc(var(--spacing) * 9)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.align-middle{vertical-align:middle}.font-display{font-family:var(--font-display)}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[13px\]{font-size:13px}.text-\[15px\]{font-size:15px}.text-\[17px\]{font-size:17px}.text-\[19px\]{font-size:19px}.text-\[22px\]{font-size:22px}.text-\[34px\]{font-size:34px}.text-\[56px\]{font-size:56px}.leading-\[\.94\]{--tw-leading:.94;line-height:.94}.leading-\[\.95\]{--tw-leading:.95;line-height:.95}.leading-\[\.96\]{--tw-leading:.96;line-height:.96}.leading-\[\.98\]{--tw-leading:.98;line-height:.98}.leading-\[1\.05\]{--tw-leading:1.05;line-height:1.05}.leading-\[1\.5\]{--tw-leading:1.5;line-height:1.5}.leading-\[1\.6\]{--tw-leading:1.6;line-height:1.6}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-extrabold{--tw-font-weight:var(--font-weight-extrabold);font-weight:var(--font-weight-extrabold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[\.1em\]{--tw-tracking:.1em;letter-spacing:.1em}.tracking-\[\.04em\]{--tw-tracking:.04em;letter-spacing:.04em}.tracking-\[\.06em\]{--tw-tracking:.06em;letter-spacing:.06em}.tracking-\[\.08em\]{--tw-tracking:.08em;letter-spacing:.08em}.tracking-\[\.12em\]{--tw-tracking:.12em;letter-spacing:.12em}.tracking-\[\.14em\]{--tw-tracking:.14em;letter-spacing:.14em}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[\#4A5566\]{color:#4a5566}.text-club{color:var(--color-club)}.text-club-content{color:var(--color-club-content)}.text-club-dark{color:var(--color-club-dark)}.text-dim{color:var(--color-dim)}.text-edge{color:var(--color-edge)}.text-gray-500{color:var(--color-gray-500)}.text-ice{color:var(--color-ice)}.text-ice-ink{color:var(--color-ice-ink)}.text-info{color:var(--color-info)}.text-info-text{color:var(--color-info-text)}.text-ink{color:var(--color-ink)}.text-muted{color:var(--color-muted)}.text-ok{color:var(--color-ok)}.text-ok-text{color:var(--color-ok-text)}.text-on-dark{color:var(--color-on-dark)}.text-on-dark-dim{color:var(--color-on-dark-dim)}.text-on-dark-faint{color:var(--color-on-dark-faint)}.text-referee{color:var(--color-referee)}.text-sky-500{color:var(--color-sky-500)}.text-slate{color:var(--color-slate)}.text-warn{color:var(--color-warn)}.text-warn-deep{color:var(--color-warn-deep)}.text-warn-text{color:var(--color-warn-text)}.text-white{color:var(--color-white)}.text-white\/80{color:#fffc}@supports (color:color-mix(in lab, red, red)){.text-white\/80{color:color-mix(in oklab, var(--color-white) 80%, transparent)}}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.line-through{text-decoration-line:line-through}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.accent-ink{accent-color:var(--color-ink)}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-80{opacity:.8}.opacity-\[\.72\]{opacity:.72}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[-24px_0_60px_rgba\(11\,18\,32\,\.2\)\]{--tw-shadow:-24px 0 60px var(--tw-shadow-color,#0b122033);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_24px_60px_rgba\(11\,18\,32\,\.18\)\]{--tw-shadow:0 24px 60px var(--tw-shadow-color,#0b12202e);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[inset_3px_0_0_var\(--color-info\)\]{--tw-shadow:inset 3px 0 0 var(--tw-shadow-color,var(--color-info));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-offset-2{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);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,)}.grayscale{--tw-grayscale:grayscale(100%);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,)}.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-filter{-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,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.placeholder\:text-dim::placeholder{color:var(--color-dim)}.placeholder\:text-on-dark::placeholder{color:var(--color-on-dark)}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.empty\:hidden:empty{display:none}@media (hover:hover){.hover\:border-white:hover{border-color:var(--color-white)}.hover\:bg-ink:hover{background-color:var(--color-ink)}.hover\:bg-rule:hover{background-color:var(--color-rule)}.hover\:bg-steel:hover{background-color:var(--color-steel)}.hover\:bg-subhead:hover{background-color:var(--color-subhead)}.hover\:bg-white\/25:hover{background-color:#ffffff40}@supports (color:color-mix(in lab, red, red)){.hover\:bg-white\/25:hover{background-color:color-mix(in oklab, var(--color-white) 25%, transparent)}}.hover\:text-ink:hover{color:var(--color-ink)}.hover\:text-white:hover{color:var(--color-white)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}}.focus\:border-ink:focus{border-color:var(--color-ink)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.has-checked\:border-ink:has(:checked){border-color:var(--color-ink)}.has-checked\:bg-ink:has(:checked){background-color:var(--color-ink)}.has-checked\:text-white:has(:checked){color:var(--color-white)}@media (min-width:40rem){.sm\:col-span-2{grid-column:span 2/span 2}.sm\:block{display:block}.sm\:hidden{display:none}.sm\:inline{display:inline}.sm\:h-16{height:calc(var(--spacing) * 16)}.sm\:w-16{width:calc(var(--spacing) * 16)}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.sm\:gap-3{gap:calc(var(--spacing) * 3)}.sm\:px-6{padding-inline:calc(var(--spacing) * 6)}.sm\:text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.sm\:text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}}@media (min-width:48rem){.md\:col-span-2{grid-column:span 2/span 2}.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\:text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}}@media (min-width:64rem){.lg\:flex{display:flex}.lg\:w-fit{width:fit-content}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}}@media (min-width:80rem){.xl\:sticky{position:sticky}.xl\:top-4{top:calc(var(--spacing) * 4)}.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.xl\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.xl\:grid-cols-\[1\.2fr_1fr\]{grid-template-columns:1.2fr 1fr}.xl\:grid-cols-\[1\.6fr_1fr\]{grid-template-columns:1.6fr 1fr}.xl\:grid-cols-\[1\.35fr_1fr\]{grid-template-columns:1.35fr 1fr}.xl\:self-start{align-self:flex-start}}.\[\&\:\:-webkit-details-marker\]\:hidden::-webkit-details-marker{display:none}}@font-face{font-family:Barlow;font-style:normal;font-weight:400;font-display:swap;src:url(../fonts/barlow-latin-400-normal.woff2)format("woff2");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow;font-style:normal;font-weight:500;font-display:swap;src:url(../fonts/barlow-latin-500-normal.woff2)format("woff2");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow;font-style:normal;font-weight:600;font-display:swap;src:url(../fonts/barlow-latin-600-normal.woff2)format("woff2");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow;font-style:normal;font-weight:700;font-display:swap;src:url(../fonts/barlow-latin-700-normal.woff2)format("woff2");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow Condensed;font-style:normal;font-weight:600;font-display:swap;src:url(../fonts/barlow-condensed-latin-600-normal.woff2)format("woff2");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow Condensed;font-style:normal;font-weight:700;font-display:swap;src:url(../fonts/barlow-condensed-latin-700-normal.woff2)format("woff2");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow Condensed;font-style:normal;font-weight:800;font-display:swap;src:url(../fonts/barlow-condensed-latin-800-normal.woff2)format("woff2");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:IBM Plex Mono;font-style:normal;font-weight:400;font-display:swap;src:url(../fonts/ibm-plex-mono-latin-400-normal.woff2)format("woff2");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:IBM Plex Mono;font-style:normal;font-weight:500;font-display:swap;src:url(../fonts/ibm-plex-mono-latin-500-normal.woff2)format("woff2");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@keyframes pulse{50%{opacity:.5}}
\ No newline at end of file