Sea Select: rebuild as a felt + Gaussian spread modal, unify w. my_sea — TDD

Hollow out the gameroom DRAW SEA dark modal into the two surfaces my_sea
uses: a --duoUser felt (.sea-page--room) filling the hex pane where the
Celtic Cross deals, + a Gaussian spread modal (#id_sea_spread_modal: the
.sea-select combobox w. the two Celtic Cross 6-card opts ONLY, AUTO DRAW/DEL,
a mini preview, + a corner #id_sea_cancel NVM). Opened by DRAW SEA
(html.sea-open); the room gear's NVM (room-menu-sea) returns to the hex;
#id_text_btn + #id_sky_btn go inert while the felt is open.

- persist: epic:sea_save / sea_delete upsert the seat's Character.celtic_cross
  (none of my_sea's MySeaDraw quota/Brief machinery); room ctx adds
  saved_by_position + saved_sea_spread + sea_default_spread + hand_complete so
  a reload re-renders the filled cross. celtic_cross field already existed (no
  migration)
- mini spread preview (_sea_spread_preview.html) in BOTH the gameroom + my_sea
  modals — shape only, NEVER dealt to: SeaDeal scopes its slot queries to
  .sea-cross:not(.sea-cross--preview)
- always TWO deck stacks (Gravity + Levity) in the room Sea Select — the gamer
  draws from either populated half (sea_deck split), even a CARTE monodeck;
  unlike my_sea / Sig Select's polarization collapse
- glow coordination: the sky-saved glow is muted in the sky/sea phases
  (html.sky-open / sea-open / sea-entered); sea glow color --priYl -> --priId
  (distinct from sky's --priTk); the sea glow-machine fires at hand-COMPLETION
  (mirrors Sky Select), not during drawing
- guard copy "Auto deal cards?" -> "Auto Draw cards?" (match the AUTO DRAW btn)
- fix: drop the stale `html.sea-open #id_aperture_fill { opacity:1 }` — it
  painted the opaque z-90 fill over the z-5 felt so the spread flashed then
  vanished (same trap as the CAST SKY felt); removed the dead .sea-backdrop /
  .sea-overlay / .sea-modal-* SCSS
- tests: epic PickSeaPersistTest (7) + PickSeaUnifiedFeltTest (6) ITs; SeaDeal
  preview-scoping + BurgerSpec sky-glow-mute Jasmine specs; my_sea sig-card
  ITs scoped to .my-sea-cross (the preview adds a 2nd .sea-sig-card)

[[feedback-felt-aperture-fill-covers-felt]]
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Disco DeDisco
2026-06-07 21:42:24 -04:00
parent 4322e1fc17
commit c037e876e2
21 changed files with 1100 additions and 293 deletions

View File

@@ -172,18 +172,21 @@
// ── First-draw glow handoff (phase 3 of the Sea sub-btn rollout) ─────
//
// Pre-first-draw nudge for the my-sea picker: a --priYl + --ninUser glow
// rides the affordance chain to teach the user where to click.
// Pre-first-draw nudge for the my-sea picker + the gameroom Sea Select felt: a
// --priId + --ninUser glow rides the affordance chain to teach the user where to
// click. --priId (indigo) keeps it DISTINCT from the sky-saved cue's --priTk
// (user-spec 2026-06-07) so the two machines never read as the same glow.
//
// burger → click → sea_btn → click → .sea-select → click → end
//
// Modal close (Esc / backdrop / DEL) w/o AUTO DRAW restarts the cycle on
// the burger. AUTO DRAW's guard-OK ends the cycle permanently (the user
// has actually drawn — they've found the path). Owner: my_sea.html JS.
// has actually drawn — they've found the path). Owner: my_sea.html +
// _sea_overlay.html JS.
#id_burger_btn.glow-handoff,
#id_sea_btn.glow-handoff {
color: rgba(var(--priYl), 1);
border-color: rgba(var(--priYl), 1);
color: rgba(var(--priId), 1);
border-color: rgba(var(--priId), 1);
box-shadow:
0 0 0.5rem 0.1rem rgba(var(--ninUser), 0.75),
0 0 1.2rem 0.3rem rgba(var(--ninUser), 0.35);
@@ -209,7 +212,7 @@
// ── Voice affordance glow + pulse (Phase 3, my-sea voice) ─────────────
//
// Distinct from the sea-btn's --priYl `.glow-handoff` draw nudge: voice uses
// Distinct from the sea-btn's --priId `.glow-handoff` draw nudge: voice uses
// a --quaUser tint + --ninUser halo. voice-glow.js owns the class transitions
// (sea takes burger precedence; the voice glow surfaces on the voice sub-btn
// when the fan is open, or on the burger once the sea nudge clears). Once the

View File

@@ -1584,70 +1584,14 @@ body.deck-family-english {
}
}
// ── DRAW SEA overlay ─────────────────────────────────────────────────────────
// Mirrors .sky-* structure but with columns reversed:
// left = transparent (Celtic Cross card positions)
// right = rgba(--priUser) opaque (spread select)
// ── DRAW SEA cross + slots ───────────────────────────────────────────────────
// The Sea Select felt rebuild (2026-06-07) dropped the old dark-modal chrome
// (.sea-backdrop / .sea-overlay / .sea-modal-wrap / .sea-modal / -header /
// -body) — DRAW SEA is now the my_sea-style felt (.sea-page--room in _sky.scss)
// + a Gaussian spread modal (.my-sea-spread-modal in _gameboard.scss). The
// cross + slot + stack rules below are SHARED by both the felt + my_sea.
.sea-backdrop {
display: none;
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.75);
backdrop-filter: blur(4px);
z-index: 200;
}
html.sea-open .sea-backdrop { display: block; }
.sea-overlay {
display: none;
position: fixed;
inset: 0;
z-index: 201;
overflow-y: auto;
align-items: center;
justify-content: center;
}
html.sea-open .sea-overlay { display: flex; }
.sea-modal-wrap {
position: relative;
width: 90vw;
max-width: 60rem;
max-height: 90vh;
margin: auto;
opacity: 0;
transform: translateY(1.5rem);
transition: opacity 0.25s, transform 0.25s;
}
html.sea-open .sea-modal-wrap {
opacity: 1;
transform: translateY(0);
}
.sea-modal {
border-radius: 0.5rem;
overflow: hidden;
width: 100%;
}
.sea-modal-header {
padding: 0.75rem 1.25rem;
background: rgba(var(--priUser), 1);
h2 { font-size: 1.4rem; margin: 0; }
p { margin: 0.2rem 0 0; font-size: 0.85rem; opacity: 0.8; }
}
.sea-modal-body {
display: flex;
min-height: 20rem;
}
// ── Cards column (transparent / left) ────────────────────────────────────────
// ── Cards column (the spread cross) ──────────────────────────────────────────
.sea-cards-col {
flex: 1 1 55%;

View File

@@ -823,6 +823,11 @@ body.page-gameboard {
padding: 1.25rem;
pointer-events: auto;
max-width: 90vw;
// Stack the mini spread preview above the form chrome, both centred.
display: flex;
flex-direction: column;
align-items: center;
gap: 0.75rem;
.sea-form-col {
// Already-styled .sea-form-col container handles internal layout.
@@ -832,6 +837,54 @@ body.page-gameboard {
min-width: 16rem;
}
}
// Corner NVM (top-right of the panel) — closes the modal back to the felt.
.sea-modal-nvm {
position: absolute;
top: 0.4rem;
right: 0.4rem;
z-index: 2;
}
}
// ── Miniaturized spread PREVIEW (in the spread modal, both surfaces) ──────────
// A small Celtic-Cross shape that reflects the .sea-select choice. NEVER dealt
// to (SeaDeal scopes its slot queries to .sea-cross:not(.sea-cross--preview));
// slots keep their dashed-empty styling only. Tracks `data-spread` so the
// my-sea 3-card variants show their correct subset; the gameroom shows the full
// 6-card Celtic Cross.
.sea-cards-col--preview {
flex: 0 0 auto;
padding: 0.25rem;
}
.sea-cross--preview {
gap: 0.3rem;
.sea-card-slot {
width: 1.6rem;
height: 2.6rem;
border-width: 0.1rem;
font-size: 0.4rem;
}
.sea-card-slot--crossing { width: 1.6rem; height: 2.6rem; }
.sea-sig-card { transform: scale(0.85); }
// Per-spread position subsets — mirror the .my-sea-cross hide rules so the
// preview shape matches the live cross for the 3-card spreads.
&[data-spread="past-present-future"] {
.sea-pos-crown, .sea-pos-cross, .sea-pos-lay { display: none; }
}
&[data-spread="situation-action-outcome"] {
.sea-pos-leave, .sea-pos-loom, .sea-pos-cross { display: none; }
}
&[data-spread="mind-body-spirit"] {
.sea-pos-leave, .sea-pos-cover, .sea-pos-cross { display: none; }
}
&[data-spread="desire-obstacle-solution"] {
.sea-pos-leave, .sea-pos-cover, .sea-pos-lay { display: none; }
}
// Celtic Cross variants (waite-smith / escape-velocity) — all 6 visible.
}
// ── Relocated deck-stacks (Phase 2) ──────────────────────────────────

View File

@@ -39,10 +39,15 @@ html:has(.gate-backdrop) {
html:has(.gate-backdrop) #id_aperture_fill,
html:has(.sig-backdrop) #id_aperture_fill,
html:has(.role-select-backdrop) #id_aperture_fill,
html.sea-open #id_aperture_fill {
html:has(.role-select-backdrop) #id_aperture_fill {
opacity: 1;
}
// NB: `html.sea-open #id_aperture_fill { opacity: 1 }` was DROPPED in the felt
// rebuild (2026-06-07). The DRAW SEA felt now sits at z-5 INSIDE the hex pane
// (.sea-page--room), BELOW the z-90 fill — lighting the fill painted an opaque
// green sheet OVER the felt + spread (the 0.15s opacity transition is why the
// spread "flashed then vanished"). Same trap + fix as the CAST SKY felt.
// [[feedback-felt-aperture-fill-covers-felt]]
// ─── Table-hex aperture: binary scroll-snap toggle ─────────────────────────
// Mirrors my_sky's wheel<->form swap (`_sky.scss` body.sky-saved block). The
@@ -103,6 +108,13 @@ html.sky-open .room-aperture.is-scrollable {
scroll-snap-type: none;
}
// Same pin while the DRAW SEA felt is summoned (html.sea-open) — the felt fills
// the hex pane + the reelhouse below must stay out of reach.
html.sea-open .room-aperture.is-scrollable {
overflow-y: hidden;
scroll-snap-type: none;
}
.room-scroll-pane {
display: flex;
flex-direction: column;

View File

@@ -66,6 +66,43 @@ html.sky-open .position-strip {
transition: opacity 0.5s ease;
}
// ── In-room DRAW SEA felt (unified with my_sea.html) ──────────────────────────
// The Sea Select spread (the my-sea picker apparatus) rendered INSIDE
// .room-hex-pane on a --duoUser felt, mirroring the CAST SKY felt above. Hidden
// until #id_pick_sea_btn adds html.sea-open. The picker child (.my-sea-picker)
// flex-fills + centres the cross + deck stacks; the Gaussian spread modal
// (.my-sea-spread-modal) opens above it from the burger Sea sub-btn.
html.sea-open {
overflow: hidden;
}
.room-hex-pane.has-sea-stage {
position: relative;
}
.sea-page.sea-page--room {
position: absolute;
inset: 0;
z-index: 5;
display: flex;
background: rgba(var(--duoUser), 1);
// Hidden until opened — pointer-events off so the hidden felt can't eat the
// DRAW SEA btn click beneath it.
visibility: hidden;
pointer-events: none;
}
html.sea-open .sea-page.sea-page--room {
visibility: visible;
pointer-events: auto;
}
// Hide the position strip while the sea felt is up (same as the sky felt) so the
// felt reads as a clean homogeneous surface.
html.sea-open .position-strip {
visibility: hidden;
}
// ── Backdrop ──────────────────────────────────────────────────────────────────
.sky-backdrop {