diff --git a/app.js b/app.js index 71824ae..b468527 100644 --- a/app.js +++ b/app.js @@ -35,6 +35,7 @@ const statusEl = document.getElementById("status"); const monthStripEl = document.getElementById("month-strip"); const calendarEl = document.getElementById("calendar"); const timelineSectionEl = document.getElementById("timeline-section"); +const settingsSectionEl = document.getElementById("settings-section"); const calendarSectionEl = document.getElementById("calendar-section"); const holidaySectionEl = document.getElementById("holiday-section"); const audioCircleSectionEl = document.getElementById("audio-circle-section"); @@ -60,6 +61,7 @@ const quizSectionEl = document.getElementById("quiz-section"); const godsSectionEl = document.getElementById("gods-section"); const enochianSectionEl = document.getElementById("enochian-section"); const openHomeEl = document.getElementById("open-home"); +const openSettingsEl = document.getElementById("open-settings"); const openCalendarEl = document.getElementById("open-calendar"); const openCalendarTimelineEl = document.getElementById("open-calendar-timeline"); const openCalendarMonthsEl = document.getElementById("open-calendar-months"); @@ -473,6 +475,7 @@ sectionStateUi.init?.({ calendarEl, monthStripEl, nowPanelEl, + settingsSectionEl, timelineSectionEl, calendarSectionEl, holidaySectionEl, @@ -499,6 +502,7 @@ sectionStateUi.init?.({ godsSectionEl, enochianSectionEl, openHomeEl, + openSettingsEl, openCalendarEl, openCalendarTimelineEl, openCalendarMonthsEl, @@ -562,6 +566,7 @@ settingsUi.init?.({ onStatus: (text) => setStatus(text), onConnectionSaved: async () => ensureConnectedApp(), getActiveSection: () => sectionStateUi.getActiveSection?.() || "home", + setActiveSection: (section) => sectionStateUi.setActiveSection?.(section), onReopenActiveSection: (section) => sectionStateUi.setActiveSection?.(section), onRenderWeek: () => appRuntime.renderWeek?.() }); @@ -604,6 +609,7 @@ navigationUi.init?.({ selectNumberEntry, elements: { openHomeEl, + openSettingsEl, openCalendarEl, openCalendarTimelineEl, openCalendarMonthsEl, diff --git a/app/styles.css b/app/styles.css index cb354d6..e19579d 100644 --- a/app/styles.css +++ b/app/styles.css @@ -402,6 +402,16 @@ box-sizing: border-box; overflow: auto; } + #settings-section { + height: calc(100vh - 61px); + height: calc(100dvh - 61px); + background: + radial-gradient(circle at top left, rgba(245, 158, 11, 0.12), transparent 30%), + radial-gradient(circle at top right, rgba(59, 130, 246, 0.1), transparent 32%), + linear-gradient(180deg, #111318, #18181b 40%, #111318); + box-sizing: border-box; + overflow: auto; + } #tarot-section[hidden] { display: none; } @@ -429,6 +439,94 @@ #holiday-section[hidden] { display: none; } + #settings-section[hidden] { + display: none; + } + .settings-page-shell { + width: min(1120px, calc(100% - 24px)); + margin: 0 auto; + padding: clamp(18px, 2.8vw, 32px); + box-sizing: border-box; + } + .settings-page-hero { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 16px; + margin-bottom: 20px; + } + .settings-page-eyebrow { + font-size: 11px; + text-transform: uppercase; + letter-spacing: 0.16em; + color: #f59e0b; + margin-bottom: 8px; + } + .settings-page-title { + margin: 0; + font-size: clamp(28px, 4vw, 42px); + line-height: 1.05; + color: #fafafa; + } + .settings-page-copy { + margin: 10px 0 0; + max-width: 720px; + color: #cbd5e1; + line-height: 1.6; + } + .settings-page-back { + padding: 10px 14px; + border-radius: 999px; + border: 1px solid rgba(245, 158, 11, 0.35); + background: rgba(17, 24, 39, 0.78); + color: #f8fafc; + cursor: pointer; + white-space: nowrap; + } + .settings-page-back:hover { + background: rgba(31, 41, 55, 0.96); + } + .settings-page-layout { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 16px; + } + .settings-panel { + padding: 18px; + border-radius: 20px; + border: 1px solid rgba(63, 63, 70, 0.92); + background: linear-gradient(180deg, rgba(24, 24, 27, 0.96), rgba(9, 9, 11, 0.96)); + box-shadow: 0 18px 40px rgba(0, 0, 0, 0.2); + } + .settings-panel-wide { + grid-column: 1 / -1; + } + .settings-panel-head { + display: flex; + flex-direction: column; + gap: 6px; + margin-bottom: 14px; + } + .settings-panel-head strong { + color: #fafafa; + font-size: 15px; + } + .settings-panel-head span { + color: #94a3b8; + font-size: 13px; + line-height: 1.5; + } + .settings-panel-actions { + margin-top: 14px; + display: flex; + justify-content: flex-start; + } + .settings-page-actions { + margin-top: 18px; + padding-top: 16px; + border-top: 1px solid rgba(63, 63, 70, 0.7); + justify-content: flex-end; + } .calendar-year-control { display: flex; justify-content: space-between; @@ -7071,6 +7169,17 @@ .settings-popup-header button:hover { background: #3f3f46; } + @media (max-width: 800px) { + .settings-page-hero { + flex-direction: column; + } + .settings-page-layout { + grid-template-columns: minmax(0, 1fr); + } + .settings-panel-wide { + grid-column: auto; + } + } @media (max-width: 640px) { .connection-gate { padding: 16px; diff --git a/app/ui-section-state.js b/app/ui-section-state.js index 48ceb04..bdf7027 100644 --- a/app/ui-section-state.js +++ b/app/ui-section-state.js @@ -3,6 +3,7 @@ const VALID_SECTIONS = new Set([ "home", + "settings", "timeline", "calendar", "holidays", @@ -87,6 +88,7 @@ const magickDataset = getMagickDataset(); const isHomeOpen = activeSection === "home"; + const isSettingsOpen = activeSection === "settings"; const isTimelineOpen = activeSection === "timeline"; const isCalendarOpen = activeSection === "calendar"; const isHolidaysOpen = activeSection === "holidays"; @@ -120,6 +122,7 @@ const isEnochianOpen = activeSection === "enochian"; setHidden(elements.timelineSectionEl, !isTimelineOpen); + setHidden(elements.settingsSectionEl, !isSettingsOpen); setHidden(elements.calendarSectionEl, !isCalendarOpen); setHidden(elements.holidaySectionEl, !isHolidaysOpen); setHidden(elements.audioCircleSectionEl, !isAudioCircleOpen); @@ -147,6 +150,7 @@ setHidden(elements.nowPanelEl, !isHomeOpen); setPressed(elements.openHomeEl, isHomeOpen); + setPressed(elements.openSettingsEl, isSettingsOpen); setPressed(elements.openCalendarEl, isCalendarMenuOpen); toggleActive(elements.openCalendarTimelineEl, isTimelineOpen); toggleActive(elements.openCalendarMonthsEl, isCalendarOpen); @@ -177,15 +181,15 @@ setPressed(elements.openGodsEl, isGodsOpen); setPressed(elements.openEnochianEl, isEnochianOpen); - if (!isHomeOpen) { - config.settingsUi?.closeSettingsPopup?.(); - } - if (isTimelineOpen) { renderHomeFallback(); return; } + if (isSettingsOpen) { + return; + } + if (isCalendarOpen) { ensure.ensureCalendarSection?.(referenceData, magickDataset); return; diff --git a/app/ui-settings.js b/app/ui-settings.js index 0ff82b3..f076a15 100644 --- a/app/ui-settings.js +++ b/app/ui-settings.js @@ -18,16 +18,17 @@ onStatus: null, onConnectionSaved: null, onReopenActiveSection: null, + setActiveSection: null, getActiveSection: null, onRenderWeek: null }; + let lastNonSettingsSection = "home"; + function getElements() { return { openSettingsEl: document.getElementById("open-settings"), closeSettingsEl: document.getElementById("close-settings"), - settingsPopupEl: document.getElementById("settings-popup"), - settingsPopupCardEl: document.getElementById("settings-popup-card"), latEl: document.getElementById("lat"), lngEl: document.getElementById("lng"), timeFormatEl: document.getElementById("time-format"), @@ -460,28 +461,16 @@ } function openSettingsPopup() { - const { settingsPopupEl, openSettingsEl } = getElements(); - if (!settingsPopupEl) { - return; + const activeSection = typeof config.getActiveSection === "function" ? config.getActiveSection() : "home"; + if (activeSection && activeSection !== "settings") { + lastNonSettingsSection = activeSection; } - applySettingsToInputs(loadSavedSettings()); - settingsPopupEl.hidden = false; - if (openSettingsEl) { - openSettingsEl.setAttribute("aria-expanded", "true"); - } + config.setActiveSection?.("settings"); } function closeSettingsPopup() { - const { settingsPopupEl, openSettingsEl } = getElements(); - if (!settingsPopupEl) { - return; - } - - settingsPopupEl.hidden = true; - if (openSettingsEl) { - openSettingsEl.setAttribute("aria-expanded", "false"); - } + config.setActiveSection?.(lastNonSettingsSection || "home"); } async function handleSaveSettings() { @@ -502,10 +491,9 @@ ); const didPersist = saveSettings(normalized); emitSettingsUpdated(normalized); - if (typeof config.getActiveSection === "function" && config.getActiveSection() !== "home") { + if (typeof config.getActiveSection === "function" && config.getActiveSection() !== "home" && config.getActiveSection() !== "settings") { config.onReopenActiveSection?.(config.getActiveSection()); } - closeSettingsPopup(); if (connectionChanged && typeof config.onConnectionSaved === "function") { await config.onConnectionSaved(connectionResult, connectionSettings); } else if (typeof config.onRenderWeek === "function") { @@ -514,6 +502,8 @@ if (!didPersist || connectionResult.didPersist === false) { setStatus("Settings applied for this session. Browser storage is unavailable."); + } else { + setStatus("Settings saved."); } } catch (error) { setStatus(error?.message || "Unable to save settings."); @@ -557,8 +547,6 @@ useLocationEl, openSettingsEl, closeSettingsEl, - settingsPopupEl, - settingsPopupCardEl, latEl, lngEl } = getElements(); @@ -585,7 +573,7 @@ if (openSettingsEl) { openSettingsEl.addEventListener("click", (event) => { event.stopPropagation(); - if (settingsPopupEl?.hidden) { + if ((config.getActiveSection?.() || "home") !== "settings") { openSettingsPopup(); } else { closeSettingsPopup(); @@ -597,25 +585,8 @@ closeSettingsEl.addEventListener("click", closeSettingsPopup); } - document.addEventListener("click", (event) => { - const clickTarget = event.target; - if (!settingsPopupEl || settingsPopupEl.hidden) { - return; - } - - if (!(clickTarget instanceof Node)) { - return; - } - - if (settingsPopupCardEl?.contains(clickTarget) || openSettingsEl?.contains(clickTarget)) { - return; - } - - closeSettingsPopup(); - }); - document.addEventListener("keydown", (event) => { - if (event.key === "Escape") { + if (event.key === "Escape" && (config.getActiveSection?.() || "home") === "settings") { closeSettingsPopup(); } }); diff --git a/index.html b/index.html index 5aae648..01e31f9 100644 --- a/index.html +++ b/index.html @@ -22,7 +22,7 @@
- +
@@ -98,56 +98,86 @@
-