{
  "schema_version": "1.0",
  "generated_at": "2026-08-02T18:31:15.479Z",
  "source": "docs.zabazingo.eu",
  "bridge_version": "zabazingo-docs-1.0",
  "total_docs": 6,
  "total_chars": 28432,
  "total_words": 3636,
  "categories": [
    {
      "name": "Start",
      "count": 1
    },
    {
      "name": "Fundament",
      "count": 2
    },
    {
      "name": "Marke",
      "count": 1
    },
    {
      "name": "Plattform",
      "count": 1
    },
    {
      "name": "Meta",
      "count": 1
    }
  ],
  "docs": [
    {
      "file": "00_START.md",
      "title": "START — Bitte zuerst lesen",
      "category": "Start",
      "confidential": false,
      "chars": 2072,
      "words": 281,
      "headings": [
        "Wo finde ich was?",
        "Warum diese Seite existiert",
        "Diese Seite ist intern",
        "Bedienung"
      ],
      "content": "# ZABAZINGO Docs — bitte zuerst lesen\n\nDies ist die interne Dokumentationsseite des ZABAZINGO-Estates. Sie läuft auf **derselben Engine** wie `claude.adam---eve.com` (der SSGP-Doc-Server), 1:1 geklont — nur Inhalt und CI sind ZABAZINGO. Die Mechanik (Cookie-Auth, Markdown-Rendering, Sidebar, Inhaltsverzeichnis, resizable Spalten, KI-Export, EN/DE-Umschalter, Theme-Toggle) ist identisch zur Vorlage.\n\n> **Reality isn’t given. It’s chosen.**\n\n## Wo finde ich was?\n\n| Kapitel | Worum es geht |\n|---|---|\n| **Domain & Deployment Concept** | Die zentrale Anleitung: *\"Ich habe etwas Neues — WO lege ich das an?\"* Drei Dimensionen (TLD · Additivität · Umgebung). Lies das zuerst, bevor du irgendwas deployst. |\n| **Server- & Infra-Übersicht** | Die Estate-Server-Rollen (Staging=bbe-demo, Live=bbe-live, Backup=Storage Box, 159=intern, 73er=Legacy) + der Infrastructure Conductor (Agent #9). |\n| **Typografie- & Brand-Regelwerk** | Das ZABAZINGO-Typografiesystem mit echten Schrift-Specimens: Wortmarken, Slogan-Regel, Type-Scale, DBE/GFYS-Familie, Palette. |\n| **Kapitel hinzufügen (Scaffold)** | Wie du in zwei Schritten ein weiteres Kapitel ergänzt. Die Seite ist datengetrieben — neue Kapitel sind trivial. |\n\n## Warum diese Seite existiert\n\nDamit **jeder Agent** dieselbe Quelle der Wahrheit hat — kein Raten, kein Interpretieren. Was wahr ist, steht hier; wie es umgesetzt wird, entscheidet der ausführende Agent autonom nach den dokumentierten Regeln.\n\n## Diese Seite ist intern\n\nDokumentation gehört auf `.eu` (nicht `.cloud`) — diese Seite lebt unter `docs.zabazingo.eu`, hinter Cookie-Auth, mit `noindex`. Keine Secrets stehen in der Doku; Schlüssel und Tokens liegen im Vault und werden nie ausgegeben.\n\n## Bedienung\n\n- **Links** = Kapitel-Navigation (nach Kategorie gruppiert).\n- **Rechts** = Inhaltsverzeichnis der aktuellen Seite.\n- Beide Spalten sind per Drag resizable.\n- **Oben rechts**: Theme-Toggle (dunkel ↔ creme) und EN/DE-Umschalter.\n- **KI-Export**: alle Kapitel als Markdown / strukturiertes JSON / ZIP — für Cross-LLM-Review oder Agent-Konsumption.\n"
    },
    {
      "file": "01_DOMAIN_DEPLOYMENT.md",
      "title": "Domain & Deployment Concept",
      "category": "Fundament",
      "confidential": false,
      "chars": 7507,
      "words": 967,
      "headings": [
        "Dimension 1 — Domain-Platzierung (welche TLD)",
        "`.cloud` = zabazingo.cloud — ÖFFENTLICH / DRITTE",
        "`.eu` = zabazingo.eu — INTERN + DOKUMENTATION + MARKE / KOLLEKTIONEN",
        "Entscheidungsbaum (Dimension 1)",
        "Dimension 2 — Additivität (`.cloud` kommt hinzu, `.eu` bleibt)",
        "Dimension 3 — Server- / Umgebungs-Platzierung (GENERISCH)",
        "Generische Entscheidungs-Reihenfolge (von oben nach unten, erster Treffer gewinnt)",
        "Invariante (Dimension 3)",
        "CONFIG (nicht die Regel) — UNSERE konkrete SERVER-MAP",
        "Zusammengesetzt — vollständige Platzierung in 3 Fragen",
        "Querverweise"
      ],
      "content": "# Domain & Deployment Concept\n\n> Status: ratifiziert am 2026-06-04 per Operator-Direktive. Dies ist **die einzige maschinen- und agentenlesbare Quelle der Wahrheit**, die für **jeden** Agenten eine Frage beantwortet: **\"Ich habe einen neuen Service / ein neues Tool / eine neue Seite — WO lege ich das an?\"**\n\nZwei Dinge waren vorher unklar und werden hier festgezurrt:\n\n1. Die alte Server-Regel vermischte die **generische Entscheidungslogik** mit unserer **konkreten Host-Liste**. Beides ist jetzt strikt getrennt: Die Logik ist universell (sie funktioniert für jeden, sogar mit einem einzigen Server); unsere Host-Liste ist nur **Config** — eine Instanziierung der Logik.\n2. Eine zweite Achse fehlte: **welche DOMAIN (TLD)** ein Service gehört.\n\nEine Platzierungs-Entscheidung hat **DREI unabhängige Dimensionen**. Entscheide jede einzeln:\n\n| # | Dimension | Frage | Antwort-Raum |\n|---|---|---|---|\n| 1 | **Domain (TLD)** | Wer erreicht es? | `.cloud` (öffentlich / Dritte) vs. `.eu` (intern / Doku / Kollektionen) |\n| 2 | **Additivität** | Bedient `.eu` das schon? | `.cloud` wird **hinzugefügt**; `.eu` wird im selben Schritt **nie** gelöscht |\n| 3 | **Server / Umgebung** | Welche Umgebung betreibt es? | STAGING → LIVE → (Single-Server-Kollaps) + immer BACKUP |\n\nDie Dimensionen sind orthogonal: Ein Service hat eine TLD **und** eine Umgebung. Maschinenlesbarer Spiegel aller drei: `/etc/bbe/policy.yaml` (`domain_placement`, `deployment_targets.decision_order`, `server_map`).\n\n## Dimension 1 — Domain-Platzierung (welche TLD)\n\n**Eine Frage entscheidet:**\n\n> **Greift ein Dritter darauf zu?**\n> **JA → `.cloud` (zabazingo.cloud).**\n> **NEIN — nur intern / Dokumentation / Marken-Kollektion → `.eu` (zabazingo.eu).**\n\n### `.cloud` = zabazingo.cloud — ÖFFENTLICH / DRITTE\n\nAlles, in das Nutzer, Kunden oder Dritte sich **einloggen oder das sie verwenden**. Produkte und Services, die nach außen exponiert sind.\n\nBeispiele (nicht abschließend): `mail`, `secrets`, `cloud`, `storage`, `vault`, `keychain`, `login`, `app`.\n→ `mail.zabazingo.cloud`, `secrets.zabazingo.cloud`, `cloud.zabazingo.cloud`, `storage.zabazingo.cloud`, `vault.zabazingo.cloud`, `keychain.zabazingo.cloud`, `login.zabazingo.cloud`, `app.zabazingo.cloud`.\n\n### `.eu` = zabazingo.eu — INTERN + DOKUMENTATION + MARKE / KOLLEKTIONEN\n\nNur-interne Tools, die Dokumentationsseite und die Marken- / Kollektions-Seiten. Nicht für Login / Nutzung durch Dritte gedacht.\n\n- **Dokumentation** (gebaut im Stil von `claude.adam---eve.com`, aber in **ZABAZINGO CI**) lebt hier: `docs.zabazingo.eu`.\n- **Marke / Kollektionen**: `collection.zabazingo.eu`, `collections.zabazingo.eu`.\n- **Interne Tools**: jede Admin- / Ops- / agenten-interne Oberfläche.\n\nBeispiele (nicht abschließend): `docs`, `collection`, `collections`, plus alle internen / Admin- / Ops-Werkzeuge → `.eu`.\n\n### Entscheidungsbaum (Dimension 1)\n\n```\nneuer Service\n  └─ Loggt sich ein Dritter (Nutzer/Kunde/extern) ein oder nutzt es?\n        ├─ JA → .cloud   (mail, secrets, cloud, storage, vault, keychain, login, app …)\n        └─ NEIN → ist es Doku / Marken-Kollektion / nur-intern?\n                    └─ JA → .eu   (docs, collection(s), interne/Admin-Tools)\n```\n\n## Dimension 2 — Additivität (`.cloud` kommt hinzu, `.eu` bleibt)\n\nEinen Service auf `.cloud` zu bringen ist **ADDITIV**, niemals ein Verschieben-mit-Löschen.\n\n- **TU:** Stelle die `.cloud`-Instanz **zusätzlich** auf. Verifiziere sie. Betreibe sie.\n- **Die `.eu`-Instanz bleibt vollständig unangetastet und läuft weiter.**\n- **NIEMALS** die `.eu`-Instanz löschen, deaktivieren oder umbiegen, um `.cloud` bereitzustellen. Zu keinem Moment verliert das Estate die `.eu`-Oberfläche.\n- **`.eu`-Stilllegung ist eine SEPARATE Entscheidung** — explizit, pro Service und **Operator-gated**. Sie wird nie in den `.cloud`-Rollout gebündelt, nie autonom.\n\n> **Invariante:** *`.cloud` hinzufügen darf `.eu` nicht entfernen.* Wenn eine Aufgabe sagt \"verschiebe X auf `.cloud`\", lies das als \"**stelle** X **auch** auf `.cloud` bereit; lass `.eu` laufen\".\n\n## Dimension 3 — Server- / Umgebungs-Platzierung (GENERISCH)\n\nDies ist die **universelle** Logik. Sie verwendet nur abstrakte Rollen — **STAGING, LIVE (Produktion), BACKUP** — und funktioniert für jeden mit 1..N Servern. Sie macht **keine** Annahme, dass zwei getrennte Hosts existieren. (Unsere konkreten Hosts stehen im Config-Abschnitt weiter unten — das ist **nicht** Teil dieser Regel.)\n\n### Generische Entscheidungs-Reihenfolge (von oben nach unten, erster Treffer gewinnt)\n\n```\n1. STAGING existiert? (dedizierter Host ODER Staging-Zone)\n      → BAUE + VERIFIZIERE dort ZUERST. Immer. Nie überspringen.\n\n2. SEPARATE LIVE/Produktions-Umgebung existiert? (und Staging verifiziert)\n      → PROMOTE staging → live. owner/operator-gated.\n\n3. NUR EIN Server (kein separates staging/live)?\n      → läuft auf diesem EINEN Server. Staging und Live KOLLABIEREN darauf:\n        nutze eine Staging-Subdomain / Pfad / Pre-Prod-Vhost auf demselben Host,\n        verifiziere, DANN flippe auf den Prod-Vhost auf demselben Host.\n\n4. BACKUP-Ziel existiert?  [IMMER — nicht erster-Treffer]\n      → IMMER off-site restic-Backup einrichten UND Stateful-Daten auf eine\n        DEDIZIERTE Daten-Partition/Volume legen, getrennt vom OS-Volume.\n```\n\n### Invariante (Dimension 3)\n\n> **Kein Stateful-Service ohne Backup + dedizierte Daten-Partition**, wo immer ein Backup-Ziel existiert. Daten dürfen nie auf genau einer Maschine leben (`no_single_copy`). Stateful-Daten sitzen nie auf dem OS-Root-Volume.\n\n## CONFIG (nicht die Regel) — UNSERE konkrete SERVER-MAP\n\nDiese Tabelle ist **unsere Instanziierung** von Dimension 3. Sie ist **Konfiguration**, nicht die Logik. Ein anderes Estate füllt sie anders; die Regel oben bleibt unverändert. Maschinenlesbarer Spiegel: `/etc/bbe/policy.yaml` → `server_map`.\n\n| Rolle | Host | IP |\n|---|---|---|\n| **STAGING** | bbe-demo (Hetzner, host_id 4) | 178.105.187.135 |\n| **LIVE** (Produktion) | bbe-live (Hetzner, host_id 5) | 91.99.99.252 |\n| **BACKUP** | Hetzner Storage Box (restic) | box `u587136` |\n| **Nur-intern — KEIN neues öffentliches Web** | 159 / bbe-primary (Netcup) | 159.195.30.60 |\n| **Legacy-Quelle / Rollback** | 73er / alt-server (Netcup) | 45.84.199.73 |\n\nWendet man die generische Logik mit dieser Map an: Neues öffentliches Web wird **zuerst auf bbe-demo (178) gebaut**, **auf bbe-live (91.99.99.252) promotet** unter einem Operator-Gate, **auf die Storage Box gesichert**, während **159 kein neues öffentliches Web trägt** und **der 73er nur Rollback/Legacy ist** (migrieren-weg, nie neues Main).\n\n## Zusammengesetzt — vollständige Platzierung in 3 Fragen\n\nFür jeden neuen Service, der Reihe nach beantworten:\n\n1. **TLD:** Zugriff durch Dritte? → `.cloud`. intern/Doku/Kollektion? → `.eu`.\n2. **Additiv:** Wenn `.eu` das schon bedient, `.cloud` **hinzufügen**, `.eu` oben lassen. (`.eu`-Stilllegung = später, separat, Operator-gated.)\n3. **Umgebung:** STAGING zuerst → promote zu LIVE (gated) → (oder Kollaps auf den einzelnen Server) → **immer** Backup + Daten-Partition. Unsere Map: STAGING=bbe-demo/178, LIVE=bbe-live/91.99.99.252, BACKUP=Storage Box.\n\n## Querverweise\n\n- Staging→Live-Promotion-Flow + Hostname-Konventionen: `staging-policy.md`\n- Maschinenlesbare Policy: `/etc/bbe/policy.yaml`\n- Server-Inventar + Zugang: `inventory.md` und Kapitel **Server- & Infra-Übersicht**\n- No-data-loss-Migrationsschritte: `migration-protocol.md`\n- Backup-Einrichtung: `backup.md`\n- DNS (Infomaniak, beide TLDs): `infomaniak.md`\n"
    },
    {
      "file": "02_INFRA_UEBERSICHT.md",
      "title": "Server- & Infra-Übersicht",
      "category": "Fundament",
      "confidential": false,
      "chars": 3773,
      "words": 507,
      "headings": [
        "Estate-Server-Rollen",
        "Umgebungs-Logik (Kurzform)",
        "Fundament-Services (auf 159, 127.0.0.1)",
        "Zugang (Verweise, keine Secrets hier)",
        "Der Infrastructure Conductor (Agent #9)"
      ],
      "content": "# Server- & Infra-Übersicht\n\n> Diese Übersicht ist die **Config**-Ebene zum Kapitel \"Domain & Deployment Concept\". Die Platzierungs-**Regel** ist generisch; die Tabellen hier sind unsere konkrete Instanziierung. Vor Vertrauen verifizieren — Inventar gilt nur, solange es geprüft ist.\n\n## Estate-Server-Rollen\n\n| Host | IP(s) | Provider | Rolle | OS |\n|---|---|---|---|---|\n| **bbe-demo** (host_id 4) | 178.105.187.135 | Hetzner cpx32 (nbg1) | **Kanonisches STAGING / DEMO** — staging-first landet hier; off---set-Backup | Debian 13, Caddy |\n| **bbe-live** (host_id 5) | 91.99.99.252 | Hetzner cpx32 (nbg1) | **LIVE-Promotion-Ziel** — off---set serving | Debian 13, Caddy |\n| **Storage Box** | box `u587136` | Hetzner | **BACKUP** — off-site restic, no_single_copy | — |\n| **159** (bbe-primary) | 159.195.30.60 | Netcup (v2202…) | Agenten-/Infra-Host — **bleibt frei von öffentlichem Web, KEINE neuen Projekte** | Debian 13 |\n| **73er / alt-server** | 45.84.199.73 | pph-server | Legacy-Prod, überlastet, **Rollback-Fallback** — migrieren-weg, nie neues Main | Debian 12, Apache |\n\nAndere in DNS sichtbare Hosts: zabazingo `84.16.66.164` = ein gunicorn-Redirect-Host (`.it→.de`, NICHT Infomaniak); ein Shopify-Storefront ist extern.\n\n## Umgebungs-Logik (Kurzform)\n\n```\nSTAGING (bbe-demo/178)  →  bauen + verifizieren ZUERST, immer\n        │  Operator-Gate (Promotion)\n        ▼\nLIVE (bbe-live/91.99.99.252)  →  promoten, nie selbst der erste Schritt\n        +\nBACKUP (Storage Box)  →  IMMER, parallel, für alles Stateful\n```\n\n- **159 trägt kein neues öffentliches Web.** Es ist der Agenten-/Infra-Host.\n- **73er ist Rollback/Legacy.** Neue Dienste landen dort nie als Main.\n- **Kein Stateful-Service ohne Backup + dedizierte Daten-Partition.**\n\n## Fundament-Services (auf 159, 127.0.0.1)\n\n| Service | Port | Zweck |\n|---|---|---|\n| port-registry | 5099 | Port-Allokation / -Registrierung |\n| hetzner-api | 5110 | governed Server-Provisioning |\n| ip-pool-api | 5340 | IP-State-Machine; `POST /v1/ip/reserve` (clean tier) |\n| adam-eve-bridge | 5320 | MCP-Brücke zum PM |\n| infomaniak-api | 5380 | DNS-Adapter |\n| dynadot-api | 5390 | Domain-Registrar (sandbox) |\n\n## Zugang (Verweise, keine Secrets hier)\n\n- Auf **159** läuft man als `dev` mit NOPASSWD-sudo.\n- **73er**: `ssh alt-server` (User root, Key konfiguriert).\n- **bbe-live / bbe-demo**: `sudo ssh -i /root/.ssh/id_ed25519 root@<ip>` (Key `bbe-netcup-hub`).\n- rsync zu live/demo: `rsync -e \"ssh -i /root/.ssh/id_ed25519\" …` (via sudo).\n\n> Keine Schlüssel, Passwörter oder Tokens stehen in dieser Doku. Secrets liegen im age-Vault / Vaultwarden und werden nie ausgegeben.\n\n## Der Infrastructure Conductor (Agent #9)\n\nAlle Server-, Domain-, E-Mail-, Backup- und Deploy-Arbeit läuft über die `bbe-infra`-Disziplin und wird vom **Infrastructure Conductor #9** ausgeführt und protokolliert. Sein Arbeitsablauf:\n\n1. **Verify** — Inventar prüfen, bevor man vertraut.\n2. **Plan** — Platzierung über die drei Dimensionen entscheiden (TLD, Additivität, Umgebung).\n3. **Execute** — provisionieren / DNS / TLS / deployen über die Provider-Adapter (Hetzner, Netcup, Infomaniak).\n4. **Verify again** — Render-/Health-/TLS-Checks, bevor \"fertig\".\n5. **Record** — PM-Ticket für Follow-ups/Blocker, passende Memory-Datei aktualisieren.\n6. **Announce** — nach jeder abgeschlossenen Aktion eine kurze Markdown-Zusammenfassung in den `conductor-log`-Kanal posten (Mattermost), als **Infrastructure Conductor #9**: `/srv/oktogen-chat/scripts/conductor-post.sh \"<summary>\"` (auf 159; Token aus dem age-Vault, nie ausgegeben). So liest der Operator, was der Conductor getan hat.\n\n> Operator-Direktive: Der Operator führt nichts manuell aus. Infra-/DNS-/Deploy-/Console-Tasks werden als `[ROOT·service]`-PM-Ticket an den Conductor delegiert.\n"
    },
    {
      "file": "03_TYPOGRAFIE.md",
      "title": "Typografie- & Brand-Regelwerk",
      "category": "Marke",
      "confidential": false,
      "chars": 7278,
      "words": 851,
      "headings": [
        "Zwei Stimmen, scharfe Rollen",
        "Der Slogan — eine Regel, keine Ausnahme",
        "Wortmarken (Brand Elements)",
        "DBE / GFYS-Familie",
        "Display Type-Scale (H1 → H4)",
        "Sans Type-Scale (H1 → Caption)",
        "Palette"
      ],
      "content": "# Typografie- & Brand-Regelwerk\n\n> Quelle: das ratifizierte ZZ Typography System (CI Guide v1, `discord.zabazingo.eu/typography.html`). Diese Seite rendert die Regeln mit den **echten** ZABAZINGO-Schriften (lokal ausgeliefert, keine CDN-Substitute). Body min. 16px. Wortmarken einfarbig — Akzent läuft ausschließlich über Gewicht, nie über Farbe.\n\n## Zwei Stimmen, scharfe Rollen\n\n**Display trägt die Brand-Stimme** — Headlines, Wortmarken, Heros.\n**Sans trägt den Body** — UI, Text, Editorial. Es gibt keine dritte Schrift im System.\n\n| | Display · Serif | Sans · Neo-Grotesque |\n|---|---|---|\n| Schrift | Noto Serif Display ExtraCondensed | PP Neue Montreal |\n| Cuts | ExtraLight 200 · Regular 400 · Bold 700 | Light 300 · Regular 400 · Semibold 600 · Bold 700 |\n| Einsatz | Headlines, Wortmarken, Brand-Elemente | UI, Body, Editorial, Captions, Buttons, Labels |\n| Tracking | −0.05em (default) | −0.015em (Headlines) · 0 (Body) · +0.14em (Caps-Labels) |\n| Leading | 1.05 (display) · 1.02 (extreme tight) | 1.2 (Headlines) · 1.5–1.65 (Body) |\n| Case | siehe Wortmark-Regeln | Headlines lowercase · UPPERCASE nur in Labels |\n| Min. Größe | 22px — darunter Sans verwenden | — |\n\n## Der Slogan — eine Regel, keine Ausnahme\n\nDer Brand-Slogan ist **kein** Headline und folgt **nicht** der Display-Cap-Akzent-Regel. Er hat seine eigene Setting: Mantel ExtraLight 200, Akzent **«given.»** und **«chosen.»** in Bold 700. Sentence Case (R, I groß **ohne** Weight-Akzent). Tracking −0.05em, Leading 1.02. Apostroph typografisch ’ (U+2019). Der Slogan steht **immer alleine** — 2 oder 3 Zeilen, nie 1, nie 4+.\n\n<div style=\"font-family:var(--sans);text-transform:none;font-weight:200;font-size:clamp(2rem,6vw,4.5rem);line-height:1.02;letter-spacing:-0.05em;color:var(--ink);margin:2rem 0;padding:2rem 0;border-top:1px solid var(--line);border-bottom:1px solid var(--line)\">Reality isn’t <b style=\"font-weight:700\">given.</b><br>It’s <b style=\"font-weight:700\">chosen.</b></div>\n\n**Verboten** (Auswahl aus §04 Don’ts): Cap-Akzent auf R + I · Title Case · All Caps · komplett Bold · Italic (Noto Serif Display hat keinen Italic-Cut — Italic ist im ZZ-System nur PP Neue Montreal vorbehalten) · zweifarbig · Random-Weight-Mix · falsche Apostrophe (´ Akut oder gerade ' sind falsch).\n\n## Wortmarken (Brand Elements)\n\nJedes Brand-Element hat **exakt eine** Setting. Nicht improvisieren, nicht über andere Weights skalieren. Brand-Name immer UPPERCASE — niemals lowercase, niemals Mixed-Case, niemals nur eine Hälfte. Mantel = ExtraLight 200, Akzent (Z · & · Z) = Bold 700, einfarbig.\n\n<div style=\"display:flex;flex-wrap:wrap;gap:2.5rem;align-items:flex-end;margin:2rem 0;padding:2rem;background:var(--bg-2);border:1px solid var(--line);border-radius:14px\">\n  <div>\n    <div style=\"font-family:var(--serif);text-transform:uppercase;font-weight:200;font-size:3.4rem;line-height:1;letter-spacing:-0.044em;color:var(--ink)\"><b style=\"font-weight:700\">Z</b>ABA&nbsp;<b style=\"font-weight:700\">&amp;</b>&nbsp;<b style=\"font-weight:700\">Z</b>INGO</div>\n    <div style=\"font-family:var(--sans);font-size:.7rem;text-transform:uppercase;letter-spacing:.14em;color:var(--ink-dim);margin-top:.6rem\">01 · mit Ampersand · −44</div>\n  </div>\n  <div>\n    <div style=\"font-family:var(--serif);text-transform:uppercase;font-weight:200;font-size:3.4rem;line-height:1;letter-spacing:-0.044em;color:var(--ink)\"><b style=\"font-weight:700\">Z</b>ABA&nbsp;<b style=\"font-weight:700\">Z</b>INGO</div>\n    <div style=\"font-family:var(--sans);font-size:.7rem;text-transform:uppercase;letter-spacing:.14em;color:var(--ink-dim);margin-top:.6rem\">02 · kompakt · −44</div>\n  </div>\n  <div>\n    <div style=\"font-family:var(--serif);text-transform:uppercase;font-weight:700;font-size:3.4rem;line-height:1;letter-spacing:-0.2em;color:var(--ink)\">ZZ</div>\n    <div style=\"font-family:var(--sans);font-size:.7rem;text-transform:uppercase;letter-spacing:.14em;color:var(--ink-dim);margin-top:.6rem\">04 · Monogram · −200</div>\n  </div>\n</div>\n\n## DBE / GFYS-Familie\n\nAlle vier Varianten sind **dieselbe** Schrift (Display Serif). Der Unterschied liegt nur in **Weight + Case**: Caps + Bold = laut, lowercase + ExtraLight = leise.\n\n| Mark | Weight | Case | Bedeutung / Einsatz |\n|---|---|---|---|\n| **DBE** | Regular 400 | UPPERCASE | Akronym \"Don’t Believe Everything\" · Sub-Brand-Labels, Tags, Footer |\n| **dbe** | ExtraLight 200 | lowercase | leiseste Form · Editorial / Captions / Body-Mentions |\n| **GFYS** | Bold 700 | UPPERCASE | lautester Zustand · Statement-Walls, Merch, Single-Word-Heros |\n| **gfys** | ExtraLight 200 | lowercase | Editorial-Annotation, Inline-Reference |\n\nTracking durchgehend −0.05em, Leading 1.0. Niemals in einer anderen Schrift.\n\n## Display Type-Scale (H1 → H4)\n\nDisplay Serif folgt der Brand-Regel: ExtraLight 200 als Mantel, der erste Buchstabe jedes groß geschriebenen Wortes Regular 400 (Cap-Akzent). Tracking einheitlich −0.05em, Leading 1.05. Display stoppt bei **H4 (40px)** — kleiner wird Extra-Condensed unleserlich, ab H5 übernimmt PP Neue Montreal.\n\n<div style=\"margin:2rem 0;display:flex;flex-direction:column;gap:1rem\">\n  <div style=\"font-family:var(--sans);font-weight:200;font-size:4rem;line-height:1.05;letter-spacing:-0.05em;color:var(--ink)\"><span style=\"font-weight:400\">T</span>he <span style=\"font-weight:400\">S</span>ignal <span style=\"font-weight:400\">N</span>oise <span style=\"font-weight:400\">R</span>atio</div>\n  <div style=\"font-family:var(--sans);font-size:.7rem;text-transform:uppercase;letter-spacing:.14em;color:var(--ink-dim)\">H1 · 96px · lh 1.05 · ls −0.05em</div>\n  <div style=\"font-family:var(--sans);font-weight:200;font-size:2.6rem;line-height:1.05;letter-spacing:-0.05em;color:var(--ink)\"><span style=\"font-weight:400\">M</span>ore signal, less noise</div>\n  <div style=\"font-family:var(--sans);font-size:.7rem;text-transform:uppercase;letter-spacing:.14em;color:var(--ink-dim)\">H3 · 54px · lh 1.05 · ls −0.05em</div>\n</div>\n\n## Sans Type-Scale (H1 → Caption)\n\nPP Neue Montreal trägt die UI-Hierarchie und übernimmt unterhalb H4. Tracking einheitlich −0.015em, Leading 1.2 über alle Headline-Größen, Body 1.5–1.65. **Lowercase** in allen Sans-Headlines, kein Cap-Akzent. UPPERCASE nur für Labels (+0.14em).\n\n| Stufe | Cut | Größe / Setting | Beispiel |\n|---|---|---|---|\n| H1 Sans | Light 300 | 72px · lh 1.2 · lowercase | reality is built by those who refuse it. |\n| H4 Sans | Light 300 | 30px · lh 1.2 · lowercase | promo headline / card title |\n| H6 Sans | Regular 400 | 18px · lh 1.3 · lowercase | ui sub-header |\n| Body L | Light 300 | 16px · lh 1.6 | Default Body — Mindestgröße im Web, sobald Inhalt kein UI ist. |\n| Body S | Light 300 | 13px · lh 1.5 | Captions, Metadaten, Footnotes — sparsam. |\n| Caption | Regular 400 caps | 11px · lh 1.4 · ls +140 | EYEBROW · LABEL · KATEGORIE · TAG |\n\n## Palette\n\n| Token | Wert | Rolle |\n|---|---|---|\n| `--bg` (dark) | `#22201f` | warm-dunkler Hintergrund |\n| `--bg` (light) | `#fffada` | creme Hintergrund |\n| `--ink` | `#22201f` / `#f3eee4` | Text |\n| `--accent` / Terra | `#A53A2A` | einziger Akzent (CTA, Live, Links) |\n\n> Diese Doku selbst ist in der ZABAZINGO CI gesetzt: Display = Noto Serif Display ExtraCondensed, Sans = PP Neue Montreal, Akzent = Terra #A53A2A. Theme-Toggle oben rechts (dunkel ↔ creme).\n"
    },
    {
      "file": "04_CORTEX_ENGINES.md",
      "title": "ZABAZINGO Cortex — Engine-Register",
      "category": "Plattform",
      "confidential": false,
      "chars": 5252,
      "words": 688,
      "headings": [
        "Zwei harte Regeln",
        "Die Cortex-Familie",
        "Was jede Engine leistet",
        "Architektur — eine Quelle der Wahrheit",
        "Anbieter wechseln — die Ein-Zeilen-Prozedur",
        "Neue Engine aufnehmen",
        "Geltungsbereich"
      ],
      "content": "# ZABAZINGO Cortex — Engine-Register\n\n> Cortex ist der interne Markenname für alle KI- und Erkennungs-Engines, die in ZABAZINGO-Produkten Dokumente lesen, verstehen und durchsuchen. Diese Seite ist die **verbindliche Quelle** für die Engine-Namen. Externe Anbieternamen (Mistral, LlamaParse, Claude, …) erscheinen nie in einer Oberfläche, API-Antwort, einem Export oder Vertragstext — sie werden an der Darstellungsgrenze in Cortex-Codenames übersetzt.\n\n## Zwei harte Regeln\n\n1. **Kein Vendor-Name nach außen.** Welcher Anbieter eine Engine antreibt, ist Betriebs-Interna. Nutzer, Kunden, Partner, Screenshots und Exporte sehen ausschließlich `Cortex <NAME>`. Ein Anbieterwechsel darf an keiner sichtbaren Stelle auffallen.\n2. **Marke ist ZABAZINGO.** `adam-eve` ist eine interne Plattform-/Tenant-Bezeichnung und wird **nicht** nach außen verwendet. Jede nutzersichtbare Wortmarke, jeder Title-Tag und jeder Doku-Verweis lautet ZABAZINGO.\n\nBeide Regeln sind nicht stilistisch, sondern Betriebsrecht. Sie haben Vorrang vor Bequemlichkeit.\n\n## Die Cortex-Familie\n\n| Codename | Rolle (das sieht der Nutzer) | Stufe | Anbieter (intern, verborgen) |\n|---|---|---|---|\n| **Cortex SLATE** | Schnelle Basis-Texterkennung | Free OCR | PaddleOCR / Tesseract |\n| **Cortex ONYX** | Hochpräzise Erkennung, auch Handschrift | Premium OCR | Mistral OCR |\n| **Cortex PRISM** | Tabellen- und Struktur-Parsing | Premium OCR | LlamaParse |\n| **Cortex SCRIBE** | Feld- und Vertragsextraktion | Extraktion | mistral-small |\n| **Cortex LEX** | Klausel- und Risiko-Analyse | Analyse | Mistral |\n| **Cortex ORACLE** | Semantische Suche („liest deine Cloud\") | Suche | Claude |\n| **Cortex ECHO** | Quer-Review und Verifikation | Review | Gemini |\n\nNamensschema: ein kurzes, großgeschriebenes Einzelwort aus dem Tresor-/Mineral-/Orakel-Feld — passend zur warm-dunklen ZABAZINGO-CI mit Bronze-Akzent. Die Anbieter-Spalte steht ausschließlich in dieser internen Doku.\n\n## Was jede Engine leistet\n\n- **SLATE** — der kostenlose Schnell-Leser. Solide Druckschrift-Erkennung ohne Zusatzkosten, Standard für jeden Upload.\n- **ONYX** — der Premium-Leser. Hohe Genauigkeit auch bei Handschrift, schlechten Scans und Fotos. Greift, wenn SLATE nicht reicht oder der Nutzer Premium wählt.\n- **PRISM** — der Struktur-Leser. Zerlegt Tabellen, Formulare und mehrspaltige Layouts in saubere, maschinenlesbare Struktur. Wird automatisch für Tabellen-/Mehrspalten-Dokumente bevorzugt.\n- **SCRIBE** — die Feld-Extraktion. Liest aus erkannter Schrift die strukturierten Felder heraus (z. B. Vertragspartner, Laufzeit, Kündigungsfrist) — jeweils mit Konfidenz; unsichere Werte werden zur Prüfung markiert, nie still gesetzt.\n- **LEX** — die Klausel- und Risiko-Analyse. Erkennt kanonische Vertragsklauseln (Auto-Verlängerung, kurze Fristen, Preiserhöhung, Pönale, Haftung, Exklusivität, Datenschutz, lange Bindung) und stuft das Risiko ein.\n- **ORACLE** — die semantische Suche über den gesamten Tresor („liest deine Cloud\"). Beantwortet natürliche Suchanfragen über alle Dokumente.\n- **ECHO** — die unabhängige Zweitmeinung. Quer-prüft und verifiziert Ergebnisse anderer Engines.\n\n## Architektur — eine Quelle der Wahrheit\n\nDie Übersetzung von Anbieter-ID zu Codename liegt an genau einer Stelle:\n\n```\ncloud-adam-eve/lib/engine-codenames.mjs   (Register + Auflösung)\n```\n\nDas Register bildet jede Anbieter-/Modell-ID auf einen Cortex-Eintrag ab und stellt drei Helfer bereit:\n\n- `codename(vendorId)` → reiner Codename, z. B. `\"mistral-ocr-latest\"` → `\"ONYX\"`. Drop-in überall, wo bisher eine rohe Engine-ID ausgegeben wurde.\n- `engineLabel(vendorId)` → volles Label, z. B. `\"Cortex ONYX\"`, für Überschriften und Badges.\n- `sanitizeKeys(obj)` → schreibt Objekte um, deren **Schlüssel** Anbieternamen sind (Provider-/Genauigkeits-Maps, über die das UI iteriert): `{ mistral: true }` → `{ ONYX: true }`.\n\nDie Auflösung ist tolerant (Teilstring, längster Treffer zuerst), sodass sowohl `mistral-ocr-latest` als auch ein blankes `mistral` korrekt landen. Unbekannte IDs fallen sicher auf den Familiennamen `CORTEX` zurück — nie auf einen Anbieternamen.\n\n## Anbieter wechseln — die Ein-Zeilen-Prozedur\n\nWird ein Anbieter ersetzt (z. B. ONYX läuft künftig nicht mehr über Mistral OCR):\n\n1. Im Register `VENDOR_MAP` die betroffene Zeile auf die neue Anbieter-ID zeigen lassen.\n2. Den `vendor`-Vermerk des Cortex-Eintrags aktualisieren (nur interne Doku-Notiz).\n3. Diese Doku-Tabelle in der Anbieter-Spalte nachziehen.\n\nCodename, UI, API, Exporte und Verträge bleiben unverändert. Genau das ist der Zweck: **außen ändert sich nichts.**\n\n## Neue Engine aufnehmen\n\n1. Eintrag in `ENGINES` mit Codename (Tresor-/Mineral-/Orakel-Wort), `tier`, `label`, `blurb`, `vendor`.\n2. Zeile(n) in `VENDOR_MAP` für die Anbieter-/Modell-IDs.\n3. Diese Tabelle erweitern.\n4. Falls eine neue Stufe entsteht: Produkt-/Preis-Stufe gegen die bestehenden Tiers prüfen.\n\n## Geltungsbereich\n\nCortex-Namen gelten für jedes ZABAZINGO-Produkt, das diese Engines nutzt — Tresor/Dokumente, Verträge, Belege und alle künftigen. Tritt irgendwo ein roher Anbietername auf (UI-Text, API-Feld `engine`, Status-/Genauigkeitstabelle, Export, Audit-Text), ist das ein Defekt und wird über das Register behoben, nicht durch lokales Umschreiben.\n"
    },
    {
      "file": "C_BEITRAGEN.md",
      "title": "Kapitel hinzufügen (Scaffold)",
      "category": "Meta",
      "confidential": false,
      "chars": 2550,
      "words": 342,
      "headings": [
        "Schritt 1 — Markdown-Datei anlegen",
        "Schritt 2 — Eintrag im `DOCS`-Array",
        "Schritt 3 — Deploy (nach der Policy)",
        "Konventionen"
      ],
      "content": "# Kapitel hinzufügen (Scaffold)\n\nDie Seite ist **datengetrieben** — genau wie die Vorlage-Engine es vorsieht. Ein neues Kapitel hinzuzufügen sind zwei Schritte; kein Engine-Code muss angefasst werden außer einer Zeile im `DOCS`-Array.\n\n## Schritt 1 — Markdown-Datei anlegen\n\nLege die Datei unter `docs/de/` (und optional `docs/en/` für die englische Fassung) ab. Dateiname-Konvention: `NN_NAME.md` (Reihenfolge über die Nummer), oder ein Buchstaben-Präfix für Anhänge (`A_`, `C_`).\n\n```\ndocs/de/04_MEIN_KAPITEL.md\ndocs/en/04_MEIN_KAPITEL.md   (optional — Fallback auf DE, wenn fehlt)\n```\n\nMarkdown wird via `marked` gerendert. Eingebettetes HTML wird durchgereicht — so entstehen z. B. die Schrift-Specimens im Typografie-Kapitel. Tabellen brechen automatisch in einen scrollbaren `.table-wrap`.\n\n## Schritt 2 — Eintrag im `DOCS`-Array\n\nIn `server.js` (Sektion `const DOCS = [ … ]`) eine Zeile ergänzen:\n\n```js\n{ file: '04_MEIN_KAPITEL.md',\n  title:   'Mein Kapitel',          // DE-Titel (Sidebar)\n  titleEn: 'My Chapter',            // EN-Titel\n  cat:     'Fundament',             // DE-Kategorie (gruppiert die Sidebar)\n  catEn:   'Foundation',            // EN-Kategorie\n  confidential: false },            // true → Schloss-Icon + Vertraulich-Badge\n```\n\nFelder:\n\n| Feld | Pflicht | Bedeutung |\n|---|---|---|\n| `file` | ja | Dateiname in `docs/<lang>/` |\n| `title` / `titleEn` | ja / optional | Sidebar-Titel pro Sprache |\n| `cat` / `catEn` | ja / optional | Kategorie — gleiche Werte werden gruppiert |\n| `confidential` | optional | `true` markiert das Kapitel als besonders vertraulich |\n\nNeue Kategorien erscheinen automatisch in der Sidebar. Für ein eigenes Kategorie-Icon den Wert in `CAT_ICON` ergänzen (sonst Fallback-Icon).\n\n## Schritt 3 — Deploy (nach der Policy)\n\nÄnderungen werden **zuerst auf Staging** (bbe-demo) ausgerollt und render-verifiziert (Desktop + Mobile, Fonts laden, CI korrekt), dann per Operator-Gate auf Live promotet. Siehe Kapitel **Domain & Deployment Concept**.\n\n```\n# auf Staging deployen, Service neu starten, verifizieren\nrsync … → bbe-demo:/srv/zabazingo-docs/\nsystemctl restart zabazingo-docs\ncurl -fsS https://demo.docs.zabazingo.eu/health   # {\"status\":\"ok\",...}\n```\n\n## Konventionen\n\n- **Keine Emojis.** Nur premium / animiertes SVG für Icons (BBE-Designregel).\n- **Body min. 16px.** Display = Noto Serif Display, Sans = PP Neue Montreal.\n- **Nichts erfinden.** Was wahr ist, wird belegt; Annahmen werden als `[ANNAHME]` gekennzeichnet.\n- **Keine Secrets** in der Doku — Schlüssel/Tokens bleiben im Vault.\n"
    }
  ]
}