---
name: featuring-ds
description: "Use when writing or modifying React code that imports from @featuring-corp/components, @featuring-corp/design-tokens, @featuring-corp/icons, or @featuring-corp/charts, OR when styling with $css prop, Box/Flex/HStack/VStack/Center/Grid/Typo layout primitives, CoreButton/CoreTextInput/CoreSelect (legacy Core*) components, or touching @layer ft-reset/ft-normalize/ft-components/ft-utilities. Covers compound component patterns, Layout primitive enforcement, $css token-based styling, CSS Cascade Layer order, and legacy Core* preservation policy."
---

# Featuring Design System — AI Agent Skill
<!-- 자동 생성 파일. 직접 수정 금지. -->
<!-- Generated: 2026-05-22 | Commit: 7ad33fc -->

## ⚠️ 작업 전 필수 워크플로우

**항상 Docs MCP를 먼저 호출하세요.** 학습 데이터의 API/토큰/버전은 릴리스마다 바뀌므로 기억으로 추정하지 말 것.

| 작업 | 먼저 호출할 MCP |
|------|----------------|
| **스타일 / `$css` 작성** | `get_page guide/css-prop` (문법·조건·병합 우선순위) + `get_tokens <category>` (존재하는 토큰만 사용) |
| **UX·디자인 결정** | `get_page guide/ux-guide` + `guide/design-philosophy` + `guide/visual-philosophy` (계층·간격·색·인터랙션 기본값) |
| **컴포넌트 사용** | `search <이름>` 또는 `get_page components/components/<이름>` (props·variants·예시) |
| **반응형 구성** | `get_page guide/responsive` (브레이크포인트·`size` 객체) |
| **설치 / peer 버전 안내** | `get_versions` — 절대 기억으로 추정하지 말 것 |
| **기존 `Core*` 코드 작업** | `get_page components/legacy/core-<이름>` (레거시 API 그대로 유지) |

### 레거시 보존 원칙

- `Core*` (예: `CoreButton`, `CoreTextInput`, `CoreSelect`)는 **레거시 패턴**.
- **기존 `Core*` 사용처를 임의로 마이그레이션하지 말 것.** 명시적 요청이 있을 때만 변경.
- 새로 추가하는 컴포넌트/레이아웃에서만 compound 패턴(`Button.Root`, `Tag.Root`, ...) 사용.

## 설치

1. `.npmrc` — `@featuring-corp:registry=https://npm.pkg.github.com`
2. `npm install @featuring-corp/design-tokens @featuring-corp/components @featuring-corp/icons`
3. 차트용: `npm install @featuring-corp/charts recharts` (peer: `recharts ^3.8.0`)
4. 앱 진입점: `import '@featuring-corp/components/preset/featuring';`
5. 앱 루트: `#root { isolation: isolate; }` (Portal 스태킹)

> 설치 명령을 안내하기 전에 `get_versions` (Docs MCP)로 현재 정확한 버전을 확인할 것.

## 패키지

| 패키지 | 설명 |
|--------|------|
| `@featuring-corp/design-tokens` | 1,000+ 디자인 토큰 — 색상·간격·타이포그래피·radius·elevation |
| `@featuring-corp/components` | 30+ React UI 컴포넌트 + 레이아웃 primitive + CSS Preset |
| `@featuring-corp/icons` | 시스템 아이콘 333 + 서비스 아이콘 26 |
| `@featuring-corp/charts` | Recharts 1:1 래퍼, `$token` fill/stroke 지원 (peer: `recharts`) |

## 필수 규칙

- **레거시 `Core*` 코드를 임의 마이그레이션 금지** — 위 "레거시 보존 원칙" 참고
- **레이아웃은 Layout primitive 사용 필수** — `<div>` + inline flex/grid 금지. `Box`, `Flex`, `HStack`, `VStack`, `Center`, `Grid`, `Typo`만 사용. 시맨틱 HTML이 필요하면 `render={<section />}` / `render={<h2 />}` 등으로 전달.
- **스타일 우선순위**: ① `$css` prop (기본) → ② `className` (`$css`가 커버 못 하는 드문 케이스) → ③ `style` inline (최후 수단, 실제 거의 필요 없음). 무조건 `$css`가 먼저.
- **CSS Cascade Layer 순서는 preset import 1줄로 해결** — `import '@featuring-corp/components/preset/featuring'`. preset을 쓰지 않으면 `@layer ft-reset, ft-normalize, ft-components, ft-utilities;`를 소비자 루트 CSS에서 **직접 선언해야 함** ("CSS Cascade Layer" 섹션 참고).
- **소비자 CSS가 항상 우선** — DS 스타일은 `@layer ft-*`에 있고 소비자 CSS는 unlayered이라 `!important` 없이 오버라이드.
- **Compound 패턴**: `Button.Root > Button.Icon + Button.Text` — 순서 = 렌더 순서
- 토큰 기반 스타일은 반드시 **`$css` prop**으로 — 단일 API 표면
- 시맨틱 HTML 변경은 **`render` prop**: `render={<a href="/" />}` (`as` prop 사용 금지)
- **`size` prop은 반응형 값 지원** — 단일 값 `size="md"` 사용 가능, 필요 시 `size={{ mobile: 'sm', desktop: 'md' }}`로 전환. 둘 다 허용.
- Compound 컴포넌트에 **`displayName` 사용 금지**
- **`aria-label`은 소비자 책임** — 컴포넌트가 강제하지 않음
- 컴포넌트는 레이아웃만 담당. ellipsis 등 소비자 스타일은 컴포넌트에 내장하지 않음

## CSS Cascade Layer

모든 DS 스타일은 `@layer ft-*`에 격리. preset import 한 줄로 순서가 자동 선언됩니다.

```css
@layer ft-reset, ft-normalize, ft-components, ft-utilities;
/* ↑ preset이 포함. unlayered 소비자 CSS는 항상 이 모두보다 우선 */
```

| 레이어 | 내용 |
|--------|------|
| `ft-reset` | Meyer reset |
| `ft-normalize` | normalize + base element + scrollbar |
| `ft-components` | 모든 컴포넌트 CSS (vanilla-extract + plain CSS) |
| `ft-utilities` | rainbow-sprinkles의 `$css` atomic utility |
| (unlayered) | 소비자 CSS — 항상 최상위 우선순위 |

> **왜 flat name(`ft-`)인가?** CSS 스펙상 dot-nested(`ft.components`)는 한 부모 레이어 안에 묶여 다른 레이어 시스템(Tailwind 등)과 interleave 불가. 평탄하게 선언해야 자유롭게 섞임.

> Tailwind v4 등 외부 레이어와 공존하려면 `@layer tailwind, ft-reset, ft-normalize, ft-components, ft-utilities;` 식으로 순서만 확장.

## `$css` Prop

rainbow-sprinkles 기반의 토큰-aware atomic styling. 모든 레이아웃/Compound 컴포넌트에서 사용.

```tsx
<Box $css={{
  // 토큰 값 ($ 접두)
  padding: '$spacing-400',
  bgColor: '$background-1',
  borderRadius: '$radius-200',

  // 임의 CSS 값
  maxWidth: '600px',

  // 반응형 — 레이아웃 속성
  gap: { mobile: '$spacing-200', desktop: '$spacing-400' },

  // 인터랙티브 — 색상 속성
  backgroundColor: { default: '$background-1', hover: '$background-2' },
}} />
```

병합 우선순위 (낮음 → 높음): `$css` 토큰 → `$css` className → 내부 props → 소비자 className/style

## 브레이크포인트

| 이름 | 최소 너비 | 미디어 쿼리 |
|------|----------|------------|
| `mobile` | 0px | 기본값 (미디어 쿼리 없음) |
| `tablet` | 768px | `@media (min-width: 768px)` |
| `desktop` | 1024px | `@media (min-width: 1024px)` |
| `wide` | 1440px | `@media (min-width: 1440px)` |

## 인터랙티브 조건 (색상 속성)

| 조건 | CSS 선택자 | 설명 |
|------|-----------|------|
| `default` | — | 기본 상태 |
| `hover` | `&:hover` | 마우스 호버 |
| `active` | `&:active` | 클릭 중 |
| `focus` | `&:focus-visible` | 키보드 포커스 |
| `disabled` | `&:disabled` | 비활성 상태 |
| `readOnly` | `&:read-only` | 읽기 전용 |
| `focusWithin` | `&:focus-within` | 자식 요소 포커스 |
| `groupHover` | `[data-group]:hover &` | 부모 그룹 호버 |

## 컴포넌트 패턴

네 가지 패턴이 공존. JSX 예시·props·variants는 각 컴포넌트 페이지를 MCP로 조회 (`get_page components/components/<이름>`).

- **Compound (신규)** — `Button`, `Tag`, `Link`, `Avatar`, `Checkbox`, `Radio`, `Select`, `Tabs`, ... `X.Root + X.Icon + X.Text` 네임스페이스. Context로 size/loading/disabled 공유, 자식 순서 = 렌더 순서.
- **레이아웃 primitive** — `Box`, `Flex`, `HStack`, `VStack`, `Center`, `Grid`, `Typo`. 모든 레이아웃은 이걸로. 시맨틱 HTML은 `render={<section />}` / `render={<h2 />}`.
- **차트** — `@featuring-corp/charts`, recharts 1:1 래퍼. `fill`/`stroke`에 `$primary-50` 같은 토큰 전달 가능.
- **레거시 (`Core*`)** — `CoreButton`, `CoreTextInput`, `CoreSelect`, ... `forwardRef` + recipe variants. **기존 사용처 임의 마이그레이션 금지.** 새 코드에서만 compound 사용. 매핑 필요 시 `get_page components/index`.

## 테마

- Featuring: `import '@featuring-corp/components/preset/featuring';`
- DataEffect: `import '@featuring-corp/components/preset/dataEffect';`

## 토큰 네이밍

- Global: `--global-colors-{hue}-{shade}`, `--global-spacing-{scale}`, `--global-radius-{scale}`
- Semantic: `--semantic-color-{category}-{level}`, `--semantic-typography-{variant}-{property}`
- `$css`에서는 `$` 접두 — `$spacing-400`, `$background-1`, `$primary-60`

## 토큰 치트시트

자주 쓰는 토큰 (전체 목록은 `get_tokens` MCP):

| 범주 | 토큰 |
|------|------|
| Text | `$text-1` (primary) · `$text-2` (secondary) · `$text-3` (muted) · `$text-4/5` · `$text-6` (on-color) |
| Background | `$background-1` (흰 배경) · `$background-2` (gray-5) · `$background-3` (gray-10) · `$background-4` · `$background-5` (어두움) |
| Border | `$border-default` (gray-15) · `$border-1/2/3/4` (gray 30→60) |
| Support | `$support-{error|warning|success|info}-{1/2/3/4}` |
| Icon | `$icon-primary` · `$icon-secondary` · `$icon-tertiary` · `$icon-on-color-default` · `$icon-interactive` |
| Focus ring | `$focus` (primary-50 @ 20% alpha) |
| Spacing | `$spacing-{0/25/50/100/150/200/250/300/400/500/600/800/1000/1200/1600/2000}` (숫자 = px × 4) |
| Radius | `$radius-{50/100/200/300/400/full}` |
| Elevation | `$elevation-{2/4/8/16/28/64}` |
| Brand primary | `$primary-{10/20/30/40/50/60/70/80/100}` |
| Gray | `$gray-{5/10/15/20/30/40/50/60/70/80/90}` |

> 존재하지 않는 토큰을 만들어내지 말 것. 불확실하면 `get_tokens` MCP를 먼저 호출.

## 상세 문서

**코드를 쓰기 전에 항상 Docs MCP를 먼저 사용할 것.** 기억 속 API보다 MCP 응답을 진실로 삼으세요.

- **Docs MCP** — `get_versions` (설치 / peer deps) · `search` / `list_pages` / `get_page` (가이드·마이그레이션·API) · `get_tokens` (토큰 카탈로그)
- **Storybook MCP** — 실시간 props·코드 예시·인터랙션 테스트 (로컬 `storybook dev` 필요)
