ultrahand: theme
프로젝트의 테마를 한 번 구축하고 그 이후로 계속 발전시키세요. 테마는 디자인 토큰 파일과 결정 사항을 간략히 기록한 파일로, 프로젝트 내에 보관되어 이후 모든 디자인과 검토가 매번 새로운 디자인을 시작하는 대신 동일한 기반 위에서 이루어지도록 합니다. 파일 형식은 shared/theme/README.md에, 규칙은 shared/theme/rules.md에 있으며, 각 규칙은 shared/theme/sources.md를 참조합니다.
모든 테마는 비협상 조건(NN-1 ~ NN-12: 계층, 8포인트 그리드, 두 스킴, 대비, 실제 타입 스케일 등)을 유지하고 각 창의적 축(CR-1 ~ CR-10: 색조, 중성색, 타입 음성, 모서리, 깊이, 밀도…)에 대해 새로운 선택을 합니다. 규칙은 고정되어 있어 모든 테마가 잘 만들어졌다고 느껴지도록 하고, 축은 열려 있어 어떤 두 제품도 동일하게 보이지 않습니다. 시작하기 전에 rules.md를 읽으세요.
아래 스크립트는 ${CLAUDE_PLUGIN_ROOT}/shared/theme/에 있습니다.
1. 기존 항목 찾기
요청하기 전에 먼저 살펴보세요. 캔버스 아티팩트로만 존재하는 디자인의 경우, 아티팩트의 파일을 나열하고 거기서 design/을 읽으십시오. 프로젝트에서 design/THEME.md, *.tokens.json, tokens/, Style Dictionary 설정, 플랫폼의 테마 코드(CSS 사용자 정의 속성, tailwind.config.*, Flutter ThemeData / ColorScheme, SwiftUI 색상 에셋, Compose MaterialTheme)를 검색하세요. 결과에 따라 모드가 결정됩니다:
| 찾은 항목 | 모드 |
|---|---|
| 테마 파일과 THEME.md | 진화(4단계). 절대 다시 생성하지 마십시오. |
| 테마 파일은 없지만 스타일이 지정된 코드 | 추출(2단계), 그런 다음 진화. |
| 아무것도 없음 (신규 제품) | 생성(3단계). |
2. 코드에 이미 있는 테마 추출하기
목표는 디자인을 다시 하는 것이 아니라 현재의 모습을 정리하여 캡처하는 것입니다.
node scan.mjs <소스 디렉토리>를 실행하십시오(전체 목록은--json추가). 모든 색상, 간격 값, 반경 및 글꼴 크기를 개수와 위치와 함께 나열하고, 거의 중복된 색상을 그룹화하며 그리드를 벗어난 간격을 표시합니다. 플랫폼 테마 코드도 읽으십시오: 테마 객체가 명명한 값이 의도된 값이며, 흩어져 있는 원시 값은 표류입니다.- 역할 이름을 지정하십시오. 각 색상 클러스터에 대해 용도(페이지 배경, 본문 텍스트, 버튼, 테두리, 오류)를 찾아 시맨틱 역할(README.md에 필수 역할이 나열됨)에 매핑합니다. 하나의 역할, 하나의 값: 하나의 역할에 두 개의 거의 중복된 값이 있는 경우 더 많이 사용된 값을 유지합니다.
- 규칙에 맞게 조정하십시오. 간격을 NN-2 스케일로, 크기를 타입 스케일(NN-6)로, 반경을 짧은 스케일(NN-7)로 접습니다. 동일한 색조의 톤 단계를 따라 이동하여 대비 실패를 수정합니다(NN-4). 각 변경은 제품에 보이는 변화이므로 소유자의 승인을 위해 표(
13px → 12px, 4곳)로 나열하고, 소유자가 변경을 원하지 않는 것은 유지합니다. - 격차를 메우십시오. 대부분의 코드에는 다크 모드, 포커스 링 및
on-역할이 없습니다. 일반적인 것을 추가하는 대신 테마 자체 팔레트(NN-3, NN-10)에서 디자인하십시오. - 컴포넌트를 인벤토리화하십시오. 재사용 가능한 컴포넌트(
components/,ui/,widgets/,views/확인), 해당 변형 및 각각이 정의된 위치를 나열하십시오. 두 개의 다른 컴포넌트가 동일한 작업을 수행하는 경우, 테마에 복사할 대상이 아닌 병합 후보(EV-4)입니다. - 이미 가지고 있는 개성을 기록하십시오. 기존 모습을 각 창의적 축에 배치하고 THEME.md에 작성하십시오. 브랜드에서 제공한 선택(로고 색조, 라이선스 글꼴)은
locked이고, 나머지는open입니다.
그런 다음 파일을 작성합니다(5단계).
3. 새 테마 생성하기
- 개성. 세 가지 형용사와 대상, 그리고 고정된 사항(브랜드 색상, 로고, 글꼴, 플랫폼(네이티브 iOS 또는 Android 앱은 시스템 글꼴 및 색상에 의존하며, 테마는 이를 매핑합니다 [HIG-COLOR] [M3-COMPOSE]))을 물어보십시오.
- 세 가지 방향. 최소 세 가지 창의적 축에서 다른 세 가지 방향을 제안하십시오. 각각 형용사와 연결된 한 줄짜리 이유를 포함하십시오. 소유자가 원하지 않는 한 rules.md에 설명된 기본 모양은 피하십시오. 나란히 표시하고(6단계), 소유자가 하나를 선택하거나 혼합하도록 하십시오.
- 구축하십시오.
- 팔레트: 각 핵심 색상(기본, 중성, 오류 및 악센트)에 대해 어두운 쪽에서 밝은 쪽으로 약 10~13단계의 톤 스케일 [M3-HCT] [M3-COMPOSE]로, 모든 역할이 두 스킴 모두에서 대비를 충족하는 단계를 찾을 수 있도록 합니다.
- 시맨틱 색상: 모든 필수 역할, 각각의 다크 값, 각
on-X는X에 대해 디자인됩니다. - 공간: NN-2 스케일, 그런 다음 작업별 시맨틱 간격: 패딩을 위한
inset단계,gap-related,gap-group및gap-section으로 그룹 간 간격이 그룹 내 간격보다 명확히 더 크다는 구성 규칙(SEC-2 shared/composition/principles.md)이 내장됩니다. - 타입: 선택한 비율(CR-5)에서 하나의 스케일로, display, headline, title, body, label 역할 포함; body는 플랫폼 기본값(웹 16, iOS 17pt; 조밀한 데스크탑 도구의 경우 13~14, NN-6 참조).
- 모양, 깊이, 모션, 포커스: 선택한 모서리 스타일의 반경 스케일; 선택한 깊이 방법의 입체감 레벨; 지속 시간 및 이징 토큰; 2px 이상의 포커스 링.
- 컴포넌트: 컴포넌트가 해당 역할과 달라야 하는 데 필요한 컴포넌트 토큰만(EV-2). 대부분의 컴포넌트는 필요하지 않습니다.
모든 값을 버전 1.0.0에서 시작하십시오.
4. 기존 테마 진화시키기
"경고 색상 추가", "더 조밀한 테이블 필요", "더 따뜻하게 만들기", 또는 디자인 스킬이나 theme-review가 추가를 제안하는 요청의 경우:
- 먼저 THEME.md와 토큰을 읽으십시오(EV-1).
locked결정을 존중하십시오. 요청이 변경을 필요로 하는 경우 말하고 물어보십시오. - 적합한 기존 역할이 있으면 재사용하십시오(EV-2). 실제 격차가 있을 때만 기존 프리미티브 단계에 별칭을 붙여 토큰을 추가하십시오(EV-3).
- 광범위한 변경("더 따뜻하게", "더 장난기 있게")은
open창의적 축을 이동시킵니다: 프리미티브를 이동시키고, 모든 시맨틱 이름을 유지하며 대비 검사를 다시 실행하십시오. 이름은 리브랜딩을 통해서도 진실을 유지합니다(NN-11). $deprecated로 대체 이름을 지정하여 폐기하고, 이후 버전에서 제거하십시오(EV-6).- 버전을 올리고 변경된 사항과 필요한 화면을 설명하는 변경 로그 줄을 추가하십시오(EV-5).
5. 작성 및 확인
design/theme.tokens.json(또는 프로젝트의 기존 토큰 위치)과design/THEME.md를 README.md에 따라 작성하십시오. example.tokens.json이 구조를 보여줍니다.node check.mjs design/theme.tokens.json을 실행하고 모든 오류를 수정하십시오. 경고는 수정하거나 THEME.md에 이유를 기록해야 합니다.- 코드에 전달하십시오. 웹의 경우
node css.mjs design/theme.tokens.json --out <경로>/theme.css는 다크 모드가 내장된 CSS 사용자 정의 속성을 제공합니다. 다른 플랫폼 또는 여러 플랫폼을 동시에 지원하려면 이 형식을 읽고 Swift, Android, Compose 및 Flutter 코드를 작성하는 Style Dictionary를 권장합니다 [STYLE-DICT]. 스캔에서 발견된 원시 값을 토큰으로 대체하는 것을 제안하되, 모든 스타일 파일에 영향을 미치므로 요청 없이 수행하지 마십시오.
6. 테마 보여주기
소유자가 16진수 코드 목록이 아닌 작동하는 테마를 볼 수 있도록 플러그인 캔버스(shared/canvas/; README에 규약이 있음)에 견본을 구축하십시오:
node "${CLAUDE_PLUGIN_ROOT}/shared/theme/css.mjs" design/theme.tokens.json --style --out theme.html
node "${CLAUDE_PLUGIN_ROOT}/shared/canvas/build.mjs" \
--presets "${CLAUDE_PLUGIN_ROOT}/skills/desktop/references/presets.md" \
--head theme.html --screen screen.html --title "<Product> theme" --out index.html
견본의 screen.html은 테마의 사용자 정의 속성만 사용하며 다음을 보여줍니다: 측정된 비율이 있는 X 위의 on-X 텍스트로서의 색상 역할; 실제 복사본이 있는 타입 스케일; 간격 스케일; 반경 및 입체감 레벨; 각 인벤토리화된 컴포넌트의 상태별; 그리고 하나의 작은 현실적인 화면(목록과 양식)으로 구성됩니다. 캔버스의 Light/Dark 및 200% 텍스트 토글은 두 스킴과 텍스트 스케일링을 테스트합니다. 테마에 웹 글꼴이 필요한 경우 <link>를 동일한 헤드 파일에 넣으십시오.
방향 비교(3단계): 각 방향을 --style 없이 --selector '[data-state="a"]'(그런 다음 b, c)로 범위를 지정하고 화면 템플릿 자체의 <style> 상단에 붙여넣으십시오: 캔버스는 페이지 헤드가 도달할 수 없는 화면 내부에서 data-state를 설정합니다. config.json에서 방향 이름을 레이블로 하여 states a, b, c를 선언하면 상태 선택기가 전환합니다.
index.html을 아티팩트로 게시하십시오. 디자인 자체가 아티팩트인 경우, 테마로 빌드된(--head theme.html) 상태로 다시 게시하고 두 design/ 파일을 포함하십시오.
7. 발표
아티팩트 링크를 공유하십시오. 몇 줄로: 모드(생성, 추출 또는 진화), 버전, 개성이 창의적 축에 있는 위치와 이유, 잠금 및 열린 항목, 소유자가 승인해야 하는 조정 변경 사항, 검사 결과, 다음 단계(모바일, 태블릿 및 데스크탑 스킬이 읽음) 또는 theme-review로 코드 감사.