Zenoba
Documentation

Zenoba Design System

Complete guide to tokens, colors, typography and visual components. Direction A — inspired by Linear and Stripe.

Design Philosophy

The Zenoba design system follows a minimalist approach inspired by Linear, Stripe and Vercel. Every element serves a functional purpose. No superfluous decoration, no distracting visual effects. The interface must be calm, intelligent and professional.

Simple by default

Advanced features are hidden until the user needs them. Strict progressive disclosure.

Powerful on demand

Configuration tools, advanced filters and expert views are accessible without overloading the main interface.

Visual precision

4px grid, 1px hairline borders, lightweight typography (font-weight 400-500). Zero visual noise.

Color Palette

Brand and accents

Semantic colors

Surfaces and text — Light mode

Surfaces and text — Dark mode

Usage
/* CSS */
.card { background: var(--surface); border: 1px solid var(--border); }
.label { color: var(--foreground-muted); }

/* Tailwind */
<div className="bg-surface border border-border text-foreground" />
<span className="text-foreground-muted" />

Typography

Primary font: Geist Sans (Vercel). Fallback: Inter, system-ui. Headings use font-weight 500 (medium). Body text uses font-weight 400 (regular). Bold (700) is NEVER used in the interface — it breaks the visual balance of the design system.

Aa — 30pxtext-3xl font-medium
Aa — 20pxtext-xl font-medium
Aa — 16pxtext-base font-medium
Aa — 14pxtext-sm (corps de texte)
Aa — 12pxtext-xs text-foreground-muted

Forbidden: font-bold / font-weight: 700. Only use font-medium (500) for headings and font-normal (400) for body text.

Border Radius

Constrained radius scale. Each context has its predefined radius. Do not invent intermediate values.

6px--radius-sminputs
10px--radius-mdcards
14px--radius-lgmodals
18px--radius-xlpanels
pill / badge
rounded-full (9999px)

Shadows

The Zenoba design system replaces shadows with 1px hairline borders (Linear style). Classic box-shadows are not used on cards and sections. Exception: popovers, dropdowns and modals use --shadow-md for elevation.

/* Pas de box-shadow generiques dans le design system Zenoba.
   On utilise des bordures hairline 1px a la place. */

/* Correct */
<div className="border border-border" />

/* Incorrect */
<div className="shadow-lg" />  /* Ne pas utiliser */

/* Exceptions : les popover/dropdown utilisent --shadow-md */
--shadow-md: 0 2px 8px rgba(0,0,0,0.06), 0 0 0 1px rgba(0,0,0,0.04);

Spacing

Base grid: 4px. All spacings (padding, margin, gap) must be multiples of 4px. This ensures pixel-perfect alignment across the entire interface.

4
8
12
16
20
24
32
40
48
/* Base : 4px (Tailwind : 1 unit = 4px) */
p-1  = 4px    p-2  = 8px    p-3  = 12px
p-4  = 16px   p-5  = 20px   p-6  = 24px
gap-1 = 4px   gap-2 = 8px   gap-3 = 12px
gap-4 = 16px  gap-6 = 24px  gap-8 = 32px

CSS Variables and Tailwind Classes

All components use CSS variables (custom properties) that automatically switch between light and dark modes. Here is the mapping between variables, values and Tailwind classes.

CSS VariableValeurClasse Tailwind
--foreground#171717text-foreground
--foreground-muted#737373text-foreground-muted
--foreground-subtle#A3A3A3text-foreground-subtle
--background#FAFAFAbg-background
--surface#FFFFFFbg-surface
--surface-hover#F5F5F5bg-surface-hover
--border#E5E5E5border-border
--border-subtle#F0F0F0border-border-subtle
--primaryvar(--primary)bg-primary / text-primary
--successvar(--success)text-success
--warningvar(--warning)text-warning
--dangervar(--danger)text-danger

Buttons

Four button variants: Primary (main action), Gradient CTA (marketing pages), Outline (secondary actions) and Ghost (tertiary actions). Standard height: 36px (h-9). Border radius: 10px.

/* Primary */
<button className="h-9 px-4 rounded-[10px] bg-primary text-white
  text-sm font-medium hover:bg-primary-hover transition-colors">

/* Gradient CTA (pages marketing) */
<button className="h-9 px-4 rounded-[10px] bg-gradient-to-r
  from-primary to-accent text-white text-sm font-medium
  hover:opacity-90 transition-opacity">

/* Outline */
<button className="h-9 px-4 rounded-[10px] border border-border
  bg-surface text-foreground text-sm font-medium
  hover:bg-surface-hover transition-colors">

/* Ghost */
<button className="h-9 px-4 rounded-[10px] text-foreground-muted
  text-sm font-medium hover:bg-surface-hover
  hover:text-foreground transition-colors">

Icons

Exclusive library: Lucide React. StrokeWidth fixed at 1.75 (thinner than default). No emoji in code. Sizes adapted to usage context.

14pxxs (sidebar, badges)
16pxsm (boutons, inline)
20pxmd (sections, cards)
24pxlg (titres, heros)
import { Plus, Settings, Trash2 } from 'lucide-react';

/* Standard : strokeWidth 1.75, taille adaptee au contexte */
<Plus size={16} strokeWidth={1.75} className="text-foreground" />
<Settings size={14} strokeWidth={1.75} className="text-foreground-muted" />
<Trash2 size={14} strokeWidth={1.75} className="text-danger" />

Dark Mode

Dark mode uses the .dark class on the HTML root. CSS variables switch automatically — no dark: prefix is needed for design system tokens. Exception: native Tailwind colors (bg-blue-50) require a dark: override.

/* globals.css — les tokens basculent automatiquement */
:root {
  --background: #FAFAFA;
  --surface: #FFFFFF;
  --foreground: #171717;
  --border: #E5E5E5;
  --primary: var(--primary);
}

.dark {
  --background: #0A0A0B;
  --surface: #141414;
  --foreground: #FAFAFA;
  --border: #262626;
  --primary: #6B6CFF;
}

/* Pas besoin de dark: prefix dans les composants.
   Les classes Tailwind (bg-surface, text-foreground, border-border)
   utilisent les CSS variables qui basculent automatiquement. */

/* Exception : couleurs Tailwind natives */
<div className="bg-blue-50 dark:bg-blue-950/30" />

Anti-patterns

No Bootstrap

No Bootstrap components, no .btn, .card, .container Bootstrap classes. Zenoba uses exclusively Tailwind + CSS variables.

No Material Design

No MUI components, no ripple effects, no Material elevation. Zenoba aesthetics are flatter and more minimalist.

No font-bold (700)

Maximum font-weight is 500 (medium). Bold 700 breaks the visual balance. Use font-medium for headings, font-normal for text.

No heavy shadows

No shadow-lg, shadow-xl, shadow-2xl. Cards use 1px hairline borders (border-border). Only popovers have a light shadow.

No glassmorphism

No excessive backdrop-blur, no decorative transparency, no colored background gradient. The background is opaque and neutral.

No emoji in code

Use Lucide icons for all iconography. Emoji are reserved for user content (chat, comments), never in the system interface.

Avatars

Avatars are generated by the Boring Avatars library (same lib as Linear). The palette uses the 5 Zenoba brand colors. The UserAvatar component accepts a name (unique SVG generation), a real photo (src), an online indicator and several visual variants.

KA
MR
JD
SL
YP
EN
import { UserAvatar } from '@/components/shared/user-avatar';

/* Palette Zenoba : var(--primary), var(--secondary), var(--accent), var(--success), var(--warning) */

/* Avatar genere (boring-avatars, variant beam) */
<UserAvatar name="Khalid Amrani" size={32} />

/* Avec indicateur en ligne */
<UserAvatar name="Khalid Amrani" size={32} online />

/* Avec photo reelle */
<UserAvatar name="Marie Roy" size={40} src="/avatars/marie.jpg" />

/* Variantes disponibles : beam, marble, pixel, sunset, ring, bauhaus */
<UserAvatar name="Jean Doe" variant="marble" />