{
  "scope": "buchdruckerkunst",
  "timestamp": "2026-05-24T10:40:15Z",
  "orchestrator_notes": [
    "Alle 3 Bilder HTTP 200 bestätigt.",
    "API /api/design_eval funktioniert (POST + GET verifiziert).",
    "Letter-spacing .04em und .3em vorhanden — .04em auf Demo-Buchtitel (Kelmscott), .3em rein ornamental. Kein .08em. Verifier soll .04em auf Victor-Relevanz beurteilen.",
    "Keine expliziten touchstart/touchend-Handler — :active und onclick sind iOS-kompatibel. Visueller Verifier soll iPhone-Tap-Verhalten bestätigen.",
    "Marginalia-Hide auf 768px korrekt implementiert.",
    "initStandardUI IIFE vollständig, korrekt geschlossen.",
    "Version-Bump auto-aufruf am Ende des Script-Blocks vorhanden: fetch(\"/api/version/bump\")"
  ],
  "criteria": [
    {
      "id": "KRIT-01",
      "name": "Bild 1 lädt — Gutenberg-Bibel (JPG)",
      "method": "curl HTTP-Status",
      "url": "https://upload.wikimedia.org/wikipedia/commons/b/b6/Gutenberg_Bible%2C_Lenox_Copy%2C_New_York_Public_Library%2C_2009._Pic_01.jpg",
      "pass_if": "HTTP 200",
      "pre_result": "GRÜN",
      "pre_note": "HTTP 200 bestätigt"
    },
    {
      "id": "KRIT-02",
      "name": "Bild 2 lädt — Buchdrucker 1568 (PNG)",
      "method": "curl HTTP-Status",
      "url": "https://upload.wikimedia.org/wikipedia/commons/f/f8/Printer_in_1568-ce.png",
      "pass_if": "HTTP 200",
      "pre_result": "GRÜN",
      "pre_note": "HTTP 200 bestätigt"
    },
    {
      "id": "KRIT-03",
      "name": "Bild 3 lädt — Bewegliche Bleilettern (JPG)",
      "method": "curl HTTP-Status",
      "url": "https://upload.wikimedia.org/wikipedia/commons/a/ae/Metal_movable_type.jpg",
      "pass_if": "HTTP 200",
      "pre_result": "GRÜN",
      "pre_note": "HTTP 200 bestätigt"
    },
    {
      "id": "KRIT-04",
      "name": "Lightbox im HTML vorhanden und korrekt implementiert",
      "method": "HTML-Analyse: #lightbox, openLightbox(), onclick, Escape-Key-Handler",
      "pass_if": "#lightbox-div vorhanden, openLightbox() Funktion vorhanden, alle 3 Bilder haben onclick=openLightbox(), Escape-Key-Listener vorhanden",
      "pre_result": "GRÜN",
      "pre_note": "#lightbox (Zeile 1544), openLightbox() (Zeile 1549), alle 3 Bilder mit onclick, Escape-Handler (Zeile 1555) — vollständig"
    },
    {
      "id": "KRIT-05",
      "name": "Rating-System (initStandardUI) vorhanden",
      "method": "HTML-Analyse: initStandardUI IIFE, .rating-row, .rating-btn, /api/design_eval POST",
      "pass_if": "initStandardUI-Block vorhanden, rating-row in mindestens 3 Sektionen, API-Calls im JS",
      "pre_result": "GRÜN",
      "pre_note": "initStandardUI IIFE vorhanden (am Ende des Script-Blocks), rating-row data-section in 20 Sektionen, fetch /api/design_eval vorhanden"
    },
    {
      "id": "KRIT-06",
      "name": "POST /api/design_eval funktioniert",
      "method": "curl POST mit JSON-Payload",
      "pass_if": "HTTP 200 + {ok: true} oder äquivalente Erfolgsantwort",
      "pre_result": "GRÜN",
      "pre_note": "POST liefert {\"ok\": true}, Eintrag für buchdruckerkunst/test-bomb verifiziert in /api/design_eval/all"
    },
    {
      "id": "KRIT-07",
      "name": "Marginalia-CSS für Mobile vorhanden (@media max-width: 768px)",
      "method": "HTML-Analyse: @media (max-width: 768px) mit Marginalia-Regel",
      "pass_if": "@media (max-width: 768px) Block vorhanden mit display:none für letztes Kind-Element und grid-template-columns:1fr !important",
      "pre_result": "GRÜN",
      "pre_note": "Zeile 610: @media (max-width: 768px) { .book-page-inner > div[style*=\"grid-template-columns\"] > div:last-child { display: none; } } — vorhanden"
    },
    {
      "id": "KRIT-08",
      "name": "font-size: 17px im CSS (body)",
      "method": "HTML-Analyse: body-Selektor mit font-size: 17px",
      "pass_if": "body { font-size: 17px } in CSS vorhanden",
      "pre_result": "GRÜN",
      "pre_note": "Zeile 34: font-size: 17px im body-Block bestätigt"
    },
    {
      "id": "KRIT-09",
      "name": "Mobile Top-Bar vorhanden",
      "method": "HTML-Analyse: .mobile-topbar div im HTML, @media (max-width: 900px) mit display:flex",
      "pass_if": "<div class=\"mobile-topbar\"> im HTML vorhanden, CSS zeigt display:flex ab ≤900px",
      "pre_result": "GRÜN",
      "pre_note": "Zeile 694: mobile-topbar div im HTML, Zeile 587: @media (max-width: 900px) mit display:flex — vollständig"
    },
    {
      "id": "KRIT-10",
      "name": "Letter-spacing max .01em (kein .08em oder höher in Fließtext)",
      "method": "HTML-Analyse: alle letter-spacing-Werte extrahieren und prüfen",
      "pass_if": "Kein letter-spacing >= .08em in Fließtext-CSS. Dekorative Ausnahmen (.book-ornament mit .3em) erlaubt wenn klar ornamental. .02em auf std-trigger-btn erlaubt als Button-Spezial-Stil.",
      "pre_result": "GELB",
      "pre_note": "Gefundene Werte: -.01em, -.02em, .01em, .02em, .04em, .3em. Kein .08em. .3em nur auf .book-ornament (Ornament-Klasse) und ⚓-Emoji-Dekor. .04em auf Kelmscott-Chaucer-Buchtitel (Demo-Element). .02em auf .std-trigger-btn (UI-Button). GELB: Verifier soll .04em und .02em auf Content-Relevanz prüfen — technisch unter .08em, aber Absicht der Regel klären."
    },
    {
      "id": "KRIT-11",
      "name": "Sidebar auf Mobile ausgeblendet",
      "method": "HTML-Analyse: @media (max-width: 900px) { .sidebar { display: none; } }",
      "pass_if": "display:none für .sidebar in Media Query vorhanden",
      "pre_result": "GRÜN",
      "pre_note": "Zeile 572: .sidebar { display: none; } in @media (max-width: 900px) — bestätigt"
    },
    {
      "id": "KRIT-12",
      "name": "Touch-Events / :active States vorhanden (kein hover-only)",
      "method": "HTML-Analyse: :active CSS-Selektoren, onclick-Attribute auf interaktiven Elementen",
      "pass_if": "Interaktive Elemente haben :active-States im CSS (nicht nur :hover). Lightbox-Trigger hat onclick. Rating-Buttons haben :active.",
      "pre_result": "GELB",
      "pre_note": ":active vorhanden auf .sidebar a, .sidebar-logo a, .rating-btn, .comment-send, .mobile-topbar a. Lightbox via onclick. KEIN explizites touchstart/touchend-EventListener. GELB: funktioniert auf iOS da :active und onclick touch-kompatibel sind, aber kein expliziter touch-Handler. Verifier soll auf iPhone bestätigen dass Lightbox per Tap öffnet und Rating-Buttons reagieren."
    },
    {
      "id": "KRIT-13",
      "name": "Kein JS-Syntaxfehler (Script-Tags valide)",
      "method": "HTML-Analyse: Script-Block auf offensichtliche Syntaxfehler, korrekt geschlossene Klammern, Funktionsstruktur",
      "pass_if": "Script endet mit </script>, alle Funktionen korrekt definiert, keine unterminierten Strings, IIFE korrekt geschlossen",
      "pre_result": "GRÜN",
      "pre_note": "Script-Block vollständig gelesen. openLightbox(), loadState(), applyState(), initStandardUI IIFE, rating-event-handler, comment-handler — alle korrekt geschlossen. Letzter Aufruf: fetch(\"/api/version/bump\"). </script></body></html> ordnungsgemäß."
    },
    {
      "id": "KRIT-14",
      "name": "Version-Bump-Endpoint aufrufbar",
      "method": "curl POST /api/version/bump",
      "pass_if": "HTTP 200 + {status: ok} oder äquivalent",
      "pre_result": "GRÜN",
      "pre_note": "POST /api/version/bump liefert {\"status\": \"ok\"}"
    },
    {
      "id": "KRIT-15",
      "name": "Alle 3 Bilder korrekt in figure.wiki-img mit figcaption eingebettet",
      "method": "HTML-Analyse: figure.wiki-img, figcaption, loading=lazy, alt-Text",
      "pass_if": "Jedes Bild in <figure class=\"wiki-img\">, mit <figcaption>, loading=\"lazy\", aussagekräftigem alt-Text",
      "pre_result": "GRÜN",
      "pre_note": "Alle 3 Bilder in figure.wiki-img, figcaption vorhanden, loading=\"lazy\", alt-Texte beschreibend — vollständig"
    },
    {
      "id": "KRIT-16",
      "name": "Lightbox zeigt display:flex (nicht block) beim Öffnen",
      "method": "HTML-Analyse: #lightbox CSS, openLightbox() setzt style.display=flex",
      "pass_if": "#lightbox CSS hat align-items:center, justify-content:center. openLightbox() setzt lb.style.display=\"flex\"",
      "pre_result": "GRÜN",
      "pre_note": "CSS Zeile 673: #lightbox { display:none; align-items:center; justify-content:center } — openLightbox() setzt lb.style.display=\"flex\" — korrekt"
    }
  ]
}