game kit + role icons + tarot fan: in-use mini-portal label, FLIP cue polarity reset, role icon redraws
All checks were successful
ci/woodpecker/push/pyswiss Pipeline was successful
ci/woodpecker/push/main Pipeline was successful

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>
This commit is contained in:
Disco DeDisco
2026-05-03 22:28:32 -04:00
parent f78177778f
commit b1a11504f5
16 changed files with 298 additions and 154 deletions

View File

@@ -305,4 +305,42 @@ describe("FanStage", () => {
expect(activeCard().dataset.polarity).toBe("gravity");
});
});
// ── Bookmark vs polarity — sessionStorage stores card index only ─────── //
//
// The bookmark must NOT encode FLIP state: closing a modal in gravity and
// reopening it should always land on the levity-painted face (the SSR
// default + the FLIP cue). _testOpen mirrors openFan's polarity reset so
// a re-call simulates a real close + reopen.
describe("openFan polarity reset", () => {
beforeEach(() => makeFixture());
function flipBtn() { return testDiv.querySelector("#id_fan_flip"); }
function activeCard() { return testDiv.querySelector(".fan-card--active"); }
it("resets polarity to levity on reopen even after FLIP-to-gravity", () => {
GameKit._testOpen();
flipBtn().click();
jasmine.clock().tick(500);
expect(activeCard().dataset.polarity).toBe("gravity");
// Re-open: bookmark would restore currentIndex, polarity must reset.
GameKit._testOpen();
jasmine.clock().tick(250);
expect(activeCard().dataset.polarity).toBe("levity");
});
it("does not persist polarity in sessionStorage", () => {
GameKit._testOpen();
flipBtn().click();
jasmine.clock().tick(500);
// Bookmark stores currentIndex only — no polarity key anywhere.
for (let i = 0; i < sessionStorage.length; i++) {
const key = sessionStorage.key(i);
const val = sessionStorage.getItem(key);
expect(val).not.toMatch(/levity|gravity/);
}
});
});
});