test new global styles for inline buttons in details, and add links to tarot cards in planet details

This commit is contained in:
2026-04-24 01:08:00 -07:00
parent 789bb9cbbd
commit fe323552b2
7 changed files with 564 additions and 424 deletions
+24
View File
@@ -4365,6 +4365,27 @@
border-color: #7060b0; border-color: #7060b0;
color: #e0d0ff; color: #e0d0ff;
} }
.detail-inline-value {
display: inline;
}
.detail-inline-link {
padding: 0;
border: 0;
background: none;
color: #c8b8f8;
font: inherit;
line-height: inherit;
cursor: pointer;
text-align: inherit;
text-decoration: underline;
text-decoration-color: rgba(200, 184, 248, 0.45);
text-underline-offset: 0.12em;
}
.detail-inline-link:hover,
.detail-inline-link:focus-visible {
color: #e0d0ff;
text-decoration-color: currentColor;
}
/* ── Alphabet section ────────────────────────────────────────────────── */ /* ── Alphabet section ────────────────────────────────────────────────── */
#alphabet-section, #alphabet-section,
@@ -5298,6 +5319,9 @@
} }
} }
.alpha-dl dd { margin: 0; } .alpha-dl dd { margin: 0; }
.alpha-dl dd .detail-inline-link {
vertical-align: baseline;
}
.alpha-badge { .alpha-badge {
display: inline-block; display: inline-block;
padding: 1px 7px; padding: 1px 7px;
+239 -183
View File
@@ -40,21 +40,68 @@
return card; return card;
} }
function appendLinkRow(card, buttons) { function appendInlineParts(target, parts) {
const validButtons = Array.isArray(buttons) (Array.isArray(parts) ? parts : []).forEach((part) => {
? buttons.filter((button) => button instanceof Node) if (part instanceof Node) {
: []; target.appendChild(part);
if (!(card instanceof HTMLElement) || !validButtons.length) { return;
return card;
} }
const row = document.createElement("div"); const text = String(part ?? "");
row.className = "kab-god-links"; if (text) {
validButtons.forEach((button) => { target.appendChild(document.createTextNode(text));
row.appendChild(button); }
}); });
card.appendChild(row); }
return card;
function createInlineEventLink(label, eventName, detail) {
const button = document.createElement("button");
button.type = "button";
button.className = "detail-inline-link";
button.textContent = String(label || "—");
button.addEventListener("click", () => {
document.dispatchEvent(new CustomEvent(eventName, { detail }));
});
return button;
}
function createInlineActionLink(label, onActivate) {
const button = document.createElement("button");
button.type = "button";
button.className = "detail-inline-link";
button.textContent = String(label || "—");
button.addEventListener("click", () => {
onActivate?.();
});
return button;
}
function createInlineValue(parts) {
const value = document.createElement("span");
value.className = "detail-inline-value";
appendInlineParts(value, parts);
return value;
}
function createDetailList(rows) {
const list = document.createElement("dl");
list.className = "alpha-dl";
(Array.isArray(rows) ? rows : []).forEach((row) => {
const term = document.createElement("dt");
term.textContent = String(row?.label || "").trim();
const detail = document.createElement("dd");
if (row?.value instanceof Node) {
detail.appendChild(row.value);
} else {
detail.innerHTML = toDetailValueMarkup(row?.value);
}
list.append(term, detail);
});
return list;
} }
function createNavButton(label, eventName, detail) { function createNavButton(label, eventName, detail) {
@@ -92,42 +139,45 @@
const bodyEl = elements.detailBodyEl; const bodyEl = elements.detailBodyEl;
bodyEl.innerHTML = ""; bodyEl.innerHTML = "";
const summary = document.createElement("div");
summary.className = "planet-text";
summary.innerHTML = `
<dl class="alpha-dl">
<dt>Name</dt><dd>${toDetailValueMarkup(center?.name)}</dd>
<dt>Letter</dt><dd>${toDetailValueMarkup(centerLetterText)}</dd>
<dt>Element</dt><dd>${toDetailValueMarkup(center?.element)}</dd>
</dl>
`;
const associations = center?.associations || {}; const associations = center?.associations || {};
const detailButtons = [];
if (centerLetterId) {
detailButtons.push(createNavButton(centerLetter || "!", "nav:alphabet", {
alphabet: "hebrew",
hebrewLetterId: centerLetterId
}));
}
const centerTrumpNo = toFiniteNumber(associations?.tarotTrumpNumber); const centerTrumpNo = toFiniteNumber(associations?.tarotTrumpNumber);
const centerTarotCard = toDisplayText(associations?.tarotCard); const centerTarotCard = toDisplayText(associations?.tarotCard);
const centerPathNo = toFiniteNumber(associations?.kabbalahPathNumber);
const summaryRows = [
{ label: "Name", value: center?.name },
{
label: "Letter",
value: centerLetterId
? createInlineEventLink(centerLetterText, "nav:alphabet", {
alphabet: "hebrew",
hebrewLetterId: centerLetterId
})
: centerLetterText
},
{ label: "Element", value: center?.element }
];
if (centerTarotCard || centerTrumpNo != null) { if (centerTarotCard || centerTrumpNo != null) {
detailButtons.push(createNavButton(centerTarotCard || `Trump ${centerTrumpNo}`, "nav:tarot-trump", { summaryRows.push({
label: "Tarot",
value: createInlineEventLink(centerTarotCard || `Trump ${centerTrumpNo}`, "nav:tarot-trump", {
cardName: centerTarotCard, cardName: centerTarotCard,
trumpNumber: centerTrumpNo trumpNumber: centerTrumpNo
})); })
});
} }
const centerPathNo = toFiniteNumber(associations?.kabbalahPathNumber);
if (centerPathNo != null) { if (centerPathNo != null) {
detailButtons.push(createNavButton(`Path ${centerPathNo}`, "nav:kabbalah-path", { summaryRows.push({
label: "Path",
value: createInlineEventLink(`Path ${centerPathNo}`, "nav:kabbalah-path", {
pathNo: centerPathNo pathNo: centerPathNo
})); })
});
} }
bodyEl.appendChild(appendLinkRow(createMetaCard("Center Details", summary), detailButtons)); bodyEl.appendChild(createMetaCard("Center Details", createDetailList(summaryRows)));
if (Array.isArray(center?.keywords) && center.keywords.length) { if (Array.isArray(center?.keywords) && center.keywords.length) {
bodyEl.appendChild(createMetaCard("Keywords", center.keywords.join(", "))); bodyEl.appendChild(createMetaCard("Keywords", center.keywords.join(", ")));
@@ -185,37 +235,52 @@
const bodyEl = elements.detailBodyEl; const bodyEl = elements.detailBodyEl;
bodyEl.innerHTML = ""; bodyEl.innerHTML = "";
const summary = document.createElement("div"); const connectorRows = [
summary.className = "planet-text"; {
summary.innerHTML = ` label: "Letter",
<dl class="alpha-dl"> value: letterId
<dt>Letter</dt><dd>${toDetailValueMarkup(letterText)}</dd> ? createInlineEventLink(letterText, "nav:alphabet", {
<dt>From</dt><dd>${toDetailValueMarkup(fromWall?.name || formatDirectionName(fromWallId))}</dd>
<dt>To</dt><dd>${toDetailValueMarkup(toWall?.name || formatDirectionName(toWallId))}</dd>
<dt>Tarot</dt><dd>${toDetailValueMarkup(tarotCard || (tarotTrumpNumber != null ? `Trump ${tarotTrumpNumber}` : ""))}</dd>
</dl>
`;
const connectorButtons = [];
if (letterId) {
connectorButtons.push(createNavButton(letterSymbol || "!", "nav:alphabet", {
alphabet: "hebrew", alphabet: "hebrew",
hebrewLetterId: letterId hebrewLetterId: letterId
})); })
: letterText
},
{
label: "From",
value: fromWall
? createInlineActionLink(fromWall?.name || formatDirectionName(fromWallId), () => {
context.onSelectWall?.(fromWallId);
})
: (fromWall?.name || formatDirectionName(fromWallId))
},
{
label: "To",
value: toWall
? createInlineActionLink(toWall?.name || formatDirectionName(toWallId), () => {
context.onSelectWall?.(toWallId);
})
: (toWall?.name || formatDirectionName(toWallId))
}
];
if (tarotCard || tarotTrumpNumber != null) {
connectorRows.push({
label: "Tarot",
value: createInlineEventLink(tarotCard || `Trump ${tarotTrumpNumber}`, "nav:tarot-trump", {
cardName: tarotCard,
trumpNumber: tarotTrumpNumber
})
});
} }
if (pathNo != null) { if (pathNo != null) {
connectorButtons.push(createNavButton(`Path ${pathNo}`, "nav:kabbalah-path", { pathNo })); connectorRows.push({
label: "Path",
value: createInlineEventLink(`Path ${pathNo}`, "nav:kabbalah-path", { pathNo })
});
} }
if (tarotCard || tarotTrumpNumber != null) { bodyEl.appendChild(createMetaCard("Connector Details", createDetailList(connectorRows)));
connectorButtons.push(createNavButton(tarotCard || `Trump ${tarotTrumpNumber}`, "nav:tarot-trump", {
cardName: tarotCard,
trumpNumber: tarotTrumpNumber
}));
}
bodyEl.appendChild(appendLinkRow(createMetaCard("Connector Details", summary), connectorButtons));
if (astrologySummary) { if (astrologySummary) {
bodyEl.appendChild(createMetaCard("Astrology", astrologySummary)); bodyEl.appendChild(createMetaCard("Astrology", astrologySummary));
@@ -282,18 +347,47 @@
title.textContent = `Edge · ${edgeName}`; title.textContent = `Edge · ${edgeName}`;
edgeCard.appendChild(title); edgeCard.appendChild(title);
const dlWrap = document.createElement("div"); const edgeRows = [
dlWrap.className = "planet-text"; { label: "Direction", value: edgeName },
dlWrap.innerHTML = ` { label: "Edge", value: edgeWalls },
<dl class="alpha-dl"> {
<dt>Direction</dt><dd>${toDetailValueMarkup(edgeName)}</dd> label: "Letter",
<dt>Edge</dt><dd>${toDetailValueMarkup(edgeWalls)}</dd> value: edgeLetterId
<dt>Letter</dt><dd>${toDetailValueMarkup(edgeLetter)}</dd> ? createInlineEventLink(edgeLetter || edgeLetterId, "nav:alphabet", {
<dt>Astrology</dt><dd>${toDetailValueMarkup(astrologyText)}</dd> alphabet: "hebrew",
<dt>Tarot</dt><dd>${toDetailValueMarkup(tarotCard)}</dd> hebrewLetterId: edgeLetterId
</dl> })
`; : edgeLetter
edgeCard.appendChild(dlWrap); },
{
label: "Astrology",
value: astrologyType === "zodiac" && astrologyName
? createInlineValue([
astrologySymbol ? `${astrologySymbol} ` : "",
createInlineEventLink(astrologyName, "nav:zodiac", { signId: normalizeId(astrologyName) })
])
: astrologyText
}
];
if (tarotCard || tarotTrumpNumber != null) {
edgeRows.push({
label: "Tarot",
value: createInlineEventLink(tarotCard || `Trump ${tarotTrumpNumber}`, "nav:tarot-trump", {
cardName: tarotCard,
trumpNumber: tarotTrumpNumber
})
});
}
if (pathNo != null) {
edgeRows.push({
label: "Path",
value: createInlineEventLink(`Path ${pathNo}`, "nav:kabbalah-path", { pathNo })
});
}
edgeCard.appendChild(createDetailList(edgeRows));
if (Array.isArray(selectedEdge.keywords) && selectedEdge.keywords.length) { if (Array.isArray(selectedEdge.keywords) && selectedEdge.keywords.length) {
const keywords = document.createElement("p"); const keywords = document.createElement("p");
@@ -309,37 +403,6 @@
edgeCard.appendChild(description); edgeCard.appendChild(description);
} }
const links = document.createElement("div");
links.className = "kab-god-links";
if (edgeLetterId) {
links.appendChild(createNavButton(edgeLetter || "!", "nav:alphabet", {
alphabet: "hebrew",
hebrewLetterId: edgeLetterId
}));
}
if (astrologyType === "zodiac" && astrologyName) {
links.appendChild(createNavButton(astrologyName, "nav:zodiac", {
signId: normalizeId(astrologyName)
}));
}
if (tarotCard) {
links.appendChild(createNavButton(tarotCard, "nav:tarot-trump", {
cardName: tarotCard,
trumpNumber: tarotTrumpNumber
}));
}
if (pathNo != null) {
links.appendChild(createNavButton(`Path ${pathNo}`, "nav:kabbalah-path", { pathNo }));
}
if (links.childElementCount) {
edgeCard.appendChild(links);
}
detailBodyEl.appendChild(edgeCard); detailBodyEl.appendChild(edgeCard);
} }
@@ -394,57 +457,47 @@
const bodyEl = elements.detailBodyEl; const bodyEl = elements.detailBodyEl;
bodyEl.innerHTML = ""; bodyEl.innerHTML = "";
const summary = document.createElement("div"); const wallAssociations = wall.associations || {};
summary.className = "planet-text";
summary.innerHTML = `
<dl class="alpha-dl">
<dt>Opposite</dt><dd>${toDetailValueMarkup(wall.opposite)}</dd>
<dt>Face Letter</dt><dd>${toDetailValueMarkup(wallFaceLetterText)}</dd>
<dt>Element</dt><dd>${toDetailValueMarkup(wall.element)}</dd>
<dt>Planet</dt><dd>${toDetailValueMarkup(wall.planet)}</dd>
<dt>Archangel</dt><dd>${toDetailValueMarkup(wall.archangel)}</dd>
</dl>
`;
const wallButtons = [];
if (wallFaceLetterId) {
const wallFaceLetterName = getHebrewLetterName(wallFaceLetterId) || toDisplayText(wallFaceLetterId); const wallFaceLetterName = getHebrewLetterName(wallFaceLetterId) || toDisplayText(wallFaceLetterId);
const faceLetterText = [wallFaceLetter, wallFaceLetterName].filter(Boolean).join(" "); const faceLetterLabel = [wallFaceLetter, wallFaceLetterName].filter(Boolean).join(" ");
const faceLetterLabel = faceLetterText const wallRows = [
? `Face ${faceLetterText}` {
: "Face !"; label: "Opposite",
wallButtons.push(createNavButton(faceLetterLabel, "nav:alphabet", { value: wall.oppositeWallId
? createInlineActionLink(getWallById(wall.oppositeWallId)?.name || wall.oppositeWallId, () => {
onSelectWall(wall.oppositeWallId);
})
: wall.opposite
},
{
label: "Face Letter",
value: wallFaceLetterId
? createInlineEventLink(faceLetterLabel || "!", "nav:alphabet", {
alphabet: "hebrew", alphabet: "hebrew",
hebrewLetterId: wallFaceLetterId hebrewLetterId: wallFaceLetterId
})); })
} : wallFaceLetterText
},
const wallAssociations = wall.associations || {}; { label: "Element", value: wall.element },
if (wallAssociations.planetId) { {
wallButtons.push(createNavButton(toDisplayText(wall.planet) || "!", "nav:planet", { label: "Planet",
value: wallAssociations.planetId
? createInlineEventLink(toDisplayText(wall.planet) || "!", "nav:planet", {
planetId: wallAssociations.planetId planetId: wallAssociations.planetId
})); })
} : wall.planet
},
if (wallAssociations.godName) { {
wallButtons.push(createNavButton(wallAssociations.godName, "nav:gods", { label: "Archangel",
value: wallAssociations.godName
? createInlineEventLink(wallAssociations.godName, "nav:gods", {
godName: wallAssociations.godName godName: wallAssociations.godName
})); })
: wall.archangel
} }
];
if (wall.oppositeWallId) { bodyEl.appendChild(createMetaCard("Wall Details", createDetailList(wallRows)));
const oppositeWall = getWallById(wall.oppositeWallId);
const internal = document.createElement("button");
internal.type = "button";
internal.className = "kab-god-link";
internal.textContent = `Opposite: ${oppositeWall?.name || wall.oppositeWallId}`;
internal.addEventListener("click", () => {
onSelectWall(wall.oppositeWallId);
});
wallButtons.push(internal);
}
bodyEl.appendChild(appendLinkRow(createMetaCard("Wall Details", summary), wallButtons));
if (Array.isArray(wall.keywords) && wall.keywords.length) { if (Array.isArray(wall.keywords) && wall.keywords.length) {
bodyEl.appendChild(createMetaCard("Keywords", wall.keywords.join(", "))); bodyEl.appendChild(createMetaCard("Keywords", wall.keywords.join(", ")));
@@ -575,57 +628,60 @@
const bodyEl = elements.detailBodyEl; const bodyEl = elements.detailBodyEl;
bodyEl.innerHTML = ""; bodyEl.innerHTML = "";
const summary = document.createElement("div"); const edgeRows = [
summary.className = "planet-text"; { label: "Name", value: edgeName },
summary.innerHTML = ` {
<dl class="alpha-dl"> label: "Between",
<dt>Name</dt><dd>${toDetailValueMarkup(edgeName)}</dd> value: createInlineValue(edgeWalls.flatMap((wallId, index) => {
<dt>Between</dt><dd>${toDetailValueMarkup(wallNames)}</dd>
<dt>Letter</dt><dd>${toDetailValueMarkup(edgeLetterText)}</dd>
<dt>Astrology</dt><dd>${toDetailValueMarkup(astrologyText)}</dd>
<dt>Tarot</dt><dd>${toDetailValueMarkup(tarotCard || (tarotTrumpNumber != null ? `Trump ${tarotTrumpNumber}` : ""))}</dd>
<dt>Path</dt><dd>${toDetailValueMarkup(pathNo != null ? `Path ${pathNo}` : "")}</dd>
</dl>
`;
const edgeButtons = [];
edgeWalls.forEach((wallId) => {
const wall = getWallById(wallId); const wall = getWallById(wallId);
const button = document.createElement("button"); const parts = [];
button.type = "button"; if (index > 0) {
button.className = "kab-god-link"; parts.push(" ↔ ");
button.textContent = `${wall?.name || wallId} Wall`; }
button.addEventListener("click", () => { parts.push(createInlineActionLink(wall?.name || wallId, () => {
onSelectWall(wallId); onSelectWall(wallId);
}); }));
edgeButtons.push(button); return parts;
}); }))
},
if (edgeLetterId) { {
edgeButtons.push(createNavButton(edgeLetter || "!", "nav:alphabet", { label: "Letter",
value: edgeLetterId
? createInlineEventLink(edgeLetterText || edgeLetterId, "nav:alphabet", {
alphabet: "hebrew", alphabet: "hebrew",
hebrewLetterId: edgeLetterId hebrewLetterId: edgeLetterId
})); })
} : edgeLetterText
},
if (astrologyType === "zodiac" && astrologyName) { {
edgeButtons.push(createNavButton(astrologyName, "nav:zodiac", { label: "Astrology",
signId: normalizeId(astrologyName) value: astrologyType === "zodiac" && astrologyName
})); ? createInlineValue([
astrologySymbol ? `${astrologySymbol} ` : "",
createInlineEventLink(astrologyName, "nav:zodiac", { signId: normalizeId(astrologyName) })
])
: astrologyText
} }
];
if (tarotCard || tarotTrumpNumber != null) { if (tarotCard || tarotTrumpNumber != null) {
edgeButtons.push(createNavButton(tarotCard || `Trump ${tarotTrumpNumber}`, "nav:tarot-trump", { edgeRows.push({
label: "Tarot",
value: createInlineEventLink(tarotCard || `Trump ${tarotTrumpNumber}`, "nav:tarot-trump", {
cardName: tarotCard, cardName: tarotCard,
trumpNumber: tarotTrumpNumber trumpNumber: tarotTrumpNumber
})); })
});
} }
if (pathNo != null) { if (pathNo != null) {
edgeButtons.push(createNavButton(`Path ${pathNo}`, "nav:kabbalah-path", { pathNo })); edgeRows.push({
label: "Path",
value: createInlineEventLink(`Path ${pathNo}`, "nav:kabbalah-path", { pathNo })
});
} }
bodyEl.appendChild(appendLinkRow(createMetaCard("Edge Details", summary), edgeButtons)); bodyEl.appendChild(createMetaCard("Edge Details", createDetailList(edgeRows)));
if (Array.isArray(edge?.keywords) && edge.keywords.length) { if (Array.isArray(edge?.keywords) && edge.keywords.length) {
bodyEl.appendChild(createMetaCard("Keywords", edge.keywords.join(", "))); bodyEl.appendChild(createMetaCard("Keywords", edge.keywords.join(", ")));
+74 -49
View File
@@ -90,6 +90,38 @@
.join(" "); .join(" ");
} }
function appendInlineParts(target, parts) {
(Array.isArray(parts) ? parts : []).forEach((part) => {
if (part instanceof Node) {
target.appendChild(part);
return;
}
const text = String(part ?? "");
if (text) {
target.appendChild(document.createTextNode(text));
}
});
}
function createInlineButton(label, onActivate) {
const button = document.createElement("button");
button.type = "button";
button.className = "detail-inline-link";
button.textContent = String(label || "—");
button.addEventListener("click", () => {
onActivate?.();
});
return button;
}
function createInlineParagraph(parts) {
const line = document.createElement("p");
line.className = "planet-text detail-inline-value";
appendInlineParts(line, parts);
return line;
}
function buildTarotAliasText(cardNames) { function buildTarotAliasText(cardNames) {
if (typeof getTarotCardSearchAliases !== "function") { if (typeof getTarotCardSearchAliases !== "function") {
return Array.isArray(cardNames) ? cardNames.join(" ") : ""; return Array.isArray(cardNames) ? cardNames.join(" ") : "";
@@ -252,47 +284,44 @@
const tarotTitle = document.createElement("strong"); const tarotTitle = document.createElement("strong");
tarotTitle.textContent = "Tarot Correspondence"; tarotTitle.textContent = "Tarot Correspondence";
const tarotText = document.createElement("div"); const tarotParts = [];
tarotText.className = "planet-text";
tarotText.textContent = [
entry.aceCardName ? `Ace: ${entry.aceCardName}` : "",
entry.courtRank ? `Court Rank: ${entry.courtRank} (all suits)` : ""
].filter(Boolean).join(" · ") || "--";
tarotCard.append(tarotTitle, tarotText);
if (entry.aceCardName || entry.courtCardNames.length) {
const navWrap = document.createElement("div");
navWrap.className = "alpha-nav-btns";
if (entry.aceCardName) { if (entry.aceCardName) {
const tarotBtn = document.createElement("button"); tarotParts.push(
tarotBtn.type = "button"; "Ace: ",
tarotBtn.className = "alpha-nav-btn"; createInlineButton(entry.aceCardName, () => {
tarotBtn.textContent = `Open ${entry.aceCardName}`;
tarotBtn.addEventListener("click", () => {
document.dispatchEvent(new CustomEvent("nav:tarot-trump", { document.dispatchEvent(new CustomEvent("nav:tarot-trump", {
detail: { cardName: entry.aceCardName } detail: { cardName: entry.aceCardName }
})); }));
}); })
);
navWrap.appendChild(tarotBtn); }
if (entry.courtRank) {
if (tarotParts.length) {
tarotParts.push(" · ");
}
tarotParts.push(`Court Rank: ${entry.courtRank} (all suits)`);
} }
entry.courtCardNames.forEach((cardName) => { const tarotText = tarotParts.length
const courtBtn = document.createElement("button"); ? createInlineParagraph(tarotParts)
courtBtn.type = "button"; : document.createTextNode("--");
courtBtn.className = "alpha-nav-btn";
courtBtn.textContent = `Open ${cardName}`; tarotCard.append(tarotTitle, tarotText);
courtBtn.addEventListener("click", () => {
if (entry.courtCardNames.length) {
const courtParts = ["Court cards: "];
entry.courtCardNames.forEach((cardName, index) => {
if (index > 0) {
courtParts.push(", ");
}
courtParts.push(createInlineButton(cardName, () => {
document.dispatchEvent(new CustomEvent("nav:tarot-trump", { document.dispatchEvent(new CustomEvent("nav:tarot-trump", {
detail: { cardName } detail: { cardName }
})); }));
}); }));
navWrap.appendChild(courtBtn);
}); });
tarotCard.appendChild(navWrap); tarotCard.appendChild(createInlineParagraph(courtParts));
} }
const smallCardCard = document.createElement("div"); const smallCardCard = document.createElement("div");
@@ -317,36 +346,32 @@
`; `;
row.appendChild(head); row.appendChild(head);
const navWrap = document.createElement("div");
navWrap.className = "alpha-nav-btns";
if (group.signId) { if (group.signId) {
const signBtn = document.createElement("button"); row.appendChild(createInlineParagraph([
signBtn.type = "button"; "Sign: ",
signBtn.className = "alpha-nav-btn"; createInlineButton(group.signName, () => {
signBtn.textContent = `Open ${group.signName}`;
signBtn.addEventListener("click", () => {
document.dispatchEvent(new CustomEvent("nav:zodiac", { document.dispatchEvent(new CustomEvent("nav:zodiac", {
detail: { signId: group.signId } detail: { signId: group.signId }
})); }));
}); })
navWrap.appendChild(signBtn); ]));
} }
(group.cardNames || []).forEach((cardName) => { if ((group.cardNames || []).length) {
const cardBtn = document.createElement("button"); const cardParts = ["Cards: "];
cardBtn.type = "button"; group.cardNames.forEach((cardName, index) => {
cardBtn.className = "alpha-nav-btn"; if (index > 0) {
cardBtn.textContent = `Open ${cardName}`; cardParts.push(", ");
cardBtn.addEventListener("click", () => { }
cardParts.push(createInlineButton(cardName, () => {
document.dispatchEvent(new CustomEvent("nav:tarot-trump", { document.dispatchEvent(new CustomEvent("nav:tarot-trump", {
detail: { cardName } detail: { cardName }
})); }));
}));
}); });
navWrap.appendChild(cardBtn); row.appendChild(createInlineParagraph(cardParts));
}); }
row.appendChild(navWrap);
smallCardStack.appendChild(row); smallCardStack.appendChild(row);
}); });
+115 -74
View File
@@ -76,10 +76,55 @@
function metaCard(label, value, wide) { function metaCard(label, value, wide) {
const card = document.createElement("div"); const card = document.createElement("div");
card.className = wide ? "planet-meta-card kab-wide-card" : "planet-meta-card"; card.className = wide ? "planet-meta-card kab-wide-card" : "planet-meta-card";
card.innerHTML = `<strong>${label}</strong><p class="planet-text">${value || "—"}</p>`;
const title = document.createElement("strong");
title.textContent = label;
card.appendChild(title);
if (value instanceof Node) {
card.appendChild(value);
} else {
const body = document.createElement("p");
body.className = "planet-text";
body.textContent = value || "—";
card.appendChild(body);
}
return card; return card;
} }
function appendInlineParts(target, parts) {
(Array.isArray(parts) ? parts : []).forEach((part) => {
if (part instanceof Node) {
target.appendChild(part);
return;
}
const text = String(part ?? "");
if (text) {
target.appendChild(document.createTextNode(text));
}
});
}
function createInlineEventLink(label, eventName, detail) {
const btn = document.createElement("button");
btn.type = "button";
btn.className = "detail-inline-link";
btn.textContent = String(label || "—");
btn.addEventListener("click", () => {
document.dispatchEvent(new CustomEvent(eventName, { detail }));
});
return btn;
}
function inlineValue(parts) {
const body = document.createElement("p");
body.className = "planet-text detail-inline-value";
appendInlineParts(body, parts);
return body;
}
function createNavButton(label, eventName, detail) { function createNavButton(label, eventName, detail) {
const btn = document.createElement("button"); const btn = document.createElement("button");
btn.type = "button"; btn.type = "button";
@@ -91,31 +136,22 @@
return btn; return btn;
} }
function appendLinkRow(card, buttons) {
if (!buttons?.length) return;
const row = document.createElement("div");
row.className = "kab-god-links";
buttons.forEach((button) => row.appendChild(button));
card.appendChild(row);
}
function buildPlanetLuminaryCard(planetValue, context) { function buildPlanetLuminaryCard(planetValue, context) {
const card = metaCard("Planet / Luminary", planetValue);
const planetId = context.resolvePlanetId(planetValue); const planetId = context.resolvePlanetId(planetValue);
if (planetId) { if (planetId) {
appendLinkRow(card, [ return metaCard("Planet / Luminary", inlineValue([
createNavButton(`View ${PLANET_ID_TO_LABEL[planetId] || planetValue} in Planets`, "nav:planet", { planetId }) createInlineEventLink(PLANET_ID_TO_LABEL[planetId] || planetValue, "nav:planet", { planetId })
]); ]));
return card;
} }
const zodiacId = context.resolveZodiacId(planetValue); const zodiacId = context.resolveZodiacId(planetValue);
if (zodiacId) { if (zodiacId) {
appendLinkRow(card, [ return metaCard("Planet / Luminary", inlineValue([
createNavButton(`View ${zodiacId.charAt(0).toUpperCase() + zodiacId.slice(1)} in Zodiac`, "nav:zodiac", { signId: zodiacId }) createInlineEventLink(zodiacId.charAt(0).toUpperCase() + zodiacId.slice(1), "nav:zodiac", { signId: zodiacId })
]); ]));
} }
return card;
return metaCard("Planet / Luminary", planetValue);
} }
function extractMinorRank(attribution) { function extractMinorRank(attribution) {
@@ -131,61 +167,70 @@
} }
function buildTarotAttributionCard(attribution) { function buildTarotAttributionCard(attribution) {
const card = metaCard("Tarot Attribution", attribution);
const minorCards = buildMinorTarotNames(attribution); const minorCards = buildMinorTarotNames(attribution);
if (minorCards.length) { if (minorCards.length) {
appendLinkRow(card, minorCards.map((cardName) => const parts = [];
createNavButton(cardName, "nav:tarot-trump", { cardName }) minorCards.forEach((cardName, index) => {
)); if (index > 0) {
parts.push(", ");
} }
return card; parts.push(createInlineEventLink(cardName, "nav:tarot-trump", { cardName }));
});
return metaCard("Tarot Attribution", inlineValue(parts));
}
return metaCard("Tarot Attribution", attribution);
} }
function buildAstrologyCard(astrology, context) { function buildAstrologyCard(astrology, context) {
const astroText = astrology ? `${astrology.name} (${astrology.type})` : "—";
const card = metaCard("Astrology", astroText);
if (astrology?.type === "planet") { if (astrology?.type === "planet") {
const planetId = context.resolvePlanetId(astrology.name); const planetId = context.resolvePlanetId(astrology.name);
if (planetId) { if (planetId) {
appendLinkRow(card, [ return metaCard("Astrology", inlineValue([
createNavButton(`View ${PLANET_ID_TO_LABEL[planetId] || astrology.name} in Planets`, "nav:planet", { planetId }) createInlineEventLink(PLANET_ID_TO_LABEL[planetId] || astrology.name, "nav:planet", { planetId }),
]); " (planet)"
]));
} }
} else if (astrology?.type === "zodiac") { } else if (astrology?.type === "zodiac") {
const signId = context.resolveZodiacId(astrology.name); const signId = context.resolveZodiacId(astrology.name);
if (signId) { if (signId) {
appendLinkRow(card, [ return metaCard("Astrology", inlineValue([
createNavButton(`View ${signId.charAt(0).toUpperCase() + signId.slice(1)} in Zodiac`, "nav:zodiac", { signId }) createInlineEventLink(signId.charAt(0).toUpperCase() + signId.slice(1), "nav:zodiac", { signId }),
]); " (zodiac)"
]));
} }
} }
return card;
return metaCard("Astrology", astrology ? `${astrology.name} (${astrology.type})` : "—");
} }
function buildConnectsCard(path, fromName, toName) { function buildConnectsCard(path, fromName, toName) {
const card = metaCard("Connects", `${fromName}${toName}`); return metaCard("Connects", inlineValue([
appendLinkRow(card, [ createInlineEventLink(fromName, "nav:kabbalah-path", { pathNo: Number(path.connects.from) }),
createNavButton(`View ${fromName}`, "nav:kabbalah-path", { pathNo: Number(path.connects.from) }), " → ",
createNavButton(`View ${toName}`, "nav:kabbalah-path", { pathNo: Number(path.connects.to) }) createInlineEventLink(toName, "nav:kabbalah-path", { pathNo: Number(path.connects.to) })
]); ]));
return card;
} }
function buildHebrewLetterCard(letter, context) { function buildHebrewLetterCard(letter, context) {
const label = `${letter.char || ""} ${letter.transliteration || ""} — "${letter.meaning || ""}" (${letter.letterType || ""})`;
const card = metaCard("Hebrew Letter", label);
const hebrewLetterId = context.resolveHebrewLetterId(letter.transliteration || letter.char || ""); const hebrewLetterId = context.resolveHebrewLetterId(letter.transliteration || letter.char || "");
const letterLabel = `${letter.char || ""} ${letter.transliteration || ""}`.replace(/\s+/g, " ").trim() || "Letter";
const suffix = [
letter.meaning ? ` — "${letter.meaning}"` : "",
letter.letterType ? ` (${letter.letterType})` : ""
].join("");
if (hebrewLetterId) { if (hebrewLetterId) {
appendLinkRow(card, [ return metaCard("Hebrew Letter", inlineValue([
createNavButton(`View ${letter.transliteration || letter.char || "Letter"} in Alphabet`, "nav:alphabet", { createInlineEventLink(letterLabel, "nav:alphabet", {
alphabet: "hebrew", alphabet: "hebrew",
hebrewLetterId hebrewLetterId
}) }),
]); suffix
]));
} }
return card; return metaCard("Hebrew Letter", `${letterLabel}${suffix}`);
} }
function buildFourWorldsCard(tree, activeHebrewToken, context) { function buildFourWorldsCard(tree, activeHebrewToken, context) {
@@ -228,11 +273,11 @@
soulLine.textContent = `${layer.soulLayer}${layer.soulTitle}: ${layer.soulDescription}`; soulLine.textContent = `${layer.soulLayer}${layer.soulTitle}: ${layer.soulDescription}`;
row.appendChild(soulLine); row.appendChild(soulLine);
const buttonRow = []; const parts = [];
const hebrewLetterId = context.resolveHebrewLetterId(layer.hebrewToken); const hebrewLetterId = context.resolveHebrewLetterId(layer.hebrewToken);
if (hebrewLetterId) { if (hebrewLetterId) {
buttonRow.push( parts.push(
createNavButton(`View ${layer.letterChar} in Alphabet`, "nav:alphabet", { createInlineEventLink(layer.letterChar || layer.hebrewToken, "nav:alphabet", {
alphabet: "hebrew", alphabet: "hebrew",
hebrewLetterId hebrewLetterId
}) })
@@ -241,12 +286,17 @@
const linkedPath = context.findPathByHebrewToken(tree, layer.hebrewToken); const linkedPath = context.findPathByHebrewToken(tree, layer.hebrewToken);
if (linkedPath?.pathNumber != null) { if (linkedPath?.pathNumber != null) {
buttonRow.push( if (parts.length) {
createNavButton(`View Path ${linkedPath.pathNumber}`, "nav:kabbalah-path", { pathNo: Number(linkedPath.pathNumber) }) parts.push(" · ");
}
parts.push(
createInlineEventLink(`Path ${linkedPath.pathNumber}`, "nav:kabbalah-path", { pathNo: Number(linkedPath.pathNumber) })
); );
} }
appendLinkRow(row, buttonRow); if (parts.length) {
row.appendChild(inlineValue(parts));
}
if (isActive) { if (isActive) {
row.style.borderColor = "#818cf8"; row.style.borderColor = "#818cf8";
@@ -293,23 +343,18 @@
card.appendChild(meta); card.appendChild(meta);
} }
const row = document.createElement("div"); const parts = [];
row.className = "kab-god-links"; names.forEach((name, index) => {
if (index > 0) {
names.forEach((name) => { parts.push(", ");
const btn = document.createElement("button"); }
btn.type = "button"; parts.push(createInlineEventLink(name, "nav:gods", {
btn.className = "kab-god-link"; godName: name,
btn.textContent = name; pathNo: Number(pathNo)
btn.addEventListener("click", () => {
document.dispatchEvent(new CustomEvent("nav:gods", {
detail: { godName: name, pathNo: Number(pathNo) }
})); }));
}); });
row.appendChild(btn);
});
card.appendChild(row); card.appendChild(inlineValue(parts));
return card; return card;
} }
@@ -450,16 +495,12 @@
tarotLabel.textContent = "Tarot"; tarotLabel.textContent = "Tarot";
tarotMetaCard.appendChild(tarotLabel); tarotMetaCard.appendChild(tarotLabel);
if (path.tarot?.card && path.tarot.trumpNumber != null) { if (path.tarot?.card && path.tarot.trumpNumber != null) {
const tarotBtn = document.createElement("button"); const tarotBtn = createInlineEventLink(
tarotBtn.type = "button"; `${path.tarot.card} · Trump ${path.tarot.trumpNumber}`,
tarotBtn.className = "kab-tarot-link"; "kab:view-trump",
tarotBtn.textContent = `${path.tarot.card} · Trump ${path.tarot.trumpNumber}`; { trumpNumber: path.tarot.trumpNumber }
);
tarotBtn.title = "Open in Tarot section"; tarotBtn.title = "Open in Tarot section";
tarotBtn.addEventListener("click", () => {
document.dispatchEvent(new CustomEvent("kab:view-trump", {
detail: { trumpNumber: path.tarot.trumpNumber }
}));
});
tarotMetaCard.appendChild(tarotBtn); tarotMetaCard.appendChild(tarotBtn);
} else { } else {
const tarotP = document.createElement("p"); const tarotP = document.createElement("p");
+67 -56
View File
@@ -238,6 +238,41 @@
return getTarotCardDisplayName(cardName) || cardName; return getTarotCardDisplayName(cardName) || cardName;
} }
function appendInlineParts(target, parts) {
(Array.isArray(parts) ? parts : []).forEach((part) => {
if (part instanceof Node) {
target.appendChild(part);
return;
}
const text = String(part ?? "");
if (text) {
target.appendChild(document.createTextNode(text));
}
});
}
function createInlineButton(label, onActivate) {
const button = document.createElement("button");
button.type = "button";
button.className = "detail-inline-link";
button.textContent = String(label || "—");
button.addEventListener("click", () => {
onActivate?.();
});
return button;
}
function appendInlineLine(containerEl, prefix, parts) {
const line = document.createElement("p");
line.className = "planet-text detail-inline-value";
if (prefix) {
line.appendChild(document.createTextNode(prefix));
}
appendInlineParts(line, parts);
containerEl.appendChild(line);
}
function renderCorrespondence(entry, containerEl) { function renderCorrespondence(entry, containerEl) {
if (!containerEl) return; if (!containerEl) return;
containerEl.innerHTML = ""; containerEl.innerHTML = "";
@@ -249,6 +284,7 @@
fallback.className = "planet-text"; fallback.className = "planet-text";
fallback.textContent = "No tarot/day correspondence in current local dataset."; fallback.textContent = "No tarot/day correspondence in current local dataset.";
containerEl.appendChild(fallback); containerEl.appendChild(fallback);
return;
} }
const symbol = correspondence?.symbol || ""; const symbol = correspondence?.symbol || "";
@@ -265,85 +301,61 @@
containerEl.appendChild(line); containerEl.appendChild(line);
} }
// Tarot card link
if (arcana) { if (arcana) {
const btn = document.createElement("button"); const btn = createInlineButton(
btn.type = "button"; trumpNo != null ? `${arcanaLabel} · Trump ${trumpNo}` : arcanaLabel,
btn.className = "kab-tarot-link"; () => {
btn.style.marginTop = "8px";
btn.textContent = trumpNo != null ? `${arcanaLabel} \u00b7 Trump ${trumpNo}` : arcanaLabel;
btn.title = "Open in Tarot section";
btn.addEventListener("click", () => {
document.dispatchEvent(new CustomEvent("nav:tarot-trump", { document.dispatchEvent(new CustomEvent("nav:tarot-trump", {
detail: { trumpNumber: trumpNo ?? null, cardName: arcana } detail: { trumpNumber: trumpNo ?? null, cardName: arcana }
})); }));
}); }
containerEl.appendChild(btn); );
btn.title = "Open in Tarot section";
appendInlineLine(containerEl, "Tarot ", [btn]);
} }
const planetId = toPlanetId(correspondence?.id || entry?.id || entry?.name) || const planetId = toPlanetId(correspondence?.id || entry?.id || entry?.name) ||
normalizePlanetToken(correspondence?.id || entry?.id || entry?.name); normalizePlanetToken(correspondence?.id || entry?.id || entry?.name);
const kabbalahTargets = state.kabbalahTargetsByPlanetId[planetId] || []; const kabbalahTargets = state.kabbalahTargetsByPlanetId[planetId] || [];
if (kabbalahTargets.length) { if (kabbalahTargets.length) {
const row = document.createElement("div"); const parts = [];
row.className = "kab-god-links"; kabbalahTargets.forEach((target, index) => {
row.style.marginTop = "8px"; if (index > 0) {
parts.push(", ");
kabbalahTargets.forEach((target) => { }
const btn = document.createElement("button"); parts.push(createInlineButton(target.label, () => {
btn.type = "button";
btn.className = "kab-god-link";
btn.textContent = `View ${target.label}`;
btn.addEventListener("click", () => {
document.dispatchEvent(new CustomEvent("nav:kabbalah-path", { document.dispatchEvent(new CustomEvent("nav:kabbalah-path", {
detail: { pathNo: Number(target.number) } detail: { pathNo: Number(target.number) }
})); }));
}));
}); });
row.appendChild(btn); appendInlineLine(containerEl, "Kabbalah ", parts);
});
containerEl.appendChild(row);
} }
const monthRefs = state.monthRefsByPlanetId.get(planetId) || []; const monthRefs = state.monthRefsByPlanetId.get(planetId) || [];
if (monthRefs.length) { if (monthRefs.length) {
const meta = document.createElement("div"); const parts = [];
meta.className = "kab-god-meta"; monthRefs.forEach((month, index) => {
meta.textContent = "Calendar month correspondences"; if (index > 0) {
containerEl.appendChild(meta); parts.push(", ");
}
const row = document.createElement("div"); parts.push(createInlineButton(month.label || month.name, () => {
row.className = "kab-god-links";
monthRefs.forEach((month) => {
const btn = document.createElement("button");
btn.type = "button";
btn.className = "kab-god-link";
btn.textContent = `${month.label || month.name}`;
btn.addEventListener("click", () => {
document.dispatchEvent(new CustomEvent("nav:calendar-month", { document.dispatchEvent(new CustomEvent("nav:calendar-month", {
detail: { monthId: month.id } detail: { monthId: month.id }
})); }));
}));
}); });
row.appendChild(btn); appendInlineLine(containerEl, "Calendar months ", parts);
});
containerEl.appendChild(row);
} }
const cubePlacements = state.cubePlacementsByPlanetId.get(planetId) || []; const cubePlacements = state.cubePlacementsByPlanetId.get(planetId) || [];
if (cubePlacements.length) { if (cubePlacements.length) {
const meta = document.createElement("div"); const parts = [];
meta.className = "kab-god-meta"; cubePlacements.forEach((placement, index) => {
meta.textContent = "Cube placements"; if (index > 0) {
containerEl.appendChild(meta); parts.push(", ");
}
const row = document.createElement("div"); parts.push(createInlineButton(placement.label, () => {
row.className = "kab-god-links";
cubePlacements.forEach((placement) => {
const btn = document.createElement("button");
btn.type = "button";
btn.className = "kab-god-link";
btn.textContent = `${placement.label}`;
btn.addEventListener("click", () => {
document.dispatchEvent(new CustomEvent("nav:cube", { document.dispatchEvent(new CustomEvent("nav:cube", {
detail: { detail: {
planetId, planetId,
@@ -351,10 +363,9 @@
edgeId: placement.edgeId edgeId: placement.edgeId
} }
})); }));
}));
}); });
row.appendChild(btn); appendInlineLine(containerEl, "Cube placements ", parts);
});
containerEl.appendChild(row);
} }
} }
+10 -27
View File
@@ -164,22 +164,14 @@
sections.push(`<div class="planet-meta-card"> sections.push(`<div class="planet-meta-card">
<strong>Ruling Planet</strong> <strong>Ruling Planet</strong>
<div class="planet-text"> <div class="planet-text">
<p style="font-size:22px;margin:0 0 6px">${planetSym} ${cap(sign.planetId)}</p> <p style="font-size:22px;margin:0">${planetSym} <button class="detail-inline-link" data-nav="planet" data-planet-id="${sign.planetId}">${cap(sign.planetId)}</button></p>
<button class="alpha-nav-btn" data-nav="planet" data-planet-id="${sign.planetId}">
View ${cap(sign.planetId)}
</button>
</div> </div>
</div>`); </div>`);
if (cubePlacement) { if (cubePlacement) {
sections.push(`<div class="planet-meta-card"> sections.push(`<div class="planet-meta-card">
<strong>Cube of Space</strong> <strong>Cube of Space</strong>
<div class="planet-text">This sign appears in Cube edge correspondences.</div> <div class="planet-text">This sign appears at <button class="detail-inline-link" data-nav="cube-sign" data-sign-id="${sign.id}" data-wall-id="${cubePlacement.wallId}" data-edge-id="${cubePlacement.edgeId}">${cubePlacementLabel(cubePlacement)}</button>.</div>
<div class="alpha-nav-btns">
<button class="alpha-nav-btn" data-nav="cube-sign" data-sign-id="${sign.id}" data-wall-id="${cubePlacement.wallId}" data-edge-id="${cubePlacement.edgeId}">
${cubePlacementLabel(cubePlacement)}
</button>
</div>
</div>`); </div>`);
} }
@@ -193,21 +185,13 @@
<span class="zod-hebrew-glyph">${hl.char || ""}</span> <span class="zod-hebrew-glyph">${hl.char || ""}</span>
<div> <div>
<div style="font-weight:600">${hl.transliteration || ""} (${hl.meaning || ""})</div> <div style="font-weight:600">${hl.transliteration || ""} (${hl.meaning || ""})</div>
<div class="planet-list-meta">${cap(hl.letterType || "")} letter · Path ${kabPath.pathNumber}</div> <div class="planet-list-meta">${cap(hl.letterType || "")} letter · <button class="detail-inline-link" data-nav="kab-path" data-path-number="${kabPath.pathNumber}">Path ${kabPath.pathNumber}</button></div>
</div> </div>
</div> </div>
<dl class="alpha-dl" style="margin-bottom:8px"> <dl class="alpha-dl">
<dt>Trump Card</dt><dd>${kabPath.tarot?.card || "—"}</dd> <dt>Trump Card</dt><dd>${kabPath.tarot?.card ? `<button class="detail-inline-link" data-nav="trump" data-trump-number="${kabPath.tarot?.trumpNumber}">${kabPath.tarot.card}</button>` : "—"}</dd>
<dt>Intelligence</dt><dd>${kabPath.intelligence || "—"}</dd> <dt>Intelligence</dt><dd>${kabPath.intelligence || "—"}</dd>
</dl> </dl>
<div class="alpha-nav-btns">
<button class="alpha-nav-btn" data-nav="kab-path" data-path-number="${kabPath.pathNumber}">
Kabbalah Path ${kabPath.pathNumber}
</button>
<button class="alpha-nav-btn" data-nav="trump" data-trump-number="${kabPath.tarot?.trumpNumber}">
${kabPath.tarot?.card || "Tarot Card"}
</button>
</div>
</div> </div>
</div>`); </div>`);
} }
@@ -220,8 +204,8 @@
return `<div class="zod-decan-row"> return `<div class="zod-decan-row">
<span class="zod-decan-ord">${ord}</span> <span class="zod-decan-ord">${ord}</span>
<span class="zod-decan-planet">${sym} ${cap(d.rulerPlanetId)}</span> <span class="zod-decan-planet">${sym} ${cap(d.rulerPlanetId)}</span>
<button class="zod-decan-card-btn" data-nav="tarot-card" data-card-name="${d.tarotMinorArcana}"> <button class="detail-inline-link" data-nav="tarot-card" data-card-name="${d.tarotMinorArcana}">
${d.tarotMinorArcana} ${d.tarotMinorArcana}
</button> </button>
</div>`; </div>`;
}).join(""); }).join("");
@@ -233,13 +217,12 @@
if (monthRefs.length) { if (monthRefs.length) {
const monthButtons = monthRefs.map((month) => const monthButtons = monthRefs.map((month) =>
`<button class="alpha-nav-btn" data-nav="calendar-month" data-month-id="${month.id}">${month.name}</button>` `<button class="detail-inline-link" data-nav="calendar-month" data-month-id="${month.id}">${month.name}</button>`
).join(""); ).join(", ");
sections.push(`<div class="planet-meta-card"> sections.push(`<div class="planet-meta-card">
<strong>Calendar Months</strong> <strong>Calendar Months</strong>
<div class="planet-text">Month correspondences linked to ${sign.name?.en || sign.id}.</div> <div class="planet-text">Month correspondences linked to ${sign.name?.en || sign.id}: ${monthButtons}</div>
<div class="alpha-nav-btns">${monthButtons}</div>
</div>`); </div>`);
} }
+6 -6
View File
@@ -16,7 +16,7 @@
<link rel="stylesheet" href="node_modules/@fontsource/amiri/arabic-400.css"> <link rel="stylesheet" href="node_modules/@fontsource/amiri/arabic-400.css">
<link rel="stylesheet" href="node_modules/@fontsource/amiri/arabic-700.css"> <link rel="stylesheet" href="node_modules/@fontsource/amiri/arabic-700.css">
<link rel="stylesheet" href="node_modules/@fontsource/noto-naskh-arabic/arabic-400.css"> <link rel="stylesheet" href="node_modules/@fontsource/noto-naskh-arabic/arabic-400.css">
<link rel="stylesheet" href="app/styles.css?v=20260415-stellarium-toggle-01"> <link rel="stylesheet" href="app/styles.css?v=20260424-detail-inline-links-01">
</head> </head>
<body> <body>
<div class="topbar"> <div class="topbar">
@@ -1207,18 +1207,18 @@
<script src="app/ui-tarot-relation-display.js?v=20260307b"></script> <script src="app/ui-tarot-relation-display.js?v=20260307b"></script>
<script src="app/ui-tarot.js?v=20260402-frame-lightbox-01"></script> <script src="app/ui-tarot.js?v=20260402-frame-lightbox-01"></script>
<script src="app/ui-planets-references.js"></script> <script src="app/ui-planets-references.js"></script>
<script src="app/ui-planets.js"></script> <script src="app/ui-planets.js?v=20260424-detail-inline-links-01"></script>
<script src="app/ui-cycles.js"></script> <script src="app/ui-cycles.js"></script>
<script src="app/ui-elements.js"></script> <script src="app/ui-elements.js?v=20260424-detail-inline-links-01"></script>
<script src="app/ui-audio-notes.js?v=20260314-audio-notes-02"></script> <script src="app/ui-audio-notes.js?v=20260314-audio-notes-02"></script>
<script src="app/ui-audio-circle.js?v=20260314-audio-circle-01"></script> <script src="app/ui-audio-circle.js?v=20260314-audio-circle-01"></script>
<script src="app/ui-iching-references.js"></script> <script src="app/ui-iching-references.js"></script>
<script src="app/ui-iching.js"></script> <script src="app/ui-iching.js"></script>
<script src="app/ui-rosicrucian-cross.js"></script> <script src="app/ui-rosicrucian-cross.js"></script>
<script src="app/ui-kabbalah-detail.js"></script> <script src="app/ui-kabbalah-detail.js?v=20260424-detail-inline-links-01"></script>
<script src="app/ui-kabbalah-views.js"></script> <script src="app/ui-kabbalah-views.js"></script>
<script src="app/ui-kabbalah.js?v=20260312-tree-export-01"></script> <script src="app/ui-kabbalah.js?v=20260312-tree-export-01"></script>
<script src="app/ui-cube-detail.js?v=20260424-cube-links-01"></script> <script src="app/ui-cube-detail.js?v=20260424-detail-inline-links-01"></script>
<script src="app/ui-cube-chassis.js?v=20260424-cube-fixes-01"></script> <script src="app/ui-cube-chassis.js?v=20260424-cube-fixes-01"></script>
<script src="app/ui-cube-math.js"></script> <script src="app/ui-cube-math.js"></script>
<script src="app/ui-cube-selection.js?v=20260424-cube-fixes-01"></script> <script src="app/ui-cube-selection.js?v=20260424-cube-fixes-01"></script>
@@ -1231,7 +1231,7 @@
<script src="app/ui-alphabet.js?v=20260308b"></script> <script src="app/ui-alphabet.js?v=20260308b"></script>
<script src="app/ui-alphabet-text.js?v=20260315-text-search-ui-01"></script> <script src="app/ui-alphabet-text.js?v=20260315-text-search-ui-01"></script>
<script src="app/ui-zodiac-references.js"></script> <script src="app/ui-zodiac-references.js"></script>
<script src="app/ui-zodiac.js"></script> <script src="app/ui-zodiac.js?v=20260424-detail-inline-links-01"></script>
<script src="app/ui-quiz-bank-builtins-domains.js"></script> <script src="app/ui-quiz-bank-builtins-domains.js"></script>
<script src="app/ui-quiz-bank-builtins.js"></script> <script src="app/ui-quiz-bank-builtins.js"></script>
<script src="app/ui-quiz-bank.js"></script> <script src="app/ui-quiz-bank.js"></script>