# SW Header 추가 디자인 5건 — 최종 검증 기록 (2026-10-16) ## 1. 판정 **PASS — 이번 요청의 수정 및 아래 명시된 Chrome 실행 검증 범위.** 전체 HMDesign, CAD 호스트 연동, 모든 브라우저 또는 Figma 전체 픽셀 일치에 대한 승인은 아니다. Guard의 `NOT VERIFIED`는 별도로 유지한다. 작업 범위는 기존 SW 패키지와 기존 Storybook 예제(BOTH)다. 신규 업무 화면·Navigation·Story는 추가하지 않았다. Commit / Push / PR / Merge / Publish / 배포는 하지 않았다. ## 2. 시작 Branch / HEAD / Git Status - 경로: `D:\디자인시스템\HMDesign-SW` - Branch: `feature/sw-package` - HEAD: `9407c8567f57301659e591c03451cca1b828733c` - origin: `https://gitea.hmac.kr/b25027/HMDesign.git` - 기존 상태: `M package.json`, `M package-lock.json`, `?? docs/sw/`, `?? packages/sw/`, `?? src/sw/`. - 이번 요청에 명시된 작업 경로·브랜치·Commit/Push 금지가 일반 main/공식 작업 폴더 지침보다 우선한다. 원격 동기화나 Git 이력 변경은 하지 않았다. ## 3. 이전 작업 이어서 완료한 내용과 보존 근거 기존 구현을 유지하고 5건의 원인에 필요한 부분만 수정했다. 시작 상태의 `packages/sw`, `src/sw`, `docs/sw`, root manifest/lock을 별도 QA baseline에 복사하고 소스·문서 SHA-256을 기록했다. - 기존 `hiddenControls`, `menuOrder`, More 및 대표 슬롯, 속성Bar, 속성창 데이터·입력·Callback·형상 Slot 구현을 재사용했다. - 기존 `docs/sw` 문서 10개(명세·사용법·검증 기록 포함), 기존 SVG/이미지, `package.json`, `package-lock.json`은 시작 baseline과 바이트가 같다. - `SWHeader.tsx`, PropertyPanel/PropertyBar, ColorMenu, KGuide, WindowControls, 공개 export 등 나머지 소스는 수정하지 않았다. 공개 Props의 이름·타입·Callback 시그니처도 그대로다(`types.ts`는 설명 주석만 수정). - 이전 Motion·Colorize·ByLayer/ByBlock·Text Stroke 정책은 소스 보존 근거다. 이번에 Motion 전체 프레임이나 CAD 동작을 새로 검증한 것으로 표현하지 않는다. - 다른 디자인 시스템 패키지 소스, DWG/DXF Viewer, 기존 `_local` 파일은 수정하지 않았다. 빌드 산출물은 각 기존 빌드 명령으로 재생성했다. ## 4. 추가 수정 5건 결과 - **A PASS:** 선스타일 메뉴와 Dropdown의 실제 접촉 구간 1px만 검정색으로 수정. - **B PASS:** 치수스타일 고정 Story 두 개만 오른쪽 끝을 필드와 일치시킴. 동적 위치 계산은 수정하지 않음. - **C PASS:** 속성창 헤더의 원본 대각선·그림자를 가리던 레이어 순서 복원, 도구 버튼 위치와 제목 자간 보정. 네 상태의 디자인 차이 유지. - **D PASS:** Figma Hover `26:10799`를 재확인하고 치수 전용 Hover 규칙을 명시. 호스트 상세 Callback 없는 경우에도 Hover 가능하게 수정. - **E PASS:** Callback 부재와 Disabled를 분리. 일반 레이어 상세 Hover 및 명시적 Disabled 예제를 구분하고 기존 Callback 유지. ## 5. 선스타일 연결 영역 검정색 원인은 `.hm-sw-header__line-menu::before`의 노란 Gradient ring이 필드와 접하는 상단에도 그려지는 것이었다. 기존 ring은 유지하고 기존 `::after`를 접촉 구간에만 배치했다. 색은 실제 선언된 `--hm-sw-header-layer-menu-border-color`(`#000`)를 재사용한다. 공통 Dropdown의 `panelStyle.left`에서 접촉 시작점을 구하고 필드의 실제 폭을 ResizeObserver로 추적한다. More에서 필드가 축소되어도 284px을 강제로 칠하지 않는다. 공통 Dropdown Position/Align은 수정하지 않았다. 브라우저 결과: - Expanded 접촉 구간의 PNG RGB 실측: `0,0,0`. - 상단의 접촉하지 않는 좌우 부분·좌우/하단 테두리: 기존 노란색 유지. - 접촉 구간 아래 전체 Dropdown PNG 비교: 변경 픽셀 **0**. 선 Preview, 항목 정렬, Hover/Selected 행도 그대로다. - Default → Hover → Mouse Leave의 필드 색상·ring 복귀와 Selected 행 강조를 확인했다. 제목/값의 기존 노란색을 유지한다. - 1920/1440/1280/768/390px에서 검정 구간이 실제 필드 폭 밖으로 나가지 않음을 확인했다. ## 6. 치수스타일 고정 Story 위치 대상은 `치수스타일 Expanded (Figma 26:11242)`와 `치수스타일 행·상세 버튼 Hover (고정)`뿐이다. 원인은 1920px 고정 Header를 좁은 Story scroller에서 렌더링할 때 공통 경계 보정이 실제 화면 폭을 기준으로 목록을 왼쪽으로 옮기는 것이었다. 두 `MenuFrame`에만 `fixedDimension`을 지정하고 Story CSS로 `left:auto; right:0`을 적용했다. 고정 상태의 ring도 동일한 필드 기준으로 맞췄다. - 1440px 화면의 수정 전 두 예제: 필드 오른쪽 `1641px`, Dropdown 오른쪽 `1439px` — **202px 어긋남**. - 수정 후 두 예제: 필드/Dropdown 오른쪽 모두 `1641px` — **차이 0px**. - Figma 필드 폭 164px, 목록 폭 164px, 필드 하단에서 목록 시작이라는 상대 위치를 유지한다. - 1920px specimen을 가로 스크롤한 뒤에도 필드와 목록 오른쪽 끝이 일치함을 확인했다. 화면 폭에 맞춰 고정 Header 자체를 축소하지 않았다. ## 7. 동적 Dropdown 위치 불변 `useSWHeaderDropdown` 및 Text/Dimension의 공통 Position/Align을 수정하지 않았다. `선택 Callback`의 동적 치수 Dropdown 수정 전후 실측: - 1440px 화면: 필드 `x=1156, width=164`, Dropdown `x=1156, width=164`, 오른쪽 모두 `1320` — 전후 동일. - 2000px 화면: 필드/Dropdown `x=1037, width=164`, 오른쪽 `1201` — 전후 동일. - 고정 Story 전용 CSS는 동적 예제에 적용되지 않는다. ## 8. 속성창 네 상태 헤더 Figma 비교 [Figma 속성창 원본](https://www.figma.com/design/rj6wpsfk24lOWvWiVRAANP/이지빔-SW?node-id=26-11822&m=dev)을 get_design_context(스크린샷 포함)와 읽기 전용 Plugin API로 직접 확인했다. 원본 디자인은 수정하지 않았다. - `26:11886` 선택 없음: **314×256px**, 녹색 Gradient Union, 추가 도구 아이콘 있음. - `26:11823` 전체 11: **314×361px**, 녹색 Gradient Union, 추가 도구 아이콘 있음. - `26:11932` 원 1개: **314×658px**, 갈색 Union(`#211D13`), 추가 도구 아이콘 없음. - `26:12035` 모두 펼침: **314×754px**, 원 1개와 같은 갈색 헤더, 추가 도구 아이콘 없음. - **닫기 버튼은 Figma 네 상태 모두 있다.** 단일 원 상태의 닫기 기능을 제거하지 않았다. 원본 Union SVG를 새로 내려받아 기존 파일과 SHA-256을 비교했으며 동일했다. 디자인 차이는 잘못된 자산이 아니라 닫기 버튼 배경이 Union 오른쪽 대각선을 덮는 paint order였다. Union을 해당 배경 위에 배치하고 제목·도구 버튼은 그 위에 유지했다. Union은 `pointer-events:none`이어서 닫기 버튼을 차단하지 않는다. 공통 실측(패널 좌상단 기준): - 헤더 내부 영역 `(1,1)`, **312×30px**. 외곽 금색 1px·radius 4px 및 본문 경계/그림자 보존. - 제목 `x=8, y=8`, 14px, 기존 Noto Sans KR·700 유지, Figma 자간 **0.56px(0.04em)** 적용. - 추가 도구 버튼 `(241,2)`, **29×27.125px**(Figma 27.129px의 브라우저 반올림). SVG root 29×28은 보존. - 닫기 `(269,1)`, **44×30px**. 원본 Default/Hover 자산과 클릭 기능 유지. - 본문/전체 높이 네 상태 모두 시작 baseline과 동일. 네 패널 PNG를 직접 검토했다. 제목과 도구 클릭, 상단 X/키보드 Escape 닫기, Focus 복귀, Enter 확정·Escape 취소 및 Property Callback을 Chrome에서 확인했다. 형상 Slot·4개 상태 비교 Story도 유지했다. ## 9. 치수스타일 상세 Hover Figma `26:10796` Default와 `26:10799` Hover를 직접 확인했다. `26:10802` Variant3는 혼합하지 않는다. - Default: **142×24px**, 배경 `rgba(197,177,158,.15)`, radius 24px. - Hover: 배경 `rgba(197,177,158,.25)`, radius 25px, **기본 아이콘·문자 opacity 1**. - Mouse Leave: Default 배경·radius 복귀. - Callback이 있는 동적 예제는 시작 시점에도 위 Hover 값과 일치했다. 이를 다른 상세 버튼/Variant3와 같게 바꾸지 않았다. 치수 전용 규칙을 명시하고, Callback 없는 Dynamic Data에서 자동 disabled가 되던 경로를 제거했다. - Callback 없는 경우 Hover는 동작하지만 CAD 상세 기능을 만들어 실행하지 않는다. Callback이 있는 클릭은 기존 `onDimensionStyleDetail` **1회** 후 닫힘을 확인했다. - 색상/선/문자 상세 버튼의 기존 규칙은 수정하지 않았다. ## 10. 레이어 상세 Hover 및 Disabled 원인 실제 원인은 `disabled={!onDetail}`였다. Hover CSS는 존재했지만 `:hover:not(:disabled)`에서 제외됐다. pointer-events나 상위 컨테이너가 원인은 아니었다. - 일반 상태는 Callback 없어도 활성 Hover. 기본 크기 **113×24px** 유지(3배 Story 실측 339×72). - Default .15/radius 24 → Hover .25/radius 25 → Mouse Leave Default 복귀. - Hover 아이콘·글자 35%는 Figma `26:10771`대로 유지. - 기존 메뉴의 명시적 `disabled` 계약은 유지한다. Story의 Disabled specimen은 이제 호스트가 실제 `fieldset disabled`를 명시한다. Callback 부재를 Disabled 예시로 사용하지 않는다. - Callback 연결 예제에서 `onLayerDetail` 1회 후 목록 닫힘 확인. 연결되지 않은 CAD 기능·상세창은 추가하지 않았다. ## 11. 기본 디자인 10개 폭 비교 수정 전/후 Default(1920px Frame)와 Controls(viewport)의 Header 및 하위 DOM 총 **99개(루트 1 + 하위 98)**를 비교했다. - 폭: **1920,1800,1440,1180,1080,900,768,640,520,390px**. - 2개 Story × 10폭 = **20건**, 위치·크기·display·visibility·color·background 차이 **0**. - 후속 좁은 화면 보정은 열린 선스타일 Dropdown의 접촉선 폭만 변경한다. 닫힌 기본 Header에는 적용되지 않으며 해당 5개 폭을 별도 재검증했다. ## 12. 메뉴 구성 및 기능 검증 **11개 구성 × 7폭(1920/1440/1080/900/768/640/390) = 77건 PASS.** 기본 전체, A/B/C, 파일·레이어·색상·스타일 그룹·여러 메뉴 제거, 순서 변경, 숨김+순서 변경. 각 구성의 로고 32×17 유지, Header 49px, DOM 메뉴 순서, 가로 overflow 없음, More 목록이 비지 않음, 숨긴 메뉴가 More에 남지 않음을 확인했다. 추가 실행: More→문자스타일 대표 슬롯, 대표 제거→레이어 복귀, 메뉴 숨김/재표시, Dropdown 바깥 클릭, 속성창 열기·닫기/Focus 복귀, 상세 Callback, 형상 Slot 기본/비움/외부 컴포넌트/교체/Render Prop, 형상 속성 추가·삭제/외부 값 반영. 4개 패널 비교는 1440/1280/768/390px에서 가로 페이지 overflow 없이 표시됐다. Outside Click과 React 타이밍 구분: - Checkbox를 실제 포인터로 클릭하면 기존 Dropdown의 바깥 pointerdown이 먼저 닫힘 Callback을 발생시킨다. 별도로 checkbox의 DOM click만 호출해 숨길 때는 합성 닫힘 Callback이 없음을 확인했다. 실제 기능 오류로 분류하지 않는다. - 형상 지름·반지름 외부 변경은 React 렌더링 완료 조건을 기다린 뒤 `10.0000 / 5.0000`을 확인했다. 재렌더 이전 즉시 읽기를 성공/실패 근거로 쓰지 않았다. - 테스트의 잘못된 Story ID와 다른 예제 로그 선택을 수정했다. 해당 실패는 제품 코드 오류가 아니며 수정된 검사와 오류를 분리한 재실행 결과를 보존한다. ## 13. Storybook 전체 렌더링 기존 **31개 Story** 유지. 실제 Chrome에서 31/31 렌더링 및 보이는 이미지 로딩 확인. 잘못된 Story ID에서 발생한 오류를 분리하기 위한 독립 재실행에서 **page error 0 / console error 0 / HTTP error 0**. Story를 새로 추가하거나 기존 대표 Story를 교체하지 않았다. ## 14. SW / Root Typecheck 및 Build 최종 소스 기준 다음 명령 모두 **exit 0**: - `npm.cmd run typecheck:sw` - `npm.cmd run build:sw` - `npm.cmd run typecheck` (Root·workspaces) - `npm.cmd run build` - `npm.cmd run build-storybook` 실제 소스가 다시 변경된 연결선 보정 이후 영향을 받는 검증을 재실행했다. 조건이 바뀌지 않은 77개 구성·기본 Geometry 검사는 반복하지 않았다. CSS 최적화의 기존 Tailwind arbitrary value 경고와 chunk 크기 경고는 남아 있다. 빌드 실패는 없다. ## 15. 이번 변경 파일 시작 baseline 대비 수정 **7개**, 새 보고서 **1개**: 1. `packages/sw/src/components/sw-header/components/SWHeaderLayerMenu.tsx` — Callback 없는 레이어 상세 자동 Disabled 제거. 2. `packages/sw/src/components/sw-header/components/SWHeaderLineStyleMenu.tsx` — 접촉선 시작점·실제 필드 폭 전달/추적. 3. `packages/sw/src/components/sw-header/components/SWHeaderStyleListMenus.tsx` — 치수 상세 Callback 없는 Hover 허용. 4. `packages/sw/src/components/sw-header/types.ts` — 위 Callback의 설명 주석만 정정. 5. `packages/sw/src/theme/sw.css` — 접촉선, 치수 전용 Hover, 속성창 paint order/도구 위치/제목 자간. 6. `src/sw/sw-header.stories.tsx` — 고정 치수 두 예제 범위 지정, 레이어의 명시적 Disabled 예제. 7. `src/sw/sw-stories.css` — 위 고정 Story와 Disabled specimen 컨테이너 스타일. 8. 이 검증 문서. 미커밋 SW 폴더 전체를 이번에 새로 작성한 것으로 집계하지 않는다. root manifest/lock의 기존 변경도 이번 변경 파일에 포함하지 않는다. 시작 baseline 대비 실제 diff를 읽고 수정 범위를 검토했다. ## 16. 남은 디자인 차이 - 기존 정책의 **Noto Sans KR**(Figma Dotum 대신)·400/500/700을 유지했다. 제목을 포함한 글리프 모양·문자 폭은 Figma와 완전 동일하지 않다. - 기존 선스타일 열의 Noto 내용 폭, 형상 라벨 위치 등의 과거 문서상 차이는 이번 범위 밖으로 유지한다. 본문·형상 위치를 임의 변경하지 않았다. - Figma 픽셀 전체 일치로 주장하지 않는다. 이번에 PNG의 변경 픽셀 0을 확인한 범위는 선스타일 접촉선 이외 Dropdown 보존 비교다. ## 17. NOT VERIFIED 및 Guard Guard는 Storybook PARTIAL로 변경 파일을 검사하고, 마지막 연결선 소스 변경 후 해당 두 파일만 PARTIAL 재검사했다. **FAIL 0**, 원본 `status/staticStatus/runtimeStatus`는 **NOT VERIFIED**다. 이를 브라우저 PASS로 덮어쓰지 않았다. 원인: Guard가 독립 `@hm-design/sw/styles.css` 및 SW 패키지 구현 graph를 HM UI 소비 화면과 같이 해석하지 못하는 ENTRY/SCOPE 항목, Storybook 예제의 native controls·동적 class/style·token 근거 항목. SW build와 실제 컴포넌트 렌더링은 별도 실행 증거다. CSS 원본 근거도 그대로 유지: **STATIC PASS / RUNTIME NOT VERIFIED / DESIGN_INTENT PASS / FINAL NOT VERIFIED**. 내부 SW CSS를 모두 검사해 승인한 결과가 아니며 `checks=[]`인 정적 scope 한계가 있다. 이번 수정의 색·크기·상태는 위 개별 Figma/브라우저 검증으로만 판단한다. 이번 미검증: 실제 CAD 호스트/형상 렌더러, Firefox/Safari, 터치, 스크린리더, 전체 화면 픽셀 overlay, 기존 K/창 이동 Motion 전체 프레임 재검사. 과거 검증 기록은 보존한다. ## 18. 종료 Branch / HEAD / Git Status - Branch: `feature/sw-package` - HEAD: `9407c8567f57301659e591c03451cca1b828733c` (시작과 동일). - 상태: `M package.json`, `M package-lock.json`, `?? docs/sw/`, `?? packages/sw/`, `?? src/sw/`. - Staged Diff 없음. 기존 파일 삭제/초기화 없음. Commit / Push / PR / Merge / Publish / 배포 없음. ## 실행 근거 및 재현 QA Root: `C:\Users\user\.codex\visualizations\2026\10\16\01a143c9-30e2-7c42-aa06-c658d456a984\sw-header`. - `baseline/`, `baseline-sha256.json`, `git-start.txt`: 복구·변경 전 근거. - `before/capture.json`, `after/capture.json`: 10폭 Geometry 및 네 패널 실측. - `before/probe.json`, `after/probe.json`: 고정/동적 치수 위치와 Hover. - `verification.json`: 최초 통합 검사(테스트 수정 전 실패 기록 포함). - `verification-followup.json`, `verification-A.json`, `verification-E.json`: 연결선·레이어의 영향 범위 재검사. - `verification-all SW.json`: 실제 31개 Story의 독립 오류 검사. - `edges-results.json`: 닫힌 선스타일 상태, 5개 폭 접촉선, 고정 Story 스크롤 검증(8 PASS / 0 FAIL). - `build-results-final.json`, Typecheck/Build `.log`: 최종 5개 명령 exit 0. - `guard.json`, `guard-final-affected.json`: 덮어쓰지 않은 원본 NOT VERIFIED. - `panel-{none,all,circle,expanded}-final.png`, `line-seam-final.png`, `dimension-detail-hover.png`, `layer-detail-hover.png`, `fixed-dimension-scrolled.png`: Chrome 캡처. 재현 스크립트 `capture.mjs`, `probe.mjs`, `verify.mjs`, `edges.mjs`, `builds.mjs`는 QA Root에 있다. 이번 작업에서는 로컬 Storybook `127.0.0.1:6043`과 기존 Playwright/Chrome을 사용했다. 재현 시 같은 소스·dist 및 서버 포트를 확인한다. ## 시간 기록 (Asia/Seoul) - Started At: 2026-10-16 17:17:10 KST - Completed At: 2026-10-16 17:40:21 KST - Actual Duration: 23분 11초 - Estimated Duration: 약 30~50분 (분석 5~10 / 수정 15~25 / 통합 검증 10~15분) - Variance: 최초 예상 범위보다 6분 49초~26분 49초 짧음