디자인 레이어가 React + CSS Modules 전용이던 문제를 푼다. 기존 클래스명은
`.button`·`.label`·`.icon`처럼 일반명사여서, CSS Modules 스코프 밖으로 나가면 소비
프로젝트의 동명 클래스와 전부 충돌했다. SCSS만 쓰는 프로젝트(Vue·Svelte·서버 템플릿)는
버튼을 다시 만들 수밖에 없었다.
`fox-` 접두사 + BEM(fox-button__label · fox-button--primary)으로 바꿔 이름을 전역
유일하게 만들고 CSS Modules를 걷어냈다. 충돌 방지는 도구가 아니라 접두사 규율이 담당한다.
React 컴포넌트는 이 클래스를 조립하는 얇은 래퍼가 되고, 래퍼 없이도 같은 디자인을 얻는다.
진입점을 둘 다 제공한다 — `@fox/styles/components`(전부)와 개별 파티셜
`@fox/styles/fox-button`(안 쓰는 CSS를 번들에서 뺀다). 둘을 같이 써도 Sass가 모듈을
한 번만 로드해 중복되지 않는다.
마크업 계약을 스타일 파일 상단 주석과 @fox/README.md에 적었다 — React 밖 소비자는
그것만 보고 DOM을 짤 수 있어야 한다.
앱 화면 스타일은 `.module.scss` 그대로다(앱 전용이라 스코프가 이득). 규약 문서도 그
구분이 드러나게 고쳤다.
Co-Authored-By: Claude Opus 5
Figma 시안(관리자페이지 node 390:439)을 토큰만으로 옮겼다. 컴파일된 CSS의 토큰 참조
50개, 원시 hex/px/rem 리터럴 0개다.
시안에서 확인한 것(추측하지 않음): gap은 lg·md·sm이 gap-2이고 xsm만 gap-1이다.
primary에는 테두리가 없고 secondary·default만 border-1을 갖는다. disabled는 계열과
무관하게 테두리가 사라진다(시안에서 disabled-border 미사용). 높이만 고정이고 좌우
padding만 지정돼 너비는 가변이다.
토큰이 아닌 코드 세 가지를 사용자 승인 후 넣었다.
- line-height: 1 / letter-spacing: -0.025em — 시안 텍스트 스타일 label/*-strong의 값이나
Figma에서 변수로 export되지 않아 토큰이 없다. 네 크기가 같은 값이라 규칙 하나로 끝난다.
- box-sizing: border-box — 높이 고정 + secondary·default의 1px 테두리 때문에 필수다.
없으면 계열별 바깥 높이가 2px 어긋난다.
- cursor·white-space·flex-shrink — 구조·상호작용 규칙. 버튼 스코프에만 적용한다.
모양 규칙은 @fox/styles/_fox-button.scss가 소유하고 module이 @use로 끌어올린다 —
클래스명이 모듈 스코프로 감싸져 전역 충돌이 없고, index.scss는 이 파티셜을 포함하지
않아 CSS가 중복 출력되지 않는다.
아이콘은 계열별 색을 토큰으로 입히기 위해 ReactNode로 받는다(currentColor 전제).
크기는 슬롯이 form-icon-* 토큰으로 정한다.
error 계열은 시안 미정이라 클래스를 비워 뒀다.
Co-Authored-By: Claude Opus 5
Figma 컬렉션 5개(primitive/theme/size/테마/반응형)·모드 7개를 옮겼다.
색상은 light/dark를 light-dark() 한 줄에 묶어 테마 드리프트를 구조적으로 막고,
반응형 크기는 모바일 우선으로 깔고 768px 이상에서 pc 값이 덮는다.
Figma의 alias를 CSS에서도 var() 참조로 보존했다 — 색상 표현 542개 중 476개가
primitive/theme를 참조하므로 바닥층을 바꾸면 시맨틱까지 전파된다. 참조 대상이
없거나 값이 어긋나는 것만 리터럴로 떨어뜨렸다.
알파 색상은 rgb(R G B / A)로 낸다. hex는 알파를 담지 못해 그대로 두면 반투명이
불투명이 된다.
루트에 소속 없이 들어 있던 29개는 두 번째 theme 컬렉션(미제공)을 참조하며
chart-alt로 명명했다 — 이름은 임시다.
Co-Authored-By: Claude Opus 5
색상·타이포·간격·radius·그림자·모션·브레이크포인트 토큰은 실제 디자인 자료 없이
임의로 만들어진 값이었다. 디자인 시스템은 제공된 자료로만 구축한다는 원칙에 따라
값과 그에 딸린 함수·믹스인·리셋을 모두 제거한다.
자료를 받는 시점에 구조부터 다시 세운다.
Co-Authored-By: Claude Opus 5
토큰 SSOT는 tokens/의 SCSS map 하나다. 여기서 --fox-* 커스텀 프로퍼티(_root)와
토큰 이름 검증 목록(_functions)이 함께 파생되므로 값과 이름이 어긋날 수 없다.
없는 토큰 이름은 @error로 빌드를 실패시켜 하드코딩 금지를 컴파일러가 강제한다.
모든 치수는 rem이며 1rem = 10px(html font-size 62.5%). 단 미디어 쿼리의 rem은
브라우저 기본 크기 기준이라 브레이크포인트만 예외이며, 각 값에 px 환산을 병기했다.
토큰 값은 파이프라인 검증용 임시 플레이스홀더이며 Figma 확정 시 교체한다.
Co-Authored-By: Claude Opus 5