feat(site,skill): 모바일 앱 수준 UX — 바텀내비·백 키 히스토리·바텀 시트·safe area·PWA 와 L6 시나리오 E2E

- HIG(탭바 5~6·시트)·M3(바텀내비 3~5·48dp)·NN/g·CSS-Tricks 조사(research/mobile-app-ux-v1.md) 후 Nielsen 10 감사로 위반 도출
- 바텀 내비 5탭 + 더보기 바텀 시트(그룹 헤더), 뷰·다이얼로그 pushState/popstate — 안드로이드 백 키가 앱 내 뒤로 작동
- safe area(env+max)·입력 16px(iOS 확대 방지)·coarse 44px 타깃·tap-highlight·overscroll 위생, 인쇄에서 모바일 크롬 제거
- PWA: manifest + sharp 생성 아이콘(가온=장부 문항, 두레=시간표 블록)
- tools/e2e.mjs L6 시나리오: RED 1,742 단언 318 실패 → GREEN 1,762/0, verify 체인 7계층 통과
- 실기기(안드로이드 에뮬레이터·Chrome) 텍스트 근거 검증 — 백 키·시트·탭 전환, iOS 는 WebKit(L4) 대체
- 스킬 내재화: mobile-app-ux.md, audit-gate 7계층·하니스 12~14, design-gate 터치타깃 검사, SKILL.md 규칙 7
- 도그푸드: 게이트가 죽은 선택자 8종·thresholds 병합 버그 적발 — CSS v22(양앱) 범프 후 전체 재검증
This commit is contained in:
Yun Chan 2026-08-23 14:33:15 +09:00
parent 72337b7ee0
commit 14cb138e1a
133 changed files with 2139 additions and 208 deletions

View file

@ -0,0 +1,30 @@
// 임시 구문 스캐너 — 괄호·템플릿 리터럴 균형 줄 단위 추적
import fs from "node:fs";
const src = fs.readFileSync(process.argv[2], "utf8");
let inTpl = false, inStr = null, inInterp = 0, line = 1;
const stack = [];
const push = (t) => stack.push(t + "@" + line);
for (let i = 0; i < src.length; i++) {
const c = src[i], n = src[i + 1];
if (c === "\n") line++;
if (inStr) {
if (c === "\\") { i++; continue; }
if (c === inStr) inStr = null;
continue;
}
if (inTpl) {
if (c === "\\") { i++; continue; }
if (c === "$" && n === "{") { push("${"); inInterp++; i++; continue; }
if (c === "`") { inTpl = false; const m = stack.pop(); }
continue;
}
if (c === "`") { inTpl = true; push("tpl"); continue; }
if (c === "'" || c === '"') { inStr = c; continue; }
if (c === "/" && n === "/") { while (i < src.length && src[i] !== "\n") i++; continue; }
if (c === "(" || c === "[" || c === "{") push(c);
else if (c === ")" || c === "]" || c === "}") {
const m = stack.pop();
if (!m) { console.log("여분의 닫기", c, "줄", line); process.exit(0); }
}
}
console.log("미닫힘:", stack.slice(-8).join(", ") || "없음");