my_sea_visit: give the visitor a top-left deck stack (owner's deck) with a hover-revealed disabled FLIP — TDD

Mirrors the owner's deck stack onto the spectator hex, DRY:
- new shared _my_sea_deck_stack.html partial (mono DECK / dubbo DECKS by
  is_polarized) rendered by BOTH the owner picker (my_sea.html, flip_disabled=
  hand_complete) AND the visitor cross (flip_disabled=True). Owner markup is
  byte-identical, so its assertions hold.
- the visitor's stack uses the OWNER's deck (everyone at @owner's sea plays the
  owner's deck — the visitor's own equipped deck is irrelevant), pinned
  top-left (--visit) across the table from the owner who deals bottom-right.
- dubbodeck: the Gravity/Levity name flips above the face + upside-down to
  signal someone across the table is dealing.
- the read-only FLIP (disabled ×) is hidden until its stack is hovered/focused,
  then eases in (same opacity 0->1 over 0.3s as the shared flip-btn-base
  reveal; inlined since _gameboard precedes _card-deck in the import order) so a
  permanent × doesn't clutter the stack.

ITs: stack keys on the owner's deck (not the viewer's), dubbo renders 2 named
stacks, FLIP is the disabled state, no stack when the owner has no deck. Owner
deck-stack IT + FT stay green (identical markup).

Code architected by Disco DeDisco <discodedisco@outlook.com>
Git commit message Co-Authored-By:
Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Disco DeDisco
2026-05-29 23:01:21 -04:00
parent c3594d27ed
commit 260c1c1325
5 changed files with 126 additions and 29 deletions

View File

@@ -795,6 +795,40 @@ body.page-gameboard {
pointer-events: auto;
}
// Spectator (bud-sea) deck stack — the VISITOR's own deck, pinned TOP-LEFT
// (across the table from the owner, who deals bottom-right). FLIP renders
// disabled server-side (read-only). For a dubbodeck the Gravity/Levity
// `.sea-stack-name` flips ABOVE the face + upside-down, signalling that
// someone across the table is dealing. (user-spec 2026-05-29)
.my-sea-stacks-wrap.my-sea-stacks-wrap--visit {
top: 1rem;
left: 1rem;
bottom: auto;
right: auto;
// Name above the face (DOM order is face → name) + rotated 180°.
.sea-deck-stack { flex-direction: column-reverse; }
.sea-stack-name {
transform: scaleY(1.2) rotate(180deg);
transform-origin: center;
}
// Read-only FLIP (disabled ×) — hidden until its stack is hovered/focused,
// then eases in: same reveal shape as the shared `flip-btn-base` mixin
// (opacity 0→1 over 0.3s ease), inlined here because _gameboard.scss is
// imported before _card-deck.scss (where the mixin lives). Stays non-
// interactive — `.btn-disabled` keeps pointer-events:none. The base
// `.sea-stack-ok` positioning is untouched (we only add the fade).
.sea-stack-ok {
opacity: 0;
transition: opacity 0.3s ease;
}
.sea-deck-stack:hover .sea-stack-ok,
.sea-deck-stack:focus-within .sea-stack-ok {
opacity: 1;
}
}
// ── Iter 4b: Brief banner + DEL guard portal ─────────────────────────────────
// Both reuse shared chrome: the Brief is `.note-banner` from note.js
// (portaled atop h2 w. Gaussian glass); the DEL guard is `#id_guard_portal`