Loading page…
Loading page…
The treasury console runs on a handful of leaves that recur on every page: a status pill, a chip, a set of quorum dots, a read-only toggle. They live in one module so Approvals, Ledger, Signers and Controls speak the same language — a lit dot always means moving or cleared, a dashed avatar always means a key that has not yet signed. Every block takes props; the fixtures stay in the surface data.
One dotted pill, four tones. Live tones (primary, success) carry the glow; waiting and failed states sit flat, so a lit dot always reads as motion or clearance. Approvals maps its four statuses onto these tones; Disbursements uses the primary pill to mark a batch.
Awaiting quorum — signatures still outstanding.
Quorum met; the movement can execute.
Signed and on the wire.
import { TreasuryStatusPill } from "@coldharbor/webui";
<TreasuryStatusPill tone="success">Ready to execute</TreasuryStatusPill>--ch-primary--ch-primary-muted--ch-success--ch-warning--ch-danger--ch-border--ch-surfaceThe filter chip carries toolbar facets: account, movement type, period. Exactly one chip per group is active. The role chip names a signer's standing; custodians hold the cold keys, so they alone read in accent.
Active chip first; the rest sit quiet.
Custodian in accent; every other role in the quiet register.
import { TreasuryFilterChip, TreasuryRoleChip } from "@coldharbor/webui";
<TreasuryFilterChip label="Cold Storage" active />
<TreasuryRoleChip role="Custodian" />--ch-primary--ch-primary-muted--ch-success--ch-warning--ch-danger--ch-border--ch-surfaceTwo dot readings that must never be confused. QuorumDots states the requirement — what the policy demands. SignatureMeter states progress — what has actually been collected against it, with the mono count spelled out for anyone counting keys.
Accent marks the deeper cold-storage bar.
Filled dots are signatures in hand; outlines are keys still to come.
import { QuorumDots, SignatureMeter } from "@coldharbor/webui";
<QuorumDots label="Cold storage" quorum={POLICY.coldQuorum} tone="accent" />
<SignatureMeter collected={approval.collected} required={approval.required} />--ch-primary--ch-accent--ch-border-strong--ch-bg-raised--ch-fg--ch-fg-muted--ch-fg-faintTreasury pages are Server Components and pass no handlers across the RSC boundary, so policy state is shown, never operated. semantics picks the reading: a read-only switch where an operator would flip it, a state indicator where the real control lives elsewhere.
role="switch", aria-readonly — Controls.
role="img" — a picture of policy state on Signers.
import { TreasuryStaticToggle } from "@coldharbor/webui";
<TreasuryStaticToggle on label="Whitelist-only withdrawals" />
<TreasuryStaticToggle on label="Whitelist-only sends" semantics="indicator" />--ch-primary--ch-primary-muted--ch-success--ch-warning--ch-danger--ch-border--ch-surfaceA name reduced to one letter — the treasury's stand-in for a face. Always decorative: the name itself sits in text alongside. The pending tone is dashed and unfilled, for a key invited but never used.
sm in signer pills, md on roster rows, lg on the account masthead.
Enrolled, not yet signing.
import { TreasuryInitialAvatar } from "@coldharbor/webui";
<TreasuryInitialAvatar name={cold.name} size="lg" tone="accent" />
<TreasuryInitialAvatar name={signer.name} tone={pending ? "pending" : "primary"} />--ch-primary--ch-primary-muted--ch-accent--ch-accent-muted--ch-border-strong--ch-bg-raised--ch-fg-mutedThree ways to state a figure. The tile frames one reconciled number; the strip runs counts by state across the head of a queue and takes the same tones as the pill; the meta cell is one labelled fact inside a dl, mono when it has to line up.
Tone dots mirror the status pills — same vocabulary, smaller voice.
Inflow · 30d
+8.1500 BTC
Outflow · 30d
−1.5200 BTC
Net · 30d
+6.6300 BTC
Default, success and danger tones.
Renders dt/dd — always inside a dl.
import {
TreasuryMetaCell,
TreasurySummaryStrip,
TreasurySummaryTile,
} from "@coldharbor/webui";
<TreasurySummaryStrip label="Approvals summary" cells={SUMMARY} />
<TreasurySummaryTile label="Net · 30d" value="+6.6300 BTC" />
<TreasuryMetaCell label="Requested" value={approval.requestedAt} mono />--ch-surface--ch-bg-raised--ch-border--ch-border-faint--ch-fg--ch-fg-muted--ch-fg-faintThe Controls page is built from these two. ControlBlock titles a group of master functions and carries the note explaining the consequence; ControlRow is one labelled setting with its control on the right.
A mandatory delay between signing and broadcast for the coldest funds — a window to catch a coerced or mistaken withdrawal.
import {
TreasuryControlBlock,
TreasuryControlRow,
TreasuryStaticToggle,
} from "@coldharbor/webui";
<TreasuryControlBlock title="Time-lock" note="A mandatory delay…">
<TreasuryControlRow
label="Cold-withdrawal time-lock"
description={POLICY.timelock}
control={<TreasuryStaticToggle on label="Cold-withdrawal time-lock" />}
/>
</TreasuryControlBlock>--ch-surface--ch-bg-raised--ch-border--ch-border-faint--ch-fg--ch-fg-muted--ch-fg-faintThe signing vocabulary on the flat canvas layer.
--ch-primary--ch-accent--ch-border-strong--ch-bg-raised--ch-fg--ch-fg-muted--ch-fg-faint