Files
HMDesign/packages/sw/ai/DESIGN_RULES.md
T
shkim4 3a5e29f2fa Merge branch 'integration/sw-home-menu' into feature/sw-home-menu
Integrate the SW home (logo) menu into SWHeader for SW general mode only.
SW viewer mode code and stories are unchanged.

- Resolve conflicts: keep both sw-home-menu and sw-viewer exports;
  renumber AI docs (catalog viewer 8->9, patterns home menu 7->8,
  design rules home menu 11->12)
- SWHeader: start the home menu after the file name when it sits
  inside controls, so the file name stays visible
- AI guides: mark home menu as general-mode only; forbid it in viewer
  mode (AI_USAGE, catalog, design rules, patterns, VIEWER.md, AI_GUIDE)
- Tests: ignore wildcard identifiers in ai-docs check; update expected
  Storybook SW titles (SW/Tool removed, SW/Viewer added)
- Add merge QA report docs/sw/sw-home-menu-merge-2026-10-19.md
2026-10-19 18:21:19 +09:00

18 KiB
Raw Blame History

SW 디자인 규칙

출처: @hm-design/sw styles.css(원본 src/theme/sw.css)의 토큰과 규칙, Figma 이지빔 SW rj6wpsfk24lOWvWiVRAANP node 26:8944와 사용자 확정값. 이 문서에 없는 값은 확정값이 아닙니다. 새 컴포넌트에 임의 값을 만들지 말고 아래 토큰을 var(--…)로 읽으세요. 참고할 토큰·값이 없을 때만 AI_USAGE.md §0.4 ③으로 구성하고 "AI 구성 값 — 디자인 확인 필요"로 보고합니다.

  • 토큰은 .hm-sw-header와 .hm-sw-theme(<SWTheme>)에만 정의됩니다. 새 컴포넌트는 그 안에 렌더링합니다.
  • SW는 @hm-design/ui 토큰을 쓰지 않습니다. UI 패키지 토큰을 복제하거나 섞지 않습니다.
  • Light/Dark 분기 없음. 전역 선택자(html, body, *) 없음.
  • 모드: §1~10과 §12는 SW 일반 모드(SWHeader·SWPopup·SWToolButton·SWHomeMenu) 기준입니다. SW 뷰어 모드(SWViewer*)의 토큰·상태는 §11과 VIEWER.md를 봅니다. 모드 선택·혼합 금지는 AI_USAGE.md §0.

1. 크기·간격

항목 값 토큰
Header 높이 / 면 높이 49px / 48px --hm-sw-header-height / --hm-sw-header-bar-height
면 사이 간격 2px (Header bar gap)
필드 높이 38px(면 안 위아래 5px) --hm-sw-header-field-height
필드 사이 간격 4px --hm-sw-header-gap
로고 슬롯 32 × 17 (홈 80 × 48 안 12, 16) --hm-sw-header-logo-width / -height
필드 폭 레이어 234, 색상 192, 선스타일 284, 문자·치수스타일 164 —
상세보기 / 창 영역 157 × 38 / 240 × 48(pill 85 × 42, 창 이동 88, 버튼 32 × 2) —
필드 내부 padding 0 10px 0 11px, 텍스트 사이 12px —

2. 색·표면

역할 값 토큰
Header 배경 #060606 --hm-sw-header-background
기본 글자 / 제목 #F6F4F2 / #F0F7F5 --hm-sw-header-text-color / --hm-sw-header-title-color
Selected·On·Hover 글자 #FFC600 --hm-sw-header-selected-color
화살표 #47AF91 --hm-sw-header-arrow-color
파일명 면 세로 gradient, 테두리 #0E4C3A --hm-sw-header-document-background, --hm-sw-header-document-border-color
객체 수정 면 gradient, 테두리 #135643, radius 6px --hm-sw-header-object-background, -object-border-color, -object-radius
속성 필드 면 검정 45–40% gradient, 테두리 #08251C, radius 3px, shadow 0 1px 4px rgba(9,39,30,.7) --hm-sw-header-property-background, -property-border-color, -property-radius, -property-shadow
인쇄·K pill rgba(0,0,0,.8), 테두리 #092920 --hm-sw-header-pill-background, -pill-border-color
문서 Dropdown #103127, 테두리 #041611 --hm-sw-header-document-menu-*
필드 Dropdown(레이어·색상·선·문자·치수) #27241D, 테두리 #000, radius 3px, 행 Hover #62533D + 글자 #FF5C00 --hm-sw-header-layer-menu-*, --hm-sw-header-layer-row-hover-*
Input 글자 #E60403, 편집 #0F0D0A --hm-sw-header-input-*
Tooltip rgba(0,0,0,.8) / #FFF --hm-sw-header-tooltip-*

사용자 확정 면 3개(파일명·객체 수정·속성 필드)는 기본값 유지를 권장합니다.

3. Typography

항목 값
글꼴 Noto Sans KR → Malgun Gothic → Apple SD Gothic Neo (Figma Dotum 대체, 의도된 결정). 폰트 파일은 앱이 로드
기본 / 라벨 14px / 12px (--hm-sw-header-font-size / --hm-sw-header-label-size)
Weight 400, 500, 700만 사용(600 없음). 값·제목·토글 700
자간 값 0.04em, 라벨 0.02em, 파일명 0.06em
Text Stroke Figma Stroke가 있는 텍스트만 검정 외곽선: 14·16px --hm-sw-header-text-outline(1.3px), 12px --hm-sw-header-label-outline(1px). 자기 색 Stroke 없음. More·Tooltip·+ New/Open 제외
말줄임 값은 한 줄 ellipsis, title로 전체 표시

4. 상태

상태 규칙
Hover(테두리 있는 버튼·필드·More·인쇄·K) 1px 테두리가 노란 세로 gradient로 바뀜(--hm-sw-header-hover-border-gradient, 폭 --hm-sw-header-hover-border-width). 크기·배경·그림자 변화 없음, 자기 Dropdown이 열린 필드는 Hover 없음
Hover(파일명, 속성Bar/속성창 토글) 글자만 #FFC600. 링·배경 없음
Hover(필드 미리보기) 텍스트·선/폰트/치수 미리보기 #FFC600
Selected / On 글자·단색 아이콘 #FFC600(data-selected="true"), 배경·테두리 변화 없음
Expanded(Dropdown 열림) 필드 테두리 #081813, 아래 모서리 직각, 필드+목록을 감싸는 1px 노란 링
Focus 2px #F0F7F5 outline, offset −2px(:focus-visible)
Disabled opacity 0.4, 커서 기본. 창 버튼은 disabled 영향 없음
목록 행 Hover와 Selected가 같은 강조(#62533D + #FF5C00)

5. Overlay·Dropdown

  • 필드 Dropdown은 필드 바로 아래(top: 100%)에 겹쳐 열립니다. Portal·Dim 없음, z-index 30. 화면(또는 Header) 밖으로 나가면 좌우만 보정합니다. 부모에 overflow: hidden을 두지 않습니다.
  • 목록 최대 높이 240px(8행), 넘치면 내부 스크롤. 색상 팔레트 118px.
  • 속성창·K 가이드는 position: fixed Overlay(뷰포트 안 보정, Portal·Dim 없음).
  • 한 번에 하나의 Dropdown(SWHeader). 단독 사용 시 각 컴포넌트가 바깥 클릭으로 스스로 닫힙니다.

6. Motion

대상 규칙
창 이동 Hover 1.4s 반복(커서 상승 → 약 444ms 문구 → 오른쪽 위 이동 → 약 888ms부터 유지). Drag(:active) 중 정지. Reduced Motion: 원본 아이콘과 정적 Tooltip
K 가이드 원본 이미지 Pan/Zoom 반복(400ms 대기 후 1022·1022·511·511ms 전환). Reduced Motion 정적
레이어 토글 배경·아이콘 300ms ease-out
기타 Hover·Selected는 즉시 전환(Transition 없음)

7. 반응형 (SWHeader 전용)

Container hm-sw-header 기준 Breakpoint: < 1800 선/문자/치수스타일 → More, < 1180 그리기모드 숨김, < 1080 상세보기 → More·창 이동 24px(창 영역 176), < 900 색상 → More, < 640 인쇄·K → More·창 이동 숨김(창 영역 64), < 520 레이어 상태 아이콘 숨김. More에서 고른 필드는 첫 칸(레이어 자리)에 표시되고 Dropdown이 바로 열립니다(UI 상태만, 데이터 Callback 없음).

로고 클릭 메뉴는 좁은 폭에서 접히지 않고 메뉴 안에서 가로 스크롤합니다(좁은 폭 전용 디자인 없음, §12).

조합 Header(개별 컴포넌트)에는 이 규칙이 적용되지 않습니다. 필요한 컨트롤만 배치하고 폭 정책은 소비 앱이 정합니다.

8. Popup (속성창 프레임, SWPopup / SWHeaderPropertyPanel)

프로젝트마다 내용이 달라도 아래 외형은 그대로 유지됩니다(프레임은 패키지가 그림). 새 Popup 화면은 SWPopup을 쓰고 프레임을 다시 만들지 않습니다.

항목 값 토큰
폭 / 높이 314px / 콘텐츠 높이(최대 화면 − 8px), 넘치면 본문 세로 스크롤 —
표면 / 테두리 / radius #E4DBC9 / 1px #A67D03 / 4px, 안쪽 1px 검정 그림자 --hm-sw-property-surface, --hm-sw-property-border
제목줄 30px, Figma 제목 아트, 제목 14px 700 #FFC600 + 검정 외곽선, 닫기 44 × 30(Hover 자산) --hm-sw-header-selected-color
본문 padding 7px, 그룹 사이 8px —
그룹 면(SWPopupSection) 제목 700 · 검정 70%, 내용 면 #F1ECE1, 1px #585349, radius 4px --hm-sw-property-content
행(SWPopupRow) 최소 32px, 라벨 72px 700 검정, 값 글자 #E60403 500, 단위 12px --hm-sw-property-label, --hm-sw-header-input-color
값 상자 28px, Hover 1px rgba(33,29,19,.4), 숫자 편집 On #0F0D0A(단위 흰색), Dropdown On #211D13 --hm-sw-property-field-*
동작 Non-modal(Dim·Portal·Focus trap 없음). Escape는 Popup 안이면 그 Popup, 밖이면 최근 사용 Popup 하나. autoFocus면 열릴 때 Focus, 안에서 닫히면 원래 위치로 —
  • 밝은 Popup 면에는 SW Header의 어두운 컨트롤(필드·SWToolButton)이 디자인상 맞지 않습니다. 쓸 수는 있지만(Dropdown은 고정 Overlay로 잘리지 않음) 행 모양이 필요하면 SWPopupRow + SWHeaderInput 또는 속성창 picker를 씁니다.
  • Popup 하단 버튼의 SW 디자인은 없습니다. 임의 색·크기로 만들지 말고 @hm-design/ui Button 등 기존 컴포넌트를 쓰거나 사용자에게 디자인을 확인합니다.

9. 도구 버튼 (SWToolButton / SWToolGroup)

appearance 기존 기준 상태
text 속성Bar·속성창 토글: 19px 행, 14px 700, 자간 0.04em, 묶음 위 12px 캡션, 버튼 사이 1px 구분선 Hover·pressed 글자 #FFC600, 테두리·배경 변화 없음
pill 인쇄·K: pill(rgba(0,0,0,.8), 1px #092920, radius 4px) 안 40 × 38 버튼, 아이콘 영역 24 × 23 Hover 노란 gradient 링 + hoverIcon. 아이콘 색은 기존 인쇄 아이콘 #B6D0C9 → Hover #FFC600(--hm-sw-header-selected-color)
document 파일명 면: 48px, gradient 표면, 위·오른쪽·아래 1px #0E4C3A, 글자 #F0F7F5 700 · 자간 0.06em 글자만 Hover #FFC600. Home 바로 뒤면 로고 사선 접점 공유, 그 뒤 파일명은 왼쪽 여백 12px

10. 새 컴포넌트 체크리스트

  1. <SWTheme>(또는 SWHeader의 tools) 안에서 렌더링한다.
  2. 표면·크기·색은 위 토큰만 쓴다. 필드형이면 38px·속성 필드 면·12px 라벨 + 14px 700 값.
  3. Hover/Focus/Disabled/Selected를 §4 규칙대로 구현한다(테두리형은 gradient 링, 텍스트형은 글자만 #FFC600).
  4. 입력이 필요하면 SWHeaderInput을 재사용한다.
  5. 값은 Props, 동작은 Callback. CAD 데이터를 내부에서 바꾸지 않는다.
  6. hm-sw-* class를 새로 쓰거나 덮어쓰지 않는다(자기 접두사 사용, 예: app-).
  7. 버튼·탭·토글이면 먼저 SWToolButton의 세 모양(§9)으로 해결되는지 본다. 팝업·설정창이면 SWPopup + SWPopupSection / SWPopupRow(§8).
  8. 팝업 안의 새 콘텐츠는 §8의 Popup 토큰(--hm-sw-property-*)만 읽는다. Header용 어두운 토큰을 밝은 Popup 면에 섞지 않는다.

11. 뷰어 모드 토큰·상태 요약 (SWViewer* 전용)

출처: @hm-design/sw styles.css(원본 src/theme/sw-viewer.css)에서 그대로 옮긴 값입니다. 사용 규칙·크기 상세는 VIEWER.md, 모드 선택·혼합 금지는 AI_USAGE.md §0입니다. §1~10은 일반 모드 기준이며 이 절의 토큰은 뷰어 모드 신규 UI에서만 읽습니다(일반 모드 신규 UI에 쓰지 않음). 토큰은 .hm-sw-header, .hm-sw-theme에 선언됩니다.

영역 토큰 = 기본값
Header --hm-sw-viewer-height 52px, --hm-sw-viewer-background linear-gradient(180deg, #266651 0%, #123328 45%, #0a221d 100%), --hm-sw-viewer-border-color #071e18, --hm-sw-viewer-text #fff, --hm-sw-viewer-muted #bddfd4, --hm-sw-viewer-accent #ffc600, --hm-sw-viewer-hover #266651
로고 면 --hm-sw-viewer-brand-width 72px, --hm-sw-viewer-brand-empty-width 24px(로고 없음), --hm-sw-viewer-brand-top #123328, --hm-sw-viewer-brand-middle #205241, --hm-sw-viewer-brand-bottom #071e18
크기·글자 --hm-sw-viewer-gap 4px, --hm-sw-viewer-radius 4px, --hm-sw-viewer-control-height 40px, --hm-sw-viewer-button-height 34px, --hm-sw-viewer-font-size 14px, --hm-sw-viewer-label-size 11px, --hm-sw-viewer-icon-size 16px, --hm-sw-viewer-disabled-opacity 0.6
Header 스위치·아이콘 --hm-sw-viewer-switch-off #0a221d, --hm-sw-viewer-switch-bevel inset 0 1px 0 rgba(255, 255, 255, 0.1), inset 0 -1px 1px rgba(0, 0, 0, 0.25), --hm-sw-viewer-icon-outline-color = var(--hm-sw-header-text-outline-color), --hm-sw-viewer-icon-outline-width 1px
Dropdown·More --hm-sw-viewer-menu-background #fff, --hm-sw-viewer-menu-border-color #dedbd2, --hm-sw-viewer-menu-text #0a221d, --hm-sw-viewer-menu-muted #6e6759, --hm-sw-viewer-menu-highlight rgba(189, 223, 212, 0.45), --hm-sw-viewer-menu-highlight-text #123328, --hm-sw-viewer-menu-shadow 0 0 12px rgba(0, 0, 0, 0.2), --hm-sw-viewer-menu-item-height 36px, --hm-sw-viewer-more-background #f5f0e5, --hm-sw-viewer-more-border-color #897445
패널 콘텐츠 --hm-sw-viewer-panel-background = var(--hm-sw-property-surface), --hm-sw-viewer-panel-field-background = var(--hm-sw-property-content), --hm-sw-viewer-panel-inner-border = var(--hm-sw-property-inner-border), --hm-sw-viewer-panel-text = var(--hm-sw-property-label), --hm-sw-viewer-panel-heading #3e3523, --hm-sw-viewer-panel-label #6e6759, --hm-sw-viewer-panel-primary #123328, --hm-sw-viewer-panel-switch-off = var(--hm-sw-property-inner-border), --hm-sw-viewer-panel-switch-on #266651, --hm-sw-viewer-panel-badge-background = var(--hm-sw-property-table), --hm-sw-viewer-panel-overlay rgba(0, 0, 0, 0.1), --hm-sw-viewer-panel-spacing 12px
  • 공유 토큰(모드 혼합 아님): 뷰어 Header의 파일명·객체 수정·속성 면은 --hm-sw-header-document-*, --hm-sw-header-object-*, --hm-sw-header-property-*를, 글자 외곽선은 --hm-sw-header-text-outline·--hm-sw-header-label-outline을 그대로 읽습니다(§2·§3). 패널 제목 막대 추가 버튼(ghost)의 Hover·Focus 색은 --hm-sw-header-selected-color입니다.
상태 Header 항목(button·toggle·menu·tabs·switch) 패널 콘텐츠
Hover 면 --hm-sw-viewer-hover(#266651) outline 버튼: 면 --hm-sw-viewer-panel-field-background / primary: 면·테두리 --hm-sw-viewer-hover / tone="green": 면·테두리 --hm-sw-viewer-hover, 글자 #fff / ghost: 글자만 --hm-sw-header-selected-color
Active·Pressed·열림·선택 탭 글자·아이콘 --hm-sw-viewer-accent(#ffc600), 선택 박스 없음 tone="green" 누르는 동안: 면·테두리 --hm-sw-viewer-panel-primary, 글자 #fff
Checked(스위치) 면 --hm-sw-viewer-accent, thumb --hm-sw-viewer-switch-off 면 --hm-sw-viewer-panel-switch-on
Focus 2px solid --hm-sw-viewer-accent 외곽선 버튼·Input·Slider: 2px solid --hm-sw-viewer-panel-switch-on 외곽선
Disabled --hm-sw-viewer-disabled-opacity(0.6) 버튼·Input·Field 0.5
Dropdown 항목 면 --hm-sw-viewer-menu-highlight, 글자 --hm-sw-viewer-menu-highlight-text(Focus·Hover·서브메뉴 열림), Disabled 0.5 —
상태 표시 SWViewerStatus: 글자 --hm-sw-viewer-muted 11px 400, error는 --hm-sw-viewer-accent, loading 아이콘 회전 —
  • Typography(뷰어): Header 항목 14px 500, 캡션·개수·상태 11px 400, 패널 필드 라벨 14px 500, Section 제목 12px 700, 패널 버튼·Badge 12px 500, Input 12px. Font Weight는 400/500/700만 씁니다.
  • 뷰어 신규 컴포넌트 체크리스트: ① VIEWER.md·카탈로그 §9 컴포넌트로 해결되는지 먼저 본다 ② 위 토큰을 var(--…)로만 읽고 일반 모드 전용 모양(§8 SWPopupRow, §9 SWToolButton)을 섞지 않는다 ③ 상태는 위 표대로 ④ 토큰에 없는 값은 결과 보고에 "AI 구성 값 — 디자인 확인 필요"로 적는다 ⑤ hm-sw-viewer-* class를 쓰거나 덮어쓰지 않는다.

12. 로고 클릭 메뉴 (SWHeader homeMenu / SWHomeMenu, Figma 26:10591) — SW 일반 모드 전용

이 절의 값은 일반 모드 SWHeader의 홈 메뉴에만 씁니다. 뷰어 모드(§11)에는 홈 메뉴가 없으며 --hm-sw-home-menu-*·--hm-sw-recent-files-* 토큰을 뷰어 신규 UI에 쓰지 않습니다.

항목 값 토큰
위치 Header 맨 위(top 0), 객체 수정 영역 왼쪽 −2px ~ 창 영역 왼쪽(1920에서 x 375, 폭 1305). DOM 측정이며 고정 좌표 없음. controls로 파일명이 객체 수정 영역 안에 있으면 파일명 오른쪽 −2px부터 시작. 로고·파일명·창 영역은 가리지 않음. z-index 20(속성Bar 위, Dropdown 30·속성창 40 아래) —
크기 메뉴 높이 77(섹션 75 + 하단 강조 2), 그룹 46, 타일 80 × 46, 아이콘 18 슬롯, 섹션 폭은 타일 수로 자동 —
섹션 면 세로 gradient 면 + 1px #081813 + 안쪽 1px #20190E, 아래 모서리 3px --hm-sw-home-menu-section-*
섹션 제목 Figma tit_* badge(9-slice), 글자 400 검정 --hm-sw-home-menu-title-color
타일 상태 Default 아이콘 #B6B4AF · Hover·Active 주황 gradient 1px 테두리 + 아이콘·글자 #FF5C00, 1px 위·왼쪽 이동. 라벨 700 --hm-sw-home-menu-item-*, --hm-sw-home-menu-icon-color
하단 강조 sections = 섹션마다 주황 띠, outline = 메뉴 전체 2px 외곽선(하위 패널이 열린 동안, auto 기본) --hm-sw-home-menu-accent-*
최근파일 패널 폭 354, 행 50, 배경 #27241D, 주황 테두리, 행 Hover #62533D + #FF5C00, 미리보기 310 × 270 --hm-sw-recent-files-*
동작 기본 숨김 → 로고 클릭 열기 → 다시 클릭 닫기. 메뉴 빈 곳 클릭 닫기(Figma CLOSE). Escape: 하위 패널 → 메뉴, 닫히면 로고로 Focus. 메뉴 밖 클릭은 닫지 않음(Figma overlay 기준) —
좁은 폭 접는 디자인이 없어 메뉴 안 가로 스크롤(의도된 동작, 겹침·잘림 없음) —
  • 열림 상태 Header 상·하단 #5F4B0F 2px 선(Figma home on)과 로고 열림 표시는 적용하지 않습니다(디자인 승인 대기). 임의로 추가하지 않습니다.
  • 새 색·크기는 위 토큰만 style로 덮어씁니다. hm-sw-home-menu* class를 소비 코드에 쓰지 않습니다.