Switch RSVP button rows to CSS grid; brighten the face-off meta line

flex-1 + min-w-0 still wasn't producing equal-width In/Out (and In/Maybe/
Out) buttons in practice -- a longer label's own content could still win
a wider share. Switched every such row to CSS grid (grid-cols-2/3): each
track is a content-independent minmax(0, 1fr), so equal width is
guaranteed by the grid itself rather than relying on flex-basis/min-width
interactions. Applied to the hero In/Out row, its Cancel/Confirm pair,
event_detail's 3-way In/Maybe/Out row, and its own Cancel/Confirm pair.

Also brightened the hero's face-off/meet/location meta line (was
text-on-dark, a dim grey) to plain white, matching the readability pass
already done on the "are you in?" subtext and the button labels.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ECGMEwrc2k4D8VQuwjstj9
This commit is contained in:
2026-08-22 15:51:29 +02:00
parent dba28ffc24
commit a9bf98a3c9
3 changed files with 27 additions and 21 deletions

View File

@@ -21,26 +21,31 @@
Neither button is colour-coded (no green "In") -- nobody has answered yet Neither button is colour-coded (no green "In") -- nobody has answered yet
at this point (that's the whole reason for the "are you in?" prompt), so at this point (that's the whole reason for the "are you in?" prompt), so
a green default would misleadingly read as an already-recorded answer. a green default would misleadingly read as an already-recorded answer.
Both are the same neutral steel tone with a shared border/white-Text Both are the same neutral steel tone with a shared border/white-text
treatment for readability against the photo backdrop, and via min-w-0, treatment for readability against the photo backdrop.
exactly the same width -- flex-1 alone doesn't guarantee that once one
button's label is longer ("Out" vs "In"): flex items default to The row is CSS grid (grid-cols-2), not flex -- flex-1 alone kept giving
min-width:auto, so the longer label's own intrinsic width can win a "Out" a wider share than "In" in practice (a longer label's own
bigger share of the row unless min-width is forced to 0 on both. intrinsic content width can still influence a flex item's rendered size
even with flex-basis:0, depending on what else is set on it/its
children -- min-w-0 didn't fully neutralise it here). Two equal-width
`1fr` grid columns don't have that ambiguity: track size is fixed by the
grid regardless of content, full stop.
The Out reason step (label + textarea + Cancel/Confirm) is wrapped in one The Out reason step (label + textarea + Cancel/Confirm) is wrapped in one
bordered/backed panel, same border colour as the In/Out pair -- reads as bordered/backed panel, same border colour as the In/Out pair -- reads as
one cohesive control rather than loose floating text and buttons. one cohesive control rather than loose floating text and buttons. Its
own Cancel/Confirm pair is grid-cols-2 for the same equal-width reason.
{% endcomment %} {% endcomment %}
<div class="mt-3" x-data="{ asking: false, reason: '{{ hero_attendance.note|default:""|escapejs }}' }"> <div class="mt-3" x-data="{ asking: false, reason: '{{ hero_attendance.note|default:""|escapejs }}' }">
<div class="flex gap-2" x-show="!asking"> <div class="grid grid-cols-2 gap-2" x-show="!asking">
<form class="min-w-0 flex-1" method="post" action="{% url "mobile:event_detail" hero_attendance.event.pk %}" hx-boost="false"> <form method="post" action="{% url "mobile:event_detail" hero_attendance.event.pk %}" hx-boost="false">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="member_id" value="{{ hero_attendance.member.pk }}"> <input type="hidden" name="member_id" value="{{ hero_attendance.member.pk }}">
<input type="hidden" name="status" value="present"> <input type="hidden" name="status" value="present">
<button class="btn w-full border border-white/30 bg-steel text-white" type="submit">{% trans "In" %}</button> <button class="btn w-full border border-white/30 bg-steel text-white" type="submit">{% trans "In" %}</button>
</form> </form>
<button class="btn w-full min-w-0 flex-1 border border-white/30 bg-steel text-white" type="button" @click="asking = true">{% trans "Out" %}</button> <button class="btn w-full border border-white/30 bg-steel text-white" type="button" @click="asking = true">{% trans "Out" %}</button>
</div> </div>
<form x-show="asking" x-cloak class="rounded-lg border border-white/30 bg-steel/60 p-3" method="post" action="{% url "mobile:event_detail" hero_attendance.event.pk %}" hx-boost="false"> <form x-show="asking" x-cloak class="rounded-lg border border-white/30 bg-steel/60 p-3" method="post" action="{% url "mobile:event_detail" hero_attendance.event.pk %}" hx-boost="false">
@@ -49,9 +54,9 @@
<input type="hidden" name="status" value="absent"> <input type="hidden" name="status" value="absent">
<label class="mb-1 block text-xs font-semibold text-white">{% trans "Reason -- only you and the coach can see this" %}</label> <label class="mb-1 block text-xs font-semibold text-white">{% trans "Reason -- only you and the coach can see this" %}</label>
<textarea class="h-16 w-full rounded-lg border border-white/20 bg-black/20 p-2 text-sm text-white placeholder:text-on-dark" name="note" x-model="reason" required minlength="2" placeholder="{% trans "e.g. sick, family event..." %}"></textarea> <textarea class="h-16 w-full rounded-lg border border-white/20 bg-black/20 p-2 text-sm text-white placeholder:text-on-dark" name="note" x-model="reason" required minlength="2" placeholder="{% trans "e.g. sick, family event..." %}"></textarea>
<div class="mt-2 flex gap-2"> <div class="mt-2 grid grid-cols-2 gap-2">
<button class="btn flex-1 border border-white/30 bg-steel text-white" type="button" @click="asking = false">{% trans "Cancel" %}</button> <button class="btn border border-white/30 bg-steel text-white" type="button" @click="asking = false">{% trans "Cancel" %}</button>
<button class="btn btn-dark flex-1 border border-white/30" type="submit">{% trans "Confirm" %}</button> <button class="btn btn-dark border border-white/30" type="submit">{% trans "Confirm" %}</button>
</div> </div>
</form> </form>
</div> </div>

View File

@@ -89,16 +89,17 @@
{% trans "Out" as label_out %} {% trans "Out" as label_out %}
{% with status=answer.attendance.status %} {% with status=answer.attendance.status %}
<div x-data="{ asking: null, reason: '{{ answer.attendance.note|default:""|escapejs }}' }"> <div x-data="{ asking: null, reason: '{{ answer.attendance.note|default:""|escapejs }}' }">
<div class="flex gap-1.5" x-show="!asking"> {# grid, not flex -- see _hero_rsvp.html's own comment: flex-1/min-w-0 kept letting a longer label win a wider share; grid-cols-3's tracks are content-independent. #}
<form class="min-w-0 flex-1" method="post" action="{% url "mobile:event_detail" event.pk %}" hx-boost="false"> <div class="grid grid-cols-3 gap-1.5" x-show="!asking">
<form method="post" action="{% url "mobile:event_detail" event.pk %}" hx-boost="false">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="member_id" value="{{ answer.member.pk }}"> <input type="hidden" name="member_id" value="{{ answer.member.pk }}">
<input type="hidden" name="status" value="present"> <input type="hidden" name="status" value="present">
<input type="hidden" name="next" value="event_detail"> <input type="hidden" name="next" value="event_detail">
<button type="submit" class="btn h-11 w-full text-[15px] {% if status == "present" %}btn-positive{% else %}bg-paper border border-stroke text-muted{% endif %}">{{ label_in }}</button> <button type="submit" class="btn h-11 w-full text-[15px] {% if status == "present" %}btn-positive{% else %}bg-paper border border-stroke text-muted{% endif %}">{{ label_in }}</button>
</form> </form>
<button type="button" class="btn h-11 w-full min-w-0 flex-1 text-[15px] {% if status == "maybe" %}bg-steel text-white{% else %}bg-paper border border-stroke text-muted{% endif %}" @click="asking = 'maybe'">{{ label_maybe }}</button> <button type="button" class="btn h-11 w-full text-[15px] {% if status == "maybe" %}bg-steel text-white{% else %}bg-paper border border-stroke text-muted{% endif %}" @click="asking = 'maybe'">{{ label_maybe }}</button>
<button type="button" class="btn h-11 w-full min-w-0 flex-1 text-[15px] {% if status == "absent" %}bg-club text-white{% else %}bg-paper border border-stroke text-muted{% endif %}" @click="asking = 'absent'">{{ label_out }}</button> <button type="button" class="btn h-11 w-full text-[15px] {% if status == "absent" %}bg-club text-white{% else %}bg-paper border border-stroke text-muted{% endif %}" @click="asking = 'absent'">{{ label_out }}</button>
</div> </div>
{% comment %} {% comment %}
@@ -117,9 +118,9 @@
<label class="mb-1 block text-xs font-semibold text-muted" x-show="asking === 'absent'">{% trans "Reason -- only you and the coach can see this" %}</label> <label class="mb-1 block text-xs font-semibold text-muted" x-show="asking === 'absent'">{% trans "Reason -- only you and the coach can see this" %}</label>
<label class="mb-1 block text-xs font-semibold text-muted" x-show="asking === 'maybe'">{% trans "Add a reason (optional) -- only you and the coach can see this" %}</label> <label class="mb-1 block text-xs font-semibold text-muted" x-show="asking === 'maybe'">{% trans "Add a reason (optional) -- only you and the coach can see this" %}</label>
<textarea class="h-16 w-full rounded-lg border border-stroke bg-paper p-2 text-sm text-ink" name="note" x-model="reason" placeholder="{% trans "e.g. sick, family event..." %}"></textarea> <textarea class="h-16 w-full rounded-lg border border-stroke bg-paper p-2 text-sm text-ink" name="note" x-model="reason" placeholder="{% trans "e.g. sick, family event..." %}"></textarea>
<div class="mt-2 flex gap-2"> <div class="mt-2 grid grid-cols-2 gap-2">
<button type="button" class="btn btn-secondary h-9 flex-1 text-xs" @click="asking = null">{% trans "Cancel" %}</button> <button type="button" class="btn btn-secondary h-9 text-xs" @click="asking = null">{% trans "Cancel" %}</button>
<button type="submit" class="btn btn-dark h-9 flex-1 text-xs">{% trans "Confirm" %}</button> <button type="submit" class="btn btn-dark h-9 text-xs">{% trans "Confirm" %}</button>
</div> </div>
</form> </form>
</div> </div>

View File

@@ -46,7 +46,7 @@
<p class="mt-1 font-display text-2xl leading-none font-extrabold uppercase">{{ hero_attendance.event.title }}</p> <p class="mt-1 font-display text-2xl leading-none font-extrabold uppercase">{{ hero_attendance.event.title }}</p>
</div> </div>
<div class="p-4"> <div class="p-4">
<div class="flex flex-wrap gap-4 font-mono text-xs text-on-dark"> <div class="flex flex-wrap gap-4 font-mono text-xs text-white">
<span>{% blocktrans with time=hero_attendance.event.start|date:"H:i" %}{{ time }} face-off{% endblocktrans %}</span> <span>{% blocktrans with time=hero_attendance.event.start|date:"H:i" %}{{ time }} face-off{% endblocktrans %}</span>
{% if hero_attendance.event.gathering %} {% if hero_attendance.event.gathering %}
<span>{% blocktrans with time=hero_attendance.event.gathering|date:"H:i" %}Meet {{ time }}{% endblocktrans %}</span> <span>{% blocktrans with time=hero_attendance.event.gathering|date:"H:i" %}Meet {{ time }}{% endblocktrans %}</span>