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

17 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, GNB 콘텐츠 LNB divider
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%, Table 행 20% / 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

| color.palette.green-dark-3 | --hm-sem-palette-green-dark-3 | #020a07 | ui_viz 확정 브랜드 단계 | Yes | Color Reference / 선택적 Theme palette | | color.palette.brown-light-3 | --hm-sem-palette-brown-light-3 | #c1a770 | ui_viz 확정 브랜드 단계 | Yes | Color Reference / 선택적 Theme palette | | color.palette.brown-dark-2 | --hm-sem-palette-brown-dark-2 | #2f281c | ui_viz 확정 브랜드 단계 | Yes | Color Reference / 선택적 Theme palette | | color.palette.brown-dark-3 | --hm-sem-palette-brown-dark-3 | #1d1810 | ui_viz 확정 브랜드 단계 | Yes | Color Reference / 선택적 Theme palette | | color.palette.orange-light-3 | --hm-sem-palette-orange-light-3 | #ec8f53 | ui_viz 확정 브랜드 단계 | Yes | Color Reference / 선택적 Theme palette | | color.palette.orange-light-2 | --hm-sem-palette-orange-light-2 | #f87725 | ui_viz 확정 브랜드 단계 | Yes | Color Reference / 선택적 Theme palette | | color.palette.orange-light-1 | --hm-sem-palette-orange-light-1 | #eb5f00 | ui_viz 확정 브랜드 단계 | Yes | Color Reference / 선택적 Theme palette | | color.palette.orange-dark-1 | --hm-sem-palette-orange-dark-1 | #bc4c00 | 2026-10-11 사용자 확정 브랜드 단계 | Yes | Color Reference / 선택적 Theme palette | | color.palette.orange-dark-2 | --hm-sem-palette-orange-dark-2 | #883700 | 2026-10-11 사용자 확정 브랜드 단계 | Yes | Color Reference / 선택적 Theme palette | | color.palette.orange-dark-3 | --hm-sem-palette-orange-dark-3 | #4f2000 | 2026-10-11 사용자 재확정 브랜드 단계 | Yes | Color Reference / 선택적 Theme palette |

총 83개. 기존 25개 + 핵심 역할 6개 + 선택적 팔레트 52개(2026-10-11 ui_viz 확정 단계 8개 및 사용자 확정 Orange Dark 1·2 추가). 팔레트는 컴포넌트별 계약이 아니며 Primary / Active / Focus를 개별 지정하면 팔레트 alias보다 우선한다. Focus와 Active, Primary와 On Accent는 각각 sibling이며 서로 alias하지 않는다.

color.action.cancel의 공개 key·기본값은 보존한다. 2026-10-10 Gray 통일 요청에 따라 기본 Outline 취소 ink는 기존 Gray palette #767676을 사용한다. 기본값과 다른 명시적 취소 컬러 override는 내부 Button mapping에 전달하고 Reset 시 복원한다. 전체 Default preset을 주입해도 기본 Gray와 동일하다. Solid 취소는 기존 Gray mapping을 유지한다. Runtime Theme.

디자인팀 Runtime 운영 결정 — 2026-10-06, 팔레트 보강 2026-10-11

기존 v1 입력 73개와 이전 팔레트 보강 이후 81개의 Key·CSS property·type·Default를 유지한다. Orange Dark 1·2는 최신 사용자 확정값으로 공개 입력에 추가하며 Dark 3는 기존 값을 유지한다. 과거 Needs Review 기록은 이력으로 보존하고 현재 기준은 브랜드 컬러 단계를 따른다. 공개 API isRuntimeTheme(unknown): value is RuntimeTheme를 제공한다. 이 사전 검증은 DOM을 변경하지 않는다. 기존 applyRuntimeTheme의 invalid 입력 시 reset 정책은 유지한다. 편집기는 사전 검증으로 invalid Import를 차단해 마지막 유효 Theme를 보존한다.

Default 컬러의 운영 원본은 themes/default.json(81개 컬러)이다. 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에 상태 입력은 추가하지 않으며, 실제 Production 소비처가 반복되어 공통 색상 의미가 확정될 때만 Semantic Token 승격을 검토한다.