# Badho Design System

A single source of truth for the Badho product UI — color, typography, spacing, iconography, and the component library. All values below are pulled directly from the live token file (`src/index.css`) and the shipped component implementations, not from mockups — this document should always match the running app and its Storybook.

---

## 1. Foundations

### 1.1 Color

Colors are defined in two layers: **primitives** (raw palettes, never used directly in product code) and **semantic tokens** (the aliases components actually consume). Always build UI with semantic tokens so theme changes propagate automatically.

#### Primitives

**Violet Primary** (brand)
| Token | Hex |
|---|---|
| `violet-primary-50` | `#f8eeff` |
| `violet-primary-100` | `#ecd2ff` |
| `violet-primary-200` | `#d7a3ff` |
| `violet-primary-300` | `#c073ff` |
| `violet-primary-400` | `#ad4eff` |
| `violet-primary-500` | `#892cdc` |
| `violet-primary-600` | `#6e1eb5` |
| `violet-primary-700` | `#5703a4` |
| `violet-primary-800` | `#400279` |
| `violet-primary-900` | `#2a0250` |

**Violet Muted**
| Token | Hex |
|---|---|
| `violet-muted-50` | `#f7f5f9` |
| `violet-muted-100` | `#e0d8e8` |
| `violet-muted-200` | `#c9b9d9` |
| `violet-muted-300` | `#b29aca` |
| `violet-muted-400` | `#9c7abc` |
| `violet-muted-500` | `#8559af` |
| `violet-muted-600` | `#6f4b8f` |
| `violet-muted-700` | `#583f6d` |
| `violet-muted-800` | `#41314e` |
| `violet-muted-900` | `#271636` |

**Neutral**
| Token | Hex |
|---|---|
| `neutral-25` | `#ffffff` |
| `neutral-50` | `#f9f9f9` |
| `neutral-100` | `#f5f5f5` |
| `neutral-200` | `#ebebeb` |
| `neutral-300` | `#c8c8c8` |
| `neutral-400` | `#ababab` |
| `neutral-500` | `#8e8e8e` |
| `neutral-600` | `#717171` |
| `neutral-700` | `#555555` |
| `neutral-800` | `#3a3a3a` |
| `neutral-900` | `#222222` |
| `neutral-950` | `#111111` |

**Magenta** (order/commerce accent)
| Token | Hex |
|---|---|
| `magenta-default-50` | `#fdf6fa` |
| `magenta-default-100` | `#ffedf8` |
| `magenta-default-200` | `#ffa7de` |
| `magenta-default-300` | `#f46bc3` |
| `magenta-default-400` | `#f248b7` |
| `magenta-default-500` | `#de078e` |
| `magenta-default-600` | `#bd007f` |
| `magenta-default-700` | `#960165` |
| `magenta-default-800` | `#790854` |
| `magenta-default-900` | `#4c0535` |

**Accents & Supplementary**
| Token | Hex |
|---|---|
| `accent-amber-50` / `100` / `400` / `800` | `#fdf9e6` / `#faf0c3` / `#f2d05b` / `#896a0b` |
| `accent-green-50` / `100` / `700` / `800` | `#ebfff2` / `#d5ffe3` / `#179038` / `#116628` |
| `accent-red-50` / `100` / `500` / `600` / `700` | `#fbe0e0` / `#f7bfbf` / `#e43b44` / `#d01e28` / `#a51820` |
| `supplementary-blue-default-50` / `100` / `800` / `900` | `#eeeffd` / `#e1e1f7` / `#3846ab` / `#2f3a8f` |
| `supplementary-blue-muted-100` / `500` | `#eaeaf1` / `#a4a5bc` |
| `supplementary-orange-default-50` | `#fff7ef` |

#### Semantic tokens

**Background**
| Token | Alias |
|---|---|
| `color-background-default` | `neutral-50` |
| `color-background-white` | `neutral-25` |
| `color-background-dark-gray` | `supplementary-blue-muted-100` |

**Text**
| Token | Alias |
|---|---|
| `color-text-default` | `neutral-950` |
| `color-text-subtext` | `neutral-600` |
| `color-text-brand` | `violet-primary-500` |
| `color-text-brand-dark` | `violet-primary-700` |
| `color-text-brand-muted` | `violet-muted-500` |
| `color-text-placeholder` | `neutral-500` |
| `color-text-white` | `neutral-25` |
| `color-text-sucess` | `accent-green-800` |
| `color-text-error` | `accent-red-700` |
| `color-text-warning` | `accent-amber-800` |
| `color-text-info` | `supplementary-blue-default-900` |
| `color-text-order` | `magenta-default-500` |

**Border**
| Token | Alias |
|---|---|
| `color-border-default` | `neutral-200` |
| `color-border-strong` | `neutral-300` |
| `color-border-light` | `neutral-100` |
| `color-border-brand-bright` | `violet-primary-500` |
| `color-border-brand-light` | `violet-primary-100` |
| `color-border-brand-muted` | `violet-muted-200` |
| `color-border-error-bright` | `accent-red-600` |
| `color-border-sucess-success` | `accent-green-700` |
| `color-border-warning-light` | `accent-amber-100` |
| `color-border-warning-bright` | `accent-amber-400` |
| `color-border-info-light` | `supplementary-blue-default-100` |
| `color-border-info-bright` | `supplementary-blue-default-800` |

**Action**
| Token | Alias |
|---|---|
| `color-action-primary-bg` | `violet-primary-500` |
| `color-action-primary-bg-pressed` | `violet-primary-700` |
| `color-action-primary-bg-disabled` | `neutral-100` |
| `color-action-primary-text` | `neutral-25` |
| `color-action-primary-text-disabled` | `neutral-500` |
| `color-action-secondary-bg` | `violet-primary-50` |
| `color-action-secondary-bg-pressed` | `violet-primary-100` |
| `color-action-secondary-text` | `violet-primary-500` |
| `color-action-ghost-text` | `violet-primary-500` |
| `color-action-ghost-border` | `violet-primary-500` |
| `color-action-error-surface` | `accent-red-500` |
| `color-action-error-border` | `accent-red-500` |
| `color-action-error-text` | `neutral-25` |
| `color-action-order-bg-bright` | `magenta-default-500` |
| `color-action-order-text` | `neutral-25` |

**Surface**
| Token | Alias |
|---|---|
| `surface-default` | `neutral-25` |
| `surface-gray` | `neutral-50` |
| `surface-selected-filter` | `violet-primary-50` |
| `surface-selected-tab` | `neutral-950` |
| `surface-disabled` | `neutral-50` |
| `surface-brand` | `violet-primary-50` |
| `surface-error` | `accent-red-50` |
| `surface-warning` | `accent-amber-50` |
| `surface-sucess` | `accent-green-50` |
| `surface-info` | `supplementary-blue-muted-100` |

**Icon**
| Token | Alias |
|---|---|
| `color-icon-default` | `neutral-800` |
| `color-icon-secondary` | `neutral-500` |
| `color-icon-disabled` | `neutral-400` |
| `color-icon-brand` | `violet-primary-500` |
| `color-icon-on-action` | `neutral-25` |

**Badge**
| Token | Alias |
|---|---|
| `color-badge-light-bg-brand` | `violet-primary-100` |
| `color-badge-bright-brand` | `violet-primary-600` |

> Icons must always be colored with `color="currentColor"` and inherit color from their parent's CSS, never a hardcoded hex — this lets active/hover/disabled state rules recolor them correctly (see the Bottom Navbar note in §3.4).

### 1.2 Typography

Single typeface across English and Hindi content.

- **Primary font:** Inter — weights 300 / 400 / 500 / 600 / 700 / 800
- **Devanagari fallback:** Noto Sans Devanagari — weights 300–700
- **Monospace:** JetBrains Mono / Fira Code (OTP fields, codes)

**Type size scale** (`--typography-size-*`): `10, 11, 12, 13, 14, 15, 16, 18, 20, 24, 28` px

**Letter spacing** (`--typography-letterspacing-*`):
| Token | Value |
|---|---|
| `normal` | `0px` |
| `tight` | `-0.5px` |
| `wide` | `0.5px` |
| `wider` | `1px` |

Weights observed in component usage: `400` (body/regular), `500` (labels/medium — most common), `600` (emphasis/headings), `700` (strong emphasis).

### 1.3 Spacing

Base spacing scale (`--spacing-*`), in px:

| Token | Value | Token | Value |
|---|---|---|---|
| `spacing-0` | 0 | `spacing-7` | 20 |
| `spacing-1` | 2 | `spacing-8` | 24 |
| `spacing-2` | 4 | `spacing-9` | 32 |
| `spacing-3` | 6 | `spacing-10` | 40 |
| `spacing-4` | 8 | `spacing-11` | 48 |
| `spacing-5` | 12 | `spacing-12` | 64 |
| `spacing-6` | 16 | `spacing--ve` | -12 |

**Component-level aliases** built on top of the base scale:

| Token | Resolves to |
|---|---|
| `spacing-component-padding-xs/sm/md/lg/xl` | `spacing-2/3/4/5/6` |
| `spacing-component-gap-xs/sm/md/lg` | `spacing-2/3/4/5` |
| `spacing-layout-screen-horizontal` | `spacing-6` (16px) |
| `spacing-layout-screen-vertical` | `spacing-8` (24px) |
| `spacing-layout-section-gap` | `spacing-8` (24px) |
| `spacing-layout-section-gap-lg` | `spacing-9` (32px) |
| `spacing-layout-content-gap` | `spacing-6` (16px) |
| `spacing-button-padding-horizontal/vertical` | `spacing-6` (16px) / `spacing-4` (8px) |
| `spacing-button-padding-horizontal-lg/vertical-lg` | `spacing-8` (24px) / `spacing-5` (12px) |
| `spacing-card-padding` / `-lg` | `spacing-6` (16px) / `spacing-8` (24px) |
| `spacing-card-gap-content` / `-sections` | `spacing-4` (8px) / `spacing-5` (12px) |
| `spacing-input-padding-horizontal/vertical` | `spacing-5` (12px) / `spacing-4` (8px) |

### 1.4 Border radius

| Token | Value |
|---|---|
| `border-radius-none` | 0px |
| `border-radius-xs` | 4px |
| `border-radius-s` | 6px |
| `border-radius-md` | 8px |
| `border-radius-lg` | 12px |
| `border-radius-xl` | 16px |
| `border-radius-full` | 999px |

**Component aliases:**
| Token | Resolves to |
|---|---|
| `border-radius-button-default` | `s` (6px) |
| `border-radius-button-large` | `md` (8px) |
| `border-radius-inputfield` | `xs` (4px) |
| `border-radius-card-default` | `s` (6px) |
| `border-radius-card-large` | `lg` (12px) |
| `border-radius-tag` | `xs` (4px) |
| `border-radius-capsule` | `full` |
| `border-radius-avatar` | `full` |
| `border-radius-toast` | `xs` (4px) |
| `border-radius-toggle` | `full` |

### 1.5 Border width

| Token | Value |
|---|---|
| `border-width-none` | 0px |
| `border-width-thinner` | 0.5px |
| `border-width-thin` | 1px |
| `border-width-thick` | 1.5px |
| `border-width-thicker` | 2px |

### 1.6 Iconography

- **Library:** [Phosphor Icons](https://phosphoricons.com/) (`@phosphor-icons/react`)
- **Weights:** thin, light, regular, bold, fill, duotone
- **Standard sizes:** 16 / 20 / 24 px
- **Color rule:** icons render with `color="currentColor"` so they inherit `color-icon-*` tokens from their container — never hardcode an icon's fill/stroke color, or state-based recoloring (hover, active, disabled) breaks.
- Full searchable icon set lives at `Foundations → Icons` in both the app and Storybook.

---

## 2. Navigation & information architecture

The product docs site (and its Storybook mirror) are organized as:

```
Getting Started
  └─ Introduction

Foundations
  ├─ Colors → Base, Semantic
  ├─ Typography
  ├─ Spacing
  ├─ Border
  ├─ Shadows
  └─ Icons

Visual Components
  ├─ Empty State Card
  └─ App Header

Navigation Controls
  ├─ Bottom Navbar
  ├─ Slider Tabs
  └─ Vertical Tabs

Components
  ├─ Buttons & CTAs
  │   └─ Button → Default, Icon Button, FAB Button, Underlined CTA, Order Button
  ├─ Data Display
  │   └─ Badge, Avatar, Chip, Accordion
  ├─ Forms & Inputs
  │   └─ Text Input, Numeric Input, Checkbox, Radio Button, Toggle, Search Bar
  └─ Feedback
      ├─ Toast
      ├─ Progress Bar → Linear, Segmented, Stepper
      └─ Spin Loader
```

Every component page in the app carries a **version badge** and a **"View in Storybook"** deep link to its exact `Playground` story, keeping the two surfaces in lockstep.

---

## 3. Components

Each entry lists the primary variants/states implemented today.

### 3.1 Buttons & CTAs
- **Default Button** — primary / secondary / ghost / error variants; default, hover, pressed, disabled, loading states; standard + large sizing.
- **Icon Button** — icon-only, circular/square, same state set as Default Button.
- **FAB Button** — floating action button, elevated, brand-colored.
- **Underlined CTA** — text link with underline affordance, used for lightweight in-flow actions.
- **Order Button** — magenta/order-accent variant for commerce-specific CTAs (`color-action-order-*` tokens).

### 3.2 Data Display
- **Badge** — brand light/bright backgrounds, compact label chip.
- **Avatar** — circular (`border-radius-avatar`), image or initials fallback.
- **Chip** — selectable/removable tag, single Playground story with interactive states.
- **Accordion** — expand/collapse panel, single header + content pattern.

### 3.3 Forms & Inputs
- **Text Input** — default, focused, error, disabled, with helper/error text.
- **Numeric Input (OTP)** — segmented numeric entry cells.
- **Checkbox** — unselected, selected, disabled, disabled+selected, with optional helper text.
- **Radio Button** — same state set as Checkbox, single-select semantics.
- **Toggle** — on/off switch, `border-radius-toggle` (full/pill).
- **Search Bar** — icon-prefixed input with clear affordance.
- **Selection List** — list-based checkbox/radio group with dividers, sizes (sm/md).

### 3.4 Navigation Controls
- **Bottom Navbar** — up to 5 tabs, icon + label, active tab indicated by a sliding top indicator **and** the active icon/label recoloring to `color-icon-brand` / `color-text-brand`. Icons must use `currentColor` (not a hardcoded hex) so the active-state CSS rule can recolor them — this was a real bug fixed in Storybook and is the canonical gotcha for this component.
- **Slider Tabs** — horizontal tab strip with animated sliding underline/pill.
- **Vertical Tabs** — sidebar-style vertical tab list with active state highlight.

### 3.5 Feedback
- **Toast** — success/error/warning/info surfaces (`surface-*` + `color-text-*` tokens), auto-dismiss pattern.
- **Progress Bar — Linear** — determinate horizontal bar.
- **Progress Bar — Segmented** — multi-step segmented bar (e.g. story progress).
- **Progress Bar — Stepper** — numbered/checked step indicator for multi-step flows.
- **Spin Loader** — indeterminate circular loader, size + variant props.

### 3.6 Visual Components
- **Empty State Card** — illustration + heading + body + optional CTA, for zero-data states.
- **App Header** — top app bar with title, optional back action, optional trailing actions.

---

## 4. Implementation notes

- **Framework:** Next.js 16 (App Router) for the live product-facing documentation site; Storybook 8 (`@storybook/react-vite`) as the component-development and QA surface.
- **Styling:** plain CSS custom properties (`src/index.css`) as the token source of truth, consumed via CSS Modules / scoped `.css` files per component (e.g. `BottomNavbar.css`) — not Tailwind, for the `src/components` design-system library itself. (The surrounding docs app shell uses Tailwind + shadcn/ui separately.)
- **Icons:** `@phosphor-icons/react`, always passed `color="currentColor"`.
- **Fonts:** loaded via Google Fonts `@import` in `index.css` — Inter + Noto Sans Devanagari.
- **Parity rule:** the Storybook `Playground` story for a component must be a single, controls-driven story (no more than one export per component) that matches the live app page 1:1 in props, states, and visuals — no divergent placeholder content, hardcoded colors, or stale prop defaults.
