Design System
Tokens, primitives and composition patterns powering MDX Engage. Single source of truth in apps/web/src/components/ui/.
How to use
Import primitives from @/components/ui/primitives and the page chrome from @/components/ui/shell. Stick to the StatusTone token for semantic color instead of hand-picked Tailwind shades.
primitives.statusToneClass
// (neutral | blue | green | red | amber)
01 · Tokens
Status tones
Semantic color scale. Use via tone prop on Pill, Dot, Stat, Banner. Never hand-roll color for status.
tone="neutral"tone="blue"tone="green"tone="red"tone="amber"02 · Tokens
Surfaces & dividers
Layered dark surfaces and border alphas. Hex values should NOT appear outside ui/ and layout.tsx.
app bg#08090csidebar bg#0a0b0ecard bg#0e1014surface /02rgba(255,255,255,0.02)surface /04rgba(255,255,255,0.04)surface /08rgba(255,255,255,0.08)divider /08rgba(255,255,255,0.08)divider /10rgba(255,255,255,0.10)03 · Tokens
Radii
Rounded scale used across chrome. Cards default to xl; hero-style Metric/Section cards use [1.5rem]/[1.9rem].
rounded-mdrounded-lgrounded-xlrounded-[1.5rem]rounded-[1.9rem]04 · Tokens
Typography
Geist Sans + Geist Mono. Compact scale optimized for information density on an operator console.
Page titleSection titleCard titleBodyMuted bodySmall / hintEyebrow05 · Primitives
Button
primary = emphasized action · secondary = default · ghost = low-emphasis · danger = destructive.
Size md (default)
Size sm
06 · Primitives
Pill & Dot
Inline status markers. Combine Pill + Dot for list rows where a glanceable indicator sits next to context.
07 · Primitives
Banner
Inline notifications placed above a panel or toolbar. Prefer Banner to hand-made alert divs.
08 · Primitives
Card & CardHeader
Primary container. Pass padding=none|sm|md|lg to control internal spacing. Use CardHeader for title rows.
padding="sm"
Tight container for list rows.
padding="md" · default
Standard panel spacing.
padding="lg"
Breathing room for empty/hero states.
With CardHeader
Dense title + description + action slot, optimized for panel tops.
Body content sits under the header with a consistent 16px gap.
09 · Primitives
Forms: Field + input tokens
Form controls use shared class strings (inputClass, selectClass, textareaClass) to stay visually uniform.
Anatomy
Field renders the label + hint row; inputs bring the border, focus ring and placeholder color.
- •
inputClass— base text/number/email/time inputs - •
selectClass— addsappearance-none - •
textareaClass— addsresize-y+ leading - • Focus ring is always blue-500/40 — do not override per field.
10 · Data display
Stat (primitive) vs MetricCard (composed)
Both render KPI tiles. Stat is compact and tone-ring based; MetricCard is taller with a gradient glow. Prefer Stat for dense grids, MetricCard for hero headers.
Stat — 4×
In review
12
Approved today
7
Rate blocked
3
Failed
1
MetricCard — 3×
Today published
12 / 20
Cap resets at midnight America/Caracas.
Success rate
94%
Trailing 7 days across 189 publishes.
Cooldown
69s
Next publish eligible in just over a minute.
11 · Patterns
Empty state + list composition
Use Empty for zero-state surfaces. Compose Card rows inside a SectionCard to match the existing operator screens.
No watchlist accounts yet
Import a handle list or add accounts one by one to start discovering opportunities.
Queue preview
Composition example — 3 rows, real spacing.
@marcelocedeno
Wireframes matter more than pixels early on.
@richmtz
Design systems lose value without adoption metrics.
@mdx_inc
Shipped rate-limit Phase 2 this morning.
12 · Guardrails
Do / Don't
Keep new screens on-brand by following these rules.
Do
- Use
StatusTonefor all semantic color. - Reach for
Cardbefore rolling a new panel div. - Keep hex values inside
ui/andlayout.tsx. - Wrap forms with
Fieldfor label + hint alignment. - Use
Statin dense grids,MetricCardin hero rows.
Don't
- Don't hand-pick Tailwind colors per component — pass a tone.
- Don't duplicate
rounded-xl border border-white/8inline — use Card. - Don't introduce new radius values outside the scale.
- Don't override focus rings; the blue ring is intentional.
- Don't create yet another KPI tile variant — extend Stat/MetricCard.