cards 48–49 polarity-split titles; sea-stage mobile breakpoints; @comment fix — TDD
- migration 0015 fills card 49 levity_reversal=The Vibrational Mould of Man, gravity_reversal=The All-Bestowing Eagle (card 48 already seeded in 0004)
- _tarot_fan.html: 4 new data-* attrs (data-levity-emanation / data-gravity-emanation / data-levity-reversal / data-gravity-reversal); upright + reversal slots render full polarity-split title in name slot when set, qualifier slots blank
- StageCard.fromDataset: parse the 4 new attrs; populateCard: emanationOverride / reversalOverride per polarity bypasses the standard name+qualifier rendering
- model: emanation_for / reversal_for fall back to name_title (group prefix stripped) instead of full self.name; reversal_for uses self.reversal_qualifier (was leftover self.reversal post-rename)
- sea-stage-content: --sig-card-w lifted from inline style to SCSS w. portrait ≤480px / landscape ≤500h breakpoints both stepping to 130px (mirrors fan modal triggers); default 180px
- _tarot_fan.html: rewrite multi-line {# #} that rendered as page text into {% comment %}{% endcomment %}
Code architected by Disco DeDisco <discodedisco@outlook.com>
Git commit message Co-Authored-By:
Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
"""Populate card 49's polarity-split reversal titles.
|
||||
|
||||
The Earthman deck's last two cards (48–49) carry distinct titles per polarity
|
||||
(stored in `levity_emanation` / `gravity_emanation` / `levity_reversal` /
|
||||
`gravity_reversal`) rather than a shared title + qualifier.
|
||||
|
||||
Card 48 had its full set seeded in migration 0004:
|
||||
levity: Father Sky → reversal: The Storm
|
||||
gravity: Mother Sea → reversal: The Flood
|
||||
|
||||
Card 49 had only emanations seeded; this migration fills the reversals:
|
||||
levity: The Effulgent Mould of Man → reversal: The Vibrational Mould of Man
|
||||
gravity: The Devouring Eagle → reversal: The All-Bestowing Eagle
|
||||
|
||||
The "qualifier" (Effulgent / Vibrational / Devouring / All-Bestowing) is baked
|
||||
into the title between "The" and the title-proper rather than rendered as a
|
||||
separate qualifier slot — the per-polarity title strings are stored verbatim.
|
||||
"""
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
def populate_card49_reversals(apps, schema_editor):
|
||||
TarotCard = apps.get_model("epic", "TarotCard")
|
||||
DeckVariant = apps.get_model("epic", "DeckVariant")
|
||||
try:
|
||||
earthman = DeckVariant.objects.get(slug="earthman")
|
||||
except DeckVariant.DoesNotExist:
|
||||
return
|
||||
TarotCard.objects.filter(
|
||||
deck_variant=earthman, arcana="MAJOR", number=49,
|
||||
).update(
|
||||
levity_reversal="The Vibrational Mould of Man",
|
||||
gravity_reversal="The All-Bestowing Eagle",
|
||||
)
|
||||
|
||||
|
||||
def clear_card49_reversals(apps, schema_editor):
|
||||
TarotCard = apps.get_model("epic", "TarotCard")
|
||||
DeckVariant = apps.get_model("epic", "DeckVariant")
|
||||
try:
|
||||
earthman = DeckVariant.objects.get(slug="earthman")
|
||||
except DeckVariant.DoesNotExist:
|
||||
return
|
||||
TarotCard.objects.filter(
|
||||
deck_variant=earthman, arcana="MAJOR", number=49,
|
||||
).update(
|
||||
levity_reversal="",
|
||||
gravity_reversal="",
|
||||
)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("epic", "0014_rename_reversal_to_reversal_qualifier"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(populate_card49_reversals, reverse_code=clear_card49_reversals),
|
||||
]
|
||||
@@ -291,21 +291,22 @@ class TarotCard(models.Model):
|
||||
|
||||
def emanation_for(self, polarity):
|
||||
"""Return the upright title for a given polarity ('levity' or 'gravity').
|
||||
Falls back to name for cards without a polarity split."""
|
||||
Falls back to name_title (group prefix stripped) for cards without a
|
||||
polarity split."""
|
||||
if polarity == 'levity' and self.levity_emanation:
|
||||
return self.levity_emanation
|
||||
if polarity == 'gravity' and self.gravity_emanation:
|
||||
return self.gravity_emanation
|
||||
return self.name
|
||||
return self.name_title
|
||||
|
||||
def reversal_for(self, polarity):
|
||||
"""Return the reversed title for a given polarity.
|
||||
Falls back to reversal (blank = same as emanation_for)."""
|
||||
Falls back to reversal_qualifier (blank = same as emanation_for)."""
|
||||
if polarity == 'levity' and self.levity_reversal:
|
||||
return self.levity_reversal
|
||||
if polarity == 'gravity' and self.gravity_reversal:
|
||||
return self.gravity_reversal
|
||||
return self.reversal or self.emanation_for(polarity)
|
||||
return self.reversal_qualifier or self.emanation_for(polarity)
|
||||
|
||||
@property
|
||||
def name_group(self):
|
||||
|
||||
@@ -31,6 +31,13 @@ var StageCard = (function () {
|
||||
levity_qualifier: el.dataset.levityQualifier || '',
|
||||
gravity_qualifier: el.dataset.gravityQualifier || '',
|
||||
reversal_qualifier: el.dataset.reversalQualifier || '',
|
||||
// Polarity-split title overrides — non-blank for cards 48-49 only,
|
||||
// where each polarity (and within each polarity, each axis state)
|
||||
// has a fully distinct title rather than a shared name + qualifier.
|
||||
levity_emanation: el.dataset.levityEmanation || '',
|
||||
gravity_emanation: el.dataset.gravityEmanation || '',
|
||||
levity_reversal: el.dataset.levityReversal || '',
|
||||
gravity_reversal: el.dataset.gravityReversal || '',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -47,11 +54,17 @@ var StageCard = (function () {
|
||||
// falls back to the current polarity's qualifier when blank (6F behavior).
|
||||
function populateCard(stageCard, card, polarity) {
|
||||
if (!stageCard) return;
|
||||
var isLevity = polarity === 'levity';
|
||||
var isLevity = polarity === 'levity';
|
||||
var qualifier = isLevity ? (card.levity_qualifier || '') : (card.gravity_qualifier || '');
|
||||
var isMajor = _isMajor(card);
|
||||
var title = card.name_title || '';
|
||||
var isMajor = _isMajor(card);
|
||||
var title = card.name_title || '';
|
||||
var reversalQualifier = card.reversal_qualifier || '';
|
||||
// Polarity-split overrides (cards 48-49). When set, the full title
|
||||
// string already incorporates whatever qualifier the card carries
|
||||
// ("The Effulgent Mould of Man" etc.) — render as a single line and
|
||||
// leave the upright qualifier slots empty.
|
||||
var emanationOverride = isLevity ? (card.levity_emanation || '') : (card.gravity_emanation || '');
|
||||
var reversalOverride = isLevity ? (card.levity_reversal || '') : (card.gravity_reversal || '');
|
||||
|
||||
stageCard.querySelectorAll('.fan-corner-rank').forEach(function (el) {
|
||||
el.textContent = card.corner_rank || '';
|
||||
@@ -66,27 +79,38 @@ var StageCard = (function () {
|
||||
});
|
||||
|
||||
var nameGroupEl = stageCard.querySelector('.fan-card-name-group');
|
||||
if (nameGroupEl) nameGroupEl.textContent = card.name_group || '';
|
||||
if (nameGroupEl) nameGroupEl.textContent = emanationOverride ? '' : (card.name_group || '');
|
||||
|
||||
var arcanaEl = stageCard.querySelector('.fan-card-arcana');
|
||||
if (arcanaEl) arcanaEl.textContent = isMajor ? 'Major Arcana' : 'Middle Arcana';
|
||||
|
||||
var nameEl = stageCard.querySelector('.fan-card-name');
|
||||
if (nameEl) nameEl.textContent = isMajor ? title + ',' : title;
|
||||
|
||||
var qAbove = stageCard.querySelector('.sig-qualifier-above');
|
||||
if (qAbove) qAbove.textContent = isMajor ? '' : qualifier;
|
||||
var qBelow = stageCard.querySelector('.sig-qualifier-below');
|
||||
if (qBelow) qBelow.textContent = isMajor ? qualifier : '';
|
||||
|
||||
// Reversal face — three cases:
|
||||
// Major: title (with comma) in qualifier slot, qualifier in name slot
|
||||
if (emanationOverride) {
|
||||
// Cards 48-49 — single-line title, no qualifier slots.
|
||||
if (nameEl) nameEl.textContent = emanationOverride;
|
||||
if (qAbove) qAbove.textContent = '';
|
||||
if (qBelow) qBelow.textContent = '';
|
||||
} else {
|
||||
if (nameEl) nameEl.textContent = isMajor ? title + ',' : title;
|
||||
if (qAbove) qAbove.textContent = isMajor ? '' : qualifier;
|
||||
if (qBelow) qBelow.textContent = isMajor ? qualifier : '';
|
||||
}
|
||||
|
||||
// Reversal face — four cases:
|
||||
// Polarity-split: full reversal title in qualifier slot (top-after-spin), name slot empty
|
||||
// Major: title (with comma) in qualifier slot, qualifier in name slot
|
||||
// Non-major + reversal_qual: reversal_qualifier in qualifier slot, title in name slot
|
||||
// Non-major no reversal_qual: fall back to current polarity's qualifier
|
||||
var rQual = stageCard.querySelector('.fan-card-reversal-qualifier');
|
||||
var rName = stageCard.querySelector('.fan-card-reversal-name');
|
||||
if (rQual && rName) {
|
||||
if (isMajor) {
|
||||
if (reversalOverride) {
|
||||
rQual.textContent = reversalOverride;
|
||||
rName.textContent = '';
|
||||
} else if (isMajor) {
|
||||
rQual.textContent = title + ',';
|
||||
rName.textContent = qualifier;
|
||||
} else if (reversalQualifier) {
|
||||
|
||||
Reference in New Issue
Block a user