composer applets: .applet-btn-panel behind the OK btn for contrast on the --duoUser felt — TDD

Giving New Game / New Post the --duoUser green felt made the green OK .btn-confirm hard to see. Wrap it in an .applet-btn-panel — a --priUser fill + faint --terUser border, mirroring .gate-roles-panel (_room.scss) with tighter padding so it stays snug beside the line input — so the button reads clearly against the felt.

Applied in _applet-new-game.html and the shared _form.html (New Post now; room.html's composer inherits it when ported).

Tests: GameboardViewTest.test_new_game_ok_button_in_applet_btn_panel (OK btn inside #id_applet_new_game .applet-btn-panel); NewPostTest.test_new_post_applet_has_ok_confirm_button extended to assert the panel wrap. The New Game OK btn stays clickable inside the panel (GatekeeperTest.test_founder_creates_room_and_sees_gatekeeper FT green).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Disco DeDisco
2026-06-02 00:15:11 -04:00
parent 22fc38b92b
commit 114f0fd0db
5 changed files with 35 additions and 3 deletions

View File

@@ -84,11 +84,16 @@ class NewPostTest(TestCase):
self.assertEqual(line_input.get("aria-describedby"), "id_new_post_text_feedback") self.assertEqual(line_input.get("aria-describedby"), "id_new_post_text_feedback")
def test_new_post_applet_has_ok_confirm_button(self): def test_new_post_applet_has_ok_confirm_button(self):
"""New Post gains an OK .btn-confirm submit button, like New Game.""" """New Post gains an OK .btn-confirm submit button, like New Game
wrapped in an .applet-btn-panel so it reads against the --duoUser felt."""
form = self._new_post_form(self.post_invalid_input()) form = self._new_post_form(self.post_invalid_input())
buttons = form.cssselect("button.btn-confirm") buttons = form.cssselect("button.btn-confirm")
self.assertTrue(buttons, "no OK .btn-confirm in New Post applet") self.assertTrue(buttons, "no OK .btn-confirm in New Post applet")
self.assertEqual(buttons[0].text_content().strip(), "OK") self.assertEqual(buttons[0].text_content().strip(), "OK")
self.assertTrue(
form.cssselect(".applet-btn-panel button.btn-confirm"),
"OK .btn-confirm not inside .applet-btn-panel",
)
@override_settings(COMPRESS_ENABLED=False) @override_settings(COMPRESS_ENABLED=False)
class PostViewTest(TestCase): class PostViewTest(TestCase):

View File

@@ -37,6 +37,14 @@ class GameboardViewTest(TestCase):
def test_gameboard_shows_new_game_applet(self): def test_gameboard_shows_new_game_applet(self):
[_] = self.parsed.cssselect("#id_applet_new_game") [_] = self.parsed.cssselect("#id_applet_new_game")
def test_new_game_ok_button_in_applet_btn_panel(self):
"""The OK .btn-confirm sits in an .applet-btn-panel so it reads against
the New Game applet's --duoUser felt (mirrors .gate-roles-panel)."""
[panel] = self.parsed.cssselect("#id_applet_new_game .applet-btn-panel")
btns = panel.cssselect("button.btn-confirm")
self.assertTrue(btns, "OK .btn-confirm not inside .applet-btn-panel")
self.assertEqual(btns[0].text_content().strip(), "OK")
def test_gameboard_shows_my_sea_applet(self): def test_gameboard_shows_my_sea_applet(self):
# Sprint 3 of the My Sea roadmap — applet shell only; sigs/sea/draw # Sprint 3 of the My Sea roadmap — applet shell only; sigs/sea/draw
# flow lands in later sprints. Seeded via migration 0008. # flow lands in later sprints. Seeded via migration 0008.

View File

@@ -137,6 +137,21 @@
} }
} }
// Backdrop panel behind a composer applet's OK button — mirrors
// `.gate-roles-panel` (`_room.scss`): a --priUser fill + faint --terUser
// border so the green .btn-confirm reads against the --duoUser felt. Tighter
// padding than the gate panel so it stays snug beside the line input.
.applet-btn-panel {
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
border: 0.1rem solid rgba(var(--terUser), 0.25);
border-radius: 0.5rem;
padding: 0.4rem;
background: rgba(var(--priUser), 1);
}
// Page-level gear buttons — fixed to viewport bottom-right // Page-level gear buttons — fixed to viewport bottom-right
.gameboard-page, .gameboard-page,
.dashboard-page, .dashboard-page,

View File

@@ -19,7 +19,9 @@ below the row (and its id tracks `input_id` for aria-describedby).
style="flex:1; min-width:0;" style="flex:1; min-width:0;"
required required
/> />
<button type="submit" id="{{ submit_id }}" class="btn btn-confirm">OK</button> <div class="applet-btn-panel">
<button type="submit" id="{{ submit_id }}" class="btn btn-confirm">OK</button>
</div>
</div> </div>
{% if form.errors %} {% if form.errors %}
<div id="{{ input_id }}_feedback" class="invalid-feedback"> <div id="{{ input_id }}_feedback" class="invalid-feedback">

View File

@@ -6,6 +6,8 @@
<form method="POST" action="{% url "epic:create_room" %}" style="display:flex; gap:0.5rem; align-items:center;"> <form method="POST" action="{% url "epic:create_room" %}" style="display:flex; gap:0.5rem; align-items:center;">
{% csrf_token %} {% csrf_token %}
<input id="id_new_game_name" name="name" type="text" placeholder="Room name" class="form-control form-control-lg" style="flex:1; min-width:0;" /> <input id="id_new_game_name" name="name" type="text" placeholder="Room name" class="form-control form-control-lg" style="flex:1; min-width:0;" />
<button type="submit" id="id_create_game_btn" class="btn btn-confirm">OK</button> <div class="applet-btn-panel">
<button type="submit" id="id_create_game_btn" class="btn btn-confirm">OK</button>
</div>
</form> </form>
</section> </section>