Commit Graph
Select branches
Hide Pull Requests
main
pre-drf
Select branches
Hide Pull Requests
main
pre-drf
-
86a349b64e
wallet shop: free ($0) RWS + Fiorentine decks — FREE ITEM claim unlocks to Game Kit — TDD
main
Disco DeDisco
2026-05-30 14:51:21 -04:00 -
d8377b57bc
my-sea cards: fix rotated significator/cross blur — drop the 4-shadow contour chain on rotated image cards, keep depth — TDD
Disco DeDisco
2026-05-30 02:26:29 -04:00 -
7e39740f9c
my_sea_visit nav: phase-aware NVM (hex→bud page, draw→hex) + navbar GATE VIEW → visit gate + guard reposition on resize — TDD
Disco DeDisco
2026-05-30 02:15:23 -04:00 -
571d5a84ae
voice glow: regression spec — 3-min mute auto-disconnect stops the priRd/.fa-ban path + returns to the available nudge, live — TDD
Disco DeDisco
2026-05-30 01:49:35 -04:00 -
668105aeeb
my-sea voice: persist mute across in-sea nav/refresh + 3-min muted auto-disconnect; fix first-connect glow/mute race — TDD
Disco DeDisco
2026-05-30 01:41:30 -04:00 -
de4dcd7979
my-sea deck glow: single (monodeck) stack matches the levity/gravity --ninUser halo — make every deck match
Disco DeDisco
2026-05-30 01:19:14 -04:00 -
b7d871388e
my-sea deck-stack + spread-card glow: unify hover-reveal / click-persist + --ninUser halo — TDD
Disco DeDisco
2026-05-30 01:11:39 -04:00 -
7e876557aa
my-sea spectate: broadcast spread on modal-close + sequence the spectator's AUTO DRAW reveal — TDD
Disco DeDisco
2026-05-30 00:45:00 -04:00 -
9678d187b4
my-sea spectate: live spread-sync + owner seat-ring push + visit caption fix — TDD
Disco DeDisco
2026-05-30 00:35:18 -04:00 -
877e0f544a
my-sea: seated chairs settle to --secUser; owner sees all seated members; gear menu column; visit hex scales — TDD
Disco DeDisco
2026-05-30 00:04:04 -04:00 -
0693a422d2
my-sea: second spectate broadcast — seat ring updates live on deposit / BYE — TDD
Disco DeDisco
2026-05-29 23:42:22 -04:00 -
32836704b7
my_sea_visit: add --visible on live-filled spectator slots so the card lands at final opacity (no empty->filled ease race)
Disco DeDisco
2026-05-29 23:36:59 -04:00 -
01ee8dc1fb
my-sea: async witness — spectators see the owner's draw land live via WS, no refresh — TDD
Disco DeDisco
2026-05-29 23:14:48 -04:00 -
a85f5b6f44
my-sea slot: render the 5+-char numeral squeeze (--rank-long) server-side so it survives a refresh — TDD
Disco DeDisco
2026-05-29 23:06:19 -04:00 -
260c1c1325
my_sea_visit: give the visitor a top-left deck stack (owner's deck) with a hover-revealed disabled FLIP — TDD
Disco DeDisco
2026-05-29 23:01:21 -04:00 -
c3594d27ed
my_sea_visit: share the owner picker styling (--duoUser felt + fill) when showing the draw — TDD
Disco DeDisco
2026-05-29 22:42:00 -04:00 -
02d2d565a3
RWS card faces: thin the contour stroke for the english deck so it doesn't double the card's own border
Disco DeDisco
2026-05-29 22:28:11 -04:00 -
c4e738ad16
my-sea voice: persist the call across in-sea reloads via auto-rejoin; pngquant the RWS card back — TDD
Disco DeDisco
2026-05-29 22:08:45 -04:00 -
2cbc1bf292
my-sea spectator: render all present members on the hex (2C-6C), not just the viewer — TDD
Disco DeDisco
2026-05-29 22:01:23 -04:00 -
cb7ca4b5f3
voice consumer: cap live connections at 6 per room (defense-in-depth) — TDD
Disco DeDisco
2026-05-29 21:56:24 -04:00 -
92d46b3dce
my-sea voice: volume-reactive equalizer glow + muted (--priRd/.fa-ban) state — TDD
Disco DeDisco
2026-05-29 21:46:08 -04:00 -
f0b9f02c7c
my-sea voice: cap visitors at 5 (6 seats) + free a seat on leave — TDD
Disco DeDisco
2026-05-29 21:35:22 -04:00 -
da97c623c9
voice: fail loud on insecure-context join (mic blocked over HTTP) instead of silent reject — TDD
Disco DeDisco
2026-05-29 21:29:42 -04:00 -
6799749ede
my-sea voice: guard before NVM disconnects voice + harden mute (honor pre-stream mute) — TDD
Disco DeDisco
2026-05-29 21:22:21 -04:00 -
b021d8017c
my-sea voice: voice-btn glow/pulse state machine (sea-precedence, pulse-while-alone, 2x on 2nd party) — TDD
Disco DeDisco
2026-05-29 21:06:02 -04:00 -
7bd8e3256a
my-sea spectator: render owner's draw as the identical interactive cross stage; owner seated in 1C when paid OR drawn — TDD
Disco DeDisco
2026-05-29 20:48:31 -04:00 -
1ac380dfc5
my-buds async add: insert new row before .applet-list-buffer, not after — keeps spacer last
Disco DeDisco
2026-05-29 12:56:03 -04:00 -
af8452f22d
my-buds async add: render full row (anchor + the <Title> + data-tt-* attrs) so the appended entry's tooltip isn't empty — TDD
Disco DeDisco
2026-05-29 11:56:31 -04:00 -
3bf35ad539
remove dead my-sea invite accept/decline endpoints — acceptance is now implicit on bud-page sea-btn visit (accept-on-GET)
Disco DeDisco
2026-05-29 11:52:38 -04:00 -
f5ee83be0a
bud page sea-btn cascade: live-invite window + accept-on-GET + glow handoff; my-buds tooltip clamp + row hover/lock — TDD
Disco DeDisco
2026-05-29 11:36:25 -04:00 -
d87f26003b
CI: wrap test-two-browser-FTs commands in _retry_failed.sh
Disco DeDisco
2026-05-28 14:32:04 -04:00 -
b563e96f82
RWS deck: flip has_card_images=True to light up image-mode rendering — TDD
Disco DeDisco
2026-05-28 14:01:57 -04:00 -
1e1a0a5ab8
deck images: resize Minchiate + RWS to 700px height + re-pngquant; drop orphan MySeaInviteAcceptanceLogTest — TDD
Disco DeDisco
2026-05-28 13:52:14 -04:00 -
6cc11924e3
bud landing page: /billboard/buds/<id>/ + my_buds tooltip portal + @mailman post-attribution anchor — TDD
Disco DeDisco
2026-05-28 11:45:20 -04:00 -
c41cf7ed36
coturn: activate [coturn] inventory host (turn.earthmanrpg.me + v4/v6)
Disco DeDisco
2026-05-27 14:30:38 -04:00 -
68239ac5d4
coturn: wire COTURN_* into app env template (gamearray.env.j2)
Disco DeDisco
2026-05-27 14:16:33 -04:00 -
c9a61e5614
coturn: optional dual-stack TURN via guarded coturn_public_ip6
Disco DeDisco
2026-05-27 14:10:28 -04:00 -
41217d5438
my-sea voice Phase C: WebRTC mesh signaling app + TURN endpoint + voice-btn wiring + coturn infra — TDD
Disco DeDisco
2026-05-27 13:57:09 -04:00 -
d0c39b51b6
my-sea spectator Phase B: seat-2C occupancy + visitor token gate + one-shot seated glow + gear BYE — TDD
Disco DeDisco
2026-05-27 13:35:00 -04:00 -
fb8563eed2
my-sea bud-invite Phase A: SeaInvite model + @mailman log + OK/BYE accept/decline — TDD
Disco DeDisco
2026-05-27 13:14:06 -04:00 -
1c799d35ca
room-stage FTs: realign 4 fails to new my-sea NVM + spread-modal + landscape kit-bag UX — TDD
Disco DeDisco
2026-05-27 02:00:35 -04:00 -
c30b63cd5d
burger Sea sub-btn: first-draw --priYl glow handoff (phase 3/3) — TDD
Disco DeDisco
2026-05-27 00:39:46 -04:00 -
a39053d3f6
CI #345 fixes: bud-kit mutual exclusion test → portrait viewport; carte sign-gate-brief wait → wait_for_slow
Disco DeDisco
2026-05-27 00:19:34 -04:00 -
6fbeed78d8
burger Sea sub-btn: spread-form modal + relocated deck stacks + mid-draw CONT DRAW escape — TDD (phase 2/3)
Disco DeDisco
2026-05-27 00:15:30 -04:00 -
3ae85b962b
burger sea sub-btn: wire .active =
show_picker and not hand_complete(phase 1/3) — TDD
Disco DeDisco
2026-05-26 23:24:27 -04:00 -
5cade51d03
my-sea gear NVM: gatekeeper + picker nav-back to table hex instead of ejecting to gameboard — TDD
Disco DeDisco
2026-05-26 22:39:26 -04:00 -
ca960d1d43
my_sea.html: persist burger + bud btns across all 3 phases — TDD
Disco DeDisco
2026-05-26 22:27:44 -04:00 -
894d65fd6b
burger sub-btns: opacity-0.6 inactive default + 2-pulse --priRd flash w. fa-ban swap on click — TDD
Disco DeDisco
2026-05-26 22:23:03 -04:00 -
6809681e5a
my_sea_gate burger; _bud_apparatus shared shell; CI #344 tray-anchor fix — TDD
Disco DeDisco
2026-05-26 21:57:45 -04:00 -
03feaee9f2
burger z-index drop 318→314 to match .gear-btn; FT base dismiss_brief_if_present helper — TDD
Disco DeDisco
2026-05-26 21:39:36 -04:00 -
3ca986fb45
room.html burger btn + 5-fan; universal landscape btn refactor; kit_bag_dialog vertical bar — TDD
Disco DeDisco
2026-05-26 20:40:33 -04:00 -
3ad372bc36
FT fix CI #342: seed log_tax_debit in test_saved_draw_renders_brief_banner — @taxman ledger sprint left the FT stale
Disco DeDisco
2026-05-26 18:19:11 -04:00 -
c84b3ba9f3
.btn font-family: explicit Segoe UI / system-ui stack — kills the Firefox UA-default inheritance trap
Disco DeDisco
2026-05-26 18:03:05 -04:00 -
4ddc0f810c
sprint A.8 gatekeeper: token deposit ↔ withdraw redact-pair on the room scroll — TDD
Disco DeDisco
2026-05-26 17:55:26 -04:00 -
c0f4711589
my_sea AUTO DRAW: flash FLIP btn per-card for monodecks too — fall back to --single stack
Disco DeDisco
2026-05-26 16:42:56 -04:00 -
c745d2453f
my_sign main: extend sea_stage FLIP corner-swap fix — SPIN-click now hides + reanchors FLIP to visual bottom-left
Disco DeDisco
2026-05-26 16:40:35 -04:00 -
bf79963fec
@taxman ledger polish: My Posts applet preview uses Line.display_text; tax debits read "My Sea's …" not "my_sea.html …" — TDD
Disco DeDisco
2026-05-26 16:30:11 -04:00 -
f44a282007
@taxman Debits & credits ledger + NVM-persistent FREE/PAID DRAW Briefs — TDD
Disco DeDisco
2026-05-26 16:26:42 -04:00 -
7f6c0c2883
FT fix CI #340: re-seed Earthman deck in GameboardNavigationTest setUp — TransactionTestCase flush trap
Disco DeDisco
2026-05-26 15:18:18 -04:00 -
de9c97a2f8
sea_stage reversed-card open: slow auto-rotate-in + FLIP-btn corner-swap — TDD
Disco DeDisco
2026-05-26 13:49:48 -04:00 -
a133a9c1c3
FT fixes for polish-9 spec changes — CI #338 surfaced 4 stale assertions; sig-gate Brief race exposed by removing implicit wait
Disco DeDisco
2026-05-26 02:34:02 -04:00 -
652cef09c0
image tree refactor: cards-faces/<family>/<variant>/ + RWS deck import (78 cards + back, renamed + pngquant'd)
Disco DeDisco
2026-05-26 01:51:12 -04:00 -
955bdc7f67
polish + bugfix session — wallet/Game Kit applet realign; my_sea label/shadow polish; DEL/FLIP state machine; sig-change cooldown loophole closure; sky-wheel planet shadow; Fiorentine additive numerals; kit-bag DOFF async refresh — TDD
Disco DeDisco
2026-05-26 01:18:51 -04:00 -
9cdd2cda68
Sky-wheel Aspected / Unaspected mini-portal — new
#id_mini_tooltip_portalfor the sky tooltip's DON|DOFF apparatus + dashboard My Sky applet parity + styling polish.
Disco DeDisco
2026-05-25 22:31:52 -04:00 -
c4bbac0938
A.7.5-polish-7 h2 3-letter suffix spacing — Sky/Sea/Kit use
space-aroundinstead ofspace-betweenso the trio doesn't park letters at slot edges. User-reported 2026-05-25 PM: "These three 3-letter titles—Sky, Sea, and Kit—take up way too much space" — the defaultjustify-content: space-betweenon the suffix word-span (_base.scss:248-253) put the first + last letter flush against the slot's edges + left a yawning gap mid-span ("S E A" reads as a stretched-apart trio).
Disco DeDisco
2026-05-25 21:40:21 -04:00 -
d10ef94161
A.7.5-polish-6-fix applet FLIP-btn hover-reveal — drop leftover
_billboard.scssrule whose ID-context cascaded above the hover-reveal. User-reported 2026-05-25 PM after polish-6 (b308115): "still not seeing it on My Sign applet, but looks good everywhere else". DOM inspection confirmed the btn was present + opacity:0 at rest as expected, but real-hover never flipped it to opacity:1.
Disco DeDisco
2026-05-25 19:52:51 -04:00 -
b308115fcf
A.7.5-polish-6 FLIP btn everywhere — applet gate dropped + sea_stage modal gets FLIP. User-spec 2026-05-25 PM ("If it's interfering to have bespoke rules, just allow the FLIP btn everywhere, including in my_sea.html") follow-up to polish-5 (
1e2041e).
Disco DeDisco
2026-05-25 19:31:45 -04:00 -
1e2041ed9f
A.7.5-polish-5 DRY
_stat_face.htmlpartial + FLIP-btn SCSS unification + my_sign FLIP DOM move-into-card + universal hover-reveal + instant mid-flip vanish + sea-stage-card image-mode bg fix + multi-line comment syntax cleanup. User-spec 2026-05-25 PM bundle of 5 cleanup threads atop polish-4 (4554c71).
Disco DeDisco
2026-05-25 19:22:08 -04:00 -
a03d0b0cac
Papa Quattro pngquant pass — 980k → 339k (-65% / 641k saved). User-suggested 2026-05-25 PM after the bg-trim re-export grew the file: "if it is higher res, we should strip it like we did yesterday". Same flags as the
0add163import batch:pngquant --quality=65-85 --speed=1 --strip --skip-if-larger. Resulting file is now smaller than the pre-trim version (378k) too — the user's editor had re-saved w/o pngquant's aggressive quantization; this restores the optimized baseline.
Disco DeDisco
2026-05-25 18:23:50 -04:00 -
9d33cda139
Papa Quattro trump asset re-export — user trimmed leftover background pixels they'd neglected to remove from the original scan (per user 2026-05-25 PM). File grew 378402 → 980335 bytes — the bg trim itself shrinks visible content but the user's editor likely re-saved w. less-aggressive PNG compression than the original pngquant run; consider a re-pngquant pass before prod if asset-size becomes a concern.
Disco DeDisco
2026-05-25 18:20:39 -04:00 -
4554c71aed
A.7.5-polish-4 stat-block chip restructure + top-pin + CSS-transition SPIN + sea-sig-card image-mode bg fix + title --quaUser unification — TDD. Mid-session 2026-05-25 PM bundle of 5 user-spec'd polish threads atop the polish-3 alpha bump (
1839a37):
Disco DeDisco
2026-05-25 18:14:42 -04:00 -
b1c6833956
Sky wheel
.nw-rxbadge —.shop-badgeparity for retrograde planets. User-spec 2026-05-25 PM: "Can you help me give a similar badge to .nw-rx as to that by the stack of ×5 Tithe Tokens in wallet.html's Shop applet? One commensurately scaled to the planet, and containing the Rx symbol where it already is, slightly overlapping its planet and along the same degree as it". Mirrors the wallet Shop applet's.shop-badge×N quantity chip:--secUserdisc +--priUserglyph + bold weight.
Disco DeDisco
2026-05-25 17:30:21 -04:00 -
1839a375fe
A.7.5-polish-3 stat-block alpha unification (1.0) — supersedes polish-2's 0.5. User-reverted 2026-05-25 PM: "please undo that and set all of them to the higher opacity that My Sign just had". The 0.5 unification from polish-2 (
efcef15) made all 4 stat-blocks too washed-out against the page bg bleed; user wants them fully opaque matching the My Sign applet's original gravity-state appearance (=rgba(var(--priUser), 1)). Forward edit rather than git revert since the polarity-bg + label-color collapses from earlier polish commits stay in place — only the alpha changes.
Disco DeDisco
2026-05-25 15:28:35 -04:00 -
efcef15487
A.7.5-polish-2 stat-block alpha unification — all 4 surfaces collapse to
rgba(var(--priUser), 0.5)matching the my_sign main page. User-reported 2026-05-25 PM after the polarity-bg unification (2ec23ea): "Lots of different opacities all around here. Can you unify those too, to the My Sign stat block?" — the my_sign main page's.sig-stat-blockdefault isrgba(var(--priUser), 0.5); the 3 other stat-block surfaces were carrying different alphas (sea 0.85, fan 1.0, applet 0.8 default + 1.0 gravity override) — visually inconsistent. Collapse all to 0.5.
Disco DeDisco
2026-05-25 15:05:07 -04:00 -
2ec23ea2c0
A.7.5-polish stat-block polarity bg unification — gravity flipped to --priUser across sig + sea + fan stages (match My Sign applet's no-flip convention). User-reported 2026-05-25 PM after the A.7.5 land (
a9ad422): "the --priUser and --secUser polarity seems to be reversed everywhere but the My Sign applet". DOM inspection confirmed: applet stat-block under gravity =rgb(50, 30, 95)(--priUser); main.sig-stat-blockunder gravity =rgba(162, 170, 173, 0.75)(--secUser). Applet keeps --priUser bg under BOTH polarities (no gravity override on bg; only label/keyword colors flipped). Main page + sea_stage + fan_stage were doing the opposite-polarity flip per the [[feedback-card-polarity-convention]] lock, which the user is now revising — stat-block should match applet pattern (always --priUser bg, regardless of polarity).
Disco DeDisco
2026-05-25 14:44:07 -04:00 -
a9ad422b35
A.7.5 Game Kit carousel image-mode + universal stat-block top-left chip + EMANATION/REVERSAL --secUser convention — TDD. Mid-session 2026-05-25 PM (Sprint A.7.5 of [[project-image-based-deck-face-rendering]] — slotted between A.7 polish + tomorrow's A.8 room.html). Three threads bundled: (1) Game Kit
_tarot_fan.htmlcarousel modal gets the image-mode branch + per-card FLIP-to-back for non-polarized image-equipped decks (Minchiate today; brings the carousel into parity w. the other 5 image-mode surfaces shipped in A.3-A.7); (2) the A.3 Q3-spec top-left rank+suit chip lands across all 4 stat-block surfaces (my_sign main / _applet-my-sign / _sea_stage modal / new game_kit fan stage), retrofitting work that A.3 explicitly deferred per the "Lower-priority follow-ups" list in the project memory; (3) chip + EMANATION/REVERSAL label adopt --secUser as the new universal color convention so the title (--quaUser/--terUser per arcana) stays the focal text + the chip-and-label header recedes visually.
Disco DeDisco
2026-05-25 14:25:41 -04:00 -
5a1acbd9ca
CI test-FTs-room #334 fix —
_seed_earthman_sig_pilemissingis_polarized=True+has_card_images=Falsedefaults (13 errors) + staleid_kit_fiorentine_deckselector →id_kit_tarot_deck(1 error). CI pipeline #334 test-FTs-room reported 1 FAIL + 13 errors after retry on a clean local-green branch; user asked for diagnosis. Two unrelated root causes — both pure FT-helper / FT-selector bugs surfaced by today's earlier landings (15025b4my_sea single-stack collapse +f107522RWS rename). No app code touched.
Disco DeDisco
2026-05-25 11:12:16 -04:00 -
711b609e0c
A.7-polish-4 applet stat-block palette tweak — user-edited 2026-05-25 PM. Two adjustments inside
_billboard.scss's.my-sign-applet-stat-blockblock: (1) Minor/middle .stat-face-title color shifts from --quiUser to --quaUser — the previous --quiUser tint blended too closely w. the keywords text in the applet at applet-card-w sizing; --quaUser provides better contrast against the dimmer surrounding body. (2) The gravity-polarity stat-block inversion now reads --priUser bg + --secUser-tinted keywords/border (was --secUser bg + --priUser keywords) — the prior assignment had the stat-block more saturated than the adjacent card, drawing the eye away from the card art; flipping the assignment lets the card stay the visual anchor while the stat-block recedes into a calmer companion surface. .stat-face-label color stays --quiUser since it's the always-on identity marker and reads correctly against both bg variants. Pure SCSS — no template / view / JS / test changes
Disco DeDisco
2026-05-25 02:46:55 -04:00 -
7c6ab39635
A.7-polish-3 stat-block title + arcana fields across 3 surfaces + spread-switch unlock after DEL — TDD. End-of-session 2026-05-25 PM. Two changes bundled (both user-requested as round-out work for tonight's final push):
Disco DeDisco
2026-05-25 02:43:00 -04:00 -
26cdf0d38b
A.7-polish-2 Sea Stage modal img scaffold — TDD. User-reported bug 2026-05-25 PM after the my_sea polish commit (
15025b4): drawing a card manually opens the Sea Stage modal but the card area is blank instead of showing the v2-convention card image (or the old text fallback). Root cause: stage-card.js's_setImageMode(added in A.3) correctly adds the.sig-stage-card--imageclass to the modal's.sig-stage-card.sea-stage-cardwhen the drawn card has a non-emptyimage_urlpayload (now flowing through from A.7-polish'scard_dictupdate), and the shared SCSS rule (_card-deck.scss.sig-stage-card.sig-stage-card--image) correctly hides the text scaffold children (.fan-card-corner / .fan-card-face) via display:none. But — the modal's HTML scaffold in_sea_stage.htmlwas missing the<img class="sig-stage-card-img">slot that the JS expects to populate._setImageModequeriesstageCard.querySelector('.sig-stage-card-img'), gets null, and silently falls through — leaving the modal w. the text scaffold hidden + no img element to show. Net: blank card. Fix: add the same hidden<img class="sig-stage-card-img" alt="" style="display:none">slot to_sea_stage.htmlthat already lives inmy_sign.html's stage card scaffold (the contract the stage-card.js module assumes). Matches the my_sign pattern: inlinestyle="display:none"is cleared by JS viaimg.style.display = ''when image mode activates (vs. the my_sign template back-img which uses pure CSS-toggled visibility — different contract since the back-img is server-rendered conditionally). No SCSS / JS changes — the shared image-mode SCSS rule already covers the modal's.sig-stage-card.sig-stage-card--imageselector (lifted to top-level in A.5 commit82813e9specifically so non-.sig-stage-nested cards like the my_sea central sig + Sea Stage modal both work). Also memory-updated: noted the pre-existing AUTO DRAW bug (only works on default SAO spread; other 5 spreads silently fail). Bug pre-dates the image-rendering sprint per user — likely a hardcoded position-list or pile-slice assumption in sea.js's auto-draw handler. Not blocking A.8; flagged in [[project-image-based-deck-face-rendering]] follow-ups. Tests: 1306/1306 IT+UT total green (74s, unchanged — pure template scaffold extension, no test surface). Visual verify: refresh /gameboard/my-sea/ + draw a Minchiate card manually → modal should now show the actual Minchiate card image w. contour stroke + depth shadow, NOT the previous blank state
Disco DeDisco
2026-05-25 02:21:31 -04:00 -
15025b4188
A.7-polish my_sea slot image-rendering (server-saved + mid-draw JS) + non-polarized single-deck-stack collapse — TDD. End-of-session wrap-up 2026-05-25 PM. Three changes covering my_sea.html surfaces that weren't in A.5/A.7's central-sig-only scope: (1) saved-hand slot rendering (
_my_sea_slot.htmlserver-rendered partial fired when a draw is resumed via refresh); (2) mid-draw slot fill (sea.js's_fillSlotwrites slot.innerHTML on each card-deposit click; previously rendered corner-rank + suit-icon only, NOW renders <img> when card.image_url is non-empty); (3) deck-stack collapse for non-polarized decks (Minchiate today) — the bottom-right of my_sea.html showed two side-by-side GRAVITY + LEVITY stacks regardless of equipped-deck polarization; for non-polarized decks polarity has no meaning so the dual layout misleads. **Critical lock**: collapse is my_sea-ONLY. room.html keeps the dual stacks since multiple gamers contribute (each might bring a different polarization). Server-side template branches{% if request.user.equipped_deck.is_polarized %}to pick dual vs. single rendering; the--singlestack carries the actual deck back-image via<img class="sea-stack-face-img">(object-fit: cover) when has_card_images=True. Sub-changes:card_dict()inapps/epic/utils.pynow includesimage_url+arcana_keyfields so the picker grid's JSON payload carries the data the JS fill-handler needs (single source of truth shared w. the gameroom sea_deck endpoint —apps/gameboard/views.py'ssaved_by_positiondict gets the parallel additions for server-rendered saved hand). SCSS: extended the shared image-mode rule's comma-list selector in_card-deck.scssto include.sea-card-slot.sea-card-slot--imageso the contour stroke + depth shadow apply to both saved + mid-draw slots from a single rule definition. Also added.sea-deck-stack--single .sea-stack-faceblock w. neutral --priUser/--terUser palette (vs. gravity's --quiUser/--quaUser + levity's --terUser/--ninUser) + the corresponding hover/active glow rule positioned AFTER the$_sea-shadowSCSS variable definition at line 1808 (initial draft hit a compile error:Undefined variable: "$_sea-shadow"because the hover rule was placed before the variable was defined; SCSS variables are scope/order-dependent). JS:_fillSlotinsea.jsbranches oncard.image_url— when non-empty, write<img class="sig-stage-card-img">+ add.sea-card-slot--imagemarker +data-arcana-keyattr; otherwise legacy corner-rank + suit-icon. innerHTML alt-attribute properly escapes"to"so card names w. quotes (none today, but defensive) don't break HTML. Existing JS that activates a clicked stack (_activeStackflow +_showOk/_hideOk) works unchanged w. the single-stack variant since the selector.sea-deck-stackmatches all variants regardless of polarity suffix; theisLevity = stack.classList.contains('sea-deck-stack--levity')check at the deposit moment returns false for--single→ defaults to gravity polarity assignment, which is fine for non-polarized decks (polarity field has no card-content effect). Memory updated:project_image_based_deck_face_rendering.mdnow lists A.0-A.7 done + this polish + room.html (A.8) as the sole remaining surface for tomorrow. The 6-surface scope sheet shows A.8 as the last red box; everything else green. Tests: 1306/1306 IT+UT total green (73s). No new ITs in this commit — the saved-slot render touch was an extension of existingsaved_by_positionview context shape (covered by existing slot-render tests' implicit invariance); the JS change is hard to test via Django ITs (would need Jasmine spec or FT, deferred); the deck-stack collapse is a template branch (visual; user verified live in browser this session). Tomorrow: A.8 room.html image-rendering (multi-user surface via Channels WebSocket payload + same template branch pattern; keep dual gravity/levity stacks per user spec)
Disco DeDisco
2026-05-25 02:16:53 -04:00 -
dd99364b78
A.6 + A.7 billboard My Sign applet + gameboard My Sea applet image-rendering + applet-level FLIP-to-back — TDD. Sprints A.6 + A.7 of [[project-image-based-deck-face-rendering]]: rolls image-mode out to the two card-rendering applets (My Sign on /billboard/, My Sea on /gameboard/). Both reuse the shared
.sig-stage-card.sig-stage-card--imageSCSS contract via a comma-list selector extension covering the parallel container classes (.my-sign-applet-card.my-sign-applet-card--image+.my-sea-slot.my-sea-slot--image) — single source of truth for the contour-stroke drop-shadow chain + tray-card silhouette black depth shadow + .is-flipped-to-back visibility toggle + the--img-stroke-colorarcana-keyed CSS prop. Templates branch server-side oncard.deck_variant.has_card_images: image-mode renders<img class="sig-stage-card-img" src="{{ card.image_url }}">w. the marker class +data-arcana-keyattr; text mode keeps the existing fan-card-corner + fan-card-face scaffold unchanged. SCSS import-order quirk:_card-deck.scssimports BEFORE both_billboard.scss(which nests.my-sign-applet-cardinside.my-sign-applet-bodyfor container queries) and_gameboard.scss(which nests.my-sea-slot--filled.--gravity/--levityinside#id_applet_my_seaw. specificity 1,2,0). The shared top-level image-mode rule at 0,2,0 loses on bg/border/padding to those nested base rules, so each app's stylesheet gets a parallel&.--image { background: transparent; border: 0; padding: 0 }override inside its own nest. The filter-chain rules on.sig-stage-card-img(descendant selector inside the shared rule) DO win since the apps don't restyle that class — only the outer container needs the parallel override. Sprint A.6 bonus: applet-level FLIP btn for non-polarized image-equipped decks (Minchiate today). Mirrors the my_sign.html main page A.5-polish-2 FLIP-to-back contract —.my-sign-applet-flip-btnnested inside the .--image card so absolute positioning anchors to the card bounds; inline<script>IIFE (gated inside the sig-present {% with card %} scope to keepcardin lexical reach + prevent the JS selector string leaking into the no-sig DOM whereassertNotContains "my-sign-applet-card"ITs catch it) attaches a click handler that runs the same rotateY 0→90→0 animation, toggles.is-flipped-to-backat the halfway point, and clearsdata-flippingat end; SCSS.my-sign-applet-card[data-flipping] .my-sign-applet-flip-btn { opacity: 0; pointer-events: none }hides the btn mid-spin. Critical scope bug caught + fixed during browser verify: initial draft had the script BLOCK + its{% if card.deck_variant.has_card_images %}gate placed AFTER the{% endwith %}closing tag —cardwas out of scope at the{% if %}evaluation, Django treats undefined vars as empty string, the gate evaluated falsy, and the script NEVER rendered (the FLIP btn rendered fine since it was inside the with block, but no JS handler → click did nothing but the CSS depress animation). Fix: move{% endwith %}to AFTER the script gate socardis still in scope. 7 new ITs total: 2 inBillboardAppletMySignTest(image-equipped Minchiate renders--imageclass + img + correct asset URL + lacks text scaffold; Earthman keeps the text scaffold + lacks--image); 3 inBillboardMySignViewTest(data-deck-polarized attr present; back-img element renders for non-polarized image deck; polarized deck omits it); 1 inGameboardViewTest(image-equipped Minchiate slot renders--image+ img + lacks text scaffold); plus regression coverage on the no-sig empty-state assertion that originally caught the script-scope bug (assertNotContains validates the script doesn't leak in the no-sig case). Tests: 6 new ITs green; 1306/1306 IT+UT total green (72s; +6 from bdf6a25's 1303 — minus 3 dups since some ITs were counted across both A.6 + A.5-polish-2 runs). Visual verify by user 2026-05-25 PM: stage card image renders cleanly; FLIP cycles to back image + back via animation; FLIP btn hides during 500ms spin; placeholder dim styling correctly distinguishes no-deck state
Disco DeDisco
2026-05-25 01:58:36 -04:00 -
bdf6a251f4
A.5-polish-2 FLIP-to-back bug fixes — TDD. Two user-reported bugs from the first FLIP-to-back commit (
1963ad4): (1) FLIPping made the entire card disappear instead of showing the back; (2) the FLIP btn stayed visible during the animation when it should hide just like the tarot-fan view's flip btn does. Root cause of (1): the back-image element was rendered with inlinestyle="display:none"in the template. Inline styles beat CSS class rules in the cascade — my.sig-stage-card.is-flipped-to-back .sig-stage-card-back-img { display: block }rule was the right specificity but couldn't override an inlinestyleattribute. So the toggle hid the front (CSS-controlled, no inline override) but failed to show the back (CSS blocked by inline). Net: empty stage. Fix: removed the inline style on the back-img element; default.sig-stage-card-back-img { display: none }rule (already present in SCSS) handles the hidden default, and the.is-flipped-to-backtoggle now flips visibility cleanly. Both rules are pure-CSS so they cascade as expected. Root cause of (2): the non-polarized FLIP handler was a bare class toggle (no animation, nodata-flippingattr), so there was no SCSS hook to hide the btn. Plus there was no equivalent SCSS rule even for the polarized_flipPolarityAnimatedflow which DID setdata-flipping— the polarized flip just animated without hiding the btn either. Fix: (a) added_flipToBackAnimated()JS function mirroring_flipPolarityAnimated's shape — rotateY 0→90→0 at 500ms ease, swap visual content at the halfway point (here: class toggle instead of revInput/polarity flip), setstageCard.dataset.flipping = '1'for the duration so SCSS has a hook. (b) New SCSS rule.my-sign-stage:has(.sig-stage-card[data-flipping]) .my-sign-flip-btn { opacity: 0; pointer-events: none }mirrors the tarot-fan view's pattern (_card-deck.scss:459—.tarot-fan-wrap:has(.fan-card[data-flipping]) .fan-flip-btn). The :has() selector covers BOTH the polarized animation (which already sets data-flipping) AND the new non-polarized animation, so the btn hide-during-flip behavior now lands consistently across both flip modes — fixes a latent polished-flow gap not just the new code path. No new tests — the existing 3 ITs from1963ad4already verify the template/scaffold contract (data-deck-polarized attr + back-img element conditional render); the bug fixes here are CSS/JS-level behavior best caught by visual verify (no automated test would have caught the inline-style cascade issue since the IT asserted on element presence, not display state). 1303/1303 IT+UT total green (71s, unchanged from1963ad4since no new tests in this commit)
Disco DeDisco
2026-05-25 01:35:47 -04:00 -
1963ad4c71
A.5-polish FLIP-to-back for non-polarized image-equipped decks — TDD. User-spec'd feature 2026-05-25 PM after browser-verifying A.5: the FLIP button on my_sign.html cycles polarity for polarized decks (Earthman) — gravity/levity swap w. a 3D-spin animation, stat block updates to the new polarity's emanation/reversal qualifiers. For non-polarized decks (Minchiate today, future RWS-with-images, future classic-playing decks), polarity has no meaning — clicking FLIP just runs an animation that doesn't change anything content-wise. User wants FLIP repurposed for non-polarized decks: reveal the card-back image while leaving the stat block untouched, so the gesture has visible payoff w/o forcing a meaningless polarity-state change. Implementation thread: server-side page wrapper carries a new
data-deck-polarized="{{ user.equipped_deck.is_polarized|yesno:'true,false' }}"attr so the in-page JS can branch on it without making an API call or guessing from card data; stage-card scaffold conditionally renders a hidden<img.sig-stage-card-back-img>element whenequipped_deck.has_card_images AND NOT is_polarized(image-equipped polarized decks would still cycle polarity per existing flow — back-image element absent for them, no resource waste). JS branch inflipBtn.click:if (pageEl.dataset.deckPolarized === 'false') { stageCard.classList.toggle('is-flipped-to-back') } else { _flipPolarityAnimated() }— same.is-reversedclass toggle on the btn itself so visual feedback is consistent across both modes (btn rotates to signal "flipped state on"). SCSS:.sig-stage-card-back-imgjoins the existing.sig-stage-card-imgfilter chain (same contour stroke + silhouette black shadow — back image gets identical visual treatment to the front so the flip reads as same-deck consistency); defaultdisplay: none;.sig-stage-card.is-flipped-to-backflips visibility — hides front, shows back. Stat block + arcana-key stroke color stay put per user spec — FLIP for non-polarized is purely a visual reveal, no polarity-cycle or content swap. 3 new ITs inMySignViewTest: data-deck-polarized="true" for default Earthman; data-deck-polarized="false" + back-img element present w. correct v2-convention back asset URL when user switches to Minchiate; polarized deck omits the back-img element. No JS unit test (Jasmine spec) for the flipBtn branch — visual verify covers the hover/click interaction; the IT covers the server-side conditional render that determines whether the branch can fire. No FT (the existing my_sign FTs cover the polarized-flip flow already; non-polarized-flip is a CSS class toggle, low-risk for regression). Tests: 3 new green; 9/9 MySignViewTest class green; 1303/1303 IT+UT total green (71s; +3 from 82813e9's 1300). Out of scope: my_sea's central sig card doesn't have a FLIP btn (no analogous behavior to add there); room.html FLIP behavior will be covered in A.8 if applicable; Sea Stage modal FLIP behavior (if any) lands in the my-sea fetch-endpoint extension later in A.5
Disco DeDisco
2026-05-25 01:31:42 -04:00 -
82813e9fc1
A.5 my_sea.html central sig card image-rendering + SCSS lift-out fix — TDD. Sprint A.5 of [[project-image-based-deck-face-rendering]]: second visible surface after my_sign A.3. When the user's equipped deck is image-equipped (Minchiate today), the central significator card in the Celtic-Cross-style spread (
.sig-stage-card.sea-sig-cardinside .sea-pos-core) renders the transparent-PNG <img> w. contour-following arcana-color drop-shadow stroke + tray-card silhouette black shadow — same visual identity as my_sign's saved-sig stage card so the user's "this is my sig" anchor reads the same across both surfaces. Server-side template branch onsignificator.deck_variant.has_card_images: image branch renders<img class="sig-stage-card-img" src="{{ significator.image_url }}">+ adds.sig-stage-card--imagemarker class +data-arcana-key="{{ arcana }}"for the stroke-color selector; text branch keeps the existing corner-rank + suit-icon render unchanged (Earthman, RWS). No JS needed — central sig is statically rendered (vs my_sign's stage card which is JS-populated from the picker grid). Critical SCSS lift-out: the A.3.sig-stage-card--imagerule lived nested inside.sig-stage .sig-stage-card, scoped to my_sign.html's stage container only. my_sea's central sig isn't inside.sig-stage(lives in .sea-pos-core), so the rule wasn't applying — image rendered at native pixel dimensions (~620×1024 PNG) instead of being constrained to the card container, showing only a top-left portion (user bug-report 2026-05-25 PM: "It doesn't scale the img down for the sig — just a portion of the full img"). Fix: moved the entire.sig-stage-card.sig-stage-card--image { ... }block OUT of the.sig-stagenest into top-level scope so it applies to ANY.sig-stage-cardcarrying the--imageclass regardless of parent (my_sign's.sig-stage, my_sea's.sea-pos-core, future room.html's table center, future deck-bag UI). Same lift-out also expands thedisplay: nonelist to include.fan-corner-rank+> i.fa-solid— these elements appear in my_sea's text-mode central sig and need hiding when image-mode kicks in (my_sign's text mode uses the wrapped.fan-card-corner+.fan-card-faceclasses which were already covered). 2 new ITs inMySeaPickerPhaseTemplateTest: image-equipped Minchiate sig renders.sig-stage-card--imageclass + <img> w. correct v2-convention src; non-image Earthman keeps.fan-corner-ranktext + lacks --image class. Earthman Minchiate test fixture needs the super-nomad + super-schizo Note unlocks (granted manually viaNote.grant_if_newsince the post_save signal only fires on initial user creation, and we promote-to-superuser AFTER create) to let Il Matto (MAJOR 0) through_filter_major_unlocks. Tests: 2 new green; 1300/1300 IT+UT total green (70s; +2 from 750fef8's 1298). Visual verify pending: refresh /gameboard/my-sea/ w. Minchiate equipped + Il Matto as sig → central sig card should now scale the back image to fit the card container instead of showing a top-left crop. Sea Stage modal + drawn-card slot rendering (the bigger A.5 scope) still pending — they go through stage-card.js + the my-sea draw fetch endpoint, which need data-attr + JSON-payload extensions in a follow-up commit
Disco DeDisco
2026-05-25 01:20:07 -04:00 -
750fef890e
A.4 cont.: card-deck icon placeholder mode (no-deck-equipped) styled like empty dice slot — TDD. User polish 2026-05-25 PM after browser-verifying the kit-bag dialog: when no deck is equipped (kit-bag-placeholder branch fires) the new card-stack icon should not animate + should render w. the same dimmed
rgba(--quaUser, 0.x)palette as the existing fa-dice empty slot next to it, not the bright --terUser stroke / --priUser fill of an equipped-deck icon. Two SCSS changes: (1) Removed.deck-stack-icon:hover+.deck-stack-icon:activefrom the splay-trigger selector list — only wrapper-based selectors (.token.deck-variant, .kit-bag-deck) fire the fan-out now. Placeholder icons land inside .kit-bag-placeholder (or game_kit applet's .kit-item empty-state) which aren't in the trigger list, so they stay static no matter where the user hovers. (2) New.kit-bag-placeholder .deck-stack-icon+.kit-item .deck-stack-icondescendant-selector rule: drops color (= stroke via currentColor) torgba(--quaUser, 0.3)matching the existing .kit-bag-placeholder color (_game-kit.scss:143); drops .deck-stack-icon__card fill torgba(--quaUser, 0.15)(lower than the stroke alpha — user-dialed 2026-05-25 PM for a subtler look, the cards read as faintly-present "absence" rather than bright-but-grey). 1 new IT inKitBagViewTest(clears equipped_deck → asserts .kit-bag-deck absent, .kit-bag-placeholder present + carries svg.deck-stack-icon + lacks fa-id-badge). Tests: 1 new green; 1298/1298 IT+UT total green (71s; +1 from d26c45b's 1297). Visual verify pending: refresh /gameboard/ + clear equipped deck → kit-bag dialog Deck slot should show a dimmed static card-stack icon matching the dice slot's washed-out look
Disco DeDisco
2026-05-25 01:07:24 -04:00 -
d26c45bf77
A.4 cont.: deck back-image renders inside card-stack icon + kit-bag dialog Deck section adopts the icon + size+pattern polish — TDD. Three follow-up improvements after user browser-verified A.4's first cut: (1) image-equipped decks (Minchiate today, future Earthman) now render the deck's actual <deck-slug>-back.png as the card-stack icon's visible faces instead of the placeholder --priUser solid fill — feels like a real deck, not a generic stand-in. (2) The kit-bag dialog Deck section (
#id_kit_bag_dialog .kit-bag-deck) gets the same new card-stack icon (was still showing the old fa-regular fa-id-badge), with(×2)tooltip decoration on polarized decks for consistency w. the gameboard applet. (3) Visual polish: icon bumped 1.5× (1.5rem → 2.25rem width; 2.4rem → 3.6rem height, 5:8 aspect preserved); SVG <pattern> switched frompatternUnits=userSpaceOnUse(which painted the image at fixed user-space coordinates and let the rect slide out from under it on hover, reading as "low opacity" to the user) topatternUnits=objectBoundingBox + patternContentUnits=objectBoundingBox(transform-aware — image tracks the rect through rest-state offsets + hover fan-out). NewDeckVariant.back_image_urlproperty mirrors A.2'sTarotCard.image_urlpattern: returns full static-asset URL for<deck-slug>-back.pngwhen has_card_images=True, else empty string. Template partial_deck_stack_icon.htmlextended w. conditional<defs><pattern>block that renders only whendeck.has_card_imagesis true; each of the 3 card rects then carries an inlinestyle="fill: url(#deck-back-<short_key>)"overriding the SCSS defaultfill: rgba(--priUser, 1)(inline style beats CSS, the only way to opt out of the cascade default per-element). When no deck is passed (kit-bag placeholder branch) or deck has no images (Earthman + RWS), the partial falls through to the placeholder fill — single template handles both modes._kit_bag_panel.htmlDeck section: equipped-deck branch swaps<i class="fa-regular fa-id-badge">for{% include _deck_stack_icon.html with deck=equipped_deck %}+ adds(×2)span in --terUser forequipped_deck.is_polarized; placeholder branch swaps for the same include withoutdeck=so the partial's conditional falls through. SCSS reorg: lifted the.deck-stack-iconbase rules out of the#id_applet_game_kitnest (they were scoped to gameboard's Game Kit applet only) into top-level scope so the same SCSS applies in the kit-bag dialog context too. Hover/active/focus trigger selector list broadened to cover.deck-stack-iconitself +.token.deck-variantwrapper +.kit-bag-deckwrapper. 4 new ITs total: 2 inGameboardViewTest(image-equipped Minchiate's <pattern> defines + inline fill style on all 3 rects + asset URL ref; non-image Earthman has NEITHER pattern nor inline fill); 2 indashboard.KitBagViewTest(kit-bag Deck section renders svg.deck-stack-icon + lacks fa-id-badge; polarized equipped deck tooltip carries .tt-x2 — element-presence assertion since literal "×2" character had encoding issues in the dashboard test file vs the gameboard one, which is fine since the template-side rendering of the literal × is exercised by the parent template). Tests: 4 new green; 1297/1297 IT+UT total green (69s; +4 from A.4's 1293). Visual verify pending: refresh /gameboard/ → Minchiate icon should show 3 stacked Minchiate card-backs at 1.5× size, fan out on hover w. back image tracking; refresh kit-bag dialog → same icon visible in Deck section w. (×2) on Earthman tooltip
Disco DeDisco
2026-05-25 01:01:05 -04:00 -
b9bb73db69
A.4 card-deck stack icon + game_kit applet's Card Decks polarization (×2) tooltip decoration — TDD. Sprint A.4 of [[project-image-based-deck-face-rendering]] (folded down from the originally-standalone Sprint D per [[project-card-deck-icon]] 2026-05-25 PM scope-fold). Replaces the
<i class="fa-regular fa-id-badge">placeholder on.token.deck-variantin the gameboard's Game Kit applet w. a new inline SVG card-stack icon: 3 rect children (rx=2.5, 20×32 viewport units inside a 32×48 viewBox to land 5:8 tarot card aspect), stacked tightly at rest w. ±0.4px vertical micro-offsets (suggests stack depth without separating cards visually), whole stack rotated 5° clockwise via.deck-stack-icon__stackgroup transform. On:hover/:active/:focusof the parent.token.deck-variant, cards 2 + 3 fan out symmetrically — card 2 translates (-5px, -2px) + rotates -12°, card 3 translates (+5px, -2px) + rotates +12° — card 1 stays put on top. Fan-out CSS pseudo-classes match the existing JS-portal tooltip trigger so the splay animation + tooltip-appearance co-activate as user spec'd. Placeholder card-back design: solid--priUserfill +currentColorstroke (=--terUser); detailed Earthman planet-impact illustration deferred to a future art-asset commit (the SVG structure is ready to receive richer fills + pattern elements without re-jigging the stack/fan transforms). Drop-shadow for "lifted off the felt" depth cue:0.08rem 0.08rem 0.15rem rgba(0, 0, 0, 0.6)— softer than the my-sign-stage card's tray-card-style 1,1 black silhouette since the icon is small + always on a felt background. SVG itself usesoverflow: visibleso the fan-out exceeds the viewBox bounds;transform-box: fill-box+transform-origin: 50% 50%ensure rotation centers on each card's own geometric center (not the viewBox center). New_deck_stack_icon.htmlpartial intemplates/apps/gameboard/_partials/keeps the SVG markup DRY for the future room.html pile + deck-bag rollouts (per [[project-card-deck-icon]] "other surfaces deferred to later sprints"). New.tt-x2style in%tt-token-fieldsplaceholder mixin —--terUsercolor + font-weight 600 — appended inline in.tt-descriptionforis_polarized=Truedecks (Earthman today): "106-card Tarot deck (×2)" where the (×2) signals "double-polarized = 6 segments = fills 2× as many seats" per [[project-card-deck-icon]]'s decoration rule. Non-polarized decks (Tarot RWS, future Minchiate) render the description without the suffix. 3 new ITs inGameboardViewTest: SVG card-stack renders w. 3 rect children + fa-id-badge gone; polarized Earthman tooltip carries.tt-x2w. "×2" content; non-polarized RWS tooltip lacks.tt-x2. Out of scope this commit: the dedicated /game-kit/ page's.gk-deck-cardrectangles (different template —_game_kit_sections.html) keep their fa-id-badge for now; folding them into the new icon happens in a follow-up "Card Decks rectangle teardown" sprint per user spec ("by the time we finish A.8 the dynamically shaped rectangles around the deck <i> els and their names will be no more"). Tests: 3 new ITs green; 27/27 GameboardViewTest class green; 1293/1293 IT+UT total green (68s; +3 from A.3-polish's 1290). Visual verify pending: browser refresh expected to show the stacked-3-card icon w. 5° rest tilt, fan-out on hover, tooltip + (×2) decoration on Earthman
Disco DeDisco
2026-05-25 00:40:10 -04:00 -
436a710478
A.3-polish-2: thicker contour stroke (0.2rem each cardinal) + tray-card down-right black silhouette drop-shadow. User visual polish after browser-verifying A.3+A.3-polish: stroke thickness bumped from 1.5px → 0.2rem (~3.2px) per cardinal, giving ~6.4px combined apparent stroke (~2× prior); user-confirmed thickness is comfortable in palette-baltimore at the current sig-card-w. Bonus: appended the same silhouette black drop-shadow that
.tray-cell > imgcarries (_tray.scss:272,drop-shadow(1px 1px 2px rgba(0,0,0,1))) to the sig-stage-card image filter chain as a "lifted off the felt" depth cue — consistent w. the rest of the project's image-card treatment. Ordering matters in the filter chain: silhouette black comes AFTER the 4 stroke drop-shadows so it traces the STROKED contour, not just the original PNG alpha (otherwise the depth shadow would land underneath the orange-or-mustard stroke, partially occluded). 4-cardinal stroke is still adequate at 0.2rem; flagged in comment to bump to 8-direction (cardinals + diagonals) if we ever push past ~0.5rem since curved edges would otherwise show uneven thickness at gap-prone diagonals. Pure SCSS — no model/template/JS/test changes. Visual-only polish atop 50a12bc's A.3-polish
Disco DeDisco
2026-05-25 00:28:09 -04:00 -
50a12bccab
A.3-polish: cross-deck sig picker (MINOR + MIDDLE courts) + My Sea applet sig-decoupling — TDD. Two user-reported bugs caught during A.3 visual verify (2026-05-25 PM). Bug 1: my_sign picker shows only 2 cards (Major 0 + 1) for Minchiate-equipped users since
_sig_unique_cards_for_deckfilters byarcana=MIDDLEwhich Minchiate (and any non-Earthman tarot family) doesn't classify its courts as — Minchiate courts are MINOR per its standard structure. User spec confirmed: my_sign picker = courts + Major 0/1 for EVERY deck (NOT segment-limited, NOT arcana-classification-limited). Fix: broaden the filter toarcana__in=[MIDDLE, MINOR]so courts qualify regardless of how the deck classifies them. For Earthman, behavior unchanged (no MINOR 11-14 cards exist in seed — its courts are exclusively MIDDLE); for Minchiate + RWS, picker expands from 2 → 18 cards as designed. Two side-by-side suit queries (brands_crowns + blades_grails) collapse to a single 4-suit query since the union was already covering all 4 — that was historical artifact, not segment-limiting in effect. Bug 2: deleting the user's sig on /billboard/my-sign/ blanks the My Sea applet on /gameboard/ even though the saved MySeaDraw spread is still in the DB (visible on /billboard/my-sea/), reappearing only when any sig is re-selected. Root cause:_applet-my-sea.htmlgated the slot-render branch on{% if not request.user.significator_id %}first, treating no-sig as "no draws yet" regardless of actual draw state. But MySeaDraw rows carry their ownsignificator_idsnapshot at first-draw time (gameboard.models.MySeaDrawdoc lines 130-132) precisely so user-sig clearing doesn't invalidate saved draws — the template ignored that contract. Fix: invert the template branches — slot render now keys solely onmy_sea_slots; the sig-gate Brief banner only fires in the empty-state branch when ALSOnot request.user.significator_id(the "fresh user, no draws, no sig" case). MySeaDraw display now correctly decoupled from current sig state — sig deletion only matters for users who haven't drawn yet. Companion code:_sig_unique_cards_for_deckdocstring updated to articulate the cross-deck symmetry rule ("courts recognized by rank 11-14 regardless of arcana classification") + the spec-confirmed non-segment-limitation. 1 new regression IT inGameboardViewTest.test_my_sea_applet_renders_slots_even_when_user_significator_clearedlocks Bug 2's fix: creates a MySeaDraw row w. one filled slot, then sets User.significator=None, GETs /gameboard/, asserts the filled slot still renders + "No draws yet" empty state is absent. Tests: 1 new IT green; 810/810 epic+gameboard+billboard ITs green; 1290/1290 IT+UT total green (70s, +1 from A.3's 1289). No FT changes needed — Bug 1's fix changes the count of cards in the picker grid; existing FTs that count cards target Earthman where the count is unchanged. Visual verify still pending; user will confirm both fixes via Claudezilla browser session
Disco DeDisco
2026-05-25 00:16:55 -04:00 -
5e78e6b832
A.3 my_sign.html image-rendering — first visible surface — TDD. Sprint A.3 of [[project-image-based-deck-face-rendering]]. When the user's equipped deck has
has_card_images=True(Minchiate Fiorentine 1860-1890 today), the saved-sig stage card on /billboard/my-sign/ renders as an <img> over the irregular-shape transparent PNG with a contour-following arcana-colored stroke — not the text fan-card scaffold. First of 6 surfaces in the image-rendering rollout (my_sea + both billboard applets + room + game_kit follow in A.5+). NewTarotCard.image_urlproperty (consumes A.2's image_filename + DeckVariant.has_card_images + django.templatetags.static.static() to produce a full static-asset URL) — empty string when has_card_images=False so legacy text-only decks (Earthman, RWS) pass through transparently.my_sign.htmlpicker grid.sig-cardelements gaindata-image-url+data-arcana-keyattrs (the latter for stroke-color CSS selection); the.sig-stage-cardscaffold gains a hidden<img class="sig-stage-card-img">slot that JS swaps visible when image-mode is active.stage-card.jsextendsfromDatasetto read image_url + arcana_key; new_setImageMode(stageCard, card)toggles the.sig-stage-card--imagemarker class + setsdata-arcana-keyon the stage card + populates the img src/alt; called frompopulateCardso all existing sig-stage flows pick up image rendering automatically (text-mode decks still pass through since image_url is empty). SCSS: new.sig-stage-card.sig-stage-card--imagerule hides the.fan-card-corner+.fan-card-facetext scaffold, strips the rectangular border/padding, and applies a 4-cardinal-directionfilter: drop-shadow()stack to the<img>so the stroke FOLLOWS the alpha contour of the PNG instead of tracing a rectangular bounding box (per user spec 2026-05-25 PM clarification — early draft used a rectangular border which doesn't match the irregular-card aesthetic). Stroke color is driven by a CSS custom prop--img-stroke-colordefaulting torgba(var(--quiUser), 1)(cream — minor + middle arcana);[data-arcana-key="MAJOR"]override flips it torgba(var(--terUser), 1)(gold) per Q2 lock. mobile-safe — filter on raster images works cross-browser (the [[feedback-mobile-svg-glow]] dead-end was specifically SVG glow, not raster drop-shadows). New_seed_minchiate_image_fixtures()helper infunctional_tests/sig_page.pyre-seeds the minimal Minchiate fixture (DeckVariant + Il Matto + Papa Uno) needed for image FTs after TransactionTestCase's flush wipes migration data — mirrors the existing_seed_earthman_sig_pilepattern per [[feedback-transactiontestcase-flush]]. NewMySignImageRenderingTest.test_saved_sig_renders_as_img_for_image_deckFT seeds Minchiate + creates a superuser test gamer (superuser auto-gets super-nomad + super-schizo Notes via the User post_save signal, which_filter_major_unlocksthen lets through to expose Il Matto in the picker grid — otherwise Minchiate's sig pool is empty since it has no MIDDLE arcana cards), equips Minchiate, saves Il Matto as sig, visits /billboard/my-sign/, asserts the stage card displays + contains an <img> w. src ending in the v2-convention filenameminchiate-fiorentine-1860-1890-trumps-00-il-matto.png+ carries.sig-stage-card--imagemarker class. Out of scope for this commit (deferred to A.3 follow-up polish + A.5+): the full stat-block restructure (top-left rank+suit chip Q♥ inline w. EMANATION/REVERSAL header; title in arcana-color font; keyword reposition; FYI panel re-anchor — per the locked Q3 spec) — image card-face ships now w. the existing stat-block layout to land the visible-win first. Tests: 1 new FT green; 15/15 my_sign FT class green (no regression on the 14 existing tests); 1289/1289 IT+UT total green (68s, unchanged from A.2 since no new ITs in this commit — FT covers the wiring end-to-end). Sprint A backend foundation (A.0+A.1+A.2) + first visible surface (A.3) all landed; 5 surfaces remain (A.5-A.8 + A.4's card-deck icon)
Disco DeDisco
2026-05-25 00:04:18 -04:00 -
91df482dd8
A.2 TarotCard.image_filename + display_suit_name properties — TDD. Sprint A.2 of [[project-image-based-deck-face-rendering]]. Adds two per-card derived properties that consume the new
DeckVariant.familyfield (locked in A.0) to translate canonical-Earthman SUIT enum (BRANDS/CROWNS/GRAILS/BLADES) into family-authentic filename slugs + UI labels per [[reference-card-image-naming-convention]] v2.DeckVariantgains the family-mapping tables + methods (suit_slug/suit_display/trump_category);TarotCardconsumes them viaimage_filename+display_suit_name. Two mapping tables live on DeckVariant (single source of truth for per-family vocab):_SUIT_SLUG_BY_FAMILY(4 families × 4 suits = 16 entries: earthman is identity-mapped {BRANDS→brands, CROWNS→crowns, GRAILS→grails, BLADES→blades}; italian is {BRANDS→batons, CROWNS→coins, GRAILS→cups, BLADES→swords}; english is {BRANDS→wands, CROWNS→pentacles, GRAILS→cups, BLADES→swords}; playing is {BRANDS→clubs, CROWNS→diamonds, GRAILS→hearts, BLADES→spades}) and_TRUMP_CATEGORY_BY_FAMILY(earthman+italian use "trumps", english uses "majors" matching Modern Tarot's "Major Arcana", playing is None since 52-card decks have no trump category — jokers handled separately when a playing deck is seeded).DeckVariant.suit_slug(canonical)returns the filename slug;suit_display(canonical)returns capitalized UI label (via slug.capitalize());trump_categoryis a property since it takes no per-card argument.TarotCard.image_filenamebranches on arcana: MAJOR returns<deck-slug>-<trump-category>-<NN>-<card-slug>.png(NN = zero-padded number per v2 convention, e.g. 00 for Il Matto; card-slug carries the italian name like "il-gobbo" or english like "the-fool"); MINOR/MIDDLE returns<deck-slug>-<suit-slug>-<NN>[-<court>].pngwhere court suffix is "page"/"knight"/"queen"/"king" for ranks 11-14 (tarot family courts; playing-family's 3-court jack/queen/king deferred to playing-deck-seed sprint).display_suit_namereturns capitalized family-authentic suit name ("Batons" for italian BRANDS, "Pentacles" for english CROWNS) or empty string for major arcana (no suit). Both properties are pure-derived — no schema migration needed, no DB writes; the template (Sprint A.3+) decides whether to render <img src=image_filename> based ondeck.has_card_images. RWS deck's image_filename returns a path even though has_card_images=False (path is correct per convention; just no file exists at that path yet — once RWS images are sourced, flip the flag). 17 new ITs inCardImageFilenameA2Testcover: Minchiate trumps (Il Matto rank-00, Il Gobbo rank-11, Le Trombe rank-40, L'Acqua rank-21 w. apostrophe-restored slug); Minchiate minors (Ace of Batons pip-with-no-court-suffix, Ten of Coins, Page of Cups w. court suffix, King of Swords); RWS post-revocab (Ace of Cups uses english-family "cups" slug despite suit=GRAILS, The Fool uses "majors" category, King of Pentacles uses "pentacles" slug despite suit=CROWNS); Earthman identity-mapped (BRANDS→brands); display_suit_name across all 3 tarot families (italian BRANDS→"Batons", italian CROWNS→"Coins", english CROWNS→"Pentacles", earthman BRANDS→"Brands"); empty for majors. Tests: 17 new green; 1289/1289 IT+UT total green (63s; +17 from A.1's 1272). Out of scope: A.3 wires my_sign.html's first render branch (the visible-win first surface); A.4 builds card-deck icon + game_kit applet; A.5-A.8 DRY across my_sea + both billboard applets + room
Disco DeDisco
2026-05-24 23:37:16 -04:00 -
a4ac25605d
A.1 seed Minchiate Fiorentine 1860-1890 deck (97 cards) — TDD. Sprint A.1 follow-up to [[project-image-based-deck-face-rendering]]. Creates the actual Minchiate Fiorentine
DeckVariant(separate from the renamed-from-fiorentine-minchiate RWS Tarot now living attarot-rider-waite-smithper A.0). Slugminchiate-fiorentine-1860-1890matches the asset dir committed in0add163(98 PNGs atsrc/apps/epic/static/apps/epic/images/cards-faces/minchiate-fiorentine-1860-1890/); Sprint A.2'simage_filenameproperty will usedeck.slugto point at those images. Schema fields set:family='italian'(drives display + filename slug mapping per [[reference-card-image-naming-convention]] — BRANDS→batons, CROWNS→coins, GRAILS→cups, BLADES→swords),has_card_images=True(first deck w. images shipped),is_polarized=False(Earthman remains the only polarized deck),is_default=False(Earthman is default),card_count=97. 97 TarotCard rows seeded: 41 trumps (Il Matto at rank 0 per the unnumbered-Fool-gets-sortable-position convention from [[reference-card-image-naming-convention]]; then 40 numbered 1-40) + 56 minors (4 suits × 14 cards = pip 1-10 + page=11 + knight=12 + queen=13 + king=14 per the v2 convention's number-prefixed-courts decision). Trump names are Italian (Papa Uno / Papa Due / La Temperanza / La Forza / La Giustizia / La Ruota della Fortuna / Il Carro / Il Gobbo / L'Impiccato / La Morte / Il Diavolo / La Casa del Diavolo / La Speranza / La Prudenza / La Fede / La Carita / Il Fuoco / L'Acqua / La Terra / L'Aria + 12 zodiac signs + La Stella / La Luna / Il Sole / Il Mondo / Le Trombe). Card-suit canonical enum stays BRANDS/CROWNS/GRAILS/BLADES per A.0's lock; minor card NAMES use Italian-family display vocab ("Page of Batons" not "Page of Brands") since names are the user-facing label whereas suit is the structural identity. 16 trumps carry acorrespondencefield pointing to their RWS Tarot equivalent (Il Matto→The Fool, Il Carro→The Chariot, Il Gobbo→The Hermit, L'Impiccato→The Hanged Man, La Morte→Death, Il Diavolo→The Devil, La Casa del Diavolo→The Tower, La Temperanza→Temperance, La Forza→Strength, La Giustizia→Justice, La Ruota della Fortuna→Wheel of Fortune, La Stella→The Star, La Luna→The Moon, Il Sole→The Sun, Il Mondo→The World, Le Trombe→Judgement); the 25 Minchiate-only trumps (5 popes + 4 theological/cardinal virtues + 4 elements + 12 zodiac) have no RWS parallel → empty correspondence.keywords_upright/keywords_reversedintentionally left empty[]: those are interpretive content the user owns; admin form (Sprint B) will enrich via UI rather than have them committed as code in a migration. Five trumps in the v2 filename convention have elided-apostrophe slugs restored (l-impiccato, l-acqua, l-aria, l-ariete, l-acquario); DB slug field matches (no apostrophe, but with the leadingl-prefix). 17 new ITs inMinchiateFiorentine1860SeedTestcover the deck attributes (name + family + has_card_images + is_polarized + card_count) + total row count (97) + arcana breakdown (41 trumps + 56 minors + 0 middle) + specific cards (Il Matto at rank 0 + Il Gobbo at rank 11 w. correspondence "The Hermit" + Le Trombe at rank 40 + 5 popes are MAJOR ranks 1-5 + Page of Batons + King of Coins) + canonical-suit-only check (no WANDS/CUPS/SWORDS/PENTACLES in DB) + court rank range (11-14 per suit). Tests: 17 new green; 1272/1272 IT+UT total green (64s; +17 from A.0's 1255). Out of scope: A.2 adds theTarotCard.image_filename+display_suit_nameproperties consumingdeck.familyfor per-family translation; A.3 wires my_sign.html's first render branch
Disco DeDisco
2026-05-24 23:32:19 -04:00 -
f107522b20
A.0 image-rendering schema + RWS rename + canonical-Earthman suit collapse — TDD. Sprint A.0 of [[project-image-based-deck-face-rendering]]. Adds three
DeckVariantfields:has_card_images(BooleanField default=True — Earthman keeps False until its artwork ships, every new deck defaults True),family(CharField choices=[earthman, italian, english, playing] default=earthman — drives per-family display + filename slug mapping per [[reference-card-image-naming-convention]]),is_polarized(BooleanField default=False — Earthman is True today; Sprint A.4 game_kit applet will render "(×2)" in --terUser for polarized decks; Sprint C+B segment model uses it for segment-count logic).TarotCard.SUIT_CHOICEScollapses from 8 values to 4 canonical Earthman values (BRANDS / CROWNS / GRAILS / BLADES); WANDS / CUPS / SWORDS / PENTACLES dropped — they were duplicative at the structural level sincesig_deck_cards+levity/gravity_sig_cardsalready treated [WANDS, BRANDS, CROWNS] as one segment and [SWORDS, BLADES, CUPS, GRAILS] as another (so the project already *functionally* equated them; the lock just makes that explicit). Per-family display vocab (batonsfor Italian,wandsfor English,clubsfor Playing) lives in Sprint A.2'sdisplay_suit_nameproperty, not in the enum. Audit 2026-05-25 revealed the existingfiorentine-minchiateDeckVariant is actually 78-card RWS Tarot in disguise (22 majors numbered 0-21 w. RWS names: The Fool / The Magician / ... / The World; 56 minors in 4 suits × 14 cards) — NOT Minchiate (which has 40 trumps + 1 Il Matto + 56 minors = 97 cards). Migration 0012 renames the slug →tarot-rider-waite-smith, name → "Tarot (Rider-Waite-Smith)", sets family='english', has_card_images=False, is_polarized=False — and revocabs its 56 minor cards' suits in-place (WANDS→BRANDS, CUPS→GRAILS, SWORDS→BLADES, PENTACLES→CROWNS) so they match the new canonical enum. FKs (User.equipped_deck, User.unlocked_decks, TableSeat.deck_variant, etc.) survive untouched — slug-only changes don't break referential integrity. Earthman fields set explicitly in 0012 too (family=earthman, has_card_images=False, is_polarized=True). Companion code simplifications:sig_deck_cards+_sig_unique_cards_for_deckqueries shrink fromsuit__in=[3 values]and[4 values]to[2 values]each (one per segment);TarotCard.suit_iconmapping shrinks from 8 entries to 4;gameboard.views.tarot_fan._suit_ordershrinks from 8 keys to 4. Existing test files updated:test_game_room_tray.py(largest update —self.fiorentine→self.rws,id_kit_fiorentine_deck→id_kit_tarot_deck(template-id derives from deck.short_key = first slug segment), assertion "Fiorentine" → "Rider-Waite-Smith");test_game_room_deck_contrib.py(same pattern, smaller);lyric/test_models.py+gameboard/test_views.py(slug literal swaps only);epic/test_models.py_make_sig_cardtest fixtures: "WANDS"→"BRANDS", "CUPS"→"GRAILS". 14 new ITs inDeckSchemaA0Testcover the schema additions + migration outcomes (field existence + choice values + earthman has all three fields set correctly + RWS rename verified + RWS cards use canonical suits + dropped enum values absent from SUIT_CHOICES). Tests: 14 new green; 1255/1255 IT+UT total green (38s); no regressions. Out of scope: Sprint A.1 will seed the actual Minchiate Fiorentine 1860-1890 (97-card) DeckVariant + TarotCard rows w. family='italian', has_card_images=True; A.2 adds theimage_filename+display_suit_nameproperties that consume the newfamilyfield; A.3+ wires the render branches across 6 surfaces
Disco DeDisco
2026-05-24 23:25:26 -04:00 -
0add163f5b
feat: import Minchiate Fiorentine 1860-1890 deck assets (98 PNGs, alpha-channel transparent bg) + naming convention v2 + pngquant optimization tooling. Public-domain 1860-1890 lithograph scans sourced from Wikimedia (single download series + trump 11 Il Gobbo individually-sourced from same era series); user removed white backgrounds in Photoshop to leave irregular card-shape with transparent canvas. Filenames v2-conformant per [[reference-card-image-naming-convention]] (revised from v1 of 2026-05-24): deck slug carries
-1860-1890publication-year suffix so future Minchiate Fiorentine variants from different publishers/eras coexist cleanly; courts use rank-number-prefix (batons-11-pagenotbatons-page) for linear sort key; trumps carry both numeric rank AND italian-name suffix (trumps-01-papa-uno,trumps-11-il-gobbo) for forensic identification across variant decks the user plans to sell. Il Matto (unnumbered Fool in Minchiate tradition) assigned rank00to give it a sortable position. Five trump filenames had elided-apostrophe slugs restored from the download source (-lacqua→-l-acquaetc.). Card-back at<deck-slug>-back.pngsorts alphabetically before all suit categories — no separatecard-back/subdir needed. pngquant 2.17.0 installed at C:\Users\adamc\AppData\Local\Programs\pngquant\, added to user PATH (effective next session) for future deck imports; ran with--quality=65-85 --speed=1 --strip --skip-if-largerfor 57.6% size reduction (86.6 MB → 36.7 MB total, 935 KB → 383 KB avg). Second pass at--quality=40-65hit pngquant's floor (only 0.5% further reduction — re-quantizing an already-quantized image has little headroom). Il Gobbo from Wikimedia was a dimensional outlier (1426x2366 vs siblings ~620x1024) — resized via System.Drawing HighQualityBicubic to 620x1029 before optimization. Format32bppArgb alpha channel verified intact across samples after optimization pass. Visually validated by user: cards must fill entire screen before any pixelization visible. Sprint A precursor —DeckVariant.has_card_imagestoggle + image-rendering template branch per [[project-image-based-deck-face-rendering]] follows in subsequent commits, will consume these assets in 6 surfaces (my_sign, my_sea, both billboard applets, room, game_kit). Asset set also unblocks downstream Sprint C+B [[project-deck-segment-model]] (admin form will require image upload + enforce naming convention) and Sprint D [[project-card-deck-icon]] (uses-back.pngas the deck-stack icon's repeating card-face). Future: when Sprint B's admin form ships, wire pngquant into anoptimize_card_imagesmanagement command so admin uploads auto-optimize on save. Gitignore linesrc/apps/epic/static/apps/epic/images/cards-faces/minchiate-fiorentine/dropped — v1 staging dir deleted (was only ever the rename-staging set; superseded by v2-named optimized set). Total disk delta: +36.7 MB binary content. No code changes — pure asset + convention import
Disco DeDisco
2026-05-24 22:39:21 -04:00 -
8a56ebff2c
fix: swap UserAdmin's
unlocked_decks+budsM2M widgets fromSelectMultipletofilter_horizontal(dual-listbox). The defaultSelectMultiplewidget renders ALL DeckVariant/User rows in a single listbox with only the currently-selected ones blue-highlighted — visually indistinguishable from "all of these are unlocked" if the reader doesn't notice the highlight state. This cost a half-hour staging bug investigation: Fiorentine Minchiate appeared in the listbox for admindiscoand was read as "unlocked", but the Game Kit + Card Decks applets correctly rendered only Earthman because only Earthman was actually inunlocked_decks(Fiorentine was an *available option*, not a selected value).filter_horizontalsplits into "Available" (left) + "Chosen" (right) panes with explicit arrows between — selected vs available is unambiguous. Same trap applies tobuds(also a bare M2M per [[project-deck-contribution-spec]] adjacent note), so fixing both. No model/template/test changes — just the admin widget.UserAdminTestonly exercises the changelist (/admin/lyric/user/), not the change form, so no test impact
Disco DeDisco
2026-05-24 17:05:14 -04:00 -
92df686d80
fix: significator_reversed=polarity bug + Pattern B name-swap rendering + qualifier-aware applet faces + sticky PAID DRAW + cooldown anchor on User + stat-block polarity unification across Sig/Sea/Fan/applets
Disco DeDisco
2026-05-23 15:06:35 -04:00 -
53cd7afeb4
feat: My Sea applet dynamic population + lay/leave POSITION_LABELS swap fix + My Sign applet stat-block + Brief-fied sign-gate + --duoUser olive on all four personal-data surfaces. Six visual+structural items batched across the dashboard/billboard/gameboard.
Disco DeDisco
2026-05-22 15:19:34 -04:00 -
1452de1a76
feat: My Sign saved-sig state — --duoUser bg, centred card+stat-block, stage card auto-rotates for reversed sigs on landing. Three follow-up polish items atop the
f609313read-only-saved-sig batch.
Disco DeDisco
2026-05-22 13:21:55 -04:00 -
f6093136f1
fix: shop tooltip price flex-pinned right (cross-file
#id_tooltip_portal .tt-title { display: block }was clobbering the flex h4) + My Sign page collapses to read-only card+stat-block when sig is saved + My Sign applet card gets proper 5:8 shell + Game Kit row space-evenly. Five visual polish items batched.
Disco DeDisco
2026-05-22 12:42:03 -04:00