{% extends "core/base.html" %}
{% load static tooltip_tags %}

{% block title_text %}Gameboard{% endblock title_text %}
{# Two-word reel: GAME ROOM rests in view; GAME SCROLL is parked just below #}
{# in the title slot's bottom fade. room-scroll.js toggles `.is-scroll` on   #}
{# the <h2> when the table-hex aperture snaps to the provenance feed, and    #}
{# the CSS reel slides ROOM up & out / SCROLL up & in (reverses on scroll-   #}
{# up). The window span carries `data-letters-split` so base.html's letter-  #}
{# splitter skips it and splits the two inner `.gr-word`s instead. Only in   #}
{# the table phase (a scroll exists to reveal); the gate phase stays plain.  #}
{% comment %}
    Title reel — two axes on NESTED elements so they never blend. ROOM
    (`.gr-word--base`) + the outer `.gr-views-reel` ride the VERTICAL reel (hex ⇄
    views, driven by `.is-scroll`). The inner `.gr-views-track` (the five view
    words in VIEW_ORDER) rides the HORIZONTAL axis, keyed by `data-active-view`
    (set by room-views.js) ALONE — so the active view's cell sits in the slot at
    all times, including at the hex. Result: hex⇄views is a pure vertical reel
    landing on wherever you left off; lateral nav is a pure horizontal slide
    (old word out one side, new in from the other). base.html splits `.gr-word`.
{% endcomment %}{% block header_text %}<span>Game</span>{% if room.table_status %}<span class="gr-swap" data-letters-split="1"><span class="gr-word gr-word--base">room</span><span class="gr-views-reel"><span class="gr-views-track"><span class="gr-word gr-word--atlas">atlas</span><span class="gr-word gr-word--scroll">scroll</span><span class="gr-word gr-word--yarn">yarn</span><span class="gr-word gr-word--post">post</span><span class="gr-word gr-word--pulse">pulse</span></span></span></span>{% else %}<span>room</span>{% endif %}{% endblock header_text %}

{% block content %}
    <div class="room-page" data-room-id="{{ room.id }}"
         {% if room.table_status %}data-select-role-url="{% url 'epic:select_role' room.id %}"{% endif %}
         data-scroll-status-url="{% url 'epic:scroll_status' room.id %}">
        <div id="id_aperture_fill"></div>
        {# Table-hex aperture — a binary scroll-snap viewport (mirrors my_sky's #}
        {# wheel<->form swap): the hex pane is the default view; from Role       #}
        {# Select onwards a 2nd pane holds the room's provenance feed, revealed  #}
        {# by scrolling DOWN. `is-scrollable` engages scroll-snap (2 panes), so  #}
        {# the hex content is replaced entirely by the Scroll (no partial scroll #}
        {# — `scroll-snap-stop: always`). DRY seam: my_sea reuses _room_scroll.  #}
        <div id="id_room_aperture" class="room-aperture{% if room.table_status %} is-scrollable{% endif %}">
        {# `has-sig-stage` (active sig pick) makes the pane a positioning context #}
        {# so the green-felt _sig_select_overlay fills it (my_sea-style), covering #}
        {# the hex/seats behind. Dismissing the overlay (this gamer's sigs done)   #}
        {# reveals the hex + waiting message underneath. #}
        <div class="room-pane room-hex-pane{% if room.table_status == "SIG_SELECT" and user_polarity and not polarity_done and viewer_cost_current %} has-sig-stage{% endif %}{% if room.table_status == "SKY_SELECT" and not sky_confirmed and viewer_cost_current %} has-sky-stage{% endif %}{% if room.table_status == "SKY_SELECT" and sky_confirmed and viewer_cost_current %} has-sea-stage{% endif %}">
        <div class="room-shell">
            <div id="id_game_table" class="room-table">
                {# SCAN SIGS advances the whole table past role-select — gated on  #}
                {# the viewer's token cost being current (a lapsed gamer gets GATE  #}
                {# VIEW in the center instead; only their own ROLE pick survives).  #}
                {% if room.table_status == "ROLE_SELECT" and viewer_cost_current %}
                <div id="id_pick_sigs_wrap"{% if starter_roles|length < 6 %} style="display:none"{% endif %}>
                    <form method="POST" action="{% url 'epic:pick_sigs' room.id %}">
                        {% csrf_token %}
                        <button id="id_pick_sigs_btn" type="submit" class="btn btn-primary">SCAN<br>SIGS</button>
                    </form>
                </div>
                {% endif %}
                {% include "core/_partials/_table_hex.html" with hex_center="apps/gameboard/_partials/_room_hex_center.html" hex_seats="apps/gameboard/_partials/_room_hex_seats.html" %}
            </div>
        </div>{# /.room-shell #}
        {# Sig Select stage — green-felt card stage + thumbnail grid, rendered   #}
        {# INSIDE the hex pane (absolute-fills it on --duoUser felt, my_sea-      #}
        {# style) for this gamer's polarity group. Suppressed once their polarity #}
        {# sigs are assigned (then the hex/waiting-msg shows through). #}
        {% if room.table_status == "SIG_SELECT" and user_polarity and not polarity_done and viewer_cost_current %}
            {% include "apps/gameboard/_partials/_sig_select_overlay.html" %}
        {% endif %}
        {# CAST SKY felt — natal chart entry, my_sea-style --duoUser felt that   #}
        {# fills the hex pane (replaces the old root-level dark modal). Hidden    #}
        {# until the CAST SKY btn (or, once saved, the burger Sky sub-btn) adds   #}
        {# html.sky-open. Rendered through the confirmed state too so the saved   #}
        {# wheel stays re-openable from the burger; `has-sky-stage` (the active   #}
        {# entry surface) is dropped once confirmed — the hex then shows DRAW     #}
        {# SEA and the felt sits hidden, primed with the saved chart.            #}
        {% if room.table_status == "SKY_SELECT" and viewer_cost_current %}
            {% include "apps/gameboard/_partials/_sky_overlay.html" %}
        {% endif %}
        {# DRAW SEA felt — Sea Select's --duoUser felt, my_sea-style, fills the   #}
        {# hex pane (like the CAST SKY felt). Server-rendered once the sky is     #}
        {# confirmed (reload path); opened by #id_pick_sea_btn (html.sea-open).   #}
        {% if room.table_status == "SKY_SELECT" and sky_confirmed and viewer_cost_current %}
            {% include "apps/gameboard/_partials/_sea_overlay.html" %}
        {% endif %}
        {# No-reload path: the post-save sky cascade fetches sea_partial + injects #}
        {# the DRAW SEA felt HERE (inside the pane so .sea-page--room fills it),   #}
        {# executing its inline init. Empty until _injectSeaOverlay runs.         #}
        {% if room.table_status == "SKY_SELECT" and not sky_confirmed and viewer_cost_current %}
            <div id="id_sea_inject"></div>
        {% endif %}
        {# Position circles scroll away WITH the hex (they live inside the hex   #}
        {# pane, not at room-page root). Neither the aperture nor the pane sets  #}
        {# z-index/transform, so the strip's z-130 still resolves in the root    #}
        {# stacking context — above the gate/sig overlays — as before.          #}
        {% if room.gate_status != "RENEWAL_DUE" and room.table_status != "SIG_SELECT" %}
            {% include "apps/gameboard/_partials/_table_positions.html" %}
        {% endif %}
        </div>{# /.room-hex-pane #}
        {% if room.table_status %}
        <div class="room-pane room-scroll-pane">
            {# Horizontal game-views carousel (ATLAS/SCROLL/POST/CHAT/PULSE),    #}
            {# landing on SCROLL — which still wraps _room_scroll.html, so the   #}
            {# binary vertical snap + the provenance feed behave as before.      #}
            {% include "apps/gameboard/_partials/_room_views.html" %}
        </div>
        {% endif %}
        </div>{# /.room-aperture #}

        {# Game-views icon strip — root-level (outside the aperture) so it       #}
        {# clears the scroll card's fade mask + the aperture's scroll clip.      #}
        {% if room.table_status %}
            {% include "apps/gameboard/_partials/_room_views_strip.html" %}
        {% endif %}

        {# Phase overlays are gated on `viewer_cost_current` too: a lapsed gamer #}
        {# gets GATE VIEW in the center, so the SKY/SEA modals (which embed      #}
        {# their trigger-btn ids in JS) must not render alongside it. (The Sig   #}
        {# Select stage now lives INSIDE the hex pane above — my_sea-style felt.) #}

        {# Sky tooltips — rendered at room-page root so they escape the felt's    #}
        {# overflow clip (the wheel's planet-hover tooltips are position:fixed).  #}
        {# Present through the confirmed state too (the burger reopen shows the   #}
        {# saved wheel, whose planet hovers need these portals).                  #}
        {% if room.table_status == "SKY_SELECT" and viewer_cost_current %}
            <div id="id_sky_tooltip" class="tt" style="display:none;"></div>
            <div id="id_sky_tooltip_2" class="tt" style="display:none;"></div>
        {% endif %}

        {# Gamer-needed stub — a seat lapsed past its renewal grace and was   #}
        {# auto-BYE'd, so the table no longer fills all six. Minimal stub      #}
        {# until the mid-game re-seat flow lands (_table_positions +          #}
        {# _gatekeeper are already suppressed for RENEWAL_DUE below).          #}
        {% if room.gate_status == "RENEWAL_DUE" %}
            <div id="id_gamer_needed" class="hex-stub">
                <p>A seat opened — awaiting a gamer.</p>
            </div>
        {% endif %}

        {% if not room.table_status and room.gate_status != "RENEWAL_DUE" %}
            {% include "apps/gameboard/_partials/_gatekeeper.html" %}
            {# Owner-only invite affordance: handshake btn at the upper-right #}
            {# of the right sidebar w. slide-out + autocomplete. Replaces the #}
            {# legacy inline `<form action="invite_gamer">` panel.            #}
            {% if request.user == room.owner %}
                {% include "apps/billboard/_partials/_bud_invite_panel.html" %}
            {% endif %}
        {% endif %}
        {% if room.table_status %}
        <div id="id_tray_wrap"{% if room.table_status == "ROLE_SELECT" and starter_roles|length < 6 %} class="role-select-phase"{% endif %}>
            <div id="id_tray_handle">
                <div id="id_tray_grip"></div>
                <button id="id_tray_btn" aria-label="Open seat tray">
                    <i class="fa-solid fa-dice-d20"></i>
                </button>
            </div>
            <div id="id_tray" style="display:none"><div id="id_tray_grid" data-role-icons-url="{% static 'apps/epic/icons/cards-roles/' %}">{% if my_tray_role %}<div class="tray-cell tray-role-card" data-role="{{ my_tray_role }}"><img src="{% static my_tray_scrawl_static_path %}" alt="{{ my_tray_role }}">{% tooltip my_tray_role_tooltip %}</div>{% else %}<div class="tray-cell"></div>{% endif %}{% if my_tray_sig %}<div class="tray-cell tray-sig-card"><div class="sig-stage-card sea-sig-card" aria-label="{{ my_tray_sig.name }}" data-energies="{{ my_tray_sig.energies_json }}" data-operations="{{ my_tray_sig.operations_json }}"><span class="fan-corner-rank">{{ my_tray_sig.corner_rank }}</span>{% if my_tray_sig.suit_icon %}<i class="fa-solid {{ my_tray_sig.suit_icon }}"></i>{% endif %}</div></div>{% else %}<div class="tray-cell"></div>{% endif %}{% for i in "345678" %}<div class="tray-cell"></div>{% endfor %}</div></div>
        </div>
        {% endif %}
        {% comment %}
            Tray-tooltip portal — sibling of the tray so it sits at room-page root,
            not inside the tray's overflow:hidden / mask-image clip. JS populates
            innerHTML on hover of .tray-role-card > img (and Phase 2: sig card).
        {% endcomment %}
        {% if room.table_status %}
            <div id="id_tooltip_portal" class="tt" style="display:none;"></div>
        {% endif %}
        {# Position-circle tooltip portal — rendered whenever the circles can  #}
        {# (gatekeeper + role-select; the SIG_SELECT phase hides the strip).   #}
        {% include "apps/gameboard/_partials/_position_tooltip.html" %}
        {# scroll_filter (table phase only) adds the Frame/Redact gear pane that #}
        {# room-scroll.js swaps in when the aperture is scrolled to the feed.    #}
        {% include "apps/gameboard/_partials/_room_gear.html" with scroll_filter=room.table_status %}
        {% include "apps/gameboard/_partials/_burger.html" %}
    </div>
{% endblock content %}

{% block scripts %}
    {# Brief module — needed by _bud_invite_panel's OK handler so the     #}
    {# slide-down banner shows up on a successful gatekeeper invite.      #}
    <script src="{% static 'apps/dashboard/note.js' %}"></script>
    <script src="{% static 'apps/epic/room.js' %}"></script>
    <script src="{% static 'apps/epic/gatekeeper.js' %}"></script>
    <script src="{% static 'apps/epic/role-select.js' %}"></script>
    <script src="{% static 'apps/epic/stage-card.js' %}"></script>
    <script src="{% static 'apps/epic/combobox.js' %}"></script>
    <script src="{% static 'apps/epic/sig-select.js' %}"></script>
    <script src="{% static 'apps/epic/sea.js' %}"></script>
    <script src="{% static 'apps/epic/tray.js' %}"></script>
    <script src="{% static 'apps/epic/tray-tooltip.js' %}"></script>
    <script src="{% static 'apps/epic/position-tooltip.js' %}"></script>
    <script src="{% static 'apps/epic/burger-btn.js' %}"></script>
    {# Voice-affordance glow/pulse machine (keys on voice_active + the live mesh #}
    {# state) — same as my_sea/my_sea_visit. burger-btn.js owns the click→join;  #}
    {# voice-mesh.js lazy-loads on first join. Coexists w. the sea-btn glow      #}
    {# handoff (sea takes burger precedence; voice is the second-place reveal).   #}
    <script src="{% static 'apps/voice/voice-glow.js' %}"></script>
    <script src="{% static 'apps/epic/room-scroll.js' %}"></script>
    <script src="{% static 'apps/epic/room-views.js' %}"></script>
{% endblock scripts %}
