+
+
+From backend/templates/app_layout.templ (Plan 02 output):
+```go
+templ AppLayout(title string, user *auth.User, csrfToken string, activePath string, tablos []sqlc.Tablo)
+```
+
+From backend/internal/db/sqlc/tablos.sql.go:
+```go
+// Already exists — confirmed in RESEARCH.md:
+func (q *Queries) ListTablosByUser(ctx context.Context, userID uuid.UUID) ([]Tablo, error)
+```
+
+From backend/templates/tablos.templ (current signatures to replace):
+```go
+// CURRENT — replace these:
+templ TablosDashboard(user *auth.User, csrfToken string, tablos []TabloCardView)
+templ TabloDetailPage(user *auth.User, csrfToken string, tablo sqlc.Tablo, tasks []sqlc.Task, etapes []sqlc.Etape, counts EtapeTaskCounts, filter EtapeFilter, files []sqlc.TabloFile, events EventsCalendar, discussion DiscussionTabData, activeTab string)
+templ TabloNotFoundPage(user *auth.User, csrfToken string)
+
+// AFTER:
+templ TablosDashboard(user *auth.User, csrfToken string, activePath string, tablos []sqlc.Tablo, cards []TabloCardView)
+templ TabloDetailPage(user *auth.User, csrfToken string, activePath string, sidebarTablos []sqlc.Tablo, tablo sqlc.Tablo, tasks []sqlc.Task, etapes []sqlc.Etape, counts EtapeTaskCounts, filter EtapeFilter, files []sqlc.TabloFile, events EventsCalendar, discussion DiscussionTabData, activeTab string)
+templ TabloNotFoundPage(user *auth.User, csrfToken string, activePath string, sidebarTablos []sqlc.Tablo)
+```
+
+From backend/internal/web/ui/empty_state.templ:
+```go
+type EmptyStateProps struct {
+ Title string
+ Description string
+ Icon string // optional
+ Action templ.Component // optional button
+}
+templ EmptyState(props EmptyStateProps)
+// CSS class on root element: "ui-empty-state"
+```
+
+From backend/internal/web/ui/icon_button.templ:
+```go
+type IconButtonProps struct {
+ Label string
+ Icon string // "pencil" or "trash" for card actions
+ Variant IconButtonVariant
+ Tone IconButtonTone
+ Type string
+ Attrs templ.Attributes
+}
+templ IconButton(props IconButtonProps)
+// IconButtonVariantNeutral, IconButtonVariantDanger
+// IconButtonToneGhost
+```
+
+From backend/templates/tablos.templ (current HTMX delete attrs to preserve):
+```go
+// Delete button HTMX attrs (preserve exactly per D-C04 + Pitfall 3):
+"hx-get": "/tablos/" + tablo.ID.String() + "/delete-confirm"
+"hx-target": "closest .tablo-delete-zone"
+"hx-swap": "outerHTML"
+
+// The .tablo-delete-zone wrapper must wrap the delete icon button:
+
+ @ui.IconButton(ui.IconButtonProps{...delete attrs...})
+
+```
+
+Current title edit HTMX attrs (for card edit button per D-C02):
+```go
+// From tablos.templ TabloTitleDisplay zone (lines 305-315):
+"hx-get": "/tablos/" + tablo.ID.String() + "/edit-title"
+"hx-target": ".tablo-title-zone" // or "closest .tablo-title-zone"
+"hx-swap": "outerHTML"
+```
+
+From backend/templates/planning.templ (current signature):
+```go
+templ PlanningPage(user *auth.User, csrfToken string, agenda PlanningAgenda)
+// AFTER:
+templ PlanningPage(user *auth.User, csrfToken string, activePath string, tablos []sqlc.Tablo, agenda PlanningAgenda)
+```
+
+From backend/templates/account_providers.templ:
+```go
+// BEFORE:
+@Layout("Linked providers", user, csrfToken)
+// AFTER: uses AppLayout with activePath="/" (settings don't exist yet, closest is /)
+```
+
+