- Split .gate-overlay into .gate-backdrop (z-100, blur) + .gate-overlay modal (z-120) so .table-position elements (z-110) render above backdrop but below modal - New _table_positions.html partial: 6 .table-position divs with .fa-chair, role label, and .fa-ban/.fa-circle-check status icons; included unconditionally in room.html - New epic:room view at /gameboard/room/<uuid>/; gatekeeper redirects there when table_status set; pick_roles redirects there - role-select.js: adds .active glow to position on selectRole(); swaps .fa-ban→.fa-circle-check in placeCard onComplete; handleTurnChanged clears stale .active from all positions - FTs: PositionIndicatorsTest (5 tests) + RoleSelectTest 8a/8b (glow + check state) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
99 lines
5.2 KiB
HTML
99 lines
5.2 KiB
HTML
{% extends "core/base.html" %}
|
|
{% load static %}
|
|
|
|
{% block title_text %}Gameboard{% endblock title_text %}
|
|
{% block header_text %}<span>Game</span>room{% 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 %}>
|
|
<div class="room-shell">
|
|
<div id="id_game_table" class="room-table">
|
|
<div class="table-hex-border">
|
|
<div class="table-hex">
|
|
<div class="table-center">
|
|
{% if room.table_status == "ROLE_SELECT" and card_stack_state %}
|
|
<div class="card-stack" data-state="{{ card_stack_state }}"
|
|
data-starter-roles="{{ starter_roles|join:',' }}"
|
|
data-user-slots="{{ user_slots|join:',' }}">
|
|
{% if card_stack_state == "ineligible" %}
|
|
<i class="fa-solid fa-ban"></i>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% if room.table_status == "SIG_SELECT" and sig_seats %}
|
|
{% for seat in sig_seats %}
|
|
<div class="table-seat{% if seat == sig_active_seat %} active{% endif %}" data-role="{{ seat.role }}" data-slot="{{ seat.slot_number }}">
|
|
<div class="seat-portrait">{{ seat.slot_number }}</div>
|
|
<div class="seat-card-arc"></div>
|
|
<span class="seat-label">
|
|
{% if seat.gamer %}@{{ seat.gamer.username|default:seat.gamer.email }}{% endif %}
|
|
</span>
|
|
</div>
|
|
{% endfor %}
|
|
{% else %}
|
|
{% for slot in room.gate_slots.all %}
|
|
<div class="table-seat{% if slot.slot_number == active_slot %} active{% endif %}"
|
|
data-slot="{{ slot.slot_number }}">
|
|
<div class="seat-portrait">{{ slot.slot_number }}</div>
|
|
<div class="seat-card-arc"></div>
|
|
<span class="seat-label">
|
|
{% if slot.gamer %}@{{ slot.gamer.username|default:slot.gamer.email }}{% endif %}
|
|
</span>
|
|
</div>
|
|
{% endfor %}
|
|
{% endif %}
|
|
{% include "apps/gameboard/_partials/_table_positions.html" %}
|
|
</div>
|
|
</div>
|
|
|
|
{% if room.table_status == "SIG_SELECT" and sig_cards %}
|
|
<div id="id_sig_deck"
|
|
data-select-sig-url="{% url 'epic:select_sig' room.id %}"
|
|
data-user-role="{{ user_seat.role|default:'' }}">
|
|
{% for card, deck_type in sig_cards %}
|
|
<div class="sig-card {{ deck_type }}-deck" data-card-id="{{ card.id }}" data-deck="{{ deck_type }}">
|
|
<div class="fan-card-corner fan-card-corner--tl">
|
|
<span class="fan-corner-rank">{{ card.corner_rank }}</span>
|
|
{% if card.suit_icon %}<i class="fa-solid {{ card.suit_icon }}"></i>{% endif %}
|
|
</div>
|
|
<div class="fan-card-face">
|
|
{% if card.name_group %}<p class="fan-card-name-group">{{ card.name_group }}</p>{% endif %}
|
|
<h3 class="fan-card-name">{{ card.name_title }}</h3>
|
|
<p class="fan-card-arcana">{{ card.get_arcana_display }}</p>
|
|
</div>
|
|
<div class="fan-card-corner fan-card-corner--br">
|
|
<span class="fan-corner-rank">{{ card.corner_rank }}</span>
|
|
{% if card.suit_icon %}<i class="fa-solid {{ card.suit_icon }}"></i>{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if not room.table_status and room.gate_status != "RENEWAL_DUE" %}
|
|
{% include "apps/gameboard/_partials/_gatekeeper.html" %}
|
|
{% endif %}
|
|
<div id="id_tray_wrap">
|
|
<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">{% for i in "12345678" %}<div class="tray-cell"></div>{% endfor %}</div></div>
|
|
</div>
|
|
{% include "apps/gameboard/_partials/_room_gear.html" %}
|
|
</div>
|
|
{% endblock content %}
|
|
|
|
{% block scripts %}
|
|
<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/sig-select.js' %}"></script>
|
|
<script src="{% static 'apps/epic/tray.js' %}"></script>
|
|
{% endblock scripts %} |