---
version: alpha
name: Opal
description: Warm industrial minimalism — Die Grotesk C grotesque sans on a paper-warm off-white canvas, near-black ink, with a charged signal-yellow and burnt-orange accent pair. Editorial restraint, hairline neutrals, zero-radius hard edges contrasted with full pill controls.
colors:
  # Canvas + ink
  background: "#f5f4ef"
  surface: "#ffffff"
  surface-soft: "#f2f2f2"
  ink: "#111111"
  ink-pure: "#000000"
  ink-near: "#0d0d0d"

  # Brand accents
  primary: "#ffdb00"        # signal yellow — the Opal mark
  accent-orange: "#ec672c"  # burnt orange secondary

  # Warm dark neutrals
  warm-900: "#342e2f"
  warm-800: "#332e2f"

  # Neutral scale
  gray-700: "#767676"
  gray-600: "#7c7c7c"
  gray-500: "#818181"
  gray-300: "#bababa"
  gray-200: "#d5d5d5"
  gray-100: "#e8e7e8"
  gray-50: "#eeeeee"
  hairline: "#f1f1f1"

  # On-color
  on-primary: "#111111"     # ink reads on yellow
  on-accent: "#ffffff"      # white reads on orange
  on-ink: "#f5f4ef"         # canvas-warm text on dark

typography:
  display-hero:
    fontFamily: "Die Grotesk C, system-ui, sans-serif"
    fontSize: 80px
    fontWeight: 700
    lineHeight: 1.00
    letterSpacing: -0.5px
  section-heading:
    fontFamily: "Die Grotesk C, system-ui, sans-serif"
    fontSize: 48px
    fontWeight: 700
    lineHeight: 1.05
    letterSpacing: -0.25px
  heading:
    fontFamily: "Die Grotesk C, system-ui, sans-serif"
    fontSize: 40px
    fontWeight: 700
    lineHeight: 1.10
    letterSpacing: 0px
  sub-heading:
    fontFamily: "Die Grotesk C, system-ui, sans-serif"
    fontSize: 32px
    fontWeight: 400
    lineHeight: 1.20
    letterSpacing: 0px
  card-title:
    fontFamily: "Die Grotesk C, system-ui, sans-serif"
    fontSize: 24px
    fontWeight: 700
    lineHeight: 1.25
    letterSpacing: 0px
  body-large:
    fontFamily: "Die Grotesk C, system-ui, sans-serif"
    fontSize: 18px
    fontWeight: 400
    lineHeight: 1.55
    letterSpacing: 0px
  body:
    fontFamily: "Die Grotesk C, system-ui, sans-serif"
    fontSize: 16px
    fontWeight: 400
    lineHeight: 1.50
    letterSpacing: 0.16px
  body-medium:
    fontFamily: "Die Grotesk C, system-ui, sans-serif"
    fontSize: 16px
    fontWeight: 700
    lineHeight: 1.50
    letterSpacing: 0.16px
  caption:
    fontFamily: "Die Grotesk C, system-ui, sans-serif"
    fontSize: 14px
    fontWeight: 400
    lineHeight: 1.40
    letterSpacing: 0.14px
  label-mono:
    fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace"
    fontSize: 14px
    fontWeight: 400
    lineHeight: 1.40
    letterSpacing: 0.48px

spacing:
  micro: 2px
  xs: 4px
  sm: 8px
  md: 12px
  lg: 16px
  xl: 24px
  2xl: 40px
  3xl: 64px
  4xl: 120px

rounded:
  none: 0px
  xs: 4px
  sm: 8px
  md: 12px
  pill: 9999px

components:
  button-primary:
    backgroundColor: "{colors.ink}"
    textColor: "{colors.on-ink}"
    typography: "{typography.body-medium}"
    rounded: "{rounded.pill}"
    padding: 12px 24px
  button-primary-hover:
    backgroundColor: "{colors.ink-pure}"
    textColor: "{colors.on-ink}"
    typography: "{typography.body-medium}"
    rounded: "{rounded.pill}"
    padding: 12px 24px
  button-accent:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.on-primary}"
    typography: "{typography.body-medium}"
    rounded: "{rounded.pill}"
    padding: 12px 24px
  button-secondary:
    backgroundColor: "{colors.background}"
    textColor: "{colors.ink}"
    typography: "{typography.body-medium}"
    rounded: "{rounded.pill}"
    padding: 12px 24px
    borderColor: "{colors.gray-200}"
  badge:
    backgroundColor: "{colors.accent-orange}"
    textColor: "{colors.on-accent}"
    typography: "{typography.caption}"
    rounded: "{rounded.pill}"
    padding: 4px 12px
  card:
    backgroundColor: "{colors.surface}"
    textColor: "{colors.ink}"
    rounded: "{rounded.none}"
    padding: 32px
    borderColor: "{colors.hairline}"
  card-soft:
    backgroundColor: "{colors.surface-soft}"
    textColor: "{colors.ink}"
    rounded: "{rounded.none}"
    padding: 32px
    borderColor: "{colors.gray-100}"
  input:
    backgroundColor: "{colors.surface}"
    textColor: "{colors.ink}"
    typography: "{typography.body}"
    rounded: "{rounded.none}"
    padding: 12px 16px
    borderColor: "{colors.gray-200}"
  input-focus:
    backgroundColor: "{colors.surface}"
    textColor: "{colors.ink}"
    borderColor: "{colors.ink}"
  nav-bar:
    backgroundColor: "{colors.background}"
    textColor: "{colors.ink}"
    typography: "{typography.body-medium}"
    padding: 16px 24px
    borderColor: "{colors.hairline}"
  divider:
    backgroundColor: "{colors.hairline}"
    height: 1px
    width: 100%
---

# Opal Design System

## Overview

Opal makes premium webcams and the Tadpole — small, considered hardware objects — and the site reads exactly like the product philosophy it sells: restraint, warmth, and precision. The canvas is not pure white but a paper-warm off-white (`{colors.background}`), which gives the whole page the feel of high-grade stock rather than a screen. Against it, near-black ink (`{colors.ink}`) carries the type, and the layout leans on whitespace and editorial rhythm rather than chrome to organize itself.

The typographic voice is the identity. Opal sets everything in **Die Grotesk C**, a tight, contemporary grotesque sans with squared terminals and a confident, slightly mechanical cadence. It runs in just two weights — 400 for reading and 700 for announcing — and scales from a billboard 80px hero down to 14px captions. There is no serif, no display flourish, and no decorative typeface. The grotesque does all the work, which keeps the page feeling industrial and exact.

Color is used as signal, not decoration. The brand's charged signal-yellow (`{colors.primary}`) is the Opal mark and appears as a high-voltage accent; a burnt orange (`{colors.accent-orange}`) backs it as a warm secondary. Everything else is a disciplined neutral ramp — hairline grays from `{colors.hairline}` to `{colors.gray-700}`, plus a pair of warm darks (`{colors.warm-900}`) that keep even the shadows off-cool. Accents are rationed; most of any given screen is canvas, ink, and a single hairline.

Structurally, Opal plays hard edges against soft ones. Surfaces, cards, inputs, and images are **zero-radius** — hard, square, architectural. The only round things are the interactive controls: buttons and pills run full `{rounded.pill}`. That contrast — sharp containers, soft controls — is the system's signature tactile move.

**Key Characteristics:**
- Die Grotesk C grotesque sans for everything, two weights only (400 / 700)
- Paper-warm off-white canvas (`{colors.background}`) instead of pure white
- Signal-yellow (`{colors.primary}`) + burnt-orange (`{colors.accent-orange}`) accents, rationed as signal
- Zero-radius hard-edged surfaces contrasted with full-pill controls
- Hairline neutral dividers instead of heavy borders or shadows
- Warm dark neutrals (`{colors.warm-900}`) keep the palette off-cool
- Editorial whitespace and rhythm over UI chrome

## Colors

### Primary
- **Canvas Warm** (`{colors.background}`): The page background — warm off-white, the dominant surface.
- **Opal Ink** (`{colors.ink}`): Primary text and headings, near-black.
- **True Black** (`{colors.ink-pure}`): Hover/pressed states, deepest contrast.

### Brand Accents
- **Signal Yellow** (`{colors.primary}`): The Opal mark — high-voltage accent fills, ink reads on top.
- **Burnt Orange** (`{colors.accent-orange}`): Warm secondary accent, badges, white reads on top.

### Warm Darks
- **Warm 900** (`{colors.warm-900}`): Warm dark panels and deep neutrals.
- **Warm 800** (`{colors.warm-800}`): Secondary warm dark.

### Neutral Scale
- **Gray 700** (`{colors.gray-700}`): Secondary text, muted labels.
- **Gray 600 / 500** (`{colors.gray-600}` / `{colors.gray-500}`): Tertiary text, captions.
- **Gray 300 / 200** (`{colors.gray-300}` / `{colors.gray-200}`): Input borders, control outlines.
- **Gray 100 / 50** (`{colors.gray-100}` / `{colors.gray-50}`): Soft fills, subtle dividers.
- **Hairline** (`{colors.hairline}`): The default 1px divider and card edge.

### Surfaces
- **Surface** (`{colors.surface}`): Pure-white cards that sit above the warm canvas.
- **Surface Soft** (`{colors.surface-soft}`): Quiet gray panel for grouped content.

## Typography

### Font Family
- **Primary**: `Die Grotesk C`, with fallbacks: `system-ui, sans-serif`
- **Mono (labels only)**: `ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace`

### Hierarchy

The complete type scale lives in the `typography:` token block above. Reference tokens directly (`{typography.display-hero}`, `{typography.body}`, etc.).

| Token | Use |
|---|---|
| `display-hero` | 80px hero — billboard headline |
| `section-heading` | 48px section titles |
| `heading` | 40px sub-section titles |
| `sub-heading` | 32px lighter intros (weight 400) |
| `card-title` | 24px card and feature titles |
| `body-large` | 18px lead paragraphs |
| `body` | 16px standard reading text |
| `body-medium` | 16px emphasized / UI labels (weight 700) |
| `caption` | 14px metadata, captions |
| `label-mono` | 14px monospace technical labels |

### Principles
- **One grotesque, two weights**: 400 reads, 700 announces. No third weight, no second family.
- **Warm grotesque restraint**: The face is mechanical and exact; the warm canvas softens it so the page feels considered, not clinical.
- **Light tracking on body**: Body and caption carry a touch of positive tracking (0.14–0.16px) for legibility on the warm stock; headings sit tight to neutral.

## Layout

### Spacing System
The complete scale lives in the `spacing:` token block above. Built on an 8px rhythm, with a large jump to `{spacing.4xl}` (120px) for the gallery-style section gaps.

### Grid & Container
- Centered single-column hero with generous top padding
- Feature sections use 2–3 column grids on hard-edged surfaces
- Hairline (`{colors.hairline}`) dividers separate major sections — no boxes, no shadows

### Whitespace Philosophy
- **Editorial emptiness**: Large vertical gaps (`{spacing.3xl}`–`{spacing.4xl}`) let the type and product imagery breathe.
- **Hard containers, soft controls**: Square zero-radius surfaces give the page an industrial, product-catalog feel; only pills break the grid.
- **Signal economy**: Accent color appears rarely and deliberately — most of the page is canvas and ink.

## Shapes

| Token | Value | Use |
|---|---|---|
| `none` | 0px | Cards, surfaces, inputs, images — the default |
| `xs` | 4px | Small inline elements |
| `sm` | 8px | Minor grouped controls |
| `md` | 12px | Occasional soft containers |
| `pill` | 9999px | Buttons, badges, all interactive controls |

## Components

The full component spec lives in the `components:` token block above. Reference tokens directly (`{components.button-primary}`, `{components.card}`).

### Buttons
- **`button-primary`** — Ink fill, warm-canvas text, full pill. The default CTA.
- **`button-accent`** — Signal-yellow fill with ink text — the brand-charged CTA.
- **`button-secondary`** — Canvas fill with gray-200 outline, full pill.

### Badges
- **`badge`** — Burnt-orange fill, white text, full pill, 14px caption.

### Cards
- **`card`** — White surface, zero radius, hairline edge, 32px padding.
- **`card-soft`** — Quiet gray panel for grouped content.

### Inputs
- **`input`** — White, zero radius, gray-200 border; focus deepens the border to ink.

### Navigation
- **`nav-bar`** — Warm-canvas header, ink labels (weight 700), hairline bottom edge.

## Do's and Don'ts

### Do
- Use the warm off-white canvas (`{colors.background}`) — never pure white for the page
- Set everything in Die Grotesk C, weights 400 and 700 only
- Keep surfaces, cards, and inputs zero-radius; reserve pills for controls
- Ration the signal-yellow and orange — accent as signal, not fill
- Use hairline dividers (`{colors.hairline}`) instead of shadows or heavy borders

### Don't
- Don't round cards or images — hard edges are the identity
- Don't introduce a second typeface or a third weight
- Don't flood the page with yellow — it loses its charge
- Don't use pure-white page backgrounds — the warmth matters
- Don't lean on drop shadows for separation — use space and hairlines

## Responsive Behavior

### Breakpoints
| Name | Width | Key Changes |
|------|-------|-------------|
| Mobile | <600px | Single column, hero scales 80px → ~40px |
| Tablet | 600–1024px | 2-column grids begin |
| Desktop | >1024px | Full multi-column layout, max content width |

### Collapsing Strategy
- Hero: 80px → ~40px, maintains 700 weight
- Navigation: inline links → menu toggle
- Feature grids: 3-column → 2 → single column
- Section spacing: 120px → ~64px on mobile

## Agent Prompt Guide

### Quick Color Reference
- Page background: Canvas Warm `{colors.background}`
- Heading / body text: Opal Ink `{colors.ink}`
- Secondary text: Gray 700 `{colors.gray-700}`
- Primary CTA: Ink `{colors.ink}` fill, pill
- Brand accent CTA: Signal Yellow `{colors.primary}`, ink text
- Divider: 1px `{colors.hairline}`

### Example Component Prompts
- "Hero on warm off-white (`{colors.background}`). Headline 80px Die Grotesk C weight 700, line-height 1.0, color `{colors.ink}`. Subtitle 18px weight 400, `{colors.gray-700}`. Ink pill CTA (`{colors.ink}` fill, white-warm text, 9999px radius, 12px 24px padding)."
- "Card: pure-white surface, zero radius, 1px `{colors.hairline}` border, 32px padding. Title 24px Die Grotesk C weight 700, body 16px weight 400 `{colors.gray-700}`."
- "Accent button: signal-yellow `{colors.primary}` fill, ink `{colors.ink}` text, full pill, 16px weight 700."

### Iteration Guide
1. Warm canvas + ink + one hairline is the baseline of any screen
2. Two weights only: 400 reads, 700 announces
3. Square everything except controls (pills)
4. Accent color is signal — use it once, deliberately
5. Separate with space and hairlines, never shadows

---

## Attribution

Independent design analysis from [Design Swatches](https://designmd.santiagoalonso.com) by [Santiago Alonso](https://santiagoalonso.com). Based on publicly observable interface patterns. Not affiliated with or endorsed by Opal. Brand names and trademarks belong to their respective owners.
