Build contract — exchanger surfaces
1 · One number, one action, per screen. The assurance band answers
"where am I" with the two statutory clocks and "what next" with a single primary CTA.
Everything else is secondary. Deadlines are framed forward — days remaining paired with the
exact date and the gating action — because the job here is to lower anxiety, not manufacture
urgency.
2 · An overdue clock is never a satisfied state. In the critical
state the 45-day ring renders on
--bad with the word EXPIRED and the escalation
path. It must never green out, never round to zero-and-hide, and never be "extended" from
this surface. A statutory date moves only through an approved four-eyes override recorded
with its legal basis — an exchanger has no control that can do it.
3 · The exchanger can never move funds. Constructive receipt is the
whole product. Nothing on any exchanger screen initiates, holds or releases money; the wire
row shows
needs-approval and stays there. Every disbursement requires four eyes,
where the approver is not the proposer, and it happens in a Vectr workflow — never inline.
4 · Neela drafts and explains; she does not transact. Her guardrail
line is permanent and non-dismissible. Her suggestion chips open a draft or a search — none
of them commits a signature, a payment, or an identification.
5 · Signatures require the signer's own intent. E-Sign buttons take
the exchanger to the signing ceremony under their own authenticated session (eSign Act /
UETA). There is no "sign on behalf" affordance anywhere, for any role.
6 · KYC is the first gate and it gates real things. The locked
marketplace card and the disabled ID Hub button are the same rule the API enforces, not a
visual state. Nobody may mark another party verified.
7 · Every figure is DB-backed and every claim is provenanced.
Calculator inputs seed from the exchange record and persist to Supabase — never localStorage
for business state. The calculator carries its "illustrative estimate, not tax advice"
disclaimer wherever the number appears. Workflow rows name the real Vectr workflow that
produced them; a row with no workflow behind it does not ship.
7a · A workflow badge is a claim, and an unbuilt workflow says so.
A solid
vectr-badge asserts that a Vectr workflow ran and produced the row above
it. A workflow that has not been built renders
.is-unarmed — dashed amber, the
literal words
not yet armed, and a hollow non-pulsing status dot — and is named in the
provenance banner at the top of the surface. It may never render as
live,
running,
ready,
watching or
blocked, because all five read
as "something is on this for me."
forty-five-day-id-watcher,
one-eighty-day-deadline-guard and
escrow-funds-received are unbuilt
today (docs/COMPLIANCE.md IRS1031-002 / -003 / -007: the app emits the lifecycle event, the
consuming Vectr workflow is the open half), so all three are dashed everywhere they appear on
this surface. The underlying facts stay as they are — the stored deadline dates are real, and
the escrow receipt row stays green because the money genuinely arrived and a QI officer
recorded it; only the claim about
what noticed is withdrawn. The moment a workflow
ships, its modifier and its banner clause come off together; never one without the other.
8 · Colour splits two jobs. Hub hue is wayfinding — which leg of the
exchange — and status is a separate good / warn / bad scale that always ships with a word
and an icon, so nothing is legible by colour alone.
9 · Tokens only. No raw hex in the implementation. Every colour
resolves through
tokens.css; text on a filled control uses that control's
-on token (
--hub-on,
--bad-on) because white fails AA
on the dark-theme fills.
--ink-4 is icons, rules and disabled glyphs only —
never body text.
Light and dark are both designed here. Matt Belcher, the address, the amounts and every
identifier on this surface are synthetic demo data.