UX/UI 설계 감사 — 공개/구매자 화면
- 작성: PRODUCT_DESIGN (L1, 외부 설계 감사 레인)
- 일자: 2026-11-02 · 대상: https://staging.yetdapay.com · 로컬 기준:
8e2f0a6(main) - 방법: Playwright chromium, 라우트별 데스크톱 1440×900 + 모바일 375×812 전체 페이지 스크린샷, 데스크톱 다크 모드 세트(
prefers-color-scheme: dark); 랩핑/오버플로용 DOM 지오메트리/computed-style 측정; 라이브 스테이징 데이터;fe/assets/css/main.css토큰 및Ui*컴포넌트 대비 소스 검토. - 픽스처: 익명 구매자; 라이브 스토어
s-e30305fda8e2(상품 3개), 완료 페이지용 실제 mock 구매. - 증적:
/tmp/ux-audit/public/{desktop,mobile,dark}/*.png(48컷),/tmp/ux-audit/public/meta.json - 범위 참고: 설계 검토 전용 — 제품 코드 변경 없음. 기능/인증 결함은 INDEPENDENT_QA 영역. 심각도 척도(위임 브리프 기준): critical = 금전 경로에서 구매자를 차단/오도 · major = 실질적 마찰, 막힘, 화면 간 불일치 · polish = 외관/일관성.
- 부작용: 라이브 완료 페이지 도달을 위해 스테이징에 mock 주문 2건 생성(
ord_0c3281f89334,ord_dded9f3f44f2) — 설계된 샌드박스 흐름, 실제 청구 없음.
화면 목록
| # | 라우트 | 데스크톱 | 모바일 | 다크 | 스테이징 라이브 상태 |
|---|---|---|---|---|---|
| P1 | / | home | home | light-only | 완전 렌더 |
| P2 | /login | login | login | light-only | 완전 렌더 |
| P3 | /signup | signup | signup | light-only | 완전 렌더 |
| P4 | /legal/privacy, /legal/terms | legal-* | legal-* | light-only | 플레이스홀더 문서 |
| P5 | /store/s-e30305fda8e2 | store-index | store-index | ok | 상품 3개 |
| P6 | /store/…/p/prod_661d517f1e50 | store-product | store-product | ok | one_time ₩1,000 |
| P7 | /store/nonexistent-slug-xyz | store-404 | store-404 | ok | 404 상태 |
| P8 | /donate/s-e30305fda8e2 | donate | donate | ok | 기부 상품 라이브 |
| P9 | /checkout/prod_…?store=… | checkout-product-real / -filled / -sub | checkout-product-real | ok | 실제 폼(?store= 필요) |
| P10 | /checkout/prod_… (단독) | checkout-product | checkout-product | ok | "스토어 링크 필요" 가드 |
| P11 | /checkout/item/gi_dia100 | checkout-item | checkout-item | ok | 항상 not-found(F8 참조) |
| P12 | /checkout/complete/ord_… | checkout-complete-real | checkout-complete-real | ok | 세션 전용(F5 참조) |
| P13 | /license/verify | license-verify | license-verify | ok | 개발 도구 페이지 |
| P14 | /demo/proj_… ×2 | demo-a/b | demo-b | ok | 항상 not-found(F8 참조) |
확인된 정상 항목 (유지)
- 375px 전체 10개 측정 라우트에서 가로 오버플로 없음(
scrollWidth == innerWidth). 반응형 그리드가 올바르게 접힘(상품 그리드 3→1, 체크아웃 2열→적층, 4단 타일→2×2). - 토큰 규율이 높음: 페이지들이
.card,input-base,--ng-*색상,UiCard/UiField/UiInput/UiButton/UiBadge/UiEmpty/UiSkeleton/UiSegmented를 일관 사용.PaymentMethodPicker의 정당한 브랜드 색상(fe/components/payments/PaymentMethodPicker.vue:8-11) 외 페이지 마크업에 임의 hex 없음. 모든 가격에tabular-nums. - 모바일 탭 대상 ≥44px — 링크/nav/체크박스 행에
min-h-11컨벤션 적용;.input-basemin-height 44px 미디어 규칙(main.css:177-181); 타일 h-11. - 로딩 스켈레톤이 최종 레이아웃 반영 — store/product/checkout/donate(
UiSkeleton형태 플레이스홀더 — 예:[productId].vue:93-100,checkout/[productId].vue:166-176). - 모든 곳에서 mock 환경을 정직하게 표시:
SANDBOX/MOCK 결제배지, "Mock 결제 · 실제 청구되지 않습니다" 캡션, 스토어의 PoC 배너, license-verify의 경고 배너. 신뢰할 수 있는 라벨링. - 활성화된 곳의 다크 모드 렌더 정상 — 반전된 primary 버튼, 부드러운 다크 표면, store/checkout/donate/license-verify에서 읽기 가능한 배지(dark/* 샷). 토큰 커버리지 완비.
- 오류 상태 대체로 일관적 — store-404, product-404, checkout no-store에서
UiEmpty+ 복구 CTA(스토어로 이동/홈으로 이동/다시 시도). - 한국어 문구 톤: 일관된 존댓말, 간결한 도움말; 폼 힌트가 유용("라이선스 키가 이 이메일과 연결됩니다").
- 체크아웃 주문 요약, license-verify 요청/결과 분리, 기부 프리셋+직접 금액이 잘 구성된 단일 목적 컴포지션.
발견 사항
S-P1 / — 랜딩
| ID | 심각도 | 발견 | 권고 | 파일 |
|---|---|---|---|---|
| P1-1 | polish | 기능 카드 icon 필드(Package, Store, KeyRound…)가 정의됐으나 렌더되지 않음 — UiCard에 icon prop이 없음. 카드가 텍스트만 표시; 죽은 데이터는 미완성 시각 패스를 암시. | 아이콘 렌더(카드 제목 위 작은 accent 틴트 타일) 또는 필드 제거. | fe/pages/index.vue:3-10; fe/components/ui/UiCard.vue:2 |
| P1-2 | major | 페이지가 다크 선호를 완전히 무시(C2 참조) — 랜딩은 브랜드 현관인데 연결된 스토어가 다크로 가는 동안 light 유지. | 테마를 전역 적용(C2). | fe/pages/index.vue:2 |
S-P2 /login — S-P3 /signup
| ID | 심각도 | 발견 | 권고 | 파일 |
|---|---|---|---|---|
| P2-1 | polish | 로그인에 비밀번호 재설정 경로 없음. 재설정이 아직 제품 기능이 아니라면 괜찮지만 힌트도 없음. | 기능 도입 시 비밀번호 재설정 링크 추가 또는 지원 안내 문구. | fe/pages/login.vue:45-47 |
| P3-1 | polish | 비밀번호 필드가 placeholder="8자 이상"과 hint="8자 이상" 둘 다 표시 — 입력 아래에 중복 마이크로카피. | hint 유지, placeholder를 비밀번호로 변경. | fe/pages/signup.vue:58-59 |
| P3-2 | polish | 동의 링크 라벨 개인정보 처리가 문서 제목 개인정보 처리방침과 불일치. | 문서 실제 이름으로 링크 라벨 지정. | fe/pages/signup.vue:75 |
S-P4 /legal/privacy, /legal/terms — 법적 문서 페이지
| ID | 심각도 | 발견 | 권고 | 파일 |
|---|---|---|---|---|
| P4-1 | major | 막힌 chrome: 워드마크→홈이 유일한 탈출구. 푸터 없음, privacy↔terms 교차 링크 없음, 연락 경로 없음, 기준 언어 표시 없음. 이 페이지들은 회원가입 동의에서 (필수, target=_blank) 링크됨 — 신뢰와 가장 연관된 화면이 방치되어 보임. | 법적 페이지에 최소 공용 chrome 부여: 뒤로/홈 유도, 두 문서 간 교차 링크, 연락 채널, 최종 갱신일. | fe/pages/legal/privacy.vue, terms.vue (13줄 스텁) |
| P4-2 | major | 내용이 3단락 플레이스홀더(검토 대상 배지). 페이지 스스로 정책이 미확정임을 인정 — 그런데 회원가입이 사용자에게 동의를 요구. (시각보다 문구/제품 갭.) | PM 에스컬레이션: 동의 UI가 미확정 문서를 구속력 있는 계약처럼 제시하면 안 됨; 중간 문구는 범위를 명확히 표시. | same |
| P4-3 | polish | UiBadge variant="warn" — 유효하지 않은 prop(컴포넌트는 tone 사용); 배지가 조용히 중립 회색으로 렌더되어 의도한 warn 의미 상실. | tone="warn". UiBadge의 다른 variant= 사용 전수 점검. | fe/pages/legal/privacy.vue:6, terms.vue 동일 위치; fe/components/ui/UiBadge.vue:3 |
S-P5 /store/[slug] — 공개 스토어프런트
| ID | 심각도 | 발견 | 권고 | 파일 |
|---|---|---|---|---|
| P5-1 | polish | 카드 CTA 자세히 →가 호버 전까지 opacity-0 — 터치에서 보이지 않는 유도; 모바일에서 카드가 정적 콘텐츠처럼 보임. | 터치에서 상시 유도 표시(예: sm 미만에서 항상 chevron), 또는 카드 전체 링크 스타일 단서(가격 + 화살표 힌트) 활용. | fe/pages/store/[sellerSlug]/index.vue:136-138 |
| P5-2 | polish | SANDBOX 배지(UiBadge의 hidden sm:inline-flex)가 스테이징 모바일에 여전히 노출 — 375px에서 display:flex 측정, DOM 클래스 목록에 템플릿의 inline-flex 유틸리티 부재. A1 수정은 로컬에 존재하나 미커밋 worktree 내용(git diff fe/components/ui/UiBadge.vue)이고 배포 번들이 그 이전. 시각적으로 무해하나 배포↔소스 어긋남을 입증. | A1 수정 커밋 + 배포 후 스테이징 재검증. 배포 동등성 확인을 INDEPENDENT_QA에 플래그. | fe/layouts/storefront.vue:24; fe/components/ui/UiBadge.vue:9; cf. docs/ux-audit-admin.md A1 |
| P5-3 | polish | 히어로 h1이 seller.tagline을 렌더하고 seller.name은 아바타 글자 + 브라우저 탭에만 표시 — 태그라인이 빈 스토어는 빈 히어로 생성. 기부 상품 커버(D)가 그라디언트 형제 대비 거의 흰 타일로 렌더 — 커버 없는 상품이 그리드 품질 저하. | h1을 seller.name으로 폴백; coverGradient가 비어 있을 때 기본 브랜드 커버 부여. | fe/pages/store/[sellerSlug]/index.vue:89-92,122-125 |
| P5-4 | polish | 푸터 Powered by 워드마크가 링크 아님(놓친 브랜드 루프); 판매자 콘솔 →은 구매자 페이지의 판매자 대상 CTA. | 워드마크를 /로 링크; 콘솔 링크 강조 축소 고려. | fe/layouts/storefront.vue:33-34 |
S-P6 /store/[slug]/p/[id] — 상품 상세
| ID | 심각도 | 발견 | 권고 | 파일 |
|---|---|---|---|---|
| P6-1 | polish | 구매 카드 상단의 stray 헤어라인: border-t border-line-soft pt-5 구분선이 앞에 플랜 선택기/기부 블록이 없어도 렌더(이 상품에서 고아 선으로 보임). | 구분선 조건부 렌더(`v-if="prodPlans.length > 1 | |
| P6-2 | polish | 라이선스 상품의 구매 카드가 빈약 — 가격 + CTA + mock 캡션뿐. 라이선스 정책은 콘텐츠 열 아래 멀리 위치; 구매자가 결정 시점에 "무엇을 받는지" 확인 불가. | licensePolicy.enabled 시 카드에 간결한 권한/라이선스 요약 행 추가(키 발급, 기기 수). | same file, aside block :169-228 |
| P6-3 | polish | 모바일: sticky aside가 모든 콘텐츠 뒤에 in-flow — CTA는 괜찮으나 설명이 길면 가격 컨텍스트를 폴드 위에 반복 가능. | 선택적 <lg sticky 하단 CTA. | same file :107,169 |
S-P7 /store/[bad] — 스토어프런트 404
| ID | 심각도 | 발견 | 권고 | 파일 |
|---|---|---|---|---|
| P7-1 | polish | 404에서 헤더가 빈 판매자 식별 슬롯 렌더 — 왼쪽에 보이지 않는 아바타 + 빈 이름(스크린샷: 헤더 좌측 전체가 데드 스페이스). | headerSeller가 비면 YetdaPay 워드마크 → /로 폴백. | fe/layouts/storefront.vue:9,16-22 |
S-P8 /donate/[slug] — 기부 페이지
| ID | 심각도 | 발견 | 권고 | 파일 |
|---|---|---|---|---|
| P8-1 | polish | 메인 폼에 스토어 복귀 유도 없음 — 오류/완료 상태엔 스토어로 돌아가기가 있으나 폼 자체에는 없음; 유일한 탈출이 워드마크(/dashboard→login 바운스로 이동, C1 참조). | 카드 위에 뒤로 링크 추가(상품/체크아웃 페이지와 같은 패턴). | fe/pages/donate/[slug].vue:123-158 vs :99-110 |
| P8-2 | polish | 375px에서 h1 단어 중간 줄바꿈: …후원하\n기 — 긴 판매자명에서 2행 72px 측정(C7 클러스터). | 헤딩에 word-break: keep-all; 긴 판매자명 truncate. | fe/pages/donate/[slug].vue:126 |
| P8-3 | polish | 결제 수단이 호출에 kakaopay로 하드코딩되고 표시되지 않음 — 수단 유도 없는 결제 형태 폼은 체크아웃의 picker와 다름. | 수단 표시(mock에는 읽기 전용 배지로 충분) 또는 picker 재사용. | fe/pages/donate/[slug].vue:62 |
S-P9 /checkout/[productId] — 체크아웃 폼 (실제 흐름)
| ID | 심각도 | 발견 | 권고 | 파일 |
|---|---|---|---|---|
| P9-1 | critical | 헤더 워드마크가 /dashboard로 링크 → 체크아웃 중 로고를 클릭한 익명 구매자가 /login으로 튕겨 체크아웃 컨텍스트 상실. default 레이아웃의 모든 공개 페이지 공유(donate, license-verify, complete, demo). | 워드마크를 /로(또는 있으면 현재 스토어 slug로). 화면에서 가장 레버리지 높은 한 줄 수정. | fe/layouts/default.vue:5 |
| P9-2 | major | 단독 /checkout/[productId](?store= 없음)가 홈으로 이동만 있는 "스토어 링크가 필요합니다"에서 막힘 — 그런데 productId는 알려져 있음; 공유/복사된 체크아웃 링크가 구매 한 단계 앞에서 구매자를 버림. | 공개 상품 fetch로 product→seller 해석해 자동 리다이렉트, 또는 해석 가능 시 스토어로 이동 제공. | fe/pages/checkout/[productId].vue:67,263-275 |
| P9-3 | major | 결제 타일 라벨이 375px에서 단어 중간 줄바꿈: 네이버페\n이, 카카오페\n이 — 4글자 라벨이 단일 행 20px 대신 41px(2행) 측정; 구매자 경로에서 가장 중요한 상호작용 컴포넌트가 깨져 보임. | 라벨 span에 whitespace-nowrap(또는 sm 미만 grid-cols-1). | fe/components/payments/PaymentMethodPicker.vue:34-36 |
| P9-4 | major | default 레이아웃에 푸터 없음 — 법적/개인정보/연락 링크가 전혀 없는 결제 페이지(storefront 레이아웃엔 푸터 있음; default에는 없음). | 공유 공개 푸터(법적 링크 + powered-by)를 default 레이아웃에 추가. | fe/layouts/default.vue (부재) vs storefront.vue:31-36 |
| P9-5 | polish | 모바일: 주문 요약 + 결제 CTA가 적층 카드 3개 아래 — 구매자가 합계까지 ~2 뷰포트 스크롤. | <lg에서 컴팩트 sticky 요약/CTA 바 고려. | fe/pages/checkout/[productId].vue:183-260 |
| P9-6 | polish | 결제 시뮬레이션 세그먼트(성공/실패/취소)가 구매자에게 노출 — PoC 샌드박스엔 적절하나 프로덕션 UX에선 env-gate 또는 제거 필요. | 같은 paidCheckoutEnabled/demo 플래그 계열로 게이트; 릴리스 체크리스트에 기록. | fe/pages/checkout/[productId].vue:201-216 |
S-P10 /checkout/item/[itemId] — 게임 아이템 체크아웃
| ID | 심각도 | 발견 | 권고 | 파일 |
|---|---|---|---|---|
| P10-1 | major | db.gameItemById/projectById를 로컬 상태에서만 읽음 — API 모드에서 익명 세션엔 프로젝트가 없어 라우트가 항상 "상품을 찾을 수 없습니다" 렌더. 공개 아이템 체크아웃 링크가 동작할 수 없음. | 공개 아이템 fetch 연결(스토어용 usePublicStore처럼) 또는 라우트 게이트; 구매자 화면으로 공개하지 말 것. | fe/pages/checkout/item/[itemId].vue:13-14 |
| P10-2 | polish | not-found UiEmpty에 CTA가 전혀 없음 — 진짜 막힘(store/product/checkout 가드가 복구 버튼을 제공하는 것과 불일치). | 홈으로 이동/재시도 CTA 추가. | fe/pages/checkout/item/[itemId].vue:82 |
S-P11 /checkout/complete/[orderId] — 주문 확인
| ID | 심각도 | 발견 | 권고 | 파일 |
|---|---|---|---|---|
| P11-1 | major | 세션 전용 영수증: 페이지가 db.orderById로 주문 해석 — API 모드에서 업무 데이터는 지속되지 않음(persist.client.ts:30-34), 새로고침/북마크/공유 링크는 "주문을 찾을 수 없습니다" 표시. Mock 이메일이므로 구매자가 라이선스 키나 영수증으로 돌아갈 지속 가능한 방법이 없음 — 완료 페이지가 사실상 세션 후 자폭. 라이선스 키 블록은 존재하나 세션 상태가 사는 동안만 렌더. | 제품 결정 필요: 공개 주문 조회(주문 번호 + 이메일), 또는 명시적 "지금 키 저장" 유도 + 복사/다운로드; 최소한 페이지가 재오픈 불가임을 경고. 조회 엔드포인트는 BACKEND_INFRA와 조율. | fe/pages/checkout/complete/[orderId].vue:12-14; fe/plugins/persist.client.ts:8-9,30-34 |
| P11-2 | polish | 요약 dl 행이 375px에서 단어 중간 줄바꿈 — 긴 이메일 값 아래 구매\n자 라벨 랩핑(C7 클러스터). | dt → whitespace-nowrap flex-none; dd → min-w-0 break-all/truncate. | fe/pages/checkout/complete/[orderId].vue:78-83 |
| P11-3 | polish | 오류 상태 CTA 라벨 스토어로 이동이 스토어 컨텍스트 없을 때 /로 이동 — 라벨/목적지 불일치. | 폴백이 /이면 홈으로 이동 라벨. | fe/pages/checkout/complete/[orderId].vue:98 |
S-P12 /license/verify — 라이선스 검증 도구
| ID | 심각도 | 발견 | 권고 | 파일 |
|---|---|---|---|---|
| P12-1 | polish | 좋은 페이지(요청 폼, 적절한 빈 상태의 결과 패널, 데모 키 채우기, API 예시, 정직한 Mock 배너). 유일한 지적: 로그인 판매자에게 레이아웃이 dashboard로 전환 — 공개 도구가 조용히 콘솔 chrome이 됨; 세션을 가진 구매자가 이중 레이아웃 전환에 놀라지 않는지 확인. | 유지하거나 dashboard chrome을 콘솔 전용 라우트로 한정. | fe/pages/license/verify.vue:12-22 |
S-P13 /demo/[projectId] — 게임 데모
| ID | 심각도 | 발견 | 권고 | 파일 |
|---|---|---|---|---|
| P13-1 | major | P10-1과 같은 로컬 상태 데드 라우트 — db.projectById/itemsForProject가 API 모드 익명에서 절대 해석되지 않음; 테스트한 두 프로젝트 id 모두 "프로젝트를 찾을 수 없습니다" 렌더. 데모 카드 UI(프로젝트 헤더, 플레이어 잔액, 상점, 구매 모달)는 공개 화면으로 사실상 출시 불가. | P10-1과 같은 해결 계열: 공개 fetch 또는 게이트. QA 시드 링크(proj_2f071a8d5455, proj_space)도 오래됨 — 데이터 스토리 결정 후 픽스처 갱신. | fe/pages/demo/[projectId].vue:14-15 |
| P13-2 | polish | not-found UiEmpty에 복구 CTA 없음. | CTA 추가(P10-2 패턴). | fe/pages/demo/[projectId].vue:130 |
교차 발견
| ID | 심각도 | 발견 | 권고 |
|---|---|---|---|
| C1 | critical | 브랜드 마크의 목적지/동작이 세 가지로 갈림: 랜딩 헤더(로컬), storefront(판매자 식별), default 레이아웃 워드마크→/dashboard(익명은 login 바운스). 구매자 경로에서 로고가 인증 장벽으로 라우팅되면 안 됨. | 공개 워드마크를 /로; 콘솔 링크는 콘솔로 라벨. (fe/layouts/default.vue:5) |
| C2 | major | 다크 모드가 ThemeToggle → useTheme 경유로만 적용되고 default/storefront/admin/dashboard 레이아웃에 마운트됨. layout:false 페이지(index, login, signup, legal/*)는 실행하지 않음 → .dark 미적용 → 시스템 다크 사용자가 light 랜딩 → dark 스토어 → light 체크아웃 인접 페이지: 비일관. | 테마를 앱 전체 적용(부팅 시 ng-theme/시스템 읽는 클라이언트 플러그인) 후, 그 페이지들에 토글을 줄지 의도적으로 결정. (fe/composables/useTheme.ts:20-26; fe/layouts/default.vue:10; pages/index.vue:2, login.vue:5, signup.vue:2, legal/*.vue:1) |
| C3 | major | 푸터가 랜딩 + storefront에만 존재. default 레이아웃 페이지(checkout, donate, license-verify, complete, demo)에는 푸터 없음 → 결제 경로에 법적/연락 링크 부재. | default 레이아웃용 공유 최소 공개 푸터. |
| C4 | polish | 빈 상태 CTA 커버리지 불일치: store-404/product-404/checkout 가드는 복구 버튼 제공; /demo/*와 /checkout/item/*은 없음. | 모든 공개 UiEmpty 상태에 복구 CTA를 필수 슬롯 패턴으로. |
| C5 | polish | 모든 공개 페이지가 <title>YetdaPay</title> 제공 — /h/[publicId] 외 페이지별 title/description 없음. 탭 식별, 공유 미리보기, SEO를 해침(유일하게 SEO가 중요한 화면에서). | 공개 페이지별 useHead/useSeoMeta(예: {product.name} · {store} — YetdaPay). (fe/pages/h/[publicId].vue:77이 선례) |
| C6 | polish | 한국어 단어 분리 위생: 375px에서 donate h1(후원하/기), 결제 타일(네이버페/이), complete dl(구매/자)의 단어 중간 줄바꿈 확인. 기본 overflow-wrap/break 규칙이 CJK를 단어 중간에 끊음. | 헤딩/라벨에 word-break: keep-all; 공간 허용 시 whitespace-nowrap; break-all은 값 쪽만. |
| C7 | polish | 배포↔소스 어긋남 확인: 스테이징 UiBadge DOM에 템플릿 inline-flex 클래스 부재, hidden 무력화 재현됨(P5-2); A1 수정은 미커밋 로컬 worktree 내용. Worktree에 UiButton/UiDropdown/UiKpi/UiSegmented, layouts/admin.vue, pages/admin/index.vue의 미커밋 편집도 있음(이전 세션의 리메디에이션 — 이번 감사 것 아님). | 보류 중 리메디에이션 커밋 + 배포; UI 수정 재테스트 전 배포 번들이 소스와 일치하는지 INDEPENDENT_QA/④-C 확인. |
상위 5개 우선순위
- 로고→
/dashboard바운스 제거(P9-1/C1).fe/layouts/default.vue:5의 한 줄 수정; 현재 모든 공개 페이지의 브랜드 마크가 익명 구매자를 로그인으로 내보냄. 금전 경로에서 critical. - 구매자에게 지속 가능한 영수증 제공(P11-1).
/checkout/complete/*가 세션 전용; 새로고침 = "주문을 찾을 수 없습니다" + 라이선스 키 회수 불가(mock 이메일). 결정: 공개 주문 조회(백엔드) 또는 명시적 "이 페이지 저장 / 키 복사" 유도. Major — PM+BACKEND_INFRA 필요. - 죽은 공개 라우트 부활 또는 게이트(P10-1, P13-1).
/demo/*와/checkout/item/*은 API 모드 익명에 절대 렌더 불가; 공개 fetch 연결(usePublicStore와 동등) 또는 공개 화면에서 제거 — 그리고 모든 공개 빈 상태에 복구 CTA(C4). Major. - 테마 커버리지 통일(C2). 앱 부팅 시 테마 적용으로 랜딩/로그인/회원가입/법적 페이지가 사용자의 다크 선호를 따르게 — 현재 브랜드 진입 페이지만 조용히 무시. Major 일관성.
- 법적 페이지 신뢰 패스 + 모바일 단어 분리 일괄(P4-1/2/3, C6, P9-3).
/legal/*에 실제 chrome + 교차 링크 + 확정 동의 스토리(필수 회원가입 동의에서 링크됨), 그리고 단어 중간 한국어 줄바꿈용keep-all/nowrap일괄 — 결제 타일 랩핑이 최악 사례. Major + polish 클러스터; 무료 수정도 함께: stray 구매 카드 구분선(P6-1), 유효하지 않은variantprop(P4-3), default 레이아웃 푸터(P9-4/C3).
한계
- 다크 모드 검토는
default/storefront페이지로 한정(적용 가능한 유일한 페이지); light-only 페이지는 갭 입증용으로 다크 선호 하에 캡처했을 뿐 다크 렌더 검사 아님. /demo/*와/checkout/item/*은 not-found 상태로만 검토 가능 — 채워진 디자인은 코드에만 존재(fe/pages/demo/[projectId].vue:62-129,fe/pages/checkout/item/[itemId].vue:52-84); 공개 데이터 경로가 생기면 후속 시각 패스 권장.- 체크아웃 완료 성공 상태는 실제 mock 주문 2건으로 검토; 기부 성공 카드와 라이선스 상품 라이선스 블록은 라이브로 실행하지 않음(조건부 렌더는 소스에서만 확인).
- 스테이징이 로컬 소스보다 뒤처질 수 있음(C7) — 발견은 배포 번들에서 측정; 일부는 로컬에서 이미 수정되었을 수 있음.
- 이번 라운드는 a11y 트리/대비 측정 패스 없음(지오메트리 + 시각 검토만); 공개 세트에 대한 axe 실행을 INDEPENDENT_QA에 권장.