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

12 KiB
Raw Blame History

SW Header 창 이동 Motion — GIF 기준 최종 검증 (2026-10-16)

1. 최종 판정: PARTIAL

GIF 기준 모션 수정과 Chrome 브라우저 검증 PASS, Root Typecheck / SW Build / Root Build / Storybook Build PASS입니다. 실제 호스트의 OS 창 이동·최소화·종료, 다른 브라우저·보조기술과 독립 SW 패키지의 Guard coverage는 NOT VERIFIED이므로 전체 PASS로 확대하지 않습니다. GIF 이전 검증은 과거 기록으로 보존합니다.

2. 시작 Git 상태

  • Worktree: D:\디자인시스템\HMDesign-SW, branch feature/sw-package.
  • HEAD: 9407c8567f57301659e591c03451cca1b828733c.
  • 기존 변경: M package-lock.json, M package.json, ?? docs/sw/, ?? packages/sw/, ?? src/sw/.
  • _local/sw-motion-gif-qa/baseline.json에 기존 SW·Story·문서와 root manifest/Lockfile의 SHA-256을 보존하고, 변경 전 CSS·창 제어 TSX·Story 사본도 저장했습니다. 기존 미추적 파일을 삭제·초기화하지 않았습니다.

3. 기존 구현과 GIF의 차이

기존 구현은 2.7265658초 1회 재생이며, 커서가 이미 위쪽에 있는 별도 SVG로 fade-in하고 창을 축소한 뒤 오른쪽으로 이동했습니다. 문구가 이른 시점부터 나타났고 마지막에 dissolve로 Default로 복귀했습니다. 이 방식은 이번 GIF의 ‘아래쪽 커서 상승 → 문구 → 전체 이동 → 유지 → 즉시 반복’과 달랐습니다. 수정 전에 같은 40ms 간격의 41개 실제 브라우저 프레임을 캡처했습니다.

4. 추가 수정 범위

기존 모션 CSS만 GIF 표본으로 바꾸고 기존 Window Move Motion Story의 설명·고정 시간·반복 로그를 갱신했습니다. 기존 Default SVG, Hover용 SVG 두 개, 줄무늬, Tooltip box·색상·크기, 공개 API와 TSX 이벤트 연결은 유지했습니다. Tooltip 글꼴 선언만 Figma의 Inter를 우선하고 기존 SW 글꼴을 fallback하도록 명시했습니다. 폰트 파일이나 의존성은 추가하지 않았습니다.

누르는 동안 CSS :active로 3개 애니메이션을 일시정지하고 Tooltip을 숨깁니다. 전역 이벤트·포인터 캡처·preventDefault·React 상태는 추가하지 않았습니다.

5. 프레임별 비교 결과

기준 파일: D:\디자인시스템\ani_hover_move.gif, SHA-256 c7d22819cfb8f8cd8593684ce1e5c676a545fa09fa9fc7573d59f0f237d28026. 640 × 192px, 41프레임, 각 40ms, 1640ms, 무한 반복입니다.

GIF 높이 192px를 48px Header bar의 4배로 환산했습니다. 창의 녹색 폭도 96 / 4 = 24px로 기존 SVG와 일치합니다. GIF의 여분 가로 캔버스는 UI에 넣지 않았습니다. 비교 이미지에서만 가로 여백 32px를 잘라 기존 아이콘의 시작 위치를 정렬했습니다. 비교 결과는 Header 크기의 CSS px로 표시합니다.

  • 0–520ms: 창은 제자리, 커서는 오른쪽 아래에서 위로 약 12.5px 이동하고 왼쪽으로 0.75px 이동합니다.
  • 520ms: 문구가 처음 나타납니다. 41개 프레임 전체에서 문구 표시 여부가 일치했습니다.
  • 약 600–1040ms: 창은 오른쪽 28px / 위 4.5px 이동합니다. 커서는 최초 위치 대비 오른쪽 27.25px / 위 17px입니다. 40ms 표본 사이를 선형 보간하여 원본의 가속·감속을 따라가며 GIF에 없는 spring overshoot를 제거했습니다.
  • 1040–1640ms: 600ms 동안 창·커서·문구의 끝 자세를 유지합니다. 1640ms에 첫 프레임으로 즉시 반복합니다.
  • 최종 41개 캡처의 녹색 도형 좌상단 비교: 창 위치 최대 오차 0px, 커서 최대 오차 0.5px. 문구 glyph 좌상단 최대 오차 0.5px입니다.
  • 커서와 문구의 보이는 간격: GIF 9px, 구현 9.25–9.5px이며 프레임별 차이는 0.5px 이내입니다.

위 수치는 색이 있는 도형/glyph의 경계 좌표 비교이며 전체 픽셀 동일성 판정은 아닙니다. 기존 Figma SVG의 검정 외곽선·녹색 줄무늬·Tooltip 배경을 유지했으므로 GIF의 검정 캔버스와 외관 전체를 복제하지 않았습니다. 현재 동작은 Figma Prototype의 1.022/0.744/0.958초 spring·1회 정책보다 GIF의 시간과 반복을 우선합니다.

6. Drag 검증

실제 공개 @hm-design/sw를 React로 렌더링한 QA fixture에서 확인했습니다. onWindowMoveStart가 원래 div의 PointerEvent를 한 번 받았고 target/currentTarget, pointerId, pointerType=mouse, buttons=1, defaultPrevented=false를 유지했습니다. 호스트 모의 코드가 설정한 Pointer Capture를 통해 Tooltip·창 제어 버튼 위로 이동해도 pointermove와 pointerup이 전달됐습니다.

포인터를 누르는 동안 애니메이션은 paused이며 200ms가 지나도 currentTime이 변하지 않았고 Tooltip은 숨겨졌습니다. Drag 중 최소화·종료 콜백은 발생하지 않았고, 이후 각 버튼 클릭은 자신의 콜백만 호출했습니다. Reduced Motion에서도 드래그 콜백·해제가 유지됐습니다. 실제 OS 창 이동과 네이티브 호스트 통합은 NOT VERIFIED입니다.

7. Tooltip · 반복 · Reduced Motion · Focus

  • PASS: 45 × 17px, 검정 80% 배경, 흰색 12px/400, Inter 우선 + SW fallback 선언. 한글 또는 Inter가 없는 환경은 기존 Noto Sans KR 등으로 표시되며 Inter 파일 로드를 보증하지 않습니다.
  • PASS: 장식 자식 전체의 pointer-events: none, Tooltip 겹침 위치에서 최소화 버튼 hit test, 최소화·종료 Callback 전달.
  • PASS: 실제 Hover를 유지해 1.64초 간격의 iteration 2회, 중복 animationstart 없음. 12회 빠른 진입·이탈에서 start/cancel 각 12회, 잔여 애니메이션 0개.
  • PASS: Hover 해제 즉시 Default SVG·위치·문구 숨김, 재진입 시 처음부터 시작.
  • PASS: 재생 중 reduce 전환 시 애니메이션 0개, 원래 Default SVG와 정적 Tooltip 유지. 누르는 동안 Tooltip 숨김, 이탈하면 숨김. 24px 단계의 기존 그림 숨김 정책도 유지.
  • PASS: 최소화 → 종료 Tab 이동, 2px Focus 윤곽선, Enter로 종료 콜백.
  • 기존 제한: 이동 div는 role=presentation/Tab 비대상이며 키보드 창 이동·Focus Tooltip을 제공하지 않습니다. 호스트의 키보드 대안과 보조기술은 미검증입니다.

8. 반응형

1920 / 1440 / 1280(추가) / 1080 / 1079 / 768 / 640 / 639 / 390px에서 실제 viewport와 Header 폭을 검사했습니다. 모두 높이 49px, Header 및 문서의 가로 overflow 0px, Tooltip은 Header 경계 안이었습니다. 1080px 이상 이동 영역 88px, 640–1079px는 24px와 정적 Tooltip만, 639px 이하는 영역 숨김을 유지합니다. 최소화·종료의 배치와 클릭은 유지했습니다.

Tooltip은 기존처럼 이동 영역 밖으로 나와 최소화·종료 일부에 시각적으로 겹칩니다. 시각적 겹침이 없다고 판정하지 않았으며, 포인터 차단이나 가로 스크롤이 없음을 확인했습니다. 기존 문서명·레이어명의 말줄임 구조는 변경하지 않았습니다.

9. Typecheck · Build · Storybook · Guard

  • PASS: npm.cmd run typecheck — root·SW를 포함한 workspace 타입 검사와 기존 pretypecheck의 theme 확인·package build. 최종 CSS와 Story 변경 뒤 실행했습니다.
  • PASS: npm.cmd run build:sw 및 최종 pretypecheck에 포함된 SW Build.
  • PASS: npm.cmd --ignore-scripts run build, npm.cmd --ignore-scripts run build-storybook. 이미 통과한 공통 prerequisite을 중복 실행하지 않았습니다.
  • PASS: Chrome 155.0.8059.79, 실제 CSS 애니메이션·9개 Story 단계·520ms 등장/1640ms 반복 경계·motion cycle/Drag/최소화/종료 로그·Reduced Motion. 브라우저 통합 검사 41개 PASS, pageerror 0건, HTTP 오류 0건.
  • 기존 경고: 문서 예시 bg-[var(...)] CSS 최적화, Storybook :host-context minifier, 500kB 초과 chunk와 plugin timing 안내. exit 0이며 범위 밖의 기존 코드를 수정하지 않았습니다.
  • 개발 서버의 기존 포트·프로세스를 건드리지 않고 빌드된 Storybook과 QA fixture를 임시 localhost 서버에서 검사하고 종료했습니다.
  • 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, FAIL 없음. SW styles export 미해석 ENTRY-002, 패키지 graph 밖 SCOPE-001, 연결에 의존한 Token/동적 값 미검증이 남았습니다. Guard를 수정하거나 PASS로 덮어쓰지 않았습니다.
  • Guard 원본 styleEvidence는 STATIC PASS / RUNTIME NOT VERIFIED / DESIGN_INTENT PASS / FINAL NOT VERIFIED이며 checks=[]입니다. SW 실검사 완료라는 뜻은 아닙니다. 별도 Runtime은 위 Chrome 범위 PASS, 디자인 의도는 GIF 프레임 좌표·순서 및 Figma 자산·Tooltip 규격 범위에서 확인했고, 전체 검증은 호스트 등의 미검증 때문에 PARTIAL입니다.

10. 변경 파일 · 근거

  1. packages/sw/src/theme/sw.css — 창 이동 모션 블록만 수정.
  2. src/sw/sw-header.stories.tsx — 기존 모션 Story 블록만 갱신.
  3. docs/sw/sw-header-design-spec.md — 과거 §11.3을 보존하고 현재 GIF 기준 §11.4 추가.
  4. docs/sw/sw-header-usage.md — 현재 모션·Drag·반복·Story 사용법 반영.
  5. packages/sw/README.md — 현재 GIF 기준과 검증 링크 반영.
  6. 이 검증 기록 — 신규 문서.

Git 무시 경로 _local/sw-motion-gif-qa/에 원본 분석 JSON, 전/후 41개 PNG 및 좌표 JSON, frame-comparison.json, 비교 이미지 gif-before-after.png, 실제 React 캡처 미리보기 window-move-preview.gif, 폭별 PNG, storybook-final.png, verification.json, build 로그, 원본 guard.json, 시작 해시와 사본을 보존합니다. GIF는 QA 미리보기일 뿐 제품 Header에 사용하지 않습니다.

11. 기존 디자인 · 작업 보호

모션 블록 밖 CSS와 기존 TSX/이벤트 연결이 시작 사본과 동일함을 확인했습니다. SVG·나머지 Story·기존 반응형·다른 Header 요소·root package.json/Lockfile·과거 검증 문서도 시작 해시와 일치합니다. 다른 패키지 소스·다른 Worktree·DWG/DXF 뷰어를 변경하지 않았습니다. Root의 기존 package build는 Git 무시 dist만 재생성했습니다. 의존성 설치는 없습니다.

12. 남은 항목

실제 Electron/설치형 호스트의 OS 창 이동·최소화·종료, 터치/펜, 다른 브라우저, 키보드 창 이동 대안과 스크린리더, 전용 SW Guard coverage는 NOT VERIFIED입니다. Tooltip의 기존 시각적 버튼 겹침은 명시한 채 유지했습니다.

13. 종료 Git 상태

브랜치 feature/sw-package, HEAD 9407c8567f57301659e591c03451cca1b828733c를 유지합니다. 기존 status 그룹 M package-lock.json, M package.json, ?? docs/sw/, ?? packages/sw/, ?? src/sw/도 유지하며 이번 변경은 그 미추적 그룹 내부에 포함됩니다. Index 변경·Commit·Push·PR·Merge·Publish·배포는 수행하지 않았습니다. git diff --check와 문서 링크/공백 검사를 확인했습니다.

작업 시간(KST, GIF 수신 후 실제 작업): Started At 2026-10-16 13:38:28 / Completed At 2026-10-16 13:52:16 / Actual Duration 13분 48초 / Estimated Duration 20~30분 / Variance 20분 대비 −6분 12초, 30분 대비 −16분 12초.

14. 후속 변경 — 1400ms 및 Composed Controls Hover

위 1.64초·41프레임 검증은 당시 결과로 보존합니다. 이후 사용자 요청으로 경로·Keyframes 비율을 유지한 채 주기만 1400ms로 변경했습니다. 현재 문구 등장 약 444ms, 이동 완료 약 888ms, 유지 약 512ms입니다. 원본 GIF의 시간과 다른 의도적인 변경입니다.

같은 후속 작업에서 그룹 필드의 Hover 텍스트 및 지정 선/폰트/치수 미리보기를 #FFC600으로 추가 강조했습니다. 검정 외곽선과 기존 Gradient Hover Border·색상 견본·레이어 상태를 유지하고 상세보기는 제외했습니다. 이 변경의 새로운 검증 결과와 미검증 범위는 속도·Composed Hover 통합 검증에 별도로 기록합니다. 위 과거 수치와 판정을 소급 변경하지 않습니다.