KQ-2056 · COUNCIL/TABLE

Council Table

An AI chat answered by a council of specialists seated along an arc above the thread. When the floor changes, a baton travels round the arc to the new seat on springs.snap — position and tilt derived from one motion value, so it passes the seats between — and that seat rises on the same spring while its reply enters the thread on springs.glide; a reply that disagrees with an earlier one draws a thin bracket back up the gutter to the message it disputes on glide. The seats are a toolbar (arrows walk the arc, Enter addresses, Delete dismisses), @ in the composer opens the council as a listbox, and under 34rem the arc flattens into a row of avatars.

KQ-2056 · COUNCIL/TABLE

Basinworks Team pricing

4 specialists · 3 replies

  1. 14 min ago

    We're moving Basinworks Team from $18 to $24 a seat on 1 September. What do we need to get right?

  2. PlanningRollout and timing13 min ago

    Ship it in two steps: $21 on 1 September for everyone, then $24 on 1 December. A smaller first jump keeps cancellations down while support learns which questions come up.

  3. LegalContracts and notice11 min ago

    Two steps means two price-change notices. Contracts signed before June promise 60 days' notice of any change, so a second step can't land before 1 February. One change, announced once, is cleaner.

  4. FinanceRevenue and churn8 min ago

    At $24, revenue rises 21% even if 8% of teams leave. Holding $21 until December gives up about $310k, so I'd go in one step if Legal's notice holds.

Arrow keys move between seats, Enter addresses one, Delete dismisses it.

Finance has the floor.

floor · finance · basinworks pricing council

Install

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

$ pnpm dlx shadcn@latest add @kinetiq/council-table

Props

seatShape
"disc" | "tile" | "arch"
default "disc"
Round discs, rounded tiles, or arch-topped seat backs — on the arc, in the thread and in the @ list.
density
"compact" | "cozy" | "roomy"
default "cozy"
Seat size, the arc's height, type size and spacing.
accent
string
default "var(--accent-bright)"
Any CSS colour for the baton, the floor ring, the addressee chip, lit brackets and Send.
specialists
CouncilSpecialist[]
default defaultCouncilSpecialists
The council, left to right along the arc: id, name, remit, initials and a state (idle, thinking or failed).
turns / defaultTurns
CouncilTurn[]
default — / defaultCouncilTurns
The thread, controlled or initial: author ("you" or a specialist id), text, time, an optional addressee, the turn it disputes with a short note, or summary points.
onTurnsChange
(turns: CouncilTurn[]) => void
default —
Fires from a send with the whole new thread.
floor
string | null
default the thinking seat, else the newest speaker
Who holds the baton.
dismissed / defaultDismissed
string[]
default — / []
Seats sent away from the table, controlled or initial; their turns stay in the thread.
onDismiss
(id: string) => void
default —
A seat was dismissed (Delete on a seat, or its ×).
onRestore
(id: string) => void
default —
A dismissed seat was brought back from the header.
onAddressSpecialist
(id: string | null) => void
default —
A specialist was addressed from its seat or with @, or the address was cleared.
onSend
(text: string, addressee: string | null) => void
default —
A message was sent, with the addressed specialist if there was one.
onSummarise
() => void
default —
Summarise was pressed; answer with a turn that has points to show the summary card.
summarising
boolean
default false
Holds Summarise busy while the host writes the summary.
onRetry
(id: string) => void
default —
Retry was pressed on a seat that failed to answer.
onReload
() => void
default —
Try again was pressed after the thread failed to load.
now
number
default defaultCouncilNow
The moment relative times count from, in ms — never the wall clock during render.
title
string
default "Basinworks Team pricing"
The conversation's name in the header.
you
string
default "You"
How the person asking is named in the thread.
status
"ready" | "loading" | "error"
default "ready"
Loading draws skeleton seats and turns; error offers Try again.
height
number
default 540
The surface's height in px; the thread scrolls inside it.
placeholder
string
default "Ask, or @ a specialist"
The composer's placeholder.
disabled
boolean
default false
Read only: nothing can be addressed, sent or dismissed.
className
string
default —
Classes for the outer surface.