Prisma
Live Preview
Heading 1
Heading 2
Heading 3
Heading 4
Body text — The quick brown fox jumps over the lazy dog. Lorem ipsum dolor sit amet.
Small text — Used for captions and helper text.
Monospace — code snippets and technical details

Typography System Generation Skill

Skill này hướng dẫn bạn (AI Agent) tạo Typography System — hệ thống chữ hoàn chỉnh bao gồm các semantic text roles ánh xạ đến typography tokens.

1. Mục tiêu (Objective)

Tạo hệ thống Typography với các component/utility class cho mọi vai trò text (display, headline, title, body, label, caption). Đảm bảo nhất quán, accessible, và mapping 100% từ typography tokens.

2. AI Context & Intent (Ngữ cảnh cho AI)

Khi nào dùng Typography?

  • MỌI LÚC hiển thị text: heading, paragraph, label, caption
  • Đảm bảo nhất quán: Không tự ý chọn font-size/weight — phải dùng typography role

Typography Roles — Hệ thống vai trò chữ

Mỗi role phục vụ một mục đích cụ thể trong hierarchy:

Role Mục đích Khi nào dùng
Display Hero text, landing page headline Rất lớn, branding, 1/page
Headline Section headings H1–H3, phân chia page sections
Title Component titles Card title, dialog title, list item title
Body Paragraph, long-form content Nội dung chính, mô tả, article body
Label Form labels, button text, nav items UI controls text, compact
Caption Supplementary info Timestamps, footnotes, helper text, metadata

Decision Tree cho AI

text
Văn bản cần hiển thị?
├─ Xác định LAYER trước (Ground / Card / Surface)
│  ├─ Ground (page-level) → dùng headline + body
│  ├─ Card (component) → dùng title + body-sm
│  └─ Surface (overlay) → dùng title-sm + caption
│
├─ Chọn ROLE theo mục đích:
│  ├─ Hero / landing / branding → Display (xl, lg)
│  ├─ Page section heading → Headline (lg, md, sm)
│  ├─ Component title (card, dialog) → Title (lg, md, sm)
│  ├─ Main content paragraph → Body (lg, md, sm)
│  ├─ UI control label → Label (lg, md, sm)
│  ├─ Secondary / time / footnote → Caption
│  └─ Inline emphasis → Body + bold/italic
│
└─ Kiểm tra 3-AXIS CONTRAST (T16, T17):
   ├─ Title weight ≥ 600? ✓
   ├─ Description dùng muted-foreground? ✓
   └─ Size gap ≥ 2 step? ✓

3. Ngữ nghĩa & Phân loại (Semantics)

3.1. Typography Scale — Mapping đến Tokens

Role Size Token font.size Token font.weight Token font.leading Token font.tracking HTML
Display XL 9xl (128px) font.size.9xl font.weight.bold font.tracking.tight <h1>
Display LG 7xl (72px) font.size.7xl font.weight.bold font.tracking.tight <h1>
Display MD 5xl (48px) font.size.5xl font.weight.bold font.tracking.tight <h1>
Headline LG 4xl (36px) font.size.4xl font.weight.semibold font.leading.10 font.tracking.tight <h1>
Headline MD 3xl (30px) font.size.3xl font.weight.semibold font.leading.9 font.tracking.normal <h2>
Headline SM 2xl (24px) font.size.2xl font.weight.semibold font.leading.8 font.tracking.normal <h3>
Title LG xl (20px) font.size.xl font.weight.semibold font.leading.7 font.tracking.normal <h4>
Title MD lg (18px) font.size.lg font.weight.semibold font.leading.7 font.tracking.normal <h5>
Title SM base (16px) font.size.base font.weight.semibold font.leading.6 font.tracking.normal <h6>
Body LG lg (18px) font.size.lg font.weight.normal font.leading.7 font.tracking.normal <p>
Body MD base (16px) font.size.base font.weight.normal font.leading.6 font.tracking.normal <p>
Body SM sm (14px) font.size.sm font.weight.normal font.leading.5 font.tracking.normal <p>
Label LG base (16px) font.size.base font.weight.medium font.leading.6 font.tracking.normal <span>
Label MD sm (14px) font.size.sm font.weight.medium font.leading.5 font.tracking.normal <span> / <label>
Label SM xs (12px) font.size.xs font.weight.medium font.leading.4 font.tracking.wide <span> / <label>
Caption xs (12px) font.size.xs font.weight.normal font.leading.4 font.tracking.normal <span> / <small>

3.2. Color Tokens cho Typography

Context Token Path
Default text base.foreground
Secondary/muted text base.muted-foreground
Inverse (on dark bg) base.foreground-inverse
Primary accent text base.primary-muted-foreground
Error text base.destructive-muted-foreground
Success text base.success-muted-foreground
Warning text base.warning-muted-foreground
Info text base.info-muted-foreground

3.3. Title/Description Pairing Rules (T16, T17, T18)

Source: title-hierarchy-systems.md — MD3 + shadcn research

3-Axis Contrast — Mọi cặp Title/Description PHẢI đạt ít nhất 2/3 trục:

Axis Title Description Rule ID
Size Lớn hơn ≥ 2 step Nhỏ hơn ≥ 2 step
Weight semibold (600) trở lên regular (400) T16
Color foreground / card-foreground muted-foreground T17

Elevation × Typography Matrix (T18):

Elevation Title Role Description Role Label Ví dụ
Ground headline-lgheadline-sm body-lgbody-md label-md Page header, section
Card title-lgtitle-md body-mdbody-sm label-sm Card, stat widget
Surface title-mdtitle-sm body-smcaption label-sm Dialog, tooltip, toast

3.4. Component Typography Spec

Component Layer Title Description Label Caption
Page Header Ground headline-md body-md muted
Section Header Ground headline-sm body-sm muted
Card Card title-md body-sm muted label-sm caption
Stat Widget Card label-md (name) headline-sm (value) caption (trend)
List Item Card title-sm body-sm muted label-sm caption
Dialog Surface title-lg body-md muted label-md
Toast Surface title-sm body-sm muted caption
App Bar Ground title-md label-sm
Sidebar Ground title-sm (section) label-md (nav) caption
Table Card title-sm (header) body-sm (cell) label-sm caption
Form Field Card body-sm (helper) label-md caption (error)

3.5. Anti-patterns (Typography)

❌ Sai ✅ Đúng Rule
Card title dùng headline-lg Card title dùng title-md T18
Description cùng foreground với Title Description dùng muted-foreground T17
Title weight 400, Desc weight 400 Title ≥ 600, Desc 400 T16
Dialog title dùng headline-md Dialog title dùng title-lg T18

4. Token Mapping

📦 Atomic Mapping: See ATOMIC-MAPPING.md for complete token spec.

Xem bảng chi tiết mục 3.1 — mỗi typography role ánh xạ trực tiếp đến bộ 4 tokens:

  • font.size.* → font-size
  • font.weight.* → font-weight
  • font.leading.* → line-height
  • font.tracking.* → letter-spacing

5. Props & API

typescript
interface TextProps {
  /** Typography role — quyết định toàn bộ visual */
  role?: 'display-xl' | 'display-lg' | 'display-md' |
         'headline-lg' | 'headline-md' | 'headline-sm' |
         'title-lg' | 'title-md' | 'title-sm' |
         'body-lg' | 'body-md' | 'body-sm' |
         'label-lg' | 'label-md' | 'label-sm' |
         'caption';
  /** Render as HTML tag (override default) */
  as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'label' | 'small' | 'div';
  /** Color variant */
  color?: 'default' | 'muted' | 'inverse' | 'primary' | 'destructive' | 'success' | 'warning' | 'info';
  /** Text alignment */
  align?: 'left' | 'center' | 'right';
  /** Truncate with ellipsis */
  truncate?: boolean;
  /** Max lines before truncation */
  maxLines?: number;
  /** Weight override (trong cùng role) */
  weight?: 'normal' | 'medium' | 'semibold' | 'bold';
  /** Content */
  children: ReactNode;
}

6. Accessibility (a11y)

  • Heading hierarchy: Phải tuân thủ H1 → H2 → H3 theo thứ tự, không nhảy level.
  • Không dùng heading cho style: Nếu chỉ cần text to, dùng role="body-lg" + as="p", KHÔNG dùng <h2>.
  • Contrast ratio: Text trên background phải đạt tối thiểu 4.5:1 (WCAG AA), 3:1 cho large text.
  • Line length: Body text nên 45–75 ký tự/dòng (readability).
  • Truncation: Nếu truncate, toàn bộ text phải accessible qua title attribute hoặc tooltip.

7. Best Practices & Rules

  • Semantic HTML: Role ánh xạ đến HTML tag đúng (headline → <h*>, body → <p>, label → <label>/<span>).
  • Prop as override: Cho phép tách visual (role) khỏi semantic (HTML tag) — vd: role="headline-md" as="h3".
  • Không Hardcode: KHÔNG BAO GIỜ viết font-size: var(--font-size-sm) trực tiếp — phải dùng token.
  • Responsive: Display/Headline sizes có thể giảm trên mobile via media query.
  • Dark Mode: Tự động qua color tokens.

8. Example Usage

jsx
{/* Page headline */}
<Text role="headline-lg" as="h1">Tổng quan tài khoản</Text>

{/* Card title */}
<Text role="title-md">Giao dịch gần đây</Text>

{/* Body paragraph */}
<Text role="body-md" color="muted">
  Tài khoản của bạn đã được kích hoạt thành công.
</Text>

{/* Form label */}
<Text role="label-md" as="label" htmlFor="email">
  Email
</Text>

{/* Caption */}
<Text role="caption" color="muted">
  Cập nhật lần cuối: 26/02/2026
</Text>

{/* Truncated text */}
<Text role="body-sm" truncate maxLines={2}>
  Đây là một đoạn text rất dài sẽ bị cắt sau 2 dòng...
</Text>