Files
HMDesign/docs/sw/sw-header-window-motion-verification-2026-10-16.md
T

86 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SW Header 창 이동 Motion 최종 검증 — 2026-10-16
## 1. 최종 판정: PARTIAL
요청 범위의 Chrome 브라우저 검증과 빌드는 통과했습니다. Reduced Motion의 실제 CSS 오류 한 건을 수정하고 영향 범위를 재검증했습니다. 실제 호스트 창 제어, Figma player의 반복 정책·수치 곡선 동등성, 전용 SW Guard 검증은 미완료이므로 전체 PASS로 처리하지 않습니다.
## 2. 작업 시작 시 Git 상태
- 경로: `D:\디자인시스템\HMDesign-SW`, 브랜치 `feature/sw-package`.
- HEAD: `9407c8567f57301659e591c03451cca1b828733c`.
- origin: `https://gitea.hmac.kr/b25027/HMDesign.git`.
- 기존 변경: ` M package-lock.json`, ` M package.json`, `?? docs/sw/`, `?? packages/sw/`, `?? src/sw/`. SW는 미추적 상태이므로 일반 `git diff`만으로 기존 구현과 이번 작업을 구분할 수 없습니다.
- 이 작업은 사용자 지정 SW Worktree에서만 수행했고 Git 이력·Index·원격을 변경하지 않았습니다. 시작 파일의 SHA-256은 `_local/sw-motion-qa/baseline.json`에 보존했습니다.
## 3. 기존 Claude 구현에서 확인한 사항
`SWHeaderWindowControls.tsx`의 기존 div / `onPointerDown`, 3개 SVG, 4개 CSS Keyframes, 직접 선언된 `linear()` easing, 1회 재생·즉시 이탈 복귀, Tooltip, 88px / 24px / 숨김 단계, `Window Move Motion` Story와 7개 고정 프레임이 실제로 존재했습니다. 300ms의 Hover 창·커서·Tooltip opacity는 `0.930667`로 측정했습니다. 모션과 Drag 코드를 다시 작성하지 않았습니다.
## 4. 이번 추가 수정
기존 Reduced Motion 규칙 `.hm-sw-header__motion:hover > *`보다 레이어별 애니메이션 선택자의 specificity가 높아 모션 해제가 적용되지 않았습니다. 이 규칙만 동일 specificity의 `:is(.레이어...)` 선택자로 바꿨습니다. 일반 Keyframes·시간·SVG·좌표·공개 Props·Callback·Breakpoint는 그대로입니다. 나머지 수정은 문서 추가입니다.
초기 검증 JSON의 두 FAIL은 보존했습니다. 수정 후 해당 Reduced Motion 검사와 영향 범위만 별도로 재검사했으며, 성공했던 일반 모션·반응형 검사를 형식적으로 반복하지 않았습니다.
## 5. Figma 3단계 비교
Figma `rj6wpsfk24lOWvWiVRAANP` / `26:10220`의 디자인 컨텍스트·스크린샷·Prototype reactions를 읽었습니다. Default `26:10221`, Hover `26:10258`, Hover2 `26:10295`의 크기와 좌표는 [명세 §11.3](./sw-header-design-spec.md#113-창-이동-hover-motion--figma-2610220-2026-10-16)에 기록했습니다.
- PASS: 1022ms의 창 (32, 15), 24 × 18.857px; 1767ms의 창 (59, 12), 커서 (72, 10), Tooltip (89, 11). CSS subpixel 오차 0.05px 이내로 비교했습니다.
- PASS: GENTLE / QUICK / BOUNCY preset 이름, SMART_ANIMATE / DISSOLVE, 1.0220938 / 0.7442555 / 0.9582165초와 두 1ms 대기는 원본 reactions와 일치합니다. QUICK overshoot, DISSOLVE 혼합, 실제 1회 재생 완료·Default 복귀도 확인했습니다.
- PASS: Hover SVG 두 개는 원본과 일치하며 Default SVG는 마스크 ID 차이만 있습니다. 원본 파일을 교체하지 않았습니다.
- PARTIAL: Figma motion API의 animated-node 결과는 비어 있었고 preset의 수치 곡선은 반환되지 않았습니다. 기존 spring 표본 근사와 opacity용 단조 BOUNCY를 유지했으며, 중간 프레임의 완전 동일성은 검증하지 않았습니다. Tooltip 글꼴은 기존 SW 정책인 Noto Sans KR이며 Figma의 Inter와 다릅니다.
- NOT VERIFIED: Figma Prototype player에서 Default 복귀 뒤 포인터 유지 중 자동 재시작하는지. 구현은 1회 재생 정책을 유지했습니다.
## 6. Drag 검증
공개 `@hm-design/sw` 패키지를 실제 React로 렌더링한 로컬 QA fixture에서 PointerEvent를 받았습니다. `onWindowMoveStart` 1회, `currentTarget`과 `target`이 기존 div임, `pointerId`·`pointerType=mouse`·`buttons=1` 전달, `defaultPrevented=false`를 확인했습니다. 호스트 모의 코드가 Pointer Capture를 설정한 뒤 Tooltip·최소화 영역 위로 이동해도 pointermove와 pointerup이 전달됐습니다. Drag 중 최소화·종료 콜백이 발생하지 않았고, 이후 각 버튼 클릭은 자신의 콜백만 호출했습니다. Reduced Motion에서도 같은 전달을 확인했습니다.
실제 Electron/설치형 호스트의 OS 창 이동·최소화·종료, 터치·펜 입력과 네이티브 Drag 중 애니메이션은 **NOT VERIFIED**입니다. 브라우저 검증은 호스트 통합 완료 판정이 아닙니다.
## 7. Tooltip · Reduced Motion · Focus
- PASS: Tooltip과 내부 그래픽의 `pointer-events: none`; Tooltip이 겹친 위치의 hit test는 최소화 버튼에 도달합니다. 실제 버튼 콜백도 전달됩니다.
- PASS: Hover 종료 즉시 기본 상태; 빠른 진입·이탈 12회에서 start/cancel 각각 12회, 잔여 애니메이션 0개; 포인터를 4초 이상 유지해도 비정상 반복 없음.
- PASS(수정 후): reduce에서 애니메이션 0개, 기본 아이콘과 정적 Tooltip 유지, 이탈 시 숨김, 재생 중 reduce 전환 즉시 정지. 24px 영역은 기존대로 그림을 숨기고 Tooltip만 표시합니다.
- PASS: 최소화 → 종료 Tab 이동, 접근성 이름과 2px Focus 윤곽선, Enter로 종료 콜백.
- 기존 제한: 창 이동 div는 `role=presentation`, `tabIndex=-1`이며 키보드 이동·Focus Tooltip을 제공하지 않습니다. 키보드 이동 대안과 보조기술 검증은 호스트 과제입니다. 접근성 전체 PASS를 선언하지 않습니다.
## 8. 반응형
실제 viewport와 독립 Header 폭으로 1920 / 1440 / 1280(추가) / 1080 / 1079 / 768 / 640 / 639 / 390px를 검사했습니다. 모든 폭에서 높이 49px, 문서와 Header의 가로 overflow 0px, Tooltip은 Header의 세로·가로 경계 안이었습니다. 1080px 이상 move 88px, 640–1079px move 24px와 정적 Tooltip, 639px 이하 숨김을 확인했습니다.
Tooltip은 원본 좌표 관계상 최소화와 종료 왼쪽 일부에 **시각적으로 겹칩니다**. 클릭을 차단하거나 가로 스크롤을 만들지는 않으나, 이를 ‘시각적 겹침 없음’으로 판정하지 않았고 승인된 배치를 임의로 바꾸지 않았습니다. 390px의 기존 문서명·레이어명 말줄임도 유지됩니다.
## 9. Typecheck · Build · Storybook · Guard
- PASS: `npm.cmd run typecheck` — root와 SW를 포함한 workspace typecheck. 기존 pretypecheck의 theme 확인·package build도 통과했습니다.
- PASS: `npm.cmd run build:sw` — CSS 수정 후 최종 산출물 생성.
- PASS: `npm.cmd --ignore-scripts run build`, `npm.cmd --ignore-scripts run build-storybook` — 이미 통과한 공통 prerequisite의 중복 실행을 생략했습니다. CSS 변경 후 관련 build 결과를 다시 생성했습니다. 의존성 설치·Lockfile 수정은 없습니다.
- PASS: 빌드된 Storybook의 실제 CSS animation, 단계별 7개 프레임 고정 시간, 기존 pointer/animation/callback log, 정상·reduce 모드. Chrome `155.0.8059.79`, headless mouse/keyboard에서 확인했습니다. 6024 개발 서버의 포트 불가 안내 뒤 기존 프로세스를 건드리지 않고 임시 localhost 서버를 사용했으며 종료했습니다.
- 기존 경고: 문서 예시 `bg-[var(...)]`의 CSS 최적화, Storybook의 `:host-context` minifier, 500kB 초과 chunk 및 plugin timing 안내. 관련 과거 문서에도 기록된 경고이며 이번 오류로 분류하지 않았습니다. runtime pageerror는 0건입니다. 초기 fixture에서 404 console 경고 1건이 있었고 최종 동일 fixture의 HTTP 오류 재확인에서는 0건이었습니다(초기 경고 URL은 기록하지 않아 원인 단정 안 함).
- Guard 1회: `node scripts/ai-generation-guard.mjs --target . --profile STORYBOOK --scope PARTIAL --files src/sw/sw-header.stories.tsx,packages/sw/src/theme/sw.css --json`. 원본 `status` / `staticStatus`는 **NOT VERIFIED**입니다. `@hm-design/sw/styles.css` 연결 미해석(`ENTRY-002`), 패키지 구현이 Storybook graph 밖(`SCOPE-001`), 해당 연결에 의존한 Token/동적 값 미확인이 남았습니다. Guard를 변경하거나 원본 결과를 PASS로 덮어쓰지 않았습니다.
- Guard `styleEvidence`: STATIC PASS / RUNTIME NOT VERIFIED / DESIGN_INTENT PASS / FINAL NOT VERIFIED, `checks=[]`. SW CSS 실검사 완료를 뜻하지 않습니다. 별도 브라우저 Runtime은 위 범위 PASS, 디자인 의도는 정적 좌표 확인과 spring/반복 미검증을 합쳐 PARTIAL, 최종은 PARTIAL입니다.
## 10. 변경 파일
1. `packages/sw/src/theme/sw.css` — Reduced Motion 해제 선택자 수정.
2. `docs/sw/sw-header-design-spec.md` — §11.3 추가.
3. `docs/sw/sw-header-usage.md` — §10.2와 기존 Story 설명 보완.
4. `packages/sw/README.md` — 모션 사용·검증 링크 추가.
5. 이 검증 기록 — 신규 문서.
로컬 QA fixture·JSON·캡처·로그는 Git 무시 경로 `_local/sw-motion-qa/`에 있습니다. 원본 FAIL을 포함한 `verification.json`, 수정 후 `reduced-final.json`, 종합 `final-summary.json`, 원본 `guard.json`, `baseline.json`, build 로그와 폭별 PNG를 보존합니다. 이 파일들은 패키지 배포·공개 API에 포함하지 않습니다.
## 11. 기존 디자인 · 작업 보호
시작 해시와 비교해 기존 파일 중 변경된 것은 위 CSS·문서 4개뿐입니다. 새 선택자를 원래 한 줄로 되돌린 임시 사본의 SHA-256이 시작 CSS와 일치하여, CSS의 다른 바이트는 보존됨을 확인했습니다. 기존 TSX·SVG·Story·package.json·Lockfile은 시작 상태와 일치합니다. 다른 패키지의 소스·DWG/DXF 뷰어·다른 Worktree는 수정하지 않았습니다. Root의 기존 prerequisite build에 의해 Git 무시 dist는 재생성됐습니다.
## 12. 남은 문제 · NOT VERIFIED
실제 네이티브 창 제어, Figma player 반복 및 수치 easing의 완전 동등성, `linear()` 미지원 브라우저, 다른 브라우저·터치·펜·스크린리더, 키보드 창 이동 대안, 전용 SW Guard coverage는 미검증/후속 범위입니다. Tooltip의 시각적 버튼 겹침은 위와 같이 명시하며 변경하지 않았습니다.
## 13. 작업 종료 시 Git 상태
브랜치와 HEAD는 시작 상태를 유지합니다. 변경 그룹도 ` M package-lock.json`, ` M package.json`, `?? docs/sw/`, `?? packages/sw/`, `?? src/sw/`이며, 기존 미추적 그룹 내부에 이번 CSS·문서 변경이 포함됩니다. Stage·Commit·Push·PR·Merge·Publish·배포는 수행하지 않았습니다. Git 상태만으로 이번 변경이 0개라는 뜻은 아니며 파일별 시작 해시 비교를 함께 사용합니다.