diff --git a/README.md b/README.md
index 5bd9c39..0caf72c 100644
--- a/README.md
+++ b/README.md
@@ -1,639 +1,639 @@
-# DHBW 2025: Web Engineering Prüfungsleistung
-**Maximale Punktzahl: 100 Punkte**
-
----
-
-## 1. Grundanforderungen (25 Punkte)
-
-### Projektgrundlagen (15 Punkte)
-- **Funktionsfähige Anwendung** (8 Punkte)
- - Webapp oder Backend-Anwendung läuft fehlerfrei
- - Kernfunktionalitäten sind in der Projektdokumentation beschrieben und testbar
-- **Repository** (4 Punkte)
- - GitHub/GitLab/CodeBerg Repository ist (öffentlich) zugänglich
- - Commit-Historie zeigt kontinuierliche Entwicklung
-- **Projektdokumentation** (3 Punkte)
- - Aussagekräftiger Projekttitel und Beschreibung
- - README.md mit Installation, Verwendung und Technologie-Stack
- - Kurze Erklärung der Hauptfunktionen am Anfang relevanter Dateien
-
-### Präsentation (20 Punkte)
-- **Elevator Pitch** (5 Punkte)
- - Maximal 1 Minute
- - Welches Problem wird gelöst und warum wurde es vorher noch nicht gelöst?
- - Zielgruppe definiert
-- **Technische Präsentation** (5 Punkte)
- - PowerPoint/Folien mit Technologie-Stack
- - Live-Demo der Anwendung
-- **Projektevolution:** (5 Punkte)
- Jedes Projekt verläuft unterschiedlich.
- Sofern es zutrifft, beschreibt die unterschiedlichen Phasen des Projekts.
- *Wie weit seid ihr gekommen? Wo waren die Stolpersteine? Wie könnte sich eure Anwendung bei fortgesetzter Arbeit entwickeln?*
-
- 0. (Paper) Prototype
- 1. Make it work (PoC)
- 2. Make it right (MvP)
- 3. Make it fast (Production)
-
----
-
-## 2. Clean Code Prinzipien (35 Punkte)
-
-### Projektstruktur (10 Punkte)
-- **Ordnerstruktur** (5 Punkte)
- ```
- projekt/
- ├── src/
- │ ├── components/ # React Components / UI
- │ ├── config/ # Konfigurationen, Hard-coded Strings etc.
- │ ├── services/ # Separitiere für-sich-stehende Funktionen Klassen, Clients etc.
- │ ├── utils/ # Hilfsfunktionen
- │ ├── main.css # Haupteinstieg in CSS Klassen, Variablen, Imports etc.
- │ ├── main.js # Die eigentliche Appliktion
- │ └── index.js # Haupteinstieg in die gesamte Applikation
- ├── public/ # Statische Assets, Ressourcen, Bilder etc.
- ├── tests/ # Test-Dateien
- ├── .gitignore
- ├── package.json
- └── README.md
- ```
- - Logische Trennung von Funktionalitäten
- - Konsistente Benennung
-
-- **Datei-Organisation** (5 Punkte)
- - Ein Konzept pro Datei (Single Responsibility)
- - Konsistente Namenskonventionen: `kebab-case` für Dateien, `camelCase` für Variablen, `PascalCase` für Komponenten/Klassen
-
-### Code-Qualität (15 Punkte)
-
-#### KISS Prinzip (5 Punkte)
-
-**❌ Nicht so einfach:**
-```javascript
-const processData = (d) => d.filter(x => x.status === 'active').map(x => ({...x, processed: true})).reduce((acc, curr) => acc + curr.value, 0);
-```
-
-**✅ Einfach:**
-```javascript
-function calculateActiveTotal(data) {
- const activeItems = data.filter(item => item.status === 'active');
- const processedItems = activeItems.map(item => ({
- ...item,
- processed: true
- }));
- return processedItems.reduce((total, item) => total + item.value, 0);
-}
-```
-
-**❌ Nicht so einfach:**
-```javascript
-const u = users.find(u => u.id === id && u.active && !u.deleted) || null;
-```
-
-**✅ Einfach:**
-```javascript
-function findActiveUser(users, userId) {
- return users.find(user =>
- user.id === userId &&
- user.active &&
- !user.deleted
- ) || null;
-}
-```
-
-#### Beschreibende Namen (5 Punkte)
-
-**❌ Schlecht:**
-```javascript
-let isActive = true;
-let data = [];
-function calc(x, y) { return x * y; }
-```
-
-**✅ Gut:**
-```javascript
-let isMenuVisible = true;
-let userProfiles = [];
-function calculateTotalPrice(price, taxRate) { return price * taxRate; }
-```
-
-**❌ Unklar und uneindeutig:**
-```javascript
-const btn = document.getElementById('btn');
-let flag = false;
-function process(items) { /* ... */ }
-```
-
-**✅ Sprechende Variablennamen:**
-```javascript
-const submitButton = document.getElementById('submit-btn');
-let isFormValid = false;
-function validateUserInput(formData) { /* ... */ }
-```
-
-#### Funktionsverantwortlichkeiten (5 Punkte)
-
-**❌ Zu viele Verantwortlichkeiten:**
-```javascript
-function handleUser(userData) {
- // Validiert Daten
- if (!userData.email) return false;
- // Speichert in DB
- database.save(userData);
- // Sendet Email
- sendWelcomeEmail(userData.email);
- // Updated UI
- updateUserList();
- return true;
-}
-```
-
-**✅ Eine klare Verantwortlichkeit pro Funktion:**
-```javascript
-function validateUserData(userData) {
- return userData.email && userData.name;
-}
-
-function saveUser(userData) {
- return database.save(userData);
-}
-
-function sendWelcomeEmail(email) {
- return emailService.send(email, 'welcome');
-}
-```
-
-### Kommentierung & Dokumentation (5 Punkte)
-**JSDoc ist optional und der beste Code muss nicht kommentiert werden.**
-
-**❌ Über-/Unterkommentiert:**
-```javascript
-// Erhöht i um 1
-i++;
-// Checked ob user existiert
-if (user) {
- // Macht irgendwas
- doSomething();
-}
-```
-
-**✅ Sinnvoll kommentiert:**
-```javascript
-/**
- * Handles user authentication and session management
- *
- * OR
- *
- * This file manages JWT tokens and user permissions
- */
-
-function calculateCompoundInterest(principal, rate, time) {
- // Using compound interest formula: A = P(1 + r/n)^(nt)
- return principal * Math.pow((1 + rate), time);
-}
-```
-
-**❌ Unterkommentiert:**
-```javascript
-function x(a,b,c,d,e) {
- return a*b+c-d/e;
-}
-```
-
-**✅ Mit JSDoc dokumentiert:**
-```javascript
-/**
- * Calculates shipping cost based on weight, distance and priority
- * @param {number} weight - Package weight in kg
- * @param {number} distance - Delivery distance in km
- * @param {boolean} isPriority - Priority delivery flag
- * @returns {number} Total shipping cost
- */
-function calculateShippingCost(weight, distance, priority) {
- const baseCost = weight * 2.5;
- const distanceCost = distance * 0.1;
- const priorityMultiplier = priority ? 1.5 : 1;
- return (baseCost + distanceCost) * priorityMultiplier;
-}
-```
-
-### Live-Demo (10 Punkte)
-- **Fehlerfreie Demonstration** (10 Punkte)
- - Anwendung läuft während der Präsentation stabil
- - Alle Kernfunktionen werden erfolgreich vorgeführt
- - Ungefähr 5 Minuten Demo-Zeit
-
----
-
-## 3. Accessibility & UX (25 Punkte)
-
-### Web Accessibility (15 Punkte)
-
-#### Semantisches HTML (5 Punkte)
-
-**❌ Nicht semantisch:**
-```html
-
-
-
Welcome
-
Description...
-
-```
-
-**✅ Semantisch korrekt:**
-```html
-
-
-
- Welcome
- Description...
-
-
-```
-
-#### ARIA Labels & Alt-Texte (5 Punkte)
-
-**❌ Schlecht:**
-```html
-
-
-
-We don't send spam
-```
-
-**✅ Gut:**
-```html
-
-
-
-Wir versenden keine Spam-Mails
-```
-
-#### Tastaturnavigation (5 Punkte)
-- Alle interaktiven Elemente per Tab erreichbar
-- Sichtbarer Focus-Indikator
-- Logische Tab-Reihenfolge
-
-**❌ Nicht tastaturzugänglich:**
-```html
-🍔
-```
-
-```css
-div.clickable {
- cursor: pointer;
-}
-```
-
-**✅ Tastaturzugänglich:**
-```css
-div.clickable:focus {
- outline: 2px solid #007acc;
-}
-```
-
-```html
-🍔
-```
-
-### Responsive Design (10 Punkte)
-
-#### Mobile First Approach (5 Punkte - mindestens 1 Breakpoint)
-```css
-/* Mobile First */
-.container {
- width: 100%;
- padding: 1rem;
-}
-
-/* Desktop */
-@media (min-width: 768px) {
- .container {
- max-width: 1200px;
- margin: 0 auto;
- padding: 2rem;
- }
-}
-```
-
-#### Flexbox/Grid Layout (5 Punkte)
-
-**❌ Veraltete Layouts:**
-```css
-.container {
- float: left;
- width: 33.33%;
-}
-.clearfix::after {
- content: "";
- display: table;
- clear: both;
-}
-```
-
-**✅ Moderne Layouts:**
-```css
-.card-grid {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
- gap: 1.5rem;
-}
-.navigation {
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-```
-
----
-
-## 4. Erweiterte Technologien & Innovation (15 Punkte)
-
-### Plattformunabhängigkeit (5 Punkte)
-- Funktioniert auf macOS, Windows, GNU/Linux
-- Browser-Kompatibilität (Chrome, Firefox, Safari, Edge)
-
-**❌ Plattformspezifisch:**
-```javascript
-// Nur Chrome
-navigator.clipboard.writeText(text);
-```
-
-**✅ Plattformunabhängig:**
-
-In aller Regel sind solche sog. Polyfills kaum noch eigenhändig zu implementieren.
-Nichtsdestotrotz gilt es die Plattformunabhängig zu prüfen und ggf. Alternativen für die Implementierung zu finden wie im folgenden Beispiel für die Zwischenablage:
-
-```javascript
-// Fallback für ältere Browser
-function copyToClipboard(text) {
- if (navigator.clipboard) {
- return navigator.clipboard.writeText(text);
- } else {
- const textArea = document.createElement('textarea');
- textArea.value = text;
- document.body.appendChild(textArea);
- textArea.select();
- document.execCommand('copy');
- document.body.removeChild(textArea);
- }
-}
-```
-
-### Entwicklungs-Tools (10 Punkte)
-
-#### Package Management (4 Punkte)
-
-Sämtliche nodeJS/JavaScript Projekte sollten eine `package.json` beinhalten.
-`npm init` und ein Dialog öffnet sich.
-
-```json
-{
- "name": "my-project",
- "scripts": {
- "start": "vite",
- "build": "vite build",
- "test": "jest",
- "lint": "eslint src/"
- },
- "dependencies": {
- "react": "^18.0.0"
- },
- "devDependencies": {
- "vite": "^4.0.0",
- "jest": "^29.0.0"
- }
-}
-```
-
-#### Build Tools & Optimierung (6 Punkte)
-- Vite, Webpack, oder ähnliche Tools
-- Optimierte Produktions-Builds
- - Debugger und unnötige console.log()'s entfernen
- - Code-Splitting
- - Nur Teile statt gesamte Bibliotheken importieren
- - Bspw. PostCSS für Entfernung von überschüssigem CSS
-
-**❌ Entwicklungs-Build:**
-```javascript
-// Unminified, alle Dependencies geladen
-import * as _ from 'lodash';
-// Debugging
-console.log('Debug info:', data);
-debugger;
-```
-
-**✅ Produktions-Build:**
-```javascript
-// Minified, nur benötigte Funktionen
-import { debounce } from 'lodash';
-
-// Debug-Code entfernt in Production
-```
-
-### Zusätzliche Features (Bonus: bis zu 10 Punkte)
-**Wähle mindestens 2 Bereiche:**
-
-#### API Integration (5 Punkte)
-
-**❌ Ohne Error Handling:**
-```javascript
-async function getUser(id) {
- const response = await fetch(`/api/users/${id}`);
- return response.json();
-}
-```
-
-**✅ Mit Error Handling:**
-```javascript
-async function fetchUserData(userId) {
- try {
- const response = await fetch(`/api/users/${userId}`);
- if (!response.ok) {
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
- }
- return await response.json();
- } catch (error) {
- console.error('Fehler beim Laden der Benutzerdaten:', error);
- throw new Error('Benutzerdaten konnten nicht geladen werden');
- }
-}
-```
-
-#### Local Storage / State Management (5 Punkte)
-
-**❌ Ohne Error Handling:**
-```javascript
-function saveData(data) {
- localStorage.setItem('data', JSON.stringify(data));
-}
-function loadData() {
- return JSON.parse(localStorage.getItem('data'));
-}
-```
-
-**✅ Mit Error Handling:**
-```javascript
-function saveUserPreferences(prefs) {
- try {
- localStorage.setItem('userPrefs', JSON.stringify(prefs));
- return true;
- } catch (error) {
- console.warn('Local Storage nicht verfügbar:', error);
- return false;
- }
-}
-
-function loadUserPreferences() {
- try {
- const data = localStorage.getItem('userPrefs');
- return data ? JSON.parse(data) : getDefaultPreferences();
- } catch (error) {
- console.warn('Fehler beim Laden der Einstellungen:', error);
- return getDefaultPreferences();
- }
-}
-```
-
-#### Progressive Web App Features (5 Punkte)
-- Service Worker für Offline-Funktionalität
-- Manifest.json für App-Installation
-- Caching-Strategien
-
-**❌ Ohne PWA:**
-```html
-
-```
-
-**✅ Mit PWA Features:**
-```html
-
-
-
-
-```
-
-#### Testing (10 Punkte)
-
-Von Vornherein mitgedachte Tests helfen beim Code-Splitting.
-Um beim Testen jene Funktionen eindeutig referenzieren zu können, hilft es sie in einzelne Dateien zu verteilen und Ordnern zu gruppieren.
-
-**❌ Ohne Tests:**
-```javascript
-// Keine Tests vorhanden
-function calculateTotal(price, tax) {
- return price + (price * tax);
-}
-```
-
-**✅ Mit Tests:**
-```javascript
-// calculate.js
-export function calculateTotal(price, tax) {
- if (typeof price !== 'number' || typeof tax !== 'number') {
- throw new Error('Price and tax must be numbers');
- }
- return price + (price * tax);
-}
-
-// calculate.test.js
-import { calculateTotal } from './calculate.js';
-
-test('calculateTotal should return correct sum', () => {
- expect(calculateTotal(100, 0.19)).toBeCloseTo(119);
-});
-
-test('calculateTotal should throw error for invalid input', () => {
- expect(() => calculateTotal('100', 0.19)).toThrow();
-});
-```
-
-#### Responsive Design Erweitert (5 Punkte - 2 oder mehr Breakpoints)
-```css
-/* Mobile */
-.grid { display: block; }
-
-/* Tablet */
-@media (min-width: 768px) {
- .grid {
- display: grid;
- grid-template-columns: 1fr 1fr;
- }
-}
-
-/* Desktop */
-@media (min-width: 1024px) {
- .grid {
- grid-template-columns: repeat(3, 1fr);
- }
-}
-
-/* Large Desktop */
-@media (min-width: 1440px) {
- .grid {
- grid-template-columns: repeat(4, 1fr);
- }
-}
-```
-
-#### Security Features (5 Punkte)
-
-**❌ Unsicher:**
-```javascript
-// XSS anfällig
-element.innerHTML = userInput;
-// Unvalidierte Eingabe
-function search(query) {
- return database.query(`SELECT * FROM users WHERE name = '${query}'`);
-}
-```
-
-**✅ Sicher:**
-```javascript
-// XSS-sicher durch HTML-Escaping
-function escapeHtml(text) {
- const div = document.createElement('div');
- div.textContent = text;
- return div.innerHTML;
-}
-element.innerHTML = escapeHtml(userInput);
-
-// SQL-Injection sicher
-function search(query) {
- const sanitizedQuery = query.replace(/[^\w\s]/gi, '');
- return database.query('SELECT * FROM users WHERE name = ?', [sanitizedQuery]);
-}
-```
-
----
-
-## Abgabe
-
-- **Deadline:** 20.07.2025
-- **Format:** GitHub/GitLab Repository Link + Live-Demo URL (falls gehostet)
-- **Präsentation:** 11.07.2025 - 10-15 Minuten pro Gruppe + ~5 Minuten Demo
-
-## Tipps
-
-1. **Beginnt früh** mit der Eingrenzung des Funktionsumfangs
-2. **Testet eure Anwendung** auf verschiedenen Geräten, Betriebssystemen und Browsern
-3. **Fragt bei Unklarheiten** rechtzeitig nach
-4. **Fokussiert euch** auf Qualität statt Quantität
-5. **Behaltet Barrieren im Blick** und vermeidet sie rechtzeitig
-5. **Verwendet gute Struktur** um eure Code-Beispiele zu organisieren
+# DHBW 2025: Web Engineering Prüfungsleistung
+**Maximale Punktzahl: 100 Punkte**
+
+---
+
+## 1. Grundanforderungen (25 Punkte)
+
+### Projektgrundlagen (15 Punkte)
+- **Funktionsfähige Anwendung** (8 Punkte)
+ - Webapp oder Backend-Anwendung läuft fehlerfrei
+ - Kernfunktionalitäten sind in der Projektdokumentation beschrieben und testbar
+- **Repository** (4 Punkte)
+ - GitHub/GitLab/CodeBerg Repository ist (öffentlich) zugänglich
+ - Commit-Historie zeigt kontinuierliche Entwicklung
+- **Projektdokumentation** (3 Punkte)
+ - Aussagekräftiger Projekttitel und Beschreibung
+ - README.md mit Installation, Verwendung und Technologie-Stack
+ - Kurze Erklärung der Hauptfunktionen am Anfang relevanter Dateien
+
+### Präsentation (20 Punkte)
+- **Elevator Pitch** (5 Punkte)
+ - Maximal 1 Minute
+ - Welches Problem wird gelöst und warum wurde es vorher noch nicht gelöst?
+ - Zielgruppe definiert
+- **Technische Präsentation** (5 Punkte)
+ - PowerPoint/Folien mit Technologie-Stack
+ - Live-Demo der Anwendung
+- **Projektevolution:** (5 Punkte)
+ Jedes Projekt verläuft unterschiedlich.
+ Sofern es zutrifft, beschreibt die unterschiedlichen Phasen des Projekts.
+ *Wie weit seid ihr gekommen? Wo waren die Stolpersteine? Wie könnte sich eure Anwendung bei fortgesetzter Arbeit entwickeln?*
+
+ 0. (Paper) Prototype
+ 1. Make it work (PoC)
+ 2. Make it right (MvP)
+ 3. Make it fast (Production)
+
+---
+
+## 2. Clean Code Prinzipien (35 Punkte)
+
+### Projektstruktur (10 Punkte)
+- **Ordnerstruktur** (5 Punkte)
+ ```
+ projekt/
+ ├── src/
+ │ ├── components/ # React Components / UI
+ │ ├── config/ # Konfigurationen, Hard-coded Strings etc.
+ │ ├── services/ # Separitiere für-sich-stehende Funktionen Klassen, Clients etc.
+ │ ├── utils/ # Hilfsfunktionen
+ │ ├── main.css # Haupteinstieg in CSS Klassen, Variablen, Imports etc.
+ │ ├── main.js # Die eigentliche Appliktion
+ │ └── index.js # Haupteinstieg in die gesamte Applikation
+ ├── public/ # Statische Assets, Ressourcen, Bilder etc.
+ ├── tests/ # Test-Dateien
+ ├── .gitignore
+ ├── package.json
+ └── README.md
+ ```
+ - Logische Trennung von Funktionalitäten
+ - Konsistente Benennung
+
+- **Datei-Organisation** (5 Punkte)
+ - Ein Konzept pro Datei (Single Responsibility)
+ - Konsistente Namenskonventionen: `kebab-case` für Dateien, `camelCase` für Variablen, `PascalCase` für Komponenten/Klassen
+
+### Code-Qualität (15 Punkte)
+
+#### KISS Prinzip (5 Punkte)
+
+**❌ Nicht so einfach:**
+```javascript
+const processData = (d) => d.filter(x => x.status === 'active').map(x => ({...x, processed: true})).reduce((acc, curr) => acc + curr.value, 0);
+```
+
+**✅ Einfach:**
+```javascript
+function calculateActiveTotal(data) {
+ const activeItems = data.filter(item => item.status === 'active');
+ const processedItems = activeItems.map(item => ({
+ ...item,
+ processed: true
+ }));
+ return processedItems.reduce((total, item) => total + item.value, 0);
+}
+```
+
+**❌ Nicht so einfach:**
+```javascript
+const u = users.find(u => u.id === id && u.active && !u.deleted) || null;
+```
+
+**✅ Einfach:**
+```javascript
+function findActiveUser(users, userId) {
+ return users.find(user =>
+ user.id === userId &&
+ user.active &&
+ !user.deleted
+ ) || null;
+}
+```
+
+#### Beschreibende Namen (5 Punkte)
+
+**❌ Schlecht:**
+```javascript
+let isActive = true;
+let data = [];
+function calc(x, y) { return x * y; }
+```
+
+**✅ Gut:**
+```javascript
+let isMenuVisible = true;
+let userProfiles = [];
+function calculateTotalPrice(price, taxRate) { return price * taxRate; }
+```
+
+**❌ Unklar und uneindeutig:**
+```javascript
+const btn = document.getElementById('btn');
+let flag = false;
+function process(items) { /* ... */ }
+```
+
+**✅ Sprechende Variablennamen:**
+```javascript
+const submitButton = document.getElementById('submit-btn');
+let isFormValid = false;
+function validateUserInput(formData) { /* ... */ }
+```
+
+#### Funktionsverantwortlichkeiten (5 Punkte)
+
+**❌ Zu viele Verantwortlichkeiten:**
+```javascript
+function handleUser(userData) {
+ // Validiert Daten
+ if (!userData.email) return false;
+ // Speichert in DB
+ database.save(userData);
+ // Sendet Email
+ sendWelcomeEmail(userData.email);
+ // Updated UI
+ updateUserList();
+ return true;
+}
+```
+
+**✅ Eine klare Verantwortlichkeit pro Funktion:**
+```javascript
+function validateUserData(userData) {
+ return userData.email && userData.name;
+}
+
+function saveUser(userData) {
+ return database.save(userData);
+}
+
+function sendWelcomeEmail(email) {
+ return emailService.send(email, 'welcome');
+}
+```
+
+### Kommentierung & Dokumentation (5 Punkte)
+**JSDoc ist optional und der beste Code muss nicht kommentiert werden.**
+
+**❌ Über-/Unterkommentiert:**
+```javascript
+// Erhöht i um 1
+i++;
+// Checked ob user existiert
+if (user) {
+ // Macht irgendwas
+ doSomething();
+}
+```
+
+**✅ Sinnvoll kommentiert:**
+```javascript
+/**
+ * Handles user authentication and session management
+ *
+ * OR
+ *
+ * This file manages JWT tokens and user permissions
+ */
+
+function calculateCompoundInterest(principal, rate, time) {
+ // Using compound interest formula: A = P(1 + r/n)^(nt)
+ return principal * Math.pow((1 + rate), time);
+}
+```
+
+**❌ Unterkommentiert:**
+```javascript
+function x(a,b,c,d,e) {
+ return a*b+c-d/e;
+}
+```
+
+**✅ Mit JSDoc dokumentiert:**
+```javascript
+/**
+ * Calculates shipping cost based on weight, distance and priority
+ * @param {number} weight - Package weight in kg
+ * @param {number} distance - Delivery distance in km
+ * @param {boolean} isPriority - Priority delivery flag
+ * @returns {number} Total shipping cost
+ */
+function calculateShippingCost(weight, distance, priority) {
+ const baseCost = weight * 2.5;
+ const distanceCost = distance * 0.1;
+ const priorityMultiplier = priority ? 1.5 : 1;
+ return (baseCost + distanceCost) * priorityMultiplier;
+}
+```
+
+### Live-Demo (10 Punkte)
+- **Fehlerfreie Demonstration** (10 Punkte)
+ - Anwendung läuft während der Präsentation stabil
+ - Alle Kernfunktionen werden erfolgreich vorgeführt
+ - Ungefähr 5 Minuten Demo-Zeit
+
+---
+
+## 3. Accessibility & UX (25 Punkte)
+
+### Web Accessibility (15 Punkte)
+
+#### Semantisches HTML (5 Punkte)
+
+**❌ Nicht semantisch:**
+```html
+
+
+
Welcome
+
Description...
+
+```
+
+**✅ Semantisch korrekt:**
+```html
+
+
+
+ Welcome
+ Description...
+
+
+```
+
+#### ARIA Labels & Alt-Texte (5 Punkte)
+
+**❌ Schlecht:**
+```html
+
+
+
+We don't send spam
+```
+
+**✅ Gut:**
+```html
+
+
+
+Wir versenden keine Spam-Mails
+```
+
+#### Tastaturnavigation (5 Punkte)
+- Alle interaktiven Elemente per Tab erreichbar
+- Sichtbarer Focus-Indikator
+- Logische Tab-Reihenfolge
+
+**❌ Nicht tastaturzugänglich:**
+```html
+🍔
+```
+
+```css
+div.clickable {
+ cursor: pointer;
+}
+```
+
+**✅ Tastaturzugänglich:**
+```css
+div.clickable:focus {
+ outline: 2px solid #007acc;
+}
+```
+
+```html
+🍔
+```
+
+### Responsive Design (10 Punkte)
+
+#### Mobile First Approach (5 Punkte - mindestens 1 Breakpoint)
+```css
+/* Mobile First */
+.container {
+ width: 100%;
+ padding: 1rem;
+}
+
+/* Desktop */
+@media (min-width: 768px) {
+ .container {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 2rem;
+ }
+}
+```
+
+#### Flexbox/Grid Layout (5 Punkte)
+
+**❌ Veraltete Layouts:**
+```css
+.container {
+ float: left;
+ width: 33.33%;
+}
+.clearfix::after {
+ content: "";
+ display: table;
+ clear: both;
+}
+```
+
+**✅ Moderne Layouts:**
+```css
+.card-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
+ gap: 1.5rem;
+}
+.navigation {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+```
+
+---
+
+## 4. Erweiterte Technologien & Innovation (15 Punkte)
+
+### Plattformunabhängigkeit (5 Punkte)
+- Funktioniert auf macOS, Windows, GNU/Linux
+- Browser-Kompatibilität (Chrome, Firefox, Safari, Edge)
+
+**❌ Plattformspezifisch:**
+```javascript
+// Nur Chrome
+navigator.clipboard.writeText(text);
+```
+
+**✅ Plattformunabhängig:**
+
+In aller Regel sind solche sog. Polyfills kaum noch eigenhändig zu implementieren.
+Nichtsdestotrotz gilt es die Plattformunabhängig zu prüfen und ggf. Alternativen für die Implementierung zu finden wie im folgenden Beispiel für die Zwischenablage:
+
+```javascript
+// Fallback für ältere Browser
+function copyToClipboard(text) {
+ if (navigator.clipboard) {
+ return navigator.clipboard.writeText(text);
+ } else {
+ const textArea = document.createElement('textarea');
+ textArea.value = text;
+ document.body.appendChild(textArea);
+ textArea.select();
+ document.execCommand('copy');
+ document.body.removeChild(textArea);
+ }
+}
+```
+
+### Entwicklungs-Tools (10 Punkte)
+
+#### Package Management (4 Punkte)
+
+Sämtliche nodeJS/JavaScript Projekte sollten eine `package.json` beinhalten.
+`npm init` und ein Dialog öffnet sich.
+
+```json
+{
+ "name": "my-project",
+ "scripts": {
+ "start": "vite",
+ "build": "vite build",
+ "test": "jest",
+ "lint": "eslint src/"
+ },
+ "dependencies": {
+ "react": "^18.0.0"
+ },
+ "devDependencies": {
+ "vite": "^4.0.0",
+ "jest": "^29.0.0"
+ }
+}
+```
+
+#### Build Tools & Optimierung (6 Punkte)
+- Vite, Webpack, oder ähnliche Tools
+- Optimierte Produktions-Builds
+ - Debugger und unnötige console.log()'s entfernen
+ - Code-Splitting
+ - Nur Teile statt gesamte Bibliotheken importieren
+ - Bspw. PostCSS für Entfernung von überschüssigem CSS
+
+**❌ Entwicklungs-Build:**
+```javascript
+// Unminified, alle Dependencies geladen
+import * as _ from 'lodash';
+// Debugging
+console.log('Debug info:', data);
+debugger;
+```
+
+**✅ Produktions-Build:**
+```javascript
+// Minified, nur benötigte Funktionen
+import { debounce } from 'lodash';
+
+// Debug-Code entfernt in Production
+```
+
+### Zusätzliche Features (Bonus: bis zu 10 Punkte)
+**Wähle mindestens 2 Bereiche:**
+
+#### API Integration (5 Punkte)
+
+**❌ Ohne Error Handling:**
+```javascript
+async function getUser(id) {
+ const response = await fetch(`/api/users/${id}`);
+ return response.json();
+}
+```
+
+**✅ Mit Error Handling:**
+```javascript
+async function fetchUserData(userId) {
+ try {
+ const response = await fetch(`/api/users/${userId}`);
+ if (!response.ok) {
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
+ }
+ return await response.json();
+ } catch (error) {
+ console.error('Fehler beim Laden der Benutzerdaten:', error);
+ throw new Error('Benutzerdaten konnten nicht geladen werden');
+ }
+}
+```
+
+#### Local Storage / State Management (5 Punkte)
+
+**❌ Ohne Error Handling:**
+```javascript
+function saveData(data) {
+ localStorage.setItem('data', JSON.stringify(data));
+}
+function loadData() {
+ return JSON.parse(localStorage.getItem('data'));
+}
+```
+
+**✅ Mit Error Handling:**
+```javascript
+function saveUserPreferences(prefs) {
+ try {
+ localStorage.setItem('userPrefs', JSON.stringify(prefs));
+ return true;
+ } catch (error) {
+ console.warn('Local Storage nicht verfügbar:', error);
+ return false;
+ }
+}
+
+function loadUserPreferences() {
+ try {
+ const data = localStorage.getItem('userPrefs');
+ return data ? JSON.parse(data) : getDefaultPreferences();
+ } catch (error) {
+ console.warn('Fehler beim Laden der Einstellungen:', error);
+ return getDefaultPreferences();
+ }
+}
+```
+
+#### Progressive Web App Features (5 Punkte)
+- Service Worker für Offline-Funktionalität
+- Manifest.json für App-Installation
+- Caching-Strategien
+
+**❌ Ohne PWA:**
+```html
+
+```
+
+**✅ Mit PWA Features:**
+```html
+
+
+
+
+```
+
+#### Testing (10 Punkte)
+
+Von Vornherein mitgedachte Tests helfen beim Code-Splitting.
+Um beim Testen jene Funktionen eindeutig referenzieren zu können, hilft es sie in einzelne Dateien zu verteilen und Ordnern zu gruppieren.
+
+**❌ Ohne Tests:**
+```javascript
+// Keine Tests vorhanden
+function calculateTotal(price, tax) {
+ return price + (price * tax);
+}
+```
+
+**✅ Mit Tests:**
+```javascript
+// calculate.js
+export function calculateTotal(price, tax) {
+ if (typeof price !== 'number' || typeof tax !== 'number') {
+ throw new Error('Price and tax must be numbers');
+ }
+ return price + (price * tax);
+}
+
+// calculate.test.js
+import { calculateTotal } from './calculate.js';
+
+test('calculateTotal should return correct sum', () => {
+ expect(calculateTotal(100, 0.19)).toBeCloseTo(119);
+});
+
+test('calculateTotal should throw error for invalid input', () => {
+ expect(() => calculateTotal('100', 0.19)).toThrow();
+});
+```
+
+#### Responsive Design Erweitert (5 Punkte - 2 oder mehr Breakpoints)
+```css
+/* Mobile */
+.grid { display: block; }
+
+/* Tablet */
+@media (min-width: 768px) {
+ .grid {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ }
+}
+
+/* Desktop */
+@media (min-width: 1024px) {
+ .grid {
+ grid-template-columns: repeat(3, 1fr);
+ }
+}
+
+/* Large Desktop */
+@media (min-width: 1440px) {
+ .grid {
+ grid-template-columns: repeat(4, 1fr);
+ }
+}
+```
+
+#### Security Features (5 Punkte)
+
+**❌ Unsicher:**
+```javascript
+// XSS anfällig
+element.innerHTML = userInput;
+// Unvalidierte Eingabe
+function search(query) {
+ return database.query(`SELECT * FROM users WHERE name = '${query}'`);
+}
+```
+
+**✅ Sicher:**
+```javascript
+// XSS-sicher durch HTML-Escaping
+function escapeHtml(text) {
+ const div = document.createElement('div');
+ div.textContent = text;
+ return div.innerHTML;
+}
+element.innerHTML = escapeHtml(userInput);
+
+// SQL-Injection sicher
+function search(query) {
+ const sanitizedQuery = query.replace(/[^\w\s]/gi, '');
+ return database.query('SELECT * FROM users WHERE name = ?', [sanitizedQuery]);
+}
+```
+
+---
+
+## Abgabe
+
+- **Deadline:** 27.07.2025
+- **Format:** GitHub/GitLab Repository Link + Live-Demo URL (falls gehostet)
+- **Präsentation:** 18.07.2025 - 10-15 Minuten pro Gruppe + ~5 Minuten Demo
+
+## Tipps
+
+1. **Beginnt früh** mit der Eingrenzung des Funktionsumfangs
+2. **Testet eure Anwendung** auf verschiedenen Geräten, Betriebssystemen und Browsern
+3. **Fragt bei Unklarheiten** rechtzeitig nach
+4. **Fokussiert euch** auf Qualität statt Quantität
+5. **Behaltet Barrieren im Blick** und vermeidet sie rechtzeitig
+5. **Verwendet gute Struktur** um eure Code-Beispiele zu organisieren