코드로 받는 방법(zero/app/ui/)
원본: projects/skill-lens/design/ui-handoff.md
디자인 값의 원본은 ideber 저장소
projects/skill-lens/design/하나입니다. 보기용은 문서 사이트(https://skilllens.ideber.com/design/, 저장소에서 자동으로 만들어짐, 공개, 검색 제외)입니다. 디자인 시스템 아티팩트는 더 이상 쓰지 않습니다(PM 2026-11-09).ui/는 받아 쓰는 쪽이고 손으로 고치지 않습니다.
1. 받아 오는 파일 (ideber projects/skill-lens/design/ → zero/app/ui/)
| 저장소 경로 | ui/ 경로 | 비고 |
|---|---|---|
tokens.json | ui/tokens.json | 정본. 그대로 복사 |
| (생성) | ui/css/tokens.css | node scripts/build-tokens.mjs ui/tokens.json ui/css/tokens.css로 생성. 안의 @font-face가 ../fonts/를 가리키므로 반드시 ui/css/에 둔다. 커밋은 하되 편집 금지 |
components/bundle.css | ui/css/sl.css | 그대로 복사. sl- 접두어라 다른 CSS와 안 섞임 |
assets/Logo/skilllens-mark.svg, assets/Ambient/entry-light.webp | ui/assets/Logo/, ui/assets/Ambient/ | sl.css가 ../assets/로 부르므로 이 위치여야 로고 점과 입구 빛 바탕이 보임 |
components/lucide-sprite.svg | ui/lucide-sprite.svg | 아이콘 심볼. 추가는 Lucide에서 같은 규격으로 |
fonts/PretendardVariable.woff2 | ui/fonts/PretendardVariable.woff2 | ui/css/tokens.css의 @font-face가 ../fonts/를 참조하므로 이 위치여야 글꼴이 불러와짐 |
components/<Comp>/preview.html | (참고) | React 컴포넌트의 마크업·클래스·상태 정의. 그대로 옮김 |
components/<Comp>/README.md | (참고) | 각 컴포넌트의 props(“소비자가 제공”)와 규칙. 첫 줄 상태 딱지 확인 |
content.md, patterns.md, dataviz.md | (참고) | 문장, 흐름, 데이터 표시 |
2. 컴포넌트 → React 대응 (26개)
상태가 Stable인 14개부터. React 컴포넌트는 마크업과 클래스를 preview.html과 똑같이 내고, 동작만 props로 받습니다. 스타일을 새로 쓰지 않습니다.
| React | 클래스 | 상태 | Radix |
|---|---|---|---|
Button | sl-btn + --primary/--secondary/--link/--sm/--final | Stable | 없음 |
Chip | sl-chip + --brand/--neutral/--level/--kind/--success/--warning/--danger | Stable | 없음 |
Tabs | sl-tabs/sl-tab/sl-tab__count | Stable | @radix-ui/react-tabs |
OptionCard | sl-option (role=radio) | Stable | @radix-ui/react-radio-group |
ListRow | sl-row + --ai, sl-check, sl-tile | Stable | @radix-ui/react-checkbox |
ProgressBar | sl-bar/sl-bar-legend | Stable | 없음 |
StepProgress | sl-steps + __glide/__fill | Stable | 없음 |
DropZone | sl-drop/sl-file | Stable | 없음 |
ScoreStepper | sl-score (role=slider) | Stable | @radix-ui/react-slider |
Top | sl-top + --lg, sl-accent | Stable | 없음 |
BottomCTA | sl-cta + __row/__reason | Stable | 없음 |
TextField | sl-field + is-focus/is-error/is-filled/is-disabled | Stable | 없음 |
StatRow | sl-stats/sl-stat + --accent/--attention, count-up | Stable | 없음 |
SummaryCard | sl-summary | Stable | 없음 |
GlassFrame | sl-glass, sl-topbar, sl-band | In Progress | 없음 |
Shell(온보딩 틀) | sl-shell + __top/__card/__bottom | In Progress | 없음 |
AdminShell(작업 틀) | sl-admin + __nav/__item/__kbd/__menu/__ptitle/__guide/__top/__body/__main/__content/__head/__actions/__grid, sl-col-*, sl-cmdk, sl-views, sl-toolbar, sl-filter, sl-bulk, sl-grid(행 is-selected/is-attention/is-focus), sl-lvl, sl-drawer, sl-props | In Progress | 명령 팔레트는 cmdk, 서랍은 Radix Dialog(비모달) 또는 직접. 라우터의 현재 경로를 aria-current. 행 높이 선택은 저장 |
Responsive(foundations) | .sl-vp 컨테이너, breakpoint와 layout 토큰 | In Progress | 없음. 화면 루트를 .sl-vp로 감싸면 창 폭 규칙과 같음 |
LoadingSteps | sl-loading, sl-lens--orbit | In Progress | 없음 |
EmptyState | sl-empty | In Progress | 없음 |
Completion | sl-done-screen, sl-lens--merge | In Progress | 없음 |
BottomSheet | sl-scrim, sl-sheet | In Progress | @radix-ui/react-dialog (포커스 트랩 해결) |
Dialog | sl-dialog + --danger | In Progress | @radix-ui/react-alert-dialog |
DataTable | sl-table | In Progress | 없음 (정렬과 키보드는 9판 범위 밖) |
Toast | sl-toast | In Progress | @radix-ui/react-toast |
Combobox | sl-combo + __list/__item/__source/__empty, 폰은 sl-sheet__search | In Progress | @radix-ui/react-popover 또는 cmdk(코드 쪽 선택) |
DatePicker | sl-date + __chips/__chip, sl-cal + __day 상태 | In Progress | @radix-ui/react-popover + 달력 로직(코드 쪽) |
LevelPicker | sl-level + __btn/__desc, 폰은 sl-level-list + sl-level-row | In Progress | @radix-ui/react-radio-group |
Pagination | sl-pager + __count/__nav/__btn/__num/__gap | In Progress | 없음 |
DataTablePhone | sl-rowcards + sl-rowcard + __head/__facts/__actions | In Progress | 없음 (DataTable과 같은 데이터, 767px 기준 전환) |
Skeleton | sl-skel | Experimental | 없음 (1초 미만 + 재방문만) |
Entry | sl-entry, sl-ambient--reactive, sl-lens--intro | Experimental | 없음 |
Flow(데모) | sl-stage/sl-page | Experimental | 전환 로직만 가져감 |
StateGlyph, ChartColors, Motion | foundations | 없음 | 차트는 chart-* 토큰만 |
Lens(렌즈)는 공용 조각: <Lens mode="intro|orbit|merge" /> → sl-lens sl-lens--<mode> + <i/><i/>.
3. 경계 규칙 (게이트 훅 린트)
- 구간 분기는
ui/css/sl.css의 media와 container 규칙만.screens/에서 직접 미디어 쿼리를 쓰지 않는다. 구간이 더 필요하면breakpoint토큰에 먼저 추가.
screens/안에는.css·.scss파일 금지.style={}금지.<button>·<input>직접 사용 금지(ui 컴포넌트로).- 색은
var(--…)만. hex(#)·rgb(·hsl(리터럴 금지(ui/css/tokens.css제외). - 크기는 토큰 또는
ui/css/sl.css의 클래스.px리터럴은ui/밖에서 금지. - 아이콘은
<Icon name="zap" size="sm|md|lg" />(스프라이트 참조)만. 이모지·문자 기호 금지. - 문장은
content.md일곱 상황 중 하나로. 버튼 라벨은 동사·결과형. npm run check= 린트 + Playwright 스크린샷 비교(screens/__shots__/). 게이트 훅에서 자동.
4. 받는 순서
- 저장소
design/에서tokens.json,bundle.css,lucide-sprite.svg, 폰트,assets/의 로고와 빛 바탕을 받아 위 표의 위치에 둔다. 그 다음build-tokens.mjs를 실행한다. ui/index.ts에서 26개 컴포넌트 export. 스타일 파일은ui/css/tokens.css와ui/css/sl.css둘뿐./parts(부품 보기) 화면: 컴포넌트별 상태를 preview.html과 같은 순서로. 문서 사이트의 부품 견본과 나란히 비교 → 다르면ui/가 틀린 것.- 화면 작업.
이 사이트는 ideber 저장소 projects/skill-lens/ 에서 자동으로 만들어집니다. 고칠 때는 저장소를 고칩니다. 공개 주소이지만 검색엔진에는 나오지 않습니다.