feat: neue Website mit Docker-Deployment
Docker-Image bauen / Image bauen und veröffentlichen (push) Failing after 1m31s

This commit is contained in:
2026-07-13 22:12:02 +02:00
commit 5f9e64e9f4
17 changed files with 3603 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
.git
.gitea
.DS_Store
README.md
package.json
server.mjs
node_modules
npm-debug.log*
+48
View File
@@ -0,0 +1,48 @@
name: Docker-Image bauen
on:
push:
branches:
- main
workflow_dispatch:
env:
REGISTRY: git.servercentral.org
IMAGE: git.servercentral.org/jonas/hardtschule-karlsruhe.de
jobs:
build-and-push:
name: Image bauen und veröffentlichen
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Repository auschecken
uses: actions/checkout@v4
- name: An der Container-Registry anmelden
env:
REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
run: |
test -n "$REGISTRY_USERNAME" || (echo "Secret REGISTRY_USERNAME fehlt" && exit 1)
test -n "$REGISTRY_TOKEN" || (echo "Secret REGISTRY_TOKEN fehlt" && exit 1)
printf '%s' "$REGISTRY_TOKEN" | docker login "$REGISTRY" --username "$REGISTRY_USERNAME" --password-stdin
- name: Docker-Image bauen
run: |
docker build --pull \
--label "org.opencontainers.image.revision=${{ gitea.sha }}" \
--tag "$IMAGE:latest" \
--tag "$IMAGE:${{ gitea.sha }}" \
.
- name: Docker-Image veröffentlichen
run: |
docker push "$IMAGE:latest"
docker push "$IMAGE:${{ gitea.sha }}"
- name: Von der Container-Registry abmelden
if: ${{ always() }}
run: docker logout "$REGISTRY"
+14
View File
@@ -0,0 +1,14 @@
FROM nginx:alpine
LABEL org.opencontainers.image.title="Hardtschule Karlsruhe"
LABEL org.opencontainers.image.description="Statische Website der Hardtschule Karlsruhe"
LABEL org.opencontainers.image.source="https://git.servercentral.org/jonas/hardtschule-karlsruhe.de"
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY index.html impressum.html datenschutz.html styles.css script.js /usr/share/nginx/html/
COPY public/ /usr/share/nginx/html/public/
EXPOSE 80
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget -q --spider http://127.0.0.1/healthz || exit 1
+67
View File
@@ -0,0 +1,67 @@
# Neue Website der Hardtschule Karlsruhe
Ein eigenständiger, responsiver Website-Prototyp auf Basis öffentlich auffindbarer Informationen der bisherigen Schulwebsite, des Webarchivs und der Stadt Karlsruhe.
## Lokal ansehen
```sh
npm run dev
```
Danach ist die Seite unter `http://127.0.0.1:4173` erreichbar.
## Mit Docker betreiben
Das veröffentlichte Image kann direkt aus der Gitea-Container-Registry gestartet werden:
```sh
docker run -d \
--name hardtschule-website \
--restart unless-stopped \
-p 8080:80 \
git.servercentral.org/jonas/hardtschule-karlsruhe.de:latest
```
Die Website ist anschließend unter `http://localhost:8080` erreichbar. Alternativ genügt mit der enthaltenen Compose-Datei:
```sh
docker compose up -d
```
Falls das Gitea-Paket nicht öffentlich ist, muss auf dem Zielsystem zuvor einmal `docker login git.servercentral.org` ausgeführt werden.
### Image lokal bauen
```sh
docker build -t hardtschule-website .
docker run --rm -p 8080:80 hardtschule-website
```
### Automatischer Build in Gitea
Der Workflow unter `.gitea/workflows/docker.yml` baut bei jedem Push auf `main` zwei Tags:
- `git.servercentral.org/jonas/hardtschule-karlsruhe.de:latest`
- `git.servercentral.org/jonas/hardtschule-karlsruhe.de:<commit-sha>`
Damit der Workflow das Image veröffentlichen kann:
1. Repository-Actions und einen Runner mit dem Label `ubuntu-latest` aktivieren.
2. In Gitea einen Personal Access Token mit Schreibrecht für Pakete erstellen.
3. Unter **Repository → Einstellungen → Actions → Secrets** die Secrets `REGISTRY_USERNAME` und `REGISTRY_TOKEN` hinterlegen.
Der unveränderliche Commit-Tag erlaubt bei Bedarf ein gezieltes Rollback. `latest` zeigt immer auf den aktuellen Stand von `main`.
## Inhaltliche Quellen
- bisherige Website und Webarchiv der Hardtschule Karlsruhe
- Stadt Karlsruhe: Hardtschule Brandschutz und WC-Sanierung
- Stadt Karlsruhe: Städtischer Schülerhort an der Hardtschule
- Werkraum Karlsruhe: Theaterprojekte 2023/24
## Vor einer Veröffentlichung
- aktuelle Termine, Materiallisten und Pläne ergänzen
- Kontaktangaben und Zuständigkeiten von der Schule bestätigen lassen
- Impressum und Datenschutz an Hosting und tatsächliche Dienste anpassen
- Nutzungsfreigabe für Fotos dokumentieren (Fotos im Prototyp: Dirk Altenkirch / Stadt Karlsruhe)
+7
View File
@@ -0,0 +1,7 @@
services:
website:
image: git.servercentral.org/jonas/hardtschule-karlsruhe.de:latest
container_name: hardtschule-website
restart: unless-stopped
ports:
- "8080:80"
+38
View File
@@ -0,0 +1,38 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="robots" content="noindex" />
<title>Datenschutz · Hardtschule Karlsruhe</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body class="legal-body">
<header class="legal-header">
<div class="shell header-inner">
<a class="brand brand-footer" href="index.html" aria-label="Zurück zur Startseite">
<span class="brand-mark" aria-hidden="true"><span class="brand-roof"></span><span class="brand-door"></span></span>
<span class="brand-copy"><strong>Hardtschule</strong><span>Karlsruhe</span></span>
</a>
<a class="button button-sun button-small" href="index.html">Zur Startseite</a>
</div>
</header>
<main class="legal-main">
<article class="shell legal-content">
<p class="eyebrow">Rechtliches</p>
<h1>Datenschutz</h1>
<h2>Verantwortliche Stelle</h2>
<p>Hardtschule Karlsruhe<br />Hardtstraße 3<br />76185 Karlsruhe<br />Telefon: <a href="tel:+497211334686">0721 133-4686</a><br />E-Mail: <a href="mailto:schulleitung@hardtschule-karlsruhe.de">schulleitung@hardtschule-karlsruhe.de</a></p>
<h2>Datenverarbeitung auf dieser Website</h2>
<p>Der vorliegende Prototyp verwendet keine Analysewerkzeuge, keine Werbetracker, keine extern geladenen Schriftarten und setzt selbst keine Cookies. Die Kontaktlinks öffnen lediglich die Telefon- oder E-Mail-Anwendung des jeweiligen Geräts.</p>
<h2>Server-Protokolle</h2>
<p>Beim späteren Hosting können technisch notwendige Server-Protokolle anfallen, zum Beispiel IP-Adresse, Browsertyp, Betriebssystem und Zeitpunkt des Seitenaufrufs. Umfang, Speicherdauer und Rechtsgrundlage hängen vom ausgewählten Hostinganbieter ab und müssen vor Veröffentlichung ergänzt werden.</p>
<h2>Externe Links</h2>
<p>Links zu Seiten der Stadt Karlsruhe und zu OpenStreetMap werden erst nach einem aktiven Klick aufgerufen. Ab diesem Zeitpunkt gelten die Datenschutzbestimmungen des jeweiligen Anbieters.</p>
<h2>Ihre Rechte</h2>
<p>Betroffene Personen haben im gesetzlichen Rahmen insbesondere Rechte auf Auskunft, Berichtigung, Löschung, Einschränkung der Verarbeitung und Beschwerde bei der zuständigen Datenschutzaufsicht.</p>
<p class="legal-note"><strong>Vor Veröffentlichung erforderlich:</strong> Diese Datenschutzhinweise müssen an den tatsächlichen Hostinganbieter, mögliche Formulare, eingebundene Dienste und die Datenschutzorganisation des Schulträgers angepasst und fachlich geprüft werden.</p>
</article>
</main>
</body>
</html>
+38
View File
@@ -0,0 +1,38 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="robots" content="noindex" />
<title>Impressum · Hardtschule Karlsruhe</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body class="legal-body">
<header class="legal-header">
<div class="shell header-inner">
<a class="brand brand-footer" href="index.html" aria-label="Zurück zur Startseite">
<span class="brand-mark" aria-hidden="true"><span class="brand-roof"></span><span class="brand-door"></span></span>
<span class="brand-copy"><strong>Hardtschule</strong><span>Karlsruhe</span></span>
</a>
<a class="button button-sun button-small" href="index.html">Zur Startseite</a>
</div>
</header>
<main class="legal-main">
<article class="shell legal-content">
<p class="eyebrow">Rechtliches</p>
<h1>Impressum</h1>
<h2>Angaben zum Anbieter</h2>
<p>Hardtschule (Grundschule)<br />Hardtstraße 3<br />76185 Karlsruhe</p>
<h2>Kontakt</h2>
<p>Telefon: <a href="tel:+497211334685">0721 133-4685</a> (Schulleitung)<br />Telefon: <a href="tel:+497211334686">0721 133-4686</a> (Sekretariat)<br />E-Mail: <a href="mailto:schulleitung@hardtschule-karlsruhe.de">schulleitung@hardtschule-karlsruhe.de</a></p>
<h2>Vertretung</h2>
<p>Vertreten durch die Schulleitung: Elena Hauer.</p>
<h2>Haftung für Inhalte und Links</h2>
<p>Die Hardtschule ist für eigene Inhalte auf diesen Seiten verantwortlich. Für Inhalte verlinkter externer Seiten ist der jeweilige Anbieter verantwortlich. Werden Rechtsverletzungen bekannt, werden entsprechende Links oder Inhalte geprüft und gegebenenfalls entfernt.</p>
<h2>Urheberrecht</h2>
<p>Die auf dieser Website erstellten Inhalte unterliegen dem deutschen Urheberrecht. Fotos der städtischen Projektseite sind mit dem jeweiligen Bildnachweis gekennzeichnet.</p>
<p class="legal-note"><strong>Hinweis zum Prototyp:</strong> Die Angaben wurden aus der bisherigen Schulwebsite rekonstruiert. Vor einer Veröffentlichung müssen sie von der Schule rechtlich und redaktionell geprüft werden.</p>
</article>
</main>
</body>
</html>
+531
View File
@@ -0,0 +1,531 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta
name="description"
content="Hardtschule Karlsruhe bewegte Grundschule in Mühlburg. Lernen, Gemeinschaft und wichtige Informationen für Familien."
/>
<meta name="theme-color" content="#0c4a3e" />
<title>Hardtschule Karlsruhe · Bewegte Grundschule</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><rect width=%22100%22 height=%22100%22 rx=%2224%22 fill=%22%230c4a3e%22/><path d=%22M22 67V39L50 22l28 17v28%22 fill=%22none%22 stroke=%22%23f5c95d%22 stroke-width=%229%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22/><path d=%22M35 70V52h30v18%22 fill=%22none%22 stroke=%22white%22 stroke-width=%229%22 stroke-linecap=%22round%22/></svg>" />
<link rel="stylesheet" href="styles.css" />
<script src="script.js" defer></script>
</head>
<body>
<a class="skip-link" href="#hauptinhalt">Zum Inhalt springen</a>
<svg class="svg-library" aria-hidden="true">
<symbol id="icon-arrow" viewBox="0 0 24 24">
<path d="M5 12h14M13 6l6 6-6 6" />
</symbol>
<symbol id="icon-calendar" viewBox="0 0 24 24">
<path d="M6 3v3M18 3v3M4 9h16M5 5h14a1 1 0 0 1 1 1v14H4V6a1 1 0 0 1 1-1Z" />
<path d="m8 14 2 2 5-5" />
</symbol>
<symbol id="icon-bag" viewBox="0 0 24 24">
<path d="M8 8V6a4 4 0 0 1 8 0v2M5 8h14l1 13H4L5 8Z" />
<path d="M9 12h6" />
</symbol>
<symbol id="icon-sun" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="4" />
<path d="M12 2v2M12 20v2M4.93 4.93l1.42 1.42M17.65 17.65l1.42 1.42M2 12h2M20 12h2M4.93 19.07l1.42-1.42M17.65 6.35l1.42-1.42" />
</symbol>
<symbol id="icon-clock" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="9" />
<path d="M12 7v6l4 2" />
</symbol>
<symbol id="icon-phone" viewBox="0 0 24 24">
<path d="M7.2 3H4.6A1.6 1.6 0 0 0 3 4.6C3 13.66 10.34 21 19.4 21a1.6 1.6 0 0 0 1.6-1.6v-2.58l-4-1.34-1.08 2.16a14.2 14.2 0 0 1-9.56-9.56L8.52 7 7.2 3Z" />
</symbol>
<symbol id="icon-shoe" viewBox="0 0 24 24">
<path d="M4 4c2 1 3 4 4 7l4 2 2-2 2 2 3-1 2 5c-2 2-5 3-9 3H5a2 2 0 0 1-2-2v-2l4-2" />
<path d="M8 11 6 13M11 12l-2 3" />
</symbol>
<symbol id="icon-heart" viewBox="0 0 24 24">
<path d="M20.8 5.7a5.4 5.4 0 0 0-7.6 0L12 6.9l-1.2-1.2a5.4 5.4 0 0 0-7.6 7.6L12 22l8.8-8.7a5.4 5.4 0 0 0 0-7.6Z" />
</symbol>
<symbol id="icon-speech" viewBox="0 0 24 24">
<path d="M4 4h16v12H9l-5 4V4Z" />
<path d="M8 9h8M8 12h5" />
</symbol>
<symbol id="icon-book" viewBox="0 0 24 24">
<path d="M3 5.5A4.5 4.5 0 0 1 7.5 1H11v18H7.5A4.5 4.5 0 0 0 3 23V5.5ZM21 5.5A4.5 4.5 0 0 0 16.5 1H13v18h3.5A4.5 4.5 0 0 1 21 23V5.5Z" />
</symbol>
<symbol id="icon-map" viewBox="0 0 24 24">
<path d="m3 6 6-3 6 3 6-3v15l-6 3-6-3-6 3V6Z" />
<path d="M9 3v15M15 6v15" />
</symbol>
<symbol id="icon-mail" viewBox="0 0 24 24">
<path d="M3 5h18v14H3V5Z" />
<path d="m3 7 9 7 9-7" />
</symbol>
<symbol id="icon-close" viewBox="0 0 24 24">
<path d="m6 6 12 12M18 6 6 18" />
</symbol>
</svg>
<div class="utility-bar">
<div class="shell utility-inner">
<span>Grundschule in Karlsruhe-Mühlburg</span>
<a href="tel:+497211334686">
<svg aria-hidden="true"><use href="#icon-phone"></use></svg>
Sekretariat: 0721 133-4686
</a>
</div>
</div>
<header class="site-header" data-header>
<div class="shell header-inner">
<a class="brand" href="#top" aria-label="Hardtschule Karlsruhe Startseite">
<span class="brand-mark" aria-hidden="true">
<span class="brand-roof"></span>
<span class="brand-door"></span>
</span>
<span class="brand-copy">
<strong>Hardtschule</strong>
<span>Karlsruhe</span>
</span>
</a>
<nav class="desktop-nav" aria-label="Hauptnavigation">
<a href="#schule">Die Schule</a>
<a href="#schulleben">Schulleben</a>
<a href="#gemeinschaft">Gemeinschaft</a>
<a href="#elterninfo">Elterninfo</a>
</nav>
<a class="button button-small button-dark header-contact" href="#kontakt">
Kontakt
<svg aria-hidden="true"><use href="#icon-arrow"></use></svg>
</a>
<button class="menu-button" type="button" aria-expanded="false" aria-controls="mobile-navigation" data-menu-button>
<span class="sr-only">Menü öffnen</span>
<span></span><span></span><span></span>
</button>
</div>
<nav class="mobile-nav" id="mobile-navigation" aria-label="Mobile Navigation" data-mobile-nav hidden>
<div class="shell mobile-nav-inner">
<a href="#schule">Die Schule</a>
<a href="#schulleben">Schulleben</a>
<a href="#gemeinschaft">Gemeinschaft</a>
<a href="#elterninfo">Elterninfo</a>
<a href="#kontakt">Kontakt</a>
</div>
</nav>
</header>
<main id="hauptinhalt">
<section class="hero" id="top">
<div class="hero-dots" aria-hidden="true"></div>
<div class="shell hero-grid">
<div class="hero-copy">
<p class="eyebrow eyebrow-light reveal">Willkommen an der Hardtschule</p>
<h1 class="reveal" style="--delay: 80ms">Bewegt lernen.<br /><em>Gemeinsam wachsen.</em></h1>
<p class="hero-lead reveal" style="--delay: 160ms">
Eine lebendige Grundschule in Mühlburg, an der Kinder neugierig lernen, Verantwortung übernehmen und sich wohlfühlen können.
</p>
<div class="hero-actions reveal" style="--delay: 240ms">
<a class="button button-sun" href="#schule">
Schule kennenlernen
<svg aria-hidden="true"><use href="#icon-arrow"></use></svg>
</a>
<a class="text-link text-link-light" href="#elterninfo">
Direkt zu den Elterninfos
<svg aria-hidden="true"><use href="#icon-arrow"></use></svg>
</a>
</div>
<div class="hero-signals reveal" style="--delay: 320ms" aria-label="Schwerpunkte der Hardtschule">
<span><i class="signal-dot signal-yellow"></i> Bewegte Grundschule</span>
<span><i class="signal-dot signal-coral"></i> Soziales Lernen</span>
<span><i class="signal-dot signal-blue"></i> Deutschförderung</span>
</div>
</div>
<div class="hero-visual reveal" style="--delay: 120ms">
<div class="hero-image-wrap">
<img
src="public/images/hardtschule-hero.jpg"
alt="Historischer Anbau der Hardtschule mit gelber Backsteinfassade"
width="1500"
height="785"
/>
<span class="photo-credit">Foto: Dirk Altenkirch / Stadt Karlsruhe</span>
</div>
<div class="hero-sticker sticker-year" aria-hidden="true">
<span>seit</span>
<strong>1847</strong>
<span>in Mühlburg</span>
</div>
<div class="hero-sticker sticker-move" aria-hidden="true">
<svg><use href="#icon-shoe"></use></svg>
<span>Hier bewegt<br />sich was!</span>
</div>
</div>
</div>
<div class="hero-wave" aria-hidden="true"></div>
</section>
<section class="quick-section" aria-labelledby="quick-title">
<div class="shell">
<div class="quick-heading">
<div>
<p class="eyebrow">Schnell gefunden</p>
<h2 id="quick-title">Was brauchen Sie gerade?</h2>
</div>
<p>Die wichtigsten Wege für Familien ohne langes Suchen.</p>
</div>
<div class="quick-grid">
<button class="quick-card quick-blue" type="button" data-detail="schulanfang">
<span class="quick-icon"><svg aria-hidden="true"><use href="#icon-calendar"></use></svg></span>
<span><strong>Schulanfang</strong><small>Gut vorbereitet starten</small></span>
<svg class="quick-arrow" aria-hidden="true"><use href="#icon-arrow"></use></svg>
</button>
<button class="quick-card quick-coral" type="button" data-detail="materiallisten">
<span class="quick-icon"><svg aria-hidden="true"><use href="#icon-bag"></use></svg></span>
<span><strong>Materiallisten</strong><small>Für Klassen 14 &amp; VKL</small></span>
<svg class="quick-arrow" aria-hidden="true"><use href="#icon-arrow"></use></svg>
</button>
<a class="quick-card quick-yellow" href="https://www.karlsruhe.de/bildung-soziales/schulstadt-karlsruhe/schulferien" target="_blank" rel="noreferrer">
<span class="quick-icon"><svg aria-hidden="true"><use href="#icon-sun"></use></svg></span>
<span><strong>Ferien</strong><small>Termine der Stadt Karlsruhe</small></span>
<svg class="quick-arrow" aria-hidden="true"><use href="#icon-arrow"></use></svg>
</a>
<a class="quick-card quick-green" href="https://www.karlsruhe.de/bildung-soziales/schulstadt-karlsruhe/schulkindbetreuung/staedtische-schuelerhorte-auf-einen-blick/staedtischer-schuelerhort-an-der-hardtschule" target="_blank" rel="noreferrer">
<span class="quick-icon"><svg aria-hidden="true"><use href="#icon-clock"></use></svg></span>
<span><strong>Betreuung</strong><small>Städtischer Schülerhort</small></span>
<svg class="quick-arrow" aria-hidden="true"><use href="#icon-arrow"></use></svg>
</a>
<a class="quick-card quick-cream" href="tel:+497211334686">
<span class="quick-icon"><svg aria-hidden="true"><use href="#icon-phone"></use></svg></span>
<span><strong>Fehlzeit melden</strong><small>Sekretariat &amp; Anrufbeantworter</small></span>
<svg class="quick-arrow" aria-hidden="true"><use href="#icon-arrow"></use></svg>
</a>
</div>
</div>
</section>
<section class="profile-section section" id="schule">
<div class="shell">
<div class="section-heading section-heading-centered reveal">
<p class="eyebrow">Was uns ausmacht</p>
<h2>Eine Schule, die Kinder <em>ganzheitlich</em> stärkt</h2>
<p>Wissen, Bewegung, Sprache und ein respektvolles Miteinander gehören an der Hardtschule zusammen.</p>
</div>
<div class="profile-grid">
<article class="profile-card profile-movement reveal">
<div class="profile-icon"><svg aria-hidden="true"><use href="#icon-shoe"></use></svg></div>
<span class="profile-number">01</span>
<h3>Lernen in Bewegung</h3>
<p>Bewegungszeiten, bewegtes Lernen und abwechslungsreiche Pausen bringen Körper und Kopf in Schwung.</p>
<div class="profile-fact"><strong>Seit 2010</strong><span>zertifizierte Grundschule mit sport- und bewegungserzieherischem Schwerpunkt</span></div>
<button class="text-link" type="button" data-detail="bewegung">Mehr erfahren <svg aria-hidden="true"><use href="#icon-arrow"></use></svg></button>
</article>
<article class="profile-card profile-community reveal" style="--delay: 100ms">
<div class="profile-icon"><svg aria-hidden="true"><use href="#icon-heart"></use></svg></div>
<span class="profile-number">02</span>
<h3>Stark miteinander</h3>
<p>Klassenrat, Schüler*innenparlament und soziale Lernzeiten geben Kindern Stimme, Halt und Verantwortung.</p>
<div class="profile-fact"><strong>Seit 2023</strong><span>verankert ein Sozialcurriculum die gemeinsame Präventionsarbeit im Schulalltag</span></div>
<button class="text-link" type="button" data-detail="miteinander">Mehr erfahren <svg aria-hidden="true"><use href="#icon-arrow"></use></svg></button>
</article>
<article class="profile-card profile-language reveal" style="--delay: 200ms">
<div class="profile-icon"><svg aria-hidden="true"><use href="#icon-speech"></use></svg></div>
<span class="profile-number">03</span>
<h3>Sprache öffnet Türen</h3>
<p>In der Vorbereitungsklasse und der nachgehenden Förderung bekommen Kinder Zeit und Raum für Deutsch.</p>
<div class="profile-fact"><strong>VKL &amp; Förderung</strong><span>für einen sicheren Einstieg in Unterricht, Freundschaften und den Schulalltag</span></div>
<button class="text-link" type="button" data-detail="sprache">Mehr erfahren <svg aria-hidden="true"><use href="#icon-arrow"></use></svg></button>
</article>
</div>
</div>
</section>
<section class="place-section section">
<div class="shell place-grid">
<div class="place-visual reveal">
<img
class="place-image-main"
src="public/images/hardtschule-anbau.jpg"
alt="Seitenansicht des denkmalgeschützten Anbaus der Hardtschule"
width="1500"
height="998"
loading="lazy"
/>
<img
class="place-image-small"
src="public/images/hardtschule-fassade.jpg"
alt="Nahansicht der historischen Backsteinfassade"
width="1500"
height="1500"
loading="lazy"
/>
<span class="place-caption">Historischer Charakter,<br />modern weitergedacht.</span>
</div>
<div class="place-copy reveal" style="--delay: 100ms">
<p class="eyebrow">Unser Ort</p>
<h2>Ein Schulhaus mit <em>Geschichte</em> und Zukunft</h2>
<p class="place-lead">Die Hardtschule prägt Mühlburg seit 1847. Hinter der historischen Fassade entsteht jeden Tag Neues: Ideen, Freundschaften und mutige erste Schritte.</p>
<div class="place-facts">
<div><strong>1847</strong><span>erbaut in Mühlburg</span></div>
<div><strong>2020</strong><span>denkmalgerecht saniert</span></div>
<div><strong>direkt nebenan</strong><span>Carl-Benz-Halle für Sport &amp; Feste</span></div>
</div>
<p>Zum Schulgelände gehören Klassenzimmer, Lesezimmer, Schülerhort, der Schulhof und die „Grüne Insel“ mit Spielgeräten.</p>
<button class="button button-outline" type="button" data-detail="rundgang">
Rundgang entdecken
<svg aria-hidden="true"><use href="#icon-arrow"></use></svg>
</button>
<small class="image-source">Fotos: Dirk Altenkirch / Stadt Karlsruhe</small>
</div>
</div>
</section>
<section class="life-section section" id="schulleben">
<div class="shell">
<div class="section-heading section-heading-split reveal">
<div>
<p class="eyebrow eyebrow-light">Schulleben</p>
<h2>Neugier sieht jeden Tag <em>anders</em> aus</h2>
</div>
<p>Werkstatt, Theater, Bewegung oder Technik: Kinder lernen besonders gut, wenn sie selbst ausprobieren und gestalten dürfen.</p>
</div>
<div class="story-grid">
<article class="story-card story-large story-yellow reveal">
<div class="story-art story-art-letters" aria-hidden="true">
<span>A</span><span>B</span><span>C</span>
<i></i><i></i><i></i>
</div>
<div class="story-copy">
<span class="story-tag">Klasse 1</span>
<h3>Ein Fest für alle Buchstaben</h3>
<p>Beim Buchstabenfest wird aus ersten Zeichen eine ganze Welt voller Wörter.</p>
</div>
</article>
<article class="story-card story-blue reveal" style="--delay: 80ms">
<div class="story-art story-art-robot" aria-hidden="true">
<span class="robot-head"><i></i><i></i></span>
<span class="robot-body"></span>
<span class="robot-signal"></span>
</div>
<div class="story-copy">
<span class="story-tag">Klasse 4</span>
<h3>Tüfteln, bauen, Roboter steuern</h3>
<p>Technik wird spannend, wenn eigene Ideen laufen lernen.</p>
</div>
</article>
<article class="story-card story-coral reveal" style="--delay: 140ms">
<div class="story-art story-art-print" aria-hidden="true">
<span class="print-sheet"></span><span class="print-roll"></span><i></i>
</div>
<div class="story-copy">
<span class="story-tag">Museum in der Box</span>
<h3>Druckwerkstatt zum Anfassen</h3>
<p>Material, Farbe und Handwerk machen Geschichte begreifbar.</p>
</div>
</article>
<article class="story-card story-wide story-green reveal" style="--delay: 200ms">
<div class="story-copy">
<span class="story-tag">Bewegte Schule</span>
<h3>Kopf an. Schuhe an. Los!</h3>
<p>Bewegung findet nicht nur im Sportunterricht statt sondern auch beim Lernen, in den Pausen und bei gemeinsamen Aktionen.</p>
<button class="text-link text-link-light" type="button" data-detail="bewegung">Unser Bewegungskonzept <svg aria-hidden="true"><use href="#icon-arrow"></use></svg></button>
</div>
<div class="story-art story-art-track" aria-hidden="true"><span></span><i></i><b></b></div>
</article>
</div>
</div>
</section>
<section class="community-section section" id="gemeinschaft">
<div class="shell">
<div class="section-heading section-heading-centered reveal">
<p class="eyebrow">Gemeinschaft</p>
<h2>Viele Menschen. <em>Eine Schule.</em></h2>
<p>Kinder, Familien, Kollegium und Partner gestalten die Hardtschule gemeinsam.</p>
</div>
<div class="community-grid">
<article class="community-card reveal">
<span class="community-icon community-icon-blue"><svg aria-hidden="true"><use href="#icon-speech"></use></svg></span>
<h3>Kinder reden mit</h3>
<p>Im Klassenrat und Schüler*innenparlament werden Ideen besprochen, Verantwortung geteilt und Lösungen gefunden.</p>
<button type="button" class="text-link" data-detail="mitbestimmung">Mitbestimmung ansehen <svg aria-hidden="true"><use href="#icon-arrow"></use></svg></button>
</article>
<article class="community-card reveal" style="--delay: 100ms">
<span class="community-icon community-icon-coral"><svg aria-hidden="true"><use href="#icon-heart"></use></svg></span>
<h3>Beratung, die da ist</h3>
<p>Die Schulsozialarbeit unterstützt Kinder, Eltern und Lehrkräfte freiwillig, vertraulich und kostenlos.</p>
<button type="button" class="text-link" data-detail="beratung">Beratung finden <svg aria-hidden="true"><use href="#icon-arrow"></use></svg></button>
</article>
<article class="community-card reveal" style="--delay: 200ms">
<span class="community-icon community-icon-yellow"><svg aria-hidden="true"><use href="#icon-book"></use></svg></span>
<h3>Engagement, das ankommt</h3>
<p>Der Förderverein ermöglicht Pausenobst, Bücher, Spielgeräte, Theaterbesuche und gemeinsame Erlebnisse.</p>
<button type="button" class="text-link" data-detail="foerderverein">Förderverein kennenlernen <svg aria-hidden="true"><use href="#icon-arrow"></use></svg></button>
</article>
</div>
<blockquote class="community-quote reveal">
<svg aria-hidden="true"><use href="#icon-heart"></use></svg>
<p>„Zusammen arbeiten, zusammen leben und zusammen lernen.“</p>
<cite>Aus dem sozialen Leitbild der Hardtschule</cite>
</blockquote>
</div>
</section>
<section class="parents-section section" id="elterninfo">
<div class="shell parents-grid">
<div class="parents-intro reveal">
<p class="eyebrow eyebrow-light">Für Familien</p>
<h2>Alles Wichtige.<br /><em>Einfach erklärt.</em></h2>
<p>Vom ersten Schultag bis zur Betreuung: Hier finden Sie die häufigsten Themen auf einen Blick.</p>
<div class="parents-note">
<svg aria-hidden="true"><use href="#icon-phone"></use></svg>
<div>
<span>Direkt mit uns sprechen</span>
<a href="tel:+497211334686">0721 133-4686</a>
</div>
</div>
</div>
<div class="info-accordion reveal" style="--delay: 100ms">
<details name="elterninfo" open>
<summary><span>01</span>Mein Kind kommt in die Schule <i></i></summary>
<div class="accordion-content">
<p>Für zukünftige Erstklässler*innen bündelt die Schule Informationen zu Anmeldung, Kennenlernen, Einschulung und dem Start in Klasse 1.</p>
<button type="button" class="text-link" data-detail="schulanfang">Infos zum Schulanfang <svg aria-hidden="true"><use href="#icon-arrow"></use></svg></button>
</div>
</details>
<details name="elterninfo">
<summary><span>02</span>Material, Pläne &amp; Downloads <i></i></summary>
<div class="accordion-content">
<p>Materiallisten werden nach Klasse und Schuljahr geordnet. Stunden-, AG- und Ferienpläne erhalten einen eigenen, schnell auffindbaren Downloadbereich.</p>
<button type="button" class="text-link" data-detail="materiallisten">Zum Downloadbereich <svg aria-hidden="true"><use href="#icon-arrow"></use></svg></button>
</div>
</details>
<details name="elterninfo">
<summary><span>03</span>Betreuung nach dem Unterricht <i></i></summary>
<div class="accordion-content">
<p>Der städtische Schülerhort befindet sich direkt an der Hardtschule. Verbindliche Angaben zu Angebot und Anmeldung stellt die Stadt Karlsruhe bereit.</p>
<a class="text-link" href="https://www.karlsruhe.de/bildung-soziales/schulstadt-karlsruhe/schulkindbetreuung/staedtische-schuelerhorte-auf-einen-blick/staedtischer-schuelerhort-an-der-hardtschule" target="_blank" rel="noreferrer">Zur Hort-Seite <svg aria-hidden="true"><use href="#icon-arrow"></use></svg></a>
</div>
</details>
<details name="elterninfo">
<summary><span>04</span>Fehlzeiten &amp; Beurlaubung <i></i></summary>
<div class="accordion-content">
<p>Bitte melden Sie eine Fehlzeit möglichst früh über den mit der Klasse vereinbarten Weg. Das Sekretariat und der Anrufbeantworter sind unter 0721 133-4686 erreichbar.</p>
<a class="text-link" href="tel:+497211334686">Sekretariat anrufen <svg aria-hidden="true"><use href="#icon-arrow"></use></svg></a>
</div>
</details>
<details name="elterninfo">
<summary><span>05</span>Unterstützung &amp; Beratung <i></i></summary>
<div class="accordion-content">
<p>Schulsozialarbeit und Beratung unterstützen bei schulischen, persönlichen und familiären Anliegen. Gespräche sind vertraulich und kostenlos.</p>
<button type="button" class="text-link" data-detail="beratung">Ansprechstellen ansehen <svg aria-hidden="true"><use href="#icon-arrow"></use></svg></button>
</div>
</details>
</div>
</div>
</section>
<section class="contact-section section" id="kontakt">
<div class="shell contact-grid">
<div class="contact-copy reveal">
<p class="eyebrow">Kontakt &amp; Anfahrt</p>
<h2>Wir sind gern <em>für Sie da.</em></h2>
<p class="contact-lead">Sie haben eine Frage? Rufen Sie an oder schreiben Sie uns. Bei einem Besuch melden Sie sich bitte zuerst im Sekretariat.</p>
<div class="contact-list">
<div>
<span class="contact-icon"><svg aria-hidden="true"><use href="#icon-map"></use></svg></span>
<p><strong>Hardtschule Karlsruhe</strong><br />Hardtstraße 3<br />76185 Karlsruhe</p>
</div>
<div>
<span class="contact-icon"><svg aria-hidden="true"><use href="#icon-phone"></use></svg></span>
<p><strong>Sekretariat</strong><br /><a href="tel:+497211334686">0721 133-4686</a><br /><small>Anrufbeantworter ist geschaltet</small></p>
</div>
<div>
<span class="contact-icon"><svg aria-hidden="true"><use href="#icon-clock"></use></svg></span>
<p><strong>Öffnungszeiten</strong><br />MoDo, 7:3011:30 Uhr<br /><small>Freitags ist das Sekretariat nicht besetzt.</small></p>
</div>
<div>
<span class="contact-icon"><svg aria-hidden="true"><use href="#icon-mail"></use></svg></span>
<p><strong>E-Mail</strong><br /><a href="mailto:schulleitung@hardtschule-karlsruhe.de">schulleitung@hardtschule-karlsruhe.de</a></p>
</div>
</div>
</div>
<div class="map-card reveal" style="--delay: 120ms" aria-label="Anfahrt zur Hardtschule">
<div class="map-illustration" aria-hidden="true">
<span class="map-road road-one"></span>
<span class="map-road road-two"></span>
<span class="map-road road-three"></span>
<span class="map-water"></span>
<span class="map-park park-one"></span>
<span class="map-park park-two"></span>
<span class="map-pin"><i></i></span>
<span class="map-label">Hardtschule</span>
<span class="map-river-label">Alb</span>
</div>
<div class="map-footer">
<div><strong>Hardtstraße 3</strong><span>Karlsruhe-Mühlburg</span></div>
<a class="button button-dark button-small" href="https://www.openstreetmap.org/search?query=Hardtstra%C3%9Fe%203%2C%2076185%20Karlsruhe" target="_blank" rel="noreferrer">Route planen <svg aria-hidden="true"><use href="#icon-arrow"></use></svg></a>
</div>
</div>
</div>
</section>
</main>
<footer class="site-footer">
<div class="shell footer-top">
<a class="brand brand-footer" href="#top" aria-label="Zurück nach oben">
<span class="brand-mark" aria-hidden="true"><span class="brand-roof"></span><span class="brand-door"></span></span>
<span class="brand-copy"><strong>Hardtschule</strong><span>Karlsruhe</span></span>
</a>
<p>Eine bewegte Grundschule mit Herz mitten in Mühlburg.</p>
<a class="button button-sun button-small" href="mailto:schulleitung@hardtschule-karlsruhe.de">E-Mail schreiben <svg aria-hidden="true"><use href="#icon-arrow"></use></svg></a>
</div>
<div class="shell footer-links">
<div>
<strong>Entdecken</strong>
<a href="#schule">Die Schule</a><a href="#schulleben">Schulleben</a><a href="#gemeinschaft">Gemeinschaft</a>
</div>
<div>
<strong>Für Familien</strong>
<a href="#elterninfo">Elterninfo</a><a href="https://www.karlsruhe.de/bildung-soziales/schulstadt-karlsruhe/schulferien" target="_blank" rel="noreferrer">Ferienplan</a><a href="#kontakt">Kontakt</a>
</div>
<div>
<strong>Adresse</strong>
<span>Hardtstraße 3<br />76185 Karlsruhe</span><a href="tel:+497211334686">0721 133-4686</a>
</div>
</div>
<div class="shell footer-bottom">
<span>© <span data-year></span> Hardtschule Karlsruhe</span>
<div><a href="impressum.html">Impressum</a><a href="datenschutz.html">Datenschutz</a></div>
</div>
</footer>
<dialog class="detail-dialog" data-dialog>
<div class="dialog-shell">
<button class="dialog-close" type="button" aria-label="Dialog schließen" data-dialog-close>
<svg aria-hidden="true"><use href="#icon-close"></use></svg>
</button>
<span class="dialog-kicker" data-dialog-kicker></span>
<h2 data-dialog-title></h2>
<div class="dialog-content" data-dialog-content></div>
<div class="dialog-actions" data-dialog-actions></div>
</div>
</dialog>
</body>
</html>
+50
View File
@@ -0,0 +1,50 @@
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
index index.html;
charset utf-8;
server_tokens off;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
gzip on;
gzip_vary on;
gzip_min_length 512;
gzip_types text/css application/javascript image/svg+xml;
location = /healthz {
access_log off;
default_type text/plain;
return 200 "ok\n";
}
location = / {
expires -1;
try_files /index.html =404;
}
location ~* \.html$ {
expires -1;
try_files $uri =404;
}
location ~* \.(?:css|js)$ {
expires 1h;
try_files $uri =404;
}
location ^~ /public/images/ {
expires 30d;
try_files $uri =404;
}
location / {
try_files $uri $uri/ =404;
}
}
+10
View File
@@ -0,0 +1,10 @@
{
"name": "hardtschule-karlsruhe",
"version": "1.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "node server.mjs",
"start": "node server.mjs"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 377 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 524 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 311 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

+267
View File
@@ -0,0 +1,267 @@
const menuButton = document.querySelector("[data-menu-button]");
const mobileNav = document.querySelector("[data-mobile-nav]");
const dialog = document.querySelector("[data-dialog]");
const dialogTitle = document.querySelector("[data-dialog-title]");
const dialogKicker = document.querySelector("[data-dialog-kicker]");
const dialogContent = document.querySelector("[data-dialog-content]");
const dialogActions = document.querySelector("[data-dialog-actions]");
const dialogClose = document.querySelector("[data-dialog-close]");
const detailContent = {
schulanfang: {
kicker: "Für zukünftige Erstklässler*innen",
title: "Ein guter Start in die Schule",
html: `
<p>Die Hardtschule informiert Familien rechtzeitig über Schulanmeldung, Kennenlernnachmittag, Elternabend und Einschulung.</p>
<p><strong>Für verbindliche Termine des kommenden Schuljahres</strong> wenden Sie sich bitte an das Sekretariat. So landen keine veralteten Termine aus dem Webarchiv auf Ihrer Merkliste.</p>
<div class="dialog-note">Dieser Prototyp ist bereits für eine jährlich aktualisierbare Termin- und Downloadpflege vorbereitet.</div>
`,
actions: [
{ label: "Sekretariat anrufen", href: "tel:+497211334686", primary: true },
{ label: "E-Mail schreiben", href: "mailto:schulleitung@hardtschule-karlsruhe.de" },
],
},
materiallisten: {
kicker: "Downloads",
title: "Materiallisten klar nach Klasse sortiert",
html: `
<p>Vorgesehen sind aktuelle Listen für <strong>Klasse 1, 2, 3, 4 sowie die VKL</strong>. Frühere Listen aus dem Schuljahr 2025/26 wurden bewusst nicht als aktuell übernommen.</p>
<p>Bis die neuen PDF-Dateien von der Schule eingestellt sind, erhalten Familien die verbindliche Liste über die Klassenleitung oder das Sekretariat.</p>
<div class="dialog-note">Gut erhaltene Schulsachen können in der Regel weiterverwendet werden bitte immer die aktuelle Klassenliste beachten.</div>
`,
actions: [
{ label: "Liste anfragen", href: "mailto:schulleitung@hardtschule-karlsruhe.de?subject=Aktuelle%20Materialliste", primary: true },
{ label: "Sekretariat anrufen", href: "tel:+497211334686" },
],
},
bewegung: {
kicker: "Schulprofil",
title: "Bewegung gehört zum Lernen",
html: `
<p>Die Hardtschule ist seit 2010 als Grundschule mit sport- und bewegungserzieherischem Schwerpunkt zertifiziert und wurde 2016 erfolgreich rezertifiziert.</p>
<ul>
<li>regelmäßige Bewegungszeiten im Klassenzimmer</li>
<li>Methoden des bewegten Lernens</li>
<li>drei Sportstunden in der benachbarten Carl-Benz-Halle</li>
<li>Spiel- und Sportgeräte für aktive Pausen</li>
</ul>
<p>So können Kinder nach konzentrierten Arbeitsphasen neue Energie sammeln und Lernen mit allen Sinnen erleben.</p>
`,
actions: [{ label: "Zur Schulgemeinschaft", href: "#gemeinschaft", primary: true }],
},
miteinander: {
kicker: "Soziales Lernen",
title: "Respekt wird jeden Tag geübt",
html: `
<p>Das 2023 verabschiedete Sozialcurriculum bildet die Grundlage für Prävention und soziales Lernen.</p>
<ul>
<li>angemessen und respektvoll mit Konflikten umgehen</li>
<li>zusammen arbeiten, leben und lernen</li>
<li>einander unterstützen und bei Bedarf Hilfe holen</li>
<li>Verantwortung im Klassenrat und Schüler*innenparlament übernehmen</li>
</ul>
<p>Ergänzend finden bedarfsgerechte Projekte mit externen Partnern statt etwa Theaterpädagogik, Selbstbehauptung und Klassentraining.</p>
`,
actions: [{ label: "Beratung kennenlernen", action: "beratung", primary: true }],
},
sprache: {
kicker: "VKL & Deutschförderung",
title: "Sprache schafft Zugehörigkeit",
html: `
<p>In der Vorbereitungsklasse (VKL) lernen neu zugewanderte Kinder Deutsch und finden schrittweise in den Schulalltag hinein.</p>
<p>Die Förderung verbindet sprachliches Lernen mit Begegnung, Orientierung und der Teilnahme an der Schulgemeinschaft. Nach dem Wechsel in eine Regelklasse kann nachgehende Deutschförderung unterstützen.</p>
<div class="dialog-note">Aufnahme und Förderumfang werden individuell mit Schule und zuständigen Stellen abgestimmt.</div>
`,
actions: [
{ label: "VKL-Anfrage senden", href: "mailto:schulleitung@hardtschule-karlsruhe.de?subject=Anfrage%20zur%20VKL", primary: true },
{ label: "Sekretariat anrufen", href: "tel:+497211334686" },
],
},
rundgang: {
kicker: "Gebäude & Gelände",
title: "Willkommen in der Hardtschule",
html: `
<p>Im historischen Schulhaus befinden sich Klassenräume, Sekretariat und Rektorat. Das Lesezimmer wird auch für den Unterricht der VKL genutzt.</p>
<ul>
<li>Klassenzimmer auf mehreren Etagen</li>
<li>Lesezimmer und Räume für Förderung</li>
<li>Schülerhort direkt an der Schule</li>
<li>Schulhof, Spielplatz und „Grüne Insel“</li>
<li>Carl-Benz-Halle für Sport, Einschulung und Feste</li>
</ul>
<p>Der denkmalgeschützte Anbau von 1906 wurde 2020 behutsam saniert. Historische Materialien blieben dabei erhalten.</p>
`,
actions: [
{ label: "Anfahrt ansehen", href: "#kontakt", primary: true },
{ label: "Städtisches Bauprojekt", href: "https://www.karlsruhe.de/mobilitaet-stadtbild/hochbau-und-architektur/neubauten-und-bauen-im-bestand/hardtschule-brandschutz-und-wc-sanierung", external: true },
],
},
mitbestimmung: {
kicker: "Schüler*innenparlament",
title: "Kinder gestalten ihre Schule mit",
html: `
<p>Klassensprecher*innen bringen die Perspektiven ihrer Klassen in das Schüler*innenparlament ein. Sie hören zu, vertreten Interessen und helfen dabei, gemeinsame Lösungen zu finden.</p>
<p>Klassenrat, Pausenengel und soziale Lernstunden geben Beteiligung einen festen Platz im Alltag nicht nur bei besonderen Projekten.</p>
`,
actions: [{ label: "Mehr zum sozialen Lernen", action: "miteinander", primary: true }],
},
beratung: {
kicker: "Schulsozialarbeit",
title: "Vertrauliche Hilfe direkt an der Schule",
html: `
<p>Die Schulsozialarbeit ist ein Beratungsangebot der Stadt Karlsruhe für Schüler*innen, Erziehungsberechtigte und das Kollegium.</p>
<ul>
<li>freiwillig, vertraulich und kostenlos</li>
<li>Unterstützung bei schulischen und persönlichen Anliegen</li>
<li>Begleitung bei Konflikten und Fragen zum Kinder- und Jugendschutz</li>
<li>Projekte zu Prävention, Sozialkompetenz und Klassengemeinschaft</li>
</ul>
<p><strong>Telefon Schulsozialarbeit:</strong> 0721 133-5755<br><strong>Sprechzeiten:</strong> Montag, Mittwoch, Donnerstag und Freitag, 9:0013:00 Uhr. Individuelle Termine sind möglich.</p>
`,
actions: [
{ label: "Schulsozialarbeit anrufen", href: "tel:+497211335755", primary: true },
{ label: "Infos der Stadt", href: "https://www.karlsruhe.de/schuso", external: true },
],
},
foerderverein: {
kicker: "Engagement",
title: "Gemeinsam mehr möglich machen",
html: `
<p>Der Förderverein unterstützt Lern- und Erfahrungsmöglichkeiten, die allen Kindern der Hardtschule zugutekommen.</p>
<ul>
<li>Theaterbesuche und außerschulische Lernorte</li>
<li>Pausenobst im Rahmen des EU-Schulprogramms</li>
<li>neue Bücher und Spiele für das Lesezimmer</li>
<li>Spiel- und Sportgeräte für die Pausen</li>
<li>Feste, Projekttage und gemeinschaftliche Erlebnisse</li>
</ul>
<p>Mitgliedschaft und Mithilfe stärken ein solidarisches Miteinander im Interesse aller Kinder.</p>
`,
actions: [{ label: "Mitgliedschaft anfragen", href: "mailto:schulleitung@hardtschule-karlsruhe.de?subject=Kontakt%20zum%20F%C3%B6rderverein", primary: true }],
},
};
function setMenu(open) {
if (!menuButton || !mobileNav) return;
menuButton.setAttribute("aria-expanded", String(open));
mobileNav.hidden = !open;
document.body.classList.toggle("menu-open", open);
}
menuButton?.addEventListener("click", () => {
setMenu(menuButton.getAttribute("aria-expanded") !== "true");
});
mobileNav?.querySelectorAll("a").forEach((link) => {
link.addEventListener("click", () => setMenu(false));
});
function renderActions(actions = []) {
dialogActions.innerHTML = "";
actions.forEach((action) => {
const element = document.createElement("a");
element.className = `button ${action.primary ? "button-dark" : "button-outline"}`;
element.textContent = action.label;
if (action.action) {
element.href = "#";
element.addEventListener("click", (event) => {
event.preventDefault();
openDetail(action.action);
});
} else {
element.href = action.href;
if (action.external) {
element.target = "_blank";
element.rel = "noreferrer";
}
if (action.href?.startsWith("#")) {
element.addEventListener("click", () => dialog.close());
}
}
const arrow = document.createElementNS("http://www.w3.org/2000/svg", "svg");
arrow.setAttribute("aria-hidden", "true");
const use = document.createElementNS("http://www.w3.org/2000/svg", "use");
use.setAttribute("href", "#icon-arrow");
arrow.append(use);
element.append(arrow);
dialogActions.append(element);
});
}
function openDetail(key) {
const content = detailContent[key];
if (!content || !dialog) return;
dialogKicker.textContent = content.kicker;
dialogTitle.textContent = content.title;
dialogContent.innerHTML = content.html;
renderActions(content.actions);
if (!dialog.open) dialog.showModal();
document.body.classList.add("dialog-open");
}
document.querySelectorAll("[data-detail]").forEach((trigger) => {
trigger.addEventListener("click", () => openDetail(trigger.dataset.detail));
});
dialogClose?.addEventListener("click", () => dialog.close());
dialog?.addEventListener("click", (event) => {
if (event.target === dialog) dialog.close();
});
dialog?.addEventListener("close", () => {
document.body.classList.remove("dialog-open");
});
document.querySelectorAll("[data-year]").forEach((element) => {
element.textContent = new Date().getFullYear();
});
const revealElements = document.querySelectorAll(".reveal");
const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
if (reduceMotion || !("IntersectionObserver" in window)) {
revealElements.forEach((element) => element.classList.add("is-visible"));
} else {
const revealObserver = new IntersectionObserver(
(entries, observer) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) return;
entry.target.classList.add("is-visible");
observer.unobserve(entry.target);
});
},
{ threshold: 0.12, rootMargin: "0px 0px -40px" },
);
revealElements.forEach((element) => revealObserver.observe(element));
}
const navLinks = [...document.querySelectorAll(".desktop-nav a")];
const sections = navLinks
.map((link) => document.querySelector(link.getAttribute("href")))
.filter(Boolean);
if ("IntersectionObserver" in window && navLinks.length) {
const sectionObserver = new IntersectionObserver(
(entries) => {
const visible = entries
.filter((entry) => entry.isIntersecting)
.sort((a, b) => b.intersectionRatio - a.intersectionRatio)[0];
if (!visible) return;
navLinks.forEach((link) => {
const active = link.getAttribute("href") === `#${visible.target.id}`;
if (active) link.setAttribute("aria-current", "true");
else link.removeAttribute("aria-current");
});
},
{ rootMargin: "-30% 0px -60%", threshold: [0, 0.1, 0.3] },
);
sections.forEach((section) => sectionObserver.observe(section));
}
+38
View File
@@ -0,0 +1,38 @@
import { createReadStream, existsSync, statSync } from "node:fs";
import { createServer } from "node:http";
import { extname, join, normalize } from "node:path";
const root = process.cwd();
const port = Number(process.env.PORT || 4173);
const mimeTypes = {
".css": "text/css; charset=utf-8",
".html": "text/html; charset=utf-8",
".js": "text/javascript; charset=utf-8",
".jpg": "image/jpeg",
".jpeg": "image/jpeg",
".png": "image/png",
".svg": "image/svg+xml",
};
createServer((request, response) => {
const pathname = decodeURIComponent(new URL(request.url, `http://${request.headers.host}`).pathname);
const requested = pathname === "/" ? "/index.html" : pathname;
const safePath = normalize(requested).replace(/^(\.\.(\/|\\|$))+/, "");
let filePath = join(root, safePath);
if (!filePath.startsWith(root) || !existsSync(filePath)) {
response.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
response.end("Nicht gefunden");
return;
}
if (statSync(filePath).isDirectory()) filePath = join(filePath, "index.html");
response.writeHead(200, {
"Content-Type": mimeTypes[extname(filePath).toLowerCase()] || "application/octet-stream",
"Cache-Control": "no-cache",
});
createReadStream(filePath).pipe(response);
}).listen(port, "127.0.0.1", () => {
console.log(`Hardtschule-Website: http://127.0.0.1:${port}`);
});
+2487
View File
File diff suppressed because it is too large Load Diff