Agents: - ui-scout: Playwright MCP + Variant(variant.com/community) visual capture - design-system-architect: unified design tokens (CSS vars / RN StyleSheet) - component-refactor-engineer: per-system component refactoring - visual-qa-tester: before/after screenshot comparison Skills: - ui-overhaul-orchestrator: E2E pipeline (capture->tokens->refactor->QA) - playwright-visual-capture: Playwright MCP + Variant workflow - design-token-system: tokens.css with Pretendard, 4px grid, brand colors - component-refactor: Button/Card/Badge patterns for 4 systems Bot: /design capture|variant|tokens|homepage|itsm|manager|app|qa|ab Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
211 lines
5.9 KiB
Markdown
211 lines
5.9 KiB
Markdown
---
|
|
name: design-token-system
|
|
description: "zio 4개 시스템(홈페이지·ITSM·Manager·Messenger) 통합 디자인 토큰 설계·구현 스킬. Pretendard 폰트, 딥블루+스카이블루 브랜드 색상, 4px 간격 시스템을 CSS변수·Tailwind·React Native StyleSheet로 변환한다. 다음 상황에서 반드시 사용: (1) '디자인 토큰 만들어줘', '색상 시스템 정의', '폰트 통일'; (2) tokens.css 생성/수정; (3) CSS 변수 리팩토링; (4) 다시 실행, 업데이트, 보완."
|
|
---
|
|
|
|
# zio 통합 디자인 토큰 시스템
|
|
|
|
## 적용 파일 위치
|
|
|
|
| 시스템 | 파일 |
|
|
|--------|------|
|
|
| 홈페이지 | `workspace/zioinfo-web/frontend/src/styles/tokens.css` |
|
|
| ITSM | `itsm/static/tokens.css` |
|
|
| Manager | `manager/frontend/src/styles/tokens.css` |
|
|
| Messenger | `app/constants/tokens.ts` |
|
|
|
|
---
|
|
|
|
## tokens.css (홈페이지·Manager 공용)
|
|
|
|
```css
|
|
/* ── zio 통합 디자인 토큰 ── */
|
|
|
|
/* 폰트 */
|
|
@import url('https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css');
|
|
|
|
:root {
|
|
/* ── 브랜드 색상 ── */
|
|
--color-primary-50: #eff4ff;
|
|
--color-primary-100: #dbe4ff;
|
|
--color-primary-200: #bac8ff;
|
|
--color-primary-300: #91b4fa;
|
|
--color-primary-400: #4d7ef5;
|
|
--color-primary-500: #0051A2;
|
|
--color-primary-600: #003f7f;
|
|
--color-primary-700: #002d5c;
|
|
--color-primary-800: #001c3a;
|
|
--color-primary-900: #000d1a;
|
|
|
|
--color-accent-400: #38bdf8;
|
|
--color-accent-500: #00A3E0;
|
|
--color-accent-600: #0082b3;
|
|
|
|
/* ── 뉴트럴 ── */
|
|
--color-neutral-0: #ffffff;
|
|
--color-neutral-50: #f8fafc;
|
|
--color-neutral-100: #f1f5f9;
|
|
--color-neutral-200: #e2e8f0;
|
|
--color-neutral-300: #cbd5e1;
|
|
--color-neutral-400: #94a3b8;
|
|
--color-neutral-500: #64748b;
|
|
--color-neutral-600: #475569;
|
|
--color-neutral-700: #334155;
|
|
--color-neutral-800: #1e293b;
|
|
--color-neutral-900: #0f172a;
|
|
|
|
/* ── 시맨틱 ── */
|
|
--color-success: #22c55e;
|
|
--color-success-bg: #f0fdf4;
|
|
--color-warning: #f59e0b;
|
|
--color-warning-bg: #fffbeb;
|
|
--color-danger: #ef4444;
|
|
--color-danger-bg: #fef2f2;
|
|
--color-info: #3b82f6;
|
|
--color-info-bg: #eff6ff;
|
|
|
|
/* ── 타이포 ── */
|
|
--font-family: 'Pretendard', 'Apple SD Gothic Neo', 'Noto Sans KR', sans-serif;
|
|
--font-mono: 'JetBrains Mono', 'Fira Code', monospace;
|
|
|
|
--text-xs: 11px;
|
|
--text-sm: 13px;
|
|
--text-base: 15px;
|
|
--text-lg: 17px;
|
|
--text-xl: 20px;
|
|
--text-2xl: 24px;
|
|
--text-3xl: 30px;
|
|
--text-4xl: 36px;
|
|
--text-5xl: 48px;
|
|
|
|
--font-normal: 400;
|
|
--font-medium: 500;
|
|
--font-semibold: 600;
|
|
--font-bold: 700;
|
|
--font-black: 900;
|
|
|
|
--leading-tight: 1.25;
|
|
--leading-normal: 1.6;
|
|
--leading-loose: 1.8;
|
|
|
|
/* ── 간격 (4px 기반) ── */
|
|
--space-0: 0px;
|
|
--space-1: 4px;
|
|
--space-2: 8px;
|
|
--space-3: 12px;
|
|
--space-4: 16px;
|
|
--space-5: 20px;
|
|
--space-6: 24px;
|
|
--space-8: 32px;
|
|
--space-10: 40px;
|
|
--space-12: 48px;
|
|
--space-16: 64px;
|
|
--space-20: 80px;
|
|
--space-24: 96px;
|
|
|
|
/* ── 반경 ── */
|
|
--radius-xs: 2px;
|
|
--radius-sm: 4px;
|
|
--radius-md: 8px;
|
|
--radius-lg: 12px;
|
|
--radius-xl: 16px;
|
|
--radius-2xl: 24px;
|
|
--radius-full: 9999px;
|
|
|
|
/* ── 그림자 ── */
|
|
--shadow-xs: 0 1px 2px rgba(0,0,0,.06);
|
|
--shadow-sm: 0 1px 3px rgba(0,0,0,.08), 0 1px 2px rgba(0,0,0,.06);
|
|
--shadow-md: 0 4px 6px rgba(0,0,0,.07), 0 2px 4px rgba(0,0,0,.06);
|
|
--shadow-lg: 0 10px 15px rgba(0,0,0,.10), 0 4px 6px rgba(0,0,0,.05);
|
|
--shadow-xl: 0 20px 25px rgba(0,0,0,.10), 0 10px 10px rgba(0,0,0,.04);
|
|
|
|
/* ── 전환 ── */
|
|
--ease-fast: 150ms cubic-bezier(.4,0,.2,1);
|
|
--ease-normal: 250ms cubic-bezier(.4,0,.2,1);
|
|
--ease-slow: 400ms cubic-bezier(.4,0,.2,1);
|
|
|
|
/* ── 레이아웃 ── */
|
|
--container-sm: 640px;
|
|
--container-md: 768px;
|
|
--container-lg: 1024px;
|
|
--container-xl: 1280px;
|
|
--container-2xl: 1536px;
|
|
|
|
/* ── Z-index ── */
|
|
--z-dropdown: 100;
|
|
--z-modal: 200;
|
|
--z-toast: 300;
|
|
--z-tooltip: 400;
|
|
}
|
|
|
|
/* ── 다크모드 (ITSM 전용) ── */
|
|
[data-theme="dark"] {
|
|
--color-neutral-0: #0f172a;
|
|
--color-neutral-50: #1e293b;
|
|
--color-neutral-100: #334155;
|
|
--color-neutral-200: #475569;
|
|
--bg-page: #0f172a;
|
|
--bg-surface: #1e293b;
|
|
--bg-card: #1e293b;
|
|
--text-main: #f1f5f9;
|
|
--text-muted: #94a3b8;
|
|
--border: #334155;
|
|
}
|
|
|
|
/* ── 라이트모드 ── */
|
|
:root, [data-theme="light"] {
|
|
--bg-page: var(--color-neutral-50);
|
|
--bg-surface: var(--color-neutral-0);
|
|
--bg-card: var(--color-neutral-0);
|
|
--text-main: var(--color-neutral-900);
|
|
--text-muted: var(--color-neutral-500);
|
|
--border: var(--color-neutral-200);
|
|
}
|
|
|
|
/* ── 글로벌 리셋 ── */
|
|
*, *::before, *::after { box-sizing: border-box; }
|
|
body {
|
|
font-family: var(--font-family);
|
|
font-size: var(--text-base);
|
|
line-height: var(--leading-normal);
|
|
color: var(--text-main);
|
|
background: var(--bg-page);
|
|
-webkit-font-smoothing: antialiased;
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## tokens.ts (Messenger RN)
|
|
|
|
```typescript
|
|
// app/constants/tokens.ts
|
|
export const colors = {
|
|
primary: { 50:'#eff4ff', 500:'#0051A2', 600:'#003f7f' },
|
|
accent: { 400:'#38bdf8', 500:'#00A3E0' },
|
|
neutral: { 0:'#fff', 50:'#f8fafc', 100:'#f1f5f9', 200:'#e2e8f0',
|
|
500:'#64748b', 700:'#334155', 900:'#0f172a' },
|
|
success: '#22c55e',
|
|
warning: '#f59e0b',
|
|
danger: '#ef4444',
|
|
info: '#3b82f6',
|
|
} as const;
|
|
|
|
export const spacing = {
|
|
1:4, 2:8, 3:12, 4:16, 5:20, 6:24, 8:32, 10:40, 12:48,
|
|
} as const;
|
|
|
|
export const radii = {
|
|
sm:4, md:8, lg:12, xl:16, full:9999,
|
|
} as const;
|
|
|
|
export const shadows = {
|
|
sm: { shadowColor:'#000', shadowOffset:{width:0,height:1}, shadowOpacity:.06, shadowRadius:3, elevation:2 },
|
|
md: { shadowColor:'#000', shadowOffset:{width:0,height:4}, shadowOpacity:.08, shadowRadius:6, elevation:4 },
|
|
} as const;
|
|
|
|
export const typography = {
|
|
xs:11, sm:13, base:15, lg:17, xl:20, '2xl':24, '3xl':30,
|
|
} as const;
|
|
```
|