Lehrplan: 4 Modul-Detailseiten + lehrplan.php + simulationen.php + 78 Anker

- Gemeinsamer Partial App/pages/_partials/modul_detail.php
- modul-klima/fluss/heli/stadt als 3-Zeilen-Wrapper
- lehrplan.php: Filter Land/Thema/Typ, TOC, URL-Persistenz
- simulationen.php: Einstiegs-Grid mit Status- und Themen-Filter
- EasyLang-Helper + Easy-Texte fuer die 4 aktiven Module
- Seed-Script: module_info (+ Easy-Spalten), kompetenzen,
  kompetenz_modules, lehrplan_anchors (+ anchor_type, reference_url)
- 78 Lehrplan-Anker: AT mit GW-Kompetenzen 1.9/2.1/4.2 etc.,
  13 uebergreifende Themen, andere Faecher (Bio, Chemie, Physik,
  Mathematik, GSP, Bewegung+Sport); DE 10 Bundeslaender-Quellen +
  DGfG; CH Lehrplan 21 (RZG, NT, MA, MI, WAH, ERG, BNE); LI LiLe
- iPad-First: Touch-Ziele >=40px, :active-Feedback, Breakpoint 900px
- Inbox: Konventionen (Instanz-Name, iPad, Leichte Sprache,
  _status.md, Git-Commits) umgesetzt

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-19 00:05:12 +02:00
parent dfb9e80664
commit db9ed43407
20 changed files with 3517 additions and 0 deletions
+657
View File
@@ -0,0 +1,657 @@
<?php
/**
* Modul-Detailseiten — gemeinsamer Partial
* -----------------------------------------
* Wird von modul-klima.php, modul-fluss.php, modul-heli.php, modul-stadt.php
* eingebunden. Erwartet im includierenden Scope:
*
* $MODULE_ID string — module_info.module_id (z.B. 'klima')
*
* Quellen:
* - module_info (Metadaten, inkl. Easy-Varianten)
* - glossar + glossar_modules (Begriffe)
* - kompetenzen + kompetenz_modules
* + lehrplan_anchors (Lehrplan-Bezug, gruppiert nach Typ)
* - EasyLang-Helper (pickt Normal- oder Easy-Text)
*
* Design: iPad Landscape (1180×820) als Hauptreferenz (siehe
* module-interface.md Abschnitt 4c).
*/
if (!isset($MODULE_ID) || !is_string($MODULE_ID)) {
http_response_code(500);
echo 'modul_detail.php: $MODULE_ID fehlt.';
exit;
}
require_once __DIR__ . '/../../php/config/app.php';
require_once __DIR__ . '/../../php/config/db.php';
require_once __DIR__ . '/../../php/lib/EasyLang.php';
$db = getDB();
$module = $db->prepare('SELECT * FROM module_info WHERE module_id = ?');
$module->execute([$MODULE_ID]);
$module = $module->fetch();
if (!$module) {
http_response_code(404);
echo 'Modul nicht gefunden.';
exit;
}
// Easy-Varianten per Helper (Fallback: Normalform)
$shortDesc = EasyLang::pick($module['short_desc'] ?? null, $module['short_desc_easy'] ?? null);
$longDesc = EasyLang::pick($module['long_desc'] ?? null, $module['long_desc_easy'] ?? null);
$goalsRaw = EasyLang::pick($module['learning_goals'] ?? null, $module['learning_goals_easy'] ?? null);
// Lernziele — JSON-Array mit Strings
$learningGoals = [];
if ($goalsRaw) {
$decoded = json_decode($goalsRaw, true);
if (is_array($decoded)) $learningGoals = $decoded;
}
// Glossar-Begriffe zum Modul
$stmt = $db->prepare('
SELECT g.key_slug, g.title, g.short, g.category
FROM glossar g
INNER JOIN glossar_modules m ON m.glossar_id = g.id
WHERE m.module_id = ?
ORDER BY g.title
');
$stmt->execute([$MODULE_ID]);
$glossarTerms = $stmt->fetchAll();
// Kompetenzen + Lehrplan-Anker
$stmt = $db->prepare('
SELECT k.id, k.key_slug, k.title, k.description, k.category,
km.strength, km.level
FROM kompetenzen k
INNER JOIN kompetenz_modules km ON km.kompetenz_id = k.id
WHERE km.module_id = ?
ORDER BY km.strength, k.sort_order, k.title
');
$stmt->execute([$MODULE_ID]);
$kompetenzen = $stmt->fetchAll();
$ankerStmt = $db->prepare("
SELECT anchor_type, country, region, school_type, grade, subject,
title, reference, reference_url, quote
FROM lehrplan_anchors
WHERE kompetenz_id = ?
ORDER BY FIELD(anchor_type, 'fach', 'uebergreifendes_thema', 'anderes_fach'),
country, sort_order
");
foreach ($kompetenzen as &$k) {
$ankerStmt->execute([$k['id']]);
$rows = $ankerStmt->fetchAll();
$k['anchors_fach'] = array_values(array_filter($rows, fn($r) => $r['anchor_type'] === 'fach'));
$k['anchors_uebergreifend'] = array_values(array_filter($rows, fn($r) => $r['anchor_type'] === 'uebergreifendes_thema'));
$k['anchors_andere_faecher'] = array_values(array_filter($rows, fn($r) => $r['anchor_type'] === 'anderes_fach'));
}
unset($k);
$bp = BASE_PATH;
$api = BASE_URL . '/php/api/glossar.php';
$pageTitle = htmlspecialchars($module['title']) . ' — Lehrplan geograsim.at';
$easyActive = EasyLang::isActive();
if (!function_exists('esc')) {
function esc(?string $s): string { return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); }
}
$countryMeta = [
'AT' => ['flag' => '🇦🇹', 'label' => 'Österreich'],
'DE' => ['flag' => '🇩🇪', 'label' => 'Deutschland'],
'CH' => ['flag' => '🇨🇭', 'label' => 'Schweiz'],
'LI' => ['flag' => '🇱🇮', 'label' => 'Liechtenstein'],
];
?><!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= $pageTitle ?></title>
<meta name="description" content="<?= esc($module['subtitle']) ?> — Lernziele, Begriffe und Lehrplan-Bezug für die GeoGraSim-Simulation <?= esc($module['title']) ?>.">
<link rel="icon" type="image/svg+xml" href="<?= $bp ?>/favicon.svg">
<link rel="icon" type="image/png" href="<?= $bp ?>/favicon-96x96.png" sizes="96x96">
<link rel="stylesheet" href="<?= $bp ?>/assets/fonts/inter.css">
<link rel="stylesheet" href="<?= $bp ?>/assets/css/design-system.css">
<style>
/* Seite ist scrollbar — Design-System-Body ist overflow:hidden, das ueberschreiben wir hier */
body { overflow: auto; height: auto; min-height: 100vh; background: var(--ggs-bg); }
/* ===== Topbar (identisch zu glossar.php) ===== */
.md-topbar {
background: var(--ggs-white);
padding: .55rem 1.2rem;
display: flex; align-items: center; gap: .8rem;
border-bottom: 1px solid var(--ggs-border);
position: sticky; top: 0; z-index: 50;
}
.md-topbar a { text-decoration: none; }
.md-topbar-brand { display: flex; align-items: center; gap: .5rem; }
.md-topbar-brand img.md-text { height: 40px; display: block; }
.md-topbar .spacer { flex: 1; }
.md-btn-sm {
/* iPad-Touch: min 40px Höhe; padding angepasst */
padding: .5rem .85rem; border: 1px solid var(--ggs-border);
border-radius: var(--ggs-radius-sm); background: var(--ggs-white);
font-size: .78rem; font-weight: 600; cursor: pointer;
color: var(--ggs-text); font-family: inherit; text-decoration: none;
display: inline-flex; align-items: center; min-height: 40px;
}
.md-btn-sm:hover { background: var(--ggs-fjord-light); color: var(--ggs-fjord-dark); border-color: var(--ggs-fjord); }
.md-btn-sm:active { transform: scale(0.97); }
.md-btn-sm.md-btn-primary { background: var(--ggs-fjord); color: var(--ggs-white); border-color: var(--ggs-fjord); }
.md-btn-sm.md-btn-primary:hover { background: var(--ggs-fjord-dark); }
.md-easy-pill {
background: var(--ggs-moss-light); color: var(--ggs-moss-dark);
border-color: var(--ggs-moss); font-weight: 700;
}
/* ===== Breadcrumb ===== */
.md-breadcrumb {
max-width: 1100px; margin: 0 auto; padding: .9rem 1.2rem .2rem;
font-size: .82rem; color: var(--ggs-text-muted);
}
.md-breadcrumb a { color: var(--ggs-fjord); text-decoration: none; }
.md-breadcrumb a:hover { text-decoration: underline; }
.md-breadcrumb .sep { margin: 0 .4rem; opacity: .5; }
/* ===== Hero ===== */
.md-hero {
max-width: 1100px; margin: 0 auto; padding: 1.5rem 1.2rem 2rem;
display: grid; grid-template-columns: minmax(220px, 340px) 1fr;
gap: 2rem; align-items: center;
}
.md-hero-card {
background: var(--ggs-white); border-radius: var(--ggs-radius-lg);
overflow: hidden; box-shadow: var(--ggs-shadow-md);
border: 1px solid var(--ggs-border);
}
.md-hero-card img {
width: 100%; aspect-ratio: 1; object-fit: cover; display: block;
}
.md-hero-text h1 {
font-size: clamp(1.8rem, 4vw, 2.6rem);
font-weight: 900; letter-spacing: -.03em;
color: var(--ggs-fjord-dark);
display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
margin-bottom: .4rem;
}
.md-hero-icon { font-size: 1.3em; }
.md-hero-subtitle {
font-size: 1.1rem; color: var(--ggs-text); line-height: 1.5;
margin-bottom: 1.4rem;
}
.md-hero-cta { display: flex; flex-wrap: wrap; gap: .6rem; }
.md-cta-btn {
/* iPad-Touch: generous padding, min 44px */
display: inline-flex; align-items: center; gap: .5rem;
padding: .85rem 1.5rem; border-radius: var(--ggs-radius-sm);
font-weight: 700; font-size: 1rem; text-decoration: none;
border: 1.5px solid transparent; transition: all .2s var(--ggs-ease);
min-height: 48px;
}
.md-cta-primary { background: var(--ggs-fjord); color: var(--ggs-white); }
.md-cta-primary:hover { background: var(--ggs-fjord-dark); transform: translateY(-1px); }
.md-cta-primary:active { transform: scale(0.98); }
.md-cta-secondary {
background: var(--ggs-white); color: var(--ggs-fjord);
border-color: var(--ggs-fjord);
}
.md-cta-secondary:hover { background: var(--ggs-fjord-light); }
.md-cta-secondary:active { transform: scale(0.98); }
/* ===== Meta-Bar (Dauer, Alter, Status) ===== */
.md-meta {
max-width: 1100px; margin: 0 auto 2rem; padding: 0 1.2rem;
display: flex; flex-wrap: wrap; gap: .6rem;
}
.md-meta-item {
display: inline-flex; align-items: center; gap: .4rem;
background: var(--ggs-white); border: 1px solid var(--ggs-border);
border-radius: var(--ggs-radius-pill);
padding: .5rem .95rem;
font-size: .88rem; color: var(--ggs-text);
min-height: 36px;
}
.md-meta-icon { font-size: 1rem; }
.md-meta-label { color: var(--ggs-text-muted); font-weight: 600; }
.md-meta-value { font-weight: 700; }
.md-status-pill { padding: 2px 10px; border-radius: var(--ggs-radius-pill); font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; }
.md-status-aktiv { background: var(--ggs-moss-light); color: var(--ggs-moss-dark); }
.md-status-beta { background: var(--ggs-sand); color: #7a6540; }
.md-status-geplant { background: var(--ggs-fjord-light); color: var(--ggs-fjord-dark); }
/* ===== Sections ===== */
.md-section {
max-width: 1100px; margin: 0 auto 2.5rem; padding: 0 1.2rem;
}
.md-section-title {
font-size: .75rem; font-weight: 800; text-transform: uppercase;
letter-spacing: .12em; color: var(--ggs-fjord);
margin-bottom: .4rem;
}
.md-section-h2 {
font-size: 1.7rem; font-weight: 900; color: var(--ggs-fjord-dark);
letter-spacing: -.02em; margin-bottom: .9rem;
}
.md-section-text {
font-size: 1rem; line-height: 1.7; color: var(--ggs-text); max-width: 780px;
}
/* Lernziele-Grid */
.md-goals {
display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 1rem; margin-top: 1rem;
}
.md-goal {
background: var(--ggs-white); border: 1px solid var(--ggs-border);
border-left: 4px solid var(--ggs-moss);
border-radius: var(--ggs-radius-md); padding: 1rem 1.2rem;
font-size: .95rem; line-height: 1.5;
}
.md-goal-num {
display: inline-block; font-size: .72rem; font-weight: 800;
color: var(--ggs-moss-dark); background: var(--ggs-moss-light);
padding: 2px 8px; border-radius: var(--ggs-radius-pill);
margin-bottom: .4rem;
}
/* Glossar-Chips */
.md-glossar {
display: flex; flex-wrap: wrap; gap: .45rem; margin-top: 1rem;
}
.md-glossar-chip {
/* iPad-Touch: min 40px Höhe */
display: inline-flex; align-items: center; gap: .3rem;
background: var(--ggs-white); border: 1px solid var(--ggs-border);
border-radius: var(--ggs-radius-pill);
padding: .5rem 1rem; min-height: 40px;
font-size: .88rem; font-weight: 600; color: var(--ggs-fjord-dark);
text-decoration: none; transition: all .2s var(--ggs-ease);
cursor: pointer;
}
.md-glossar-chip:hover, .md-glossar-chip:active {
background: var(--ggs-fjord-light); border-color: var(--ggs-fjord);
}
.md-glossar-empty { color: var(--ggs-text-muted); font-size: .9rem; font-style: italic; }
.md-glossar-link {
display: inline-block; margin-top: 1rem;
font-size: .9rem; color: var(--ggs-fjord); text-decoration: none; font-weight: 600;
padding: .4rem 0; /* vergrossertes Touch-Ziel ohne Rahmen */
}
.md-glossar-link:hover { text-decoration: underline; }
/* Lehrplan-Bezug */
.md-lehrplan-filters {
display: flex; flex-wrap: wrap; gap: .5rem; margin: 1rem 0 1.2rem;
}
.md-chip {
/* iPad-Touch: min 40x40 */
display: inline-flex; align-items: center; gap: .3rem;
padding: .55rem 1rem; border-radius: var(--ggs-radius-pill);
background: var(--ggs-white); border: 1.5px solid var(--ggs-border);
font-size: .88rem; font-weight: 600; color: var(--ggs-text-muted);
cursor: pointer; transition: all .2s var(--ggs-ease); font-family: inherit;
min-height: 40px; min-width: 40px;
}
.md-chip:hover { border-color: var(--ggs-fjord); color: var(--ggs-fjord); }
.md-chip:active { transform: scale(0.96); }
.md-chip.active { background: var(--ggs-fjord); color: var(--ggs-white); border-color: var(--ggs-fjord); }
.md-kompetenz {
background: var(--ggs-white); border: 1px solid var(--ggs-border);
border-radius: var(--ggs-radius-md); padding: 1.2rem 1.4rem 1rem;
margin-bottom: 1rem;
}
.md-kompetenz-header { display: flex; align-items: baseline; gap: .7rem; flex-wrap: wrap; margin-bottom: .4rem; }
.md-kompetenz-title { font-size: 1.15rem; font-weight: 800; color: var(--ggs-fjord-dark); }
.md-kompetenz-strength {
font-size: .65rem; font-weight: 700; text-transform: uppercase; letter-spacing: .07em;
padding: 2px 8px; border-radius: var(--ggs-radius-pill);
}
.md-strength-primaer { background: var(--ggs-moss-light); color: var(--ggs-moss-dark); }
.md-strength-sekundaer { background: var(--ggs-bg-dark); color: var(--ggs-text-muted); }
.md-kompetenz-desc {
font-size: .9rem; color: var(--ggs-text); line-height: 1.55;
margin-bottom: .9rem;
}
.md-anchors { display: grid; gap: .55rem; }
.md-anchor {
display: grid; grid-template-columns: 28px 1fr; gap: .6rem; align-items: start;
font-size: .9rem; padding: .6rem .8rem;
background: var(--ggs-bg); border-radius: var(--ggs-radius-sm);
border-left: 3px solid var(--ggs-fjord-light);
}
.md-anchor-flag { font-size: 1.2rem; line-height: 1.3; text-align: center; }
.md-anchor-meta { font-size: .75rem; color: var(--ggs-text-muted); margin-bottom: .15rem; }
.md-anchor-title { font-weight: 700; color: var(--ggs-fjord-dark); margin-bottom: .2rem; }
.md-anchor-quote { font-size: .88rem; color: var(--ggs-text); font-style: italic; line-height: 1.45; }
.md-anchor-ref {
font-size: .72rem; color: var(--ggs-text-muted);
margin-top: .3rem;
}
.md-anchor-link {
color: var(--ggs-fjord); text-decoration: none; font-weight: 600;
border-bottom: 1px dotted var(--ggs-fjord); transition: color .2s var(--ggs-ease);
padding: 2px 0; /* Touch-Ziel leicht vergroessern */
}
.md-anchor-link:hover { color: var(--ggs-fjord-dark); border-bottom-style: solid; }
/* Anker-Gruppen (Fach / Fächerübergreifend / Andere Fächer) */
.md-anchor-group { margin-top: .9rem; }
.md-anchor-group:first-child { margin-top: 0; }
.md-anchor-group-head {
display: flex; align-items: baseline; gap: .6rem;
margin: .2rem 0 .5rem;
flex-wrap: wrap;
}
.md-anchor-group-title {
font-size: .74rem; font-weight: 800; text-transform: uppercase;
letter-spacing: .1em; color: var(--ggs-fjord-dark);
}
.md-anchor-group-sub {
font-size: .72rem; color: var(--ggs-text-muted); font-weight: 500;
}
.md-anchor--fach { border-left-color: var(--ggs-fjord); }
.md-anchor--uebergreifendes_thema { border-left-color: var(--ggs-moss); background: var(--ggs-moss-light); }
.md-anchor--anderes_fach { border-left-color: var(--ggs-sand-dark); background: var(--ggs-bg-dark); }
.md-anchor--uebergreifendes_thema .md-anchor-flag,
.md-anchor--anderes_fach .md-anchor-flag { opacity: .65; }
.md-anchor.hidden { display: none; }
.md-lehrplan-note {
font-size: .82rem; color: var(--ggs-text-muted); font-style: italic;
margin-top: 1rem; max-width: 780px;
}
/* ===== Footer ===== */
.md-footer {
text-align: center; padding: 2rem 1rem 2.5rem;
font-size: .78rem; color: var(--ggs-text-muted);
border-top: 1px solid var(--ggs-border);
background: var(--ggs-white);
margin-top: 2rem;
}
.md-footer img { height: 36px; opacity: .5; margin-bottom: .5rem; }
.md-footer a { color: var(--ggs-fjord); text-decoration: none; padding: .3rem .2rem; }
.md-footer a:hover { text-decoration: underline; }
/* Responsive — Design-System-konforme Breakpoints 900 / 1200 */
@media (max-width: 900px) {
.md-hero { grid-template-columns: 1fr; gap: 1rem; padding-top: 1rem; }
.md-hero-card { max-width: 260px; margin: 0 auto; }
.md-hero-text { text-align: center; }
.md-hero-cta { justify-content: center; }
.md-meta { justify-content: center; }
.md-section-h2 { font-size: 1.35rem; }
}
</style>
</head>
<body>
<!-- Einheitlicher Header -->
<header class="md-topbar">
<a href="<?= $bp ?>/index.html" class="md-topbar-brand" aria-label="GeoGraSim Startseite">
<img class="md-text" src="<?= $bp ?>/assets/img/geograsim_t.svg" alt="GeoGraSim">
</a>
<span class="spacer"></span>
<?php if ($easyActive): ?>
<span class="md-btn-sm md-easy-pill" title="Leichte Sprache ist aktiv">🟢 Leichte Sprache</span>
<?php endif; ?>
<a href="<?= $bp ?>/pages/simulationen.php" class="md-btn-sm">Alle Simulationen</a>
<a href="<?= $bp ?>/pages/lehrplan.php" class="md-btn-sm">Lehrplan</a>
<a href="<?= $bp ?>/glossar" class="md-btn-sm">Glossar</a>
<a href="<?= $bp ?>/login.html" class="md-btn-sm md-btn-primary">Anmelden</a>
</header>
<nav class="md-breadcrumb" aria-label="Brotkrumen">
<a href="<?= $bp ?>/index.html">Start</a>
<span class="sep"></span>
<a href="<?= $bp ?>/pages/simulationen.php">Simulationen</a>
<span class="sep"></span>
<span><?= esc($module['title']) ?></span>
</nav>
<!-- HERO -->
<section class="md-hero">
<div class="md-hero-card">
<img src="<?= $bp ?>/assets/img/<?= esc($module['card_image']) ?>" alt="<?= esc($module['title']) ?>">
</div>
<div class="md-hero-text">
<h1><span class="md-hero-icon"><?= esc($module['icon']) ?></span><?= esc($module['title']) ?></h1>
<p class="md-hero-subtitle"><?= esc($shortDesc ?? $module['subtitle']) ?></p>
<div class="md-hero-cta">
<?php if ($module['status'] === 'aktiv' || $module['status'] === 'beta'): ?>
<a href="<?= $bp ?>/<?= esc($module['play_url']) ?>" class="md-cta-btn md-cta-primary">
▶ Jetzt probieren
</a>
<?php else: ?>
<a href="<?= $bp ?>/login.html" class="md-cta-btn md-cta-primary">
🔒 In Entwicklung — Newsletter
</a>
<?php endif; ?>
<a href="#lehrplan-bezug" class="md-cta-btn md-cta-secondary">
📘 Lehrplan-Bezug
</a>
</div>
</div>
</section>
<!-- META -->
<div class="md-meta">
<?php if (!empty($module['duration_min'])): ?>
<span class="md-meta-item">
<span class="md-meta-icon">⏱️</span>
<span class="md-meta-label">Dauer:</span>
<span class="md-meta-value">ca. <?= (int)$module['duration_min'] ?> Min</span>
</span>
<?php endif; ?>
<?php if (!empty($module['age_min']) && !empty($module['age_max'])): ?>
<span class="md-meta-item">
<span class="md-meta-icon">👧</span>
<span class="md-meta-label">Alter:</span>
<span class="md-meta-value"><?= (int)$module['age_min'] ?><?= (int)$module['age_max'] ?> Jahre</span>
</span>
<?php endif; ?>
<span class="md-meta-item">
<span class="md-meta-icon">🏷️</span>
<span class="md-meta-label">Modul-ID:</span>
<code style="font-size: .82rem;"><?= esc($module['module_id']) ?></code>
</span>
<span class="md-meta-item">
<span class="md-meta-label">Status:</span>
<span class="md-status-pill md-status-<?= esc($module['status']) ?>"><?= esc($module['status']) ?></span>
</span>
<span class="md-meta-item">
<span class="md-meta-icon">📚</span>
<span class="md-meta-label">Begriffe im Glossar:</span>
<span class="md-meta-value"><?= count($glossarTerms) ?></span>
</span>
</div>
<!-- WAS LERNST DU -->
<?php if (!empty($learningGoals)): ?>
<section class="md-section">
<div class="md-section-title">Was lernst du?</div>
<h2 class="md-section-h2">Lernziele dieses Moduls</h2>
<div class="md-goals">
<?php foreach ($learningGoals as $i => $g): ?>
<div class="md-goal">
<span class="md-goal-num"><?= str_pad((string)($i+1), 2, '0', STR_PAD_LEFT) ?></span>
<div><?= esc($g) ?></div>
</div>
<?php endforeach; ?>
</div>
</section>
<?php endif; ?>
<!-- WIE FUNKTIONIERT'S -->
<?php if (!empty($longDesc)): ?>
<section class="md-section">
<div class="md-section-title">Wie funktioniert's?</div>
<h2 class="md-section-h2">Die Simulation</h2>
<p class="md-section-text"><?= nl2br(esc($longDesc)) ?></p>
</section>
<?php endif; ?>
<!-- BEGRIFFE AUS DEM GLOSSAR -->
<section class="md-section">
<div class="md-section-title">Begriffe, die du kennenlernst</div>
<h2 class="md-section-h2">Glossar-Einträge zu diesem Modul</h2>
<?php if (empty($glossarTerms)): ?>
<p class="md-glossar-empty">Noch keine Begriffe zugeordnet — das Glossar wächst laufend weiter.</p>
<?php else: ?>
<div class="md-glossar">
<?php foreach ($glossarTerms as $t): ?>
<a class="md-glossar-chip"
href="<?= $bp ?>/glossar?term=<?= urlencode($t['key_slug']) ?>"
title="<?= esc($t['short']) ?>">
<?= esc($t['title']) ?>
</a>
<?php endforeach; ?>
</div>
<?php endif; ?>
<a class="md-glossar-link" href="<?= $bp ?>/glossar?module=<?= urlencode($MODULE_ID) ?>">
→ Alle <?= count($glossarTerms) ?> Begriffe im Glossar ansehen
</a>
</section>
<!-- LEHRPLAN-BEZUG -->
<section class="md-section" id="lehrplan-bezug">
<div class="md-section-title">Für Lehrpersonen</div>
<h2 class="md-section-h2">Lehrplan-Bezug</h2>
<p class="md-section-text">
Dieses Modul bedient die folgenden didaktischen Kompetenzbereiche. Für jeden
Bereich haben wir typische Verankerungen in den Lehrplänen für
Österreich, Deutschland, Schweiz und Liechtenstein recherchiert — sie
helfen, das Modul an den eigenen Lehrplan anzudocken.
</p>
<div class="md-lehrplan-filters" id="md-filter-row">
<button type="button" class="md-chip active" data-country="">🌐 Alle Länder</button>
<?php foreach ($countryMeta as $c => $info): ?>
<button type="button" class="md-chip" data-country="<?= esc($c) ?>">
<?= $info['flag'] ?> <?= esc($info['label']) ?>
</button>
<?php endforeach; ?>
</div>
<?php if (empty($kompetenzen)): ?>
<p class="md-glossar-empty">Noch keine Kompetenzen zugeordnet.</p>
<?php else: ?>
<?php foreach ($kompetenzen as $k): ?>
<article class="md-kompetenz">
<header class="md-kompetenz-header">
<div class="md-kompetenz-title"><?= esc($k['title']) ?></div>
<span class="md-kompetenz-strength md-strength-<?= esc($k['strength']) ?>">
<?= $k['strength'] === 'primaer' ? 'Primär' : 'Sekundär' ?>
</span>
</header>
<?php if (!empty($k['description'])): ?>
<p class="md-kompetenz-desc"><?= esc($k['description']) ?></p>
<?php endif; ?>
<?php
$groups = [
['anchors_fach', 'Fachbezug', 'Direkte Zuordnung im Fach-Lehrplan'],
['anchors_uebergreifend', 'Fächerübergreifende Themen', 'Verbindliche Querschnittsthemen des Lehrplans'],
['anchors_andere_faecher', 'Anknüpfungspunkte in anderen Fächern', 'Wo das Thema zusätzlich auftaucht'],
];
foreach ($groups as [$key, $heading, $sub]):
$list = $k[$key] ?? [];
if (empty($list)) continue;
?>
<div class="md-anchor-group">
<div class="md-anchor-group-head">
<span class="md-anchor-group-title"><?= esc($heading) ?></span>
<span class="md-anchor-group-sub"><?= esc($sub) ?></span>
</div>
<div class="md-anchors">
<?php foreach ($list as $a): ?>
<?php $cm = $countryMeta[$a['country']] ?? ['flag' => '🏳️', 'label' => $a['country']]; ?>
<div class="md-anchor md-anchor--<?= esc($a['anchor_type']) ?>"
data-country="<?= esc($a['country']) ?>">
<div class="md-anchor-flag" title="<?= esc($cm['label']) ?>"><?= $cm['flag'] ?></div>
<div>
<div class="md-anchor-meta">
<strong><?= esc($a['country']) ?></strong>
<?= $a['region'] ? ' · ' . esc($a['region']) : '' ?>
<?= $a['school_type'] ? ' · ' . esc($a['school_type']) : '' ?>
<?= $a['grade'] ? ' · ' . esc($a['grade']) : '' ?>
<?= $a['subject'] ? ' · ' . esc($a['subject']) : '' ?>
</div>
<div class="md-anchor-title"><?= esc($a['title']) ?></div>
<?php if (!empty($a['quote'])): ?>
<div class="md-anchor-quote">„<?= esc($a['quote']) ?>"</div>
<?php endif; ?>
<?php if (!empty($a['reference'])): ?>
<div class="md-anchor-ref">
Quelle:
<?php if (!empty($a['reference_url'])): ?>
<a href="<?= esc($a['reference_url']) ?>"
target="_blank" rel="noopener noreferrer"
class="md-anchor-link"><?= esc($a['reference']) ?> ↗</a>
<?php else: ?>
<?= esc($a['reference']) ?>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<?php endforeach; ?>
</article>
<?php endforeach; ?>
<?php endif; ?>
<p class="md-lehrplan-note">
Die Anker sind beispielhaft ausgewählt — bitte mit dem konkreten
Jahres- oder Semesterplan abgleichen. Vollständige Lehrplan-Übersicht:
<a href="<?= $bp ?>/pages/lehrplan.php">Lehrplan-Seite</a>.
</p>
</section>
<!-- Footer -->
<footer class="md-footer">
<img src="<?= $bp ?>/assets/img/bildLogo.png" alt="">
<div>
Lehrplan geograsim.at ·
<a href="<?= $bp ?>/pages/simulationen.php">Simulationen</a> ·
<a href="<?= $bp ?>/pages/lehrplan.php">Lehrplan</a> ·
<a href="<?= $bp ?>/glossar">Glossar</a> ·
<a href="<?= $bp ?>/ueber.html">Über</a> ·
<a href="<?= $bp ?>/impressum.html">Impressum</a> ·
<a href="<?= $bp ?>/datenschutz.html">Datenschutz</a>
</div>
</footer>
<script>
// Länder-Filter für Lehrplan-Anker — übergreifende Themen + andere Fächer bleiben sichtbar (Land-agnostisch)
(function () {
const filterRow = document.getElementById('md-filter-row');
if (!filterRow) return;
filterRow.addEventListener('click', (e) => {
const btn = e.target.closest('.md-chip');
if (!btn) return;
filterRow.querySelectorAll('.md-chip').forEach(c => c.classList.remove('active'));
btn.classList.add('active');
const country = btn.dataset.country;
document.querySelectorAll('.md-anchor').forEach(a => {
// Anker mit einem Land: nur zeigen wenn passt. Anker ohne Land oder mit allen Laendern: immer zeigen.
const hide = country && a.dataset.country && a.dataset.country !== country;
a.classList.toggle('hidden', !!hide);
});
});
})();
</script>
</body>
</html>