sea deck stack: rename the stale .sea-stack-ok class to .sea-stack-flip (the btn renders FLIP now) — TDD
Pure rename, no behavior change — the deck-stack reveal btn kept the name `.sea-stack-ok` from when it said OK; it has rendered FLIP for a while. Renamed across all 8 references: _card-deck.scss (reveal + pointer-events rules) + a _gameboard.scss comment; the 3 templates that emit or query it (_sea_overlay.html, _my_sea_deck_stack.html, my_sea.html inline JS); and the 3 tests that select it (test_game_room_select_sea FT, test_game_my_sea FT, test_sea_visit IT rendered-HTML asserts). Verified 47 green across all three surfaces (visit IT + gameroom PickSeaDeal stack FT + my_sea CardDraw FT). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -165,9 +165,9 @@ class MySeaVisitContextTest(TestCase):
|
|||||||
self.assertIn("sea-deck-stack--gravity", html)
|
self.assertIn("sea-deck-stack--gravity", html)
|
||||||
self.assertIn("sea-deck-stack--levity", html)
|
self.assertIn("sea-deck-stack--levity", html)
|
||||||
# FLIP is the disabled (×) state; never an enabled FLIP for a visitor.
|
# FLIP is the disabled (×) state; never an enabled FLIP for a visitor.
|
||||||
self.assertIn("sea-stack-ok btn-disabled", html)
|
self.assertIn("sea-stack-flip btn-disabled", html)
|
||||||
self.assertNotIn(
|
self.assertNotIn(
|
||||||
'class="btn btn-reveal sea-stack-ok" type="button">FLIP', html)
|
'class="btn btn-reveal sea-stack-flip" type="button">FLIP', html)
|
||||||
|
|
||||||
def test_stack_keys_on_owner_deck_not_viewer_deck(self):
|
def test_stack_keys_on_owner_deck_not_viewer_deck(self):
|
||||||
# Viewer has no deck, owner has one → the stack still renders (it's the
|
# Viewer has no deck, owner has one → the stack still renders (it's the
|
||||||
|
|||||||
@@ -756,7 +756,7 @@ class MySeaCardDrawTest(FunctionalTest):
|
|||||||
)
|
)
|
||||||
stack.click()
|
stack.click()
|
||||||
flip = self.wait_for(
|
flip = self.wait_for(
|
||||||
lambda: stack.find_element(By.CSS_SELECTOR, ".sea-stack-ok")
|
lambda: stack.find_element(By.CSS_SELECTOR, ".sea-stack-flip")
|
||||||
)
|
)
|
||||||
self.wait_for(lambda: self.assertTrue(flip.is_displayed()))
|
self.wait_for(lambda: self.assertTrue(flip.is_displayed()))
|
||||||
flip.click()
|
flip.click()
|
||||||
|
|||||||
@@ -299,7 +299,7 @@ class PickSeaDealTest(ChannelsFunctionalTest):
|
|||||||
))
|
))
|
||||||
self.browser.execute_script("arguments[0].click()", stack)
|
self.browser.execute_script("arguments[0].click()", stack)
|
||||||
ok_btn = self.wait_for(lambda: self.browser.find_element(
|
ok_btn = self.wait_for(lambda: self.browser.find_element(
|
||||||
By.CSS_SELECTOR, ".sea-deck-stack--levity .sea-stack-ok"
|
By.CSS_SELECTOR, ".sea-deck-stack--levity .sea-stack-flip"
|
||||||
))
|
))
|
||||||
# Choosing the spread scroll-snaps the felt onto two pages; the deck
|
# Choosing the spread scroll-snaps the felt onto two pages; the deck
|
||||||
# stacks sit on a different page than the post-OK scroll lands on in
|
# stacks sit on a different page than the post-OK scroll lands on in
|
||||||
@@ -320,14 +320,14 @@ class PickSeaDealTest(ChannelsFunctionalTest):
|
|||||||
))
|
))
|
||||||
self.browser.execute_script("arguments[0].click()", stack)
|
self.browser.execute_script("arguments[0].click()", stack)
|
||||||
self.wait_for(lambda: self.browser.find_element(
|
self.wait_for(lambda: self.browser.find_element(
|
||||||
By.CSS_SELECTOR, ".sea-deck-stack--levity .sea-stack-ok"
|
By.CSS_SELECTOR, ".sea-deck-stack--levity .sea-stack-flip"
|
||||||
).is_displayed())
|
).is_displayed())
|
||||||
# Click the sea cards column (not a stack)
|
# Click the sea cards column (not a stack)
|
||||||
col = self.browser.find_element(By.CSS_SELECTOR, ".sea-cards-col")
|
col = self.browser.find_element(By.CSS_SELECTOR, ".sea-cards-col")
|
||||||
self.browser.execute_script("arguments[0].click()", col)
|
self.browser.execute_script("arguments[0].click()", col)
|
||||||
self.wait_for(lambda: not any(
|
self.wait_for(lambda: not any(
|
||||||
el.is_displayed()
|
el.is_displayed()
|
||||||
for el in self.browser.find_elements(By.CSS_SELECTOR, ".sea-stack-ok")
|
for el in self.browser.find_elements(By.CSS_SELECTOR, ".sea-stack-flip")
|
||||||
))
|
))
|
||||||
|
|
||||||
# ── Card draw ─────────────────────────────────────────────────────── #
|
# ── Card draw ─────────────────────────────────────────────────────── #
|
||||||
@@ -340,7 +340,7 @@ class PickSeaDealTest(ChannelsFunctionalTest):
|
|||||||
))
|
))
|
||||||
self.browser.execute_script("arguments[0].click()", stack)
|
self.browser.execute_script("arguments[0].click()", stack)
|
||||||
ok_btn = self.wait_for(lambda: self.browser.find_element(
|
ok_btn = self.wait_for(lambda: self.browser.find_element(
|
||||||
By.CSS_SELECTOR, ".sea-deck-stack--levity .sea-stack-ok"
|
By.CSS_SELECTOR, ".sea-deck-stack--levity .sea-stack-flip"
|
||||||
))
|
))
|
||||||
self.browser.execute_script("arguments[0].click()", ok_btn)
|
self.browser.execute_script("arguments[0].click()", ok_btn)
|
||||||
self.wait_for(lambda: self.browser.find_element(
|
self.wait_for(lambda: self.browser.find_element(
|
||||||
@@ -361,7 +361,7 @@ class PickSeaDealTest(ChannelsFunctionalTest):
|
|||||||
))
|
))
|
||||||
self.browser.execute_script("arguments[0].click()", stack)
|
self.browser.execute_script("arguments[0].click()", stack)
|
||||||
ok_btn = self.wait_for(lambda: self.browser.find_element(
|
ok_btn = self.wait_for(lambda: self.browser.find_element(
|
||||||
By.CSS_SELECTOR, ".sea-deck-stack--levity .sea-stack-ok"
|
By.CSS_SELECTOR, ".sea-deck-stack--levity .sea-stack-flip"
|
||||||
))
|
))
|
||||||
self.browser.execute_script("arguments[0].click()", ok_btn)
|
self.browser.execute_script("arguments[0].click()", ok_btn)
|
||||||
|
|
||||||
@@ -370,7 +370,7 @@ class PickSeaDealTest(ChannelsFunctionalTest):
|
|||||||
self.wait_for(lambda: self.assertIn(
|
self.wait_for(lambda: self.assertIn(
|
||||||
"btn-disabled",
|
"btn-disabled",
|
||||||
self.browser.find_element(
|
self.browser.find_element(
|
||||||
By.CSS_SELECTOR, ".sea-deck-stack--levity .sea-stack-ok"
|
By.CSS_SELECTOR, ".sea-deck-stack--levity .sea-stack-flip"
|
||||||
).get_attribute("class"),
|
).get_attribute("class"),
|
||||||
))
|
))
|
||||||
|
|
||||||
@@ -383,7 +383,7 @@ class PickSeaDealTest(ChannelsFunctionalTest):
|
|||||||
))
|
))
|
||||||
self.browser.execute_script("arguments[0].click()", stack)
|
self.browser.execute_script("arguments[0].click()", stack)
|
||||||
ok_btn = self.wait_for(lambda: self.browser.find_element(
|
ok_btn = self.wait_for(lambda: self.browser.find_element(
|
||||||
By.CSS_SELECTOR, ".sea-deck-stack--levity .sea-stack-ok"
|
By.CSS_SELECTOR, ".sea-deck-stack--levity .sea-stack-flip"
|
||||||
))
|
))
|
||||||
self.browser.execute_script("arguments[0].click()", ok_btn)
|
self.browser.execute_script("arguments[0].click()", ok_btn)
|
||||||
self.wait_for(lambda: self.browser.find_element(
|
self.wait_for(lambda: self.browser.find_element(
|
||||||
|
|||||||
@@ -2046,7 +2046,7 @@ $_sea-card-glow: 0 0 0.5rem 0.5rem rgba(var(--ninUser), 0.3), 0 0 0.4rem rgba(0,
|
|||||||
z-index: 1; // sits above the name label
|
z-index: 1; // sits above the name label
|
||||||
}
|
}
|
||||||
|
|
||||||
.sea-stack-ok {
|
.sea-stack-flip {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 0;
|
left: 0;
|
||||||
@@ -2064,9 +2064,9 @@ $_sea-card-glow: 0 0 0.5rem 0.5rem rgba(var(--ninUser), 0.3), 0 0 0.4rem rgba(0,
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
transition: opacity 0.3s ease;
|
transition: opacity 0.3s ease;
|
||||||
}
|
}
|
||||||
.sea-deck-stack:hover .sea-stack-ok,
|
.sea-deck-stack:hover .sea-stack-flip,
|
||||||
.sea-deck-stack:focus-within .sea-stack-ok,
|
.sea-deck-stack:focus-within .sea-stack-flip,
|
||||||
.sea-deck-stack--active .sea-stack-ok { opacity: 1; }
|
.sea-deck-stack--active .sea-stack-flip { opacity: 1; }
|
||||||
// Interactivity is gated on the PERSIST state (`--active`), NOT hover. Hover is
|
// Interactivity is gated on the PERSIST state (`--active`), NOT hover. Hover is
|
||||||
// a purely VISUAL preview — same as the spectator's disabled FLIP, whose "hover
|
// a purely VISUAL preview — same as the spectator's disabled FLIP, whose "hover
|
||||||
// effect" is just the reveal. Keeping the FLIP click-through on hover preserves
|
// effect" is just the reveal. Keeping the FLIP click-through on hover preserves
|
||||||
@@ -2074,7 +2074,7 @@ $_sea-card-glow: 0 0 0.5rem 0.5rem rgba(var(--ninUser), 0.3), 0 0 0.4rem rgba(0,
|
|||||||
// Were it clickable on hover, a single stack-click would land on the centred
|
// Were it clickable on hover, a single stack-click would land on the centred
|
||||||
// FLIP itself + deal early. The spectator's FLIP stays `.btn-disabled` (read-
|
// FLIP itself + deal early. The spectator's FLIP stays `.btn-disabled` (read-
|
||||||
// only) so it never becomes interactive even while persisted.
|
// only) so it never becomes interactive even while persisted.
|
||||||
.sea-deck-stack--active .sea-stack-ok:not(.btn-disabled) { pointer-events: auto; }
|
.sea-deck-stack--active .sea-stack-flip:not(.btn-disabled) { pointer-events: auto; }
|
||||||
|
|
||||||
.sea-deck-stack { gap: 0; } // remove gap so name slides under the face
|
.sea-deck-stack { gap: 0; } // remove gap so name slides under the face
|
||||||
|
|
||||||
|
|||||||
@@ -954,7 +954,7 @@ body.page-gameboard {
|
|||||||
transform-origin: center;
|
transform-origin: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FLIP reveal (hover-fade + click-persist) is now the SHARED `.sea-stack-ok`
|
// FLIP reveal (hover-fade + click-persist) is now the SHARED `.sea-stack-flip`
|
||||||
// behaviour in _card-deck.scss — unified with the owner picker per user-spec
|
// behaviour in _card-deck.scss — unified with the owner picker per user-spec
|
||||||
// 2026-05-30, so the visitor's prior hover-only override is gone. The
|
// 2026-05-30, so the visitor's prior hover-only override is gone. The
|
||||||
// spectator's click-persist (`.sea-deck-stack--active`) is wired in
|
// spectator's click-persist (`.sea-deck-stack--active`) is wired in
|
||||||
|
|||||||
@@ -10,13 +10,13 @@
|
|||||||
<span class="sea-stacks-label">DECKS</span>
|
<span class="sea-stacks-label">DECKS</span>
|
||||||
<div class="sea-deck-stack sea-deck-stack--gravity">
|
<div class="sea-deck-stack sea-deck-stack--gravity">
|
||||||
<div class="sea-stack-face">
|
<div class="sea-stack-face">
|
||||||
<button class="btn btn-reveal sea-stack-ok{% if flip_disabled %} btn-disabled{% endif %}" type="button">{% if flip_disabled %}×{% else %}FLIP{% endif %}</button>
|
<button class="btn btn-reveal sea-stack-flip{% if flip_disabled %} btn-disabled{% endif %}" type="button">{% if flip_disabled %}×{% else %}FLIP{% endif %}</button>
|
||||||
</div>
|
</div>
|
||||||
<span class="sea-stack-name">Gravity</span>
|
<span class="sea-stack-name">Gravity</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="sea-deck-stack sea-deck-stack--levity">
|
<div class="sea-deck-stack sea-deck-stack--levity">
|
||||||
<div class="sea-stack-face">
|
<div class="sea-stack-face">
|
||||||
<button class="btn btn-reveal sea-stack-ok{% if flip_disabled %} btn-disabled{% endif %}" type="button">{% if flip_disabled %}×{% else %}FLIP{% endif %}</button>
|
<button class="btn btn-reveal sea-stack-flip{% if flip_disabled %} btn-disabled{% endif %}" type="button">{% if flip_disabled %}×{% else %}FLIP{% endif %}</button>
|
||||||
</div>
|
</div>
|
||||||
<span class="sea-stack-name">Levity</span>
|
<span class="sea-stack-name">Levity</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
{% if deck.has_card_images %}
|
{% if deck.has_card_images %}
|
||||||
<img class="sea-stack-face-img" src="{{ deck.back_image_url }}" alt="">
|
<img class="sea-stack-face-img" src="{{ deck.back_image_url }}" alt="">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<button class="btn btn-reveal sea-stack-ok{% if flip_disabled %} btn-disabled{% endif %}" type="button">{% if flip_disabled %}×{% else %}FLIP{% endif %}</button>
|
<button class="btn btn-reveal sea-stack-flip{% if flip_disabled %} btn-disabled{% endif %}" type="button">{% if flip_disabled %}×{% else %}FLIP{% endif %}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -131,13 +131,13 @@ via epic:sea_save. `?seat` threads the CARTE-selected seat onto the action URLs.
|
|||||||
<span class="sea-stacks-label">DECKS</span>
|
<span class="sea-stacks-label">DECKS</span>
|
||||||
<div class="sea-deck-stack sea-deck-stack--gravity">
|
<div class="sea-deck-stack sea-deck-stack--gravity">
|
||||||
<div class="sea-stack-face">
|
<div class="sea-stack-face">
|
||||||
<button class="btn btn-reveal sea-stack-ok{% if hand_complete %} btn-disabled{% endif %}" type="button">{% if hand_complete %}×{% else %}FLIP{% endif %}</button>
|
<button class="btn btn-reveal sea-stack-flip{% if hand_complete %} btn-disabled{% endif %}" type="button">{% if hand_complete %}×{% else %}FLIP{% endif %}</button>
|
||||||
</div>
|
</div>
|
||||||
<span class="sea-stack-name">Gravity</span>
|
<span class="sea-stack-name">Gravity</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="sea-deck-stack sea-deck-stack--levity">
|
<div class="sea-deck-stack sea-deck-stack--levity">
|
||||||
<div class="sea-stack-face">
|
<div class="sea-stack-face">
|
||||||
<button class="btn btn-reveal sea-stack-ok{% if hand_complete %} btn-disabled{% endif %}" type="button">{% if hand_complete %}×{% else %}FLIP{% endif %}</button>
|
<button class="btn btn-reveal sea-stack-flip{% if hand_complete %} btn-disabled{% endif %}" type="button">{% if hand_complete %}×{% else %}FLIP{% endif %}</button>
|
||||||
</div>
|
</div>
|
||||||
<span class="sea-stack-name">Levity</span>
|
<span class="sea-stack-name">Levity</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -261,7 +261,7 @@ via epic:sea_save. `?seat` threads the CARTE-selected seat onto the action URLs.
|
|||||||
}
|
}
|
||||||
function _setComplete(on, live) {
|
function _setComplete(on, live) {
|
||||||
_locked = on;
|
_locked = on;
|
||||||
overlay.querySelectorAll('.sea-deck-stack .sea-stack-ok').forEach(function (btn) {
|
overlay.querySelectorAll('.sea-deck-stack .sea-stack-flip').forEach(function (btn) {
|
||||||
btn.classList.toggle('btn-disabled', on);
|
btn.classList.toggle('btn-disabled', on);
|
||||||
btn.innerHTML = on ? '×' : 'FLIP';
|
btn.innerHTML = on ? '×' : 'FLIP';
|
||||||
});
|
});
|
||||||
@@ -340,7 +340,7 @@ via epic:sea_save. `?seat` threads the CARTE-selected seat onto the action URLs.
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (_activeStack === stack) _hideOk(); else _showOk(stack);
|
if (_activeStack === stack) _hideOk(); else _showOk(stack);
|
||||||
});
|
});
|
||||||
var ok = stack.querySelector('.sea-stack-ok');
|
var ok = stack.querySelector('.sea-stack-flip');
|
||||||
if (ok) {
|
if (ok) {
|
||||||
ok.addEventListener('click', function (e) {
|
ok.addEventListener('click', function (e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|||||||
@@ -439,7 +439,7 @@
|
|||||||
// draw, NOT at completion).
|
// draw, NOT at completion).
|
||||||
_locked = on;
|
_locked = on;
|
||||||
picker.classList.toggle('my-sea-picker--locked', on);
|
picker.classList.toggle('my-sea-picker--locked', on);
|
||||||
picker.querySelectorAll('.sea-deck-stack .sea-stack-ok').forEach(function (btn) {
|
picker.querySelectorAll('.sea-deck-stack .sea-stack-flip').forEach(function (btn) {
|
||||||
btn.classList.toggle('btn-disabled', on);
|
btn.classList.toggle('btn-disabled', on);
|
||||||
// Mirrors DEL btn convention: disabled label is × (the
|
// Mirrors DEL btn convention: disabled label is × (the
|
||||||
// template's initial render does the same), active is
|
// template's initial render does the same), active is
|
||||||
@@ -477,7 +477,7 @@
|
|||||||
if (_activeStack === stack) _hideOk();
|
if (_activeStack === stack) _hideOk();
|
||||||
else _showOk(stack);
|
else _showOk(stack);
|
||||||
});
|
});
|
||||||
var ok = stack.querySelector('.sea-stack-ok');
|
var ok = stack.querySelector('.sea-stack-flip');
|
||||||
if (ok) {
|
if (ok) {
|
||||||
ok.addEventListener('click', function (e) {
|
ok.addEventListener('click', function (e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|||||||
Reference in New Issue
Block a user