branch-coexist: 3 neue decks 223015b-2026 / 223015c-2026 / dhbw-2026 daneben main

per user-request einen branch der main-content UND rewrite-content trägt — saubere separierung statt symlink/merge-conflict.

struktur:
- slides/<course>/ → main-content restored, eigene assets (kein new-demo-leak)
- slides/<course>-2026/ → rewrite-content, eigene assets (komplett kopiert + new demos)

Makefile: COURSES += 223015b-2026 223015c-2026 dhbw-2026 mit eigenen NAME/KAPITEL/DEPLOY/KLAUSUR-konfig. Klausur für b+c=1, dhbw=leer. Deploy-paths /hdm/223015b-2026 etc.

make build durchlaufen für alle 6 decks, 0 fehler.

dedup: 223015c+dhbw assets identisch in beiden ordnern (kein neu-demos auf b ergänzt). 223015b 86 → 120 files in -2026 (= +34 neue eroeffner/usb-c-drei-achsen/container-vs-codec/etc).
This commit is contained in:
libretech committed 2026-05-14 21:54:15 +02:00
1 parent 6209f9f3a0
commit 351e3dfc23
467 files changed
+32391 -4701

No files matched your search

+228
View File
@@ -0,0 +1,228 @@
---
marp: true
theme: gaia
paginate: true
backgroundColor: #fff
header: "Grundlagen IT- und Internettechnik (223015c)"
footer: "Michael Czechowski – HdM Stuttgart – SoSe 2026"
title: Grundlagen IT- und Internettechnik
---
<style>
:root {
--color-foreground: #1a1a2e;
--color-highlight: #d63384;
--color-dimmed: #4a4a6a;
}
section.invert {
--color-foreground: #fff;
}
section {
font-size: 1.7rem;
}
h1 {
color: #a02060;
}
section.invert h1 {
color: #fff;
}
h2 {
color: #1f2937;
}
pre {
background: #0f0f23;
color: #d63384;
border-radius: 8px;
border-left: 3px solid #d63384;
}
pre code {
background: transparent;
color: inherit;
}
code {
background: #1a1a2e;
color: #d63384;
padding: 0.15em 0.4em;
border-radius: 4px;
}
a {
color: var(--color-highlight);
}
section.klausur {
background: repeating-linear-gradient(
135deg,
#fce4ec,
#fce4ec 40px,
#fff 40px,
#fff 80px
) !important;
}
@media print {
section.klausur {
background: #fce4ec !important;
}
}
section.aufgabe {
background: #fce4ec !important;
}
section.aufgabe footer {
display: none;
}
</style>
<!-- _class: invert -->
<!-- _header: '' -->
<!-- _backgroundColor: #000 -->
![bg cover opacity:0.2](./assets/background-termin-1.png)
# Grundlagen IT- und Internettechnik
**223015c** · Modul "Technik 1" · 1. Semester
Digital- und Medienwirtschaft
Hochschule der Medien Stuttgart
**Sommersemester 2026**
[https://librete.ch/hdm/223015c/](https://librete.ch/hdm/223015c/)
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/qr/slides-223015c.png)
---
<!-- _class: lead -->
# Herzlich willkommen!
## Einführung
---
# Über mich
**Michael Werner Czechowski**
- Systems and Platform Engineer
- Schwerpunkte:
- Web-Technologien, Barriere-Armut, Open Source
- Hintergrund:
- Philosophie (Uni Stuttgart)
- Wirtschaftsinformatik (Leibniz-FH Hannover)
- Kontakt: lb-czechowski@hdm-stuttgart.de
---
# Warum dieses Modul?
**Das Internet ist überall** – aber was steckt dahinter?
* Warum sehen Webseiten auf dem Handy anders aus?
* Wie funktioniert eigentlich das Internet?
* Wie erkennen Sie, ob eine Werbeagentur gute Arbeit leistet?
* Was hat ein Unterseekabel mit meiner E-Mail zu tun?
* **→ Die Technik dahinter verstehen und fundierte Entscheidungen treffen**
---
# Das Ziel
**Technische Grundlagen verstehen**, um fundierte Entscheidungen treffen zu können.
Als Digital- und MedienwirtschaftlerInnen werdet ihr täglich mit technischen Fragen konfrontiert:
* Wie baue ich eine barrierearme Webseite?
* Welches Protokoll für welchen Zweck?
* Wie funktioniert das Web hinter den Kulissen?
* **→ Mitreden können – und selbst Webseiten bauen!**
---
# Was Sie hier lernen werden
**In dieser Veranstaltung erwerben Sie folgende Kompetenzen:**
* Geschichte des Computers und Internets
* HTML-Grundlagen und semantisches Markup
* CSS für Layout und Gestaltung
* Netzwerke und Protokolle (TCP/IP, DNS, HTTP(S))
* "Barrierefreiheit" im Web
* Grundlagen von JavaScript und Interaktivität
---
# Kurze Umfrage
**Bitte Hand heben:**
* Wer hat schon mal eine Webseite gebaut?
* Wer weiß, was HTML ist?
* Wer hat schon mal CSS geschrieben?
* Wer kennt den Unterschied zwischen Internet und WWW?
* Wer hat schon mal mit JavaScript gearbeitet?
---
# Kursübersicht
**Kapitel:**
1. Geschichte, Grundlagen & **HTML**
2. Netzwerke, Protokolle, **semantisches HTML** & **CSS**
3. Interaktivität, Animationen & **JavaScript**
**Ziel:** "Gelernte Hilflosigkeit" ablegen
---
<!-- _class: klausur -->
<!-- _header: '' -->
<!-- _footer: '' -->
<!-- _backgroundColor: #fce4ec -->
# Prüfungsleistung
**Nach aktuellem Kenntnisstand:**
* 90 min insg. (Technik 1)
* Schriftliche Klausur (digital)
* Teils offene Fragen
* So gut wie kein Coding/Programmieren
* **Prüfungsrelevant:** Folien sind markiert mit anderem Hintergrund
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/klausur-01.png)
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/klausur-02.png)
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/klausur-03.png)
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/splan.png)
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/asta.png)
@@ -0,0 +1,786 @@
---
marp: true
theme: gaia
paginate: true
backgroundColor: #fff
header: "Grundlagen IT- und Internettechnik (223015c)"
footer: "Michael Czechowski – HdM Stuttgart – SoSe 2026"
title: "Kapitel 1: Geschichte, Grundlagen & HTML"
---
<style>
:root {
--color-foreground: #1a1a2e;
--color-highlight: #d63384;
--color-dimmed: #4a4a6a;
}
section.invert { --color-foreground: #fff; }
section { font-size: 1.7rem; }
h1 { color: #a02060; }
section.invert h1 { color: #fff; }
h2 { color: #1f2937; }
pre {
background: #0f0f23;
color: #d63384;
border-radius: 8px;
border-left: 3px solid #d63384;
}
pre code { background: transparent; color: inherit; }
code {
background: #0f0f23;
padding: 0.15em 0.4em;
border-radius: 4px;
font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}
section code:not(.hljs) { color: #d63384 !important; }
section code.hljs { color: #f8f8f8 !important; }
a { color: var(--color-highlight); }
section.klausur {
background: repeating-linear-gradient(
135deg,
#fce4ec,
#fce4ec 40px,
#fff 40px,
#fff 80px
) !important;
}
@media print {
section.klausur { background: #fce4ec !important; }
}
section.aufgabe { background: #fce4ec !important; }
section.aufgabe footer { display: none; }
section.erklaerung { font-size: 1.1rem; }
section.erklaerung h1 { font-size: 1.5rem; color: #a02060; margin-bottom: 0.3rem; }
section.erklaerung ul, section.erklaerung ol { font-size: 1.0rem; line-height: 1.4; }
section.erklaerung p { font-size: 1.0rem; line-height: 1.4; }
section.erklaerung table { font-size: 0.9rem; }
</style>
<!-- _class: invert -->
<!-- _header: '' -->
<!-- _footer: '' -->
<!-- _backgroundColor: black -->
![bg fit opacity:0.2](./assets/background-termin-2.png)
# Kapitel 1
## Geschichte, Grundlagen & HTML
223015c · Grundlagen IT- und Internettechnik
HdM Stuttgart · SoSe 2026
[https://librete.ch/hdm/223015c/](https://librete.ch/hdm/223015c/)
---
<!-- _class: lead -->
# „Du tippst `librete.ch` ein. Was alles dahinter steht."
<!--
Eröffner-Hook. Studis kennen das Tippen einer URL aus dem Alltag.
Aber: was passiert wirklich? Ein ganzer Stapel von Schichten:
1. Browser parst die URL
2. DNS findet die IP-Adresse zu librete.ch
3. TCP-Handshake mit dem Server in Frankfurt
4. TLS-Handshake für https
5. HTTP-Request wird gesendet
6. Server antwortet mit HTML
7. Browser parst HTML + CSS + JS und rendert Pixel
Dieser ganze Stack ist 70 Jahre Computing-Geschichte. Wir packen ihn in diesem Kapitel an einem Ende an — bei den Pionieren des Rechnens — und enden beim HTML-Tag, das auf eurem Bildschirm landet.
In Kap 2 wird der Netzwerk-Teil aufgepackt (TCP/IP, DNS, HTTP), in Kap 3 das Interaktive (JavaScript).
-->
---
<!-- _class: lead -->
# Die Pioniere des Computings
<!--
Wir starten bei den Personen, die die Grundlagen geschaffen haben — von der ersten Programmidee bis zur Architektur, die wir heute noch nutzen.
6 Personen, eine pro Folie. Keine Galerie-Inflation.
-->
---
![bg right:35%](./assets/ada-lovelace.jpg)
# Ada Lovelace (1815–1852)
**Erster Algorithmus in der Geschichte.**
Babbage entwarf 1830er die *Analytical Engine* — eine programmierbare Rechenmaschine. Ada Lovelace beschrieb 1843, wie man Bernoulli-Zahlen damit berechnen könnte.
→ **Ihre Notes sind der erste publizierte Algorithmus, der für eine Maschine geschrieben wurde.**
<!--
Ada Lovelace war Mathematikerin und Tochter von Lord Byron. Sie übersetzte einen italienischen Aufsatz über die Analytical Engine — und fügte „Notes" hinzu, die länger waren als das Original.
In Note G beschrieb sie eine Schritt-für-Schritt-Anleitung, wie die Maschine eine mathematische Sequenz berechnen würde. Das gilt heute als erster Algorithmus.
Sie war auch die Erste, die erkannte: die Analytical Engine könnte mehr als nur Zahlen. Man könnte Musik, Texte, jede Form von Logik darüber abbilden. Eine erstaunliche Voraussicht — fast 100 Jahre vor Turing.
Die Programmiersprache „Ada" (1980, vom US-Verteidigungsministerium) wurde nach ihr benannt.
-->
---
![bg right:35%](./assets/herman-hollerith.jpg)
# Herman Hollerith (1860–1929)
**Lochkarte als Datenträger.**
1890er: US-Volkszählung. Hollerith entwickelt eine Maschine, die Daten auf Lochkarten speichert und liest. **8 Jahre Auswertung → 1 Jahr.**
→ Seine Firma wird 1911 zu **CTR**, 1924 zu **IBM**.
<!--
Vor Hollerith dauerte die US-Volkszählung 8 Jahre — bis zur nächsten. Hollerith's Maschine brachte das auf 1 Jahr.
Lochkarten waren bis in die 1980er der Standard-Datenträger. Programme wurden auf Lochkarten gestanzt und in Stapeln zum Rechenzentrum gebracht. „Batch processing".
IBM (1924 unter Thomas J. Watson Sr.) wurde aus Hollerith's Firma. Watson prägte den Slogan "THINK", der noch heute zu IBM-Logos gehört.
Schatten: IBM lieferte in den 1930er Jahren Tabelliermaschinen auch ins NS-Deutschland, wo sie für die Volkszählungen und später für die Lager-Buchhaltung eingesetzt wurden. Edwin Black hat das 2001 in „IBM and the Holocaust" dokumentiert. Wichtig: das ist Teil der IT-Geschichte, nicht ein Anhang.
-->
---
![bg right:33% contain](./assets/alan-turing.jpg)
# Alan Turing (1912–1954)
**Theoretisches Fundament moderner Computer.**
* **1936** — Turing-Maschine
* **1940er** — Bletchley Park, Enigma-Bruch (geheim bis 1974)
* **1950** — Turing-Test
<!--
Alan Turing ist der Vater der theoretischen Informatik.
Die Turing-Maschine ist ein mathematisches Modell:
- Ein unendliches Band als Speicher
- Ein Lese-/Schreibkopf
- Ein Regelsatz für Zustandsübergänge
Damit beweist Turing 1936, dass es prinzipiell unentscheidbare Probleme gibt (Halteproblem). Und dass es eine „universelle" Maschine geben kann, die jede andere Maschine simulieren kann.
In Bletchley Park wendet er das Konzept praktisch an: gemeinsam mit anderen baut er die „Bombe", eine elektromechanische Maschine, die Enigma-Schlüssel durchprobiert. Geheim bis 1974 — Großbritannien verriet jahrzehntelang nicht, dass sie deutsche Funksprüche entschlüsseln konnten.
Tragisches Ende: Turing wurde 1952 wegen Homosexualität verurteilt und chemisch kastriert. 1954 Selbstmord. 2009 erst offizielle Entschuldigung der britischen Regierung.
Heute trägt der ACM Turing Award (der „Informatik-Nobelpreis") seinen Namen.
-->
---
![bg right:35%](./assets/von-neumann.jpg)
# John von Neumann (1903–1957)
**Die Architektur, die wir heute noch nutzen.**
1945: das **EDVAC-Papier** — Daten und Programm im selben Speicher.
Vorher: ENIAC musste für jedes neue Programm **physisch umgekabelt** werden. 6.000 Schalter, oft Wochen.
Nachher: einfach den Speicher überschreiben.
<!--
John von Neumann war einer der bedeutendsten Universalwissenschaftler des 20. Jahrhunderts — Mathematik, Physik, Wirtschaft, Spieltheorie, Computing.
Sein „First Draft of a Report on the EDVAC" (1945) wurde unautorisiert von Herman Goldstine verteilt. Da der Bericht nur von Neumann's Namen trug, wurde die darin beschriebene Architektur als „Von-Neumann-Architektur" bekannt — obwohl maßgebliche Vorarbeit von Eckert und Mauchly stammte. Bis heute kontrovers.
Die zentrale Innovation: „stored-program" — Daten und Code im gleichen Speicher, addressierbar wie Daten. Damit können Programme als Daten manipuliert werden (Compiler, Debugger, JIT) — heute selbstverständlich, damals revolutionär.
Auch beteiligt: Manhattan-Projekt (Implosions-Linsen für die Atombombe). Zwiespältig.
-->
---
# Von-Neumann-Architektur · 5 Komponenten
| # | Komponente | Aufgabe |
|---|------------|---------|
| 1 | **Steuerwerk** (Control Unit) | holt Befehl, entscheidet was zu tun ist |
| 2 | **Rechenwerk** (ALU) | führt Rechnung / Vergleich aus |
| 3 | **Speicher** (Memory) | hält Daten *und* Programm |
| 4 | **Eingabe / Ausgabe** (I/O) | Tastatur, Bildschirm, Netzwerk |
| 5 | **Bus** (Verbindung) | transportiert Daten zwischen allen |
**Schlüssel:** Speicher hält *beides* — Daten + Programm. (Stored Program.)
<!--
Klausurfähig: die 5 Komponenten und ihre Aufgaben benennen.
Wo seht ihr das in eurem eigenen Gerät?
- Steuerwerk + Rechenwerk = CPU
- Speicher = RAM (flüchtig) + SSD (persistent)
- I/O = USB-Ports, Display, Audio
- Bus = im Chip (Intern), zwischen Chips (PCIe, USB)
Die Architektur ist seit 1945 stabil. Quantencomputer brechen sie auf (kein klassisches stored program). Aber jeder PC, Mac, Smartphone, jeder Server, jede Spielkonsole folgt ihr noch immer.
-->
---
# Hopper, Booth, Hamilton
**Grace Hopper** (1906–1992): erster *Compiler* (1952). „Submarine of code." US Navy Admiral.
**Kathleen Booth** (1922–2022): erste **Assembly Language** (1947). Notation für Maschinen-Befehle.
**Margaret Hamilton** (*1936): leitete die Software für **Apollo 11**. Prägte den Begriff „Software Engineering".
<!--
Drei Personen, die wichtige Schichten oberhalb der Hardware geschaffen haben:
Grace Hopper:
- Arbeitete an Mark I (Harvard)
- Erfand den ersten Compiler (A-0, 1952) — Mensch-lesbare Sprache → Maschinen-Code
- Hat den Begriff „Bug" populär gemacht (echter Motte im Mark II 1947 gefunden, ins Logbuch geklebt)
- Wurde später US Navy Rear Admiral
Kathleen Booth:
- Erste praktische Assembly Language für die ARC (All-purpose Electronic Computer) am Birkbeck College London
- Vor ihr musste man Befehle in Binär eintippen
- Ihre Notation (z.B. ADD R1, R2) ist im Prinzip noch heute in jeder Assembly-Sprache
Margaret Hamilton:
- Leitete die On-board Software für Apollo 11 (1969, Mondlandung)
- Berühmt: 5 Minuten vor Mondlandung gibt es Alarm 1202 + 1201 — ihre Software hat Prioritäten richtig gesetzt und die wichtige Aufgabe fortgesetzt
- Sie und ihr Team prägten den Begriff „Software Engineering" 1968 — vorher gab es das als Disziplin nicht
Lektionen für heute: Programmierung ist nicht Hardware. Es ist eine eigenständige Disziplin mit ingenieurmäßiger Strenge. Hamilton's Berkeley-Adoptierung des Begriffs „Engineering" war damals nicht selbstverständlich.
-->
---
<!-- _class: lead -->
# Vom Militär zum Netz
<!--
Pivot. Wir verlassen die einzelne Maschine und schauen, wie viele Maschinen miteinander verbunden wurden.
Das Internet entsteht im Kalten Krieg als militärisches Forschungsprojekt — und wird zum globalen Netz.
-->
---
# Kalter Krieg: das Problem der Kommunikation
**Atomare Bedrohung** in den 1960ern.
Klassisches Telefonnetz ist **zentral** — ein Knoten down, ganzer Bezirk down.
**Paul Baran** (RAND, 1962): wenn das Netz **dezentral** ist und Daten in kleinen Paketen reisen, überlebt es einzelne Ausfälle.
→ **Packet Switching** statt **Circuit Switching.**
<!--
Hintergrund: USA und UdSSR im Kalten Krieg. Telefon-Netz war zentral organisiert — ein paar Backbone-Stationen, wenn die ausfielen war alles tot.
Paul Baran beim RAND-Think-Tank schlug 1962 vor: zerteilt Nachrichten in kleine Pakete, jedes Paket findet eigenständig seinen Weg durch ein Mesh-Netzwerk. Wenn ein Knoten ausfällt, finden Pakete einen anderen Pfad.
Das ist die Geburt von „packet switching" — heute Grundlage des gesamten Internets.
ARPANET (1969) ist die erste praktische Umsetzung. 4 Knoten anfangs: UCLA, Stanford, UCSB, Utah. Erste Nachricht: „LOGIN" — Maschine crasht nach „LO".
-->
---
# Internet-Timeline · 4 Milestones
| Jahr | Was | Was hat es verändert |
|------|-----|----------------------|
| **1969** | ARPANET | Erstes paket-vermitteltes Netzwerk, 4 Knoten |
| **1971** | Email (Ray Tomlinson) | Erste Nutzung des `@`-Zeichens |
| **1983** | TCP/IP | Wurde Standard-Protokoll des ARPANET |
| **1989** | **WWW** (Berners-Lee, CERN) | HTML, HTTP, URL — das Web wie wir es kennen |
1993: Mosaic-Browser → Internet wird *populär*.
<!--
Klausurfähig: die 4 Meilensteine und ihre Bedeutung.
Anmerkungen:
- 1969 ARPANET: noch militärisch + Forschung. Wenige Knoten.
- 1971 Email: Ray Tomlinson schickt die erste E-Mail mit @-Zeichen, das er gewählt hat um „User AT Maschine" zu trennen. Heute auf jedem Tastatur als Standard.
- 1983 TCP/IP: Vint Cerf + Bob Kahn. ARPANET wechselt am 1. Jan 1983 von NCP zu TCP/IP. Das ist die „Geburt des modernen Internets" im technischen Sinne.
- 1989 WWW: Tim Berners-Lee am CERN. Er erfindet HTTP (Protokoll), HTML (Markup) und URL (Adress-System) — drei Standards, eine Person.
- 1993 Mosaic: erste GUI-Browser, der Bilder im Text-Fluss anzeigen konnte. Damit explodierte die Web-Nutzung.
Internet ist nicht Web — Internet ist das Netzwerk, Web ist eine Anwendung darauf. Aber im Volksmund verwechselt.
-->
---
![bg right:45% contain](./assets/tim-berners-lee.jpg)
# Tim Berners-Lee + das WWW (1989)
**CERN, Genf.** Berners-Lee schlägt ein „Hypertext-System" für die interne Wissenschaftler-Kommunikation vor.
Sein Memo „Information Management: A Proposal" wird abgelehnt. Er baut es trotzdem.
**Drei Standards:**
- **HTTP** (Protokoll)
- **HTML** (Format)
- **URL** (Adresse)
1991: erste Website (`info.cern.ch`). Bis heute online.
<!--
Berners-Lee arbeitete am CERN als Informatiker, hatte aber Frustration mit der Fragmentierung der internen Dokumentation. Sein System sollte alle Dokumente verbindbar machen.
Sein erstes Memo wurde mit „vague but exciting" beantwortet. Er bekam keine offizielle Finanzierung, baute den ersten Webserver + Webbrowser dennoch.
Diese drei Standards sind bis heute das Web:
- HTTP: wie geht eine Anfrage über das Netz
- HTML: wie sieht ein Dokument aus
- URL: wo finde ich ein Dokument
Berners-Lee gab das alles **patentfrei** frei. Hätte er die Standards verkauft, wäre das Web vermutlich nie groß geworden — andere Standards (Microsoft Blackbird, AOL-Pages, Apple eWorld) sind alle gescheitert.
2004 wurde er von Queen Elizabeth zum Sir geadelt. 2016 ACM Turing Award.
-->
---
# 1,3 Mio km Unterseekabel
![bg right:45% contain](./assets/unterseekabel-karte.jpg)
Das Internet ist **physisch.**
400+ Unterseekabel transportieren ~99% des interkontinentalen Datenverkehrs.
**DE-CIX Frankfurt:** einer der größten Internet-Knoten der Welt. >12 Tbit/s im Peak.
→ Auch eure WhatsApp-Nachricht nach New York fließt durch ein Glasfaserkabel im Atlantik.
<!--
Internet ist nicht „die Cloud" — die Cloud ist Hardware in Rechenzentren, die mit Glasfaser-Kabeln verbunden sind.
Unterseekabel:
- ~400 aktive Kabel weltweit, ~1,3 Mio km Länge gesamt
- Werden von Spezialschiffen verlegt
- Lebensdauer ~25 Jahre
- Glasfaser-Stränge mit Verstärkern alle ~50–100 km
- Ein einziges Kabel kann 100+ Tbit/s übertragen
Großbritannien-USA: TAT-1 (1956), erst Telefon. Heute: MAREA (2018), Marea, Dunant — alle mehrere Tbit/s.
DE-CIX Frankfurt:
- Internet Exchange Point (IXP) — Punkt, wo viele ISPs sich treffen und Daten austauschen
- Größter IXP der Welt nach Datenverkehr
- ~1.000 Mitglieder (ISPs, Content-Provider)
- ~12 Tbit/s im Peak
Frankfurt hat sich aus historischen Gründen entwickelt (Banken brauchten gute Netzwerk-Anbindung). Heute strategisch wichtig — wer Frankfurt kontrolliert, kontrolliert einen Großteil des europäischen Traffic.
-->
---
<!-- _class: lead -->
# Vom Internet zum Browser-Render
<!--
Pivot. Wir haben gesehen, wie Daten durch das Netzwerk reisen.
Jetzt: was bekommt der Browser eigentlich vom Server? Antwort: HTML.
Dann: wie ist HTML aufgebaut, was sind die wichtigsten Tags, wie schreibe ich eine gültige Webseite?
-->
---
# Was bekommt der Browser?
Wenn ihr `librete.ch` eintippt, schickt der Server:
```html
<!DOCTYPE html>
<html lang="de">
<head>
<title>Librete</title>
</head>
<body>
<h1>Willkommen</h1>
<p>Dies ist HTML.</p>
</body>
</html>
```
Der Browser **parsed** das, rendert es als Pixel, und ihr seht eine Seite.
<!--
HTML = Hypertext Markup Language. „Hypertext" weil Tags Links zu anderen Dokumenten erlauben.
Das Beispiel zeigt:
- DOCTYPE-Deklaration (sagt dem Browser: das ist HTML5)
- html-Element als Wurzel
- head: Meta-Informationen (Titel, Encoding, CSS-Links)
- body: das, was angezeigt wird
- Heading-Tag h1
- Paragraph-Tag p
Nichts Magisches dran. Plain-Text mit Tags drum. Studis könnten das in Notepad oder TextEdit schreiben und sofort im Browser öffnen.
-->
---
# HTML-Anatomie
```html
<a href="https://librete.ch">Mein Link</a>
```
| Bestandteil | Was |
|-------------|-----|
| `<a` | **Opening-Tag** mit Tag-Namen |
| `href="https://..."` | **Attribut** (Name + Wert) |
| `>` | Ende des Opening-Tags |
| `Mein Link` | **Inhalt** des Elements |
| `</a>` | **Closing-Tag** |
Alles zusammen = ein **Element.**
<!--
Klausurfähig. Studis sollen die Bestandteile eines HTML-Elements unterscheiden können:
- Opening-Tag
- Closing-Tag
- Attribute (Name=Wert)
- Inhalt
- Element = alles zusammen
Achtung: einige Tags sind „self-closing" und haben keinen Closing-Tag:
- `<img src="..." alt="...">`
- `<br>`
- `<input>`
- `<meta>`
Diese werden auf der nächsten Folie behandelt.
-->
---
# Wichtige Attribute
| Attribut | Wo | Bedeutung |
|----------|----|-----------|
| `id` | jedes Element | eindeutige ID auf der Seite |
| `class` | jedes Element | für CSS (mehrere möglich) |
| `href` | `<a>`, `<link>` | Ziel-URL |
| `src` | `<img>`, `<script>` | Quell-URL |
| `alt` | `<img>` | **Alt-Text für A11y!** |
| `title` | jedes Element | Tooltip beim Hover |
| `lang` | meist `<html>` | Sprache des Inhalts |
<!--
Diese Attribute begegnen Studis täglich — wenn auch unbemerkt.
`alt`-Text auf Bildern ist a11y-Pflicht. Wer das vergisst, macht die Seite für Blinde unlesbar. Screen-Reader liest stattdessen `alt`-Wert vor.
`class` vs `id`:
- id: einmal auf der Seite (Anker, JS-Hook)
- class: beliebig oft (Style-Gruppen)
`lang="de"` auf html-Element sagt Screen-Readers, in welcher Sprache der Inhalt ist — wichtig für korrekte Aussprache.
-->
---
# Self-closing Tags
```html
<img src="foto.jpg" alt="Sonnenuntergang">
<br>
<input type="text" name="username">
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
```
Diese Tags haben **kein Closing**. Sie sind „leer" — der Browser-Render erzeugt das Pixel-Resultat allein aus dem Opening-Tag.
<!--
Self-closing Tags:
- img: Bild einfügen
- br: Zeilenumbruch
- hr: horizontale Linie
- input: Eingabefeld
- meta: Metadaten im head
- link: Verbindung zu CSS/Favicon
Streng XML-konform würde man `<br />` schreiben (mit / vor >). HTML5 erlaubt beides. Modern üblich: ohne /.
Wichtig: vergesst nicht den `alt`-Text für `<img>` — A11y.
-->
---
# Document-Struktur: das Grundgerüst
```html
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Meine Seite</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Hallo Welt</h1>
<!-- alle sichtbaren Inhalte -->
</body>
</html>
```
<!--
Klausurfähig: die DOCTYPE + head + body-Struktur reproduzieren können.
Was passiert wo?
- DOCTYPE: sagt dem Browser „das ist HTML5". Ohne DOCTYPE: Quirks-Mode (alte Browser-Verhaltensweisen).
- html-Element + lang: Wurzel-Element + Sprache
- head: alles, was *nicht* sichtbar ist (Meta, Title, CSS-Links, Scripts)
- meta charset: sagt Browser, wie die Byte zu interpretieren sind (UTF-8 = international, alle Sprachen)
- meta viewport: für Mobile-Rendering, ohne zoomt iPhone alles auf 980px
- title: Browser-Tab-Titel + Lesezeichen-Name
- link stylesheet: CSS einbinden
- body: alle sichtbaren Inhalte
-->
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/demos/grundgeruest.png)
<!--
Visualisierung des Grundgerüsts.
Pädagogisches Ziel: Studis sollen das Muster „<head> = unsichtbares Meta, <body> = sichtbares Drinnen" verinnerlichen.
Faustregel: alles, was den Inhalt der Seite betrifft → body. Alles, was die Seite *beschreibt* → head.
-->
---
# Semantische HTML-Tags
| Tag | Bedeutung | Beispiel |
|-----|-----------|----------|
| `<header>` | Kopfbereich (Logo, Nav) | oben auf der Seite |
| `<nav>` | Navigations-Menü | Hauptmenü |
| `<main>` | Hauptinhalt | das eigentliche Thema |
| `<section>` | Thematischer Abschnitt | Kapitel der Seite |
| `<article>` | eigenständiger Inhalt | Blog-Post, News-Beitrag |
| `<aside>` | Seiten-Inhalt | Sidebar, Werbung |
| `<footer>` | Fußbereich | Impressum, Copyright |
**Vorteil:** Screen-Reader, Suchmaschinen + andere Entwickler verstehen die Struktur.
<!--
Klausurfähig: die 7 semantischen Tags und ihre Bedeutung.
Vor HTML5 (2008) gab es nur `<div>`. Man hat alles in div verpackt und mit Klassen markiert: `<div class="header">`. Funktioniert visuell — aber Maschinen (Screen-Reader, Suchmaschinen) verstehen nichts.
Mit semantischen Tags:
- Screen-Reader kann „Hauptnavigation überspringen" anbieten
- Google versteht, was Haupt-Inhalt der Seite ist (SEO-Boost)
- Andere Entwickler lesen den Code schneller
Faustregel: wenn ein Tag den *Zweck* eines Bereichs ausdrückt — semantisch. Wenn nur Styling — div.
Drei A11y-relevante Anti-Patterns:
- `<div onclick="...">` statt `<button>` (Tastatur nicht erreichbar)
- `<a href="javascript:void(0)">` statt `<button>` (semantisch falsch)
- alles in `<div>` (keine Hierarchie für Screen-Reader)
-->
---
# Häufige inline-Tags
| Tag | Was |
|-----|-----|
| `<a>` | Hyperlink |
| `<strong>` | wichtig (fett dargestellt) |
| `<em>` | hervorgehoben (kursiv) |
| `<span>` | semantisch neutrale Inline-Container |
| `<code>` | Inline-Code |
| `<br>` | Zeilenumbruch |
| `<img>` | Bild |
**vs Block-Tags:** `<h1>`–`<h6>`, `<p>`, `<div>`, `<ul>`/`<ol>`/`<li>`, `<table>`, alle semantischen.
<!--
Block-Tags brechen automatisch eine neue Zeile, Inline-Tags nicht.
Wichtig pädagogisch:
- `<strong>` ist semantisch (wichtig), nicht stilistisch (fett). Wenn ihr nur fett wollt → CSS, nicht `<b>`.
- `<em>` (emphasized) vs `<i>` (italic) — gleiche Unterscheidung
- `<span>` ist der „div" für Inline — semantisch neutral, nur zum Markieren
Browser stylen die Tags per Default:
- strong → fett
- em → kursiv
- h1 → groß+fett
- p → Absatz mit Margin
Aber das kann mit CSS überschrieben werden. Daher: Tags semantisch wählen, dann mit CSS gestalten.
-->
---
# Listen, Bilder, Links
```html
<!-- Unsortierte Liste -->
<ul>
<li>Erstes Item</li>
<li>Zweites Item</li>
</ul>
<!-- Bild mit Alt-Text -->
<img src="./foto.jpg" alt="Sonnenuntergang über Stuttgart">
<!-- Link -->
<a href="https://hdm-stuttgart.de" target="_blank" rel="noopener">
HdM Stuttgart
</a>
```
<!--
Drei sehr häufige Patterns:
Listen:
- `<ul>` unsortiert (Bullet Points)
- `<ol>` sortiert (Nummern)
- `<li>` für jedes Item
Bilder:
- src: Pfad zum Bild
- alt: Alt-Text — Pflicht für A11y
- Bild-Pfad relativ oder absolut
Links:
- href: Ziel-URL
- target="_blank": neuer Tab (sparsam einsetzen)
- rel="noopener": Sicherheits-Best-Practice für target="_blank"
-->
---
# Formulare: Inputs + Labels
```html
<form>
<label for="name">Name:</label>
<input type="text" id="name" name="name" required>
<label for="email">E-Mail:</label>
<input type="email" id="email" name="email">
<button type="submit">Absenden</button>
</form>
```
**Immer:** `<label>` mit `for` → `<input>` mit gleichem `id`. **Pflicht für A11y.**
<!--
Formulare sind kritisch für A11y. Screen-Reader liest den Label-Text vor dem Input vor, damit der Nutzer weiß, was eingegeben werden soll.
Verbindung Label-Input:
- `<label for="name">` muss zum `<input id="name">` passen
- Alternative: Input INSIDE Label
- Ohne Label: nur Placeholder-Text → A11y-Mangel
Input-Types (HTML5):
- text, email, tel, url, password, number, date, time, color, range, search
Browser validiert automatisch (z.B. type="email" zeigt Fehler wenn kein @ drin).
-->
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/demos/dom-tree.png)
<!--
Das Dokument-Objekt-Modell (DOM): HTML im Speicher des Browsers als Baum.
Jeder Tag wird zu einem Element-Node. Der Browser baut diesen Baum beim Parsing auf.
JavaScript (Kap 3) kann diesen Baum manipulieren — Elemente erzeugen, ändern, entfernen.
Vorgriff: `document.querySelector('h1').textContent = 'Neuer Text'` ändert den Inhalt eines H1.
-->
---
<!-- _class: aufgabe -->
# Selbstlernen — Inspector live
1. Öffnet eure **Lieblings-Webseite**
2. **Rechtsklick → Untersuchen** (oder F12)
3. Tab **Elements / Inspector** öffnen
4. **HTML-Baum** durchklicken
5. Findet: das `<header>`, das `<main>`, mindestens ein `<a href="...">`
**Bonus:** Element auswählen → in der Console: `$0.style.background = 'pink'`. *Was passiert?*
<!--
Aufgabe ist niederschwellig und zugleich erkenntnisreich.
Ziel: Studis erleben, dass jede Webseite aus HTML-Tags besteht. Es ist nichts Magisches dahinter.
DevTools-Tipps für die Vorlesung:
- F12 öffnet DevTools in den meisten Browsern
- Elements-Tab zeigt den live DOM
- $0 ist eine Referenz zum aktuell selektierten Element (für Console-Experimente)
- Style-Edit live im Inspector — schöne erste Erfahrung mit „selber CSS schreiben"
-->
---
# Zusammenfassung
**Pioniere:** Lovelace (erster Algorithmus), Hollerith (Lochkarte), Turing (Theorie), von Neumann (Architektur), Hopper/Booth/Hamilton (Sprache + SoftwareEng).
**Internet:** ARPANET 1969 → TCP/IP 1983 → WWW 1989. Heute physisch über 1,3 Mio km Unterseekabel.
**HTML:** Tag-Struktur (`<tag attr>Inhalt</tag>`). Document-Grundgerüst (DOCTYPE + head + body). Semantische Tags (`header`, `nav`, `main`, …) als A11y-Foundation.
→ **In Kap 2:** wie reisen die Bytes durchs Netz — und wie wird HTML mit CSS hübsch + barrierefrei?
<!--
Recap.
Zwei Strangs in diesem Kapitel:
1. Wie wurde Computing erfunden? (Pioniere → Von-Neumann-Architektur)
2. Wie wurde es vernetzt? (ARPANET → WWW)
Beides mündet in das, was Studis tagtäglich sehen: HTML in einem Browser.
Anschluss zu Kap 2:
- Netzwerk-Tiefe: TCP/IP-Schichten, IP/MAC/Port, DNS, HTTP, der ganze „URL bis Pixel"-Ablauf
- Visuelle Tiefe: CSS, Box-Model, Flexbox, Grid
- A11y-Tiefe: BFSG, WCAG POUR, semantisches HTML + ARIA
In Kap 3 dann das Dynamische: JavaScript, DOM-Manipulation, Events.
-->
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,901 @@
---
marp: true
theme: gaia
paginate: true
backgroundColor: #fff
header: "Grundlagen IT- und Internettechnik (223015c)"
footer: "Michael Czechowski – HdM Stuttgart – SoSe 2026"
title: "Kapitel 3: Interaktivität & JavaScript"
---
<style>
:root {
--color-foreground: #1a1a2e;
--color-highlight: #d63384;
--color-dimmed: #4a4a6a;
}
section.invert { --color-foreground: #fff; }
section { font-size: 1.7rem; }
h1 { color: #a02060; }
section.invert h1 { color: #fff; }
h2 { color: #1f2937; }
pre {
background: #0f0f23;
color: #d63384;
border-radius: 8px;
border-left: 3px solid #d63384;
}
pre code { background: transparent; color: inherit; }
code {
background: #0f0f23;
padding: 0.15em 0.4em;
border-radius: 4px;
font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}
section code:not(.hljs) { color: #d63384 !important; }
section code.hljs { color: #f8f8f8 !important; }
a { color: var(--color-highlight); }
section.aufgabe { background: #fce4ec !important; }
section.aufgabe footer { display: none; }
section.erklaerung { font-size: 1.1rem; }
section.erklaerung h1 { font-size: 1.5rem; color: #a02060; margin-bottom: 0.3rem; }
</style>
<!-- _class: lead -->
# Kapitel 3
## Interaktivität & JavaScript
<!--
Eine Stunde, eine Frage: *Was passiert, wenn HTML + CSS da sind und nichts reagiert?*
JavaScript (JS) macht Webseiten interaktiv:
- DOM manipulieren (Elemente ändern, hinzufügen, entfernen)
- Auf Events reagieren (Klick, Tastendruck, Scroll)
- Daten holen (fetch) + speichern (localStorage)
- Animationen, dynamische UI, SPA-Frameworks
Per Klausur-Themen-Vorschlag: JavaScript ist nicht klausurrelevant. Lernziele auf Verstehen-Niveau (Code-Lesen, nicht Code-Schreiben).
-->
---
<!-- _class: lead -->
# „Statisch ist langweilig"
<!--
Hook: eine reine HTML+CSS-Seite reagiert auf nichts. Klick auf Button → nichts passiert (außer Form-Submit).
JS bringt das Reagieren rein. Daher der Name „Interaktivität".
Beispiele aus dem Alltag:
- Dropdown-Menü, das aufklappt
- Dark-Mode-Toggle
- „Mehr laden"-Button ohne Page-Reload
- Live-Validierung in Formularen
- Maps, die zoomen
- Spotify-Player, der weitermacht beim Wechseln der Seite
-->
---
# Was kann JavaScript?
| Kann | Beispiel |
|------|----------|
| DOM ändern | Element-Text, -Klasse, -Inhalt manipulieren |
| Events behandeln | Klick, Tastendruck, Scroll, Submit |
| Daten holen | `fetch()` API-Anfragen |
| Daten lokal speichern | `localStorage`, `sessionStorage` |
| Animationen | `requestAnimationFrame`, CSS-Animationen triggern |
| Web-APIs nutzen | Geolocation, Camera, Audio, Notification |
**Aus Sicherheitsgründen NICHT:** willkürlich Dateien auf der Platte lesen/schreiben.
<!--
JavaScript läuft im Browser-Sandkasten. Es darf:
- alles am DOM ändern
- Daten an Server schicken (mit CORS-Beschränkungen)
- LocalStorage für ~5-10 MB nutzen
- Mit User-Erlaubnis: GPS, Kamera, Mikrofon, Push-Notifications
JS darf NICHT (ohne User-Aktion):
- Beliebige Dateien lesen oder schreiben (FileSystem-Access nur mit User-Picker)
- Auf andere Tabs / Fenster zugreifen (Same-Origin-Policy)
- Direkt zu beliebigen Servern verbinden (CORS-Schutz)
Außerhalb des Browsers: Node.js erlaubt JS, alles zu tun was eine Programmiersprache normal kann (Files, Netzwerk, Kindprozesse). Davon später (in DHBW-Modul).
-->
---
# JavaScript-Timeline
| Jahr | Was |
|------|-----|
| **1995** | Brendan Eich entwickelt JS in 10 Tagen für Netscape |
| 1997 | ECMAScript-1 standardisiert (offizieller Name) |
| 2009 | **Node.js** — JS auch außerhalb des Browsers |
| **2015** | ES6 (große Erneuerung: `let`, `const`, arrow functions, classes, modules) |
| 2017+ | jährliche Updates (ES2017, ES2018, …) |
| heute | TypeScript als statisch-getypter Aufsatz |
JS ist die **am weitesten verbreitete** Programmiersprache der Welt.
<!--
Brendan Eich bekam 10 Tage um JavaScript zu entwickeln — daher viele frühe Quirks (`null` ist ein object, `0 == "0"` ist true). Diese Quirks bleiben aus Kompatibilitätsgründen.
Node.js (2009) hat alles verändert: JS ist nicht mehr nur Browser-Spielzeug, sondern serverseitig nutzbar. Heute laufen viele große Websites auf Node-Backend (Netflix, LinkedIn, Walmart).
ES6 (2015) brachte JS auf moderne Sprachen-Niveau:
- `let` und `const` statt `var`
- Arrow functions: `(x) => x * 2`
- Classes (Syntax-Sugar für Prototyp-Vererbung)
- Modules: import/export
Seitdem: jährliche Updates mit kleineren Features.
-->
---
# JavaScript einbinden
```html
<!-- External (best practice) -->
<script src="./app.js"></script>
<!-- Inline (für kleine Snippets) -->
<script>
console.log('Hallo Welt');
</script>
<!-- Modern: als Modul -->
<script type="module" src="./main.js"></script>
```
**Modern:** als ES-Modul mit `type="module"`. Erlaubt `import` / `export`.
<!--
Drei Wege, JS in HTML einzubinden:
1. External via `<script src="...">` — Best Practice für nicht-triviale Apps
2. Inline mit `<script>...</script>` — für ganz kleine Snippets, ok
3. ES-Modul mit `type="module"` — für moderne Apps mit import/export
Wichtig: Script-Position
- `<script>` im `<head>` ohne Defer/Async: blockiert das Rendern
- `<script defer>` im head: parallel laden, vor DOMContentLoaded ausführen
- `<script async>`: parallel laden, sofort ausführen (gefährlich für Reihenfolge)
- `<script>` am Ende des `<body>`: erst nach HTML-Parsing
-->
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/demos/js-console.png)
<!--
Die Browser-Konsole ist die wichtigste JS-Spielwiese für Anfänger.
DevTools öffnen (F12), Tab „Console":
- `console.log('Hallo')` → Hallo
- `1 + 1` → 2
- `let x = 10` → undefined, dann `x` → 10
- `document.title` → aktueller Tab-Titel
- `document.body.style.background = 'pink'` → Hintergrund wird pink
Studis können in der Konsole alles erst mal ausprobieren, bevor sie eine richtige .js-Datei schreiben.
-->
---
# Variablen — Daten speichern
```javascript
let name = "Ada"; // veränderlich
const PI = 3.14159; // konstant
var alt = "vermeiden"; // pre-ES6, hat skopen-bugs
// Verändern:
name = "Grace"; // OK
PI = 3.0; // FEHLER: const kann nicht überschrieben werden
```
**Faustregel:** `const` als Default. Nur `let`, wenn man umzuweisen plant. Niemals `var`.
<!--
Variable-Deklaration:
- `let`: Block-skopisch, veränderlich
- `const`: Block-skopisch, nicht-überschreibbar
- `var`: function-skopisch, hat historische Bugs — vermeiden
`const` heißt nicht „unveränderlich" — bei Objekten/Arrays kann der Inhalt verändert werden, nur die Referenz nicht.
```javascript
const list = [1, 2, 3];
list.push(4); // OK — Array selbst ist mutiert
list = []; // FEHLER — Referenz kann nicht überschrieben werden
```
-->
---
# Datentypen
```javascript
let text = "Hallo"; // string
let zahl = 42; // number
let ist_an = true; // boolean
let nichts = null; // null
let nicht_gesetzt; // undefined
let liste = [1, 2, 3]; // array
let objekt = { x: 1 }; // object
typeof text // "string"
typeof liste // "object" (auch arrays sind objects)
```
**6 Grund-Typen** + objects/arrays.
<!--
JavaScript ist dynamisch typisiert: eine Variable kann verschiedene Typen halten.
`typeof` zeigt den Typ. Arrays und Objects sind beide „object" — historische Quirks.
Modern: TypeScript fügt statische Typen drüber:
```typescript
let zahl: number = 42;
let text: string = "Hallo";
```
Das ist ein Aufsatz, der zu JavaScript kompiliert wird.
-->
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/demos/js-arrays.png)
<!--
Arrays = geordnete Listen.
```javascript
let früchte = ["Apfel", "Banane", "Kirsche"];
früchte[0] // "Apfel"
früchte.length // 3
früchte.push("Datte") // hängt an
früchte.includes("Banane") // true
früchte.indexOf("Kirsche") // 2
// Array-Methoden:
früchte.map(f => f.toUpperCase()) // ["APFEL", ...]
früchte.filter(f => f.length > 5) // ["Banane", "Kirsche"]
früchte.forEach(f => console.log(f))
```
Alles 0-indiziert.
-->
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/demos/js-objects.png)
<!--
Objekte = Sammlung von Key-Value-Paaren.
```javascript
let person = {
name: "Ada",
alt: 56,
hobbies: ["Mathe", "Schach"]
};
person.name // "Ada"
person["name"] // "Ada" (gleich wie oben)
person.alt = 57 // ändern
// Schlüssel:
Object.keys(person) // ["name", "alt", "hobbies"]
```
JSON ist Objekt-Notation.
-->
---
# Funktionen
```javascript
// Function declaration
function gruessen(name) {
return "Hallo " + name;
}
// Arrow function (modern, kompakt)
const gruessen = (name) => "Hallo " + name;
// Mit mehreren Zeilen
const summe = (a, b) => {
const result = a + b;
return result;
};
gruessen("Ada") // "Hallo Ada"
summe(3, 4) // 7
```
<!--
Funktionen sind in JS „first-class" — können als Variable, als Argument, als Rückgabe-Wert verwendet werden.
Arrow Functions sind die moderne Form (ES6+):
- Kürzer
- Kein eigener `this`-Kontext
- Implizites Return bei One-Liner
Best Practice: arrow functions als default, function declaration wenn man hoisting braucht.
-->
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/demos/js-loops.png)
<!--
Schleifen — Wiederholungen.
```javascript
// for-Schleife (klassisch)
for (let i = 0; i < 5; i++) {
console.log(i); // 0, 1, 2, 3, 4
}
// for...of (über Array)
for (const frucht of ["A", "B", "C"]) {
console.log(frucht);
}
// forEach (Array-Methode)
[1, 2, 3].forEach(n => console.log(n));
// map (transformieren)
[1, 2, 3].map(n => n * 2); // [2, 4, 6]
// filter (auswählen)
[1, 2, 3, 4].filter(n => n > 2); // [3, 4]
```
Modern: bevorzuge map/filter/forEach über klassische for-Loops.
-->
---
# Kontrollstrukturen
```javascript
// if / else
if (age >= 18) {
console.log("erwachsen");
} else if (age >= 14) {
console.log("jugendlich");
} else {
console.log("kind");
}
// Ternärer Operator (Kurzform)
const status = age >= 18 ? "erwachsen" : "kind";
// switch (mehrere Werte)
switch (browser) {
case "Chrome": return "Blink";
case "Safari": return "WebKit";
case "Firefox": return "Gecko";
default: return "unknown";
}
```
<!--
Bedingungen mit if/else if/else — wie in vielen Sprachen.
Ternärer Operator ist ein Kurzschluss für einfache if/else: `condition ? a : b`.
switch für viele Werte, oft mit return statt break. Aber: modern oft durch Map oder Object-Lookup ersetzt:
```javascript
const engine = { Chrome: "Blink", Safari: "WebKit" }[browser];
```
-->
---
<!-- _class: lead -->
# Das DOM
## HTML im Speicher des Browsers
<!--
Pivot. Bis hier war JS allgemeine Programmierung. Jetzt: JS im Web-Kontext.
DOM = Document Object Model. Browser bauen aus HTML einen JavaScript-zugreifbaren Baum. JS kann diesen Baum manipulieren.
-->
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/demos/dom-tree.png)
<!--
DOM als Baum-Struktur.
Jedes HTML-Element wird zu einem JS-Object. Diese Objects sind verbunden:
- parent: das Eltern-Element
- children: die Kind-Elemente
- nextSibling, previousSibling: die Nachbarn
Wenn JS den DOM ändert, ändert sich SOFORT die Anzeige.
Wichtig: JS kann nicht das HTML auf der Festplatte ändern — nur das DOM IM BROWSER. Wenn die Seite neu geladen wird, ist alles weg.
-->
---
# Elemente finden
```javascript
// EIN Element (erstes match)
const heading = document.querySelector('h1');
const btn = document.querySelector('#submit-button');
const card = document.querySelector('.card');
// MEHRERE Elemente (NodeList)
const allButtons = document.querySelectorAll('button');
const allCards = document.querySelectorAll('.card');
// Iterieren
allButtons.forEach(btn => console.log(btn.textContent));
```
`querySelector(...)` nimmt **denselben Selektor wie CSS.**
<!--
querySelector + querySelectorAll sind die modernen Wege, Elemente im DOM zu finden.
CSS-Selektoren wiederverwendbar:
- `'h1'` — alle h1
- `'#header'` — Element mit id
- `'.card'` — Elemente mit class
- `'nav > a'` — direkte Kinder
- `'input[type="email"]'` — Attribut-Selektor
Alternative ältere Methoden (querySelector ersetzt sie alle):
- `getElementById('header')`
- `getElementsByClassName('card')`
- `getElementsByTagName('h1')`
-->
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/demos/js-manipulate.png)
<!--
Elemente manipulieren — drei Hauptzugriffe:
```javascript
const el = document.querySelector('.greeting');
// Text-Inhalt
el.textContent = 'Hallo Welt';
// HTML-Inhalt (gefährlich — XSS-Risiko bei User-Input!)
el.innerHTML = '<strong>Achtung!</strong>';
// Attribute
el.setAttribute('href', 'https://librete.ch');
el.getAttribute('class');
// Klassen
el.classList.add('active');
el.classList.remove('hidden');
el.classList.toggle('open');
```
innerHTML ist mächtig, aber bei User-Input gefährlich — XSS-Angriffe möglich. Lieber textContent + createElement.
-->
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/demos/js-create.png)
<!--
Elemente neu erzeugen:
```javascript
const newP = document.createElement('p');
newP.textContent = 'Frisch gemacht';
newP.classList.add('notice');
document.body.appendChild(newP);
// Elemente entfernen
const old = document.querySelector('.old-stuff');
old.remove();
```
Verwendung: To-Do-Items dynamisch hinzufügen, Chat-Nachrichten anzeigen, Modal öffnen.
-->
---
<!-- _class: lead -->
# Events
## Auf User-Aktionen reagieren
<!--
Events = Ereignisse, die im Browser passieren:
- click, dblclick
- input, change (Form-Elemente)
- submit (Form)
- keydown, keyup
- scroll, resize
- load, DOMContentLoaded
JS kann auf Events „lauschen" und reagieren.
-->
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/demos/js-event-listener.png)
<!--
Event-Listener: callback function wird ausgeführt, wenn Event passiert.
```javascript
const btn = document.querySelector('#myBtn');
btn.addEventListener('click', () => {
console.log('Klick!');
btn.textContent = 'Geklickt';
});
// Mit Event-Objekt
btn.addEventListener('click', (event) => {
console.log(event.target); // welches Element
console.log(event.clientX); // Maus-X-Koordinate
});
// Mehrere Listener auf einem Element möglich
btn.addEventListener('click', handler1);
btn.addEventListener('click', handler2);
```
Modern: addEventListener statt onclick-Attribut.
-->
---
# Häufige Events
| Event | Wo | Wann |
|-------|----|----|
| `click` | jedes Element | Maus-Klick |
| `input` | input, textarea, select | bei jedem Tastendruck |
| `change` | input, select | wenn Wert verändert (bei blur) |
| `submit` | form | wenn Form abgeschickt wird |
| `keydown` | document, input | beim Tastendruck |
| `scroll` | window, scrollbare Elemente | beim Scrollen |
| `load` | window | wenn Seite + Resources geladen |
| `DOMContentLoaded` | document | wenn DOM bereit (vor Bildern) |
<!--
Pro Event-Typ andere Anwendung:
- input vs change: input feuert bei jedem Tastendruck, change erst wenn der Cursor das Feld verlässt
- submit auf form: erlaubt preventDefault um Standard-Verhalten zu unterbinden
- load: alles geladen (Bilder, CSS) — oft zu spät für JS
- DOMContentLoaded: DOM ready — best practice, JS hier starten
-->
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/demos/js-preventdefault.png)
<!--
preventDefault: verhindert die Standard-Reaktion.
```javascript
// Form ohne page-reload submitten
form.addEventListener('submit', (e) => {
e.preventDefault(); // verhindert Standard-Reload
// stattdessen: fetch + JSON
});
// Link, der nicht navigieren soll
link.addEventListener('click', (e) => {
e.preventDefault();
// stattdessen: Modal öffnen
});
```
Wichtig für moderne Single-Page-Apps — Navigation wird komplett von JS gesteuert.
-->
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/demos/js-darkmode.png)
<!--
Dark-Mode-Toggle — Klassiker.
```javascript
const toggle = document.querySelector('#darkmode-toggle');
const body = document.body;
toggle.addEventListener('click', () => {
body.classList.toggle('dark-mode');
});
```
CSS:
```css
body.dark-mode {
background: #1a1a2e;
color: #fff;
}
```
In ~10 Zeilen Code + ein bisschen CSS. Erste „echte" interaktive App für Anfänger.
-->
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/demos/js-todo.png)
<!--
To-Do-Liste — der „Hello World" der Web-Apps.
```javascript
const form = document.querySelector('#todo-form');
const input = document.querySelector('#todo-input');
const list = document.querySelector('#todo-list');
form.addEventListener('submit', (e) => {
e.preventDefault();
const text = input.value.trim();
if (!text) return;
const li = document.createElement('li');
li.textContent = text;
list.appendChild(li);
input.value = '';
});
```
Konzepte zusammen:
- Form-Submit + preventDefault
- Element erzeugen (createElement)
- Element anhängen (appendChild)
- Form zurücksetzen
-->
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/demos/js-fetch.png)
<!--
fetch — Daten holen.
```javascript
fetch('https://api.github.com/users/torvalds')
.then(response => response.json())
.then(data => {
console.log(data.name); // "Linus Torvalds"
console.log(data.public_repos);
})
.catch(error => console.error(error));
// Mit async/await (moderne syntax)
async function ladeUser() {
const res = await fetch('https://api.github.com/users/torvalds');
const data = await res.json();
return data;
}
```
Modern: async/await statt then-Chains.
-->
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/demos/js-localstorage.png)
<!--
localStorage — Daten persistent speichern (im Browser).
```javascript
// Speichern (nur Strings möglich)
localStorage.setItem('username', 'Ada');
// Laden
const name = localStorage.getItem('username');
// Object speichern: erst JSON
const settings = { darkmode: true, lang: 'de' };
localStorage.setItem('settings', JSON.stringify(settings));
// Laden: JSON parsen
const saved = JSON.parse(localStorage.getItem('settings'));
// Löschen
localStorage.removeItem('username');
localStorage.clear(); // alles weg
```
5-10 MB pro Origin. Bleibt zwischen Sessions. Nicht für sensible Daten (nicht verschlüsselt).
-->
---
<!-- _class: lead -->
# Frameworks
## Wann braucht man die?
<!--
Frameworks sind „voll-tooled" Abstraktionen über die DOM-API.
Wenn der Code mehr als ~500 Zeilen hat, wird vanilla DOM-Manipulation unübersichtlich. Frameworks helfen mit:
- Komponentenmodell
- Reactive State (Daten ändert sich, UI passt automatisch an)
- Routing
- Tools (Build, Linter, Tests)
-->
---
# React · Vue · Angular · Svelte
| Framework | Typ | Stärke |
|-----------|-----|--------|
| **React** | Library (mit Ökosystem) | dominierend, große Community |
| **Vue** | Framework | sanfter Einstieg, gute Doku |
| **Angular** | Framework | „Enterprise"-Setup, Google |
| **Svelte** | Compiler | kein Virtual DOM, kleine Bundle |
| **Astro** | Hybrid | Static-First, Multi-Framework |
Alle: **Komponenten** als Konzept. **State** verändert sich → UI re-rendert.
<!--
Übersicht ohne Galerie-Inflation.
Aktuelle Markt-Verteilung (2025-2026):
- React: ~40% (mit Next.js Framework drum herum)
- Vue: ~15-20% (Vue 3 + Nuxt)
- Angular: ~10% (in Enterprise)
- Svelte: ~5% (wächst stark)
- Astro: ~3% (für Content-sites)
- Vanilla: ~25% (klein-Projekte, Landing Pages)
Konzeptionell sind alle ähnlich: Komponenten, State, Re-Render.
Studis sollen wissen DASS es Frameworks gibt, aber für 223015c nicht im Detail. Tiefere Behandlung in Webentwicklung-Modulen (z.B. DHBW-Curriculum).
-->
---
# Library vs. Framework
| | Library | Framework |
|--|---------|-----------|
| Wer ruft | **du** rufst die Library | das Framework ruft **dich** |
| Beispiel | jQuery, React (offiziell), Lodash | Angular, Vue, Next.js, Astro |
| Vorteil | mehr Freiheit | mehr Struktur |
| Nachteil | mehr Setup-Arbeit | weniger Flexibilität |
**„Inversion of Control":** Library = du kontrollierst, Framework = es kontrolliert dich.
<!--
Begriffsklärung:
- Library: Sammlung von Funktionen. Du entscheidest wann/wie sie aufgerufen werden. Beispiel: `_.map(...)` von Lodash.
- Framework: Skelett, das deinen Code aufruft. Du füllst nur die richtigen Stellen. Beispiel: Angular Component Lifecycle Hooks.
Grenzen sind unscharf. React positioniert sich als Library, wird mit Next.js als Framework ergänzt. Vue mit/ohne Nuxt.
Faustregel: wenn du `npm run dev` für etwas Eigenes brauchst, ist es ein Framework.
-->
---
<!-- _class: aufgabe -->
# Selbstlernen — eigenes Mini-Projekt
Wähle eines:
**A. Dark-Mode-Toggle** — Button auf einer Seite, der `dark`-Klasse am body togglet. localStorage merkt den Zustand.
**B. To-Do-App** — Form, das neue Items zur Liste hinzufügt. localStorage für Persistenz.
**C. API-Visualisierung** — fetch zu `jsonplaceholder.typicode.com/users` und Daten als Liste rendern.
**Bonus:** mit GitHub Pages deployen → öffentlich zugängliche URL.
<!--
Niederschwellige Praxis-Aufgabe. ~30-60 Minuten pro Variante.
Tools:
- VS Code als Editor
- Live-Server-Extension oder einfach Doppelklick auf HTML-Datei
- Browser-DevTools für Debug
Lernziele:
- Eigenes Mini-Projekt produzieren
- DOM-Manipulation in Praxis
- Events handhaben
- API-Anfrage stellen (Variante C)
- Code öffentlich teilen (Bonus mit GitHub Pages)
-->
---
# Zusammenfassung
**Was JS macht:** DOM manipulieren · Events behandeln · Daten holen + speichern.
**Was JS NICHT macht (ohne User-Aktion):** willkürliche Datei-/Hardware-Zugriffe.
**Patterns:** querySelector → manipulate → addEventListener.
**Frameworks (React, Vue, …):** Abstraktion + State + Komponenten — für Projekte ab ~500 Zeilen.
→ **Du hast jetzt:** verstanden wie Daten reisen (Kap 2), wie sie dargestellt werden (HTML+CSS, Kap 1+2), und wie sie *interaktiv* werden (JS, Kap 3). Das ganze moderne Web in drei Kapiteln.
<!--
Recap Kap 3 + Synthese des ganzen Kurses.
Ende des Kurses:
- Pioniere → Architektur → Internet → HTML → CSS → A11y → JS
- Studis haben einen vollständigen mentalen Bauplan des Webs
Anschluss:
- Webentwicklung-Module: tieferer Stack (React, Node, Datenbanken, Deployment)
- DHBW-Module: Industrie-Praxis-Stack
Klausur:
- Hauptsächlich Kap 1+2 (Geschichte, Netzwerk, HTML, CSS, A11y)
- JS nur konzeptionell (Block J auf Verstehen-Niveau)
-->
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 926 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 486 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Preview: __TITLE__</title>
<style>
:root {
--hl: #d63384;
--dark: #0f0f23;
--chrome: #1a1a2e;
--muted: #4a4a6a;
}
html, body { margin: 0; padding: 0; background: var(--dark); font-family: system-ui, -apple-system, sans-serif; }
.browser { box-sizing: border-box; width: 100vw; min-height: 100vh; padding: 18px; }
.window { background: #fff; border-radius: 10px; box-shadow: 0 12px 32px rgba(0,0,0,.35); overflow: hidden; border: 2px solid var(--hl); }
.chrome { background: var(--chrome); border-bottom: 2px solid var(--hl); padding: 10px 14px; display: flex; align-items: center; gap: 7px; }
.dot { width: 11px; height: 11px; border-radius: 50%; opacity: 0.9; }
.r { background: #ff5f56; } .y { background: #ffbd2e; } .g { background: #27c93f; }
.url { flex: 1; margin-left: 12px; background: var(--dark); border: 1px solid var(--hl); border-radius: 6px; padding: 5px 10px; font: 12px/1.3 ui-monospace, "SF Mono", Menlo, monospace; color: var(--hl); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
iframe { display: block; width: 100%; height: 700px; border: 0; background: #fff; }
</style>
</head>
<body>
<div class="browser">
<div class="window">
<div class="chrome">
<span class="dot r"></span><span class="dot y"></span><span class="dot g"></span>
<span class="url">__URL__</span>
</div>
<iframe src="__SRC__"></iframe>
</div>
</div>
</body>
</html>
@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Preview: a11y-error</title>
<style>
:root {
--hl: #d63384;
--dark: #0f0f23;
--chrome: #1a1a2e;
--muted: #4a4a6a;
}
html, body { margin: 0; padding: 0; background: var(--dark); font-family: system-ui, -apple-system, sans-serif; }
.browser { box-sizing: border-box; width: 100vw; min-height: 100vh; padding: 18px; }
.window { background: #fff; border-radius: 10px; box-shadow: 0 12px 32px rgba(0,0,0,.35); overflow: hidden; border: 2px solid var(--hl); }
.chrome { background: var(--chrome); border-bottom: 2px solid var(--hl); padding: 10px 14px; display: flex; align-items: center; gap: 7px; }
.dot { width: 11px; height: 11px; border-radius: 50%; opacity: 0.9; }
.r { background: #ff5f56; } .y { background: #ffbd2e; } .g { background: #27c93f; }
.url { flex: 1; margin-left: 12px; background: var(--dark); border: 1px solid var(--hl); border-radius: 6px; padding: 5px 10px; font: 12px/1.3 ui-monospace, "SF Mono", Menlo, monospace; color: var(--hl); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
iframe { display: block; width: 100%; height: 700px; border: 0; background: #fff; }
</style>
</head>
<body>
<div class="browser">
<div class="window">
<div class="chrome">
<span class="dot r"></span><span class="dot y"></span><span class="dot g"></span>
<span class="url">file:///beispiel/email-form.html</span>
</div>
<iframe src="./a11y-error.html"></iframe>
</div>
</div>
</body>
</html>
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Fehlermeldung</title>
<style>
body { font-family: system-ui, sans-serif; padding: 1.2rem; }
label { display: block; margin-bottom: 4px; font-weight: 600; }
input {
font: inherit;
padding: 6px 10px;
width: 100%;
box-sizing: border-box;
border: 2px solid #d63384;
border-radius: 4px;
}
#email-error {
color: #d63384;
font-size: 0.9em;
margin-top: 6px;
}
</style>
</head>
<body>
<label for="email">E-Mail-Adresse</label>
<input id="email" type="email" aria-describedby="email-error" value="michael@">
<p id="email-error" role="alert">
Bitte geben Sie eine gültige E-Mail-Adresse ein.
</p>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Preview: a11y-focus</title>
<style>
:root {
--hl: #d63384;
--dark: #0f0f23;
--chrome: #1a1a2e;
--muted: #4a4a6a;
}
html, body { margin: 0; padding: 0; background: var(--dark); font-family: system-ui, -apple-system, sans-serif; }
.browser { box-sizing: border-box; width: 100vw; min-height: 100vh; padding: 18px; }
.window { background: #fff; border-radius: 10px; box-shadow: 0 12px 32px rgba(0,0,0,.35); overflow: hidden; border: 2px solid var(--hl); }
.chrome { background: var(--chrome); border-bottom: 2px solid var(--hl); padding: 10px 14px; display: flex; align-items: center; gap: 7px; }
.dot { width: 11px; height: 11px; border-radius: 50%; opacity: 0.9; }
.r { background: #ff5f56; } .y { background: #ffbd2e; } .g { background: #27c93f; }
.url { flex: 1; margin-left: 12px; background: var(--dark); border: 1px solid var(--hl); border-radius: 6px; padding: 5px 10px; font: 12px/1.3 ui-monospace, "SF Mono", Menlo, monospace; color: var(--hl); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
iframe { display: block; width: 100%; height: 700px; border: 0; background: #fff; }
</style>
</head>
<body>
<div class="browser">
<div class="window">
<div class="chrome">
<span class="dot r"></span><span class="dot y"></span><span class="dot g"></span>
<span class="url">file:///beispiel/focus.html</span>
</div>
<iframe src="./a11y-focus.html"></iframe>
</div>
</div>
</body>
</html>
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Fokus-Indikator</title>
<style>
body { font-family: system-ui, sans-serif; padding: 1.4rem; font-size: 1rem; }
button { font: inherit; padding: 10px 18px; margin: 8px 0; display: block; border: 1.5px solid #d1d5db; background: #fff; border-radius: 4px; cursor: pointer; }
button:focus-visible, button.is-focused {
outline: 3px solid #d63384;
outline-offset: 3px;
border-radius: 4px;
}
</style>
</head>
<body>
<p><strong>Tab-Taste drücken:</strong></p>
<button class="is-focused">Erster Button</button>
<button>Zweiter Button</button>
<button>Dritter Button</button>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Preview: a11y-semantic</title>
<style>
:root {
--hl: #d63384;
--dark: #0f0f23;
--chrome: #1a1a2e;
--muted: #4a4a6a;
}
html, body { margin: 0; padding: 0; background: var(--dark); font-family: system-ui, -apple-system, sans-serif; }
.browser { box-sizing: border-box; width: 100vw; min-height: 100vh; padding: 18px; }
.window { background: #fff; border-radius: 10px; box-shadow: 0 12px 32px rgba(0,0,0,.35); overflow: hidden; border: 2px solid var(--hl); }
.chrome { background: var(--chrome); border-bottom: 2px solid var(--hl); padding: 10px 14px; display: flex; align-items: center; gap: 7px; }
.dot { width: 11px; height: 11px; border-radius: 50%; opacity: 0.9; }
.r { background: #ff5f56; } .y { background: #ffbd2e; } .g { background: #27c93f; }
.url { flex: 1; margin-left: 12px; background: var(--dark); border: 1px solid var(--hl); border-radius: 6px; padding: 5px 10px; font: 12px/1.3 ui-monospace, "SF Mono", Menlo, monospace; color: var(--hl); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
iframe { display: block; width: 100%; height: 700px; border: 0; background: #fff; }
</style>
</head>
<body>
<div class="browser">
<div class="window">
<div class="chrome">
<span class="dot r"></span><span class="dot y"></span><span class="dot g"></span>
<span class="url">file:///beispiel/klick.html</span>
</div>
<iframe src="./a11y-semantic.html"></iframe>
</div>
</div>
</body>
</html>
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>div vs button</title>
<style>
body { font-family: system-ui, sans-serif; padding: 1.2rem; }
h3 { margin: 0.8rem 0 0.4rem; font-size: 1rem; }
.bad { color: #b91c1c; }
.good { color: #15803d; }
.button {
display: inline-block;
background: #e5e7eb;
border: 1px solid #9ca3af;
padding: 6px 14px;
cursor: pointer;
border-radius: 4px;
}
button { font: inherit; padding: 6px 14px; }
</style>
</head>
<body>
<h3 class="bad">Schlecht (div)</h3>
<div class="button" onclick="alert('!')">Klick mich</div>
<p><small>❌ Tab überspringt, kein Enter, kein Screenreader</small></p>
<h3 class="good">Gut (button)</h3>
<button type="button">Klick mich</button>
<p><small>✅ Tastatur + Screenreader eingebaut</small></p>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

@@ -0,0 +1,65 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>ARP</title>
<style>
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, sans-serif; }
body { padding: 30px; display: inline-block; }
.row { display: flex; align-items: center; gap: 16px; margin-bottom: 20px; }
.actor {
background: #1a1a2e;
color: #fff;
padding: 10px 16px;
border-radius: 6px;
font-weight: 700;
min-width: 160px;
text-align: center;
font-size: 0.9rem;
}
.laptop { background: #1e40af; }
.router { background: #c2410c; }
.arrow-right, .arrow-left {
width: 0; height: 0;
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
}
.arrow-right { border-left: 14px solid #d63384; }
.arrow-left { border-right: 14px solid #15803d; }
.bubble {
padding: 10px 14px;
border-radius: 8px;
font-size: 0.95rem;
max-width: 460px;
}
.ask { background: #fce7f3; border: 2px solid #d63384; color: #7c2d12; }
.reply { background: #dcfce7; border: 2px solid #15803d; color: #14532d; }
.meta {
font-size: 0.7rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.05em;
opacity: 0.7;
margin-bottom: 3px;
}
</style>
</head>
<body>
<div class="row">
<div class="actor laptop">Laptop</div>
<div class="arrow-right"></div>
<div class="bubble ask">
<div class="meta">Broadcast</div>
"Wer hat die IP 192.168.1.1? Sag mir deine MAC!"
</div>
</div>
<div class="row">
<div class="bubble reply">
<div class="meta">Antwort</div>
"Das bin ich! Meine MAC ist 11:22:33:44:55:66"
</div>
<div class="arrow-left"></div>
<div class="actor router">Router</div>
</div>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

@@ -0,0 +1,53 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Box-Modell Diagramm</title>
<style>
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, sans-serif; }
body { padding: 40px; display: inline-block; box-sizing: border-box; }
.layer {
padding-top: 38px;
padding-bottom: 30px;
padding-left: 30px;
padding-right: 30px;
position: relative;
border-radius: 4px;
}
.layer::before {
position: absolute;
top: 8px; left: 14px;
font-size: 0.95rem;
font-weight: 700;
letter-spacing: 0.02em;
}
.margin { background: #fde68a; }
.margin::before { content: "margin"; color: #92400e; }
.border { background: #fca5a5; }
.border::before { content: "border"; color: #991b1b; }
.padding { background: #86efac; }
.padding::before { content: "padding"; color: #166534; }
.content {
background: #93c5fd;
width: 260px;
height: 110px;
display: flex;
align-items: center;
justify-content: center;
color: #1e3a8a;
font-weight: 700;
font-size: 1.2rem;
border-radius: 4px;
}
</style>
</head>
<body>
<div class="layer margin">
<div class="layer border">
<div class="layer padding">
<div class="content">content</div>
</div>
</div>
</div>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Preview: button</title>
<style>
:root {
--hl: #d63384;
--dark: #0f0f23;
--chrome: #1a1a2e;
--muted: #4a4a6a;
}
html, body { margin: 0; padding: 0; background: var(--dark); font-family: system-ui, -apple-system, sans-serif; }
.browser { box-sizing: border-box; width: 100vw; min-height: 100vh; padding: 18px; }
.window { background: #fff; border-radius: 10px; box-shadow: 0 12px 32px rgba(0,0,0,.35); overflow: hidden; border: 2px solid var(--hl); }
.chrome { background: var(--chrome); border-bottom: 2px solid var(--hl); padding: 10px 14px; display: flex; align-items: center; gap: 7px; }
.dot { width: 11px; height: 11px; border-radius: 50%; opacity: 0.9; }
.r { background: #ff5f56; } .y { background: #ffbd2e; } .g { background: #27c93f; }
.url { flex: 1; margin-left: 12px; background: var(--dark); border: 1px solid var(--hl); border-radius: 6px; padding: 5px 10px; font: 12px/1.3 ui-monospace, "SF Mono", Menlo, monospace; color: var(--hl); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
iframe { display: block; width: 100%; height: 700px; border: 0; background: #fff; }
</style>
</head>
<body>
<div class="browser">
<div class="window">
<div class="chrome">
<span class="dot r"></span><span class="dot y"></span><span class="dot g"></span>
<span class="url">file:///beispiel/button.html</span>
</div>
<iframe src="./button.html"></iframe>
</div>
</div>
</body>
</html>
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Button</title>
</head>
<body>
<button>Add to favorites</button>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

@@ -0,0 +1,180 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Byte-Fluss: Bit → Hex → ASCII</title>
<style>
:root {
--hl: #d63384;
--dark: #1a1a2e;
--muted: #6b7280;
--border: #cbd5e1;
--bg-soft: #f8fafc;
--byte-border: #94a3b8;
}
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
body { padding: 22px 28px; }
h1 { text-align: center; margin: 0 0 4px; font-size: 1.55rem; }
.sub { text-align: center; color: var(--muted); margin-bottom: 18px; font-size: 0.95rem; }
.stage { display: flex; flex-direction: column; align-items: center; gap: 8px; max-width: 920px; margin: 0 auto; }
.file {
width: 100%; box-sizing: border-box;
border: 2px solid var(--dark);
border-radius: 10px;
background: var(--bg-soft);
overflow: hidden;
box-shadow: 0 6px 20px rgba(0,0,0,0.08);
}
.file .head {
background: var(--dark); color: #fff; padding: 8px 14px;
font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.08em; font-weight: 700;
display: flex; justify-content: space-between; align-items: center;
}
.file .head .name { font-family: ui-monospace, monospace; }
.file .head .meta { font-weight: 400; opacity: 0.7; text-transform: none; letter-spacing: 0; font-size: 0.85em; }
.file .body { padding: 12px 14px; }
.row-bytes { display: flex; gap: 6px; margin-bottom: 6px; flex-wrap: nowrap; }
.row-bytes:last-child { margin-bottom: 0; }
.byte-bin {
border: 1px solid var(--byte-border);
border-radius: 4px;
padding: 4px 7px;
font-family: ui-monospace, "SF Mono", Menlo, monospace;
font-size: 0.92rem;
font-weight: 700;
background: #fff;
letter-spacing: 0.04em;
}
.byte-hex {
border: 1px solid var(--byte-border);
border-radius: 4px;
padding: 6px 0;
font-family: ui-monospace, monospace;
font-size: 1.1rem;
font-weight: 700;
background: #fff;
min-width: 88px;
text-align: center;
}
.byte-ascii {
border: 1px solid var(--byte-border);
border-radius: 4px;
padding: 6px 0;
font-family: ui-monospace, monospace;
font-size: 1.2rem;
font-weight: 700;
background: #fff;
min-width: 88px;
text-align: center;
}
.byte-ascii.np { color: var(--muted); font-style: italic; }
.truncate { color: var(--muted); font-family: ui-monospace, monospace; padding: 4px 6px; font-weight: 700; align-self: center; }
.arrow-stack { display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 4px 0; }
.arrow {
width: 0; height: 0;
border-left: 11px solid transparent;
border-right: 11px solid transparent;
border-top: 14px solid var(--hl);
}
.arrow-label {
font-size: 0.78rem; color: var(--hl); font-weight: 700;
text-transform: uppercase; letter-spacing: 0.05em;
}
.legend {
margin-top: 12px;
display: flex; gap: 14px; flex-wrap: wrap; justify-content: center;
font-size: 0.85rem; color: var(--muted);
}
.legend strong { color: var(--dark); }
.legend code { background: var(--bg-soft); border: 1px solid var(--border); padding: 1px 6px; border-radius: 3px; font-family: ui-monospace, monospace; }
</style>
</head>
<body>
<h1>1 Byte = 8 Bit = 2 Hex = 1 ASCII-Zeichen</h1>
<div class="sub">Dieselbe Datei — dieselben Byte, drei Schreibweisen. Jeder Rahmen = ein Byte.</div>
<div class="stage">
<!-- Stage 1: Bitstream -->
<div class="file">
<div class="head"><span class="name">datei.bin</span><span class="meta">Roh-Bit · 8 Bit pro Rahmen</span></div>
<div class="body">
<div class="row-bytes">
<span class="byte-bin">01001000</span><span class="byte-bin">01100101</span><span class="byte-bin">01101100</span><span class="byte-bin">01101100</span><span class="byte-bin">01101111</span><span class="byte-bin">00101100</span><span class="byte-bin">00100000</span><span class="byte-bin">01010111</span>
</div>
<div class="row-bytes">
<span class="byte-bin">01101111</span><span class="byte-bin">01110010</span><span class="byte-bin">01101100</span><span class="byte-bin">01100100</span><span class="byte-bin">00100001</span><span class="byte-bin">00100000</span><span class="byte-bin">01001000</span><span class="byte-bin">01101111</span>
</div>
<div class="row-bytes">
<span class="byte-bin">01110111</span><span class="byte-bin">00100000</span><span class="byte-bin">01100001</span><span class="byte-bin">01110010</span><span class="byte-bin">01100101</span><span class="byte-bin">00100000</span><span class="byte-bin">01111001</span><span class="byte-bin">01101111</span>
</div>
<div class="row-bytes">
<span class="byte-bin">01110101</span><span class="byte-bin">00111111</span><span class="byte-bin">00001010</span><span class="truncate">… (weitere Byte)</span>
</div>
</div>
</div>
<div class="arrow-stack">
<div class="arrow-label">je 8 Bit → 2 Hex-Ziffern</div>
<div class="arrow"></div>
</div>
<!-- Stage 2: Hex -->
<div class="file">
<div class="head"><span class="name">datei.hex</span><span class="meta">Hex-Sicht · 2 Hex-Ziffern pro Rahmen</span></div>
<div class="body">
<div class="row-bytes">
<span class="byte-hex">48</span><span class="byte-hex">65</span><span class="byte-hex">6C</span><span class="byte-hex">6C</span><span class="byte-hex">6F</span><span class="byte-hex">2C</span><span class="byte-hex">20</span><span class="byte-hex">57</span>
</div>
<div class="row-bytes">
<span class="byte-hex">6F</span><span class="byte-hex">72</span><span class="byte-hex">6C</span><span class="byte-hex">64</span><span class="byte-hex">21</span><span class="byte-hex">20</span><span class="byte-hex">48</span><span class="byte-hex">6F</span>
</div>
<div class="row-bytes">
<span class="byte-hex">77</span><span class="byte-hex">20</span><span class="byte-hex">61</span><span class="byte-hex">72</span><span class="byte-hex">65</span><span class="byte-hex">20</span><span class="byte-hex">79</span><span class="byte-hex">6F</span>
</div>
<div class="row-bytes">
<span class="byte-hex">75</span><span class="byte-hex">3F</span><span class="byte-hex">0A</span><span class="truncate">…</span>
</div>
</div>
</div>
<div class="arrow-stack">
<div class="arrow-label">je 1 Byte → 1 Zeichen</div>
<div class="arrow"></div>
</div>
<!-- Stage 3: ASCII -->
<div class="file">
<div class="head"><span class="name">datei.txt</span><span class="meta">Text-Sicht · 1 ASCII-Zeichen pro Rahmen</span></div>
<div class="body">
<div class="row-bytes">
<span class="byte-ascii">H</span><span class="byte-ascii">e</span><span class="byte-ascii">l</span><span class="byte-ascii">l</span><span class="byte-ascii">o</span><span class="byte-ascii">,</span><span class="byte-ascii np">␣</span><span class="byte-ascii">W</span>
</div>
<div class="row-bytes">
<span class="byte-ascii">o</span><span class="byte-ascii">r</span><span class="byte-ascii">l</span><span class="byte-ascii">d</span><span class="byte-ascii">!</span><span class="byte-ascii np">␣</span><span class="byte-ascii">H</span><span class="byte-ascii">o</span>
</div>
<div class="row-bytes">
<span class="byte-ascii">w</span><span class="byte-ascii np">␣</span><span class="byte-ascii">a</span><span class="byte-ascii">r</span><span class="byte-ascii">e</span><span class="byte-ascii np">␣</span><span class="byte-ascii">y</span><span class="byte-ascii">o</span>
</div>
<div class="row-bytes">
<span class="byte-ascii">u</span><span class="byte-ascii">?</span><span class="byte-ascii np">↵</span><span class="truncate">…</span>
</div>
</div>
</div>
<div class="legend">
<span><code>␣</code> = Leerzeichen (0x20)</span>
<span><code>↵</code> = Zeilenumbruch (0x0A, nicht druckbar)</span>
<span><strong>Byte ändern sich nicht.</strong> Nur die Anzeige.</span>
</div>
</div>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

@@ -0,0 +1,185 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Byte → Nibble → Hex</title>
<style>
:root {
--hl: #d63384;
--dark: #1a1a2e;
--muted: #6b7280;
--border: #cbd5e1;
--bg-soft: #f8fafc;
}
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
body { padding: 28px 32px; }
h1 { text-align: center; margin: 0 0 4px; font-size: 1.55rem; }
.sub { text-align: center; color: var(--muted); margin-bottom: 22px; font-size: 0.95rem; }
.stage { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.level { display: flex; flex-direction: column; align-items: center; }
.label { font-size: 0.78rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 6px; font-weight: 600; }
/* Level 1: whole byte */
.byte {
display: flex;
gap: 4px;
padding: 8px 14px;
border: 2px solid var(--dark);
border-radius: 8px;
background: var(--bg-soft);
}
.byte .bit { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 1.3rem; font-weight: 700; padding: 4px 8px; min-width: 22px; text-align: center; }
.byte .sep { width: 2px; background: var(--hl); margin: 2px 6px; border-radius: 2px; }
/* Split arrows */
.split { display: flex; justify-content: space-between; width: 360px; margin: 2px 0; }
.split .arrow {
width: 0; height: 0;
border-left: 9px solid transparent;
border-right: 9px solid transparent;
border-top: 12px solid var(--hl);
}
/* Level 2: two nibbles */
.nibbles { display: flex; gap: 80px; }
.nibble {
display: flex; flex-direction: column; align-items: center; gap: 6px;
padding: 10px 14px;
border: 2px solid var(--hl);
border-radius: 8px;
background: #fff;
}
.nibble .bits { display: flex; gap: 4px; font-family: ui-monospace, monospace; font-size: 1.15rem; font-weight: 700; }
.nibble .bits span { padding: 2px 6px; min-width: 20px; text-align: center; }
.nibble .meta { font-size: 0.78rem; color: var(--muted); }
.single-arrow {
width: 0; height: 0;
border-left: 9px solid transparent;
border-right: 9px solid transparent;
border-top: 12px solid var(--hl);
margin: 2px 0;
}
/* Level 3: hex digits */
.hex-digits { display: flex; gap: 80px; }
.hex-digit {
display: flex; flex-direction: column; align-items: center; gap: 4px;
padding: 8px 22px;
border: 2px solid var(--dark);
border-radius: 8px;
background: var(--dark);
color: var(--hl);
}
.hex-digit .digit { font-family: ui-monospace, monospace; font-size: 2rem; font-weight: 800; line-height: 1; }
.hex-digit .meta { font-size: 0.72rem; color: #f3f4f6; opacity: 0.7; }
/* Merge down to byte */
.merge {
display: flex; justify-content: center; margin-top: 2px;
}
.merge-v {
display: grid;
grid-template-columns: 60px 60px;
justify-content: center;
align-items: center;
}
.merge-v .line {
height: 20px;
border-right: 2px solid var(--hl);
}
.merge-v .line.l { border-right: none; border-left: 2px solid var(--hl); }
.bottom-bar { height: 2px; background: var(--hl); width: 120px; }
/* Final result */
.result {
margin-top: 14px;
padding: 14px 22px;
background: #fef3f8;
border-left: 4px solid var(--hl);
border-radius: 4px;
font-size: 1.05rem;
text-align: center;
max-width: 640px;
}
.result code { background: var(--dark); color: var(--hl); padding: 2px 8px; border-radius: 4px; font-family: ui-monospace, monospace; font-weight: 700; }
.result strong { color: var(--hl); }
.math {
margin-top: 10px;
font-size: 0.95rem;
color: var(--dark);
text-align: center;
}
.math .eq { font-family: ui-monospace, monospace; font-weight: 700; }
</style>
</head>
<body>
<h1>1 Byte → 2 Nibble → 2 Hex-Ziffern</h1>
<div class="sub">Jedes Byte lässt sich sauber halbieren – und 4 Bit passen exakt auf eine Hex-Ziffer.</div>
<div class="stage">
<!-- Level 1 -->
<div class="level">
<div class="label">1 Byte · 8 Bit · 2⁸ = 256 Werte</div>
<div class="byte">
<span class="bit">0</span><span class="bit">1</span><span class="bit">0</span><span class="bit">0</span>
<span class="sep"></span>
<span class="bit">1</span><span class="bit">1</span><span class="bit">0</span><span class="bit">1</span>
</div>
</div>
<div class="split">
<div class="arrow"></div>
<div class="arrow"></div>
</div>
<!-- Level 2 -->
<div class="level">
<div class="label">2 Nibble · je 4 Bit · 2⁴ = 16 Werte</div>
<div class="nibbles">
<div class="nibble">
<div class="bits"><span>0</span><span>1</span><span>0</span><span>0</span></div>
<div class="meta">= 4 (dez)</div>
</div>
<div class="nibble">
<div class="bits"><span>1</span><span>1</span><span>0</span><span>1</span></div>
<div class="meta">= 13 (dez)</div>
</div>
</div>
</div>
<div class="split">
<div class="arrow"></div>
<div class="arrow"></div>
</div>
<!-- Level 3 -->
<div class="level">
<div class="label">2 Hex-Ziffern · Symbole 0–F</div>
<div class="hex-digits">
<div class="hex-digit">
<div class="digit">4</div>
<div class="meta">Nibble → 1 Ziffer</div>
</div>
<div class="hex-digit">
<div class="digit">D</div>
<div class="meta">13 → D</div>
</div>
</div>
</div>
<div class="result">
<code>01001101</code> (bin) &nbsp;=&nbsp; <code>4D</code> (hex) &nbsp;=&nbsp; <strong>77</strong> (dez) &nbsp;=&nbsp; <strong>"M"</strong> (ASCII)
</div>
<div class="math">
<span class="eq">16 × 16 = 256</span> &nbsp;·&nbsp; <span class="eq">2⁴ × 2⁴ = 2⁸</span> &nbsp;·&nbsp; Darum passt Hex so gut zu Bytes.
</div>
</div>
</body>
</html>
</content>
</invoke>
Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

@@ -0,0 +1,58 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Client/Server Ports</title>
<style>
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, sans-serif; }
body { padding: 30px; display: inline-block; }
.endpoint {
border: 2px solid #4a4a6a;
border-radius: 6px;
padding: 18px 24px;
margin-bottom: 24px;
min-width: 380px;
background: #f3f4f6;
}
.endpoint.client { background: #dbeafe; border-color: #1e40af; }
.endpoint.server { background: #fed7aa; border-color: #c2410c; }
.role {
font-weight: 700;
font-size: 1rem;
margin-bottom: 6px;
}
.client .role { color: #1e3a8a; }
.server .role { color: #7c2d12; }
.addr {
font-family: ui-monospace, monospace;
font-size: 1.4rem;
color: #0f172a;
}
.port {
background: #fde68a;
color: #7c2d12;
padding: 1px 8px;
border-radius: 4px;
font-weight: 700;
}
.label {
margin-top: 6px;
font-size: 0.85rem;
color: #4a4a6a;
font-style: italic;
}
</style>
</head>
<body>
<div class="endpoint client">
<div class="role">Client</div>
<div class="addr">141.62.xxx.xxx:<span class="port">52431</span></div>
<div class="label">↳ zufälliger Port vom OS</div>
</div>
<div class="endpoint server">
<div class="role">Server</div>
<div class="addr">212.132.79.37:<span class="port">443</span></div>
<div class="label">↳ HTTPS-Standardport</div>
</div>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Preview: Kontrast</title>
<style>
:root {
--hl: #d63384;
--dark: #0f0f23;
--chrome: #1a1a2e;
--muted: #4a4a6a;
}
html, body { margin: 0; padding: 0; background: var(--dark); font-family: system-ui, -apple-system, sans-serif; }
.browser { box-sizing: border-box; width: 100vw; min-height: 100vh; padding: 18px; }
.window { background: #fff; border-radius: 10px; box-shadow: 0 12px 32px rgba(0,0,0,.35); overflow: hidden; border: 2px solid var(--hl); }
.chrome { background: var(--chrome); border-bottom: 2px solid var(--hl); padding: 10px 14px; display: flex; align-items: center; gap: 7px; }
.dot { width: 11px; height: 11px; border-radius: 50%; opacity: 0.9; }
.r { background: #ff5f56; } .y { background: #ffbd2e; } .g { background: #27c93f; }
.url { flex: 1; margin-left: 12px; background: var(--dark); border: 1px solid var(--hl); border-radius: 6px; padding: 5px 10px; font: 12px/1.3 ui-monospace, "SF Mono", Menlo, monospace; color: var(--hl); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
iframe { display: block; width: 100%; height: 700px; border: 0; background: #fff; }
</style>
</head>
<body>
<div class="browser">
<div class="window">
<div class="chrome">
<span class="dot r"></span><span class="dot y"></span><span class="dot g"></span>
<span class="url">file:///beispiel/contrast.html</span>
</div>
<iframe src="./contrast-levels.html"></iframe>
</div>
</div>
</body>
</html>
@@ -0,0 +1,97 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Kontrast-Stufen</title>
<style>
body { font-family: system-ui, sans-serif; padding: 1.6rem; margin: 0; }
.row {
background: #fff;
padding: 22px 20px;
margin-bottom: 14px;
border-radius: 6px;
border: 1px solid #e5e7eb;
display: flex;
align-items: center;
justify-content: space-between;
gap: 14px;
}
.sample {
font-size: 1.5rem;
font-weight: 600;
flex: 1;
}
.meta {
text-align: right;
font-size: 0.85rem;
white-space: nowrap;
}
.ratio {
font-family: ui-monospace, monospace;
font-weight: 700;
font-size: 0.95rem;
color: #1a1a2e;
}
.badge {
display: inline-block;
padding: 2px 8px;
border-radius: 3px;
font-size: 0.7rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.05em;
margin-top: 4px;
}
.fail { background: #fee2e2; color: #991b1b; }
.aa-large { background: #fed7aa; color: #7c2d12; }
.aa { background: #dcfce7; color: #166534; }
.aaa { background: #bbf7d0; color: #14532d; }
.hint {
margin-top: 14px;
font-size: 0.78rem;
color: #6b7280;
font-style: italic;
text-align: right;
}
.hint a { color: #d63384; }
</style>
</head>
<body>
<div class="row" style="background: #fff;">
<div class="sample" style="color: #aaaaaa;">Barrierefrei lesen</div>
<div class="meta">
<div class="ratio">2.3:1</div>
<span class="badge fail">✗ Fail</span>
</div>
</div>
<div class="row" style="background: #fff;">
<div class="sample" style="color: #949494;">Barrierefrei lesen</div>
<div class="meta">
<div class="ratio">3:1</div>
<span class="badge aa-large">AA Large</span>
</div>
</div>
<div class="row" style="background: #fff;">
<div class="sample" style="color: #767676;">Barrierefrei lesen</div>
<div class="meta">
<div class="ratio">4.5:1</div>
<span class="badge aa">✓ AA</span>
</div>
</div>
<div class="row" style="background: #fff;">
<div class="sample" style="color: #595959;">Barrierefrei lesen</div>
<div class="meta">
<div class="ratio">7:1</div>
<span class="badge aaa">✓ AAA</span>
</div>
</div>
<div class="row" style="background: #fff;">
<div class="sample" style="color: #1a1a1a;">Barrierefrei lesen</div>
<div class="meta">
<div class="ratio">16:1</div>
<span class="badge aaa">✓ AAA+</span>
</div>
</div>
<div class="hint">Check: webaim.org/resources/contrastchecker</div>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Preview: css-anatomie</title>
<style>
:root {
--hl: #d63384;
--dark: #0f0f23;
--chrome: #1a1a2e;
--muted: #4a4a6a;
}
html, body { margin: 0; padding: 0; background: var(--dark); font-family: system-ui, -apple-system, sans-serif; }
.browser { box-sizing: border-box; width: 100vw; min-height: 100vh; padding: 18px; }
.window { background: #fff; border-radius: 10px; box-shadow: 0 12px 32px rgba(0,0,0,.35); overflow: hidden; border: 2px solid var(--hl); }
.chrome { background: var(--chrome); border-bottom: 2px solid var(--hl); padding: 10px 14px; display: flex; align-items: center; gap: 7px; }
.dot { width: 11px; height: 11px; border-radius: 50%; opacity: 0.9; }
.r { background: #ff5f56; } .y { background: #ffbd2e; } .g { background: #27c93f; }
.url { flex: 1; margin-left: 12px; background: var(--dark); border: 1px solid var(--hl); border-radius: 6px; padding: 5px 10px; font: 12px/1.3 ui-monospace, "SF Mono", Menlo, monospace; color: var(--hl); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
iframe { display: block; width: 100%; height: 700px; border: 0; background: #fff; }
</style>
</head>
<body>
<div class="browser">
<div class="window">
<div class="chrome">
<span class="dot r"></span><span class="dot y"></span><span class="dot g"></span>
<span class="url">file:///beispiel/anatomie.html</span>
</div>
<iframe src="./css-anatomie.html"></iframe>
</div>
</div>
</body>
</html>
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>CSS Anatomie</title>
<style>
body { padding: 1.2rem; font-family: system-ui, sans-serif; }
p { color: blue; font-size: 16px; }
</style>
</head>
<body>
<p>Dieser Absatz ist blau und 16 Pixel groß.</p>
<p>Alle p-Elemente werden gleich gestylt.</p>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Preview: css-box-model</title>
<style>
:root {
--hl: #d63384;
--dark: #0f0f23;
--chrome: #1a1a2e;
--muted: #4a4a6a;
}
html, body { margin: 0; padding: 0; background: var(--dark); font-family: system-ui, -apple-system, sans-serif; }
.browser { box-sizing: border-box; width: 100vw; min-height: 100vh; padding: 18px; }
.window { background: #fff; border-radius: 10px; box-shadow: 0 12px 32px rgba(0,0,0,.35); overflow: hidden; border: 2px solid var(--hl); }
.chrome { background: var(--chrome); border-bottom: 2px solid var(--hl); padding: 10px 14px; display: flex; align-items: center; gap: 7px; }
.dot { width: 11px; height: 11px; border-radius: 50%; opacity: 0.9; }
.r { background: #ff5f56; } .y { background: #ffbd2e; } .g { background: #27c93f; }
.url { flex: 1; margin-left: 12px; background: var(--dark); border: 1px solid var(--hl); border-radius: 6px; padding: 5px 10px; font: 12px/1.3 ui-monospace, "SF Mono", Menlo, monospace; color: var(--hl); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
iframe { display: block; width: 100%; height: 700px; border: 0; background: #fff; }
</style>
</head>
<body>
<div class="browser">
<div class="window">
<div class="chrome">
<span class="dot r"></span><span class="dot y"></span><span class="dot g"></span>
<span class="url">file:///beispiel/box-model.html</span>
</div>
<iframe src="./css-box-model.html"></iframe>
</div>
</div>
</body>
</html>
@@ -0,0 +1,58 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Box-Modell</title>
<style>
body { padding: 1.2rem; font-family: system-ui, sans-serif; background: #fff; }
.box { display: inline-block; }
.layer {
padding-top: 22px;
padding-bottom: 18px;
padding-left: 18px;
padding-right: 18px;
position: relative;
}
.layer::before {
position: absolute;
top: 4px; left: 8px;
font-size: 0.75em;
font-weight: 600;
}
.margin { background: #fde68a; }
.margin::before { content: "margin"; color: #92400e; }
.border { background: #fca5a5; }
.border::before { content: "border"; color: #991b1b; }
.padding { background: #86efac; }
.padding::before { content: "padding"; color: #166534; }
.content {
background: #93c5fd;
width: 140px;
height: 56px;
display: flex;
align-items: center;
justify-content: center;
color: #1e3a8a;
font-weight: 600;
}
pre { background: #f3f4f6; padding: 10px; border-radius: 4px; font-size: 0.85em; margin-top: 1rem; font-family: ui-monospace, monospace; }
</style>
</head>
<body>
<div class="box">
<div class="layer margin">
<div class="layer border">
<div class="layer padding">
<div class="content">content</div>
</div>
</div>
</div>
</div>
<pre>.box {
width: 140px;
padding: 18px;
border: 18px solid;
margin: 18px;
}</pre>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Preview: css-colors</title>
<style>
:root {
--hl: #d63384;
--dark: #0f0f23;
--chrome: #1a1a2e;
--muted: #4a4a6a;
}
html, body { margin: 0; padding: 0; background: var(--dark); font-family: system-ui, -apple-system, sans-serif; }
.browser { box-sizing: border-box; width: 100vw; min-height: 100vh; padding: 18px; }
.window { background: #fff; border-radius: 10px; box-shadow: 0 12px 32px rgba(0,0,0,.35); overflow: hidden; border: 2px solid var(--hl); }
.chrome { background: var(--chrome); border-bottom: 2px solid var(--hl); padding: 10px 14px; display: flex; align-items: center; gap: 7px; }
.dot { width: 11px; height: 11px; border-radius: 50%; opacity: 0.9; }
.r { background: #ff5f56; } .y { background: #ffbd2e; } .g { background: #27c93f; }
.url { flex: 1; margin-left: 12px; background: var(--dark); border: 1px solid var(--hl); border-radius: 6px; padding: 5px 10px; font: 12px/1.3 ui-monospace, "SF Mono", Menlo, monospace; color: var(--hl); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
iframe { display: block; width: 100%; height: 700px; border: 0; background: #fff; }
</style>
</head>
<body>
<div class="browser">
<div class="window">
<div class="chrome">
<span class="dot r"></span><span class="dot y"></span><span class="dot g"></span>
<span class="url">file:///beispiel/colors.html</span>
</div>
<iframe src="./css-colors.html"></iframe>
</div>
</div>
</body>
</html>
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Farben</title>
<style>
body { padding: 1.2rem; font-family: system-ui, sans-serif; font-size: 14px; }
.swatch { display: flex; align-items: center; margin-bottom: 8px; }
.chip { width: 40px; height: 40px; border-radius: 4px; margin-right: 12px; border: 1px solid #e5e7eb; }
code { background: #f3f4f6; padding: 2px 6px; border-radius: 3px; font-family: ui-monospace, monospace; font-size: 0.85em; }
</style>
</head>
<body>
<div class="swatch"><div class="chip" style="background: red;"></div><code>color: red;</code></div>
<div class="swatch"><div class="chip" style="background: rebeccapurple;"></div><code>color: rebeccapurple;</code></div>
<div class="swatch"><div class="chip" style="background: #FF0000;"></div><code>#FF0000</code></div>
<div class="swatch"><div class="chip" style="background: rgb(255, 0, 0);"></div><code>rgb(255, 0, 0)</code></div>
<div class="swatch"><div class="chip" style="background: rgba(255, 0, 0, 0.5);"></div><code>rgba(255, 0, 0, 0.5)</code></div>
<div class="swatch"><div class="chip" style="background: hsl(0, 100%, 50%);"></div><code>hsl(0, 100%, 50%)</code></div>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Preview: css-combinators</title>
<style>
:root {
--hl: #d63384;
--dark: #0f0f23;
--chrome: #1a1a2e;
--muted: #4a4a6a;
}
html, body { margin: 0; padding: 0; background: var(--dark); font-family: system-ui, -apple-system, sans-serif; }
.browser { box-sizing: border-box; width: 100vw; min-height: 100vh; padding: 18px; }
.window { background: #fff; border-radius: 10px; box-shadow: 0 12px 32px rgba(0,0,0,.35); overflow: hidden; border: 2px solid var(--hl); }
.chrome { background: var(--chrome); border-bottom: 2px solid var(--hl); padding: 10px 14px; display: flex; align-items: center; gap: 7px; }
.dot { width: 11px; height: 11px; border-radius: 50%; opacity: 0.9; }
.r { background: #ff5f56; } .y { background: #ffbd2e; } .g { background: #27c93f; }
.url { flex: 1; margin-left: 12px; background: var(--dark); border: 1px solid var(--hl); border-radius: 6px; padding: 5px 10px; font: 12px/1.3 ui-monospace, "SF Mono", Menlo, monospace; color: var(--hl); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
iframe { display: block; width: 100%; height: 700px; border: 0; background: #fff; }
</style>
</head>
<body>
<div class="browser">
<div class="window">
<div class="chrome">
<span class="dot r"></span><span class="dot y"></span><span class="dot g"></span>
<span class="url">file:///beispiel/combinators.html</span>
</div>
<iframe src="./css-combinators.html"></iframe>
</div>
</div>
</body>
</html>
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Kombinatoren</title>
<style>
body { padding: 1.2rem; font-family: system-ui, sans-serif; font-size: 14px; }
article p { line-height: 1.6; background: #fef3c7; padding: 4px; }
nav > a { text-decoration: none; color: #d63384; margin-right: 10px; font-weight: 600; }
h2 + p { font-size: 1.2em; color: #065f46; }
p.wichtig { color: red; }
</style>
</head>
<body>
<nav>
<a href="#">Link</a><a href="#">Link</a>
</nav>
<article>
<h2>Artikel-Überschrift</h2>
<p>Direkt nach h2 (größer, grün).</p>
<p>Normaler Absatz im article (gelb).</p>
<p class="wichtig">Wichtig (rot).</p>
</article>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Preview: css-pseudo-classes</title>
<style>
:root {
--hl: #d63384;
--dark: #0f0f23;
--chrome: #1a1a2e;
--muted: #4a4a6a;
}
html, body { margin: 0; padding: 0; background: var(--dark); font-family: system-ui, -apple-system, sans-serif; }
.browser { box-sizing: border-box; width: 100vw; min-height: 100vh; padding: 18px; }
.window { background: #fff; border-radius: 10px; box-shadow: 0 12px 32px rgba(0,0,0,.35); overflow: hidden; border: 2px solid var(--hl); }
.chrome { background: var(--chrome); border-bottom: 2px solid var(--hl); padding: 10px 14px; display: flex; align-items: center; gap: 7px; }
.dot { width: 11px; height: 11px; border-radius: 50%; opacity: 0.9; }
.r { background: #ff5f56; } .y { background: #ffbd2e; } .g { background: #27c93f; }
.url { flex: 1; margin-left: 12px; background: var(--dark); border: 1px solid var(--hl); border-radius: 6px; padding: 5px 10px; font: 12px/1.3 ui-monospace, "SF Mono", Menlo, monospace; color: var(--hl); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
iframe { display: block; width: 100%; height: 700px; border: 0; background: #fff; }
</style>
</head>
<body>
<div class="browser">
<div class="window">
<div class="chrome">
<span class="dot r"></span><span class="dot y"></span><span class="dot g"></span>
<span class="url">file:///beispiel/pseudo-classes.html</span>
</div>
<iframe src="./css-pseudo-classes.html"></iframe>
</div>
</div>
</body>
</html>
@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Pseudo-Klassen</title>
<style>
body { padding: 1.2rem; font-family: system-ui, sans-serif; font-size: 14px; }
a { color: #2563eb; }
a:hover, a.is-hovered { color: red; text-decoration: underline; }
a:visited, a.is-visited { color: purple; }
input:focus, input.is-focused { border-color: blue; outline: 2px solid blue; }
input { padding: 4px 8px; border: 1px solid #9ca3af; border-radius: 3px; }
ul { list-style: none; padding: 0; }
li { padding: 6px 10px; }
li:first-child, li.is-first { font-weight: bold; }
li:nth-child(odd), li.is-odd { background: #eee; }
h3 { margin: 0.6rem 0 0.3rem; font-size: 0.95rem; }
</style>
</head>
<body>
<h3>:hover / :visited</h3>
<a href="#" class="is-hovered">Link mit Hover</a> &middot;
<a href="#" class="is-visited">Besuchter Link</a>
<h3>:focus</h3>
<input class="is-focused" value="fokussiert">
<h3>:first-child, :nth-child(odd)</h3>
<ul>
<li class="is-first is-odd">Erster (bold, zebra)</li>
<li>Zweiter</li>
<li class="is-odd">Dritter (zebra)</li>
<li>Vierter</li>
<li class="is-odd">Fünfter (zebra)</li>
</ul>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Preview: css-pseudo-elements</title>
<style>
:root {
--hl: #d63384;
--dark: #0f0f23;
--chrome: #1a1a2e;
--muted: #4a4a6a;
}
html, body { margin: 0; padding: 0; background: var(--dark); font-family: system-ui, -apple-system, sans-serif; }
.browser { box-sizing: border-box; width: 100vw; min-height: 100vh; padding: 18px; }
.window { background: #fff; border-radius: 10px; box-shadow: 0 12px 32px rgba(0,0,0,.35); overflow: hidden; border: 2px solid var(--hl); }
.chrome { background: var(--chrome); border-bottom: 2px solid var(--hl); padding: 10px 14px; display: flex; align-items: center; gap: 7px; }
.dot { width: 11px; height: 11px; border-radius: 50%; opacity: 0.9; }
.r { background: #ff5f56; } .y { background: #ffbd2e; } .g { background: #27c93f; }
.url { flex: 1; margin-left: 12px; background: var(--dark); border: 1px solid var(--hl); border-radius: 6px; padding: 5px 10px; font: 12px/1.3 ui-monospace, "SF Mono", Menlo, monospace; color: var(--hl); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
iframe { display: block; width: 100%; height: 700px; border: 0; background: #fff; }
</style>
</head>
<body>
<div class="browser">
<div class="window">
<div class="chrome">
<span class="dot r"></span><span class="dot y"></span><span class="dot g"></span>
<span class="url">file:///beispiel/pseudo-elements.html</span>
</div>
<iframe src="./css-pseudo-elements.html"></iframe>
</div>
</div>
</body>
</html>
@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Pseudo-Elemente</title>
<style>
body { padding: 1.2rem; font-family: system-ui, sans-serif; font-size: 14px; }
.required::before {
content: "* ";
color: red;
}
p.drop { line-height: 1.5; }
p.drop::first-letter {
font-size: 3em;
font-weight: bold;
color: #d63384;
float: left;
line-height: 0.9;
padding-right: 6px;
padding-top: 2px;
}
label { display: block; margin-top: 10px; }
input { padding: 4px 8px; border: 1px solid #9ca3af; border-radius: 3px; margin-top: 3px; }
h3 { margin: 0.6rem 0 0.3rem; font-size: 0.95rem; }
</style>
</head>
<body>
<h3>::before (Pflichtfeld-Sternchen)</h3>
<label class="required">E-Mail-Adresse</label>
<input type="email">
<h3>::first-letter (Initial-Buchstabe)</h3>
<p class="drop">Lorem ipsum dolor sit amet. Der erste Buchstabe wird per CSS hervorgehoben – kein extra HTML nötig.</p>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

@@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Responsive Container</title>
<style>
body { padding: 0; margin: 0; font-family: system-ui, sans-serif; background: #fff; }
.container {
padding: 1rem;
background: white;
color: #111;
text-align: left;
font-weight: 600;
border: 1px solid #d1d5db;
}
.container::before { content: "< 768px — weiß, padding 1rem"; }
@media (min-width: 768px) {
.container { padding: 2rem; background: red; color: white; border: none; }
.container::before { content: "≥ 768px — rot, padding 2rem"; }
}
@media (min-width: 1024px) {
.container { background: green; }
.container::before { content: "≥ 1024px — grün"; }
}
</style>
</head>
<body>
<div class="container"></div>
</body>
</html>
@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Preview: css-responsive</title>
<style>
:root {
--hl: #d63384;
--dark: #0f0f23;
--chrome: #1a1a2e;
--muted: #4a4a6a;
}
html, body { margin: 0; padding: 0; background: var(--dark); font-family: system-ui, -apple-system, sans-serif; }
.browser { box-sizing: border-box; width: 100vw; min-height: 100vh; padding: 18px; }
.window { background: #fff; border-radius: 10px; box-shadow: 0 12px 32px rgba(0,0,0,.35); overflow: hidden; border: 2px solid var(--hl); }
.chrome { background: var(--chrome); border-bottom: 2px solid var(--hl); padding: 10px 14px; display: flex; align-items: center; gap: 7px; }
.dot { width: 11px; height: 11px; border-radius: 50%; opacity: 0.9; }
.r { background: #ff5f56; } .y { background: #ffbd2e; } .g { background: #27c93f; }
.url { flex: 1; margin-left: 12px; background: var(--dark); border: 1px solid var(--hl); border-radius: 6px; padding: 5px 10px; font: 12px/1.3 ui-monospace, "SF Mono", Menlo, monospace; color: var(--hl); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
iframe { display: block; width: 100%; height: 700px; border: 0; background: #fff; }
</style>
</head>
<body>
<div class="browser">
<div class="window">
<div class="chrome">
<span class="dot r"></span><span class="dot y"></span><span class="dot g"></span>
<span class="url">file:///beispiel/responsive.html</span>
</div>
<iframe src="./css-responsive.html"></iframe>
</div>
</div>
</body>
</html>
@@ -0,0 +1,45 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Responsive Design – 3 Viewports</title>
<style>
html, body { margin: 0; padding: 0; font-family: system-ui, sans-serif; background: #fff; }
body { padding: 1rem; }
.viewport {
margin-bottom: 12px;
border: 1px solid #9ca3af;
border-radius: 4px;
overflow: hidden;
}
.bar {
background: #e5e7eb;
padding: 4px 10px;
font-size: 11px;
color: #374151;
font-family: ui-monospace, monospace;
border-bottom: 1px solid #9ca3af;
}
iframe { display: block; width: 100%; border: 0; }
.vp-mobile iframe { width: 360px; }
.vp-tablet iframe { width: 800px; }
.vp-desktop iframe { width: 1100px; }
.vp-mobile { width: 362px; }
.scroll { overflow: hidden; }
</style>
</head>
<body>
<div class="viewport vp-mobile">
<div class="bar">Mobile @ 360px</div>
<div class="scroll"><iframe src="./css-responsive-container.html" height="80"></iframe></div>
</div>
<div class="viewport vp-tablet">
<div class="bar">Tablet @ 800px</div>
<div class="scroll" style="overflow-x: auto;"><iframe src="./css-responsive-container.html" height="100"></iframe></div>
</div>
<div class="viewport vp-desktop">
<div class="bar">Desktop @ 1100px</div>
<div class="scroll" style="overflow-x: auto;"><iframe src="./css-responsive-container.html" height="100"></iframe></div>
</div>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Preview: css-selector-class</title>
<style>
:root {
--hl: #d63384;
--dark: #0f0f23;
--chrome: #1a1a2e;
--muted: #4a4a6a;
}
html, body { margin: 0; padding: 0; background: var(--dark); font-family: system-ui, -apple-system, sans-serif; }
.browser { box-sizing: border-box; width: 100vw; min-height: 100vh; padding: 18px; }
.window { background: #fff; border-radius: 10px; box-shadow: 0 12px 32px rgba(0,0,0,.35); overflow: hidden; border: 2px solid var(--hl); }
.chrome { background: var(--chrome); border-bottom: 2px solid var(--hl); padding: 10px 14px; display: flex; align-items: center; gap: 7px; }
.dot { width: 11px; height: 11px; border-radius: 50%; opacity: 0.9; }
.r { background: #ff5f56; } .y { background: #ffbd2e; } .g { background: #27c93f; }
.url { flex: 1; margin-left: 12px; background: var(--dark); border: 1px solid var(--hl); border-radius: 6px; padding: 5px 10px; font: 12px/1.3 ui-monospace, "SF Mono", Menlo, monospace; color: var(--hl); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
iframe { display: block; width: 100%; height: 700px; border: 0; background: #fff; }
</style>
</head>
<body>
<div class="browser">
<div class="window">
<div class="chrome">
<span class="dot r"></span><span class="dot y"></span><span class="dot g"></span>
<span class="url">file:///beispiel/selector-class.html</span>
</div>
<iframe src="./css-selector-class.html"></iframe>
</div>
</div>
</body>
</html>
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Klassen-Selektor</title>
<style>
body { padding: 1.2rem; font-family: system-ui, sans-serif; }
.wichtig { color: red; font-weight: bold; }
</style>
</head>
<body>
<p class="wichtig">Dieser Text ist wichtig.</p>
<p>Dieser nicht.</p>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Preview: css-selector-element</title>
<style>
:root {
--hl: #d63384;
--dark: #0f0f23;
--chrome: #1a1a2e;
--muted: #4a4a6a;
}
html, body { margin: 0; padding: 0; background: var(--dark); font-family: system-ui, -apple-system, sans-serif; }
.browser { box-sizing: border-box; width: 100vw; min-height: 100vh; padding: 18px; }
.window { background: #fff; border-radius: 10px; box-shadow: 0 12px 32px rgba(0,0,0,.35); overflow: hidden; border: 2px solid var(--hl); }
.chrome { background: var(--chrome); border-bottom: 2px solid var(--hl); padding: 10px 14px; display: flex; align-items: center; gap: 7px; }
.dot { width: 11px; height: 11px; border-radius: 50%; opacity: 0.9; }
.r { background: #ff5f56; } .y { background: #ffbd2e; } .g { background: #27c93f; }
.url { flex: 1; margin-left: 12px; background: var(--dark); border: 1px solid var(--hl); border-radius: 6px; padding: 5px 10px; font: 12px/1.3 ui-monospace, "SF Mono", Menlo, monospace; color: var(--hl); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
iframe { display: block; width: 100%; height: 700px; border: 0; background: #fff; }
</style>
</head>
<body>
<div class="browser">
<div class="window">
<div class="chrome">
<span class="dot r"></span><span class="dot y"></span><span class="dot g"></span>
<span class="url">file:///beispiel/selector-element.html</span>
</div>
<iframe src="./css-selector-element.html"></iframe>
</div>
</div>
</body>
</html>
@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Element-Selektor</title>
<style>
body { padding: 1.2rem; }
p { color: gray; font-family: Georgia, serif; }
h1, h2, h3 { font-family: sans-serif; }
</style>
</head>
<body>
<h1>Überschrift (sans-serif)</h1>
<p>Absatz: grau, Georgia (serif).</p>
<h2>Untertitel (sans-serif)</h2>
<p>Noch ein grauer Absatz.</p>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Preview: css-selector-id</title>
<style>
:root {
--hl: #d63384;
--dark: #0f0f23;
--chrome: #1a1a2e;
--muted: #4a4a6a;
}
html, body { margin: 0; padding: 0; background: var(--dark); font-family: system-ui, -apple-system, sans-serif; }
.browser { box-sizing: border-box; width: 100vw; min-height: 100vh; padding: 18px; }
.window { background: #fff; border-radius: 10px; box-shadow: 0 12px 32px rgba(0,0,0,.35); overflow: hidden; border: 2px solid var(--hl); }
.chrome { background: var(--chrome); border-bottom: 2px solid var(--hl); padding: 10px 14px; display: flex; align-items: center; gap: 7px; }
.dot { width: 11px; height: 11px; border-radius: 50%; opacity: 0.9; }
.r { background: #ff5f56; } .y { background: #ffbd2e; } .g { background: #27c93f; }
.url { flex: 1; margin-left: 12px; background: var(--dark); border: 1px solid var(--hl); border-radius: 6px; padding: 5px 10px; font: 12px/1.3 ui-monospace, "SF Mono", Menlo, monospace; color: var(--hl); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
iframe { display: block; width: 100%; height: 700px; border: 0; background: #fff; }
</style>
</head>
<body>
<div class="browser">
<div class="window">
<div class="chrome">
<span class="dot r"></span><span class="dot y"></span><span class="dot g"></span>
<span class="url">file:///beispiel/selector-id.html</span>
</div>
<iframe src="./css-selector-id.html"></iframe>
</div>
</div>
</body>
</html>
@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>ID-Selektor</title>
<style>
body { padding: 0; margin: 0; font-family: system-ui, sans-serif; }
#hauptnavigation {
background: #333;
padding: 1rem;
color: white;
}
#hauptnavigation a { color: #fff; margin-right: 1rem; }
</style>
</head>
<body>
<nav id="hauptnavigation">
<a href="#">Home</a>
<a href="#">Kurse</a>
<a href="#">Kontakt</a>
</nav>
<p style="padding: 1rem;">Rest der Seite.</p>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Preview: css-specificity</title>
<style>
:root {
--hl: #d63384;
--dark: #0f0f23;
--chrome: #1a1a2e;
--muted: #4a4a6a;
}
html, body { margin: 0; padding: 0; background: var(--dark); font-family: system-ui, -apple-system, sans-serif; }
.browser { box-sizing: border-box; width: 100vw; min-height: 100vh; padding: 18px; }
.window { background: #fff; border-radius: 10px; box-shadow: 0 12px 32px rgba(0,0,0,.35); overflow: hidden; border: 2px solid var(--hl); }
.chrome { background: var(--chrome); border-bottom: 2px solid var(--hl); padding: 10px 14px; display: flex; align-items: center; gap: 7px; }
.dot { width: 11px; height: 11px; border-radius: 50%; opacity: 0.9; }
.r { background: #ff5f56; } .y { background: #ffbd2e; } .g { background: #27c93f; }
.url { flex: 1; margin-left: 12px; background: var(--dark); border: 1px solid var(--hl); border-radius: 6px; padding: 5px 10px; font: 12px/1.3 ui-monospace, "SF Mono", Menlo, monospace; color: var(--hl); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
iframe { display: block; width: 100%; height: 700px; border: 0; background: #fff; }
</style>
</head>
<body>
<div class="browser">
<div class="window">
<div class="chrome">
<span class="dot r"></span><span class="dot y"></span><span class="dot g"></span>
<span class="url">file:///beispiel/specificity.html</span>
</div>
<iframe src="./css-specificity.html"></iframe>
</div>
</div>
</body>
</html>
@@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Spezifität</title>
<style>
body { padding: 1.2rem; font-family: system-ui, sans-serif; }
p { color: blue; } /* 0,0,0,1 */
.text { color: green; } /* 0,0,1,0 */
#intro { color: red; } /* 0,1,0,0 */
code { background: #f3f4f6; padding: 1px 5px; border-radius: 3px; font-size: 0.9em; }
.row { margin-bottom: 10px; }
.label { color: #6b7280; font-size: 0.85em; }
</style>
</head>
<body>
<div class="row">
<p>Nur <code>p</code>: <strong>blau</strong></p>
<span class="label">0,0,0,1</span>
</div>
<div class="row">
<p class="text">Nur <code>.text</code>: <strong>grün</strong> schlägt p</p>
<span class="label">0,0,1,0 &gt; 0,0,0,1</span>
</div>
<div class="row">
<p id="intro" class="text">ID <code>#intro</code>: <strong>rot</strong> schlägt alles</p>
<span class="label">0,1,0,0 &gt; 0,0,1,0</span>
</div>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

@@ -0,0 +1,65 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Decapsulation Stack</title>
<style>
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, sans-serif; }
body { padding: 30px; display: inline-block; }
.stack { display: flex; flex-direction: column; gap: 0; }
.layer {
border: 2px solid;
border-radius: 6px;
padding: 10px 18px;
min-width: 540px;
font-size: 0.95rem;
margin-bottom: 4px;
}
.layer-name { font-weight: 700; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.05em; opacity: 0.8; }
.layer-desc { font-family: ui-monospace, monospace; margin-top: 3px; }
.check { margin-top: 3px; font-size: 0.85rem; font-style: italic; }
.http { background: #e0e7ff; border-color: #4f46e5; color: #3730a3; }
.tcp { background: #dbeafe; border-color: #1e40af; color: #1e3a8a; }
.ip { background: #dcfce7; border-color: #15803d; color: #14532d; }
.eth { background: #fed7aa; border-color: #c2410c; color: #7c2d12; }
.bit { background: #e5e7eb; border-color: #4b5563; color: #1f2937; }
.arrow {
align-self: center;
width: 0; height: 0;
border-left: 9px solid transparent;
border-right: 9px solid transparent;
border-top: 12px solid #d63384;
margin: 2px 0;
}
</style>
</head>
<body>
<div class="stack">
<div class="layer bit">
<div class="layer-name">Physical</div>
<div class="layer-desc">Bits empfangen</div>
</div>
<div class="arrow"></div>
<div class="layer eth">
<div class="layer-name">Ethernet-Frame</div>
<div class="check">MAC = meine MAC? ✓ auspacken</div>
</div>
<div class="arrow"></div>
<div class="layer ip">
<div class="layer-name">IP-Paket</div>
<div class="check">Ziel-IP = meine IP? ✓ auspacken</div>
</div>
<div class="arrow"></div>
<div class="layer tcp">
<div class="layer-name">TCP-Segment</div>
<div class="check">Port 52431 = mein Browser? ✓ auspacken</div>
</div>
<div class="arrow"></div>
<div class="layer http">
<div class="layer-name">HTTP-Response</div>
<div class="layer-desc">"HTTP/1.1 200 OK ..."</div>
<div class="check">→ Browser rendert Seite</div>
</div>
</div>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Preview: details-closed</title>
<style>
:root {
--hl: #d63384;
--dark: #0f0f23;
--chrome: #1a1a2e;
--muted: #4a4a6a;
}
html, body { margin: 0; padding: 0; background: var(--dark); font-family: system-ui, -apple-system, sans-serif; }
.browser { box-sizing: border-box; width: 100vw; min-height: 100vh; padding: 18px; }
.window { background: #fff; border-radius: 10px; box-shadow: 0 12px 32px rgba(0,0,0,.35); overflow: hidden; border: 2px solid var(--hl); }
.chrome { background: var(--chrome); border-bottom: 2px solid var(--hl); padding: 10px 14px; display: flex; align-items: center; gap: 7px; }
.dot { width: 11px; height: 11px; border-radius: 50%; opacity: 0.9; }
.r { background: #ff5f56; } .y { background: #ffbd2e; } .g { background: #27c93f; }
.url { flex: 1; margin-left: 12px; background: var(--dark); border: 1px solid var(--hl); border-radius: 6px; padding: 5px 10px; font: 12px/1.3 ui-monospace, "SF Mono", Menlo, monospace; color: var(--hl); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
iframe { display: block; width: 100%; height: 700px; border: 0; background: #fff; }
</style>
</head>
<body>
<div class="browser">
<div class="window">
<div class="chrome">
<span class="dot r"></span><span class="dot y"></span><span class="dot g"></span>
<span class="url">file:///beispiel/details.html</span>
</div>
<iframe src="./details-closed.html"></iframe>
</div>
</div>
</body>
</html>
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Details/Summary</title>
</head>
<body>
<details>
<summary>Klick mich!</summary>
<p>Dieser Text war versteckt.</p>
</details>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Preview: details-open</title>
<style>
:root {
--hl: #d63384;
--dark: #0f0f23;
--chrome: #1a1a2e;
--muted: #4a4a6a;
}
html, body { margin: 0; padding: 0; background: var(--dark); font-family: system-ui, -apple-system, sans-serif; }
.browser { box-sizing: border-box; width: 100vw; min-height: 100vh; padding: 18px; }
.window { background: #fff; border-radius: 10px; box-shadow: 0 12px 32px rgba(0,0,0,.35); overflow: hidden; border: 2px solid var(--hl); }
.chrome { background: var(--chrome); border-bottom: 2px solid var(--hl); padding: 10px 14px; display: flex; align-items: center; gap: 7px; }
.dot { width: 11px; height: 11px; border-radius: 50%; opacity: 0.9; }
.r { background: #ff5f56; } .y { background: #ffbd2e; } .g { background: #27c93f; }
.url { flex: 1; margin-left: 12px; background: var(--dark); border: 1px solid var(--hl); border-radius: 6px; padding: 5px 10px; font: 12px/1.3 ui-monospace, "SF Mono", Menlo, monospace; color: var(--hl); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
iframe { display: block; width: 100%; height: 700px; border: 0; background: #fff; }
</style>
</head>
<body>
<div class="browser">
<div class="window">
<div class="chrome">
<span class="dot r"></span><span class="dot y"></span><span class="dot g"></span>
<span class="url">file:///beispiel/details.html</span>
</div>
<iframe src="./details-open.html"></iframe>
</div>
</div>
</body>
</html>
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Details/Summary (offen)</title>
</head>
<body>
<details open>
<summary>Klick mich!</summary>
<p>Dieser Text war versteckt.</p>
</details>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Preview: dialog</title>
<style>
:root {
--hl: #d63384;
--dark: #0f0f23;
--chrome: #1a1a2e;
--muted: #4a4a6a;
}
html, body { margin: 0; padding: 0; background: var(--dark); font-family: system-ui, -apple-system, sans-serif; }
.browser { box-sizing: border-box; width: 100vw; min-height: 100vh; padding: 18px; }
.window { background: #fff; border-radius: 10px; box-shadow: 0 12px 32px rgba(0,0,0,.35); overflow: hidden; border: 2px solid var(--hl); }
.chrome { background: var(--chrome); border-bottom: 2px solid var(--hl); padding: 10px 14px; display: flex; align-items: center; gap: 7px; }
.dot { width: 11px; height: 11px; border-radius: 50%; opacity: 0.9; }
.r { background: #ff5f56; } .y { background: #ffbd2e; } .g { background: #27c93f; }
.url { flex: 1; margin-left: 12px; background: var(--dark); border: 1px solid var(--hl); border-radius: 6px; padding: 5px 10px; font: 12px/1.3 ui-monospace, "SF Mono", Menlo, monospace; color: var(--hl); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
iframe { display: block; width: 100%; height: 700px; border: 0; background: #fff; }
</style>
</head>
<body>
<div class="browser">
<div class="window">
<div class="chrome">
<span class="dot r"></span><span class="dot y"></span><span class="dot g"></span>
<span class="url">file:///beispiel/dialog.html</span>
</div>
<iframe src="./dialog.html"></iframe>
</div>
</div>
</body>
</html>
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Dialog</title>
</head>
<body>
<dialog open>
<p>Greetings, one and all!</p>
<form method="dialog">
<button>OK</button>
</form>
</dialog>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

@@ -0,0 +1,129 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>DNS-Lookup Sequence</title>
<style>
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, sans-serif; }
body { padding: 30px; display: inline-block; }
.diagram { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; min-width: 900px; }
.actor {
background: #1a1a2e;
color: #fff;
padding: 10px;
text-align: center;
border-radius: 4px;
font-weight: 700;
font-size: 0.85rem;
}
.lifeline {
border-left: 2px dashed #9ca3af;
margin-left: 50%;
height: 480px;
position: relative;
}
.msg {
position: absolute;
padding: 6px 10px;
background: #f3f4f6;
border: 1px solid #4a4a6a;
border-radius: 4px;
font-size: 0.8rem;
white-space: nowrap;
}
.arrow-right {
position: absolute;
height: 2px;
background: #d63384;
}
.arrow-right::after {
content: "";
position: absolute;
right: -1px; top: -4px;
border-left: 8px solid #d63384;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
}
.arrow-left {
position: absolute;
height: 2px;
background: #15803d;
}
.arrow-left::before {
content: "";
position: absolute;
left: -1px; top: -4px;
border-right: 8px solid #15803d;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
}
.arrow-label {
position: absolute;
font-size: 0.75rem;
background: #fff;
padding: 1px 5px;
white-space: nowrap;
}
.ask { color: #7c2d12; }
.reply { color: #14532d; font-style: italic; }
</style>
</head>
<body>
<div class="diagram">
<div class="actor">Ihr Laptop</div>
<div class="actor">Resolver</div>
<div class="actor">Root (.)</div>
<div class="actor">.de-Server</div>
<div class="actor">HdM-NS</div>
<!-- lifelines (5 cols) -->
<div style="position: relative; grid-column: 1 / span 5; height: 520px;">
<!-- vertical dashed lines per actor at 10%, 30%, 50%, 70%, 90% -->
<div style="position: absolute; left: 10%; top: 0; bottom: 0; border-left: 2px dashed #9ca3af;"></div>
<div style="position: absolute; left: 30%; top: 0; bottom: 0; border-left: 2px dashed #9ca3af;"></div>
<div style="position: absolute; left: 50%; top: 0; bottom: 0; border-left: 2px dashed #9ca3af;"></div>
<div style="position: absolute; left: 70%; top: 0; bottom: 0; border-left: 2px dashed #9ca3af;"></div>
<div style="position: absolute; left: 90%; top: 0; bottom: 0; border-left: 2px dashed #9ca3af;"></div>
<!-- Laptop → Resolver at y=20 -->
<div style="position: absolute; left: 10%; top: 20px; width: 20%; height: 2px; background: #d63384;"></div>
<div style="position: absolute; left: 30%; top: 16px; transform: translateX(-100%);"><div style="border-left: 8px solid #d63384; border-top: 5px solid transparent; border-bottom: 5px solid transparent;"></div></div>
<div style="position: absolute; left: 12%; top: 0; font-size: 0.75rem; color: #7c2d12;">"Wo ist www.hdm-stuttgart.de?"</div>
<!-- Resolver → Root at y=90 -->
<div style="position: absolute; left: 30%; top: 90px; width: 20%; height: 2px; background: #d63384;"></div>
<div style="position: absolute; left: 50%; top: 86px; transform: translateX(-100%);"><div style="border-left: 8px solid #d63384; border-top: 5px solid transparent; border-bottom: 5px solid transparent;"></div></div>
<div style="position: absolute; left: 32%; top: 70px; font-size: 0.75rem; color: #7c2d12;">"Wer verwaltet .de?"</div>
<!-- Root → Resolver at y=150 -->
<div style="position: absolute; left: 30%; top: 150px; width: 20%; height: 2px; background: #15803d;"></div>
<div style="position: absolute; left: 30%; top: 146px;"><div style="border-right: 8px solid #15803d; border-top: 5px solid transparent; border-bottom: 5px solid transparent;"></div></div>
<div style="position: absolute; left: 32%; top: 130px; font-size: 0.75rem; color: #14532d; font-style: italic;">"Frag 194.0.0.53"</div>
<!-- Resolver → .de at y=220 -->
<div style="position: absolute; left: 30%; top: 220px; width: 40%; height: 2px; background: #d63384;"></div>
<div style="position: absolute; left: 70%; top: 216px; transform: translateX(-100%);"><div style="border-left: 8px solid #d63384; border-top: 5px solid transparent; border-bottom: 5px solid transparent;"></div></div>
<div style="position: absolute; left: 32%; top: 200px; font-size: 0.75rem; color: #7c2d12;">"Wer verwaltet hdm-stuttgart.de?"</div>
<!-- .de → Resolver at y=280 -->
<div style="position: absolute; left: 30%; top: 280px; width: 40%; height: 2px; background: #15803d;"></div>
<div style="position: absolute; left: 30%; top: 276px;"><div style="border-right: 8px solid #15803d; border-top: 5px solid transparent; border-bottom: 5px solid transparent;"></div></div>
<div style="position: absolute; left: 32%; top: 260px; font-size: 0.75rem; color: #14532d; font-style: italic;">"Frag Nameserver der HdM"</div>
<!-- Resolver → HdM at y=350 -->
<div style="position: absolute; left: 30%; top: 350px; width: 60%; height: 2px; background: #d63384;"></div>
<div style="position: absolute; left: 90%; top: 346px; transform: translateX(-100%);"><div style="border-left: 8px solid #d63384; border-top: 5px solid transparent; border-bottom: 5px solid transparent;"></div></div>
<div style="position: absolute; left: 32%; top: 330px; font-size: 0.75rem; color: #7c2d12;">"Welche IP hat www?"</div>
<!-- HdM → Resolver at y=410 -->
<div style="position: absolute; left: 30%; top: 410px; width: 60%; height: 2px; background: #15803d;"></div>
<div style="position: absolute; left: 30%; top: 406px;"><div style="border-right: 8px solid #15803d; border-top: 5px solid transparent; border-bottom: 5px solid transparent;"></div></div>
<div style="position: absolute; left: 32%; top: 390px; font-size: 0.75rem; color: #14532d; font-style: italic;">"212.132.79.37"</div>
<!-- Resolver → Laptop at y=480 -->
<div style="position: absolute; left: 10%; top: 480px; width: 20%; height: 2px; background: #15803d;"></div>
<div style="position: absolute; left: 10%; top: 476px;"><div style="border-right: 8px solid #15803d; border-top: 5px solid transparent; border-bottom: 5px solid transparent;"></div></div>
<div style="position: absolute; left: 12%; top: 460px; font-size: 0.75rem; color: #14532d; font-style: italic;">"IP ist 212.132.79.37"</div>
</div>
</div>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

@@ -0,0 +1,62 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>DNS-Hierarchie</title>
<style>
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, sans-serif; }
body { padding: 20px; display: inline-block; }
svg { display: block; }
.node rect { fill: #fef3c7; stroke: #ca8a04; stroke-width: 2; rx: 6; }
.node.root rect { fill: #fde68a; stroke: #b45309; }
.node.leaf rect { fill: #dbeafe; stroke: #1e40af; }
.node text { font-family: ui-monospace, monospace; font-weight: 700; font-size: 15px; fill: #713f12; }
.node.leaf text { fill: #1e3a8a; }
.line { stroke: #d63384; stroke-width: 2; fill: none; }
</style>
</head>
<body>
<svg width="620" height="520" viewBox="0 0 620 520">
<!-- Root -->
<g class="node root">
<rect x="250" y="10" width="120" height="44"/>
<text x="310" y="38" text-anchor="middle">. (Root)</text>
</g>
<!-- Lines from Root to .de, .com, .org -->
<line class="line" x1="310" y1="54" x2="70" y2="120"/>
<line class="line" x1="310" y1="54" x2="310" y2="120"/>
<line class="line" x1="310" y1="54" x2="550" y2="120"/>
<!-- .de -->
<g class="node">
<rect x="20" y="120" width="100" height="44"/>
<text x="70" y="148" text-anchor="middle">.de</text>
</g>
<!-- .com -->
<g class="node">
<rect x="260" y="120" width="100" height="44"/>
<text x="310" y="148" text-anchor="middle">.com</text>
</g>
<!-- .org -->
<g class="node">
<rect x="500" y="120" width="100" height="44"/>
<text x="550" y="148" text-anchor="middle">.org</text>
</g>
<!-- Line .de → hdm-stuttgart -->
<line class="line" x1="70" y1="164" x2="70" y2="210"/>
<line class="line" x1="70" y1="210" x2="220" y2="210"/>
<line class="line" x1="220" y1="210" x2="220" y2="250"/>
<!-- hdm-stuttgart -->
<g class="node">
<rect x="120" y="250" width="200" height="44"/>
<text x="220" y="278" text-anchor="middle">hdm-stuttgart</text>
</g>
<!-- Line hdm → www -->
<line class="line" x1="220" y1="294" x2="220" y2="340"/>
<!-- www -->
<g class="node leaf">
<rect x="170" y="340" width="100" height="44"/>
<text x="220" y="368" text-anchor="middle">www</text>
</g>
</svg>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

@@ -0,0 +1,55 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>DOM-Baum</title>
<style>
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, sans-serif; }
body { padding: 30px; display: inline-block; }
.tree { display: flex; flex-direction: column; align-items: center; }
.node {
background: #dbeafe;
border: 2px solid #1e40af;
color: #1e3a8a;
padding: 7px 16px;
border-radius: 6px;
font-family: ui-monospace, monospace;
font-weight: 700;
font-size: 0.9rem;
}
.root { background: #e0e7ff; border-color: #4f46e5; color: #3730a3; }
.content { background: #dcfce7; border-color: #15803d; color: #14532d; font-weight: 400; font-style: italic; }
.level { display: flex; gap: 28px; margin-top: 10px; align-items: flex-start; }
.col { display: flex; flex-direction: column; align-items: center; }
</style>
</head>
<body>
<div class="tree">
<div class="node root">document</div>
<svg width="200" height="24"><line x1="100" y1="0" x2="100" y2="24" stroke="#d63384" stroke-width="2"/></svg>
<div class="node root">&lt;html&gt;</div>
<svg width="380" height="26">
<line x1="190" y1="0" x2="90" y2="26" stroke="#d63384" stroke-width="2"/>
<line x1="190" y1="0" x2="290" y2="26" stroke="#d63384" stroke-width="2"/>
</svg>
<div class="level">
<div class="col">
<div class="node">&lt;head&gt;</div>
<svg width="120" height="22"><line x1="60" y1="0" x2="60" y2="22" stroke="#d63384" stroke-width="2"/></svg>
<div class="node">&lt;title&gt;</div>
</div>
<div class="col">
<div class="node">&lt;body&gt;</div>
<svg width="220" height="26">
<line x1="110" y1="0" x2="55" y2="26" stroke="#d63384" stroke-width="2"/>
<line x1="110" y1="0" x2="165" y2="26" stroke="#d63384" stroke-width="2"/>
</svg>
<div class="level">
<div class="node">&lt;h1&gt;</div>
<div class="node">&lt;p&gt;</div>
</div>
</div>
</div>
</div>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Loaded 100 of 467 files, more files were not shown because too many files have changed in this diff. Show more