# Emma's Schatzkiste — Design-System Live-Dateien: `index.html`, `hilfe-verein.html`, `shop.html`, `assets/site.css`. Stand 2026-09-21. Offene Punkte: [`README.md`](README.md). ## Benannte Referenz Workspace-Regel: *kein UI-Code ohne benannte Referenz*. Diese Seiten stehen auf einer: **[`emmas-schatzkiste-ds.md`](../design-references/entries/emmas-schatzkiste-ds.md)** — das mitgelieferte, gebundene Handoff-Design-System. Neue Familie *Warm Local Retail / Handmade Consumer*; vorher hatte die Bibliothek für ein Projekt dieser Art keinen Eintrag. **Übernommen:** die handgelegte Headline (jede Zeile eigenes Grid-Item mit eigener Rotation), die Zwei-Farbwelten-Trennung Shop = blau / Verein = gelb, die eigene Kante der Vereinsseite (gelbe 6px-Unterkante, rotierte Pille statt Eyebrow-Text, zwei Buttons statt einem, freies Logo unten rechts), durchgehende Pill-Rundung, blaustichige Schatten, 4px-Raster, Motion ausschließlich als Zustandsfeedback, Sprache und Tonalität. **Nicht übernommen:** Dreifach-Akzent, neunstufige Typo-Skala, die durchgefallenen Textkontraste, die fixen Pixel-Stopps im Hero-Scrim, `mix-blend-mode` auf den Logos, Pexels-Hotlinks. Begründung je unten. ## Produktwahrheit Baby- und Kinder-Second-Hand-Laden in **84056 Rottenburg a.d. Laaber**, seit September in neuer Hand. Dazu der **Hilfe Verein** („Hilfe. Herz. Hoffnung."), **noch nicht eingetragen** — deshalb keine Spendenstufen, kein Zahlungsformular, kein Mitgliedschafts-Flow. Drei Hilfearten, genau wie vom Kunden benannt: Geldspenden, ehrenamtliche Helfer, Weitersagen. Kontakt nur über `tel:` und `mailto:`. **Opa Martin** ist der Inhaber; Bild und Name, kein Bildtext — Kundenvorgabe. Der Online-Shop ist bewusst geparkt. Tonalität: **Du-Form**, Satzkleinschreibung, keine Emoji. ## Drei Abweichungen vom Handoff Alle drei freigegeben. Der Handoff erklärt Farben und Typo für final; diese drei Punkte kollidieren mit den [Guardrails](../design-references/GUARDRAILS.md), zwei davon sind zusätzlich messbare Fehler. ### 1. Farbe — Guardrail bewusst gelockert Guardrail: *„Ein einziger Akzent-Ton pro Seite."* Die erste Fassung hielt ihn streng ein und wurde vom Auftraggeber am 2026-09-21 als **zu blass** zurückgewiesen. Der Guardrail ist damit bewusst gelockert — dasselbe Vorgehen wie bei Hypno Active, wo die drei Logofarben ebenfalls gegen den Guardrail stehen und im CSS-Kopf dokumentiert sind. Damit die Hierarchie trotzdem trägt, gilt eine harte Ersatzregel: > **Farbe lebt in Flächen und in Display-Typo — nie im Fließtext.** Alle drei Buntfamilien laufen wieder, aber ausschließlich als Sektionsflächen, Kachelfüllungen, Icon-Chips und H1-Zeilen. Jeder Fließtext bleibt `--ink-500` oder `--ink-700`. So konkurrieren die Farben nie auf derselben Leseebene. Die Seitenidentität bleibt: `--accent*` ist weiter pro Seite gesetzt und regiert Icons, Rahmen, Kontaktkarten, Footer-Kante und den aktiven Nav-Zustand. | Seite | `--accent` | `--accent-text` | `--accent-soft` | `--accent-line` | |---|---|---|---|---| | Startseite, Shop (`.page-shop`) | `--sky-500` | `--sky-600` | `--sky-50` | `--sky-400` | | Hilfe Verein (`.page-verein`) | `--sun-600` | `--sun-700` | `--sun-100` | `--sun-400` | **H1 wieder dreifarbig,** Reihenfolge pro Seite gespiegelt: Startseite Sky → Sun → Coral, Verein Sun → Coral → Sky. Zulässig, weil Display-Typo ab 24px die Large-Text-Schwelle 3.0 nutzt und alle drei Werte darüber liegen (auf Weiß 3.86 / 3.92 / 4.00, auf Creme 3.52 / 3.57 / 3.65). Im Fließtext wäre keiner davon erlaubt. **Ein gesättigtes Vollflächen-Band pro Seite.** Pastelltöne allein trugen die Seite nicht, sie verschwinden gegen Weiß. Startseite: „Für Familien" auf `--sky-500` mit weißer Überschrift und weißen Kacheln. Verein: „Wir brauchen Hilfe" auf `--sun-400` mit `--ink-700`. Weiß auf `--sky-500` misst 3.86 und reicht nur für Überschriften ab 24px — deshalb steht auf dem blauen Band **kein** Fließtext, der sitzt in den weißen Kacheln. `--ink-700` auf `--sun-400` misst 8.67 und ist überall zulässig. Der Seitenrhythmus ist damit: Foto-Hero → Weiß → Creme → gesättigtes Band → Weiß → Creme-Band → Footer. Coral bleibt unverändert **ausschließlich** Handlungsfarbe der primären Buttons. Eine bewusste Ausnahme: das Band *„Wo alles angefangen hat"* auf der Vereinsseite steht im Blau der Shop-Welt. Es verweist auf den Laden; die Tönung markiert den Themenwechsel. ### 2. Kontrast Guardrail: *„Graue Schrift auf farbigem Grund."* Gemessen statt geschätzt: | Paar | Verhältnis | | |---|---|---| | `--ink-300` `#8B94A0` auf `--sun-100` `#FDF4DC` | **2.80** | durchgefallen — das war die §19-Zeile | | weiß auf `--coral-400` `#F4715A` | **2.85** | durchgefallen | | weiß auf `--sky-400` `#4A9FE0` | **2.87** | durchgefallen — Header-Farbe des Handoffs | | `--ink-500` `#4A5560` auf `--sun-100` | 6.94 | bestanden | Der Fließtext auf Creme bestand also; dort war der Guardrail stilistisch. Die §19-Zeile und die beiden weiß-auf-bunt-Fälle waren echte Fehler. Geändert: Text auf farbigem Grund steht in `--ink-700` (13.20 auf Creme). Der Header ist weiß mit `--ink-700`-Navigation statt `--sky-400` mit Weiß. Für den Primärbutton kamen drei Stufen dazu, die bei jedem Zustand nachdunkeln und nie heller werden: | Zustand | Füllung | Weiß darauf | |---|---|---| | Ruhe | `--coral-600` `#C8402B` | 4.97 | | Hover | `--coral-700` `#B03422` | 6.25 | | Press | `--coral-800` `#A82F1E` | 6.80 | Dazu `--sun-700` `#8F6510` für gelben Text in Body-Größe (4.74 auf Creme); `--sun-600` bleibt für Displaygrößen. `--coral-400` und `--sky-400` bleiben als Flächen im System, nicht mehr als Grund für weißen Text. **Alle drei Seiten sind gegen WCAG AA geprüft, inklusive der Large-Text-Schwellen (≥24px, oder ≥18.66px ab Weight 700). Keine Verstöße.** Eine Stelle fiel dabei auf, die im Handoff nicht sichtbar war: `Lied vom Laden` stand in `--accent` bei 20px/600 — 3.86 bei verlangten 4.5, weil 20px/600 die Large-Text-Ausnahme nicht erreicht. Steht jetzt in `--accent-text`. ### 3. Typo-Skala Guardrail: *„Typo-Extreme (groß oder klein, kein Mittelmaß)."* Neun gleichmäßige Stufen (56 · 42 · 32 · 24 · 19 · 17 · 15 · 13 · 11) sind genau das Mittelmaß — 24/19/17/15 liegen so dicht, dass der Unterschied nicht mehr liest. Auf sechs reduziert, gestrichen sind 42, 24, 19 und 15: | Token | Wert | Face | |---|---|---| | `--t-display` | `clamp(34px, 7.2vw, 60px)` / 1.02 | Fredoka 700 | | `--t-h2` | `clamp(24px, 3.1vw, 30px)` / 1.12 | Fredoka 600 | | `--t-h3` | 20px / 1.3 | Fredoka 600 | | `--t-body` | 17px / 1.65 | Nunito 400 | | `--t-small` | 13px / 1.5 | Nunito 400 | | `--t-label` | 11px / 1.4, `+0.08em`, versal | Nunito 700 | Display-Tracking `-0.01em`. **Fredoka** und **Nunito** sind laut Handoff Platzhalter für einen nicht gelieferten Markenfont — ersetzen, sobald echte Binaries da sind. Kein Inter, kein System-Font. ## Weitere Korrekturen **Hero unter 820px.** Der Handoff markiert die fixen Gradient-Stopps (430/560/820px) selbst als Schwachstelle: unter ~820px deckt der Scrim das Foto fast vollständig zu. Ab 820px bleibt der Scrim wie spezifiziert; darunter stapelt der Hero — Foto oben, Text darunter auf voller Fläche, Scrim aus. **Mobile Header.** Wortmarke plus vier Nav-Items passen unter 640px nicht nebeneinander; die Nav brach aus den 64px heraus und legte sich über den Hero. Unter 640px ist die Wortmarke auf das Zeichen reduziert, die Nav enger und notfalls horizontal scrollbar statt umbrechend. **Logos freigestellt.** Die Client-JPEGs haben einen eingebackenen weißen Kasten, im Handoff per `mix-blend-mode: multiply` kaschiert — das bricht auf jedem dunkleren Grund und ließ auf der Vereinsseite sichtbar Weiß stehen. Beide sind jetzt echt freigestellt (Flood-Fill über randverbundenes Nahe-Weiß plus weiche Kante, 800px, 96-Farben-Palette) und liegen als `assets/logo-*.png`, zusammen 135 KB statt 326 KB. Blend-Mode ist raus. **Fokusring.** `--ring-focus` stand im Base-Block **vor** den Button-Regeln. Bei gleicher Spezifität gewinnt die spätere Regel, also überschrieb `.btn--primary` ihre eigene `box-shadow` über den Ring: auf Buttons war für Tastaturnutzer gar kein Fokus sichtbar. Der Fokus-Block steht jetzt am Dateiende, und `.btn:focus-visible` setzt Ring **und** eigenen Schatten. Geprüft mit echter Tab-Navigation. **Keine Hotlinks.** Die beiden Pexels-Fotos waren auf ein fremdes CDN verlinkt. Statt sie zu übernehmen liegen beschriftete Platzhalter in `assets/`, die unübersehbar als solche lesen. Ersetzen, siehe README. ## Bilder Alle Fotos von **Pexels**, [Lizenz](https://www.pexels.com/license/) am 2026-09-21 geprüft: kommerzielle Nutzung frei, keine Namensnennung nötig, Selbsthosting erlaubt. Sie sind **heruntergeladen und selbst gehostet**, nicht vom fremden CDN verlinkt wie im Handoff. | Datei | Pexels-ID | Motiv | |---|---|---| | `assets/hero-start.jpg` | 10831693 | bunte Holzfahrzeuge auf Holz | | `assets/hero-verein.jpg` | 34148341 | Kindersachen auf der Kleiderstange | | `assets/laden-story.jpg` | 6591155 | Hände legen ein Oberteil zusammen | **Bewusst keine Kinderfotos.** Pexels gibt für erkennbare Personen **kein Model Release**; für eine deutsche Gewerbeseite wäre das ein unnötiges Risiko. Deshalb Sachmotive und, beim Story-Bild, Hände ohne Gesicht. Aus demselben Grund aussortiert: Motive mit klar erkennbaren Personen und englischen Aufdrucken („VOLUNTEER", „DONATE") sowie die generischen Hände-im-Kreis-Klischees. Beim Verein-Hero war im ersten Zuschnitt ein fremdes Kleidungs-Etikett sichtbar — weg geschnitten, weil die Pexels-Lizenz Darstellungen untersagt, die eine Markenempfehlung nahelegen. Zuschnitte sind rechtsbetont: die Textspalte sitzt links unter dem Scrim, das Motiv muss im rechten Drittel liegen. Alle 2000×1100, progressives JPEG, Qualität 76. Das Vereinslogo im Hero liegt auf einer weißen Karte — auf dem gemusterten Stoff war die feine Schrift darin sonst nicht lesbar. ## Motion Nur Zustandsfeedback, wie im Handoff: 120ms Farbe, 200ms Lift, 340ms alles Größere, `--ease: cubic-bezier(.2,.6,.3,1)`. Hover hebt 3px und vertieft den Schatten, Press `scale(.97)` mit `--shadow-xs`. Kein Load-Fade, kein Parallax, keine Loop-Animation, kein Bounce-Easing. `prefers-reduced-motion: reduce` schaltet Transitions ab und stellt Headline, Pille und Logo aufrecht. ## Recht und Datenschutz Kein Anwaltsersatz — aber die technische Seite ist so gebaut, dass möglichst wenig zu regeln bleibt. **Die Seite macht null Anfragen an Dritte.** Gemessen im Browser: keine Cookies, kein Local oder Session Storage, keine Skripte, keine Iframes, keine Fremd-Origins. Damit ist § 25 TDDDG nicht berührt und **ein Einwilligungsbanner ist nicht erforderlich** — es gibt nichts, wozu man einwilligen könnte. Das ist die bessere Lösung als ein aufgesetztes Banner: kein Klickhindernis, keine Consent-Logik, nichts, was falsch konfiguriert sein kann. **Schriften selbst gehostet.** Vorher kamen Fredoka und Nunito von `fonts.googleapis.com` / `fonts.gstatic.com`. Das überträgt die IP jedes Besuchers an Google; das LG München I hat darin am 20.01.2022 (3 O 17493/20) eine Verletzung des Persönlichkeitsrechts gesehen. Beide liegen jetzt als woff2 in `assets/fonts/`, eingebunden über `assets/fonts.css`. Es sind Variable Fonts — alle Schnitte einer Familie in einer Datei, deshalb je eine `@font-face`-Deklaration mit Gewichtsbereich statt sechs. Nur die Subsets `latin` und `latin-ext`, zusammen 106 KB. Lizenz SIL OFL 1.1, Lizenztexte liegen daneben. **Was bewusst fehlt:** die OS-Plattform. Sie wurde zum 20.07.2025 abgeschaltet (VO (EU) 2024/3228), die Hinweispflicht ist entfallen, und ein stehengebliebener Link darauf ist inzwischen selbst abmahnfähig. Beim Übernehmen alter Rechtstexte ist das der erste Punkt, den man rauswerfen muss. **Zwei neue Seiten:** `impressum.html` (§ 5 DDG — nicht mehr § 5 TMG, das ist seit Mai 2024 abgelöst) und `datenschutz.html`. Beide nutzen die `.prose`-Klassen. Offene Angaben stehen als `.todo`-Felder mit gestricheltem Coral-Rahmen im Fließtext, damit nichts davon versehentlich live geht, plus ein `.prose__warn`-Kasten oben auf jeder Seite. ## Mobil und Touch Geprüft bei 320 · 375 · 390 · 640 · 768 · 1024 · 1440 · 1920 px, auf allen fünf Seiten, jeweils auf horizontalen Overflow, Zielgrößen, Schriftgrößen und Randabstände. Alles sauber. Gefunden und behoben wurde dabei: **Der Header war auf dem Handy kaputt.** Nav-Links 28px hoch, Wortmarken-Link 32px breit, und unter 400px scrollte die Navigation seitlich weg, ohne dass es jemand sieht. Jetzt unter 640px zwei Zeilen: Wortmarke mittig, darunter die vier Punkte als Viererraster über die volle Breite, jedes Ziel 44px. „Hilfe Verein" bricht bei 320px sauber um. Der Header ist auf dem Handy dafür **nicht mehr sticky** — zwei Zeilen würden dauerhaft ein Sechstel des Displays wegnehmen, und bei fünf Unterseiten ist eine mitlaufende Navigation kein Verlust. **Zielgrößen nach WCAG.** Zwei Schwellen, bewusst getrennt: | Element | vorher | jetzt | Maßstab | |---|---|---|---| | Nav-Links, Wortmarke | 28–34px | 44px | 2.5.5 (AAA) | | Telefon/E-Mail in Kontaktkarten | 23px | 44px | wichtigste Links der Seite | | Telefon/E-Mail im Impressum | 23px | 44px | stehen allein, nicht im Satz | | Footer-Links | 21px | 30px Desktop, 44px Handy | 2.5.8 (AA) verlangt 24px | Links **mitten im Fließtext** (etwa der Pexels-Verweis) bleiben unverändert — für die gilt die Inline-Ausnahme von WCAG 2.5.8. **Schriftgrößen.** Die 11px-Versallabels gehen auf dem Handy auf 12px hoch. Auf dem Desktop bleiben sie bei 11px, so wie das Handoff-DS es vorgibt. **Versionierte Stylesheets.** Die CSS-Links tragen einen Hash des Dateiinhalts (`site.css?v=…`). Ändert sich das CSS, ändert sich die URL, und Besucher mit altem Browser-Cache bekommen zwingend die neue Datei. `deploy.sh` setzt den Hash bei jedem Deploy automatisch neu. Das war keine Theorie: beim Testen hat der Panel-Cache mehrfach veraltetes CSS ausgeliefert und Korrekturen als „nicht gewirkt" erscheinen lassen. ## Technik Statische Seiten ohne Build, wie die übrigen `Websites/*` im Workspace. Eine Abweichung vom Hausmuster: das CSS liegt als `assets/site.css` statt inline, weil es drei Seiten trägt. Icons sind als Lucide-Pfade inline gesetzt — kein CDN-UMD-Build, keine Netzabhängigkeit. Fonts über Google Fonts mit `preconnect`. Lokal ansehen: ```bash cd "/Users/andrej/ASX Studio/Emmas schatzkiste" && python3 -m http.server 4173 ```