---
phase: 20-tablo-detail-kanban-restyle
plan: "03"
subsystem: go-backend/ui
tags: [css, tablo-detail, kanban, task-card, etapes, files-table]
dependency_graph:
  requires:
    - 20-01 (TabloDetailViewModel, handler, route)
    - 20-02 (TabloDetailPage templ components — CSS class consumers)
  provides:
    - All tablo detail + kanban restyle CSS rules in app.css
    - .tablo-detail-header, .tablo-detail-title, .tablo-metadata-row
    - .tablo-progress-bar (brand-primary fill, not project-color)
    - .tablo-kanban-board, .tablo-kanban-column, column sub-rules
    - .task-card (column-flex, hover shadow, opacity transitions)
    - .task-drag-handle / .task-card-delete (opacity 0 at rest, 1 on hover)
    - .tablo-etapes-section, .tablo-etape-row
    - .tablo-files-table-wrapper with border-radius 12px
    - .task-list updated with gap 8px + padding 8px
  affects:
    - go-backend/internal/web/ui/app.css
tech_stack:
  added: []
  patterns:
    - CSS custom properties from base.css token system
    - Opacity-based visibility transitions (0.12s ease) for drag handle and delete icon
    - Scoped overrides (.tablo-tab-bar .tab-nav-item) to avoid global style pollution
key_files:
  created: []
  modified:
    - go-backend/internal/web/ui/app.css
decisions:
  - .tablo-progress-bar uses var(--color-brand-primary) not var(--project-color); separate class from .project-progress-bar to avoid breaking tablo card list page
  - .task-card is a new selector; .task-row unchanged — no CSS cascade collision between tablo detail and global tasks page
  - .tasks-section border-radius kept at 1rem; only .tablo-kanban-column gets 0.75rem per UI-SPEC
  - .task-list gap/padding change is intentional for both global tasks and tablo detail (gap between cards desired everywhere)
metrics:
  duration: "~2min"
  completed_date: "2026-05-18"
  tasks_completed: 2
  files_created: 0
  files_modified: 1
---

# Phase 20 Plan 03: Tablo Detail + Kanban CSS Restyle Summary

All tablo detail page CSS rules applied to app.css: header layout, metadata row, progress bar with brand-primary fill, kanban board columns (18rem, 0.75rem radius), column-flex task cards with opacity-based drag handle and delete visibility, etapes section, files table wrapper, and task-list gap update.

## What Was Built

**go-backend/internal/web/ui/app.css** — new section "/* === Tablo Detail Page === */" appended at end of file.

**Task 1 — Tablo detail header and metadata CSS (lines appended ~1950+):**
- `.tablo-detail-page` — outer page container, `padding: 24px 32px`
- `.tablo-detail-header` — flex column with `border-bottom: 1px solid var(--color-border-muted)`
- `.tablo-detail-title-row` — flex row for avatar + h1, `gap: 16px`, `padding-bottom: 16px`
- `.tablo-detail-avatar` — 48×48 colored circle, `border-radius: 12px`, white bold initial
- `.tablo-detail-title` — h1 at `1.75rem / 600`, `color: var(--color-text-primary)`
- `.tablo-metadata-row` — horizontal flex, `gap: 24px`, `padding-block: 16px`, border-bottom
- `.tablo-meta-segment` — each metadata segment at 0.875rem with `gap: 8px`
- `.tablo-meta-progress` — progress segment override
- `.tablo-progress-bar` — **`background: var(--color-brand-primary)`**, `height: 5px`, `border-radius: 9999px`
- `.tablo-tab-bar` — tab nav container, `border-bottom`, `gap: 24px`, `padding-top: 8px`
- `.tablo-tab-bar .tab-nav-item` — scoped override at `0.875rem`, `padding-bottom: 12px`

**Task 2 — Kanban, task card, etapes, files, task-list update:**
- `.tablo-kanban-board` — flex container, `gap: 16px`, `overflow-x: auto`, `padding-top: 24px`
- `.tablo-kanban-column` — `width: 18rem`, `border-radius: 0.75rem`, `border: 1px solid var(--color-border-default)`
- `.tablo-kanban-column-header` — `background: var(--color-surface-muted)`, `padding: 12px 16px`
- `.tablo-kanban-column-title` — 0.875rem weight 600
- `.tablo-kanban-task-count` — pill with `border-radius: 9999px`, 0.75rem
- `.tablo-kanban-add-link` — `color: var(--color-text-brand)`, 0.875rem weight 400
- `.tablo-kanban-empty` — centered "Aucune tâche" state, `padding: 24px 16px`
- `.task-card` — new column-flex card, `border-radius: 8px`, hover shadow `0 8px 24px rgba(15,23,42,.08)`
- `.task-card:hover` — `border-color: var(--color-border-strong)`, box-shadow reveal
- `.task-card-top-row` — `align-items: flex-start`, `gap: 6px`
- `.task-drag-handle` — `opacity: 0; transition: opacity 0.12s ease` at rest
- `.task-card:hover .task-drag-handle` — `opacity: 1`
- `.task-card-title` — 0.875rem weight 400, single-line ellipsis
- `.task-card-delete` — `opacity: 0; transition: opacity 0.12s ease` at rest
- `.task-card:hover .task-card-delete` — `opacity: 1`
- `.task-list` — **updated** to add `gap: 8px; padding: 8px` (was flex-column only)
- `.tablo-etapes-section` — `border-top`, `margin-top: 24px`, `padding-top: 24px`
- `.tablo-etapes-section h2/h3` — 1rem weight 600
- `.tablo-etapes-section ul` — list reset with `gap: 8px`
- `.tablo-etape-row` — flex row, `border-radius: 8px`, `padding: 10px 16px`
- `.tablo-etape-name` — 0.875rem weight 500
- `.tablo-etape-count` — 0.75rem secondary color
- `.tablo-files-table-wrapper` — `border-radius: 12px`, `overflow: hidden`
- `.tablo-files-table-wrapper thead tr/th` — muted background, uppercase caption style
- `.tablo-files-table-wrapper tbody tr` — border-bottom separator
- `.tablo-files-table-wrapper tbody tr:hover` — `background: var(--color-surface-subtle)`

## Security (Threat Model)

| Threat | Mitigation | Status |
|--------|------------|--------|
| T-20-06: .task-card vs .task-row CSS cascade collision | .task-card is new selector; .task-row unchanged — no overlap | Mitigated |

## Verification

All must-haves confirmed:

- `.tablo-detail-header` — PRESENT with flex-direction, border-bottom
- `.tablo-detail-title` — PRESENT with font-size 1.75rem, font-weight 600
- `.tablo-metadata-row` — PRESENT with display flex, gap 24px
- `.tablo-kanban-board` — PRESENT with display flex, gap 16px, overflow-x auto
- `.tablo-kanban-column` — PRESENT with width 18rem, border-radius 0.75rem, border
- `.task-card` — PRESENT with flex-direction column, border-radius 8px, gap 8px
- `.task-drag-handle` — PRESENT with opacity 0; `.task-card:hover .task-drag-handle` — opacity 1
- `.task-card-delete` — PRESENT with opacity 0; `.task-card:hover .task-card-delete` — opacity 1
- `.tablo-progress-bar` — PRESENT with `background: var(--color-brand-primary)` (NOT project-color)
- `.tablo-files-table-wrapper` — PRESENT with border-radius 12px
- `.task-list` — UPDATED with gap 8px and padding 8px
- `.tablo-etapes-section` and `.tablo-etape-row` — PRESENT
- `.task-row` — UNCHANGED (no regression on global tasks page)
- `.tasks-section` border-radius — UNCHANGED at 1rem
- `go build ./...` — PASSES

## Commits

| Hash | Type | Description |
|------|------|-------------|
| 58710d6 | feat | tablo detail header, metadata row, and tab bar CSS |
| 910c3b6 | feat | kanban board, task card, etapes section, files table CSS + task-list gap |

## Deviations from Plan

None — plan executed exactly as written.

## Known Stubs

None. All CSS rules are complete per UI-SPEC.

## Threat Flags

None. CSS file edit only — no new network endpoints, auth paths, or schema changes introduced.

## Self-Check

Files modified:
- go-backend/internal/web/ui/app.css — FOUND

Commits:
- 58710d6 — FOUND
- 910c3b6 — FOUND

go build ./... — PASSES

## Self-Check: PASSED
