Files
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

148 lines
7.8 KiB
HTML

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kofferdetektiv — Welt-Übersicht aller Länder</title>
<style>
:root{
--fjord:#2f6f8f; --fjord-dark:#1f4b5f; --fjord-light:#e4eef2; --moss:#5a8a5e;
--honey:#e8c547; --sand:#f4efe4; --coral:#b04a3e; --ink:#1f2733; --muted:#6a7886; --border:#d8dde3;
}
*{box-sizing:border-box}
body{margin:0;font-family:"Segoe UI",system-ui,sans-serif;background:#eef2f5;color:var(--ink)}
header{position:sticky;top:0;z-index:10;background:linear-gradient(180deg,#1f4b5f,#2f6f8f);color:#fff;
padding:16px 22px;box-shadow:0 2px 12px rgba(20,40,55,.25)}
header h1{margin:0 0 3px;font-size:22px}
header .sub{font-size:13px;opacity:.85}
.controls{display:flex;gap:10px;flex-wrap:wrap;margin-top:12px;align-items:center}
.controls input,.controls select{padding:9px 12px;border-radius:9px;border:1px solid #4a7c92;
background:#fff;font-size:14px;min-height:40px}
.controls input{flex:1;min-width:180px}
.controls .count{font-size:13px;opacity:.9;white-space:nowrap}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(330px,1fr));gap:16px;padding:18px 22px;max-width:1600px;margin:0 auto}
.card{background:#fff;border:1px solid var(--border);border-radius:16px;overflow:hidden;
box-shadow:0 2px 8px rgba(40,55,70,.08);display:flex;flex-direction:column}
.card-head{display:flex;align-items:center;gap:11px;padding:13px 15px 10px}
.card-head img.flag{width:46px;height:auto;border-radius:5px;box-shadow:0 1px 3px rgba(0,0,0,.25);flex-shrink:0}
.card-head .ttl{line-height:1.2}
.card-head .name{font-size:18px;font-weight:700;color:var(--fjord-dark)}
.card-head .cap{font-size:12.5px;color:var(--muted)}
.card-head .cls{margin-left:auto;font-size:11px;font-weight:700;color:#fff;background:var(--fjord);
border-radius:999px;padding:3px 9px;align-self:flex-start}
.card-visual{display:flex;gap:8px;padding:0 15px 10px}
.card-visual .lm{flex:1;border-radius:10px;overflow:hidden;background:#e7e2d4;aspect-ratio:4/3;min-width:0}
.card-visual .lm img{width:100%;height:100%;object-fit:cover;display:block}
.card-visual .ol{width:118px;flex-shrink:0;background:#eef3f0;border-radius:10px;display:flex;align-items:center;justify-content:center}
.card-visual canvas{max-width:100%;height:auto}
.facts{padding:4px 15px 15px;font-size:12.7px;line-height:1.5}
.facts div{padding:4px 0;border-top:1px solid #eef1f4;display:flex;gap:8px}
.facts div:first-child{border-top:none}
.facts .k{color:var(--muted);min-width:104px;flex-shrink:0}
.facts .v{font-weight:600}
.facts .lmrow .v{font-weight:500}
.empty{grid-column:1/-1;text-align:center;color:var(--muted);padding:40px}
footer{text-align:center;color:var(--muted);font-size:12px;padding:18px}
</style>
</head>
<body>
<header>
<h1>🌍 Kofferdetektiv — Welt-Übersicht</h1>
<div class="sub">Alle Fall-Länder mit ihren Visitenkarten: Flagge, Wahrzeichen, Umriss und Steckbrief.</div>
<div class="controls">
<input id="q" type="search" placeholder="Land suchen …" autocomplete="off">
<select id="cont">
<option value="alle">Alle Kontinente</option>
<option>Europa</option><option>Asien</option><option>Afrika</option>
<option>Nordamerika</option><option>Südamerika</option><option>Ozeanien</option>
</select>
<select id="cls">
<option value="alle">Alle Stufen</option>
<option value="A">A · bekannt</option>
<option value="B">B · mittel</option>
<option value="C">C · schwierig</option>
<option value="D">💎 D · Platin-Liga</option>
</select>
<span class="count" id="count"></span>
</div>
</header>
<div class="grid" id="grid"></div>
<footer>Kofferdetektiv · GeoGraSim — Welt-Übersicht</footer>
<script src="data.js"></script>
<script>
const BASE = './';
let outlines = {};
/* Umriss zeichnen (mit Aspektkorrektur via cos(Breite) + Hauptstadt-Punkt) */
function drawOutline(cv, iso){
const entry = outlines[iso]; if(!entry){ cv.style.display='none'; return; }
const rings = entry.rings || entry, cap = entry.cap || null;
const g = cv.getContext('2d');
let minLon=1e9,maxLon=-1e9,minY=1e9,maxY=-1e9;
rings.forEach(r=>r.forEach(p=>{minLon=Math.min(minLon,p[0]);maxLon=Math.max(maxLon,p[0]);minY=Math.min(minY,p[1]);maxY=Math.max(maxY,p[1]);}));
const k = Math.abs(Math.cos((minY+maxY)/2*Math.PI/180)) || 1;
const minX=minLon*k, maxX=maxLon*k;
const pad=8, sc=Math.min((cv.width-pad*2)/(maxX-minX),(cv.height-pad*2)/(maxY-minY));
const ox=(cv.width-(maxX-minX)*sc)/2, oy=(cv.height-(maxY-minY)*sc)/2;
const px=lon=>ox+(lon*k-minX)*sc, py=lat=>oy+(maxY-lat)*sc;
g.clearRect(0,0,cv.width,cv.height);
g.fillStyle='#dceada'; g.strokeStyle='#1f4b37'; g.lineWidth=1.2;
rings.forEach(r=>{ g.beginPath(); r.forEach((p,i)=>{i?g.lineTo(px(p[0]),py(p[1])):g.moveTo(px(p[0]),py(p[1]));}); g.closePath(); g.fill(); g.stroke(); });
if(cap){ const cx=px(cap[0]),cy=py(cap[1]); g.beginPath();g.arc(cx,cy,4.5,0,7);g.strokeStyle='#b04a3e';g.lineWidth=1.4;g.stroke(); g.beginPath();g.arc(cx,cy,2.1,0,7);g.fillStyle='#b04a3e';g.fill(); }
}
function fact(k,v){ return v ? '<div><span class="k">'+k+'</span><span class="v">'+v+'</span></div>' : ''; }
function card(c){
const el = document.createElement('div'); el.className='card';
el.dataset.name=(c.name||'').toLowerCase(); el.dataset.cont=c.continent||''; el.dataset.cls=c.cls||'';
el.innerHTML =
'<div class="card-head">'+
'<img class="flag" src="'+BASE+'assets/img/flags/'+c.iso2+'.svg" alt="" onerror="this.style.visibility=\'hidden\'">'+
'<div class="ttl"><div class="name">'+c.name+'</div><div class="cap">🏙️ '+(c.capital||'—')+' · '+(c.continent||'')+'</div></div>'+
'<span class="cls">Stufe '+(c.cls||'?')+'</span>'+
'</div>'+
'<div class="card-visual">'+
'<div class="lm"><img src="'+BASE+'assets/img/landmarks/'+c.iso2+'.webp" alt="" loading="lazy" onerror="this.parentElement.style.display=\'none\'"></div>'+
'<div class="ol"><canvas width="116" height="100"></canvas></div>'+
'</div>'+
'<div class="facts">'+
fact('Einwohner', c.population)+
fact('Fläche', c.area)+
fact('Dichte', c.density ? c.density+' Ew./km²' : '')+
fact('Region', c.region)+
fact('Amtssprache', c.language)+
fact('Währung', c.currency)+
fact('Nachbarn', c.neighbours && c.neighbours.length ? c.neighbours.join(', ') : 'Inselstaat / keine')+
fact('Staatsform', c.gov)+
fact('BIP/Kopf', c.gdp ? c.gdp+' US-$' : '')+
fact('Lebenserw.', c.lifeExp ? c.lifeExp+' Jahre' : '')+
fact('UN seit', c.unSince)+
fact('Zeitzone', c.timezone)+
fact('Domain', c.domain)+
fact('Klima', c.climate)+
fact('Exporte', c.exports)+
(c.landmark ? '<div class="lmrow"><span class="k">Wahrzeichen</span><span class="v">'+c.landmark+(c.landmarkNote?' — '+c.landmarkNote.replace(/^Auf der Rückseite steht: „?/,'').replace(/[“".]+$/,''):'')+'</span></div>' : '')+
'</div>';
drawOutline(el.querySelector('canvas'), c.iso2);
return el;
}
function render(){
const grid=$('grid'); grid.innerHTML='';
const q=($('q').value||'').toLowerCase().trim(), cont=$('cont').value, cls=$('cls').value;
const list = KD_COUNTRIES.slice().sort((a,b)=>a.name.localeCompare(b.name,'de'))
.filter(c=>(!q||c.name.toLowerCase().includes(q)) && (cont==='alle'||c.continent===cont) && (cls==='alle'||c.cls===cls));
list.forEach(c=>grid.appendChild(card(c)));
if(!list.length) grid.innerHTML='<div class="empty">Kein Land gefunden.</div>';
$('count').textContent = list.length + ' von ' + KD_COUNTRIES.length + ' Ländern';
}
function $(id){return document.getElementById(id);}
fetch(BASE+'assets/data/outlines.json').then(r=>r.json()).then(j=>{outlines=j;render();}).catch(()=>render());
['q','cont','cls'].forEach(id=>$(id).addEventListener('input',render));
</script>
</body>
</html>