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;
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,
@@ -5298,6 +5319,9 @@
}
}
.alpha-dl dd { margin: 0; }
.alpha-dl dd .detail-inline-link {
vertical-align: baseline;
}
.alpha-badge {
display: inline-block;
padding: 1px 7px;
+259 -203
View File
@@ -40,21 +40,68 @@
return card;
}
function appendLinkRow(card, buttons) {
const validButtons = Array.isArray(buttons)
? buttons.filter((button) => button instanceof Node)
: [];
if (!(card instanceof HTMLElement) || !validButtons.length) {
return card;
}
function appendInlineParts(target, parts) {
(Array.isArray(parts) ? parts : []).forEach((part) => {
if (part instanceof Node) {
target.appendChild(part);
return;
}
const row = document.createElement("div");
row.className = "kab-god-links";
validButtons.forEach((button) => {
row.appendChild(button);
const text = String(part ?? "");
if (text) {
target.appendChild(document.createTextNode(text));
}
});
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) {
@@ -92,42 +139,45 @@
const bodyEl = elements.detailBodyEl;
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 detailButtons = [];
if (centerLetterId) {
detailButtons.push(createNavButton(centerLetter || "!", "nav:alphabet", {
alphabet: "hebrew",
hebrewLetterId: centerLetterId
}));
}
const centerTrumpNo = toFiniteNumber(associations?.tarotTrumpNumber);
const centerTarotCard = toDisplayText(associations?.tarotCard);
if (centerTarotCard || centerTrumpNo != null) {
detailButtons.push(createNavButton(centerTarotCard || `Trump ${centerTrumpNo}`, "nav:tarot-trump", {
cardName: centerTarotCard,
trumpNumber: centerTrumpNo
}));
}
const centerPathNo = toFiniteNumber(associations?.kabbalahPathNumber);
if (centerPathNo != null) {
detailButtons.push(createNavButton(`Path ${centerPathNo}`, "nav:kabbalah-path", {
pathNo: centerPathNo
}));
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) {
summaryRows.push({
label: "Tarot",
value: createInlineEventLink(centerTarotCard || `Trump ${centerTrumpNo}`, "nav:tarot-trump", {
cardName: centerTarotCard,
trumpNumber: centerTrumpNo
})
});
}
bodyEl.appendChild(appendLinkRow(createMetaCard("Center Details", summary), detailButtons));
if (centerPathNo != null) {
summaryRows.push({
label: "Path",
value: createInlineEventLink(`Path ${centerPathNo}`, "nav:kabbalah-path", {
pathNo: centerPathNo
})
});
}
bodyEl.appendChild(createMetaCard("Center Details", createDetailList(summaryRows)));
if (Array.isArray(center?.keywords) && center.keywords.length) {
bodyEl.appendChild(createMetaCard("Keywords", center.keywords.join(", ")));
@@ -185,37 +235,52 @@
const bodyEl = elements.detailBodyEl;
bodyEl.innerHTML = "";
const summary = document.createElement("div");
summary.className = "planet-text";
summary.innerHTML = `
<dl class="alpha-dl">
<dt>Letter</dt><dd>${toDetailValueMarkup(letterText)}</dd>
<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 = [];
const connectorRows = [
{
label: "Letter",
value: letterId
? createInlineEventLink(letterText, "nav:alphabet", {
alphabet: "hebrew",
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 (letterId) {
connectorButtons.push(createNavButton(letterSymbol || "!", "nav:alphabet", {
alphabet: "hebrew",
hebrewLetterId: letterId
}));
if (tarotCard || tarotTrumpNumber != null) {
connectorRows.push({
label: "Tarot",
value: createInlineEventLink(tarotCard || `Trump ${tarotTrumpNumber}`, "nav:tarot-trump", {
cardName: tarotCard,
trumpNumber: tarotTrumpNumber
})
});
}
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) {
connectorButtons.push(createNavButton(tarotCard || `Trump ${tarotTrumpNumber}`, "nav:tarot-trump", {
cardName: tarotCard,
trumpNumber: tarotTrumpNumber
}));
}
bodyEl.appendChild(appendLinkRow(createMetaCard("Connector Details", summary), connectorButtons));
bodyEl.appendChild(createMetaCard("Connector Details", createDetailList(connectorRows)));
if (astrologySummary) {
bodyEl.appendChild(createMetaCard("Astrology", astrologySummary));
@@ -282,18 +347,47 @@
title.textContent = `Edge · ${edgeName}`;
edgeCard.appendChild(title);
const dlWrap = document.createElement("div");
dlWrap.className = "planet-text";
dlWrap.innerHTML = `
<dl class="alpha-dl">
<dt>Direction</dt><dd>${toDetailValueMarkup(edgeName)}</dd>
<dt>Edge</dt><dd>${toDetailValueMarkup(edgeWalls)}</dd>
<dt>Letter</dt><dd>${toDetailValueMarkup(edgeLetter)}</dd>
<dt>Astrology</dt><dd>${toDetailValueMarkup(astrologyText)}</dd>
<dt>Tarot</dt><dd>${toDetailValueMarkup(tarotCard)}</dd>
</dl>
`;
edgeCard.appendChild(dlWrap);
const edgeRows = [
{ label: "Direction", value: edgeName },
{ label: "Edge", value: edgeWalls },
{
label: "Letter",
value: edgeLetterId
? createInlineEventLink(edgeLetter || edgeLetterId, "nav:alphabet", {
alphabet: "hebrew",
hebrewLetterId: edgeLetterId
})
: edgeLetter
},
{
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) {
const keywords = document.createElement("p");
@@ -309,37 +403,6 @@
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);
}
@@ -394,57 +457,47 @@
const bodyEl = elements.detailBodyEl;
bodyEl.innerHTML = "";
const summary = document.createElement("div");
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 faceLetterText = [wallFaceLetter, wallFaceLetterName].filter(Boolean).join(" ");
const faceLetterLabel = faceLetterText
? `Face ${faceLetterText}`
: "Face !";
wallButtons.push(createNavButton(faceLetterLabel, "nav:alphabet", {
alphabet: "hebrew",
hebrewLetterId: wallFaceLetterId
}));
}
const wallAssociations = wall.associations || {};
if (wallAssociations.planetId) {
wallButtons.push(createNavButton(toDisplayText(wall.planet) || "!", "nav:planet", {
planetId: wallAssociations.planetId
}));
}
const wallFaceLetterName = getHebrewLetterName(wallFaceLetterId) || toDisplayText(wallFaceLetterId);
const faceLetterLabel = [wallFaceLetter, wallFaceLetterName].filter(Boolean).join(" ");
const wallRows = [
{
label: "Opposite",
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",
hebrewLetterId: wallFaceLetterId
})
: wallFaceLetterText
},
{ label: "Element", value: wall.element },
{
label: "Planet",
value: wallAssociations.planetId
? createInlineEventLink(toDisplayText(wall.planet) || "!", "nav:planet", {
planetId: wallAssociations.planetId
})
: wall.planet
},
{
label: "Archangel",
value: wallAssociations.godName
? createInlineEventLink(wallAssociations.godName, "nav:gods", {
godName: wallAssociations.godName
})
: wall.archangel
}
];
if (wallAssociations.godName) {
wallButtons.push(createNavButton(wallAssociations.godName, "nav:gods", {
godName: wallAssociations.godName
}));
}
if (wall.oppositeWallId) {
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));
bodyEl.appendChild(createMetaCard("Wall Details", createDetailList(wallRows)));
if (Array.isArray(wall.keywords) && wall.keywords.length) {
bodyEl.appendChild(createMetaCard("Keywords", wall.keywords.join(", ")));
@@ -575,57 +628,60 @@
const bodyEl = elements.detailBodyEl;
bodyEl.innerHTML = "";
const summary = document.createElement("div");
summary.className = "planet-text";
summary.innerHTML = `
<dl class="alpha-dl">
<dt>Name</dt><dd>${toDetailValueMarkup(edgeName)}</dd>
<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 button = document.createElement("button");
button.type = "button";
button.className = "kab-god-link";
button.textContent = `${wall?.name || wallId} Wall`;
button.addEventListener("click", () => {
onSelectWall(wallId);
});
edgeButtons.push(button);
});
if (edgeLetterId) {
edgeButtons.push(createNavButton(edgeLetter || "!", "nav:alphabet", {
alphabet: "hebrew",
hebrewLetterId: edgeLetterId
}));
}
if (astrologyType === "zodiac" && astrologyName) {
edgeButtons.push(createNavButton(astrologyName, "nav:zodiac", {
signId: normalizeId(astrologyName)
}));
}
const edgeRows = [
{ label: "Name", value: edgeName },
{
label: "Between",
value: createInlineValue(edgeWalls.flatMap((wallId, index) => {
const wall = getWallById(wallId);
const parts = [];
if (index > 0) {
parts.push(" ↔ ");
}
parts.push(createInlineActionLink(wall?.name || wallId, () => {
onSelectWall(wallId);
}));
return parts;
}))
},
{
label: "Letter",
value: edgeLetterId
? createInlineEventLink(edgeLetterText || edgeLetterId, "nav:alphabet", {
alphabet: "hebrew",
hebrewLetterId: edgeLetterId
})
: edgeLetterText
},
{
label: "Astrology",
value: astrologyType === "zodiac" && astrologyName
? createInlineValue([
astrologySymbol ? `${astrologySymbol} ` : "",
createInlineEventLink(astrologyName, "nav:zodiac", { signId: normalizeId(astrologyName) })
])
: astrologyText
}
];
if (tarotCard || tarotTrumpNumber != null) {
edgeButtons.push(createNavButton(tarotCard || `Trump ${tarotTrumpNumber}`, "nav:tarot-trump", {
cardName: tarotCard,
trumpNumber: tarotTrumpNumber
}));
edgeRows.push({
label: "Tarot",
value: createInlineEventLink(tarotCard || `Trump ${tarotTrumpNumber}`, "nav:tarot-trump", {
cardName: tarotCard,
trumpNumber: tarotTrumpNumber
})
});
}
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) {
bodyEl.appendChild(createMetaCard("Keywords", edge.keywords.join(", ")));
+80 -55
View File
@@ -90,6 +90,38 @@
.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) {
if (typeof getTarotCardSearchAliases !== "function") {
return Array.isArray(cardNames) ? cardNames.join(" ") : "";
@@ -252,47 +284,44 @@
const tarotTitle = document.createElement("strong");
tarotTitle.textContent = "Tarot Correspondence";
const tarotText = document.createElement("div");
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) {
const tarotBtn = document.createElement("button");
tarotBtn.type = "button";
tarotBtn.className = "alpha-nav-btn";
tarotBtn.textContent = `Open ${entry.aceCardName}`;
tarotBtn.addEventListener("click", () => {
const tarotParts = [];
if (entry.aceCardName) {
tarotParts.push(
"Ace: ",
createInlineButton(entry.aceCardName, () => {
document.dispatchEvent(new CustomEvent("nav:tarot-trump", {
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 courtBtn = document.createElement("button");
courtBtn.type = "button";
courtBtn.className = "alpha-nav-btn";
courtBtn.textContent = `Open ${cardName}`;
courtBtn.addEventListener("click", () => {
const tarotText = tarotParts.length
? createInlineParagraph(tarotParts)
: document.createTextNode("--");
tarotCard.append(tarotTitle, tarotText);
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", {
detail: { cardName }
}));
});
navWrap.appendChild(courtBtn);
}));
});
tarotCard.appendChild(navWrap);
tarotCard.appendChild(createInlineParagraph(courtParts));
}
const smallCardCard = document.createElement("div");
@@ -317,36 +346,32 @@
`;
row.appendChild(head);
const navWrap = document.createElement("div");
navWrap.className = "alpha-nav-btns";
if (group.signId) {
const signBtn = document.createElement("button");
signBtn.type = "button";
signBtn.className = "alpha-nav-btn";
signBtn.textContent = `Open ${group.signName}`;
signBtn.addEventListener("click", () => {
document.dispatchEvent(new CustomEvent("nav:zodiac", {
detail: { signId: group.signId }
}));
});
navWrap.appendChild(signBtn);
row.appendChild(createInlineParagraph([
"Sign: ",
createInlineButton(group.signName, () => {
document.dispatchEvent(new CustomEvent("nav:zodiac", {
detail: { signId: group.signId }
}));
})
]));
}
(group.cardNames || []).forEach((cardName) => {
const cardBtn = document.createElement("button");
cardBtn.type = "button";
cardBtn.className = "alpha-nav-btn";
cardBtn.textContent = `Open ${cardName}`;
cardBtn.addEventListener("click", () => {
document.dispatchEvent(new CustomEvent("nav:tarot-trump", {
detail: { cardName }
if ((group.cardNames || []).length) {
const cardParts = ["Cards: "];
group.cardNames.forEach((cardName, index) => {
if (index > 0) {
cardParts.push(", ");
}
cardParts.push(createInlineButton(cardName, () => {
document.dispatchEvent(new CustomEvent("nav:tarot-trump", {
detail: { cardName }
}));
}));
});
navWrap.appendChild(cardBtn);
});
row.appendChild(createInlineParagraph(cardParts));
}
row.appendChild(navWrap);
smallCardStack.appendChild(row);
});
+116 -75
View File
@@ -76,10 +76,55 @@
function metaCard(label, value, wide) {
const card = document.createElement("div");
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;
}
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) {
const btn = document.createElement("button");
btn.type = "button";
@@ -91,31 +136,22 @@
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) {
const card = metaCard("Planet / Luminary", planetValue);
const planetId = context.resolvePlanetId(planetValue);
if (planetId) {
appendLinkRow(card, [
createNavButton(`View ${PLANET_ID_TO_LABEL[planetId] || planetValue} in Planets`, "nav:planet", { planetId })
]);
return card;
return metaCard("Planet / Luminary", inlineValue([
createInlineEventLink(PLANET_ID_TO_LABEL[planetId] || planetValue, "nav:planet", { planetId })
]));
}
const zodiacId = context.resolveZodiacId(planetValue);
if (zodiacId) {
appendLinkRow(card, [
createNavButton(`View ${zodiacId.charAt(0).toUpperCase() + zodiacId.slice(1)} in Zodiac`, "nav:zodiac", { signId: zodiacId })
]);
return metaCard("Planet / Luminary", inlineValue([
createInlineEventLink(zodiacId.charAt(0).toUpperCase() + zodiacId.slice(1), "nav:zodiac", { signId: zodiacId })
]));
}
return card;
return metaCard("Planet / Luminary", planetValue);
}
function extractMinorRank(attribution) {
@@ -131,61 +167,70 @@
}
function buildTarotAttributionCard(attribution) {
const card = metaCard("Tarot Attribution", attribution);
const minorCards = buildMinorTarotNames(attribution);
if (minorCards.length) {
appendLinkRow(card, minorCards.map((cardName) =>
createNavButton(cardName, "nav:tarot-trump", { cardName })
));
const parts = [];
minorCards.forEach((cardName, index) => {
if (index > 0) {
parts.push(", ");
}
parts.push(createInlineEventLink(cardName, "nav:tarot-trump", { cardName }));
});
return metaCard("Tarot Attribution", inlineValue(parts));
}
return card;
return metaCard("Tarot Attribution", attribution);
}
function buildAstrologyCard(astrology, context) {
const astroText = astrology ? `${astrology.name} (${astrology.type})` : "—";
const card = metaCard("Astrology", astroText);
if (astrology?.type === "planet") {
const planetId = context.resolvePlanetId(astrology.name);
if (planetId) {
appendLinkRow(card, [
createNavButton(`View ${PLANET_ID_TO_LABEL[planetId] || astrology.name} in Planets`, "nav:planet", { planetId })
]);
return metaCard("Astrology", inlineValue([
createInlineEventLink(PLANET_ID_TO_LABEL[planetId] || astrology.name, "nav:planet", { planetId }),
" (planet)"
]));
}
} else if (astrology?.type === "zodiac") {
const signId = context.resolveZodiacId(astrology.name);
if (signId) {
appendLinkRow(card, [
createNavButton(`View ${signId.charAt(0).toUpperCase() + signId.slice(1)} in Zodiac`, "nav:zodiac", { signId })
]);
return metaCard("Astrology", inlineValue([
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) {
const card = metaCard("Connects", `${fromName}${toName}`);
appendLinkRow(card, [
createNavButton(`View ${fromName}`, "nav:kabbalah-path", { pathNo: Number(path.connects.from) }),
createNavButton(`View ${toName}`, "nav:kabbalah-path", { pathNo: Number(path.connects.to) })
]);
return card;
return metaCard("Connects", inlineValue([
createInlineEventLink(fromName, "nav:kabbalah-path", { pathNo: Number(path.connects.from) }),
" → ",
createInlineEventLink(toName, "nav:kabbalah-path", { pathNo: Number(path.connects.to) })
]));
}
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 letterLabel = `${letter.char || ""} ${letter.transliteration || ""}`.replace(/\s+/g, " ").trim() || "Letter";
const suffix = [
letter.meaning ? ` — "${letter.meaning}"` : "",
letter.letterType ? ` (${letter.letterType})` : ""
].join("");
if (hebrewLetterId) {
appendLinkRow(card, [
createNavButton(`View ${letter.transliteration || letter.char || "Letter"} in Alphabet`, "nav:alphabet", {
return metaCard("Hebrew Letter", inlineValue([
createInlineEventLink(letterLabel, "nav:alphabet", {
alphabet: "hebrew",
hebrewLetterId
})
]);
}),
suffix
]));
}
return card;
return metaCard("Hebrew Letter", `${letterLabel}${suffix}`);
}
function buildFourWorldsCard(tree, activeHebrewToken, context) {
@@ -228,11 +273,11 @@
soulLine.textContent = `${layer.soulLayer}${layer.soulTitle}: ${layer.soulDescription}`;
row.appendChild(soulLine);
const buttonRow = [];
const parts = [];
const hebrewLetterId = context.resolveHebrewLetterId(layer.hebrewToken);
if (hebrewLetterId) {
buttonRow.push(
createNavButton(`View ${layer.letterChar} in Alphabet`, "nav:alphabet", {
parts.push(
createInlineEventLink(layer.letterChar || layer.hebrewToken, "nav:alphabet", {
alphabet: "hebrew",
hebrewLetterId
})
@@ -241,12 +286,17 @@
const linkedPath = context.findPathByHebrewToken(tree, layer.hebrewToken);
if (linkedPath?.pathNumber != null) {
buttonRow.push(
createNavButton(`View Path ${linkedPath.pathNumber}`, "nav:kabbalah-path", { pathNo: Number(linkedPath.pathNumber) })
if (parts.length) {
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) {
row.style.borderColor = "#818cf8";
@@ -293,23 +343,18 @@
card.appendChild(meta);
}
const row = document.createElement("div");
row.className = "kab-god-links";
names.forEach((name) => {
const btn = document.createElement("button");
btn.type = "button";
btn.className = "kab-god-link";
btn.textContent = name;
btn.addEventListener("click", () => {
document.dispatchEvent(new CustomEvent("nav:gods", {
detail: { godName: name, pathNo: Number(pathNo) }
}));
});
row.appendChild(btn);
const parts = [];
names.forEach((name, index) => {
if (index > 0) {
parts.push(", ");
}
parts.push(createInlineEventLink(name, "nav:gods", {
godName: name,
pathNo: Number(pathNo)
}));
});
card.appendChild(row);
card.appendChild(inlineValue(parts));
return card;
}
@@ -450,16 +495,12 @@
tarotLabel.textContent = "Tarot";
tarotMetaCard.appendChild(tarotLabel);
if (path.tarot?.card && path.tarot.trumpNumber != null) {
const tarotBtn = document.createElement("button");
tarotBtn.type = "button";
tarotBtn.className = "kab-tarot-link";
tarotBtn.textContent = `${path.tarot.card} · Trump ${path.tarot.trumpNumber}`;
const tarotBtn = createInlineEventLink(
`${path.tarot.card} · Trump ${path.tarot.trumpNumber}`,
"kab:view-trump",
{ trumpNumber: path.tarot.trumpNumber }
);
tarotBtn.title = "Open in Tarot section";
tarotBtn.addEventListener("click", () => {
document.dispatchEvent(new CustomEvent("kab:view-trump", {
detail: { trumpNumber: path.tarot.trumpNumber }
}));
});
tarotMetaCard.appendChild(tarotBtn);
} else {
const tarotP = document.createElement("p");
+69 -58
View File
@@ -238,6 +238,41 @@
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) {
if (!containerEl) return;
containerEl.innerHTML = "";
@@ -249,6 +284,7 @@
fallback.className = "planet-text";
fallback.textContent = "No tarot/day correspondence in current local dataset.";
containerEl.appendChild(fallback);
return;
}
const symbol = correspondence?.symbol || "";
@@ -265,85 +301,61 @@
containerEl.appendChild(line);
}
// Tarot card link
if (arcana) {
const btn = document.createElement("button");
btn.type = "button";
btn.className = "kab-tarot-link";
btn.style.marginTop = "8px";
btn.textContent = trumpNo != null ? `${arcanaLabel} \u00b7 Trump ${trumpNo}` : arcanaLabel;
const btn = createInlineButton(
trumpNo != null ? `${arcanaLabel} · Trump ${trumpNo}` : arcanaLabel,
() => {
document.dispatchEvent(new CustomEvent("nav:tarot-trump", {
detail: { trumpNumber: trumpNo ?? null, cardName: arcana }
}));
}
);
btn.title = "Open in Tarot section";
btn.addEventListener("click", () => {
document.dispatchEvent(new CustomEvent("nav:tarot-trump", {
detail: { trumpNumber: trumpNo ?? null, cardName: arcana }
}));
});
containerEl.appendChild(btn);
appendInlineLine(containerEl, "Tarot ", [btn]);
}
const planetId = toPlanetId(correspondence?.id || entry?.id || entry?.name) ||
normalizePlanetToken(correspondence?.id || entry?.id || entry?.name);
const kabbalahTargets = state.kabbalahTargetsByPlanetId[planetId] || [];
if (kabbalahTargets.length) {
const row = document.createElement("div");
row.className = "kab-god-links";
row.style.marginTop = "8px";
kabbalahTargets.forEach((target) => {
const btn = document.createElement("button");
btn.type = "button";
btn.className = "kab-god-link";
btn.textContent = `View ${target.label}`;
btn.addEventListener("click", () => {
const parts = [];
kabbalahTargets.forEach((target, index) => {
if (index > 0) {
parts.push(", ");
}
parts.push(createInlineButton(target.label, () => {
document.dispatchEvent(new CustomEvent("nav:kabbalah-path", {
detail: { pathNo: Number(target.number) }
}));
});
row.appendChild(btn);
}));
});
containerEl.appendChild(row);
appendInlineLine(containerEl, "Kabbalah ", parts);
}
const monthRefs = state.monthRefsByPlanetId.get(planetId) || [];
if (monthRefs.length) {
const meta = document.createElement("div");
meta.className = "kab-god-meta";
meta.textContent = "Calendar month correspondences";
containerEl.appendChild(meta);
const row = document.createElement("div");
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", () => {
const parts = [];
monthRefs.forEach((month, index) => {
if (index > 0) {
parts.push(", ");
}
parts.push(createInlineButton(month.label || month.name, () => {
document.dispatchEvent(new CustomEvent("nav:calendar-month", {
detail: { monthId: month.id }
}));
});
row.appendChild(btn);
}));
});
containerEl.appendChild(row);
appendInlineLine(containerEl, "Calendar months ", parts);
}
const cubePlacements = state.cubePlacementsByPlanetId.get(planetId) || [];
if (cubePlacements.length) {
const meta = document.createElement("div");
meta.className = "kab-god-meta";
meta.textContent = "Cube placements";
containerEl.appendChild(meta);
const row = document.createElement("div");
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", () => {
const parts = [];
cubePlacements.forEach((placement, index) => {
if (index > 0) {
parts.push(", ");
}
parts.push(createInlineButton(placement.label, () => {
document.dispatchEvent(new CustomEvent("nav:cube", {
detail: {
planetId,
@@ -351,10 +363,9 @@
edgeId: placement.edgeId
}
}));
});
row.appendChild(btn);
}));
});
containerEl.appendChild(row);
appendInlineLine(containerEl, "Cube placements ", parts);
}
}
+10 -27
View File
@@ -164,22 +164,14 @@
sections.push(`<div class="planet-meta-card">
<strong>Ruling Planet</strong>
<div class="planet-text">
<p style="font-size:22px;margin:0 0 6px">${planetSym} ${cap(sign.planetId)}</p>
<button class="alpha-nav-btn" data-nav="planet" data-planet-id="${sign.planetId}">
View ${cap(sign.planetId)}
</button>
<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>
</div>
</div>`);
if (cubePlacement) {
sections.push(`<div class="planet-meta-card">
<strong>Cube of Space</strong>
<div class="planet-text">This sign appears in Cube edge correspondences.</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 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>`);
}
@@ -193,21 +185,13 @@
<span class="zod-hebrew-glyph">${hl.char || ""}</span>
<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>
<dl class="alpha-dl" style="margin-bottom:8px">
<dt>Trump Card</dt><dd>${kabPath.tarot?.card || ""}</dd>
<dl class="alpha-dl">
<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>
</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>`);
}
@@ -220,8 +204,8 @@
return `<div class="zod-decan-row">
<span class="zod-decan-ord">${ord}</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}">
${d.tarotMinorArcana}
<button class="detail-inline-link" data-nav="tarot-card" data-card-name="${d.tarotMinorArcana}">
${d.tarotMinorArcana}
</button>
</div>`;
}).join("");
@@ -233,13 +217,12 @@
if (monthRefs.length) {
const monthButtons = monthRefs.map((month) =>
`<button class="alpha-nav-btn" data-nav="calendar-month" data-month-id="${month.id}">${month.name}</button>`
).join("");
`<button class="detail-inline-link" data-nav="calendar-month" data-month-id="${month.id}">${month.name}</button>`
).join(", ");
sections.push(`<div class="planet-meta-card">
<strong>Calendar Months</strong>
<div class="planet-text">Month correspondences linked to ${sign.name?.en || sign.id}.</div>
<div class="alpha-nav-btns">${monthButtons}</div>
<div class="planet-text">Month correspondences linked to ${sign.name?.en || sign.id}: ${monthButtons}</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-700.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>
<body>
<div class="topbar">
@@ -1207,18 +1207,18 @@
<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-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-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-circle.js?v=20260314-audio-circle-01"></script>
<script src="app/ui-iching-references.js"></script>
<script src="app/ui-iching.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.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-math.js"></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-text.js?v=20260315-text-search-ui-01"></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.js"></script>
<script src="app/ui-quiz-bank.js"></script>