← Prompts

Kanban

Read the current prompt
# Task: Build a Kanban Project Board

Build a kanban project-management board (vanilla JS, no external assets, no CDN, no libraries) in the spirit of Trello or Linear. The top priority is **flawless drag-and-drop** — it looks simple, but the edge cases are where implementations fall apart.

## Core Specification

**Board Model**
- Columns (default: Backlog, To Do, In Progress, Review, Done) containing ordered cards
- Cards have: title, description, optional labels (colored chips), optional due date
- Full CRUD: add/rename/delete columns (keep at least one), add/edit/delete cards; inline editing (click title to edit, Enter commits, Escape cancels)

**Drag & Drop (the hard part — get every detail right)**
- Drag cards within a column to reorder, and across columns to move them
- **Live drop indicator:** while dragging, a gap/placeholder shows exactly where the card will land, updating smoothly as the cursor moves between cards and into empty columns (including empty columns — dropping into a column with zero cards must work)
- Auto-scroll: dragging near the left/right board edge scrolls horizontally; near the top/bottom of a column scrolls that column
- The dragged card follows the cursor with a slight tilt/elevation; original spot shows the placeholder, not a duplicate
- Escape mid-drag cancels and returns the card to its exact original position
- Column drag-to-reorder as well (drag by column header)
- Use the Pointer Events API (or mousedown/mousemove) rather than HTML5 drag-and-drop — you need pixel-following control; no ghost-image defaults

**Board Features**
- Per-column card count in the header; optional WIP limit per column (configurable in a column menu) that highlights the column in red when exceeded — but never blocks drops
- Label manager: a fixed palette of ~6 colors with names; filter bar to show only cards matching selected labels (filtering is a view — hidden cards keep their positions when the filter clears)
- Board search: filters cards by title text as you type
- Full persistence: columns, cards, order, labels, WIP limits, and filter state serialize to `localStorage` and restore exactly on reload
- Undo for destructive actions at minimum (card/column delete) — a toast with Undo is fine

## Visual Style
- Clean, modern SaaS aesthetic: light neutral background, softly elevated cards, pastel label chips, generous spacing
- Columns scroll independently; board scrolls horizontally; sticky board header
- Satisfying micro-interactions: card lift on drag-start, settle animation on drop, subtle hover raise
- Empty columns show a dashed drop zone state so they're obviously valid targets

## Technical Requirements
- Vanilla JS; all code organized with clear section comments
- Single source of truth: a serializable board model — rendering, hit-testing, and persistence derive from it; never reconstruct state by reading the DOM
- Tunable constants block at the top (colors, label palette, drag thresholds, scroll speed)
- No layout thrash: reads and writes batched during drag; smooth 60 FPS dragging with ~100 cards

## Quality Bar (must hit all)
- Dropping between two cards lands exactly there; dropping at a column's end appends; dropping into an empty column works
- Cancel mid-drag (Escape) restores the original order exactly — no orphaned placeholders, no state drift
- Rapid dragging (pick up, move fast across columns, drop) never duplicates or loses a card
- Filtered view never corrupts positions; clearing the filter restores the exact prior order
- Reload mid-session restores the board identically, including card order within columns

## Self-Check Before Finishing
Verify with the browser tools (probe by dispatching pointer events and asserting the resulting model/DOM order):
- Create 3 columns with 2, 0, and 3 cards; drag a card into the empty column and to the top, middle, and bottom of the 3-card column — assert final order each time
- Drag a card, press Escape, assert the model is byte-identical to before the drag
- Set a WIP limit of 1 on a column, drag 2 cards in, assert the red highlight appears
- Apply a label filter, then clear it, and assert card order matches the pre-filter order
- Reload and assert the board model is identical