{% extends "core/base.html" %} {% load static %} {% block title_text %}Game Sea{% endblock title_text %} {% block header_text %}GameSea{% endblock header_text %} {% block content %} {# note.js exposes window.Brief — needed by BOTH the no-sig branch's #} {# sign-gate Brief partial AND the with-sig branch's Default-deck + #} {# Free-draw-locked Briefs. Hoisted out of the branches so it loads #} {# exactly once regardless of which path the user is on (note.js #} {# declares `const Brief = ...` at global scope — a second load would #} {# SyntaxError on re-declaration). #}
{% if not user_has_sig %} {# Sprint 4b sign-gate — DRYly Brief-banner'd (was inline div #} {# .my-sea-sign-gate, refactored 2026-05-22 to use the project- #} {# wide `.note-banner` portal via `Brief.showBanner`). NVM lives #} {# inside the Brief shell; FYI links to /billboard/my-sign/. #} {# Page body stays empty — the Brief is the entire no-sig UX. #} {% include "apps/gameboard/_partials/_my_sea_sign_gate_brief.html" %} {% else %} {% if not show_picker %} {# Sprint 5 iter 1 — DRAW SEA landing UX. DRY table hex from #} {# the room shell (.room-shell > .room-table > … > .table-hex) #} {# w. 6 chair seats labeled 1C-6C as placeholders for the #} {# friend-invite feature per the My Sea roadmap architectural #} {# anchor "Six chairs retained even in solo". #} {# #} {# Iter 6b — landing primary-btn state machine, 3-way: #} {# • FREE DRAW (`#id_draw_sea_btn`) when no active quota row #} {# (fresh user OR >24h since last draw); #} {# • PAID DRAW (`#id_my_sea_paid_draw_btn`) when the user has #} {# deposited a token via the gatekeeper but hasn't yet #} {# committed it; one-click POST commits + redirects to #} {# fresh-quota /gameboard/my-sea/. #} {# • GATE VIEW (`#id_my_sea_gate_view_btn`) when the user's #} {# quota row exists, the hand is empty, AND no deposit yet #} {# (post-DEL state). Routes to the Sprint-6 gatekeeper. #} {# Seat 1 (`data-slot="1"`) carries `.seated` + `.fa-circle- #} {# check` when the user's hand is non-empty (server-rendered #} {# so reloads preserve the state). Otherwise `.fa-ban`. Other #} {# 5 seats are placeholders for the future friend-invite #} {# feature — always banned in solo my-sea. #}
{% if show_cont_draw %} {# CONT DRAW — user came to the landing via the gear- #} {# menu NVM mid-draw (?phase=landing). The picker hand #} {# is non-empty + incomplete; CONT DRAW re-enters the #} {# picker (a fresh GET w.o. ?phase=landing falls through #} {# to show_picker=True via the hand_non_empty branch). #} CONT
DRAW
{% elif show_paid_draw %} {# PAID DRAW — two underlying states collapse into one #} {# button (user-spec 2026-05-23): #} {# • `deposit_reserved` → POST commits the deposited #} {# token via `my_sea_paid_draw` + redirects to picker. #} {# • `paid_through` (token already spent this cycle, #} {# hand still empty) → POST is a no-op commit branch #} {# in the view; the view redirects to picker anyway. #}
{% csrf_token %}
{% elif show_gate_view %} {% else %} {% endif %}
{% for n in "123456" %} {# Chair-position labels (1C-6C). No roles in #} {# my-sea (this is the solo draw flow); using #} {# `.seat-position-label` instead of the room's #} {# `.seat-role-label` to keep the no-role #} {# semantics clean. `.position-status-icon` + #} {# `.fa-ban` are unchanged — already role- #} {# agnostic in _room.scss. #}
{{ n }}C
{% endfor %}
{% endif %} {# Picker phase — per-spread flexible layout. Sig pins .sea- #} {# pos-core; the 6 surrounding positions all render in DOM #} {# so the SPREAD dropdown can swap `.my-sea-cross[data- #} {# spread]` between the 4 three-card variants (each w. its #} {# own 3-position subset + draw order) + the 2 six-card #} {# Celtic Cross variants (all 6 surrounding positions). #} {# Each empty slot carries a `.sea-pos-label` caption (re- #} {# appropriated from the GRAVITY/LEVITY .sea-stack-name look) #} {# that JS updates per spread. #} {# #} {# `id="id_sea_overlay"` aliases the picker to what SeaDeal #} {# binds to (the gameroom uses the same ID on a different #} {# page — no DOM collision since my-sea + gameroom never co- #} {# exist in one DOM). FLIP click delegates to SeaDeal. #} {# openStage(), which fills the slot AND opens the portaled #} {# stage modal w. SPIN / FYI controls. #} {# Iter 4b — DEL guard reuses the shared `#id_guard_portal` #} {# from base.html (the same one the room's gear-menu DEL btn #} {# uses). Gaussian-glass tooltip positioned above the DEL btn,#} {# no backdrop. The picker IIFE below invokes it via #} {# `window.showGuard(delBtn, "Are you sure?", confirmFn, null,#} {# {yesLabel: "DEL"})` when DEL is clicked post-lock. #} {# Sprint 5 iter 4a — shuffled deck (levity + gravity halves, #} {# sig excluded) embedded as JSON; JS reads on init and #} {# pops from the relevant pile on each deposit. #} {{ sea_deck_data|json_script:"id_my_sea_deck" }} {# StageCard + SeaDeal — both bind to `#id_sea_overlay` (the #} {# my-sea-picker) + `#id_sea_stage` (the stage partial) on #} {# DOMContentLoaded; openStage() runs on FLIP click below. #} {# Shared one-shot "seated" glow module — also drives seat 2C on #} {# the spectator page. Exposes window.playSeatGlow + auto-plays on #} {# load for any server-rendered .seated[data-seat-token] seat. #} {# Brief 'Default deck warning' banner — lifted verbatim from #} {# /billboard/my-sign/'s no-equipped-deck path. Same copy, #} {# same FYI (→ /gameboard/) + NVM (dismiss + proceed) actions.#} {# Tagged w. .my-sea-intro-banner so FTs disambiguate from #} {# any other Briefs on the page. note.js itself is hoisted #} {# to the top of {% block content %} (single load per page). #} {# @taxman Briefs — server-driven render. Payloads are populated by #} {# the my_sea view's `_tax_brief_payload` helper, which returns #} {# None when the user's NVM-dismissal anchor is more recent than #} {# the latest TAX_LEDGER Brief of that slug (FREE/PAID DRAW). User- #} {# spec 2026-05-26: Briefs persist-dismiss until the next spend #} {# resets the cycle. `dismiss_url` is in the payload — note.js #} {# POSTs it on NVM click + the my_sea_lock/paid_draw views clear #} {# the matching User.*_brief_dismissed_at on the next spend. #} {% if free_draw_brief_payload %} {{ free_draw_brief_payload|json_script:"id_free_draw_brief_payload" }} {% endif %} {% if paid_draw_brief_payload %} {{ paid_draw_brief_payload|json_script:"id_paid_draw_brief_payload" }} {% endif %} {% if show_backup_intro_banner %} {% endif %} {% endif %} {# Sprint 6 iter 6c — gear-btn lives on every my-sea page state #} {# (sign-gate / landing / picker). NVM-only menu. Picker NVM #} {# nav-backs to the my-sea TABLE HEX via `?phase=landing` — #} {# without the query param, the server would re-render the #} {# picker on the next GET (hand_non_empty branch wins). The #} {# landing then renders a CONT DRAW btn (since active_draw #} {# exists + incomplete) so the user can re-enter the picker. #} {# Sign-gate + landing NVM nav-back to /gameboard/ (default). #} {% if show_picker %}{% url 'my_sea' as nvm_base %}{% with nvm_url=nvm_base|add:'?phase=landing' %}{% include "apps/gameboard/_partials/_my_sea_gear.html" %}{% endwith %}{% else %}{% include "apps/gameboard/_partials/_my_sea_gear.html" %}{% endif %} {# Bud + burger persist across every stage too — same affordance #} {# as on the my-sea gatekeeper, so the user can invite + reach #} {# the cross-cutting menu from sign-gate / landing / picker alike.#} {% include "apps/gameboard/_partials/_my_sea_bud_panel.html" %} {% include "apps/gameboard/_partials/_burger.html" %} {# Voice-affordance glow/pulse machine (keys on voice_active + the live #} {# mesh state). Coexists w. the sea-btn glow-handoff machine below — #} {# sea takes burger precedence; voice is the second-place reveal. #} {# Phase 2 of the Sea sub-btn rollout — wires #id_sea_btn click to #} {# open #id_sea_spread_modal. AUTO DRAW + Escape + backdrop click #} {# all close the modal. AUTO DRAW closes BEFORE its own handler fires #} {# (capture-phase listener) so the existing guard-portal + draw flow #} {# runs against a closed modal, returning the spread crucifix to view #} {# as the cards animate in. #} {# Phase 3 — first-draw glow handoff state machine. Owner of the #} {# .glow-handoff transitions across burger → sea_btn → sea-select → #} {# end. Modal close w/o AUTO DRAW restarts at burger. AUTO DRAW #} {# guard-OK ends the cycle permanently. The initial glow on burger #} {# is set either server-side (see sea_first_draw_pending below) OR #} {# client-side in the FREE DRAW handler that transitions data-phase #} {# to 'picker'. #}
{% endblock content %}