Sfoglia il codice sorgente

Compress CLAUDE.md, restructure TASKS.md with priority+owner tags, drop duplicate memory files

- CLAUDE.md: tightened prose (~30% shorter), added session-start-announcement
  rule, task owner-tag convention, and a note that TASKS.md status can drift
  from actual code (caught 2 stale-done P0 items this session).
- TASKS.md: numbered priority within P0, added [Claude]/[Bob] owner tags per
  task, added session-grouping suggestions. Removed 2 already-fixed items
  (Hello Worlddd debug text, Event->Horeca overflow - both git-confirmed
  fixed 2026-08-02) and corrected the EvenementHorecagelegenheid image-crash
  task description (no ConditionalBuilder wrap exists yet, contrary to prior
  note).
- Deleted 13 auto-memory files that duplicated CLAUDE.md content 1:1 (that
  file loads automatically every session already); MEMORY.md now just points
  back to CLAUDE.md/TASKS.md.
- Re-added .gitignore's .claude/ exclusion line (wiped by a prior export).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
bob 1 mese fa
parent
commit
170ffb46b1
2 ha cambiato i file con 319 aggiunte e 304 eliminazioni
  1. 175 178
      CLAUDE.md
  2. 144 126
      TASKS.md

+ 175 - 178
CLAUDE.md

@@ -4,33 +4,54 @@
 
 Werk uitsluitend binnen deze projectdirectory
 (`/home/bob/Projects/ff-app/uitgaanskrant-1qhvtd`). Niet daarbuiten
-zoeken of scannen (bijvoorbeeld geen `find /` over het hele
-bestandssysteem) — scope alle bestandsoperaties tot dit project.
+zoeken of scannen — scope alle bestandsoperaties tot dit project.
 
-## Sessiegeheugen — lees dit eerst
+## Werkwijze binnen een sessie
 
-Bob bespreekt elke taak in een **nieuwe, aparte chat**. Dit bestand en
-`TASKS.md` zijn daarom het geheugen tussen sessies — er is geen eerdere
-conversatie om op terug te vallen.
+- **Meld bij elke nieuwe stap kort vooraf wat je gaat doen**, vóór je
+  begint (staande voorkeur Bob, 2026-08-04).
+- Bob bespreekt elke taak in een **nieuwe, aparte chat** — geen
+  eerdere conversatie om op terug te vallen. `CLAUDE.md` + `TASKS.md`
+  zijn samen het volledige geheugen tussen sessies.
+- **Groepeer opgepakte taken per sessie op FlutterFlow-paginagebied**
+  waar mogelijk (bv. twee taken op dezelfde pagina/component samen
+  oppakken) — minder heen-en-weer-navigeren in de builder, minder
+  tokens. Zie de sessie-indeling bovenaan `TASKS.md`.
+- **`TASKS.md`-status kan achterlopen op de echte code** (Bob werkt
+  gelijktijdig, en documentatie-updates lopen niet altijd synchroon
+  met de export). Check een taak die er al even staat met
+  `git log --oneline -S"<kenmerkende string/tekst>"` of een gerichte
+  `grep` vóórdat je 'm oppakt — niet blind vertrouwen dat "open"
+  betekent "nog niet gefixt". (Precedent: 2026-08-04 bleken 2 "open"
+  P0-taken al op 2026-08-02 gefixt te zijn, git-bevestigd.)
+- **Eigenaar-tag per taak in `TASKS.md`**: `[Claude]` (zelfstandig of
+  via browser-automation te doen), `[Bob]` (sneller/simpeler voor Bob
+  zelf — meestal builder-UI met een bekend fragiele dialoog, zie
+  hieronder), of `[Bob — bezig]` (al geclaimd). Vuistregel: een kort,
+  mechanisch herhaald patroon zonder geneste dialogen → Claude;
+  ConditionalBuilder/JSON-Path-condities, List-typed
+  function-argumenten, of iets dat eerder al vastliep → Bob.
 
-**Vaste afsluitroutine, aan het eind van elke sessie/taak:**
-1. Werk `TASKS.md` bij: **een afgeronde taak wordt volledig verwijderd
-   uit de lijst** (niet gearchiveerd in een "Afgerond"-sectie — dat is
-   onnodige context/kosten voor toekomstige sessies). Zorg dat elke
-   resterende open taak zelfstandig te begrijpen is (concreet, met
-   bestandspad/context) zonder de chat gelezen te hebben waarin hij
-   ontstond.
-2. Werk dit bestand (`CLAUDE.md`) bij: **alleen** toevoegen als het
-   een blijvend herbruikbaar inzicht is (een conventie, een
-   architectuurkeuze, een bekende valkuil/bug-patroon) dat een latere
-   sessie anders opnieuw zou moeten uitzoeken. Geen sessieverslag,
-   geen changelog van wat er gedaan is, geen herhaling van
-   redeneringen. Ruim verouderde/dubbele info op in plaats van
-   eronder te plakken — dit bestand moet klein en scanbaar blijven.
+## Sessiegeheugen — afsluitroutine
+
+Aan het eind van elke sessie/taak:
+1. **`TASKS.md`**: een afgeronde taak wordt volledig **verwijderd**
+   (niet gearchiveerd — onnodige context/kosten voor latere sessies).
+   Elke resterende open taak moet zelfstandig te begrijpen zijn
+   (concreet, met bestandspad) zonder de ontstaanschat gelezen te
+   hebben.
+2. **`CLAUDE.md`**: alleen aanvullen met blijvend herbruikbare inzichten
+   (conventie, architectuurkeuze, bekend valkuil-patroon) die een
+   latere sessie anders opnieuw zou moeten uitzoeken. Geen
+   sessieverslag/changelog. Ruim verouderde info op i.p.v. eronder te
+   plakken — dit bestand moet klein en scanbaar blijven.
 3. Commit + push de gewijzigde `.md`-bestanden direct (geen
-   FlutterFlow-export nodig voor pure documentatiewijzigingen — alleen
-   de export/build-cyclus hieronder draaien als er ook echt
-   app-code is gewijzigd).
+   FlutterFlow-export nodig voor pure documentatiewijzigingen).
+
+**Geen apart memory-systeem meer nodig voor projectfeiten** — die
+staan allemaal hier en in `TASKS.md`, wat al elke sessie automatisch
+geladen wordt. (Auto-memory-bestanden zijn per 2026-08-04
+opgeschoond omdat ze dit bestand 1-op-1 dupliceerden.)
 
 ## FlutterFlow-workflow — belangrijk
 
@@ -38,188 +59,157 @@ Dit project wordt gebouwd via FlutterFlow (app.flutterflow.io). De
 FlutterFlow-cloudomgeving is de bron van waarheid, niet deze lokale
 code-export.
 
-- De gebruiker kan **geen** code rechtstreeks genereren of bewerken in
-  dit repo. Alle wijzigingen aan pagina's, componenten en modellen
-  moeten via de FlutterFlow-website gebeuren.
-- De enige uitzondering is **custom functions/widgets**
-  (`lib/custom_code/`) — en ook die voert de gebruiker in via de
-  Custom Code-editor op de FlutterFlow-website, niet door hier
-  rechtstreeks bestanden te bewerken.
+- Bob kan **geen** code rechtstreeks bewerken in dit repo. Alle
+  wijzigingen aan pagina's, componenten en modellen moeten via de
+  FlutterFlow-website. Enige uitzondering: custom functions/widgets
+  (`lib/custom_code/`) — ook die voert Bob in via de Custom
+  Code-editor op de website, niet hier lokaal.
 - Gevolg: directe Edit/Write-wijzigingen aan gegenereerde bestanden
-  (pagina's, blocks, components, models, `lib/flutter_flow/*` e.d.)
-  worden bij de volgende export/sync vanuit FlutterFlow overschreven.
-  Zulke bestanden hier aanpassen is dus **niet duurzaam**.
-- Werkwijze: gebruik deze lokale repo om code te lezen, logica te
-  ontwerpen en te verifiëren (bijv. met `flutter analyze`) — maar
-  vertaal het eindresultaat naar concrete, stapsgewijze instructies
-  voor wat de gebruiker in de FlutterFlow-builder (of de Custom
-  Code-editor) moet doen, of voer het zelf uit via browser-automation
-  (zie hieronder). Ga er niet van uit dat een lokale bestandswijziging
-  behouden blijft.
-- Als er via de Chrome-browser (Claude in Chrome) rechtstreeks in de
-  FlutterFlow-builder wordt gewerkt: maak na elke **afgeronde taak**
-  (niet na elke losse klik/handeling) een **commit binnen FlutterFlow
-  zelf** (het eigen versiebeheer, te zien bovenin de builder als
-  "main"/"Synced"), met een duidelijke omschrijving van wat er is
-  veranderd. Dit is geen lokale `git commit`.
-- **Gebruik `mcp__claude-in-chrome__*` (Bob's eigen, gedeelde Chrome),
-  niet de in-app Browser pane** — dat is de afgesproken tool voor
-  builder-automation.
-- **Resize de browser niet zelf** (`resize_window` e.d.) — dit is
-  Bob's eigen gedeelde vensters. Als iets buiten beeld valt, meld dat
-  en vraag het aan Bob i.p.v. zelf te resizen.
-- Bob werkt vaak **gelijktijdig zelf** in dezelfde builder-sessie. Ga
-  er niet van uit dat elke wijziging die je in de widget tree/`git
-  diff` ziet van jezelf komt — check eerst of hij iets claimde
-  ("dat regel ik zelf") voordat je het overschrijft.
+  worden bij de volgende export overschreven — **niet duurzaam**.
+  Gebruik deze repo om te lezen/ontwerpen/verifiëren (`flutter
+  analyze`), maar voer het eindresultaat uit via de builder (zelf via
+  browser-automation, of als instructie aan Bob). Ga nooit uit van
+  behoud van een lokale bestandswijziging.
+- Werk je rechtstreeks in de builder (Claude in Chrome): commit na
+  elke **afgeronde taak** binnen FlutterFlow's eigen versiebeheer
+  ("main"/"Synced" bovenin), met duidelijke omschrijving. Geen lokale
+  `git commit`.
+- **Gebruik `mcp__claude-in-chrome__*`** (Bob's gedeelde Chrome), niet
+  de in-app Browser pane.
+- **Resize de browser niet zelf.** Bob's eigen gedeelde vensters —
+  meld en vraag i.p.v. zelf te resizen.
+- Bob werkt vaak **gelijktijdig zelf** in dezelfde builder-sessie —
+  check eerst of hij iets claimde ("dat regel ik zelf") voordat je
+  wijzigingen overschrijft.
 - Check bij een mislukte export/pull eerst het **Issues-paneel**
-  (badge-icoon rechtsboven, naast de sync-checkmarks) voordat je een
-  bug bij jezelf zoekt — een rode teller daar blokkeert *elke* export,
-  ook voor niet-gerelateerde correcte wijzigingen, en is vaak Bob's
-  eigen work-in-progress.
+  (badge rechtsboven) voordat je een bug bij jezelf zoekt — een rode
+  teller blokkeert *elke* export, ook niet-gerelateerde, en is vaak
+  Bob's eigen work-in-progress.
 
 ## Lokale git-repo + pull/push-workflow
 
-De projectdirectory zelf is een schone git-repo met `origin` op
+Projectdirectory = eigen schone git-repo, `origin`
 `ssh://gogs.digitalforce.tv:2222/Uitgaanskrant.com/flutterflow.git`,
-branch `master`. Dit is een eigen repo van de gebruiker, los van de
-grotere/rommelige repo die hoger in de mappenstructuur staat (die met
-AndroidStudioProjects, Flutter-SDK-installaties e.d.) — commits en
-pushes horen hier, in de projectdirectory zelf.
+branch `master`. Los van de grotere/rommelige repo hoger in de
+mappenstructuur (AndroidStudioProjects, Flutter-SDK e.d.) — commits en
+pushes horen hier.
 
 Vaste workflow na elke afgeronde taak (staand akkoord, geen aparte
-bevestiging per keer nodig): niet los `flutterflow export-code`
-draaien, maar het bestaande script gebruiken:
+bevestiging nodig): niet los `flutterflow export-code`, maar:
 
 ```
 export PATH="/home/bob/fvm/bin:$HOME/.pub-cache/bin:$PATH" && /home/bob/Projects/ff-run-fvm.sh emulator-5554 uitgaanskrant-1qhvtd -s
 ```
 
-- **De `export PATH=...` prefix is verplicht.** De Bash-tool draait
-  niet-interactief, dus `~/.bashrc` (waar `fvm`/`flutterflow` normaal
-  op PATH komen) wordt niet geladen. Zonder deze prefix faalt het
-  script stil met "fvm: command not found" / "Prerequisites not met,
-  skipping execution" — geen harde error, dus makkelijk te missen.
-- Dit script is interactief (device-run + hot-restart-loop) — moet via
-  Bash met `run_in_background: true`. Volg de output tot minimaal
-  "All done!" (export gelukt) én idealiter een succesvolle app-launch
-  op de emulator (`Launching lib/main.dart...`, geen nieuwe
-  `EXCEPTION CAUGHT BY RENDERING LIBRARY` t.o.v. bekende issues in
-  `TASKS.md`) voordat je verder gaat.
+- **De `export PATH=...` prefix is verplicht** — Bash draait
+  niet-interactief, `~/.bashrc` wordt niet geladen. Zonder prefix
+  faalt het script stil ("fvm: command not found" — geen harde error).
+- Interactief script (device-run + hot-restart-loop) → Bash met
+  `run_in_background: true`. Volg tot minimaal "All done!" én
+  idealiter een succesvolle app-launch (`Launching lib/main.dart...`,
+  geen nieuwe `EXCEPTION CAUGHT BY RENDERING LIBRARY`).
 
 Daarna automatisch:
-1. `git status --short` bekijken, dan `git add` — **niet blind `-A`**.
-   Voeg alleen daadwerkelijke FlutterFlow/app-wijzigingen toe (`lib/`,
-   `android/`, `ios/`, `pubspec*`, `.gitignore` e.d.). Sluit `.claude/`
-   uit (staat in .gitignore) — dat is sessiestate van Claude Code,
-   geen app-code. Wijzigingen die niet van jezelf zijn (Bob's eigen
-   concurrent werk) horen gewoon mee in dezelfde commit — dit is één
-   gedeeld project.
-2. `git commit` met een duidelijke boodschap.
-3. `git push` (of `git push -u origin master` als tracking nog niet
-   staat).
+1. `git status --short`, dan `git add` — **niet blind `-A`**. Alleen
+   echte FlutterFlow/app-wijzigingen (`lib/`, `android/`, `ios/`,
+   `pubspec*`, `.gitignore`). `.claude/` blijft uitgesloten
+   (sessiestate, geen app-code). Bob's eigen concurrente wijzigingen
+   horen gewoon mee in dezelfde commit.
+2. `git commit` met duidelijke boodschap.
+3. `git push` (`-u origin master` als tracking nog niet staat).
 
-**Valkuil: `flutterflow export-code` overschrijft `.gitignore` bij
-elke export terug naar FlutterFlow's eigen standaardversie.** Voeg dus
-na elke export, vóór je staged, deze regel weer toe aan `.gitignore`
-als hij ontbreekt:
+**Valkuil:** `flutterflow export-code` overschrijft `.gitignore` bij
+elke export terug naar FlutterFlow's standaardversie. Voeg na elke
+export, vóór staging, deze regel weer toe als hij ontbreekt:
 ```
 # Claude Code session state (not app code)
 .claude/
 ```
-(`CLAUDE.md` zelf overleeft een export altijd — alleen bij een volledig
-verwijderde en opnieuw gepulde projectmap zou het verdwijnen. Check
-voor de zekerheid toch even of het bestand er nog is.)
+(`CLAUDE.md` zelf overleeft een export altijd — check voor de
+zekerheid toch even.)
 
 ## Eerst research, dan bouwen
 
-Voordat je aan een niet-triviale taak begint (een bugfix, een nieuw
-patroon, een integratie): zoek eerst kort op internet naar bestaande
-oplossingen/patronen voordat je het zelf helemaal uitvindt via
-trial-and-error in de builder. Geldt niet voor triviale/mechanische
-herhaling van een patroon dat al bevestigd werkt (zie hieronder).
+Vóór een niet-triviale taak (bugfix, nieuw patroon, integratie): kort
+online zoeken naar bestaande oplossingen i.p.v. zelf trial-and-error
+in de builder. Geldt niet voor mechanische herhaling van een patroon
+dat al bevestigd werkt.
 
 ## FlutterFlow-builder: bekende problemen & patronen
 
-**Geneste "Set Variable"-dialoog kan lijken vast te zitten.** Bij het
-instellen van een conditie (`ConditionalBuilder`, Visibility →
-Conditional) op een niet-triviaal type (JSON Path, API-response-veld)
-opent een tweede dialoog bovenop de eerste. Confirm/Cancel op die
-binnenste dialoog reageren soms niet zichtbaar. Twee bekende oorzaken,
-in volgorde van proberen:
-1. **Viewport-clipping** — de knoppen renderen buiten het zichtbare
-   canvas, niet echt vast. Sleep de dialoog omhoog via het handvat
-   bovenin (kleine grijze balk) naar een hogere y-positie; de
-   Confirm/Cancel-knoppen worden dan zichtbaar en werken gewoon.
-2. **Echt bevroren pagina** (alle clicks, ook op onbetrokken plekken,
-   doen niets) — de widget-wrap zelf is al server-side opgeslagen,
-   maar de conditie-edit niet. Los op door de pagina te herladen
-   (`navigate` naar dezelfde URL); de wrap blijft staan, de
-   half-ingevulde conditie moet opnieuw.
-- **Kortere weg om deze dialoog te vermijden:** gebruik als operator
-  **"Is Set"** in plaats van "Not Equal To" + lege string — dan is er
-  geen Second Value nodig en dus geen tweede geneste dialoog.
-- Als dit na 1-2 pogingen (incl. de reload-poging) nog vastloopt: dit
-  kost dan meer tijd dan Bob het zelf kan doen — meld het concreet
-  (component, precieze stappen) en vraag het aan hem i.p.v. te blijven
-  proberen.
+**Geneste "Set Variable"-dialoog lijkt vast te zitten.** Bij een
+conditie (`ConditionalBuilder`, Visibility → Conditional) op een
+niet-triviaal type (JSON Path, API-response-veld, `List<DataType>`
+function-argument) opent een tweede dialoog bovenop de eerste;
+Confirm/Cancel reageren soms niet zichtbaar. Twee oorzaken, in
+volgorde van proberen:
+1. **Viewport-clipping** (meest voorkomend) — knoppen renderen buiten
+   het zichtbare canvas. Sleep de dialoog omhoog via het handvat
+   bovenin naar een hogere y-positie; de knoppen worden dan zichtbaar
+   en werken gewoon.
+2. **Echt bevroren pagina** (alle clicks doen niets) — de widget-wrap
+   staat al server-side, de conditie-edit niet. Herlaad de pagina
+   (`navigate` naar dezelfde URL); wrap blijft staan, conditie moet
+   opnieuw.
+- **Kortere weg om dit te vermijden:** operator **"Is Set"** i.p.v.
+  "Not Equal To" + lege string — geen Second Value nodig, dus geen
+  tweede dialoog.
+- Loopt dit na 1-2 pogingen (incl. reload) nog vast: kost dan meer
+  tijd dan Bob het zelf kan doen — meld concreet (component, exacte
+  stappen) en vraag het aan hem.
 
 **Component Name kan per ongeluk overschreven worden.** Vlak na
-paginanavigatie kan een klik bedoeld voor het "Search properties..."
-veld in plaats daarvan op het Component Name-veld landen (focus/
-z-order race condition), en typen hernoemt dan stilletjes het hele
-component. Mitigatie: na een click-before-type altijd eerst een
-screenshot om focus te bevestigen, zeker vlak na navigatie. Herstel:
-rechtsklik component in de zoekresultatenlijst → "Rename Component".
+paginanavigatie kan een klik bedoeld voor "Search properties..." op
+het Component Name-veld landen (focus/z-order race), en typen
+hernoemt dan stilletjes het component. Zelfde risico bij een
+widget-tree zoekactie die per ongeluk double-click-to-rename triggert
+i.p.v. navigeren — druk direct **Escape** om te herstellen. Mitigatie:
+na elke click-before-type eerst een screenshot om focus te bevestigen,
+zeker vlak na navigatie. Herstel: rechtsklik component in
+zoekresultaten → "Rename Component".
 
-**Rechterpaneel kan te breed zijn voor de viewport.** Sommige
-controls (Expansion segmented control, Visibility → Conditional
-expression builder) renderen soms deels buiten beeld — dit is geen
-`resize_window`-probleem (zie hierboven: niet zelf resizen). Na 1-2
+**Rechterpaneel kan te breed zijn voor de viewport.** Sommige controls
+(Expansion segmented control, Visibility → Conditional
+expression-builder) renderen soms deels buiten beeld — geen
+`resize_window`-probleem (niet zelf resizen, zie boven). Na 1-2
 bevestigde pogingen stoppen en aan Bob vragen.
 
-**Patroon: lege/ontbrekende afbeeldings-URL laten crashen.**
+**Patroon: lege/ontbrekende afbeeldings-URL laat de app crashen.**
 `CachedNetworkImage` gooit een **synchrone** `ArgumentError` bij het
 *bouwen* van de widget als `imageUrl` een lege string is — dit gebeurt
-vóórdat er ooit een netwerkverzoek wordt gedaan, dus `errorWidget`/
-"Show Error Image on Failure" vangt dit **niet** (dat vangt alleen
-échte laadfouten zoals 404's). Werkende fix, toegepast op 9 van de ~10
-bekende instanties (zie `TASKS.md`):
+vóórdat er ooit een netwerkverzoek is, dus `errorWidget`/"Show Error
+Image on Failure" vangt dit **niet** (dat vangt alleen échte
+laadfouten zoals 404's). Werkende fix:
 1. Rechtsklik het Image-widget → **Wrap Widget (Ctrl+B)** →
    **ConditionalBuilder**.
 2. IF-conditie: **Conditions → Single Condition** → First Value = de
    exacte expressie waar de Image's Path-property al aan gebonden was
-   (component-parameter, JSON Path, of custom-function-resultaat via
-   "Evenement Response" → API Response Options → JSON Body → JSON
-   Path, bv. `$[0].logo`) → operator **"Is Set"**.
+   → operator **"Is Set"**.
 3. THEN-tak: de bestaande Image (blijft staan na de wrap).
-4. ELSE-tak: rechtsklik → Insert Widget → Icon → zoek "image not
+4. ELSE-tak: rechtsklik → Insert Widget → Icon → "image not
    supported" → eerste Material-resultaat.
 - **Simpeler alternatief indien van toepassing:** de "Default Variable
-  Value"-toggle op een willekeurige "Set from Variable"-binding
-  substitueert al bij zowel `null` als lege string (bevestigd via
-  in-builder tooltip: "if the resulting value is null or empty") —
-  géén ConditionalBuilder nodig. Werkt hier alleen niet voor
-  Image-widgets met `Image Type: Network`, omdat er nog geen gehoste
-  fallback-afbeeldings-URL bestaat in dit project. Mocht die er ooit
-  komen (bv. een default-logo op de FlutterFlow-CDN of Drupal-server):
-  gebruik dan Default Variable Value + "Show Error Image on Failure"
-  i.p.v. ConditionalBuilder — sneller te bouwen.
+  Value"-toggle op een "Set from Variable"-binding substitueert al bij
+  zowel `null` als lege string (in-builder tooltip: "if the resulting
+  value is null or empty") — géén ConditionalBuilder nodig. Werkt hier
+  niet voor Image-widgets met `Image Type: Network` zolang er geen
+  gehoste fallback-afbeeldings-URL bestaat in dit project. Komt die er
+  ooit (bv. default-logo op FlutterFlow-CDN/Drupal-server): gebruik
+  dan Default Variable Value + "Show Error Image on Failure" — sneller
+  te bouwen dan ConditionalBuilder.
 
 **Tooltip toevoegen aan een icon-only widget:** rechtsklik → Wrap
 Widget (Ctrl+B) → 4e rij van de grid (kan geclipt lijken) → 1e icoon
-(spraakwolkje) = "Tooltip". Genereert een `AlignedTooltip` (zelfde
-stijl als de gedeelde header), geen losse styling nodig. Werkt niet op
-iconen die embedded zitten als `suffixIcon` van een `TextFormField`
-(bv. Login-pagina's wis-/toon-wachtwoord-iconen — geen losse
-wrapbare tree-node).
+(spraakwolkje) = "Tooltip". Genereert een `AlignedTooltip`, geen losse
+styling nodig. Werkt niet op iconen embedded als `suffixIcon` van een
+`TextFormField` (bv. Login-pagina wis-/toon-wachtwoord-iconen — geen
+losse wrapbare tree-node).
 
 **API-call headers: check op hardcoded literals i.p.v. `[varname]`
-templates.** Als een API-call via curl wél werkt maar vanuit de app/
-Response & Test-panel niet, controleer het Headers-tabblad van de
-call-configuratie — een handmatig ingeplakte testwaarde (bv. een
-Cookie-header) kan per ongeluk blijven staan i.p.v. de
-`[sessionname]=[sessionid]`-template. Check ook het per-variabele
+templates.** Werkt een call via curl wél maar vanuit de app/Response &
+Test-panel niet: check het Headers-tabblad — een handmatig ingeplakte
+testwaarde (bv. Cookie-header) kan per ongeluk blijven staan i.p.v.
+`[sessionname]=[sessionid]`. Check ook het per-variabele
 "Include"-vinkje in Response & Test — staat die uit, dan wordt de
 letterlijke `[varname]`-tekst meegestuurd i.p.v. de testwaarde.
 
@@ -232,33 +222,40 @@ letterlijke `[varname]`-tekst meegestuurd i.p.v. de testwaarde.
 - **Drupal page cache bootstrapt vóór de sessie** — een ooit anoniem
   gecachete response (bv. een 403) kan session-bootstrap, hooks én
   custom-module-logging volledig overslaan. Bij twijfel: Drupal-cache
-  legen en opnieuw testen vóór je verder debugt.
+  legen en opnieuw testen vóór verder debuggen.
 - **Views numeric filter**: `$view->filter['uid']->value` moet
   `array('value' => $uid)` zijn, niet `array($uid)` — de foute vorm
   faalt stil (geen filter toegepast) i.p.v. een error te geven.
-- Provincie/gemeente is en blijft het basismodel voor content-scoping
-  (bevestigd door Bob: mensen zoeken primair lokaal). Home is de
-  landelijke standaard-startpagina zónder verplichte gemeente-keuze
-  vooraf (task #31, afgerond) — dat vervangt niet het provincie/
-  gemeente-model, het is een aanvullende ingang.
+- Provincie/gemeente blijft het basismodel voor content-scoping
+  (bevestigd: mensen zoeken primair lokaal). Home is de landelijke
+  standaard-startpagina zónder verplichte gemeente-keuze vooraf — dat
+  vervangt het provincie/gemeente-model niet, het is een aanvullende
+  ingang. De `Home`-prefixed componenten (`HomeUitgaantabelKaartComponent`
+  e.d.) zijn een **bewuste kopie** van `PUitgaanSliderComponent`/
+  `UitgaantabelKaartComponent` + een eigen cityid-loze API-call — geen
+  dode code, niet meenemen in opschoonacties.
 - Favorieten/login zijn P0. Backend-endpoint bestaat al; Drupal 7
   views die de respons voeden hebben soms nog aanpassing nodig.
+- **Geen enkele "hasError"/netwerkfout-afhandeling bevestigd aanwezig**
+  in de app (gecheckt 2026-08-04, hele `lib/` doorzocht) — elke
+  FutureBuilder die alleen op `!snapshot.hasData` checkt, blijft bij
+  een mislukte call voor altijd op de laadspinner hangen. Ga er dus
+  niet van uit dat er ergens al een werkend voorbeeldpatroon staat om
+  te kopiëren — dit moet nog van de grond af ontworpen worden (zie
+  P0-taak in `TASKS.md`).
 
 ## Samenwerken met Bob
 
-- Bob is de enige developer/eigenaar en werkt vaak **zelf gelijktijdig**
-  in dezelfde FlutterFlow-builder-sessie. Neem niet aan dat elke
-  wijziging van jou komt.
+- Bob is de enige developer/eigenaar, werkt vaak **zelf gelijktijdig**
+  in dezelfde builder-sessie. Neem niet aan dat elke wijziging van jou
+  komt.
 - Prioriteit: "eerst een werkende app live, daarna features" — P0
-  (blokkeert livegang) weegt zwaar boven P1 (polish/performance) en P2
-  (nieuwe features). Bob herprioriteert soms fors zelf (bv. login+
-  favorieten van P2 naar P0) — volg dat exact.
-- Als Bob een taak terugclaimt ("dat regel ik zelf") — stop daar direct
+  weegt zwaar boven P1 en P2. Bob herprioriteert soms fors zelf (bv.
+  login+favorieten van P2 naar P0) — volg dat exact.
+- Claimt Bob een taak terug ("dat regel ik zelf") — stop daar direct
   mee en pak iets anders onafhankelijks op.
-- **Als iets veel tijd kost door handmatige builder-acties** (vastzittende
-  dialogen, geclipte controls e.d.): na 1-2 serieuze pogingen stoppen
-  en concreet aan Bob voorstellen dat hij het zelf doet (met exacte
-  stappen) i.p.v. door te blijven proberen.
-- Browser niet zelf resizen (zie boven).
+- Kost iets veel tijd door handmatige builder-acties (vastzittende
+  dialogen, geclipte controls): na 1-2 serieuze pogingen stoppen en
+  concreet aan Bob voorstellen dat hij het zelf doet (exacte stappen).
 - Rapporteer nieuw gevonden bugs (vooral op een pagina waar Bob net
   zelf op zit) direct en duidelijk, niet pas in een latere samenvatting.

+ 144 - 126
TASKS.md

@@ -1,14 +1,43 @@
 # Uitgaanskrant — takenlijst
 
 Bijgewerkt: 2026-08-04. Zie `CLAUDE.md` voor werkinstructies/conventies.
-Elke openstaande taak hieronder is bedoeld om zonder eerdere chatcontext
-opgepakt te kunnen worden — bestandspaden en concrete stappen staan
-erbij waar bekend.
+Elke openstaande taak hieronder is zelfstandig te begrijpen zonder de
+chat gelezen te hebben waarin hij ontstond. Volgorde binnen elke
+prioriteit = geschatte ernst/impact, hoogste eerst. Eigenaar-tag per
+taak: **[Claude]** (zelfstandig/via browser-automation te doen),
+**[Bob]** (sneller/simpeler voor hem zelf — meestal builder-UI met een
+bekend fragiele dialoog, zie `CLAUDE.md`), **[Bob — bezig]** (al
+geclaimd).
+
+**2026-08-04 documentatie-correctie:** 2 taken die hier als open
+stonden bleken al gefixt (git-bevestigd, commits van 2026-08-02) —
+verwijderd: "Hello Worlddd"-debugtekst en de Event→Horeca
+overflow-bug. Ook bleek er **nergens in de app een werkend
+`hasError`-patroon** te bestaan om te kopiëren (zie `CLAUDE.md`,
+Domein/architectuurcontext) — de foutafhandelings-taken hieronder gaan
+dus uit van een nieuw te ontwerpen patroon, niet een bestaand te
+repliceren patroon.
+
+## Sessie-indeling (suggestie voor tokenefficiëntie)
+
+Groepeer bij het oppakken bij voorkeur per FlutterFlow-paginagebied:
+- **Nu opgepakt:** Home-slider empty-state + Foutafhandeling
+  Horeca-overzicht (zie onder) — 2 losse paginagebieden, maar beide
+  hoogste-ernst P0.
+- **Volgende sessie, Login/favorieten-afronding:** lege-lijst
+  empty-state favorietenpagina + hartje-op-gemeente (ná designantwoord)
+  + favorieten-sync-verificatie.
+- **Volgende sessie, laatste image-crash + Flexible-wrap:**
+  EvenementHorecagelegenheid-carousel [Bob] + sliderkaartje-datumregel
+  [Claude] — klein, kan samen met opruimwerk in dezelfde pagina's.
+- **Volgende sessie, toegankelijkheid:** alle 5 punten onder
+  "Toegankelijkheid & navigatie" samen — klein en gelijksoortig.
+- **Volgende sessie, opschonen:** lib/kanweg + dubbel menu + EventWidget-route.
 
 ## Status: actief bij Bob (geen Claude-actie nodig, ter info)
 
-- **FavorietenAgenda 403-fout**: Bob is dit zelf aan het troubleshooten.
-  FlutterFlow-requests komen bij nginx binnen met een lege
+- **FavorietenAgenda 403-fout** [Bob — bezig]: Bob troubleshoot dit
+  zelf. FlutterFlow-requests komen bij nginx binnen met een lege
   Cookie-header; zijn eigen browser/curl (via dezelfde Cloudflare-edge)
   sturen de sessie-cookie wél mee. Cloudflare Cache Rule voor `SSESS*`
   staat al goed (bypass, eerste regel). Werkhypothese: Cloudflare Bot
@@ -18,151 +47,140 @@ erbij waar bekend.
 
 ## P0 — blokkeert livegang
 
-- [ ] **Home-slider crasht (RangeError) bij 0 API-resultaten.**
-  `CarouselSlider.builder` met `itemCount: 0` crasht. De originele
-  `PUitgaanSliderComponent` had deze bug (al gefixt daar, zie
-  "afgerond" hieronder). `HomeUitgaantabelKaartComponent`/de
-  Home-slider is een kopie van diezelfde code voor de landelijke
-  (cityid-loze) query — waarschijnlijk dezelfde bug geërfd. Check en
-  fix met hetzelfde patroon (empty-state check vóór de builder).
-
-- [ ] **Werkende login + favorieten — resterende deeltjes.** Grote
-  basis is af (zie "afgerond"): login echt gekoppeld, wachtwoord-
-  vergeten-flow, favorieten drawer-link + 3-tabblad-pagina, hartje op
-  horeca-kaart + horeca-detailpagina. Nog open:
-  - Lege-lijst empty-state op de favorietenpagina (nu kale/lege
-    Container als er nog geen favorieten zijn).
-  - Bevestigen dat favorieten écht syncen via Drupal bij inloggen
-    (i.p.v. alleen lokaal opgeslagen) — hangt af van het
-    FavorietenAgenda-403-issue hierboven.
-  - Hartje op **gemeente** (zie apart item hieronder — geblokkeerd op
-    een designvraag).
-
-- [ ] **Hartje-icoon op gemeente — geblokkeerd op designvraag.** Bob
-  koos: heart ergens anders dan de gemeente-dropdown zelf (dropdown
-  blijft ongewijzigd). Blocker: **geen enkele pagina toont de
-  geselecteerde gemeente-náám als tekst** — alleen het numerieke ID
-  (`FFAppState().gemeenteSelectId`) wordt doorgegeven als filter (bv.
-  `plaats`/`townid` param op `PUitgaanPageWidget`). `GemeentenCall.
-  gemeenteName()` in `lib/backend/api_requests/api_calls.dart` bestaat
-  al maar is ongebruikt. **Voordat je bouwt: vraag Bob expliciet waar
-  de gemeente-naam + hartje moeten komen** (meest voor de hand
-  liggende kandidaat: AppBar van `PUitgaanPageWidget`, de pagina die je
-  bereikt na het kiezen van een gemeente in de drawer) — niet zelf
-  raden aan de layout.
-  - Gerelateerd: een custom function `provincieNaamById`/
-    `gemeenteNaamById` (in `lib/flutter_flow/custom_functions.dart`,
-    committed, compileert) is al gebouwd maar nog **niet gekoppeld**
-    aan een widget — de binding-poging liep vast op een FlutterFlow-
-    builderbug met `List<CustomDataType>`-argumenten (zie CLAUDE.md,
-    "geneste Set Variable-dialoog"). Simpeler alternatief dat die bug
-    vermijdt: naam vastleggen in een plain String App State-variabele
-    op het moment van selectie, i.p.v. 'm live op te zoeken via een
-    List-typed lookup function.
-
-- [ ] **"Hello Worlddd" — letterlijke debugtekst op de live
-  Event-pagina.** Geen veldnaam-fallback, een vergeten testregel.
-  `lib/evenement/evenement_info/evenement_info_widget.dart:185-188`
-  (translation key `kslnk9ez`).
-
-- [ ] **Overflow-bug in Event→Horeca-kaartje.** Zelfde
-  Row+Icon+Text-zonder-Flexible-patroon dat al 2x eerder gefixt is
-  (slider + tabelkaart, zie "afgerond") — nu op de adres/plaats- én
-  telefoonregel.
-  `lib/evenement/evenement_horecagelegenheid/evenement_horecagelegenheid_widget.dart:471-599`.
-
-- [ ] **Foutafhandeling ontbreekt op HorecagelegenhedenOverzicht.** 6
-  FutureBuilders checken alleen "geen data nog", geen enkele checkt op
-  een mislukte call — bij een netwerkfout blijft het laadwieltje
-  voor altijd draaien.
-  `lib/horecagelegenhedenoverzicht/horecagelegenheden_overzicht/horecagelegenheden_overzicht_widget.dart`
-  (regels 276, 460, 644, 828, 1012, 1196).
-
-- [ ] **Drupal: anonieme leestoegang onderzoeken voor browse-
-  endpoints.** Bob's eigen actie op Drupal-niveau, geen Claude-taak.
+1. [ ] **Home-slider crasht (RangeError) bij 0 API-resultaten — interim
+   fix staat, proper fix nog niet.** [Claude, met fallback naar Bob]
+   `CarouselSlider.builder` met `itemCount: 0` crasht. Commit `1a22bbf`
+   (2026-08-03, Bob) wrapte de Home-slider al in een ConditionalBuilder
+   met een **altijd-waar** conditie + placeholder-else, als tijdelijke
+   patch — expliciet bedoeld als interim, "proper native empty-state
+   binding" staat nog open. `home_uitgaan_slider_component_widget.dart`.
+   **Vraag aan Bob vóór starten:** wat moet de eindtoestand tonen bij 0
+   resultaten — niets (component skip) of een "geen evenementen"-melding
+   op Home? En: ben je zelf al met de proper-fix bezig?
+
+2. [ ] **Foutafhandeling ontbreekt op HorecagelegenhedenOverzicht.**
+   [Claude] 6 FutureBuilders checken alleen `!snapshot.hasData` — bij
+   een mislukte call (niet alleen "nog geen data") blijft het
+   laadwieltje voor altijd draaien, want er is geen `hasError`-tak.
+   Bevestigd: dit patroon bestaat nergens elders in de app om te
+   kopiëren, dus zelf een compacte foutmelding + retry ontwerpen.
+   `lib/horecagelegenhedenoverzicht/horecagelegenheden_overzicht/horecagelegenheden_overzicht_widget.dart`
+   (regels 283, 467, 651, 835, 1019, 1203).
+   **Vraag aan Bob vóór starten:** akkoord met "compacte melding +
+   Opnieuw proberen-knop" als aanpak, of andere voorkeur voor
+   tekst/vormgeving?
+
+3. [ ] **Hartje-icoon op gemeente — geblokkeerd op designvraag.** [Bob]
+   Bob koos: heart ergens anders dan de gemeente-dropdown zelf (die
+   blijft ongewijzigd). Blocker: **geen enkele pagina toont de
+   geselecteerde gemeente-náám als tekst** — alleen het numerieke ID
+   (`FFAppState().gemeenteSelectId`) wordt doorgegeven als filter (bv.
+   `plaats`/`townid` param op `PUitgaanPageWidget`). `GemeentenCall.
+   gemeenteName()` in `lib/backend/api_requests/api_calls.dart` bestaat
+   al maar is ongebruikt. **Vraag aan Bob:** waar moeten gemeente-naam +
+   hartje komen (kandidaat: AppBar van `PUitgaanPageWidget`)? Niet zelf
+   raden aan de layout.
+   - Bekende valkuil als dit gebouwd wordt: bind de naam niet live via
+     een `List<CustomDataType>`-typed lookup function-argument (bv.
+     `provincieNaamById`/`gemeenteNaamById` in
+     `lib/flutter_flow/custom_functions.dart`, al gebouwd, compileert,
+     nog niet gekoppeld) — dat argument-bindingsdialoog loopt vast op
+     de geneste Set Variable-bug (zie `CLAUDE.md`). Simpeler: naam
+     vastleggen in een plain String App State-variabele op moment van
+     selectie i.p.v. 'm live op te zoeken.
+
+4. [ ] **Werkende login + favorieten — resterende deeltjes.** [Bob]
+   Basis is af: login gekoppeld, wachtwoord-vergeten-flow, favorieten
+   drawer-link + 3-tabblad-pagina, hartje op horeca-kaart +
+   -detailpagina. Nog open:
+   - Lege-lijst empty-state op de favorietenpagina (nu kale/lege
+     Container als er nog geen favorieten zijn). `lib/favorieten/favorieten_widget.dart`.
+   - Bevestigen dat favorieten écht syncen via Drupal bij inloggen —
+     hangt af van het FavorietenAgenda-403-issue hierboven.
+
+5. [ ] **Drupal: anonieme leestoegang onderzoeken voor browse-
+   endpoints.** [Bob] Drupal-niveau, geen Claude-taak.
 
 ## P1 — snel na livegang
 
 - [ ] **Lege image-URL crash (CachedNetworkImage) — 1 van 10
-  resterend.** Patroon en volledige uitleg staan in `CLAUDE.md`
-  ("Patroon: lege/ontbrekende afbeeldings-URL laten crashen"). 9 van
-  de 10 bekende instanties zijn al gefixt en gepusht. **Laatste
-  resterende:** component `EvenementHorecagelegenheid`, widget
-  `Column > Carousel > Carousel Page > Image` (Path gebonden aan
-  `fotoosItem`, een lijst-item-string). De `ConditionalBuilder`-wrap
-  staat al (server-side opgeslagen), maar de IF-conditie is nog
-  `Unset` — het instellen ervan liep herhaaldelijk vast op de geneste
-  Set Variable-dialoogbug (zie CLAUDE.md). Volgende poging: gewoon
-  opnieuw proberen met de "Is Set"-operator (korte weg, geen Second
-  Value nodig); lukt dat niet binnen 1-2 pogingen, vraag het aan Bob
-  (exacte stappen staan in CLAUDE.md).
-  - Nog niet gecontroleerd of er ook op andere, nog niet doorzochte
-    pagina's instanties van dit patroon voorkomen — de 10 bekende
-    kwamen uit een gerichte `grep -rl "CachedNetworkImage"` over
-    `lib/**/*_widget.dart`; die grep zelf is waarschijnlijk nog
-    compleet, maar een her-check na toekomstige nieuwe pagina's is
-    verstandig.
-
-- [ ] **Loading/foutafhandeling-patroon repliceren naar andere
-  lijstpagina's.** Het patroon dat al werkt op de Uitgaan-pagina
-  (eventenlijst) toepassen op overige lijst-/detailpagina's (Event,
-  HorecagelegenheidCurrent, sliders) — nu geen enkele foutstatus
-  daar, alleen "geen data nog".
-
-- [ ] **"Thuis bezorgen" koppelen aan een echt leverbaar-veld per
-  horecagelegenheid.** Wacht op Bob: hij moet eerst het
-  API-endpoint aan Drupal-kant configureren. Daarna: tonen/verbergen
-  op basis van het echte veld i.p.v. de huidige dode tap.
-
-- [ ] **Overflow op Home-pagina.** Live gereproduceerd tijdens het
+  resterend.** [Bob] Patroon in `CLAUDE.md` ("Patroon: lege/ontbrekende
+  afbeeldings-URL"). 9 van de 10 bekende instanties zijn al gefixt en
+  gepusht. **Laatste resterende, status gecorrigeerd 2026-08-04:**
+  component `EvenementHorecagelegenheid`, Carousel-Image
+  (`imageUrl: fotoosItem`, regel ~299) — er staat **nog geen**
+  ConditionalBuilder-wrap (eerdere aanname dat de wrap al stond en
+  alleen de conditie `Unset` was, klopt niet met de huidige export).
+  Moet van scratch: wrap + conditie ("Is Set") + else-icon, zoals
+  omschreven in `CLAUDE.md`. Dit is exact het patroon dat eerder al
+  meerdere keren vastliep op de geneste Set Variable-dialoog — vandaar
+  Bob i.p.v. Claude.
+  - Nog niet herchecked op nieuwe pagina's sinds de laatste gerichte
+    `grep -rl "CachedNetworkImage"` over `lib/**/*_widget.dart`.
+
+- [ ] **Loading/foutafhandeling-patroon uitrollen naar overige
+  lijst-/detailpagina's.** [Claude, ná P0 #2] Zodra het patroon uit P0
+  #2 (Horeca-overzicht) staat, hetzelfde toepassen op Event,
+  HorecagelegenheidCurrent, sliders — nu nergens een echte
+  foutstatus, alleen "geen data nog".
+
+- [ ] **Overflow op Home-pagina.** [Claude] Live gereproduceerd tijdens
   testen (2026-08-03): `RenderFlex overflowed by 7338 pixels` in een
   `Column` zonder `Expanded`/scrollcontainer.
   `lib/uitgaanspaginas/home/home_widget.dart:316`.
 
-- [ ] **~25+ plekken tonen letterlijke veldnaam i.p.v. nette
-  placeholder** (bv. "titel", "adres", "def") bij ontbrekende data.
-  Nog niet geïnventariseerd welke exact — audit-agent-bevinding,
-  concrete lijst nog te maken.
+- [ ] **Sliderkaartje: datumregel mist de Flexible-wrap.** [Claude]
+  Zelfde mechanische patroon als de twee regels eronder die al gefixt
+  zijn (consistentie) — bevestigd nog open.
+  `p_uitgaan_slider_kaart_component_widget.dart` (Row met
+  `Icons.calendar_month` + Text zonder Flexible).
 
-- [ ] **EstablishmentsCall crasht zonder categoriefilter.**
-  `horcat ??= null!;` — nu geen probleem omdat elke aanroep toevallig
-  altijd een filter meegeeft, wel een landmijn voor de toekomst.
-  `lib/backend/api_requests/api_calls.dart:1151`.
+- [ ] **EstablishmentsCall crasht zonder categoriefilter.** [Bob]
+  `horcat ??= null!;` — bevestigd nog aanwezig, regel 1443. Nu geen
+  probleem omdat elke aanroep toevallig altijd een filter meegeeft,
+  wel een landmijn voor de toekomst. `lib/backend/api_requests/api_calls.dart`.
+  Fix zit vermoedelijk in de FlutterFlow API-call-configuratie (default
+  parameterwaarde), niet in lokale code.
 
-- [ ] **Sliderkaartje: datumregel mist de Flexible-wrap.** Zelfde
-  patroon als de twee regels eronder die al gefixt zijn (consistentie).
-  `p_uitgaan_slider_kaart_component_widget.dart:273-306`.
+- [ ] **"Thuis bezorgen" koppelen aan een echt leverbaar-veld per
+  horecagelegenheid.** [Bob] Wacht op Bob: eerst het API-endpoint aan
+  Drupal-kant configureren. Daarna tonen/verbergen op basis van het
+  echte veld i.p.v. de huidige dode tap.
+
+- [ ] **~25+ plekken tonen letterlijke veldnaam i.p.v. nette
+  placeholder** (bv. "titel", "adres", "def") bij ontbrekende data.
+  [Claude] Nog niet geïnventariseerd welke exact — audit nog te doen.
 
 - [ ] **Account/profielscherm** (wachtwoord wijzigen, uitloggen,
-  account verwijderen) — bovenop de login/favorieten-P0-basis. Account
-  verwijderen heeft mogelijk AVG-implicaties aan Drupal-kant.
+  account verwijderen). [Bob] Bovenop de login/favorieten-P0-basis.
+  Account verwijderen heeft mogelijk AVG-implicaties aan Drupal-kant.
 
-- [ ] **Toegankelijkheid & navigatie, restpunten:**
+- [ ] **Toegankelijkheid & navigatie, restpunten:** [Claude, klein
+  batchbaar in 1 sessie]
   - Login-pagina: 2 icon-only knoppen zonder tooltip (veld wissen +
-    wachtwoord tonen/verbergen) — `login_widget.dart:270-280,
-    392-401`. Let op: dit zijn `suffixIcon`s van een `TextFormField`,
-    de standaard Tooltip-wrap werkt daar niet op (zie CLAUDE.md).
+    wachtwoord tonen/verbergen) — `login_widget.dart` (suffixIcon
+    van een `TextFormField` — standaard Tooltip-wrap werkt daar niet
+    op, zie `CLAUDE.md`; bevestigd nog open).
   - Overige icon-only knoppen buiten de header van tooltip voorzien.
   - Bevestig-stap toevoegen aan de provincie/gemeente-kiezer (nu geen
     "Toepassen"-knop of bevestiging).
-  - Vaste "terug naar hoofdlijst"-snelkoppeling op detailpagina's
-    (nu alleen letterlijk terug/`context.pop`).
+  - Vaste "terug naar hoofdlijst"-snelkoppeling op detailpagina's.
   - Deep-link/query-param robuustheid checken (ongeldig/verlopen
-    `nid`, bv. gedeelde link naar verwijderd event).
+    `nid`).
 
-- [ ] **Visuele polish** (los, per pagina): Uitgaan-pagina
-  (typografie/contrast/spacing), Event-pagina, HorecagelegenhedenOverzicht,
-  tabel-kaartje-afstemming met slider-kaartje, categorie-tag mag
-  titel/datum niet overstemmen in dichte lijstweergaves.
+- [ ] **Visuele polish** (los, per pagina): [Bob/Claude, geen
+  builder-risico's bekend] Uitgaan-pagina (typografie/contrast/spacing),
+  Event-pagina, HorecagelegenhedenOverzicht, tabel-kaartje-afstemming
+  met slider-kaartje, categorie-tag mag titel/datum niet overstemmen.
 
-- [ ] **Performance:**
+- [ ] **Performance:** [onderzoek nodig, geen owner bepaald]
   - Dubbele/onnodige netwerkverzoeken checken (audit, nog te doen).
   - 6-7 tabbladen laden allemaal meteen hun eigen data bij elke
     tabwissel/herbouw (TabBarView bouwt alle tabs eager) —
     `horecagelegenheden_overzicht(_sort_page/_page_data_type)_widget.dart`.
 
-- [ ] **Responsive/screensize-audit** — o.a. het vaste 200×200px-
-  tegelformaat in het venue-event-grid dat botst met de
+- [ ] **Responsive/screensize-audit** [onderzoek nodig] — o.a. het
+  vaste 200×200px-tegelformaat in het venue-event-grid dat botst met de
   grid-berekening.
 
 ## P2 — features & concept, na livegang
@@ -184,7 +202,7 @@ erbij waar bekend.
 - [ ] Tekstzoeken op titel op de horeca-overzichtspagina (los van de
   Datatype/Sort-experimenten die Bob daar zelf op test — die zijn
   actief werk-in-uitvoering, geen dode code).
-- [ ] **Opschonen:**
+- [ ] **Opschonen:** [Bob]
   - Merge `kaartTabelUitgaanComp` + `kaartTabelUitgaanSComp` — Bob
     doet dit zelf ("ik kijk er zelf naar").
   - `lib/kanweg` opnieuw leegmaken indien teruggekomen na een latere