---
version: alpha
schema: adant-design-v1
name: AdAnt Studio
description: AdAnt authenticated product design system, light theme.
scope: studio
theme: light
colors:
  canvas: "#f5f5f5"
  canvas-soft: "#fafafa"
  surface-card: "#ffffff"
  surface-strong: "#f0efed"
  surface-dark: "#0c0a09"
  surface-dark-elev: "#1c1917"
  hairline: "#e7e5e4"
  hairline-strong: "#d6d3d1"
  ink: "#0c0a09"
  ink-soft: "#292524"
  on-primary: "#ffffff"
  body: "#4e4e4e"
  muted: "#706a62"
  muted-label: "#706a62"
  muted-soft: "#a8a29e"
  success: "#16a34a"
  warning: "#d97706"
  error: "#dc2626"
  error-strong: "#b91c1c"
  info: "#2f6bd6"
  clay: "#cd7f5f"
  clay-warm: "#c2855c"
  clay-rose: "#cf8a96"
  clay-mauve: "#b386a0"
  clay-sand: "#d49a7e"
  aurora-edge-from: "#5ea0ff"
  aurora-edge-mid: "#9b7be8"
  aurora-edge-to: "#f0a07a"
typography:
  font-display: "\"EB Garamond\", \"Times New Roman\", Georgia, serif"
  font-sans: "\"Inter\", system-ui, -apple-system, \"Segoe UI\", sans-serif"
  font-mono: "\"JetBrains Mono\", ui-monospace, \"SF Mono\", Menlo, monospace"
  text-display-mega: "64px"
  text-display-xl: "48px"
  text-display-lg: "36px"
  text-display-md: "32px"
  text-display-sm: "24px"
  text-studio-2xs: "10.5px"
  text-studio-xs: "11.5px"
  text-studio-sm: "12px"
  text-studio-md: "12.5px"
  text-studio-base: "13px"
  text-studio-lg: "13.5px"
  text-studio-xl: "14px"
  text-studio-title: "20px"
  text-studio-dialog-title: "22px"
  text-studio-stat: "34px"
spacing:
  unit: "4px"
  language: "Tailwind spacing utilities"
rounded:
  radius-control-sm: "8px"
  radius-control-compact: "9px"
  radius-control: "10px"
  radius-popover: "12px"
  radius-card: "16px"
  radius-dialog: "18px"
  radius-media: "20px"
  radius-composer: "24px"
  radius-pill: "9999px"
motion:
  duration-instant: "120ms"
  duration-fast: "140ms"
  duration-ui: "160ms"
  duration-dialog-backdrop: "180ms"
  duration-enter: "260ms"
  ease-standard: "cubic-bezier(0.2, 0.7, 0.2, 1)"
  ease-out: "cubic-bezier(0.16, 1, 0.3, 1)"
layers:
  z-menu: "200"
  z-sticky: "20"
  z-shell-overlay: "30"
  z-feature-overlay: "120"
  z-settings: "340"
  z-settings-dialog: "350"
  z-payment-redirect: "360"
  z-dialog: "400"
  z-toast: "500"
components:
  StudioButton:
    variants: [primary, outline, ghost, danger, danger-solid]
    sizes: [sm, md]
  StudioChip:
    tones: [neutral, ink, success, warning, error, info]
  StudioDialog:
    sizes: [sm, md, lg]
  StudioField:
    states: [default, checking, valid, invalid]
  StudioMenu:
    sizes: [sm, md]
  StudioPage:
    includes: [SectionCard, StatCard, SegmentTabs]
  StudioTable:
    includes: [Pagination]
---

<!-- Generated by scripts/generate-design-manifests.mjs. Edit the canonical docs or token sources, then run pnpm design:generate. -->

# AdAnt Studio design system

This is the canonical implementation contract for AdAnt product UI. Historical
prototype notes may explain individual screens, but this document owns the
current visual language and CSS architecture.

## 1. Visual language

Studio uses a warm neutral canvas, white elevated surfaces, quiet hairlines,
soft shadows, editorial EB Garamond display headings, Inter UI text, JetBrains
Mono numeric text, and clay as the primary brand accent. Studio is light-only.

The public marketing experience is deliberately independent and is documented
in [marketing.md](./design.marketing.md). Marketing styles must remain scoped to the
landing feature and must not redefine Studio tokens.

## 2. Sources of truth

- `packages/ui/styles` owns every CSS foundation and selectable theme.
- `packages/ui/styles/src/themes/studio.css` owns Studio color, shape, motion,
  focus, elevation, layer, typography, generic primitive aliases, and semantic
  Tailwind mappings.
- `packages/ui/styles/src/studio/type-scale.css` owns display typography and
  shared texture utilities; `studio.css` composes the complete app entrypoint.
- `packages/ui/studio/src/studio-*.tsx` owns reusable product primitives using
  static semantic Tailwind class maps and contains no CSS.
- `apps/web/src/features/studio` owns feature-only layout and choreography.

A CSS token or utility shared by multiple surfaces belongs in
`@anyloop/ui-styles`; shared React structure and interaction belong in
`@anyloop/ui-studio`. Feature CSS must not recreate either shared contract.

## 3. Token language

Components consume semantic names rather than visual literals:

- canvas and surfaces: `--canvas`, `--surface-card`, `--surface-strong`
- text: `--ink`, `--body`, `--muted`, `--muted-label`
- lines: `--hairline`, `--hairline-strong`
- accents and status: `--clay`, `--success`, `--warning`, `--error`, `--info`
- shape: `--radius-control`, `--radius-card`, `--radius-composer`, `--radius-pill`
- motion: `--duration-*`, `--ease-standard`, `--ease-out`
- layers: `--z-menu`, `--z-dialog`, `--z-toast`

`--muted-soft` is reserved for placeholders, disabled text, and decoration. Any
small text a user must read uses `--muted-label` or a stronger token.

Raw colors are declared only in the token file. A truly feature-specific brand
or media literal may be declared as a component-scoped custom property and must
not duplicate an existing semantic token.

The complete `studio.css` entrypoint loads the theme definition, but Studio
values activate only under `[data-theme="studio"]`. `apps/admin-web` sets that
attribute statically; `apps/web` manages it for the lifetime of Studio routes
so public routes keep the default theme and body-level portals inherit the
correct values. Additional runtime themes must implement the same generic and
product semantic contracts under their own selector; React components must not
branch on the selected theme.

## 4. Tailwind and component usage

Tailwind is the everyday styling language. Use structural utilities for grid,
flex, spacing, alignment, and responsive behavior, and semantic utilities for
visual decisions, for example:

```tsx
<div className="rounded-card border border-hairline bg-surface-card text-ink shadow-soft" />
```

Shared React primitives keep complete, statically discoverable class strings or
variant maps in their component files. Do not build Tailwind class names through
string interpolation.

Do not use arbitrary color, radius, shadow, or z-index utilities in Studio.
Prefer a shared primitive such as `StudioButton` or `StudioDialog` when it owns
repeated behavior and states. Feature CSS is reserved for pseudo-elements,
complex gradients, keyframes, third-party overrides, and feature-specific
composition.

## 5. Interaction and accessibility

Every interactive control has hover, disabled, and `:focus-visible` treatment.
Focus uses the shared focus tokens. Functional text targets WCAG AA contrast.
Every nonessential animation has a `prefers-reduced-motion` fallback; JS-driven
motion also uses the Studio motion provider.

`@anyloop/ui-styles/studio.css` supplies the final scoped keyboard-focus and
reduced-motion safety net for the Studio stage and sidebar. Component styles may
specialize that treatment but must not remove it.

Global classes and keyframes must be uniquely owned. Shared classes use the
`studio-` prefix plus a component name; app-local feature styles use a feature
prefix or CSS Modules.

## 6. Published contract

`/design.md` is generated from this document and the live Studio tokens. It is
the public, machine-readable light-theme contract. AdAnt does not publish a
`/design.dark.md` contract until a complete dark theme and visual baseline exist.

## 7. Validation

- `pnpm --filter @anyloop/web check` enforces the Studio CSS contract and checks
  that published design manifests are current.
- `pnpm --filter @anyloop/web test` covers UI behavior.
- `pnpm --filter @anyloop/e2e test:visual` compares the current UI with committed
  desktop and mobile screenshots.

Screenshot baselines change only for intentional design changes after the diff
has been reviewed. Structural consolidation should normally produce no new
visual diffs.
