Guidelines

Practical rules for building with RDS consistently.

Typography

Use the three-font system intentionally:

  • font-display (Instrument Serif) — hero headings, large display text only. Don’t use for body copy.
  • font-mono (DM Mono) — code blocks, labels, tags, timestamps, numeric data.
  • font-sans (DM Sans) — everything else: body, UI text, captions.

Type scale usage:

  • text-4xl / text-5xl — page heroes only
  • text-2xl / text-3xl — section headings
  • text-lg — subheadings, card titles
  • text-sm — secondary text, metadata, captions
  • text-xs — badges, tags, helper text

Color

RDS uses a single ink color at varying opacities for hierarchy:

  • text-foreground — primary text (full ink)
  • text-muted-foreground — secondary text (~60% opacity)
  • text-muted-foreground/60 — disabled / hint text

Avoid introducing custom colors. Use semantic tokens: bg-background, bg-muted, bg-card, border, ring.

For destructive actions: text-destructive, bg-destructive.

Spacing

Use the Tailwind spacing scale. Prefer multiples of 4:

  • gap-2 (8px) — tight groups (icon + label)
  • gap-4 (16px) — form fields, card internals
  • gap-6 (24px) — section content
  • gap-8 (32px) — between major sections

Max content width: 1140px (max-w-screen-xl), padding: px-8 (32px).

Component Composition Rules

  • Always use asChild on trigger components when passing a custom element (e.g. Next.js Link inside Button)
  • Always pair inputs with a Label using matching id / htmlFor
  • Wrap form inputs in FormField > FormItem > FormControl when using React Hook Form
  • Use cn() utility for conditional classNames — never string concatenation

Multimedia Guidelines

  • Media controls should always have visible play/pause state — don’t rely on icon alone
  • Waveform displays need a loading skeleton while audio data is fetched
  • Timeline comment markers need aria-label with the timestamp included
  • Audio players must respect prefers-reduced-motion for waveform animations

Do / Don’t

DoDon’t
Use font-mono for timestamps and numeric dataUse serif fonts for body copy
Use semantic color tokensHardcode hex values in className
Use asChild to forward props to custom elementsWrap components in unnecessary divs
Use Sonner (toast) for notificationsUse the legacy Toast component
Show skeleton while content loadsShow empty space or layout shift