From 767b43e2ff078f0a0ec824db2134b6bf9e8303b3 Mon Sep 17 00:00:00 2001 From: Alexander Bocken Date: Wed, 4 Feb 2026 11:17:40 +0100 Subject: [PATCH] rosary: split final prayers into individual bead sections with scroll tracking Map each ending bead to its corresponding prayer (Gloria/Fatima, Salve Regina, Schlussgebet, St. Michael, Paternoster, Sign of the Cross), add scroll-to-top button with action_button styling, and fix SVG scroll lock to prevent snap-back when scrolling to top. --- .../[rosary=rosaryLang]/+page.svelte | 86 +++++++++++++++++-- 1 file changed, 80 insertions(+), 6 deletions(-) diff --git a/src/routes/[faithLang=faithLang]/[rosary=rosaryLang]/+page.svelte b/src/routes/[faithLang=faithLang]/[rosary=rosaryLang]/+page.svelte index 0499049..7afaff4 100644 --- a/src/routes/[faithLang=faithLang]/[rosary=rosaryLang]/+page.svelte +++ b/src/routes/[faithLang=faithLang]/[rosary=rosaryLang]/+page.svelte @@ -2,6 +2,7 @@ import { onMount } from "svelte"; import { createLanguageContext } from "$lib/contexts/languageContext.js"; import "$lib/css/christ.css"; +import "$lib/css/action_button.css"; import Kreuzzeichen from "$lib/components/prayers/Kreuzzeichen.svelte"; import Credo from "$lib/components/prayers/Credo.svelte"; import Paternoster from "$lib/components/prayers/Paternoster.svelte"; @@ -370,7 +371,12 @@ const sectionPositions = { secret4: 1120, secret4_transition: 1360, secret5: 1400, - final_transition: 1640 + final_transition: 1690, + final_salve: 1730, + final_schlussgebet: 1760, + final_michael: 1790, + final_paternoster: 1830, + final_cross: 1920 }; onMount(() => { @@ -569,7 +575,7 @@ onMount(() => { // Get the first and final prayer sections const firstSection = sectionElements.cross; - const finalSection = sectionElements.final_transition; + const finalSection = sectionElements.final_cross; if (!firstSection || !finalSection) return; const firstSectionRect = firstSection.getBoundingClientRect(); @@ -579,6 +585,7 @@ onMount(() => { if (scrollY < 50) { // Scroll SVG to top if (svgContainer.scrollTop > 10) { // Only if not already at top + setScrollLock('prayer'); smoothScrollElement(svgContainer, 0); } } @@ -587,6 +594,7 @@ onMount(() => { // Scroll SVG to bottom const maxScroll = svgContainer.scrollHeight - svgContainer.clientHeight; if (svgContainer.scrollTop < maxScroll - 10) { // Only if not already at bottom + setScrollLock('prayer'); smoothScrollElement(svgContainer, maxScroll); } } @@ -594,6 +602,7 @@ onMount(() => { else if (firstSectionRect.top > viewportHeight * 0.6) { // Scroll SVG to top if (svgContainer.scrollTop > 10) { // Only if not already at top + setScrollLock('prayer'); smoothScrollElement(svgContainer, 0); } } @@ -602,6 +611,7 @@ onMount(() => { // Scroll SVG to bottom const maxScroll = svgContainer.scrollHeight - svgContainer.clientHeight; if (svgContainer.scrollTop < maxScroll - 10) { // Only if not already at bottom + setScrollLock('prayer'); smoothScrollElement(svgContainer, maxScroll); } } @@ -1227,6 +1237,14 @@ h1 { margin-right: 0.5em; color: var(--nord11); } + +.scroll-top-button { + margin: 2rem auto 0; +} + +.scroll-padding { + height: 50vh; +} {labels.pageTitle} @@ -1313,7 +1331,7 @@ h1 {
- + @@ -1382,8 +1400,20 @@ h1 { class:counted-bead={i < decadeCounters.secret5} data-section="secret5" /> {/each} + + - + + + + + + + + + + @@ -1409,8 +1439,14 @@ h1 { - + + + + + + +
@@ -1565,21 +1601,59 @@ h1 {

{labels.fatimaPrayer} ({labels.optional})

+ +

Salve Regina

+
+

{labels.finalPrayer}

+
+

{labels.saintMichael}

+
-

+
+

{labels.ourFather}

+ +
+ +
+

{labels.signOfCross}

+

{labels.footnoteSign}

+ +