KQ-1745 · BACKWARD/PLAN
Backward Plan
A deadline-first planner: every task is scheduled as late as it can be and drawn as a car on a timeline that ends at the deadline flag. Dragging the flag, or any unlocked car, pulls the train — each car's finish follows the start of the car after it through the springs.snap calibration, integrated per frame in one loop, so the pull travels back down the train and every car settles a beat after the one ahead; the release projects the throw to a whole day and the flag springs there with its velocity. Cars pushed before today turn amber, locked cars hold their dates and lean toward the pull before springing upright on springs.recoil, and the flag is a slider whose arrow keys move the deadline a day while Tab reaches every task.
Fieldline site handover
Starts Tue 27 Oct · 8 days to spare
Handover Fri 27 Nov
Left and Right move the deadline a day, Page Up and Page Down a week. On a task, L locks it; a locked task moves with Left and Right; Shift with Left or Right changes its length.
Survey sign-off
StartsTue 27 Oct· 3 d
Order steel
StartsFri 30 Oct· 5 d
Groundworks
StartsSun 1 Nov· 6 d
Frame & roof
StartsSat 7 Nov· 8 d
Services first fix
StartsSun 15 Nov· 5 d
Fit-out
StartsFri 20 Nov· 6 d
Handover pack
StartsWed 25 Nov· 3 d
Snagging walk
StartsThu 26 Nov· 2 d
handover fri 27 nov · starts tue 27 oct · 8 days spare
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/backward-plan
Props
- barStyle
- "solid" | "soft" | "track"
- default "soft"
- How a task is drawn: a pigment bar, a tinted bar with a strong leading edge, or a thin rail with its dates above.
- dayWidth
- number
- default 12
- Pixels per day on the board: the scale of the timeline (8 to 40).
- accent
- "cobalt" | "moss" | "plum" | "slate"
- default "cobalt"
- The bars' pigment at a fixed lightness; tasks in the past are always amber.
- tasks / defaultTasks
- PlanTask[]
- default — / defaultPlanTasks
- Each { id, name, days, after?: id[], locked?, start? }; start is the first day of a locked task. Controlled or initial.
- onTasksChange
- (tasks) => void
- default —
- Fires with every task after a lock, a pinned move or a length change.
- deadline / defaultDeadline
- number
- default — / defaultPlanDeadline
- The handover day, ms at UTC midnight; controlled or initial.
- onDeadlineChange
- (deadline) => void
- default —
- Fires from the drag release or the key that moved the deadline, with the new day.
- onTaskChange
- (task) => void
- default —
- Fires when one task's pinned dates or length change.
- onLock
- (task, locked) => void
- default —
- Fires when a task is locked (to its current dates) or unlocked.
- now
- number
- default defaultPlanNow
- Today in ms; tasks that would start before it turn amber. Never read from the clock.
- range
- [number, number]
- default [10, 70]
- Earliest and latest deadline, in days after now.
- status
- "ready" | "loading" | "error"
- default "ready"
- Loading shows placeholder bars; error explains and offers Try again.
- onRetry
- () => void
- default —
- Try again was pressed after the plan failed to load.
- title
- string
- default "Fieldline site handover"
- The heading.
- height
- number
- default 540
- Height of the surface in px; the board scrolls inside it.
- disabled
- boolean
- default false
- Read only: nothing can be moved or locked.
- className
- string
- default —
- Classes for the surface.
| Prop | Type | Default | Description |
|---|---|---|---|
| barStyle | "solid" | "soft" | "track" | "soft" | How a task is drawn: a pigment bar, a tinted bar with a strong leading edge, or a thin rail with its dates above. |
| dayWidth | number | 12 | Pixels per day on the board: the scale of the timeline (8 to 40). |
| accent | "cobalt" | "moss" | "plum" | "slate" | "cobalt" | The bars' pigment at a fixed lightness; tasks in the past are always amber. |
| tasks / defaultTasks | PlanTask[] | — / defaultPlanTasks | Each { id, name, days, after?: id[], locked?, start? }; start is the first day of a locked task. Controlled or initial. |
| onTasksChange | (tasks) => void | — | Fires with every task after a lock, a pinned move or a length change. |
| deadline / defaultDeadline | number | — / defaultPlanDeadline | The handover day, ms at UTC midnight; controlled or initial. |
| onDeadlineChange | (deadline) => void | — | Fires from the drag release or the key that moved the deadline, with the new day. |
| onTaskChange | (task) => void | — | Fires when one task's pinned dates or length change. |
| onLock | (task, locked) => void | — | Fires when a task is locked (to its current dates) or unlocked. |
| now | number | defaultPlanNow | Today in ms; tasks that would start before it turn amber. Never read from the clock. |
| range | [number, number] | [10, 70] | Earliest and latest deadline, in days after now. |
| status | "ready" | "loading" | "error" | "ready" | Loading shows placeholder bars; error explains and offers Try again. |
| onRetry | () => void | — | Try again was pressed after the plan failed to load. |
| title | string | "Fieldline site handover" | The heading. |
| height | number | 540 | Height of the surface in px; the board scrolls inside it. |
| disabled | boolean | false | Read only: nothing can be moved or locked. |
| className | string | — | Classes for the surface. |