FairGarden Design

Sticker

Hand art with a die-cut halo: an 8 px face around the drawing's silhouette that lifts it off any ground without a shadow, a tint or a blur.

import { Sticker, StickerDetail } from '@fairgarden-private/design/components/Sticker'

Pass the asset's viewBox, its halo path and its line art. The halo is a path drawn into the asset, 8 px outside every part and merged into one silhouette with rounded bridges; never build it with a stroke, an outline or a blur. The Sticker fills the halo with the face color and strokes the art in the heading ink, at the silhouette weight; wrap interior lines in StickerDetail for the lighter weight, and give ink-spot parts fill="currentColor". Use one sticker per scene, never on a photograph, and keep text out of the art. It is decorative, so it is hidden from assistive technology.

Sizes and the bare variant

Sizes and the bare variant

Stickers come in two native sizes: S, 152 px, and L, 312 px, each with its own stroke pair. They never scale with the viewport; swap the size instead. bare drops the halo and draws the art in the surrounding ground's heading ink, with open counters. Never set a bare drawing on a pattern.

S, with halo
L, with halo
S, bare
StickerSizes.tsx
import { Sticker } from '@fairgarden-private/design/components/Sticker'
import { SeedlingArt, seedlingHalo, seedlingViewBox } from '../Seedling'
import styles from './sizes.module.css'

/** S (152 px) and L (312 px) with the halo, and the bare variant in the host's heading ink. */
export function StickerSizes() {
  return (
    <div className={styles.row}>
      <figure className={styles.item}>
        <Sticker viewBox={seedlingViewBox} halo={seedlingHalo}>
          <SeedlingArt />
        </Sticker>
        <figcaption className={styles.name}>S, with halo</figcaption>
      </figure>
      <figure className={styles.item}>
        <Sticker size="l" viewBox={seedlingViewBox} halo={seedlingHalo}>
          <SeedlingArt />
        </Sticker>
        <figcaption className={styles.name}>L, with halo</figcaption>
      </figure>
      <figure className={styles.item}>
        <Sticker bare viewBox={seedlingViewBox}>
          <SeedlingArt />
        </Sticker>
        <figcaption className={styles.name}>S, bare</figcaption>
      </figure>
    </div>
  )
}

On paper, rose, forest and leaf

On paper, rose, forest and leaf

A sticker is its own white scope, so the same asset looks the same on every ground. On a page ground it follows the page's light or dark mode; inside a field or the night band it stays light in both modes. In print the halo drops out and the line prints black.

paper

rose

forest

leaf

StickerGrounds.tsx
import { Sticker } from '@fairgarden-private/design/components/Sticker'
import { PresetGround } from '@/components/PresetGround'
import { SeedlingArt, seedlingHalo, seedlingViewBox } from '../Seedling'
import styles from './grounds.module.css'

const presets = ['paper', 'rose', 'forest', 'leaf'] as const

/** The same sticker on a page ground, a pastel, a dark field and a solid field. */
export function StickerGrounds() {
  return (
    <div className={styles.row}>
      {presets.map((preset) => (
        <PresetGround key={preset} preset={preset} className={styles.band}>
          <Sticker viewBox={seedlingViewBox} halo={seedlingHalo}>
            <SeedlingArt />
          </Sticker>
          <p className={styles.name}>{preset}</p>
        </PresetGround>
      ))}
    </div>
  )
}

API Reference

Sticker

A §6.5 sticker: pass the asset’s viewBox, its pre-expanded halo path and its line art as children. It declares its own white scope, so the same asset looks identical on every ground within a mode: a face that follows the page mode on a page ground, a light island inside a field or the night band. In print the halo vanishes and the line prints black.

PropTypeDescription
bare
boolean | undefined

The bare variant: no halo and no scope of its own; the art draws in the host ground’s --role-heading with open counters. Never on a decorative pattern. Default false.

halo
React.ReactNode | undefined

The halo layer: the asset’s pre-expanded path, 8 px (--ds-space-halo) outside every part, merged into one silhouette with rounded concave bridges and no sharp outer corners. Never a runtime stroke, outline or blur. Filled --primary1; no edge, ever. Ignored with bare.

primary
| 'ruby'
| 'olive'
| 'sage'
| 'slate'
| 'sand'
| 'gray'
| 'mauve'
| 'brown'
| 'bronze'
| 'gold'
| 'red'
| 'crimson'
| 'tomato'
| 'pink'
| 'plum'
| 'indigo'
| 'iris'
| 'violet'
| 'purple'
| null
| undefined

Primary Radix scale: the halo’s --primary1 (the sticker’s own scope), or, when bare, the host’s. Override only with a pairing §2 verifies [D128]. Never defaulted.

secondary
| 'ruby'
| 'olive'
| 'sage'
| 'slate'
| 'sand'
| 'gray'
| 'mauve'
| 'brown'
| 'bronze'
| 'gold'
| 'red'
| 'crimson'
| 'tomato'
| 'pink'
| 'plum'
| 'indigo'
| 'iris'
| 'violet'
| 'purple'
| 'amber'
| 'blue'
| 'cyan'
| 'grass'
| 'green'
| 'jade'
| 'lime'
| 'mint'
| 'orange'
| 'sky'
| 'teal'
| 'yellow'
| null
| undefined

Secondary Radix scale: the line’s --role-heading (step 12). Override only with a verified pairing [D128]. Never defaulted.

size
StickerSize | undefined

s (default): --ds-size-art-s, 152 px. l: --ds-size-art-l, 312 px.

viewBox
string | undefined

The asset’s viewBox, drawn at its native size: 0 0 152 152 for S, 0 0 312 312 for L (other aspect ratios keep the width).

children
React.ReactNode | undefined

The line art, stroked in --role-heading at the silhouette weight (--ds-stroke-3 at S, --ds-stroke-4 at L), round caps and joins, no fill; give ink-spot parts fill="currentColor", and wrap interior lines in StickerDetail. No text inside the art.

StickerDetail

Interior lines, one stroke step lighter than the silhouette (--border-size-2 at S, --ds-stroke-3 at L): at most two weights per drawing, depth by weight, never tone (§6.2).

Additional types

sticker
StickerDetailProps

Props for StickerDetail: SVG group props.

type StickerDetailProps = Omit<React.SVGProps<SVGGElement>, 'ref'>
StickerProps

Props for Sticker: span props, render, the art, the size, bare and the color axes.

type StickerProps = {
  /**
   * The asset's viewBox, drawn at its native size: `0 0 152 152` for S,
   * `0 0 312 312` for L (other aspect ratios keep the width).
   */
  viewBox: string;
  /**
   * The halo layer: the asset's pre-expanded path, 8 px (`--ds-space-halo`)
   * outside every part, merged into one silhouette with rounded concave
   * bridges and no sharp outer corners. Never a runtime stroke, outline or
   * blur. Filled `--primary1`; no edge, ever. Ignored with `bare`.
   */
  halo?: React.ReactNode;
  /**
   * The line art, stroked in `--role-heading` at the silhouette weight
   * (`--ds-stroke-3` at S, `--ds-stroke-4` at L), round caps and joins, no
   * fill; give ink-spot parts `fill="currentColor"`, and wrap interior lines
   * in `StickerDetail`. No text inside the art.
   */
  children: React.ReactNode;
  /** `s` (default): `--ds-size-art-s`, 152 px. `l`: `--ds-size-art-l`, 312 px. */
  size?: StickerSize;
  /**
   * The bare variant: no halo and no scope of its own; the art draws in the
   * host ground's `--role-heading` with open counters. Never on a
   * decorative pattern. Default `false`.
   */
  bare?: boolean;
  /**
   * Primary Radix scale: the halo's `--primary1` (the sticker's own scope),
   * or, when bare, the host's. Override only with a pairing §2 verifies
   * [D128]. Never defaulted.
   */
  primary?:
    | 'ruby'
    | 'olive'
    | 'sage'
    | 'slate'
    | 'sand'
    | 'gray'
    | 'mauve'
    | 'brown'
    | 'bronze'
    | 'gold'
    | 'red'
    | 'crimson'
    | 'tomato'
    | 'pink'
    | 'plum'
    | 'indigo'
    | 'iris'
    | 'violet'
    | 'purple'
    | null;
  /**
   * Secondary Radix scale: the line's `--role-heading` (step 12). Override
   * only with a verified pairing [D128]. Never defaulted.
   */
  secondary?:
    | 'ruby'
    | 'olive'
    | 'sage'
    | 'slate'
    | 'sand'
    | 'gray'
    | 'mauve'
    | 'brown'
    | 'bronze'
    | 'gold'
    | 'red'
    | 'crimson'
    | 'tomato'
    | 'pink'
    | 'plum'
    | 'indigo'
    | 'iris'
    | 'violet'
    | 'purple'
    | 'amber'
    | 'blue'
    | 'cyan'
    | 'grass'
    | 'green'
    | 'jade'
    | 'lime'
    | 'mint'
    | 'orange'
    | 'sky'
    | 'teal'
    | 'yellow'
    | null;
}
StickerSize

The two native sticker sizes (§6.2): S 152 px, L 312 px.

type StickerSize = 's' | 'l'

Specification: DESIGN-SYSTEM.md §6.5 (the sticker halo), §6.12 (drawings on grounds) and §6.14 (responsive art).