--- phase: 20-tablo-detail-kanban-restyle plan: 03 type: execute wave: 2 depends_on: - 20-01 files_modified: - go-backend/internal/web/ui/app.css autonomous: true requirements: - DETAIL-01 - TASK-01 must_haves: truths: - "app.css contains a .tablo-detail-header rule with flex-direction, padding, and border-bottom" - "app.css contains a .tablo-detail-title rule with font-size 1.75rem and font-weight 600" - "app.css contains a .tablo-metadata-row rule with display flex and gap 24px" - "app.css contains a .tablo-kanban-board rule with display flex, gap 16px, and overflow-x auto" - "app.css contains a .tablo-kanban-column rule with width 18rem, border-radius 0.75rem, and border" - "app.css contains a .task-card rule with flex-direction column, border-radius 8px, and gap 8px" - "app.css contains a .task-drag-handle rule with opacity 0 and a .task-card:hover .task-drag-handle rule with opacity 1" - "app.css contains a .task-card-delete rule with opacity 0 at rest and visible on .task-card:hover" - "app.css contains a .tablo-progress-bar rule with background var(--color-brand-primary) — NOT var(--project-color)" - "app.css contains a .tablo-files-table-wrapper rule with border-radius 12px" - "app.css .task-list rule is updated to include gap 8px and padding 8px" - "app.css contains a .tablo-etapes-section rule and a .tablo-etape-row rule" artifacts: - path: "go-backend/internal/web/ui/app.css" provides: "All tablo detail + kanban restyle + etapes section CSS rules" contains: ".tablo-detail-header" key_links: - from: "go-backend/internal/web/views/tablo_detail.templ" to: "go-backend/internal/web/ui/app.css" via: "CSS class names applied to HTML elements" pattern: ".tablo-kanban-board" --- Apply all CSS changes from the UI-SPEC to app.css: new tablo detail header styles, kanban board layout, task card restyle (column-flex, hover shadow, opacity-based drag handle), progress bar fill fix, files table wrapper, etapes section, and updated task-list gap. This plan runs in parallel with Plan 02 since CSS class names are already locked in the UI-SPEC. Purpose: Without these CSS rules, the templ components from Plan 02 render unstyled. This plan is the visual half of the restyle. Output: Updated app.css with all new and modified CSS blocks from UI-SPEC. @/Users/arthur.belleville/Documents/perso/projects/xtablo-source/.claude/get-shit-done/workflows/execute-plan.md @/Users/arthur.belleville/Documents/perso/projects/xtablo-source/.claude/get-shit-done/templates/summary.md @/Users/arthur.belleville/Documents/perso/projects/xtablo-source/.planning/phases/20-tablo-detail-kanban-restyle/20-UI-SPEC.md @/Users/arthur.belleville/Documents/perso/projects/xtablo-source/.planning/phases/20-tablo-detail-kanban-restyle/20-RESEARCH.md @/Users/arthur.belleville/Documents/perso/projects/xtablo-source/.claude/skills/sketch-findings-xtablo-source/SKILL.md Task 1: Tablo detail header and metadata CSS go-backend/internal/web/ui/app.css - go-backend/internal/web/ui/app.css (read lines 1040-1080 — existing .project-progress-track, .project-progress-bar, .project-progress-label rules to understand context before modifying) - go-backend/internal/web/ui/app.css (read lines 880-920 — existing .tab-nav, .tab-nav-item rules to confirm no tab changes needed) - go-backend/internal/web/ui/base.css (read first 60 lines — confirm --color-brand-primary, --color-border-default, --color-surface-muted, --color-text-primary token names) Edit go-backend/internal/web/ui/app.css. Append a new section at the end of the file titled "/* === Tablo Detail Page === */". Add the following CSS blocks in this order. Use exact property values from the UI-SPEC — do not approximate or simplify. BLOCK 1: .tablo-detail-page — outer container padding: 24px 32px; BLOCK 2: .tablo-detail-header — header element border-bottom: 1px solid var(--color-border-muted); display: flex; flex-direction: column; gap: 0; padding-bottom: 0; BLOCK 3: .tablo-detail-title-row — flex row with avatar + h1 align-items: center; display: flex; gap: 16px; margin-bottom: 0; padding-bottom: 16px; BLOCK 4: .tablo-detail-avatar — 48×48 colored circle align-items: center; border-radius: 12px; color: #ffffff; display: flex; flex-shrink: 0; font-size: 1rem; font-weight: 700; height: 48px; justify-content: center; width: 48px; BLOCK 5: .tablo-detail-title — h1 tablo name color: var(--color-text-primary); font-size: 1.75rem; font-weight: 600; line-height: 1.2; margin: 0; BLOCK 6: .tablo-metadata-row — metadata flex row align-items: center; border-bottom: 1px solid var(--color-border-muted); display: flex; flex-wrap: wrap; gap: 24px; padding-block: 16px; BLOCK 7: .tablo-meta-segment — each segment in metadata row align-items: center; color: var(--color-text-secondary); display: flex; font-size: 0.875rem; gap: 8px; BLOCK 8: .tablo-meta-progress — progress segment override align-items: center; display: flex; gap: 8px; BLOCK 9: .tablo-progress-bar — detail page progress bar fill (MUST use brand-primary, NOT project-color — Pitfall 5) background: var(--color-brand-primary); border-radius: 9999px; height: 5px; BLOCK 10: .tablo-tab-bar — tab navigation below header border-bottom: 1px solid var(--color-border-muted); display: flex; gap: 24px; margin-top: 0; padding-top: 8px; BLOCK 11: .tablo-tab-bar .tab-nav-item — override for tabs within tablo detail font-size: 0.875rem; padding-bottom: 12px; Do NOT modify the existing .project-progress-bar rule (it is used by tablo cards on the list page which keep var(--project-color)). The tablo detail page uses .tablo-progress-bar (different class) to avoid the conflict. Do NOT modify .tab-nav or .tab-nav-item globally — only scope changes to .tablo-tab-bar context if any override is needed. grep -c "tablo-detail-header\|tablo-detail-title\|tablo-metadata-row\|tablo-progress-bar\|tablo-tab-bar" /Users/arthur.belleville/Documents/perso/projects/xtablo-source/go-backend/internal/web/ui/app.css grep count returns 5 or more (one match per class block); .tablo-progress-bar uses var(--color-brand-primary) not var(--project-color); grep for "tablo-progress-bar" returns a rule with "background: var(--color-brand-primary)". Task 2: Kanban board, task card, etapes section, files table, and task-list gap CSS go-backend/internal/web/ui/app.css - go-backend/internal/web/ui/app.css (read lines 1283-1350 — existing .task-list, .task-row, .task-body, .task-check rules; understand what to modify vs what to add) - go-backend/internal/web/ui/app.css (read lines 1254-1268 — existing .tasks-section rule with border-radius: 1rem — do NOT change this; kanban column gets its own rule) - go-backend/internal/web/ui/base.css (confirm --color-surface-default, --color-border-default, --color-border-strong, --color-surface-muted token names) Edit go-backend/internal/web/ui/app.css. Continue the "/* === Tablo Detail Page === */" section from Task 1 (or append after it). Add the following blocks: BLOCK 12: .tablo-kanban-board — flex container for the kanban columns display: flex; gap: 16px; overflow-x: auto; padding-bottom: 16px; padding-top: 24px; BLOCK 13: .tablo-kanban-column — each column card background: var(--color-surface-default); border: 1px solid var(--color-border-default); border-radius: 0.75rem; flex-shrink: 0; overflow: hidden; width: 18rem; BLOCK 14: .tablo-kanban-column-header — column header area align-items: center; background: var(--color-surface-muted); display: flex; gap: 8px; justify-content: space-between; padding: 12px 16px; BLOCK 15: .tablo-kanban-column-title — column h3 label color: var(--color-text-primary); font-size: 0.875rem; font-weight: 600; margin: 0; BLOCK 16: .tablo-kanban-task-count — task count pill background: var(--color-surface-default); border: 1px solid var(--color-border-muted); border-radius: 9999px; color: var(--color-text-secondary); font-size: 0.75rem; padding: 0 8px; BLOCK 17: .tablo-kanban-add-link — "+ Ajouter" link color: var(--color-text-brand); font-size: 0.875rem; font-weight: 400; margin-left: auto; text-decoration: none; BLOCK 18: .tablo-kanban-empty — empty column state color: var(--color-text-faint); font-size: 0.875rem; padding: 24px 16px; text-align: center; BLOCK 19: .task-card — new card layout (replaces/supplements .task-row for tablo detail) background: var(--color-surface-default); border: 1px solid var(--color-border-default); border-radius: 8px; cursor: pointer; display: flex; flex-direction: column; gap: 8px; padding-block: 8px; padding-inline: 12px; transition: box-shadow 0.12s ease, border-color 0.12s ease; BLOCK 20: .task-card:hover border-color: var(--color-border-strong); box-shadow: 0 8px 24px rgba(15, 23, 42, 0.08); BLOCK 21: .task-card-top-row — row with drag handle, title, delete icon align-items: flex-start; display: flex; gap: 6px; BLOCK 22: .task-drag-handle — drag handle (Braille pattern) color: var(--color-text-faint); cursor: grab; flex-shrink: 0; font-size: 1rem; opacity: 0; transition: opacity 0.12s ease; BLOCK 23: .task-card:hover .task-drag-handle — reveal on card hover opacity: 1; BLOCK 24: .task-card-title — task title text color: var(--color-text-primary); flex: 1; font-size: 0.875rem; font-weight: 400; line-height: 1.4; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; BLOCK 25: .task-card-delete — delete icon wrapper (opacity hidden at rest) flex-shrink: 0; opacity: 0; transition: opacity 0.12s ease; BLOCK 26: .task-card:hover .task-card-delete — reveal on card hover opacity: 1; Now modify the EXISTING .task-list rule (around line 1283 in app.css): Find the current rule: .task-list { display: flex; flex-direction: column; } Change it to add gap and padding: .task-list { display: flex; flex-direction: column; gap: 8px; padding: 8px; } This change affects both the global tasks page and the tablo detail page equally — gap between cards is desired everywhere. Add etapes section CSS: BLOCK 27: .tablo-etapes-section — etapes list below kanban board border-top: 1px solid var(--color-border-muted); margin-top: 24px; padding-top: 24px; BLOCK 28: .tablo-etapes-section h2, .tablo-etapes-section h3 — section heading color: var(--color-text-primary); font-size: 1rem; font-weight: 600; margin: 0 0 12px 0; BLOCK 29: .tablo-etapes-section ul — list reset list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; BLOCK 30: .tablo-etape-row — each etape row align-items: center; background: var(--color-surface-default); border: 1px solid var(--color-border-default); border-radius: 8px; display: flex; gap: 12px; justify-content: space-between; padding: 10px 16px; BLOCK 31: .tablo-etape-name — etape stage name color: var(--color-text-primary); font-size: 0.875rem; font-weight: 500; BLOCK 32: .tablo-etape-count — task count label color: var(--color-text-secondary); font-size: 0.75rem; Add files table wrapper CSS: BLOCK 33: .tablo-files-table-wrapper — wrapper for the files table border: 1px solid var(--color-border-default); border-radius: 12px; overflow: hidden; BLOCK 34: .tablo-files-table-wrapper thead tr background: var(--color-surface-muted); BLOCK 35: .tablo-files-table-wrapper thead th color: var(--color-text-muted); font-size: 0.75rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; BLOCK 36: .tablo-files-table-wrapper tbody tr border-bottom: 1px solid var(--color-border-default); BLOCK 37: .tablo-files-table-wrapper tbody tr:hover background: var(--color-surface-subtle); CRITICAL checks before saving: - .tablo-progress-bar uses "background: var(--color-brand-primary)" — verify with grep after writing - .task-card and .task-row are SEPARATE rules — .task-row must NOT be removed (it is used by the global tasks page) - .tasks-section border-radius (1rem) must NOT be changed — only .tablo-kanban-column gets 0.75rem - All opacity transitions use "0.12s ease" consistent with design system grep "background: var(--color-brand-primary)" /Users/arthur.belleville/Documents/perso/projects/xtablo-source/go-backend/internal/web/ui/app.css grep returns at least one line containing "background: var(--color-brand-primary)" (the .tablo-progress-bar rule); .task-card block exists with flex-direction: column; .task-drag-handle exists with opacity: 0; .task-card:hover .task-drag-handle exists with opacity: 1; .tablo-kanban-board exists with overflow-x: auto; .task-list updated to include gap: 8px; .task-row unchanged; .tablo-etapes-section and .tablo-etape-row rules present. ## Trust Boundaries | Boundary | Description | |----------|-------------| | CSS cascade | New .task-card rules must not override or break .task-row rules used on global /tasks page | ## STRIDE Threat Register | Threat ID | Category | Component | Disposition | Mitigation Plan | |-----------|----------|-----------|-------------|-----------------| | T-20-06 | Tampering | CSS cascade — .task-card vs .task-row collision | mitigate | .task-card is a new separate selector; .task-row selector is unchanged; they do not overlap since tablo-detail uses task-card and global tasks page uses task-row | | T-20-SC | Tampering | npm/pip/cargo installs | accept | No package installs — CSS file edit only | After Plan 03: - grep for "tablo-kanban-board" in app.css returns at least one match with "overflow-x: auto" - grep for ".tablo-progress-bar" in app.css returns a match with "background: var(--color-brand-primary)" - grep for "tablo-progress-bar" does NOT return "var(--project-color)" - grep for ".task-card" in app.css returns the column-flex card rule (flex-direction: column) - grep for ".task-drag-handle" returns opacity: 0 rule - grep for ".task-card:hover .task-drag-handle" returns opacity: 1 rule - grep for ".task-row" still returns the original horizontal rule (not removed) - grep for ".tasks-section" still has border-radius: 1rem (not changed to 0.75rem) - grep for ".task-list" returns updated rule with gap: 8px - grep for ".tablo-etapes-section" returns a CSS rule - grep for ".tablo-etape-row" returns a CSS rule - go build ./... still exits 0 (CSS is static — no compilation risk, but verify Go still compiles cleanly) - Visual: tablo detail header shows tablo name in large font, metadata row, and progress bar with purple fill - Visual: kanban columns are 18rem wide with rounded corners, muted header background - Visual: task cards are white box with column layout, subtle border, hover shadow - Visual: drag handle appears on card hover (opacity transition, not display toggle) - Visual: delete icon appears on card hover - Visual: empty columns show "Aucune tâche" centered - Visual: etapes section renders below kanban board with stage names and task counts - CSS regression: global /tasks kanban page still renders correctly (task-row unchanged) Create `.planning/phases/20-tablo-detail-kanban-restyle/20-03-SUMMARY.md` when done.