KQ-1722 · PATINA/BOARD

Patina Board

A kanban board whose cards weather while they wait: every day still adds a faint patina — tarnish gathering at the edges first, then a mottled bloom from a seeded turbulence mask — mixed with the ink so it darkens on a light page and lifts like dust on a dark one, and a corner counter turns warn when a card goes stale and offers to nudge its owner. Moving or editing a card polishes it: a band of light crosses its face on a move-eased tween while a clip follows its edge and wipes the patina off, and the counter rolls to today on snap. The Stale filter gathers the oldest cards to the top of each column on glide; cards move by drag on flick and snap or by keys — Space lifts, arrows carry, Space drops, Escape puts back, Enter renames, N nudges.

KQ-1722 · PATINA/BOARD

Basinworks facilities

14 requests · 7 stale

Arrow keys move between cards. Space picks a card up; arrows carry it, Space drops it, Escape puts it back. Enter renames a card; N nudges the owner of a stale one.

Requested

2 stale5
  • BW-13112dReplace the dock door seal
  • BW-1383dLeak above the cold storeJoel
  • BW-1409dNew badge reader at gate 2
  • BW-1421dRepaint the loading bay linesKenji
  • BW-144todayBreak room lights flickerSade

Quoting

2 stale4
  • BW-11821dForklift charger quote
  • BW-12215dHVAC service contract
  • BW-1276dPallet racking inspectionMara
  • BW-1334dWindow film for the south officeJoel

Approved

3 stale5
  • BW-10918dClear the roof drains
  • BW-1128dFire door closers
  • BW-1152dBike shelter by receptionSade
  • BW-1195dOffice chairs for financeTomas
  • BW-12111dWater cooler filters

Scheduled

0
  • All clearNothing waiting here.

14 requests · 7 stale

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/patina-board

Props

columns
PatinaColumn[]
default defaultPatinaColumns
The columns in order ({ id, title, status? }); a loading column draws outlines.
cards / defaultCards
PatinaCard[]
default defaultPatinaCards
Controlled or initial cards ({ id, columnId, title, key?, owner?, still }); still is when the card last moved or changed.
onCardsChange
(cards: PatinaCard[]) => void
default —
Fires with every card after a move or an edit; the touched card's still is now.
onMove
(move: PatinaMove) => void
default —
Fires from the drop or key that moved a card.
onEdit
(cardId: string, title: string) => void
default —
Fires when a card's title is edited in place.
onNudgeOwner
(card: PatinaCard) => void
default —
Nudge was pressed (or N) on a stale card, for its owner.
staleFirst / defaultStaleFirst
boolean
default false
Controlled or initial Stale filter: the oldest cards gathered to the top of each column.
onFilterStale
(on: boolean) => void
default —
Fires from the toggle that turned the Stale filter on or off.
patinaRate
number
default 0.08
How much patina a card gains per day still, as a share of full; full at 1 / rate days.
cardStyle
"plain" | "raised" | "outline"
default "plain"
Cards drawn plain with a hairline, raised on a shadow, or as an outline over the column.
tone
"copper" | "rust" | "dust" | "ink"
default "copper"
The patina's pigment; it follows the theme.
staleAfter
number
default 7
Days still before a card counts as stale: its counter warns and its owner can be nudged.
now
number
default defaultPatinaNow
Today, ms since the epoch.
status
"ready" | "loading" | "error"
default "ready"
Whether the board's cards have arrived.
onRetry
() => void
default —
"Try again" was pressed after the board failed to load.
title
string
default "Basinworks facilities"
The heading.
height
number
default 460
The board's height in px; columns scroll inside it.
label
string
default —
The board's accessible name; defaults to the title.
disabled
boolean
default false
Freezes the board: no drags, keys, edits or nudges.
className
string
default —
Classes for the outer panel.