Files
HMDesign/docs/guidelines/runtime-theme-contract.md
T

15 KiB

Public Runtime Theme Contract

계약 Source of Truth: packages/ui/src/theme/contract.ts. 모든 입력은 선택적이며 외부 override 가능. Component/derived 변수는 공개 입력이 아니다.

Runtime JSON Token CSS Token Default 의미 외부 override 주요 영향
color.bg.content --hm-sem-bg-content #f5f0e5 콘텐츠 면 Yes gnb, lnb
color.bg.surface --hm-sem-bg-surface #ffffff 기본/카드/입력 면 Yes checkbox, radio, switch, slider, badge, table, input, select, button, gnb
color.fg.primary --hm-sem-fg-primary #0a221d 주요 텍스트 Yes calendar, pagination, badge, table, input, select, gnb
color.fg.secondary --hm-sem-fg-secondary #6e6759 보조 텍스트 Yes calendar, pagination, badge, table, gnb
color.fg.placeholder --hm-sem-fg-placeholder #999999 Placeholder Yes input, select
color.action.primary --hm-sem-action-primary #123328 Strong / Primary ink Yes checkbox/radio hover, slider Hover/Drag halo, pagination current, badge default, button outline, navigation current ink
color.action.cancel --hm-sem-action-cancel #6e6759 공개 취소 역할 Yes Button variant="cancel" + appearance="outline"
color.action.destructive --hm-sem-action-destructive #d32f2f 오류/위험 역할 Yes checkbox, radio, badge, input, button
color.stroke.default --hm-sem-stroke-default #9a9284 기본 border Yes checkbox, radio, switch, badge
color.stroke.input.default --hm-sem-stroke-input-default #dedbd2 입력/패널 divider border Yes table, input, select
color.stroke.input.focus --hm-sem-stroke-input-focus #266651 공통 Focus border/ring Yes input, select, button, checkbox, calendar, slider Keyboard Focus halo 등; GNB/LNB는 contextual 예외
color.bg.brand.stop.0 --hm-sem-brand-bg-stop-0 #0a221d 기존 gradient stop: color.bg.brand.stop.0 Yes Theme palette / adapter
color.bg.brand.stop.12 --hm-sem-brand-bg-stop-12 #071e18 기존 gradient stop: color.bg.brand.stop.12 Yes Theme palette / adapter
color.bg.brand.stop.42 --hm-sem-brand-bg-stop-42 #123328 기존 gradient stop: color.bg.brand.stop.42 Yes Theme palette / adapter
color.bg.brand.stop.78 --hm-sem-brand-bg-stop-78 #266651 기존 gradient stop: color.bg.brand.stop.78 Yes Theme palette / adapter
color.bg.brand.stop.100 --hm-sem-brand-bg-stop-100 #205241 기존 gradient stop: color.bg.brand.stop.100 Yes Theme palette / adapter
surface.action.primary.stop.0 --hm-sem-action-surface-stop-0 #1f8265 기존 gradient stop: surface.action.primary.stop.0 Yes button, gnb
surface.action.primary.stop.30 --hm-sem-action-surface-stop-30 #165c47 기존 gradient stop: surface.action.primary.stop.30 Yes button, gnb
surface.action.primary.stop.65 --hm-sem-action-surface-stop-65 #114838 기존 gradient stop: surface.action.primary.stop.65 Yes button, gnb
surface.action.primary.stop.100 --hm-sem-action-surface-stop-100 #08241c 기존 gradient stop: surface.action.primary.stop.100 Yes button, gnb
surface.action.primary.border.stop.0 --hm-sem-action-border-stop-0 #0a221d 기존 gradient stop: surface.action.primary.border.stop.0 Yes button
surface.action.primary.border.stop.50 --hm-sem-action-border-stop-50 #34daaa 기존 gradient stop: surface.action.primary.border.stop.50 Yes button
surface.action.primary.border.stop.100 --hm-sem-action-border-stop-100 #08241c 기존 gradient stop: surface.action.primary.border.stop.100 Yes button
radius.input.default --hm-radius-input 4px Input/Select radius Yes input, select
radius.container.default --hm-radius-container 4px Container radius Yes Theme palette / adapter
color.state.active --hm-sem-state-active #266651 Checked / Selected / ON fill Yes checkbox, radio, switch, slider, progress, calendar
color.on.state.active --hm-sem-on-state-active #ffffff Active 위 텍스트/indicator Yes checkbox, calendar
color.fg.inverse --hm-sem-on-action-primary #ffffff 반전 텍스트 Yes pagination, badge, button, gnb, lnb
color.bg.subtle --hm-sem-bg-subtle #f4f1ea 은은한 면 Yes calendar, badge, table
color.accent --hm-sem-accent #bddfd4 Soft Highlight 45% / Selected·Open surface 100% 원색 Yes select, combobox, menu item, table, calendar, pagination hover / toggle, menubar, navigation-menu trigger
color.on.accent --hm-sem-on-accent #123328 Accent 위 텍스트; Primary와 독립 sibling Yes select, combobox, menu item, calendar, pagination hover, toggle, menubar, navigation-menu
color.palette.green-light-4 --hm-sem-palette-green-light-4 #34daaa 선택적 Theme 팔레트: green-light-4 Yes button
color.palette.green-light-3 --hm-sem-palette-green-light-3 #249473 선택적 Theme 팔레트: green-light-3 Yes data-table Sort Direction Accent, tabs 장식, lnb gradient
color.palette.green-light-2 --hm-sem-palette-green-light-2 #266651 선택적 Theme 팔레트: green-light-2 Yes checkbox, radio, switch, slider, progress, calendar, table, input, select, gnb, lnb
color.palette.green-light-1 --hm-sem-palette-green-light-1 #205241 선택적 Theme 팔레트: green-light-1 Yes table, button, lnb
color.palette.green-default --hm-sem-palette-green-default #123328 선택적 Theme 팔레트: green-default Yes checkbox, radio, slider, calendar, pagination, badge, select, button, gnb, lnb
color.palette.green-dark-1 --hm-sem-palette-green-dark-1 #0a221d 선택적 Theme 팔레트: green-dark-1 Yes calendar, pagination, badge, table, input, select, button, gnb
color.palette.green-dark-2 --hm-sem-palette-green-dark-2 #071e18 선택적 Theme 팔레트: green-dark-2 Yes Theme palette / adapter
color.palette.brown-light-2 --hm-sem-palette-brown-light-2 #897445 선택적 Theme 팔레트: brown-light-2 Yes button
color.palette.brown-light-1 --hm-sem-palette-brown-light-1 #604f32 선택적 Theme 팔레트: brown-light-1 Yes button
color.palette.brown-default --hm-sem-palette-brown-default #3e3523 선택적 Theme 팔레트: brown-default Yes button
color.palette.brown-dark-1 --hm-sem-palette-brown-dark-1 #352d1d 선택적 Theme 팔레트: brown-dark-1 Yes button
color.palette.brown-light-4 --hm-sem-palette-brown-light-4 #ecd4a2 선택적 Theme 팔레트: brown-light-4 Yes Theme palette / adapter
color.palette.orange-light-4 --hm-sem-palette-orange-light-4 #feba88 선택적 Theme 팔레트: orange-light-4 Yes button
color.palette.orange-default --hm-sem-palette-orange-default #cc5200 선택적 Theme 팔레트: orange-default Yes button
color.palette.warm-neutral-light --hm-sem-palette-warm-neutral-light #e0dace 선택적 Theme 팔레트: warm-neutral-light Yes slider, progress
color.palette.warm-neutral-mid --hm-sem-palette-warm-neutral-mid #9a9284 선택적 Theme 팔레트: warm-neutral-mid Yes checkbox, radio, switch, badge
color.palette.warm-neutral-dark --hm-sem-palette-warm-neutral-dark #6e6759 선택적 Theme 팔레트: warm-neutral-dark Yes calendar, pagination, badge, table, gnb
color.palette.beige-light --hm-sem-palette-beige-light #f5f0e5 선택적 Theme 팔레트: beige-light Yes gnb, lnb
color.palette.red-danger --hm-sem-palette-red-danger #d32f2f 선택적 Theme 팔레트: red-danger Yes checkbox, radio, badge, input, button
color.palette.white --hm-sem-palette-white #ffffff 선택적 Theme 팔레트: white Yes checkbox, radio, switch, slider, calendar, pagination, badge, table, input, select, button, gnb, lnb
color.palette.black --hm-sem-palette-black #000000 선택적 Theme 팔레트: black Yes checkbox, switch, select, button, gnb, lnb
color.palette.neutral-gray-500 --hm-sem-palette-neutral-gray-500 #999999 선택적 Theme 팔레트: neutral-gray-500 Yes input, select
color.palette.green-tone-1 --hm-sem-palette-green-tone-1 #1f8265 선택적 Theme 팔레트: green-tone-1 Yes button, gnb
color.palette.green-tone-2 --hm-sem-palette-green-tone-2 #165c47 선택적 Theme 팔레트: green-tone-2 Yes button, gnb
color.palette.green-tone-3 --hm-sem-palette-green-tone-3 #114838 선택적 Theme 팔레트: green-tone-3 Yes button, gnb
color.palette.green-tone-4 --hm-sem-palette-green-tone-4 #08241c 선택적 Theme 팔레트: green-tone-4 Yes button, gnb
color.palette.warm-neutral-pale --hm-sem-palette-warm-neutral-pale #dedbd2 선택적 Theme 팔레트: warm-neutral-pale Yes table, input, select
color.palette.warm-neutral-secondary --hm-sem-palette-warm-neutral-secondary #ede8db 선택적 Theme 팔레트: warm-neutral-secondary Yes Theme palette / adapter
color.palette.warm-neutral-muted --hm-sem-palette-warm-neutral-muted #f4f1ea 선택적 Theme 팔레트: warm-neutral-muted Yes calendar, badge, table
color.palette.green-tint --hm-sem-palette-green-tint #bddfd4 선택적 Theme 팔레트: green-tint Yes calendar, pagination, table, select, gnb, lnb
color.palette.yellow-accent --hm-sem-palette-yellow-accent #ffc600 선택적 Theme 팔레트: yellow-accent Yes lnb
color.palette.brown-deep --hm-sem-palette-brown-deep #221d13 선택적 Theme 팔레트: brown-deep Yes button
color.palette.brown-highlight --hm-sem-palette-brown-highlight #a98d53 선택적 Theme 팔레트: brown-highlight Yes button
color.palette.orange-light --hm-sem-palette-orange-light #d35a00 선택적 Theme 팔레트: orange-light Yes button
color.palette.orange-mid --hm-sem-palette-orange-mid #ce5600 선택적 Theme 팔레트: orange-mid Yes button
color.palette.orange-dark --hm-sem-palette-orange-dark #b44b00 선택적 Theme 팔레트: orange-dark Yes button
color.palette.orange-deep --hm-sem-palette-orange-deep #783402 선택적 Theme 팔레트: orange-deep Yes button
color.palette.orange-border --hm-sem-palette-orange-border #bc4c00 선택적 Theme 팔레트: orange-border Yes button
color.palette.orange-border-deep --hm-sem-palette-orange-border-deep #5e2902 선택적 Theme 팔레트: orange-border-deep Yes button
color.palette.gray --hm-sem-palette-gray #767676 선택적 Theme 팔레트: gray Yes button
color.palette.gray-dark --hm-sem-palette-gray-dark #5a5a5a 선택적 Theme 팔레트: gray-dark Yes button
color.palette.indicator --hm-sem-palette-indicator #2d2d2d 선택적 Theme 팔레트: indicator Yes select

총 73개. 기존 25개 + 핵심 역할 6개 + 선택적 팔레트 42개. 팔레트는 컴포넌트별 계약이 아니며 Primary / Active / Focus를 개별 지정하면 팔레트 alias보다 우선한다. Focus와 Active, Primary와 On Accent는 각각 sibling이며 서로 alias하지 않는다.

color.action.cancel은 Button의 variant="cancel" Outline ink를 위한 Public Runtime role로 사용한다. Solid 취소는 기존 gray Component mapping을 유지하고, Outline 취소는 이 semantic role을 소비한다. 외부 소비 가능성이 있으므로 deprecated로 간주하지 않는다. 적용·병합·fallback·scope 정책은 Runtime Theme를 따른다.

디자인팀 Runtime 운영 추가 결정 — 2026-10-06

기존 v1 입력 73개와 CSS property/type 계약을 유지한다. 공개 API isRuntimeTheme(unknown): value is RuntimeTheme를 제공한다. 이 사전 검증은 DOM을 변경하지 않는다. 기존 applyRuntimeTheme의 invalid 입력 시 reset 정책은 유지한다. 편집기는 사전 검증으로 invalid Import를 차단해 마지막 유효 Theme를 보존한다.

Default 컬러의 운영 원본은 themes/default.json(71개 컬러)이다. scripts/theme-defaults.mjs가 JSON과 컬러 literal 없는 alias/geometry template에서 package primitives.css, default.css, default-values.generated.ts를 생성한다. contract.ts의 defaultValue와 defaultRuntimeTheme는 생성 데이터를 읽는다. 2개 radius/geometry는 template에서 유지한다. CSS fallback/현재 색을 유지하고 세 가지 최종 명령의 pre hook에서 stale 생성 데이터를 검사한다. Theme-only 산출은 npm run build:themes로 분리한다.

Storybook Theme/Designer Playground/Editor는 17개 상위 컬러 역할과 JSON URL/파일 Preview를 제공하는 소비자다. Global decorator에서 resolveRuntimeTheme(theme, defaultJson) 후 Production applyRuntimeTheme(document.documentElement, theme) → CSS Custom Properties → 기존 Mapping으로 적용한다. JSON Export/Import는 동일 v1 계약이다. 컬러 artifact/편집기만 radius를 거부한다. Production API의 기존 radius/gradient 계약은 유지한다.

추가 Production API는 fetchRuntimeTheme(url, request?), resolveRuntimeTheme(theme, defaults?), loadRuntimeTheme(root,url,options?)다. fetch는 DOM과 분리되며 validation은 기존 isRuntimeTheme을 재사용한다. Loader 실패는 HM package fallback, partial은 같은 계약으로 교체/병합하며 superseded 요청은 새 Theme를 덮거나 reset하지 않는다. 회사 CDN URL은 하드코딩하지 않는다.

사용법: 디자인팀 Theme 가이드, Theme 운영/배포. 적용·fallback·scope 정책: Runtime Theme.

Dashboard 상태 색상 범위

Dashboard의 active / hold / done / issue 업무 상태 계약은 packages/ui/src/patterns/dashboard-status/contract.ts에서 ID·label·tone을 제공한다. 상태 변수 원본은 packages/ui/src/patterns/dashboard-status/dashboard-status.css이며 @hm-design/ui/dashboard-status.css로 배포한다. src/patterns/dashboard-status-contract.css는 기존 Story/HTML 경로의 호환 import다. Theme CSS 다음에 상태 CSS를 로드하고 --hm-dashboard-status-active|hold|done|issue를 화면 요소의 색상에 별도로 연결한다. 상태 CSS 자체는 Badge나 data-status를 자동으로 꾸미지 않는다. active/hold/issue는 기존 Story 색상을 보존하는 compatibility mapping이고 done은 :root 및 [data-hm-theme]에서 해당 scope의 기존 HM white token을 참조한다. 기존 HM Theme 및 Public Runtime Token/JSON 73개는 변경하지 않으며, 실제 Production 소비처가 반복되어 공통 색상 의미가 확정될 때만 Semantic Token 승격을 검토한다.