Fix scrambled mobile layout on member detail and sweep the rest of the app

The mobile responsive pass still had real gaps: on member_detail.html,
dt/dd label-value rows (phone numbers, dates) squeezed onto one line
below `sm` instead of stacking, and guardian call/emergency-call
buttons -- whose labels embed the guardian's name -- used a bare
`grow` inside a non-wrapping flex row, pushing the whole row off
screen once a name was long enough. Both patterns are fixed here and
propagated to every other page with the same shape of bug:
event_detail.html and event_series_detail.html still had the
unmigrated dt/dd rows from before the first pass; sponsor_list.html's
URLs and parent_claim_list.html's emails could force a table-card
wider than the viewport (unbreakable strings, fixed with break-all);
parent_claim_list.html's Approve/Reject buttons could both land on
the left edge once the row wrapped (fixed with ms-auto); news_list.html's
team-badge list and news_detail.html's per-photo action buttons were
missing flex-wrap; team_detail.html had a stray table never converted
to table-cards and two unstacked stat lists; referee_management.html's
per-game referee badges were missing flex-wrap.

Also hide the three dashboard charts (signups, fee status, renewal
rate) below `lg` -- three squeezed canvases stacked on a phone added
scroll without adding readability the stat cards above don't already
give, and match family_list.html's search box to member_list.html's
icon-only-below-`sm` pattern.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-16 10:35:26 +02:00
parent 9f4a0ea687
commit bff685966d
13 changed files with 123 additions and 89 deletions

View File

@@ -19,7 +19,7 @@
</div>
<ul class="divide-y divide-base-200">
{% for referee in referees %}
<li class="flex items-center justify-between py-2 gap-2">
<li class="flex flex-col gap-1 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<span>
{{ referee.display_name }}
{% if referee.is_external %}<span class="badge badge-neutral badge-xs">{% trans "External" %}</span>{% endif %}

View File

@@ -37,42 +37,42 @@
<div class="card-body">
<h2 class="card-title text-base">{% lucide "info" size=18 %} {% trans "Details" %}</h2>
<dl class="divide-y divide-base-200">
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "Start" %}</dt>
<dd>{{ event.start|date:"j M Y H:i" }}</dd>
<dd class="sm:text-right">{{ event.start|date:"j M Y H:i" }}</dd>
</div>
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "End" %}</dt>
<dd>{{ event.end|date:"j M Y H:i"|default:"—" }}</dd>
<dd class="sm:text-right">{{ event.end|date:"j M Y H:i"|default:"—" }}</dd>
</div>
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "Gathering" %}</dt>
<dd>{{ event.gathering|date:"j M Y H:i"|default:"—" }}</dd>
<dd class="sm:text-right">{{ event.gathering|date:"j M Y H:i"|default:"—" }}</dd>
</div>
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "Registration deadline" %}</dt>
<dd>{{ event.deadline|date:"j M Y H:i"|default:"—" }}</dd>
<dd class="sm:text-right">{{ event.deadline|date:"j M Y H:i"|default:"—" }}</dd>
</div>
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "Location" %}</dt>
<dd>{{ event.location|default:"—" }}</dd>
<dd class="sm:text-right">{{ event.location|default:"—" }}</dd>
</div>
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "Opponent" %}</dt>
<dd>{{ event.opponent|default:"—" }}</dd>
<dd class="sm:text-right">{{ event.opponent|default:"—" }}</dd>
</div>
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "Teams" %}</dt>
<dd>{% for team in event.teams.all %}{{ team.name }}{% if not forloop.last %}, {% endif %}{% empty %}—{% endfor %}</dd>
<dd class="sm:text-right">{% for team in event.teams.all %}{{ team.name }}{% if not forloop.last %}, {% endif %}{% empty %}—{% endfor %}</dd>
</div>
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "Groups" %}</dt>
<dd>{% for group in event.groups.all %}{{ group.name }}{% if not forloop.last %}, {% endif %}{% empty %}—{% endfor %}</dd>
<dd class="sm:text-right">{% for group in event.groups.all %}{{ group.name }}{% if not forloop.last %}, {% endif %}{% empty %}—{% endfor %}</dd>
</div>
{% if event.club_wide %}
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "Audience" %}</dt>
<dd><span class="badge badge-primary">{% trans "Whole club" %}</span></dd>
<dd class="sm:text-right"><span class="badge badge-primary">{% trans "Whole club" %}</span></dd>
</div>
{% endif %}
</dl>
@@ -91,9 +91,9 @@
</div>
<dl class="divide-y divide-base-200">
{% for group in attendance_groups %}
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{{ group.label }}</dt>
<dd class="font-semibold tabular-nums font-mono">{{ group.rows|length }}</dd>
<dd class="font-semibold tabular-nums font-mono sm:text-right">{{ group.rows|length }}</dd>
</div>
{% endfor %}
</dl>

View File

@@ -22,21 +22,21 @@
<div class="card-body">
<h2 class="card-title text-base">{% lucide "repeat" size=18 %} {% trans "Recurrence" %}</h2>
<dl class="divide-y divide-base-200">
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "Pattern" %}</dt>
<dd>{{ recurrence_summary }}</dd>
<dd class="sm:text-right">{{ recurrence_summary }}</dd>
</div>
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "First occurrence" %}</dt>
<dd>{{ series.dtstart|date:"j M Y H:i" }}</dd>
<dd class="sm:text-right">{{ series.dtstart|date:"j M Y H:i" }}</dd>
</div>
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "Repeats until" %}</dt>
<dd>{{ series.until|date:"j M Y H:i"|default:"—" }}</dd>
<dd class="sm:text-right">{{ series.until|date:"j M Y H:i"|default:"—" }}</dd>
</div>
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "Generated up to" %}</dt>
<dd>{{ series.generated_until|date:"j M Y"|default:"—" }}</dd>
<dd class="sm:text-right">{{ series.generated_until|date:"j M Y"|default:"—" }}</dd>
</div>
</dl>
</div>
@@ -46,17 +46,17 @@
<div class="card-body">
<h2 class="card-title text-base">{% lucide "info" size=18 %} {% trans "Template" %}</h2>
<dl class="divide-y divide-base-200">
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "Location" %}</dt>
<dd>{{ series.location|default:"—" }}</dd>
<dd class="sm:text-right">{{ series.location|default:"—" }}</dd>
</div>
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "Opponent" %}</dt>
<dd>{{ series.opponent|default:"—" }}</dd>
<dd class="sm:text-right">{{ series.opponent|default:"—" }}</dd>
</div>
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "Teams" %}</dt>
<dd>{% for team in series.teams.all %}{{ team.name }}{% if not forloop.last %}, {% endif %}{% empty %}—{% endfor %}</dd>
<dd class="sm:text-right">{% for team in series.teams.all %}{{ team.name }}{% if not forloop.last %}, {% endif %}{% empty %}—{% endfor %}</dd>
</div>
</dl>
</div>

View File

@@ -11,14 +11,15 @@
{% endblock actions %}
{% block panel %}
<form method="get" class="mb-2 flex flex-wrap items-center gap-2">
<label class="input">
<form method="get" class="mb-2 flex items-center gap-2">
<label class="input grow sm:grow-0">
<span class="opacity-50">{% lucide "search" size=16 %}</span>
<input type="search" name="q" value="{{ search }}" placeholder="{% trans 'Search by parent or child name ...' %}" class="input input-bordered w-full max-w-xs">
<input type="search" name="q" value="{{ search }}" placeholder="{% trans 'Search by parent or child name ...' %}" class="input input-bordered w-full sm:max-w-xs">
</label>
<button class="btn btn-outline gap-2" type="submit">{% lucide "search" size=16 %} {% trans "Search" %}</button>
{# Icon-only below `sm`: label text next to a growing input is what forced this row to wrap on a phone. #}
<button class="btn btn-outline gap-2" type="submit" aria-label="{% trans 'Search' %}">{% lucide "search" size=16 %}<span class="hidden sm:inline">{% trans "Search" %}</span></button>
{% if search %}
<a class="btn gap-2" href="{% url "management:family_list" %}">{% lucide "x" size=16 %} {% trans "Clear filter" %}</a>
<a class="btn gap-2" href="{% url "management:family_list" %}" aria-label="{% trans 'Clear filter' %}">{% lucide "x" size=16 %}<span class="hidden sm:inline">{% trans "Clear filter" %}</span></a>
{% endif %}
</form>

View File

@@ -140,7 +140,8 @@
</div>
{% if is_club_admin %}
<div class="mb-6 grid gap-4 lg:grid-cols-3">
{# Charts are desktop-only: three squeezed canvases stacked on a phone add scroll without adding much readability -- the same numbers already sit in the stat cards above. #}
<div class="mb-6 hidden gap-4 lg:grid lg:grid-cols-3">
<div class="card bg-base-100 shadow">
<div class="card-body">
<h2 class="card-title text-base">{% lucide "user-plus" size=18 %} {% trans "Signups per month" %}</h2>

View File

@@ -16,36 +16,37 @@
<div class="card-body">
<h2 class="card-title text-base">{% lucide "user" size=18 %} {% trans "Personal information" %}</h2>
<dl class="divide-y divide-base-200">
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "Date of birth" %}</dt>
<dd class="font-semibold">{{ member.date_of_birth|default:"-" }}</dd>
<dd class="font-semibold sm:text-right">{{ member.date_of_birth|default:"-" }}</dd>
</div>
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "Phone" %}</dt>
<dd class="font-semibold">{{ member.phone.as_international|default:"-" }}</dd>
<dd class="font-semibold sm:text-right">{{ member.phone.as_international|default:"-" }}</dd>
</div>
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "Emergency phone" %}</dt>
<dd class="font-semibold">{{ member.emergency_phone.as_international|default:"-" }}</dd>
<dd class="font-semibold sm:text-right">{{ member.emergency_phone.as_international|default:"-" }}</dd>
</div>
{% for guardian in guardians %}
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "Parent phone" %} — {{ guardian.get_full_name }}</dt>
<dd class="font-semibold">{{ guardian.phone.as_international|default:"-" }}</dd>
<dd class="font-semibold sm:text-right">{{ guardian.phone.as_international|default:"-" }}</dd>
</div>
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "Parent emergency phone" %} — {{ guardian.get_full_name }}</dt>
<dd class="font-semibold">{{ guardian.emergency_phone.as_international|default:"-" }}</dd>
<dd class="font-semibold sm:text-right">{{ guardian.emergency_phone.as_international|default:"-" }}</dd>
</div>
{% endfor %}
</dl>
<div class="flex flex-row gap-2 items-center mt-2">
{# flex-col below `sm`: a button's own label never wraps, so two grow buttons side by side in a fixed row push wider than the screen once either label is long -- stacking avoids that regardless of label length. #}
<div class="flex flex-col gap-2 sm:flex-row sm:items-center mt-2">
{% if member.phone %}
<a class="btn btn-sm btn-outline btn-primary grow" href="tel:{{ member.phone.as_international }}">{% lucide "phone" size=14 %} {% trans "Call" %}</a>
<a class="btn btn-sm btn-outline btn-primary sm:grow" href="tel:{{ member.phone.as_international }}">{% lucide "phone" size=14 %} {% trans "Call" %}</a>
{% endif %}
{% if member.emergency_phone %}
<a class="btn btn-sm btn-outline btn-error grow" href="tel:{{ member.emergency_phone.as_international }}">{% lucide "shield-alert" size=14 %} {% trans "Emergency call" %}</a>
<a class="btn btn-sm btn-outline btn-error sm:grow" href="tel:{{ member.emergency_phone.as_international }}">{% lucide "shield-alert" size=14 %} {% trans "Emergency call" %}</a>
{% endif %}
</div>
@@ -56,12 +57,12 @@
</div>
{% for guardian in guardians %}
{% if guardian.phone or guardian.emergency_phone %}
<div class="flex flex-row gap-2 items-center mt-2">
<div class="flex flex-col gap-2 sm:flex-row sm:items-center mt-2">
{% if guardian.phone %}
<a class="btn btn-sm btn-outline btn-primary grow" href="tel:{{ guardian.phone.as_international }}">{% lucide "phone" size=14 %} {% blocktrans with name=guardian.get_full_name %}Call {{ name }}{% endblocktrans %}</a>
<a class="btn btn-sm btn-outline btn-primary sm:grow" href="tel:{{ guardian.phone.as_international }}">{% lucide "phone" size=14 %} {% blocktrans with name=guardian.get_full_name %}Call {{ name }}{% endblocktrans %}</a>
{% endif %}
{% if guardian.emergency_phone %}
<a class="btn btn-sm btn-outline btn-error grow" href="tel:{{ guardian.emergency_phone.as_international }}">{% lucide "shield-alert" size=14 %} {% blocktrans with name=guardian.get_full_name %}Emergency: {{ name }}{% endblocktrans %}</a>
<a class="btn btn-sm btn-outline btn-error sm:grow" href="tel:{{ guardian.emergency_phone.as_international }}">{% lucide "shield-alert" size=14 %} {% blocktrans with name=guardian.get_full_name %}Emergency: {{ name }}{% endblocktrans %}</a>
{% endif %}
</div>
{% endif %}
@@ -92,22 +93,22 @@
</div>
{% endif %}
<dl class="divide-y divide-base-200">
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "Joined as" %}</dt>
<dd class="font-semibold">{{ current_membership.get_kind_display|capfirst }}</dd>
<dd class="font-semibold sm:text-right">{{ current_membership.get_kind_display|capfirst }}</dd>
</div>
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "License" %}</dt>
<dd class="font-semibold">{{ current_membership.license|default:"-" }}</dd>
<dd class="font-semibold sm:text-right">{{ current_membership.license|default:"-" }}</dd>
</div>
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "Status" %}</dt>
<dd class="font-semibold">{{ current_membership.get_status_display }}</dd>
<dd class="font-semibold sm:text-right">{{ current_membership.get_status_display }}</dd>
</div>
{% if not current_membership.is_guardian %}
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "Fee status" %}</dt>
<dd class="font-semibold">{{ current_membership.get_fee_status_display }}</dd>
<dd class="font-semibold sm:text-right">{{ current_membership.get_fee_status_display }}</dd>
</div>
{% endif %}
</dl>
@@ -157,11 +158,11 @@
{% if referee_profile and referee_profile.level %}
<dl class="divide-y divide-base-200">
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "Level" %}</dt>
<dd class="font-semibold">{{ referee_profile.level }}</dd>
<dd class="font-semibold sm:text-right">{{ referee_profile.level }}</dd>
</div>
<div class="flex items-center justify-between py-2">
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<dt class="text-sm opacity-70">{% trans "Valid until" %}</dt>
<dd class="font-semibold flex items-center gap-2">
{{ referee_profile.valid_until|default:"—" }}

View File

@@ -68,7 +68,7 @@
<span class="badge badge-success badge-sm absolute top-1 left-1">{% trans "Main" %}</span>
{% endif %}
{% if can_edit %}
<div class="flex gap-1 mt-1">
<div class="flex flex-wrap gap-1 mt-1">
{% if not photo.is_main %}
<form method="post" action="{% url 'management:news_photo_set_main' news_item.pk photo.pk %}">
{% csrf_token %}

View File

@@ -28,11 +28,13 @@
<tr>
<td><a class="link link-hover font-semibold" href="{% url 'management:news_detail' news_item.pk %}">{{ news_item.title }}</a></td>
<td data-label="{% trans 'Teams' %}">
{% for team in news_item.teams.all %}
<span class="badge badge-neutral badge-sm">{{ team.short_name }}</span>
{% empty %}
<span class="opacity-60">{% trans "Club-wide" %}</span>
{% endfor %}
<div class="flex flex-wrap gap-2">
{% for team in news_item.teams.all %}
<span class="badge badge-neutral badge-sm">{{ team.short_name }}</span>
{% empty %}
<span class="opacity-60">{% trans "Club-wide" %}</span>
{% endfor %}
</div>
</td>
<td data-label="{% trans 'Visibility' %}">{{ news_item.get_visibility_display }}</td>
<td data-label="{% trans 'Status' %}">
@@ -46,7 +48,7 @@
</td>
<td class="text-right">
{% if news_item.can_edit %}
<div class="flex justify-end gap-1">
<div class="flex flex-wrap justify-end gap-1">
<a class="btn btn-outline btn-sm" href="{% url 'management:news_detail' news_item.pk %}" aria-label="{% trans 'Edit' %}">{% lucide "pencil" size=14 %} {% trans "Edit" %}</a>
<button class="btn btn-sm btn-outline btn-error" type="button" onclick="document.getElementById('{{ news_item.pk|dom_id:"news_delete_modal" }}').showModal()" aria-label="{% trans 'Delete' %}">{% lucide "trash-2" size=14 %} {% trans "Delete" %}</button>
</div>

View File

@@ -19,7 +19,7 @@
<div>
<div class="text-xs opacity-70">{% trans "Parent says they are" %}</div>
<div class="font-semibold">{{ claim.parent_name }}</div>
<div class="text-sm opacity-70">{{ claim.parent_email }}</div>
<div class="text-sm opacity-70 break-all">{{ claim.parent_email }}</div>
</div>
<div>
<div class="text-xs opacity-70">{% trans "Parent of" %}</div>
@@ -36,7 +36,12 @@
justify-between (rather than everything in one flex-wrap run) keeps
Approve and Reject apart even as the row wraps on a narrow card --
Approve stays pinned left, Reject right, so the two are never one
stray click apart the way adjacent buttons would be.
stray click apart the way adjacent buttons would be. ms-auto on Reject
is the part that actually guarantees "right": once the row is narrow
enough that Approve and Reject fall onto separate flex-wrap lines,
justify-between has only one item per line and pins it to the *start*
-- margin-inline-start:auto keeps Reject flush right regardless of
which line it ends up sharing (or not sharing) with Approve.
{% endcomment %}
<div class="flex flex-wrap items-center justify-between gap-x-4 gap-y-2">
{% if claim.has_candidates %}
@@ -49,7 +54,7 @@
<p class="text-sm opacity-70">{% trans "No child without a parent matches this. Check the spelling and the date of birth with them before rejecting." %}</p>
{% endif %}
<button class="btn btn-outline btn-error btn-sm gap-2" type="button" onclick="document.getElementById('{{ claim.pk|dom_id:"claim_reject_modal" }}').showModal()">
<button class="btn btn-outline btn-error btn-sm gap-2 ms-auto" type="button" onclick="document.getElementById('{{ claim.pk|dom_id:"claim_reject_modal" }}').showModal()">
{% lucide "x" size=14 %} {% trans "Reject" %}
</button>
</div>
@@ -76,9 +81,9 @@
<p class="text-sm opacity-70">{% trans "Imported without a parent. They stay here until someone claims them." %}</p>
<ul class="divide-y divide-base-200">
{% for child in awaiting_a_parent %}
<li class="py-2 flex items-center justify-between">
<li class="py-2 flex flex-col gap-0.5 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<a class="link link-hover" href="{% url 'management:member_detail' child.pk %}">{{ child }}</a>
<span class="text-sm opacity-70">{{ child.date_of_birth|date:"j F Y"|default:"—" }}</span>
<span class="text-sm opacity-70 sm:text-right">{{ child.date_of_birth|date:"j F Y"|default:"—" }}</span>
</li>
{% empty %}
<li class="py-2 text-sm opacity-60">{% trans "Every child has a parent linked." %}</li>
@@ -104,7 +109,7 @@
<tbody>
{% for claim in reviewed %}
<tr>
<td class="font-semibold">{{ claim.parent_name }}<div class="text-xs font-normal opacity-60">{{ claim.parent_email }}</div></td>
<td class="font-semibold">{{ claim.parent_name }}<div class="text-xs font-normal opacity-60 break-all">{{ claim.parent_email }}</div></td>
<td data-label="{% trans 'Claimed' %}">{{ claim.claimed_child_name }}</td>
<td data-label="{% trans 'Outcome' %}">
{% if claim.status == "approved" %}

View File

@@ -52,7 +52,7 @@
{% if game.opponent %}{% trans "vs" %} {{ game.opponent }}{% endif %}
</a>
<div class="text-xs opacity-70">{{ game.start|date:"H:i" }}{% if game.location %} — {{ game.location }}{% endif %}</div>
<div class="text-xs">
<div class="flex flex-wrap gap-1 text-xs">
{% for referee in game.referee_rows %}
<span class="badge badge-primary badge-sm">{{ referee.display_name }}{% if referee.is_external %} ({% trans "ext." %}){% endif %}</span>
{% empty %}

View File

@@ -33,7 +33,7 @@
<td class="font-semibold">{{ sponsor.name }}</td>
<td data-label="{% trans 'URL' %}">
{% if sponsor.url %}
<a class="link link-hover" href="{{ sponsor.url }}" target="_blank" rel="noopener noreferrer">{{ sponsor.url }}</a>
<a class="link link-hover break-all" href="{{ sponsor.url }}" target="_blank" rel="noopener noreferrer">{{ sponsor.url }}</a>
{% else %}
<span class="opacity-50">&mdash;</span>
{% endif %}

View File

@@ -78,7 +78,7 @@
<h2 class="card-title text-base">{% lucide "trending-up" size=18 %} {% trans "Top attenders" %}</h2>
<ul class="divide-y divide-base-200">
{% for entry in top_attenders %}
<li class="flex items-center justify-between py-2">
<li class="flex flex-col gap-1 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<span class="text-sm">{{ entry.member }}</span>
<span class="font-semibold tabular-nums font-mono">{{ entry.rate }}%</span>
</li>
@@ -94,7 +94,7 @@
<h2 class="card-title text-base">{% lucide "trending-down" size=18 %} {% trans "Needs attention" %}</h2>
<ul class="divide-y divide-base-200">
{% for entry in bottom_attenders %}
<li class="flex items-center justify-between py-2">
<li class="flex flex-col gap-1 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
<span class="text-sm">{{ entry.member }}</span>
<span class="font-semibold tabular-nums font-mono">{{ entry.rate }}%</span>
</li>
@@ -205,7 +205,7 @@
{% endif %}
</div>
<div class="overflow-x-auto">
<table class="table">
<table class="table table-cards">
<thead>
<tr>
<th>{% trans "Member" %}</th>
@@ -216,11 +216,11 @@
<tbody>
{% for assignment in staff %}
<tr>
<td>{{ assignment.member }}</td>
<td>{{ assignment.position }}</td>
<td class="font-semibold">{{ assignment.member }}</td>
<td data-label="{% trans 'Position' %}">{{ assignment.position }}</td>
<td class="text-right">
{% if can_manage %}
<div class="flex justify-end gap-1">
<div class="flex flex-wrap justify-end gap-1">
<button class="btn btn-outline btn-sm" type="button" onclick="document.getElementById('{{ assignment.pk|dom_id:"edit_staff_modal" }}').showModal()" aria-label="{% trans 'Edit' %}">{% lucide "pencil" size=14 %} {% trans "Edit" %}</button>
<button class="btn btn-sm btn-outline btn-error" type="button" onclick="document.getElementById('{{ assignment.pk|dom_id:"remove_staff_modal" }}').showModal()" aria-label="{% trans 'Remove' %}">{% lucide "user-minus" size=14 %} {% trans "Remove" %}</button>
</div>

View File

@@ -3107,6 +3107,9 @@
border-block-end-width: calc(var(--border, 1px) * var(--join-h));
}
}
.ms-auto {
margin-inline-start: auto;
}
.modal-action {
@layer daisyui.l1.l2.l3 {
margin-top: calc(0.25rem * 6);
@@ -3624,6 +3627,9 @@
.justify-start {
justify-content: flex-start;
}
.gap-0\.5 {
gap: calc(var(--spacing) * 0.5);
}
.gap-1 {
gap: var(--spacing);
}
@@ -4035,6 +4041,9 @@
--tw-tracking: var(--tracking-wider);
letter-spacing: var(--tracking-wider);
}
.break-all {
word-break: break-all;
}
.whitespace-nowrap {
white-space: nowrap;
}
@@ -4426,6 +4435,11 @@
max-width: var(--container-xs);
}
}
.sm\:grow {
@media (width >= 40rem) {
flex-grow: 1;
}
}
.sm\:grow-0 {
@media (width >= 40rem) {
flex-grow: 0;
@@ -4476,6 +4490,11 @@
padding-inline: calc(var(--spacing) * 6);
}
}
.sm\:text-right {
@media (width >= 40rem) {
text-align: right;
}
}
.sm\:text-2xl {
@media (width >= 40rem) {
font-size: var(--text-2xl);
@@ -4528,6 +4547,11 @@
display: flex;
}
}
.lg\:grid {
@media (width >= 64rem) {
display: grid;
}
}
.lg\:hidden {
@media (width >= 64rem) {
display: none;