Dot iconDesign system
ComponentSite and product

Dot icon

Static SVG icon defined by rows of dots and rings.

npx context-ds add dot-glyph
On the site
In the product

Usage

Use it for

Plan marks, card glyphs, empty states.

Avoid

  • Dot icons as body illustrations
  • Moving or melting dots (use a glyph tile or glyph melt)

Example

examples/dot-glyph.tsx
import { DotGlyph } from "@/components/ui/dot-glyph";// 2 is a solid dot, 1 a ring, anything else an empty cell.const GEM = ["..2..", ".222.", "22222", ".222.", "..2.."];const SEARCH = ["222..", "2.2..", "222..", "...2.", "....2"];const PAGE = ["2222.", "2..22", "2...2", "2...2", "22222"];const CHECK = ["1111111", "1111112", "1111122", "2111221", "2212211", "1222111", "1121111"];// The dot icon is a static SVG icon: small, inline with text, in the text's color.export function Product() {  return (    <div className="flex flex-col items-start gap-5">      <span className="flex items-center gap-1.5 text-body-sm text-fg">        <DotGlyph rows={GEM} className="size-4 text-brand" />        4,820 credits      </span>      <div className="flex flex-wrap items-center gap-4 text-body-sm text-fg-muted">        <span className="flex items-center gap-1.5">          <DotGlyph rows={PAGE} className="size-3 text-brand" />          Scrape        </span>        <span className="flex items-center gap-1.5">          <DotGlyph rows={SEARCH} className="size-3 text-fg/55" />          Search        </span>      </div>    </div>  );}export function Site() {  return (    <div className="flex items-center gap-4">      <DotGlyph rows={CHECK} className="size-12 text-fg-brand" />      <p className="text-body text-fg">SOC 2 Type II</p>    </div>  );}

Source

components/ui/dot-glyph.tsx
import type { CSSProperties, ReactNode } from "react";export const GLYPH_PITCH = 3.2;export const GLYPH_DOT_RADIUS = 1.25;const GLYPH_RING_STROKE = 0.55;/** * An icon drawn on a small square grid of dots, the brand's dot language. Each row is a string: 2 is a solid dot, * 1 a hollow ring, anything else an empty cell. Each dot carries --dot-delay, growing along the diagonal from the top * left, for animations that sweep across the glyph. Children draw on the same grid, above the dots. */export function DotGlyph({ rows, className, dotStaggerMs = 0, children }: { rows: readonly string[]; className?: string; dotStaggerMs?: number; children?: ReactNode }) {  const size = rows.length * GLYPH_PITCH;  return (    <svg aria-hidden="true" viewBox={`0 0 ${size} ${size}`} data-slot="dot-glyph" className={className}>      {rows.flatMap((row, y) =>        [...row].map((cell, x) => {          if (cell !== "1" && cell !== "2") return null;          const solid = cell === "2";          return (            <circle              key={`${x}:${y}`}              cx={(x + 0.5) * GLYPH_PITCH}              cy={(y + 0.5) * GLYPH_PITCH}              r={solid ? GLYPH_DOT_RADIUS : GLYPH_DOT_RADIUS - GLYPH_RING_STROKE / 2}              fill={solid ? "currentColor" : "none"}              stroke={solid ? "none" : "currentColor"}              strokeWidth={GLYPH_RING_STROKE}              style={{ "--dot-delay": `${(x + y) * dotStaggerMs}ms` } as CSSProperties}            />          );        }),      )}      {children}    </svg>  );}

Reference: context-dashboard c0ddf7a src/components/ui/dot-glyph.tsx.