2026-04-30 23:36:35 -04:00
|
|
|
{% load tarot_filters %}
|
2026-03-24 22:57:12 -04:00
|
|
|
{% for card in cards %}
|
2026-04-30 21:01:52 -04:00
|
|
|
<div class="fan-card"
|
|
|
|
|
data-index="{{ forloop.counter0 }}"
|
|
|
|
|
data-suit-icon="{{ card.suit_icon }}"
|
|
|
|
|
data-corner-rank="{{ card.corner_rank }}"
|
|
|
|
|
data-name-group="{{ card.name_group }}"
|
|
|
|
|
data-name-title="{{ card.name_title }}"
|
|
|
|
|
data-arcana="{{ card.get_arcana_display }}"
|
|
|
|
|
data-correspondence="{{ card.correspondence|default:'' }}"
|
|
|
|
|
data-keywords-upright="{{ card.keywords_upright|join:',' }}"
|
|
|
|
|
data-keywords-reversed="{{ card.keywords_reversed|join:',' }}"
|
|
|
|
|
data-energies="{{ card.energies_json }}"
|
|
|
|
|
data-operations="{{ card.operations_json }}"
|
|
|
|
|
data-levity-qualifier="{{ card.levity_qualifier }}"
|
|
|
|
|
data-gravity-qualifier="{{ card.gravity_qualifier }}"
|
2026-04-30 21:51:23 -04:00
|
|
|
data-reversal-qualifier="{{ card.reversal_qualifier }}"
|
|
|
|
|
data-levity-emanation="{{ card.levity_emanation }}"
|
|
|
|
|
data-gravity-emanation="{{ card.gravity_emanation }}"
|
|
|
|
|
data-levity-reversal="{{ card.levity_reversal }}"
|
2026-04-30 23:36:35 -04:00
|
|
|
data-gravity-reversal="{{ card.gravity_reversal }}"
|
|
|
|
|
data-italic-word="{{ card.italic_word }}">
|
2026-03-25 00:24:26 -04:00
|
|
|
<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>
|
2026-03-24 22:57:12 -04:00
|
|
|
<div class="fan-card-face">
|
2026-04-30 21:01:52 -04:00
|
|
|
<div class="fan-card-face-upright">
|
game kit + role icons + tarot fan: in-use mini-portal label, FLIP cue polarity reset, role icon redraws
Heterogeneous pre-existing changes (carried across multiple sessions, finally committed alongside the SIG SELECT exit sprint). Grouped:
- gameboard.js: _inUseLabel(roomName) — buildMiniContent renders "In-Use: <name>" on hover (cap 24 chars; overflow → 21 + "…"). Reads token.dataset.inUseRoomName for decks & token.dataset.currentRoomName for trinkets.
- _applet-game-kit.html: removes the inline <p class="tt-token-room-name"> + <p class="tt-deck-game-name"> paragraphs (now redundant — mini-portal carries the name); deck token gains data-in-use-room-name attr.
- gameboard tests: assertions retargeted at data-in-use-room-name + the mini-portal flow rather than the deleted inline paragraphs (test_views, test_deck_contribution, test_trinket_carte_blanche).
- game-kit.js: openFan + _testOpen reset _polarity = 'levity' so reopening the fan after FLIP-to-gravity always lands on the levity-painted face (the FLIP cue). The sessionStorage bookmark intentionally tracks card index only; polarity does NOT persist across reopen.
- _tarot_fan.html: SSR-default polarity flipped from levity to gravity (levity_emanation → gravity_emanation, levity_qualifier → gravity_qualifier, levity_reversal → gravity_reversal across upright + reversal faces). Pairs w. the JS polarity reset above so JS repaints to levity on open.
- FanStageSpec: 2 new specs — openFan polarity reset on reopen even after FLIP-to-gravity; sessionStorage stores no levity/gravity string.
- starter-role-*.svg (Alchemist, Builder, Economist, Narrator, Player, Shepherd): redrawn / re-cropped art — viewBox tightened from 288×560 to ~154×156, paths re-traced. No new role added; existing 6 swapped in place. New starter-role-blank.svg added as fallback for unmapped role codes (referenced by tray.js _ROLE_SCRAWL default → 'Blank').
Code architected by Disco DeDisco <discodedisco@outlook.com>
Git commit message Co-Authored-By:
Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 22:28:32 -04:00
|
|
|
{% if card.gravity_emanation %}
|
2026-04-30 23:36:35 -04:00
|
|
|
{# Polarity-split title (cards 48-49 + trumps 19-21); no qualifier slots — qualifier is baked into the title between "The" and the proper noun #}
|
game kit + role icons + tarot fan: in-use mini-portal label, FLIP cue polarity reset, role icon redraws
Heterogeneous pre-existing changes (carried across multiple sessions, finally committed alongside the SIG SELECT exit sprint). Grouped:
- gameboard.js: _inUseLabel(roomName) — buildMiniContent renders "In-Use: <name>" on hover (cap 24 chars; overflow → 21 + "…"). Reads token.dataset.inUseRoomName for decks & token.dataset.currentRoomName for trinkets.
- _applet-game-kit.html: removes the inline <p class="tt-token-room-name"> + <p class="tt-deck-game-name"> paragraphs (now redundant — mini-portal carries the name); deck token gains data-in-use-room-name attr.
- gameboard tests: assertions retargeted at data-in-use-room-name + the mini-portal flow rather than the deleted inline paragraphs (test_views, test_deck_contribution, test_trinket_carte_blanche).
- game-kit.js: openFan + _testOpen reset _polarity = 'levity' so reopening the fan after FLIP-to-gravity always lands on the levity-painted face (the FLIP cue). The sessionStorage bookmark intentionally tracks card index only; polarity does NOT persist across reopen.
- _tarot_fan.html: SSR-default polarity flipped from levity to gravity (levity_emanation → gravity_emanation, levity_qualifier → gravity_qualifier, levity_reversal → gravity_reversal across upright + reversal faces). Pairs w. the JS polarity reset above so JS repaints to levity on open.
- FanStageSpec: 2 new specs — openFan polarity reset on reopen even after FLIP-to-gravity; sessionStorage stores no levity/gravity string.
- starter-role-*.svg (Alchemist, Builder, Economist, Narrator, Player, Shepherd): redrawn / re-cropped art — viewBox tightened from 288×560 to ~154×156, paths re-traced. No new role added; existing 6 swapped in place. New starter-role-blank.svg added as fallback for unmapped role codes (referenced by tray.js _ROLE_SCRAWL default → 'Blank').
Code architected by Disco DeDisco <discodedisco@outlook.com>
Git commit message Co-Authored-By:
Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 22:28:32 -04:00
|
|
|
<p class="fan-card-name {{ card.title_squeeze_class }}">{{ card.gravity_emanation|italicize:card.italic_word }}</p>
|
2026-04-30 21:51:23 -04:00
|
|
|
{% else %}
|
|
|
|
|
{% if card.name_group %}<p class="fan-card-name-group">{{ card.name_group }}</p>{% endif %}
|
game kit + role icons + tarot fan: in-use mini-portal label, FLIP cue polarity reset, role icon redraws
Heterogeneous pre-existing changes (carried across multiple sessions, finally committed alongside the SIG SELECT exit sprint). Grouped:
- gameboard.js: _inUseLabel(roomName) — buildMiniContent renders "In-Use: <name>" on hover (cap 24 chars; overflow → 21 + "…"). Reads token.dataset.inUseRoomName for decks & token.dataset.currentRoomName for trinkets.
- _applet-game-kit.html: removes the inline <p class="tt-token-room-name"> + <p class="tt-deck-game-name"> paragraphs (now redundant — mini-portal carries the name); deck token gains data-in-use-room-name attr.
- gameboard tests: assertions retargeted at data-in-use-room-name + the mini-portal flow rather than the deleted inline paragraphs (test_views, test_deck_contribution, test_trinket_carte_blanche).
- game-kit.js: openFan + _testOpen reset _polarity = 'levity' so reopening the fan after FLIP-to-gravity always lands on the levity-painted face (the FLIP cue). The sessionStorage bookmark intentionally tracks card index only; polarity does NOT persist across reopen.
- _tarot_fan.html: SSR-default polarity flipped from levity to gravity (levity_emanation → gravity_emanation, levity_qualifier → gravity_qualifier, levity_reversal → gravity_reversal across upright + reversal faces). Pairs w. the JS polarity reset above so JS repaints to levity on open.
- FanStageSpec: 2 new specs — openFan polarity reset on reopen even after FLIP-to-gravity; sessionStorage stores no levity/gravity string.
- starter-role-*.svg (Alchemist, Builder, Economist, Narrator, Player, Shepherd): redrawn / re-cropped art — viewBox tightened from 288×560 to ~154×156, paths re-traced. No new role added; existing 6 swapped in place. New starter-role-blank.svg added as fallback for unmapped role codes (referenced by tray.js _ROLE_SCRAWL default → 'Blank').
Code architected by Disco DeDisco <discodedisco@outlook.com>
Git commit message Co-Authored-By:
Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 22:28:32 -04:00
|
|
|
{% if card.arcana != "MAJOR" and card.gravity_qualifier %}
|
|
|
|
|
<p class="sig-qualifier-above">{{ card.gravity_qualifier }}</p>
|
2026-04-30 21:51:23 -04:00
|
|
|
{% endif %}
|
game kit + role icons + tarot fan: in-use mini-portal label, FLIP cue polarity reset, role icon redraws
Heterogeneous pre-existing changes (carried across multiple sessions, finally committed alongside the SIG SELECT exit sprint). Grouped:
- gameboard.js: _inUseLabel(roomName) — buildMiniContent renders "In-Use: <name>" on hover (cap 24 chars; overflow → 21 + "…"). Reads token.dataset.inUseRoomName for decks & token.dataset.currentRoomName for trinkets.
- _applet-game-kit.html: removes the inline <p class="tt-token-room-name"> + <p class="tt-deck-game-name"> paragraphs (now redundant — mini-portal carries the name); deck token gains data-in-use-room-name attr.
- gameboard tests: assertions retargeted at data-in-use-room-name + the mini-portal flow rather than the deleted inline paragraphs (test_views, test_deck_contribution, test_trinket_carte_blanche).
- game-kit.js: openFan + _testOpen reset _polarity = 'levity' so reopening the fan after FLIP-to-gravity always lands on the levity-painted face (the FLIP cue). The sessionStorage bookmark intentionally tracks card index only; polarity does NOT persist across reopen.
- _tarot_fan.html: SSR-default polarity flipped from levity to gravity (levity_emanation → gravity_emanation, levity_qualifier → gravity_qualifier, levity_reversal → gravity_reversal across upright + reversal faces). Pairs w. the JS polarity reset above so JS repaints to levity on open.
- FanStageSpec: 2 new specs — openFan polarity reset on reopen even after FLIP-to-gravity; sessionStorage stores no levity/gravity string.
- starter-role-*.svg (Alchemist, Builder, Economist, Narrator, Player, Shepherd): redrawn / re-cropped art — viewBox tightened from 288×560 to ~154×156, paths re-traced. No new role added; existing 6 swapped in place. New starter-role-blank.svg added as fallback for unmapped role codes (referenced by tray.js _ROLE_SCRAWL default → 'Blank').
Code architected by Disco DeDisco <discodedisco@outlook.com>
Git commit message Co-Authored-By:
Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 22:28:32 -04:00
|
|
|
<p class="fan-card-name {{ card.title_squeeze_class }}">{{ card.name_title|italicize:card.italic_word }}{% if card.arcana == "MAJOR" and card.gravity_qualifier %},{% endif %}</p>
|
|
|
|
|
{% if card.arcana == "MAJOR" and card.gravity_qualifier %}
|
|
|
|
|
<p class="sig-qualifier-below">{{ card.gravity_qualifier }}</p>
|
2026-04-30 21:51:23 -04:00
|
|
|
{% endif %}
|
2026-04-30 21:01:52 -04:00
|
|
|
{% endif %}
|
|
|
|
|
</div>
|
2026-03-24 22:57:12 -04:00
|
|
|
<p class="fan-card-arcana">{{ card.get_arcana_display }}</p>
|
2026-04-30 21:01:52 -04:00
|
|
|
<div class="fan-card-face-reversal">
|
2026-04-30 21:51:23 -04:00
|
|
|
{% comment %}
|
|
|
|
|
DOM order: reversal-name first, reversal-qualifier second.
|
|
|
|
|
After SPIN's 180° rotation DOM-second appears visually on top.
|
|
|
|
|
{% endcomment %}
|
game kit + role icons + tarot fan: in-use mini-portal label, FLIP cue polarity reset, role icon redraws
Heterogeneous pre-existing changes (carried across multiple sessions, finally committed alongside the SIG SELECT exit sprint). Grouped:
- gameboard.js: _inUseLabel(roomName) — buildMiniContent renders "In-Use: <name>" on hover (cap 24 chars; overflow → 21 + "…"). Reads token.dataset.inUseRoomName for decks & token.dataset.currentRoomName for trinkets.
- _applet-game-kit.html: removes the inline <p class="tt-token-room-name"> + <p class="tt-deck-game-name"> paragraphs (now redundant — mini-portal carries the name); deck token gains data-in-use-room-name attr.
- gameboard tests: assertions retargeted at data-in-use-room-name + the mini-portal flow rather than the deleted inline paragraphs (test_views, test_deck_contribution, test_trinket_carte_blanche).
- game-kit.js: openFan + _testOpen reset _polarity = 'levity' so reopening the fan after FLIP-to-gravity always lands on the levity-painted face (the FLIP cue). The sessionStorage bookmark intentionally tracks card index only; polarity does NOT persist across reopen.
- _tarot_fan.html: SSR-default polarity flipped from levity to gravity (levity_emanation → gravity_emanation, levity_qualifier → gravity_qualifier, levity_reversal → gravity_reversal across upright + reversal faces). Pairs w. the JS polarity reset above so JS repaints to levity on open.
- FanStageSpec: 2 new specs — openFan polarity reset on reopen even after FLIP-to-gravity; sessionStorage stores no levity/gravity string.
- starter-role-*.svg (Alchemist, Builder, Economist, Narrator, Player, Shepherd): redrawn / re-cropped art — viewBox tightened from 288×560 to ~154×156, paths re-traced. No new role added; existing 6 swapped in place. New starter-role-blank.svg added as fallback for unmapped role codes (referenced by tray.js _ROLE_SCRAWL default → 'Blank').
Code architected by Disco DeDisco <discodedisco@outlook.com>
Git commit message Co-Authored-By:
Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 22:28:32 -04:00
|
|
|
{% if card.gravity_reversal %}
|
2026-04-30 21:51:23 -04:00
|
|
|
{# Polarity-split reversal title — single line, qualifier slot empty. Title goes in the qualifier slot so it visually lands on top after spin. #}
|
|
|
|
|
<p class="fan-card-reversal-name"></p>
|
game kit + role icons + tarot fan: in-use mini-portal label, FLIP cue polarity reset, role icon redraws
Heterogeneous pre-existing changes (carried across multiple sessions, finally committed alongside the SIG SELECT exit sprint). Grouped:
- gameboard.js: _inUseLabel(roomName) — buildMiniContent renders "In-Use: <name>" on hover (cap 24 chars; overflow → 21 + "…"). Reads token.dataset.inUseRoomName for decks & token.dataset.currentRoomName for trinkets.
- _applet-game-kit.html: removes the inline <p class="tt-token-room-name"> + <p class="tt-deck-game-name"> paragraphs (now redundant — mini-portal carries the name); deck token gains data-in-use-room-name attr.
- gameboard tests: assertions retargeted at data-in-use-room-name + the mini-portal flow rather than the deleted inline paragraphs (test_views, test_deck_contribution, test_trinket_carte_blanche).
- game-kit.js: openFan + _testOpen reset _polarity = 'levity' so reopening the fan after FLIP-to-gravity always lands on the levity-painted face (the FLIP cue). The sessionStorage bookmark intentionally tracks card index only; polarity does NOT persist across reopen.
- _tarot_fan.html: SSR-default polarity flipped from levity to gravity (levity_emanation → gravity_emanation, levity_qualifier → gravity_qualifier, levity_reversal → gravity_reversal across upright + reversal faces). Pairs w. the JS polarity reset above so JS repaints to levity on open.
- FanStageSpec: 2 new specs — openFan polarity reset on reopen even after FLIP-to-gravity; sessionStorage stores no levity/gravity string.
- starter-role-*.svg (Alchemist, Builder, Economist, Narrator, Player, Shepherd): redrawn / re-cropped art — viewBox tightened from 288×560 to ~154×156, paths re-traced. No new role added; existing 6 swapped in place. New starter-role-blank.svg added as fallback for unmapped role codes (referenced by tray.js _ROLE_SCRAWL default → 'Blank').
Code architected by Disco DeDisco <discodedisco@outlook.com>
Git commit message Co-Authored-By:
Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 22:28:32 -04:00
|
|
|
<p class="fan-card-reversal-qualifier {{ card.title_squeeze_class }}">{{ card.gravity_reversal|italicize:card.italic_word }}</p>
|
2026-04-30 21:51:23 -04:00
|
|
|
{% elif card.arcana == "MAJOR" %}
|
game kit + role icons + tarot fan: in-use mini-portal label, FLIP cue polarity reset, role icon redraws
Heterogeneous pre-existing changes (carried across multiple sessions, finally committed alongside the SIG SELECT exit sprint). Grouped:
- gameboard.js: _inUseLabel(roomName) — buildMiniContent renders "In-Use: <name>" on hover (cap 24 chars; overflow → 21 + "…"). Reads token.dataset.inUseRoomName for decks & token.dataset.currentRoomName for trinkets.
- _applet-game-kit.html: removes the inline <p class="tt-token-room-name"> + <p class="tt-deck-game-name"> paragraphs (now redundant — mini-portal carries the name); deck token gains data-in-use-room-name attr.
- gameboard tests: assertions retargeted at data-in-use-room-name + the mini-portal flow rather than the deleted inline paragraphs (test_views, test_deck_contribution, test_trinket_carte_blanche).
- game-kit.js: openFan + _testOpen reset _polarity = 'levity' so reopening the fan after FLIP-to-gravity always lands on the levity-painted face (the FLIP cue). The sessionStorage bookmark intentionally tracks card index only; polarity does NOT persist across reopen.
- _tarot_fan.html: SSR-default polarity flipped from levity to gravity (levity_emanation → gravity_emanation, levity_qualifier → gravity_qualifier, levity_reversal → gravity_reversal across upright + reversal faces). Pairs w. the JS polarity reset above so JS repaints to levity on open.
- FanStageSpec: 2 new specs — openFan polarity reset on reopen even after FLIP-to-gravity; sessionStorage stores no levity/gravity string.
- starter-role-*.svg (Alchemist, Builder, Economist, Narrator, Player, Shepherd): redrawn / re-cropped art — viewBox tightened from 288×560 to ~154×156, paths re-traced. No new role added; existing 6 swapped in place. New starter-role-blank.svg added as fallback for unmapped role codes (referenced by tray.js _ROLE_SCRAWL default → 'Blank').
Code architected by Disco DeDisco <discodedisco@outlook.com>
Git commit message Co-Authored-By:
Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 22:28:32 -04:00
|
|
|
<p class="fan-card-reversal-name">{{ card.gravity_qualifier|default:card.levity_qualifier }}</p>
|
|
|
|
|
<p class="fan-card-reversal-qualifier {{ card.title_squeeze_class }}">{{ card.name_title|italicize:card.italic_word }}{% if card.gravity_qualifier %},{% endif %}</p>
|
2026-04-30 21:01:52 -04:00
|
|
|
{% else %}
|
2026-05-01 02:06:55 -04:00
|
|
|
<p class="fan-card-reversal-name {{ card.title_squeeze_class }}">{{ card.name_title|italicize:card.italic_word }}</p>
|
2026-04-30 21:01:52 -04:00
|
|
|
<p class="fan-card-reversal-qualifier">{{ card.reversal_qualifier|default:card.gravity_qualifier }}</p>
|
|
|
|
|
{% endif %}
|
|
|
|
|
</div>
|
2026-03-25 00:24:26 -04:00
|
|
|
</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 %}
|
2026-03-24 22:57:12 -04:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{% endfor %}
|