Overview
Tokens, icons, motion and React components for Arcadia products.
Working
Components
46 components, each shown where it lives in a product.
Install
The kit isn't published to npm yet. Inside the Arcadia workspace, depend on it directly; React 19 is a peer dependency.
package.json
Set up the root
Boot the theme before the first paint, load the kit's CSS before your own, and mount the three hosts once.
server.ts
app.tsx
Things that silently break
- No ConfirmHost
confirm()rejects with an error instead of asking, so the action behind it never runs.- No Toaster
toast()returns an id and nothing appears. There is no warning.- No boot script
- The theme is applied after the first paint, so anyone on a light theme sees a dark flash on every load.
- CSS outside a layer
- Unlayered rules beat every layer, the kit's
overridesincluded, so they quietly undo the reduced-motion contract and the legibility cut. Put product CSS in@layer features.
Sodium Horizon: slate neutrals with a blue-hour cast, white ink, dove prose and one beacon.
- Slate and two inks
- One neutral page, a step for what floats or frames code and one for what you touch. Every neutral is one slate hue with a blue-hour cast. Labels and headings are white; long reading is dove.
- The beacon
- One light, spent only on things that are literally lights: the horizon, unread and needs-you dots and the caret. It never fills a control, colours a link or marks a selection.
- Pills and one highlight
- Everything you press is a pill at weight 500, and nothing shrinks. In a list one highlight glides from row to row instead of each row lighting its own.
- The pine sweep
- The running glyph is the Arcadia pine, lit one stroke at a time: left arm, pine, right arm, pine. It stays neutral and quiet.
- One clock
- Every live loop divides a 3.2s watch, so a running agent's light, its glyph and its working text restart together.
- Calm motion
- Hovers change colour only. Popups slide a few pixels and never zoom; dialogs rise on a critically damped spring. Scrolling stays native, and a jump the app makes lands on a spring.
- Continuous corners
- Large surfaces take superellipse corners, a quarter larger so they read at the same size as a round corner.
- The serifed I
- SF Pro's
cv05gives the capital I a serif, soIl1andILineItemnever collide in identifier-heavy prose.
- Layers
- Every CSS file wraps its rules in exactly one layer, in the order
reset,tokens,brand,base,ds,features,overrides. Kit components live indsand product code infeatures, which wins at any specificity, so there is no!importantand no specificity game. - Tokens
- Three tiers, every value written once in
tokens.ts. Per theme: one--ink, the rank alphas, five opaque surfaces, hues, shadows and the only literal colours. Derived ladders and scales come next (--text-1to--text-4,--fill-*,--space-*), then component tokens on component roots (--button-bg). - Naming
- Files are kebab-case, TSX and CSS in pairs. Components are PascalCase with flat compound exports (
Menu,MenuItem). Kit classes areui-component-part, the public slot hook, and booleans are present-or-absent attributes (data-open). - Product code
- Imports only from
@arcadia/ui, lays primitives out and sets their documented component tokens. Semantic and scale tokens only. When a need recurs, add a variant to the kit; one anatomy per concept, so every row is aListRowand every disclosure aCollapsible. - Focus
- One treatment: keyboard focus draws a 2px ring of neutral ink, never the accent. Components choose only its offset, and text fields show focus through their border instead.
- Hierarchy
- Hierarchy comes from rank and medium weight. Placeholders and key hints use
--text-3;--text-4is only for disabled labels and decoration.
Variant vocabulary
The same words mean the same thing on every component, and a variant only reassigns component tokens.
| Prop | Values | Default |
|---|---|---|
variant | primarysecondaryoutlineghosttextdangerinverse | ghost |
size | xssmmdlg | md (IconButton sm) |
shape | roundedpill | rounded |
tone | neutralmutedaccentsuccesswarningdangerplanaskdebug | neutral |
render | An element or a function: swap the element, keep the behaviour. | The part's own |
Two documented exceptions: a Shimmer's tone is a text rank (secondary or tertiary), and a toast's tone is an outcome (info, success, warning or error).