# SOUL — BSC Score > Diese Datei ist das Herzstück des Projekts: **wofür** die App existiert und **wie** wir daran arbeiten. > Für Menschen, für zukünftige Agents, für Frank-in-6-Monaten-der-vergessen-hat-warum-Tap-to-Score. --- ## Was diese App ist **BSC Score** ist eine **PWA zum Live-Scoring von Pool-/Billardpartien** — gebaut für den Einsatz **am Tisch**, nicht als Statistik-Portal oder Social App. **Tagline:** *Schnell punkten, nicht nachdenken.* **Der 3-Sekunden-Test:** Jemand startet ein neues Spiel und trägt den ersten Punkt ein — ohne Tutorial, ohne Login, ohne Netzwerk. **Nicht:** *„Wo war nochmal der Plus-Button?"* **Eine Rolle, klar:** - **Scorekeeper am Tisch** — Partie anlegen, Punkte tippen, Undo, fertig. Alles andere ist Nebenrolle. **Kontext:** App für den **Billard Sports Club** (BSC), produktiv unter [`score.bsc-gp.de`](https://score.bsc-gp.de). Lokale Daten bleiben auf dem Gerät (IndexedDB). --- ## Stimme & Ton - **Sprache:** Deutsch in UI, Labels und Fehlermeldungen. Billard-Standardbegriffe bleiben Englisch, wo sie am Tisch so gesagt werden: *Race to*, *Break*, *Rematch*, *Winnerbreak*, *Wechselbreak*, *8-Ball* / *9-Ball* / *10-Ball*. - **Formality:** Direkt und sachlich. Formelles *Sie* nur in Bestätigungsdialogen (z. B. Löschen). Sonst neutral-kurz — kein Smalltalk, kein Marketing. - **Fehlermeldungen:** Ehrlich, konkret, ohne Schuldzuweisung. Was fehlt, was zu tun ist. - **Kein App-Store-Sprech.** Kein „Erlebnis optimieren", kein „Synergien", kein Gamification-Buzz. **Werte sind funktional, nicht dekorativ:** Schnelligkeit am Tisch schlägt Feature-Reichtum. Ein Tipp = ein Punkt. Undo statt Minus-Buttons. ### Wording-Beispiele | Kontext | Gut | Schlecht | |---------|-----|----------| | Erfolg | „Alex hat gewonnen!" | „Glückwunsch! Dein Match wurde erfolgreich abgeschlossen." | | Fehler | „Spielername ist erforderlich" | „Ungültige Eingabe. Bitte prüfen Sie Ihre Daten." | | Leer | „Keine Spiele vorhanden" | „Starte jetzt deine Billard-Reise!" | | Aktion | „+ Neues Spiel" / „Spiel beenden" | „Match initialisieren" / „Session terminieren" | | Bestätigung | „Möchten Sie das Spiel wirklich löschen?" | „Bist du sicher???" | --- ## Visuelle & technische DNA | Element | Ja | Nö | |---------|----|----| | Dark Mode (`#1a1a1a` Hintergrund, `#222` Surfaces) | ✓ | | | Akzent Orange `#ff9800` | ✓ | | | Große Touch-Targets (44–56 px, Tablet-first) | ✓ | | | Vollbild-PWA (`display: fullscreen`) | ✓ | | | Tap auf Spieler-Karte = +1, Undo zum Zurücknehmen | ✓ | | | +/- Buttons am Scoreboard | | ✓ (entfernt, Issue #29) | | Toast-Spam bei jedem Punkt | | ✓ | | Helles Theme als Default | | ✓ | | Kleine Buttons, Desktop-only Layout | | ✓ | | Login, Accounts, Onboarding-Wizard | | ✓ | **Technik-Philosophie (2026):** Astro 5 (Islands) + Preact + TypeScript strict. Offline-first mit Service Worker und IndexedDB. Modular unter `src/lib` — Domain → Data → State → Features → Astro-Shell. Playwright-Recordings für wiederholbare Flows. Qualität heißt: **am Tablet im Querformat bedienbar, schnell hydratisierend, ohne Netz** — nicht Feature-Bloat. **Architektur-Regel (nicht verhandelbar):** ``` domain → data → state → features → app shell ``` Untere Schichten importieren nie aus höheren. Neue Logik zuerst in `@lib/domain`, dann nach oben. **Signature-Features (Teil der Identität):** - **Neues-Spiel-Wizard** (7 Schritte) — Spieler 1–3 (3 optional) → Spielart → Race-to / Endlos → Break-Regel → Break-Reihenfolge; **WizardSummary** zeigt bisherige Auswahl mit; jeder Schritt hat eigene Hintergrundfarbe (`step-player1` … `step-breakOrder`) - **Spieler-Historie** — Schnellauswahl bekannter Namen - **Break-Anzeige** — Weißer Punkt beim aktuellen Breaker - **Rematch** — Direkt neue Partie mit gleichen Spielern - **Vollbild-Toggle** — Fixiert oben rechts (Scoreboard-Steuerung unten frei) Cloud-Sync-Felder existieren im Domain-Modell, sind aber **noch nicht Produktfeature**. --- ## Was die App können muss **Spielarten:** 8-Ball, 9-Ball, 10-Ball — jeweils Race-to oder **Endlos** (14/1). **Kernflows:** 1. Neues Spiel anlegen (Wizard, max. wenige Schritte) 2. Live-Scoring (Score antippen → +1) 3. Undo (letzter Stand zurück) 4. Spiel beenden → Gewinner/Rematch 5. Spiele filtern (Alle / Aktiv / Abgeschlossen), löschen **Geräte-Priorität:** Android-Tablet / iPad **quer**, am Billardtisch. Virtual Keyboard darf Layout nicht zerlegen: `App.tsx` setzt `--app-height` und `--keyboard-offset` aus `visualViewport` (auch bei Orientierungswechsel). Mobile Portrait ist zweite Priorität, Desktop dritte. **Daten:** Alles lokal in `BSCScoreDB` (IndexedDB). Kein Server-State, keine Analytics, kein Tracking. --- ## Wie wir zusammenarbeiten ### Fränky liefert, Agent bindet ein | Datei | Zweck | |-------|-------| | [`NOTES.md`](NOTES.md) | Scratchpad — frei, chaotisch erlaubt | | [`SOUL.md`](SOUL.md) | Vision, Ton, Arbeitsweise | | [`.gitea`](.gitea) | Aktuelles Gitea-Issue für Traceability | **Regel:** Issue-getriebene Arbeit — Code-Änderungen gehören zu einem Gitea-Issue. Commits referenzieren die Issue-Nummer (`Refs #N` / `Fixes #N`). ### Arbeitsmodus Agent 1. **Scope eng halten** — nur anfassen, was die Aufgabe verlangt. Kein Refactor „nebenbei". 2. **Domain first** — Logik in `@lib/domain`, UI bleibt dünn. 3. **Tablet testen** — Landscape, Touch, Vollbild. Playwright-Recordings unter `tests/recordings/` als Referenz-Flows. 4. **`npm run build`** vor „fertig" — bei Permission-Problemen Docker wie in [`README.md`](README.md). 5. **Keine Commits**, unless Fränky explizit will. 6. **Englische Fehlertexte in `App.tsx`** sind Tech-Debt — neue UI-Texte immer Deutsch (siehe `VALIDATION_MESSAGES` in `@lib/domain/constants`). ### Prioritäten bei Konflikten ``` Bedienbarkeit am Tisch (80%) > Architektur-Schönheit (20%) Offline-Zuverlässigkeit > Cloud-Features Weniger Taps > mehr Optionen Deutsch + Billard-Jargon > eingedeutschte Fachbegriffe Barrierefreiheit (ARIA, Touch) > Animationen ``` --- ## Anti-Manifest (bitte nicht) - Statistik-Dashboard, Ranglisten, Social Sharing - User-Accounts, Login, Multiplayer-Sync (solange nicht explizit geplant) - Gamification (Badges, Streaks, XP) - i18n-Overhead — UI bleibt Deutsch - Feature-Creep im Wizard (jeder Schritt kostet Zeit am Tisch) - Monolithische Komponenten — der Refactor nach `src/lib` war bewusst, nicht rückgängig machen - Plus/Minus-Buttons am Score — Tap + Undo ist der Flow --- ## Für Agents: Quick Start 1. [`SOUL.md`](SOUL.md) lesen (du bist hier) 2. [`src/lib/docs/architecture.md`](src/lib/docs/architecture.md) — Modul-Layout und Import-Regeln 3. [`src/lib/domain/constants.ts`](src/lib/domain/constants.ts) — UI-Texte, Validierung, Design-Tokens 4. `npm run dev` → `http://localhost:3000` — Tablet-Viewport testen 5. Änderungen am **Ton** gegen SOUL abgleichen; am **Scoring-Flow** gegen Playwright-Recordings 6. Vor „fertig": `npm run build` + mindestens ein Kernflow manuell (Neues Spiel → Score → Undo → Beenden) --- ## Project-Specific Rules - Tap auf die ganze Spieler-Karte erhöht um 1 — kein separates Plus-UI — `Refs #29` - Wizard und Features leben unter `@lib/features/*`, Astro-`src/components` ist nur Shell - Deploy: `astro build` → `dist/` → nginx via [`compose.yml`](compose.yml) auf `score.bsc-gp.de` - PRD-Referenz in Cursor-Rules (`docs/prd.md`) — Datei fehlt im Repo; bei Widersprüchen SOUL + Code als führend behandeln und nachfragen --- ## Ein Satz zum Mitnehmen **BSC Score** ist der digitale Schiedsrichter-Zettel am Billardtisch — dunkel, orange, große Finger, ein Tipp pro Punkt, funktioniert auch ohne WLAN.