diff --git a/src/static_src/scss/_card-deck.scss b/src/static_src/scss/_card-deck.scss index e1a021e..ef618e6 100644 --- a/src/static_src/scss/_card-deck.scss +++ b/src/static_src/scss/_card-deck.scss @@ -887,6 +887,18 @@ html:has(.sig-backdrop) { display: inline-flex; } +// Sprint A.5 — hide FLIP btn during the flip animation. `data-flipping="1"` +// is set on .sig-stage-card by _flipPolarityAnimated (polarized) AND +// _flipToBackAnimated (non-polarized) for the 500ms animation duration; CSS +// :has() selects the parent .my-sign-stage when any child carries that attr +// and zeros the btn so it doesn't visually interfere w. the rotateY mid-spin. +// Mirrors the tarot-fan view's pattern (`_card-deck.scss:459` — +// `.tarot-fan-wrap:has(.fan-card[data-flipping]) .fan-flip-btn`). +.my-sign-stage:has(.sig-stage-card[data-flipping]) .my-sign-flip-btn { + opacity: 0; + pointer-events: none; +} + // ─── Mini card grid ─────────────────────────────────────────────────────────── // flex: 0 0 auto — shrinks to card content; no background (backdrop blur). // align-content: start prevents CSS grid from distributing extra height between rows. diff --git a/src/templates/apps/billboard/my_sign.html b/src/templates/apps/billboard/my_sign.html index 1e14e01..19e7bd8 100644 --- a/src/templates/apps/billboard/my_sign.html +++ b/src/templates/apps/billboard/my_sign.html @@ -42,9 +42,11 @@ {# non-polarized decks). Pre-rendered back-image element; CSS #} {# toggles visibility via `.sig-stage-card.is-flipped-to-back`. #} {% if request.user.equipped_deck.has_card_images and not request.user.equipped_deck.is_polarized %} + {# No inline style — `.sig-stage-card-back-img` defaults to #} + {# `display: none` via SCSS; `.sig-stage-card.is-flipped-to-back` #} + {# overrides to `display: block`. Inline would beat the toggle. #} + src="{{ request.user.equipped_deck.back_image_url }}"> {% endif %}
@@ -359,20 +361,38 @@ }); } + // Sprint A.5 — non-polarized FLIP animation. Mirrors the polarized + // `_flipPolarityAnimated` shape (rotateY-90 mid-spin + dataset.flipping + // for the duration so SCSS can hide the btn) but swaps a class + // toggle for the polarity revInput-flip at the halfway point. + function _flipToBackAnimated() { + if (!stageCard || stageCard.dataset.flipping) return; + stageCard.dataset.flipping = '1'; + var rest = 'translateX(0px) rotateY(0deg) scale(1)'; + var mid = 'translateX(0px) rotateY(90deg) scale(1)'; + stageCard.animate([ + { transform: rest }, + { transform: mid, offset: 0.5 }, + { transform: rest }, + ], { duration: 500, easing: 'ease' }); + setTimeout(function () { + stageCard.classList.toggle('is-flipped-to-back'); + if (flipBtn) flipBtn.classList.toggle( + 'is-reversed', + stageCard.classList.contains('is-flipped-to-back') + ); + }, 250); + setTimeout(function () { delete stageCard.dataset.flipping; }, 500); + } + if (flipBtn) { flipBtn.addEventListener('click', function () { if (!_currentCard) return; - // Sprint A.5 — non-polarized decks (Minchiate, RWS): FLIP - // shows the deck card-back instead of cycling polarity (no - // gravity/levity to toggle on these decks). Stat block stays - // unchanged — user spec 2026-05-25 PM. Polarized decks - // (Earthman) keep the existing polarity-flip animation. + // Non-polarized decks (Minchiate, RWS): FLIP shows the deck + // card-back; stat block stays unchanged — user spec 2026-05-25 PM. + // Polarized decks (Earthman) keep the existing polarity cycle. if (pageEl.dataset.deckPolarized === 'false') { - stageCard.classList.toggle('is-flipped-to-back'); - if (flipBtn) flipBtn.classList.toggle( - 'is-reversed', - stageCard.classList.contains('is-flipped-to-back') - ); + _flipToBackAnimated(); } else { _flipPolarityAnimated(); }