1e51ef7def
- 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>
1184 lines
74 KiB
HTML
1184 lines
74 KiB
HTML
<!doctype html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<title>Live-Cockpit Konzept — GeoGraSim</title>
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<style>
|
||
:root {
|
||
--bg: #f5f1e6;
|
||
--card: #fff;
|
||
--ink: #1a1a1a;
|
||
--muted: #6a6a6a;
|
||
--line: rgba(0,0,0,.08);
|
||
--green: #5a8a5e;
|
||
--green-d: #3a6a3e;
|
||
--green-soft: #dceadd;
|
||
--orange: #c9913a;
|
||
--orange-soft: #fbe6c2;
|
||
--red: #b04a3e;
|
||
--red-soft: #f4d8d2;
|
||
--gray: #9a9a9a;
|
||
--gray-soft: #ece9df;
|
||
--blue: #4a7c8a;
|
||
--blue-soft: #d8e8ed;
|
||
--gold: #e8c547;
|
||
}
|
||
* { margin:0; padding:0; box-sizing:border-box; }
|
||
body { font-family:Inter,system-ui,-apple-system,sans-serif; background:var(--bg); color:var(--ink); line-height:1.5; padding:0 1.5rem 4rem; }
|
||
|
||
/* === Top-Nav === */
|
||
.nav { background:rgba(245,241,230,.95); backdrop-filter:blur(20px); border-bottom:1px solid var(--line); padding:.7rem 0; position:sticky; top:0; z-index:50; margin:0 -1.5rem 0; padding-left:1.5rem; padding-right:1.5rem; }
|
||
.nav-wrap { max-width:1200px; margin:0 auto; display:flex; justify-content:space-between; align-items:center; }
|
||
.nav-title { font-weight:800; color:var(--green-d); font-size:1.05rem; }
|
||
.nav-meta { font-size:.78rem; color:var(--muted); }
|
||
.nav-meta b { color:var(--green-d); font-variant-numeric:tabular-nums; }
|
||
|
||
/* === Container === */
|
||
.wrap { max-width:1200px; margin:0 auto; padding:1.5rem 0; }
|
||
|
||
/* === H1 + Notiz === */
|
||
h1 { font-size:1.6rem; font-weight:900; color:var(--green-d); margin-bottom:.3rem; letter-spacing:-.02em; }
|
||
.lead { color:var(--muted); font-size:.92rem; max-width:780px; margin-bottom:1.5rem; }
|
||
|
||
/* === Abschnitt mit Erläuterung === */
|
||
.erklär { background:#fff8e1; border-left:4px solid var(--gold); border-radius:0 8px 8px 0; padding:.8rem 1.1rem; margin:1rem 0 1.6rem; font-size:.85rem; color:#5a4a1a; }
|
||
.erklär b { color:#3a2f0a; }
|
||
|
||
/* === Cards === */
|
||
.card { background:var(--card); border-radius:12px; padding:1.2rem 1.4rem; margin-bottom:1.2rem; border:1px solid var(--line); box-shadow:0 1px 4px rgba(0,0,0,.03); }
|
||
.card-h { font-size:.85rem; font-weight:700; color:var(--ink); margin-bottom:.8rem; text-transform:uppercase; letter-spacing:.04em; }
|
||
|
||
/* === EBENE 1: Status-Übersicht === */
|
||
.status-grid { display:grid; grid-template-columns:repeat(4, 1fr); gap:.7rem; margin-bottom:.9rem; }
|
||
.status-tile { padding:.9rem 1rem; border-radius:10px; border:1px solid var(--line); display:flex; align-items:center; gap:.7rem; }
|
||
.status-tile .num { font-size:1.7rem; font-weight:800; line-height:1; font-variant-numeric:tabular-nums; }
|
||
.status-tile .lab { font-size:.78rem; line-height:1.25; }
|
||
.status-tile.aktiv { background:var(--green-soft); border-color:rgba(90,138,94,.3); }
|
||
.status-tile.aktiv .num { color:var(--green-d); }
|
||
.status-tile.heute { background:var(--orange-soft); border-color:rgba(201,145,58,.3); }
|
||
.status-tile.heute .num { color:#8a6516; }
|
||
.status-tile.kalt { background:var(--gray-soft); border-color:rgba(0,0,0,.06); }
|
||
.status-tile.kalt .num { color:var(--gray); }
|
||
.status-tile.hilfe { background:var(--red-soft); border-color:rgba(176,74,62,.3); }
|
||
.status-tile.hilfe .num { color:var(--red); }
|
||
.status-tile.zero .num { opacity:.5; }
|
||
|
||
.heute-prog { display:flex; align-items:center; gap:.8rem; padding:.6rem 0 0; border-top:1px solid var(--line); }
|
||
.heute-prog .lab { font-size:.78rem; color:var(--muted); white-space:nowrap; }
|
||
.heute-prog .bar { flex:1; height:10px; background:#f0ede5; border-radius:4px; overflow:hidden; position:relative; }
|
||
.heute-prog .bar > div { position:absolute; left:0; top:0; height:100%; background:var(--green); }
|
||
.heute-prog .sum { font-size:.78rem; color:#3a3a3a; font-variant-numeric:tabular-nums; white-space:nowrap; }
|
||
.heute-prog .sum b { color:var(--green-d); }
|
||
|
||
/* === Filter-Bar === */
|
||
.filter-bar { display:flex; flex-wrap:wrap; gap:.4rem; align-items:center; }
|
||
.pill { display:inline-flex; align-items:center; gap:.3rem; padding:.32rem .7rem; border-radius:999px; font-size:.74rem; font-weight:600; border:1px solid rgba(0,0,0,.12); background:#fff; cursor:pointer; transition:all .15s; }
|
||
.pill:hover { background:#f5f0e0; }
|
||
.pill.active { background:var(--green-d); color:#fff; border-color:var(--green-d); }
|
||
.pill .dot { display:inline-block; width:8px; height:8px; border-radius:50%; }
|
||
.pill .dot.g { background:var(--green); }
|
||
.pill .dot.o { background:var(--orange); }
|
||
.pill .dot.k { background:var(--gray); }
|
||
.pill .dot.r { background:var(--red); }
|
||
.pill .badge { background:rgba(255,255,255,.3); padding:0 .5em; border-radius:99px; font-weight:800; }
|
||
.pill.active .badge { background:rgba(255,255,255,.25); }
|
||
.sep { width:1px; height:1.4rem; background:rgba(0,0,0,.12); margin:0 .35rem; }
|
||
.filter-lab { font-size:.7rem; color:var(--muted); }
|
||
.filter-select { font-size:.74rem; padding:.32rem .55rem; border:1px solid rgba(0,0,0,.15); border-radius:6px; background:#fff; }
|
||
|
||
/* === EBENE 2: Schüler-Liste === */
|
||
.student-list { display:flex; flex-direction:column; gap:.5rem; }
|
||
.stu-row { background:#fff; border:1px solid var(--line); border-left:4px solid transparent; border-radius:10px; padding:.7rem .9rem; display:grid; grid-template-columns:auto 1fr auto; gap:.8rem; align-items:start; transition:box-shadow .15s; }
|
||
.stu-row:hover { box-shadow:0 2px 8px rgba(0,0,0,.06); }
|
||
.stu-row.aktiv { border-left-color:var(--green); background:#fbfdf9; }
|
||
.stu-row.heute { border-left-color:var(--orange); background:#fdfaf2; }
|
||
.stu-row.kalt { border-left-color:var(--gray); background:#fafaf8; }
|
||
.stu-row.hilfe { border-left-color:var(--red); background:#fdf5f3; }
|
||
|
||
.stu-avatar-block { display:flex; align-items:center; gap:.55rem; }
|
||
.stu-status-icon { font-size:1.1rem; line-height:1; }
|
||
.stu-avatar { width:40px; height:40px; border-radius:50%; background:linear-gradient(135deg,#dceadd,#a8c3aa); display:flex; align-items:center; justify-content:center; font-size:1.4rem; }
|
||
.stu-meta { min-width:0; }
|
||
.stu-name { font-weight:700; font-size:.92rem; color:var(--ink); margin-bottom:.1rem; display:flex; align-items:center; gap:.4rem; }
|
||
.stu-name .pulse { display:inline-block; width:8px; height:8px; background:var(--green); border-radius:50%; animation:pulse 1.5s infinite; }
|
||
@keyframes pulse { 0%,100%{opacity:1; transform:scale(1)} 50%{opacity:.5; transform:scale(.8)} }
|
||
.stu-sub { font-size:.76rem; color:var(--muted); display:flex; flex-wrap:wrap; gap:.5rem .9rem; align-items:center; }
|
||
.stu-sub .module-chip { display:inline-flex; align-items:center; gap:.25rem; padding:.06rem .4rem; background:#f0ede5; border-radius:999px; font-size:.72rem; font-weight:600; color:#3a3a3a; }
|
||
.stu-sub .phase { font-style:italic; color:#3a3a3a; }
|
||
.stu-sub .heartbeat { color:var(--green-d); font-size:.7rem; font-weight:600; }
|
||
.stu-sub .heartbeat.warn { color:var(--orange); }
|
||
.stu-sub .heartbeat.stale { color:var(--gray); }
|
||
|
||
.stu-mini-stats { margin-top:.5rem; display:grid; grid-template-columns:repeat(4, minmax(80px, 1fr)); gap:.4rem; font-size:.7rem; }
|
||
.stu-mini-stats .ms { background:#f5f3eb; border-radius:6px; padding:.32rem .5rem; }
|
||
.stu-mini-stats .ms .l { color:var(--muted); font-size:.66rem; }
|
||
.stu-mini-stats .ms .v { font-weight:700; color:#3a3a3a; font-variant-numeric:tabular-nums; }
|
||
.stu-mini-stats .ms.good .v { color:var(--green-d); }
|
||
.stu-mini-stats .ms.warn .v { color:#8a6516; }
|
||
.stu-mini-stats .ms.bad .v { color:var(--red); }
|
||
|
||
.stu-actions { display:flex; flex-direction:column; gap:.3rem; align-items:flex-end; min-width:140px; }
|
||
.stu-btn { font-size:.72rem; padding:.32rem .65rem; border-radius:6px; border:none; cursor:pointer; font-weight:600; white-space:nowrap; }
|
||
.stu-btn.primary { background:var(--green-d); color:#fff; }
|
||
.stu-btn.outline { background:#fff; border:1px solid rgba(0,0,0,.12); color:#3a3a3a; }
|
||
.stu-btn.alert { background:var(--red); color:#fff; }
|
||
.stu-stars { font-size:.78rem; color:var(--gold); letter-spacing:1px; }
|
||
|
||
/* === Stille / Kalt-Liste kompakt === */
|
||
.stu-row.kalt { padding:.45rem .9rem; }
|
||
.stu-row.kalt .stu-mini-stats { display:none; }
|
||
|
||
/* === Hint-Box === */
|
||
.next { background:var(--blue-soft); border:1px solid rgba(74,124,138,.3); border-radius:10px; padding:1rem 1.3rem; margin-top:1.5rem; font-size:.86rem; line-height:1.55; }
|
||
.next b { color:var(--blue); }
|
||
.next ul { margin:.4rem 0 0 1.4rem; }
|
||
|
||
/* === Detail-Sketch === */
|
||
.detail-sketch { background:#1a2620; color:#d8d5cd; border-radius:14px; padding:1.4rem 1.6rem; font-family:'JetBrains Mono', Consolas, monospace; font-size:.78rem; line-height:1.55; overflow-x:auto; }
|
||
.detail-sketch .h { color:#a8c3aa; font-weight:700; }
|
||
.detail-sketch .k { color:#e8c547; }
|
||
.detail-sketch .v { color:#c9e1d0; }
|
||
.detail-sketch .ok { color:#8acf95; }
|
||
.detail-sketch .warn { color:#e8a247; }
|
||
|
||
/* === Mini-Stat mit Range-Balken === */
|
||
.stu-mini-stats .ms { display:flex; flex-direction:column; gap:.18rem; }
|
||
.ms-row { display:flex; justify-content:space-between; align-items:baseline; gap:.4rem; }
|
||
.ms-range { display:flex; align-items:center; gap:.3rem; font-size:.6rem; color:var(--muted); }
|
||
.ms-range .rmin, .ms-range .rmax { font-variant-numeric:tabular-nums; min-width:1.6em; }
|
||
.ms-range .rbar { flex:1; height:5px; background:#e8e2d2; border-radius:2px; position:relative; overflow:hidden; }
|
||
.ms-range .rfill { position:absolute; top:0; bottom:0; left:0; border-radius:2px; }
|
||
.ms-range .rfill.good { background:var(--green); }
|
||
.ms-range .rfill.warn { background:var(--orange); }
|
||
.ms-range .rfill.bad { background:var(--red); }
|
||
.ms-range .rfill.neut { background:var(--blue); }
|
||
/* Marker an der Stelle des Wertes — schmaler Strich oben drüber */
|
||
.ms-range .rmarker { position:absolute; top:-2px; bottom:-2px; width:2px; background:#1a1a1a; opacity:.85; }
|
||
|
||
/* === Top 3 / Schwächste 3 === */
|
||
.ranking-grid { display:grid; grid-template-columns:1fr 1fr; gap:1rem; margin-top:1rem; padding-top:.8rem; border-top:1px solid var(--line); }
|
||
.ranking-block h3 { font-size:.78rem; font-weight:700; text-transform:uppercase; letter-spacing:.04em; margin-bottom:.55rem; display:flex; align-items:center; gap:.4rem; }
|
||
.ranking-block.top h3 { color:var(--green-d); }
|
||
.ranking-block.bottom h3 { color:#8a6516; }
|
||
.ranking-list { display:flex; flex-direction:column; gap:.32rem; }
|
||
.rank-row { background:#fff; border:1px solid var(--line); border-radius:8px; padding:.4rem .6rem; display:grid; grid-template-columns:auto auto 1fr auto; gap:.55rem; align-items:center; }
|
||
.rank-row .rk { font-weight:800; color:var(--muted); font-size:.78rem; min-width:1.4em; text-align:center; }
|
||
.rank-row.top .rk { color:var(--green-d); }
|
||
.rank-row.bottom .rk { color:#8a6516; }
|
||
.rank-row .av { width:26px; height:26px; border-radius:50%; background:linear-gradient(135deg,#dceadd,#a8c3aa); display:flex; align-items:center; justify-content:center; font-size:.95rem; }
|
||
.rank-row .nm { font-size:.8rem; font-weight:600; color:#3a3a3a; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
||
.rank-row .pc { font-size:.85rem; font-weight:800; font-variant-numeric:tabular-nums; }
|
||
.rank-row.top .pc { color:var(--green-d); }
|
||
.rank-row.bottom .pc { color:#8a6516; }
|
||
.rank-row .pcbar { position:relative; height:5px; background:#f0ede5; border-radius:3px; overflow:hidden; grid-column:2/-1; margin-top:.1rem; }
|
||
.rank-row .pcbar > div { position:absolute; left:0; top:0; height:100%; }
|
||
.rank-row.top .pcbar > div { background:var(--green); }
|
||
.rank-row.bottom .pcbar > div { background:var(--orange); }
|
||
|
||
/* === Klassen-Fleiß über Zeit (Säulen-Diagramm) === */
|
||
.klassen-fleiss-zeit { margin-top:1rem; padding-top:.9rem; border-top:1px solid var(--line); }
|
||
.kfz-head { display:flex; justify-content:space-between; align-items:baseline; gap:.6rem; margin-bottom:.5rem; }
|
||
.kfz-head h3 { font-size:.78rem; font-weight:700; text-transform:uppercase; letter-spacing:.04em; color:var(--ink); }
|
||
.kfz-head .meta { font-size:.7rem; color:var(--muted); }
|
||
.kfz-head .meta b { color:#3a3a3a; }
|
||
.kfz-grid { display:grid; grid-template-columns:repeat(7,1fr); gap:.45rem; align-items:end; padding:.4rem 0 .2rem; }
|
||
.kfz-col { display:flex; flex-direction:column; align-items:center; gap:.3rem; }
|
||
.kfz-col .col-wrap { height:90px; width:32px; display:flex; align-items:flex-end; }
|
||
.kfz-col .col-stack { width:100%; display:flex; flex-direction:column-reverse; border-radius:3px 3px 0 0; overflow:hidden; box-shadow:0 0 0 1px rgba(0,0,0,.05); }
|
||
.kfz-col .col-stack > span { display:block; min-height:1px; }
|
||
.kfz-col .col-empty { width:60%; border-top:1px dashed rgba(0,0,0,.12); }
|
||
.kfz-col .col-lab { font-size:.7rem; color:var(--muted); font-weight:600; }
|
||
.kfz-col .col-val { font-size:.65rem; color:#3a3a3a; font-variant-numeric:tabular-nums; }
|
||
.kfz-col.today .col-lab { color:var(--green-d); }
|
||
|
||
/* === Globaler Zeitraum-Filter für Fleiß-Anzeigen === */
|
||
.kfz-filter { display:flex; align-items:center; gap:.4rem; flex-wrap:wrap; padding:.55rem .7rem; background:#f5f3eb; border:1px solid var(--line); border-radius:8px; margin-bottom:.9rem; }
|
||
.kfz-filter-lab { font-size:.7rem; color:var(--muted); font-weight:600; text-transform:uppercase; letter-spacing:.04em; }
|
||
.kfz-filter-saved { margin-left:auto; font-size:.66rem; color:var(--muted); font-weight:600; cursor:help; }
|
||
.kfz-filter-hint { font-size:.66rem; color:var(--blue); font-weight:600; cursor:help; padding-left:.5rem; border-left:1px solid rgba(0,0,0,.10); }
|
||
|
||
/* === Zeitraum-Varianten (Tag / Monat / Schuljahr) === */
|
||
.zeitraum-variant { padding:.7rem 0 0; }
|
||
.zv-head { font-size:.78rem; font-weight:600; color:#3a3a3a; margin-bottom:.55rem; }
|
||
.zv-tag { display:inline-block; background:var(--green-d); color:#fff; font-size:.66rem; font-weight:700; padding:.13rem .55rem; border-radius:4px; margin-right:.4rem; text-transform:uppercase; letter-spacing:.04em; }
|
||
.zv-foot { margin-top:.55rem; font-size:.72rem; color:var(--muted); padding:.45rem .65rem; background:rgba(0,0,0,.02); border-radius:6px; }
|
||
.zv-foot b { color:#3a3a3a; }
|
||
|
||
/* Tag-Grid: 25 Stunden */
|
||
.zv-day-grid { display:grid; grid-template-columns:repeat(25, 1fr); gap:.2rem; align-items:end; padding:.4rem .15rem .2rem; background:#fbfaf3; border-radius:6px; }
|
||
.zv-day-col { display:flex; flex-direction:column; align-items:center; gap:.18rem; padding:.25rem 0; border-radius:3px; }
|
||
.zv-day-col.school { background:rgba(232,197,71,.18); }
|
||
.zv-day-col.today { box-shadow:0 0 0 2px var(--green-d); border-radius:4px; }
|
||
.zv-col-wrap { height:60px; width:100%; display:flex; align-items:flex-end; justify-content:center; }
|
||
.zv-col-stack { width:75%; display:flex; flex-direction:column-reverse; border-radius:2px 2px 0 0; overflow:hidden; box-shadow:0 0 0 1px rgba(0,0,0,.04); }
|
||
.zv-col-stack > span { display:block; min-height:1px; }
|
||
.zv-col-empty { width:50%; border-top:1px dashed rgba(0,0,0,.10); }
|
||
.zv-h { font-size:.6rem; color:var(--muted); font-weight:600; font-variant-numeric:tabular-nums; }
|
||
|
||
/* Monat-Grid: 30/31 Tage */
|
||
.zv-month-grid { display:grid; grid-template-columns:repeat(30, 1fr); gap:.2rem; align-items:end; padding:.4rem .15rem .2rem; background:#fbfaf3; border-radius:6px; }
|
||
.zv-month-grid .zv-day-col { padding:.18rem 0; }
|
||
.zv-month-grid .zv-col-wrap { height:55px; }
|
||
|
||
/* Schuljahr-Grid: bis zu 12 Monate */
|
||
.zv-year-grid { display:grid; grid-template-columns:repeat(10, 1fr); gap:.4rem; align-items:end; padding:.5rem .2rem .25rem; background:#fbfaf3; border-radius:6px; }
|
||
.zv-year-col { display:flex; flex-direction:column; align-items:center; gap:.18rem; padding:.3rem 0; border-radius:4px; }
|
||
.zv-year-col.today { box-shadow:0 0 0 2px var(--green-d); }
|
||
.zv-year-col .zv-col-wrap { width:34px; }
|
||
.zv-year-col .zv-col-stack { width:100%; }
|
||
.zv-y { font-size:.7rem; color:#3a3a3a; font-weight:600; }
|
||
.zv-y-sum { font-size:.62rem; color:var(--muted); font-variant-numeric:tabular-nums; }
|
||
|
||
/* === Polish-Sektion (Tooltips / Persistenz / Schuljahr-Land) === */
|
||
.polish-grid { display:grid; grid-template-columns:repeat(3, 1fr); gap:1rem; }
|
||
.polish-block { background:#fbfaf3; border:1px solid var(--line); border-radius:10px; padding:.95rem 1.1rem; }
|
||
.polish-block h3 { font-size:.86rem; color:var(--green-d); margin-bottom:.5rem; font-weight:700; }
|
||
.polish-block p { font-size:.82rem; color:#3a3a3a; margin-bottom:.6rem; line-height:1.5; }
|
||
.polish-block code { font-family:'JetBrains Mono',Consolas,monospace; font-size:.74rem; background:rgba(0,0,0,.05); padding:.05rem .3rem; border-radius:3px; color:#3a3a3a; }
|
||
.polish-spec { background:#fff; border:1px solid var(--line); border-radius:8px; padding:.55rem .7rem; font-size:.74rem; }
|
||
.ps-row { display:grid; grid-template-columns:60px 1fr; gap:.5rem; padding:.2rem 0; border-bottom:1px solid rgba(0,0,0,.04); }
|
||
.ps-row:last-child { border-bottom:none; }
|
||
.ps-k { font-weight:700; color:var(--green-d); }
|
||
.ps-v { color:#3a3a3a; line-height:1.4; }
|
||
.polish-code { background:#1a2620; color:#d8d5cd; border-radius:8px; padding:.7rem .9rem; font-family:'JetBrains Mono',Consolas,monospace; font-size:.72rem; line-height:1.55; white-space:pre; }
|
||
.polish-code .pc-k { color:#a8c3aa; font-weight:700; }
|
||
.polish-code .pc-v { color:#e8c547; }
|
||
.schuljahr-table { width:100%; border-collapse:collapse; font-size:.74rem; background:#fff; border-radius:6px; overflow:hidden; }
|
||
.schuljahr-table th { background:var(--green-d); color:#fff; padding:.35rem .55rem; text-align:left; font-weight:700; font-size:.68rem; text-transform:uppercase; letter-spacing:.03em; }
|
||
.schuljahr-table td { padding:.32rem .55rem; border-bottom:1px solid rgba(0,0,0,.05); color:#3a3a3a; }
|
||
.schuljahr-table tr:last-child td { border-bottom:none; }
|
||
.schuljahr-table tr:nth-child(even) td { background:rgba(0,0,0,.02); }
|
||
|
||
/* === Benchmark-Erklärbox === */
|
||
.benchmark { background:var(--blue-soft); border:1px solid rgba(74,124,138,.3); border-radius:10px; padding:.95rem 1.2rem; margin:1.2rem 0; font-size:.84rem; }
|
||
.benchmark h3 { color:var(--blue); font-size:.85rem; font-weight:700; margin-bottom:.4rem; }
|
||
.benchmark table { width:100%; border-collapse:collapse; margin:.4rem 0; font-size:.78rem; }
|
||
.benchmark th { background:rgba(74,124,138,.18); padding:.3rem .55rem; text-align:left; font-weight:700; color:var(--blue); font-size:.7rem; }
|
||
.benchmark td { padding:.3rem .55rem; border-bottom:1px solid rgba(0,0,0,.05); vertical-align:top; }
|
||
.benchmark td code { font-family:'JetBrains Mono',Consolas,monospace; font-size:.7rem; background:rgba(0,0,0,.04); padding:.05rem .3rem; border-radius:3px; }
|
||
|
||
@media (max-width:880px) {
|
||
.status-grid { grid-template-columns:repeat(2,1fr); }
|
||
.stu-row { grid-template-columns:auto 1fr; }
|
||
.stu-actions { grid-column:1/-1; flex-direction:row; align-items:center; justify-content:flex-end; flex-wrap:wrap; }
|
||
.stu-mini-stats { grid-template-columns:repeat(2,1fr); }
|
||
.ranking-grid { grid-template-columns:1fr; }
|
||
.kfz-col .col-wrap { width:24px; }
|
||
.zv-day-grid { grid-template-columns:repeat(13,1fr); }
|
||
.zv-day-grid .zv-day-col:nth-child(n+14) { display:none; }
|
||
.zv-month-grid { grid-template-columns:repeat(15,1fr); }
|
||
.zv-year-grid { grid-template-columns:repeat(5,1fr); }
|
||
.polish-grid { grid-template-columns:1fr; }
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<div class="nav">
|
||
<div class="nav-wrap">
|
||
<span class="nav-title">📊 Live-Cockpit Konzept</span>
|
||
<span class="nav-meta">Entwurf · GeoGraSim Lehrer-Cockpit · Stand 2026-06-10</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="wrap">
|
||
|
||
<h1>Live-Cockpit · Konzept-Entwurf <span style="font-size:.55em;font-weight:500;color:var(--muted);vertical-align:.4em">v2 — Thomas-Review eingearbeitet</span></h1>
|
||
<p class="lead">
|
||
Ziel: die Lehrperson sieht <b>auf einen Blick</b>, was in der Klasse gerade los ist —
|
||
wer aktiv ist, wer hinterher ist, wer heute noch nichts gemacht hat,
|
||
<b>wer die Top 3 und wer die Schwächsten 3 sind</b> —
|
||
und kann pro Schüler:in bei Bedarf bis ins Detail einsteigen.
|
||
Vier Ebenen: <b>Status & Ranking</b> ganz oben, dann <b>Filter</b> auf die ganze Klassenliste,
|
||
dann <b>pro Schüler:in eine Zeile</b> mit Live-Stats (jeder Wert mit Range-Balken),
|
||
und auf Klick der <b>Detail-Drill-Down</b>.
|
||
</p>
|
||
|
||
<div class="erklär">
|
||
<b>Änderungen vs. v1 (Thomas-Review 2026-06-10):</b>
|
||
<ul style="margin:.4rem 0 0 1.4rem">
|
||
<li><b>Klassen-Fleiß-Balken „heute" raus</b> — wenig Aussagekraft. Stattdessen:</li>
|
||
<li><b>Top 3 + Schwächste 3</b> als Schüler:innen-Ranking nach <b>Benchmark-Prozent</b> über alle Apps</li>
|
||
<li><b>Klassen-Fleiß als Säulen über Zeit</b> (Mo–So bzw. nach Filter) statt nur als Tages-Summe</li>
|
||
<li><b>In den Mini-Stats pro Schüler:in zusätzlich Range-Balken</b>, damit man weiß: ist 425 ppm CO₂ gut oder schlecht?</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<!-- ============== EBENE 1: STATUS + RANKING + KLASSEN-FLEISS ============== -->
|
||
|
||
<div class="card">
|
||
<div class="card-h">Ebene 1 · Klassen-Status auf einen Blick</div>
|
||
|
||
<!-- A) Status-Tiles: alle 4 Zahlen beziehen sich auf SCHÜLER:INNEN -->
|
||
<div class="status-grid">
|
||
<div class="status-tile aktiv">
|
||
<span class="num">4</span>
|
||
<span class="lab"><b>jetzt aktiv</b><br><span style="color:var(--muted);font-size:.7rem">Schüler:innen mit Heartbeat in den letzten 30 s</span></span>
|
||
</div>
|
||
<div class="status-tile heute">
|
||
<span class="num">9</span>
|
||
<span class="lab"><b>heute aktiv</b><br><span style="color:var(--muted);font-size:.7rem">heute schon gearbeitet, gerade pausiert</span></span>
|
||
</div>
|
||
<div class="status-tile kalt">
|
||
<span class="num">12</span>
|
||
<span class="lab"><b>heute noch nichts</b><br><span style="color:var(--muted);font-size:.7rem">kein Login seit heute 0:00 Uhr</span></span>
|
||
</div>
|
||
<div class="status-tile hilfe zero">
|
||
<span class="num">0</span>
|
||
<span class="lab"><b>brauchen Hilfe</b><br><span style="color:var(--muted);font-size:.7rem">stockt · viele Fehlversuche · Pilot-Übernahme</span></span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- B) Ranking: Top 3 + Schwächste 3 (nach Benchmark über alle Apps) -->
|
||
<div class="ranking-grid">
|
||
|
||
<div class="ranking-block top">
|
||
<h3>🏆 Top 3 — Benchmark gesamt</h3>
|
||
<div class="ranking-list">
|
||
|
||
<div class="rank-row top">
|
||
<span class="rk">1.</span>
|
||
<span class="av">🐬</span>
|
||
<span class="nm">Lenchen</span>
|
||
<span class="pc">87 %</span>
|
||
<span class="pcbar"><div style="width:87%"></div></span>
|
||
</div>
|
||
|
||
<div class="rank-row top">
|
||
<span class="rk">2.</span>
|
||
<span class="av">🐝</span>
|
||
<span class="nm">Franz</span>
|
||
<span class="pc">81 %</span>
|
||
<span class="pcbar"><div style="width:81%"></div></span>
|
||
</div>
|
||
|
||
<div class="rank-row top">
|
||
<span class="rk">3.</span>
|
||
<span class="av">🦫</span>
|
||
<span class="nm">Teresa</span>
|
||
<span class="pc">76 %</span>
|
||
<span class="pcbar"><div style="width:76%"></div></span>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<div class="ranking-block bottom">
|
||
<h3>👀 Schwächste 3 — Benchmark gesamt</h3>
|
||
<div class="ranking-list">
|
||
|
||
<div class="rank-row bottom">
|
||
<span class="rk">23.</span>
|
||
<span class="av">🐉</span>
|
||
<span class="nm">Lukas</span>
|
||
<span class="pc">28 %</span>
|
||
<span class="pcbar"><div style="width:28%"></div></span>
|
||
</div>
|
||
|
||
<div class="rank-row bottom">
|
||
<span class="rk">24.</span>
|
||
<span class="av">🐧</span>
|
||
<span class="nm">bubi</span>
|
||
<span class="pc">19 %</span>
|
||
<span class="pcbar"><div style="width:19%"></div></span>
|
||
</div>
|
||
|
||
<div class="rank-row bottom">
|
||
<span class="rk">25.</span>
|
||
<span class="av" style="background:#e0dccd">?</span>
|
||
<span class="nm">Sabine</span>
|
||
<span class="pc" style="color:var(--gray)">– %</span>
|
||
<span class="pcbar"><div style="width:0%"></div></span>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<!-- C) Klassen-Fleiß über Zeit — Säulen pro Bucket -->
|
||
<div class="klassen-fleiss-zeit">
|
||
|
||
<!-- Globaler Zeitraum-Filter — gilt für ALLE Fleißanzeigen -->
|
||
<!-- Auswahl wird in localStorage 'ggs-fleiss-range' gespeichert,
|
||
sodass die Lehrperson sie nicht jedes Mal neu setzen muss. -->
|
||
<div class="kfz-filter">
|
||
<span class="kfz-filter-lab">Zeitraum:</span>
|
||
<span class="pill" title="Heute · 25 Stunden 0:00 – 24:00 · Schulkernzeit 8–13 Uhr hervorgehoben">
|
||
<span class="dot k"></span>Tag
|
||
</span>
|
||
<span class="pill active" title="Aktuelle Kalenderwoche · Mo–So · heutiger Tag markiert">
|
||
Woche
|
||
</span>
|
||
<span class="pill" title="Letzte 30 Tage · alle Tage sichtbar, Wochenenden als Lücken erkennbar">
|
||
Monat
|
||
</span>
|
||
<span class="pill" title="Aktuelles Schuljahr · ab Schulanfang (Land-abhängig) bis Schulende · leere Monate am Anfang/Ende weggelassen">
|
||
Schuljahr
|
||
</span>
|
||
<span class="kfz-filter-saved" title="Die zuletzt gewählte Einstellung wird automatisch gespeichert (localStorage ggs-fleiss-range)">
|
||
💾 gemerkt
|
||
</span>
|
||
<span class="kfz-filter-hint" title="Der Filter gilt auch für die Schüler:innen-Fleiß-Säulen im Ergebnisse-Tab">
|
||
🔗 wirkt auch auf die Schüler-Fleißsäulen
|
||
</span>
|
||
</div>
|
||
|
||
<div class="kfz-head">
|
||
<h3>📊 Klassen-Fleiß über Zeit</h3>
|
||
<span class="meta"><b>Diese Woche · Mo–So</b> · Säule = aktive Lernzeit der ganzen Klasse · Farbe = Modul · <b>Klassensumme 22 h 14 min</b></span>
|
||
</div>
|
||
<div class="kfz-grid">
|
||
|
||
<div class="kfz-col">
|
||
<span class="col-val">3 h 12 min</span>
|
||
<div class="col-wrap">
|
||
<div class="col-stack" style="height:65%">
|
||
<span style="background:var(--blue);height:55%"></span>
|
||
<span style="background:var(--green);height:30%"></span>
|
||
<span style="background:var(--orange);height:15%"></span>
|
||
</div>
|
||
</div>
|
||
<span class="col-lab">Mo</span>
|
||
</div>
|
||
|
||
<div class="kfz-col">
|
||
<span class="col-val">4 h 48 min</span>
|
||
<div class="col-wrap">
|
||
<div class="col-stack" style="height:95%">
|
||
<span style="background:var(--blue);height:45%"></span>
|
||
<span style="background:var(--green);height:35%"></span>
|
||
<span style="background:var(--orange);height:20%"></span>
|
||
</div>
|
||
</div>
|
||
<span class="col-lab">Di</span>
|
||
</div>
|
||
|
||
<div class="kfz-col">
|
||
<span class="col-val">2 h 30 min</span>
|
||
<div class="col-wrap">
|
||
<div class="col-stack" style="height:50%">
|
||
<span style="background:var(--green);height:60%"></span>
|
||
<span style="background:#7c3aed;height:40%"></span>
|
||
</div>
|
||
</div>
|
||
<span class="col-lab">Mi</span>
|
||
</div>
|
||
|
||
<div class="kfz-col">
|
||
<span class="col-val">3 h 50 min</span>
|
||
<div class="col-wrap">
|
||
<div class="col-stack" style="height:78%">
|
||
<span style="background:var(--orange);height:40%"></span>
|
||
<span style="background:var(--green);height:35%"></span>
|
||
<span style="background:var(--blue);height:25%"></span>
|
||
</div>
|
||
</div>
|
||
<span class="col-lab">Do</span>
|
||
</div>
|
||
|
||
<div class="kfz-col today">
|
||
<span class="col-val"><b style="color:var(--green-d)">4 h 22 min</b></span>
|
||
<div class="col-wrap">
|
||
<div class="col-stack" style="height:85%">
|
||
<span style="background:var(--blue);height:50%"></span>
|
||
<span style="background:var(--orange);height:30%"></span>
|
||
<span style="background:var(--green);height:20%"></span>
|
||
</div>
|
||
</div>
|
||
<span class="col-lab"><b>Fr · heute</b></span>
|
||
</div>
|
||
|
||
<div class="kfz-col">
|
||
<span class="col-val">45 min</span>
|
||
<div class="col-wrap">
|
||
<div class="col-stack" style="height:15%">
|
||
<span style="background:var(--green);height:100%"></span>
|
||
</div>
|
||
</div>
|
||
<span class="col-lab">Sa</span>
|
||
</div>
|
||
|
||
<div class="kfz-col">
|
||
<span class="col-val">—</span>
|
||
<div class="col-wrap">
|
||
<div class="col-empty"></div>
|
||
</div>
|
||
<span class="col-lab">So</span>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<!-- Modul-Legende -->
|
||
<div style="display:flex;flex-wrap:wrap;gap:.4rem .8rem;margin-top:.7rem;font-size:.7rem;color:#3a3a3a">
|
||
<span style="display:inline-flex;align-items:center;gap:.3rem"><span style="display:inline-block;width:10px;height:10px;background:var(--blue);border-radius:2px"></span> 🌍 Klima</span>
|
||
<span style="display:inline-flex;align-items:center;gap:.3rem"><span style="display:inline-block;width:10px;height:10px;background:var(--green);border-radius:2px"></span> 🚁 Heli</span>
|
||
<span style="display:inline-flex;align-items:center;gap:.3rem"><span style="display:inline-block;width:10px;height:10px;background:var(--orange);border-radius:2px"></span> 🍽️ Weltküche</span>
|
||
<span style="display:inline-flex;align-items:center;gap:.3rem"><span style="display:inline-block;width:10px;height:10px;background:#7c3aed;border-radius:2px"></span> 🚌 Busfahrt</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ============== ZEITRAUM-FILTER · ALLE VARIANTEN ============== -->
|
||
|
||
<div class="card">
|
||
<div class="card-h">Zeitraum-Filter · alle vier Varianten im Vergleich</div>
|
||
<p style="font-size:.78rem;color:var(--muted);margin-bottom:1rem">
|
||
Der Filter oben (<b>Tag · Woche · Monat · Schuljahr</b>) wirkt auf alle Fleiß-Säulen-Anzeigen
|
||
gleichzeitig — Klassen-Fleiß im Live-Cockpit und Schüler:innen-Fleiß-Matrix im Ergebnisse-Tab.
|
||
Die folgenden Skizzen zeigen, wie die Säulen-Auflösung pro Variante aussieht.
|
||
</p>
|
||
|
||
<!-- Tag-Ansicht: 25 Stunden-Säulen, Schulzeit 8-13 hervorgehoben -->
|
||
<div class="zeitraum-variant">
|
||
<div class="zv-head"><span class="zv-tag">Tag</span> · Stunden 0–24 · Schulkernzeit grau hinterlegt</div>
|
||
<div class="zv-day-grid">
|
||
<!-- Nachtstunden 0-7: nur Marker, kaum Aktivität -->
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><span class="zv-col-empty"></span></div><span class="zv-h">0</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><span class="zv-col-empty"></span></div><span class="zv-h">1</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><span class="zv-col-empty"></span></div><span class="zv-h">2</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><span class="zv-col-empty"></span></div><span class="zv-h">3</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><span class="zv-col-empty"></span></div><span class="zv-h">4</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><span class="zv-col-empty"></span></div><span class="zv-h">5</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><span class="zv-col-empty"></span></div><span class="zv-h">6</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><span class="zv-col-empty"></span></div><span class="zv-h">7</span></div>
|
||
|
||
<!-- Schulkernzeit 8-13: hervorgehoben -->
|
||
<div class="zv-day-col school"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:70%"><span style="background:var(--blue);height:60%"></span><span style="background:var(--green);height:40%"></span></div></div><span class="zv-h">8</span></div>
|
||
<div class="zv-day-col school"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:88%"><span style="background:var(--blue);height:50%"></span><span style="background:var(--orange);height:30%"></span><span style="background:var(--green);height:20%"></span></div></div><span class="zv-h">9</span></div>
|
||
<div class="zv-day-col school"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:95%"><span style="background:var(--blue);height:55%"></span><span style="background:var(--green);height:25%"></span><span style="background:var(--orange);height:20%"></span></div></div><span class="zv-h">10</span></div>
|
||
<div class="zv-day-col school"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:62%"><span style="background:var(--orange);height:55%"></span><span style="background:#7c3aed;height:45%"></span></div></div><span class="zv-h">11</span></div>
|
||
<div class="zv-day-col school"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:48%"><span style="background:var(--green);height:100%"></span></div></div><span class="zv-h">12</span></div>
|
||
<div class="zv-day-col school"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:30%"><span style="background:#7c3aed;height:100%"></span></div></div><span class="zv-h">13</span></div>
|
||
|
||
<!-- Nachmittag 14-19: leichte Aktivität (HÜ) -->
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><span class="zv-col-empty"></span></div><span class="zv-h">14</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:22%"><span style="background:var(--blue);height:100%"></span></div></div><span class="zv-h">15</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:35%"><span style="background:var(--blue);height:70%"></span><span style="background:var(--orange);height:30%"></span></div></div><span class="zv-h">16</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:18%"><span style="background:var(--orange);height:100%"></span></div></div><span class="zv-h">17</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><span class="zv-col-empty"></span></div><span class="zv-h">18</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><span class="zv-col-empty"></span></div><span class="zv-h">19</span></div>
|
||
|
||
<!-- Abend 20-24: praktisch leer -->
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><span class="zv-col-empty"></span></div><span class="zv-h">20</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><span class="zv-col-empty"></span></div><span class="zv-h">21</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><span class="zv-col-empty"></span></div><span class="zv-h">22</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><span class="zv-col-empty"></span></div><span class="zv-h">23</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><span class="zv-col-empty"></span></div><span class="zv-h">24</span></div>
|
||
</div>
|
||
<div class="zv-foot">
|
||
<span>📌 Die <b>Schulkernzeit 8–13 Uhr</b> ist hellgelb hinterlegt — so erkennt die Lehrperson schnell, ob im Unterricht oder vor allem als Hausübung gearbeitet wurde.</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Monat-Ansicht: 30 Tage, leere am Anfang weglassen -->
|
||
<div class="zeitraum-variant" style="margin-top:1.4rem">
|
||
<div class="zv-head"><span class="zv-tag">Monat</span> · 30 Tage (1.–30.) · alle Tage sichtbar, leere Tage als gestrichelte Baseline</div>
|
||
<div class="zv-month-grid">
|
||
<!-- 30 Säulen mit Beispiel-Heights -->
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:42%"><span style="background:var(--blue);height:100%"></span></div></div><span class="zv-h">1</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:58%"><span style="background:var(--blue);height:60%"></span><span style="background:var(--green);height:40%"></span></div></div><span class="zv-h">2</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:35%"><span style="background:var(--green);height:100%"></span></div></div><span class="zv-h">3</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><span class="zv-col-empty"></span></div><span class="zv-h">4</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><span class="zv-col-empty"></span></div><span class="zv-h">5</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:68%"><span style="background:var(--orange);height:50%"></span><span style="background:var(--blue);height:30%"></span><span style="background:var(--green);height:20%"></span></div></div><span class="zv-h">6</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:72%"><span style="background:var(--blue);height:70%"></span><span style="background:var(--orange);height:30%"></span></div></div><span class="zv-h">7</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:45%"><span style="background:var(--green);height:100%"></span></div></div><span class="zv-h">8</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:88%"><span style="background:var(--blue);height:60%"></span><span style="background:var(--orange);height:25%"></span><span style="background:#7c3aed;height:15%"></span></div></div><span class="zv-h">9</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:52%"><span style="background:var(--orange);height:100%"></span></div></div><span class="zv-h">10</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><span class="zv-col-empty"></span></div><span class="zv-h">11</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><span class="zv-col-empty"></span></div><span class="zv-h">12</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:65%"><span style="background:var(--blue);height:50%"></span><span style="background:var(--green);height:30%"></span><span style="background:var(--orange);height:20%"></span></div></div><span class="zv-h">13</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:78%"><span style="background:var(--blue);height:55%"></span><span style="background:var(--orange);height:45%"></span></div></div><span class="zv-h">14</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:42%"><span style="background:var(--green);height:100%"></span></div></div><span class="zv-h">15</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:38%"><span style="background:var(--orange);height:100%"></span></div></div><span class="zv-h">16</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:62%"><span style="background:var(--blue);height:80%"></span><span style="background:var(--green);height:20%"></span></div></div><span class="zv-h">17</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><span class="zv-col-empty"></span></div><span class="zv-h">18</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><span class="zv-col-empty"></span></div><span class="zv-h">19</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:82%"><span style="background:var(--blue);height:60%"></span><span style="background:var(--orange);height:40%"></span></div></div><span class="zv-h">20</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:55%"><span style="background:var(--orange);height:60%"></span><span style="background:var(--green);height:40%"></span></div></div><span class="zv-h">21</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:48%"><span style="background:var(--green);height:100%"></span></div></div><span class="zv-h">22</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:35%"><span style="background:var(--blue);height:100%"></span></div></div><span class="zv-h">23</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><span class="zv-col-empty"></span></div><span class="zv-h">24</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><span class="zv-col-empty"></span></div><span class="zv-h">25</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:72%"><span style="background:var(--blue);height:70%"></span><span style="background:var(--orange);height:30%"></span></div></div><span class="zv-h">26</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:88%"><span style="background:var(--blue);height:50%"></span><span style="background:var(--green);height:30%"></span><span style="background:var(--orange);height:20%"></span></div></div><span class="zv-h">27</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:65%"><span style="background:var(--orange);height:55%"></span><span style="background:var(--green);height:45%"></span></div></div><span class="zv-h">28</span></div>
|
||
<div class="zv-day-col"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:42%"><span style="background:var(--green);height:100%"></span></div></div><span class="zv-h">29</span></div>
|
||
<div class="zv-day-col today"><div class="zv-col-wrap"><div class="zv-col-stack" style="height:78%"><span style="background:var(--blue);height:50%"></span><span style="background:var(--orange);height:30%"></span><span style="background:var(--green);height:20%"></span></div></div><span class="zv-h"><b>30</b></span></div>
|
||
</div>
|
||
<div class="zv-foot">
|
||
<span>📌 <b>Wochenenden klar erkennbar</b> als systematische Lücken (4./5., 11./12., 18./19., 25./26.).</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Schuljahr-Ansicht: nur Monate mit Aktivität -->
|
||
<div class="zeitraum-variant" style="margin-top:1.4rem">
|
||
<div class="zv-head"><span class="zv-tag">Schuljahr</span> · Aug–Jul · leere Monate am Anfang & Ende weggelassen</div>
|
||
<div class="zv-year-grid">
|
||
<!-- August und Juli werden hier weggelassen (Schulanfang fängt erst Sep an im Beispiel) -->
|
||
<div class="zv-year-col"><div class="zv-col-wrap" style="height:120px"><div class="zv-col-stack" style="height:25%"><span style="background:var(--blue);height:60%"></span><span style="background:var(--green);height:40%"></span></div></div><span class="zv-y">Sep</span><span class="zv-y-sum">8 h 12 min</span></div>
|
||
<div class="zv-year-col"><div class="zv-col-wrap" style="height:120px"><div class="zv-col-stack" style="height:60%"><span style="background:var(--blue);height:50%"></span><span style="background:var(--green);height:30%"></span><span style="background:var(--orange);height:20%"></span></div></div><span class="zv-y">Okt</span><span class="zv-y-sum">19 h 48 min</span></div>
|
||
<div class="zv-year-col"><div class="zv-col-wrap" style="height:120px"><div class="zv-col-stack" style="height:75%"><span style="background:var(--blue);height:45%"></span><span style="background:var(--orange);height:30%"></span><span style="background:var(--green);height:15%"></span><span style="background:#7c3aed;height:10%"></span></div></div><span class="zv-y">Nov</span><span class="zv-y-sum">24 h 30 min</span></div>
|
||
<div class="zv-year-col"><div class="zv-col-wrap" style="height:120px"><div class="zv-col-stack" style="height:55%"><span style="background:var(--orange);height:50%"></span><span style="background:var(--blue);height:30%"></span><span style="background:var(--green);height:20%"></span></div></div><span class="zv-y">Dez</span><span class="zv-y-sum">17 h 50 min</span></div>
|
||
<div class="zv-year-col"><div class="zv-col-wrap" style="height:120px"><div class="zv-col-stack" style="height:88%"><span style="background:var(--blue);height:40%"></span><span style="background:var(--green);height:30%"></span><span style="background:var(--orange);height:20%"></span><span style="background:#7c3aed;height:10%"></span></div></div><span class="zv-y">Jän</span><span class="zv-y-sum">28 h 04 min</span></div>
|
||
<div class="zv-year-col"><div class="zv-col-wrap" style="height:120px"><div class="zv-col-stack" style="height:72%"><span style="background:var(--blue);height:35%"></span><span style="background:var(--orange);height:35%"></span><span style="background:var(--green);height:20%"></span><span style="background:#7c3aed;height:10%"></span></div></div><span class="zv-y">Feb</span><span class="zv-y-sum">22 h 56 min</span></div>
|
||
<div class="zv-year-col"><div class="zv-col-wrap" style="height:120px"><div class="zv-col-stack" style="height:80%"><span style="background:var(--orange);height:40%"></span><span style="background:var(--blue);height:30%"></span><span style="background:var(--green);height:30%"></span></div></div><span class="zv-y">Mär</span><span class="zv-y-sum">25 h 30 min</span></div>
|
||
<div class="zv-year-col"><div class="zv-col-wrap" style="height:120px"><div class="zv-col-stack" style="height:48%"><span style="background:var(--green);height:50%"></span><span style="background:var(--blue);height:50%"></span></div></div><span class="zv-y">Apr</span><span class="zv-y-sum">15 h 18 min</span></div>
|
||
<div class="zv-year-col"><div class="zv-col-wrap" style="height:120px"><div class="zv-col-stack" style="height:92%"><span style="background:var(--blue);height:35%"></span><span style="background:var(--orange);height:30%"></span><span style="background:var(--green);height:25%"></span><span style="background:#7c3aed;height:10%"></span></div></div><span class="zv-y">Mai</span><span class="zv-y-sum">29 h 12 min</span></div>
|
||
<div class="zv-year-col today"><div class="zv-col-wrap" style="height:120px"><div class="zv-col-stack" style="height:38%"><span style="background:var(--blue);height:55%"></span><span style="background:var(--orange);height:30%"></span><span style="background:var(--green);height:15%"></span></div></div><span class="zv-y"><b>Jun · aktuell</b></span><span class="zv-y-sum">12 h 04 min</span></div>
|
||
</div>
|
||
<div class="zv-foot">
|
||
<span>📌 <b>Aug 2025</b> und <b>Jul 2026</b> ausgeblendet — vor Schulanfang und nach Schulschluss keine Aktivität, daher nicht relevant. Sobald in einem dieser Monate Aktivität entsteht, wird er automatisch eingeblendet.</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Woche-Ansicht-Verweis -->
|
||
<div style="margin-top:1rem;padding:.7rem .9rem;background:#f5f3eb;border-radius:8px;font-size:.78rem;color:var(--muted)">
|
||
<b style="color:var(--green-d)">Woche</b>-Ansicht: siehe Ebene-1-Sektion oben (Mo–So, „heute" markiert) — das ist der Default-Filter beim ersten Aufruf des Cockpits (bei späteren Aufrufen die zuletzt gewählte Einstellung).
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ============== POLISH-DETAILS DES FILTERS ============== -->
|
||
|
||
<div class="card">
|
||
<div class="card-h">Polish-Details des Zeitraum-Filters</div>
|
||
|
||
<div class="polish-grid">
|
||
|
||
<!-- 1) Tooltips -->
|
||
<div class="polish-block">
|
||
<h3>💡 Tooltips an den Filter-Pills</h3>
|
||
<p>
|
||
Hover über jede Pill zeigt eine Kurz-Spec — nützlich besonders für die Lehrperson,
|
||
die das Cockpit zum ersten Mal sieht. Probier es oben am Filter mal aus.
|
||
</p>
|
||
<div class="polish-spec">
|
||
<div class="ps-row"><span class="ps-k">Tag</span><span class="ps-v">Heute · 25 Stunden 0:00 – 24:00 · Schulkernzeit 8–13 Uhr hervorgehoben</span></div>
|
||
<div class="ps-row"><span class="ps-k">Woche</span><span class="ps-v">Aktuelle Kalenderwoche · Mo–So · heutiger Tag markiert</span></div>
|
||
<div class="ps-row"><span class="ps-k">Monat</span><span class="ps-v">Letzte 30 Tage · alle Tage sichtbar, Wochenenden als Lücken erkennbar</span></div>
|
||
<div class="ps-row"><span class="ps-k">Schuljahr</span><span class="ps-v">Aktuelles Schuljahr · ab Schulanfang (Land-abhängig) bis Schulende · leere Monate am Anfang/Ende weggelassen</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 2) localStorage-Persistenz -->
|
||
<div class="polish-block">
|
||
<h3>💾 Persistenz der Auswahl</h3>
|
||
<p>
|
||
Die gewählte Einstellung wird in <code>localStorage</code> gespeichert.
|
||
Bei jedem späteren Aufruf des Cockpits steht der Filter direkt auf dem
|
||
zuletzt gewählten Wert — keine Mehrfach-Klicks pro Tag.
|
||
</p>
|
||
<div class="polish-code">
|
||
<span class="pc-k">localStorage-Key:</span> <span class="pc-v">ggs-fleiss-range</span>
|
||
<span class="pc-k">Mögliche Werte:</span> <span class="pc-v">day · week · month · year</span>
|
||
<span class="pc-k">Default beim ersten Aufruf:</span> <span class="pc-v">week</span>
|
||
<span class="pc-k">Sichtbar im UI:</span> <span class="pc-v">💾 gemerkt (rechts neben den Pills)</span></div>
|
||
<p style="font-size:.78rem;color:var(--muted);margin-top:.5rem">
|
||
Der Wert ist <b>pro Lehrperson</b> (Browser-lokal), nicht pro Klasse — das hält die
|
||
Bedienung leichtgewichtig. Falls jemand mehrere Klassen oft umschaltet, kann
|
||
später auf Server-Seite ein User-Preference-Feld dazu (siehe Memory).
|
||
</p>
|
||
</div>
|
||
|
||
<!-- 3) Land-basierte Schuljahre — DACH+LI -->
|
||
<div class="polish-block">
|
||
<h3>🌍 Schuljahr aus Land · DACH+LI</h3>
|
||
<p>
|
||
Die Plattform bedient gezielt <b>Österreich, Deutschland, Schweiz, Liechtenstein</b>.
|
||
Schul-Anfangs- und Endmonate ziehen wir aus <code>App/php/lib/Country.php</code>
|
||
(existiert schon für andere Sprach-/Lehrplan-Themen).
|
||
</p>
|
||
<table class="schuljahr-table">
|
||
<thead>
|
||
<tr><th>Land</th><th>Schulanfang</th><th>Schulende</th><th>Bemerkung</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr><td>🇦🇹 Österreich</td><td>September</td><td>Juli</td><td>1. Schultag Mo nach 1. September (Ost) bzw. 2. Mo im September (West)</td></tr>
|
||
<tr><td>🇩🇪 Deutschland</td><td>August / September</td><td>Juli</td><td>variiert nach Bundesland · BY/BW: Mitte Sep · HH/B/MV: Anfang Aug</td></tr>
|
||
<tr><td>🇨🇭 Schweiz</td><td>August</td><td>Juli / August</td><td>variiert nach Kanton · ZH/BE/SG: Mitte Aug · TI: Anfang Sep</td></tr>
|
||
<tr><td>🇱🇮 Liechtenstein</td><td>August</td><td>Juli</td><td>angelehnt an Schweiz (Mitte Aug)</td></tr>
|
||
</tbody>
|
||
</table>
|
||
<p style="font-size:.78rem;color:var(--muted);margin-top:.5rem">
|
||
<b>Konkret im Code:</b> <code>Country::schoolYearStart('AT')</code> liefert <code>{month: 9, dayApprox: 5}</code>,
|
||
<code>Country::schoolYearStart('CH')</code> liefert <code>{month: 8, dayApprox: 15}</code>.
|
||
Die Schuljahr-Säulen-Anzeige beginnt beim ersten Monat nach dem Schulanfang mit Aktivität
|
||
und endet beim letzten — leere Monate am Rand werden weggelassen (Sommerferien-Lücken
|
||
im Schuljahr also auch automatisch unsichtbar, falls eine Klasse über Ferien nichts spielt).
|
||
</p>
|
||
<p style="font-size:.78rem;color:var(--muted);margin-top:.4rem">
|
||
<b>DE-Bundesland-Logik</b>: in DE genauer Schulanfang ist Bundesland-spezifisch.
|
||
Pragmatisch: pro Klasse ein Feld <code>classes.school_region</code> (optional) — sonst Default „Mitte August".
|
||
Sehr selten relevant für die Säulen-Anzeige, weil ein Säulen-Bucket ein ganzer Monat ist.
|
||
</p>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<!-- Implementations-Notiz -->
|
||
<div style="margin-top:1.2rem;padding:.8rem 1rem;background:#fff8e1;border-left:4px solid var(--gold);border-radius:0 8px 8px 0;font-size:.78rem">
|
||
<b style="color:#8a6516">Implementierungs-Aufwand für die drei Polish-Punkte zusammen:</b>
|
||
ca. <b>1,5 Stunden</b>. Tooltips sind reine <code>title</code>-Attribute (~15 min), localStorage-Persistenz ist
|
||
ein Wrapper um das State-Setting (~20 min), das Schuljahr-aus-Country für AT/DE/CH/LI braucht
|
||
eine neue Methode in <code>Country.php</code> plus die kleine 4-Zeilen-Mapping-Tabelle (~30 min)
|
||
sowie eine kleine Anpassung im Säulen-Renderer (~15 min). Tests + Edge-Cases
|
||
(Schuljahres-Wechsel im August/September, Halbjahr-Ferien-Lücken) ~10 min.
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ============== BENCHMARK-KONZEPT (Erklärung) ============== -->
|
||
|
||
<div class="benchmark">
|
||
<h3>🎯 Wie funktioniert das Benchmark-Prozent über alle Apps?</h3>
|
||
<p>
|
||
Jede Simulation liefert einen normalisierten <b>Modul-Score 0–100 %</b>, der die
|
||
Leistung in einer Session widerspiegelt. Der <b>Gesamt-Benchmark einer Schüler:in</b>
|
||
ist der Mittelwert aller ihrer abgeschlossenen Sessions — gewichtet so, dass eine
|
||
häufig gespielte Sim nicht alles dominiert (max. 3 Sessions pro Modul zählen ein,
|
||
danach gilt nur das beste Ergebnis).
|
||
</p>
|
||
|
||
<table>
|
||
<tr><th>Modul</th><th>Was ergibt 100 %?</th><th>Berechnung (Vorschlag)</th></tr>
|
||
<tr>
|
||
<td>🌍 Klimawächter</td>
|
||
<td>Temp ≤ +1 °C, Inselüberflutung 0 %, Budget > 1000, Bevölkerung 100 %</td>
|
||
<td><code>(tempScore + inselScore + budgetScore + popScore) / 4</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>🚁 Heli</td>
|
||
<td>Alle Wegpunkte ohne Fehlversuch, Audio durch</td>
|
||
<td><code>planCorrect/planTotal × (1 − planAttempts/15)</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>🚌 Busfahrt</td>
|
||
<td>Quiz Erste-Wahl-Quote 100 %, Distanz-Abweichung < 30 km Ø</td>
|
||
<td><code>0.7×quizFirstTryRate + 0.3×(1 − distMean/200)</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>🍽️ Weltküche</td>
|
||
<td>Alle Gerichte abgeschlossen, <3 Fehlklicks pro Zutat</td>
|
||
<td><code>completedDishes/totalDishes × (1 − mistakes/maxMistakes)</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>🌾 Farmer</td>
|
||
<td>Erfolgsrate 100 %, Jahr ≥ 20 erreicht, CO₂ niedrig</td>
|
||
<td><code>0.5×successRate + 0.3×(years/20) + 0.2×(1 − co2Norm)</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>🪐 Sonnensystem</td>
|
||
<td>Alle 20 Aufgaben gelöst, möglichst Erste-Wahl</td>
|
||
<td><code>completed/total × (1 − attempts/maxAttempts)</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>🏛️ EU-Werkstatt</td>
|
||
<td>Alle 4 Fälle korrekt, Mülleimer leer</td>
|
||
<td><code>firstTryHits/totalSteps × (1 − muelleimer/totalAttempts)</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>⚡ Energiemanager</td>
|
||
<td>Alle 8 Blöcke ohne Defizit, alle 6 Sets durch</td>
|
||
<td><code>perfectBlocks/totalBlocks × setIndex/setTotal</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>🌊 Fluss</td>
|
||
<td>Biodiv ≥ 80, Economy ≥ 60, Flood < 20, Population stabil</td>
|
||
<td><code>(biodiv + economy + (100-flood) + popStable) / 4</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>✈️ Fluggesellschaft</td>
|
||
<td>Alle Aufträge gewonnen, Quiz Erste-Wahl 100 %, hohe Marge</td>
|
||
<td><code>0.5×wonRate + 0.3×quizFirstTry + 0.2×marginScore</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>📦 Logistik</td>
|
||
<td>≥80 % Aufträge pünktlich abgeschlossen, Endbilanz positiv</td>
|
||
<td><code>0.7×onTimeRate + 0.3×profitNorm</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>📅 Entscheidungstag</td>
|
||
<td>Tag-Ziel erreicht, CO₂/kWh-Limit eingehalten</td>
|
||
<td><code>noch zu definieren</code></td>
|
||
</tr>
|
||
</table>
|
||
|
||
<p style="margin-top:.5rem;color:#3a3a3a;font-size:.78rem">
|
||
<b>Wichtig:</b> der Prozentwert ist <b>nicht</b> eine Note — er ist eine Orientierung.
|
||
Beim Klick auf „Detail" sieht die Lehrperson, woraus sich die Zahl zusammensetzt
|
||
(welches Modul, welche Dimension hat ihn nach unten oder oben gezogen).
|
||
Schüler:innen sehen den eigenen Wert nicht direkt — das verhindert Wettkampfdruck.
|
||
Die Lehrperson kann pro Klasse entscheiden, ob sie ihn teilen möchte.
|
||
</p>
|
||
</div>
|
||
|
||
<!-- ============== FILTER ============== -->
|
||
|
||
<div class="card">
|
||
<div class="card-h">Ebene 2 · Filter & Sortierung</div>
|
||
|
||
<div class="filter-bar">
|
||
<span class="pill active">Alle <span class="badge">25</span></span>
|
||
<span class="pill"><span class="dot g"></span>Jetzt aktiv <span class="badge">4</span></span>
|
||
<span class="pill"><span class="dot o"></span>Heute aktiv <span class="badge">9</span></span>
|
||
<span class="pill"><span class="dot k"></span>Heute nichts <span class="badge">12</span></span>
|
||
<span class="pill"><span class="dot r"></span>Brauchen Hilfe <span class="badge">0</span></span>
|
||
<span class="sep"></span>
|
||
<span class="filter-lab">Modul:</span>
|
||
<select class="filter-select">
|
||
<option>Alle Module</option>
|
||
<option>🌍 Klimawächter</option>
|
||
<option>🚁 Heli-Navigation</option>
|
||
<option>🍽️ Weltküche</option>
|
||
<option>🚌 Busfahrt</option>
|
||
<option>📅 Entscheidungstag</option>
|
||
</select>
|
||
<span class="sep"></span>
|
||
<span class="filter-lab">Sortierung:</span>
|
||
<select class="filter-select">
|
||
<option>Status (aktiv zuerst)</option>
|
||
<option>Name A–Z</option>
|
||
<option>Lernzeit heute ↓</option>
|
||
<option>Letzter Heartbeat ↓</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ============== EBENE 3: SCHÜLERLISTE ============== -->
|
||
|
||
<div class="card">
|
||
<div class="card-h">Ebene 3 · Klassenliste (Mockup mit Beispieldaten)</div>
|
||
|
||
<div class="student-list">
|
||
|
||
<!-- Jetzt aktiv: Klima -->
|
||
<div class="stu-row aktiv">
|
||
<div class="stu-avatar-block">
|
||
<span class="stu-status-icon" title="Jetzt aktiv">🟢</span>
|
||
<div class="stu-avatar">🐬</div>
|
||
</div>
|
||
<div class="stu-meta">
|
||
<div class="stu-name">Lenchen <span class="pulse"></span></div>
|
||
<div class="stu-sub">
|
||
<span class="module-chip">🌍 Klimawächter</span>
|
||
<span class="phase">Jahr 12 von 75</span>
|
||
<span class="heartbeat">⏱ aktiv vor 3 s · Sitzung 14 min</span>
|
||
</div>
|
||
<div class="stu-mini-stats">
|
||
<div class="ms good">
|
||
<div class="ms-row"><div class="l">CO₂</div><div class="v">425 ppm</div></div>
|
||
<div class="ms-range"><span class="rmin">280</span><div class="rbar"><div class="rfill good" style="width:33%"></div><div class="rmarker" style="left:33%"></div></div><span class="rmax">600</span></div>
|
||
</div>
|
||
<div class="ms">
|
||
<div class="ms-row"><div class="l">ΔTemp</div><div class="v">+0,4 °C</div></div>
|
||
<div class="ms-range"><span class="rmin">0</span><div class="rbar"><div class="rfill good" style="width:13%"></div><div class="rmarker" style="left:13%"></div></div><span class="rmax">+3°</span></div>
|
||
</div>
|
||
<div class="ms warn">
|
||
<div class="ms-row"><div class="l">Budget</div><div class="v">480 Mio</div></div>
|
||
<div class="ms-range"><span class="rmin">0</span><div class="rbar"><div class="rfill warn" style="width:48%"></div><div class="rmarker" style="left:48%"></div></div><span class="rmax">1000</span></div>
|
||
</div>
|
||
<div class="ms good">
|
||
<div class="ms-row"><div class="l">Bevölkerung</div><div class="v">98 %</div></div>
|
||
<div class="ms-range"><span class="rmin">0</span><div class="rbar"><div class="rfill good" style="width:98%"></div><div class="rmarker" style="left:98%"></div></div><span class="rmax">100</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="stu-actions">
|
||
<button class="stu-btn primary">Live anschauen →</button>
|
||
<button class="stu-btn outline">Letzte Ergebnisse</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Jetzt aktiv: Heli mit Sternen -->
|
||
<div class="stu-row aktiv">
|
||
<div class="stu-avatar-block">
|
||
<span class="stu-status-icon" title="Jetzt aktiv">🟢</span>
|
||
<div class="stu-avatar">🐝</div>
|
||
</div>
|
||
<div class="stu-meta">
|
||
<div class="stu-name">Franz <span class="pulse"></span></div>
|
||
<div class="stu-sub">
|
||
<span class="module-chip">🚁 Heli-Navigation</span>
|
||
<span class="phase">M2 „Bergrettung Bezau" · Wegpunkt 3/6</span>
|
||
<span class="heartbeat">⏱ aktiv vor 2 s · Sitzung 8 min</span>
|
||
<span class="stu-stars">★★★☆☆</span>
|
||
</div>
|
||
<div class="stu-mini-stats">
|
||
<div class="ms good">
|
||
<div class="ms-row"><div class="l">Wegpunkte</div><div class="v">3/6</div></div>
|
||
<div class="ms-range"><span class="rmin">0</span><div class="rbar"><div class="rfill good" style="width:50%"></div><div class="rmarker" style="left:50%"></div></div><span class="rmax">6</span></div>
|
||
</div>
|
||
<div class="ms good">
|
||
<div class="ms-row"><div class="l">Treffer-Quote</div><div class="v">3/5 · 60 %</div></div>
|
||
<div class="ms-range"><span class="rmin">0</span><div class="rbar"><div class="rfill warn" style="width:60%"></div><div class="rmarker" style="left:60%"></div></div><span class="rmax">100</span></div>
|
||
</div>
|
||
<div class="ms">
|
||
<div class="ms-row"><div class="l">Fehlversuche</div><div class="v">2</div></div>
|
||
<div class="ms-range"><span class="rmin">0</span><div class="rbar"><div class="rfill good" style="width:13%"></div><div class="rmarker" style="left:13%"></div></div><span class="rmax">15</span></div>
|
||
</div>
|
||
<div class="ms good">
|
||
<div class="ms-row"><div class="l">Phase</div><div class="v">Plan</div></div>
|
||
<div class="ms-range"><span class="rmin">Audio</span><div class="rbar"><div class="rfill good" style="width:50%"></div><div class="rmarker" style="left:50%"></div></div><span class="rmax">Flug</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="stu-actions">
|
||
<button class="stu-btn primary">Live anschauen →</button>
|
||
<button class="stu-btn outline">Audio nochmal</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Jetzt aktiv: Weltküche mit Fortschritt -->
|
||
<div class="stu-row aktiv">
|
||
<div class="stu-avatar-block">
|
||
<span class="stu-status-icon" title="Jetzt aktiv">🟢</span>
|
||
<div class="stu-avatar">🦫</div>
|
||
</div>
|
||
<div class="stu-meta">
|
||
<div class="stu-name">Teresa <span class="pulse"></span></div>
|
||
<div class="stu-sub">
|
||
<span class="module-chip">🍽️ Weltküche</span>
|
||
<span class="phase">Moussaka · Zutat 4/15 · Lamm gesucht</span>
|
||
<span class="heartbeat">⏱ aktiv vor 1 s · Sitzung 6 min</span>
|
||
</div>
|
||
<div class="stu-mini-stats">
|
||
<div class="ms warn">
|
||
<div class="ms-row"><div class="l">Gerichte fertig</div><div class="v">3/8</div></div>
|
||
<div class="ms-range"><span class="rmin">0</span><div class="rbar"><div class="rfill warn" style="width:38%"></div><div class="rmarker" style="left:38%"></div></div><span class="rmax">8</span></div>
|
||
</div>
|
||
<div class="ms warn">
|
||
<div class="ms-row"><div class="l">Score</div><div class="v">540</div></div>
|
||
<div class="ms-range"><span class="rmin">0</span><div class="rbar"><div class="rfill warn" style="width:34%"></div><div class="rmarker" style="left:34%"></div></div><span class="rmax">1600</span></div>
|
||
</div>
|
||
<div class="ms warn">
|
||
<div class="ms-row"><div class="l">Fehlklicks (Ø/Zutat)</div><div class="v">7 · Ø 2,3</div></div>
|
||
<div class="ms-range"><span class="rmin">0</span><div class="rbar"><div class="rfill warn" style="width:46%"></div><div class="rmarker" style="left:46%"></div></div><span class="rmax">5</span></div>
|
||
</div>
|
||
<div class="ms good">
|
||
<div class="ms-row"><div class="l">Abzeichen</div><div class="v">2/10</div></div>
|
||
<div class="ms-range"><span class="rmin">0</span><div class="rbar"><div class="rfill good" style="width:20%"></div><div class="rmarker" style="left:20%"></div></div><span class="rmax">10</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="stu-actions">
|
||
<button class="stu-btn primary">Live anschauen →</button>
|
||
<button class="stu-btn outline">Rezept-Verlauf</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Hilfe-Bedarf: jemand der hängt -->
|
||
<div class="stu-row hilfe">
|
||
<div class="stu-avatar-block">
|
||
<span class="stu-status-icon" title="Braucht Hilfe">🆘</span>
|
||
<div class="stu-avatar">🐉</div>
|
||
</div>
|
||
<div class="stu-meta">
|
||
<div class="stu-name">Lukas <span class="pulse" style="background:var(--red)"></span></div>
|
||
<div class="stu-sub">
|
||
<span class="module-chip">🚁 Heli-Navigation</span>
|
||
<span class="phase">M1 „St. Anton" · Wegpunkt 2/4</span>
|
||
<span class="heartbeat warn">⏱ aktiv vor 1 s · <b>14 Fehlversuche</b> · Pilot bald übernimmt</span>
|
||
</div>
|
||
<div class="stu-mini-stats">
|
||
<div class="ms bad">
|
||
<div class="ms-row"><div class="l">Fehlversuche</div><div class="v">14 / 15</div></div>
|
||
<div class="ms-range"><span class="rmin">0</span><div class="rbar"><div class="rfill bad" style="width:93%"></div><div class="rmarker" style="left:93%"></div></div><span class="rmax">15</span></div>
|
||
</div>
|
||
<div class="ms bad">
|
||
<div class="ms-row"><div class="l">Treffer-Quote</div><div class="v">1/4 · 25 %</div></div>
|
||
<div class="ms-range"><span class="rmin">0</span><div class="rbar"><div class="rfill bad" style="width:25%"></div><div class="rmarker" style="left:25%"></div></div><span class="rmax">100</span></div>
|
||
</div>
|
||
<div class="ms warn">
|
||
<div class="ms-row"><div class="l">Sitzungsdauer</div><div class="v">22 min</div></div>
|
||
<div class="ms-range"><span class="rmin">0</span><div class="rbar"><div class="rfill warn" style="width:55%"></div><div class="rmarker" style="left:55%"></div></div><span class="rmax">40 min</span></div>
|
||
</div>
|
||
<div class="ms warn">
|
||
<div class="ms-row"><div class="l">Letzter Treffer</div><div class="v">vor 18 min</div></div>
|
||
<div class="ms-range"><span class="rmin">jetzt</span><div class="rbar"><div class="rfill bad" style="width:60%"></div><div class="rmarker" style="left:60%"></div></div><span class="rmax">30+</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="stu-actions">
|
||
<button class="stu-btn alert">Eingreifen →</button>
|
||
<button class="stu-btn outline">Hinweis schicken</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Heute aktiv, pausiert -->
|
||
<div class="stu-row heute">
|
||
<div class="stu-avatar-block">
|
||
<span class="stu-status-icon" title="Heute aktiv, gerade pausiert">🟡</span>
|
||
<div class="stu-avatar">🦊</div>
|
||
</div>
|
||
<div class="stu-meta">
|
||
<div class="stu-name">Marie</div>
|
||
<div class="stu-sub">
|
||
<span class="module-chip">🍽️ Weltküche</span>
|
||
<span class="phase">Pizza erfolgreich abgeschlossen</span>
|
||
<span class="heartbeat stale">⏱ letzter Heartbeat vor 12 min</span>
|
||
<span class="stu-stars">★★★★★</span>
|
||
</div>
|
||
</div>
|
||
<div class="stu-actions">
|
||
<button class="stu-btn outline">Was hat sie gemacht?</button>
|
||
<button class="stu-btn outline">Tagesübersicht</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Heute aktiv, abgeschlossen -->
|
||
<div class="stu-row heute">
|
||
<div class="stu-avatar-block">
|
||
<span class="stu-status-icon" title="Heute aktiv, fertig">🟡</span>
|
||
<div class="stu-avatar">🐢</div>
|
||
</div>
|
||
<div class="stu-meta">
|
||
<div class="stu-name">Hannah</div>
|
||
<div class="stu-sub">
|
||
<span class="module-chip">🚌 Busfahrt</span>
|
||
<span class="phase">Tour 3 abgeschlossen · 12 Städte, Ø 47 km Abweichung</span>
|
||
<span class="heartbeat stale">⏱ letzter Heartbeat vor 1 h 12 min</span>
|
||
<span class="stu-stars">★★★★☆</span>
|
||
</div>
|
||
</div>
|
||
<div class="stu-actions">
|
||
<button class="stu-btn outline">Ergebnis öffnen</button>
|
||
<button class="stu-btn outline">Reflexion sehen</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Heute noch nichts -->
|
||
<div class="stu-row kalt">
|
||
<div class="stu-avatar-block">
|
||
<span class="stu-status-icon" title="Heute noch nicht aktiv">⚫</span>
|
||
<div class="stu-avatar">🐧</div>
|
||
</div>
|
||
<div class="stu-meta">
|
||
<div class="stu-name">bubi</div>
|
||
<div class="stu-sub">
|
||
<span class="phase" style="color:var(--gray)">heute noch nicht eingeloggt</span>
|
||
<span class="heartbeat stale">letzter Login: gestern 14:30 · Heli M1 abgebrochen</span>
|
||
</div>
|
||
</div>
|
||
<div class="stu-actions">
|
||
<button class="stu-btn outline">Erinnerung senden</button>
|
||
<button class="stu-btn outline">Verlauf öffnen</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Heute noch nichts -->
|
||
<div class="stu-row kalt">
|
||
<div class="stu-avatar-block">
|
||
<span class="stu-status-icon" title="Heute noch nicht aktiv">⚫</span>
|
||
<div class="stu-avatar">🐺</div>
|
||
</div>
|
||
<div class="stu-meta">
|
||
<div class="stu-name">Jonas</div>
|
||
<div class="stu-sub">
|
||
<span class="phase" style="color:var(--gray)">heute noch nicht eingeloggt</span>
|
||
<span class="heartbeat stale">letzter Login: vor 3 Tagen</span>
|
||
</div>
|
||
</div>
|
||
<div class="stu-actions">
|
||
<button class="stu-btn outline">Erinnerung senden</button>
|
||
<button class="stu-btn outline">Verlauf öffnen</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Nie aktiv -->
|
||
<div class="stu-row kalt">
|
||
<div class="stu-avatar-block">
|
||
<span class="stu-status-icon" title="Noch nie eingeloggt">⚫</span>
|
||
<div class="stu-avatar" style="background:#e0dccd">?</div>
|
||
</div>
|
||
<div class="stu-meta">
|
||
<div class="stu-name" style="color:var(--gray)">Sabine</div>
|
||
<div class="stu-sub">
|
||
<span class="phase" style="color:var(--gray)">noch nie eingeloggt</span>
|
||
<span class="heartbeat stale">Konto angelegt vor 5 Tagen</span>
|
||
</div>
|
||
</div>
|
||
<div class="stu-actions">
|
||
<button class="stu-btn outline">Erstanleitung schicken</button>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ============== DETAIL-DRILL-DOWN ============== -->
|
||
|
||
<div class="card">
|
||
<div class="card-h">Ebene 4 · Detail-Drill-Down („Live anschauen →")</div>
|
||
<p style="font-size:.85rem;color:var(--muted);margin-bottom:.8rem">
|
||
Klick auf <b>„Live anschauen →"</b> öffnet einen Vollbild-Spectator-Modus, in dem die Lehrperson
|
||
die Sim aus Schüler-Perspektive mit-sieht (heute schon teilweise via <code>?view=teacher</code>).
|
||
Plus: rechts daneben ein <b>Daten-Panel</b> mit den Modul-spezifischen Live-Werten der API.
|
||
</p>
|
||
<div class="detail-sketch">
|
||
<span class="h"># Detail-View für Lenchen · 🌍 Klimawächter · Jahr 12/75</span>
|
||
|
||
<span class="k">Modul-Live-State</span> <span class="k">Tageshistorie heute</span>
|
||
───────────────── ─────────────────────
|
||
CO₂ <span class="ok">425 ppm</span> 08:42 → Lenchen startet Klima L1
|
||
ΔTemp +0,4 °C 08:46 → erste Maßnahme gekauft: Solaranlage
|
||
Budget <span class="warn">480 Mio</span> 09:01 → +10 Jahre, Budget 510 Mio
|
||
Bevölkerung <span class="ok">98 %</span> 09:08 → Sturmflut-Ereignis (akzeptiert)
|
||
Überflutet 4 % 09:14 → Deich gebaut Zone B
|
||
Status <span class="ok">stabil</span> 09:15 → JETZT (live)
|
||
|
||
<span class="k">Schnellaktionen</span>
|
||
- Tempo-Sperre [⏸ pausieren]
|
||
- Auftrag wechseln [Modul ▾]
|
||
- Hinweis senden [✉ Text]
|
||
|
||
<span class="k">Was Lenchen sieht (Spectator):</span>
|
||
╔═══════════════════════════════════════╗
|
||
║ [Live-Karte der Insel · 2D] ║
|
||
║ ║
|
||
║ ⚡ Wind, ☀ Solar, 🌊 Deich ║
|
||
║ ║
|
||
║ Status-Leiste mit Mini-Graphen ║
|
||
╚═══════════════════════════════════════╝
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ============== IMPLEMENTATIONS-HINWEISE ============== -->
|
||
|
||
<div class="next">
|
||
<b>Implementations-Skizze v2</b> (technisch, falls Konzept passt):
|
||
<ul>
|
||
<li><b>Benchmark-Engine</b> als neue Plattform-Lib <code>App/php/lib/Benchmark.php</code> — pro Modul eine Formel laut Tabelle oben. Input: <code>assessments.results</code>-JSON pro Submission. Output: <code>{moduleId, modulePct, dimensions:[{key,label,score}]}</code>. Aggregat pro Schüler:in: max. 3 beste pro Modul, dann Mittelwert über alle Module mit Submissions.</li>
|
||
<li><b>Backend Live-API</b>: <code>/api/live?class_id=X</code> erweitern um:
|
||
<ul>
|
||
<li>Komplette Klassenliste (auch stille Schüler:innen)</li>
|
||
<li>Status pro Person (<code>aktiv|heute|kalt|nie</code>) + Tages-Summary</li>
|
||
<li><code>benchmarkPct</code> pro Schüler:in (über alle Apps) + <code>perModule</code>-Breakdown</li>
|
||
<li><code>topN</code> / <code>bottomN</code> als bequeme Ranking-Listen</li>
|
||
<li><code>weeklyByDay</code>: Klassen-Lernzeit pro Tag, gestapelt nach Modul</li>
|
||
<li><code>needsHelp</code>-Heuristik (Heli-Fails ≥10, Klima-Budget < 0, Weltküche-Fehlklicks > 15/Runde, >10 min ohne Heartbeat während Sim offen)</li>
|
||
</ul>
|
||
</li>
|
||
<li><b>Modul-Range-Definition</b> als JSON-Schema in jeder Sim: <code>GGS_LIVE_RANGES = { co2:{min:280, max:600, bad:'high'}, budget:{min:0, max:1000, bad:'low'} }</code>. Frontend rendert dann automatisch die Range-Bars in den Mini-Stats. Spart das Hartkodieren pro Sim.</li>
|
||
<li><b>Frontend</b>: <code>renderLiveSummary</code> komplett ersetzen — 4 neue Render-Funktionen: <code>renderLiveStatus</code> (Tiles + Ranking + Klassen-Säulen), <code>renderLiveFilter</code>, <code>renderLiveStudentList</code>, <code>renderLiveDetail</code>.</li>
|
||
<li><b>Auto-Refresh</b>: alle 5 s, nur Daten-Diff, kein Re-Render des ganzen DOMs (DOM-Patches statt innerHTML).</li>
|
||
<li><b>„Eingreifen"-Aktion</b>: neue API <code>POST /api/live {action:'nudge', studentId, text}</code> — pusht Toast in laufende Schüler-Sim via Pause-Polling-Channel.</li>
|
||
<li><b>Aufwand-Schätzung neu</b>: 2–3 Tage. Benchmark-Engine 1 Tag · Backend-Erweiterung ½ Tag · Frontend 1 Tag · Range-Definitionen pro Sim ½ Tag.</li>
|
||
</ul>
|
||
<p style="margin-top:.6rem"><b>Erste Schritte konkret</b>:
|
||
(1) Benchmark.php-Formeln mit Thomas durchgehen und finalisieren.
|
||
(2) Range-Definitionen pro Sim als JSON-Schema spec'en (zentrale Stelle).
|
||
(3) Lokal renderLiveStatus prototypisch bauen, gegen Mock-Daten testen.
|
||
(4) Echtes Backend nachziehen wenn UI sitzt.
|
||
</p>
|
||
</div>
|
||
|
||
<p style="font-size:.75rem;color:var(--muted);margin-top:1.5rem;text-align:center">
|
||
Entwurf · liegt unter <code>.dontDeploy/entwurfswerkzeug/live-konzept.html</code> ·
|
||
Stand <b>2026-06-10</b> · GeoGraSim/Atlas
|
||
</p>
|
||
|
||
</div>
|
||
</body>
|
||
</html>
|