diff --git a/api.html b/api.html
new file mode 100644
index 0000000..499f0b9
--- /dev/null
+++ b/api.html
@@ -0,0 +1,143 @@
+
+
+
+
+
+
+ API Demo β David & Karo
+
+
+
+
+
+
+
+
+ π fetch & API Demo
+ Live-Daten von jsonplaceholder.typicode.com/users β geladen per JavaScript fetch(). β¨
+
+
+
+ π‘ Wie funktioniert's?
+
+
+
1οΈβ£ fetch(URL)
+
JavaScript sendet einen HTTP-GET Request an die API-URL und erhΓ€lt eine Promise zurΓΌck.
+
+
+
2οΈβ£ .then(r => r.json())
+
Die Antwort wird als JSON geparst β aus Text werden echte JavaScript-Objekte.
+
+
+
3οΈβ£ DOM rendern
+
Die Daten werden mit createElement in den DOM eingefΓΌgt β kein Reload nΓΆtig!
+
+
+
4οΈβ£ .catch(err)
+
Fehlerbehandlung: Falls die API nicht erreichbar ist, wird eine Fehlermeldung angezeigt.
+
+
+
+
+
+ π₯ Benutzer von der API
+ Die Liste wird live beim Laden der Seite von jsonplaceholder.typicode.com abgerufen:
+
+
+
+
+
+
+
+
+
+
Daten werden geladenβ¦
+
+
+
+
+
β
+
+ Fehler beim Laden der Daten.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ π Quellcode-ErklΓ€rung
+ // 1. fetch aufrufen
+fetch('https://jsonplaceholder.typicode.com/users')
+
+ // 2. Antwort als JSON parsen
+ .then(response => {
+ if (!response.ok) {
+ throw new Error('HTTP ' + response.status);
+ }
+ return response.json();
+ })
+
+ // 3. Daten in console.log prΓΌfen & im DOM rendern
+ .then(users => {
+ console.log('API-Daten:', users);
+ renderUsers(users);
+ })
+
+ // 4. Fehlerbehandlung
+ .catch(error => {
+ console.error('Fetch-Fehler:', error);
+ showApiError(error.message);
+ });
+
+
+
+
+
+
+
+
+
diff --git a/css/style.css b/css/style.css
index 95d4304..c09542e 100644
--- a/css/style.css
+++ b/css/style.css
@@ -2926,3 +2926,264 @@ body.dark .nav-toggle span {
text-align: center;
}
}
+
+/* βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+ API Demo β api.html
+ βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */
+
+/* Info-Cards (ErklΓ€rung wie fetch funktioniert) */
+.info-cards {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+ gap: 1.25rem;
+ margin: 1.5rem 0;
+}
+
+.info-card {
+ background: linear-gradient(135deg, #fff0f5, #fce7f3);
+ border: 1px solid #f9a8d4;
+ border-radius: 12px;
+ padding: 1.25rem;
+ text-align: center;
+}
+
+.info-card h4 {
+ color: #be185d;
+ margin-bottom: 0.5rem;
+ font-size: 1rem;
+}
+
+.info-card p {
+ font-size: 0.9rem;
+ color: #555;
+ margin: 0;
+}
+
+.info-card code {
+ background: #fce7f3;
+ padding: 0.1em 0.35em;
+ border-radius: 4px;
+ font-size: 0.85em;
+ color: #be185d;
+}
+
+/* API Controls (Button + Suchfeld) */
+.api-controls {
+ display: flex;
+ gap: 1rem;
+ align-items: center;
+ flex-wrap: wrap;
+ margin: 1.25rem 0;
+}
+
+#api-search {
+ flex: 1 1 220px;
+ padding: 0.6rem 1rem;
+ border: 2px solid #f9a8d4;
+ border-radius: 25px;
+ font-size: 0.95rem;
+ outline: none;
+ transition: border-color 0.2s;
+}
+
+#api-search:focus {
+ border-color: #ec4899;
+}
+
+/* Lade-Indikator */
+.api-loading {
+ display: flex;
+ align-items: center;
+ gap: 1rem;
+ padding: 1.5rem;
+ color: #be185d;
+}
+
+.api-loading[hidden] { display: none; }
+
+.api-spinner {
+ width: 32px;
+ height: 32px;
+ border: 4px solid #fce7f3;
+ border-top-color: #ec4899;
+ border-radius: 50%;
+ animation: spin 0.8s linear infinite;
+ flex-shrink: 0;
+}
+
+@keyframes spin {
+ to { transform: rotate(360deg); }
+}
+
+/* Fehlermeldung */
+.api-error {
+ display: flex;
+ align-items: flex-start;
+ gap: 1rem;
+ background: #fff0f0;
+ border: 1px solid #fca5a5;
+ border-radius: 10px;
+ padding: 1rem 1.25rem;
+ color: #b91c1c;
+ margin: 1rem 0;
+}
+
+.api-error[hidden] { display: none; }
+
+.api-error span:first-child {
+ font-size: 1.5rem;
+ flex-shrink: 0;
+}
+
+/* Benutzer-Liste */
+.user-list {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
+ gap: 1.25rem;
+}
+
+/* User-Karte */
+.api-user-card {
+ background: #fff;
+ border: 1px solid #f9a8d4;
+ border-radius: 14px;
+ padding: 1.25rem;
+ display: flex;
+ gap: 1rem;
+ align-items: flex-start;
+ box-shadow: 0 2px 8px rgba(236,72,153,0.08);
+ transition: transform 0.2s, box-shadow 0.2s;
+}
+
+.api-user-card:hover {
+ transform: translateY(-3px);
+ box-shadow: 0 6px 18px rgba(236,72,153,0.15);
+}
+
+.api-user-avatar {
+ width: 48px;
+ height: 48px;
+ background: linear-gradient(135deg, #ec4899, #be185d);
+ color: #fff;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 1.3rem;
+ font-weight: 700;
+ flex-shrink: 0;
+}
+
+.api-user-name {
+ font-size: 1rem;
+ font-weight: 700;
+ color: #be185d;
+ margin: 0 0 0.15rem;
+}
+
+.api-user-username {
+ font-size: 0.85rem;
+ color: #888;
+ margin: 0 0 0.5rem;
+}
+
+.api-user-details {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ font-size: 0.85rem;
+ color: #444;
+ display: flex;
+ flex-direction: column;
+ gap: 0.2rem;
+}
+
+.api-user-details a {
+ color: #ec4899;
+ text-decoration: none;
+}
+
+.api-user-details a:hover {
+ text-decoration: underline;
+}
+
+/* Ergebnis-ZΓ€hler */
+.api-count {
+ text-align: right;
+ font-size: 0.9rem;
+ color: #888;
+ margin-top: 0.75rem;
+}
+
+/* Keine Ergebnisse */
+.api-no-results {
+ grid-column: 1 / -1;
+ text-align: center;
+ padding: 2rem;
+ color: #aaa;
+ font-size: 1rem;
+}
+
+/* Code-Block */
+.code-block {
+ background: #1e1e2e;
+ color: #cdd6f4;
+ border-radius: 12px;
+ padding: 1.5rem;
+ overflow-x: auto;
+ font-size: 0.88rem;
+ line-height: 1.65;
+ border: 1px solid #313244;
+}
+
+.code-block code {
+ font-family: 'Courier New', Courier, monospace;
+}
+
+/* ββ Dark Mode ββ */
+body.dark .info-card {
+ background: linear-gradient(135deg, #1e1e2e, #2d2d3f);
+ border-color: #7c3aed44;
+}
+
+body.dark .info-card h4 { color: #f9a8d4; }
+body.dark .info-card p { color: #aaa; }
+body.dark .info-card code {
+ background: #2d2d3f;
+ color: #f9a8d4;
+}
+
+body.dark #api-search {
+ background: #1e1e2e;
+ color: #f0f0f0;
+ border-color: #7c3aed55;
+}
+
+body.dark .api-loading { color: #f9a8d4; }
+body.dark .api-spinner { border-color: #333; border-top-color: #f9a8d4; }
+
+body.dark .api-error {
+ background: #2d1515;
+ border-color: #7f1d1d;
+ color: #fca5a5;
+}
+
+body.dark .api-user-card {
+ background: #1e1e2e;
+ border-color: #7c3aed44;
+}
+
+body.dark .api-user-name { color: #f9a8d4; }
+body.dark .api-user-username { color: #777; }
+body.dark .api-user-details { color: #ccc; }
+body.dark .api-user-details a { color: #f9a8d4; }
+
+/* ββ Responsive ββ */
+@media (max-width: 600px) {
+ .api-controls { flex-direction: column; align-items: stretch; }
+ #api-search { flex: unset; width: 100%; }
+ .user-list { grid-template-columns: 1fr; }
+}
diff --git a/eis_projekt.html b/eis_projekt.html
index 02247a3..7a0c2ad 100644
--- a/eis_projekt.html
+++ b/eis_projekt.html
@@ -34,6 +34,7 @@
Galerie
Notenrechner
Textanalyse
+ API Demo
Kontakt
Impressum
@@ -175,7 +176,8 @@
© 2026 β Made with π & β¨ β David & Karo
diff --git a/galerie.html b/galerie.html
index fc605c9..49014fe 100644
--- a/galerie.html
+++ b/galerie.html
@@ -34,6 +34,7 @@
Galerie
Notenrechner
Textanalyse
+ API Demo
Kontakt
Impressum
@@ -87,7 +88,8 @@
© 2026 β Made with π & β¨ β David & Karo
diff --git a/impressum.html b/impressum.html
index 434543b..b757496 100644
--- a/impressum.html
+++ b/impressum.html
@@ -34,6 +34,7 @@
Galerie
Notenrechner
Textanalyse
+ API Demo
Kontakt
Impressum
@@ -117,7 +118,8 @@
© 2026 β Made with π & β¨ β David & Karo
diff --git a/index.html b/index.html
index 498803f..106353a 100644
--- a/index.html
+++ b/index.html
@@ -34,6 +34,7 @@
Galerie
Notenrechner
Textanalyse
+ API Demo
Kontakt
Impressum
@@ -87,7 +88,8 @@
© 2026 β Made with π & β¨ β David & Karo
diff --git a/js/api-demo.js b/js/api-demo.js
new file mode 100644
index 0000000..861bdd2
--- /dev/null
+++ b/js/api-demo.js
@@ -0,0 +1,169 @@
+/**
+ * api-demo.js
+ * Fetch & API Demo β jsonplaceholder.typicode.com/users
+ * LΓ€dt Benutzer per fetch(), rendert sie im DOM, mit Fehlerbehandlung & Filterung.
+ */
+
+document.addEventListener('DOMContentLoaded', function () {
+ // ββ DOM-Referenzen ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+ const userList = document.getElementById('user-list');
+ const loadingEl = document.getElementById('api-loading');
+ const errorEl = document.getElementById('api-error');
+ const errorMsgEl = document.getElementById('api-error-msg');
+ const countEl = document.getElementById('user-count');
+ const searchInput = document.getElementById('api-search');
+ const btnReload = document.getElementById('btn-reload');
+ const btnRetry = document.getElementById('btn-retry');
+
+ // Nur auf der API-Demo-Seite ausfΓΌhren
+ if (!userList) return;
+
+ // Alle geladenen User merken (fΓΌr Client-seitigen Filter)
+ let allUsers = [];
+
+ // ββ Hilfsfunktionen βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+
+ /** Zeigt den Lade-Spinner */
+ function showLoading () {
+ loadingEl.removeAttribute('hidden');
+ errorEl.setAttribute('hidden', '');
+ userList.innerHTML = '';
+ countEl.textContent = '';
+ if (btnReload) btnReload.disabled = true;
+ }
+
+ /** Versteckt den Lade-Spinner */
+ function hideLoading () {
+ loadingEl.setAttribute('hidden', '');
+ if (btnReload) btnReload.disabled = false;
+ }
+
+ /** Zeigt eine Fehlermeldung an */
+ function showApiError (message) {
+ hideLoading();
+ errorMsgEl.textContent = message;
+ errorEl.removeAttribute('hidden');
+ countEl.textContent = '';
+ }
+
+ /**
+ * Erstellt eine User-Karte als -Element
+ * @param {Object} user β JSON-Objekt aus der API
+ * @returns {HTMLLIElement}
+ */
+ function createUserCard (user) {
+ const li = document.createElement('li');
+ li.className = 'api-user-card';
+ li.innerHTML = `
+
+ ${user.name.charAt(0).toUpperCase()}
+
+
+
${user.name}
+
@${user.username}
+
+
+ `;
+ return li;
+ }
+
+ /**
+ * Rendert eine Liste von Usern in den DOM
+ * @param {Array} users
+ */
+ function renderUsers (users) {
+ userList.innerHTML = '';
+
+ if (users.length === 0) {
+ userList.innerHTML = 'Keine Benutzer gefunden. π';
+ countEl.textContent = '';
+ return;
+ }
+
+ // DocumentFragment fΓΌr performantes EinfΓΌgen (ein Reflow statt n)
+ const fragment = document.createDocumentFragment();
+ users.forEach(function (user) {
+ fragment.appendChild(createUserCard(user));
+ });
+ userList.appendChild(fragment);
+
+ countEl.textContent = users.length + ' Benutzer geladen β
';
+ }
+
+ // ββ Haupt-Fetch-Funktion ββββββββββββββββββββββββββββββββββββββββββββββββββ
+
+ function loadUsers () {
+ showLoading();
+
+ // β fetch() aufrufen
+ fetch('https://jsonplaceholder.typicode.com/users')
+
+ // β‘ Antwort prΓΌfen & als JSON parsen
+ .then(function (response) {
+ if (!response.ok) {
+ throw new Error('HTTP-Fehler: ' + response.status + ' ' + response.statusText);
+ }
+ return response.json();
+ })
+
+ // β’ Daten verarbeiten & im DOM rendern
+ .then(function (users) {
+ console.log('β
API-Antwort erhalten:', users);
+ console.table(users.map(function (u) {
+ return { Name: u.name, 'E-Mail': u.email, Stadt: u.address.city, Firma: u.company.name };
+ }));
+
+ allUsers = users;
+ hideLoading();
+ renderUsers(allUsers);
+
+ // Suchfeld zurΓΌcksetzen
+ if (searchInput) searchInput.value = '';
+ })
+
+ // β£ Fehlerbehandlung
+ .catch(function (err) {
+ console.error('β Fetch-Fehler:', err);
+ showApiError(err.message || 'Unbekannter Fehler. Bitte Internetverbindung prΓΌfen.');
+ });
+ }
+
+ // ββ Client-seitiger Filter ββββββββββββββββββββββββββββββββββββββββββββββββ
+
+ function filterUsers (query) {
+ if (!query.trim()) {
+ renderUsers(allUsers);
+ return;
+ }
+ const q = query.toLowerCase();
+ const filtered = allUsers.filter(function (user) {
+ return (
+ user.name.toLowerCase().includes(q) ||
+ user.username.toLowerCase().includes(q) ||
+ user.address.city.toLowerCase().includes(q) ||
+ user.company.name.toLowerCase().includes(q) ||
+ user.email.toLowerCase().includes(q)
+ );
+ });
+ renderUsers(filtered);
+ }
+
+ // ββ Event Listener ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+
+ if (btnReload) btnReload.addEventListener('click', loadUsers);
+ if (btnRetry) btnRetry.addEventListener('click', loadUsers);
+
+ if (searchInput) {
+ searchInput.addEventListener('input', function () {
+ filterUsers(this.value);
+ });
+ }
+
+ // ββ Beim Seitenaufruf automatisch laden βββββββββββββββββββββββββββββββββββ
+ loadUsers();
+});
diff --git a/kontakt.html b/kontakt.html
index a2b736f..9e8afea 100644
--- a/kontakt.html
+++ b/kontakt.html
@@ -127,7 +127,8 @@
© 2026 β Made with π & β¨ β David & Karo
diff --git a/notenrechner.html b/notenrechner.html
index ad094da..75c16ee 100644
--- a/notenrechner.html
+++ b/notenrechner.html
@@ -34,6 +34,7 @@
Galerie
Notenrechner
Textanalyse
+ API Demo
Kontakt
Impressum
diff --git a/team.html b/team.html
index 2fb444d..b2cf778 100644
--- a/team.html
+++ b/team.html
@@ -34,6 +34,7 @@
Galerie
Notenrechner
Textanalyse
+ API Demo
Kontakt
Impressum
diff --git a/textanalyse.html b/textanalyse.html
index ac2f784..69f14ff 100644
--- a/textanalyse.html
+++ b/textanalyse.html
@@ -34,6 +34,7 @@
Galerie
Notenrechner
Textanalyse
+ API Demo
Kontakt
Impressum
diff --git a/ueber_uns.html b/ueber_uns.html
index cd64910..bce70bc 100644
--- a/ueber_uns.html
+++ b/ueber_uns.html
@@ -34,6 +34,7 @@
Galerie
Notenrechner
Textanalyse
+ API Demo
Kontakt
Impressum
@@ -108,7 +109,8 @@
© 2026 β Made with π & β¨ β David & Karo