ablassgebete: add prayer page with sticky crucifix and draggable PiP
All checks were successful
CI / update (push) Successful in 1m31s
All checks were successful
CI / update (push) Successful in 1m31s
- Add AblassGebete component and crucifix images - Desktop: sticky crucifix on right, centered prayer with balanced spacing - Mobile: draggable picture-in-picture thumbnail that snaps to corners - Double-tap to enlarge/shrink with directional animation - Monolingual sections override bilingual grey styling - 404 for English route /faith/prayers/ablassgebete (German only) - Reposition on window resize including desktop/mobile breakpoint crossing
This commit is contained in:
64
src/lib/components/prayers/AblassGebete.svelte
Normal file
64
src/lib/components/prayers/AblassGebete.svelte
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
<script>
|
||||||
|
import Prayer from './Prayer.svelte';
|
||||||
|
import Paternoster from './Paternoster.svelte';
|
||||||
|
import AveMaria from './AveMaria.svelte';
|
||||||
|
import GloriaPatri from './GloriaPatri.svelte';
|
||||||
|
|
||||||
|
export let verbose = false;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Prayer>
|
||||||
|
{#snippet children(showLatin, urlLang)}
|
||||||
|
<div class="monolingual">
|
||||||
|
<p>
|
||||||
|
<v lang=de>
|
||||||
|
Seele Christi, heilige mich.
|
||||||
|
<i>✻</i>
|
||||||
|
Leib Christi erlöse mich.
|
||||||
|
<i>✻</i>
|
||||||
|
Blut Christi, tränke mich.
|
||||||
|
<i>✻</i>
|
||||||
|
Wasser der Seite Christi, wasche mich.
|
||||||
|
<i>✻</i>
|
||||||
|
Leiden Christi, stärke mich.
|
||||||
|
<i>✻</i>
|
||||||
|
O gütiger Jesus, erhöre mich.
|
||||||
|
<i>✻</i>
|
||||||
|
Verbirg in Deine Wunden mich.
|
||||||
|
<i>✻</i>
|
||||||
|
Von Dir lass nimmer scheiden mich.
|
||||||
|
<i>✻</i>
|
||||||
|
In meiner Todesstunde rufe mich,
|
||||||
|
<i>✻</i>
|
||||||
|
Und heisse zur Dir kommen mich,
|
||||||
|
<i>✻</i>
|
||||||
|
Damit ich möge loben Dich
|
||||||
|
<i>✻</i>
|
||||||
|
Mit Deinen Heiligen ewiglich. Amen.
|
||||||
|
</v>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<h3> Vollkommener Ablass</h3>
|
||||||
|
<h4> Paternoster </h4>
|
||||||
|
{#if verbose }
|
||||||
|
<Paternoster />
|
||||||
|
{/if}
|
||||||
|
<h4> Ave Maria </h4>
|
||||||
|
{#if verbose }
|
||||||
|
<AveMaria />
|
||||||
|
{/if}
|
||||||
|
<h4> Gloria Patri </h4>
|
||||||
|
{#if verbose }
|
||||||
|
<GloriaPatri />
|
||||||
|
{/if}
|
||||||
|
<p>
|
||||||
|
{#if showLatin}
|
||||||
|
<v lang=la >En ego, o bone et dulcíssime Jesu, ante contspéctum tuum génibusme provólvo ac máximo ánimi ardóre te oro atque obtéstor, ut meum in in cor vívidos fídei, spei et caritátis sensus, atque veram peccatórum meórum pœniténtiam, éaque emendándi firmíssimam voluntátem velis imprímere; dum magno ánimi afféctu et dolóre tua quinque vúlnera mecum ipse consídero ac mente contémplor, illud præ óculis habens, quod jam in ore ponébat tuo David Prophéta de te, o bone Jesu: Fodérunt manus meas et pedes meos; dinumeravérunt ómnio ossa mea (Ps. 21, 17-18)</v>
|
||||||
|
{/if}
|
||||||
|
<v lang=de>
|
||||||
|
Siehe, o gütiger und milder Jesus, ich werfe mich vor Deinen Augen auf die Knie. Inbrünstig bitte und beschwöre ich Dich: Präge meinem Herzen lebendige Gefühle des Glaubens, der Hoffung und der Liebe ein sowie wahre Reue über meine Sünden und den ganz festen Willen, mich zu bessern. Voll Liebe und Schwerz schaue ich Deine fünf Wunden und betrachte sie in meinem Geiste. Dabei halte ich mir vor Augen, was im Hinblick auf Dich, o guter Jesus, schon der Prophet David Dir in den Mund legte: «Sie haben Meine Hände und Meine Füsse durchbohrt; alle meine Gebeine haben sie gezählt.» (Ps. 21, 17-18)
|
||||||
|
</v>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
{/snippet}
|
||||||
|
</Prayer>
|
||||||
@@ -19,6 +19,8 @@
|
|||||||
import BruderKlausGebet from "$lib/components/prayers/BruderKlausGebet.svelte";
|
import BruderKlausGebet from "$lib/components/prayers/BruderKlausGebet.svelte";
|
||||||
import JosephGebet from "$lib/components/prayers/JosephGebet.svelte";
|
import JosephGebet from "$lib/components/prayers/JosephGebet.svelte";
|
||||||
import Confiteor from "$lib/components/prayers/Confiteor.svelte";
|
import Confiteor from "$lib/components/prayers/Confiteor.svelte";
|
||||||
|
import AblassGebete from "$lib/components/prayers/AblassGebete.svelte";
|
||||||
|
import Prayer from "$lib/components/prayers/Prayer.svelte";
|
||||||
|
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
|
|
||||||
@@ -55,7 +57,8 @@
|
|||||||
confiteor: isEnglish ? 'The Confiteor' : 'Das Confiteor',
|
confiteor: isEnglish ? 'The Confiteor' : 'Das Confiteor',
|
||||||
searchPlaceholder: isEnglish ? 'Search prayers...' : 'Gebete suchen...',
|
searchPlaceholder: isEnglish ? 'Search prayers...' : 'Gebete suchen...',
|
||||||
clearSearch: isEnglish ? 'Clear search' : 'Suche löschen',
|
clearSearch: isEnglish ? 'Clear search' : 'Suche löschen',
|
||||||
textMatch: isEnglish ? 'Match in prayer text' : 'Treffer im Gebetstext'
|
textMatch: isEnglish ? 'Match in prayer text' : 'Treffer im Gebetstext',
|
||||||
|
ablassgebete: 'Ablassgebete'
|
||||||
});
|
});
|
||||||
|
|
||||||
// JS-only search (hidden without JS)
|
// JS-only search (hidden without JS)
|
||||||
@@ -88,7 +91,8 @@
|
|||||||
{ id: 'michael', searchTerms: ['michael', 'archangel', 'erzengel', 'satan', 'devil', 'teufel'], slug: isEnglish ? 'prayer-to-st-michael-the-archangel' : 'gebet-zum-hl-erzengel-michael' },
|
{ id: 'michael', searchTerms: ['michael', 'archangel', 'erzengel', 'satan', 'devil', 'teufel'], slug: isEnglish ? 'prayer-to-st-michael-the-archangel' : 'gebet-zum-hl-erzengel-michael' },
|
||||||
{ id: 'bruderKlaus', searchTerms: ['bruder klaus', 'nicholas', 'niklaus', 'flüe'], slug: isEnglish ? 'prayer-of-st-nicholas-of-flue' : 'bruder-klaus-gebet' },
|
{ id: 'bruderKlaus', searchTerms: ['bruder klaus', 'nicholas', 'niklaus', 'flüe'], slug: isEnglish ? 'prayer-of-st-nicholas-of-flue' : 'bruder-klaus-gebet' },
|
||||||
{ id: 'joseph', searchTerms: ['joseph', 'josef', 'pius'], slug: isEnglish ? 'prayer-to-st-joseph-by-pope-st-pius-x' : 'josephgebet-des-hl-papst-pius-x' },
|
{ id: 'joseph', searchTerms: ['joseph', 'josef', 'pius'], slug: isEnglish ? 'prayer-to-st-joseph-by-pope-st-pius-x' : 'josephgebet-des-hl-papst-pius-x' },
|
||||||
{ id: 'confiteor', searchTerms: ['confiteor', 'i confess', 'ich bekenne', 'mea culpa'], slug: isEnglish ? 'the-confiteor' : 'das-confiteor' }
|
{ id: 'confiteor', searchTerms: ['confiteor', 'i confess', 'ich bekenne', 'mea culpa'], slug: isEnglish ? 'the-confiteor' : 'das-confiteor' },
|
||||||
|
{ id: 'ablassgebete', searchTerms: ['ablass', 'kommunion'], slug: 'ablassgebete' }
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Base URL for prayer links
|
// Base URL for prayer links
|
||||||
@@ -108,7 +112,8 @@
|
|||||||
michael: labels.michael,
|
michael: labels.michael,
|
||||||
bruderKlaus: labels.bruderKlaus,
|
bruderKlaus: labels.bruderKlaus,
|
||||||
joseph: labels.joseph,
|
joseph: labels.joseph,
|
||||||
confiteor: labels.confiteor
|
confiteor: labels.confiteor,
|
||||||
|
ablassgebete: labels.ablassgebete
|
||||||
};
|
};
|
||||||
return nameMap[id] || id;
|
return nameMap[id] || id;
|
||||||
}
|
}
|
||||||
@@ -316,6 +321,12 @@ h1{
|
|||||||
<p slot="intro">{labels.gloriaIntro}</p>
|
<p slot="intro">{labels.gloriaIntro}</p>
|
||||||
<Gloria />
|
<Gloria />
|
||||||
</Gebet>
|
</Gebet>
|
||||||
|
{:else if prayer.id === 'ablassgebete'}
|
||||||
|
{#if data.lang === 'de'}
|
||||||
|
<Gebet name={getPrayerName(prayer.id)} is_bilingue={false} id={prayer.id} href="{baseUrl}/{prayer.slug}">
|
||||||
|
<AblassGebete />
|
||||||
|
</Gebet>
|
||||||
|
{/if}
|
||||||
{:else}
|
{:else}
|
||||||
<Gebet name={getPrayerName(prayer.id)} is_bilingue={prayerMeta[prayer.id]?.bilingue ?? true} id={prayer.id} href="{baseUrl}/{prayer.slug}">
|
<Gebet name={getPrayerName(prayer.id)} is_bilingue={prayerMeta[prayer.id]?.bilingue ?? true} id={prayer.id} href="{baseUrl}/{prayer.slug}">
|
||||||
{#if prayer.id === 'signOfCross'}
|
{#if prayer.id === 'signOfCross'}
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ const validSlugs = new Set([
|
|||||||
'gebet-zum-hl-erzengel-michael', 'prayer-to-st-michael-the-archangel',
|
'gebet-zum-hl-erzengel-michael', 'prayer-to-st-michael-the-archangel',
|
||||||
'bruder-klaus-gebet', 'prayer-of-st-nicholas-of-flue',
|
'bruder-klaus-gebet', 'prayer-of-st-nicholas-of-flue',
|
||||||
'josephgebet-des-hl-papst-pius-x', 'prayer-to-st-joseph-by-pope-st-pius-x',
|
'josephgebet-des-hl-papst-pius-x', 'prayer-to-st-joseph-by-pope-st-pius-x',
|
||||||
'das-confiteor', 'the-confiteor'
|
'das-confiteor', 'the-confiteor',
|
||||||
|
'ablassgebete',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ params, url }) => {
|
export const load: PageServerLoad = async ({ params, url }) => {
|
||||||
@@ -22,6 +23,10 @@ export const load: PageServerLoad = async ({ params, url }) => {
|
|||||||
throw error(404, 'Prayer not found');
|
throw error(404, 'Prayer not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (params.faithLang === 'faith' && params.prayer === 'ablassgebete') {
|
||||||
|
throw error(404, 'Prayer not found');
|
||||||
|
}
|
||||||
|
|
||||||
const latinParam = url.searchParams.get('latin');
|
const latinParam = url.searchParams.get('latin');
|
||||||
const hasUrlLatin = latinParam !== null;
|
const hasUrlLatin = latinParam !== null;
|
||||||
const initialLatin = hasUrlLatin ? latinParam !== '0' : true;
|
const initialLatin = hasUrlLatin ? latinParam !== '0' : true;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
import BruderKlausGebet from "$lib/components/prayers/BruderKlausGebet.svelte";
|
import BruderKlausGebet from "$lib/components/prayers/BruderKlausGebet.svelte";
|
||||||
import JosephGebet from "$lib/components/prayers/JosephGebet.svelte";
|
import JosephGebet from "$lib/components/prayers/JosephGebet.svelte";
|
||||||
import Confiteor from "$lib/components/prayers/Confiteor.svelte";
|
import Confiteor from "$lib/components/prayers/Confiteor.svelte";
|
||||||
|
import AblassGebete from "$lib/components/prayers/AblassGebete.svelte";
|
||||||
|
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
|
|
||||||
@@ -49,7 +50,8 @@
|
|||||||
'josephgebet-des-hl-papst-pius-x': { id: 'joseph', name: isEnglish ? 'Prayer to St. Joseph by Pope St. Pius X' : 'Josephgebet des hl. Papst Pius X', bilingue: false },
|
'josephgebet-des-hl-papst-pius-x': { id: 'joseph', name: isEnglish ? 'Prayer to St. Joseph by Pope St. Pius X' : 'Josephgebet des hl. Papst Pius X', bilingue: false },
|
||||||
'prayer-to-st-joseph-by-pope-st-pius-x': { id: 'joseph', name: isEnglish ? 'Prayer to St. Joseph by Pope St. Pius X' : 'Josephgebet des hl. Papst Pius X', bilingue: false },
|
'prayer-to-st-joseph-by-pope-st-pius-x': { id: 'joseph', name: isEnglish ? 'Prayer to St. Joseph by Pope St. Pius X' : 'Josephgebet des hl. Papst Pius X', bilingue: false },
|
||||||
'das-confiteor': { id: 'confiteor', name: isEnglish ? 'The Confiteor' : 'Das Confiteor', bilingue: true },
|
'das-confiteor': { id: 'confiteor', name: isEnglish ? 'The Confiteor' : 'Das Confiteor', bilingue: true },
|
||||||
'the-confiteor': { id: 'confiteor', name: isEnglish ? 'The Confiteor' : 'Das Confiteor', bilingue: true }
|
'the-confiteor': { id: 'confiteor', name: isEnglish ? 'The Confiteor' : 'Das Confiteor', bilingue: true },
|
||||||
|
'ablassgebete': { id: 'ablassgebete', name: 'Ablassgebete', bilingue: true }
|
||||||
});
|
});
|
||||||
|
|
||||||
const prayer = $derived(prayerDefs[data.prayer]);
|
const prayer = $derived(prayerDefs[data.prayer]);
|
||||||
@@ -64,11 +66,150 @@
|
|||||||
// Toggle href for no-JS fallback (navigates to opposite latin state)
|
// Toggle href for no-JS fallback (navigates to opposite latin state)
|
||||||
const latinToggleHref = $derived(data.initialLatin ? '?latin=0' : '?');
|
const latinToggleHref = $derived(data.initialLatin ? '?latin=0' : '?');
|
||||||
|
|
||||||
|
// PiP drag-to-corner logic
|
||||||
|
let pipEl = $state(null);
|
||||||
|
let corner = $state('bottom-right');
|
||||||
|
let dragging = $state(false);
|
||||||
|
let enlarged = $state(false);
|
||||||
|
let dragOffset = { x: 0, y: 0 };
|
||||||
|
let dragPos = $state({ x: 0, y: 0 });
|
||||||
|
let dragMoved = false;
|
||||||
|
let lastTapTime = 0;
|
||||||
|
const MARGIN = 16;
|
||||||
|
const TAP_THRESHOLD = 10; // px movement to distinguish tap from drag
|
||||||
|
const DOUBLE_TAP_MS = 400;
|
||||||
|
|
||||||
|
function getCornerPos(c, el) {
|
||||||
|
const vw = window.innerWidth;
|
||||||
|
const vh = window.innerHeight;
|
||||||
|
const r = el.getBoundingClientRect();
|
||||||
|
const positions = {
|
||||||
|
'top-left': { x: MARGIN, y: MARGIN },
|
||||||
|
'top-right': { x: vw - r.width - MARGIN, y: MARGIN },
|
||||||
|
'bottom-left': { x: MARGIN, y: vh - r.height - MARGIN },
|
||||||
|
'bottom-right': { x: vw - r.width - MARGIN, y: vh - r.height - MARGIN },
|
||||||
|
};
|
||||||
|
return positions[c];
|
||||||
|
}
|
||||||
|
|
||||||
|
function snapToCorner(el, c) {
|
||||||
|
const pos = getCornerPos(c, el);
|
||||||
|
corner = c;
|
||||||
|
dragPos = pos;
|
||||||
|
el.style.transition = 'transform 0.25s ease';
|
||||||
|
el.style.transform = `translate(${pos.x}px, ${pos.y}px)`;
|
||||||
|
el.addEventListener('transitionend', () => { el.style.transition = ''; }, { once: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
function nearestCorner(x, y, el) {
|
||||||
|
const vw = window.innerWidth;
|
||||||
|
const vh = window.innerHeight;
|
||||||
|
const r = el.getBoundingClientRect();
|
||||||
|
const cx = x + r.width / 2;
|
||||||
|
const cy = y + r.height / 2;
|
||||||
|
const left = cx < vw / 2;
|
||||||
|
const top = cy < vh / 2;
|
||||||
|
return `${top ? 'top' : 'bottom'}-${left ? 'left' : 'right'}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onPointerDown(e) {
|
||||||
|
if (!pipEl || window.matchMedia('(min-width: 1024px)').matches) return;
|
||||||
|
dragging = true;
|
||||||
|
dragMoved = false;
|
||||||
|
const r = pipEl.getBoundingClientRect();
|
||||||
|
dragOffset = { x: e.clientX - r.left, y: e.clientY - r.top };
|
||||||
|
pipEl.setPointerCapture(e.pointerId);
|
||||||
|
pipEl.style.transition = '';
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onPointerMove(e) {
|
||||||
|
if (!dragging || !pipEl) return;
|
||||||
|
const x = e.clientX - dragOffset.x;
|
||||||
|
const y = e.clientY - dragOffset.y;
|
||||||
|
if (!dragMoved) {
|
||||||
|
const dx = Math.abs(x - dragPos.x);
|
||||||
|
const dy = Math.abs(y - dragPos.y);
|
||||||
|
if (dx > TAP_THRESHOLD || dy > TAP_THRESHOLD) dragMoved = true;
|
||||||
|
}
|
||||||
|
dragPos = { x, y };
|
||||||
|
pipEl.style.transform = `translate(${x}px, ${y}px)`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleEnlarged() {
|
||||||
|
if (!pipEl) return;
|
||||||
|
const rect = pipEl.getBoundingClientRect();
|
||||||
|
const vh = window.innerHeight / 100;
|
||||||
|
const currentH = enlarged ? 37.5 * vh : 25 * vh;
|
||||||
|
const targetH = enlarged ? 25 * vh : 37.5 * vh;
|
||||||
|
const ratio = targetH / currentH;
|
||||||
|
|
||||||
|
enlarged = !enlarged;
|
||||||
|
|
||||||
|
// Calculate new size and keep the anchored corner fixed
|
||||||
|
const newW = rect.width * ratio;
|
||||||
|
const newH = rect.height * ratio;
|
||||||
|
let newX = rect.left;
|
||||||
|
let newY = rect.top;
|
||||||
|
if (corner.includes('right')) newX = rect.right - newW;
|
||||||
|
if (corner.includes('bottom')) newY = rect.bottom - newH;
|
||||||
|
|
||||||
|
dragPos = { x: newX, y: newY };
|
||||||
|
pipEl.style.transition = 'transform 0.25s ease';
|
||||||
|
pipEl.style.transform = `translate(${newX}px, ${newY}px)`;
|
||||||
|
pipEl.addEventListener('transitionend', () => {
|
||||||
|
pipEl.style.transition = '';
|
||||||
|
}, { once: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
function onPointerUp(e) {
|
||||||
|
if (!dragging || !pipEl) return;
|
||||||
|
dragging = false;
|
||||||
|
|
||||||
|
if (!dragMoved) {
|
||||||
|
// It was a tap, check for double-tap
|
||||||
|
const now = Date.now();
|
||||||
|
if (now - lastTapTime < DOUBLE_TAP_MS) {
|
||||||
|
lastTapTime = 0;
|
||||||
|
toggleEnlarged();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lastTapTime = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
const r = pipEl.getBoundingClientRect();
|
||||||
|
snapToCorner(pipEl, nearestCorner(r.left, r.top, pipEl));
|
||||||
|
}
|
||||||
|
|
||||||
|
function onResize() {
|
||||||
|
if (!pipEl) return;
|
||||||
|
const isDesktop = window.matchMedia('(min-width: 1024px)').matches;
|
||||||
|
if (isDesktop) {
|
||||||
|
pipEl.style.opacity = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const pos = getCornerPos(corner, pipEl);
|
||||||
|
dragPos = pos;
|
||||||
|
pipEl.style.transform = `translate(${pos.x}px, ${pos.y}px)`;
|
||||||
|
pipEl.style.opacity = '1';
|
||||||
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
// Clean up URL params after hydration (state is now in component state)
|
// Clean up URL params after hydration (state is now in component state)
|
||||||
if (window.location.search) {
|
if (window.location.search) {
|
||||||
history.replaceState({}, '', window.location.pathname);
|
history.replaceState({}, '', window.location.pathname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initial position for PiP
|
||||||
|
if (pipEl && !window.matchMedia('(min-width: 1024px)').matches) {
|
||||||
|
const pos = getCornerPos(corner, pipEl);
|
||||||
|
dragPos = pos;
|
||||||
|
pipEl.style.transform = `translate(${pos.x}px, ${pos.y}px)`;
|
||||||
|
pipEl.style.opacity = '1';
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('resize', onResize);
|
||||||
|
return () => window.removeEventListener('resize', onResize);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -106,6 +247,12 @@ h1 {
|
|||||||
:global(.bilingue v:lang(de)) {
|
:global(.bilingue v:lang(de)) {
|
||||||
color: grey;
|
color: grey;
|
||||||
}
|
}
|
||||||
|
:global(.bilingue .monolingual v:lang(de)) {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
:global(.bilingue .monolingual v:lang(de) i) {
|
||||||
|
color: var(--nord11);
|
||||||
|
}
|
||||||
:global(.gebet i) {
|
:global(.gebet i) {
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
color: var(--nord11);
|
color: var(--nord11);
|
||||||
@@ -126,8 +273,126 @@ h1 {
|
|||||||
background-color: var(--nord5);
|
background-color: var(--nord5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.crucifix-layout {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
margin: auto;
|
||||||
|
padding: 0 1em;
|
||||||
|
}
|
||||||
|
.crucifix-layout .crucifix-wrap {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 10000;
|
||||||
|
width: auto;
|
||||||
|
opacity: 0;
|
||||||
|
touch-action: none;
|
||||||
|
cursor: grab;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
.crucifix-layout .crucifix-wrap:active {
|
||||||
|
cursor: grabbing;
|
||||||
|
}
|
||||||
|
.crucifix-layout .crucifix-wrap img {
|
||||||
|
height: 25vh;
|
||||||
|
width: auto;
|
||||||
|
object-fit: contain;
|
||||||
|
border-radius: 6px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
||||||
|
pointer-events: none;
|
||||||
|
transition: height 0.25s ease;
|
||||||
|
}
|
||||||
|
.crucifix-layout .crucifix-wrap.enlarged img {
|
||||||
|
height: 37.5vh;
|
||||||
|
}
|
||||||
|
.crucifix-layout .prayer-scroll {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 700px;
|
||||||
|
}
|
||||||
|
@media (min-width: 1024px) {
|
||||||
|
.crucifix-layout {
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 2em;
|
||||||
|
}
|
||||||
|
.crucifix-layout .prayer-scroll {
|
||||||
|
flex: 0 1 700px;
|
||||||
|
}
|
||||||
|
.crucifix-layout .crucifix-wrap {
|
||||||
|
position: sticky;
|
||||||
|
top: 4rem;
|
||||||
|
left: auto;
|
||||||
|
transform: none !important;
|
||||||
|
opacity: 1;
|
||||||
|
flex: 1;
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 0;
|
||||||
|
order: 1;
|
||||||
|
cursor: default;
|
||||||
|
touch-action: auto;
|
||||||
|
user-select: auto;
|
||||||
|
}
|
||||||
|
.crucifix-layout .crucifix-wrap img {
|
||||||
|
max-height: calc(100vh - 4rem);
|
||||||
|
height: auto;
|
||||||
|
width: 100%;
|
||||||
|
object-fit: contain;
|
||||||
|
border-radius: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
.crucifix-layout .crucifix-wrap {
|
||||||
|
background-color: var(--nord5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: light) and (min-width: 1024px) {
|
||||||
|
.crucifix-layout .crucifix-wrap {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 1400px) {
|
||||||
|
.crucifix-layout::before {
|
||||||
|
content: '';
|
||||||
|
flex: 1;
|
||||||
|
order: -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
{#if prayerId === 'ablassgebete'}
|
||||||
|
|
||||||
|
<h1>{prayerName}</h1>
|
||||||
|
|
||||||
|
<div class="toggle-controls">
|
||||||
|
<LanguageToggle
|
||||||
|
initialLatin={data.initialLatin}
|
||||||
|
hasUrlLatin={data.hasUrlLatin}
|
||||||
|
href={latinToggleHref}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="crucifix-layout">
|
||||||
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||||
|
<div
|
||||||
|
class="crucifix-wrap"
|
||||||
|
class:enlarged
|
||||||
|
bind:this={pipEl}
|
||||||
|
onpointerdown={onPointerDown}
|
||||||
|
onpointermove={onPointerMove}
|
||||||
|
onpointerup={onPointerUp}
|
||||||
|
>
|
||||||
|
<img src="/glaube/crucifix.webp" alt="Crucifix">
|
||||||
|
</div>
|
||||||
|
<div class="prayer-scroll">
|
||||||
|
<div class="gebet-wrapper">
|
||||||
|
<div class="gebet" class:bilingue={isBilingue}>
|
||||||
|
<AblassGebete verbose={true} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1>{prayerName}</h1>
|
<h1>{prayerName}</h1>
|
||||||
|
|
||||||
@@ -139,6 +404,7 @@ h1 {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="gebet-wrapper">
|
<div class="gebet-wrapper">
|
||||||
{#if prayerId === 'gloria'}
|
{#if prayerId === 'gloria'}
|
||||||
<p class="intro">{gloriaIntro}</p>
|
<p class="intro">{gloriaIntro}</p>
|
||||||
@@ -172,3 +438,4 @@ h1 {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
|
|||||||
BIN
static/glaube/crucifix.jpg
Normal file
BIN
static/glaube/crucifix.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 64 KiB |
BIN
static/glaube/crucifix.webp
Normal file
BIN
static/glaube/crucifix.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 46 KiB |
Reference in New Issue
Block a user