Dwellir design system
Build the site from parts, not paint
The components, tokens and rules behind every Dwellir page. Pick a part, set its variant, arrange it. The look comes with it.
Foundations
Tokens before components
Every component reads the same small set of tokens. Learn these and you can read any screen.
Colour
Name colours by role, never by value. The classes read the identity's tokens, so a sheet that swaps its grounds restyles everything inside it.
The status scale paints uptime and incidents: a fill per tier for bars and tints, at 3:1 on the ground and the card, and an ink for text, at 4.5:1. The uptime bar and the status badges use it.
Type
Ubuntu for display and headings, Roboto for body text, JetBrains Mono for code, at 400 and 700 only. Sizes match stock Tailwind in pixels: text-sm is 14px.
Shape and depth
Controls are pills. Nested corners are concentric: inner radius = outer radius − inset. By day, depth comes from a top light and a long, soft drop. At night a surface rises by lightness and the shadows go: its 1px edge, white at 10%, marks it.
Logo
DwellirLogo draws the wordmark or, with mark="shield", the shield alone. One file serves both themes: on dark grounds the green rim carries the shape, on light ones the fill. Size it with a height class; the link around it names it.
Units
The site's root font size is 62.5%, so 1rem is 10px. The theme scales spacing, type, radii and widths to match: p-4 is 16px and max-w-md is 448px, as in stock Tailwind. Under 900px the root drops to 60% and everything scales with it.
Do
- Use role tokens:
text-muted-foreground,bg-card. - Use
text-accent-inkfor green text; it meets AA on every ground. - Pick from the scales. Add a token to the theme when a design needs a new one.
Don't
- Write raw colours:
bg-[#2e2e2e],text-emerald-500. - Use
text-primaryfor text: the filled green is under AA on white. - Fake weights: only 400 and 700 load, so 500 and 600 render as one of them.
Radius
One corner for every control
Every control reads one theme token, --radius-control. This site sets it to a pill. An app sets it once in its theme, such as 8px, and its buttons, fields, tabs and key caps all follow.
The radius scale
Pick a corner by the role of the surface. Multiline fields and key caps cap the control token at their role's limit.
Set it once per app
The second panel sets --radius-control to 8px on one wrapper. No part changes: the same controls take the new corner. The two pinned buttons keep the legacy shape they pass.
Requests this period.
Requests this period.
Do
- Set
--radius-controlonce in the app theme to square every control. - Pick card, floating-layer and item corners from the scale above.
Don't
- Pass
shapeto a Button in new code. It stays only so existing callers keep their corners. - Add a
rounded-*class to a control at a call site. The part owns its corner. - Give a multiline field the pill corner. It caps at 16px instead.
Surfaces
Which surface?
Where a card sits picks its surface. Grain is the default; the other surfaces each have one job. Glass only earns its cost where the aurora moves behind it.
| Where the card sits | Surface |
|---|---|
| A standalone card on the page ground or the alt sheetFeature cards, pricing cards, FAQ, stat cards | grain |
| A card directly over the aurora, or a panel that floats over the pageThe hero window, cards on sky sheets, the footer islands, navbar panels | glass |
| Glass over moving content where every frame countsAn app pane over the live aurora or a scrolling list: an 8px blur, no saturate | glass-lite |
| The one call to action among glass panesThe footer enquiry card, the lead column of a navbar panel | sky |
| A card inside a card, or dense contentTables, forms, code, ranked rows, lists of links | plain |
| A card on an app panel's groundThe dashboard mock's tool, rail and request cards | raised |
| A read-out inside a cardCalculator sums, the volume summary | well |
| A row in a list inside a card's contentEndpoint and status rows: plain or well, with a corner that follows the card | + inset |
| Any card inside a menu, a popover or a dropdownKeeps its surface and drops the shadow: it belongs to the panel | + flat |
On the page ground
Grain lifts the card off the ground. Glass has nothing to frost and looks flat. Plain is quiet.
Grain
The default. The card colour under a still film grain. By day a top light and a soft drop; at night the card is lighter than the ground.
Glass
Frosted: the aurora glows through it. On a flat ground there is nothing to frost, and it reads as a dull card.
Glass, lite
Glass with an 8px blur and no saturate, for a pane over moving content where every frame counts.
Plain
No texture. For tables, forms and cards inside cards, where grain would be noise.
On the alt sheet
The sheet takes the card colour and its cards take the page ground, so they still stand out. Use the alt sheet to alternate bands down a long page. This band uses space="roomy", the landing page's padding (80px, 128px from lg); pages use the default (56px, 80px) and demos compact.
Grain
The default. The card colour under a still film grain. By day a top light and a soft drop; at night the card is lighter than the ground.
Glass
Frosted: the aurora glows through it. On a flat ground there is nothing to frost, and it reads as a dull card.
Glass, lite
Glass with an 8px blur and no saturate, for a pane over moving content where every frame counts.
Plain
No texture. For tables, forms and cards inside cards, where grain would be noise.
Over the aurora
Here glass belongs: the curtain glows through it. Grain stays readable and solid. At lite motion quality, glass drops its blur and turns almost solid.
Grain
The default. The card colour under a still film grain. By day a top light and a soft drop; at night the card is lighter than the ground.
Glass
Frosted: the aurora glows through it. On a flat ground there is nothing to frost, and it reads as a dull card.
Glass, lite
Glass with an 8px blur and no saturate, for a pane over moving content where every frame counts.
Plain
No texture. For tables, forms and cards inside cards, where grain would be noise.
Cards in the solar wind
On the sky and alt sheets the solar wind blows past the cards and strikes them. The collider prop says when: hover, always or off. Lite motion quality draws fewer lines; still quality and reduced motion draw none. Other marketing apps install the wind with npx shadcn add @dwellir/solar-wind; dense app screens keep the still parts.
collider="hover"
The default. At rest the wind passes behind the card; it strikes the card while the pointer or the focus is on it.
collider="always"
The wind strikes the card at all times, brighter under the pointer. For the one centrepiece of a sheet, such as the hero window.
collider="off"
The wind passes through. For cards inside cards, rows, overlays and panels that do nothing on hover.
The aurora rim
A 1px ring in green and violet. rim="lit" marks the one featured card in a set. rim="hover" marks clickable cards; it also lights on keyboard focus, which the solar wind cannot show.
Developer
For a first production app.
25M
API responses a month
Growth
The featured plan: rim="lit".
150M
API responses a month
Scale
A clickable card: rim="hover".
500M
API responses a month
A piece of the sky
surface="sky" takes the deep ground and grain of the hero and the close. It isolates, so an AuroraCurtain inside it shows over the ground. Use it for the one call to act in a group of glass panes.
Need a dedicated cluster?
surface="sky" rim="lit", with an AuroraCurtain.
Latest guides
surface="sky" rim="hover": the lead column of a navbar panel. In the panel it is also flat.
Flat inside a panel
A card in a menu, a popover or a dropdown is part of the panel. Set flat: it keeps its surface and drops its shadow, so nothing hangs past the panel's edge.
Latest guides
surface="sky" flat: no shadow past the panel.
- Docs
- Blog
- Gas tracker
Raised cards on an app panel
An app screen, such as the dashboard mock, sets its cards on the panel's ground. surface="raised" is plain with upstream's small shadow.
Request console
surface="raised": plain, with a small shadow.
Usage this month
surface="raised": plain, with a small shadow.
Wells and rows
Inside a card, surface="well" sets a read-out apart with a muted fill. size="xs" makes compact rows for a ranked list.
Unlimited Node · 100 RPS
A card with a well for the sums.
Same traffic billed per response$520/month
You save$41/month
- 1DwellirGrowth plan$299
- 2Provider BBusiness plan$499
- 3Provider CPremium plan + overage$772
Inset rows
A bordered row inside a card's content sets inset on a plain or well card. Its corner (rounded-inset) is the outer corner less the 1px edge and 16px, the padding of a size="xs" card, and never under 12px. This example's card pads 24px, and at this site's 18px card the 12px floor sets the corner.
Endpoints
Each row is a plain inset card. Its corner follows the outer card's.
- Europeeu.example.dwellir.com38 ms
- Asiaasia.example.dwellir.com112 ms
- Americasus.example.dwellir.com96 ms
Hairlines
--border-hairline is 0.5px on a screen with 2 or more device pixels per CSS pixel, and 1px below that. Separator and the PageHeader border take it. In an app, draw your own line with border-b-(length:--border-hairline) or gap-(--border-hairline).
Latency by region
Europe38 ms
Asia112 ms
Americas96 ms
Clickable cards
asChild renders the card as its child: a link to a post, or a button. The focus outline and the rim show on keyboard focus. For one choice from a set, use ChoiceGroup tiles.
Read the guide
Card asChild with an anchor: one link, one focus stop, the rim on hover and focus.
Open the changelog
Card asChild with an anchor: one link, one focus stop, the rim on hover and focus.
A bento frame
size="flush" drops the card's own padding, for one grain frame whose cells carry theirs and share hairline edges, as the homepage's numbers do. It clips its cells, so its rim sits just inside the border: lit, and on hover.
A wide cell carries its own padding.
A narrow cell shares its edge.
A wide cell carries its own padding.
A narrow cell shares its edge.
A wide cell carries its own padding.
A narrow cell shares its edge.
Do
- Use grain for every standalone card on the ground and the alt sheet, the FAQ too.
- Use glass only over the aurora: the hero, the sky sheets, the footer islands.
- Use plain for dense content and for a card inside a card.
- Set flat on every card inside a menu, a popover or a dropdown.
- Light the rim on one card per set at most.
Don't
- Put glass on a flat ground: the blur costs frame time and shows nothing.
- Stack grain on grain: nest a plain card inside a grain card.
- Let a card in a menu cast a shadow past the panel.
- Add borders, shadows or radii to a Card with className. Pick a surface.
- Light every rim: when everything is featured, nothing is.
Actions and labels
One loud action, many quiet ones
Every control is a pill. The primary green is for the one action that moves the reader forward.
Button
Eight variants, five sizes, four icon sizes and a row size; shape rounded for app UI. One primary per view; the rest step down. Link-ink is for the links beside a view's one green action. Destructive is for an action that deletes. Visual is for a control its children draw, such as a video's thumbnail. A link or an action is a Button, never a Badge.
Toggle
One on/off control. On, it takes the accent tint, as a pressed outline Button does. Visual leaves the look to its children, such as a chart's bar. Several that belong together are a ToggleGroup (see Forms).
Badge
Identity metadata uses neutral: ecosystem, network, plan tier and role. Keep colour for state. The status tones describe the uptime scale. The text meets AA on its own tint. A badge never starts with a status dot: the word and the variant give the state. A badge that names a chain starts with the chain's icon.
Do
- Write the action as a verb: “Create an account”, not “Submit”.
- Give icon buttons an
aria-labeland hide the icon. - Use
asChildto give a link the button's look; keep its href. - Let a press answer a finger: on a touch screen a held button shrinks to 97%, as a finger never hovers. Reduced motion keeps it still.
- Put the chain's icon before its name wherever a label names a chain: a chip, badge, option, list, table or menu. Use
ChainIconwith the catalog's icon, at a fixed size; the icon is decorative.
Don't
- Put two primary buttons side by side.
- Change a button's padding or height with className: pick a size.
- Use a badge as a button. If it does something, it is a Button.
- Start a chip, badge or pill with a status dot. Say the state in the label, or pick a variant.
Forms
Fields that explain themselves
Pill fields with a 3:1 edge, labels above, errors in words. Shown on the alt sheet, where the cards take the page ground.
Fields
Input, Label and Select. Every field has a visible label. A search field takes icon="start".
Enter a number, such as 500.
Choices
ChoiceGroup for one of a few options (segmented, pills, or tiles with a line each): native radios, so the arrow keys move the choice; disabled locks every radio. ToggleGroup for on/off filters, in the same looks. variant="bare" leaves the look to each item, such as a badge (see Overlays, Popover, bare). default and outline are Toggle's looks: they take a size, and join into one bar unless spacing parts them. visual leaves the whole look to each item's children, such as a chart's bars, which read the item's data-state. Checkbox for an on/off choice with a label, md or lg in a settings row. Slider for a range, also orientation="vertical".
Field
The frame round a control: label, description and error. orientation is vertical, horizontal or responsive (a row from the FieldGroup's md width). data-invalid turns the label red; FieldError says why, from children or react-hook-form errors.
Textarea, Switch and RadioGroup
Textarea has the Input's look: sizing="content" grows with the text, fixed keeps its rows. Switch for a setting that applies at once, size default or sm. RadioGroup for one choice from a list, orientation vertical or horizontal, items md or lg; ChoiceGroup covers pills and tiles. Fields take the calm input edge. A checkbox, a radio and an off switch track have no text inside, so their edge is their only cue: they take input-strong (3:1).
Form, with react-hook-form and zod
useForm({ resolver: zodResolver(schema) }). FormField, FormItem, FormControl and FormMessage wire the ids and errors for you. Field with a Controller does the same by hand: pass fieldState.error to FieldError. Submit it empty to see the errors.
Submitted values
Input group
Addons round one field. align is inline-start, inline-end, block-start or block-end. The group draws the Input's fill, edge and focus ring; aria-invalid and disabled on the control reach the whole group. A group with rows or a text area takes the Textarea's corners.
Enter a domain, such as app.example.com.
When to use which
Input with icon="start" for a plain search field. InputGroup when the field needs a prefix, a key hint, a button or a row of filters. Give the control a Label or an aria-label; an addon's text does not name it.
Composer, size="lg"
A 56px field with 18px text and rounded-3xl corners; addons, buttons and text step up with it, and no class overrides it. Its focus ring lies on the edge, not 2px outside it, so a field this large shows one frame. Filters are outline buttons with aria-pressed; the hint is a Kbd with size="lg". surface="glass" frosts the field for a composer over the aurora, as the dashboard's home search.
What do you want to query?
Kbd and Spinner
Kbd names a key; KbdGroup holds keys pressed together. Spinner shows work in progress: size is sm, md or lg, and tone is current, muted or accent. A Button with pending shows a Spinner, turns disabled and sets aria-busy; an icon button swaps its icon for the Spinner. A pending link (asChild) ignores a click and Enter.
Do
- Pair every field with a Label (
htmlFor= the field's id). - Mark errors with
aria-invalidand say how to fix them. - Use ChoiceGroup for one of two to five options; Select for more.
Don't
- Use a placeholder as the label: it disappears as the reader types.
- Use colour alone for an error: write the message.
- Shrink field text below 16px on a touch screen, an iPad too: iOS zooms in on focus. The fields here drop to 14px only for a mouse or trackpad.
App controls
Clear choices, reachable actions
Vertical native radios show selection with a dot. Under a finger every control takes a 44 px tap; hit areas meet halfway in a gap.
Touch targets
Under a coarse pointer, phones and tablets, the controls below take a tap of at least 44 by 44 px; REGISTRY.md lists the few that do not. Hit areas meet halfway in a gap and never reach over a neighbour. A mouse sees every control at its base size. Lay out with gap-*: a part reads its room from the nearest gap.
- Input, InputGroup, Select
- A field is wide, so its box grows to 44px.
- Button, Toggle, ToggleGroup, ChoiceGroup, Select sm
- The box keeps its size and an invisible hit area reaches into half the gap on each side. Where the box and the gap make less than 44px, the box grows by the difference.
- ToggleGroup, segmented ChoiceGroup
- One line of items: the gap is gap-x, so the room above and below is the parent’s. A segmented item takes its room from the track’s padding.
- Joined ToggleGroup (spacing 0)
- Each hit area spans its own box: neighbours meet on the seam.
- Calendar
- The days touch, so each column asks for 44px and gives way to 36px, its mouse size, in a narrow container.
- Text links, visual variants
- A link keeps its line and a visual control takes its children’s size; neither grows.
Vertical ChoiceGroup
Set orientation="vertical" for a list. Each item accepts description and disabled. Group disabled locks every item. Arrow keys skip disabled choices.
Shared select trigger
Use selectTriggerVariants on a native button inside DropdownMenuTrigger or PopoverTrigger. The recipe adds SelectTrigger's touch target; pass touch: false to opt out. Both sizes share SelectTrigger's fill, edge, focus, disabled and invalid states. Add a decorative chevron as a child.
Copy fields
One copy control for short values, URLs, keys, commands and prompts. Click anywhere on the field or use its copy button.
Copy field inside an input
A read-only input with an inline secondary copy button. The whole field is the button: hover fills it, press fills it further, Tab rings it, and Enter or Space copies. A drag selects text and does not copy. Copy success keeps the button name and announces Copied.
Inline chip in context
The chip centres its one line on its copy and reveal buttons, in a table cell, in 14px and 16px running text and in a stacked row.
| Name | API key |
|---|---|
| Demo key | fdc22b86-3e38-4eb1-8395 |
| Masked key | •••••••••••••••• |
In your terminal, run dwellir auth login
In your terminal, run dwellir auth login
- Endpoint
https://api.example.com- Key
••••••••••••••••
Inline chip
variant=inline. Fits beside running text and truncates within its container.
npm install @dwellir/sdkSingle-line field
variant=field. A read-only input with an associated label and an inline copy button.
Masked value
masked. Reveal and copy work independently. Copy always uses the full value.
Without a label
Use name to give the button a useful accessible name.
Multi-line read-out
variant=multiline. Fixed height with internal scrolling. Tab into the text to scroll with the keyboard.
Connect this project to a Dwellir RPC endpoint.
Read the endpoint URL from the environment.
Keep API keys on the server.
Report connection errors in the interface.
Before sending a request:
1. Check the selected network.
2. Check the method parameters.
3. Set a request timeout.
After receiving a response:
1. Check the response status.
2. Parse the result.
3. Show the latest block number.Disabled
disabled. Neither the field nor its buttons can copy or reveal.
Action lists
Full-width action rows for tool and integration cards. Icons stay neutral. The trailing mark explains each action.
Integration actions
Compose ActionListItem with a link, copy action or button. Long labels wrap on phones.
Pending, done and disabled
pending blocks activation and announces progress. done adds a check. Leading icons are slots.
- In progress
- Done
Navigation and disclosure
Show one thing at a time
Tabs switch between views of the same kind. The accordion folds answers away until the reader asks; a collapsible folds away one block.
Tabs
A pill track; the active tab takes the ground colour under the aurora wash, with the aurora rim for its border (aurora-current, as on the sidebar's current row). With long labels, variant="stretch" shares a phone's width between the tabs, icon over label (narrow the window to see it). variant="stack" is a column of rich rows beside a preview, as in the homepage's Hyperliquid products. It has no track: place it in a card, and set orientation="vertical" on Tabs, so Up and Down move between the rows. variant="line" underlines the active tab on a rule, as in an app's page header. It stays one row and scrolls sideways when narrow, and it scrolls the active tab into view. Give the triggers flex-1 justify-center and they share the full row. When the tabs stand for states, a tone colours the active one.
A flat monthly price for 25 to 1,000 RPS, from $119 a month. No credits and no overages.
Dedicated node clusters for high volume.
Dedicated node clusters for high volume.
Successful responses this session.
Accordion
For questions and answers. The first item may start open. With forceMount on AccordionContent, closed answers stay in the HTML for search engines.
debug_traceTransaction costs one credit too, on the paid plans. Links and code in an answer take the theme from AccordionContent.Collapsible
One block that opens and closes. The plain collapsible has no look: its trigger is a Button through asChild. variant="card" is a card whose header row opens it, for reference entries. With forceMount on CollapsibleContent, closed text stays in the HTML and shows when script is off.
From 20 RPS on the free plan to 5,000 RPS, with bursts to 10,000.
An app shows WTIOIL; the Info and trading APIs take the canonical coin, xyz:CL.
Spot markets go by an @index or a pair label; HIP-3 perpetuals go by dex and symbol.
Do
- Keep tab labels to one or two words.
- Write accordion triggers as the reader's question.
- Put forceMount on content that search engines and readers without script need.
Don't
- Use tabs for steps in a sequence: the reader cannot see what comes next.
- Hide the one fact a reader needs to decide in a closed accordion.
App shell
A sidebar for app screens
The navigation of the API platform dashboard: it collapses to icons on a desktop and opens as a sheet on a phone.
Sidebar
shadcn's Sidebar family on the registry sheet, tooltip, separator, input, skeleton and button. SidebarProvider holds the state; SidebarTrigger, the rail and Cmd+B or Ctrl+B toggle it. Collapsed to icons, each row's tooltip names it. A hovered row takes the muted fill; the current row takes the aurora wash and rim (aurora-current, as on a selected tab) and a heavier icon stroke. Here the sidebar is position="contained" in a frame; the app shell keeps the default, fixed. Hover a row for its More action. On a phone, mobileSurface="plain" gives the sheet the card fill without grain, for app screens.
Do
- Give every row an icon and a tooltip, so it reads when collapsed.
- Mark the current page with isActive and aria-current="page".
Don't
- Put a status dot on a row or its badge: say the state in words.
- Use the sidebar on marketing pages: they keep the site navbar.
Overlays
Layers over the page
Open each one. They sit over the navbar and the cookie notice, trap focus where they should, and close on Escape.
Dialog
A short task that blocks the page: confirm, name, create. Placed in the corner, a compact one, such as the cookie preferences. DialogFooter showCloseButton closes a dialog that only informs. surface="plain" drops the grain, for app screens.
Sheet
Longer settings beside the page. Slides in from an edge: right by default, or left, top or bottom. surface="plain" drops the grain, for app screens.
Long content
Content taller than the screen goes in DialogBody, SheetBody or AlertDialogBody. The body scrolls with a quiet bar inside the panel's straight edge; the title and the footer's action stay in view, also on a short phone.
Dropdown menu
Actions on one thing: an account, a key, a row. Checkbox items toggle; radio items pick one of a set. A sub trigger opens a submenu; inset lines an item up with the icons.
Dropdown menu, compact
The sm size, as in an app's header: a tighter menu. The chosen item is tinted and checked on the right.
Popover
Extra detail or a small form, anchored to its trigger. PopoverHeader holds its title and description.
Popover, bare
A row of chips under a field, with no surface of its own. The arrow keys move between the chips; a choice or Escape closes the row.
Tooltip
A short hint for an icon or a term. Never the only copy. Primary is the brand green; sm fits a one-word hint. A disabled button takes no pointer or focus, so its tooltip goes on a focusable span around it (the last one).
Do
- Give every dialog and sheet a title; it names the layer for screen readers.
- Put the safe action on the left and the main action on the right.
- Wrap content that can outgrow a phone in the body part, so the footer's action stays in view.
- Open one on a phone: the panel takes the focus, not its first field, so the keyboard waits for a tap. Its edges clear the status bar, the notch and the home indicator, and its close button takes a 44px tap.
Don't
- Open a dialog on page load.
- Put anything in a tooltip that a touch reader also needs: there is no hover.
Command and dates
Find anything, pick a period
The app parts: a command palette for the dashboard's Cmd+K, and calendars for usage periods and log windows.
Command
A search field over a list that filters as you type. The arrow keys move the highlight and Enter runs the item. surface picks the panel: plain on the page or in a card, bare inside a dialog or a popover.
Calendar
react-day-picker 10 in the theme. It draws no surface: a plain card on the page, a popover in a form. The month buttons take a Button variant through buttonVariant. Today is green and bold; a pick is the primary green; a range fills with the accent tint.
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
| Su | Mo | Tu | We | Th | Fr | Sa | |
|---|---|---|---|---|---|---|---|
| 40 | |||||||
| 41 | |||||||
| 42 | |||||||
| 43 | |||||||
| 44 |
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
Date picker
A Button that opens a Calendar in a Popover. DatePicker closes on a pick; DateRangePicker shows two months and stays open until Escape or a click outside. The trigger takes the Button's variant, size and shape.
Do
- Give a palette item a
CommandShortcutonly when the shortcut works outside the palette. - Disable the days a reader cannot pick, such as future days for usage.
Don't
- Use a Command for two to five options: a ChoiceGroup or a Select shows them all.
- Ask for a date a reader knows by heart, such as a birthday, with a calendar.
App controls
Option picker
Search a grouped list. Choose one value, or keep several as removable chips inside the field.
Choose a resource.
The field is the search box. ArrowDown opens the list. Each edit highlights the first match. Enter selects. In single mode, typing starts a fresh query; Escape restores the chosen label. The first Escape closes the list; the next closes its Dialog. In multiple mode, Backspace removes the last selection when search is empty. Each chip has a named remove button. Hidden chips remain selected and can be found through search. Clear removes every selection. Options accept an icon slot for a logo or icon, a group, search keywords, and disabled. Use defaultValue for local state, or value and onValueChange for controlled state. Set level for chain, network, or endpoint indentation. Set maxSelections for a live count and limit. Set summary={false} to hide the count and Clear row. The action slot receives open and onOpenChange. The logo slot accepts any node, including the registry ChainIcon. Set maxVisibleOptions to cap results; the default is 150.
Data
Dense, calm, scannable
Tables carry the facts; separators and skeletons keep the rhythm while data loads, and an empty view says what will be there.
Table
On a plain card. The wrapper scrolls sideways, so a wide table never widens the page.
| Network | Family | Protocols | Network type |
|---|---|---|---|
| EVM | HTTPS, WSS | Mainnet | |
| Substrate | HTTPS, WSS | Mainnet | |
| Cosmos | HTTPS | Mainnet | |
| Move | HTTPS, gRPC | Mainnet |
Uptime bar
A green bar per period, with a slice at its foot as tall as the downtime (at least 5%), in the tier's colour: clean from 99.99%, minor from 95%, major from 80%, down below. A period without data is grey. The bars are decorative; the strip is one slider, so the pointer, the arrow keys, Home and End read a period, and screen readers hear its date and uptime. Up and Down step as Right and Left do. A period may carry detail lines: one tooltip follows the active period, and the slider reads the lines too. A lag marker caps the bar.
Empty
In place of data the reader cannot see yet. The default is plain and md, as upstream. card stands in for content, dashed outlines where it will appear, xs with align="start" is a note in a list of results. EmptyMedia holds an icon, bare or on a tile (icon); EmptyTitle asChild makes the title a heading. Give a live result role="status".
No API keys yet
Scroll area
Content that scrolls inside a fixed height; it takes keyboard focus, so the arrow keys scroll it. The bar shows on hover; type="auto" shows it while the content overflows. overscroll="contain" keeps the wheel in a panel at its end, as in the hero dashboard.
Selectable rows, compact, quiet headers
density="compact" sets 10px cell padding and 36px header rows, for app UI. head="quiet" gives sentence-case, medium-weight, muted headers with normal tracking, for app UI; the default head="eyebrow" is the website look. A Checkbox column takes no right padding and sits on the text line. A row whose disclosure is open (aria-expanded) keeps the hover tint.
| Key | Created | Requests, 30 days | Details | |
|---|---|---|---|---|
| indexer-prod | 2 Oct 2026 | 1.2M | ||
| Allowed origins: Any origin | ||||
| wallet-staging | 14 Sep 2026 | 86k | ||
Row headers
Key facts, one per row. TableHead scope="row" labels the row; long values wrap with whitespace-normal.
| Founded | 2021, in Uppsala, Sweden |
|---|---|
| Core offering | HTTP and WebSocket RPC access to 150+ networks through one API key |
| Uptime SLA | 99.99% on production endpoints |
Code block
Mono on the ground colour, with a copy button. Long lines scroll sideways.
grpcurl -proto v3.proto \
-H "x-api-key: $DWELLIR_API_KEY" \
"$HYPERLIQUID_GRPC_ENDPOINT" listCode block, wrapped
lines="wrap" for one-line payloads, which wrap instead of scrolling.
{"coin": "BTC", "blockNumber": "1140007989", "bids": [{"px": "78497", "sz": "2.59056", "n": 16}]}Code block, one-line command
copy="block" makes the whole block the copy control: hover tints it, a click, Enter or Space copies, and the icon shows the copied state. A drag still selects text. Use it for one-line commands; add lines="wrap" for a long one.
npx skills add dwellir-public/hyperliquid-skillsCode block with a title
title puts a row over the code: its language or file name. size="lg" keeps code in running text readable on a phone. tokens="shiki" colours Shiki output with two themes (defaultColor: false) by the site theme, as in the blog articles.
const block = await client.getBlockNumber();
console.log(block);Skeleton
The shape of the content that is on its way. SkeletonRows holds a list or table that has no layout yet: it takes a label for screen readers, the row count, and the row height (sm, default, lg). LoadingSplash covers a whole screen or region when even rows presume too much: it waits out its delay first, so a fast load never flashes it.
Separator
A hairline between groups. Decorative by default.
Do
- Align numbers to the right and use the same unit in a column.
- Put tables on a plain card: grain under small text is noise.
Don't
- Use a table for layout.
- Show a spinner where a skeleton can show the shape.
App data
Charts and tables for app screens
Usage over time and lists of records, as on the API platform dashboard. Both sit on plain cards and take their colours from the theme.
Chart
shadcn's Recharts wrapper, on plain cards. A ChartConfig names each series and picks its colour, chart-1 to chart-5; the chart sets --color-<key> for the series to read. Hover or focus a chart for the tooltip: indicator is dot, line or dashed. Give the container a height, as here, or keep its 16:9 frame. Name each chart with aria-labelledby on its title and summarise its data in description; a chain series sets its icon. chartConfigForSeries assigns distinct series colours for a set of names. missing defaults to gap, so a bucket with no reading breaks the line; pass missing="zero" only for a range you measured. chartDateAxisProps steps date labels to the width useChartWidth measures on the container, so they never collide, and the quiet preset (QUIET_GRID_PROPS, QUIET_SERIES_PROPS) keeps horizontal guides only and dots on isolated or active points. Under a chart, ChartLegendList aligns its rows on phones, highlights on hover and focus, and folds a long list into +N more.
Requests per day
Area, stacked. Tooltip indicator="line".
Latency
Line. Tooltip indicator="dashed".
Requests by chain (thousands)
Bar, stacked, with a legend: all five series colours.
Requests by chain, measured
missing="zero", the quiet preset, and a stepped date axis.
Requests by chain, with no reading
The default, missing="gap": Base breaks on 4 and 5 Oct.
- EthereumMainnet1.8M
- BaseMainnet, no reading 4 to 5 Oct882K
Data table
A TanStack Table v9 table on the Table part, on a plain card. A string header gets a sort button; enableSorting: false turns it off. selectable adds the checkbox column, columnToggle the columns menu, toolbar the controls before it, and pageSize the pages (0 shows every row). options passes any other TanStack option, such as manualPagination for server data. head="quiet" passes the Table's quiet headers, sort buttons included.
| Created | Allowed origins | ||||
|---|---|---|---|---|---|
| indexer-prod | 2 Oct 2026 | 1,204,000 | Any origin | Active | |
| wallet-staging | 14 Sep 2026 | 86,000 | app.example.com | Active | |
| bot-arbitrage | 9 Sep 2026 | 3,410,000 | Any origin | Active | |
| explorer-backfill | 28 Aug 2026 | 912,000 | Any origin | Revoked | |
| dashboard-demo | 21 Aug 2026 | 4,100 | demo.example.com | Active |
0 of 8 rows selected
Data table, loading
loading shows skeleton rows in the table's shape and hides the pages. density="compact" is the Table's app density.
| Created | Allowed origins | |||
|---|---|---|---|---|
Data table, empty
With no rows, the table shows an Empty note. empty sets its content.
| Created | Allowed origins | |||
|---|---|---|---|---|
No API keys yet Create a key to start sending requests. | ||||
Do
- Pick series colours from chart-1 to chart-5, in order.
- Name every series in the config, so the tooltip and legend say what a colour means.
Don't
- Paint a series with a raw colour or an aurora utility.
- Show more than five series in one chart: split it or group the rest.
Responsive tables
Keep each record together
Opt in to stacked records in a narrow container, or pin a comparison table’s first column. Existing tables keep their current layout.
Data table, stacked below 3xl
Set stack="auto". The default stackBelow="3xl" means a container narrower than 768px, even inside a desktop rail or dialog. stack="never" is the default. Sorting, selection, pages, hidden columns and expansion share one row model. Name each navigation landmark with paginationLabel when a page has several tables.
| Details | |||||
|---|---|---|---|---|---|
Production indexer | 1,204,000 | Operations | indexer | ||
Wallet staging | 86,000 | Product | wallet |
0 of 3 rows selected
A narrow container on a wide screen
This container uses stackBelow="xl" (576px). Supported container tokens: lg (512px), xl (576px), 2xl (672px), 3xl (768px), and 4xl (896px). The wide layout starts at the chosen size.
| Details | |||||
|---|---|---|---|---|---|
Production indexer | 1,204,000 | Operations | indexer | ||
Wallet staging | 86,000 | Product | wallet |
0 of 3 rows selected
Column roles and plain tables
Use column meta.stackRole: title for the identity, action for row controls, and hidden for desktop-only fields. Set meta.stackLabel for functional headers. Other fields use the header string or column ID. Keep the identity column visible with enableHiding: false. Plain TableCell takes label and stackRole directly.
| Project | Owner | Actions |
|---|---|---|
Production indexer | Operations |
Sticky first column, four grounds
Set stickyFirstColumn and match surface to the ground: card (default), background, muted inside a card, or glass over the aurora. The edge appears only after horizontal scrolling. Row hover and selection keep an opaque fill.
| Included | Free | Developer | Growth | Scale |
|---|---|---|---|---|
| Monthly responses | 1 million | 25 million | 150 million | 500 million |
| Requests per second | 25 | 100 | 500 | 1,000 |
| Included | Free | Developer | Growth | Scale |
|---|---|---|---|---|
| Monthly responses | 1 million | 25 million | 150 million | 500 million |
| Requests per second | 25 | 100 | 500 | 1,000 |
| Included | Free | Developer | Growth | Scale |
|---|---|---|---|---|
| Monthly responses | 1 million | 25 million | 150 million | 500 million |
| Requests per second | 25 | 100 | 500 | 1,000 |
| Included | Free | Developer | Growth | Scale |
|---|---|---|---|---|
| Monthly responses | 1 million | 25 million | 150 million | 500 million |
| Requests per second | 25 | 100 | 500 | 1,000 |
Loading outside the scroller
Stacked and sticky data tables place loading and empty states outside the scroller. statePlacement="outside" opts in without changing layout. Skeletons match the visible column count, including selection.
Empty content stays on screen
The empty slot can include a recovery action. Plain Table accepts state="loading" or state="empty", visibleColumns, loadingRows, and empty. With no new props, existing states stay unchanged.
Stats and page header
Figures and the title row of a page
One read-out for every metric, and one header for every app page. The dashboard's stat cards, usage rows and top bar, and the status page's uptime figures, all read from these two parts.
Stat
A label, a figure in tabular numbers, and quiet meta. StatGroup answers to its own width: a compact list in a narrow card, a row in a wide one. Colour marks a state only: limited requests take the warning tone, the rest stay neutral. A stat carries no surface; it sits on a plain card here, as in the dashboard.
Inline stats, states, and the count-up
layout="inline" reads as a list: label left, figure right. The same part shows a skeleton while it loads and a dash when a figure is not available. animate counts a numeric value up as it changes, and skips the count under reduced motion; screen readers hear the final figure once. A ready-made string takes a unit, as an uptime figure does.
Uptime status tones
Each figure uses its status tier's ink, so it matches the uptime bar.
Page header
A muted icon slot, the title with a quiet description, secondary readings beside them, and the page's actions; a tabs or toolbar row goes under it all as children. sticky keeps it at the top of its scroll container: clear at rest, frosted glass with a hairline once the page scrolls under it. The title truncates on a phone and the actions shrink before they cover it. size="lg" is the same part as a page lead, below the frame.
Usage
Requests across every API key
Scroll the overview frame: the header stays at the top and frosts over the rows under it.
Scroll the overview frame: the header stays at the top and frosts over the rows under it.
Scroll the overview frame: the header stays at the top and frosts over the rows under it.
Scroll the overview frame: the header stays at the top and frosts over the rows under it.
Scroll the overview frame: the header stays at the top and frosts over the rows under it.
Scroll the overview frame: the header stays at the top and frosts over the rows under it.
Scroll the overview frame: the header stays at the top and frosts over the rows under it.
Scroll the overview frame: the header stays at the top and frosts over the rows under it.
Ethereum mainnet
Archive node in the eu-north region, with debug and trace methods.
Do
- Let StatGroup answer to the card's width, not the viewport's.
- Pick a tone only when the figure itself is the news: a limit hit, an error rate.
- Give a delta its tone apart from its arrow: up can be bad news.
- Head a group outside the part, or name it with aria-label.
Don't
- Paint every figure green: neutral is the default, colour is the state.
- Put the only copy of important text in a hint tooltip.
- Wrap a stat in its own card inside a group: one card holds the group.
- Build a page's title row by hand next to a PageHeader.
Feedback
Tell the reader what happened
Messages in the page, questions that block it, progress and toasts. The tones reuse the theme's inks: green for done, orange for a warning, red for a failure.
Alert
An inline message about the content around it. It stays until the cause goes away. The theme has no info colour: an info message is default with an info icon.
Requests slow down at the limit. Upgrade to keep full speed.
Alert dialog
A question the reader must answer before going on. It has no close button and does not close on a click outside. Cancel takes the focus. AlertDialogMedia puts an icon over the title. surface="plain" drops the grain, for app screens.
Progress
How far a task or a quota has come. size sets the height; variant warns near a limit or shows a failure. A value past the maximum shows a full bar.
Avatar
A person: their photo, or their initials while it loads or when there is none. Give the image the person's name as alt. AvatarBadge marks a corner; say what it means in text nearby. AvatarGroup overlaps a team and ends with AvatarGroupCount.
Toast (sonner)
The result of an action, in the corner for a few seconds. Mount <Toaster /> once, then call toast() from sonner anywhere. The promise toast fails every second time.
Do
- Say what happened and what to do next, in the title and one sentence.
- Use a toast for the result of an action; use an alert for a state that stays.
Don't
- Put the only copy of an error in a toast: it closes on its own.
- Ask with an alert dialog when Undo would do.
Brand blocks
The parts that make it Dwellir
Pages are built from these. They carry the sheets, the grain and the aurora, so a new page looks like the homepage without new CSS.
Section
components/brand/section.tsx
One band of a page: tone="ground", "alt" or "sky", plus aurora for a still curtain. Keeps data-au-band, so the solar wind shows inside the sheets.
SectionHeading
components/brand/section-heading.tsx
Eyebrow, title and lede. size="display" with as="h1" once per page; the default is a section h2.
PageHero
components/brand/page-hero.tsx
The opening of a page: the h1 on a sky sheet, with a lede, actions, a visual and the aurora. layout is center, split or lead. See the samples.
Container
components/brand/container.tsx
The centred column: page (160rem), narrow (137.5rem) or prose.
Prose
components/brand/prose.tsx
Long text from plain HTML: headings, paragraphs, lists, links, code. In a max-w-3xl column. size="lg" for text read from start to end. Tables go in the Table part.
AuroraCurtain
components/brand/aurora-curtain.tsx
A still CSS curtain for places without the hero canvas. No frame cost. tint takes a CSS colour for the lower rays, such as a chain's icon colour.
IconChip
components/brand/icon-chip.tsx
A tinted square for a card's icon. tone is one of the four aurora hues; a grid of cards cycles iconChipTone(index), a lone chip stays green. tone="neutral" is a grey chip for icons that carry no meaning, as on app screens. nested takes the smallest radius, for a chip inside a link's hover fill, so its corners stay concentric with the fill's.
grain · grain-sky
styles/design-system.css
Utilities: the card grain (overlay blend) and the sky grain.
rim · rim-hover · glass
styles/design-system.css
Utilities behind Card's rim and surface="glass". Reach for the Card props first. Every pane shares one blur, --au-glass-blur: glass is 80% solid, the navbar pill and the hero window 70%.
Monthly billing, no lock-in
Every plan bills monthly with no long-term commitment. See pricing for the plans, and call eth_chainId to check an endpoint.
What you get
- One API key for 150+ networks
- Trace and debug APIs on every paid plan
About the role
You will build the software that runs our nodes, from monitoring to the tools that deploy new chains.
- Talk to the team
- Solve a short task
- No tint: the palette
- tint="var(--au-dot-4)"
- fade="left", on the right
- fade="right", on the left
- fade="both", in the middle
Do
- Alternate ground and alt bands; open and close a page with a sky sheet.
- Keep wrappers around a Section transparent, so the wind shows through.
Don't
- Put two alt sheets next to each other.
- Paint a background on a wrapper above a sheet: it hides the wind.
A sky sheet
Ship UI without the clean-up
Section tone="sky" with aurora, a centred SectionHeading and one primary action: the shape of a closing call to action.
Aurora canvas
The moving curtain, for any app
AuroraCanvas draws the hero's curtain on one canvas, in a worker, at 24 frames a second. It needs no solar wind. Until the canvas draws, a CSS still of the same curtain holds its place.
Live and still
The canvas fills its nearest positioned parent. It pauses off screen and in a hidden tab, and draws one still frame for reduced motion. The still on the right is what shows before JavaScript runs.
Do
- Use
AuroraCanvasfor one moving curtain: a dashboard header or a page backdrop. - Use the still
AuroraCurtainwhere many curtains share a screen. It costs no frame time. - Pass
quietwhere text sits on the curtain, so the light thins out there.
Don't
- Put a moving curtain behind dense tables or forms: it pulls the eye from the data.
- Install
solar-windfor the curtain alone. The wind is for marketing pages.
Page hero
One hero for every page
PageHero opens a page: the h1 on a sky sheet, with a lede, the actions, a visual and the aurora. Pick a layout; the hero keeps the title cap and stacks the actions on phones, so nothing moves when the fonts load.
The samples below use as="h2", as this page has its own h1. On a page, pass the live aurora as backdrop.
layout: center
Centred: a content page
The default without a visual: about, contact, the legal pages, the blog archive.
layout: split · width: narrow · space: tall
Split: a product page.
The accent, a second line.
The default with a visual: copy and visual in equal columns from lg, the visual under the copy below.
A visual
Beside the copy from lg.
100 RPS
layout: lead
Lead: the Hyperliquid pagesThe accent, a smaller line
The copy leads in 7 of 12 columns at the top; the visual takes 5 and centres on the copy.
A visual
In 5 of 12 columns.
100 RPS
Do
- Use one PageHero per page, with the h1 as its title.
- Put the promise in accent: it reads as the second line of the h1.
- Give it two actions at most: the main one first.
Don't
- Build a hero from a Section and a SectionHeading by hand.
- Put a visual in a centred hero: use split or lead.
How to build with it
Four rules
For engineers and their agents. The full guide is in CLAUDE.md under “Design system”.
- 01
Build from the parts
Compose pages from
components/uiandcomponents/brand. Arrange them with layout classes on plain elements:grid,gap-6,md:grid-cols-3. - 02
Never restyle a part
Give a part layout classes only (
w-full,mt-6). Its colour, type, padding and shape come from its variants. No new styled-components, no raw colours, nop-[13px]. - 03
Run the linter
npm run lint:dschecks every design-system file. Its errors say what to use instead; fix them before you commit. CI runs it on every pull request. - 04
Change a part and its base styles
Add variants to the part's
cva. Shared bases live instyles/design-system-parts.css. Keep overrides visible tocn(). Update the registry theme, then runnpm run registry:build.
Rune icons
Dwellir's icon set: 176 icons cut as runes. They replace Tabler, lucide and react-icons. Install them with @dwellir/rune-icons. They are decorative by default.
Navigation and layout
37 icons, in components/brand/rune-icons/navigation.tsx.
- RuneHomeHome: Othala, the homestead.
- RuneArrowLeftGo back, or move left: Tiwaz, the arrow rune, laid down.
- RuneArrowRightGo on, or move right: Tiwaz, the arrow rune, laid down.
- RuneArrowUpMove up, or sort ascending: Tiwaz, the arrow rune.
- RuneArrowDownMove down, or sort descending: Tiwaz, turned over.
- RuneArrowUpDownSortable, not sorted yet: one stave with both Tiwaz heads.
- RuneArrowUpRightOpen or go to a destination: an arrow cut up and out.
- RuneArrowDownRightFall or go down and out: an arrow cut down and out.
- RuneChevronUpOpen upward, or collapse: half a Gebo.
- RuneChevronDownOpen downward, or expand: half a Gebo.
- RuneChevronLeftPrevious: half a Gebo, pointing back.
- RuneChevronRightNext, or a link onward: half a Gebo, pointing on.
- RuneChevronsUpScroll or jump up: two chevrons.
- RuneChevronsDownScroll or jump down: two chevrons.
- RuneChevronsLeftJump back several steps: two chevrons.
- RuneChevronsRightJump on several steps: two chevrons.
- RuneChevronFirstThe first page: a chevron against a stave.
- RuneChevronLastThe last page: a chevron against a stave.
- RuneSelectorA select or combobox that opens a list: a chevron up over a chevron down.
- RuneSidebarShow or hide the sidebar: a frame with a side panel.
- RuneSidebarCollapseCollapse the sidebar: the frame, with a chevron pointing in.
- RuneSidebarExpandExpand the sidebar: the frame, with a chevron pointing out.
- RuneGripDrag to reorder: two rows of cut studs.
- RuneMoreMore actions: three cut studs in a row.
- RuneMoreVerticalMore actions, in a narrow column: three cut studs, stacked.
- RuneMenuOpen the menu: three staves.
- RuneMaximizeFull screen, or open larger: two arrows cut out to the corners.
- RuneMinimizeLeave full screen, or open smaller: two arrows cut in from the corners.
- RuneExternalLinkA link that leaves the site: an arrow out of a frame.
- RuneLinkA link or a URL: two cut links on a diagonal, interlocked as RuneChains' links are.
- RuneColumnsShow or choose columns: a frame cut in three.
- RuneLayoutGridA grid view: four cut tiles.
- RuneDashboardThe dashboard, or an overview: four tiles of two heights.
- RuneWindowA window, an app or a transport: a frame with a title bar.
- RuneEnterEnter, return or insert: an arrow that turns down and back.
- RuneLoginSign in: Tiwaz, the arrow, into the door.
- RuneLogoutSign out: Tiwaz, the arrow, through the door.
Actions
33 icons, in components/brand/rune-icons/actions.tsx.
- RuneSearchSearch: a cut lens on a straight handle.
- RunePlusAdd: two crossed staves.
- RuneMinusRemove one, or reduce: one stave, laid down.
- RuneCheckDone, chosen or true: a check cut in two strokes.
- RuneCloseClose or clear: Gebo, the crossing.
- RuneCopyCopy: one tablet over another.
- RuneDownloadDownload: an arrow down into a tray.
- RuneUploadUpload: an arrow up out of a tray.
- RuneCloudDownloadDownload from the cloud, or a bulk export: an arrow down out of a cut cloud.
- RuneFileDownloadDownload a file, such as a CSV: an arrow down inside a page.
- RuneFileExportExport to a file: an arrow out of a page.
- RuneShareShare: three Ingwaz nodes joined.
- RuneRefreshRefresh or reload: two arrows round a cut ring.
- RuneResetReset or undo: one arrow turning back round a cut ring.
- RuneHistoryHistory, or recent items: the reset arrow round a clock face.
- RuneRepeatRepeat, or a recurring job: two arrows round a loop.
- RuneTrashDelete: a bin with a lid.
- RuneSaveSave: a floppy disk with its shutter and label.
- RuneFilterFilter: a cut funnel.
- RuneSortAscendingSort ascending: staves that grow, beside an arrow up.
- RuneSortDescendingSort descending: staves that shrink, beside an arrow down.
- RunePlayPlay or start: a cut wedge.
- RunePausePause: two staves.
- RuneStopStop: a square block.
- RuneStopSolidStop, as a filled button: the stop block, solid.
- RuneRewindRewind or replay: two wedges turned back.
- RuneEyeShow, or a preview: a cut eye with an Ingwaz pupil.
- RuneEyeOffHide: the cut eye, struck through.
- RuneEditEdit or write: a cut pencil.
- RuneSendSend: a paper dart, cut.
- RunePinPin to the top: a cut pushpin.
- RunePowerTurn on, or activate: the power mark, a stave through a cut ring.
- RunePowerOffTurn off, or deactivate: the power mark, struck through.
Status and feedback
28 icons, in components/brand/rune-icons/status.tsx.
- RuneInfoInformation, or a note: an i in a cut ring.
- RuneHelpHelp, or a question: a cut ? in a cut ring.
- RuneAlertAn alert or an error message: a ! in a cut ring.
- RuneWarningA warning: a ! in a cut triangle.
- RuneErrorFailed, or an error toast: Gebo, the crossing, in a cut ring.
- RuneSuccessSuccess, or done: a check in a cut ring.
- RuneSuccessSolidSuccess, as a filled mark: the success ring, solid, with the check cut out.
- RuneLoaderLoading: three quarters of a cut ring. Spin it with `animate-spin`.
- RuneCircleA radio choice, or an empty mark: a cut ring.
- RuneDotA chosen radio, or a bullet: a solid cut stud.
- RuneHandStopStop, or rate limited: a raised hand.
- RuneBellNotifications: a cut bell.
- RuneBellOffNotifications off, or unsubscribe: the cut bell, struck through.
- RuneClockTime, or a duration: hands on a cut clock face.
- RuneExpiringExpiring, or timed out: a cut clock face with Gebo at its edge.
- RuneTimerA timer, or a trial period: a cut stopwatch.
- RuneFlameA streak, or hot: a cut flame.
- RuneBoltFast, unmetered, or power: Sowilo, the lightning rune.
- RuneSparklesAI, or something new: a cut four-point star and two sparks.
- RuneStarA favourite, or a top pick: a cut five-point star.
- RuneHeartLiked, or a favourite: a cut heart.
- RuneCrownThe owner, or a top tier: a cut crown.
- RuneTrophyA win, an award or a ranking: a cut cup with handles.
- RuneShieldSecurity, or protected: a cut shield.
- RuneShieldCheckVerified, or secure: a check on the cut shield.
- RuneShieldLockLocked down, or private: a keyhole on the cut shield.
- RuneShieldAlertNot authorised: a ! on the cut shield.
- RuneNotFoundPage not found: 404, cut in straight strokes.
Data and charts
23 icons, in components/brand/rune-icons/data.tsx.
- RuneUsageUsage: staves rising, each with a twig.
- RuneLogsLogs: the lines of a runestone.
- RuneChartBarA bar chart: three cut bars on a base line.
- RuneChartLineA line chart: a cut line over a base line.
- RuneChartAreaAn area chart: the cut line, closed down to the base.
- RuneChartCandleA candle chart: two candles with wicks.
- RuneChartStackedStacked bars: two bars, each cut in two.
- RuneChartGroupedBars side by side: two pairs of staves.
- RuneActivityActivity, or a live stream: a cut pulse line.
- RuneGaugeSpeed, rate or load: a needle on a cut dial.
- RuneCalculatorCalculate, or a cost estimate: a cut calculator.
- RuneNumberA number field, or a count: 123, cut in straight strokes.
- RuneHashAn ID, a hash or a chain ID: a cut #.
- RunePercentA percentage, or uptime: two cut studs and a slash.
- RuneDollarMoney in dollars: a cut $.
- RuneInfinityUnlimited: two Ingwaz loops, crossed.
- RuneListA list: three studs and three staves.
- RuneListOrderedAn ordered list: a cut 1 and 2 beside three staves.
- RuneListCheckA checklist: three checks beside three staves.
- RuneReportA report, or analytics: bars inside a page.
- RuneCalendarA date: a cut calendar.
- RuneCalendarEventAn event on a date: the calendar, with one day marked.
- RuneCalendarStatsStats over time, or a year in review: the calendar, with bars.
Product nouns
55 icons, in components/brand/rune-icons/nouns.tsx.
- RuneChainsChains, or networks: two Ingwaz, linked.
- RuneHyperliquidHyperliquid: the Hyperliquid mark, cut as Chains is: a small link and a larger one, centred on one line as the mark's two lobes are.
- RuneKeyAn API key: a carved key with an Ingwaz head.
- RuneAgentsAgents, or the in-app assistant: Mannaz, the one who acts.
- RuneBotA bot, or a prompt for an agent: a cut robot head.
- RuneDocsDocs: an open book with a straight spine.
- RuneBookA guide, or a closed book: a cut book with its pages.
- RuneSettingsSettings: a six-tooth cog cut from straight lines, with an Ingwaz hub.
- RuneProfileThe user's own profile: a cut head over shoulders.
- RuneUserPlusInvite a member: a cut head over shoulders, with a plus.
- RuneAccountThe organisation's account: a hall.
- RuneTeamThe team, or users: two figures.
- RunePlanA plan, and moving up one: Tiwaz, the arrow rune.
- RuneBillingBilling, or a price: a hacked-silver coin with a cut $.
- RuneCoinsCredits, or a balance: two hacked-silver coins.
- RuneCreditCardA card payment: a cut card with its stripe.
- RuneReceiptA receipt, or an invoice: a slip with a torn edge.
- RuneDiscountA discount: a % in a cut ring.
- RuneServerA server, or a node: two cut units with their lights.
- RuneServerCogA managed server, or sign-in to one: a cut unit and a small cog of two squares.
- RuneDatabaseA database, or archive data: a cut drum.
- RuneCloudThe cloud, or hosting: a cut cloud.
- RuneNetworkA network: three cut boxes, joined.
- RuneWorldThe world, a region, or the public web: a cut globe.
- RuneApiAn API: the letters API, cut.
- RuneChipA chip, or compute: a cut die with pins.
- RuneComponentA component: four Ingwaz, set as a cross.
- RunePlugAn integration, or connected: a cut plug.
- RuneWebhookA webhook: three cut rings, each hooked to the next.
- RuneTerminalA terminal, or a CLI: a prompt and a cursor.
- RuneCodeCode: two chevrons and a slash.
- RuneBracesJSON, or a config object: a pair of cut braces.
- RuneFileA page or a document: a page with lines.
- RuneFileCodeA code file, or a schema: a page with two chevrons.
- RunePuzzleAn add-on, or an extension: a puzzle piece with cut knobs.
- RuneRocketA launch, or getting started: a cut rocket.
- RuneLayersLayers, a stack, or an order book: three cut sheets.
- RuneCompassGuides, or explore: a needle in a cut ring.
- RuneLifebuoySupport: a cut lifebuoy.
- RuneHeadsetTalk to a person, or live support: a cut headset.
- RuneMailEmail: a cut envelope.
- RunePhonePhone: a cut handset.
- RuneMessageA message, or a chat: a cut speech bubble.
- RuneInboxAn inbox, or nothing to show yet: a cut tray.
- RuneLockLocked, or private: a cut padlock.
- RuneRssA feed, or RSS: a stud and two cut waves.
- RuneBroadcastA broadcast, or a live feed: a stud between cut waves.
- RuneWavesA raw stream, or water: three cut waves.
- RuneWrenchTools, or maintenance: a cut wrench.
- RuneNutA hex nut: hardware, or a fixed part. A cut hexagon round a cut ring.
- RuneFuelGas, or fees: a cut fuel pump.
- RuneMonitorThe system theme, or a desktop: a cut monitor on its stand.
- RuneSunThe light theme: Sowilo's sun, an Ingwaz core with eight rays.
- RuneMoonThe dark theme: a cut crescent.
- RuneBeerHomebrew: a cut pint glass.
Filled states and the spinner
runeSolid() fills a rune for a filled state, with the same outline as its stroked twin. RuneLoader is three quarters of a cut hexagon; spin it with animate-spin.
Size
Without size, CSS sizes the icon, as a sidebar does. Pass size in px to set width and height together. Every icon must read at 14px.
[&_svg]:size-5 on the parentColour
The icons draw in currentColor. Set a theme text colour; switch the page theme to see both grounds.
Name map
rune-icon-map.json maps every Tabler, lucide and react-icons name the dashboard, the site and the status page use, and their near neighbours, to a rune: 201 tabler, 488 lucide, 440 react-icons names. A name marked ≈ maps to a rune with a different picture; hover it for the difference.
| Rune | Tabler | lucide | react-icons |
|---|---|---|---|
| RuneAccount | ≈IconBuilding | ≈Building | ≈LuBuilding, ≈TbBuilding |
| RuneActivity | IconActivity | Activity | LuActivity, TbActivity |
| RuneAlert | IconAlertCircle, IconAlertOctagon, IconExclamationCircle | AlertCircle, CircleAlert | LuAlertCircle, LuCircleAlert, TbAlertCircle, TbAlertOctagon, TbExclamationCircle |
| RuneApi | IconApi | None | TbApi |
| RuneArrowDown | IconArrowDown | ArrowDown, MoveDown | LuArrowDown, LuMoveDown, TbArrowDown |
| RuneArrowDownRight | IconArrowDownRight | ArrowDownRight, MoveDownRight | LuArrowDownRight, LuMoveDownRight, TbArrowDownRight |
| RuneArrowLeft | IconArrowLeft | ArrowLeft, MoveLeft | LuArrowLeft, LuMoveLeft, TbArrowLeft |
| RuneArrowRight | IconArrowRight | ArrowRight, MoveRight | LuArrowRight, LuMoveRight, TbArrowRight |
| RuneArrowUp | IconArrowUp | ArrowUp, MoveUp | LuArrowUp, LuMoveUp, TbArrowUp |
| RuneArrowUpDown | IconArrowsSort, IconArrowsUpDown, IconArrowsVertical | ArrowDownUp, ArrowUpDown, MoveVertical | LuArrowDownUp, LuArrowUpDown, LuMoveVertical, TbArrowsSort, TbArrowsUpDown, TbArrowsVertical |
| RuneArrowUpRight | IconArrowUpRight | ArrowUpRight, MoveUpRight | LuArrowUpRight, LuMoveUpRight, TbArrowUpRight |
| RuneBeer | IconBeer | Beer | LuBeer, TbBeer |
| RuneBell | IconBell | Bell | LuBell, TbBell |
| RuneBellOff | IconBellOff | BellOff | LuBellOff, TbBellOff |
| RuneBilling | ≈IconCoin | ≈BadgeDollarSign, CircleDollarSign | ≈LuBadgeDollarSign, LuCircleDollarSign, ≈TbCoin |
| RuneBolt | IconBolt | Zap | LuZap, TbBolt |
| RuneBook | IconBook2 | Book, BookText | LuBook, LuBookText, TbBook2 |
| RuneBot | IconRobot | Bot | LuBot, TbRobot |
| RuneBraces | IconBraces | Braces | LuBraces, TbBraces |
| RuneBroadcast | IconBroadcast | Radio | LuRadio, TbBroadcast |
| RuneCalculator | IconCalculator | Calculator | LuCalculator, TbCalculator |
| RuneCalendar | IconCalendar | Calendar | LuCalendar, TbCalendar |
| RuneCalendarEvent | IconCalendarEvent | None | TbCalendarEvent |
| RuneCalendarStats | IconCalendarStats | None | TbCalendarStats |
| RuneChartArea | IconChartArea | AreaChart, ChartArea | LuAreaChart, LuChartArea, TbChartArea |
| RuneChartBar | IconChartBar | BarChart, BarChart3, ≈ChartBar, ChartColumn, ChartColumnBig | LuBarChart, LuBarChart3, ≈LuChartBar, LuChartColumn, LuChartColumnBig, TbChartBar |
| RuneChartCandle | IconChartCandle | CandlestickChart, ChartCandlestick | LuCandlestickChart, LuChartCandlestick, TbChartCandle |
| RuneChartLine | IconChartLine | ChartLine, ≈ChartSpline, LineChart | LuChartLine, ≈LuChartSpline, LuLineChart, TbChartLine |
| RuneChartStacked | None | ChartColumnStacked | LuChartColumnStacked |
| RuneCheck | IconCheck | Check | LuCheck, TbCheck |
| RuneChevronDown | IconChevronDown | ChevronDown | LuChevronDown, TbChevronDown |
| RuneChevronFirst | IconChevronLeftPipe | ChevronFirst | LuChevronFirst, TbChevronLeftPipe |
| RuneChevronLast | IconChevronRightPipe | ChevronLast | LuChevronLast, TbChevronRightPipe |
| RuneChevronLeft | IconChevronLeft | ChevronLeft | LuChevronLeft, TbChevronLeft |
| RuneChevronRight | IconChevronRight | ChevronRight | LuChevronRight, TbChevronRight |
| RuneChevronsDown | IconChevronsDown | ChevronsDown | LuChevronsDown, TbChevronsDown |
| RuneChevronsLeft | IconChevronsLeft | ChevronsLeft | LuChevronsLeft, TbChevronsLeft |
| RuneChevronsRight | IconChevronsRight | ChevronsRight | LuChevronsRight, TbChevronsRight |
| RuneChevronsUp | IconChevronsUp | ChevronsUp | LuChevronsUp, TbChevronsUp |
| RuneChevronUp | IconChevronUp | ChevronUp | LuChevronUp, TbChevronUp |
| RuneChip | IconCpu | Cpu | LuCpu, TbCpu |
| RuneCircle | IconCircle | Circle | LuCircle, TbCircle |
| RuneClock | IconClock | Clock | LuClock, TbClock |
| RuneClose | IconX | X | LuX, TbX |
| RuneCloud | IconCloud, ≈IconCloudComputing | Cloud | LuCloud, TbCloud, ≈TbCloudComputing |
| RuneCloudDownload | IconCloudDownload | CloudDownload | LuCloudDownload, TbCloudDownload |
| RuneCode | IconCode | Code, Code2, CodeXml | LuCode, LuCode2, LuCodeXml, TbCode |
| RuneCoins | IconCoins | Coins | LuCoins, TbCoins |
| RuneColumns | IconColumns, IconColumns3 | Columns, Columns3 | LuColumns, LuColumns3, TbColumns, TbColumns3 |
| RuneCompass | IconCompass | Compass | LuCompass, TbCompass |
| RuneComponent | IconComponents | Component | LuComponent, TbComponents |
| RuneCopy | IconCopy | Copy | LuCopy, TbCopy |
| RuneCreditCard | IconCreditCard | CreditCard | LuCreditCard, TbCreditCard |
| RuneCrown | IconCrown | Crown | LuCrown, TbCrown |
| RuneDashboard | IconLayoutDashboard | LayoutDashboard | LuLayoutDashboard, TbLayoutDashboard |
| RuneDatabase | IconDatabase | Database, ≈DatabaseZap | LuDatabase, ≈LuDatabaseZap, TbDatabase |
| RuneDiscount | IconDiscount, IconDiscount2 | BadgePercent | LuBadgePercent, TbDiscount, TbDiscount2 |
| RuneDocs | IconBook | BookOpen, BookOpenText | LuBookOpen, LuBookOpenText, TbBook |
| RuneDollar | IconCurrencyDollar | DollarSign | LuDollarSign, TbCurrencyDollar |
| RuneDot | IconPoint, IconPointFilled | Dot | LuDot, TbPoint, TbPointFilled |
| RuneDownload | IconDownload | Download | LuDownload, TbDownload |
| RuneEdit | IconEdit, IconPencil | Edit, Edit2, Edit3, Pen, Pencil, PencilLine, PenLine, ≈SquarePen | LuEdit, LuEdit2, LuEdit3, LuPen, LuPencil, LuPencilLine, LuPenLine, ≈LuSquarePen, TbEdit, TbPencil |
| RuneEnter | IconCornerDownLeft | CornerDownLeft | LuCornerDownLeft, TbCornerDownLeft |
| RuneError | IconCircleX | CircleX, OctagonX, XCircle | LuCircleX, LuOctagonX, LuXCircle, TbCircleX |
| RuneExpiring | IconClockX | None | TbClockX |
| RuneExternalLink | IconExternalLink | ExternalLink, SquareArrowOutUpRight | LuExternalLink, LuSquareArrowOutUpRight, TbExternalLink |
| RuneEye | IconEye | Eye | LuEye, TbEye |
| RuneEyeOff | IconEyeOff | EyeOff | LuEyeOff, TbEyeOff |
| RuneFile | IconFile, IconFileText | File, FileText | LuFile, LuFileText, TbFile, TbFileText |
| RuneFileCode | IconFileCode | FileCode | LuFileCode, TbFileCode |
| RuneFileDownload | IconFileDownload | FileDown | LuFileDown, TbFileDownload |
| RuneFileExport | IconFileExport | FileOutput | LuFileOutput, TbFileExport |
| RuneFilter | IconFilter | Filter, Funnel, ≈ListFilter | LuFilter, LuFunnel, ≈LuListFilter, TbFilter |
| RuneFlame | IconFlame | Flame | LuFlame, TbFlame |
| RuneFuel | IconGasStation | Fuel | LuFuel, TbGasStation |
| RuneGauge | IconGauge | Gauge | LuGauge, TbGauge |
| RuneGrip | IconGripVertical | GripVertical | LuGripVertical, TbGripVertical |
| RuneHandStop | IconHandStop | Hand | LuHand, TbHandStop |
| RuneHash | IconHash | Hash | LuHash, TbHash |
| RuneHeadset | IconHeadset | Headset | LuHeadset, TbHeadset |
| RuneHeart | IconHeart | Heart | LuHeart, TbHeart |
| RuneHelp | IconHelp, IconHelpCircle | CircleHelp, HelpCircle | LuCircleHelp, LuHelpCircle, TbHelp, TbHelpCircle |
| RuneHistory | IconHistory | History | LuHistory, TbHistory |
| RuneHome | IconHome, IconHome2 | Home, House | LuHome, LuHouse, TbHome, TbHome2 |
| RuneIcon | Icon, TablerIcon | LucideIcon | None |
| RuneIconProps | IconProps, TablerIconsProps | LucideProps | None |
| RuneInbox | IconInbox | Inbox | LuInbox, TbInbox |
| RuneInfinity | IconInfinity | Infinity | LuInfinity, TbInfinity |
| RuneInfo | IconInfoCircle | Info | LuInfo, TbInfoCircle |
| RuneKey | IconKey | Key, KeyRound | LuKey, LuKeyRound, TbKey |
| RuneLayers | IconStack, IconStack2 | Layers | LuLayers, TbStack, TbStack2 |
| RuneLayoutGrid | IconLayoutGrid | LayoutGrid | LuLayoutGrid, TbLayoutGrid |
| RuneLifebuoy | IconLifebuoy | LifeBuoy | LuLifeBuoy, TbLifebuoy |
| RuneLink | IconLink | Link, Link2 | LuLink, LuLink2, TbLink |
| RuneList | IconList | List | LuList, TbList |
| RuneListCheck | IconListCheck | ListCheck, ListChecks | LuListCheck, LuListChecks, TbListCheck |
| RuneListOrdered | IconListNumbers | ListOrdered | LuListOrdered, TbListNumbers |
| RuneLoader | IconLoader, IconLoader2 | Loader, Loader2, LoaderCircle | LuLoader, LuLoader2, LuLoaderCircle, TbLoader, TbLoader2 |
| RuneLock | IconLock | Lock, LockKeyhole | LuLock, LuLockKeyhole, TbLock |
| RuneLogin | IconLogin, IconLogin2 | LogIn | LuLogIn, TbLogin, TbLogin2 |
| RuneLogout | IconLogout, IconLogout2 | LogOut | LuLogOut, TbLogout, TbLogout2 |
| RuneLogs | IconLogs | Logs, ScrollText | LuLogs, LuScrollText, TbLogs |
| RuneMail | IconMail | LuMail, TbMail | |
| RuneMaximize | IconArrowsMaximize, IconMaximize | ≈Expand, Fullscreen, Maximize, Maximize2 | ≈LuExpand, LuFullscreen, LuMaximize, LuMaximize2, TbArrowsMaximize, TbMaximize |
| RuneMenu | IconMenu, IconMenu2 | ≈AlignJustify, Menu | ≈LuAlignJustify, LuMenu, TbMenu, TbMenu2 |
| RuneMessage | IconMessage, IconMessageCircle | MessageCircle, MessageSquare | LuMessageCircle, LuMessageSquare, TbMessage, TbMessageCircle |
| RuneMinimize | IconArrowsMinimize, IconMinimize | Minimize, Minimize2, ≈Shrink | LuMinimize, LuMinimize2, ≈LuShrink, TbArrowsMinimize, TbMinimize |
| RuneMinus | IconMinus | Minus | LuMinus, TbMinus |
| RuneMonitor | IconDeviceDesktop | Monitor | LuMonitor, TbDeviceDesktop |
| RuneMoon | IconMoon | Moon | LuMoon, TbMoon |
| RuneMore | IconDots | Ellipsis, MoreHorizontal | LuEllipsis, LuMoreHorizontal, TbDots |
| RuneMoreVertical | IconDotsVertical | EllipsisVertical, MoreVertical | LuEllipsisVertical, LuMoreVertical, TbDotsVertical |
| RuneNetwork | IconNetwork | Network | LuNetwork, TbNetwork |
| RuneNotFound | IconError404 | None | TbError404 |
| RuneNumber | IconNumber123 | None | TbNumber123 |
| RuneNut | IconNut | Bolt | LuBolt, TbNut |
| RunePause | IconPlayerPause | Pause | LuPause, TbPlayerPause |
| RunePercent | IconPercentage | Percent | LuPercent, TbPercentage |
| RunePhone | IconPhone | Phone | LuPhone, TbPhone |
| RunePin | IconPin | Pin | LuPin, TbPin |
| RunePlay | IconPlayerPlay | Play | LuPlay, TbPlayerPlay |
| RunePlug | IconPlug, IconPlugConnected | Plug, ≈PlugZap | LuPlug, ≈LuPlugZap, TbPlug, TbPlugConnected |
| RunePlus | IconPlus | Plus | LuPlus, TbPlus |
| RunePower | IconPower | Power | LuPower, TbPower |
| RunePowerOff | None | PowerOff | LuPowerOff |
| RuneProfile | IconUser | User | LuUser, TbUser |
| RunePuzzle | IconPuzzle | Puzzle | LuPuzzle, TbPuzzle |
| RuneReceipt | IconReceipt | Receipt | LuReceipt, TbReceipt |
| RuneRefresh | IconRefresh | RefreshCcw, RefreshCw, ≈RotateCw | LuRefreshCcw, LuRefreshCw, ≈LuRotateCw, TbRefresh |
| RuneRepeat | IconRepeat | Repeat | LuRepeat, TbRepeat |
| RuneReport | IconFileAnalytics | FileBarChart, FileChartColumn | LuFileBarChart, LuFileChartColumn, TbFileAnalytics |
| RuneReset | ≈IconArrowBackUp, IconRotate | RotateCcw, ≈Undo2 | LuRotateCcw, ≈LuUndo2, ≈TbArrowBackUp, TbRotate |
| RuneRewind | IconPlayerTrackPrev | Rewind | LuRewind, TbPlayerTrackPrev |
| RuneRocket | IconRocket | Rocket | LuRocket, TbRocket |
| RuneRss | IconRss | Rss | LuRss, TbRss |
| RuneSave | IconDeviceFloppy | Save | LuSave, TbDeviceFloppy |
| RuneSearch | IconSearch | Search | LuSearch, TbSearch |
| RuneSelector | IconSelector | ChevronsUpDown | LuChevronsUpDown, TbSelector |
| RuneSend | IconSend | Send, SendHorizonal, SendHorizontal | LuSend, LuSendHorizonal, LuSendHorizontal, TbSend |
| RuneServer | IconServer, ≈IconServer2 | Server | LuServer, TbServer, ≈TbServer2 |
| RuneServerCog | IconServerCog | ServerCog | LuServerCog, TbServerCog |
| RuneSettings | IconSettings | Cog, Settings, ≈Settings2 | LuCog, LuSettings, ≈LuSettings2, TbSettings |
| RuneShare | IconShare, ≈IconShare2 | ≈Share, Share2 | ≈LuShare, LuShare2, TbShare, ≈TbShare2 |
| RuneShield | IconShield | Shield | LuShield, TbShield |
| RuneShieldAlert | IconShieldExclamation | ShieldAlert | LuShieldAlert, TbShieldExclamation |
| RuneShieldCheck | IconShieldCheck | ShieldCheck | LuShieldCheck, TbShieldCheck |
| RuneShieldLock | IconShieldLock | None | TbShieldLock |
| RuneSidebar | IconLayoutSidebar | PanelLeft, Sidebar | LuPanelLeft, LuSidebar, TbLayoutSidebar |
| RuneSidebarCollapse | IconLayoutSidebarLeftCollapse | PanelLeftClose, SidebarClose | LuPanelLeftClose, LuSidebarClose, TbLayoutSidebarLeftCollapse |
| RuneSidebarExpand | IconLayoutSidebarLeftExpand | PanelLeftOpen, SidebarOpen | LuPanelLeftOpen, LuSidebarOpen, TbLayoutSidebarLeftExpand |
| RuneSortAscending | IconSortAscending | ArrowUpNarrowWide, SortAsc | LuArrowUpNarrowWide, LuSortAsc, TbSortAscending |
| RuneSortDescending | IconSortDescending | ArrowDownWideNarrow, SortDesc | LuArrowDownWideNarrow, LuSortDesc, TbSortDescending |
| RuneSparkles | IconSparkles, ≈IconWand | ≈Sparkle, Sparkles, ≈WandSparkles | ≈LuSparkle, LuSparkles, ≈LuWandSparkles, TbSparkles, ≈TbWand |
| RuneStar | IconStar | Star | LuStar, TbStar |
| RuneStop | IconPlayerStop | ≈Square | ≈LuSquare, TbPlayerStop |
| RuneStopSolid | IconPlayerStopFilled | None | TbPlayerStopFilled |
| RuneSuccess | IconCircleCheck | CheckCircle, CheckCircle2, CircleCheck, CircleCheckBig | LuCheckCircle, LuCheckCircle2, LuCircleCheck, LuCircleCheckBig, TbCircleCheck |
| RuneSuccessSolid | IconCircleCheckFilled | None | TbCircleCheckFilled |
| RuneSun | IconSun | Sun | LuSun, TbSun |
| RuneTeam | IconUsers | Users | LuUsers, TbUsers |
| RuneTerminal | IconTerminal, ≈IconTerminal2 | ≈SquareTerminal, Terminal | ≈LuSquareTerminal, LuTerminal, TbTerminal, ≈TbTerminal2 |
| RuneTimer | IconStopwatch | Timer | LuTimer, TbStopwatch |
| RuneTrash | IconTrash | Trash, Trash2 | LuTrash, LuTrash2, TbTrash |
| RuneTrophy | ≈IconAward, IconTrophy | ≈Award, Trophy | ≈LuAward, LuTrophy, ≈TbAward, TbTrophy |
| RuneUpload | IconUpload | Upload | LuUpload, TbUpload |
| RuneUserPlus | IconUserPlus | UserPlus | LuUserPlus, TbUserPlus |
| RuneWarning | IconAlertTriangle | AlertTriangle, TriangleAlert | LuAlertTriangle, LuTriangleAlert, TbAlertTriangle |
| RuneWaves | IconWaveSine | Waves | LuWaves, TbWaveSine |
| RuneWebhook | IconWebhook | Webhook | LuWebhook, TbWebhook |
| RuneWindow | IconAppWindow, IconBrowser, ≈IconLayoutNavbar | AppWindow, ≈PanelTop | LuAppWindow, ≈LuPanelTop, TbAppWindow, TbBrowser, ≈TbLayoutNavbar |
| RuneWorld | IconWorld | Earth, Globe, Globe2 | LuEarth, LuGlobe, LuGlobe2, TbWorld |
| RuneWrench | IconTool | Wrench | LuWrench, TbTool |
Draw a new icon
Add it to its category file under components/brand/rune-icons/ with a doc comment that names its job and its rune or object. Map its library names in scripts/rune-icons/rune-icon-map.json, then run npm run registry:build to refresh this list.
Do
- Use straight strokes only. A curve or an arc breaks the carved look, so
M L H V Zare the only path commands. - Cut a ring as a hexagon, a diamond or a square: six corners at most. An octagon reads as a circle at 14px.
- Cut square ends and mitred corners. The factory sets both, so a path needs no cap or join.
- Draw on the 24px grid. Keep every point inside
0 0 24 24and the shape inside the live area the set shares, about 3 to 21. - Leave the stroke at 2. The factory sets it, and the icons share one weight at every size. Keep parallel strokes 4 units apart and the facets that make a rune 3 units long or more.
- Draw one
<path>per icon withrune(). UseruneSolid()only where a filled state is the job, such as a stop button. Draw its outline 1 unit outside the stroked twin; a second subpath cuts a hole. - Mirror the shapes that pair: chevrons up and down, sort up and down, play and pause, sun and moon.
Don't
- Round a corner to make a shape read better. Add a short straight cut instead.
- Draw the rune alone. A reader who knows Tabler or lucide should see the icon's job at 14px first, and the rune second.
- Set a colour or a stroke width in the path. Callers colour the icon with text colour.
- Animate inside the icon.
RuneLoaderis still; the caller spins it withanimate-spin.
Chain icon
One logo in lists, tables and cards. Artwork paints before hydration. Missing or failed logos show an initials disc.
Sizes and frames
Sizes sm, md and lg. The tile adds a frame around the same glyph size.
Theme sources and fallbacks
Switch the page theme. Acurast has no dark artwork and gets a light neutral backplate on dark ground. Paired artwork keeps its own colours.
Pass name for initials, src for light artwork and darkSrc for dark artwork. The logo is decorative by default. Use alt when it stands alone. Theme classes select the source before hydration. Set chain-icon-ground once to adjust the backplate. Measured catalog data keeps bright marks on the dark ground and gives dark ink a backplate.
Network badge
Identity stays neutral. Network types appear in words, so colour can carry state.
Network types
Supply the type from your catalog. Existing type words are kept without a second suffix.
Node types and ecosystems
Use the catalog's display names. Premium describes access, not a service state.
Use NetworkBadge with name and type. Put a decorative ChainIcon in its icon slot when the name identifies a chain.NodeTypeBadge and EcosystemBadge take their labels as children. These parts expose no colour variants. Use the state variants of Badge for incidents and availability.
Start free.1 response = 1 credit.
100,000 responses a day at 20 per second, on 150+ networks. Upgrade when you need more.