KQ-2070 · STANDUP/CARDS

Standup Cards

A daily standup for a team of agents: one card each with what it did, what it does next and what it is stuck on. When the table comes into view the cards are dealt onto it in turn on springs.snap — from a deck with a seeded tilt, dropped from above, or slid in from the left — and an unanswered blocker glows in the warn colour until someone answers it. Answering slides the item off its card: a chip lifts from the row and glides to the resolved tray on springs.glide, landing there on springs.recoil while the card closes the gap on glide, and reassigning swaps the owner on snap. Tab moves card to card, Down and Up walk a card's items, B jumps to the next blocker; the cards form two columns from 36rem and a swipeable stack under 30rem, where a projected flick sends the front card to the back.

KQ-2070 · STANDUP/CARDS

Thursday standup

Gaugeworks support · Thu 15 Oct · 4 agents

Pike · Triage

Online

Blocked
  • Needs Dana Reyes · On-call

Wren · Refunds

Online

Blocked
  • Needs Priya Nair · Billing

Moss · Escalations

Online

Nothing blocked

Lark · Help center

Offline since 06:40

Blocked
  • Needs Sam Osei · Design
Resolved · 0Answered blockers land here.

Tab moves between cards. Down and Up walk a card’s items. B jumps to the next blocker.

3 blocked · 4 agents

Install

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

$ pnpm dlx shadcn@latest add @kinetiq/standup-cards

Props

agents
StandupAgent[]
default defaultStandupAgents (4)
The agents at the standup, one card each in dealing order: { id, name, role, online?, lastSeen? }.
items
StandupItem[]
default defaultStandupItems
Every agent's items: { id, agent, kind, text, owner? }; kind is done, next or blocked, and a blocker names the owner it needs.
owners
StandupOwner[]
default defaultStandupOwners (4)
People a blocker can need and be reassigned to: { id, name, team? }.
resolved / defaultResolved
StandupResolution[]
default — / []
Answered blockers, newest first: { item, answer, at }. They leave their cards and sit in the resolved tray.
onResolvedChange
(resolved: StandupResolution[]) => void
default —
Fires with the whole list when a blocker is answered.
onAnswerBlocker
(item: StandupItem, answer: string) => void
default —
A blocker was answered (Send or Enter in its field).
onReassign
(item: StandupItem, owner: StandupOwner) => void
default —
A blocker was reassigned from its owner menu.
onOpenItem
(item: StandupItem) => void
default —
An item, or a resolved chip, was pressed.
now
number
default Thu 15 Oct 2026, 09:30 UTC
The moment of the standup, in ms: stamps answers and dates the header.
utcOffset
number
default 0
Minutes added to UTC before a time is printed.
title
string
default "Thursday standup"
The standup's name and the region's accessible name.
team
string
default "Gaugeworks support"
Whose agents, under the title.
dealStyle
"deck" | "drop" | "slide"
default "deck"
How the cards arrive: dealt from a deck at the top with a seeded tilt, dropped into place, or slid in from the left.
density
"compact" | "cozy" | "roomy"
default "cozy"
Type size, padding and gaps of the cards.
accent
string
default "var(--accent-bright)"
Agent marks, Answer and Send, the flight, the tray and focus accents — any CSS colour.
trigger
"mount" | "inView"
default "inView"
When the cards are dealt: as soon as they mount, or when the table scrolls into view.
height
number
default 560
The surface's height in px; the table scrolls inside it.
status
"ready" | "loading" | "error"
default "ready"
Whether the standup has loaded; loading draws placeholder cards, error offers Try again.
onReload
() => void
default —
Try again was pressed after the standup failed to load.
disabled
boolean
default false
Read only: nothing can be answered or reassigned.
className
string
default —
Classes for the outer region.