Component library · v1.0

Every component, every state, on one page.

Built as the review surface for handoff: each row forces the states a spec sheet has to prove. Hover and active are simulated with classes so they can be inspected side by side; in production they come from real pointer state.

Buttons 6 variantsInputs 6 states Risk markers 4 tiersFindings 2 states

Buttons

Height 44px minimum, 36px for compact header actions, 52px for large, 68px for the hero primary. Focus ring is 2px at 3px offset on every variant. The loading state keeps the label box for width stability and swaps in a 18px spinner.

VariantDefaultHoverActiveFocusDisabledLoading
primary
secondary
outline
ghost
danger
icon
n/a
Primary XL · hero
Loading

Chain selector

Radio group semantics, arrow keys move between the two chains, 44px targets. The selected pill takes the chain's own colour as border and tint, and always carries its logo, so the state is not colour-only. Two instances exist: the two-up selector (input card, final CTA, entry states) and the compact pill in the results header.

Default · Ethereum
Selected · BSC
Disabled
Loading
Compact BNB Chain Remembered on this device

Address field

EVM addresses only. The chain logo sits inside the field so the address and the chain are read together. Paste control is 40px; the hint line below is the validation channel and reserves its height so nothing jumps.

Default
EVM address, 42 characters. A DEMO address is loaded.
Focus
Valid EVM address for BNB Smart Chain.
Invalid
Not an EVM address: 42 characters, starting with 0x.
Loading
Resolving the address…
Disabled
Screening is paused on this workspace.
Unsupported chain shape
Looks like a Tron address. Tron is not covered yet.

Badges, chips and tags

Chain badges always pair the official logo with the chain name. Risk chips always pair colour, icon and the tier word. Tags are mono, lowercase and used for categories and formats.

Ethereum BNB Smart Chain DEMO Neutral sanctionsmixerbridge PDFJSON
Low Moderate High Severe Low risk Moderate risk High risk Severe risk
Low Moderate High Severe

Risk markers

Gauge geometry is fixed: 270 degrees, 9px stroke, rounded caps, 11 ticks with a longer tick every fifth. The number and the tier word are the primary signal; the arc is confirmation.

Low
Moderate
High
Severe

Findings row

A summary row is 68px tall with a 44px severity tile. The expanded body indents to the text column, not the tile, so evidence keeps a single reading edge. Native details/summary gives keyboard and screen-reader behaviour for free.

Indirect match to a designated entity
Severesanctions2 hops · 4.8% of inflow

Collapsed default. Click to open the evidence block below.

Match typeIndirect · exposure based
SourceUS Treasury SDN · 24 Oct 2026
Mixer and tumbler exposure
Highmixer12.4% of inflow

Expanded state. Evidence rows use mono for values so addresses and dates line up across rows.

Volume41.2 ETH
Counterparty0x91c4…4a2b
Window02 Feb – 18 Sep 2026

Alerts and states

Four tones, one geometry. Feedback colour never reuses the risk ladder: a rate limit is not a severe finding.

That address is not valid
EVM addresses are 42 characters and start with 0x.
Rate limit reached
The next free check unlocks in 47 seconds.
New wallet: no score issued
Below the minimum of 10 transfers and 30 days of history.
Screening complete
4 findings were returned from 3 datasets.
Loading skeleton
Toast
Report copied to clipboard.
DEMO: export is not wired in this prototype.

Controls

Tabs
Language switch
Theme
Copy
Exposure bar

Data display

FindingTierShare
Sanctions · indirectSevere4.8%
Mixer exposureHigh12.4%
Darknet-adjacentModerate3.1%
Bridge hopsLow6 hops
JSON
{
  "tier": "high",
  "score": 68,
  "chain": "ethereum",
  "audit_id": "TL-8F42-01C9"
}

Wallet connection

A scan cannot run before a wallet is connected: Check wallet opens the connection step instead of producing a report, and the report screen has its own locked state rather than reusing the input form. The sheet is one component, built in JS so every page shares it.

Connection trigger

Every button that opens wallet connection carries the connect-btn class and is bound by the wallet script. The interface adds no handler of its own, so the script always receives the click.

Account chip · connected
Inline requirement note
A connected wallet is required to run a scan.

Hidden once a wallet is connected; the chip takes its place in the header.

Component contract

ComponentTokens usedStatesNotes
Buttongrad-cta, glow-cta, r-3/4, dur-26 + 4 sizesLoading keeps width; label hidden, not removed
Chain pillchain-eth, chain-bnb, chain-*-tint6Role radio; arrows move selection
Address fieldsurface, border-strong, focus cyan6Hint line reserves 18px to prevent layout shift
Risk chiprisk-*, risk-*-tint, risk-*-edge4 tiers × 3 sizesIcon + word mandatory
Finding rowsurface-2, risk-*, r-4collapsed, open, hoverNative details/summary, 68px summary
Gaugerisk ramp, dur-54 tiers, emptyStarts at 0 and sweeps once on mount
Alertok/warn/danger/info4 tonesNever encodes risk severity
Account chipborder-strong, mono 11.5connected onlyHidden on mobile address text, keeps the chain logo