Files
geograsim/App/admin-styleguide.html
Adminator 362aaba883 Feinschliff-Spalten + Kopfzeilen-Panels (Placement/Transparenz)
- teacher.html Aktuell-Spalten: Weltkueche '🏆 Punkte' (score), Fluss
  '👥 Einw.' + '🌾 Ernte' (population/food), Busfahrt '📍 Ø km' (avgTapKm).
  (Kofferdetektiv Items-% vertagt: Sim liefert live noch keine Item-Zahl.)
- admin-styleguide.html Kopfzeile: Untermenues 30% transparent (Blur);
  Tempo oeffnet links + bleibt offen, Musik klappt nach unten + schliesst
  nach Song-Auswahl; Toggle per Klick.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-25 13:04:32 +02:00

490 lines
37 KiB
HTML
Raw Permalink 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">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GeoGraSim — Style-Guide (Admin)</title>
<link rel="icon" type="image/png" href="favicon-96x96.png" sizes="96x96">
<link rel="icon" type="image/svg+xml" href="favicon.svg">
<link rel="stylesheet" href="assets/fonts/inter.css">
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:'Inter',sans-serif;background:#f7f6f3;min-height:100vh;color:#2a2a2a}
.topbar{background:#fff;padding:.6rem 1.2rem;display:flex;align-items:center;gap:.8rem;border-bottom:1px solid rgba(0,0,0,.06)}
.topbar h1{font-size:.95rem;font-weight:800;color:#4a7c8a;flex:1;display:flex;align-items:center;gap:.5rem}
.topbar h1 img{height:28px}
.btn-sm{padding:.3rem .6rem;border:1px solid rgba(0,0,0,.08);border-radius:6px;background:#fff;font-size:.68rem;font-weight:600;cursor:pointer;color:#4a4a4a;text-decoration:none}
.btn-sm:hover{background:#dae8ec;color:#4a7c8a}
.wrap{max-width:980px;margin:1rem auto;padding:0 1rem}
.card{background:#fff;border-radius:10px;padding:1.2rem 1.3rem;box-shadow:0 1px 4px rgba(0,0,0,.03);border:1px solid rgba(0,0,0,.04);margin-bottom:1rem}
.card-h{font-size:.65rem;font-weight:700;color:#4a7c8a;text-transform:uppercase;letter-spacing:.06em;margin-bottom:.65rem}
h2{font-size:1.15rem;font-weight:800;color:#1f4b37;margin-bottom:.4rem}
h3{font-size:.95rem;font-weight:700;color:#4a7c8a;margin:.9rem 0 .4rem}
p{font-size:.82rem;line-height:1.55;color:#4a4a4a;margin-bottom:.5rem}
p.lead{font-size:.78rem;color:#6a6a6a}
code{font-family:'JetBrains Mono','Fira Code',monospace;font-size:.78rem;background:#f0ede4;padding:.05rem .35rem;border-radius:4px;color:#1f4b37}
pre{font-family:'JetBrains Mono','Fira Code',monospace;font-size:.74rem;background:#f0ede4;padding:.7rem .9rem;border-radius:7px;color:#1f4b37;line-height:1.5;white-space:pre-wrap;word-break:break-word;margin:.4rem 0}
.copy-block{position:relative}
.copy-btn{position:absolute;top:.45rem;right:.5rem;font-size:.6rem;padding:.2rem .55rem;border:1.5px solid rgba(0,0,0,.1);border-radius:5px;background:#fff;cursor:pointer;font-weight:600;color:#4a7c8a}
.copy-btn:hover{background:#dae8ec}
.copy-btn.ok{background:#dceadd;color:#5a8a5e;border-color:#5a8a5e}
.swatches{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:.7rem;margin:.5rem 0}
.sw{border:1px solid rgba(0,0,0,.06);border-radius:7px;overflow:hidden;cursor:pointer;background:#fff;transition:transform .12s}
.sw:hover{transform:translateY(-1px);border-color:#4a7c8a}
.sw-color{height:60px}
.sw-meta{padding:.45rem .55rem;font-size:.68rem}
.sw-meta strong{display:block;color:#1f4b37}
.sw-meta span{color:#8a8a8a;font-family:'JetBrains Mono',monospace;font-size:.66rem}
.pill{display:inline-block;padding:.18rem .55rem;border-radius:999px;font-size:.65rem;font-weight:600;background:#dae8ec;color:#1f4e5a;margin-right:.3rem}
.pill.warn{background:#fde8d0;color:#a05a2b}
.pill.bad{background:#f2ddd8;color:#a04a3a}
table{width:100%;border-collapse:collapse;font-size:.76rem;margin:.4rem 0}
th{text-align:left;background:#f7f6f3;padding:.4rem .55rem;font-weight:700;color:#4a4a4a;border-bottom:2px solid rgba(0,0,0,.06)}
td{padding:.4rem .55rem;border-bottom:1px solid rgba(0,0,0,.04);vertical-align:top}
ul{margin:.3rem 0 .6rem 1.3rem;font-size:.82rem;line-height:1.55;color:#4a4a4a}
ul li{margin-bottom:.2rem}
.toc{display:flex;flex-wrap:wrap;gap:.4rem;margin-bottom:1rem}
.toc a{padding:.3rem .65rem;background:#fff;border:1.5px solid rgba(0,0,0,.06);border-radius:6px;font-size:.7rem;color:#4a7c8a;text-decoration:none;font-weight:600}
.toc a:hover{background:#dae8ec;border-color:#4a7c8a}
</style>
</head>
<body>
<div class="topbar">
<h1><img src="assets/img/geograsim_t.svg" alt="GeoGraSim"> Style-Guide (Admin)</h1>
<a href="admin-licenses.html" class="btn-sm">🔑 Lizenzen</a>
<a href="admin-modules.html" class="btn-sm">🧩 Module</a>
<a href="admin-levels.html" class="btn-sm">🎮 Level</a>
<a href="admin-accounts.html" class="btn-sm">👤 Admins</a>
<a href="admin.html" class="btn-sm">Logout</a>
</div>
<div class="wrap">
<div class="toc">
<a href="#bildstil">🎨 Bildstil</a>
<a href="#farben-bild">🌿 Bild-Farbpalette</a>
<a href="#farben-ui">🧩 UI-Farbtokens</a>
<a href="#leistung">📊 Leistungs-Skala</a>
<a href="#kopfzeile">🎩 Kopfzeile</a>
<a href="#layout">📐 Layout &amp; Spacing</a>
<a href="#typo">🔤 Typografie</a>
<a href="#bilder">🖼️ Bildformate</a>
<a href="#ipad">📱 iPad-Patterns</a>
<a href="#sprache">🗣️ Sprache</a>
</div>
<div class="card">
<h2>Style-Guide</h2>
<p class="lead">Verbindliche Stil-Referenz für alle GeoGraSim-Module. Klick auf Farbfelder oder „Kopieren" überträgt den Wert in die Zwischenablage. Diese Seite ist die Single-Source-of-Truth — wenn du etwas änderst, musst du es hier auch aktualisieren.</p>
</div>
<!-- ============================================================== -->
<div class="card" id="bildstil">
<div class="card-h">DALL-E / Bildgenerierung</div>
<h3>Offizieller Prompt-Block</h3>
<p>Verbatim verwenden, NICHT umformulieren. Bei jedem Bild diesen Block voranstellen, danach nur den Szenen-Teil ergänzen.</p>
<div class="copy-block">
<button class="copy-btn" data-copy="prompt-base">Kopieren</button>
<pre id="prompt-base">Flat Scandinavian illustration, wide panoramic landscape filling the entire 16:9 frame edge-to-edge, painted style with clean vector shapes, dark forest green (#1f4b37) and sage green (#4a7c4e) tones, yellow-mustard (#e8c547) accents, beige (#e8e4d8) buildings and valleys, white highlights. No text, no watermark, no logos, no borders, no frame.</pre>
</div>
<h3>Eckdaten</h3>
<table>
<tr><th>Feld</th><th>Wert</th></tr>
<tr><td>Modell</td><td><code>dall-e-3</code></td></tr>
<tr><td>Splash-Auflösung</td><td>1792 × 1024 (16:9 panoramisch)</td></tr>
<tr><td>Glossar-Bilder</td><td>1792 × 1024, standard quality</td></tr>
<tr><td>Avatar-Bilder</td><td>1024 × 1024, kreisrund maskiert via CSS</td></tr>
<tr><td>Format</td><td>PNG</td></tr>
<tr><td>API-Key</td><td><code>OPENAI_API_KEY</code> in <code>App/.env.local</code> (nicht im Git)</td></tr>
</table>
<h3>Tabu</h3>
<p>
<span class="pill bad">keine Schrift im Bild</span>
<span class="pill bad">keine Logos</span>
<span class="pill bad">keine Wasserzeichen</span>
<span class="pill bad">keine Rahmen / Borders</span>
</p>
<h3>Single-Source-of-Truth</h3>
<p>Lauffähiger Referenz-Generator: <code>App/sims/logistik/scripts/generate-splash-images.sh</code> (Variable <code>PROMPT_BASE</code>). Bei Pipeline-Fragen dort als Vorlage abschauen.</p>
<h3>Why</h3>
<p>Konsistenz über alle Module. Die Sims stehen auf der Schülerseite nebeneinander; wenn ein Modul aus dem Stil ausbricht, fällt es sofort auf. Gilt nicht nur für Splashes, sondern auch für Spielfeld-Hintergründe, Sprites, Marker-Icons, Bewertungs-Visuals.</p>
</div>
<!-- ============================================================== -->
<div class="card" id="farben-bild">
<div class="card-h">Bild-Farbpalette (verbindlich für DALL-E + Sprites + SVGs)</div>
<p>Klick auf eine Karte kopiert den Hex-Wert.</p>
<div class="swatches">
<div class="sw" data-copy-text="#1f4b37"><div class="sw-color" style="background:#1f4b37"></div><div class="sw-meta"><strong>Forest green</strong><span>#1f4b37</span></div></div>
<div class="sw" data-copy-text="#4a7c4e"><div class="sw-color" style="background:#4a7c4e"></div><div class="sw-meta"><strong>Sage green</strong><span>#4a7c4e</span></div></div>
<div class="sw" data-copy-text="#e8c547"><div class="sw-color" style="background:#e8c547"></div><div class="sw-meta"><strong>Yellow-mustard</strong><span>#e8c547</span></div></div>
<div class="sw" data-copy-text="#e8e4d8"><div class="sw-color" style="background:#e8e4d8"></div><div class="sw-meta"><strong>Beige</strong><span>#e8e4d8</span></div></div>
<div class="sw" data-copy-text="#ffffff"><div class="sw-color" style="background:#ffffff;border:1px solid #ccc"></div><div class="sw-meta"><strong>Weiß-Highlights</strong><span>#ffffff</span></div></div>
</div>
</div>
<!-- ============================================================== -->
<div class="card" id="farben-ui">
<div class="card-h">UI-Farbtokens (CSS-Variablen aus design-system.css)</div>
<p>Diese Tokens nutzen alle Plattform-UIs (Cockpits, Admin, Wrapper, Modale). In Sims als <code>var(--ggs-fjord)</code> referenzieren.</p>
<h3>Akzent (Fjord)</h3>
<div class="swatches">
<div class="sw" data-copy-text="#4a7c8a"><div class="sw-color" style="background:#4a7c8a"></div><div class="sw-meta"><strong>--ggs-fjord</strong><span>#4a7c8a</span></div></div>
<div class="sw" data-copy-text="#1f4e5a"><div class="sw-color" style="background:#1f4e5a"></div><div class="sw-meta"><strong>--ggs-fjord-dark</strong><span>#1f4e5a</span></div></div>
<div class="sw" data-copy-text="#dae8ec"><div class="sw-color" style="background:#dae8ec"></div><div class="sw-meta"><strong>--ggs-fjord-light</strong><span>#dae8ec</span></div></div>
</div>
<h3>Erfolg (Moss)</h3>
<div class="swatches">
<div class="sw" data-copy-text="#5a8a5e"><div class="sw-color" style="background:#5a8a5e"></div><div class="sw-meta"><strong>--ggs-moss</strong><span>#5a8a5e</span></div></div>
<div class="sw" data-copy-text="#3a6b3e"><div class="sw-color" style="background:#3a6b3e"></div><div class="sw-meta"><strong>--ggs-moss-dark</strong><span>#3a6b3e</span></div></div>
<div class="sw" data-copy-text="#dcead0"><div class="sw-color" style="background:#dcead0"></div><div class="sw-meta"><strong>--ggs-moss-light</strong><span>#dcead0</span></div></div>
</div>
<h3>Warnung &amp; Fehler</h3>
<div class="swatches">
<div class="sw" data-copy-text="#e8833a"><div class="sw-color" style="background:#e8833a"></div><div class="sw-meta"><strong>--ggs-orange / warning</strong><span>#e8833a</span></div></div>
<div class="sw" data-copy-text="#c85c4a"><div class="sw-color" style="background:#c85c4a"></div><div class="sw-meta"><strong>--ggs-coral / danger</strong><span>#c85c4a</span></div></div>
<div class="sw" data-copy-text="#f0d0ca"><div class="sw-color" style="background:#f0d0ca"></div><div class="sw-meta"><strong>--ggs-coral-light</strong><span>#f0d0ca</span></div></div>
</div>
<h3>Neutral &amp; Sand</h3>
<div class="swatches">
<div class="sw" data-copy-text="#f5f2eb"><div class="sw-color" style="background:#f5f2eb;border:1px solid #ddd"></div><div class="sw-meta"><strong>--ggs-bg</strong><span>#f5f2eb</span></div></div>
<div class="sw" data-copy-text="#e8e4d8"><div class="sw-color" style="background:#e8e4d8;border:1px solid #ddd"></div><div class="sw-meta"><strong>--ggs-bg-dark</strong><span>#e8e4d8</span></div></div>
<div class="sw" data-copy-text="#e8d5b5"><div class="sw-color" style="background:#e8d5b5"></div><div class="sw-meta"><strong>--ggs-sand</strong><span>#e8d5b5</span></div></div>
<div class="sw" data-copy-text="#c4a97a"><div class="sw-color" style="background:#c4a97a"></div><div class="sw-meta"><strong>--ggs-sand-dark</strong><span>#c4a97a</span></div></div>
<div class="sw" data-copy-text="#e0ddd4"><div class="sw-color" style="background:#e0ddd4"></div><div class="sw-meta"><strong>--ggs-border</strong><span>#e0ddd4</span></div></div>
</div>
<h3>Text</h3>
<div class="swatches">
<div class="sw" data-copy-text="#2a2a2a"><div class="sw-color" style="background:#2a2a2a"></div><div class="sw-meta"><strong>--ggs-text</strong><span>#2a2a2a</span></div></div>
<div class="sw" data-copy-text="#8a8a8a"><div class="sw-color" style="background:#8a8a8a"></div><div class="sw-meta"><strong>--ggs-text-muted</strong><span>#8a8a8a</span></div></div>
<div class="sw" data-copy-text="#b0b0b0"><div class="sw-color" style="background:#b0b0b0"></div><div class="sw-meta"><strong>--ggs-text-light</strong><span>#b0b0b0</span></div></div>
</div>
<h3>Komplette CSS-Variable als Block</h3>
<div class="copy-block">
<button class="copy-btn" data-copy="css-tokens">Kopieren</button>
<pre id="css-tokens">--ggs-fjord: #4a7c8a;
--ggs-fjord-dark: #1f4e5a;
--ggs-fjord-light: #dae8ec;
--ggs-moss: #5a8a5e;
--ggs-moss-dark: #3a6b3e;
--ggs-moss-light: #dcead0;
--ggs-sand: #e8d5b5;
--ggs-sand-dark: #c4a97a;
--ggs-coral: #c85c4a;
--ggs-coral-light: #f0d0ca;
--ggs-orange: #e8833a;
--ggs-bg: #f5f2eb;
--ggs-bg-dark: #e8e4d8;
--ggs-white: #ffffff;
--ggs-text: #2a2a2a;
--ggs-text-muted: #8a8a8a;
--ggs-text-light: #b0b0b0;
--ggs-border: #e0ddd4;
--ggs-success: #5a8a5e;
--ggs-warning: #e8833a;
--ggs-danger: #c85c4a;
--ggs-info: #4a7c8a;</pre>
</div>
</div>
<!-- ============================================================== -->
<div class="card" id="leistung">
<div class="card-h">Leistungs-Skala — 5 Stufen (Standard für ALLE Sims)</div>
<p class="lead">EINE Skala für Schülerleistung überall im Programm: Prozentwert (0100) + dünner Balken in der Ampelfarbe. <strong>Sterne entfallen.</strong> Die Grenzen <strong>50 / 80 / 90</strong> sind zugleich die Triage-Grenzen (ab 90 % „Fordern", ab 80 % „Läuft gut", ab 50 % „Begleiten", darunter „Fördern"), damit Balkenfarbe und Feld immer übereinstimmen. Quelle in Code: <code>pctColor()</code> = <code>_tagTraffic()</code>.</p>
<div style="display:grid;grid-template-columns:26px auto 1fr 90px;gap:.55rem 1rem;align-items:center;max-width:520px;margin:.7rem 0 1.3rem;font-size:.85rem">
<span style="width:22px;height:22px;border-radius:6px;background:#1f7a3d"></span><b>≥ 90 %</b><span style="color:#5a5a5a">sehr gut &nbsp;<code style="font-size:.72rem">#1f7a3d</code></span><div><div style="font-weight:800;color:#1f7a3d;font-size:.82rem">90 %</div><div style="margin-top:2px;height:5px;border-radius:99px;background:rgba(0,0,0,.07);overflow:hidden"><div style="height:100%;width:90%;background:#1f7a3d"></div></div></div>
<span style="width:22px;height:22px;border-radius:6px;background:#7cb342"></span><b>8089 %</b><span style="color:#5a5a5a">gut &nbsp;<code style="font-size:.72rem">#7cb342</code></span><div><div style="font-weight:800;color:#7cb342;font-size:.82rem">80 %</div><div style="margin-top:2px;height:5px;border-radius:99px;background:rgba(0,0,0,.07);overflow:hidden"><div style="height:100%;width:80%;background:#7cb342"></div></div></div>
<span style="width:22px;height:22px;border-radius:6px;background:#f9c33b"></span><b>6079 %</b><span style="color:#5a5a5a">solide &nbsp;<code style="font-size:.72rem">#f9c33b</code></span><div><div style="font-weight:800;color:#f9c33b;font-size:.82rem">60 %</div><div style="margin-top:2px;height:5px;border-radius:99px;background:rgba(0,0,0,.07);overflow:hidden"><div style="height:100%;width:60%;background:#f9c33b"></div></div></div>
<span style="width:22px;height:22px;border-radius:6px;background:#ef8b2c"></span><b>5059 %</b><span style="color:#5a5a5a">wackelig &nbsp;<code style="font-size:.72rem">#ef8b2c</code></span><div><div style="font-weight:800;color:#ef8b2c;font-size:.82rem">50 %</div><div style="margin-top:2px;height:5px;border-radius:99px;background:rgba(0,0,0,.07);overflow:hidden"><div style="height:100%;width:50%;background:#ef8b2c"></div></div></div>
<span style="width:22px;height:22px;border-radius:6px;background:#d8453a"></span><b>&lt; 50 %</b><span style="color:#5a5a5a">kritisch &nbsp;<code style="font-size:.72rem">#d8453a</code></span><div><div style="font-weight:800;color:#d8453a;font-size:.82rem">40 %</div><div style="margin-top:2px;height:5px;border-radius:99px;background:rgba(0,0,0,.07);overflow:hidden"><div style="height:100%;width:40%;background:#d8453a"></div></div></div>
</div>
<h3>Triage-Felder (aus % × Fleiß)</h3>
<p><strong>&lt; 50 % → Fördern</strong> (Hilfe) · <strong>5079 % → Begleiten</strong> · <strong>8089 % → Läuft gut</strong> · <strong>≥ 90 % → Fordern</strong> (mehr herausfordern) — jeweils nur, wenn aktiv gearbeitet wurde, sonst „inaktiv".</p>
<div style="display:flex;gap:.6rem;flex-wrap:wrap;margin:.4rem 0 1rem">
<span style="font-size:.8rem;font-weight:700;color:#b04a3e;background:#f7e2dc;padding:.25rem .7rem;border-radius:12px">Fördern</span>
<span style="font-size:.8rem;font-weight:700;color:#9a6a12;background:#f7edd6;padding:.25rem .7rem;border-radius:12px">Begleiten</span>
<span style="font-size:.8rem;font-weight:700;color:#3a6b3e;background:#dceadd;padding:.25rem .7rem;border-radius:12px">Läuft gut</span>
<span style="font-size:.8rem;font-weight:700;color:#155e2a;background:#c8e6cd;padding:.25rem .7rem;border-radius:12px">Fordern</span>
<span style="font-size:.8rem;font-weight:700;color:#8a8a8a;background:#efeee8;padding:.25rem .7rem;border-radius:12px">inaktiv</span>
</div>
<h3>CSS-Variablen</h3>
<div style="background:#1f2733;border-radius:8px;padding:1rem;overflow:auto"><pre style="margin:0;color:#e8eef4;font-size:.78rem;font-family:'Courier New',monospace">--ggs-perf-5: #1f7a3d; /* ≥ 90 % sehr gut */
--ggs-perf-4: #7cb342; /* 8089 % gut */
--ggs-perf-3: #f9c33b; /* 6079 % solide */
--ggs-perf-2: #ef8b2c; /* 5059 % wackelig */
--ggs-perf-1: #d8453a; /* &lt; 50 % kritisch */
/* Triage */
--ggs-triage-foerdern: #b04a3e;
--ggs-triage-begleiten: #9a6a12;
--ggs-triage-gut: #3a6b3e;
--ggs-triage-inaktiv: #8a8a8a;</pre></div>
<p style="font-size:.78rem;color:#8a8a8a;margin-top:.6rem">Vorschau der Zuordnung je Sim: <a href="admin-lehrer-view.html">Lehrer-View Parameter-Überblick</a>.</p>
</div>
<!-- ============================================================== -->
<div class="card" id="kopfzeile">
<div class="card-h">Kopfzeile — Entwurf B (schwebend)</div>
<p class="lead">Standard-Kopfzeile für ALLE Sims: <strong>Kreis-Logo · Titel · Level</strong> als eine schwebende Pille — Home und rechts die Steuerung: <strong>Tempo</strong> (nur Echtzeit-Sims) · Musik · Ton · Neustart · Hilfe · Glossar (<code>target="_blank"</code>). <strong>Eigene Icons im App-Stil</strong> statt Emojis, alle Elemente auf <strong>gleicher Höhe</strong>. Lehrplan entfällt. Musik überall (Klima-Track als Platzhalter).</p>
<style>
.khz-scene{position:relative;border-radius:12px;overflow:hidden;background:linear-gradient(135deg,#a7cbe0 0%,#8bb98d 55%,#e6dca6 100%);border:1px solid #cfd6cf}
.khz-scene .khz-sky{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:rgba(255,255,255,.5);font-size:1.5rem;font-weight:800;letter-spacing:.08em;pointer-events:none}
.khz-scene .khz-content{position:absolute;left:14px;bottom:12px;display:flex;gap:8px;pointer-events:none}
.khz-scene .khz-content i{width:70px;height:44px;border-radius:8px;background:rgba(255,255,255,.35);display:block}
/* Alle Header-Elemente 38px hoch, vertikal zentriert (Logo·Titel·Level = eine Pille) */
.ghdr{position:absolute;left:0;right:0;top:0;display:flex;align-items:center;gap:.5rem;padding:.55rem .7rem;z-index:3}
.ghdr .sp{flex:1}
.ghdr .grp{display:flex;align-items:center;gap:.5rem;height:38px;padding:0 .8rem 0 .3rem;background:rgba(255,255,255,.96);border-radius:19px;box-shadow:0 2px 9px rgba(0,0,0,.2)}
.ghdr .grp .logo{width:30px;height:30px;border-radius:50%;background:#1f4e5a;flex:none;overflow:hidden;display:flex;align-items:center;justify-content:center}
.ghdr .grp .logo img{width:100%;height:100%;object-fit:cover}
.ghdr .grp .title{font-weight:800;color:#1f4e5a;font-size:.92rem;white-space:nowrap;line-height:1}
.ghdr .grp .ctx{font-size:.6rem;font-weight:800;color:#fff;background:#5a8a5e;border-radius:9px;padding:.2rem .5rem;line-height:1;white-space:nowrap}
.ghdr .btn{width:38px;height:38px;border-radius:12px;border:none;background:rgba(255,255,255,.96);box-shadow:0 2px 9px rgba(0,0,0,.2);display:flex;align-items:center;justify-content:center;cursor:pointer;color:#1f4e5a;padding:0}
.ghdr .btn .ic{width:20px;height:20px}
.khz-variant{margin:1rem 0}
.khz-frame-lab{font-size:.66rem;font-weight:700;color:#8a8a8a;text-transform:uppercase;letter-spacing:.04em;margin:.9rem 0 .3rem}
.khz-ipad{height:150px}
.khz-fhd{height:120px}
.khz-scroll{overflow-x:auto}
/* Aufgeklappte Steuerung */
.khz-pop{display:inline-flex;align-items:center;gap:.25rem;height:38px;padding:0 .3rem;background:rgba(255,255,255,.7);backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);border-radius:12px;box-shadow:0 2px 9px rgba(0,0,0,.14);border:1px solid rgba(255,255,255,.5);vertical-align:middle}
.khz-pop .ic{width:16px;height:16px;color:#1f4e5a}
.khz-seg{height:30px;min-width:36px;padding:0 .6rem;border:none;background:transparent;border-radius:8px;font-weight:800;font-size:.82rem;color:#4a4a4a;cursor:pointer;display:flex;align-items:center;justify-content:center}
.khz-seg.on{background:#4a7c8a;color:#fff}
.khz-seg.on .ic{color:#fff}
.khz-music{gap:.5rem;padding:0 .55rem}
.khz-select{height:30px;border:1px solid rgba(0,0,0,.12);border-radius:8px;padding:0 .55rem;font-size:.78rem;color:#1f4e5a;font-weight:700;background:#f7f6f3;display:inline-flex;align-items:center;gap:.35rem;white-space:nowrap}
.khz-range{width:96px;height:6px;border-radius:99px;background:linear-gradient(90deg,#4a7c8a 0 62%,#dfe6e9 62% 100%);position:relative}
.khz-range::after{content:'';position:absolute;left:62%;top:50%;transform:translate(-50%,-50%);width:14px;height:14px;border-radius:50%;background:#4a7c8a;box-shadow:0 1px 3px rgba(0,0,0,.3)}
/* Tempo-Button zeigt IMMER den aktuellen Stand */
.khz-spd{width:38px;height:38px;border-radius:12px;border:none;background:#fff;box-shadow:0 2px 9px rgba(0,0,0,.2);display:inline-flex;flex-direction:column;align-items:center;justify-content:center;color:#1f4e5a;font-weight:800;line-height:1;cursor:pointer;vertical-align:middle}
.khz-spd b{font-size:.82rem}
.khz-spd small{font-size:.5rem;font-weight:700;margin-top:1px;color:#4a7c8a;letter-spacing:.02em}
.khz-spd.act{background:#4a7c8a;color:#fff}
.khz-spd.act small{color:#dbe9ee}
.khz-spd .ic{width:18px;height:18px;color:inherit}
</style>
<svg width="0" height="0" style="position:absolute" aria-hidden="true"><defs>
<symbol id="ic-home" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 11.4 12 4l8 7.4"/><path d="M6 10.3V19a1 1 0 0 0 1 1h3v-5h4v5h3a1 1 0 0 0 1-1v-8.7"/></symbol>
<symbol id="ic-tempo" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4.6 16.5a7.5 7.5 0 0 1 14.8 0"/><path d="M12 16 15.2 12"/><circle cx="12" cy="16.3" r="1.3" fill="currentColor" stroke="none"/></symbol>
<symbol id="ic-music" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M9 17V6.4l9-1.8V15"/><circle cx="6.5" cy="17" r="2.4"/><circle cx="15.5" cy="15" r="2.4"/></symbol>
<symbol id="ic-sound" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 9.5h3.2L11 6v12l-3.8-3.5H4z"/><path d="M14.6 9.6a4 4 0 0 1 0 4.8"/><path d="M17 7.4a7 7 0 0 1 0 9.2"/></symbol>
<symbol id="ic-restart" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M19 12a7 7 0 1 1-2-4.9"/><path d="M19 4.5V9h-4.5"/></symbol>
<symbol id="ic-help" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="8.4"/><path d="M9.7 9.3a2.4 2.4 0 0 1 4.6.8c0 1.6-2.3 1.8-2.3 3.2"/><circle cx="12" cy="16.4" r=".7" fill="currentColor" stroke="none"/></symbol>
<symbol id="ic-glossar" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 6.6C10 5.2 7 5.2 5 6.2v11c2-1 5-1 7 .4"/><path d="M12 6.6c2-1.4 5-1.4 7-.4v11c-2-1-5-1-7 .4"/><path d="M12 6.6v11.4"/></symbol>
<symbol id="ic-pause" viewBox="0 0 24 24"><rect x="6" y="5" width="4" height="14" rx="1.2" fill="currentColor"/><rect x="14" y="5" width="4" height="14" rx="1.2" fill="currentColor"/></symbol>
<symbol id="ic-caret" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M7 10l5 5 5-5"/></symbol>
</defs></svg>
<p style="font-size:.78rem;color:#4a4a4a;margin:.2rem 0 .3rem">Die Stufen hinter der Zeile deuten den Sim-Inhalt an — so sieht man, wie wenig die schwebende Zeile verdeckt. Logo, Titel und Level sitzen in <b>einer</b> Pille auf gleicher Höhe wie die Buttons.</p>
<div class="khz-variant">
<div class="khz-frame-lab">📱 iPad-Landscape (~1024 px)</div>
<div class="khz-scene khz-ipad" style="max-width:1024px">
<div class="khz-sky">SIM-INHALT</div><div class="khz-content"><i></i><i></i><i></i></div>
<div class="ghdr">
<div class="grp"><span class="logo"><img src="assets/img/bildLogo.png" alt=""></span><span class="title">Klimawächter</span><span class="ctx">Level 2</span></div>
<button class="btn" title="Startseite"><svg class="ic"><use href="#ic-home"/></svg></button>
<span class="sp"></span>
<button class="btn" title="Tempo"><svg class="ic"><use href="#ic-tempo"/></svg></button>
<button class="btn" title="Musik"><svg class="ic"><use href="#ic-music"/></svg></button>
<button class="btn" title="Ton"><svg class="ic"><use href="#ic-sound"/></svg></button>
<button class="btn" title="Neustart"><svg class="ic"><use href="#ic-restart"/></svg></button>
<button class="btn" title="Hilfe"><svg class="ic"><use href="#ic-help"/></svg></button>
<button class="btn" title="Glossar (neuer Tab)"><svg class="ic"><use href="#ic-glossar"/></svg></button>
</div>
</div>
<div class="khz-frame-lab">🖥️ Full-HD PC (1920 px — mehr Platz zwischen den Elementen)</div>
<div class="khz-scroll"><div class="khz-scene khz-fhd" style="width:1600px">
<div class="khz-sky">SIM-INHALT</div><div class="khz-content"><i></i><i></i><i></i><i></i><i></i></div>
<div class="ghdr">
<div class="grp"><span class="logo"><img src="assets/img/bildLogo.png" alt=""></span><span class="title">Klimawächter</span><span class="ctx">Level 2</span></div>
<button class="btn" title="Startseite"><svg class="ic"><use href="#ic-home"/></svg></button>
<span class="sp"></span>
<button class="btn" title="Tempo"><svg class="ic"><use href="#ic-tempo"/></svg></button>
<button class="btn" title="Musik"><svg class="ic"><use href="#ic-music"/></svg></button>
<button class="btn" title="Ton"><svg class="ic"><use href="#ic-sound"/></svg></button>
<button class="btn" title="Neustart"><svg class="ic"><use href="#ic-restart"/></svg></button>
<button class="btn" title="Hilfe"><svg class="ic"><use href="#ic-help"/></svg></button>
<button class="btn" title="Glossar (neuer Tab)"><svg class="ic"><use href="#ic-glossar"/></svg></button>
</div>
</div></div>
</div>
<div class="khz-frame-lab">Aufgeklappt · Tempo — öffnet LINKS vom Button, bleibt offen (nur Echtzeit-Sims) · 30 % transparent</div>
<div class="khz-pop">
<button class="khz-seg" title="Pause"><svg class="ic"><use href="#ic-pause"/></svg></button>
<button class="khz-seg on">1×</button>
<button class="khz-seg">2×</button>
<button class="khz-seg">4×</button>
</div>
<div class="khz-frame-lab">Tempo-Button im Header — zeigt IMMER den aktuellen Stand</div>
<div style="display:flex;gap:.5rem;align-items:center;flex-wrap:wrap">
<button class="khz-spd" title="Normal"><b>1×</b></button>
<button class="khz-spd" title="Doppelt"><b>2×</b></button>
<button class="khz-spd act" title="Logistik: Auto-Tempo"><b>8×</b><small>Auto</small></button>
<button class="khz-spd" title="Pausiert"><svg class="ic"><use href="#ic-pause"/></svg></button>
</div>
<p style="font-size:.76rem;color:#6a6a6a;margin:.5rem 0 0">Klick öffnet das Tempo-Panel und lässt es offen bis zum erneuten Klick (Toggle) — genauso beim Musik-Player. Der Button selbst zeigt jederzeit den Speed: <b>1×</b>, <b>2×</b>, <b>8× Auto</b> (z. B. Logistik) oder <b>⏸ Pause</b>. So bleibt der Zustand sichtbar, ohne dass das Panel offen bleiben muss.</p>
<div class="khz-frame-lab">Aufgeklappt · Musikplayer — klappt nach UNTEN auf, schließt nach Song-Auswahl · 30 % transparent</div>
<div class="khz-pop khz-music">
<button class="khz-seg on" title="Pause"><svg class="ic"><use href="#ic-pause"/></svg></button>
<span class="khz-select"><svg class="ic"><use href="#ic-music"/></svg> Ruhige Klänge <svg class="ic"><use href="#ic-caret"/></svg></span>
<svg class="ic" style="width:18px;height:18px;color:#1f4e5a"><use href="#ic-sound"/></svg>
<span class="khz-range"></span>
</div>
<div style="background:#f0f7f1;border:1px solid #cfe6d2;border-radius:8px;padding:.7rem .9rem;font-size:.8rem;color:#2f5e39;margin-top:1rem">
<b>Aufbau:</b> links die Pille Kreis-Logo · Titel · Level (gleiche Höhe) + Home — rechts Tempo (nur Echtzeit-Sims: Klima, Fluss, Tourismus, Logistik) · Musik · Ton · Neustart · Hilfe · Glossar (neuer Tab). Eigene SVG-Icons im App-Stil. <b>Untermenüs:</b> Tempo öffnet <b>links</b> vom Button und bleibt offen (Zustand steht ohnehin im Button); Musik klappt <b>nach unten</b> auf und schließt nach der Song-Auswahl; beide 30 % transparent hinterlegt als Untermenü-Signal, Toggle per Klick. Sim-eigene KPIs (Budget, Jahr …) bleiben in einer eigenen Unterzeile, nicht in der Markenzeile.
</div>
</div>
<!-- ============================================================== -->
<div class="card" id="layout">
<div class="card-h">Layout &amp; Spacing</div>
<table>
<tr><th>Token</th><th>Wert</th><th>Verwendung</th></tr>
<tr><td><code>--ggs-gap-xs</code></td><td>4 px</td><td>Inline-Abstände, Pill-Padding</td></tr>
<tr><td><code>--ggs-gap-sm</code></td><td>8 px</td><td>Button-Innenabstand, Form-Felder</td></tr>
<tr><td><code>--ggs-gap-md</code></td><td>16 px</td><td>Card-Innenabstand, Standard-Layout</td></tr>
<tr><td><code>--ggs-gap-lg</code></td><td>24 px</td><td>Sektion-Abstand</td></tr>
<tr><td><code>--ggs-gap-xl</code></td><td>32 px</td><td>Hero-Bereiche</td></tr>
<tr><td><code>--ggs-radius-sm</code></td><td>6 px</td><td>Pills, kleine Buttons</td></tr>
<tr><td><code>--ggs-radius-md</code></td><td>12 px</td><td>Karten, Modale</td></tr>
<tr><td><code>--ggs-radius-lg</code></td><td>16 px</td><td>Hero-Cards, große Modale</td></tr>
<tr><td><code>--ggs-radius-pill</code></td><td>999 px</td><td>Pills, Avatar-Kreise</td></tr>
<tr><td><code>--ggs-shadow-sm</code></td><td><code>0 1px 3px rgba(0,0,0,.08)</code></td><td>Karten</td></tr>
<tr><td><code>--ggs-shadow-md</code></td><td><code>0 2px 8px rgba(0,0,0,.12)</code></td><td>Modale, schwebende Layers</td></tr>
<tr><td><code>--ggs-shadow-lg</code></td><td><code>0 4px 16px rgba(0,0,0,.16)</code></td><td>Tooltips, Spectator-Banner</td></tr>
</table>
</div>
<!-- ============================================================== -->
<div class="card" id="typo">
<div class="card-h">Typografie</div>
<table>
<tr><th>Token</th><th>Wert</th></tr>
<tr><td><code>--ggs-font</code></td><td><code>'Inter', system-ui, -apple-system, sans-serif</code></td></tr>
<tr><td><code>--ggs-font-mono</code></td><td><code>'JetBrains Mono', 'Fira Code', monospace</code></td></tr>
</table>
<h3>Größenrichtlinien</h3>
<ul>
<li><strong>0.62 rem</strong> — Card-Header (uppercase, letter-spacing .05em)</li>
<li><strong>0.7 rem</strong> — Hilfstexte, Subtitles</li>
<li><strong>0.78 rem</strong> — Body-Text in Karten</li>
<li><strong>0.85 rem</strong> — Modul-Namen, Tabs</li>
<li><strong>0.95 rem</strong> — H3 / Section-Titel</li>
<li><strong>1.15 rem</strong> — H2 / Page-Titel</li>
</ul>
</div>
<!-- ============================================================== -->
<div class="card" id="bilder">
<div class="card-h">Bildformate &amp; Pfade</div>
<table>
<tr><th>Typ</th><th>Maße</th><th>Pfad</th></tr>
<tr><td>Modul-Card-Image (Cockpit)</td><td>≈ 800 × 450 (16:9)</td><td><code>App/assets/img/sim-NN-&lt;slug&gt;.png</code></td></tr>
<tr><td>Glossar-Bild</td><td>1792 × 1024</td><td><code>App/assets/img/glossar/&lt;slug&gt;.png</code></td></tr>
<tr><td>Glossar-SVG (Schemata)</td><td>vektor</td><td><code>App/assets/img/glossar/&lt;slug&gt;-schema.svg</code></td></tr>
<tr><td>Splash (Sim-Intro)</td><td>1792 × 1024</td><td><code>App/sims/&lt;slug&gt;/assets/splash-*.png</code></td></tr>
<tr><td>Avatar (User)</td><td>1024 × 1024</td><td><code>App/assets/img/avatars/avatar-&lt;slug&gt;.png</code></td></tr>
<tr><td>Logo (SVG)</td><td>vektor</td><td><code>App/assets/img/geograsim_t.svg</code></td></tr>
</table>
<h3>Avatar-Slugs (30 Stück, 3 Gruppen)</h3>
<ul>
<li><strong>Geo-Welt:</strong> pilotin · pilot · kartografin · geologe · meteorologin · stadtplaner · forscherin · forscher · taucherin · astronaut</li>
<li><strong>Cool &amp; lustig:</strong> coole-girl · coole-boy · lustige-girl · lustige-boy · nerd-girl · sportlich-boy · kuenstlerin · musiker · gaertnerin · abenteurer</li>
<li><strong>Tier-Begleiter:</strong> fuchs-explorer · eule-prof · baer-foerster · pinguin-polar · affe-tropen · delfin-meer · adler-pilot · schildkroete-w · katze-stadt · biene-natur</li>
</ul>
</div>
<!-- ============================================================== -->
<div class="card" id="ipad">
<div class="card-h">iPad-Patterns (Hauptzielgerät: iPad Landscape 1180 × 820)</div>
<ul>
<li><strong>Touch-Ziele</strong> ≥ 36 px Höhe, idealerweise 44 px für primäre Aktionen</li>
<li><strong>Kein Hover-Kleber</strong> — alle Interaktionen müssen ohne Hover funktionieren</li>
<li><strong>Modale nutzen</strong> <code>height: 100dvh</code> + <code>safe-area-inset-bottom</code></li>
<li><strong>Sticky Aktions-Buttons</strong> unten im Modal — nicht außerhalb scrollen lassen</li>
<li><strong>Float-✕ oben rechts</strong> bei Modalen, damit „Schließen" immer erreichbar ist</li>
<li><strong>Layout breit statt hoch</strong> — Badges horizontal, 2-Spalten-Grids wo möglich</li>
<li><strong>viewport-fit=cover</strong> + <code>100dvh</code> für Vollbild-Sims</li>
</ul>
</div>
<!-- ============================================================== -->
<div class="card" id="sprache">
<div class="card-h">Sprache (Lernarbeit-Lexikon)</div>
<p>Niemals „spielen / Spiel / Spieler*in" verwenden. GeoGraSim ist Lernarbeit nach Wygotski, kein Spiel.</p>
<table>
<tr><th>Statt</th><th>Verwende</th></tr>
<tr><td>spielen</td><td>arbeiten mit · bearbeiten</td></tr>
<tr><td>Spiel</td><td>Simulation · Modul</td></tr>
<tr><td>Spieler*in</td><td>Bearbeiter*in · Schüler*in</td></tr>
<tr><td>Spielrunde</td><td>Durchgang</td></tr>
<tr><td>Game Over</td><td>Durchgang beendet</td></tr>
</table>
<p>Ausnahme: in Code-Variablen (<code>state.gameOver</code>, <code>player_progress</code>) ist „game/player" als technischer Begriff unkritisch — Hauptsache an der UI nicht sichtbar.</p>
</div>
</div>
<script>
function copyText(text, el) {
navigator.clipboard.writeText(text).then(function() {
if (el) {
var orig = el.textContent;
el.textContent = '✓ kopiert';
el.classList.add('ok');
setTimeout(function() { el.textContent = orig; el.classList.remove('ok'); }, 1100);
}
});
}
// Copy-Buttons mit data-copy=ID
document.querySelectorAll('.copy-btn[data-copy]').forEach(function(btn) {
btn.addEventListener('click', function() {
var src = document.getElementById(btn.getAttribute('data-copy'));
if (src) copyText(src.textContent, btn);
});
});
// Swatches mit data-copy-text
document.querySelectorAll('.sw[data-copy-text]').forEach(function(sw) {
sw.addEventListener('click', function() {
var txt = sw.getAttribute('data-copy-text');
copyText(txt, null);
var meta = sw.querySelector('.sw-meta strong');
if (meta) {
var orig = meta.textContent;
meta.textContent = '✓ kopiert';
setTimeout(function() { meta.textContent = orig; }, 900);
}
});
});
// Auth-Check: nur eingeloggter Admin darf hier sein
fetch('/api/admin', {
method:'POST', headers:{'Content-Type':'application/json'}, credentials:'same-origin',
body: JSON.stringify({action:'status'})
}).then(function(r) { return r.json(); }).then(function(r) {
if (!r.authenticated) location.href = 'admin.html';
}).catch(function() {});
</script>
<script src="assets/js/version-tag.js" defer></script>
</body>
</html>