Files
geograsim/App/sims/weltkueche/preview.html
T
Adminator 1e51ef7def Nachtrag: alle bisher untracked Ordner + hängende Änderungen mit-committen
- Konzept/, didaktik_geografie/, didaktik_simulation/, v2-modules/, v2-platform/
- 12 code-workspace-Files
- STATUS-*.md
- viele M/D/R-Änderungen an bereits getrackten Files
- .gitignore verstärkt: **/.humaninput/, **/secret_keys.txt

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-08 02:27:02 +02:00

129 lines
7.3 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Weltküche · Vorschau aller 30 Gerichte</title>
<style>
:root { --moss:#1f4b37; --sage:#4a7c4e; --sand:#e8c547; --beige:#e8e4d8; --ink:#2a2a2a; --muted:#6a6a6a; --line:rgba(0,0,0,.08); }
*{box-sizing:border-box}
body{font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;background:var(--beige);color:var(--ink);margin:0;padding:1.2rem;line-height:1.5}
.wrap{max-width:1280px;margin:0 auto}
h1{font-size:1.8rem;margin:0 0 .3rem;color:var(--moss);letter-spacing:-.01em}
.sub{color:var(--muted);font-size:.85rem;margin-bottom:1.5rem}
.filter{display:flex;gap:.5rem;margin-bottom:1.5rem;flex-wrap:wrap}
.filter button{padding:.4rem .9rem;border:1.5px solid var(--line);background:#fff;border-radius:18px;font-size:.78rem;font-weight:700;cursor:pointer;color:var(--ink)}
.filter button.active{background:var(--moss);color:#fff;border-color:var(--moss)}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1rem}
.dish{background:#fff;border-radius:12px;border:1px solid var(--line);overflow:hidden;display:flex;flex-direction:column}
.dish img{width:100%;height:240px;object-fit:cover;background:var(--beige);display:block}
.dish img.missing{opacity:0.3}
.dish-body{padding:.9rem 1rem 1rem;flex:1;display:flex;flex-direction:column}
.dish-head{display:flex;align-items:flex-start;gap:.5rem;margin-bottom:.3rem}
.dish-emoji{font-size:1.6rem;line-height:1}
.dish-name{font-weight:800;font-size:1.05rem;color:var(--moss);flex:1}
.dish-origin{font-size:.74rem;color:var(--muted);margin-bottom:.6rem;font-weight:600}
.dish-tags{display:flex;gap:.3rem;flex-wrap:wrap;margin-bottom:.6rem}
.tag{font-size:.65rem;background:var(--beige);padding:.15rem .5rem;border-radius:8px;color:var(--muted);font-weight:600}
.dish-nutrition{display:grid;grid-template-columns:repeat(3,1fr);gap:.3rem;font-size:.7rem;margin-bottom:.7rem;background:var(--beige);padding:.5rem;border-radius:6px}
.dish-nutrition span{display:flex;justify-content:space-between}
.dish-nutrition b{color:var(--moss)}
details{margin-bottom:.5rem;font-size:.78rem;border-top:1px dashed var(--line);padding-top:.5rem}
details summary{cursor:pointer;color:var(--sage);font-weight:700;font-size:.74rem;text-transform:uppercase;letter-spacing:.04em}
details ol{margin:.4rem 0 .3rem;padding-left:1.3rem;font-size:.72rem;line-height:1.5}
details li{margin-bottom:.3rem}
.ings{display:flex;gap:.25rem;flex-wrap:wrap;font-size:.65rem;color:var(--muted)}
.ings code{background:var(--beige);padding:.05rem .35rem;border-radius:4px;font-family:monospace}
.fact{font-size:.75rem;color:var(--muted);font-style:italic;margin-top:auto;padding-top:.5rem;border-top:1px dashed var(--line)}
.category-badge{display:inline-block;font-size:.64rem;padding:.1rem .45rem;border-radius:8px;font-weight:700;letter-spacing:.03em;text-transform:uppercase}
.category-badge.regional-at{background:#d4e6da;color:#1f4b37}
.category-badge.dach{background:#f0e2c3;color:#8a6516}
.category-badge.europa{background:#eee5ed;color:#5a3a6a}
.category-badge.exotisch{background:#efd6cb;color:#9c4d2e}
</style>
</head>
<body>
<div class="wrap">
<h1>🍽 Weltküche — Vorschau aller 30 Gerichte</h1>
<p class="sub">Tranche A (5 AT-regional) · B (10 DACH) · C (10 Europa) · D (5 exotisch). Bild-Status wird live geladen.</p>
<div class="filter" id="filter">
<button data-cat="all" class="active">Alle (30)</button>
<button data-cat="regional-at">🇦🇹 AT-regional (5)</button>
<button data-cat="dach">🇦🇹🇩🇪🇨🇭 DACH (10)</button>
<button data-cat="europa">🇪🇺 Europa (10)</button>
<button data-cat="exotisch">🌍 Exotisch (5)</button>
</div>
<div class="grid" id="grid">Lade…</div>
</div>
<script>
async function loadJson(path) {
try { const r = await fetch(path); return await r.json(); }
catch(e) { return {}; }
}
function esc(s){return String(s||'').replace(/[<>&"]/g,c=>({'<':'&lt;','>':'&gt;','&':'&amp;','"':'&quot;'}[c]));}
function renderDish(id, d) {
const n = d.nutrition || {};
const r = d.recipe || {};
return `<div class="dish" data-cat="${d.category}">
<img src="${d.imagePath}" alt="${esc(d.name)}" onerror="this.classList.add('missing');this.src='data:image/svg+xml;utf8,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 60%22><rect fill=%22%23e8e4d8%22 width=%22100%22 height=%2260%22/><text x=%2250%22 y=%2235%22 text-anchor=%22middle%22 font-family=%22sans-serif%22 font-size=%228%22 fill=%22%236a6a6a%22>kein Bild</text></svg>';">
<div class="dish-body">
<div class="dish-head">
<span class="dish-emoji">${d.emoji}</span>
<span class="dish-name">${esc(d.name)}</span>
<span class="category-badge ${d.category}">${d.category}</span>
</div>
<div class="dish-origin">📍 ${esc(d.origin)} · <strong>${d.diff}</strong>${d.diff_note?' · <span style="color:var(--muted);font-weight:400">'+esc(d.diff_note)+'</span>':''}</div>
<div class="dish-tags">${(d.tags||[]).map(t=>'<span class="tag">'+esc(t)+'</span>').join('')}</div>
<div class="dish-nutrition">
<span>kcal <b>${n.kcal||''}</b></span>
<span>Eiweiß <b>${n.protein_g||''} g</b></span>
<span>KH <b>${n.carbs_g||''} g</b></span>
<span>Fett <b>${n.fat_g||''} g</b></span>
<span>Ballast <b>${n.fiber_g||''} g</b></span>
<span>Salz <b>${n.salt_g||''} g</b></span>
</div>
<details>
<summary>📋 Rezept (${r.portions||'?'} Portionen, ${r.time_min||'?'} min)</summary>
<ol>${(r.steps||[]).map(s=>'<li>'+esc(s)+'</li>').join('')}</ol>
${r.tipp?'<p style="font-size:.72rem;color:var(--moss)"><b>💡 Tipp:</b> '+esc(r.tipp)+'</p>':''}
</details>
<details>
<summary>📚 Lehrplan-Bezug</summary>
${Object.entries(d.lehrplan||{}).map(([k,v])=>'<p style="font-size:.72rem;margin:.3rem 0"><b>'+k.toUpperCase()+':</b> '+esc(v)+'</p>').join('')}
</details>
<details>
<summary>🧪 Welt-Zutaten + Pantry</summary>
<p style="font-size:.72rem;margin:.3rem 0"><b>Welt-Zutaten:</b> <span class="ings">${(d.ings||[]).map(i=>'<code>'+esc(i)+'</code>').join(' ')}</span></p>
<p style="font-size:.72rem;margin:.3rem 0"><b>Pantry (lokal):</b> ${(d.pantry||[]).map(esc).join(', ')}</p>
</details>
<p class="fact">💡 ${esc(d.fact)}</p>
</div>
</div>`;
}
async function init() {
const [a, b, c, dd] = await Promise.all([
loadJson('assets/data/dishes.json'),
loadJson('assets/data/dishes-tranche-b.json'),
loadJson('assets/data/dishes-tranche-c.json'),
loadJson('assets/data/dishes-tranche-d.json'),
]);
const all = {...a, ...b, ...c, ...dd};
delete all._meta;
const grid = document.getElementById('grid');
grid.innerHTML = '';
for (const id in all) {
grid.insertAdjacentHTML('beforeend', renderDish(id, all[id]));
}
document.getElementById('filter').addEventListener('click', e => {
if (e.target.tagName !== 'BUTTON') return;
const cat = e.target.dataset.cat;
document.querySelectorAll('#filter button').forEach(b => b.classList.toggle('active', b===e.target));
document.querySelectorAll('.dish').forEach(el => {
el.style.display = (cat==='all' || el.dataset.cat===cat) ? '' : 'none';
});
});
}
init();
</script>
</body>
</html>