xtablo-source/.planning/phases/09-etapes/09-UI-SPEC.md
2026-05-15 22:25:43 +02:00

9.6 KiB

phase slug status shadcn_initialized preset created
09 etapes approved false none 2026-05-15

Phase 09 - UI Design Contract

Visual and interaction contract for Phase 9. This phase adds etape controls to the existing Go/HTMX Tasks tab without redesigning the kanban.


Design System

Property Value
Tool none
Preset not applicable
Component library local backend/internal/web/ui helpers plus Tailwind utility classes
Icon library none currently used in this backend UI; do not introduce an icon package for this phase
Font inherited app/system sans-serif

Product Intent

Phase 9 should feel like an extension of the current working kanban, not a new task product. The user asked for a first functional UI now and a beautiful UI later. Keep the surface quiet, compact, and explicit.

Locked decisions from 09-CONTEXT.md:

  • Etapes live in a compact top strip above the existing kanban.
  • Etapes render as chips with task counts.
  • Include an Unassigned chip.
  • Selecting an etape filters the existing kanban.
  • Status columns and task drag/drop behavior remain the primary task interaction.
  • Task assignment happens in task create/edit forms.

Layout Contract

Tasks Tab Structure

TasksTabFragment must render in this order:

  1. Etape strip zone.
  2. Existing kanban board.

Use a whole-fragment swap for etape filtering so active chip state, chip counts, add-task forms, and kanban contents stay in sync.

Required outer ids/classes:

  • #tab-content remains the tab switch target.
  • #tasks-tab should wrap the full Tasks tab fragment after Phase 9.
  • #etape-strip should wrap the chip strip and etape management controls.
  • #kanban-board remains the kanban board id.
  • Existing .sortable-column, .task-card-zone, and .task-card semantics must remain stable.

Etape Strip

The etape strip sits directly above #kanban-board.

Visual contract:

  • Horizontal flex row with wrapping: flex flex-wrap items-center gap-2.
  • Bottom spacing before kanban: mb-4.
  • No surrounding card, no nested card, no panel border around the whole strip.
  • Chips are compact inline buttons or links, not large cards.
  • Chips should not resize the kanban columns.
  • Long etape titles must truncate inside the chip with max-w-*, truncate, and visible count.

Minimum chip set:

  • All chip: shows all tasks.
  • Unassigned chip: filters tasks with no etape.
  • One chip per etape.

The All chip is allowed even though the user only explicitly requested Unassigned; it is the necessary return path from a filtered view.

Kanban Board

Keep the existing four horizontal columns and fixed column width.

Do not:

  • split columns into etape groups,
  • turn etapes into lanes,
  • move status labels under etapes,
  • change TaskColumns,
  • place the kanban inside a decorative card.

When a filter has no tasks in a status, keep the existing empty copy style: No tasks yet.


Interaction Contract

Filtering

Chip behavior:

  • All chip requests /tablos/{id}/tasks with no etape filter.
  • Unassigned chip requests /tablos/{id}/tasks?etape=unassigned.
  • Etape chips request /tablos/{id}/tasks?etape={etape_id}.
  • HTMX target should be #tab-content or #tasks-tab, not only #kanban-board, because active chip state and counts must update with the board.
  • hx-push-url should keep the current filter URL shareable and refresh-safe when practical.

Active chip state:

  • Active chip uses a stronger border/text/background than inactive chips.
  • Active chip must be visible without relying on color alone: use both border weight/color and text weight.

Etape Create/Edit/Delete

Management controls should remain close to the strip.

Recommended first shape:

  • A compact New etape button at the end of the strip.
  • Inline create form swaps into a small strip-adjacent zone, not into the kanban columns.
  • Edit/delete controls may be exposed from the active etape chip or an inline edit state; the plan may choose the simplest HTMX pattern that stays compact.
  • Delete confirmation copy must make clear that tasks are kept and unassigned.

Etape reorder:

  • Reordering can be implemented with explicit up/down controls or Sortable.js over the chip strip.
  • If using Sortable.js, do not interfere with .sortable-column task drag/drop.
  • Reorder controls must preserve chip dimensions and avoid layout shift.

Task Assignment

Task create/edit forms must include an etape selector.

Selector contract:

  • Label: Etape.
  • Options include No etape.
  • Existing etapes are listed by title.
  • If the current board filter is a specific etape, new task forms may preselect that etape.
  • If the current filter is Unassigned, forms should default to No etape.
  • If the current filter is All, forms should default to No etape unless editing an assigned task.

Selector styling should match existing inputs:

  • text size text-sm,
  • border border-slate-300,
  • rounded border,
  • px-2 py-1 inside compact task cards or px-3 py-2 in larger forms.

Deletion

Etape delete confirmation copy:

  • Heading: Delete etape?
  • Body: Tasks in this etape will stay in the tablo and move to Unassigned.
  • Primary destructive action: Delete etape
  • Secondary action: Keep etape

Deleting an etape must not visually remove task cards permanently from the tablo. After deletion, affected tasks should appear under Unassigned or All depending on the active filter.


Spacing Scale

Declared values are multiples of 4 and align with existing Tailwind usage.

Token Value Usage
xs 4px Icon-free inline gaps, chip inner count spacing
sm 8px Chip gaps, compact form field gaps
md 16px Strip-to-board spacing, card padding, column gaps
lg 24px Existing tab content rhythm
xl 32px Not required for this compact feature
2xl 48px Not required
3xl 64px Not required

Exceptions: none.


Typography

Use current app typography; do not introduce viewport-scaled text.

Role Size Weight Line Height
Body 14px (text-sm) 400 default Tailwind normal
Label 14px (text-sm) 500 default Tailwind normal
Compact meta/count 12px (text-xs) 500 default Tailwind normal
Section heading 16px (text-base) 600 default Tailwind normal
Page heading unchanged existing page heading unchanged unchanged

Chip titles should use text-sm. Counts should use text-xs or local badge styling.


Color

Use the existing slate-forward palette. Do not add a new brand accent for etapes.

Role Value Usage
Dominant (60%) #ffffff / bg-white Task cards, form surfaces
Secondary (30%) #f1f5f9 / bg-slate-100; #e2e8f0 / border-slate-200 Column headers, chip backgrounds, borders
Accent (10%) #1e293b / text-slate-800, border-slate-800 Active chip, active tab-like state
Destructive existing danger button styles Etape delete confirmation only

Accent reserved for:

  • active etape chip,
  • selected tab/filter state,
  • primary create/save actions through existing ui.Button default styling.

Do not use gradients, decorative colored strips, or a one-off etape color palette.


Copywriting Contract

Element Copy
Primary CTA New etape
Etape title label Title
Etape description label Description (optional)
Empty etape strip body No etapes yet
Empty etape strip action New etape
Filter chip for all tasks All
Filter chip for tasks without etape Unassigned
Task assignment label Etape
Task assignment empty option No etape
Etape title validation Title is required
Etape delete heading Delete etape?
Etape delete body Tasks in this etape will stay in the tablo and move to Unassigned.
Etape delete action Delete etape
Etape delete cancel Keep etape
Generic server error Something went wrong. Please try again.

Avoid explanatory UI text about keyboard shortcuts, implementation, or how filtering works. The chip labels and active state should carry the interaction.


Accessibility Contract

  • Chips must be real links or buttons.
  • Active chip must include aria-current="true" when rendered as a link.
  • Delete/edit controls must have task- or etape-specific aria-label values when the visible label is short.
  • Form labels must be associated with inputs via for/id or an equivalent explicit label pattern.
  • Count badges must remain readable as text, not only visual badges.
  • Focus styles must remain visible through existing browser/Tailwind focus treatment.

HTMX Swap Contract

Preferred fragment boundaries:

  • Filtering: swap #tasks-tab or #tab-content.
  • Etape create/edit/delete: swap a dedicated etape strip/form zone and include out-of-band updates if counts or board contents change.
  • Task create/update: preserve current .task-card-zone and add-task slot behavior.
  • Reorder: preserve #kanban-board as the task reorder response target.

Any response that changes etape assignment or etape deletion should update chip counts. Whole Tasks-tab swap is acceptable for the first version.


Registry Safety

Registry Blocks Used Safety Gate
shadcn official none not required
third-party registry none do not use

Checker Sign-Off

  • Dimension 1 Copywriting: PASS
  • Dimension 2 Visuals: PASS
  • Dimension 3 Color: PASS
  • Dimension 4 Typography: PASS
  • Dimension 5 Spacing: PASS
  • Dimension 6 Registry Safety: PASS

Approval: approved 2026-05-15