fOERbico/docs/relilab-client-mockup-2026-...

417 lines
830 KiB
HTML
Raw Normal View History

<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>relilab-Schaufenster — Mockup</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&family=Roboto+Condensed:wght@300;400;500;700&family=Yanone+Kaffeesatz:wght@300;400;600;700&display=swap" rel="stylesheet">
<style>
:root{
/* Institutionsfarben - Farbkarte FOERBICO x rpi-virtuell, v2 */
--relilab:#34b2f6; /* Primaerfarbe relilab */
--relilab-tief:#1a8fd0; /* dunklere Stufe fuer Hover und Text auf Weiss */
--magenta:#d225f8; /* Endpunkt des relilab-Gradienten */
--rpi:#0072aa; --foerbico:#203a8f; --fusion:#1a5699; --fau:#04316a;
/* Warm-Spektrum - Akzente */
--amber:#f29422; /* Primaerakzent: Aktionen, Hervorhebungen */
--amber-tief:#d97d13;
--pink:#e54d9a; /* Community-Events, partizipative Formate */
--orange:#ff8103; /* relilab-Orange: Akzent, Gamification */
--mint:#2ecc88; /* Funktionsfarbe: Erfolg, Status */
/* Flaechen und Text */
--rl-text:#1a1e2e; --rl-text-leise:#5a6178;
--rl-dunkel:#04316a; --rl-linie:#e6e9f2; --rl-flaeche:#f6f7fb;
--rl-flaeche-2:#eef0f7; --rl-weiss:#ffffff;
--schatten:0 2px 24px rgba(20,50,100,.08);
--schatten-hover:0 8px 40px rgba(20,50,100,.15);
--verlauf:linear-gradient(135deg,var(--relilab) 0%,var(--magenta) 100%);
--rl-container:1499px; --rl-kopf:120px;
/* Drei Schriften, drei Rollen */
--schrift-text:Roboto,system-ui,-apple-system,"Segoe UI",sans-serif;
--schrift-label:"Roboto Condensed",Roboto,system-ui,sans-serif;
--schrift-ueber:"Yanone Kaffeesatz",Roboto,system-ui,sans-serif;
/* Rueckwaertskompatible Namen */
--rl-blau:var(--relilab); --rl-blau-dunkel:var(--relilab-tief);
}
*{box-sizing:border-box}
body{margin:0;font-family:var(--schrift-text);font-weight:400;color:var(--rl-text);background:var(--rl-weiss);line-height:1.65;font-size:16px;-webkit-font-smoothing:antialiased}
h1,h2,h3,h4,h5,h6{font-family:var(--schrift-ueber);font-weight:700;color:var(--rl-dunkel);line-height:1.15;margin:0 0 .4em}
h1{font-size:clamp(2rem,4vw,3rem)} h2{font-size:clamp(1.6rem,3vw,2.25rem)} h3{font-size:1.35rem}
a{color:var(--relilab-tief);text-decoration:none} a:hover{color:var(--magenta);text-decoration:underline}
img{max-width:100%;display:block}
.container{max-width:var(--rl-container);margin:0 auto;padding:0 24px}
.schmal{max-width:820px}
/* Kopfzeile */
header.kopf{height:var(--rl-kopf);border-bottom:1px solid var(--rl-linie);background:var(--rl-weiss);position:sticky;top:0;z-index:50}
.kopf-innen{height:100%;display:flex;align-items:center;justify-content:space-between;gap:24px}
.marke{font-family:var(--schrift-ueber);font-size:2rem;font-weight:700;color:var(--rl-dunkel);letter-spacing:-.01em}
.marke span{background:var(--verlauf);-webkit-background-clip:text;background-clip:text;color:transparent}
nav.haupt{display:flex;gap:8px;flex-wrap:wrap}
nav.haupt button{font-family:var(--schrift-label);font-size:1.05rem;font-weight:500;letter-spacing:.02em;color:var(--rl-text);background:none;border:0;padding:10px 18px;border-radius:6px;cursor:pointer;transition:background .15s,color .15s}
nav.haupt button:hover{background:var(--rl-flaeche);color:var(--rl-dunkel)}
nav.haupt button[aria-current="page"]{background:var(--relilab);color:var(--fau);font-weight:700}
/* Hinweisleiste Mockup */
.hinweis{background:var(--rl-dunkel);color:#cbd8e6;font-family:var(--schrift-label);font-size:.86rem;padding:8px 0;text-align:center}
.hinweis b{color:#fff}
/* Aufmacher */
.aufmacher{background:var(--verlauf);padding:72px 0 76px;color:#fff;position:relative;overflow:hidden}
.aufmacher::after{content:"";position:absolute;inset:0;background:radial-gradient(ellipse at 78% 15%,rgba(255,255,255,.22),transparent 55%);pointer-events:none}
.aufmacher .container{position:relative;z-index:1}
.aufmacher h1{color:#fff}
.aufmacher .augenbraue{font-family:var(--schrift-label);font-size:.82rem;font-weight:500;letter-spacing:.16em;text-transform:uppercase;color:rgba(255,255,255,.82);margin:0 0 14px}
.aufmacher p.unter{font-size:1.18rem;max-width:680px;margin:0;color:rgba(255,255,255,.94);font-weight:300}
/* Raster */
.raster{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:28px}
.karte{background:var(--rl-weiss);border:1px solid var(--rl-linie);border-radius:10px;overflow:hidden;display:flex;flex-direction:column;transition:box-shadow .18s,transform .18s;cursor:pointer;text-align:left;padding:0;font:inherit;color:inherit;width:100%}
.karte:hover{box-shadow:var(--schatten-hover);transform:translateY(-3px);border-color:transparent}
.karte-bild{aspect-ratio:16/9;background:var(--rl-flaeche);display:flex;align-items:center;justify-content:center;overflow:hidden;border-bottom:1px solid var(--rl-linie)}
/* Bilder sind 150x150-Thumbnails - zentriert statt verzerrt */
.karte-bild img{width:96px;height:96px;object-fit:cover;border-radius:8px}
.karte-innen{padding:20px;display:flex;flex-direction:column;gap:10px;flex:1}
.karte h3{margin:0;font-size:1.3rem}
.karte .anriss{font-size:.93rem;margin:0;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.meta{font-family:var(--schrift-label);font-size:.86rem;color:var(--rl-text-leise);display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin-top:auto;padding-top:8px}
.marker{font-family:var(--schrift-label);display:inline-block;background:var(--rl-flaeche-2);color:var(--rl-text-leise);border-radius:999px;padding:3px 11px;font-size:.78rem;font-weight:500;letter-spacing:.01em}
.marker.pink{background:rgba(229,77,154,.13);color:#c22e7d}
.marker.mint{background:rgba(46,204,136,.15);color:#1a9c63}
.marker.amber{background:rgba(242,148,34,.16);color:var(--amber-tief)}
.marker.blau{background:rgba(52,178,246,.14);color:var(--relilab-tief)}
/* Termin-Datumsblock */
.termin{display:flex;gap:18px;align-items:flex-start;padding:20px;border:1px solid var(--rl-linie);border-radius:10px;background:#fff;cursor:pointer;text-align:left;font:inherit;color:inherit;width:100%;transition:box-shadow .18s}
.termin:hover{box-shadow:var(--schatten-hover);border-color:transparent}
.datum{flex:0 0 76px;text-align:center;background:rgba(229,77,154,.09);border-radius:8px;padding:10px 6px}
.datum .tag{font-family:var(--schrift-ueber);font-size:2.1rem;font-weight:700;color:var(--pink);line-height:1}
.datum .monat{font-family:var(--schrift-label);font-size:.75rem;font-weight:500;text-transform:uppercase;letter-spacing:.08em;color:var(--rl-text)}
.datum .jahr{font-family:var(--schrift-label);font-size:.72rem;color:var(--rl-text-leise)}
.termin.vergangen .datum{background:var(--rl-flaeche-2)}
.termin.vergangen .datum .tag{color:#93a0b8}
.termin-bild{flex:0 0 76px;height:76px;border-radius:8px;overflow:hidden;background:var(--rl-flaeche);display:flex;align-items:center;justify-content:center}
.termin-bild img{width:100%;height:100%;object-fit:cover}
.termin-bild span{font-family:var(--schrift-ueber);font-size:.95rem;color:#c3d2e0}
.termin.vergangen .termin-bild img{filter:grayscale(.55);opacity:.75}
.termin-txt{flex:1;min-width:0}
.termin-txt h3{font-size:1.15rem;margin:0 0 6px}
/* Filterleiste */
.filter{display:flex;flex-wrap:wrap;gap:8px;padding:20px 0;border-bottom:1px solid var(--rl-linie);margin-bottom:32px}
.filter button{font-family:var(--schrift-label);font-size:.9rem;font-weight:500;border:1px solid var(--rl-linie);background:#fff;color:var(--rl-text);padding:7px 15px;border-radius:999px;cursor:pointer;transition:all .15s}
.filter button:hover{border-color:var(--amber);color:var(--amber-tief)}
.filter button[aria-pressed="true"]{background:var(--amber);border-color:var(--amber);color:var(--fau);font-weight:700}
.umschalter{display:inline-flex;border:1px solid var(--rl-linie);border-radius:8px;overflow:hidden;margin-bottom:24px}
.umschalter button{font-family:var(--schrift-label);font-size:.95rem;font-weight:500;border:0;background:#fff;color:var(--rl-text);padding:9px 22px;cursor:pointer}
.umschalter button[aria-pressed="true"]{background:var(--relilab);color:var(--fau);font-weight:700}
/* Aufmacher zweispaltig: Text und Bewegtbild */
.aufmacher-raster{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);gap:48px;align-items:center}
.aufmacher-bild{margin:0;border-radius:14px;overflow:hidden;box-shadow:0 12px 44px rgba(4,49,106,.28);background:rgba(255,255,255,.14);aspect-ratio:16/9}
.aufmacher-bild img{width:100%;height:100%;object-fit:cover;display:block}
/* Knoepfe im Verlauf Magenta -> Orange, wie auf relilab.org */
.knopf{display:inline-block;font-family:var(--schrift-label);font-size:1.06rem;font-weight:700;
color:#fff;text-decoration:none;padding:11px 24px;border-radius:6px;letter-spacing:.01em;
background:linear-gradient(90deg,var(--magenta) 0%,var(--pink) 50%,#e8721a 100%);
text-shadow:0 1px 2px rgba(90,20,0,.35);
box-shadow:0 3px 14px rgba(210,37,248,.26);transition:transform .15s,box-shadow .15s}
.knopf:hover{transform:translateY(-2px);box-shadow:0 7px 22px rgba(210,37,248,.36);color:#fff;text-decoration:none}
.knopf-hell{margin-top:26px;background:#fff;color:#a512c4;font-weight:700;text-shadow:none;box-shadow:0 4px 18px rgba(4,49,106,.22)}
.knopf-hell:hover{color:#8d0fa8}
.knopf-gross{border-radius:999px;padding:13px 32px;font-size:1.05rem}
/* Die vier Kaesten */
.kaesten{display:grid;grid-template-columns:repeat(auto-fit,minmax(420px,1fr));gap:26px;max-width:1180px;margin:0 auto}
.kasten{background:#fff;border:1px solid var(--rl-linie);border-radius:12px;padding:30px 32px 32px;box-shadow:var(--schatten)}
.kasten h2{font-size:1.9rem;margin:0 0 16px}
.kasten p{margin:0 0 22px;color:var(--rl-text)}
.kasten-knoepfe{display:flex;flex-wrap:wrap;gap:12px}
.newsletter{text-align:center;margin-top:40px}
section.block{padding:56px 0}
section.block.grau{background:var(--rl-flaeche);border-top:1px solid var(--rl-linie);border-bottom:1px solid var(--rl-linie)}
.block-kopf{display:flex;justify-content:space-between;align-items:baseline;gap:16px;margin-bottom:28px;flex-wrap:wrap}
.block-kopf h2{margin:0}
.augenbraue.dunkel{font-family:var(--schrift-label);font-size:.8rem;font-weight:500;letter-spacing:.14em;text-transform:uppercase;color:var(--relilab-tief);margin:0 0 6px}
.liste{display:flex;flex-direction:column;gap:14px}
/* Detailansicht */
.detail-kopf{padding:40px 0 28px;border-bottom:1px solid var(--rl-linie);margin-bottom:32px}
.zurueck{background:none;border:0;color:var(--relilab-tief);font-family:var(--schrift-label);font-size:.95rem;font-weight:500;cursor:pointer;padding:0;margin-bottom:20px}
.zurueck:hover{text-decoration:underline}
.inhalt{font-size:1.02rem}
.inhalt h1,.inhalt h2,.inhalt h3,.inhalt h4,.inhalt h5,.inhalt h6{margin-top:1.6em}
.inhalt h5,.inhalt h6{font-size:1.1rem}
.inhalt img{border-radius:8px;margin:1.4em 0}
.inhalt ul,.inhalt ol{padding-left:1.4em}
.inhalt blockquote{border-left:3px solid var(--relilab);margin:1.4em 0;padding:.4em 0 .4em 1.2em;color:var(--rl-text-leise)}
.inhalt code{background:var(--rl-flaeche);padding:2px 6px;border-radius:4px;font-size:.9em}
.inhalt pre{background:var(--rl-flaeche);padding:16px;border-radius:8px;overflow-x:auto}
.inhalt table{width:100%;border-collapse:collapse;margin:1.4em 0}
.inhalt td,.inhalt th{border:1px solid var(--rl-linie);padding:8px 12px;text-align:left}
.herkunft{background:var(--rl-flaeche);border-left:3px solid var(--amber);border-radius:0 8px 8px 0;padding:16px 20px;font-size:.92rem;margin:32px 0}
.herkunft strong{color:var(--rl-dunkel)}
footer.fuss{background:var(--rl-dunkel);color:#a8bccf;padding:48px 0;margin-top:64px;font-size:.92rem;font-weight:300}
footer.fuss a{color:var(--relilab)}
footer.fuss .marke{color:#fff;margin-bottom:12px}
footer.fuss .marke span{background:linear-gradient(135deg,var(--relilab) 0%,#f28ffb 100%);-webkit-background-clip:text;background-clip:text;color:transparent}
.leer{padding:48px;text-align:center;color:var(--rl-text-leise);background:var(--rl-flaeche);border-radius:10px}
.zaehler{font-family:var(--schrift-label);font-size:.92rem;color:var(--rl-text-leise)}
@media(max-width:640px){
:root{--rl-kopf:auto}
header.kopf{position:static}
.kopf-innen{flex-direction:column;align-items:flex-start;padding:16px 0;gap:12px}
section.block{padding:36px 0}
.termin-bild{display:none}
.aufmacher-raster{grid-template-columns:1fr;gap:32px}
.kasten{padding:24px}
}
</style>
</head>
<body>
<div class="hinweis container-voll">
<b>Mockup</b> — statisches Abbild mit <b>111 echten Events</b> von relay.edufeed.org (61 Artikel, 50 Termine). Kein Relay-Zugriff im Browser.
</div>
<header class="kopf">
<div class="container kopf-innen">
<div class="marke">reli<span>lab</span></div>
<nav class="haupt" id="nav"></nav>
</div>
</header>
<main id="app"></main>
<footer class="fuss">
<div class="container">
<div class="marke fuss-marke">reli<span>lab</span></div>
<p>Schaufenster auf Nostr — Inhalte stammen aus dem Relay <code>relay.edufeed.org</code>,
gespiegelt von <a href="https://relilab.org">relilab.org</a>.</p>
<p style="margin-top:20px;font-size:.82rem;opacity:.75">Mockup zur Gestaltungsabstimmung. Farben und Schriften nach dem Designsystem <span style="white-space:nowrap">FOERBICO&nbsp;×&nbsp;rpi-virtuell</span> (Farbfusion &amp; Typografie-Konzept v2).</p>
</div>
</footer>
<script>
const DATEN = {"artikel":[{"id":"23530be7fe35659b075fb7683abb7c76f269f97596d7b7ec94da07a9783fa6ce","titel":"Schulgottesdienst Schuljahresende 2026","anriss":"Mach mal Pause! sagt Jesus zu 5000 Menschen und lädt sie ein zum Picknick am See. PAUSE machen verändert meine Wahrnehmung. Ich kann spüren: Kurzbeschreibung Der Schulgottesdienst zum Schuljahresende 2026 steht unter dem Titel „Mach mal Pause!“ und greift die biblische Geschichte der Speisung der 5000 aus Johannes 6 auf. Die umfangreiche Sammlung bietet zahlreiche Bausteine \\[…\\]","bild":"https://relilab.org/wp-content/uploads/2026/05/image-150x150.png","datum":1779296912,"themen":["elternarbeit","neues testament","schuljahresende","oer communities","schulgottesdienst","wahrnehmung","relilab"],"quelle":"https://relilab.org/schulgottesdienst-schuljahresende-2026/","autor":"Corinna Link","body":"> generiert mit ChatGPT, Lizenz CC0, Mai 2026\n\n## Mach mal Pause! sagt Jesus zu 5000 Menschen und lädt sie ein zum Picknick am See.\n\n**PAUSE machen verändert meine Wahrnehmung.**\n\nIch kann spüren:\n\n* Wie geht es mir gerade?\n* Was macht mich satt?\n* Und was bleibt am Ende des Schuljahres übrig?\n\n##### Kurzbeschreibung\n\nDer Schulgottesdienst zum Schuljahresende 2026 steht unter dem Titel **„Mach mal Pause!“** und greift die biblische Geschichte der Speisung der 5000 aus Johannes 6 auf.\n\nDie umfangreiche Sammlung bietet zahlreiche Bausteine für einen lebendigen und praxisnahen Gottesdienst: von Begrüßung, Musik und Gebeten über kreative Erzählformen bis hin zu Fürbitten, Segensmomenten und einem „Sprühsegen“ zum Abschluss. Neben einem vollständigen Ablauf finden sich unterschiedliche Varianten einzelner Elemente etwa als Kamishibai, Anspiel oder Playmobil-Fotostory sodass der Gottesdienst flexibel an Schulform, Altersgruppe und Zeitrahmen angepasst werden kann.\n\n[Schulgottesdienst 2026 Mach mal Pause!-3](https://relilab.org/wp-content/uploads/2026/05/Schulgottesdienst-2026-Mach-mal-Pause-3.pdf)[Herunterladen](https://relilab.org/wp-content/uploads/2026/05/Schulgottesdienst-2026-Mach-mal-Pause-3.pdf)\n\n[Schulgottesdienst 2026 Mach mal Pause!](https://relilab.org/wp-content/uploads/2026/05/Schulgottesdienst-2026-Mach-mal-Pause-2.docx)[Herunterladen](https://relilab.org/wp-content/uploads/2026/05/Schulgottesdienst-2026-Mach-mal-Pause-2.docx)\n\n[Einladung Elternbrief](https://relilab.org/wp-content/uploads/2026/05/Einladung-Elternbrief-2.docx)[Herunterladen](https://relilab.org/wp-content/uploads/2026/05/Einladung-Elternbrief-2.docx)\n\n##### Community zusammen weiterdenken\n\nDu hast Fragen oder willst gern noch weitere Ideen mit uns teilen?  \n\n Vielleicht hast du Lust uns von eurem Schulgottesdienst  \n zu erzählen und ein paar Fotos zu schicken?\n\n##### Kontakt\n\n **Wenn du magst, nimm gern Kontakt mit uns auf:**\n\nPfarrerin Christina Hinderer \n Apostelkirche Weilheim \n ![](blob:https://relilab.org/5c58dca4-e198-4589-978c-5d3f9d5a3b04) [christina.hinderer@elkb.de](mailto:christina.hinderer@elkb.de) \n ![](blob:https://relilab.org/417bd250-69d3-4fad-a44b-f37b32e32db4) 0881-929 151 \n ![](blob:https://relilab.org/0d7f2846-624a-4026-8a47-6deb1526e201)@segens\\_reich\n\nReligionspädagogin Ulrike Schramm \n Religionspädagogischer Arbeitskreis Dekanat Weilheim \n ![](blob:https://relilab.org/587a628f-d8e7-4b57-9055-97acc2d034a9)[ulrike.schramm@elkb.de](mailto:ulrike.schramm@elkb.de) \n ![](blob:https://relilab.org/f8c86540-8cb6-4960-9a05-f3235712d149) @segen\\_glitzert\n\nBilder: KI generiert \n Texte: Christina Hinderer \n Ideen: ökumenische Schulgottesdienstwerkstatt  \n Mai 2026, Weilheim in Oberbayern\n\nAutorinnen: Christina Hinderer, Ulrike Schramm \nWeiternutzung als OER ausdrücklich erlaubt: Dieses Werk und dessen Inhalte sind sofern nicht anders angegeben lizenziert unter CC BY SA 4.0. Nennung gemäß TULLU-Regel bitte wie folgt: „Schulgottesdienst-Schuljahresende 2026. Mach mal Pause.“ | Christina Minderer, Ulrike Schramm| re
</script>
<script>
const F = {
datum: ts => new Date(ts*1000).toLocaleDateString('de-DE',{day:'numeric',month:'long',year:'numeric'}),
tag: ts => new Date(ts*1000).toLocaleDateString('de-DE',{day:'2-digit'}),
monat: ts => new Date(ts*1000).toLocaleDateString('de-DE',{month:'short'}).replace('.',''),
jahr: ts => new Date(ts*1000).getFullYear(),
zeit: ts => new Date(ts*1000).toLocaleTimeString('de-DE',{hour:'2-digit',minute:'2-digit'}),
};
const esc = s => (s||'').replace(/[&<>"]/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;'}[c]));
const jetzt = Math.floor(Date.now()/1000);
// Ortsangaben sind uneinheitlich: "Zoom: https://...", nackte URLs, echte Orte
function ortKurz(o){
if(!o) return '';
const t = o.replace(/^(Zoom|Online|Ort)\s*:\s*/i,'').trim();
return /^https?:\/\//.test(t) ? 'Online' : (t.length>48 ? t.slice(0,46)+'…' : t);
}
// Minimaler Markdown-Renderer fuer die Detailansicht
function md(s){
if(!s) return '';
const zeilen = s.split('\n'); let out=[], inListe=null, inCode=false;
const inline = t => esc(t)
.replace(/!\[([^\]]*)\]\(([^)]+)\)/g,'<img src="$2" alt="$1">')
.replace(/\[([^\]]+)\]\(([^)]+)\)/g,'<a href="$2" target="_blank" rel="noopener">$1</a>')
.replace(/\*\*([^*]+)\*\*/g,'<strong>$1</strong>')
.replace(/(^|[^*])\*([^*]+)\*/g,'$1<em>$2</em>')
.replace(/`([^`]+)`/g,'<code>$1</code>');
const schliessen = ()=>{ if(inListe){out.push(`</${inListe}>`); inListe=null;} };
for(let z of zeilen){
if(/^```/.test(z)){ schliessen(); out.push(inCode?'</pre>':'<pre>'); inCode=!inCode; continue; }
if(inCode){ out.push(esc(z)); continue; }
const h = z.match(/^(#{1,6})\s+(.*)/);
if(h){ schliessen(); const n=Math.min(h[1].length+1,6);
out.push(`<h${n}>${inline(h[2])}</h${n}>`); continue; }
if(/^>\s?/.test(z)){ schliessen(); out.push(`<blockquote>${inline(z.replace(/^>\s?/,''))}</blockquote>`); continue; }
if(/^\|/.test(z)){
if(/^\|[\s:|-]+\|?\s*$/.test(z)) continue; // Trennzeile der Tabelle
const zellen = z.split('|').slice(1,-1).map(c=>`<td>${inline(c.trim())}</td>`).join('');
if(inListe!=='table'){ schliessen(); out.push('<table>'); inListe='table'; }
out.push(`<tr>${zellen}</tr>`); continue;
}
const ul = z.match(/^[-*]\s+(.*)/), ol = z.match(/^\d+\.\s+(.*)/);
if(ul){ if(inListe!=='ul'){schliessen();out.push('<ul>');inListe='ul';} out.push(`<li>${inline(ul[1])}</li>`); continue; }
if(ol){ if(inListe!=='ol'){schliessen();out.push('<ol>');inListe='ol';} out.push(`<li>${inline(ol[1])}</li>`); continue; }
if(!z.trim()){ schliessen(); continue; }
schliessen(); out.push(`<p>${inline(z)}</p>`);
}
schliessen(); return out.join('\n');
}
// Texte und Ziele der vier Kaesten von relilab.org uebernommen
const KAESTEN = [
{ titel:'Wer wir sind',
text:'Das relilab ist das, was du daraus machst. Wenn du Teilnehmer*innen fragst, wirst du ganz unterschiedliche Antworten erhalten.',
knoepfe:[['Lerne uns kennen!','https://relilab.org/wer-wir-sind/']] },
{ titel:'Wie wir arbeiten',
text:'Du bist auf der Suche nach Strukturen um religionsbezogene Bildung voranzubringen. Lass dich in unserem Netzwerk inspirieren.',
knoepfe:[['Lass dich inspirieren!','https://relilab.org/wiewirarbeiten']] },
{ titel:'Was wir tun',
text:'Entdecke die verschiedenen <a href="https://relilab.org/termine/" target="_blank" rel="noopener">synchronen</a> und <a href="https://relilab.org/category/formate-asynchron/lernmodul/" target="_blank" rel="noopener">asynchronen</a> Anlässe, die dich zum Lernen inspirieren möchten.',
knoepfe:[['synchrone Anlässe','https://relilab.org/termine/'],
['asynchrone Anlässe','https://relilab.org/category/formate-asynchron/lernmodul/']] },
{ titel:'Mitmachen',
text:'Du entscheidest, wie du hier lernst. Hier kannst du dich über die verschiedenen Möglichkeiten informieren.',
knoepfe:[['Deine Möglichkeiten','https://relilab.org/mitmachen/'],
['relilab.context','https://relilab.org/context/']] }
];
let zustand = { ansicht:'start', thema:null, richtung:'kommend', detail:null };
const bild = (b,alt) => b
? `<div class="karte-bild"><img src="${esc(b)}" alt="${esc(alt)}" loading="lazy"></div>`
: `<div class="karte-bild"><span style="font-family:var(--schrift-ueber);font-size:2.4rem;color:#c3d2e0">relilab</span></div>`;
function karteArtikel(a){
return `<button class="karte" onclick="oeffne('a','${a.id}')">
${bild(a.bild,a.titel)}
<div class="karte-innen">
<h3>${esc(a.titel)}</h3>
<p class="anriss">${esc(a.anriss)}</p>
<div class="meta"><span>${F.datum(a.datum)}</span>
${a.themen.slice(0,2).map(t=>`<span class="marker">${esc(t)}</span>`).join('')}</div>
</div></button>`;
}
function zeileTermin(t){
const vorbei = t.start < jetzt;
return `<button class="termin ${vorbei?'vergangen':''}" onclick="oeffne('t','${t.id}')">
<div class="datum"><div class="tag">${F.tag(t.start)}</div>
<div class="monat">${F.monat(t.start)}</div><div class="jahr">${F.jahr(t.start)}</div></div>
<div class="termin-bild">${t.bild
? `<img src="${esc(t.bild)}" alt="" loading="lazy">`
: `<span aria-hidden="true">relilab</span>`}</div>
<div class="termin-txt"><h3>${esc(t.titel)}</h3>
<div class="meta"><span>${F.zeit(t.start)} Uhr</span>
${t.ort?`<span class="marker pink">${esc(ortKurz(t.ort))}</span>`:''}
${vorbei?'<span class="marker">vergangen</span>':''}</div>
</div></button>`;
}
const filterleiste = () => `<div class="filter">
<button aria-pressed="${!zustand.thema}" onclick="setThema(null)">Alle</button>
${DATEN.themen.map(t=>`<button aria-pressed="${zustand.thema===t}" onclick="setThema('${esc(t)}')">${esc(t)}</button>`).join('')}
</div>`;
const nachThema = xs => zustand.thema ? xs.filter(x=>x.themen.includes(zustand.thema)) : xs;
const ANSICHTEN = {
start(){
const artikel = DATEN.artikel.slice(0,6);
const kommend = DATEN.termine.filter(t=>t.start>=jetzt).sort((a,b)=>a.start-b.start).slice(0,5);
return `<div class="aufmacher"><div class="container aufmacher-raster">
<div>
<p class="augenbraue">relilab · Schaufenster im Nostr-Netz</p>
<h1>Gemeinsam religionsbezogene Bildung ermöglichen.</h1>
<p class="unter">Lernmodule, Beiträge und Fortbildungen aus dem relilab — als offene Inhalte im Nostr-Netz, lesbar überall.</p>
<a class="knopf knopf-hell" href="https://relilab.org/live" target="_blank" rel="noopener">👉 Am Live-Anlass teilnehmen 👈</a>
</div>
<figure class="aufmacher-bild">
<img src="https://relilab.org/wp-content/uploads/2024/09/White-Minimal-Jewelry-Channel-Intro-Outro-Youtube-Video-1.gif"
alt="Animiertes relilab-Intro" loading="lazy" decoding="async" width="1920" height="1080">
</figure>
</div></div>
<section class="block"><div class="container">
<div class="block-kopf"><div><p class="augenbraue dunkel">Material &amp; Praxis</p><h2>Aktuelle Beiträge</h2></div>
<button class="zurueck" onclick="geh('artikel')">Alle ${DATEN.artikel.length} Beiträge →</button></div>
<div class="raster">${artikel.map(karteArtikel).join('')}</div>
</div></section>
<section class="block"><div class="container">
<div class="block-kopf"><div><p class="augenbraue dunkel">Fortbildung &amp; Austausch</p><h2>Kommende Termine</h2></div>
<button class="zurueck" onclick="geh('termine')">Alle Termine →</button></div>
<div class="liste">${kommend.map(zeileTermin).join('')}</div>
</div></section>
<section class="block grau"><div class="container">
<div class="kaesten">
${KAESTEN.map(k=>`<article class="kasten">
<h2>${esc(k.titel)}</h2>
<p>${k.text}</p>
<div class="kasten-knoepfe">${k.knoepfe.map(b=>
`<a class="knopf" href="${esc(b[1])}" target="_blank" rel="noopener">${esc(b[0])}</a>`).join('')}</div>
</article>`).join('')}
</div>
<div class="newsletter">
<a class="knopf knopf-gross" href="https://relilab.org/newsletter/" target="_blank" rel="noopener">👉 Anmeldung zum Newsletter 👈</a>
</div>
</div></section>`;
},
artikel(){
const xs = nachThema(DATEN.artikel);
return `<section class="block"><div class="container">
<h1>Beiträge und Lernmodule</h1>
${filterleiste()}
<p class="zaehler" style="margin:-16px 0 24px">${xs.length} ${xs.length===1?'Beitrag':'Beiträge'}${zustand.thema?` zum Thema „${esc(zustand.thema)}“`:''}</p>
${xs.length?`<div class="raster">${xs.map(karteArtikel).join('')}</div>`
:`<div class="leer">Keine Beiträge zu diesem Thema.</div>`}
</div></section>`;
},
termine(){
let xs = nachThema(DATEN.termine);
xs = zustand.richtung==='kommend'
? xs.filter(t=>t.start>=jetzt).sort((a,b)=>a.start-b.start)
: xs.filter(t=>t.start<jetzt).sort((a,b)=>b.start-a.start);
return `<section class="block"><div class="container">
<h1>Termine</h1>
<div class="umschalter">
<button aria-pressed="${zustand.richtung==='kommend'}" onclick="setRichtung('kommend')">Kommende</button>
<button aria-pressed="${zustand.richtung==='vergangen'}" onclick="setRichtung('vergangen')">Vergangene</button>
</div>
${filterleiste()}
<p class="zaehler" style="margin:-16px 0 24px">${xs.length} ${xs.length===1?'Termin':'Termine'}${zustand.thema?` zum Thema „${esc(zustand.thema)}“`:''}</p>
${xs.length?`<div class="liste">${xs.map(zeileTermin).join('')}</div>`
:`<div class="leer">Keine Termine in diesem Zeitraum.</div>`}
</div></section>`;
},
detail(){
const {art,obj} = zustand.detail;
const ist_t = art==='t';
return `<div class="container schmal">
<div class="detail-kopf">
<button class="zurueck" onclick="geh('${ist_t?'termine':'artikel'}')">← Zurück zur Übersicht</button>
<h1>${esc(obj.titel)}</h1>
<div class="meta" style="margin-top:14px">
${ist_t
? `<span class="marker pink">${F.datum(obj.start)}, ${F.zeit(obj.start)} Uhr</span>
${obj.ort?`<span class="marker pink">${esc(ortKurz(obj.ort))}</span>`:''}`
: `<span>${F.datum(obj.datum)}</span>${obj.autor?`<span>von ${esc(obj.autor)}</span>`:''}`}
${obj.themen.filter(t=>DATEN.themen.includes(t)).slice(0,4).map(t=>`<span class="marker">${esc(t)}</span>`).join('')}
</div>
</div>
${obj.bild?`<img src="${esc(obj.bild)}" alt="" style="width:140px;height:140px;object-fit:cover;border-radius:10px;margin-bottom:28px">`:''}
<div class="inhalt">${md(obj.body)}</div>
<div class="herkunft">
<strong>Herkunft.</strong> ${obj.autor?`Erstellt von ${esc(obj.autor)}, u`:'U'}rsprünglich veröffentlicht auf
${obj.quelle?`<a href="${esc(obj.quelle)}" target="_blank" rel="noopener">relilab.org</a>`:'relilab.org'}.
Dieser Beitrag liegt als Nostr-Event vor und ist unter einer stabilen <code>naddr</code>-Adresse erreichbar.
</div>
</div>`;
}
};
function zeichne(){
document.getElementById('app').innerHTML = ANSICHTEN[zustand.ansicht]();
document.getElementById('nav').innerHTML = [['start','Start'],['artikel','Beiträge'],['termine','Termine']]
.map(([k,l])=>`<button ${zustand.ansicht===k?'aria-current="page"':''} onclick="geh('${k}')">${l}</button>`).join('');
window.scrollTo(0,0);
}
function geh(a){ zustand.ansicht=a; zustand.detail=null; zeichne(); }
function setThema(t){ zustand.thema=t; zeichne(); }
function setRichtung(r){ zustand.richtung=r; zeichne(); }
function oeffne(art,id){
const obj = (art==='t'?DATEN.termine:DATEN.artikel).find(x=>x.id===id);
zustand.detail={art,obj}; zustand.ansicht='detail'; zeichne();
}
zeichne();
</script>
</body>
</html>