update tarot frame settings UI
This commit is contained in:
10
app.js
10
app.js
@@ -397,7 +397,15 @@ window.TarotSpreadUi?.init?.({
|
|||||||
|
|
||||||
window.TarotFrameUi?.init?.({
|
window.TarotFrameUi?.init?.({
|
||||||
ensureTarotSection,
|
ensureTarotSection,
|
||||||
getCards: () => window.TarotSectionUi?.getCards?.() || []
|
getCards: () => window.TarotSectionUi?.getCards?.() || [],
|
||||||
|
getHouseTopCardsVisible: () => window.TarotSectionUi?.getHouseTopCardsVisible?.() !== false,
|
||||||
|
getHouseTopInfoModes: () => window.TarotSectionUi?.getHouseTopInfoModes?.() || {},
|
||||||
|
getHouseBottomCardsVisible: () => window.TarotSectionUi?.getHouseBottomCardsVisible?.() !== false,
|
||||||
|
getHouseBottomInfoModes: () => window.TarotSectionUi?.getHouseBottomInfoModes?.() || {},
|
||||||
|
setHouseTopCardsVisible: (value) => window.TarotSectionUi?.setHouseTopCardsVisible?.(value),
|
||||||
|
setHouseTopInfoMode: (mode, value) => window.TarotSectionUi?.setHouseTopInfoMode?.(mode, value),
|
||||||
|
setHouseBottomCardsVisible: (value) => window.TarotSectionUi?.setHouseBottomCardsVisible?.(value),
|
||||||
|
setHouseBottomInfoMode: (mode, value) => window.TarotSectionUi?.setHouseBottomInfoMode?.(mode, value)
|
||||||
});
|
});
|
||||||
|
|
||||||
sectionStateUi.init?.({
|
sectionStateUi.init?.({
|
||||||
|
|||||||
184
app/styles.css
184
app/styles.css
@@ -903,6 +903,57 @@
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tarot-frame-layout-panel {
|
||||||
|
position: absolute;
|
||||||
|
top: calc(100% + 10px);
|
||||||
|
right: 0;
|
||||||
|
z-index: 26;
|
||||||
|
min-width: 270px;
|
||||||
|
display: grid;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 12px;
|
||||||
|
border: 1px solid #312e81;
|
||||||
|
border-radius: 16px;
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at top, rgba(99, 102, 241, 0.16), transparent 42%),
|
||||||
|
linear-gradient(180deg, rgba(22, 22, 34, 0.98), rgba(10, 10, 18, 0.98));
|
||||||
|
box-shadow: 0 18px 38px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-frame-layout-panel[hidden] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-frame-layout-option {
|
||||||
|
display: grid;
|
||||||
|
gap: 4px;
|
||||||
|
padding: 10px 12px;
|
||||||
|
border: 1px solid rgba(99, 102, 241, 0.28);
|
||||||
|
border-radius: 12px;
|
||||||
|
background: rgba(15, 23, 42, 0.5);
|
||||||
|
color: #cbd5e1;
|
||||||
|
text-align: left;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-frame-layout-option:hover,
|
||||||
|
.tarot-frame-layout-option.is-active {
|
||||||
|
border-color: rgba(129, 140, 248, 0.85);
|
||||||
|
background: rgba(49, 46, 129, 0.44);
|
||||||
|
color: #f8fafc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-frame-layout-option strong {
|
||||||
|
font-size: 13px;
|
||||||
|
letter-spacing: 0.03em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-frame-layout-option span {
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.35;
|
||||||
|
}
|
||||||
|
|
||||||
.tarot-frame-action-btn {
|
.tarot-frame-action-btn {
|
||||||
padding: 10px 14px;
|
padding: 10px 14px;
|
||||||
border: 1px solid #4c1d95;
|
border: 1px solid #4c1d95;
|
||||||
@@ -937,6 +988,67 @@
|
|||||||
box-shadow: 0 18px 38px rgba(0, 0, 0, 0.3);
|
box-shadow: 0 18px 38px rgba(0, 0, 0, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tarot-frame-settings-group {
|
||||||
|
display: grid;
|
||||||
|
gap: 10px;
|
||||||
|
padding-top: 2px;
|
||||||
|
border-top: 1px solid rgba(99, 102, 241, 0.18);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-frame-settings-group[hidden] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-frame-settings-heading {
|
||||||
|
color: #f8fafc;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.06em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-frame-settings-subheading {
|
||||||
|
color: #cbd5e1;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-frame-settings-note {
|
||||||
|
color: #94a3b8;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 1.45;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-frame-checkbox-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-frame-check {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
min-width: 0;
|
||||||
|
padding: 8px 9px;
|
||||||
|
border: 1px solid rgba(99, 102, 241, 0.24);
|
||||||
|
border-radius: 10px;
|
||||||
|
background: rgba(15, 23, 42, 0.4);
|
||||||
|
color: #dbe4f0;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.2;
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-frame-check input {
|
||||||
|
margin: 0;
|
||||||
|
accent-color: #818cf8;
|
||||||
|
}
|
||||||
|
|
||||||
.tarot-frame-settings-panel[hidden] {
|
.tarot-frame-settings-panel[hidden] {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
@@ -963,6 +1075,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tarot-frame-toggle input:disabled,
|
.tarot-frame-toggle input:disabled,
|
||||||
|
.tarot-frame-check input:disabled,
|
||||||
|
.tarot-frame-layout-option:disabled,
|
||||||
.tarot-frame-export-btn:disabled,
|
.tarot-frame-export-btn:disabled,
|
||||||
.tarot-frame-settings-toggle:disabled {
|
.tarot-frame-settings-toggle:disabled {
|
||||||
cursor: wait;
|
cursor: wait;
|
||||||
@@ -1171,6 +1285,54 @@
|
|||||||
linear-gradient(180deg, #1e1b4b 0%, #0f172a 100%);
|
linear-gradient(180deg, #1e1b4b 0%, #0f172a 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tarot-frame-card-text-face {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: grid;
|
||||||
|
align-content: center;
|
||||||
|
justify-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
padding: 6px 5px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #fafafa;
|
||||||
|
text-align: center;
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at top, rgba(99, 102, 241, 0.16), transparent 55%),
|
||||||
|
linear-gradient(180deg, rgba(30, 41, 59, 0.94), rgba(15, 23, 42, 0.94));
|
||||||
|
pointer-events: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-frame-card-text-face.is-dense {
|
||||||
|
gap: 3px;
|
||||||
|
padding: 5px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-frame-card-text-face.is-top-hebrew .tarot-frame-card-text-primary {
|
||||||
|
font-size: clamp(11px, 1vw, 16px);
|
||||||
|
line-height: 1;
|
||||||
|
font-family: "Noto Sans Hebrew", "Segoe UI Symbol", sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-frame-card-text-primary {
|
||||||
|
display: block;
|
||||||
|
font-size: clamp(7px, 0.78vw, 10px);
|
||||||
|
line-height: 1.15;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-frame-card-text-secondary {
|
||||||
|
display: block;
|
||||||
|
color: rgba(250, 250, 250, 0.76);
|
||||||
|
font-size: clamp(6px, 0.7vw, 8px);
|
||||||
|
line-height: 1.2;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
|
||||||
.tarot-frame-card-badge {
|
.tarot-frame-card-badge {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 4px;
|
left: 4px;
|
||||||
@@ -1262,6 +1424,11 @@
|
|||||||
right: auto;
|
right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tarot-frame-layout-panel {
|
||||||
|
left: 0;
|
||||||
|
right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.tarot-frame-panel {
|
.tarot-frame-panel {
|
||||||
padding: 14px;
|
padding: 14px;
|
||||||
}
|
}
|
||||||
@@ -1274,6 +1441,23 @@
|
|||||||
font-size: 7px;
|
font-size: 7px;
|
||||||
padding: 3px 4px;
|
padding: 3px 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tarot-frame-card-text-face {
|
||||||
|
gap: 2px;
|
||||||
|
padding: 4px 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-frame-card-text-face.is-top-hebrew .tarot-frame-card-text-primary {
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-frame-card-text-primary {
|
||||||
|
font-size: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-frame-card-text-secondary {
|
||||||
|
font-size: 5px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.tarot-house-card-head {
|
.tarot-house-card-head {
|
||||||
|
|||||||
@@ -43,6 +43,40 @@
|
|||||||
throw new Error("Tarot database assembly dependencies are incomplete");
|
throw new Error("Tarot database assembly dependencies are incomplete");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildTokenDateRange(startToken, endToken) {
|
||||||
|
const parseToken = (value) => {
|
||||||
|
const match = String(value || "").trim().match(/^(\d{2})-(\d{2})$/);
|
||||||
|
if (!match) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const month = Number(match[1]);
|
||||||
|
const day = Number(match[2]);
|
||||||
|
if (!Number.isFinite(month) || !Number.isFinite(day)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Date(2025, month - 1, day);
|
||||||
|
};
|
||||||
|
|
||||||
|
const start = parseToken(startToken);
|
||||||
|
const endBase = parseToken(endToken);
|
||||||
|
if (!start || !endBase) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const wraps = endBase.getTime() < start.getTime();
|
||||||
|
const end = wraps ? new Date(2026, endBase.getMonth(), endBase.getDate()) : endBase;
|
||||||
|
|
||||||
|
return {
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
startToken: startToken || null,
|
||||||
|
endToken: endToken || null,
|
||||||
|
label: `${formatMonthDayLabel(start)}–${formatMonthDayLabel(end)}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function buildMajorCards(referenceData, magickDataset) {
|
function buildMajorCards(referenceData, magickDataset) {
|
||||||
const tarotDb = getTarotDbConfig(referenceData);
|
const tarotDb = getTarotDbConfig(referenceData);
|
||||||
const dynamicRelations = buildMajorDynamicRelations(referenceData);
|
const dynamicRelations = buildMajorDynamicRelations(referenceData);
|
||||||
@@ -178,6 +212,10 @@
|
|||||||
const windowDecans = windowDecanIds
|
const windowDecans = windowDecanIds
|
||||||
.map((decanId) => decanById.get(decanId) || null)
|
.map((decanId) => decanById.get(decanId) || null)
|
||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
|
const explicitWindowRange = buildTokenDateRange(
|
||||||
|
tarotDb.courtDateRanges?.[cardName]?.start,
|
||||||
|
tarotDb.courtDateRanges?.[cardName]?.end
|
||||||
|
);
|
||||||
|
|
||||||
const dynamicRelations = [];
|
const dynamicRelations = [];
|
||||||
const monthKeys = new Set();
|
const monthKeys = new Set();
|
||||||
@@ -255,9 +293,17 @@
|
|||||||
if (windowDecans.length) {
|
if (windowDecans.length) {
|
||||||
const firstRange = windowDecans[0].dateRange;
|
const firstRange = windowDecans[0].dateRange;
|
||||||
const lastRange = windowDecans[windowDecans.length - 1].dateRange;
|
const lastRange = windowDecans[windowDecans.length - 1].dateRange;
|
||||||
const windowLabel = firstRange && lastRange
|
const fallbackWindowRange = firstRange && lastRange
|
||||||
? `${formatMonthDayLabel(firstRange.start)}–${formatMonthDayLabel(lastRange.end)}`
|
? {
|
||||||
: "--";
|
start: firstRange.start,
|
||||||
|
end: lastRange.end,
|
||||||
|
startToken: firstRange.startToken,
|
||||||
|
endToken: lastRange.endToken,
|
||||||
|
label: `${formatMonthDayLabel(firstRange.start)}–${formatMonthDayLabel(lastRange.end)}`
|
||||||
|
}
|
||||||
|
: null;
|
||||||
|
const windowRange = explicitWindowRange || fallbackWindowRange;
|
||||||
|
const windowLabel = windowRange?.label || "--";
|
||||||
|
|
||||||
dynamicRelations.unshift(
|
dynamicRelations.unshift(
|
||||||
createRelation(
|
createRelation(
|
||||||
@@ -265,8 +311,8 @@
|
|||||||
`${rankKey}-${suitKey}`,
|
`${rankKey}-${suitKey}`,
|
||||||
`Court date window: ${windowLabel}`,
|
`Court date window: ${windowLabel}`,
|
||||||
{
|
{
|
||||||
dateStart: firstRange?.startToken || null,
|
dateStart: windowRange?.startToken || null,
|
||||||
dateEnd: lastRange?.endToken || null,
|
dateEnd: windowRange?.endToken || null,
|
||||||
dateRange: windowLabel,
|
dateRange: windowLabel,
|
||||||
decanIds: windowDecanIds
|
decanIds: windowDecanIds
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,8 @@
|
|||||||
suitInfo: hasDb && db.suitInfo && typeof db.suitInfo === "object" ? db.suitInfo : suitInfo,
|
suitInfo: hasDb && db.suitInfo && typeof db.suitInfo === "object" ? db.suitInfo : suitInfo,
|
||||||
rankInfo: hasDb && db.rankInfo && typeof db.rankInfo === "object" ? db.rankInfo : rankInfo,
|
rankInfo: hasDb && db.rankInfo && typeof db.rankInfo === "object" ? db.rankInfo : rankInfo,
|
||||||
courtInfo: hasDb && db.courtInfo && typeof db.courtInfo === "object" ? db.courtInfo : courtInfo,
|
courtInfo: hasDb && db.courtInfo && typeof db.courtInfo === "object" ? db.courtInfo : courtInfo,
|
||||||
courtDecanWindows: hasDb && db.courtDecanWindows && typeof db.courtDecanWindows === "object" ? db.courtDecanWindows : courtDecanWindows
|
courtDecanWindows: hasDb && db.courtDecanWindows && typeof db.courtDecanWindows === "object" ? db.courtDecanWindows : courtDecanWindows,
|
||||||
|
courtDateRanges: hasDb && db.courtDateRanges && typeof db.courtDateRanges === "object" ? db.courtDateRanges : {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,7 +179,36 @@
|
|||||||
return { start, end };
|
return { start, end };
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildDecanDateRange(sign, decanIndex) {
|
function buildTokenDateRange(startToken, endToken) {
|
||||||
|
const start = monthDayToDate(startToken, 2025);
|
||||||
|
const endBase = monthDayToDate(endToken, 2025);
|
||||||
|
if (!start || !endBase) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const wraps = endBase.getTime() < start.getTime();
|
||||||
|
const end = wraps ? monthDayToDate(endToken, 2026) : endBase;
|
||||||
|
if (!end) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
startMonth: start.getMonth() + 1,
|
||||||
|
endMonth: end.getMonth() + 1,
|
||||||
|
startToken: formatMonthDayToken(start),
|
||||||
|
endToken: formatMonthDayToken(end),
|
||||||
|
label: `${formatMonthDayLabel(start)}–${formatMonthDayLabel(end)}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildDecanDateRange(sign, decanIndex, decan = null) {
|
||||||
|
const explicitRange = buildTokenDateRange(decan?.dateStart, decan?.dateEnd);
|
||||||
|
if (explicitRange) {
|
||||||
|
return explicitRange;
|
||||||
|
}
|
||||||
|
|
||||||
const bounds = getSignDateBounds(sign);
|
const bounds = getSignDateBounds(sign);
|
||||||
if (!bounds || !Number.isFinite(Number(decanIndex))) {
|
if (!bounds || !Number.isFinite(Number(decanIndex))) {
|
||||||
return null;
|
return null;
|
||||||
@@ -238,7 +268,7 @@
|
|||||||
|
|
||||||
const startDegree = (index - 1) * 10;
|
const startDegree = (index - 1) * 10;
|
||||||
const endDegree = startDegree + 10;
|
const endDegree = startDegree + 10;
|
||||||
const dateRange = buildDecanDateRange(sign, index);
|
const dateRange = buildDecanDateRange(sign, index, decan);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
decan,
|
decan,
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -594,6 +594,46 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function refreshHouseUi() {
|
||||||
|
if (!state.initialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const elements = getElements();
|
||||||
|
renderHouseOfCards(elements);
|
||||||
|
syncHouseControls(elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setHouseTopCardsVisible(value) {
|
||||||
|
state.houseTopCardsVisible = Boolean(value);
|
||||||
|
refreshHouseUi();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setHouseTopInfoMode(mode, value) {
|
||||||
|
const key = String(mode || "").trim();
|
||||||
|
if (!key || !Object.prototype.hasOwnProperty.call(state.houseTopInfoModes, key)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.houseTopInfoModes[key] = Boolean(value);
|
||||||
|
refreshHouseUi();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setHouseBottomCardsVisible(value) {
|
||||||
|
state.houseBottomCardsVisible = Boolean(value);
|
||||||
|
refreshHouseUi();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setHouseBottomInfoMode(mode, value) {
|
||||||
|
const key = String(mode || "").trim();
|
||||||
|
if (!key || !Object.prototype.hasOwnProperty.call(state.houseBottomInfoModes, key)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.houseBottomInfoModes[key] = Boolean(value);
|
||||||
|
refreshHouseUi();
|
||||||
|
}
|
||||||
|
|
||||||
async function exportHouseOfCards(elements, format = "png") {
|
async function exportHouseOfCards(elements, format = "png") {
|
||||||
if (state.houseExportInProgress) {
|
if (state.houseExportInProgress) {
|
||||||
return;
|
return;
|
||||||
@@ -1076,6 +1116,14 @@
|
|||||||
ensureTarotSection,
|
ensureTarotSection,
|
||||||
selectCardByTrump,
|
selectCardByTrump,
|
||||||
selectCardByName,
|
selectCardByName,
|
||||||
getCards: () => state.cards
|
getCards: () => state.cards,
|
||||||
|
getHouseTopCardsVisible: () => state.houseTopCardsVisible,
|
||||||
|
getHouseTopInfoModes: () => ({ ...state.houseTopInfoModes }),
|
||||||
|
getHouseBottomCardsVisible: () => state.houseBottomCardsVisible,
|
||||||
|
getHouseBottomInfoModes: () => ({ ...state.houseBottomInfoModes }),
|
||||||
|
setHouseTopCardsVisible,
|
||||||
|
setHouseTopInfoMode,
|
||||||
|
setHouseBottomCardsVisible,
|
||||||
|
setHouseBottomInfoMode
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|||||||
58
index.html
58
index.html
@@ -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=20260401-tarot-frame-09">
|
<link rel="stylesheet" href="app/styles.css?v=20260401-tarot-frame-12">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="topbar">
|
<div class="topbar">
|
||||||
@@ -75,7 +75,6 @@
|
|||||||
<button id="open-tarot-cards" class="settings-trigger topbar-sub-trigger" type="button" role="menuitem">Cards</button>
|
<button id="open-tarot-cards" class="settings-trigger topbar-sub-trigger" type="button" role="menuitem">Cards</button>
|
||||||
<button id="open-tarot-spread" class="settings-trigger topbar-sub-trigger" type="button" role="menuitem">Draw Spread</button>
|
<button id="open-tarot-spread" class="settings-trigger topbar-sub-trigger" type="button" role="menuitem">Draw Spread</button>
|
||||||
<button id="open-tarot-frame" class="settings-trigger topbar-sub-trigger" type="button" role="menuitem">Frame</button>
|
<button id="open-tarot-frame" class="settings-trigger topbar-sub-trigger" type="button" role="menuitem">Frame</button>
|
||||||
<button id="open-tarot-house" class="settings-trigger topbar-sub-trigger" type="button" role="menuitem">House</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -314,16 +313,55 @@
|
|||||||
<div class="tarot-frame-header">
|
<div class="tarot-frame-header">
|
||||||
<div>
|
<div>
|
||||||
<h2 class="tarot-frame-title">Tarot Frame</h2>
|
<h2 class="tarot-frame-title">Tarot Frame</h2>
|
||||||
<p class="tarot-frame-copy">Arrange all 78 tarot cards inside one master 18x18 grid. The extra cards sit across the top row, and every square stays available for custom layouts.</p>
|
<p class="tarot-frame-copy">Arrange all 78 tarot cards inside one master 18x18 grid, then switch between the Frames and House of Cards presets without leaving the page.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="tarot-frame-actions">
|
<div class="tarot-frame-actions">
|
||||||
<button id="tarot-frame-settings-toggle" class="tarot-frame-action-btn tarot-frame-settings-toggle" type="button" aria-haspopup="dialog" aria-expanded="false" aria-controls="tarot-frame-settings-panel">Settings</button>
|
<button id="tarot-frame-settings-toggle" class="tarot-frame-action-btn tarot-frame-settings-toggle" type="button" aria-haspopup="dialog" aria-expanded="false" aria-controls="tarot-frame-settings-panel">Settings</button>
|
||||||
<button id="tarot-frame-reset" class="tarot-frame-action-btn" type="button">Reset Layout</button>
|
<button id="tarot-frame-layout-toggle" class="tarot-frame-action-btn" type="button" aria-haspopup="menu" aria-expanded="false" aria-controls="tarot-frame-layout-panel">Layout: Frames</button>
|
||||||
|
<div id="tarot-frame-layout-panel" class="tarot-frame-layout-panel" role="menu" aria-label="Tarot Frame layouts" hidden>
|
||||||
|
<button class="tarot-frame-layout-option" type="button" data-layout-preset-id="frames" role="menuitemradio" aria-checked="true">
|
||||||
|
<strong>Frames</strong>
|
||||||
|
<span>The current master frame with top-row extras and nested chronological rings.</span>
|
||||||
|
</button>
|
||||||
|
<button class="tarot-frame-layout-option" type="button" data-layout-preset-id="house" role="menuitemradio" aria-checked="false">
|
||||||
|
<strong>House of Cards</strong>
|
||||||
|
<span>The legacy house composition rebuilt inside the 18x18 snap grid.</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<div id="tarot-frame-settings-panel" class="tarot-frame-settings-panel" role="dialog" aria-label="Tarot Frame settings" hidden>
|
<div id="tarot-frame-settings-panel" class="tarot-frame-settings-panel" role="dialog" aria-label="Tarot Frame settings" hidden>
|
||||||
<label class="tarot-frame-toggle" for="tarot-frame-show-info">
|
<label class="tarot-frame-toggle" for="tarot-frame-show-info">
|
||||||
<input id="tarot-frame-show-info" type="checkbox" checked>
|
<input id="tarot-frame-show-info" type="checkbox" checked>
|
||||||
<span>Display Info</span>
|
<span>Display Info</span>
|
||||||
</label>
|
</label>
|
||||||
|
<div id="tarot-frame-house-settings" class="tarot-frame-settings-group" hidden>
|
||||||
|
<div class="tarot-frame-settings-heading">House Layout Settings</div>
|
||||||
|
<div class="tarot-frame-settings-note">These controls mirror the old House of Cards view and only apply while that layout is active.</div>
|
||||||
|
<label class="tarot-frame-toggle" for="tarot-frame-house-top-cards-visible">
|
||||||
|
<input id="tarot-frame-house-top-cards-visible" type="checkbox" checked>
|
||||||
|
<span>Show top card images</span>
|
||||||
|
</label>
|
||||||
|
<div class="tarot-frame-settings-subheading">Top Info</div>
|
||||||
|
<div class="tarot-frame-checkbox-grid">
|
||||||
|
<label class="tarot-frame-check" for="tarot-frame-house-top-info-hebrew"><input id="tarot-frame-house-top-info-hebrew" type="checkbox" checked><span>Hebrew</span></label>
|
||||||
|
<label class="tarot-frame-check" for="tarot-frame-house-top-info-planet"><input id="tarot-frame-house-top-info-planet" type="checkbox" checked><span>Planet</span></label>
|
||||||
|
<label class="tarot-frame-check" for="tarot-frame-house-top-info-zodiac"><input id="tarot-frame-house-top-info-zodiac" type="checkbox" checked><span>Zodiac</span></label>
|
||||||
|
<label class="tarot-frame-check" for="tarot-frame-house-top-info-trump"><input id="tarot-frame-house-top-info-trump" type="checkbox" checked><span>Trump</span></label>
|
||||||
|
<label class="tarot-frame-check" for="tarot-frame-house-top-info-path"><input id="tarot-frame-house-top-info-path" type="checkbox" checked><span>Path</span></label>
|
||||||
|
<label class="tarot-frame-check" for="tarot-frame-house-top-info-date"><input id="tarot-frame-house-top-info-date" type="checkbox"><span>Date</span></label>
|
||||||
|
</div>
|
||||||
|
<label class="tarot-frame-toggle" for="tarot-frame-house-bottom-cards-visible">
|
||||||
|
<input id="tarot-frame-house-bottom-cards-visible" type="checkbox" checked>
|
||||||
|
<span>Show lower card images</span>
|
||||||
|
</label>
|
||||||
|
<div class="tarot-frame-settings-subheading">Lower Info</div>
|
||||||
|
<div class="tarot-frame-checkbox-grid">
|
||||||
|
<label class="tarot-frame-check" for="tarot-frame-house-bottom-info-zodiac"><input id="tarot-frame-house-bottom-info-zodiac" type="checkbox" checked><span>Zodiac</span></label>
|
||||||
|
<label class="tarot-frame-check" for="tarot-frame-house-bottom-info-decan"><input id="tarot-frame-house-bottom-info-decan" type="checkbox" checked><span>Decan</span></label>
|
||||||
|
<label class="tarot-frame-check" for="tarot-frame-house-bottom-info-month"><input id="tarot-frame-house-bottom-info-month" type="checkbox" checked><span>Month</span></label>
|
||||||
|
<label class="tarot-frame-check" for="tarot-frame-house-bottom-info-ruler"><input id="tarot-frame-house-bottom-info-ruler" type="checkbox" checked><span>Ruler</span></label>
|
||||||
|
<label class="tarot-frame-check" for="tarot-frame-house-bottom-info-date"><input id="tarot-frame-house-bottom-info-date" type="checkbox"><span>Date</span></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<button id="tarot-frame-export-webp" class="tarot-frame-action-btn tarot-frame-export-btn" type="button">Export WebP</button>
|
<button id="tarot-frame-export-webp" class="tarot-frame-action-btn tarot-frame-export-btn" type="button">Export WebP</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1076,9 +1114,9 @@
|
|||||||
<script src="app/ui-now-helpers.js?v=20260314-now-planets-grid-01"></script>
|
<script src="app/ui-now-helpers.js?v=20260314-now-planets-grid-01"></script>
|
||||||
<script src="app/ui-now.js?v=20260314-now-planets-grid-01"></script>
|
<script src="app/ui-now.js?v=20260314-now-planets-grid-01"></script>
|
||||||
<script src="app/ui-natal.js"></script>
|
<script src="app/ui-natal.js"></script>
|
||||||
<script src="app/tarot-database-builders.js"></script>
|
<script src="app/tarot-database-builders.js?v=20260401-tarot-dates-01"></script>
|
||||||
<script src="app/tarot-database-assembly.js"></script>
|
<script src="app/tarot-database-assembly.js?v=20260401-tarot-dates-01"></script>
|
||||||
<script src="app/tarot-database.js"></script>
|
<script src="app/tarot-database.js?v=20260401-tarot-dates-01"></script>
|
||||||
<script src="app/ui-calendar-dates.js"></script>
|
<script src="app/ui-calendar-dates.js"></script>
|
||||||
<script src="app/ui-calendar-detail-panels.js"></script>
|
<script src="app/ui-calendar-detail-panels.js"></script>
|
||||||
<script src="app/ui-calendar-detail.js"></script>
|
<script src="app/ui-calendar-detail.js"></script>
|
||||||
@@ -1090,7 +1128,7 @@
|
|||||||
<script src="app/ui-tarot-card-derivations.js?v=20260307b"></script>
|
<script src="app/ui-tarot-card-derivations.js?v=20260307b"></script>
|
||||||
<script src="app/ui-tarot-detail.js?v=20260307b"></script>
|
<script src="app/ui-tarot-detail.js?v=20260307b"></script>
|
||||||
<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=20260401-house-top-date-01"></script>
|
<script src="app/ui-tarot.js?v=20260401-house-top-date-02"></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"></script>
|
||||||
<script src="app/ui-cycles.js"></script>
|
<script src="app/ui-cycles.js"></script>
|
||||||
@@ -1130,7 +1168,7 @@
|
|||||||
<script src="app/ui-numbers-detail.js"></script>
|
<script src="app/ui-numbers-detail.js"></script>
|
||||||
<script src="app/ui-numbers.js"></script>
|
<script src="app/ui-numbers.js"></script>
|
||||||
<script src="app/ui-tarot-spread.js"></script>
|
<script src="app/ui-tarot-spread.js"></script>
|
||||||
<script src="app/ui-tarot-frame.js?v=20260401-tarot-frame-09"></script>
|
<script src="app/ui-tarot-frame.js?v=20260401-tarot-frame-11"></script>
|
||||||
<script src="app/ui-settings.js?v=20260309-gate"></script>
|
<script src="app/ui-settings.js?v=20260309-gate"></script>
|
||||||
<script src="app/ui-chrome.js?v=20260328-topbar-settings-01"></script>
|
<script src="app/ui-chrome.js?v=20260328-topbar-settings-01"></script>
|
||||||
<script src="app/ui-navigation.js?v=20260401-tarot-frame-01"></script>
|
<script src="app/ui-navigation.js?v=20260401-tarot-frame-01"></script>
|
||||||
@@ -1139,7 +1177,7 @@
|
|||||||
<script src="app/ui-home-calendar.js"></script>
|
<script src="app/ui-home-calendar.js"></script>
|
||||||
<script src="app/ui-section-state.js?v=20260401-tarot-frame-01"></script>
|
<script src="app/ui-section-state.js?v=20260401-tarot-frame-01"></script>
|
||||||
<script src="app/app-runtime.js?v=20260309-gate"></script>
|
<script src="app/app-runtime.js?v=20260309-gate"></script>
|
||||||
<script src="app.js?v=20260401-tarot-frame-01"></script>
|
<script src="app.js?v=20260401-tarot-frame-02"></script>
|
||||||
<script src="app/navigation-detail-test-harness.js?v=20260401-universal-detail-02"></script>
|
<script src="app/navigation-detail-test-harness.js?v=20260401-universal-detail-02"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user