# THÍCH CAY — Design System v3.3

> **Tagline:** *Sáng tạo gia vị Việt*
> **One-liner (en):** Bold-spice Vietnamese sauces, modern jars, grandmother's voice.
> **Spec version:** 3.3 · 2026 · Vietnamese-first, fully self-hosted.

This file is the **single source of truth** for the Thích Cay design system, optimized for both humans and LLMs (Claude, Cursor, v0, Figma Make, etc.). Paste it into any LLM context to generate on-brand UI in one shot.

---

## 🔥 TL;DR — read this first

| Question | Answer |
|---|---|
| What is Thích Cay? | Vietnamese sauce brand — traditional recipes, modern packaging, no MSG. |
| Voice | Loud, declarative, grandmother-confident. **Vietnamese first**, English never replaces. |
| Primary colour | `#B41A1A` Chilli Red · `oklch(0.473 0.184 27.5)` · `--primary-600` |
| Page surface | `#FBF5E7` Cream Paper · `oklch(0.969 0.022 88.5)` · `--brand-surface` |
| Card surface | `#FFFCF1` Lifted Cream · `--surface-elevated` (always shadow-md on top) |
| Display font | **DVN Luckiest Guy** — UPPERCASE only, vi-VN full diacritics |
| Heading font | **Be Vietnam Pro** — H1–H6, mixed case, 300–900 |
| Body font | **Plus Jakarta Sans** variable 200–800 |
| Logo font | **Gagalin** — logo only, do not use in UI |
| Spacing base | 4 px linear (`--space-4` = 16 px = baseline unit) |
| Radius rule | **Always ≥ 6 px.** Never `0`. Default card = `--radius-lg` (14 px). |
| Shadow | Red-tinted `rgba(180, 26, 26, …)` — never pure black. |
| Motion default | 150 ms `--ease-bounce` `cubic-bezier(.34, 1.56, .64, 1)`. |
| Icons | Lucide 2 px rounded · default colour `--brand-accent` `#FF766A`. |
| Emoji | **None.** The chili in the logo is the only mascot pictogram. |
| CDN | `https://cdn.thichcay.vn/` — fonts, images, tokens, docs, media. |

---

## 🏢 Brand essence

| Pillar | One-line |
|---|---|
| **Đậm đà** (rich-flavoured) | Every claim is sensory — *thơm, béo, cay, đậm đà, sánh đặc*. |
| **Ấm áp** (warm) | Cream paper, warm-tinted shadows, rounded corners, no glass. |
| **Rất Việt** (very Vietnamese) | Vietnamese-first copy, full diacritics, street-food loud. |

### Hero SKUs

- **Kho Quẹt Chay** — vegetarian caramelised dipping sauce, mushroom + peanut.
- **Sốt Bơ Tỏi Hoàng Kim** — golden garlic-butter sauce for stir-fry & seafood.
- **Sốt Tôm Kho** — dried-shrimp chili sauce, thick & chunky.
- **Sốt Gỏi Cay** — sweet-sour-spicy salad sauce (hero landing-page product).

### Audience

25–45 y/o Vietnamese home cooks (≈80 % female) + diaspora. Shops on Shopee · Lazada · TikTok Shop. Values traditional taste, hates "Tây-hoá" gourmet positioning. Pays a premium for **no MSG · clean label**.

---

## ✍️ Copy rules

- **Vietnamese first**, full diacritics. English allowed only as subtitle.
- **ALL CAPS** for hero headlines and benefit pills. Body in sentence case.
- **2–4 words per line.** Stack into 2-line pills: *"VỊ NẤM / NGỌT THANH"*.
- **Numbers use "K"** Vietnamese-commerce style: *65K* = 65 000 ₫. Strikethrough old price above: ~~85.000~~ **65K**.
- **No emoji.** Em-dash `—` and middle-dot `•` are the only typographic separators.
- **Confidence by type weight**, not exclamation points.

### Do / Don't

| ✅ Do | ❌ Don't |
|---|---|
| Declarative flavour claims — "MẶN NGỌT HÀI HÒA" | Hedged marketing — "we think you might enjoy…" |
| Sensory verbs — thơm, béo, cay, sánh đặc, đậm đà | Clinical nutrition language — "% RDA", "mg sodium" |
| Direct 2nd-person — "Gỏi gì cũng ngon" | Corporate we-statements — "Chúng tôi mang đến…" |
| Bếp nhà, mâm cơm, quán vỉa hè | Fine-dining / Western gourmet vibe |

### Verbatim copy bank — use as template for new SKUs

```
GỎI NGON / ĐẬM ĐÀ        →  Chua ngọt hài hòa · Chất sốt sánh đặc
BƠ TỎI / HẢO HẠNG        →  Dậy mùi thơm béo  · Mặn ngọt hài hòa
VỊ NẤM / NGỌT THANH      →  Mặn ngọt hài hòa  · Béo bùi đậu phộng
SỐT GỎI CAY              →  banner: "Ăn gỏi chua ngọt — Thanh mát ngày hè"
Benefit chips            →  "Không cần nêm thêm" · "Hợp với mọi món gỏi" · "Tiết kiệm thời gian"
```

---

## 🎨 Color tokens (LLM-ready, all values)

### Brand core (5 tokens)

| Token | HEX | OKLCH | When to use |
|---|---|---|---|
| `--brand-primary` | `#B41A1A` | `oklch(.473 .184 27.5)` | CTA fills, headline accent, ribbon. Min 30 % visual weight on every screen. |
| `--brand-accent` | `#FF766A` | `oklch(.71 .18 28)` | **Gradient-first.** Solid only on items ≤ 48 px (chip, icon, badge). Never as page bg. |
| `--brand-secondary` | `#8A4C00` | `oklch(.443 .105 53.4)` | Stamp text on peach, secondary CTA on photo bg. |
| `--brand-secondary-container` | `#FFC697` | `oklch(.850 .077 60.5)` | Peach container — soft surface for sticker tags, success-adjacent. |
| `--brand-surface` | `#FBF5E7` | `oklch(.969 .022 88.5)` | Page background. Always level 0. **Never** plain white `#FFFFFF`. |
| `--surface-elevated` | `#FFFCF1` | `oklch(.99 .02 95)` | **All cards/panels** must use this + `shadow-md`. ★ |

### Primary scale — Chilli Red (hue 27.5° locked)

| Token | HEX | Use |
|---|---|---|
| `--primary-50`  | `#FDF2F2` | Subtlest tint — disabled CTA bg |
| `--primary-100` | `#FBE3E3` | Toast/alert bg, error-50 |
| `--primary-200` | `#F7C0C0` | Soft accent on cream |
| `--primary-300` | `#F09494` | Decorative divider |
| `--primary-400` | `#E66666` | Hover-light state |
| `--primary-500` | `#D63838` | Mid-red |
| `--primary-600` | `#B41A1A` | ★ **Brand primary** — default red |
| `--primary-700` | `#921616` | Pressed/active state of red CTA |
| `--primary-800` | `#701111` | Outline on photo bg |
| `--primary-900` | `#4E0C0C` | Dark text on cream (rare) |
| `--primary-950` | `#2C0707` | Reserved — almost-black red |

### Neutral scale (warm hue 45–88, never gray-cold)

| Token | HEX | Use |
|---|---|---|
| `--neutral-0`   | `#FFFFFF` | Reserved — DO NOT use as page bg |
| `--neutral-50`  | `#FBF5E7` | ★ Same as `--brand-surface` |
| `--neutral-100` | `#F8F0DC` | Section alt bg |
| `--neutral-200` | `#EDE3CC` | Border default |
| `--neutral-300` | `#D6CAB0` | Border strong, dividers |
| `--neutral-400` | `#A89B82` | Disabled text |
| `--neutral-500` | `#7A6E58` | Subtle text, caption |
| `--neutral-600` | `#5C5142` | Muted text |
| `--neutral-700` | `#3D352B` | Body text |
| `--neutral-800` | `#2B241E` | ★ **Default text** — body, heading |
| `--neutral-900` | `#1A1612` | Highest contrast — only headlines. **Replaces pure black.** |

### Semantic states

| Token | fg | bg | Use |
|---|---|---|---|
| Success | `#16A34A` | `#DCFCE7` | Confirmation, herb/veg callout |
| Warning | `#EAB308` | `#FEF9C3` | Soft alert, "Sắp hết" |
| Error   | `#DC2626` | `#FEE2E2` | Form error — note: **not** the brand red |
| Info    | `#2563EB` | `#DBEAFE` | Neutral system message |

### Signature gradient

```css
--gradient-signature: linear-gradient(135deg, #B41A1A 0%, #FF766A 100%);
```

Used **only** on:
- Primary CTA button fill (default)
- Hero highlight stroke (rare)

**Never** for body bg, section bg, text fill.

### Usage ratio 60 / 30 / 10

```
60 %  →  Cream + neutrals (surface, whitespace)
30 %  →  Chilli Red + Ink (headlines, CTAs, ribbons)
10 %  →  Caramel + Peach + Coral (accents, price tags, badges)
```

---

## 🔤 Typography

### 4-font stack — strict roles

| Token | Family | Role | Casing | Notes |
|---|---|---|---|---|
| `--font-display` | **DVN Luckiest Guy** | Display headlines, ribbons, pills, price | UPPERCASE | Hero only. Self-hosted from CDN. |
| `--font-heading` | **Be Vietnam Pro** | H1–H6 body content | Mixed case | Best vi-VN diacritics. Google Fonts. Weights 300–900. |
| `--font-body` | **Plus Jakarta Sans** | Body, UI, button, label, price | Mixed case | Variable 200–800. Self-hosted. |
| `--font-mono` | **Be Vietnam Pro** (tabular) | SKU, order ID, timestamp, code | Mixed | Proportional with `font-variant-numeric: tabular-nums`. |
| `--font-logo` | **Gagalin** | Wordmark logo **only** | UPPERCASE | **DO NOT** use in UI — not loaded for body. |

### Type scale (26 tokens)

```
Display (DVN Luckiest Guy, UPPERCASE — hero only)
  display-2xl  72/1.1   ls -.02   →  hero ribbon, page title
  display-xl   60/1.1   ls -.02   →  KV headline
  display-lg   48/1.1   ls -.01   →  benefit pill 2-line
  display-md   36/1.1   ls  0     →  section header on photo

Heading (Be Vietnam Pro)
  h1  36 / 1.20  ls -.02  fw 800
  h2  30 / 1.25  ls -.01  fw 700
  h3  24 / 1.30  ls -.01  fw 700
  h4  20 / 1.35  ls  0    fw 600
  h5  18 / 1.40  ls  0    fw 600
  h6  16 / 1.40  ls  0    fw 600

Body (Plus Jakarta Sans)
  body-xl   20 / 1.5    →  lede paragraph
  body-lg   18 / 1.5    →  description
  body      16 / 1.5    →  default
  body-sm   14 / 1.5    →  meta
  caption   12 / 1.4    ls .02   →  helper text

Label (Plus Jakarta, UPPERCASE 600–700)
  label-lg  14   ls .04   →  section eyebrow
  label     12   ls .06   →  chip text
  label-sm  11   ls .08   →  micro tag
  overline  11   ls .08   →  page chrome label (red)

Button (Plus Jakarta UPPERCASE 700)
  button-lg  16 / 1.0   ls .04
  button     14 / 1.0   ls .04
  button-sm  13 / 1.0   ls .04

Price (Plus Jakarta 700, brand-primary colour)
  price-lg          24 / 1.2  ls -.01
  price             18 / 1.2
  price-original    14 / 1.2  strikethrough, neutral-500

Mono (Be Vietnam Pro tabular)
  mono-lg  16 / 1.5  fw 500
  mono     14 / 1.5  fw 400
  mono-sm  12 / 1.5  fw 400
```

---

## 📐 Spacing · Radius · Shadow · Motion

### Spacing — 4 px base

`--space-0` 0 · `--space-1` 4 · `--space-2` 8 · `--space-3` 12 · `--space-4` **16 (base)** · `--space-5` 20 · `--space-6` 24 · `--space-8` 32 · `--space-10` 40 · `--space-12` 48 · `--space-16` 64 · `--space-20` 80 · `--space-24` 96

### Border radius — **house rule: always ≥ 6 px**

| Token | Value | Default use |
|---|---|---|
| `--radius-sm` | 6 px | Inline tag, code chip |
| `--radius-md` | 10 px | Input, small button |
| `--radius-lg` | 14 px | ★ **Default card** |
| `--radius-xl` | 18 px | Modal, sheet |
| `--radius-2xl` | 26 px | Hero card |
| `--radius-3xl` | 36 px | Promo block, KV frame |
| `--radius-pill` | 9999 px | Button (all), chip, badge |
| `--radius-full` | 50 % | Avatar, status dot |

### Shadow — red-tinted

```css
--shadow-xs:  0 1px 2px  0     rgba(180,26,26,.05);
--shadow-sm:  0 1px 3px  0     rgba(180,26,26,.08), 0 1px 2px -1px rgba(180,26,26,.06);
--shadow-md:  0 4px 6px  -1px  rgba(180,26,26,.08), 0 2px 4px -2px rgba(180,26,26,.06);  /* ★ default card */
--shadow-lg:  0 10px 15px -3px rgba(180,26,26,.10), 0 4px 6px -4px rgba(180,26,26,.05);
--shadow-xl:  0 20px 25px -5px rgba(180,26,26,.12), 0 8px 10px -6px rgba(180,26,26,.08);
--shadow-cta: 0 8px 24px -8px  rgba(180,26,26,.45);                                       /* primary CTA glow */
```

**Sticker shadow** (decorative — for badge/price-tag/CTA): `4–8px 4–8px 0 var(--neutral-900)` — solid offset, no blur. Gives "miếng dán dán lên giấy" feel.

### Motion

```css
--duration-instant:  100ms
--duration-fast:     150ms   /* ★ default hover/focus */
--duration-normal:   250ms
--duration-slow:     400ms
--duration-slower:   600ms

--ease-out:    cubic-bezier(0, 0, 0.2, 1)
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1)
--ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1)   /* ★ rubber-stamp entry */
```

**Rubber-stamp entry:** `scale(1.1 → 1.0) + rotate(-2° → 0°)` over 250 ms with `--ease-bounce`. Never fade-only — always pair opacity with Y or rotation.

---

## 🧩 Components rules

### 10 invariants (must hold for every card / panel / sheet)

1. Background = `--surface-elevated` (`#FFFCF1`) — never `#FFFFFF`.
2. Border = 2 px solid `--neutral-200` or `--neutral-300`. Never 1 px hairline.
3. Radius = at least `--radius-md` (10 px), default `--radius-lg` (14 px).
4. Shadow = `--shadow-md` minimum to separate from page bg.
5. Inner padding = multiple of 4 px, minimum `--space-4` (16 px).
6. Text colour = `--neutral-800` body, `--neutral-900` heading, `--neutral-600` muted.
7. Headings use Be Vietnam Pro (`--font-heading`), never DVN.
8. Buttons inside cards = pill radius (9999 px).
9. CTA primary = gradient fill `--gradient-signature` + `--shadow-cta`.
10. Hover = `transform: translateY(-1px)` + brighter shadow, transition `--duration-fast --ease-bounce`.

### Buttons — 7 variants × 4 sizes × 6 states

| Variant | Bg | Text | Border | Use |
|---|---|---|---|---|
| **Primary** | `--gradient-signature` | cream | none | Main CTA — Mua ngay, Đặt hàng |
| **Accent** | `--brand-accent` solid | cream | none | Secondary CTA — Thêm vào giỏ |
| **Outline** | transparent | `--primary-600` | 2 px `--primary-600` | Tertiary action |
| **Ghost** | transparent | `--neutral-700` | none | Toolbar, icon-only |
| **Sticker** | `--primary-600` | cream | 3 px `--neutral-900` | Hero CTA — adds 4–8 px solid black offset shadow |
| **Dark** | `--neutral-900` | cream | none | Inverted on photo |
| **Disabled** | `--neutral-200` | `--neutral-400` | none | Use sparingly |

Sizes: `sm 36 px` · `md 44 px` · `lg 52 px` · `xl 60 px`. All pill-rounded. All UPPERCASE with `letter-spacing: .04em`. All `font-weight: 700`.

### Form inputs — 7 states

`default · hover · focus · filled · error · success · disabled`

- Focus ring = 3 px `--primary-200` (not blue!).
- Error border = 2 px `--error` `#DC2626` + 1 line of error text 12 px.
- Filled bg = `--surface-elevated`, default bg = `--brand-surface`.
- Helper text below input, gap 4 px, colour `--neutral-500`.

### Product card (composition is locked)

```
[ image 1:1, radius-xl top-only, badge top-right ]
[ title h4, line-clamp 2, color neutral-800       ]
[ sale-price 18 bold red · original-price 14 strikethrough ]
[ stars 16px gold · "Đã bán Nk" mono ]
[ chip-variant pills (120ml · 250ml · Combo 3) ]
[ action row: ghost-icon · ghost-icon · accent "Thêm" · primary "Mua ngay" ]
```

---

## ⛔ Anti-patterns (NEVER do these)

- ❌ Pure white `#FFFFFF` as page or card bg — use `--brand-surface` / `--surface-elevated`.
- ❌ Pure black `#000000` for text — use `--neutral-800` or `--neutral-900`.
- ❌ `border-radius: 0` — always ≥ 6 px.
- ❌ Hairline 1 px borders — always 2 px.
- ❌ Blur / glassmorphism — Thích Cay is paper, not glass.
- ❌ Drop-shadow black — always red-tinted.
- ❌ Emoji 🔥🌶️ — chili in logo is the only mascot.
- ❌ Solid Coral on a page bg or hero (> 800 px). Coral is **gradient-first**.
- ❌ DVN Luckiest Guy in mixed case or body copy.
- ❌ Sans-serif system font for headlines — must be Be Vietnam Pro or DVN.
- ❌ Vietnamese without diacritics. Always full vi-VN.
- ❌ English-first copy on Vietnamese surfaces.
- ❌ Fine-dining / artisanal-Western tone — Thích Cay is **street-food loud**.

---

## 🖼 Iconography

- **Default set:** Lucide — `<script src="https://unpkg.com/lucide@latest"></script>`.
- **Stroke 2 px, rounded line-cap.** Solid-fill only for toggled state.
- **Default colour:** `--brand-accent` `#FF766A`. On red bg → `--brand-surface`.
- **Chili mascot:** the pepper in the logo wordmark — vector at `cdn.thichcay.vn/icons/` (pending). Use 16–24 px as bullet, 80+ px as section anchor.
- **No emoji.** Only typographic separators `•` and `—`.

---

## 📦 CDN — asset map

Base: `https://cdn.thichcay.vn/`

| Path | Content |
|---|---|
| `/docs/tokens.css` | All CSS variables (this spec, machine-readable) |
| `/docs/README.md` | This file |
| `/docs/BRAND_GUIDELINE.md` | Long-form spec (heritage) |
| `/docs/handbook.html` | Design system handbook — 1 page, all preview cards |
| `/docs/Design Guideline.html` | Slide deck for agency (HTML) |
| `/docs/preview/*.html` | Individual preview cards (colors, type, components…) |
| `/fonts/DVN-LuckiestGuy-Regular.ttf` | Display font |
| `/fonts/Gagalin-Regular.otf` | Logo font (do not load for UI) |
| `/fonts/PlusJakartaSans-VariableFont_wght.ttf` | Body variable |
| `/fonts/PlusJakartaSans-Italic-VariableFont_wght.ttf` | Body italic variable |
| `/icons/` | Vector icons (chili-mascot pending) |
| `/images/logos/thichcay-official.png` | 500×500 brand mark |
| `/images/products/{sku}.png` | 4 SKU pour shots — `bo-toi-hoang-kim`, `goi-ngon-dam-da`, `kho-quet-chay`, `sot-tom-kho` |
| `/images/landingpage/sot-goi-cay.{png,svg}` | Landing KV |
| `/images/textures/topo-paper.svg` | Topographic line texture (page bg overlay) |
| `/images/textures/brush-bottom.svg` | Brush divider |
| `/media/design-guideline-2026.pptx` | Editable PPTX guideline |

### One-liner imports

```html
<!-- Tokens (CSS variables + @font-face for all 4 fonts) -->
<link rel="stylesheet" href="https://cdn.thichcay.vn/docs/tokens.css">

<!-- Be Vietnam Pro from Google (heading font — not self-hosted) -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Be+Vietnam+Pro:wght@300;400;500;600;700;800;900&display=swap" rel="stylesheet">

<!-- Lucide icons -->
<script src="https://unpkg.com/lucide@latest"></script>
```

---

## 🤖 Prompt recipes (for LLMs using this system)

### Recipe 1 — generate a hero section

```
Build a hero section for [SKU NAME] using Thích Cay design system v3.3:
- Background: --brand-surface with topo-paper.svg overlay opacity 30%
- Hero text: DVN Luckiest Guy display-2xl, color --primary-600
- Subtitle: Be Vietnam Pro 18px italic, color --neutral-700
- CTA: gradient primary button, pill, --shadow-cta, "Mua ngay 65K"
- Hero product image: --radius-3xl, --shadow-lg, slight rotate(-2deg)
- Voice: Vietnamese, ALL CAPS headline 2 lines max, 2–4 words per line
- Avoid: white bg, blur, gradient text, emoji
```

### Recipe 2 — generate a product card

```
Generate a Thích Cay product card following the locked composition:
1:1 square image (--radius-xl top-only) + badge top-right + h4 title (line-clamp 2)
+ price row (sale --price-lg --primary-600, original --price-original strikethrough)
+ stars + variant chips + action row (4 buttons, last 2 are accent + primary).
Use --surface-elevated bg, --shadow-md, 2px --neutral-200 border, --radius-lg.
```

### Recipe 3 — generate marketing copy

```
Write 1 hero headline + 3 benefit pills for [PRODUCT] in Thích Cay voice:
- Hero: 2 lines, ALL CAPS, 2–4 words per line, declarative flavour claim
- Pills: 2-line stacked, ALL CAPS, sensory verbs (thơm, béo, cay, đậm đà, sánh đặc)
- Vietnamese only with full diacritics
- No emoji, no exclamation points, no Western gourmet language
Reference verbatim style:
  "GỎI NGON / ĐẬM ĐÀ" → "CHUA NGỌT HÀI HÒA" · "CHẤT SỐT SÁNH ĐẶC"
```

---

## 📂 Project file map (local repo)

| Path | Purpose |
|---|---|
| `colors_and_type.css` | Source of truth for CSS tokens (mirrored to CDN as `docs/tokens.css`) |
| `README.md` | This file |
| `preview/` | 23 individual design-system cards |
| `brand_guideline/Design System Handbook.html` | All cards in 1 page (TOC sidebar) |
| `brand_guideline/Brand Mood Board.html` | Magazine-style mood board |
| `slides/Design Guideline.html` | 27-slide agency deck (1920×1080) |
| `ui_kits/landing/index.html` | Landing-page UI kit reference |
| `export/ThichCay-Design-Guideline-2026.pptx` | Editable PowerPoint export |
| `cdn/` | Ready-to-deploy CDN bundle (mirrors `https://cdn.thichcay.vn/`) |
| `assets/` | Source assets (logos, products, textures, landingpage) — uploaded to `cdn/images/` |
| `fonts/` | Source font files — uploaded to `cdn/fonts/` |

---

## ⚠️ Open flags

- **No vector logo SVG yet** — using PNG raster (500×500). Drop SVG into `cdn/icons/` when available.
- **Lucide is a placeholder icon set.** Swap to custom hand-drawn pack if/when delivered.
- **Mini-App design system** is in progress (not in v3.3) — will arrive as v3.4.
- **Bilingual EN** — this system is Vietnamese-first by design. English is allowed only as subtitle, never standalone.

---

**Maintainer:** brand@thichcay.vn · **CDN:** [cdn.thichcay.vn](https://cdn.thichcay.vn) · **Repo:** github.com/thichcayvn/cdn
