Illustrations
Scenes for empty states, feature icons for cards and steps, and card art. All follow the theme.
Illustrations add tone where plain UI would read as empty or flat. BDS has three kinds, grouped by the job they do. Pick by role, then by size.
| Role | For | Size | Motion | Import from |
|---|---|---|---|---|
| Scenes | Empty, first-run, and upload states | Intrinsic | Static | illustrations/<name> |
| Feature icons | Cards, feature rows, and numbered steps | 28–64px | Hover, loop, or pulse | brand/illustrations/feature-icons |
| Card art | The top of a card | Fills its parent | Loops while in view | brand/illustrations/asset-tokenization-illo |
When to use
Use an illustration when a surface would otherwise be blank, or when a card or feature row needs a visual anchor next to its copy.
Use something else when:
- The UI needs a functional icon, such as a close button or a status. Use the icon set.
- The view is dense with data. An illustration competes with the content there; leave it out.
Scenes
Fixed compositions for the moments that plain UI reads as empty or unfinished: a blank feed, an upload step, a prompt to review. Each is a single component that carries its own light and dark artwork.
import { FeedIllustration } from '@base-org/bds-web/illustrations/feed';
<FeedIllustration />;app-reviewsfeedlink-appcoinupload-screenshotsupload-thumbnailEach scene renders at its own intrinsic size. Constrain it with a wrapper
rather than stretching the component, and pass className for layout; it
forwards to the container element.
Feature icons
Small animated icons for cards, feature rows, and the badge of a numbered step. Import any of them from one place:
import { GenerateRevenueIcon, DifferenceIcon } from '@base-org/bds-web/brand/illustrations/feature-icons';Hover icons
All but two feature icons are 64px and spring into an active state. Drive
them with isHovered, from the hover state of the card they sit in. A
Card passes its hover state for you. Hover a tile, or play them all.
GenerateRevenueIconProductLineIconKeepFundsIconServiceDesignIconServiceBuildIconServiceLaunchIconServiceGrowIconCoinbaseTrustIconLiquidityIconEcosystemIconBorrowLiquidityIconconst [hovered, setHovered] = useState(false);
<div onMouseEnter={() => setHovered(true)} onMouseLeave={() => setHovered(false)}>
<GenerateRevenueIcon isHovered={hovered} className="size-16" />
</div>Looping and pulsing icons
DifferenceIcon draws at 52px (64px from sm) and suits a row of cards; a row
starts in a left-to-right wave. StepIcon draws at 28px (32px from md)
and sits in the round badge of a step, with a gentle pulse.
liquidationstradingFlowtopOfBlockdexsassetsintegrationwithdraw<DifferenceIcon icon="liquidations" />
<span className="flex size-12 items-center justify-center rounded-full bg-bds-gray-5 md:size-14">
<StepIcon icon="assets" />
</span>Card art
Wide illustrations for the top of a card, drawn at 327×182. Each fills its positioned parent, loops a short sequence while in view, and pauses offscreen.
tokenizedStocksfxCommoditiescryptoMajorsemergingCrypto<div className="relative aspect-327/182 overflow-hidden rounded-3">
<AssetTokenizationIllo illo="cryptoMajors" />
</div>Motion
| Trigger | Illustrations | How to drive it | Under reduced motion |
|---|---|---|---|
| Hover | The 64px feature icons | isHovered, from the card's hover state | Switches state instantly |
| In view | DifferenceIcon, card art | Automatic; pauses offscreen | Stays on the first frame |
| Idle | StepIcon | Automatic | The pulse stops |
Every animated illustration renders the still design on the server, so a page never depends on it moving.
Theming
Scenes ship light and dark artwork together and switch with CSS (dark:), so
they follow the active theme without a hook or a prop. The feature icons and
card art draw their grays and blue from theme tokens. The 64px icons also take
color props (ringColor, inkColor, and so on) to repaint parts of the
drawing for an unusual background; the defaults fit both themes.
Usage
Do
Put one illustration per card or empty state, next to copy that says the same thing.
Don't
Scatter illustrations through a view, or rely on one to carry meaning the copy doesn't.
Do
Drive a hover icon on hover and when its card scrolls into view, so touch devices see the motion too.
Don't
Stretch an illustration past its size. Constrain it with a wrapper instead.
Accessibility
Scenes render role="img" with no name. Pass aria-label when the scene adds
meaning, or aria-hidden when the copy next to it already says it. Feature
icons and card art are always aria-hidden, so say what they show in the
surrounding text.
Props
Scenes take every div prop and forward them to the container. The feature
icons and card art take the props below.
GenerateRevenueIcon
| Prop | Type | Default |
|---|---|---|
blueColor | Typestring | Defaultvar(--color-brand-accent) |
bodyColor | Typestring | Defaultvar(--bds-gray-0) |
className | Typestring | Default— |
cornerGrayColor | Typestring | Defaultvar(--bds-gray-10) |
innerRingColor | Typestring | Defaultvar(--bds-gray-10) |
isHoveredPlays the icon's active state. Inside a Brand section card the card sets it on hover and in view; pass it to drive the icon yourself. | Typeboolean | Default— |
ringColor | Typestring | Defaultvar(--bds-gray-100) |
ProductLineIcon
| Prop | Type | Default |
|---|---|---|
blueColor | Typestring | Defaultvar(--color-brand-accent) |
bodyColor | Typestring | Defaultvar(--bds-gray-0) |
className | Typestring | Default— |
inkColor | Typestring | Defaultvar(--bds-gray-100) |
isHoveredPlays the icon's active state. Inside a Brand section card the card sets it on hover and in view; pass it to drive the icon yourself. | Typeboolean | Default— |
ringColor | Typestring | Defaultvar(--bds-gray-10) |
KeepFundsIcon
| Prop | Type | Default |
|---|---|---|
blueColor | Typestring | Defaultvar(--color-brand-accent) |
bodyColor | Typestring | Defaultvar(--bds-gray-0) |
className | Typestring | Default— |
inkColor | Typestring | Defaultvar(--bds-gray-100) |
isHoveredPlays the icon's active state. Inside a Brand section card the card sets it on hover and in view; pass it to drive the icon yourself. | Typeboolean | Default— |
pinStrokeColor | Typestring | Defaultvar(--bds-gray-0) |
ringColor | Typestring | Defaultvar(--bds-gray-10) |
ServiceDesignIcon
| Prop | Type | Default |
|---|---|---|
blueColorBrand accent. | Typestring | Defaultvar(--color-brand-accent) |
bodyColorWhite fills and white tile outlines. | Typestring | Default— |
className | Typestring | Default— |
grayColorRules, frames, gray tiles/corners. | Typestring | Defaultvar(--color-brand-illustration-rule) |
inkColorBlack strokes/fills. | Typestring | Default— |
isHoveredPlays the icon's active state. Inside a Brand section card the card sets it on hover and in view; pass it to drive the icon yourself. | Typeboolean | Default— |
ServiceBuildIcon
| Prop | Type | Default |
|---|---|---|
blueColorBrand accent. | Typestring | Defaultvar(--color-brand-accent) |
bodyColorWhite fills and white tile outlines. | Typestring | Defaultvar(--bds-gray-0) |
className | Typestring | Default— |
grayColorRules, frames, gray tiles/corners. | Typestring | Defaultvar(--color-brand-illustration-rule) |
inkColorBlack strokes/fills. | Typestring | Default— |
isHoveredPlays the icon's active state. Inside a Brand section card the card sets it on hover and in view; pass it to drive the icon yourself. | Typeboolean | Default— |
ServiceLaunchIcon
| Prop | Type | Default |
|---|---|---|
blueColorBrand accent. | Typestring | Defaultvar(--color-brand-accent) |
bodyColorWhite fills and white tile outlines. | Typestring | Defaultvar(--bds-gray-0) |
className | Typestring | Default— |
grayColorRules, frames, gray tiles/corners. | Typestring | Defaultvar(--color-brand-illustration-rule) |
inkColorBlack strokes/fills. | Typestring | Default— |
isHoveredPlays the icon's active state. Inside a Brand section card the card sets it on hover and in view; pass it to drive the icon yourself. | Typeboolean | Default— |
showTrend | Typeboolean | Defaulttrue |
ServiceGrowIcon
| Prop | Type | Default |
|---|---|---|
blueColorBrand accent. | Typestring | Defaultvar(--color-brand-accent) |
bodyColorWhite fills and white tile outlines. | Typestring | Defaultvar(--bds-gray-0) |
className | Typestring | Default— |
grayColorRules, frames, gray tiles/corners. | Typestring | Defaultvar(--color-brand-illustration-rule) |
inkColorBlack strokes/fills. | Typestring | Default— |
isHoveredPlays the icon's active state. Inside a Brand section card the card sets it on hover and in view; pass it to drive the icon yourself. | Typeboolean | Default— |
CoinbaseTrustIcon
| Prop | Type | Default |
|---|---|---|
blueColorBrand accent. | Typestring | Default— |
bodyColorWhite fills. | Typestring | Default— |
className | Typestring | Default— |
grayColorRules, outer arcs, frame strokes, meridians. | Typestring | Default— |
inkColorDark outlines. | Typestring | Default— |
isHoveredPlays the icon's active state. Inside a Brand section card the card sets it on hover and in view; pass it to drive the icon yourself. | Typeboolean | Default— |
markerStrokeOutline of the left/right pink ring markers. | Typestring | Default— |
markerStrokeTBOutline of the top/bottom ring markers, when it differs from left/right . | Typestring | Default— |
panelColorPanel fills. | Typestring | Default— |
panelStrokeColorOutline around small blue/pink squares that sit on a panel. | Typestring | Default— |
LiquidityIcon
| Prop | Type | Default |
|---|---|---|
className | Typestring | Default— |
isHoveredPlays the icon's active state. Inside a Brand section card the card sets it on hover and in view; pass it to drive the icon yourself. | Typeboolean | Default— |
EcosystemIcon
| Prop | Type | Default |
|---|---|---|
blueColorBrand accent. | Typestring | Default— |
bodyColorWhite fills. | Typestring | Default— |
centerGlyphCenter mark: a check or a `$`. | Type"check" | "dollar" | Defaultcheck |
className | Typestring | Default— |
grayColorRules, outer arcs, frame strokes, meridians. | Typestring | Default— |
inkColorDark outlines. | Typestring | Default— |
isHoveredPlays the icon's active state. Inside a Brand section card the card sets it on hover and in view; pass it to drive the icon yourself. | Typeboolean | Default— |
panelColorPanel fills. | Typestring | Default— |
panelStrokeColorOutline around small blue/pink squares that sit on a panel. | Typestring | Default— |
BorrowLiquidityIcon
| Prop | Type | Default |
|---|---|---|
className | Typestring | Default— |
isHoveredPlays the icon's active state. Inside a Brand section card the card sets it on hover and in view; pass it to drive the icon yourself. | Typeboolean | Default— |
AssetTokenizationIllo
| Prop | Type | Default |
|---|---|---|
illorequiredWhich asset class to draw. | Type"tokenizedStocks" | "fxCommodities" | "cryptoMajors" | "emergingCrypto" | Default— |
className | Typestring | Default— |
DifferenceIcon
| Prop | Type | Default |
|---|---|---|
iconrequiredWhich icon to draw. | Type"liquidations" | "tradingFlow" | "topOfBlock" | "dexs" | Default— |
className | Typestring | Default— |
StepIcon
| Prop | Type | Default |
|---|---|---|
iconrequiredWhich step icon to draw. | Type"assets" | "integration" | "withdraw" | Default— |
className | Typestring | Default— |