Compare commits
55 Commits
a4738134fe
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
b255fc01e9
|
|||
|
b90a42b1aa
|
|||
|
7ba0995bf8
|
|||
|
9177164ddf
|
|||
|
207efcc38e
|
|||
|
f074c0af08
|
|||
|
d0a01a75e7
|
|||
|
53da9ad26d
|
|||
|
0ea09e424e
|
|||
|
716c6cc6e6
|
|||
|
eeb3030186
|
|||
|
16d891fc2f
|
|||
|
cf73e6b62f
|
|||
|
8db7ca6bcc
|
|||
|
13fd2143d9
|
|||
|
a074fdc7e3
|
|||
|
dbf6744479
|
|||
|
28057e88d5
|
|||
|
e58c8e46ef
|
|||
|
2024551e0e
|
|||
|
c53aee7123
|
|||
|
7e94758b23
|
|||
|
10dd3158fe
|
|||
|
7922563c4d
|
|||
|
c855cdd25c
|
|||
|
f900d4217d
|
|||
|
0e9daf296d
|
|||
|
4191012cf1
|
|||
|
a435a1142f
|
|||
|
8c984f3064
|
|||
|
044fddd1c9
|
|||
|
db28629c7d
|
|||
|
0e0af55ce7
|
|||
|
601e2f6513
|
|||
|
aa64cd8306
|
|||
|
96a91ed8dd
|
|||
|
a0146927b6
|
|||
|
443e3300a1
|
|||
|
2f711c66b0
|
|||
|
7901d56b5b
|
|||
|
2c364ed351
|
|||
|
904c5c0df0
|
|||
|
091c23a0bd
|
|||
|
7bdc62489c
|
|||
|
01ccc705ee
|
|||
|
35ea60e637
|
|||
|
ac4c00a082
|
|||
|
8560077759
|
|||
|
b3c3f34e50
|
|||
|
6eaf0bb4f4
|
|||
|
07554f16df
|
|||
|
bf3014337e
|
|||
|
6182b8f943
|
|||
|
8246906a76
|
|||
|
a5e119f976
|
@@ -5,7 +5,7 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite dev",
|
"dev": "vite dev",
|
||||||
"prebuild": "npx vite-node scripts/generate-mystery-verses.ts",
|
"prebuild": "bash scripts/subset-emoji-font.sh && npx vite-node scripts/generate-mystery-verses.ts",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||||
|
|||||||
@@ -5,31 +5,33 @@
|
|||||||
import { writeFileSync } from 'fs';
|
import { writeFileSync } from 'fs';
|
||||||
import { resolve } from 'path';
|
import { resolve } from 'path';
|
||||||
import { lookupReference } from '../src/lib/server/bible';
|
import { lookupReference } from '../src/lib/server/bible';
|
||||||
import { mysteryReferences } from '../src/lib/data/mysteryDescriptions';
|
import { mysteryReferences, mysteryReferencesEnglish, theologicalVirtueReference, theologicalVirtueReferenceEnglish } from '../src/lib/data/mysteryDescriptions';
|
||||||
import type { MysteryDescription, VerseData } from '../src/lib/data/mysteryDescriptions';
|
import type { MysteryDescription, VerseData } from '../src/lib/data/mysteryDescriptions';
|
||||||
|
|
||||||
const tsvPath = resolve('static/allioli.tsv');
|
function generateVerseData(
|
||||||
|
references: Record<string, readonly { title: string; reference: string }[]>,
|
||||||
|
tsvPath: string
|
||||||
|
): Record<string, MysteryDescription[]> {
|
||||||
|
const result: Record<string, MysteryDescription[]> = {};
|
||||||
|
|
||||||
const mysteryDescriptions: Record<string, MysteryDescription[]> = {};
|
for (const [mysteryType, refs] of Object.entries(references)) {
|
||||||
|
|
||||||
for (const [mysteryType, references] of Object.entries(mysteryReferences)) {
|
|
||||||
const descriptions: MysteryDescription[] = [];
|
const descriptions: MysteryDescription[] = [];
|
||||||
|
|
||||||
for (const ref of references) {
|
for (const ref of refs) {
|
||||||
const result = lookupReference(ref.reference, tsvPath);
|
const lookup = lookupReference(ref.reference, tsvPath);
|
||||||
|
|
||||||
let text = '';
|
let text = '';
|
||||||
let verseData: VerseData | null = null;
|
let verseData: VerseData | null = null;
|
||||||
|
|
||||||
if (result && result.verses.length > 0) {
|
if (lookup && lookup.verses.length > 0) {
|
||||||
text = `«${result.verses.map((v) => v.text).join(' ')}»`;
|
text = `«${lookup.verses.map((v) => v.text).join(' ')}»`;
|
||||||
verseData = {
|
verseData = {
|
||||||
book: result.book,
|
book: lookup.book,
|
||||||
chapter: result.chapter,
|
chapter: lookup.chapter,
|
||||||
verses: result.verses
|
verses: lookup.verses
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
console.warn(`No verses found for: ${ref.reference}`);
|
console.warn(`No verses found for: ${ref.reference} in ${tsvPath}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
descriptions.push({
|
descriptions.push({
|
||||||
@@ -40,13 +42,45 @@ for (const [mysteryType, references] of Object.entries(mysteryReferences)) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
mysteryDescriptions[mysteryType] = descriptions;
|
result[mysteryType] = descriptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dePath = resolve('static/allioli.tsv');
|
||||||
|
const enPath = resolve('static/drb.tsv');
|
||||||
|
|
||||||
|
const mysteryVerseDataDe = generateVerseData(mysteryReferences, dePath);
|
||||||
|
const mysteryVerseDataEn = generateVerseData(mysteryReferencesEnglish, enPath);
|
||||||
|
|
||||||
|
// Generate theological virtue (1 Cor 13) verse data
|
||||||
|
function generateSingleRef(ref: { title: string; reference: string }, tsvPath: string): MysteryDescription {
|
||||||
|
const lookup = lookupReference(ref.reference, tsvPath);
|
||||||
|
let text = '';
|
||||||
|
let verseData: VerseData | null = null;
|
||||||
|
if (lookup && lookup.verses.length > 0) {
|
||||||
|
text = `«${lookup.verses.map((v) => v.text).join(' ')}»`;
|
||||||
|
verseData = { book: lookup.book, chapter: lookup.chapter, verses: lookup.verses };
|
||||||
|
} else {
|
||||||
|
console.warn(`No verses found for: ${ref.reference} in ${tsvPath}`);
|
||||||
|
}
|
||||||
|
return { title: ref.title, reference: ref.reference, text, verseData };
|
||||||
|
}
|
||||||
|
|
||||||
|
const theologicalVirtueDataDe = generateSingleRef(theologicalVirtueReference, dePath);
|
||||||
|
const theologicalVirtueDataEn = generateSingleRef(theologicalVirtueReferenceEnglish, enPath);
|
||||||
|
|
||||||
const output = `// Auto-generated by scripts/generate-mystery-verses.ts — do not edit manually
|
const output = `// Auto-generated by scripts/generate-mystery-verses.ts — do not edit manually
|
||||||
import type { MysteryDescription } from './mysteryDescriptions';
|
import type { MysteryDescription } from './mysteryDescriptions';
|
||||||
|
|
||||||
export const mysteryVerseData: Record<string, MysteryDescription[]> = ${JSON.stringify(mysteryDescriptions, null, '\t')};
|
export const mysteryVerseDataDe: Record<string, MysteryDescription[]> = ${JSON.stringify(mysteryVerseDataDe, null, '\t')};
|
||||||
|
|
||||||
|
export const mysteryVerseDataEn: Record<string, MysteryDescription[]> = ${JSON.stringify(mysteryVerseDataEn, null, '\t')};
|
||||||
|
|
||||||
|
export const theologicalVirtueVerseDataDe: MysteryDescription = ${JSON.stringify(theologicalVirtueDataDe, null, '\t')};
|
||||||
|
|
||||||
|
export const theologicalVirtueVerseDataEn: MysteryDescription = ${JSON.stringify(theologicalVirtueDataEn, null, '\t')};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const outPath = resolve('src/lib/data/mysteryVerseData.ts');
|
const outPath = resolve('src/lib/data/mysteryVerseData.ts');
|
||||||
|
|||||||
54
scripts/subset-emoji-font.sh
Executable file
54
scripts/subset-emoji-font.sh
Executable file
@@ -0,0 +1,54 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Subset NotoColorEmoji to only the emojis we actually use.
|
||||||
|
# Requires: fonttools (provides pyftsubset) and woff2 (provides woff2_compress)
|
||||||
|
#
|
||||||
|
# Source font: system-installed NotoColorEmoji.ttf
|
||||||
|
# Output: static/fonts/NotoColorEmoji.woff2 + .ttf
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||||
|
OUT_DIR="$PROJECT_ROOT/static/fonts"
|
||||||
|
|
||||||
|
SRC_FONT="/usr/share/fonts/noto/NotoColorEmoji.ttf"
|
||||||
|
|
||||||
|
if [ ! -f "$SRC_FONT" ]; then
|
||||||
|
echo "Error: Source font not found at $SRC_FONT" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ─── Fixed list of emojis to include ────────────────────────────────
|
||||||
|
# Recipe icons (from database + hardcoded)
|
||||||
|
# Season/liturgical: ☀️ ✝️ ❄️ 🌷 🍂 🎄 🐇
|
||||||
|
# Food/recipe: 🍽️ 🥫
|
||||||
|
# UI/cospend categories: 🛒 🛍️ 🚆 ⚡ 🎉 🤝 💸
|
||||||
|
# Status/feedback: ❤️ 🖤 ✅ ❌ 🚀 ⚠️ ✨ 🔄
|
||||||
|
# Features: 📋 🖼️ 📖 🤖 🌐 🔐 🔍 🚫
|
||||||
|
|
||||||
|
EMOJIS="☀✝❄🌷🍂🎄🐇🍽🥫🛒🛍🚆⚡🎉🤝💸❤🖤✅❌🚀⚠✨🔄📋🖼📖🤖🌐🔐🔍🚫"
|
||||||
|
# ────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
# Build Unicode codepoint list from the emoji string (Python for reliable Unicode handling)
|
||||||
|
UNICODES=$(python3 -c "print(','.join(f'U+{ord(c):04X}' for c in '$EMOJIS'))")
|
||||||
|
GLYPH_COUNT=$(python3 -c "print(len('$EMOJIS'))")
|
||||||
|
|
||||||
|
echo "Subsetting NotoColorEmoji with $GLYPH_COUNT glyphs..."
|
||||||
|
|
||||||
|
# Subset to TTF
|
||||||
|
pyftsubset "$SRC_FONT" \
|
||||||
|
--unicodes="$UNICODES" \
|
||||||
|
--output-file="$OUT_DIR/NotoColorEmoji.ttf" \
|
||||||
|
--no-ignore-missing-unicodes
|
||||||
|
|
||||||
|
# Convert to WOFF2
|
||||||
|
woff2_compress "$OUT_DIR/NotoColorEmoji.ttf"
|
||||||
|
|
||||||
|
ORIG_SIZE=$(stat -c%s "$SRC_FONT" 2>/dev/null || stat -f%z "$SRC_FONT")
|
||||||
|
TTF_SIZE=$(stat -c%s "$OUT_DIR/NotoColorEmoji.ttf" 2>/dev/null || stat -f%z "$OUT_DIR/NotoColorEmoji.ttf")
|
||||||
|
WOFF2_SIZE=$(stat -c%s "$OUT_DIR/NotoColorEmoji.woff2" 2>/dev/null || stat -f%z "$OUT_DIR/NotoColorEmoji.woff2")
|
||||||
|
|
||||||
|
echo "Done!"
|
||||||
|
echo " Original: $(numfmt --to=iec "$ORIG_SIZE")"
|
||||||
|
echo " TTF: $(numfmt --to=iec "$TTF_SIZE")"
|
||||||
|
echo " WOFF2: $(numfmt --to=iec "$WOFF2_SIZE")"
|
||||||
205
src/app.css
205
src/app.css
@@ -15,6 +15,15 @@
|
|||||||
url(/fonts/crosses.ttf) format('truetype');
|
url(/fonts/crosses.ttf) format('truetype');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Noto Color Emoji Subset';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(/fonts/NotoColorEmoji.woff2) format('woff2'),
|
||||||
|
url(/fonts/NotoColorEmoji.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
COLOR SYSTEM
|
COLOR SYSTEM
|
||||||
Based on Nord Theme with semantic naming
|
Based on Nord Theme with semantic naming
|
||||||
@@ -109,6 +118,35 @@
|
|||||||
--color-warning: var(--nord13);
|
--color-warning: var(--nord13);
|
||||||
--color-error: var(--nord11);
|
--color-error: var(--nord11);
|
||||||
--color-info: var(--nord10);
|
--color-info: var(--nord10);
|
||||||
|
|
||||||
|
/* Shared transitions & shadows */
|
||||||
|
--transition-fast: 100ms;
|
||||||
|
--transition-normal: 200ms;
|
||||||
|
--shadow-sm: 0 0 0.4em 0.05em rgba(0,0,0,0.2);
|
||||||
|
--shadow-md: 0 0 0.5em 0.1em rgba(0,0,0,0.3);
|
||||||
|
--shadow-lg: 0 0 1em 0.1em rgba(0,0,0,0.4);
|
||||||
|
--shadow-hover: 0.1em 0.1em 0.5em 0.1em rgba(0,0,0,0.3);
|
||||||
|
--radius-pill: 1000px;
|
||||||
|
--radius-card: 20px;
|
||||||
|
--radius-sm: 0.3rem;
|
||||||
|
--radius-md: 0.5rem;
|
||||||
|
--radius-lg: 0.75rem;
|
||||||
|
|
||||||
|
/* Spacing scale */
|
||||||
|
--space-xs: 0.25rem;
|
||||||
|
--space-sm: 0.5rem;
|
||||||
|
--space-md: 1rem;
|
||||||
|
--space-lg: 1.5rem;
|
||||||
|
--space-xl: 2rem;
|
||||||
|
--space-2xl: 3rem;
|
||||||
|
|
||||||
|
/* Font size scale */
|
||||||
|
--text-sm: 0.85rem;
|
||||||
|
--text-base: 1rem;
|
||||||
|
--text-lg: 1.1rem;
|
||||||
|
--text-xl: 1.5rem;
|
||||||
|
--text-2xl: 2rem;
|
||||||
|
--text-3xl: 3rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
@@ -208,65 +246,142 @@ a:focus-visible {
|
|||||||
color: var(--color-link-hover);
|
color: var(--color-link-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
FORM STYLES
|
GLOBAL UTILITY CLASSES
|
||||||
============================================ */
|
============================================ */
|
||||||
|
|
||||||
form {
|
/* Pill-shaped element base */
|
||||||
background-color: var(--color-bg-secondary);
|
.g-pill {
|
||||||
display: flex;
|
border-radius: var(--radius-pill);
|
||||||
flex-direction: column;
|
|
||||||
max-width: 600px;
|
|
||||||
gap: 0.5em;
|
|
||||||
margin-inline: auto;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
padding-block: 2rem;
|
|
||||||
margin-block: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
form label {
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
form input {
|
|
||||||
display: block;
|
|
||||||
font-size: 1.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
form:not(.search) button {
|
|
||||||
background-color: var(--color-accent);
|
|
||||||
color: var(--color-text-on-accent);
|
|
||||||
border: none;
|
border: none;
|
||||||
padding: 0.5em 1em;
|
|
||||||
font-size: 1.3em;
|
|
||||||
border-radius: 1000px;
|
|
||||||
margin-top: 1em;
|
|
||||||
transition: 100ms;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: var(--transition-fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
form:not(.search) button:hover,
|
/* Interactive hover/focus effects */
|
||||||
form:not(.search) button:focus-visible {
|
.g-interactive {
|
||||||
background-color: var(--color-accent-hover);
|
transition: var(--transition-fast);
|
||||||
scale: 1.1;
|
}
|
||||||
|
.g-interactive:hover,
|
||||||
|
.g-interactive:focus-visible {
|
||||||
|
transform: scale(1.05);
|
||||||
|
box-shadow: var(--shadow-hover);
|
||||||
|
}
|
||||||
|
.g-interactive:focus {
|
||||||
|
scale: 0.9;
|
||||||
}
|
}
|
||||||
|
|
||||||
form:not(.search) button:active {
|
/* Light background button (with dark mode) */
|
||||||
background-color: var(--color-accent-active);
|
.g-btn-light {
|
||||||
|
background-color: var(--nord5);
|
||||||
|
color: var(--nord0);
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.g-btn-light {
|
||||||
|
background-color: var(--nord0);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
form p {
|
/* Dark background button */
|
||||||
max-width: 400px;
|
.g-btn-dark,
|
||||||
margin-top: 0;
|
.g-btn-dark:visited,
|
||||||
|
.g-btn-dark:link {
|
||||||
|
background-color: var(--nord0);
|
||||||
|
color: var(--nord6);
|
||||||
|
box-shadow: var(--shadow-lg);
|
||||||
|
}
|
||||||
|
.g-btn-dark:hover,
|
||||||
|
.g-btn-dark:focus-visible {
|
||||||
|
background-color: var(--nord1);
|
||||||
|
color: var(--nord6);
|
||||||
}
|
}
|
||||||
|
|
||||||
form h4 {
|
/* Icon badge (circular icon container) */
|
||||||
margin-bottom: 0;
|
.g-icon-badge {
|
||||||
|
font-family: "Noto Color Emoji", "Noto Color Emoji Subset", emoji, sans-serif;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 50%;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: var(--transition-fast);
|
||||||
|
box-shadow: var(--shadow-lg);
|
||||||
|
}
|
||||||
|
.g-icon-badge:hover,
|
||||||
|
.g-icon-badge:focus-visible {
|
||||||
|
transform: scale(1.1);
|
||||||
|
box-shadow: var(--shadow-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 600px) {
|
/* Tag/chip styling */
|
||||||
form {
|
.g-tag,
|
||||||
margin-top: 0;
|
.g-tag:visited,
|
||||||
|
.g-tag:link {
|
||||||
|
padding: 0.25em 1em;
|
||||||
|
border-radius: var(--radius-pill);
|
||||||
|
background-color: var(--nord5);
|
||||||
|
color: var(--nord0);
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: transform var(--transition-fast), background-color var(--transition-fast), box-shadow var(--transition-fast), color var(--transition-fast);
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
|
border: none;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.g-tag:hover,
|
||||||
|
.g-tag:focus-visible {
|
||||||
|
transform: scale(1.05);
|
||||||
|
background-color: var(--nord8);
|
||||||
|
box-shadow: var(--shadow-hover);
|
||||||
|
color: var(--nord0);
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.g-tag,
|
||||||
|
.g-tag:visited,
|
||||||
|
.g-tag:link {
|
||||||
|
background-color: var(--nord0);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.g-tag:hover,
|
||||||
|
.g-tag:focus-visible {
|
||||||
|
background-color: var(--nord8);
|
||||||
|
color: var(--nord0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
RECIPE GRID
|
||||||
|
Responsive card grid used across recipe pages
|
||||||
|
============================================ */
|
||||||
|
|
||||||
|
.recipe-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
gap: 0.8em;
|
||||||
|
padding: 0 0.8em;
|
||||||
|
max-width: 1400px;
|
||||||
|
margin: 0 auto 2em;
|
||||||
|
}
|
||||||
|
@media (max-width: 250px) {
|
||||||
|
.recipe-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
.recipe-grid {
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||||
|
gap: 1.5em;
|
||||||
|
padding: 0 1.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 1024px) {
|
||||||
|
.recipe-grid {
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
|
||||||
|
gap: 1.8em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,9 +63,11 @@ async function authorization({ event, resolve }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Bible verse functionality for error pages
|
// Bible verse functionality for error pages
|
||||||
async function getRandomVerse(fetch: typeof globalThis.fetch): Promise<any> {
|
async function getRandomVerse(fetch: typeof globalThis.fetch, pathname: string): Promise<any> {
|
||||||
|
const isEnglish = pathname.startsWith('/faith/') || pathname.startsWith('/recipes/');
|
||||||
|
const endpoint = isEnglish ? '/api/faith/bibel/zufallszitat' : '/api/glaube/bibel/zufallszitat';
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/glaube/bibel/zufallszitat');
|
const response = await fetch(endpoint);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`HTTP error! status: ${response.status}`);
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
}
|
}
|
||||||
@@ -80,11 +82,14 @@ export const handleError: HandleServerError = async ({ error, event, status, mes
|
|||||||
console.error('Error occurred:', { error, status, message, url: event.url.pathname });
|
console.error('Error occurred:', { error, status, message, url: event.url.pathname });
|
||||||
|
|
||||||
// Add Bible verse to error context
|
// Add Bible verse to error context
|
||||||
const bibleQuote = await getRandomVerse(event.fetch);
|
const bibleQuote = await getRandomVerse(event.fetch, event.url.pathname);
|
||||||
|
|
||||||
|
const isEnglish = event.url.pathname.startsWith('/faith/') || event.url.pathname.startsWith('/recipes/');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
message: message,
|
message: message,
|
||||||
bibleQuote
|
bibleQuote,
|
||||||
|
lang: isEnglish ? 'en' : 'de'
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
import type { Snippet } from 'svelte';
|
import type { Snippet } from 'svelte';
|
||||||
|
|
||||||
let { href, ariaLabel = undefined, children } = $props<{ href: string, ariaLabel?: string, children?: Snippet }>();
|
let { href, ariaLabel = undefined, children } = $props<{ href: string, ariaLabel?: string, children?: Snippet }>();
|
||||||
import "$lib/css/nordtheme.css"
|
|
||||||
import "$lib/css/action_button.css"
|
import "$lib/css/action_button.css"
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -14,9 +13,9 @@ right:0;
|
|||||||
width: 1rem;
|
width: 1rem;
|
||||||
height: 1rem;
|
height: 1rem;
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
border-radius: 1000px;
|
border-radius: var(--radius-pill);
|
||||||
margin: 2rem;
|
margin: 2rem;
|
||||||
transition: 200ms;
|
transition: var(--transition-normal);
|
||||||
background-color: var(--red);
|
background-color: var(--red);
|
||||||
display: grid;
|
display: grid;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|||||||
@@ -1,83 +0,0 @@
|
|||||||
<script>
|
|
||||||
let { x = 0, y = 0, size = 40 } = $props();
|
|
||||||
</script>
|
|
||||||
<style>
|
|
||||||
.bg{
|
|
||||||
fill: white;
|
|
||||||
}
|
|
||||||
.fg{
|
|
||||||
stroke: var(--nord2);
|
|
||||||
fill: var(--nord2);
|
|
||||||
stroke-linejoin: round;
|
|
||||||
stroke-linecap: round;
|
|
||||||
}
|
|
||||||
@media (prefers-color-scheme: light) {
|
|
||||||
.bg{
|
|
||||||
fill: var(--nord3);
|
|
||||||
}
|
|
||||||
.fg{
|
|
||||||
stroke: white;
|
|
||||||
fill: white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<svg {x} {y} width={size} height={size} viewBox="0 0 334 326" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path class="bg" d="m168.72 17.281c-80.677 0-146.06 65.386-146.06 146.06 0 80.677 65.386 146.09 146.06 146.09 80.677 0 146.09-65.417 146.09-146.09 0-80.677-65.417-146.06-146.09-146.06zm2.9062 37.812c21.086 0.35166 41.858 7.6091 59.156 19.688 40.942 26.772 56.481 83.354 38.875 128.22-16.916 45.3-67.116 74.143-114.72 67.844-50.947-5.2807-92.379-52.101-94.563-102.72-4.0889-58.654 48.31-113.56 107.03-113 1.4077-0.03846 2.813-0.05469 4.2188-0.03125z"/>
|
|
||||||
<path class="bg" d="m166.45 51.969c-11.386 0.159-21.538 7.2129-24 12.25 3.2629 3.3685 6.337 8.536 7.375 19.5v159.78c-1.0775 10.727-4.1463 15.792-7.375 19.125 2.4156 4.9422 12.251 11.811 23.375 12.219v0.0312h4.8124c11.386-0.159 21.538-7.2129 24-12.25-3.2629-3.3685-6.337-8.536-7.375-19.5v-159.78c1.0775-10.727 4.1463-15.792 7.375-19.125-2.41-4.938-12.25-11.807-23.37-12.215v-0.03125h-4.8124z"/>
|
|
||||||
<path class="bg" d="m280 161.33c-0.159-11.386-7.2129-21.538-12.25-24-3.3685 3.2629-8.536 6.337-19.5 7.375h-159.78c-10.727-1.0775-15.792-4.1463-19.125-7.375-4.9422 2.4156-11.811 12.251-12.219 23.375h-0.0312v4.8124c0.159 11.386 7.2129 21.538 12.25 24 3.3685-3.2629 8.536-6.337 19.5-7.375h159.78c10.727 1.0775 15.792 4.1463 19.125 7.375 4.9422-2.4156 11.811-12.251 12.219-23.375h0.0312v-4.8124z"/>
|
|
||||||
<path class="bg" transform="matrix(.86578 0 0 .86578 78.719 48.374)" d="m69.839 72.529c0 14.565-11.807 26.373-26.373 26.373-14.565 0-26.373-11.807-26.373-26.373 0-14.565 11.807-26.373 26.373-26.373 14.565 0 26.373 11.807 26.373 26.373z"/>
|
|
||||||
<path class="bg" transform="matrix(.86578 0 0 .86578 182.94 48.396)" d="m69.839 72.529c0 14.565-11.807 26.373-26.373 26.373-14.565 0-26.373-11.807-26.373-26.373 0-14.565 11.807-26.373 26.373-26.373 14.565 0 26.373 11.807 26.373 26.373z"/>
|
|
||||||
<path class="bg" transform="matrix(.86578 0 0 .86578 78.848 152.7)" d="m69.839 72.529c0 14.565-11.807 26.373-26.373 26.373-14.565 0-26.373-11.807-26.373-26.373 0-14.565 11.807-26.373 26.373-26.373 14.565 0 26.373 11.807 26.373 26.373z"/>
|
|
||||||
<path class="bg" transform="matrix(.86578 0 0 .86578 183.14 152.6)" d="m69.839 72.529c0 14.565-11.807 26.373-26.373 26.373-14.565 0-26.373-11.807-26.373-26.373 0-14.565 11.807-26.373 26.373-26.373 14.565 0 26.373 11.807 26.373 26.373z"/>
|
|
||||||
<g class="fg" transform="matrix(.99979 .020664 -.020664 .99979 2.2515 -4.8909)" stroke="var(--nord2)">
|
|
||||||
<path d="m125.64 31.621-0.0722-0.2536 7.1008-2.0212c2.5247-0.71861 4.4393-0.95897 5.7437-0.72108 1.3044 0.23795 2.3382 0.70216 3.1013 1.3926 0.76311 0.69054 1.3404 1.7233 1.7318 3.0984 0.59992 2.1077 0.32369 3.8982-0.82869 5.3715-1.1524 1.4734-2.9805 2.542-5.4842 3.2059l-0.0674-0.23669c1.5779-0.44913 2.7221-1.2987 3.4324-2.5488 0.71031-1.25 0.84089-2.664 0.39175-4.242-0.34971-1.2285-0.89961-2.2508-1.6497-3.0669-0.75012-0.81603-1.6297-1.3485-2.6387-1.5974-1.009-0.24887-2.404-0.11987-4.1848 0.387l-1.7752 0.50529 6.0683 21.319c0.34327 1.206 0.68305 1.886 1.0193 2.0401 0.33626 0.15406 0.88198 0.12362 1.6372-0.09134l0.0674 0.23669-6.5767 1.872-0.0674-0.23669c1.1722-0.33365 1.6059-1.0359 1.3011-2.1066l-5.871-20.626c-0.25024-0.87912-0.52897-1.4303-0.8362-1.6536-0.30723-0.22322-0.82152-0.23218-1.5429-0.02688z"/>
|
|
||||||
<path d="m169.99 38.101-7.5573 0.14169-3.7357 9.8628c-0.2563 0.70806-0.38292 1.1441-0.37984 1.3081 0.007 0.38665 0.29793 0.57459 0.87205 0.56383l0.005 0.24605-3.8489 0.07216-0.005-0.24605c0.51554-0.0097 0.94669-0.14375 1.2935-0.40225 0.34678-0.2585 0.72118-0.91895 1.1232-1.9814l8.9409-23.867 0.43938-0.0082 9.6735 22.709c0.002 0.11717 0.24981 0.66634 0.74293 1.6475 0.49306 0.98116 1.2258 1.4626 2.1984 1.4444l0.005 0.24605-6.0458 0.11335-0.005-0.24605c0.55067-0.01032 0.82195-0.23224 0.81384-0.66576-0.006-0.29292-0.14904-0.75906-0.43059-1.3984-0.0478-0.04599-0.0902-0.12138-0.12731-0.22617-0.0257-0.11672-0.0443-0.17498-0.056-0.17476zm-7.3247-0.5835 6.9949-0.13115-3.6628-8.7571z"/>
|
|
||||||
<path d="m215.05 32.098-0.0754 0.25265c-0.67276-0.28643-1.3926-0.12832-2.1595 0.47432-0.0112-0.0033-0.0331 0.0085-0.0656 0.03545-0.0213 0.03035-0.0465 0.0534-0.0757 0.06913l-0.19006 0.14505c-0.0763 0.05063-0.11777 0.08716-0.12445 0.10961l-0.21872 0.11815-8.9764 7.0246 4.3093 13.156c0.45546 1.5057 0.85105 2.4952 1.1868 2.9684 0.33566 0.47322 0.71066 0.75333 1.125 0.84033l-0.0704 0.23581-6.1647-1.8404 0.0704-0.23581c0.51768 0.19124 0.83688 0.08474 0.95758-0.3195 0.0972-0.32565 0.0472-0.79308-0.15004-1.4023l-3.7548-11.449-9.4239 7.2945c-0.003 0.01123-0.19115 0.16919-0.56339 0.47387-0.41047 0.26882-0.6576 0.54359-0.7414 0.82431-0.10057 0.33687 0.13489 0.57227 0.70641 0.7062l-0.0704 0.23581-3.7056-1.1063 0.0704-0.23581c0.53899 0.16091 1.0726 0.09397 1.6009-0.20082l0.37685-0.2177 11.393-8.8529-4.2181-12.908c0.0469-0.15718-0.0793-0.51283-0.37858-1.0669-0.29932-0.55407-0.71956-0.88743-1.2607-1.0001l0.0754-0.25265 6.249 1.8656-0.0754 0.25265c-0.67376-0.20112-1.0659-0.11641-1.1766 0.25413-0.0805 0.26952-0.002 0.76385 0.23602 1.483l3.0954 9.4177 8.2667-6.4293c0.0145-0.0079 0.14851-0.13908 0.40187-0.39368 0.25331-0.25456 0.39171-0.42114 0.4152-0.49977 0.057-0.19088 0.034-0.32919-0.0688-0.41494-0.10284-0.08571-0.32269-0.17886-0.65953-0.27945l0.0754-0.25265z"/>
|
|
||||||
</g>
|
|
||||||
<g class="fg">
|
|
||||||
<path d="m235.06 72.827-0.26589-0.20212 6.4642-23.724c0.44911-1.6752 0.58908-2.7501 0.4199-3.2247-0.16922-0.47452-0.43107-0.84654-0.78557-1.116l0.15956-0.20991 4.758 3.6168-0.15956 0.20991c-0.39857-0.3471-0.73258-0.3434-1.002 0.01109-0.10639 0.13996-0.19187 0.3105-0.25644 0.51163l-5.6785 20.745 18.416-11.04c0.24704-0.15074 0.42022-0.29142 0.51954-0.42204 0.24109-0.31719 0.10378-0.64972-0.41192-0.99761l0.15957-0.20991 3.0927 2.3509-0.15957 0.20991c-0.21461-0.1631-0.46389-0.30476-0.74785-0.42496-0.28403-0.12019-0.71153-0.06612-1.2825 0.16221-0.57105 0.22835-0.87187 0.35297-0.90244 0.37386z"/>
|
|
||||||
<path d="m278.77 79.16 0.22305-0.14062 3.9185 6.2156c0.99367 1.5762 1.6777 2.7381 2.052 3.4857 0.37431 0.74758 0.59849 1.6141 0.67255 2.5995 0.074 0.98539-0.10481 1.8774-0.53644 2.6759-0.43168 0.79855-1.1332 1.5041-2.1047 2.1165-1.1103 0.69996-2.3795 1.0325-3.8075 0.99774-1.4281-0.0348-2.8734-0.44312-4.336-1.225l-1.4042 3.0464c-0.38231 0.71202-1.1219 2.4285-2.2186 5.1495-1.0968 2.721-1.6158 4.617-1.5569 5.6882 0.0588 1.0711 0.3226 1.9785 0.79134 2.722 0.46246 0.73355 1.2762 1.3981 2.4412 1.9935l-0.24115 0.27671c-1.7215-0.57713-3.1822-1.8174-4.3821-3.7207-0.79997-1.2689-1.1132-2.5953-0.93972-3.9791 0.17346-1.3839 1.233-4.2683 3.1785-8.6534 0.007-0.03233 0.0209-0.05474 0.0407-0.06724l2.0029-4.3381-1.2875-1.9104-1.1156-1.7695-8.3865 5.2872c-0.6741 0.42497-1.1011 0.81886-1.2811 1.1817-0.17994 0.3628-0.0543 0.8862 0.37693 1.5702l-0.20818 0.13124-3.5717-5.6654 0.20818-0.13124c0.47346 0.68508 0.89871 1.03 1.2757 1.0347 0.37702 0.0047 0.97693-0.25225 1.7997-0.77097l17.412-10.978c0.56503-0.35622 0.98655-0.72586 1.2646-1.1089 0.27798-0.38305 0.18445-0.9544-0.28059-1.7141zm2.2305 4.329-10.275 6.4778 1.4437 2.2899c1.1374 1.8042 2.4074 2.8737 3.8099 3.2086 1.4025 0.33488 2.7977 0.06485 4.1855-0.8101 1.3482-0.84996 2.3542-2.0833 3.0181-3.7002 0.66383-1.6168 0.31454-3.5058-1.0478-5.6668z"/>
|
|
||||||
<path d="m304.97 139.01-2.8793 1.9196-0.0812-0.19782c0.0114-0.003 0.27603-0.39661 0.7939-1.182 0.51781-0.78539 0.8634-1.6276 1.0368-2.5266 0.17331-0.89905 0.14258-1.8627-0.0922-2.8909-0.39397-1.7251-1.2005-2.9804-2.4196-3.7658-1.2191-0.78541-2.5256-1.019-3.9194-0.7007-0.92542 0.21132-1.6796 0.63296-2.2625 1.2649-0.58294 0.63196-0.99926 1.7698-1.249 3.4135-0.27608 2.7917-0.52511 4.7147-0.7471 5.7691-0.22203 1.0544-0.75747 2.1443-1.6063 3.2697-0.84889 1.1254-2.0959 1.876-3.741 2.2517-0.68549 0.15652-1.3578 0.22591-2.017 0.20816-0.65917-0.0178-1.3177-0.13787-1.9755-0.36027-0.65783-0.22243-1.2805-0.52799-1.8681-0.91668-0.58762-0.38872-1.0629-0.81208-1.426-1.2701-0.36304-0.45803-0.73392-1.2268-1.1126-2.3063-0.37873-1.0795-0.60853-1.7963-0.68941-2.1505l-1.5379-6.7348 7.3346-1.6749 0.0587 0.25706c-2.4282 0.57854-3.9944 1.5372-4.6984 2.876-0.70401 1.3388-0.78599 3.1906-0.24595 5.5555 0.49047 2.1478 1.3713 3.6626 2.6424 4.5443 1.2712 0.8817 2.6208 1.1595 4.0489 0.8334 0.86826-0.19828 1.5637-0.56143 2.0862-1.0894 0.5225-0.52802 0.93554-1.1933 1.2391-1.9959 0.30354-0.80258 0.56488-2.2506 0.78402-4.3441 0.23314-2.0847 0.51456-3.5764 0.84426-4.4751 0.32968-0.89869 0.94577-1.7275 1.8483-2.4866 0.90249-0.75903 1.885-1.2599 2.9475-1.5025 1.9536-0.44612 3.7463-0.14929 5.3781 0.89047s2.6968 2.6507 3.1952 4.8328c0.19303 0.84542 0.30463 1.7816 0.3348 2.8084 0.0301 1.0269 0.0297 1.604-0.001 1.7312-0.0124 0.0509-0.0134 0.0992-0.003 0.14492z"/>
|
|
||||||
<path d="m305.53 190.02-0.62918 4.9701-0.26159-0.0331c0.0724-0.75866-0.0212-1.3021-0.28088-1.6302-0.25969-0.32821-0.86619-0.55264-1.8195-0.6733l-23.386-2.9605 24.41-17.729-19.008-2.4064c-0.60455-0.0765-1.058-0.0867-1.3605-0.0305-0.30242 0.0562-0.51699 0.16489-0.6437 0.32604-0.12671 0.16113-0.28653 0.58386-0.47947 1.2682l-0.24415-0.0309 0.62477-4.9352 0.24414 0.0309c-0.11185 0.88357-0.0244 1.4528 0.26223 1.7076 0.28667 0.25481 1.0229 0.45728 2.2088 0.6074l17.387 2.201c1.523 0.1928 2.7938 0.1381 3.8125-0.16408 1.0186-0.3022 1.5902-1.225 1.7148-2.7685l0.26159 0.0331-0.61153 4.8306-22.945 16.656 18.136 2.296c0.97656 0.1236 1.5945 0.0246 1.8537-0.29688 0.25922-0.32158 0.42342-0.75557 0.49261-1.302z"/>
|
|
||||||
<path d="m289.19 232.48-3.433-0.43565 0.0682-0.20268c0.0103 0.005 0.46837-0.11886 1.3741-0.37304 0.90573-0.25423 1.7186-0.66421 2.4385-1.2299 0.71988-0.56577 1.3279-1.314 1.824-2.2447 0.83238-1.5615 1.0453-3.0383 0.63863-4.4303s-1.2408-2.4243-2.5024-3.0969c-0.83765-0.44653-1.6837-0.62197-2.5381-0.52631-0.85443 0.0956-1.9143 0.68265-3.1797 1.761-2.0373 1.9285-3.4852 3.2184-4.3436 3.8696-0.85845 0.65123-1.977 1.124-3.3556 1.4183-1.3786 0.29426-2.8125 0.0445-4.3016-0.7493-0.62047-0.33077-1.1739-0.71876-1.6603-1.164-0.48641-0.44522-0.90529-0.96731-1.2566-1.5663-0.35134-0.59898-0.62169-1.2378-0.81106-1.9164-0.18935-0.67863-0.27117-1.3099-0.24544-1.8937 0.0257-0.58389 0.24909-1.4077 0.67005-2.4714 0.42097-1.0637 0.7169-1.7559 0.88779-2.0765l3.2497-6.0961 6.639 3.5391-0.12403 0.23268c-2.2137-1.1535-4.025-1.4551-5.4339-0.90469-1.4089 0.55038-2.6839 1.8959-3.825 4.0365-1.0364 1.9441-1.3631 3.6656-0.98022 5.1646 0.38289 1.4989 1.2207 2.5929 2.5133 3.282 0.78593 0.41894 1.5492 0.60008 2.2899 0.54342 0.74068-0.0567 1.4886-0.28881 2.2436-0.69635 0.75509-0.40756 1.9011-1.3305 3.438-2.7687 1.5418-1.4224 2.7315-2.3652 3.5693-2.8282 0.83779-0.46308 1.8462-0.68576 3.0254-0.66807 1.1791 0.0177 2.2495 0.28285 3.2113 0.79553 1.7683 0.94264 2.9284 2.3412 3.4803 4.1958 0.55182 1.8545 0.30129 3.7694-0.75159 5.7446-0.40795 0.76523-0.93686 1.5457-1.5867 2.3413-0.6499 0.7956-1.0282 1.2313-1.1351 1.3072-0.0428 0.0303-0.0751 0.0662-0.0972 0.10756z"/>
|
|
||||||
<path d="m253.71 273.01-3.0849 2.6673-0.17245-0.19946c0.99118-0.94999 1.0384-1.9435 0.14161-2.9807-0.19161-0.22165-0.48263-0.50449-0.87307-0.84851l-14.878-13.069c-0.76791-0.63734-1.3195-0.9931-1.6548-1.0673-0.33522-0.0742-0.76579 0.0773-1.2917 0.45457l-0.16096-0.18616 4.4013-3.8055 0.16096 0.18616c-0.59151 0.48045-0.63435 1.0132-0.1285 1.5983 0.11499 0.13295 0.36769 0.37146 0.75811 0.71554l14.434 12.663-6.994-22.279 0.13297-0.11497 21.053 10.078-10.527-16.18c-0.15615-0.25228-0.35687-0.52025-0.60214-0.80391-0.44455-0.51416-0.96379-0.51447-1.5577-0.00093l-0.16096-0.18616 2.9918-2.5868 0.16096 0.18616c-0.4521 0.39089-0.69259 0.69953-0.72149 0.92591s0.0266 0.49211 0.16644 0.79721c0.13987 0.30509 0.32237 0.62367 0.54751 0.95573l11.448 17.755c1.1222 0.56333 1.9417 0.77653 2.4585 0.63959 0.51673-0.13698 0.94353-0.35109 1.2804-0.64232l0.17246 0.19945-3.6966 3.1962-20.742-10.067z"/>
|
|
||||||
<path d="m205.18 269.68 0.31132-0.12093 16.841 17.917c1.193 1.2589 2.036 1.9403 2.529 2.0443 0.49295 0.10393 0.94698 0.0753 1.3621-0.0859l0.0955 0.24578-5.571 2.164-0.0955-0.24578c0.50429-0.1582 0.67581-0.44484 0.51457-0.85991-0.0636-0.16387-0.16431-0.32592-0.30198-0.48614l-14.712-15.689-0.2212 21.471c-0.0007 0.2894 0.0286 0.51058 0.088 0.66354 0.14428 0.37137 0.49953 0.42824 1.0657 0.17061l0.0955 0.24578-3.6212 1.4066-0.0955-0.24578c0.25125-0.0976 0.50236-0.23603 0.75332-0.4152 0.25098-0.17924 0.42846-0.57191 0.53244-1.178 0.104-0.60616 0.15509-0.92773 0.15327-0.96471z"/>
|
|
||||||
</g>
|
|
||||||
<g class="fg">
|
|
||||||
<path d="m113.7 291.67 0.12516-3.4583 0.20799 0.0497c-0.005 0.0108 0.1605 0.45578 0.49511 1.335 0.33465 0.87919 0.81606 1.6518 1.4442 2.318 0.62822 0.66608 1.4281 1.2043 2.3996 1.6148 1.6301 0.68858 3.12 0.76779 4.4698 0.23762 1.3498-0.53021 2.3029-1.4538 2.8593-2.7708 0.3694-0.87442 0.46804-1.7328 0.29593-2.5751-0.17209-0.84236-0.85204-1.8452-2.0399-3.0085-2.1039-1.8556-3.5187-3.1816-4.2446-3.978-0.7258-0.7964-1.2972-1.8679-1.7143-3.2144-0.41705-1.3466-0.29725-2.7971 0.35942-4.3516 0.27363-0.6477 0.61027-1.2338 1.0099-1.7583 0.39968-0.52448 0.88198-0.98862 1.4469-1.3924 0.56495-0.40378 1.1768-0.73048 1.8357-0.98011 0.65885-0.24961 1.2802-0.38787 1.864-0.41475 0.58383-0.0269 1.4244 0.12148 2.5217 0.44508s1.8132 0.55609 2.1479 0.69745l6.3637 2.6883-2.9277 6.9304-0.24288-0.1026c0.94975-2.3085 1.0872-4.1396 0.41234-5.4932-0.67485-1.3537-2.1296-2.5025-4.3641-3.4465-2.0295-0.85733-3.7734-1.0279-5.2318-0.5118-1.4584 0.51614-2.4726 1.4489-3.0426 2.7983-0.34656 0.82043-0.45832 1.5969-0.33528 2.3295 0.12307 0.73258 0.4215 1.4566 0.89529 2.1719 0.47383 0.71537 1.4961 1.7737 3.0667 3.1751 1.5553 1.4076 2.6012 2.5078 3.1378 3.3005 0.53654 0.79274 0.84901 1.7771 0.93743 2.953 0.0884 1.1759-0.0794 2.2658-0.50351 3.2698-0.7798 1.8459-2.0684 3.1271-3.8658 3.8435-1.7974 0.71637-3.727 0.63906-5.7889-0.23193-0.79882-0.33748-1.6237-0.79406-2.4745-1.3697-0.85083-0.57572-1.3188-0.91336-1.404-1.0129-0.034-0.0398-0.0726-0.0689-0.11586-0.0871z"/>
|
|
||||||
<path d="m68.299 260.77-3.0403-2.718 0.17573-0.19658c1.0691 0.86139 2.0605 0.78098 2.9743-0.2412 0.19529-0.21842 0.43854-0.54326 0.72973-0.97453l11.056-16.429c0.53378-0.8432 0.81598-1.4358 0.8466-1.7778 0.03067-0.34197-0.17473-0.74959-0.61622-1.2229l0.16402-0.18347 4.3377 3.8778-0.16402 0.18347c-0.55224-0.52512-1.0861-0.49938-1.6016 0.0772-0.11713 0.13106-0.32133 0.41222-0.61258 0.84348l-10.71 15.937 21.201-9.7892 0.13105 0.11715-7.2989 22.17 14.699-12.513c0.23021-0.18718 0.47027-0.42055 0.7202-0.70012 0.453-0.50672 0.38682-1.0217-0.19854-1.545l0.16402-0.18347 2.9486 2.636-0.16402 0.18347c-0.44556-0.39832-0.78245-0.59732-1.0107-0.597-0.22821 0.00033-0.48466 0.0894-0.76934 0.26716-0.28467 0.17777-0.57725 0.39956-0.87775 0.66536l-16.14 13.63c-0.415 1.1851-0.52151 2.0252-0.31953 2.5202 0.20202 0.49494 0.46901 0.89081 0.80098 1.1876l-0.17573 0.19657-3.6432-3.2569 7.3287-21.86z"/>
|
|
||||||
<path d="m39.292 218.38c-1.4886-3.3138-1.6984-6.4762-0.62946-9.4873 1.069-3.011 3.1108-5.1937 6.1252-6.5479 3.8804-1.7431 7.6935-1.9915 11.439-0.74522 3.7459 1.2464 6.5241 3.8845 8.3344 7.9145 1.4694 3.271 1.6034 6.429 0.40185 9.4739-1.2015 3.0449-3.2988 5.2396-6.292 6.5842-2.0203 0.90759-4.3198 1.3368-6.8985 1.2876-2.5786-0.0492-4.9925-0.78268-7.2417-2.2004-2.2491-1.4177-3.9956-3.5108-5.2393-6.2795zm23.133-10.276c-0.7299-1.6248-1.8858-3.0326-3.4677-4.2233s-3.3413-1.897-5.2781-2.119c-1.9368-0.22191-3.7123 0.0297-5.3264 0.75478-2.2876 1.0277-4.0918 2.5736-5.4127 4.638-1.3208 2.0644-2.0722 4.3096-2.2541 6.7359-0.18187 2.4263 0.09934 4.4679 0.84363 6.1248 1.0517 2.341 2.888 4.0694 5.5089 5.1852 2.621 1.1158 5.241 1.0854 7.8599-0.0911 3.3459-1.503 5.7621-3.9888 7.2487-7.4572s1.5792-6.6511 0.27787-9.548z"/>
|
|
||||||
<path d="m54.305 176.72-0.24585 0.0109c-0.03577-0.8078-0.21116-1.325-0.52618-1.5515-0.31502-0.22652-0.8413-0.32345-1.5789-0.29079l-21.178 0.93782c-0.74924 0.0332-1.2866 0.15082-1.6119 0.35291-0.32534 0.20209-0.47899 0.77194-0.46096 1.7096l-0.26341 0.0117-0.30716-6.9366 0.26341-0.0117c0.02854 0.64391 0.13045 1.091 0.30573 1.3413 0.17533 0.25031 0.37602 0.41151 0.60206 0.48361 0.22609 0.0721 0.73132 0.0908 1.5157 0.056l18.158-0.80407c1.5571-0.0689 2.638-0.49218 3.2429-1.2697 0.60487-0.77752 0.86712-2.0736 0.78677-3.8882l-0.141-3.16c-0.06739-1.5219-0.4914-2.6205-1.272-3.2956-0.78063-0.67509-2.2088-1.0077-4.2847-0.99795l-0.01089-0.24585 6.2166-0.27528z"/>
|
|
||||||
<path d="m32.995 125.27 0.25545 0.0653c-0.11822 0.32055-0.16075 0.69977-0.12759 1.1376 0.03321 0.4379 0.17094 0.72712 0.41317 0.86767 0.24228 0.14058 0.85161 0.33569 1.828 0.58533l19.261 4.9248c1.0445 0.26708 1.694 0.38779 1.9486 0.36214 0.25452-0.0256 0.48962-0.14091 0.70531-0.34582 0.21568-0.20491 0.40336-0.61958 0.56302-1.244l0.23842 0.061-1.7113 6.6929-0.23842-0.061c0.21482-0.84016 0.18656-1.4038-0.08476-1.6909-0.27132-0.28709-0.98033-0.57724-2.127-0.87044l-19.074-4.8769c-1.1921-0.3048-2.0017-0.39084-2.4287-0.25812-0.42702 0.13273-0.71944 0.60227-0.87726 1.4086l-0.25545-0.0653z"/>
|
|
||||||
<path d="m71.729 102.86-0.18056 0.28098-24.16-4.5763c-1.7054-0.31583-2.788-0.37074-3.2477-0.16472-0.45973 0.20605-0.80997 0.49638-1.0507 0.871l-0.22182-0.14254 3.231-5.0279 0.22182 0.14254c-0.31464 0.42465-0.28466 0.75734 0.08995 0.99806 0.1479 0.09505 0.32464 0.16684 0.53023 0.21536l21.127 4.0277-12.455-17.49c-0.16972-0.23441-0.3236-0.39597-0.46163-0.4847-0.33518-0.21537-0.65588-0.05231-0.96208 0.48918l-0.22182-0.14254 2.1001-3.2682 0.22182 0.14254c-0.1457 0.22678-0.26729 0.48645-0.36477 0.77899-0.09746 0.29261-0.0099 0.71453 0.26268 1.2658 0.2726 0.5513 0.42051 0.84137 0.44374 0.8702z"/>
|
|
||||||
<path d="m76.563 57.963-0.15835-0.21082 5.383-4.0433c1.5742-1.1823 2.7385-1.9543 3.4929-2.3158 0.75443-0.36145 1.5705-0.58234 2.4482-0.66269 0.87768-0.08029 1.7895 0.07023 2.7355 0.45156 0.94598 0.38138 1.7533 1.0171 2.4219 1.9073 1.3161 1.7522 1.4922 3.7818 0.52818 6.0887 1.6798-0.86602 3.267-1.0945 4.7614-0.68544 1.4944 0.40911 2.766 1.3117 3.8146 2.7078 0.97826 1.3024 1.543 2.7323 1.6941 4.2896s-0.0607 2.8266-0.63536 3.8079c-0.5747 0.98128-1.6163 2.0385-3.1249 3.1716l-7.9973 6.0069-0.1478-0.19677c0.63716-0.47858 0.94798-0.91357 0.93246-1.305-0.01552-0.39139-0.42092-1.1165-1.2162-2.1753l-11.718-15.602c-0.56302-0.74958-0.96767-1.2444-1.214-1.4845-0.24625-0.24004-0.53578-0.33768-0.86857-0.29293-0.33277 0.04479-0.70998 0.22553-1.1316 0.54222zm4.02-2.6677 6.8303 9.0936 2.5158-1.8897c1.7053-1.2809 2.4708-2.618 2.2964-4.0112-0.17444-1.3932-0.6241-2.5724-1.349-3.5375-0.78121-1.04-1.6495-1.7472-2.6048-2.1216-0.95534-0.37429-1.9814-0.42805-3.078-0.16128-1.0967 0.26683-2.4508 1.0055-4.0625 2.216zm8.7739 8.3152-1.6163 1.214 4.9301 6.5637c0.68268 0.90889 1.1612 1.4728 1.4356 1.6917 0.27437 0.21895 0.64832 0.38509 1.1218 0.49842 0.47351 0.11334 1.0553 0.05374 1.7454-0.17879 0.69006-0.23252 1.5551-0.73939 2.5952-1.5206 1.6116-1.2105 2.4703-2.4381 2.5761-3.6827 0.10574-1.2446-0.39035-2.5978-1.4883-4.0595-1.1402-1.5179-2.3643-2.5331-3.6725-3.0454-1.3082-0.51233-2.4121-0.59181-3.3119-0.23845-0.89975 0.3534-2.3382 1.2726-4.3152 2.7576z"/>
|
|
||||||
</g>
|
|
||||||
<g class="fg">
|
|
||||||
<path d="m177.99 64.817 0.96679 2.7422h-0.24609c-2.5078-2.4961-5.461-3.7441-8.8594-3.7441-3.5274 0.000026-6.3779 1.0489-8.5518 3.1465-2.1738 2.0977-3.2608 4.6348-3.2607 7.6113-0.00001 1.8399 0.48339 3.9551 1.4502 6.3457 0.96679 2.3906 2.4932 4.3564 4.5791 5.8975 2.0859 1.541 4.6113 2.3115 7.5762 2.3115 1.9453 0 3.8525-0.31348 5.7217-0.94043 1.8691-0.62695 3.2607-1.4678 4.1748-2.5225l0.22851 0.07031-1.8105 2.7773c-2.9297 0.63281-4.8311 1.0078-5.7041 1.125-0.87307 0.11719-2.042 0.17578-3.5068 0.17578-5.4258 0-9.3076-1.2568-11.646-3.7705-2.3379-2.5137-3.5068-5.5225-3.5068-9.0264-0.00001-2.3672 0.60058-4.6435 1.8018-6.8291 1.2012-2.1855 2.9326-3.9082 5.1943-5.168 2.2617-1.2597 4.8457-1.8896 7.752-1.8896 1.4531 0.000026 2.7099 0.13186 3.7705 0.39551 1.0605 0.2637 1.9424 0.53616 2.6455 0.81738l1.1602 0.43945c0.0351 0.01174 0.0586 0.02346 0.0703 0.03516z"/>
|
|
||||||
<path d="m173.39 106.17 1.2305 3.2344-0.21094 0.0352c-0.00002-0.0117-0.32521-0.3574-0.97559-1.0371-0.6504-0.67966-1.3945-1.2041-2.2324-1.5732-0.8379-0.36911-1.7842-0.55369-2.8389-0.55371-1.7695 0.00002-3.1728 0.50686-4.21 1.5205-1.0371 1.0137-1.5557 2.2354-1.5557 3.665 0 0.94923 0.24316 1.7783 0.72949 2.4873s1.5029 1.3682 3.0498 1.9775c2.6601 0.89064 4.4795 1.5615 5.458 2.0127 0.97851 0.45118 1.9219 1.2158 2.8301 2.2939 0.90819 1.0781 1.3623 2.461 1.3623 4.1484-0.00002 0.70313-0.0821 1.374-0.2461 2.0127-0.16408 0.63868-0.42775 1.2539-0.79101 1.8457-0.3633 0.5918-0.79982 1.1309-1.3096 1.6172-0.50978 0.48633-1.0283 0.85547-1.5557 1.1074-0.52735 0.25195-1.3594 0.44238-2.4961 0.57129-1.1367 0.1289-1.8867 0.19335-2.25 0.19335h-6.9082v-7.5234h0.26367c0.0234 2.4961 0.60937 4.2363 1.7578 5.2207 1.1484 0.98438 2.9355 1.4766 5.3613 1.4766 2.2031 0 3.876-0.52148 5.0186-1.5644 1.1426-1.043 1.7139-2.2969 1.7139-3.7617-0.00001-0.89062-0.19923-1.6494-0.59766-2.2764-0.39845-0.62694-0.95509-1.1777-1.6699-1.6523-0.71485-0.4746-2.0684-1.0518-4.0605-1.7314-1.9805-0.69139-3.3721-1.2978-4.1748-1.8193-0.80274-0.52147-1.4736-1.3066-2.0127-2.3555-0.53907-1.0488-0.8086-2.1182-0.8086-3.208 0-2.0039 0.68848-3.6855 2.0654-5.0449 1.377-1.3594 3.1846-2.039 5.4228-2.0391 0.86718 0.00002 1.8047 0.0996 2.8125 0.29883 1.0078 0.19924 1.5703 0.32815 1.6875 0.38671 0.0469 0.0235 0.0937 0.0352 0.14063 0.0352z"/>
|
|
||||||
<path d="m173.39 148.48 1.2305 3.2344-0.21094 0.0352c-0.00002-0.0117-0.32521-0.3574-0.97559-1.0371-0.6504-0.67966-1.3945-1.2041-2.2324-1.5732-0.8379-0.36911-1.7842-0.55368-2.8389-0.55371-1.7695 0.00003-3.1728 0.50686-4.21 1.5205-1.0371 1.0137-1.5557 2.2354-1.5557 3.665 0 0.94924 0.24316 1.7783 0.72949 2.4873s1.5029 1.3682 3.0498 1.9775c2.6601 0.89064 4.4795 1.5615 5.458 2.0127 0.97851 0.45118 1.9219 1.2158 2.8301 2.2939 0.90819 1.0781 1.3623 2.461 1.3623 4.1484-0.00002 0.70313-0.0821 1.374-0.2461 2.0127-0.16408 0.63867-0.42775 1.2539-0.79101 1.8457-0.3633 0.5918-0.79982 1.1309-1.3096 1.6172-0.50978 0.48633-1.0283 0.85547-1.5557 1.1074-0.52735 0.25195-1.3594 0.44238-2.4961 0.57129-1.1367 0.1289-1.8867 0.19336-2.25 0.19336h-6.9082v-7.5234h0.26367c0.0234 2.4961 0.60937 4.2363 1.7578 5.2207 1.1484 0.98438 2.9355 1.4766 5.3613 1.4766 2.2031 0.00001 3.876-0.52148 5.0186-1.5644 1.1426-1.043 1.7139-2.2969 1.7139-3.7617-0.00001-0.89062-0.19923-1.6494-0.59766-2.2764-0.39845-0.62695-0.95509-1.1777-1.6699-1.6524-0.71485-0.4746-2.0684-1.0517-4.0605-1.7314-1.9805-0.6914-3.3721-1.2978-4.1748-1.8193-0.80274-0.52147-1.4736-1.3066-2.0127-2.3555-0.53907-1.0488-0.8086-2.1181-0.8086-3.208 0-2.0039 0.68848-3.6855 2.0654-5.0449 1.377-1.3594 3.1846-2.039 5.4228-2.0391 0.86718 0.00003 1.8047 0.0996 2.8125 0.29883 1.0078 0.19924 1.5703 0.32815 1.6875 0.38672 0.0469 0.0235 0.0937 0.0352 0.14063 0.0352z"/>
|
|
||||||
<path d="m177.34 190.47h4.0781v0.26367c-1.3711 0.0703-2.0567 0.79104-2.0566 2.1621-0.00003 0.29299 0.0351 0.69729 0.10547 1.2129l2.707 19.617c0.16403 0.98438 0.3486 1.6143 0.55371 1.8896 0.20505 0.27539 0.62985 0.44238 1.2744 0.50097v0.2461h-5.8184v-0.2461c0.76169 0.0234 1.1426-0.35156 1.1426-1.125-0.00002-0.17577-0.0352-0.52148-0.10546-1.0371l-2.6367-19.02-9.2812 21.428h-0.17578l-9.334-21.393-2.6191 19.125c-0.0469 0.29297-0.0703 0.62696-0.0703 1.002 0 0.67969 0.39257 1.0195 1.1777 1.0195v0.2461h-3.9551v-0.2461c0.59766 0.00001 0.98145-0.0762 1.1514-0.22851 0.16992-0.15234 0.30176-0.38965 0.39551-0.71191 0.0937-0.32227 0.16406-0.68262 0.21094-1.0811l2.9531-20.918c-0.48047-1.1601-0.96094-1.8574-1.4414-2.0918-0.48048-0.23434-0.94337-0.35153-1.3887-0.35156v-0.26367h4.8867l9.1055 21.182z"/>
|
|
||||||
<path d="m158.85 258.68v-0.24609c0.80859 0 1.333-0.15234 1.5732-0.45703 0.24023-0.30469 0.36035-0.82617 0.36035-1.5645v-21.199c0-0.74998-0.0937-1.292-0.28125-1.626-0.1875-0.33396-0.75-0.51267-1.6875-0.53613v-0.26368h6.9434v0.26368c-0.64454 0.00002-1.0957 0.0821-1.3535 0.24609-0.25782 0.16409-0.42774 0.35745-0.50977 0.58008-0.082 0.22268-0.12305 0.72659-0.12305 1.5117v18.176c0 1.5586 0.375 2.6572 1.125 3.2959 0.75 0.63867 2.0332 0.95801 3.8496 0.958h3.1641c1.5234 0.00001 2.6396-0.37499 3.3486-1.125 0.70897-0.74999 1.1045-2.1621 1.1865-4.2363h0.2461v6.2226z"/>
|
|
||||||
</g>
|
|
||||||
<rect class="bg" height="33.325" width="33.325" y="146.77" x="151.78"/>
|
|
||||||
<g class="fg">
|
|
||||||
<path d="m95.864 150.69h5.0098v0.26367c-0.76174 0.0235-1.2891 0.18459-1.582 0.4834-0.293 0.29885-0.43948 0.92873-0.43945 1.8896v23.572l-20.654-21.99v19.16c-0.000005 0.60938 0.04687 1.0606 0.14062 1.3535 0.09374 0.29297 0.22851 0.49219 0.4043 0.59765 0.17578 0.10547 0.61523 0.21094 1.3184 0.31641v0.24609h-4.9746v-0.24609c0.89062 0 1.4443-0.1582 1.6611-0.47461 0.21679-0.3164 0.32519-1.0723 0.3252-2.2676v-17.525c-0.000004-1.5351-0.21387-2.789-0.6416-3.7617-0.42774-0.97263-1.415-1.4238-2.9619-1.3535v-0.26367h4.8691l19.406 20.672v-18.281c-0.000025-0.98435-0.17581-1.5849-0.52734-1.8018-0.35159-0.21677-0.80276-0.32517-1.3535-0.32519z"/>
|
|
||||||
<path id="path3063" d="m116.49 150.96v-0.26367h11.883c3.0234 0.00002 5.4111 0.23733 7.1631 0.71191 1.7519 0.47463 3.2783 1.2217 4.5791 2.2412 1.3008 1.0196 2.332 2.3233 3.0938 3.9111 0.76169 1.5879 1.1425 3.3604 1.1426 5.3174-0.00003 1.8867-0.39553 3.7412-1.1865 5.5635-0.79104 1.8223-1.8662 3.3926-3.2256 4.7109-1.3594 1.3184-2.792 2.2207-4.2978 2.707-1.5059 0.48633-3.835 0.72949-6.9873 0.72949h-12.164v-0.24609h0.3164c0.63281 0 1.0488-0.25488 1.248-0.76465 0.19921-0.50976 0.29882-1.4326 0.29883-2.7686v-18.861c-0.00001-1.4062-0.12012-2.2558-0.36035-2.5488-0.24024-0.29294-0.74122-0.43943-1.5029-0.43945zm8.8242 0.28125h-3.9726v20.092c-0.00001 1.2656 0.21386 2.2061 0.6416 2.8213 0.42773 0.61524 1.1572 1.0606 2.1885 1.3359 1.0312 0.27539 2.4199 0.41309 4.166 0.41309 4.8516 0 8.2588-1.2451 10.222-3.7354 1.9629-2.4902 2.9443-5.206 2.9443-8.1475-0.00003-3.457-1.3448-6.4512-4.0342-8.9824-2.6895-2.5312-6.7412-3.7968-12.155-3.7969z"/>
|
|
||||||
<path d="m172.31 151.03 1.2305 3.2344-0.21094 0.0352c-0.00002-0.0117-0.32521-0.3574-0.97559-1.0371-0.6504-0.67966-1.3945-1.2041-2.2324-1.5732-0.8379-0.36912-1.7842-0.55369-2.8389-0.55371-1.7695 0.00002-3.1728 0.50686-4.21 1.5205-1.0371 1.0137-1.5557 2.2354-1.5557 3.665 0 0.94923 0.24316 1.7783 0.72949 2.4873s1.5029 1.3682 3.0498 1.9775c2.6601 0.89064 4.4795 1.5615 5.458 2.0127 0.97851 0.45119 1.9219 1.2158 2.8301 2.294 0.90819 1.0781 1.3623 2.461 1.3623 4.1484-0.00002 0.70313-0.082 1.374-0.2461 2.0127-0.16408 0.63868-0.42775 1.2539-0.79101 1.8457-0.3633 0.5918-0.79982 1.1309-1.3096 1.6172-0.50978 0.48633-1.0283 0.85547-1.5557 1.1074-0.52735 0.25196-1.3594 0.44239-2.4961 0.57129-1.1367 0.12891-1.8867 0.19336-2.25 0.19336h-6.9082v-7.5234h0.26367c0.0234 2.4961 0.60937 4.2363 1.7578 5.2207 1.1484 0.98438 2.9355 1.4766 5.3613 1.4766 2.2031 0 3.876-0.52148 5.0186-1.5644 1.1426-1.043 1.7139-2.2969 1.7139-3.7617-0.00001-0.89062-0.19923-1.6494-0.59766-2.2764-0.39845-0.62694-0.95509-1.1777-1.6699-1.6523-0.71485-0.4746-2.0684-1.0518-4.0605-1.7314-1.9805-0.69139-3.3721-1.2978-4.1748-1.8193-0.80274-0.52147-1.4736-1.3066-2.0127-2.3555-0.53907-1.0488-0.8086-2.1182-0.8086-3.208 0-2.0039 0.68848-3.6855 2.0654-5.0449 1.377-1.3594 3.1846-2.039 5.4228-2.0391 0.86718 0.00002 1.8047 0.0996 2.8125 0.29882 1.0078 0.19925 1.5703 0.32816 1.6875 0.38672 0.0469 0.0235 0.0937 0.0352 0.14063 0.0352z"/>
|
|
||||||
<path d="m213.81 150.69h4.0781v0.26367c-1.3711 0.0703-2.0567 0.79104-2.0566 2.1621-0.00002 0.29299 0.0351 0.69728 0.10547 1.2129l2.707 19.617c0.16404 0.98438 0.34861 1.6143 0.55371 1.8896 0.20505 0.27539 0.62986 0.44239 1.2744 0.50098v0.24609h-5.8184v-0.24609c0.76169 0.0234 1.1426-0.35156 1.1426-1.125-0.00003-0.17578-0.0352-0.52148-0.10547-1.0371l-2.6367-19.02-9.2812 21.428h-0.17578l-9.334-21.393-2.6191 19.125c-0.0469 0.29297-0.0703 0.62695-0.0703 1.002 0 0.67969 0.39258 1.0195 1.1777 1.0195v0.24609h-3.9551v-0.24609c0.59765 0 0.98144-0.0762 1.1514-0.22852 0.16992-0.15234 0.30176-0.38964 0.39551-0.71191 0.0937-0.32226 0.16406-0.68262 0.21094-1.081l2.9531-20.918c-0.48047-1.1601-0.96094-1.8574-1.4414-2.0918-0.48047-0.23435-0.94336-0.35154-1.3887-0.35156v-0.26367h4.8867l9.1055 21.182z"/>
|
|
||||||
<path d="m234.95 150.96v-0.26367h11.883c3.0234 0.00002 5.4111 0.23733 7.1631 0.71191 1.7519 0.47463 3.2783 1.2217 4.5791 2.2412 1.3008 1.0196 2.332 2.3233 3.0938 3.9111 0.76169 1.5879 1.1426 3.3604 1.1426 5.3174-0.00003 1.8867-0.39554 3.7412-1.1865 5.5635-0.79105 1.8223-1.8662 3.3926-3.2256 4.7109-1.3594 1.3184-2.792 2.2207-4.2978 2.707-1.5059 0.48633-3.835 0.72949-6.9873 0.72949h-12.164v-0.24609h0.31641c0.63281 0 1.0488-0.25488 1.248-0.76465 0.19922-0.50976 0.29883-1.4326 0.29883-2.7686v-18.861c0-1.4062-0.12012-2.2558-0.36035-2.5488-0.24024-0.29294-0.74121-0.43943-1.5029-0.43945zm8.8242 0.28125h-3.9727v20.092c0 1.2656 0.21386 2.2061 0.6416 2.8213 0.42773 0.61524 1.1572 1.0606 2.1885 1.3359 1.0312 0.27539 2.4199 0.41309 4.166 0.41309 4.8515 0 8.2588-1.2451 10.222-3.7354 1.9629-2.4902 2.9443-5.206 2.9443-8.1475-0.00002-3.457-1.3448-6.4512-4.0342-8.9824-2.6895-2.5312-6.7412-3.7968-12.155-3.7969z"/>
|
|
||||||
<g class="fg">
|
|
||||||
<path d="m124.76 99.299 0.9668 2.7422h-0.2461c-2.5078-2.4961-5.461-3.7441-8.8594-3.7441-3.5274 0.000025-6.3779 1.0489-8.5518 3.1465-2.1738 2.0977-3.2607 4.6348-3.2607 7.6113 0 1.8399 0.48339 3.9551 1.4502 6.3457 0.96679 2.3906 2.4932 4.3564 4.5791 5.8975 2.0859 1.541 4.6113 2.3115 7.5762 2.3115 1.9453 0 3.8525-0.31348 5.7217-0.94043 1.8691-0.62695 3.2607-1.4678 4.1748-2.5225l0.22852 0.0703-1.8106 2.7773c-2.9297 0.63282-4.8311 1.0078-5.7041 1.125-0.87307 0.11719-2.042 0.17578-3.5068 0.17578-5.4258 0-9.3076-1.2568-11.646-3.7705-2.3379-2.5137-3.5068-5.5225-3.5068-9.0264 0-2.3672 0.60058-4.6435 1.8018-6.8291 1.2012-2.1855 2.9326-3.9082 5.1943-5.168 2.2617-1.2597 4.8457-1.8896 7.752-1.8896 1.4531 0.000026 2.7099 0.13186 3.7705 0.39551 1.0605 0.2637 1.9424 0.53616 2.6455 0.81738l1.1602 0.43945c0.0351 0.01174 0.0586 0.02346 0.0703 0.03516z"/>
|
|
||||||
<path d="m226.63 97.821 1.2305 3.2344-0.21093 0.0352c-0.00002-0.0117-0.32521-0.3574-0.97559-1.0371-0.6504-0.67966-1.3945-1.2041-2.2324-1.5732-0.8379-0.36912-1.7842-0.55369-2.8389-0.55371-1.7695 0.000025-3.1729 0.50686-4.21 1.5205-1.0371 1.0137-1.5557 2.2354-1.5557 3.665-0.00001 0.94923 0.24316 1.7783 0.72949 2.4873 0.48632 0.709 1.5029 1.3682 3.0498 1.9775 2.6602 0.89064 4.4795 1.5615 5.458 2.0127 0.9785 0.45119 1.9219 1.2158 2.8301 2.294 0.90819 1.0781 1.3623 2.461 1.3623 4.1484-0.00001 0.70313-0.082 1.374-0.24609 2.0127-0.16408 0.63868-0.42775 1.2539-0.79102 1.8457-0.36329 0.5918-0.79981 1.1309-1.3096 1.6172-0.50977 0.48633-1.0283 0.85547-1.5557 1.1074-0.52736 0.25195-1.3594 0.44238-2.4961 0.57128-1.1367 0.12891-1.8867 0.19336-2.25 0.19336h-6.9082v-7.5234h0.26368c0.0234 2.4961 0.60937 4.2363 1.7578 5.2207 1.1484 0.98438 2.9355 1.4766 5.3613 1.4766 2.2031 0 3.876-0.52148 5.0186-1.5644 1.1426-1.043 1.7138-2.2969 1.7139-3.7617-0.00002-0.89062-0.19924-1.6494-0.59766-2.2764-0.39845-0.62694-0.95509-1.1777-1.6699-1.6523-0.71486-0.4746-2.0684-1.0518-4.0606-1.7314-1.9805-0.69139-3.3721-1.2978-4.1748-1.8193-0.80274-0.52147-1.4736-1.3066-2.0127-2.3555-0.53906-1.0488-0.80859-2.1182-0.80859-3.208 0-2.0039 0.68847-3.6855 2.0654-5.0449 1.377-1.3593 3.1846-2.039 5.4228-2.0391 0.86718 0.000026 1.8047 0.09963 2.8125 0.29883 1.0078 0.19924 1.5703 0.32815 1.6875 0.38672 0.0469 0.02346 0.0937 0.03518 0.14063 0.03516z" />
|
|
||||||
<path d="m212.54 202.63v-0.26367h6.7324c1.9687 0.00003 3.3633 0.0821 4.1836 0.24609 0.8203 0.16409 1.6055 0.47757 2.3555 0.94043 0.74999 0.46292 1.3887 1.1309 1.916 2.0039 0.52732 0.87307 0.791 1.8662 0.79101 2.9795-0.00001 2.1914-1.0781 3.9199-3.2344 5.1856 1.8633 0.31642 3.2695 1.0869 4.2188 2.3115 0.9492 1.2246 1.4238 2.71 1.4238 4.4561-0.00002 1.6289-0.40725 3.1113-1.2217 4.4473-0.81447 1.3359-1.7461 2.2236-2.7949 2.6631-1.0488 0.43945-2.5166 0.65918-4.4033 0.65918h-10.002v-0.24609c0.79687 0 1.3066-0.16114 1.5293-0.4834 0.22265-0.32227 0.33398-1.1455 0.33398-2.4697v-19.512c0-0.93747-0.0264-1.5762-0.0791-1.916-0.0527-0.33982-0.22559-0.59178-0.51855-0.75586-0.29297-0.16404-0.70313-0.24607-1.2305-0.2461zm4.8164 0.28125v11.373h3.1465c2.1328 0.00001 3.5478-0.60936 4.2451-1.8281 0.69725-1.2187 1.0459-2.4316 1.0459-3.6387-0.00001-1.3008-0.26954-2.3877-0.80859-3.2607-0.53908-0.87302-1.3272-1.5322-2.3643-1.9775-1.0371-0.44529-2.5635-0.66794-4.5791-0.66797zm2.0215 11.918h-2.0215v8.209c0 1.1367 0.0439 1.875 0.13184 2.2148 0.0879 0.33985 0.2871 0.69727 0.59766 1.0723 0.31054 0.375 0.81151 0.67675 1.5029 0.90527s1.6875 0.34277 2.9883 0.34277c2.0156 0 3.4394-0.46582 4.2715-1.3975 0.83202-0.93164 1.248-2.3115 1.248-4.1396-0.00002-1.8984-0.36916-3.4453-1.1074-4.6406-0.7383-1.1953-1.5733-1.9219-2.5049-2.1797-0.93165-0.2578-2.6338-0.3867-5.1064-0.38672z"/>
|
|
||||||
<path d="m108.68 203.42v-0.26367h7.3828c2.625 0.00002 4.5322 0.29299 5.7217 0.8789 1.1894 0.58597 2.0566 1.3155 2.6016 2.1885 0.5449 0.87307 0.81736 2.0244 0.81738 3.4541-0.00002 2.1914-0.75588 3.8379-2.2676 4.9394-1.5117 1.1016-3.5625 1.6289-6.1523 1.582v-0.2461c1.6406 0.00002 2.9736-0.50389 3.999-1.5117s1.5381-2.332 1.5381-3.9726c-0.00002-1.2773-0.24904-2.4111-0.74707-3.4014-0.49806-0.99021-1.1983-1.7431-2.1006-2.2588-0.90235-0.5156-2.2793-0.77341-4.1309-0.77344h-1.8457v22.166c-0.00001 1.2539 0.14062 2.001 0.42187 2.2412 0.28125 0.24023 0.81445 0.36035 1.5996 0.36035v0.2461h-6.8379v-0.2461c1.2188 0 1.8281-0.55664 1.8281-1.6699v-21.445c-0.00001-0.91404-0.11719-1.5205-0.35156-1.8193-0.23438-0.2988-0.72657-0.44822-1.4766-0.44824z"/>
|
|
||||||
<path d="m139.19 59.343c0 9.9799-8.0903 18.07-18.07 18.07-9.9799 0-18.07-8.0903-18.07-18.07 0-9.9799 8.0903-18.07 18.07-18.07 9.9799 0 18.07 8.0903 18.07 18.07z" transform="matrix(.15488 0 0 .15488 96.011 40.384)"/>
|
|
||||||
<path d="m139.19 59.343c0 9.9799-8.0903 18.07-18.07 18.07-9.9799 0-18.07-8.0903-18.07-18.07 0-9.9799 8.0903-18.07 18.07-18.07 9.9799 0 18.07 8.0903 18.07 18.07z" transform="matrix(.15488 0 0 .15488 203.55 40.283)"/>
|
|
||||||
<path d="m139.19 59.343c0 9.9799-8.0903 18.07-18.07 18.07-9.9799 0-18.07-8.0903-18.07-18.07 0-9.9799 8.0903-18.07 18.07-18.07 9.9799 0 18.07 8.0903 18.07 18.07z" transform="matrix(.17299 0 0 .17299 147.99 279.77)"/>
|
|
||||||
<path d="m139.19 59.343c0 9.9799-8.0903 18.07-18.07 18.07-9.9799 0-18.07-8.0903-18.07-18.07 0-9.9799 8.0903-18.07 18.07-18.07 9.9799 0 18.07 8.0903 18.07 18.07z" transform="matrix(.15488 0 0 .15488 131.66 277.84)"/>
|
|
||||||
<path d="m139.19 59.343c0 9.9799-8.0903 18.07-18.07 18.07-9.9799 0-18.07-8.0903-18.07-18.07 0-9.9799 8.0903-18.07 18.07-18.07 9.9799 0 18.07 8.0903 18.07 18.07z" transform="matrix(.15488 0 0 .15488 168.54 277.98)"/>
|
|
||||||
<path d="m61.398 206.07c0.38726-6.2993 0.78765-12.891-3.9191-17.556 2.2141 1.3159 3.7733 2.2888 5.016 5.4372 1.2085 3.0616 2.4354 10.148 0.93876 15.254-0.47418-1.2005-1.5449-2.5682-2.0357-3.1354z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
@@ -1,326 +0,0 @@
|
|||||||
<script lang='ts'>
|
|
||||||
import Check from '$lib/assets/icons/Check.svelte';
|
|
||||||
import Cross from '$lib/assets/icons/Cross.svelte';
|
|
||||||
import SeasonSelect from '$lib/components/SeasonSelect.svelte';
|
|
||||||
import '$lib/css/action_button.css'
|
|
||||||
import '$lib/css/nordtheme.css'
|
|
||||||
import '$lib/css/shake.css'
|
|
||||||
import { redirect } from '@sveltejs/kit';
|
|
||||||
import { RecipeModelType } from '../../types/types';
|
|
||||||
import type { PageData } from './$types';
|
|
||||||
import CardAdd from '$lib/components/CardAdd.svelte';
|
|
||||||
import CreateIngredientList from '$lib/components/CreateIngredientList.svelte';
|
|
||||||
import CreateStepList from '$lib/components/CreateStepList.svelte';
|
|
||||||
|
|
||||||
let {
|
|
||||||
data,
|
|
||||||
actions,
|
|
||||||
title,
|
|
||||||
card_data = $bindable({
|
|
||||||
icon: data.icon,
|
|
||||||
category: data.category,
|
|
||||||
name: data.name,
|
|
||||||
description: data.description,
|
|
||||||
tags: data.tags,
|
|
||||||
}),
|
|
||||||
add_info = $bindable({
|
|
||||||
preparation: data.preparation,
|
|
||||||
fermentation: {
|
|
||||||
bulk: data.fermentation.bulk,
|
|
||||||
final: data.fermentation.final,
|
|
||||||
},
|
|
||||||
baking: {
|
|
||||||
length: data.baking.length,
|
|
||||||
temperature: data.baking.temperature,
|
|
||||||
mode: data.baking.mode,
|
|
||||||
},
|
|
||||||
total_time: data.total_time,
|
|
||||||
}),
|
|
||||||
portions = $bindable(data.portions),
|
|
||||||
ingredients = $bindable(data.ingredients),
|
|
||||||
instructions = $bindable(data.instructions)
|
|
||||||
}: {
|
|
||||||
data: PageData,
|
|
||||||
actions: [String],
|
|
||||||
title: string,
|
|
||||||
card_data?: any,
|
|
||||||
add_info?: any,
|
|
||||||
portions?: any,
|
|
||||||
ingredients?: any,
|
|
||||||
instructions?: any
|
|
||||||
} = $props();
|
|
||||||
|
|
||||||
let preamble = $state(data.preamble);
|
|
||||||
let addendum = $state(data.addendum);
|
|
||||||
|
|
||||||
import { season } from '$lib/js/season_store';
|
|
||||||
season.update(() => data.season)
|
|
||||||
let season_local = $state();
|
|
||||||
season.subscribe((s) => {
|
|
||||||
season_local = s
|
|
||||||
});
|
|
||||||
|
|
||||||
let old_short_name = $state(data.short_name);
|
|
||||||
let images = $state(data.images);
|
|
||||||
let short_name = $state(data.short_name);
|
|
||||||
let password = $state();
|
|
||||||
let datecreated = $state(data.datecreated);
|
|
||||||
let datemodified = $state(new Date());
|
|
||||||
|
|
||||||
|
|
||||||
function get_season(){
|
|
||||||
let season = []
|
|
||||||
const el = document.getElementById("labels");
|
|
||||||
for(var i = 0; i < el.children.length; i++){
|
|
||||||
if(el.children[i].children[0].children[0].checked){
|
|
||||||
season.push(i+1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return season
|
|
||||||
}
|
|
||||||
function write_season(season){
|
|
||||||
const el = document.getElementById("labels");
|
|
||||||
for(var i = 0; i < season.length; i++){
|
|
||||||
el.children[i].children[0].children[0].checked = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function doDelete(){
|
|
||||||
const response = confirm("Bist du dir sicher, dass du das Rezept löschen willst?")
|
|
||||||
if(!response){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const res = await fetch('/api/delete', {
|
|
||||||
method: 'POST',
|
|
||||||
body: JSON.stringify({
|
|
||||||
old_short_name,
|
|
||||||
headers: {
|
|
||||||
'content-type': 'application/json',
|
|
||||||
bearer: password,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
async function doEdit() {
|
|
||||||
const res = await fetch('/api/edit', {
|
|
||||||
method: 'POST',
|
|
||||||
body: JSON.stringify({
|
|
||||||
: {
|
|
||||||
...card_data,
|
|
||||||
...add_info,
|
|
||||||
images, // TODO
|
|
||||||
season: season_local,
|
|
||||||
short_name,
|
|
||||||
datecreated,
|
|
||||||
datemodified,
|
|
||||||
instructions,
|
|
||||||
ingredients,
|
|
||||||
addendum,
|
|
||||||
preamble
|
|
||||||
},
|
|
||||||
old_short_name,
|
|
||||||
headers: {
|
|
||||||
'content-type': 'application/json',
|
|
||||||
bearer: password,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
const item = await res.json();
|
|
||||||
}
|
|
||||||
async function doAdd () {
|
|
||||||
const res = await fetch('/api/add', {
|
|
||||||
method: 'POST',
|
|
||||||
body: JSON.stringify({
|
|
||||||
recipe: {
|
|
||||||
...card_data,
|
|
||||||
...add_info,
|
|
||||||
images: {mediapath: short_name + '.webp', alt: "", caption: ""}, // TODO
|
|
||||||
season: season_local,
|
|
||||||
short_name,
|
|
||||||
datecreated,
|
|
||||||
datemodified,
|
|
||||||
instructions,
|
|
||||||
ingredients,
|
|
||||||
preamble,
|
|
||||||
addendum,
|
|
||||||
},
|
|
||||||
headers: {
|
|
||||||
'content-type': 'application/json',
|
|
||||||
bearer: password,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
input{
|
|
||||||
display: block;
|
|
||||||
border: unset;
|
|
||||||
margin: 1rem auto;
|
|
||||||
padding: 0.5em 1em;
|
|
||||||
border-radius: 1000px;
|
|
||||||
background-color: var(--nord4);
|
|
||||||
font-size: 1.1rem;
|
|
||||||
transition: 100ms;
|
|
||||||
|
|
||||||
}
|
|
||||||
input:hover,
|
|
||||||
input:focus-visible
|
|
||||||
{
|
|
||||||
scale: 1.05 1.05;
|
|
||||||
}
|
|
||||||
.list_wrapper{
|
|
||||||
margin-inline: auto;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
max-width: 1000px;
|
|
||||||
gap: 2rem;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
@media screen and (max-width: 700px){
|
|
||||||
.list_wrapper{
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
input[type=password]{
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: 1.5rem;
|
|
||||||
padding-block: 0.5em;
|
|
||||||
display: inline;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.submit_wrapper{
|
|
||||||
position: relative;
|
|
||||||
margin-inline: auto;
|
|
||||||
width: max(300px, 50vw)
|
|
||||||
}
|
|
||||||
.submit_wrapper button{
|
|
||||||
position: absolute;
|
|
||||||
right:-1em;
|
|
||||||
bottom: -0.5em;
|
|
||||||
}
|
|
||||||
.submit_wrapper h2{
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
h1{
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
}
|
|
||||||
.title_container{
|
|
||||||
max-width: 1000px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
margin-inline: auto;
|
|
||||||
}
|
|
||||||
.title{
|
|
||||||
position: relative;
|
|
||||||
width: min(800px, 80vw);
|
|
||||||
margin-block: 2rem;
|
|
||||||
margin-inline: auto;
|
|
||||||
background-color: var(--nord6);
|
|
||||||
background-color: red;
|
|
||||||
padding: 1rem 2rem;
|
|
||||||
}
|
|
||||||
.title p{
|
|
||||||
border: 2px solid var(--nord1);
|
|
||||||
border-radius: 10000px;
|
|
||||||
padding: 0.5em 1em;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
transition: 200ms;
|
|
||||||
}
|
|
||||||
.title p:hover,
|
|
||||||
.title p:focus-within{
|
|
||||||
scale: 1.02 1.02;
|
|
||||||
}
|
|
||||||
.addendum{
|
|
||||||
font-size: 1.1rem;
|
|
||||||
max-width: 90%;
|
|
||||||
margin-inline: auto;
|
|
||||||
border: 2px solid var(--nord1);
|
|
||||||
border-radius: 45px;
|
|
||||||
padding: 1em 1em;
|
|
||||||
transition: 100ms;
|
|
||||||
}
|
|
||||||
.addendum:hover,
|
|
||||||
.addendum:focus-within
|
|
||||||
{
|
|
||||||
scale: 1.02 1.02;
|
|
||||||
}
|
|
||||||
.addendum_wrapper{
|
|
||||||
max-width: 1000px;
|
|
||||||
margin-inline: auto;
|
|
||||||
}
|
|
||||||
h3{
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.delete{
|
|
||||||
position: fixed;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
margin: 2rem;
|
|
||||||
}
|
|
||||||
@media (prefers-color-scheme: dark){
|
|
||||||
.title{
|
|
||||||
background-color: var(--nord6-dark);
|
|
||||||
background-color: green;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<h1>{title}</h1>
|
|
||||||
|
|
||||||
<CardAdd {card_data}></CardAdd>
|
|
||||||
|
|
||||||
<h3>Kurzname (für URL):</h3>
|
|
||||||
<input bind:value={short_name} placeholder="Kurzname"/>
|
|
||||||
|
|
||||||
<div class=title_container>
|
|
||||||
<div class=title>
|
|
||||||
<h4>Eine etwas längere Beschreibung:</h4>
|
|
||||||
<p bind:innerText={preamble} contenteditable></p>
|
|
||||||
<div class=tags>
|
|
||||||
<h4>Saison:</h4>
|
|
||||||
<SeasonSelect></SeasonSelect>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class=list_wrapper>
|
|
||||||
<div>
|
|
||||||
<CreateIngredientList {ingredients} {portions}></CreateIngredientList>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<CreateStepList {instructions} {add_info}></CreateStepList>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class=addendum_wrapper>
|
|
||||||
<h3>Nachtrag:</h3>
|
|
||||||
<div class=addendum bind:innerText={addendum} contenteditable></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{#if actions.includes('add')}
|
|
||||||
<div class=submit_wrapper>
|
|
||||||
<h2>Neues Rezept hinzufügen:</h2>
|
|
||||||
<input type="password" placeholder=Passwort bind:value={password}>
|
|
||||||
<button class=action_button onclick={doAdd}><Check fill=white width=2rem height=2rem></Check></button>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
{#if actions.includes('edit')}
|
|
||||||
<div class=submit_wrapper>
|
|
||||||
<h2>Editiertes Rezept abspeichern:</h2>
|
|
||||||
<input type="password" placeholder=Passwort bind:value={password}>
|
|
||||||
<button class=action_button onclick={doEdit}><Check fill=white width=2rem height=2rem></Check></button>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{#if actions.includes('delete')}
|
|
||||||
<div class=submit_wrapper>
|
|
||||||
<h2>Rezept löschen:</h2>
|
|
||||||
<input type="password" placeholder=Passwort bind:value={password}>
|
|
||||||
<button class=action_button onclick={doDelete}><Cross fill=white width=2rem height=2rem></Cross></button>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
@@ -1,305 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
let {
|
|
||||||
ingredients = $bindable([]),
|
|
||||||
translationMetadata = null,
|
|
||||||
onchange
|
|
||||||
}: {
|
|
||||||
ingredients?: any[],
|
|
||||||
translationMetadata?: any[] | null | undefined,
|
|
||||||
onchange?: (detail: { ingredients: any[] }) => void
|
|
||||||
} = $props();
|
|
||||||
|
|
||||||
function handleChange() {
|
|
||||||
onchange?.({ ingredients });
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateIngredientGroupName(groupIndex: number, event: Event) {
|
|
||||||
const target = event.target as HTMLInputElement;
|
|
||||||
ingredients[groupIndex].name = target.value;
|
|
||||||
handleChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateIngredientItem(groupIndex: number, itemIndex: number, field: string, event: Event) {
|
|
||||||
const target = event.target as HTMLInputElement;
|
|
||||||
ingredients[groupIndex].list[itemIndex][field] = target.value;
|
|
||||||
handleChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Base recipe reference handlers
|
|
||||||
function updateLabelOverride(groupIndex: number, event: Event) {
|
|
||||||
const target = event.target as HTMLInputElement;
|
|
||||||
ingredients[groupIndex].labelOverride = target.value;
|
|
||||||
handleChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateItemBefore(groupIndex: number, itemIndex: number, field: string, event: Event) {
|
|
||||||
const target = event.target as HTMLInputElement;
|
|
||||||
if (!ingredients[groupIndex].itemsBefore) {
|
|
||||||
ingredients[groupIndex].itemsBefore = [];
|
|
||||||
}
|
|
||||||
ingredients[groupIndex].itemsBefore[itemIndex][field] = target.value;
|
|
||||||
handleChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateItemAfter(groupIndex: number, itemIndex: number, field: string, event: Event) {
|
|
||||||
const target = event.target as HTMLInputElement;
|
|
||||||
if (!ingredients[groupIndex].itemsAfter) {
|
|
||||||
ingredients[groupIndex].itemsAfter = [];
|
|
||||||
}
|
|
||||||
ingredients[groupIndex].itemsAfter[itemIndex][field] = target.value;
|
|
||||||
handleChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if a group name was re-translated
|
|
||||||
function isGroupNameTranslated(groupIndex: number): boolean {
|
|
||||||
return translationMetadata?.[groupIndex]?.nameTranslated ?? false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if a specific item was re-translated
|
|
||||||
function isItemTranslated(groupIndex: number, itemIndex: number): boolean {
|
|
||||||
return translationMetadata?.[groupIndex]?.itemsTranslated?.[itemIndex] ?? false;
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.ingredients-editor {
|
|
||||||
background: var(--nord0);
|
|
||||||
border: 1px solid var(--nord3);
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 0.75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media(prefers-color-scheme: light) {
|
|
||||||
.ingredients-editor {
|
|
||||||
background: var(--nord5);
|
|
||||||
border-color: var(--nord3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.ingredient-group {
|
|
||||||
margin-bottom: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ingredient-group:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group-name {
|
|
||||||
width: 100%;
|
|
||||||
padding: 0.5rem;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
background: var(--nord1);
|
|
||||||
border: 1px solid var(--nord3);
|
|
||||||
border-radius: 4px;
|
|
||||||
color: var(--nord6);
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 0.95rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media(prefers-color-scheme: light) {
|
|
||||||
.group-name {
|
|
||||||
background: var(--nord6);
|
|
||||||
color: var(--nord0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.ingredient-item {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 60px 60px 1fr;
|
|
||||||
gap: 0.5rem;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ingredient-item input {
|
|
||||||
padding: 0.4rem;
|
|
||||||
background: var(--nord1);
|
|
||||||
border: 1px solid var(--nord3);
|
|
||||||
border-radius: 4px;
|
|
||||||
color: var(--nord6);
|
|
||||||
font-size: 0.9rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media(prefers-color-scheme: light) {
|
|
||||||
.ingredient-item input {
|
|
||||||
background: var(--nord6);
|
|
||||||
color: var(--nord0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.ingredient-item input:focus {
|
|
||||||
outline: 2px solid var(--nord14);
|
|
||||||
border-color: var(--nord14);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ingredient-item input.amount {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Highlight re-translated items with red border */
|
|
||||||
.retranslated {
|
|
||||||
border: 2px solid var(--nord11) !important;
|
|
||||||
animation: highlight-flash 0.6s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes highlight-flash {
|
|
||||||
0% {
|
|
||||||
box-shadow: 0 0 10px var(--nord11);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
box-shadow: 0 0 0 transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.reference-badge {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 0.25rem 0.5rem;
|
|
||||||
background: var(--nord9);
|
|
||||||
color: var(--nord6);
|
|
||||||
border-radius: 4px;
|
|
||||||
font-size: 0.75rem;
|
|
||||||
font-weight: 600;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.reference-section {
|
|
||||||
padding: 0.5rem;
|
|
||||||
background: var(--nord2);
|
|
||||||
border-radius: 4px;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media(prefers-color-scheme: light) {
|
|
||||||
.reference-section {
|
|
||||||
background: var(--nord4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.reference-section-label {
|
|
||||||
font-size: 0.8rem;
|
|
||||||
font-weight: 600;
|
|
||||||
color: var(--nord8);
|
|
||||||
margin-bottom: 0.25rem;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div class="ingredients-editor">
|
|
||||||
{#each ingredients as group, groupIndex}
|
|
||||||
<div class="ingredient-group">
|
|
||||||
{#if group.type === 'reference'}
|
|
||||||
<span class="reference-badge">🔗 Base Recipe Reference</span>
|
|
||||||
|
|
||||||
{#if group.labelOverride !== undefined}
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="group-name"
|
|
||||||
value={group.labelOverride || ''}
|
|
||||||
on:input={(e) => updateLabelOverride(groupIndex, e)}
|
|
||||||
placeholder="Label override (optional)"
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{#if group.itemsBefore && group.itemsBefore.length > 0}
|
|
||||||
<div class="reference-section">
|
|
||||||
<div class="reference-section-label">Items Before Base Recipe:</div>
|
|
||||||
{#each group.itemsBefore as item, itemIndex}
|
|
||||||
<div class="ingredient-item">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="amount"
|
|
||||||
value={item.amount || ''}
|
|
||||||
on:input={(e) => updateItemBefore(groupIndex, itemIndex, 'amount', e)}
|
|
||||||
placeholder="Amt"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="unit"
|
|
||||||
class:retranslated={isItemTranslated(groupIndex, itemIndex)}
|
|
||||||
value={item.unit || ''}
|
|
||||||
on:input={(e) => updateItemBefore(groupIndex, itemIndex, 'unit', e)}
|
|
||||||
placeholder="Unit"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="name"
|
|
||||||
class:retranslated={isItemTranslated(groupIndex, itemIndex)}
|
|
||||||
value={item.name || ''}
|
|
||||||
on:input={(e) => updateItemBefore(groupIndex, itemIndex, 'name', e)}
|
|
||||||
placeholder="Ingredient name"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{#if group.itemsAfter && group.itemsAfter.length > 0}
|
|
||||||
<div class="reference-section">
|
|
||||||
<div class="reference-section-label">Items After Base Recipe:</div>
|
|
||||||
{#each group.itemsAfter as item, itemIndex}
|
|
||||||
<div class="ingredient-item">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="amount"
|
|
||||||
value={item.amount || ''}
|
|
||||||
on:input={(e) => updateItemAfter(groupIndex, itemIndex, 'amount', e)}
|
|
||||||
placeholder="Amt"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="unit"
|
|
||||||
class:retranslated={isItemTranslated(groupIndex, itemIndex)}
|
|
||||||
value={item.unit || ''}
|
|
||||||
on:input={(e) => updateItemAfter(groupIndex, itemIndex, 'unit', e)}
|
|
||||||
placeholder="Unit"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="name"
|
|
||||||
class:retranslated={isItemTranslated(groupIndex, itemIndex)}
|
|
||||||
value={item.name || ''}
|
|
||||||
on:input={(e) => updateItemAfter(groupIndex, itemIndex, 'name', e)}
|
|
||||||
placeholder="Ingredient name"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
{:else}
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="group-name"
|
|
||||||
class:retranslated={isGroupNameTranslated(groupIndex)}
|
|
||||||
value={group.name || ''}
|
|
||||||
on:input={(e) => updateIngredientGroupName(groupIndex, e)}
|
|
||||||
placeholder="Ingredient group name"
|
|
||||||
/>
|
|
||||||
{#each group.list as item, itemIndex}
|
|
||||||
<div class="ingredient-item">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="amount"
|
|
||||||
value={item.amount || ''}
|
|
||||||
on:input={(e) => updateIngredientItem(groupIndex, itemIndex, 'amount', e)}
|
|
||||||
placeholder="Amt"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="unit"
|
|
||||||
class:retranslated={isItemTranslated(groupIndex, itemIndex)}
|
|
||||||
value={item.unit || ''}
|
|
||||||
on:input={(e) => updateIngredientItem(groupIndex, itemIndex, 'unit', e)}
|
|
||||||
placeholder="Unit"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="name"
|
|
||||||
class:retranslated={isItemTranslated(groupIndex, itemIndex)}
|
|
||||||
value={item.name || ''}
|
|
||||||
on:input={(e) => updateIngredientItem(groupIndex, itemIndex, 'name', e)}
|
|
||||||
placeholder="Ingredient name"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
@@ -1,275 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
let {
|
|
||||||
instructions = $bindable([]),
|
|
||||||
translationMetadata = null,
|
|
||||||
onchange
|
|
||||||
}: {
|
|
||||||
instructions?: any[],
|
|
||||||
translationMetadata?: any[] | null | undefined,
|
|
||||||
onchange?: (detail: { instructions: any[] }) => void
|
|
||||||
} = $props();
|
|
||||||
|
|
||||||
function handleChange() {
|
|
||||||
onchange?.({ instructions });
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateInstructionGroupName(groupIndex: number, event: Event) {
|
|
||||||
const target = event.target as HTMLInputElement;
|
|
||||||
instructions[groupIndex].name = target.value;
|
|
||||||
handleChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateStep(groupIndex: number, stepIndex: number, event: Event) {
|
|
||||||
const target = event.target as HTMLTextAreaElement;
|
|
||||||
instructions[groupIndex].steps[stepIndex] = target.value;
|
|
||||||
handleChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Base recipe reference handlers
|
|
||||||
function updateLabelOverride(groupIndex: number, event: Event) {
|
|
||||||
const target = event.target as HTMLInputElement;
|
|
||||||
instructions[groupIndex].labelOverride = target.value;
|
|
||||||
handleChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateStepBefore(groupIndex: number, stepIndex: number, event: Event) {
|
|
||||||
const target = event.target as HTMLTextAreaElement;
|
|
||||||
if (!instructions[groupIndex].stepsBefore) {
|
|
||||||
instructions[groupIndex].stepsBefore = [];
|
|
||||||
}
|
|
||||||
instructions[groupIndex].stepsBefore[stepIndex] = target.value;
|
|
||||||
handleChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateStepAfter(groupIndex: number, stepIndex: number, event: Event) {
|
|
||||||
const target = event.target as HTMLTextAreaElement;
|
|
||||||
if (!instructions[groupIndex].stepsAfter) {
|
|
||||||
instructions[groupIndex].stepsAfter = [];
|
|
||||||
}
|
|
||||||
instructions[groupIndex].stepsAfter[stepIndex] = target.value;
|
|
||||||
handleChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if a group name was re-translated
|
|
||||||
function isGroupNameTranslated(groupIndex: number): boolean {
|
|
||||||
return translationMetadata?.[groupIndex]?.nameTranslated ?? false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if a specific step was re-translated
|
|
||||||
function isStepTranslated(groupIndex: number, stepIndex: number): boolean {
|
|
||||||
return translationMetadata?.[groupIndex]?.stepsTranslated?.[stepIndex] ?? false;
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.instructions-editor {
|
|
||||||
background: var(--nord0);
|
|
||||||
border: 1px solid var(--nord3);
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 0.75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media(prefers-color-scheme: light) {
|
|
||||||
.instructions-editor {
|
|
||||||
background: var(--nord5);
|
|
||||||
border-color: var(--nord3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.instruction-group {
|
|
||||||
margin-bottom: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.instruction-group:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group-name {
|
|
||||||
width: 100%;
|
|
||||||
padding: 0.5rem;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
background: var(--nord1);
|
|
||||||
border: 1px solid var(--nord3);
|
|
||||||
border-radius: 4px;
|
|
||||||
color: var(--nord6);
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 0.95rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media(prefers-color-scheme: light) {
|
|
||||||
.group-name {
|
|
||||||
background: var(--nord6);
|
|
||||||
color: var(--nord0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.step-item {
|
|
||||||
margin-bottom: 0.75rem;
|
|
||||||
display: flex;
|
|
||||||
gap: 0.5rem;
|
|
||||||
align-items: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.step-number {
|
|
||||||
min-width: 2rem;
|
|
||||||
padding: 0.4rem 0.5rem;
|
|
||||||
background: var(--nord3);
|
|
||||||
border-radius: 4px;
|
|
||||||
text-align: center;
|
|
||||||
color: var(--nord6);
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media(prefers-color-scheme: light) {
|
|
||||||
.step-number {
|
|
||||||
background: var(--nord4);
|
|
||||||
color: var(--nord0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.step-item textarea {
|
|
||||||
flex: 1;
|
|
||||||
padding: 0.5rem;
|
|
||||||
background: var(--nord1);
|
|
||||||
border: 1px solid var(--nord3);
|
|
||||||
border-radius: 4px;
|
|
||||||
color: var(--nord6);
|
|
||||||
font-size: 0.9rem;
|
|
||||||
font-family: inherit;
|
|
||||||
resize: vertical;
|
|
||||||
min-height: 3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media(prefers-color-scheme: light) {
|
|
||||||
.step-item textarea {
|
|
||||||
background: var(--nord6);
|
|
||||||
color: var(--nord0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.step-item textarea:focus {
|
|
||||||
outline: 2px solid var(--nord14);
|
|
||||||
border-color: var(--nord14);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Highlight re-translated items with red border */
|
|
||||||
.retranslated {
|
|
||||||
border: 2px solid var(--nord11) !important;
|
|
||||||
animation: highlight-flash 0.6s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes highlight-flash {
|
|
||||||
0% {
|
|
||||||
box-shadow: 0 0 10px var(--nord11);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
box-shadow: 0 0 0 transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.reference-badge {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 0.25rem 0.5rem;
|
|
||||||
background: var(--nord9);
|
|
||||||
color: var(--nord6);
|
|
||||||
border-radius: 4px;
|
|
||||||
font-size: 0.75rem;
|
|
||||||
font-weight: 600;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.reference-section {
|
|
||||||
padding: 0.5rem;
|
|
||||||
background: var(--nord2);
|
|
||||||
border-radius: 4px;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media(prefers-color-scheme: light) {
|
|
||||||
.reference-section {
|
|
||||||
background: var(--nord4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.reference-section-label {
|
|
||||||
font-size: 0.8rem;
|
|
||||||
font-weight: 600;
|
|
||||||
color: var(--nord8);
|
|
||||||
margin-bottom: 0.25rem;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div class="instructions-editor">
|
|
||||||
{#each instructions as group, groupIndex}
|
|
||||||
<div class="instruction-group">
|
|
||||||
{#if group.type === 'reference'}
|
|
||||||
<span class="reference-badge">🔗 Base Recipe Reference</span>
|
|
||||||
|
|
||||||
{#if group.labelOverride !== undefined}
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="group-name"
|
|
||||||
value={group.labelOverride || ''}
|
|
||||||
on:input={(e) => updateLabelOverride(groupIndex, e)}
|
|
||||||
placeholder="Label override (optional)"
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{#if group.stepsBefore && group.stepsBefore.length > 0}
|
|
||||||
<div class="reference-section">
|
|
||||||
<div class="reference-section-label">Steps Before Base Recipe:</div>
|
|
||||||
{#each group.stepsBefore as step, stepIndex}
|
|
||||||
<div class="step-item">
|
|
||||||
<div class="step-number">{stepIndex + 1}</div>
|
|
||||||
<textarea
|
|
||||||
class:retranslated={isStepTranslated(groupIndex, stepIndex)}
|
|
||||||
value={step || ''}
|
|
||||||
on:input={(e) => updateStepBefore(groupIndex, stepIndex, e)}
|
|
||||||
placeholder="Step description"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{#if group.stepsAfter && group.stepsAfter.length > 0}
|
|
||||||
<div class="reference-section">
|
|
||||||
<div class="reference-section-label">Steps After Base Recipe:</div>
|
|
||||||
{#each group.stepsAfter as step, stepIndex}
|
|
||||||
<div class="step-item">
|
|
||||||
<div class="step-number">{stepIndex + 1}</div>
|
|
||||||
<textarea
|
|
||||||
class:retranslated={isStepTranslated(groupIndex, stepIndex)}
|
|
||||||
value={step || ''}
|
|
||||||
on:input={(e) => updateStepAfter(groupIndex, stepIndex, e)}
|
|
||||||
placeholder="Step description"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
{:else}
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="group-name"
|
|
||||||
class:retranslated={isGroupNameTranslated(groupIndex)}
|
|
||||||
value={group.name || ''}
|
|
||||||
on:input={(e) => updateInstructionGroupName(groupIndex, e)}
|
|
||||||
placeholder="Instruction section name"
|
|
||||||
/>
|
|
||||||
{#each group.steps as step, stepIndex}
|
|
||||||
<div class="step-item">
|
|
||||||
<div class="step-number">{stepIndex + 1}</div>
|
|
||||||
<textarea
|
|
||||||
class:retranslated={isStepTranslated(groupIndex, stepIndex)}
|
|
||||||
value={step || ''}
|
|
||||||
on:input={(e) => updateStep(groupIndex, stepIndex, e)}
|
|
||||||
placeholder="Step description"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
@@ -41,9 +41,10 @@
|
|||||||
<style>
|
<style>
|
||||||
.favorite-button {
|
.favorite-button {
|
||||||
all: unset;
|
all: unset;
|
||||||
|
font-family: "Noto Color Emoji", "Noto Color Emoji Subset", emoji, sans-serif;
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: 100ms;
|
transition: var(--transition-fast);
|
||||||
filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.5));
|
filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.5));
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0.5em;
|
bottom: 0.5em;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import "$lib/css/nordtheme.css"
|
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
import Symbol from "./Symbol.svelte"
|
import Symbol from "./Symbol.svelte"
|
||||||
@@ -24,10 +23,9 @@ let underlineWidth = $state(0);
|
|||||||
let disableTransition = $state(false);
|
let disableTransition = $state(false);
|
||||||
|
|
||||||
function toggle_sidebar(state){
|
function toggle_sidebar(state){
|
||||||
// state: force hidden state (optional)
|
const checkbox = document.getElementById('nav-toggle')
|
||||||
const nav_el = document.querySelector("nav")
|
if(state === undefined) checkbox.checked = !checkbox.checked
|
||||||
if(state === undefined) nav_el.hidden = !nav_el.hidden
|
else checkbox.checked = !state
|
||||||
else nav_el.hidden = state
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateUnderline() {
|
function updateUnderline() {
|
||||||
@@ -94,16 +92,17 @@ nav{
|
|||||||
background-color: var(--nord0);
|
background-color: var(--nord0);
|
||||||
top: 0;
|
top: 0;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
display: flex !important;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: space-between !important;
|
justify-content: space-between !important;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
box-shadow: 0 1em 1rem 0rem rgba(0,0,0,0.4);
|
box-shadow: 0 1em 1rem 0rem rgba(0,0,0,0.4);
|
||||||
height: 4rem;
|
height: var(--header-h);
|
||||||
padding-left: 0.5rem;
|
padding-left: 0.5rem;
|
||||||
|
view-transition-name: site-header;
|
||||||
}
|
}
|
||||||
nav[hidden]{
|
.nav-toggle{
|
||||||
display:block;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.site_header li),
|
:global(.site_header li),
|
||||||
@@ -117,22 +116,20 @@ nav[hidden]{
|
|||||||
:global(.site_header li>a)
|
:global(.site_header li>a)
|
||||||
{
|
{
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-family: sans-serif;
|
font-size: 1rem;
|
||||||
font-size: 1.2rem;
|
|
||||||
color: inherit;
|
color: inherit;
|
||||||
border-radius: 1000px;
|
border-radius: var(--radius-pill);
|
||||||
padding: 0.5rem 0.75rem;
|
padding: 0.4rem 0.6rem;
|
||||||
}
|
}
|
||||||
:global(a.entry),
|
:global(a.entry),
|
||||||
:global(a.entry:link),
|
:global(a.entry:link),
|
||||||
:global(a.entry:visited)
|
:global(a.entry:visited)
|
||||||
{
|
{
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-family: sans-serif;
|
font-size: 1rem;
|
||||||
font-size: 1.2rem;
|
|
||||||
color: white !important;
|
color: white !important;
|
||||||
border-radius: 1000px;
|
border-radius: var(--radius-pill);
|
||||||
padding: 0.5rem 0.75rem;
|
padding: 0.4rem 0.6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.site_header li:hover),
|
:global(.site_header li:hover),
|
||||||
@@ -179,6 +176,9 @@ nav[hidden]{
|
|||||||
display: none;
|
display: none;
|
||||||
padding-inline: 0.5rem;
|
padding-inline: 0.5rem;
|
||||||
}
|
}
|
||||||
|
.header-shadow{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
.right-buttons{
|
.right-buttons{
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -190,9 +190,10 @@ nav[hidden]{
|
|||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
:global(svg.symbol){
|
:global(svg.symbol){
|
||||||
height: 4rem;
|
--symbol-size: calc(var(--header-h) - 1rem);
|
||||||
width: 4rem;
|
width: var(--symbol-size);
|
||||||
border-radius: 10000px;
|
border-radius: 10000px;
|
||||||
|
margin: 0.25rem;
|
||||||
}
|
}
|
||||||
/*:global(a:has(svg.symbol)){
|
/*:global(a:has(svg.symbol)){
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
@@ -201,6 +202,8 @@ nav[hidden]{
|
|||||||
margin-left: 1rem;
|
margin-left: 1rem;
|
||||||
}*/
|
}*/
|
||||||
.wrapper{
|
.wrapper{
|
||||||
|
--header-h: 3rem;
|
||||||
|
--symbol-size: calc(var(--header-h) - 1rem);
|
||||||
display:flex;
|
display:flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
min-height: 100svh;
|
min-height: 100svh;
|
||||||
@@ -209,95 +212,111 @@ footer{
|
|||||||
padding-block: 1rem;
|
padding-block: 1rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-top: auto;
|
margin-top: auto;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 800px) {
|
@media screen and (max-width: 800px) {
|
||||||
.button_wrapper{
|
.button_wrapper{
|
||||||
box-shadow: 0 1em 1rem 0rem rgba(0,0,0,0.4);
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
position: sticky;
|
position: sticky;
|
||||||
background-color: var(--nord0);
|
background-color: var(--nord0);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 4rem;
|
height: var(--header-h);
|
||||||
top: 0;
|
top: 0;
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
}
|
}
|
||||||
.nav_button{
|
.header-shadow{
|
||||||
border: unset;
|
|
||||||
background-color: unset;
|
|
||||||
display: block;
|
display: block;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: var(--header-h);
|
||||||
|
margin-top: calc(-1 * var(--header-h));
|
||||||
|
box-shadow: 0 1em 1rem 0rem rgba(0,0,0,0.4);
|
||||||
|
z-index: 9997;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.nav_button{
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
fill: white;
|
fill: white;
|
||||||
margin-inline: 0.5rem;
|
margin-inline: 0.5rem;
|
||||||
width: 2rem;
|
width: 1.25rem;
|
||||||
aspect-ratio: 1;
|
height: 1.25rem;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.nav_button svg{
|
.nav_button svg{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
transition: 100ms;
|
transition: var(--transition-fast);
|
||||||
}
|
}
|
||||||
.nav_button:focus{
|
.nav_button:hover,
|
||||||
fill: var(--red);
|
.nav_button:active,
|
||||||
|
.nav-toggle:focus-visible + .nav_button{
|
||||||
|
fill: var(--nord8);
|
||||||
scale: 0.9;
|
scale: 0.9;
|
||||||
}
|
}
|
||||||
.nav_site{
|
.nav_site:not(.no-links){
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
height: 100vh; /* dvh does not work, breaks because of transition and only being applied after scroll ends*/
|
height: 100vh; /* dvh does not work, breaks because of transition and only being applied after scroll ends*/
|
||||||
margin-bottom: 50vh;
|
margin-bottom: 50vh;
|
||||||
width: min(95svw, 25em);
|
width: min(95svw, 25em);
|
||||||
transition: transform 100ms;
|
z-index: 9998;
|
||||||
z-index: 10;
|
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: flex-start !important;
|
|
||||||
align-items: left;
|
|
||||||
justify-content: space-between!important;
|
|
||||||
padding-inline: 0.5rem;
|
padding-inline: 0.5rem;
|
||||||
}
|
}
|
||||||
:global(.nav_site ul){
|
.nav_site:not(.no-links)::before{
|
||||||
|
content: '';
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
:global(.nav_site:not(.no-links) ul){
|
||||||
width: 100% ;
|
width: 100% ;
|
||||||
}
|
}
|
||||||
.nav_site :first-child{
|
.nav_site:not(.no-links) :first-child{
|
||||||
display:none;
|
display:none;
|
||||||
}
|
}
|
||||||
.nav_site[hidden]{
|
.nav_site:not(.no-links){
|
||||||
transform: translateX(100%);
|
transform: translateX(100%);
|
||||||
}
|
}
|
||||||
:global(.nav_site a:last-child){
|
.wrapper:has(.nav-toggle:checked) .nav_site:not(.no-links){
|
||||||
|
transform: translateX(0);
|
||||||
|
transition: transform 100ms;
|
||||||
|
}
|
||||||
|
:global(.nav_site:not(.no-links) a:last-child){
|
||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav_site .links-wrapper {
|
.nav_site:not(.no-links) .links-wrapper {
|
||||||
align-self: flex-start;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 2rem;
|
padding: 0 2rem;
|
||||||
}
|
}
|
||||||
:global(.site_header){
|
:global(.site_header){
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding-top: min(10rem, 10vh);
|
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
:global(.site_header li, .site_header a){
|
:global(.site_header li, .site_header a){
|
||||||
font-size: 4rem;
|
font-size: 1.5rem;
|
||||||
}
|
}
|
||||||
:global(.site_header li > a, .site_header a){
|
:global(.site_header li > a, .site_header a){
|
||||||
font-size: 2rem;
|
font-size: 1.3rem;
|
||||||
}
|
}
|
||||||
:global(.site_header li:hover),
|
:global(.site_header li:hover),
|
||||||
:global(.site_header li:focus-within){
|
:global(.site_header li:focus-within){
|
||||||
transform: unset;
|
transform: unset;
|
||||||
}
|
}
|
||||||
.nav_site .header-right{
|
.nav_site:not(.no-links) .header-right{
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 2rem;
|
bottom: 2rem;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
}
|
}
|
||||||
.language-selector-desktop{
|
.nav_site:not(.no-links) .language-selector-desktop{
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.active-underline {
|
.active-underline {
|
||||||
@@ -310,17 +329,44 @@ footer{
|
|||||||
text-underline-offset: 0.3rem;
|
text-underline-offset: 0.3rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.no-links :global(button) {
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
.no-links :global(#options) {
|
||||||
|
top: calc(100% + 10px) !important;
|
||||||
|
bottom: unset !important;
|
||||||
|
right: 0 !important;
|
||||||
|
left: unset !important;
|
||||||
|
transform: none !important;
|
||||||
|
}
|
||||||
|
.no-links :global(.top.speech::after) {
|
||||||
|
border: 20px solid transparent !important;
|
||||||
|
border-bottom-color: var(--nord3) !important;
|
||||||
|
border-top: 0 !important;
|
||||||
|
top: -10px !important;
|
||||||
|
bottom: unset !important;
|
||||||
|
left: unset !important;
|
||||||
|
right: 0.25rem !important;
|
||||||
|
margin-left: 0 !important;
|
||||||
|
}
|
||||||
|
.no-links :global(button::before) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<div class=wrapper lang=de>
|
<div class=wrapper lang=de>
|
||||||
<div>
|
<div>
|
||||||
|
{#if links}
|
||||||
<div class=button_wrapper>
|
<div class=button_wrapper>
|
||||||
<a href="/" aria-label="Home"><Symbol></Symbol></a>
|
<a href="/" aria-label="Home"><Symbol></Symbol></a>
|
||||||
<div class="right-buttons">
|
<div class="right-buttons">
|
||||||
{@render language_selector_mobile?.()}
|
{@render language_selector_mobile?.()}
|
||||||
<button class=nav_button onclick={() => {toggle_sidebar()}} aria-label="Toggle navigation menu"><svg xmlns="http://www.w3.org/2000/svg" height="0.5em" viewBox="0 0 448 512"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M0 96C0 78.3 14.3 64 32 64H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z"/></svg></button>
|
<input type="checkbox" id="nav-toggle" class="nav-toggle" aria-label="Toggle navigation menu" />
|
||||||
|
<label for="nav-toggle" class=nav_button aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" height="0.5em" viewBox="0 0 448 512"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M0 96C0 78.3 14.3 64 32 64H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z"/></svg></label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<nav hidden class=nav_site>
|
<div class="header-shadow"></div>
|
||||||
|
{/if}
|
||||||
|
<nav class=nav_site class:no-links={!links}>
|
||||||
<a href="/" aria-label="Home"><Symbol></Symbol></a>
|
<a href="/" aria-label="Home"><Symbol></Symbol></a>
|
||||||
<div class="links-wrapper">
|
<div class="links-wrapper">
|
||||||
{@render links?.()}
|
{@render links?.()}
|
||||||
|
|||||||
@@ -1,564 +0,0 @@
|
|||||||
<script lang='ts'>
|
|
||||||
import { onMount } from 'svelte';
|
|
||||||
|
|
||||||
import Pen from '$lib/assets/icons/Pen.svelte'
|
|
||||||
import Cross from '$lib/assets/icons/Cross.svelte'
|
|
||||||
import Plus from '$lib/assets/icons/Plus.svelte'
|
|
||||||
import Check from '$lib/assets/icons/Check.svelte'
|
|
||||||
|
|
||||||
import "$lib/css/action_button.css"
|
|
||||||
|
|
||||||
let { list = $bindable(), list_index } = $props<{ list: any, list_index: number }>();
|
|
||||||
|
|
||||||
let edit_ingredient = $state({
|
|
||||||
amount: "",
|
|
||||||
unit: "",
|
|
||||||
name: "",
|
|
||||||
sublist: "",
|
|
||||||
list_index: "",
|
|
||||||
ingredient_index: "",
|
|
||||||
});
|
|
||||||
|
|
||||||
let edit_heading = $state({
|
|
||||||
name:"",
|
|
||||||
list_index: "",
|
|
||||||
});
|
|
||||||
|
|
||||||
function get_sublist_index(sublist_name, list){
|
|
||||||
for(var i =0; i < list.length; i++){
|
|
||||||
if(list[i].name == sublist_name){
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
export function show_modal_edit_subheading_ingredient(list_index){
|
|
||||||
edit_heading.name = ingredients[list_index].name
|
|
||||||
edit_heading.list_index = list_index
|
|
||||||
const el = document.querySelector('#edit_subheading_ingredient_modal')
|
|
||||||
el.showModal()
|
|
||||||
}
|
|
||||||
export function edit_subheading_and_close_modal(){
|
|
||||||
ingredients[edit_heading.list_index].name = edit_heading.name
|
|
||||||
const el = document.querySelector('#edit_subheading_ingredient_modal')
|
|
||||||
el.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
export function add_new_ingredient(){
|
|
||||||
if(!new_ingredient.name){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let list_index = get_sublist_index(new_ingredient.sublist, ingredients)
|
|
||||||
if(list_index == -1){
|
|
||||||
ingredients.push({
|
|
||||||
name: new_ingredient.sublist,
|
|
||||||
list: [],
|
|
||||||
})
|
|
||||||
list_index = ingredients.length - 1
|
|
||||||
}
|
|
||||||
ingredients[list_index].list.push({ ...new_ingredient})
|
|
||||||
ingredients = ingredients //tells svelte to update dom
|
|
||||||
}
|
|
||||||
export function remove_list(list_index){
|
|
||||||
if(ingredients[list_index].list.length > 1){
|
|
||||||
const response = confirm("Bist du dir sicher, dass du diese Liste löschen möchtest? Alle Zutaten der Liste werden hiermit auch gelöscht.");
|
|
||||||
if(!response){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ingredients.splice(list_index, 1);
|
|
||||||
ingredients = ingredients //tells svelte to update dom
|
|
||||||
}
|
|
||||||
export function remove_ingredient(list_index, ingredient_index){
|
|
||||||
ingredients[list_index].list.splice(ingredient_index, 1)
|
|
||||||
ingredients = ingredients //tells svelte to update dom
|
|
||||||
}
|
|
||||||
|
|
||||||
export function show_modal_edit_ingredient(list_index, ingredient_index){
|
|
||||||
edit_ingredient = {...ingredients[list_index].list[ingredient_index]}
|
|
||||||
edit_ingredient.list_index = list_index
|
|
||||||
edit_ingredient.ingredient_index = ingredient_index
|
|
||||||
edit_ingredient.sublist = ingredients[list_index].name
|
|
||||||
const modal_el = document.querySelector("#edit_ingredient_modal");
|
|
||||||
modal_el.showModal();
|
|
||||||
}
|
|
||||||
export function edit_ingredient_and_close_modal(){
|
|
||||||
ingredients[edit_ingredient.list_index].list[edit_ingredient.ingredient_index] = {
|
|
||||||
amount: edit_ingredient.amount,
|
|
||||||
unit: edit_ingredient.unit,
|
|
||||||
name: edit_ingredient.name,
|
|
||||||
}
|
|
||||||
ingredients[edit_ingredient.list_index].name = edit_ingredient.sublist
|
|
||||||
const modal_el = document.querySelector("#edit_ingredient_modal");
|
|
||||||
modal_el.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
let ghost;
|
|
||||||
let grabbed;
|
|
||||||
|
|
||||||
let lastTarget;
|
|
||||||
|
|
||||||
let mouseY = 0; // pointer y coordinate within client
|
|
||||||
let offsetY = 0; // y distance from top of grabbed element to pointer
|
|
||||||
let layerY = 0; // distance from top of list to top of client
|
|
||||||
|
|
||||||
function grab(clientY, element) {
|
|
||||||
// modify grabbed element
|
|
||||||
grabbed = element;
|
|
||||||
grabbed.dataset.grabY = clientY;
|
|
||||||
|
|
||||||
// modify ghost element (which is actually dragged)
|
|
||||||
ghost.innerHTML = grabbed.innerHTML;
|
|
||||||
|
|
||||||
// record offset from cursor to top of element
|
|
||||||
// (used for positioning ghost)
|
|
||||||
offsetY = grabbed.getBoundingClientRect().y - clientY;
|
|
||||||
drag(clientY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// drag handler updates cursor position
|
|
||||||
function drag(clientY) {
|
|
||||||
if (grabbed) {
|
|
||||||
mouseY = clientY;
|
|
||||||
layerY = ghost.parentNode.getBoundingClientRect().y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// touchEnter handler emulates the mouseenter event for touch input
|
|
||||||
// (more or less)
|
|
||||||
function touchEnter(ev) {
|
|
||||||
drag(ev.clientY);
|
|
||||||
// trigger dragEnter the first time the cursor moves over a list item
|
|
||||||
let target = document.elementFromPoint(ev.clientX, ev.clientY).closest(".item");
|
|
||||||
if (target && target != lastTarget) {
|
|
||||||
lastTarget = target;
|
|
||||||
dragEnter(ev, target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function dragEnter(ev, target) {
|
|
||||||
// swap items in data
|
|
||||||
if (grabbed && target != grabbed && target.classList.contains("item")) {
|
|
||||||
moveDatum(parseInt(grabbed.dataset.index), parseInt(target.dataset.index));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// does the actual moving of items in data
|
|
||||||
function moveDatum(from, to) {
|
|
||||||
let temp = list[0].list[from];
|
|
||||||
list[0].list = [...list[0].list.slice(0, from), ...list[0].list.slice(from + 1)];
|
|
||||||
list[0].list= [...list[0].list.slice(0, to), temp, ...list[0].list.slice(to)];
|
|
||||||
}
|
|
||||||
|
|
||||||
function release(ev) {
|
|
||||||
grabbed = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeDatum(index) {
|
|
||||||
list= [...list.slice(0, index), ...list.slice(index + 1)];
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
input::placeholder{
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.drag_handle{
|
|
||||||
cursor: grab;
|
|
||||||
display:flex;
|
|
||||||
justify-content: flex-start;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.drag_handle_header{
|
|
||||||
padding-right: 0.5em;
|
|
||||||
}
|
|
||||||
input{
|
|
||||||
color: unset;
|
|
||||||
font-size: unset;
|
|
||||||
padding: unset;
|
|
||||||
background-color: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
input.heading{
|
|
||||||
all: unset;
|
|
||||||
box-sizing: border-box;
|
|
||||||
background-color: var(--nord0);
|
|
||||||
padding: 1rem;
|
|
||||||
padding-inline: 2rem;
|
|
||||||
font-size: 1.5rem;
|
|
||||||
width: 100%;
|
|
||||||
border-radius: 1000px;
|
|
||||||
color: white;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
transition: 200ms;
|
|
||||||
}
|
|
||||||
input.heading:hover{
|
|
||||||
background-color: var(--nord1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.heading_wrapper{
|
|
||||||
position: relative;
|
|
||||||
width: 300px;
|
|
||||||
margin-inline: auto;
|
|
||||||
transition: 200ms;
|
|
||||||
}
|
|
||||||
.heading_wrapper:hover
|
|
||||||
{
|
|
||||||
transform:scale(1.1,1.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.heading_wrapper button{
|
|
||||||
position: absolute;
|
|
||||||
bottom: -1.5rem;
|
|
||||||
right: -2rem;
|
|
||||||
}
|
|
||||||
.adder{
|
|
||||||
box-sizing: border-box;
|
|
||||||
margin-inline: auto;
|
|
||||||
position: relative;
|
|
||||||
margin-block: 3rem;
|
|
||||||
width: 90%;
|
|
||||||
border-radius: 20px;
|
|
||||||
transition: 200ms;
|
|
||||||
}
|
|
||||||
.adder button{
|
|
||||||
position: absolute;
|
|
||||||
right: -1.5rem;
|
|
||||||
bottom: -1.5rem;
|
|
||||||
}
|
|
||||||
.category{
|
|
||||||
border: none;
|
|
||||||
position: absolute;
|
|
||||||
--font_size: 1.5rem;
|
|
||||||
top: -1em;
|
|
||||||
left: -1em;
|
|
||||||
font-family: sans-serif;
|
|
||||||
font-size: 1.5rem;
|
|
||||||
background-color: var(--nord0);
|
|
||||||
color: var(--nord4);
|
|
||||||
border-radius: 1000000px;
|
|
||||||
width: 23ch;
|
|
||||||
padding: 0.5em 1em;
|
|
||||||
transition: 100ms;
|
|
||||||
box-shadow: 0.5em 0.5em 1em 0.4em rgba(0,0,0,0.3);
|
|
||||||
}
|
|
||||||
.category:hover{
|
|
||||||
background-color: var(--nord1);
|
|
||||||
transform: scale(1.05,1.05);
|
|
||||||
}
|
|
||||||
.adder:hover,
|
|
||||||
.adder:focus-within
|
|
||||||
{
|
|
||||||
transform: scale(1.05, 1.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
.add_ingredient{
|
|
||||||
font-family: sans-serif;
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 1.2rem;
|
|
||||||
padding: 2rem;
|
|
||||||
padding-top: 2.5rem;
|
|
||||||
border-radius: 20px;
|
|
||||||
background-color: var(--blue);
|
|
||||||
color: #bbb;
|
|
||||||
transition: 200ms;
|
|
||||||
gap: 0.5rem;
|
|
||||||
}
|
|
||||||
.add_ingredient input{
|
|
||||||
border: 2px solid var(--nord4);
|
|
||||||
color: var(--nord4);
|
|
||||||
border-radius: 1000px;
|
|
||||||
padding: 0.5em 1em;
|
|
||||||
transition: 100ms;
|
|
||||||
}
|
|
||||||
.add_ingredient input:hover,
|
|
||||||
.add_ingredient input:focus-visible
|
|
||||||
{
|
|
||||||
border-color: white;
|
|
||||||
color: white;
|
|
||||||
transform: scale(1.02, 1.02);
|
|
||||||
|
|
||||||
}
|
|
||||||
.add_ingredient input:nth-of-type(1){
|
|
||||||
max-width: 8ch;
|
|
||||||
}
|
|
||||||
.add_ingredient input:nth-of-type(2){
|
|
||||||
max-width: 8ch;
|
|
||||||
}
|
|
||||||
.add_ingredient input:nth-of-type(3){
|
|
||||||
max-width: 30ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
dialog{
|
|
||||||
box-sizing: content-box;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-color: transparent;
|
|
||||||
border: unset;
|
|
||||||
margin: 0;
|
|
||||||
transition: 500ms;
|
|
||||||
}
|
|
||||||
dialog[open]::backdrop{
|
|
||||||
animation: show 200ms ease forwards;
|
|
||||||
}
|
|
||||||
@keyframes show{
|
|
||||||
from {
|
|
||||||
backdrop-filter: blur(0px);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
backdrop-filter: blur(10px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dialog .adder{
|
|
||||||
margin-top: 5rem;
|
|
||||||
}
|
|
||||||
dialog h2{
|
|
||||||
font-size: 3rem;
|
|
||||||
font-family: sans-serif;
|
|
||||||
color: white;
|
|
||||||
text-align: center;
|
|
||||||
margin-top: 30vh;
|
|
||||||
margin-top: 30dvh;
|
|
||||||
filter: drop-shadow(0 0 0.4em black)
|
|
||||||
drop-shadow(0 0 1em black)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
.mod_icons{
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
margin-left: 2rem;
|
|
||||||
}
|
|
||||||
.button_subtle{
|
|
||||||
padding: 0em;
|
|
||||||
animation: unset;
|
|
||||||
margin: 0.2em 0.1em;
|
|
||||||
background-color: transparent;
|
|
||||||
box-shadow: unset;
|
|
||||||
}
|
|
||||||
.button_subtle:hover{
|
|
||||||
scale: 1.2 1.2;
|
|
||||||
}
|
|
||||||
h3{
|
|
||||||
width: fit-content;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
max-width: 1000px;
|
|
||||||
justify-content: space-between;
|
|
||||||
user-select: none;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.ingredients_grid > span{
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: grid;
|
|
||||||
font-size: 1.1em;
|
|
||||||
grid-template-columns: 1em 2fr 3fr 2em;
|
|
||||||
grid-template-rows: auto;
|
|
||||||
grid-auto-flow: row;
|
|
||||||
align-items: center;
|
|
||||||
row-gap: 0.5em;
|
|
||||||
column-gap: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ingredients_grid > *{
|
|
||||||
cursor: pointer;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
.ingredients_grid>*:nth-child(3n+1){
|
|
||||||
min-width: 5ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list_wrapper{
|
|
||||||
padding-inline: 2em;
|
|
||||||
padding-block: 1em;
|
|
||||||
}
|
|
||||||
.list_wrapper p[contenteditable]{
|
|
||||||
border: 2px solid grey;
|
|
||||||
border-radius: 1000px;
|
|
||||||
padding: 0.25em 1em;
|
|
||||||
background-color: white;
|
|
||||||
transition: 200ms;
|
|
||||||
}
|
|
||||||
@media screen and (max-width: 500px){
|
|
||||||
dialog h2{
|
|
||||||
margin-top: 2rem;
|
|
||||||
}
|
|
||||||
dialog .heading_wrapper{
|
|
||||||
width: 80%;
|
|
||||||
}
|
|
||||||
.ingredients_grid .mod_icons{
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.list {
|
|
||||||
cursor: grab;
|
|
||||||
z-index: 5;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item {
|
|
||||||
min-height: 3em;
|
|
||||||
margin-bottom: 0.5em;
|
|
||||||
border-radius: 2px;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item:not(#grabbed):not(#ghost) {
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item > * {
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.buttons {
|
|
||||||
width: 32px;
|
|
||||||
min-width: 32px;
|
|
||||||
margin: auto 0;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.buttons button {
|
|
||||||
cursor: pointer;
|
|
||||||
width: 18px;
|
|
||||||
height: 18px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 0;
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0);
|
|
||||||
background-color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.buttons button:focus {
|
|
||||||
border: 1px solid black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.delete {
|
|
||||||
width: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#grabbed {
|
|
||||||
opacity: 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ghost {
|
|
||||||
pointer-events: none;
|
|
||||||
z-index: -5;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
opacity: 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ghost * {
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ghost.haunting {
|
|
||||||
z-index: 20;
|
|
||||||
opacity: 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
main {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
||||||
<main>
|
|
||||||
<div class=dragdroplist>
|
|
||||||
|
|
||||||
<div
|
|
||||||
bind:this={ghost}
|
|
||||||
id="ghost"
|
|
||||||
class={grabbed ? "item haunting" : "item"}
|
|
||||||
style={"top: " + (mouseY + offsetY - layerY) + "px"}><p></p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
||||||
<h3 onclick={() => show_modal_edit_subheading_ingredient(list_index)}>
|
|
||||||
<div class="drag_handle drag_handle_header"><svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 448 512"><path d="M0 96C0 78.3 14.3 64 32 64H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z"/></svg></div>
|
|
||||||
<div>
|
|
||||||
{#if list.name }
|
|
||||||
{list.name}
|
|
||||||
{:else}
|
|
||||||
Leer
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<div class=mod_icons>
|
|
||||||
<button class="action_button button_subtle" onclick={() => show_modal_edit_subheading_ingredient(list_index)}>
|
|
||||||
<Pen fill=var(--nord1)></Pen> </button>
|
|
||||||
<button class="action_button button_subtle" onclick={() => remove_list(list_index)}>
|
|
||||||
<Cross fill=var(--nord1)></Cross></button>
|
|
||||||
</div>
|
|
||||||
</h3>
|
|
||||||
|
|
||||||
<div class="ingredients_grid list"
|
|
||||||
on:mousemove={function(ev) {ev.stopPropagation(); drag(ev.clientY);}}
|
|
||||||
on:touchmove={function(ev) {ev.stopPropagation(); drag(ev.touches[0].clientY);}}
|
|
||||||
on:mouseup={function(ev) {ev.stopPropagation(); release(ev);}}
|
|
||||||
on:touchend={function(ev) {ev.stopPropagation(); release(ev.touches[0]);}}
|
|
||||||
>
|
|
||||||
{#each list.list as ingredient, ingredient_index}
|
|
||||||
<span
|
|
||||||
id={(grabbed && (ingredient.id ? ingredient.id : JSON.stringify(ingredient)) == grabbed.dataset.id) ? "grabbed" : ""}
|
|
||||||
class="item"
|
|
||||||
data-index={ingredient_index}
|
|
||||||
data-id={(ingredient.id ? ingredient.id : JSON.stringify(ingredient))}
|
|
||||||
data-grabY="0"
|
|
||||||
on:mousedown={function(ev) {grab(ev.clientY, this);}}
|
|
||||||
on:touchstart={function(ev) {grab(ev.touches[0].clientY, this);}}
|
|
||||||
on:mouseenter={function(ev) {ev.stopPropagation(); dragEnter(ev, ev.target);}}
|
|
||||||
on:touchmove={function(ev) {ev.stopPropagation(); ev.preventDefault(); touchEnter(ev.touches[0]);}}
|
|
||||||
>
|
|
||||||
<div class=drag_handle><svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 448 512"><path d="M0 96C0 78.3 14.3 64 32 64H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z"/></svg></div>
|
|
||||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
||||||
<div onclick={() => show_modal_edit_ingredient(list_index, ingredient_index)} >{ingredient.amount} {ingredient.unit}</div>
|
|
||||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
||||||
<div onclick={() => show_modal_edit_ingredient(list_index, ingredient_index)} >{@html ingredient.name}</div>
|
|
||||||
<div class=mod_icons><button class="action_button button_subtle" onclick={() => show_modal_edit_ingredient(list_index, ingredient_index)}>
|
|
||||||
<Pen fill=var(--nord1) height=1em width=1em></Pen></button>
|
|
||||||
<button class="action_button button_subtle" onclick="{() => remove_ingredient(list_index, ingredient_index)}"><Cross fill=var(--nord1) height=1em width=1em></Cross></button></div>
|
|
||||||
</span>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<dialog id=edit_ingredient_modal>
|
|
||||||
<h2>Zutat verändern</h2>
|
|
||||||
<div class=adder>
|
|
||||||
<input class=category type="text" bind:value={edit_ingredient.sublist} placeholder="Kategorie (optional)">
|
|
||||||
<div class=add_ingredient onkeydown={(event) => do_on_key(event, 'Enter', false, edit_ingredient_and_close_modal)}>
|
|
||||||
<input type="text" placeholder="250..." bind:value={edit_ingredient.amount} onkeydown={(event) => do_on_key(event, 'Enter', false, edit_ingredient_and_close_modal)}>
|
|
||||||
<input type="text" placeholder="mL..." bind:value={edit_ingredient.unit} onkeydown={(event) => do_on_key(event, 'Enter', false, edit_ingredient_and_close_modal)}>
|
|
||||||
<input type="text" placeholder="Milch..." bind:value={edit_ingredient.name} onkeydown={(event) => do_on_key(event, 'Enter', false, edit_ingredient_and_close_modal)}>
|
|
||||||
<button class=action_button onkeydown={(event) => do_on_key(event, 'Enter', false, edit_ingredient_and_close_modal)} onclick={edit_ingredient_and_close_modal}>
|
|
||||||
<Check fill=white style="width: 2rem; height: 2rem;"></Check>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</dialog>
|
|
||||||
|
|
||||||
<dialog id=edit_subheading_ingredient_modal>
|
|
||||||
<h2>Kategorie umbenennen</h2>
|
|
||||||
<div class=heading_wrapper>
|
|
||||||
<input class=heading type="text" bind:value={edit_heading.name} onkeydown={(event) => do_on_key(event, 'Enter', false, edit_subheading_and_close_modal)} >
|
|
||||||
<button class=action_button onkeydown={(event) => do_on_key(event, 'Enter', false, edit_subheading_and_close_modal)} onclick={edit_subheading_and_close_modal}>
|
|
||||||
<Check fill=white style="width:2rem; height:2rem;"></Check>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</dialog>
|
|
||||||
@@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
// Faith subroute mappings
|
// Faith subroute mappings
|
||||||
const faithSubroutes: Record<string, Record<string, string>> = {
|
const faithSubroutes: Record<string, Record<string, string>> = {
|
||||||
en: { gebete: 'prayers', rosenkranz: 'rosary', angelus: 'angelus' },
|
en: { gebete: 'prayers', rosenkranz: 'rosary' },
|
||||||
de: { prayers: 'gebete', rosary: 'rosenkranz', angelus: 'angelus' }
|
de: { prayers: 'gebete', rosary: 'rosenkranz' }
|
||||||
};
|
};
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
@@ -194,6 +194,15 @@
|
|||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
.language-options::after {
|
||||||
|
content: "";
|
||||||
|
border: 10px solid transparent;
|
||||||
|
border-bottom-color: var(--bg_color);
|
||||||
|
border-top: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: -10px;
|
||||||
|
right: 1rem;
|
||||||
|
}
|
||||||
/* Show via JS toggle */
|
/* Show via JS toggle */
|
||||||
.language-options.open {
|
.language-options.open {
|
||||||
display: block;
|
display: block;
|
||||||
@@ -222,7 +231,9 @@
|
|||||||
background-color: var(--nord2);
|
background-color: var(--nord2);
|
||||||
}
|
}
|
||||||
.language-options a.active{
|
.language-options a.active{
|
||||||
background-color: var(--nord14);
|
background-color: var(--nord8);
|
||||||
|
color: var(--nord0);
|
||||||
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
<style>
|
<style>
|
||||||
|
|
||||||
:global(.links_grid a:nth-child(4n)),
|
:global(.links_grid a:nth-child(4n)),
|
||||||
:global(.links_grid a:nth-child(4n) svg){
|
:global(.links_grid a:nth-child(4n) svg:not(.lock-icon)){
|
||||||
background-color: var(--nord4);
|
background-color: var(--nord4);
|
||||||
fill: var(--nord11);
|
fill: var(--nord11);
|
||||||
}
|
}
|
||||||
:global(.links_grid a:nth-child(4n+1)),
|
:global(.links_grid a:nth-child(4n+1)),
|
||||||
:global(.links_grid a:nth-child(4n+1) svg){
|
:global(.links_grid a:nth-child(4n+1) svg:not(.lock-icon)){
|
||||||
background-color: var(--nord6);
|
background-color: var(--nord6);
|
||||||
fill: var(--nord10);
|
fill: var(--nord10);
|
||||||
}
|
}
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
:global(a){
|
:global(a){
|
||||||
text-decoration: unset;
|
text-decoration: unset;
|
||||||
color: var(--nord0);
|
color: var(--nord0);
|
||||||
transition: 200ms;
|
transition: var(--transition-normal);
|
||||||
}
|
}
|
||||||
:global(.links_grid a:hover){
|
:global(.links_grid a:hover){
|
||||||
box-shadow: 1em 1em 2em 1em rgba(0,0,0, 0.3);
|
box-shadow: 1em 1em 2em 1em rgba(0,0,0, 0.3);
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
}
|
}
|
||||||
.links_grid{
|
.links_grid{
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
grid-template-columns: repeat(auto-fit, minmax(min(250px, calc(50% - 1rem)), 1fr));
|
||||||
gap: 2rem;
|
gap: 2rem;
|
||||||
max-width: 1000px;
|
max-width: 1000px;
|
||||||
margin-inline: auto;
|
margin-inline: auto;
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
text-decoration: unset;
|
text-decoration: unset;
|
||||||
color: var(--nord0);
|
color: var(--nord0);
|
||||||
transition: 200ms;
|
transition: var(--transition-normal);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -64,8 +64,50 @@
|
|||||||
right: 0.5rem;
|
right: 0.5rem;
|
||||||
width: 1.5rem;
|
width: 1.5rem;
|
||||||
height: 1.5rem;
|
height: 1.5rem;
|
||||||
fill: var(--nord0);
|
fill: var(--nord3);
|
||||||
opacity: 0.6;
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 560px) {
|
||||||
|
.links_grid {
|
||||||
|
gap: 1rem;
|
||||||
|
padding: 1.5rem 0.75rem;
|
||||||
|
}
|
||||||
|
:global(.links_grid a :is(svg, img)) {
|
||||||
|
height: 90px;
|
||||||
|
}
|
||||||
|
:global(.links_grid h3) {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
:global(.links_grid a) {
|
||||||
|
padding: 0.75rem;
|
||||||
|
}
|
||||||
|
:global(.links_grid a .lock-icon) {
|
||||||
|
width: 1.2rem;
|
||||||
|
height: 1.2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 410px) {
|
||||||
|
.links_grid {
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 1rem 0.5rem;
|
||||||
|
}
|
||||||
|
:global(.links_grid a :is(svg, img)) {
|
||||||
|
height: 64px;
|
||||||
|
}
|
||||||
|
:global(.links_grid h3) {
|
||||||
|
font-size: 0.95rem;
|
||||||
|
}
|
||||||
|
:global(.links_grid a) {
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
:global(.links_grid a .lock-icon) {
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
top: 0.3rem;
|
||||||
|
right: 0.3rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark){
|
@media (prefers-color-scheme: dark){
|
||||||
@@ -73,26 +115,25 @@
|
|||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
:global(.links_grid a .lock-icon){
|
:global(.links_grid a .lock-icon){
|
||||||
fill: white;
|
fill: var(--nord3);
|
||||||
}
|
}
|
||||||
:global(.links_grid a:nth-child(4n)),
|
:global(.links_grid a:nth-child(4n)),
|
||||||
:global(.links_grid a:nth-child(4n) svg){
|
:global(.links_grid a:nth-child(4n) svg:not(.lock-icon)){
|
||||||
background-color: var(--nord6-dark);
|
background-color: var(--nord6-dark);
|
||||||
fill: var(--nord11);
|
fill: var(--nord11);
|
||||||
}
|
}
|
||||||
:global(.links_grid a:nth-child(4n+1)),
|
:global(.links_grid a:nth-child(4n+1)),
|
||||||
:global(.links_grid a:nth-child(4n+1) svg){
|
:global(.links_grid a:nth-child(4n+1) svg:not(.lock-icon)){
|
||||||
background-color: var(--accent-dark);
|
background-color: var(--accent-dark);
|
||||||
fill: var(--nord9);
|
fill: var(--nord9);
|
||||||
}
|
}
|
||||||
:global(.links_grid a:nth-child(4n+2)),
|
:global(.links_grid a:nth-child(4n+2)),
|
||||||
:global(.links_grid a:nth-child(4n+2) svg){
|
:global(.links_grid a:nth-child(4n+2) svg:not(.lock-icon)){
|
||||||
background-color: var(--nord1);
|
background-color: var(--nord1);
|
||||||
fill: var(--nord8);
|
fill: var(--nord8);
|
||||||
|
|
||||||
}
|
}
|
||||||
:global(.links_grid a:nth-child(4n+3)),
|
:global(.links_grid a:nth-child(4n+3)),
|
||||||
:global(.links_grid a:nth-child(4n+3) svg){
|
:global(.links_grid a:nth-child(4n+3) svg:not(.lock-icon)){
|
||||||
background-color: var(--background-dark);
|
background-color: var(--background-dark);
|
||||||
fill: var(--nord7);
|
fill: var(--nord7);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,142 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
let {
|
|
||||||
germanUrl,
|
|
||||||
englishUrl,
|
|
||||||
currentLang = 'de',
|
|
||||||
hasTranslation = true
|
|
||||||
}: {
|
|
||||||
germanUrl: string,
|
|
||||||
englishUrl: string,
|
|
||||||
currentLang?: 'de' | 'en',
|
|
||||||
hasTranslation?: boolean
|
|
||||||
} = $props();
|
|
||||||
|
|
||||||
function setLanguagePreference(lang: 'de' | 'en') {
|
|
||||||
if (typeof localStorage !== 'undefined') {
|
|
||||||
localStorage.setItem('preferredLanguage', lang);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.language-switcher {
|
|
||||||
position: fixed;
|
|
||||||
top: 1rem;
|
|
||||||
right: 1rem;
|
|
||||||
z-index: 1000;
|
|
||||||
display: flex;
|
|
||||||
gap: 0.5rem;
|
|
||||||
background: var(--nord0);
|
|
||||||
padding: 0.5rem;
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media(prefers-color-scheme: light) {
|
|
||||||
.language-switcher {
|
|
||||||
background: var(--nord6);
|
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.language-switcher a {
|
|
||||||
padding: 0.5rem 1rem;
|
|
||||||
border-radius: 4px;
|
|
||||||
text-decoration: none;
|
|
||||||
color: var(--nord4);
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
transition: all 0.2s;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media(prefers-color-scheme: light) {
|
|
||||||
.language-switcher a {
|
|
||||||
color: var(--nord2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.language-switcher a:hover {
|
|
||||||
background: var(--nord3);
|
|
||||||
color: var(--nord6);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media(prefers-color-scheme: light) {
|
|
||||||
.language-switcher a:hover {
|
|
||||||
background: var(--nord4);
|
|
||||||
color: var(--nord0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.language-switcher a.active {
|
|
||||||
background: var(--nord14);
|
|
||||||
color: var(--nord0);
|
|
||||||
}
|
|
||||||
|
|
||||||
.language-switcher a.active:hover {
|
|
||||||
background: var(--nord15);
|
|
||||||
}
|
|
||||||
|
|
||||||
.language-switcher a.disabled {
|
|
||||||
opacity: 0.5;
|
|
||||||
cursor: not-allowed;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flag {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
|
||||||
.language-switcher {
|
|
||||||
top: 0.5rem;
|
|
||||||
right: 0.5rem;
|
|
||||||
padding: 0.25rem;
|
|
||||||
gap: 0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.language-switcher a {
|
|
||||||
padding: 0.4rem 0.7rem;
|
|
||||||
font-size: 0.85rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flag {
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div class="language-switcher">
|
|
||||||
<a
|
|
||||||
href={germanUrl}
|
|
||||||
class:active={currentLang === 'de'}
|
|
||||||
aria-label="Switch to German"
|
|
||||||
onclick={() => setLanguagePreference('de')}
|
|
||||||
>
|
|
||||||
<span class="flag">🇩🇪</span>
|
|
||||||
<span class="label">DE</span>
|
|
||||||
</a>
|
|
||||||
{#if hasTranslation}
|
|
||||||
<a
|
|
||||||
href={englishUrl}
|
|
||||||
class:active={currentLang === 'en'}
|
|
||||||
aria-label="Switch to English"
|
|
||||||
onclick={() => setLanguagePreference('en')}
|
|
||||||
>
|
|
||||||
<span class="flag">🇬🇧</span>
|
|
||||||
<span class="label">EN</span>
|
|
||||||
</a>
|
|
||||||
{:else}
|
|
||||||
<span
|
|
||||||
class="disabled"
|
|
||||||
title="English translation not available"
|
|
||||||
aria-label="English translation not available"
|
|
||||||
>
|
|
||||||
<span class="flag">🇬🇧</span>
|
|
||||||
<span class="label">EN</span>
|
|
||||||
</span>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
<script>
|
<script>
|
||||||
import "$lib/css/nordtheme.css";
|
|
||||||
|
|
||||||
let {
|
let {
|
||||||
value = $bindable(''),
|
value = $bindable(''),
|
||||||
@@ -17,11 +16,10 @@
|
|||||||
input {
|
input {
|
||||||
all: unset;
|
all: unset;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-family: sans-serif;
|
|
||||||
background: var(--nord0);
|
background: var(--nord0);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
padding: 0.7rem 2rem;
|
padding: 0.7rem 2rem;
|
||||||
border-radius: 1000px;
|
border-radius: var(--radius-pill);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
input::placeholder {
|
input::placeholder {
|
||||||
@@ -36,7 +34,7 @@ input::placeholder {
|
|||||||
font-size: 1.6rem;
|
font-size: 1.6rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
transition: 100ms;
|
transition: var(--transition-fast);
|
||||||
filter: drop-shadow(0.4em 0.5em 0.4em rgba(0,0,0,0.4));
|
filter: drop-shadow(0.4em 0.5em 0.4em rgba(0,0,0,0.4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
<script>
|
<script>
|
||||||
import "$lib/css/nordtheme.css";
|
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
:root{
|
:root{
|
||||||
--icon_fill: var(--nord4);
|
--icon_fill: var(--nord4);
|
||||||
}
|
}
|
||||||
svg{
|
svg{
|
||||||
transition: 100ms;
|
transition: var(--transition-fast);
|
||||||
height: 3em;
|
height: var(--symbol-size, 3em);
|
||||||
}
|
}
|
||||||
svg:hover,
|
svg:hover,
|
||||||
svg:focus-visible
|
svg:focus-visible
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
let { tag, ref } = $props<{ tag: string, ref: string }>();
|
let { tag, ref } = $props<{ tag: string, ref: string }>();
|
||||||
import '$lib/css/nordtheme.css'
|
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
a{
|
a{
|
||||||
background-color: var(--blue);
|
background-color: var(--blue);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
padding: 2rem;
|
padding: clamp(0.4rem, 0.8vw, 0.8rem) clamp(0.8rem, 1.5vw, 1.5rem);
|
||||||
border-radius: 1000000px;
|
border-radius: 1000000px;
|
||||||
transition: 100ms;
|
transition: var(--transition-fast);
|
||||||
font-size: 2rem;
|
font-size: clamp(0.85rem, 1.8vw, 1.5rem);
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
a:hover{
|
a:hover{
|
||||||
|
|||||||
@@ -5,9 +5,8 @@ div{
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
margin-inline:auto;
|
margin-inline:auto;
|
||||||
gap: 1rem;
|
gap: clamp(0.4rem, 1vw, 1rem);
|
||||||
justify-content: space-evenly;
|
justify-content: space-evenly;
|
||||||
font-family: sans-serif;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
.toggle-wrapper input[type="checkbox"] {
|
.toggle-wrapper input[type="checkbox"] {
|
||||||
appearance: none;
|
appearance: none;
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
|
margin: 0;
|
||||||
width: 44px;
|
width: 44px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
background: var(--nord2);
|
background: var(--nord2);
|
||||||
|
|||||||
@@ -81,6 +81,7 @@
|
|||||||
background-color: var(--bg_color);
|
background-color: var(--bg_color);
|
||||||
width: 30ch;
|
width: 30ch;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
|
||||||
}
|
}
|
||||||
#options ul{
|
#options ul{
|
||||||
color: white;
|
color: white;
|
||||||
@@ -97,7 +98,7 @@
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: white;
|
color: white;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
transition: 100ms;
|
transition: var(--transition-fast);
|
||||||
}
|
}
|
||||||
#options li:hover a{
|
#options li:hover a{
|
||||||
color: var(--red);
|
color: var(--red);
|
||||||
@@ -116,22 +117,31 @@ h2 + p{
|
|||||||
#options{
|
#options{
|
||||||
top: unset;
|
top: unset;
|
||||||
bottom: calc(100% + 15px);
|
bottom: calc(100% + 15px);
|
||||||
right: -200%;
|
left: 50%;
|
||||||
z-index: 99999999999999999999;
|
right: unset;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
z-index: 10;
|
||||||
}
|
}
|
||||||
.top.speech::after {
|
.top.speech::after {
|
||||||
/* (B2-1) DOWN TRIANGLE */
|
border: 20px solid transparent;
|
||||||
border-top-color: #a53d38;
|
border-top-color: var(--bg_color);
|
||||||
border-bottom: 0;
|
border-bottom-width: 0;
|
||||||
z-index: 99999999999999999999;
|
top: unset;
|
||||||
|
bottom: -20px;
|
||||||
/* (B2-2) POSITION AT BOTTOM */
|
left: 50%;
|
||||||
bottom: -20px; left: 50%;
|
|
||||||
margin-left: -20px;
|
margin-left: -20px;
|
||||||
}
|
}
|
||||||
button{
|
button{
|
||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
}
|
}
|
||||||
|
button::before{
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: inherit;
|
||||||
|
z-index: 20;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
import ProfilePicture from './ProfilePicture.svelte';
|
import ProfilePicture from './ProfilePicture.svelte';
|
||||||
import EditButton from './EditButton.svelte';
|
import EditButton from '$lib/components/EditButton.svelte';
|
||||||
import { getCategoryEmoji, getCategoryName } from '$lib/utils/categories';
|
import { getCategoryEmoji, getCategoryName } from '$lib/utils/categories';
|
||||||
import { formatCurrency as formatCurrencyUtil } from '$lib/utils/formatters';
|
import { formatCurrency as formatCurrencyUtil } from '$lib/utils/formatters';
|
||||||
|
|
||||||
@@ -5,19 +5,23 @@
|
|||||||
reference = '',
|
reference = '',
|
||||||
title = '',
|
title = '',
|
||||||
verseData = null,
|
verseData = null,
|
||||||
|
lang = 'de',
|
||||||
onClose
|
onClose
|
||||||
}: {
|
}: {
|
||||||
reference?: string,
|
reference?: string,
|
||||||
title?: string,
|
title?: string,
|
||||||
verseData?: VerseData | null,
|
verseData?: VerseData | null,
|
||||||
|
lang?: string,
|
||||||
onClose: () => void
|
onClose: () => void
|
||||||
} = $props();
|
} = $props();
|
||||||
|
|
||||||
|
const isEnglish = $derived(lang === 'en');
|
||||||
|
|
||||||
let book: string = $state(verseData?.book || '');
|
let book: string = $state(verseData?.book || '');
|
||||||
let chapter: number = $state(verseData?.chapter || 0);
|
let chapter: number = $state(verseData?.chapter || 0);
|
||||||
let verses: Array<{ verse: number; text: string }> = $state(verseData?.verses || []);
|
let verses: Array<{ verse: number; text: string }> = $state(verseData?.verses || []);
|
||||||
let loading = $state(false);
|
let loading = $state(false);
|
||||||
let error = $state(verseData ? '' : 'Keine Versdaten verfügbar');
|
let error = $state(verseData ? '' : (lang === 'en' ? 'No verse data available' : 'Keine Versdaten verfügbar'));
|
||||||
|
|
||||||
function handleBackdropClick(event: MouseEvent) {
|
function handleBackdropClick(event: MouseEvent) {
|
||||||
if (event.target === event.currentTarget) {
|
if (event.target === event.currentTarget) {
|
||||||
@@ -49,7 +53,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
<p class="modal-reference">{reference}</p>
|
<p class="modal-reference">{reference}</p>
|
||||||
</div>
|
</div>
|
||||||
<button class="close-button" onclick={onClose} aria-label="Schließen">
|
<button class="close-button" onclick={onClose} aria-label={isEnglish ? 'Close' : 'Schließen'}>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
<line x1="18" y1="6" x2="6" y2="18"></line>
|
<line x1="18" y1="6" x2="6" y2="18"></line>
|
||||||
<line x1="6" y1="6" x2="18" y2="18"></line>
|
<line x1="6" y1="6" x2="18" y2="18"></line>
|
||||||
@@ -59,7 +63,7 @@
|
|||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
{#if loading}
|
{#if loading}
|
||||||
<p class="loading">Lädt...</p>
|
<p class="loading">{isEnglish ? 'Loading...' : 'Lädt...'}</p>
|
||||||
{:else if error}
|
{:else if error}
|
||||||
<p class="error">{error}</p>
|
<p class="error">{error}</p>
|
||||||
{:else if verses.length > 0}
|
{:else if verses.length > 0}
|
||||||
@@ -72,7 +76,7 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<p class="error">Keine Verse gefunden</p>
|
<p class="error">{isEnglish ? 'No verses found' : 'Keine Verse gefunden'}</p>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -184,9 +188,9 @@
|
|||||||
border: none;
|
border: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
border-radius: 1000px;
|
border-radius: var(--radius-pill);
|
||||||
color: white;
|
color: white;
|
||||||
transition: 200ms;
|
transition: var(--transition-normal);
|
||||||
box-shadow: 0 0 1em 0.2em rgba(0, 0, 0, 0.3);
|
box-shadow: 0 0 1em 0.2em rgba(0, 0, 0, 0.3);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -244,6 +248,7 @@
|
|||||||
gap: 0.75rem;
|
gap: 0.75rem;
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
color: var(--nord4);
|
color: var(--nord4);
|
||||||
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media(prefers-color-scheme: light) {
|
@media(prefers-color-scheme: light) {
|
||||||
@@ -3,9 +3,10 @@
|
|||||||
interface Props {
|
interface Props {
|
||||||
holy?: boolean;
|
holy?: boolean;
|
||||||
burst?: boolean;
|
burst?: boolean;
|
||||||
|
fire ?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
let { holy = false, burst = false }: Props = $props();
|
let { holy = false, burst = false, fire = false}: Props = $props();
|
||||||
|
|
||||||
const burstParticles = [
|
const burstParticles = [
|
||||||
{ x: 10, y: 0, size: 8, delay: 0, dur: 1.6 },
|
{ x: 10, y: 0, size: 8, delay: 0, dur: 1.6 },
|
||||||
@@ -52,22 +53,22 @@
|
|||||||
{:else}
|
{:else}
|
||||||
<div class="fire" class:holy-fire={holy}>
|
<div class="fire" class:holy-fire={holy}>
|
||||||
<div class="fire-left">
|
<div class="fire-left">
|
||||||
<div class="main-fire"></div>
|
{#if fire}<div class="main-fire"></div>{/if}
|
||||||
<div class="particle-fire"></div>
|
<div class="particle-fire"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="fire-center">
|
<div class="fire-center">
|
||||||
<div class="main-fire"></div>
|
{#if fire}<div class="main-fire"></div>{/if}
|
||||||
<div class="particle-fire"></div>
|
<div class="particle-fire"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="fire-right">
|
<div class="fire-right">
|
||||||
<div class="main-fire"></div>
|
{#if fire}<div class="main-fire"></div>{/if}
|
||||||
<div class="particle-fire"></div>
|
<div class="particle-fire"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="fire-bottom">
|
<div class="fire-bottom">
|
||||||
<div class="main-fire"></div>
|
{#if fire}<div class="main-fire"></div>{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { getLanguageContext } from '$lib/contexts/languageContext.js';
|
import { getLanguageContext } from '$lib/contexts/languageContext.js';
|
||||||
import Toggle from './Toggle.svelte';
|
import Toggle from '$lib/components/Toggle.svelte';
|
||||||
|
|
||||||
export let initialLatin = undefined;
|
export let initialLatin = undefined;
|
||||||
export let hasUrlLatin = false;
|
export let hasUrlLatin = false;
|
||||||
119
src/lib/components/faith/PipImage.svelte
Normal file
119
src/lib/components/faith/PipImage.svelte
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* @param {ReturnType<import('$lib/js/pip.svelte').createPip>} pip - a createPip() instance
|
||||||
|
* @param {string} src - image source
|
||||||
|
* @param {string} [alt] - image alt text
|
||||||
|
* @param {boolean} [visible] - whether the PiP should be shown
|
||||||
|
* @param {(e: Event) => void} [onload] - callback when image loads
|
||||||
|
*/
|
||||||
|
let { pip, src, alt = '', visible = false, onload, el = $bindable(null) } = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||||
|
<div
|
||||||
|
class="pip-container"
|
||||||
|
class:visible
|
||||||
|
class:enlarged={pip.enlarged}
|
||||||
|
class:fullscreen={pip.fullscreen}
|
||||||
|
bind:this={el}
|
||||||
|
onpointerdown={pip.onpointerdown}
|
||||||
|
onpointermove={pip.onpointermove}
|
||||||
|
onpointerup={pip.onpointerup}
|
||||||
|
>
|
||||||
|
{#if src}
|
||||||
|
<img {src} {alt} {onload}>
|
||||||
|
{/if}
|
||||||
|
{#if pip.showControls}
|
||||||
|
<button
|
||||||
|
class="pip-fullscreen-btn"
|
||||||
|
aria-label="Fullscreen"
|
||||||
|
onpointerdown={(e) => e.stopPropagation()}
|
||||||
|
onclick={(e) => { e.stopPropagation(); pip.toggleFullscreen(); }}
|
||||||
|
>
|
||||||
|
<svg viewBox="0 0 24 24" width="28" height="28" fill="none" stroke="white" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<polyline points="8 3 3 3 3 8"/>
|
||||||
|
<polyline points="16 3 21 3 21 8"/>
|
||||||
|
<polyline points="8 21 3 21 3 16"/>
|
||||||
|
<polyline points="16 21 21 21 21 16"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.pip-container {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 10000;
|
||||||
|
opacity: 0;
|
||||||
|
touch-action: none;
|
||||||
|
cursor: grab;
|
||||||
|
user-select: none;
|
||||||
|
transition: opacity 0.25s ease;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.pip-container:active {
|
||||||
|
cursor: grabbing;
|
||||||
|
}
|
||||||
|
.pip-container 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;
|
||||||
|
}
|
||||||
|
.pip-container.enlarged img {
|
||||||
|
height: 37.5vh;
|
||||||
|
}
|
||||||
|
.pip-container.fullscreen {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
background: rgba(0, 0, 0, 0.95);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
.pip-container.fullscreen img {
|
||||||
|
border-radius: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
.pip-fullscreen-btn {
|
||||||
|
all: unset;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background: transparent;
|
||||||
|
filter: drop-shadow(0 0 1px black);
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0;
|
||||||
|
z-index: 1;
|
||||||
|
pointer-events: auto;
|
||||||
|
outline: none;
|
||||||
|
transition: transform 0.15s ease;
|
||||||
|
}
|
||||||
|
.pip-fullscreen-btn:hover,
|
||||||
|
.pip-fullscreen-btn:active {
|
||||||
|
transform: translate(-50%, -50%) scale(1.2);
|
||||||
|
}
|
||||||
|
.pip-container.fullscreen .pip-fullscreen-btn {
|
||||||
|
top: auto;
|
||||||
|
left: auto;
|
||||||
|
bottom: 10vw;
|
||||||
|
right: 10vw;
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
.pip-container.fullscreen .pip-fullscreen-btn:hover,
|
||||||
|
.pip-container.fullscreen .pip-fullscreen-btn:active {
|
||||||
|
transform: scale(0.85);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { createPip } from '$lib/js/pip.svelte';
|
import { createPip } from '$lib/js/pip.svelte';
|
||||||
|
import PipImage from '$lib/components/faith/PipImage.svelte';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {'layout' | 'overlay'} mode
|
* @param {'layout' | 'overlay'} mode
|
||||||
@@ -13,7 +14,7 @@
|
|||||||
let contentEl = $state(null);
|
let contentEl = $state(null);
|
||||||
let inView = $state(false);
|
let inView = $state(false);
|
||||||
|
|
||||||
const pip = createPip();
|
const pip = createPip({ fullscreenEnabled: true });
|
||||||
|
|
||||||
function isMobile() {
|
function isMobile() {
|
||||||
return !window.matchMedia('(min-width: 1024px)').matches;
|
return !window.matchMedia('(min-width: 1024px)').matches;
|
||||||
@@ -80,17 +81,10 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="sticky-image-layout" class:overlay={mode === 'overlay'}>
|
<div class="sticky-image-layout" class:overlay={mode === 'overlay'}>
|
||||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
<div class="image-wrap-desktop">
|
||||||
<div
|
|
||||||
class="image-wrap"
|
|
||||||
class:enlarged={pip.enlarged}
|
|
||||||
bind:this={pipEl}
|
|
||||||
onpointerdown={pip.onpointerdown}
|
|
||||||
onpointermove={pip.onpointermove}
|
|
||||||
onpointerup={pip.onpointerup}
|
|
||||||
>
|
|
||||||
<img {src} {alt}>
|
<img {src} {alt}>
|
||||||
</div>
|
</div>
|
||||||
|
<PipImage {pip} {src} {alt} visible={inView} bind:el={pipEl} />
|
||||||
<div class="content-scroll" bind:this={contentEl}>
|
<div class="content-scroll" bind:this={contentEl}>
|
||||||
{@render children()}
|
{@render children()}
|
||||||
</div>
|
</div>
|
||||||
@@ -107,32 +101,8 @@
|
|||||||
.sticky-image-layout.overlay {
|
.sticky-image-layout.overlay {
|
||||||
display: contents;
|
display: contents;
|
||||||
}
|
}
|
||||||
.image-wrap {
|
.image-wrap-desktop {
|
||||||
position: fixed;
|
display: none;
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
z-index: 10000;
|
|
||||||
width: auto;
|
|
||||||
opacity: 0;
|
|
||||||
touch-action: none;
|
|
||||||
cursor: grab;
|
|
||||||
user-select: none;
|
|
||||||
transition: opacity 0.25s ease;
|
|
||||||
}
|
|
||||||
.image-wrap:active {
|
|
||||||
cursor: grabbing;
|
|
||||||
}
|
|
||||||
.image-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;
|
|
||||||
}
|
|
||||||
.image-wrap.enlarged img {
|
|
||||||
height: 37.5vh;
|
|
||||||
}
|
}
|
||||||
.content-scroll {
|
.content-scroll {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -148,29 +118,18 @@
|
|||||||
gap: 2rem;
|
gap: 2rem;
|
||||||
width: calc(100% + 25vw + 2rem);
|
width: calc(100% + 25vw + 2rem);
|
||||||
}
|
}
|
||||||
.overlay .image-wrap {
|
.image-wrap-desktop {
|
||||||
|
display: block;
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 4rem;
|
top: 4rem;
|
||||||
left: auto;
|
|
||||||
transform: none !important;
|
|
||||||
width: auto;
|
|
||||||
align-self: start;
|
align-self: start;
|
||||||
order: 1;
|
order: 1;
|
||||||
opacity: 1;
|
|
||||||
z-index: auto;
|
|
||||||
cursor: default;
|
|
||||||
touch-action: auto;
|
|
||||||
user-select: auto;
|
|
||||||
transition: none;
|
|
||||||
}
|
}
|
||||||
.overlay .image-wrap img {
|
.overlay .image-wrap-desktop img {
|
||||||
height: auto;
|
height: auto;
|
||||||
max-height: calc(100vh - 5rem);
|
max-height: calc(100vh - 5rem);
|
||||||
width: auto;
|
width: auto;
|
||||||
max-width: 25vw;
|
max-width: 25vw;
|
||||||
border-radius: 0;
|
|
||||||
box-shadow: none;
|
|
||||||
pointer-events: auto;
|
|
||||||
}
|
}
|
||||||
.sticky-image-layout:not(.overlay) {
|
.sticky-image-layout:not(.overlay) {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@@ -180,37 +139,27 @@
|
|||||||
.sticky-image-layout:not(.overlay) .content-scroll {
|
.sticky-image-layout:not(.overlay) .content-scroll {
|
||||||
flex: 0 1 700px;
|
flex: 0 1 700px;
|
||||||
}
|
}
|
||||||
.sticky-image-layout:not(.overlay) .image-wrap {
|
.sticky-image-layout:not(.overlay) .image-wrap-desktop {
|
||||||
|
display: block;
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 4rem;
|
top: 4rem;
|
||||||
left: auto;
|
|
||||||
transform: none !important;
|
|
||||||
opacity: 1;
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
background-color: transparent;
|
|
||||||
padding: 0;
|
|
||||||
order: 1;
|
order: 1;
|
||||||
cursor: default;
|
|
||||||
touch-action: auto;
|
|
||||||
user-select: auto;
|
|
||||||
transition: none;
|
|
||||||
}
|
}
|
||||||
.sticky-image-layout:not(.overlay) .image-wrap img {
|
.sticky-image-layout:not(.overlay) .image-wrap-desktop img {
|
||||||
max-height: calc(100vh - 4rem);
|
max-height: calc(100vh - 4rem);
|
||||||
height: auto;
|
height: auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
border-radius: 0;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@media (prefers-color-scheme: light) {
|
@media (prefers-color-scheme: light) {
|
||||||
.sticky-image-layout:not(.overlay) .image-wrap {
|
.sticky-image-layout:not(.overlay) .image-wrap-desktop {
|
||||||
background-color: var(--nord5);
|
background-color: var(--nord5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@media (prefers-color-scheme: light) and (min-width: 1024px) {
|
@media (prefers-color-scheme: light) and (min-width: 1024px) {
|
||||||
.sticky-image-layout:not(.overlay) .image-wrap {
|
.sticky-image-layout:not(.overlay) .image-wrap-desktop {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,11 +54,11 @@
|
|||||||
|
|
||||||
|
|
||||||
{#if phase >= 2}
|
{#if phase >= 2}
|
||||||
<FireEffect holy={phase>=4} />
|
<FireEffect holy={phase>=4} fire={phase>=3}/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if showBurst}
|
{#if showBurst}
|
||||||
<FireEffect holy={phase>=4} burst />
|
<FireEffect holy={phase>=4} burst fire={phase>=3}/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<span class="number">{value}</span>
|
<span class="number">{value}</span>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { browser } from '$app/environment';
|
import { browser } from '$app/environment';
|
||||||
import { getRosaryStreak } from '$lib/stores/rosaryStreak.svelte';
|
import { getRosaryStreak } from '$lib/stores/rosaryStreak.svelte';
|
||||||
import StreakAura from '$lib/components/StreakAura.svelte';
|
import StreakAura from '$lib/components/faith/StreakAura.svelte';
|
||||||
import { tick, onMount } from 'svelte';
|
import { tick, onMount } from 'svelte';
|
||||||
|
|
||||||
let burst = $state(false);
|
let burst = $state(false);
|
||||||
@@ -10,9 +10,10 @@ let streak = $state<ReturnType<typeof getRosaryStreak> | null>(null);
|
|||||||
interface Props {
|
interface Props {
|
||||||
streakData?: { length: number; lastPrayed: string | null } | null;
|
streakData?: { length: number; lastPrayed: string | null } | null;
|
||||||
lang?: 'de' | 'en';
|
lang?: 'de' | 'en';
|
||||||
|
isLoggedIn?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
let { streakData = null, lang = 'de' }: Props = $props();
|
let { streakData = null, lang = 'de', isLoggedIn = false }: Props = $props();
|
||||||
|
|
||||||
const isEnglish = $derived(lang === 'en');
|
const isEnglish = $derived(lang === 'en');
|
||||||
|
|
||||||
@@ -29,9 +30,12 @@ const labels = $derived({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Initialize store on mount (client-side only)
|
// Initialize store on mount (client-side only)
|
||||||
|
// Init with server data BEFORE assigning to streak, so displayLength
|
||||||
|
// never sees stale localStorage data from the singleton
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
streak = getRosaryStreak();
|
const s = getRosaryStreak();
|
||||||
streak.initWithServerData(streakData, streakData !== null);
|
s.initWithServerData(streakData, isLoggedIn);
|
||||||
|
streak = s;
|
||||||
});
|
});
|
||||||
|
|
||||||
async function pray() {
|
async function pray() {
|
||||||
@@ -42,14 +46,15 @@ async function pray() {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="streak-container">
|
<div class="streak-container" class:no-js-hidden={!isLoggedIn}>
|
||||||
<div class="streak-display">
|
<div class="streak-display">
|
||||||
<StreakAura value={displayLength} {burst} />
|
<StreakAura value={displayLength} {burst} />
|
||||||
<span class="streak-label">{labels.days}</span>
|
<span class="streak-label">{labels.days}</span>
|
||||||
</div>
|
</div>
|
||||||
|
<form method="POST" action="?/pray" onsubmit={(e) => { e.preventDefault(); pray(); }}>
|
||||||
<button
|
<button
|
||||||
class="streak-button"
|
class="streak-button"
|
||||||
onclick={pray}
|
type="submit"
|
||||||
disabled={prayedToday}
|
disabled={prayedToday}
|
||||||
aria-label={labels.ariaLabel}
|
aria-label={labels.ariaLabel}
|
||||||
>
|
>
|
||||||
@@ -59,6 +64,7 @@ async function pray() {
|
|||||||
{labels.prayed}
|
{labels.prayed}
|
||||||
{/if}
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@@ -119,6 +125,15 @@ async function pray() {
|
|||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Hide for non-logged-in users without JS (no form action available) */
|
||||||
|
.no-js-hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(html.js-enabled) .no-js-hidden {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: light) {
|
@media (prefers-color-scheme: light) {
|
||||||
.streak-button:disabled {
|
.streak-button:disabled {
|
||||||
background: var(--nord4);
|
background: var(--nord4);
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
<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>
|
<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}
|
{/if}
|
||||||
<v lang=de>
|
<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)
|
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 Schmerz 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>
|
</v>
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
108
src/lib/components/faith/prayers/Angelus.svelte
Normal file
108
src/lib/components/faith/prayers/Angelus.svelte
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
<script>
|
||||||
|
import Prayer from './Prayer.svelte';
|
||||||
|
import AveMaria from './AveMaria.svelte';
|
||||||
|
|
||||||
|
let { verbose = false } = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Prayer>
|
||||||
|
{#snippet children(showLatin, urlLang)}
|
||||||
|
<p>
|
||||||
|
{#if showLatin}<v lang="la"><i>℣.</i> Ángelus Dómini nuntiávit Maríæ.</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de"><i>℣.</i> Der Engel des Herrn brachte Maria die Botschaft</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en"><i>℣.</i> The Angel of the Lord declared unto Mary.</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la"><i>℟.</i> Et concépit de Spíritu Sancto.</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de"><i>℟.</i> und sie empfing vom Heiligen Geist.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en"><i>℟.</i> And she conceived of the Holy Spirit.</v>{/if}
|
||||||
|
</p>
|
||||||
|
{/snippet}
|
||||||
|
</Prayer>
|
||||||
|
|
||||||
|
{#if verbose}
|
||||||
|
<AveMaria />
|
||||||
|
{:else}
|
||||||
|
<p class="ave-indicator"><i>— Ave Maria —</i></p>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<Prayer>
|
||||||
|
{#snippet children(showLatin, urlLang)}
|
||||||
|
<p>
|
||||||
|
{#if showLatin}<v lang="la"><i>℣.</i> Ecce ancílla Dómini,</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de"><i>℣.</i> Maria sprach: Siehe, ich bin die Magd des Herrn</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en"><i>℣.</i> Behold the handmaid of the Lord.</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la"><i>℟.</i> Fiat mihi secúndum verbum tuum.</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de"><i>℟.</i> mir geschehe nach Deinem Wort.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en"><i>℟.</i> Be it done unto me according to thy word.</v>{/if}
|
||||||
|
</p>
|
||||||
|
{/snippet}
|
||||||
|
</Prayer>
|
||||||
|
|
||||||
|
{#if verbose}
|
||||||
|
<AveMaria />
|
||||||
|
{:else}
|
||||||
|
<p class="ave-indicator"><i>— Ave Maria —</i></p>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<Prayer>
|
||||||
|
{#snippet children(showLatin, urlLang)}
|
||||||
|
<p>
|
||||||
|
{#if showLatin}<v lang="la"><i>℣.</i> Et Verbum caro factum est,</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de"><i>℣.</i> Und das Wort ist Fleisch geworden</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en"><i>℣.</i> And the Word was made flesh.</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la"><i>℟.</i> Et habitávit in nobis.</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de"><i>℟.</i> und hat unter uns gewohnt.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en"><i>℟.</i> And dwelt among us.</v>{/if}
|
||||||
|
</p>
|
||||||
|
{/snippet}
|
||||||
|
</Prayer>
|
||||||
|
|
||||||
|
{#if verbose}
|
||||||
|
<AveMaria />
|
||||||
|
{:else}
|
||||||
|
<p class="ave-indicator"><i>— Ave Maria —</i></p>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<Prayer>
|
||||||
|
{#snippet children(showLatin, urlLang)}
|
||||||
|
<p>
|
||||||
|
{#if showLatin}<v lang="la"><i>℣.</i> Ora pro nobis, sancta Dei Génetrix,</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de"><i>℣.</i> Bitte für uns, heilige Gottesmutter,</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en"><i>℣.</i> Pray for us, O holy Mother of God.</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la"><i>℟.</i> Ut digni efficiámur promissiónibus Christi.</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de"><i>℟.</i> auf dass wir würdig werden der Verheissungen Christi.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en"><i>℟.</i> That we may be made worthy of the promises of Christ.</v>{/if}
|
||||||
|
</p>
|
||||||
|
{/snippet}
|
||||||
|
</Prayer>
|
||||||
|
|
||||||
|
<Prayer>
|
||||||
|
{#snippet children(showLatin, urlLang)}
|
||||||
|
<p>
|
||||||
|
{#if showLatin}<v lang="la"><i>℣.</i> Orémus.</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de"><i>℣.</i> Lasset uns beten.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en"><i>℣.</i> Let us pray:</v>{/if}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{#if showLatin}<v lang="la">Grátiam tuam, quǽsumus, Dómine, méntibus nostris infúnde;</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">Allmächtiger Gott, giesse deine Gnade in unsere Herzen ein.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">Pour forth, we beseech Thee, O Lord, Thy grace into our hearts,</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">ut qui, Ángelo nuntiánte, Christi Fílii tui incarnatiónem cognóvimus,</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">Durch die Botschaft des Engels haben wir die Menschwerdung Christi, deines Sohnes, erkannt.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">that we to whom the Incarnation of Christ Thy Son was made known by the message of an angel,</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">per passiónem eius et crucem ad resurrectiónis glóriam perducámur.</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">Lass uns durch sein Leiden und Kreuz zur Herrlichkeit der Auferstehung gelangen.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">may by His Passion and Cross be brought to the glory of His Resurrection.</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">Per eúmdem Christum Dóminum nostrum. Amen.</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">Darum bitten wir durch Christus, unseren Herrn. Amen.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">Through the same Christ Our Lord. Amen.</v>{/if}
|
||||||
|
</p>
|
||||||
|
{/snippet}
|
||||||
|
</Prayer>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.ave-indicator {
|
||||||
|
text-align: center;
|
||||||
|
color: grey;
|
||||||
|
margin: 0.5em 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
53
src/lib/components/faith/prayers/AnimaChristi.svelte
Normal file
53
src/lib/components/faith/prayers/AnimaChristi.svelte
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<script>
|
||||||
|
import Prayer from './Prayer.svelte';
|
||||||
|
import Paternoster from './Paternoster.svelte';
|
||||||
|
import AveMaria from './AveMaria.svelte';
|
||||||
|
import GloriaPatri from './GloriaPatri.svelte';
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<Prayer>
|
||||||
|
{#snippet children(showLatin, urlLang)}
|
||||||
|
<p>
|
||||||
|
{#if showLatin}<v lang=la>Ánima Christi, santífica me.</v>{/if}
|
||||||
|
{#if urlLang=='de'}<v lang=de>Seele Christi, heilige mich.</v>{/if}
|
||||||
|
{#if urlLang=='en'}<v lang=en>Soul of Christ, sanctify me.</v>{/if}
|
||||||
|
{#if showLatin}<v lang=la>Corpus Christi, salva me.</v>{/if}
|
||||||
|
{#if urlLang=='de'}<v lang=de>Leib Christi, erlöse mich.</v>{/if}
|
||||||
|
{#if urlLang=='en'}<v lang=en>Body of Christ, save me.</v>{/if}
|
||||||
|
{#if showLatin}<v lang=la>Sanguis Christi, inébria me.</v>{/if}
|
||||||
|
{#if urlLang=='de'}<v lang=de>Blut Christi, tränke mich.</v>{/if}
|
||||||
|
{#if urlLang=='en'}<v lang=en>Blood of Christ, inebriate me.</v>{/if}
|
||||||
|
{#if showLatin}<v lang=la>Aqua láteris Christi, lava me.</v>{/if}
|
||||||
|
{#if urlLang=='de'}<v lang=de>Wasser der Seite Christi, wasche mich.</v>{/if}
|
||||||
|
{#if urlLang=='en'}<v lang=en>Water from the side of Christ, wash me.</v>{/if}
|
||||||
|
{#if showLatin}<v lang=la>Pássio Christi, confórta me.</v>{/if}
|
||||||
|
{#if urlLang=='de'}<v lang=de>Leiden Christi, stärke mich.</v>{/if}
|
||||||
|
{#if urlLang=='en'}<v lang=en>Passion of Christ, strenghten me.</v>{/if}
|
||||||
|
{#if showLatin}<v lang=la>O bone Iesu, exáudi me.</v>{/if}
|
||||||
|
{#if urlLang=='de'}<v lang=de>O gütiger Jesus, erhöre mich.</v>{/if}
|
||||||
|
{#if urlLang=='en'}<v lang=en>O good Jesus, hear me.</v>{/if}
|
||||||
|
{#if showLatin}<v lang=la>Intra tua vúlnera abscónde me.</v>{/if}
|
||||||
|
{#if urlLang=='de'}<v lang=de>Verbirg in Deine Wunden mich.</v>{/if}
|
||||||
|
{#if urlLang=='en'}<v lang=en>Within Thy wounds hide me.</v>{/if}
|
||||||
|
{#if showLatin}<v lang=la>Ne permíttas me separári a te.</v>{/if}
|
||||||
|
{#if urlLang=='de'}<v lang=de>Von Dir lass nimmer scheiden mich.</v>{/if}
|
||||||
|
{#if urlLang=='en'}<v lang=en>Separated from Thee let me never be.</v>{/if}
|
||||||
|
{#if showLatin}<v lang=la>Ab hoste malígno defénde me.</v>{/if}
|
||||||
|
{#if urlLang=='de'}<v lang=de>Vor dem bösen Feind beschütze mich.</v>{/if}
|
||||||
|
{#if urlLang=='en'}<v lang=en>From the malignant enemeny, defend me.</v>{/if}
|
||||||
|
{#if showLatin}<v lang=la>In hora mortis meæ voca me.</v>{/if}
|
||||||
|
{#if urlLang=='de'}<v lang=de>In meiner Todesstunde rufe mich,</v>{/if}
|
||||||
|
{#if urlLang=='en'}<v lang=en>At the hour of death, call me.</v>{/if}
|
||||||
|
{#if showLatin}<v lang=la>Et iube me veníre ad te,</v>{/if}
|
||||||
|
{#if urlLang=='de'}<v lang=de>Und heisse zur Dir kommen mich,</v>{/if}
|
||||||
|
{#if urlLang=='en'}<v lang=en>And bid me come unto Thee</v>{/if}
|
||||||
|
{#if showLatin}<v lang=la>Ut cum Sanctis tuis laudem te</v>{/if}
|
||||||
|
{#if urlLang=='de'}<v lang=de>Damit ich möge loben Dich</v>{/if}
|
||||||
|
{#if urlLang=='en'}<v lang=en>That with Thy Saints I may praise Thee</v>{/if}
|
||||||
|
{#if showLatin}<v lang=la>in sǽcula sæculórum.</v>{/if}
|
||||||
|
{#if urlLang=='de'}<v lang=de>Mit Deinen Heiligen ewiglich.</v>{/if}
|
||||||
|
{#if urlLang=='en'}<v lang=en>forever and ever.</v>{/if}
|
||||||
|
<v lang=und>Amen.</v>
|
||||||
|
</p>
|
||||||
|
{/snippet}
|
||||||
|
</Prayer>
|
||||||
68
src/lib/components/faith/prayers/ApostlesCreed.svelte
Normal file
68
src/lib/components/faith/prayers/ApostlesCreed.svelte
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<script>
|
||||||
|
import Prayer from './Prayer.svelte';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Prayer>
|
||||||
|
{#snippet children(showLatin, urlLang)}
|
||||||
|
<p>
|
||||||
|
{#if showLatin}<v lang="la">Credo in Deum Patrem omnipoténtem,</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">Ich glaube an Gott, den Vater, den Allmächtigen,</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">I believe in God, the Father almighty,</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">Creatórem cæli et terræ.</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">den Schöpfer des Himmels und der Erde.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">Creator of heaven and earth.</v>{/if}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{#if showLatin}<v lang="la">Et in Iesum Christum, Fílium eius únicum, Dóminum nostrum,</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">Und an Jesus Christus, seinen eingeborenen Sohn, unsern Herrn,</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">And in Jesus Christ, His only Son, our Lord,</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">qui concéptus est de Spíritu Sancto,</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">der empfangen ist vom Heiligen Geist,</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">who was conceived by the Holy Spirit,</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">natus ex María Vírgine,</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">geboren von der Jungfrau Maria,</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">born of the Virgin Mary,</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">passus sub Póntio Piláto,</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">gelitten unter Pontius Pilatus,</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">suffered under Pontius Pilate,</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">crucifíxus, mórtuus, et sepúltus,</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">gekreuzigt, gestorben und begraben,</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">was crucified, died, and was buried.</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">descéndit ad ínferos,</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">hinabgestiegen in das Reich des Todes,</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">He descended into hell.</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">tértia die resurréxit a mórtuis,</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">am dritten Tage auferstanden von den Toten,</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">On the third day He rose again from the dead.</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">ascéndit ad cælos,</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">aufgefahren in den Himmel,</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">He ascended into heaven,</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">sedet ad déxteram Dei Patris omnipoténtis,</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">er sitzet zur Rechten Gottes, des allmächtigen Vaters;</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">and sits at the right hand of God the Father almighty.</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">inde ventúrus est iudicáre vivos et mórtuos.</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">von dort wird er kommen, zu richten die Lebenden und die Toten.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">From thence He shall come to judge the living and the dead.</v>{/if}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{#if showLatin}<v lang="la">Credo in Spíritum Sanctum,</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">Ich glaube an den Heiligen Geist,</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">I believe in the Holy Spirit,</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">sanctam Ecclésiam cathólicam,</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">die heilige katholische Kirche,</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">the holy catholic Church,</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">sanctórum communiónem,</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">Gemeinschaft der Heiligen,</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">the communion of saints,</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">remissiónem peccatórum,</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">Vergebung der Sünden,</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">the forgiveness of sins,</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">carnis resurrectiónem,</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">Auferstehung der Toten</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">the resurrection of the body,</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">vitam ætérnam. Amen.</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">und das ewige Leben. Amen.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">and life everlasting. Amen.</v>{/if}
|
||||||
|
</p>
|
||||||
|
{/snippet}
|
||||||
|
</Prayer>
|
||||||
@@ -1,7 +1,20 @@
|
|||||||
<script>
|
<script>
|
||||||
import Prayer from './Prayer.svelte';
|
import Prayer from './Prayer.svelte';
|
||||||
|
|
||||||
|
let { intro = false } = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
{#if intro}
|
||||||
|
<Prayer hasLatin={false}>
|
||||||
|
{#snippet children(showLatin, urlLang)}
|
||||||
|
<p class="intro">
|
||||||
|
{#if urlLang === 'en'}This ancient hymn begins with the words the angels used to celebrate the newborn Savior. It first praises God the Father, then God the Son; it concludes with homage to the Most Holy Trinity, during which one makes the sign of the cross.{/if}
|
||||||
|
{#if urlLang === 'de'}Der uralte Gesang beginnt mit den Worten, mit denen die Engelscharen den neugeborenen Welterlöser feierten. Er preist zunächst Gott Vater, dann Gott Sohn; er schliesst mit einer Huldigung an die Heiligste Dreifaltigkeit, wobei man sich mit dem grossen Kreuze bezeichnet.{/if}
|
||||||
|
</p>
|
||||||
|
{/snippet}
|
||||||
|
</Prayer>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<Prayer>
|
<Prayer>
|
||||||
{#snippet children(showLatin, urlLang)}
|
{#snippet children(showLatin, urlLang)}
|
||||||
<p>
|
<p>
|
||||||
25
src/lib/components/faith/prayers/GuardianAngel.svelte
Normal file
25
src/lib/components/faith/prayers/GuardianAngel.svelte
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<script>
|
||||||
|
import Prayer from './Prayer.svelte';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Prayer>
|
||||||
|
{#snippet children(showLatin, urlLang)}
|
||||||
|
<p>
|
||||||
|
{#if showLatin}<v lang="la">Ángele Dei,</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">Engel Gottes,</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">Angel of God,</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">qui custos es mei,</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">mein Beschützer,</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">my guardian dear,</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">me, tibi commíssum pietáte supérna,</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">dir hat Gottes Vorsehung mich anvertraut;</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">to whom God's love commits me here,</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">illúmina, custódi, rege et gubérna.</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">erleuchte, beschütze, leite und führe mich.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">ever this day be at my side, to light and guard, to rule and guide.</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">Amen.</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">Amen.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">Amen.</v>{/if}
|
||||||
|
</p>
|
||||||
|
{/snippet}
|
||||||
|
</Prayer>
|
||||||
41
src/lib/components/faith/prayers/Postcommunio.svelte
Normal file
41
src/lib/components/faith/prayers/Postcommunio.svelte
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<script>
|
||||||
|
import Prayer from './Prayer.svelte';
|
||||||
|
import Paternoster from './Paternoster.svelte';
|
||||||
|
import AveMaria from './AveMaria.svelte';
|
||||||
|
import GloriaPatri from './GloriaPatri.svelte';
|
||||||
|
import AnimaChristi from './AnimaChristi.svelte';
|
||||||
|
import PrayerBeforeACrucifix from './PrayerBeforeACrucifix.svelte';
|
||||||
|
|
||||||
|
let {onlyIntro = false } = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Prayer hasLatin={false}>
|
||||||
|
{#snippet children(showLatin, urlLang)}
|
||||||
|
<p class="intro">
|
||||||
|
{#if urlLang === 'en'}A plenary indulgence is granted to the faithful who devoutly recite these prayers after Holy Communion. The usual conditions apply: sacramental confession, Eucharistic communion, prayer for the intentions of the Holy Father, and detachment from all sin, even venial.{/if}
|
||||||
|
{#if urlLang === 'de'}Den Gläubigen, die diese Gebete nach der heiligen Kommunion andächtig verrichten, wird ein vollkommener Ablass gewährt. Die üblichen Bedingungen gelten: sakramentale Beichte, eucharistische Kommunion, Gebet in den Anliegen des Heiligen Vaters und Loslösung von jeder Sünde, auch von lässlichen.{/if}
|
||||||
|
</p>
|
||||||
|
{/snippet}
|
||||||
|
</Prayer>
|
||||||
|
{#if !onlyIntro}
|
||||||
|
|
||||||
|
<Prayer>
|
||||||
|
{#snippet children(showLatin, urlLang)}
|
||||||
|
<h3> Ánima Christi </h3>
|
||||||
|
<AnimaChristi />
|
||||||
|
<h3>
|
||||||
|
{#if urlLang=='en'}Plenary Indulgence{:else}Vollkommener Ablass{/if}
|
||||||
|
</h3>
|
||||||
|
<h3>
|
||||||
|
{#if urlLang=='en'}Prayer Before a Crucifix{:else}Gebet vor einem Kruzifix{/if}
|
||||||
|
</h3>
|
||||||
|
<h4> Paternoster </h4>
|
||||||
|
<Paternoster />
|
||||||
|
<h4> Ave Maria </h4>
|
||||||
|
<AveMaria />
|
||||||
|
<h4> Gloria Patri </h4>
|
||||||
|
<GloriaPatri />
|
||||||
|
<PrayerBeforeACrucifix />
|
||||||
|
{/snippet}
|
||||||
|
</Prayer>
|
||||||
|
{/if}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<script>
|
||||||
|
import Prayer from './Prayer.svelte';
|
||||||
|
import Paternoster from './Paternoster.svelte';
|
||||||
|
import AveMaria from './AveMaria.svelte';
|
||||||
|
import GloriaPatri from './GloriaPatri.svelte';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Prayer>
|
||||||
|
{#snippet children(showLatin, urlLang)}
|
||||||
|
<p>
|
||||||
|
{#if showLatin}<v lang=la>En ego, o bone et dulcíssime Jesu,</v>{/if}
|
||||||
|
{#if urlLang=='de'}<v lang=de>Siehe, o gütiger und milder Jesus,</v>{/if}
|
||||||
|
{#if urlLang=='en'}<v lang=en>Behold, O good and sweetest Jesus,</v>{/if}
|
||||||
|
{#if showLatin}<v lang=la>ante conspéctum tuum génibus me provólvo </v>{/if}
|
||||||
|
{#if urlLang=='de'}<v lang=de>ich werfe mich vor Deinen Augen auf die Knie. </v>{/if}
|
||||||
|
{#if urlLang=='en'}<v lang=en>I cast myself upon my knees in Thy sight,</v>{/if}
|
||||||
|
{#if showLatin}<v lang=la>ac máximo ánimi ardóre te oro atque obtéstor, </v>{/if}
|
||||||
|
{#if urlLang=='de'}<v lang=de>Inbrünstig bitte und beschwöre ich Dich:</v>{/if}
|
||||||
|
{#if urlLang=='en'}<v lang=en>and with the most fervent desire of my soul I pray and beseech Thee</v>{/if}
|
||||||
|
{#if showLatin}<v lang=la> ut meum in in cor vívidos fídei, spei et caritátis sensus, atque veram peccatórum meórum pœniténtiam,</v>{/if}
|
||||||
|
{#if urlLang=='de'}<v lang=de>Präge meinem Herzen lebendige Gefühle des Glaubens, der Hoffung und der Liebe ein</v>{/if}
|
||||||
|
{#if urlLang=='en'}<v lang=en>to impress upon my heart lively sentiments of faith, hope and charity,</v>{/if}
|
||||||
|
{#if showLatin} <v lang=la>éaque emendándi firmíssimam voluntátem velis</v>{/if}
|
||||||
|
{#if urlLang=='de'}<v lang=de>sowie wahre Reue über meine Sünden und den ganz festen Willen, mich zu bessern.</v>{/if}
|
||||||
|
{#if urlLang=='en'}<v lang=en>with true repentance for my sins and a most firm desire of amendment:</v>{/if}
|
||||||
|
{#if showLatin} <v lang=la> imprímere; dum magno ánimi afféctu et dolóre tua quinque vúlnera mecum ipse consídero ac mente contémplor,</v>{/if}
|
||||||
|
{#if urlLang=='de'}<v lang=de>Voll Liebe und Schmerz schaue ich Deine fünf Wunden und betrachte sie in meinem Geiste.</v>{/if}
|
||||||
|
{#if urlLang=='en'}<v lang=en>whilst with deep affection and grief of soul I consider within myself and mentally contemplate Thy five most precious Wounds,</v>{/if}
|
||||||
|
{#if showLatin}<v lang=la>illud præ óculis habens, quod jam in ore ponébat tuo David Prophéta de te, o bone Jesu:</v>{/if}
|
||||||
|
{#if urlLang=='de'}<v lang=de>Dabei halte ich mir vor Augen, was im Hinblick auf Dich, o guter Jesus, schon der Prophet David Dir in den Mund legte:</v>{/if}
|
||||||
|
{#if urlLang=='en'}<v lang=en>having before mine eyes that which David, the prophet, long ago spoke in Thine Own person concerning Thee, my Jesus:</v>{/if}
|
||||||
|
{#if showLatin}<v lang=la> «Fodérunt manus meas et pedes meos; dinumeravérunt ómnio ossa mea.» (Ps. 21, 17-18)</v>{/if}
|
||||||
|
{#if urlLang=='de'}<v lang=de>«Sie haben Meine Hände und Meine Füsse durchbohrt; alle meine Gebeine haben sie gezählt.» (Ps. 21, 17-18)</v>{/if}
|
||||||
|
{#if urlLang=='en'}<v lang=en>"They have pierced My hands and My feet, they have numbered all My bones." (Ps. 21:17-18</v>{/if}
|
||||||
|
<v lang=und>Amen.</v>
|
||||||
|
</p>
|
||||||
|
{/snippet}
|
||||||
|
</Prayer>
|
||||||
46
src/lib/components/faith/prayers/ReginaCaeli.svelte
Normal file
46
src/lib/components/faith/prayers/ReginaCaeli.svelte
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<script>
|
||||||
|
import Prayer from './Prayer.svelte';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Prayer>
|
||||||
|
{#snippet children(showLatin, urlLang)}
|
||||||
|
<p>
|
||||||
|
{#if showLatin}<v lang="la">Regína Cæli, lætáre, allelúia.</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">Freu dich, du Himmelskönigin, alleluja.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">Queen of Heaven, rejoice, alleluia.</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">Quia quem meruísti portáre, allelúia.</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">Den du zu tragen würdig warst, alleluja.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">For He whom thou didst merit to bear, alleluia.</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">Resurréxit, sicut dixit, allelúia.</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">Er ist auferstanden, wie er gesagt hat, alleluja.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">Has risen, as He said, alleluia.</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">Ora pro nobis Deum, allelúia.</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">Bitt Gott für uns, alleluja.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">Pray for us to God, alleluia.</v>{/if}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{#if showLatin}<v lang="la"><i>℣.</i> Gaude et lætáre, Virgo María, allelúia.</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de"><i>℣.</i> Freu dich und frohlocke, Jungfrau Maria, alleluja.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en"><i>℣.</i> Rejoice and be glad, O Virgin Mary, alleluia.</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la"><i>℟.</i> Quia surréxit Dóminus vere, allelúia.</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de"><i>℟.</i> Denn der Herr ist wahrhaft auferstanden, alleluja.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en"><i>℟.</i> For the Lord has truly risen, alleluia.</v>{/if}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{#if showLatin}<v lang="la"><i>℣.</i> Orémus.</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de"><i>℣.</i> Lasset uns beten.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en"><i>℣.</i> Let us pray:</v>{/if}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{#if showLatin}<v lang="la">Deus, qui per resurrectiónem Fílii tui Dómini nostri Iesu Christi mundum lætificáre dignátus es,</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">O Gott, der du durch die Auferstehung deines Sohnes, unseres Herrn Jesus Christus, die Welt zu erfreuen dich gewürdigt hast,</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">O God, who through the resurrection of Thy Son our Lord Jesus Christ didst vouchsafe to give joy to the world,</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">præsta, quǽsumus, ut per eius Genetrícem Vírginem Maríam perpétuæ capiámus gáudia vitæ.</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">verleihe uns, wir bitten dich, dass wir durch seine Mutter, die Jungfrau Maria, die Freuden des ewigen Lebens erlangen.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">grant, we beseech Thee, that through His Mother the Virgin Mary we may obtain the joys of everlasting life.</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">Per eúmdem Christum Dóminum nostrum. Amen.</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">Durch Christus, unseren Herrn. Amen.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">Through the same Christ our Lord. Amen.</v>{/if}
|
||||||
|
</p>
|
||||||
|
{/snippet}
|
||||||
|
</Prayer>
|
||||||
@@ -38,9 +38,9 @@
|
|||||||
{#if showLatin}<v lang="la">nóbis post hoc exsílíum osténde.</v>{/if}
|
{#if showLatin}<v lang="la">nóbis post hoc exsílíum osténde.</v>{/if}
|
||||||
{#if urlLang === 'de'}<v lang="de">die gebenedeite Frucht deines Leibes.</v>{/if}
|
{#if urlLang === 'de'}<v lang="de">die gebenedeite Frucht deines Leibes.</v>{/if}
|
||||||
{#if urlLang === 'en'}<v lang="en">the blessed fruit of thy womb, <i><sup>⚬</sup></i>Jesus.</v>{/if}
|
{#if urlLang === 'en'}<v lang="en">the blessed fruit of thy womb, <i><sup>⚬</sup></i>Jesus.</v>{/if}
|
||||||
{#if showLatin}<v lang="la">O clémens, o pía, o dúlcis Vírgo <i><sup>⚬</sup></i>María.</v>{/if}
|
{#if showLatin}<v lang="la">O clémens, o pía, o dúlcis Vírgo <i><sup>⚬</sup></i>María. Amen.</v>{/if}
|
||||||
{#if urlLang === 'de'}<v lang="de">O gütige, o milde, o süsse Jungfrau <i><sup>⚬</sup></i>Maria.</v>{/if}
|
{#if urlLang === 'de'}<v lang="de">O gütige, o milde, o süsse Jungfrau <i><sup>⚬</sup></i>Maria. Amen.</v>{/if}
|
||||||
{#if urlLang === 'en'}<v lang="en">O clement, O loving, O sweet Virgin <i><sup>⚬</sup></i>Mary.</v>{/if}
|
{#if urlLang === 'en'}<v lang="en">O clement, O loving, O sweet Virgin <i><sup>⚬</sup></i>Mary. Amen.</v>{/if}
|
||||||
</p>
|
</p>
|
||||||
{/snippet}
|
{/snippet}
|
||||||
</Prayer>
|
</Prayer>
|
||||||
48
src/lib/components/faith/prayers/TantumErgo.svelte
Normal file
48
src/lib/components/faith/prayers/TantumErgo.svelte
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<script>
|
||||||
|
import Prayer from './Prayer.svelte';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Prayer>
|
||||||
|
{#snippet children(showLatin, urlLang)}
|
||||||
|
<p>
|
||||||
|
{#if showLatin}<v lang="la">Tantum ergo Sacraméntum</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">Darum lasst uns tief verehren</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">Therefore so great a Sacrament</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">venerémur cérnui:</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">ein so grosses Sakrament;</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">let us venerate with bowed heads;</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">et antíquum documéntum</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">dieser Bund soll ewig währen</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">and the old rite</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">novo cedat rítui:</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">und den neuen Bund ersetzt.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">give way to the new:</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">præstet fides suppleméntum</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">Unser Glaube soll uns lehren,</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">let faith provide a supplement</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">sénsuum deféctui.</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">was das Auge nicht erkennt.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">for the failure of the senses.</v>{/if}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{#if showLatin}<v lang="la">Genitóri, Genitóque</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">Gott dem Vater und dem Sohne</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">To the Begetter and the Begotten</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">laus et iubilátio,</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">sei Lob und Preis und Ehre,</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">be praise and jubilation,</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">salus, honor, virtus quoque</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">Heil und Ruhm und Macht und Wonne</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">salvation, honour, virtue also</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">sit et benedíctio:</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">und Segen immerdar,</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">and blessing too:</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">procedénti ab utróque</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">und dem der von beiden ausgeht,</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">to Him proceeding from both</v>{/if}
|
||||||
|
{#if showLatin}<v lang="la">compar sit laudátio. Amen.</v>{/if}
|
||||||
|
{#if urlLang === 'de'}<v lang="de">sei gleiche Ehre. Amen.</v>{/if}
|
||||||
|
{#if urlLang === 'en'}<v lang="en">let there be equal praise. Amen.</v>{/if}
|
||||||
|
</p>
|
||||||
|
{/snippet}
|
||||||
|
</Prayer>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { browser } from '$app/environment';
|
import { browser } from '$app/environment';
|
||||||
import { do_on_key } from '$lib/components/do_on_key.js'
|
import { do_on_key } from '$lib/components/recipes/do_on_key.js'
|
||||||
import Check from '$lib/assets/icons/Check.svelte'
|
import Check from '$lib/assets/icons/Check.svelte'
|
||||||
|
|
||||||
let {
|
let {
|
||||||
@@ -108,7 +108,6 @@ dialog[open]::backdrop {
|
|||||||
|
|
||||||
dialog h2 {
|
dialog h2 {
|
||||||
font-size: 3rem;
|
font-size: 3rem;
|
||||||
font-family: sans-serif;
|
|
||||||
color: white;
|
color: white;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-top: 30vh;
|
margin-top: 30vh;
|
||||||
@@ -123,7 +122,7 @@ dialog h2 {
|
|||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
max-width: 600px;
|
max-width: 600px;
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
border-radius: 20px;
|
border-radius: var(--radius-card);
|
||||||
background-color: var(--blue);
|
background-color: var(--blue);
|
||||||
color: white;
|
color: white;
|
||||||
box-shadow: 0 0 1em 0.2em rgba(0,0,0,0.3);
|
box-shadow: 0 0 1em 0.2em rgba(0,0,0,0.3);
|
||||||
@@ -141,12 +140,12 @@ dialog h2 {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0.5em 1em;
|
padding: 0.5em 1em;
|
||||||
margin-top: 0.5em;
|
margin-top: 0.5em;
|
||||||
border-radius: 1000px;
|
border-radius: var(--radius-pill);
|
||||||
border: 2px solid var(--nord4);
|
border: 2px solid var(--nord4);
|
||||||
background-color: white;
|
background-color: white;
|
||||||
color: var(--nord0);
|
color: var(--nord0);
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
transition: 100ms;
|
transition: var(--transition-fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
.selector-content select:hover,
|
.selector-content select:hover,
|
||||||
@@ -176,10 +175,10 @@ dialog h2 {
|
|||||||
.button-group button {
|
.button-group button {
|
||||||
padding: 0.75em 2em;
|
padding: 0.75em 2em;
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
border-radius: 1000px;
|
border-radius: var(--radius-pill);
|
||||||
border: none;
|
border: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: 200ms;
|
transition: var(--transition-normal);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import "$lib/css/nordtheme.css";
|
|
||||||
import "$lib/css/shake.css";
|
import "$lib/css/shake.css";
|
||||||
import "$lib/css/icon.css";
|
import "$lib/css/icon.css";
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
@@ -37,6 +36,8 @@ const img_name = $derived(
|
|||||||
const img_alt = $derived(
|
const img_alt = $derived(
|
||||||
recipe.images?.[0]?.alt || recipe.name
|
recipe.images?.[0]?.alt || recipe.name
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const img_color = $derived(recipe.images?.[0]?.color || '');
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
.card-main-link {
|
.card-main-link {
|
||||||
@@ -63,7 +64,6 @@ const img_alt = $derived(
|
|||||||
transition: var(--transition-normal);
|
transition: var(--transition-normal);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-family: sans-serif;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
height: 525px;
|
height: 525px;
|
||||||
width: 300px;
|
width: 300px;
|
||||||
@@ -95,21 +95,16 @@ const img_alt = $derived(
|
|||||||
transition: var(--transition-normal);
|
transition: var(--transition-normal);
|
||||||
border-top-left-radius: inherit;
|
border-top-left-radius: inherit;
|
||||||
border-top-right-radius: inherit;
|
border-top-right-radius: inherit;
|
||||||
|
opacity: 0;
|
||||||
}
|
}
|
||||||
.blur{
|
.image.loaded{
|
||||||
filter: blur(10px);
|
opacity: 1;
|
||||||
}
|
|
||||||
.backdrop_blur{
|
|
||||||
backdrop-filter: blur(10px);
|
|
||||||
}
|
}
|
||||||
.card-image{
|
.card-image{
|
||||||
width: 300px;
|
width: 300px;
|
||||||
height: 255px;
|
height: 255px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-size: cover;
|
|
||||||
background-position: center;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border-top-left-radius: inherit;
|
border-top-left-radius: inherit;
|
||||||
border-top-right-radius: inherit;
|
border-top-right-radius: inherit;
|
||||||
@@ -234,11 +229,11 @@ const img_alt = $derived(
|
|||||||
<a href="{routePrefix}/{recipe.short_name}" class="card-main-link" aria-label="View recipe: {recipe.name}">
|
<a href="{routePrefix}/{recipe.short_name}" class="card-main-link" aria-label="View recipe: {recipe.name}">
|
||||||
<span class="visually-hidden">View recipe: {recipe.name}</span>
|
<span class="visually-hidden">View recipe: {recipe.name}</span>
|
||||||
</a>
|
</a>
|
||||||
<div class="card-image" style="background-image:url(https://bocken.org/static/rezepte/placeholder/{img_name})">
|
<div class="card-image" style:background-color={img_color}>
|
||||||
<noscript>
|
<noscript>
|
||||||
<img class="image backdrop_blur" src="https://bocken.org/static/rezepte/thumb/{img_name}" loading={loading_strat} alt="{img_alt}"/>
|
<img class="image loaded" src="https://bocken.org/static/rezepte/thumb/{img_name}" loading={loading_strat} alt="{img_alt}"/>
|
||||||
</noscript>
|
</noscript>
|
||||||
<img class="image backdrop_blur" class:blur={!isloaded} src={'https://bocken.org/static/rezepte/thumb/' + img_name} loading={loading_strat} alt="{img_alt}" onload={() => isloaded=true}/>
|
<img class="image" class:loaded={isloaded} src={'https://bocken.org/static/rezepte/thumb/' + img_name} loading={loading_strat} alt="{img_alt}" onload={() => isloaded=true}/>
|
||||||
</div>
|
</div>
|
||||||
{#if showFavoriteIndicator && isFavorite}
|
{#if showFavoriteIndicator && isFavorite}
|
||||||
<div class="favorite-indicator">❤️</div>
|
<div class="favorite-indicator">❤️</div>
|
||||||
@@ -130,15 +130,14 @@ function remove_on_enter(event: KeyboardEvent, tag: string) {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
position: relative;
|
position: relative;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-family: sans-serif;
|
|
||||||
width: var(--card-width);
|
width: var(--card-width);
|
||||||
aspect-ratio: 4/7;
|
aspect-ratio: 4/7;
|
||||||
border-radius: 20px;
|
border-radius: var(--radius-card);
|
||||||
background-size: contain;
|
background-size: contain;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: end;
|
justify-content: end;
|
||||||
transition: 200ms;
|
transition: var(--transition-normal);
|
||||||
background-color: var(--blue);
|
background-color: var(--blue);
|
||||||
box-shadow: 0em 0em 2em 0.1em rgba(0, 0, 0, 0.3);
|
box-shadow: 0em 0em 2em 0.1em rgba(0, 0, 0, 0.3);
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
@@ -155,7 +154,7 @@ function remove_on_enter(event: KeyboardEvent, tag: string) {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
border-radius: 20px 20px 0 0 ;
|
border-radius: 20px 20px 0 0 ;
|
||||||
transition: 200ms;
|
transition: var(--transition-normal);
|
||||||
}
|
}
|
||||||
.img_label_wrapper:hover{
|
.img_label_wrapper:hover{
|
||||||
background-color: var(--red);
|
background-color: var(--red);
|
||||||
@@ -169,7 +168,7 @@ function remove_on_enter(event: KeyboardEvent, tag: string) {
|
|||||||
top:0;
|
top:0;
|
||||||
left: 0;
|
left: 0;
|
||||||
border-radius: 20px 20px 0 0;
|
border-radius: 20px 20px 0 0;
|
||||||
transition: 200ms;
|
transition: var(--transition-normal);
|
||||||
}
|
}
|
||||||
.img_label_wrapper:hover .delete{
|
.img_label_wrapper:hover .delete{
|
||||||
opacity: 100%;
|
opacity: 100%;
|
||||||
@@ -178,7 +177,7 @@ function remove_on_enter(event: KeyboardEvent, tag: string) {
|
|||||||
width: 100px;
|
width: 100px;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
fill: white;
|
fill: white;
|
||||||
transition: 200ms;
|
transition: var(--transition-normal);
|
||||||
}
|
}
|
||||||
.delete{
|
.delete{
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@@ -188,7 +187,7 @@ function remove_on_enter(event: KeyboardEvent, tag: string) {
|
|||||||
left: 2rem;
|
left: 2rem;
|
||||||
opacity: 0%;
|
opacity: 0%;
|
||||||
z-index: 4;
|
z-index: 4;
|
||||||
transition:200ms;
|
transition: var(--transition-normal);
|
||||||
}
|
}
|
||||||
.delete:hover{
|
.delete:hover{
|
||||||
transform: scale(1.2, 1.2);
|
transform: scale(1.2, 1.2);
|
||||||
@@ -220,14 +219,14 @@ input::placeholder{
|
|||||||
text-align:center;
|
text-align:center;
|
||||||
width: 2.6rem;
|
width: 2.6rem;
|
||||||
aspect-ratio: 1/1;
|
aspect-ratio: 1/1;
|
||||||
transition: 100ms;
|
transition: var(--transition-fast);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
top:-0.5em;
|
top:-0.5em;
|
||||||
right:-0.5em;
|
right:-0.5em;
|
||||||
padding: 0.25em;
|
padding: 0.25em;
|
||||||
background-color: var(--nord6);
|
background-color: var(--nord6);
|
||||||
border-radius:1000px;
|
border-radius: var(--radius-pill);
|
||||||
box-shadow: 0em 0em 2em 0.1em rgba(0, 0, 0, 0.6);
|
box-shadow: 0em 0em 2em 0.1em rgba(0, 0, 0, 0.6);
|
||||||
}
|
}
|
||||||
.card .icon:hover,
|
.card .icon:hover,
|
||||||
@@ -259,7 +258,7 @@ input::placeholder{
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
transition: 100ms;
|
transition: var(--transition-fast);
|
||||||
}
|
}
|
||||||
.card .name{
|
.card .name{
|
||||||
all: unset;
|
all: unset;
|
||||||
@@ -306,7 +305,7 @@ input::placeholder{
|
|||||||
padding-inline: 1em;
|
padding-inline: 1em;
|
||||||
line-height: 1.5em;
|
line-height: 1.5em;
|
||||||
margin-bottom: 0.5em;
|
margin-bottom: 0.5em;
|
||||||
transition: 100ms;
|
transition: var(--transition-fast);
|
||||||
box-shadow: 0.2em 0.2em 0.2em 0.05em rgba(0, 0, 0, 0.3);
|
box-shadow: 0.2em 0.2em 0.2em 0.05em rgba(0, 0, 0, 0.3);
|
||||||
}
|
}
|
||||||
.card .tag:hover,
|
.card .tag:hover,
|
||||||
@@ -330,8 +329,8 @@ input::placeholder{
|
|||||||
width: 10rem;
|
width: 10rem;
|
||||||
background-color: var(--nord0);
|
background-color: var(--nord0);
|
||||||
padding-inline: 1em;
|
padding-inline: 1em;
|
||||||
border-radius: 1000px;
|
border-radius: var(--radius-pill);
|
||||||
transition: 100ms;
|
transition: var(--transition-fast);
|
||||||
|
|
||||||
}
|
}
|
||||||
.card .title .category:hover,
|
.card .title .category:hover,
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import "$lib/css/nordtheme.css";
|
import TagChip from '$lib/components/recipes/TagChip.svelte';
|
||||||
import TagChip from './TagChip.svelte';
|
|
||||||
|
|
||||||
let {
|
let {
|
||||||
categories = [],
|
categories = [],
|
||||||
@@ -135,7 +134,6 @@
|
|||||||
input {
|
input {
|
||||||
all: unset;
|
all: unset;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-family: sans-serif;
|
|
||||||
background: var(--nord0);
|
background: var(--nord0);
|
||||||
color: var(--nord6);
|
color: var(--nord6);
|
||||||
padding: 0.5rem 0.7rem;
|
padding: 0.5rem 0.7rem;
|
||||||
194
src/lib/components/recipes/CompactCard.svelte
Normal file
194
src/lib/components/recipes/CompactCard.svelte
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import "$lib/css/shake.css";
|
||||||
|
|
||||||
|
let {
|
||||||
|
recipe,
|
||||||
|
current_month = 0,
|
||||||
|
icon_override = false,
|
||||||
|
isFavorite = false,
|
||||||
|
showFavoriteIndicator = false,
|
||||||
|
loading_strat = "lazy",
|
||||||
|
routePrefix = '/rezepte'
|
||||||
|
} = $props();
|
||||||
|
|
||||||
|
const img_name = $derived(
|
||||||
|
recipe.images?.[0]?.mediapath ||
|
||||||
|
`${recipe.germanShortName || recipe.short_name}.webp`
|
||||||
|
);
|
||||||
|
|
||||||
|
const img_alt = $derived(
|
||||||
|
recipe.images?.[0]?.alt || recipe.name
|
||||||
|
);
|
||||||
|
|
||||||
|
const img_color = $derived(recipe.images?.[0]?.color || '');
|
||||||
|
|
||||||
|
const isInSeason = $derived(icon_override || recipe.season?.includes(current_month));
|
||||||
|
|
||||||
|
function activateTransitions(event) {
|
||||||
|
const img = event.currentTarget.querySelector('.img-wrap img');
|
||||||
|
if (img) img.style.viewTransitionName = `recipe-${recipe.short_name}-img`;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.compact-card {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
border-radius: var(--radius-card);
|
||||||
|
overflow: hidden;
|
||||||
|
background: var(--color-surface);
|
||||||
|
box-shadow: 0 1px 4px rgba(0,0,0,0.08);
|
||||||
|
transition: transform var(--transition-normal), box-shadow var(--transition-normal);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.compact-card:hover,
|
||||||
|
.compact-card:focus-within {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
box-shadow: 0 8px 24px rgba(0,0,0,0.12);
|
||||||
|
}
|
||||||
|
.compact-card:hover .img-wrap img {
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
.compact-card:hover .icon,
|
||||||
|
.compact-card:focus-within .icon {
|
||||||
|
animation: shake 0.6s;
|
||||||
|
}
|
||||||
|
.card-link {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
.img-wrap {
|
||||||
|
aspect-ratio: 3 / 2;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.img-wrap img {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
transition: transform 0.4s ease;
|
||||||
|
border-radius: var(--radius-card) var(--radius-card) 0 0;
|
||||||
|
}
|
||||||
|
.info {
|
||||||
|
position: relative;
|
||||||
|
padding: 0.5em 0.6em 0.5em;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
.name {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.3;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
.info {
|
||||||
|
padding: 0.8em 0.9em 0.7em;
|
||||||
|
}
|
||||||
|
.name {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.tags {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.3em;
|
||||||
|
margin-top: 0.5em;
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
.tag {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
padding: 0.1rem 0.4rem;
|
||||||
|
border-radius: var(--radius-pill);
|
||||||
|
background-color: var(--nord5);
|
||||||
|
color: var(--nord3);
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: transform var(--transition-fast), background-color var(--transition-fast), box-shadow var(--transition-fast), color var(--transition-fast);
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
|
border: none;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.tag:hover,
|
||||||
|
.tag:focus-visible {
|
||||||
|
transform: scale(1.05);
|
||||||
|
background-color: var(--nord8);
|
||||||
|
box-shadow: var(--shadow-hover);
|
||||||
|
color: var(--nord0);
|
||||||
|
}
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
.tag {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
padding: 0.15rem 0.55rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.tag,
|
||||||
|
.tag:visited,
|
||||||
|
.tag:link {
|
||||||
|
background-color: var(--nord0);
|
||||||
|
color: var(--nord4);
|
||||||
|
}
|
||||||
|
.tag:hover,
|
||||||
|
.tag:focus-visible {
|
||||||
|
background-color: var(--nord8);
|
||||||
|
color: var(--nord0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
position: absolute;
|
||||||
|
top: -1.2em;
|
||||||
|
right: 0.6em;
|
||||||
|
width: 2em;
|
||||||
|
height: 2em;
|
||||||
|
font-size: 1rem;
|
||||||
|
background-color: var(--nord0);
|
||||||
|
color: white;
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
.icon {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.favorite {
|
||||||
|
position: absolute;
|
||||||
|
top: 0.5em;
|
||||||
|
left: 0.5em;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
filter: drop-shadow(0 0 3px rgba(0,0,0,0.8));
|
||||||
|
z-index: 2;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||||
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||||
|
<div class="compact-card" onclick={activateTransitions}>
|
||||||
|
<a href="{routePrefix}/{recipe.short_name}" class="card-link" aria-label={recipe.name}></a>
|
||||||
|
{#if showFavoriteIndicator && isFavorite}
|
||||||
|
<span class="favorite">❤️</span>
|
||||||
|
{/if}
|
||||||
|
<div class="img-wrap" style:background-color={img_color}>
|
||||||
|
<img
|
||||||
|
src="https://bocken.org/static/rezepte/thumb/{img_name}"
|
||||||
|
alt={img_alt}
|
||||||
|
loading={loading_strat}
|
||||||
|
data-recipe={recipe.short_name}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="info">
|
||||||
|
{#if isInSeason}
|
||||||
|
<a href="{routePrefix}/icon/{recipe.icon}" class="icon g-icon-badge">{recipe.icon}</a>
|
||||||
|
{/if}
|
||||||
|
<p class="name">{@html recipe.name}</p>
|
||||||
|
{#if recipe.tags?.length}
|
||||||
|
<div class="tags">
|
||||||
|
{#each recipe.tags as tag (tag)}
|
||||||
|
<a href="{routePrefix}/tag/{tag}" class="tag">{tag}</a>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -8,9 +8,9 @@ import Check from '$lib/assets/icons/Check.svelte'
|
|||||||
|
|
||||||
import "$lib/css/action_button.css"
|
import "$lib/css/action_button.css"
|
||||||
|
|
||||||
import { do_on_key } from '$lib/components/do_on_key.js'
|
import { do_on_key } from '$lib/components/recipes/do_on_key.js'
|
||||||
import { portions } from '$lib/js/portions_store.js'
|
import { portions } from '$lib/js/portions_store.js'
|
||||||
import BaseRecipeSelector from '$lib/components/BaseRecipeSelector.svelte'
|
import BaseRecipeSelector from '$lib/components/recipes/BaseRecipeSelector.svelte'
|
||||||
|
|
||||||
let portions_local = $state()
|
let portions_local = $state()
|
||||||
portions.subscribe((p) => {
|
portions.subscribe((p) => {
|
||||||
@@ -398,11 +398,11 @@ input.heading{
|
|||||||
padding-inline: 2rem;
|
padding-inline: 2rem;
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-radius: 1000px;
|
border-radius: var(--radius-pill);
|
||||||
color: white;
|
color: white;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
transition: 200ms;
|
transition: var(--transition-normal);
|
||||||
}
|
}
|
||||||
input.heading:hover{
|
input.heading:hover{
|
||||||
background-color: var(--nord1);
|
background-color: var(--nord1);
|
||||||
@@ -412,7 +412,7 @@ input.heading:hover{
|
|||||||
position: relative;
|
position: relative;
|
||||||
width: 300px;
|
width: 300px;
|
||||||
margin-inline: auto;
|
margin-inline: auto;
|
||||||
transition: 200ms;
|
transition: var(--transition-normal);
|
||||||
}
|
}
|
||||||
.heading_wrapper:hover
|
.heading_wrapper:hover
|
||||||
{
|
{
|
||||||
@@ -430,8 +430,8 @@ input.heading:hover{
|
|||||||
position: relative;
|
position: relative;
|
||||||
margin-block: 3rem;
|
margin-block: 3rem;
|
||||||
width: 90%;
|
width: 90%;
|
||||||
border-radius: 20px;
|
border-radius: var(--radius-card);
|
||||||
transition: 200ms;
|
transition: var(--transition-normal);
|
||||||
}
|
}
|
||||||
.shadow{
|
.shadow{
|
||||||
box-shadow: 0 0 1em 0.2em rgba(0,0,0,0.3);
|
box-shadow: 0 0 1em 0.2em rgba(0,0,0,0.3);
|
||||||
@@ -450,14 +450,13 @@ input.heading:hover{
|
|||||||
--font_size: 1.5rem;
|
--font_size: 1.5rem;
|
||||||
top: -1em;
|
top: -1em;
|
||||||
left: -1em;
|
left: -1em;
|
||||||
font-family: sans-serif;
|
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
background-color: var(--nord0);
|
background-color: var(--nord0);
|
||||||
color: var(--nord4);
|
color: var(--nord4);
|
||||||
border-radius: 1000000px;
|
border-radius: 1000000px;
|
||||||
width: 23ch;
|
width: 23ch;
|
||||||
padding: 0.5em 1em;
|
padding: 0.5em 1em;
|
||||||
transition: 100ms;
|
transition: var(--transition-fast);
|
||||||
box-shadow: 0.5em 0.5em 1em 0.4em rgba(0,0,0,0.3);
|
box-shadow: 0.5em 0.5em 1em 0.4em rgba(0,0,0,0.3);
|
||||||
}
|
}
|
||||||
.category:hover{
|
.category:hover{
|
||||||
@@ -471,7 +470,6 @@ input.heading:hover{
|
|||||||
}
|
}
|
||||||
|
|
||||||
.add_ingredient{
|
.add_ingredient{
|
||||||
font-family: sans-serif;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@@ -481,18 +479,18 @@ input.heading:hover{
|
|||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
padding-top: 2.5rem;
|
padding-top: 2.5rem;
|
||||||
border-radius: 20px;
|
border-radius: var(--radius-card);
|
||||||
background-color: var(--blue);
|
background-color: var(--blue);
|
||||||
color: #bbb;
|
color: #bbb;
|
||||||
transition: 200ms;
|
transition: var(--transition-normal);
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
.add_ingredient input{
|
.add_ingredient input{
|
||||||
border: 2px solid var(--nord4);
|
border: 2px solid var(--nord4);
|
||||||
color: var(--nord4);
|
color: var(--nord4);
|
||||||
border-radius: 1000px;
|
border-radius: var(--radius-pill);
|
||||||
padding: 0.5em 1em;
|
padding: 0.5em 1em;
|
||||||
transition: 100ms;
|
transition: var(--transition-fast);
|
||||||
}
|
}
|
||||||
.add_ingredient input:hover,
|
.add_ingredient input:hover,
|
||||||
.add_ingredient input:focus-visible
|
.add_ingredient input:focus-visible
|
||||||
@@ -537,7 +535,6 @@ dialog .adder{
|
|||||||
}
|
}
|
||||||
dialog h2{
|
dialog h2{
|
||||||
font-size: 3rem;
|
font-size: 3rem;
|
||||||
font-family: sans-serif;
|
|
||||||
color: white;
|
color: white;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-top: 30vh;
|
margin-top: 30vh;
|
||||||
@@ -569,7 +566,7 @@ dialog h2{
|
|||||||
border: none;
|
border: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
transition: 200ms;
|
transition: var(--transition-normal);
|
||||||
}
|
}
|
||||||
.move_buttons_container button:hover{
|
.move_buttons_container button:hover{
|
||||||
scale: 1.4;
|
scale: 1.4;
|
||||||
@@ -611,10 +608,10 @@ h3{
|
|||||||
}
|
}
|
||||||
.list_wrapper p[contenteditable]{
|
.list_wrapper p[contenteditable]{
|
||||||
border: 2px solid grey;
|
border: 2px solid grey;
|
||||||
border-radius: 1000px;
|
border-radius: var(--radius-pill);
|
||||||
padding: 0.25em 1em;
|
padding: 0.25em 1em;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
transition: 200ms;
|
transition: var(--transition-normal);
|
||||||
}
|
}
|
||||||
.list_wrapper p[contenteditable]:hover,
|
.list_wrapper p[contenteditable]:hover,
|
||||||
.list_wrapper p[contenteditable]:focus-within{
|
.list_wrapper p[contenteditable]:focus-within{
|
||||||
@@ -703,12 +700,12 @@ h3{
|
|||||||
margin-block: 1rem;
|
margin-block: 1rem;
|
||||||
padding: 1em 2em;
|
padding: 1em 2em;
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
border-radius: 1000px;
|
border-radius: var(--radius-pill);
|
||||||
background-color: var(--nord9);
|
background-color: var(--nord9);
|
||||||
color: white;
|
color: white;
|
||||||
border: none;
|
border: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: 200ms;
|
transition: var(--transition-normal);
|
||||||
box-shadow: 0 0 0.5em 0.1em rgba(0,0,0,0.2);
|
box-shadow: 0 0 0.5em 0.1em rgba(0,0,0,0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5,11 +5,10 @@ import Cross from '$lib/assets/icons/Cross.svelte'
|
|||||||
import Plus from '$lib/assets/icons/Plus.svelte'
|
import Plus from '$lib/assets/icons/Plus.svelte'
|
||||||
import Check from '$lib/assets/icons/Check.svelte'
|
import Check from '$lib/assets/icons/Check.svelte'
|
||||||
|
|
||||||
import '$lib/css/nordtheme.css'
|
|
||||||
import "$lib/css/action_button.css"
|
import "$lib/css/action_button.css"
|
||||||
|
|
||||||
import { do_on_key } from '$lib/components/do_on_key.js'
|
import { do_on_key } from '$lib/components/recipes/do_on_key.js'
|
||||||
import BaseRecipeSelector from '$lib/components/BaseRecipeSelector.svelte'
|
import BaseRecipeSelector from '$lib/components/recipes/BaseRecipeSelector.svelte'
|
||||||
|
|
||||||
let { lang = 'de' as 'de' | 'en', instructions = $bindable(), add_info = $bindable() } = $props<{ lang?: 'de' | 'en', instructions: any, add_info: any }>();
|
let { lang = 'de' as 'de' | 'en', instructions = $bindable(), add_info = $bindable() } = $props<{ lang?: 'de' | 'en', instructions: any, add_info: any }>();
|
||||||
|
|
||||||
@@ -402,7 +401,7 @@ export function update_step_position(list_index, step_index, direction){
|
|||||||
border: none;
|
border: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
transition: 200ms;
|
transition: var(--transition-normal);
|
||||||
}
|
}
|
||||||
.move_buttons_container button:hover{
|
.move_buttons_container button:hover{
|
||||||
scale: 1.4;
|
scale: 1.4;
|
||||||
@@ -441,11 +440,11 @@ input.heading{
|
|||||||
padding-inline: 2rem;
|
padding-inline: 2rem;
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-radius: 1000px;
|
border-radius: var(--radius-pill);
|
||||||
color: white;
|
color: white;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
transition: 200ms;
|
transition: var(--transition-normal);
|
||||||
}
|
}
|
||||||
input.heading:hover,
|
input.heading:hover,
|
||||||
input.heading:focus-visible
|
input.heading:focus-visible
|
||||||
@@ -457,7 +456,7 @@ input.heading:focus-visible
|
|||||||
position: relative;
|
position: relative;
|
||||||
width: min(300px, 95dvw);
|
width: min(300px, 95dvw);
|
||||||
margin-inline: auto;
|
margin-inline: auto;
|
||||||
transition: 200ms;
|
transition: var(--transition-normal);
|
||||||
}
|
}
|
||||||
.heading_wrapper:hover,
|
.heading_wrapper:hover,
|
||||||
.heading_wrapper:focus-visible
|
.heading_wrapper:focus-visible
|
||||||
@@ -475,8 +474,8 @@ input.heading:focus-visible
|
|||||||
position: relative;
|
position: relative;
|
||||||
margin-block: 3rem;
|
margin-block: 3rem;
|
||||||
width: 90%;
|
width: 90%;
|
||||||
border-radius: 20px;
|
border-radius: var(--radius-card);
|
||||||
transition: 200ms;
|
transition: var(--transition-normal);
|
||||||
background-color: var(--blue);
|
background-color: var(--blue);
|
||||||
padding: 1.5rem 2rem;
|
padding: 1.5rem 2rem;
|
||||||
}
|
}
|
||||||
@@ -497,14 +496,13 @@ dialog .adder{
|
|||||||
--font_size: 1.5rem;
|
--font_size: 1.5rem;
|
||||||
top: -1em;
|
top: -1em;
|
||||||
left: -1em;
|
left: -1em;
|
||||||
font-family: sans-serif;
|
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
background-color: var(--nord0);
|
background-color: var(--nord0);
|
||||||
color: var(--nord4);
|
color: var(--nord4);
|
||||||
border-radius: 1000000px;
|
border-radius: 1000000px;
|
||||||
width: 23ch;
|
width: 23ch;
|
||||||
padding: 0.5em 1em;
|
padding: 0.5em 1em;
|
||||||
transition: 100ms;
|
transition: var(--transition-fast);
|
||||||
box-shadow: 0.5em 0.5em 1em 0.4em rgba(0,0,0,0.3);
|
box-shadow: 0.5em 0.5em 1em 0.4em rgba(0,0,0,0.3);
|
||||||
}
|
}
|
||||||
.category:hover,
|
.category:hover,
|
||||||
@@ -520,15 +518,14 @@ dialog .adder{
|
|||||||
}
|
}
|
||||||
|
|
||||||
.add_step p{
|
.add_step p{
|
||||||
font-family: sans-serif;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
border-radius: 20px;
|
border-radius: var(--radius-card);
|
||||||
border: 2px solid var(--nord4);
|
border: 2px solid var(--nord4);
|
||||||
border-radius: 30px;
|
border-radius: 30px;
|
||||||
padding: 0.5em 1em;
|
padding: 0.5em 1em;
|
||||||
color: var(--nord4);
|
color: var(--nord4);
|
||||||
transition: 100ms;
|
transition: var(--transition-fast);
|
||||||
}
|
}
|
||||||
.add_step p:hover,
|
.add_step p:hover,
|
||||||
.add_step p:focus-visible
|
.add_step p:focus-visible
|
||||||
@@ -544,14 +541,13 @@ dialog{
|
|||||||
background-color: rgba(255,255,255, 0.001);
|
background-color: rgba(255,255,255, 0.001);
|
||||||
border: unset;
|
border: unset;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
transition: 200ms;
|
transition: var(--transition-normal);
|
||||||
}
|
}
|
||||||
dialog .adder{
|
dialog .adder{
|
||||||
margin-top: 5rem;
|
margin-top: 5rem;
|
||||||
}
|
}
|
||||||
dialog h2{
|
dialog h2{
|
||||||
font-size: 3rem;
|
font-size: 3rem;
|
||||||
font-family: sans-serif;
|
|
||||||
color: white;
|
color: white;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-top: 30vh;
|
margin-top: 30vh;
|
||||||
@@ -648,10 +644,10 @@ h3{
|
|||||||
display: inline;
|
display: inline;
|
||||||
padding: 0.25em 1em;
|
padding: 0.25em 1em;
|
||||||
border: 2px solid grey;
|
border: 2px solid grey;
|
||||||
border-radius: 1000px;
|
border-radius: var(--radius-pill);
|
||||||
}
|
}
|
||||||
.additional_info div:has(p[contenteditable]){
|
.additional_info div:has(p[contenteditable]){
|
||||||
transition: 200ms;
|
transition: var(--transition-normal);
|
||||||
display: inline;
|
display: inline;
|
||||||
}
|
}
|
||||||
.additional_info div:has(p[contenteditable]):hover,
|
.additional_info div:has(p[contenteditable]):hover,
|
||||||
@@ -731,12 +727,12 @@ h3{
|
|||||||
margin-block: 1rem;
|
margin-block: 1rem;
|
||||||
padding: 1em 2em;
|
padding: 1em 2em;
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
border-radius: 1000px;
|
border-radius: var(--radius-pill);
|
||||||
background-color: var(--nord9);
|
background-color: var(--nord9);
|
||||||
color: white;
|
color: white;
|
||||||
border: none;
|
border: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: 200ms;
|
transition: var(--transition-normal);
|
||||||
box-shadow: 0 0 0.5em 0.1em rgba(0,0,0,0.2);
|
box-shadow: 0 0 0.5em 0.1em rgba(0,0,0,0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,7 +25,6 @@ textarea {
|
|||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
margin-top: 0.5em;
|
margin-top: 0.5em;
|
||||||
font-family: sans-serif;
|
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
textarea::placeholder {
|
textarea::placeholder {
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import "$lib/css/nordtheme.css";
|
import Toggle from '$lib/components/Toggle.svelte';
|
||||||
import Toggle from './Toggle.svelte';
|
|
||||||
|
|
||||||
let {
|
let {
|
||||||
enabled = false,
|
enabled = false,
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
<script>
|
<script>
|
||||||
import "$lib/css/nordtheme.css";
|
|
||||||
import CategoryFilter from './CategoryFilter.svelte';
|
import CategoryFilter from './CategoryFilter.svelte';
|
||||||
import TagFilter from './TagFilter.svelte';
|
import TagFilter from './TagFilter.svelte';
|
||||||
import IconFilter from './IconFilter.svelte';
|
import IconFilter from './IconFilter.svelte';
|
||||||
@@ -44,7 +43,7 @@
|
|||||||
<style>
|
<style>
|
||||||
.filter-wrapper {
|
.filter-wrapper {
|
||||||
width: 900px;
|
width: 900px;
|
||||||
max-width: 95vw;
|
max-width: 80vw;
|
||||||
margin: 1rem auto 2rem;
|
margin: 1rem auto 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,16 +1,15 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import '$lib/css/nordtheme.css';
|
|
||||||
import "$lib/css/shake.css"
|
import "$lib/css/shake.css"
|
||||||
let { icon, ...restProps } = $props<{ icon: string, [key: string]: any }>();
|
let { icon, ...restProps } = $props<{ icon: string, [key: string]: any }>();
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
a{
|
a{
|
||||||
font-family: "Noto Color Emoji", emoji;
|
font-family: "Noto Color Emoji", "Noto Color Emoji Subset", emoji;
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
background-color: var(--nord4);
|
background-color: var(--nord4);
|
||||||
border-radius: 1000px;
|
border-radius: var(--radius-pill);
|
||||||
box-shadow: 0em 0em 0.5em 0.2em rgba(0, 0, 0, 0.2);
|
box-shadow: 0em 0em 0.5em 0.2em rgba(0, 0, 0, 0.2);
|
||||||
}
|
}
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import "$lib/css/nordtheme.css";
|
import TagChip from '$lib/components/recipes/TagChip.svelte';
|
||||||
import TagChip from './TagChip.svelte';
|
|
||||||
|
|
||||||
let {
|
let {
|
||||||
availableIcons = [],
|
availableIcons = [],
|
||||||
@@ -127,7 +126,7 @@
|
|||||||
input {
|
input {
|
||||||
all: unset;
|
all: unset;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-family: "Noto Color Emoji", emoji, sans-serif;
|
font-family: "Noto Color Emoji", "Noto Color Emoji Subset", emoji, sans-serif;
|
||||||
background: var(--nord0);
|
background: var(--nord0);
|
||||||
color: var(--nord6);
|
color: var(--nord6);
|
||||||
padding: 0.5rem 0.7rem;
|
padding: 0.5rem 0.7rem;
|
||||||
@@ -147,7 +146,6 @@
|
|||||||
|
|
||||||
input::placeholder {
|
input::placeholder {
|
||||||
color: var(--nord4);
|
color: var(--nord4);
|
||||||
font-family: sans-serif;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input:hover {
|
input:hover {
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Snippet } from 'svelte';
|
import type { Snippet } from 'svelte';
|
||||||
import '$lib/css/nordtheme.css';
|
import Recipes from '$lib/components/recipes/Recipes.svelte';
|
||||||
import Recipes from '$lib/components/Recipes.svelte';
|
|
||||||
import Search from './Search.svelte';
|
import Search from './Search.svelte';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
@@ -27,12 +26,12 @@
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
a{
|
a{
|
||||||
font-family: "Noto Color Emoji", emoji, sans-serif;
|
font-family: "Noto Color Emoji", "Noto Color Emoji Subset", emoji, sans-serif;
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
background-color: var(--nord4);
|
background-color: var(--nord4);
|
||||||
border-radius: 1000px;
|
border-radius: var(--radius-pill);
|
||||||
box-shadow: 0em 0em 0.5em 0.2em rgba(0, 0, 0, 0.2);
|
box-shadow: 0em 0em 0.5em 0.2em rgba(0, 0, 0, 0.2);
|
||||||
}
|
}
|
||||||
a:hover,
|
a:hover,
|
||||||
@@ -4,8 +4,6 @@ import { onNavigate } from "$app/navigation";
|
|||||||
import { browser } from '$app/environment';
|
import { browser } from '$app/environment';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
import HefeSwapper from './HefeSwapper.svelte';
|
import HefeSwapper from './HefeSwapper.svelte';
|
||||||
import '$lib/css/recipe-links.css';
|
|
||||||
|
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
|
|
||||||
// Helper function to multiply numbers in ingredient amounts
|
// Helper function to multiply numbers in ingredient amounts
|
||||||
@@ -310,9 +308,6 @@ function adjust_amount(string, multiplier){
|
|||||||
// No need for complex yeast toggle handling - everything is calculated server-side now
|
// No need for complex yeast toggle handling - everything is calculated server-side now
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
*{
|
|
||||||
font-family: sans-serif;
|
|
||||||
}
|
|
||||||
.ingredients{
|
.ingredients{
|
||||||
flex-basis: 0;
|
flex-basis: 0;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
<script>
|
<script>
|
||||||
import '$lib/css/recipe-links.css';
|
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
|
|
||||||
let multiplier = $state(data.multiplier || 1);
|
let multiplier = $state(data.multiplier || 1);
|
||||||
@@ -101,9 +100,6 @@ const labels = $derived({
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
*{
|
|
||||||
font-family: sans-serif;
|
|
||||||
}
|
|
||||||
ol li::marker{
|
ol li::marker{
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: var(--blue);
|
color: var(--blue);
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
<script>
|
<script>
|
||||||
import "$lib/css/nordtheme.css";
|
|
||||||
|
|
||||||
let {
|
let {
|
||||||
useAndLogic = true,
|
useAndLogic = true,
|
||||||
@@ -42,7 +41,7 @@
|
|||||||
|
|
||||||
.filter-label {
|
.filter-label {
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
color: var(--nord2);
|
color: var(--nord1);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
margin-bottom: 0.25rem;
|
margin-bottom: 0.25rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -66,7 +65,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
color: var(--nord4);
|
color: var(--nord3);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +86,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.toggle-switch.or-mode {
|
.toggle-switch.or-mode {
|
||||||
background: var(--nord13);
|
background: var(--nord12);
|
||||||
}
|
}
|
||||||
|
|
||||||
.toggle-knob {
|
.toggle-knob {
|
||||||
@@ -122,7 +121,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.toggle-switch.or-mode + .mode-label.or {
|
.toggle-switch.or-mode + .mode-label.or {
|
||||||
color: var(--nord13);
|
color: var(--nord12);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Snippet } from 'svelte';
|
import type { Snippet } from 'svelte';
|
||||||
import "$lib/css/nordtheme.css"
|
|
||||||
let { title = '', children } = $props<{ title?: string, children?: Snippet }>();
|
let { title = '', children } = $props<{ title?: string, children?: Snippet }>();
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import CardAdd from '$lib/components/CardAdd.svelte';
|
import CardAdd from '$lib/components/recipes/CardAdd.svelte';
|
||||||
import MediaScroller from '$lib/components/MediaScroller.svelte';
|
import MediaScroller from '$lib/components/recipes/MediaScroller.svelte';
|
||||||
import Card from '$lib/components/Card.svelte';
|
import Search from '$lib/components/recipes/Search.svelte';
|
||||||
import Search from '$lib/components/Search.svelte';
|
import SeasonSelect from '$lib/components/recipes/SeasonSelect.svelte';
|
||||||
import SeasonSelect from '$lib/components/SeasonSelect.svelte';
|
import CreateIngredientList from '$lib/components/recipes/CreateIngredientList.svelte';
|
||||||
import CreateIngredientList from '$lib/components/CreateIngredientList.svelte';
|
import CreateStepList from '$lib/components/recipes/CreateStepList.svelte';
|
||||||
import CreateStepList from '$lib/components/CreateStepList.svelte';
|
|
||||||
|
|
||||||
let {
|
let {
|
||||||
card_data = $bindable({}),
|
card_data = $bindable({}),
|
||||||
@@ -59,7 +58,7 @@ input.temp{
|
|||||||
display: block;
|
display: block;
|
||||||
margin: 1rem auto;
|
margin: 1rem auto;
|
||||||
padding: 0.2em 1em;
|
padding: 0.2em 1em;
|
||||||
border-radius: 1000px;
|
border-radius: var(--radius-pill);
|
||||||
background-color: var(--nord4);
|
background-color: var(--nord4);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import {onMount} from "svelte";
|
import {onMount} from "svelte";
|
||||||
import { browser } from '$app/environment';
|
import { browser } from '$app/environment';
|
||||||
import "$lib/css/nordtheme.css";
|
|
||||||
import FilterPanel from './FilterPanel.svelte';
|
import FilterPanel from './FilterPanel.svelte';
|
||||||
import { getCategories } from '$lib/js/categories';
|
import { getCategories } from '$lib/js/categories';
|
||||||
|
|
||||||
@@ -264,7 +263,7 @@
|
|||||||
$effect(() => {
|
$effect(() => {
|
||||||
const loadFilterData = async () => {
|
const loadFilterData = async () => {
|
||||||
try {
|
try {
|
||||||
const apiBase = isEnglish ? '/api/recipes' : '/api/rezepte';
|
const apiBase = `/api/${isEnglish ? 'recipes' : 'rezepte'}`;
|
||||||
const [tagsRes, iconsRes] = await Promise.all([
|
const [tagsRes, iconsRes] = await Promise.all([
|
||||||
fetch(`${apiBase}/items/tag`),
|
fetch(`${apiBase}/items/tag`),
|
||||||
fetch('/api/rezepte/items/icon')
|
fetch('/api/rezepte/items/icon')
|
||||||
@@ -308,11 +307,10 @@
|
|||||||
input#search {
|
input#search {
|
||||||
all: unset;
|
all: unset;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-family: sans-serif;
|
|
||||||
background: var(--nord0);
|
background: var(--nord0);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
padding: 0.7rem 2rem;
|
padding: 0.7rem 2rem;
|
||||||
border-radius: 1000px;
|
border-radius: var(--radius-pill);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
input::placeholder{
|
input::placeholder{
|
||||||
@@ -320,15 +318,15 @@ input::placeholder{
|
|||||||
}
|
}
|
||||||
|
|
||||||
.search {
|
.search {
|
||||||
width: 500px;
|
width: 560px;
|
||||||
max-width: 85vw;
|
max-width: 88vw;
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 2.5rem auto 1.2rem;
|
margin: 0 auto;
|
||||||
font-size: 1.6rem;
|
font-size: 1.6rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
transition: 100ms;
|
transition: var(--transition-fast);
|
||||||
filter: drop-shadow(0.4em 0.5em 0.4em rgba(0,0,0,0.4))
|
filter: drop-shadow(0 4px 12px rgba(0,0,0,0.25));
|
||||||
}
|
}
|
||||||
|
|
||||||
.search:hover,
|
.search:hover,
|
||||||
@@ -362,6 +360,20 @@ scale: 0.8 0.8;
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
/* Reserves space for FilterPanel before JS hydrates, preventing layout shift. */
|
||||||
|
.filter-placeholder {
|
||||||
|
display: block;
|
||||||
|
width: 900px;
|
||||||
|
max-width: 95vw;
|
||||||
|
margin: 1rem auto 2rem;
|
||||||
|
height: 3.85rem;
|
||||||
|
}
|
||||||
|
@media (max-width: 968px) {
|
||||||
|
.filter-placeholder {
|
||||||
|
width: auto;
|
||||||
|
height: calc(2.05rem + 2px);
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<form class="search" method="get" action={buildSearchUrl('')} onsubmit={(e) => { e.preventDefault(); handleSubmit(e); }}>
|
<form class="search" method="get" action={buildSearchUrl('')} onsubmit={(e) => { e.preventDefault(); handleSubmit(e); }}>
|
||||||
{#if selectedCategory}<input type="hidden" name="category" value={selectedCategory} />{/if}
|
{#if selectedCategory}<input type="hidden" name="category" value={selectedCategory} />{/if}
|
||||||
@@ -408,4 +420,6 @@ scale: 0.8 0.8;
|
|||||||
onFavoritesToggle={handleFavoritesToggle}
|
onFavoritesToggle={handleFavoritesToggle}
|
||||||
onLogicModeToggle={handleLogicModeToggle}
|
onLogicModeToggle={handleLogicModeToggle}
|
||||||
/>
|
/>
|
||||||
|
{:else}
|
||||||
|
<div class="filter-placeholder"></div>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import "$lib/css/nordtheme.css";
|
import TagChip from '$lib/components/recipes/TagChip.svelte';
|
||||||
import TagChip from './TagChip.svelte';
|
|
||||||
|
|
||||||
let {
|
let {
|
||||||
selectedSeasons = [],
|
selectedSeasons = [],
|
||||||
@@ -121,7 +120,6 @@
|
|||||||
input {
|
input {
|
||||||
all: unset;
|
all: unset;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-family: sans-serif;
|
|
||||||
background: var(--nord0);
|
background: var(--nord0);
|
||||||
color: var(--nord6);
|
color: var(--nord6);
|
||||||
padding: 0.5rem 0.7rem;
|
padding: 0.5rem 0.7rem;
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Snippet } from 'svelte';
|
import type { Snippet } from 'svelte';
|
||||||
import '$lib/css/nordtheme.css';
|
import Recipes from '$lib/components/recipes/Recipes.svelte';
|
||||||
import Recipes from '$lib/components/Recipes.svelte';
|
|
||||||
import Search from './Search.svelte';
|
import Search from './Search.svelte';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
@@ -29,12 +28,11 @@
|
|||||||
<style>
|
<style>
|
||||||
a.month{
|
a.month{
|
||||||
text-decoration: unset;
|
text-decoration: unset;
|
||||||
font-family: sans-serif;
|
border-radius: var(--radius-pill);
|
||||||
border-radius: 1000px;
|
|
||||||
background-color: var(--blue);
|
background-color: var(--blue);
|
||||||
color: var(--nord5);
|
color: var(--nord5);
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
transition: 100ms;
|
transition: var(--transition-fast);
|
||||||
min-width: 4em;
|
min-width: 4em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
<script lang=ts>
|
<script lang=ts>
|
||||||
import "$lib/css/nordtheme.css"
|
|
||||||
import { season } from '$lib/js/season_store.js'
|
import { season } from '$lib/js/season_store.js'
|
||||||
import {onMount} from "svelte";
|
import {onMount} from "svelte";
|
||||||
import {do_on_key} from "./do_on_key";
|
import {do_on_key} from "./do_on_key";
|
||||||
@@ -46,15 +45,15 @@ label{
|
|||||||
padding: 0.25em 1em;
|
padding: 0.25em 1em;
|
||||||
margin-inline: 0.1em;
|
margin-inline: 0.1em;
|
||||||
line-height: 2em;
|
line-height: 2em;
|
||||||
border-radius: 1000px;
|
border-radius: var(--radius-pill);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
position: relative;
|
position: relative;
|
||||||
transition: 100ms;
|
transition: var(--transition-fast);
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkbox_container{
|
.checkbox_container{
|
||||||
transition: 100ms;
|
transition: var(--transition-fast);
|
||||||
}
|
}
|
||||||
.checkbox_container:hover,
|
.checkbox_container:hover,
|
||||||
.checkbox_container:focus-within
|
.checkbox_container:focus-within
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
<script>
|
<script>
|
||||||
import "$lib/css/nordtheme.css";
|
|
||||||
|
|
||||||
let {
|
let {
|
||||||
tag = '',
|
tag = '',
|
||||||
@@ -17,7 +16,7 @@
|
|||||||
.tag-chip {
|
.tag-chip {
|
||||||
all: unset;
|
all: unset;
|
||||||
padding: 0.4rem 0.8rem;
|
padding: 0.4rem 0.8rem;
|
||||||
border-radius: 1000px;
|
border-radius: var(--radius-pill);
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 100ms ease;
|
transition: all 100ms ease;
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import "$lib/css/nordtheme.css";
|
import TagChip from '$lib/components/recipes/TagChip.svelte';
|
||||||
import TagChip from './TagChip.svelte';
|
|
||||||
|
|
||||||
let {
|
let {
|
||||||
availableTags = [],
|
availableTags = [],
|
||||||
@@ -118,7 +117,6 @@
|
|||||||
input {
|
input {
|
||||||
all: unset;
|
all: unset;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-family: sans-serif;
|
|
||||||
background: var(--nord0);
|
background: var(--nord0);
|
||||||
color: var(--nord6);
|
color: var(--nord6);
|
||||||
padding: 0.5rem 0.7rem;
|
padding: 0.5rem 0.7rem;
|
||||||
@@ -1,16 +1,11 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
|
|
||||||
let { src, placeholder_src, alt = "", children } = $props();
|
let { src, color = '', alt = "", transitionName = '', children } = $props();
|
||||||
|
|
||||||
let isloaded = $state(false);
|
|
||||||
let isredirected = $state(false);
|
let isredirected = $state(false);
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
const el = document.querySelector("img")
|
|
||||||
if(el?.complete){
|
|
||||||
isloaded = true
|
|
||||||
}
|
|
||||||
fetch(src, { method: 'HEAD' })
|
fetch(src, { method: 'HEAD' })
|
||||||
.then(response => {
|
.then(response => {
|
||||||
isredirected = response.redirected
|
isredirected = response.redirected
|
||||||
@@ -21,17 +16,15 @@
|
|||||||
if(isredirected){
|
if(isredirected){
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if(document.querySelector("img").complete){
|
|
||||||
document.querySelector("#img_carousel").showModal();
|
document.querySelector("#img_carousel").showModal();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
function close_dialog_img(){
|
function close_dialog_img(){
|
||||||
document.querySelector("#img_carousel").close();
|
document.querySelector("#img_carousel").close();
|
||||||
}
|
}
|
||||||
import Cross from "$lib/assets/icons/Cross.svelte";
|
import Cross from "$lib/assets/icons/Cross.svelte";
|
||||||
import "$lib/css/action_button.css";
|
import "$lib/css/action_button.css";
|
||||||
import "$lib/css/shake.css";
|
import "$lib/css/shake.css";
|
||||||
import { do_on_key } from "./do_on_key";
|
import { do_on_key } from "$lib/components/recipes/do_on_key";
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
@@ -79,21 +72,25 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.image-wrap {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
margin-inline: auto;
|
||||||
|
width: min(1000px, 100dvw);
|
||||||
|
height: max(60dvh,600px);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
.image{
|
.image{
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
width: min(1000px, 100dvw);
|
width: min(1000px, 100dvw);
|
||||||
z-index: -1;
|
|
||||||
opacity: 0;
|
|
||||||
transition: 200ms;
|
|
||||||
height: max(60dvh,600px);
|
height: max(60dvh,600px);
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
object-position: 50% 20%;
|
object-position: 50% 20%;
|
||||||
backdrop-filter: blur(20px);
|
|
||||||
filter: blur(20px);
|
|
||||||
z-index: -10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.image-container::after {
|
.image-container::after {
|
||||||
@@ -106,34 +103,6 @@
|
|||||||
:global(h1){
|
:global(h1){
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
.placeholder{
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-size: cover;
|
|
||||||
background-position: 50% 20%;
|
|
||||||
position: absolute;
|
|
||||||
width: min(1000px, 100dvw);
|
|
||||||
height: max(60dvh,600px);
|
|
||||||
z-index: -2;
|
|
||||||
}
|
|
||||||
.placeholder_blur{
|
|
||||||
width: inherit;
|
|
||||||
height: inherit;
|
|
||||||
backdrop-filter: blur(20px);
|
|
||||||
}
|
|
||||||
div:has(.placeholder){
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
margin-inline: auto;
|
|
||||||
width: min(1000px, 100dvw);
|
|
||||||
height: max(60dvh,600px);
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.unblur.image{
|
|
||||||
filter: blur(0px) !important;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* DIALOG */
|
/* DIALOG */
|
||||||
dialog{
|
dialog{
|
||||||
@@ -174,15 +143,13 @@ dialog button{
|
|||||||
<figure class="image-container">
|
<figure class="image-container">
|
||||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||||
<div class:zoom-in={isloaded && !isredirected} onclick={show_dialog_img}>
|
<div class:zoom-in={!isredirected} onclick={show_dialog_img}>
|
||||||
<div class=placeholder style="background-image:url({placeholder_src})" >
|
<div class="image-wrap" style:background-color={color}>
|
||||||
<div class=placeholder_blur>
|
<img class="image" {src} {alt} style:view-transition-name={transitionName || null}/>
|
||||||
<img class="image" class:unblur={isloaded} {src} onload={() => {isloaded=true}} {alt}/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<noscript>
|
<noscript>
|
||||||
<div class=placeholder style="background-image:url({placeholder_src})" >
|
<div class="image-wrap" style:background-color={color}>
|
||||||
<img class="image unblur" {src} onload={() => {isloaded=true}} {alt}/>
|
<img class="image" {src} {alt}/>
|
||||||
</div>
|
</div>
|
||||||
</noscript>
|
</noscript>
|
||||||
</div>
|
</div>
|
||||||
@@ -191,7 +158,7 @@ dialog button{
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<dialog id=img_carousel>
|
<dialog id=img_carousel>
|
||||||
<img class:unblur={isloaded} {src} {alt}>
|
<img {src} {alt}>
|
||||||
<button class=action_button onkeydown={(event) => do_on_key(event, 'Enter', false, close_dialog_img)} onclick={close_dialog_img}>
|
<button class=action_button onkeydown={(event) => do_on_key(event, 'Enter', false, close_dialog_img)} onclick={close_dialog_img}>
|
||||||
<Cross fill=white width=2rem height=2rem></Cross>
|
<Cross fill=white width=2rem height=2rem></Cross>
|
||||||
</button>
|
</button>
|
||||||
162
src/lib/components/recipes/ToTryCard.svelte
Normal file
162
src/lib/components/recipes/ToTryCard.svelte
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
<script>
|
||||||
|
let { item, ondelete, onedit, isEnglish = false } = $props();
|
||||||
|
|
||||||
|
function getDomain(url) {
|
||||||
|
try {
|
||||||
|
return new URL(url).hostname.replace(/^www\./, '');
|
||||||
|
} catch {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.card {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
border-radius: var(--radius-card);
|
||||||
|
overflow: hidden;
|
||||||
|
background: var(--color-surface);
|
||||||
|
box-shadow: 0 1px 4px rgba(0,0,0,0.08);
|
||||||
|
transition: transform var(--transition-normal), box-shadow var(--transition-normal);
|
||||||
|
}
|
||||||
|
.card:hover,
|
||||||
|
.card:focus-within {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
box-shadow: 0 8px 24px rgba(0,0,0,0.12);
|
||||||
|
}
|
||||||
|
.accent {
|
||||||
|
height: 6px;
|
||||||
|
background: linear-gradient(90deg, var(--nord10), var(--nord9));
|
||||||
|
}
|
||||||
|
.body {
|
||||||
|
padding: 0.8em 0.9em 0.6em;
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5em;
|
||||||
|
}
|
||||||
|
.name {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.3;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.links {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.35em;
|
||||||
|
}
|
||||||
|
.link-pill {
|
||||||
|
font-size: 0.78rem;
|
||||||
|
padding: 0.15rem 0.55rem;
|
||||||
|
border-radius: var(--radius-pill);
|
||||||
|
background-color: var(--nord5);
|
||||||
|
color: var(--nord3);
|
||||||
|
text-decoration: none;
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
|
transition: transform var(--transition-fast), background-color var(--transition-fast), box-shadow var(--transition-fast), color var(--transition-fast);
|
||||||
|
}
|
||||||
|
.link-pill:hover,
|
||||||
|
.link-pill:focus-visible {
|
||||||
|
transform: scale(1.05);
|
||||||
|
background-color: var(--nord8);
|
||||||
|
box-shadow: var(--shadow-hover);
|
||||||
|
color: var(--nord0);
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.link-pill {
|
||||||
|
background-color: var(--nord0);
|
||||||
|
color: var(--nord4);
|
||||||
|
}
|
||||||
|
.link-pill:hover,
|
||||||
|
.link-pill:focus-visible {
|
||||||
|
background-color: var(--nord8);
|
||||||
|
color: var(--nord0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.notes {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: var(--nord3);
|
||||||
|
margin: 0;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 3;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.notes {
|
||||||
|
color: var(--nord4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
font-size: 0.72rem;
|
||||||
|
color: var(--nord3);
|
||||||
|
margin-top: auto;
|
||||||
|
padding-top: 0.3em;
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.footer {
|
||||||
|
color: var(--nord4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.card-btn {
|
||||||
|
position: absolute;
|
||||||
|
top: 0.5em;
|
||||||
|
background: var(--nord11);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: var(--radius-pill);
|
||||||
|
width: 1.6em;
|
||||||
|
height: 1.6em;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
cursor: pointer;
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity var(--transition-fast);
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
.card:hover .card-btn,
|
||||||
|
.card:focus-within .card-btn {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.delete-btn {
|
||||||
|
right: 0.5em;
|
||||||
|
}
|
||||||
|
.delete-btn:hover {
|
||||||
|
background: var(--nord12);
|
||||||
|
}
|
||||||
|
.edit-btn {
|
||||||
|
right: 2.4em;
|
||||||
|
background: var(--nord10);
|
||||||
|
}
|
||||||
|
.edit-btn:hover {
|
||||||
|
background: var(--nord9);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="accent"></div>
|
||||||
|
<button class="card-btn edit-btn" onclick={() => onedit(item)} aria-label={isEnglish ? 'Edit' : 'Bearbeiten'}>✎</button>
|
||||||
|
<button class="card-btn delete-btn" onclick={() => ondelete(item._id)} aria-label={isEnglish ? 'Delete' : 'Löschen'}>✕</button>
|
||||||
|
<div class="body">
|
||||||
|
<p class="name">{item.name}</p>
|
||||||
|
{#if item.links?.length}
|
||||||
|
<div class="links">
|
||||||
|
{#each item.links as link (link.url)}
|
||||||
|
<a class="link-pill g-pill" href={link.url} target="_blank" rel="noopener noreferrer">
|
||||||
|
{link.label || getDomain(link.url)}
|
||||||
|
</a>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{#if item.notes}
|
||||||
|
<p class="notes">{item.notes}</p>
|
||||||
|
{/if}
|
||||||
|
<div class="footer">
|
||||||
|
{isEnglish ? 'Added by' : 'Hinzugefügt von'} {item.addedBy}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { TranslatedRecipeType } from '$types/types';
|
import type { TranslatedRecipeType } from '$types/types';
|
||||||
import TranslationFieldComparison from './TranslationFieldComparison.svelte';
|
import TranslationFieldComparison from './TranslationFieldComparison.svelte';
|
||||||
import CreateIngredientList from './CreateIngredientList.svelte';
|
import CreateIngredientList from '$lib/components/recipes/CreateIngredientList.svelte';
|
||||||
import CreateStepList from './CreateStepList.svelte';
|
import CreateStepList from '$lib/components/recipes/CreateStepList.svelte';
|
||||||
import GenerateAltTextButton from './GenerateAltTextButton.svelte';
|
import GenerateAltTextButton from './GenerateAltTextButton.svelte';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
@import "./shake.css";
|
||||||
|
|
||||||
:root{
|
:root{
|
||||||
--angle: 15deg;
|
--angle: 15deg;
|
||||||
}
|
}
|
||||||
@@ -5,10 +7,10 @@
|
|||||||
border: none;
|
border: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-color: var(--red);
|
background-color: var(--red);
|
||||||
transition: 200ms;
|
transition: var(--transition-normal);
|
||||||
box-shadow: 0 0 1em 0.2em rgba(0,0,0,0.3);
|
box-shadow: 0 0 1em 0.2em rgba(0,0,0,0.3);
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
border-radius: 1000px;
|
border-radius: var(--radius-pill);
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -26,33 +28,3 @@
|
|||||||
transition: 50ms;
|
transition: 50ms;
|
||||||
scale: 0.8 0.8;
|
scale: 0.8 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@keyframes shake{
|
|
||||||
0%{
|
|
||||||
transform: rotate(0)
|
|
||||||
scale(1,1);
|
|
||||||
}
|
|
||||||
25%{
|
|
||||||
box-shadow: 0em 0em 1em 0.2em rgba(0, 0, 0, 0.6);
|
|
||||||
transform: rotate(--angle)
|
|
||||||
scale(1.2,1.2)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
50%{
|
|
||||||
|
|
||||||
box-shadow: 0em 0em 1em 0.2em rgba(0, 0, 0, 0.6);
|
|
||||||
transform: rotate(calc(-1 * --angle))
|
|
||||||
scale(1.2,1.2);
|
|
||||||
}
|
|
||||||
74%{
|
|
||||||
|
|
||||||
box-shadow: 0em 0em 1em 0.2em rgba(0, 0, 0, 0.6);
|
|
||||||
transform: rotate(--angle)
|
|
||||||
scale(1.2, 1.2);
|
|
||||||
}
|
|
||||||
100%{
|
|
||||||
transform: rotate(0)
|
|
||||||
scale(1.2, 1.2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
form{
|
|
||||||
background-color: var(--nord5);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
max-width: 600px;
|
|
||||||
gap: 0.5em;
|
|
||||||
margin-inline: auto;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
padding-block: 2rem;
|
|
||||||
margin-block: 2rem;
|
|
||||||
}
|
|
||||||
@media (prefers-color-scheme: dark){
|
|
||||||
form{
|
|
||||||
background-color: var(--accent-dark);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
form label{
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
form input{
|
|
||||||
display: block;
|
|
||||||
font-size: 1.2rem;
|
|
||||||
}
|
|
||||||
form button{
|
|
||||||
background-color: var(--red);
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
padding: 0.5em 1em;
|
|
||||||
font-size: 1.3em;
|
|
||||||
border-radius: 1000px;
|
|
||||||
margin-top: 1em;
|
|
||||||
transition: 100ms;
|
|
||||||
}
|
|
||||||
form button:hover,
|
|
||||||
form button:focus-visible
|
|
||||||
{
|
|
||||||
scale: 1.1;
|
|
||||||
}
|
|
||||||
form p{
|
|
||||||
max-width: 400px;
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
form h4{
|
|
||||||
margin-bottom:0;
|
|
||||||
}
|
|
||||||
@media screen and (max-width: 600px){
|
|
||||||
form{
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,178 +0,0 @@
|
|||||||
:root{
|
|
||||||
--nord0: #2E3440;
|
|
||||||
--nord1: #3B4252;
|
|
||||||
--nord2: #434C5E;
|
|
||||||
--nord3: #4C566A;
|
|
||||||
--nord4: #D8DEE9;
|
|
||||||
--nord5: #E5E9F0;
|
|
||||||
--nord6: #ECEFF4;
|
|
||||||
--nord7: #8FBCBB;
|
|
||||||
--nord8: #88C0D0;
|
|
||||||
--nord9: #81A1C1;
|
|
||||||
--nord10: #5E81AC;
|
|
||||||
--nord11: #BF616A;
|
|
||||||
--nord12: #D08770;
|
|
||||||
--nord13: #EBCB8B;
|
|
||||||
--nord14: #A3BE8C;
|
|
||||||
--nord15: #B48EAD;
|
|
||||||
--lightblue: var(--nord9);
|
|
||||||
--blue: var(--nord10);
|
|
||||||
--red: var(--nord11);
|
|
||||||
--orange: var(--nord12);
|
|
||||||
--yellow: var(--nord13);
|
|
||||||
--green: var(--nord14);
|
|
||||||
--purple: var(--nord15);
|
|
||||||
--nord6-dark: #292c31;
|
|
||||||
--accent-dark: #1f1f21;
|
|
||||||
--background-dark: #21201b;
|
|
||||||
--font-default-dark: #ffffff;
|
|
||||||
/* Shared transitions & shadows */
|
|
||||||
--transition-fast: 100ms;
|
|
||||||
--transition-normal: 200ms;
|
|
||||||
--shadow-sm: 0 0 0.4em 0.05em rgba(0,0,0,0.2);
|
|
||||||
--shadow-md: 0 0 0.5em 0.1em rgba(0,0,0,0.3);
|
|
||||||
--shadow-lg: 0 0 1em 0.1em rgba(0,0,0,0.4);
|
|
||||||
--shadow-hover: 0.1em 0.1em 0.5em 0.1em rgba(0,0,0,0.3);
|
|
||||||
--radius-pill: 1000px;
|
|
||||||
--radius-card: 20px;
|
|
||||||
--radius-sm: 0.3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:not(:visited){
|
|
||||||
color: var(--blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
a:visited{
|
|
||||||
color: var(--purple);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
a:not(:visited){
|
|
||||||
color: var(--nord8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*{
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-family: Helvetica, Arial, "Noto Sans", sans-serif
|
|
||||||
}
|
|
||||||
body{
|
|
||||||
margin:0;
|
|
||||||
padding:0;
|
|
||||||
background-color: #fbf9f3;
|
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
body{
|
|
||||||
color: white;
|
|
||||||
background-color: var(--background-dark);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================================
|
|
||||||
Global Utility Classes
|
|
||||||
Use these in components to avoid CSS duplication
|
|
||||||
======================================== */
|
|
||||||
|
|
||||||
/* Pill-shaped element base */
|
|
||||||
.g-pill {
|
|
||||||
border-radius: var(--radius-pill);
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
display: inline-block;
|
|
||||||
text-decoration: none;
|
|
||||||
transition: var(--transition-fast);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Interactive hover/focus effects */
|
|
||||||
.g-interactive {
|
|
||||||
transition: var(--transition-fast);
|
|
||||||
}
|
|
||||||
.g-interactive:hover,
|
|
||||||
.g-interactive:focus-visible {
|
|
||||||
transform: scale(1.05);
|
|
||||||
box-shadow: var(--shadow-hover);
|
|
||||||
}
|
|
||||||
.g-interactive:focus {
|
|
||||||
scale: 0.9;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Light background button (with dark mode) */
|
|
||||||
.g-btn-light {
|
|
||||||
background-color: var(--nord5);
|
|
||||||
color: var(--nord0);
|
|
||||||
box-shadow: var(--shadow-sm);
|
|
||||||
}
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
.g-btn-light {
|
|
||||||
background-color: var(--nord0);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Dark background button */
|
|
||||||
.g-btn-dark,
|
|
||||||
.g-btn-dark:visited,
|
|
||||||
.g-btn-dark:link {
|
|
||||||
background-color: var(--nord0);
|
|
||||||
color: var(--nord6);
|
|
||||||
box-shadow: var(--shadow-lg);
|
|
||||||
}
|
|
||||||
.g-btn-dark:hover,
|
|
||||||
.g-btn-dark:focus-visible {
|
|
||||||
background-color: var(--nord1);
|
|
||||||
color: var(--nord6);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Icon badge (circular icon container) */
|
|
||||||
.g-icon-badge {
|
|
||||||
font-family: "Noto Color Emoji", emoji, sans-serif;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
border-radius: 50%;
|
|
||||||
text-decoration: none;
|
|
||||||
transition: var(--transition-fast);
|
|
||||||
box-shadow: var(--shadow-lg);
|
|
||||||
}
|
|
||||||
.g-icon-badge:hover,
|
|
||||||
.g-icon-badge:focus-visible {
|
|
||||||
transform: scale(1.1);
|
|
||||||
box-shadow: var(--shadow-hover);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Tag/chip styling */
|
|
||||||
.g-tag,
|
|
||||||
.g-tag:visited,
|
|
||||||
.g-tag:link {
|
|
||||||
font-size: 1.1rem;
|
|
||||||
padding: 0.25em 1em;
|
|
||||||
border-radius: var(--radius-pill);
|
|
||||||
background-color: var(--nord5);
|
|
||||||
color: var(--nord0);
|
|
||||||
text-decoration: none;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: var(--transition-fast);
|
|
||||||
box-shadow: var(--shadow-sm);
|
|
||||||
border: none;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
.g-tag:hover,
|
|
||||||
.g-tag:focus-visible {
|
|
||||||
transform: scale(1.05);
|
|
||||||
background-color: var(--nord8);
|
|
||||||
box-shadow: var(--shadow-hover);
|
|
||||||
color: var(--nord0);
|
|
||||||
}
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
.g-tag,
|
|
||||||
.g-tag:visited,
|
|
||||||
.g-tag:link {
|
|
||||||
background-color: var(--nord0);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.g-tag:hover,
|
|
||||||
.g-tag:focus-visible {
|
|
||||||
color: var(--nord0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,198 +0,0 @@
|
|||||||
@font-face {
|
|
||||||
font-family: 'LibertineMinimal';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 400;
|
|
||||||
font-display: swap;
|
|
||||||
src: url(/fonts/LinLibertine_minimal.woff2) format('woff2'),
|
|
||||||
url(/fonts/LinLibertine_minimal.ttf) format('truetype');
|
|
||||||
}
|
|
||||||
.sbeads{
|
|
||||||
fill: var(--nord10);
|
|
||||||
}
|
|
||||||
|
|
||||||
.chain{
|
|
||||||
stroke:black;
|
|
||||||
stroke-width: 0.7;
|
|
||||||
stroke-miterlimit: 4;
|
|
||||||
stroke: gray;
|
|
||||||
fill: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sbeads circle.hitbox{
|
|
||||||
r: 3.2px;
|
|
||||||
stroke-width:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#start1 circle{
|
|
||||||
cx:15.559271px;
|
|
||||||
cy: 20.881956px;
|
|
||||||
}
|
|
||||||
#start2 circle{
|
|
||||||
cx:21.633902px;
|
|
||||||
cy:20.367514px;
|
|
||||||
}
|
|
||||||
#start3 circle{
|
|
||||||
cx:27.96961px;
|
|
||||||
cy:21.178484px;
|
|
||||||
}
|
|
||||||
#lbead5 circle{
|
|
||||||
cx:118.50725px;
|
|
||||||
cy:59.477211px;
|
|
||||||
}
|
|
||||||
#lbead4 circle{
|
|
||||||
cx:126.81134px;
|
|
||||||
cy:15.751753px;
|
|
||||||
}
|
|
||||||
#lbead1 circle{
|
|
||||||
cx:7.6719489px;
|
|
||||||
cy:25.364584px;
|
|
||||||
}
|
|
||||||
#lbead2 circle{
|
|
||||||
cx:36.798512px;
|
|
||||||
cy:23.486462px;
|
|
||||||
}
|
|
||||||
#lbead3 circle{
|
|
||||||
cx:84.105789px;
|
|
||||||
cy:3.0456686px;
|
|
||||||
}
|
|
||||||
#lbead6 circle{
|
|
||||||
cx:72.185097px;
|
|
||||||
cy:64.006859px;
|
|
||||||
}
|
|
||||||
#start1:hover .msg,
|
|
||||||
#start2:hover .msg,
|
|
||||||
#start3:hover .msg,
|
|
||||||
#secret1:hover .msg,
|
|
||||||
#secret2:hover .msg,
|
|
||||||
#secret3:hover .msg,
|
|
||||||
#secret4:hover .msg,
|
|
||||||
#secret5:hover .msg,
|
|
||||||
#lbeads .beforedecades:hover .msg,
|
|
||||||
#lbeads .afterdecade:hover .msg,
|
|
||||||
#cross:hover .msg
|
|
||||||
{
|
|
||||||
display:block;
|
|
||||||
}
|
|
||||||
|
|
||||||
#start1:hover .sbeads circle:not(.hitbox),
|
|
||||||
#start2:hover .sbeads circle:not(.hitbox),
|
|
||||||
#start3:hover .sbeads circle:not(.hitbox),
|
|
||||||
#secret1:hover .sbeads circle,
|
|
||||||
#secret2:hover .sbeads circle,
|
|
||||||
#secret3:hover .sbeads circle,
|
|
||||||
#secret4:hover .sbeads circle,
|
|
||||||
#secret5:hover .sbeads circle
|
|
||||||
{
|
|
||||||
fill: var(--nord11);
|
|
||||||
r: 1.5px;
|
|
||||||
}
|
|
||||||
#lbead1:hover .lbead,
|
|
||||||
#lbead2:hover .lbead,
|
|
||||||
#lbead3:hover .lbead,
|
|
||||||
#lbead4:hover .lbead,
|
|
||||||
#lbead5:hover .lbead,
|
|
||||||
#lbead6:hover .lbead{
|
|
||||||
r: 2.8px;
|
|
||||||
fill: var(--nord11);
|
|
||||||
}
|
|
||||||
#cross:hover .symbol{
|
|
||||||
fill: var(--nord11);
|
|
||||||
stroke: var(--nord11);
|
|
||||||
stroke-width: 0.25;
|
|
||||||
}
|
|
||||||
#lbeads.msg{
|
|
||||||
display:block;
|
|
||||||
}
|
|
||||||
.sbeads circle{
|
|
||||||
r: 1.25px;
|
|
||||||
}
|
|
||||||
.msg .diff{
|
|
||||||
fill: var(--nord11);
|
|
||||||
}
|
|
||||||
.msg .b{
|
|
||||||
font-family: crosses;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.msg .title{
|
|
||||||
fill: var(--nord10);
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 5px;
|
|
||||||
}
|
|
||||||
.msg{
|
|
||||||
font-size: 4px;
|
|
||||||
stroke: none;
|
|
||||||
fill: var(--nord4);
|
|
||||||
display:none;
|
|
||||||
}
|
|
||||||
text{
|
|
||||||
font-family: LibertineMinimal;
|
|
||||||
}
|
|
||||||
#lbeads circle.hitbox{
|
|
||||||
r:5px;
|
|
||||||
stroke:none;
|
|
||||||
stroke-width:0;
|
|
||||||
}
|
|
||||||
.lbead{
|
|
||||||
fill: var(--nord12);
|
|
||||||
r: 2.65px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hitbox{
|
|
||||||
opacity:0;
|
|
||||||
stroke-width: 2;
|
|
||||||
fill: red;
|
|
||||||
stroke: red;
|
|
||||||
}
|
|
||||||
#coin circle{
|
|
||||||
r: 2.7px;
|
|
||||||
fill:darkgray;
|
|
||||||
}
|
|
||||||
|
|
||||||
#coin text{
|
|
||||||
fill:var(--nord0);
|
|
||||||
font-size: 4.259px;
|
|
||||||
line-height:1.25;
|
|
||||||
font-family: crosses;
|
|
||||||
}
|
|
||||||
|
|
||||||
#cross .symbol{
|
|
||||||
font-family: crosses;
|
|
||||||
fill: var(--nord4);
|
|
||||||
font-size: 17.3637px;
|
|
||||||
line-height: 1.25;
|
|
||||||
stroke-width:0.434093
|
|
||||||
}
|
|
||||||
|
|
||||||
table{
|
|
||||||
width: 100%;
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
td{
|
|
||||||
text-align:center;
|
|
||||||
border-left: 1px solid;
|
|
||||||
border-right: 1px solid;
|
|
||||||
border-color: var(--nord2);
|
|
||||||
padding-left: 5px;
|
|
||||||
padding-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr :last-child{
|
|
||||||
border-right: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr :first-child{
|
|
||||||
border-left: 0px solid;
|
|
||||||
}
|
|
||||||
|
|
||||||
thead td{
|
|
||||||
color: var(--nord4);
|
|
||||||
border-bottom-width: 3px;
|
|
||||||
border-bottom-color: var(--nord10);
|
|
||||||
border-bottom-style: dotted;
|
|
||||||
font-size: 110%;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.table{
|
|
||||||
width:100%;
|
|
||||||
overflow-x: auto;
|
|
||||||
}
|
|
||||||
@@ -105,3 +105,105 @@ export const mysteryReferences = {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
// Reference for the three opening Ave Marias (Faith, Hope, Love)
|
||||||
|
export const theologicalVirtueReference = {
|
||||||
|
title: "Das Hohelied der Liebe",
|
||||||
|
reference: "1 Kor 13, 1-13"
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export const theologicalVirtueReferenceEnglish = {
|
||||||
|
title: "The Hymn to Love",
|
||||||
|
reference: "1 Cor 13:1-13"
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export const mysteryReferencesEnglish = {
|
||||||
|
lichtreichen: [
|
||||||
|
{
|
||||||
|
title: "The first Luminous Mystery: The Baptism in the Jordan.",
|
||||||
|
reference: "Mt 3:16-17"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "The second Luminous Mystery: The Wedding at Cana.",
|
||||||
|
reference: "Jn 2:1-5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "The third Luminous Mystery: The Proclamation of the Kingdom of God.",
|
||||||
|
reference: "Mk 1:15"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "The fourth Luminous Mystery: The Transfiguration.",
|
||||||
|
reference: "Mt 17:1-2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "The fifth Luminous Mystery: The Institution of the Holy Eucharist.",
|
||||||
|
reference: "Mt 26:26"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
freudenreich: [
|
||||||
|
{
|
||||||
|
title: "The first Joyful Mystery: The Annunciation of the Archangel Gabriel to the Virgin Mary.",
|
||||||
|
reference: "Lk 1:26-27"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "The second Joyful Mystery: The Visitation of Mary to Elizabeth.",
|
||||||
|
reference: "Lk 1:39-42"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "The third Joyful Mystery: The Nativity of Jesus in the Stable at Bethlehem.",
|
||||||
|
reference: "Lk 2:1-7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "The fourth Joyful Mystery: The Presentation of Jesus in the Temple.",
|
||||||
|
reference: "Lk 2:21-24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "The fifth Joyful Mystery: The Finding of Jesus in the Temple.",
|
||||||
|
reference: "Lk 2:41-47"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
schmerzhaften: [
|
||||||
|
{
|
||||||
|
title: "The first Sorrowful Mystery: The Agony of Jesus in the Garden.",
|
||||||
|
reference: "Mt 26:36-39"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "The second Sorrowful Mystery: The Scourging at the Pillar.",
|
||||||
|
reference: "Mt 27:26"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "The third Sorrowful Mystery: The Crowning with Thorns.",
|
||||||
|
reference: "Mt 27:27-29"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "The fourth Sorrowful Mystery: Jesus Carries the Heavy Cross.",
|
||||||
|
reference: "Mk 15:21-22"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "The fifth Sorrowful Mystery: The Crucifixion of Jesus.",
|
||||||
|
reference: "Lk 23:33-46"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
glorreichen: [
|
||||||
|
{
|
||||||
|
title: "The first Glorious Mystery: The Resurrection of Jesus.",
|
||||||
|
reference: "Lk 24:1-6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "The second Glorious Mystery: The Ascension of Jesus.",
|
||||||
|
reference: "Mk 16:19"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "The third Glorious Mystery: The Descent of the Holy Spirit.",
|
||||||
|
reference: "Acts 2:1-4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "The fourth Glorious Mystery: The Assumption of Mary into Heaven.",
|
||||||
|
reference: "Lk 1:48-49"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "The fifth Glorious Mystery: The Coronation of Mary as Queen of Heaven and Earth.",
|
||||||
|
reference: "Apo 12:1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
} as const;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Auto-generated by scripts/generate-mystery-verses.ts — do not edit manually
|
// Auto-generated by scripts/generate-mystery-verses.ts — do not edit manually
|
||||||
import type { MysteryDescription } from './mysteryDescriptions';
|
import type { MysteryDescription } from './mysteryDescriptions';
|
||||||
|
|
||||||
export const mysteryVerseData: Record<string, MysteryDescription[]> = {
|
export const mysteryVerseDataDe: Record<string, MysteryDescription[]> = {
|
||||||
"lichtreichen": [
|
"lichtreichen": [
|
||||||
{
|
{
|
||||||
"title": "Das erste lichtreiche Geheimnis: Die Taufe im Jordan.",
|
"title": "Das erste lichtreiche Geheimnis: Die Taufe im Jordan.",
|
||||||
@@ -523,3 +523,654 @@ export const mysteryVerseData: Record<string, MysteryDescription[]> = {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const mysteryVerseDataEn: Record<string, MysteryDescription[]> = {
|
||||||
|
"lichtreichen": [
|
||||||
|
{
|
||||||
|
"title": "The first Luminous Mystery: The Baptism in the Jordan.",
|
||||||
|
"reference": "Mt 3:16-17",
|
||||||
|
"text": "«And Jesus being baptized, forthwith came out of the water: and lo, the heavens were opened to him: and he saw the Spirit of God descending as a dove, and coming upon him. And behold a voice from heaven saying: This is my beloved Son, in whom I am well pleased.»",
|
||||||
|
"verseData": {
|
||||||
|
"book": "Matthew",
|
||||||
|
"chapter": 3,
|
||||||
|
"verses": [
|
||||||
|
{
|
||||||
|
"verse": 16,
|
||||||
|
"text": "And Jesus being baptized, forthwith came out of the water: and lo, the heavens were opened to him: and he saw the Spirit of God descending as a dove, and coming upon him."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 17,
|
||||||
|
"text": "And behold a voice from heaven saying: This is my beloved Son, in whom I am well pleased."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "The second Luminous Mystery: The Wedding at Cana.",
|
||||||
|
"reference": "Jn 2:1-5",
|
||||||
|
"text": "«And the third day, there was a marriage in Cana of Galilee: and the mother of Jesus was there. And Jesus also was invited, and his disciples, to the marriage. And the wine failing, the mother of Jesus saith to him: They have no wine. And Jesus saith to her: Woman, what is that to me and to thee? My hour is not yet come. His mother saith to the waiters: Whatsoever he shall say to you, do ye.»",
|
||||||
|
"verseData": {
|
||||||
|
"book": "John",
|
||||||
|
"chapter": 2,
|
||||||
|
"verses": [
|
||||||
|
{
|
||||||
|
"verse": 1,
|
||||||
|
"text": "And the third day, there was a marriage in Cana of Galilee: and the mother of Jesus was there."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 2,
|
||||||
|
"text": "And Jesus also was invited, and his disciples, to the marriage."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 3,
|
||||||
|
"text": "And the wine failing, the mother of Jesus saith to him: They have no wine."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 4,
|
||||||
|
"text": "And Jesus saith to her: Woman, what is that to me and to thee? My hour is not yet come."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 5,
|
||||||
|
"text": "His mother saith to the waiters: Whatsoever he shall say to you, do ye."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "The third Luminous Mystery: The Proclamation of the Kingdom of God.",
|
||||||
|
"reference": "Mk 1:15",
|
||||||
|
"text": "«And saying: The time is accomplished and the kingdom of God is at hand. Repent and believe the gospel:»",
|
||||||
|
"verseData": {
|
||||||
|
"book": "Mark",
|
||||||
|
"chapter": 1,
|
||||||
|
"verses": [
|
||||||
|
{
|
||||||
|
"verse": 15,
|
||||||
|
"text": "And saying: The time is accomplished and the kingdom of God is at hand. Repent and believe the gospel:"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "The fourth Luminous Mystery: The Transfiguration.",
|
||||||
|
"reference": "Mt 17:1-2",
|
||||||
|
"text": "«And after six days Jesus taketh unto him Peter and James, and John his brother, and bringeth them up into a high mountain apart: And he was transfigured before them. And his face did shine as the sun: and his garments became white as snow.»",
|
||||||
|
"verseData": {
|
||||||
|
"book": "Matthew",
|
||||||
|
"chapter": 17,
|
||||||
|
"verses": [
|
||||||
|
{
|
||||||
|
"verse": 1,
|
||||||
|
"text": "And after six days Jesus taketh unto him Peter and James, and John his brother, and bringeth them up into a high mountain apart:"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 2,
|
||||||
|
"text": "And he was transfigured before them. And his face did shine as the sun: and his garments became white as snow."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "The fifth Luminous Mystery: The Institution of the Holy Eucharist.",
|
||||||
|
"reference": "Mt 26:26",
|
||||||
|
"text": "«And whilst they were at supper, Jesus took bread and blessed and broke and gave to his disciples and said: Take ye and eat. This is my body.»",
|
||||||
|
"verseData": {
|
||||||
|
"book": "Matthew",
|
||||||
|
"chapter": 26,
|
||||||
|
"verses": [
|
||||||
|
{
|
||||||
|
"verse": 26,
|
||||||
|
"text": "And whilst they were at supper, Jesus took bread and blessed and broke and gave to his disciples and said: Take ye and eat. This is my body."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"freudenreich": [
|
||||||
|
{
|
||||||
|
"title": "The first Joyful Mystery: The Annunciation of the Archangel Gabriel to the Virgin Mary.",
|
||||||
|
"reference": "Lk 1:26-27",
|
||||||
|
"text": "«And in the sixth month, the angel Gabriel was sent from God into a city of Galilee, called Nazareth, To a virgin espoused to a man whose name was Joseph, of the house of David: and the virgin's name was Mary.»",
|
||||||
|
"verseData": {
|
||||||
|
"book": "Luke",
|
||||||
|
"chapter": 1,
|
||||||
|
"verses": [
|
||||||
|
{
|
||||||
|
"verse": 26,
|
||||||
|
"text": "And in the sixth month, the angel Gabriel was sent from God into a city of Galilee, called Nazareth,"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 27,
|
||||||
|
"text": "To a virgin espoused to a man whose name was Joseph, of the house of David: and the virgin's name was Mary."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "The second Joyful Mystery: The Visitation of Mary to Elizabeth.",
|
||||||
|
"reference": "Lk 1:39-42",
|
||||||
|
"text": "«And Mary rising up in those days, went into the hill country with haste into a city of Juda. And she entered into the house of Zachary and saluted Elizabeth. And it came to pass that when Elizabeth heard the salutation of Mary, the infant leaped in her womb. And Elizabeth was filled with the Holy Ghost. And she cried out with a loud voice and said: Blessed art thou among women and blessed is the fruit of thy womb.»",
|
||||||
|
"verseData": {
|
||||||
|
"book": "Luke",
|
||||||
|
"chapter": 1,
|
||||||
|
"verses": [
|
||||||
|
{
|
||||||
|
"verse": 39,
|
||||||
|
"text": "And Mary rising up in those days, went into the hill country with haste into a city of Juda."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 40,
|
||||||
|
"text": "And she entered into the house of Zachary and saluted Elizabeth."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 41,
|
||||||
|
"text": "And it came to pass that when Elizabeth heard the salutation of Mary, the infant leaped in her womb. And Elizabeth was filled with the Holy Ghost."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 42,
|
||||||
|
"text": "And she cried out with a loud voice and said: Blessed art thou among women and blessed is the fruit of thy womb."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "The third Joyful Mystery: The Nativity of Jesus in the Stable at Bethlehem.",
|
||||||
|
"reference": "Lk 2:1-7",
|
||||||
|
"text": "«And it came to pass that in those days there went out a decree from Caesar Augustus that the whole world should be enrolled. This enrolling was first made by Cyrinus, the governor of Syria. And all went to be enrolled, every one into his own city. And Joseph also went up from Galilee, out of the city of Nazareth, into Judea, to the city of David, which is called Bethlehem: because he was of the house and family of David. To be enrolled with Mary his espoused wife, who was with child. And it came to pass that when they were there, her days were accomplished that she should be delivered. And she brought forth her first born son and wrapped him up in swaddling clothes and laid him in a manger: because there was no room for them in the inn.»",
|
||||||
|
"verseData": {
|
||||||
|
"book": "Luke",
|
||||||
|
"chapter": 2,
|
||||||
|
"verses": [
|
||||||
|
{
|
||||||
|
"verse": 1,
|
||||||
|
"text": "And it came to pass that in those days there went out a decree from Caesar Augustus that the whole world should be enrolled."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 2,
|
||||||
|
"text": "This enrolling was first made by Cyrinus, the governor of Syria."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 3,
|
||||||
|
"text": "And all went to be enrolled, every one into his own city."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 4,
|
||||||
|
"text": "And Joseph also went up from Galilee, out of the city of Nazareth, into Judea, to the city of David, which is called Bethlehem: because he was of the house and family of David."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 5,
|
||||||
|
"text": "To be enrolled with Mary his espoused wife, who was with child."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 6,
|
||||||
|
"text": "And it came to pass that when they were there, her days were accomplished that she should be delivered."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 7,
|
||||||
|
"text": "And she brought forth her first born son and wrapped him up in swaddling clothes and laid him in a manger: because there was no room for them in the inn."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "The fourth Joyful Mystery: The Presentation of Jesus in the Temple.",
|
||||||
|
"reference": "Lk 2:21-24",
|
||||||
|
"text": "«And after eight days were accomplished, that the child should be circumcised, his name was called JESUS, which was called by the angel before he was conceived in the womb. And after the days of her purification, according to the law of Moses, were accomplished, they carried him to Jerusalem, to present him to the Lord: As it is written in the law of the Lord: Every male opening the womb shall be called holy to the Lord: And to offer a sacrifice, according as it is written in the law of the Lord, a pair of turtledoves or two young pigeons:»",
|
||||||
|
"verseData": {
|
||||||
|
"book": "Luke",
|
||||||
|
"chapter": 2,
|
||||||
|
"verses": [
|
||||||
|
{
|
||||||
|
"verse": 21,
|
||||||
|
"text": "And after eight days were accomplished, that the child should be circumcised, his name was called JESUS, which was called by the angel before he was conceived in the womb."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 22,
|
||||||
|
"text": "And after the days of her purification, according to the law of Moses, were accomplished, they carried him to Jerusalem, to present him to the Lord:"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 23,
|
||||||
|
"text": "As it is written in the law of the Lord: Every male opening the womb shall be called holy to the Lord:"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 24,
|
||||||
|
"text": "And to offer a sacrifice, according as it is written in the law of the Lord, a pair of turtledoves or two young pigeons:"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "The fifth Joyful Mystery: The Finding of Jesus in the Temple.",
|
||||||
|
"reference": "Lk 2:41-47",
|
||||||
|
"text": "«And his parents went every year to Jerusalem, at the solemn day of the pasch. And when he was twelve years old, they going up into Jerusalem, according to the custom of the feast, And having fulfilled the days, when they returned, the child Jesus remained in Jerusalem. And his parents knew it not. And thinking that he was in the company, they came a day's journey and sought him among their kinsfolks and acquaintance. And not finding him, they returned into Jerusalem, seeking him. And it came to pass, that, after three days, they found him in the temple, sitting in the midst of the doctors, hearing them and asking them questions. And all that heard him were astonished at his wisdom and his answers.»",
|
||||||
|
"verseData": {
|
||||||
|
"book": "Luke",
|
||||||
|
"chapter": 2,
|
||||||
|
"verses": [
|
||||||
|
{
|
||||||
|
"verse": 41,
|
||||||
|
"text": "And his parents went every year to Jerusalem, at the solemn day of the pasch."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 42,
|
||||||
|
"text": "And when he was twelve years old, they going up into Jerusalem, according to the custom of the feast,"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 43,
|
||||||
|
"text": "And having fulfilled the days, when they returned, the child Jesus remained in Jerusalem. And his parents knew it not."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 44,
|
||||||
|
"text": "And thinking that he was in the company, they came a day's journey and sought him among their kinsfolks and acquaintance."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 45,
|
||||||
|
"text": "And not finding him, they returned into Jerusalem, seeking him."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 46,
|
||||||
|
"text": "And it came to pass, that, after three days, they found him in the temple, sitting in the midst of the doctors, hearing them and asking them questions."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 47,
|
||||||
|
"text": "And all that heard him were astonished at his wisdom and his answers."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"schmerzhaften": [
|
||||||
|
{
|
||||||
|
"title": "The first Sorrowful Mystery: The Agony of Jesus in the Garden.",
|
||||||
|
"reference": "Mt 26:36-39",
|
||||||
|
"text": "«Then Jesus came with them into a country place which is called Gethsemani. And he said to his disciples: Sit you here, till I go yonder and pray. And taking with him Peter and the two sons of Zebedee, he began to grow sorrowful and to be sad. Then he saith to them: My soul is sorrowful even unto death. Stay you here and watch with me. And going a little further, he fell upon his face, praying and saying: My Father, if it be possible, let this chalice pass from me. Nevertheless, not as I will but as thou wilt.»",
|
||||||
|
"verseData": {
|
||||||
|
"book": "Matthew",
|
||||||
|
"chapter": 26,
|
||||||
|
"verses": [
|
||||||
|
{
|
||||||
|
"verse": 36,
|
||||||
|
"text": "Then Jesus came with them into a country place which is called Gethsemani. And he said to his disciples: Sit you here, till I go yonder and pray."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 37,
|
||||||
|
"text": "And taking with him Peter and the two sons of Zebedee, he began to grow sorrowful and to be sad."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 38,
|
||||||
|
"text": "Then he saith to them: My soul is sorrowful even unto death. Stay you here and watch with me."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 39,
|
||||||
|
"text": "And going a little further, he fell upon his face, praying and saying: My Father, if it be possible, let this chalice pass from me. Nevertheless, not as I will but as thou wilt."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "The second Sorrowful Mystery: The Scourging at the Pillar.",
|
||||||
|
"reference": "Mt 27:26",
|
||||||
|
"text": "«Then he released to them Barabbas: and having scourged Jesus, delivered him unto them to be crucified.»",
|
||||||
|
"verseData": {
|
||||||
|
"book": "Matthew",
|
||||||
|
"chapter": 27,
|
||||||
|
"verses": [
|
||||||
|
{
|
||||||
|
"verse": 26,
|
||||||
|
"text": "Then he released to them Barabbas: and having scourged Jesus, delivered him unto them to be crucified."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "The third Sorrowful Mystery: The Crowning with Thorns.",
|
||||||
|
"reference": "Mt 27:27-29",
|
||||||
|
"text": "«Then the soldiers of the governor, taking Jesus into the hall, gathered together unto him the whole band. And stripping him, they put a scarlet cloak about him. And platting a crown of thorns, they put it upon his head, and a reed in his right hand. And bowing the knee before him, they mocked him, saying: Hail, King of the Jews.»",
|
||||||
|
"verseData": {
|
||||||
|
"book": "Matthew",
|
||||||
|
"chapter": 27,
|
||||||
|
"verses": [
|
||||||
|
{
|
||||||
|
"verse": 27,
|
||||||
|
"text": "Then the soldiers of the governor, taking Jesus into the hall, gathered together unto him the whole band."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 28,
|
||||||
|
"text": "And stripping him, they put a scarlet cloak about him."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 29,
|
||||||
|
"text": "And platting a crown of thorns, they put it upon his head, and a reed in his right hand. And bowing the knee before him, they mocked him, saying: Hail, King of the Jews."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "The fourth Sorrowful Mystery: Jesus Carries the Heavy Cross.",
|
||||||
|
"reference": "Mk 15:21-22",
|
||||||
|
"text": "«And they forced one Simon a Cyrenian, who passed by coming out of the country, the father of Alexander and of Rufus, to take up his cross. And they bring him into the place called Golgotha, which being interpreted is, The place of Calvary.»",
|
||||||
|
"verseData": {
|
||||||
|
"book": "Mark",
|
||||||
|
"chapter": 15,
|
||||||
|
"verses": [
|
||||||
|
{
|
||||||
|
"verse": 21,
|
||||||
|
"text": "And they forced one Simon a Cyrenian, who passed by coming out of the country, the father of Alexander and of Rufus, to take up his cross."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 22,
|
||||||
|
"text": "And they bring him into the place called Golgotha, which being interpreted is, The place of Calvary."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "The fifth Sorrowful Mystery: The Crucifixion of Jesus.",
|
||||||
|
"reference": "Lk 23:33-46",
|
||||||
|
"text": "«And when they were come to the place which is called Calvary, they crucified him there: and the robbers, one on the right hand, and the other on the left. And Jesus said: Father, forgive them, for they know not what they do. But they, dividing his garments, cast lots. And the people stood beholding. And the rulers with them derided him, saying: He saved others: let him save himself, if he be Christ, the elect of God. And the soldiers also mocked him, coming to him and offering him vinegar, And saying: If thou be the king of the Jews, save thyself. And there was also a superscription written over him in letters of Greek and Latin and Hebrew THIS IS THE KING OF THE JEWS. And one of those robbers who were hanged blasphemed him, saying: If thou be Christ, save thyself and us. But the other answering, rebuked him, saying: Neither dost thou fear God, seeing; thou art under the same condemnation? And we indeed justly: for we receive the due reward of our deeds. But this man hath done no evil. And he said to Jesus: Lord, remember me when thou shalt come into thy kingdom. And Jesus said to him: Amen I say to thee: This day thou shalt be with me in paradise. And it was almost the sixth hour: and there was darkness over all the earth until the ninth hour. And the sun was darkened, and the veil of the temple was rent in the midst. And Jesus crying with a loud voice, said: Father, into thy hands I commend my spirit. And saying this, he gave up the ghost.»",
|
||||||
|
"verseData": {
|
||||||
|
"book": "Luke",
|
||||||
|
"chapter": 23,
|
||||||
|
"verses": [
|
||||||
|
{
|
||||||
|
"verse": 33,
|
||||||
|
"text": "And when they were come to the place which is called Calvary, they crucified him there: and the robbers, one on the right hand, and the other on the left."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 34,
|
||||||
|
"text": "And Jesus said: Father, forgive them, for they know not what they do. But they, dividing his garments, cast lots."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 35,
|
||||||
|
"text": "And the people stood beholding. And the rulers with them derided him, saying: He saved others: let him save himself, if he be Christ, the elect of God."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 36,
|
||||||
|
"text": "And the soldiers also mocked him, coming to him and offering him vinegar,"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 37,
|
||||||
|
"text": "And saying: If thou be the king of the Jews, save thyself."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 38,
|
||||||
|
"text": "And there was also a superscription written over him in letters of Greek and Latin and Hebrew THIS IS THE KING OF THE JEWS."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 39,
|
||||||
|
"text": "And one of those robbers who were hanged blasphemed him, saying: If thou be Christ, save thyself and us."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 40,
|
||||||
|
"text": "But the other answering, rebuked him, saying: Neither dost thou fear God, seeing; thou art under the same condemnation?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 41,
|
||||||
|
"text": "And we indeed justly: for we receive the due reward of our deeds. But this man hath done no evil."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 42,
|
||||||
|
"text": "And he said to Jesus: Lord, remember me when thou shalt come into thy kingdom."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 43,
|
||||||
|
"text": "And Jesus said to him: Amen I say to thee: This day thou shalt be with me in paradise."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 44,
|
||||||
|
"text": "And it was almost the sixth hour: and there was darkness over all the earth until the ninth hour."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 45,
|
||||||
|
"text": "And the sun was darkened, and the veil of the temple was rent in the midst."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 46,
|
||||||
|
"text": "And Jesus crying with a loud voice, said: Father, into thy hands I commend my spirit. And saying this, he gave up the ghost."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"glorreichen": [
|
||||||
|
{
|
||||||
|
"title": "The first Glorious Mystery: The Resurrection of Jesus.",
|
||||||
|
"reference": "Lk 24:1-6",
|
||||||
|
"text": "«And on the first day of the week, very early in the morning, they came to the sepulchre, bringing the spices which they had prepared. And they found the stone rolled back from the sepulchre. And going in, they found not the body of the Lord Jesus. And it came to pass, as they were astonished in their mind at this, behold, two men stood by them, in shining apparel. And as they were afraid and bowed down their countenance towards the ground, they said unto them: Why seek you the living with the dead? He is not here, but is risen. Remember how he spoke unto you, when he was yet in Galilee,»",
|
||||||
|
"verseData": {
|
||||||
|
"book": "Luke",
|
||||||
|
"chapter": 24,
|
||||||
|
"verses": [
|
||||||
|
{
|
||||||
|
"verse": 1,
|
||||||
|
"text": "And on the first day of the week, very early in the morning, they came to the sepulchre, bringing the spices which they had prepared."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 2,
|
||||||
|
"text": "And they found the stone rolled back from the sepulchre."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 3,
|
||||||
|
"text": "And going in, they found not the body of the Lord Jesus."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 4,
|
||||||
|
"text": "And it came to pass, as they were astonished in their mind at this, behold, two men stood by them, in shining apparel."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 5,
|
||||||
|
"text": "And as they were afraid and bowed down their countenance towards the ground, they said unto them: Why seek you the living with the dead?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 6,
|
||||||
|
"text": "He is not here, but is risen. Remember how he spoke unto you, when he was yet in Galilee,"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "The second Glorious Mystery: The Ascension of Jesus.",
|
||||||
|
"reference": "Mk 16:19",
|
||||||
|
"text": "«And the Lord Jesus, after he had spoken to them, was taken up into heaven and sitteth on the right hand of God.»",
|
||||||
|
"verseData": {
|
||||||
|
"book": "Mark",
|
||||||
|
"chapter": 16,
|
||||||
|
"verses": [
|
||||||
|
{
|
||||||
|
"verse": 19,
|
||||||
|
"text": "And the Lord Jesus, after he had spoken to them, was taken up into heaven and sitteth on the right hand of God."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "The third Glorious Mystery: The Descent of the Holy Spirit.",
|
||||||
|
"reference": "Acts 2:1-4",
|
||||||
|
"text": "«And when the days of the Pentecost were accomplished, they were all together in one place: And suddenly there came a sound from heaven, as of a mighty wind coming: and it filled the whole house where they were sitting. And there appeared to them parted tongues, as it were of fire: and it sat upon every one of them. And they were all filled with the Holy Ghost: and they began to speak with divers tongues, according as the Holy Ghost gave them to speak.»",
|
||||||
|
"verseData": {
|
||||||
|
"book": "Acts",
|
||||||
|
"chapter": 2,
|
||||||
|
"verses": [
|
||||||
|
{
|
||||||
|
"verse": 1,
|
||||||
|
"text": "And when the days of the Pentecost were accomplished, they were all together in one place:"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 2,
|
||||||
|
"text": "And suddenly there came a sound from heaven, as of a mighty wind coming: and it filled the whole house where they were sitting."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 3,
|
||||||
|
"text": "And there appeared to them parted tongues, as it were of fire: and it sat upon every one of them."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 4,
|
||||||
|
"text": "And they were all filled with the Holy Ghost: and they began to speak with divers tongues, according as the Holy Ghost gave them to speak."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "The fourth Glorious Mystery: The Assumption of Mary into Heaven.",
|
||||||
|
"reference": "Lk 1:48-49",
|
||||||
|
"text": "«Because he hath regarded the humility of his handmaid: for behold from henceforth all generations shall call me blessed. Because he that is mighty hath done great things to me: and holy is his name.»",
|
||||||
|
"verseData": {
|
||||||
|
"book": "Luke",
|
||||||
|
"chapter": 1,
|
||||||
|
"verses": [
|
||||||
|
{
|
||||||
|
"verse": 48,
|
||||||
|
"text": "Because he hath regarded the humility of his handmaid: for behold from henceforth all generations shall call me blessed."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 49,
|
||||||
|
"text": "Because he that is mighty hath done great things to me: and holy is his name."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "The fifth Glorious Mystery: The Coronation of Mary as Queen of Heaven and Earth.",
|
||||||
|
"reference": "Apo 12:1",
|
||||||
|
"text": "«And a great sign appeared in heaven: A woman clothed with the sun, and the moon under her feet, and on her head a crown of twelve stars.»",
|
||||||
|
"verseData": {
|
||||||
|
"book": "Apocalypse",
|
||||||
|
"chapter": 12,
|
||||||
|
"verses": [
|
||||||
|
{
|
||||||
|
"verse": 1,
|
||||||
|
"text": "And a great sign appeared in heaven: A woman clothed with the sun, and the moon under her feet, and on her head a crown of twelve stars."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
export const theologicalVirtueVerseDataDe: MysteryDescription = {
|
||||||
|
"title": "Das Hohelied der Liebe",
|
||||||
|
"reference": "1 Kor 13, 1-13",
|
||||||
|
"text": "«Wenn ich mit den Zungen der Menschen und Engel rede, aber die Liebe nicht habe, so bin ich wie ein tönendes Erz oder eine klingende Schelle geworden. Und wenn ich die Gabe der Weissagung habe, und kenne alle Geheimnisse und alle Wissenschaft, und wenn ich allen Glauben habe, so dass ich Berge versetzen könnte, die Liebe aber nicht habe, so bin ich nichts. Und wenn ich alle meine Habe zur Speisung der Armen austeile, und wenn ich meinen Leib dahingebe, dass ich verbrannt werde, die Liebe aber nicht habe, so nützt es mir nichts. Die Liebe ist langmütig, ist gütig; die Liebe eifert nicht, sie handelt nicht unbescheiden, sie bläht sich nicht auf; sie ist nicht ehrsüchtig, sucht nicht das ihre, sie lässt sich nicht erbittern, sie rechnet das Böse nicht an; sie freut sich nicht der Ungerechtigkeit, sie freut sich aber mit der Wahrheit; alles erträgt sie, alles glaubt sie, alles hofft sie, alles übersteht sie. Die Liebe hört nie auf, wenn auch die Weissagungen abgetan werden oder die Sprachen ein Ende nehmen, und die Erkenntnis vergehen wird. Denn unser Erkennen ist Stückwerk, und unser Weissagen ist Stückwerk. Wenn aber das Vollkommene kommt, dann wird das, was Stückwerk ist, abgetan werden. Als ich ein Kind war, redete ich wie ein Kind, dachte wie ein Kind, urteilte wie ein Kind; als ich aber Mann ward, legte ich ab, was des Kindes war. Jetzt sehen wir durch einen Spiegel im Rätsel, alsdann aber von Angesicht zu Angesicht. Jetzt ist mein Erkennen Stückwerk, dann aber werde ich erkennen, so wie auch ich erkannt bin. Nun aber bleiben Glaube, Hoffnung Liebe, diese drei; das größte aber unter diesen ist die Liebe.»",
|
||||||
|
"verseData": {
|
||||||
|
"book": "1 Korinther",
|
||||||
|
"chapter": 13,
|
||||||
|
"verses": [
|
||||||
|
{
|
||||||
|
"verse": 1,
|
||||||
|
"text": "Wenn ich mit den Zungen der Menschen und Engel rede, aber die Liebe nicht habe, so bin ich wie ein tönendes Erz oder eine klingende Schelle geworden."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 2,
|
||||||
|
"text": "Und wenn ich die Gabe der Weissagung habe, und kenne alle Geheimnisse und alle Wissenschaft, und wenn ich allen Glauben habe, so dass ich Berge versetzen könnte, die Liebe aber nicht habe, so bin ich nichts."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 3,
|
||||||
|
"text": "Und wenn ich alle meine Habe zur Speisung der Armen austeile, und wenn ich meinen Leib dahingebe, dass ich verbrannt werde, die Liebe aber nicht habe, so nützt es mir nichts."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 4,
|
||||||
|
"text": "Die Liebe ist langmütig, ist gütig; die Liebe eifert nicht, sie handelt nicht unbescheiden, sie bläht sich nicht auf;"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 5,
|
||||||
|
"text": "sie ist nicht ehrsüchtig, sucht nicht das ihre, sie lässt sich nicht erbittern, sie rechnet das Böse nicht an;"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 6,
|
||||||
|
"text": "sie freut sich nicht der Ungerechtigkeit, sie freut sich aber mit der Wahrheit;"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 7,
|
||||||
|
"text": "alles erträgt sie, alles glaubt sie, alles hofft sie, alles übersteht sie."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 8,
|
||||||
|
"text": "Die Liebe hört nie auf, wenn auch die Weissagungen abgetan werden oder die Sprachen ein Ende nehmen, und die Erkenntnis vergehen wird."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 9,
|
||||||
|
"text": "Denn unser Erkennen ist Stückwerk, und unser Weissagen ist Stückwerk."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 10,
|
||||||
|
"text": "Wenn aber das Vollkommene kommt, dann wird das, was Stückwerk ist, abgetan werden."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 11,
|
||||||
|
"text": "Als ich ein Kind war, redete ich wie ein Kind, dachte wie ein Kind, urteilte wie ein Kind; als ich aber Mann ward, legte ich ab, was des Kindes war."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 12,
|
||||||
|
"text": "Jetzt sehen wir durch einen Spiegel im Rätsel, alsdann aber von Angesicht zu Angesicht. Jetzt ist mein Erkennen Stückwerk, dann aber werde ich erkennen, so wie auch ich erkannt bin."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 13,
|
||||||
|
"text": "Nun aber bleiben Glaube, Hoffnung Liebe, diese drei; das größte aber unter diesen ist die Liebe."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const theologicalVirtueVerseDataEn: MysteryDescription = {
|
||||||
|
"title": "The Hymn to Love",
|
||||||
|
"reference": "1 Cor 13:1-13",
|
||||||
|
"text": "«If I speak with the tongues of men and of angels, and have not charity, I am become as sounding brass, or a tinkling cymbal. And if I should have prophecy and should know all mysteries and all knowledge, and if I should have all faith, so that I could remove mountains, and have not charity, I am nothing. And if I should distribute all my goods to feed the poor, and if I should deliver my body to be burned, and have not charity, it profiteth me nothing. Charity is patient, is kind: charity envieth not, dealeth not perversely, is not puffed up, Is not ambitious, seeketh not her own, is not provoked to anger, thinketh no evil: Rejoiceth not in iniquity, but rejoiceth with the truth: Beareth all things, believeth all things, hopeth all things, endureth all things. Charity never falleth away: whether prophecies shall be made void or tongues shall cease or knowledge shall be destroyed. For we know in part: and we prophesy in part. But when that which is perfect is come, that which is in part shall be done away. When I was a child, I spoke as a child, I understood as a child, I thought as a child. But, when I became a man, I put away the things of a child. We see now through a glass in a dark manner: but then face to face. Now I know in part: but then I shall know even as I am known. And now there remain faith, hope, and charity, these three: but the greatest of these is charity.»",
|
||||||
|
"verseData": {
|
||||||
|
"book": "1 Corinthians",
|
||||||
|
"chapter": 13,
|
||||||
|
"verses": [
|
||||||
|
{
|
||||||
|
"verse": 1,
|
||||||
|
"text": "If I speak with the tongues of men and of angels, and have not charity, I am become as sounding brass, or a tinkling cymbal."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 2,
|
||||||
|
"text": "And if I should have prophecy and should know all mysteries and all knowledge, and if I should have all faith, so that I could remove mountains, and have not charity, I am nothing."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 3,
|
||||||
|
"text": "And if I should distribute all my goods to feed the poor, and if I should deliver my body to be burned, and have not charity, it profiteth me nothing."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 4,
|
||||||
|
"text": "Charity is patient, is kind: charity envieth not, dealeth not perversely, is not puffed up,"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 5,
|
||||||
|
"text": "Is not ambitious, seeketh not her own, is not provoked to anger, thinketh no evil:"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 6,
|
||||||
|
"text": "Rejoiceth not in iniquity, but rejoiceth with the truth:"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 7,
|
||||||
|
"text": "Beareth all things, believeth all things, hopeth all things, endureth all things."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 8,
|
||||||
|
"text": "Charity never falleth away: whether prophecies shall be made void or tongues shall cease or knowledge shall be destroyed."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 9,
|
||||||
|
"text": "For we know in part: and we prophesy in part."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 10,
|
||||||
|
"text": "But when that which is perfect is come, that which is in part shall be done away."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 11,
|
||||||
|
"text": "When I was a child, I spoke as a child, I understood as a child, I thought as a child. But, when I became a man, I put away the things of a child."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 12,
|
||||||
|
"text": "We see now through a glass in a dark manner: but then face to face. Now I know in part: but then I shall know even as I am known."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verse": 13,
|
||||||
|
"text": "And now there remain faith, hope, and charity, these three: but the greatest of these is charity."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user