전수 E2E 순회·소유자 결정 6건 구현·디자인 감사 반영
- 전수 순회: IA 전 라우트 412개 기능 인벤토리를 체크리스트 백로그로 관리 (docs/ops/e2e-full-sweep-2026-07-27.md), 신규 full-sweep 스펙 10파일 추가. RED→GREEN으로 결함 12건 수정: 관리자 무한 렌더 프리즈(TanStack autoReset 루프), 복수 코호트 저장 유실, 페르소나 보관 503(SQL 컬럼 모호성), PII 과잉 마스킹, /admin/ai watchdog 오탐 오버레이, 모바일 겹침 2건, 설정 스크롤 스파이, 온보딩 전화번호 무검증, 리뷰 조사·난도 라벨, pending 피드백 등. - 소유자 결정 구현: 설정 아바타 변경, 동의 철회·재동의 전체 흐름, 신규 학습자 기초 우선 추천, 학생 분석 테이블 가상화(@tanstack/react-virtual), 저작 모드 죽은 레일 정리, 감정 밸런스 타임라인 차트(deep turn_valence + 결정론 파생 폴백). - 디자인 감사(142차): 라이트 팔레트 AA 대비, 다크 토큰 별칭 통일, 미정의 CSS 변수 정리, 한글 keep-all 전역화, 탭 타깃 24px, LCP preconnect. - 검증: npm run e2e 병렬 432 수집 GREEN + 직렬 49/49 exit 0, 백엔드 pytest 421, gateway 29, typecheck/build/design-ssot/dead-code/중복 게이트 통과, layout-visual-gate 15/15, session-layout 8/8. 상세는 SSOT 대시보드 142~144차 노트.
This commit is contained in:
parent
0ae94499f2
commit
4511383cd9
55 changed files with 9333 additions and 573 deletions
|
|
@ -565,6 +565,10 @@
|
|||
<p class="dg-note">128차 적용(2026-07-03): 127차 후속 후보였던 live coach LLM audit 실패 은폐를 닫았다. <code>record_llm_call_audit()</code>가 DB pool 또는 <code>audit.llm_call_log</code> insert 실패로 <code>False</code>를 반환해도 기존에는 <code>generate_live_coaching()</code>이 이를 무시해 정상 <code>status=ready</code> AI 코칭처럼 보일 수 있었다. 이제 live coach는 audit hook의 <code>False</code> 또는 예외를 감사 저장 미확인으로 보고, LLM structured 응답을 버린 뒤 규칙 기반 <code>status=degraded</code> 코칭으로 내려간다. 상담 루프는 막지 않되 사용자에게 정상 AI 코칭처럼 보이지 않게 하는 조치다. 검증: <code>C:\Users\encep\AppData\Local\Programs\Python\Python311\python.exe -X utf8 -m py_compile apps/api/app/services/live_coach.py apps/api/app/test_session_turn_persistence.py</code>, <code>C:\Users\encep\AppData\Local\Programs\Python\Python311\python.exe -X utf8 -m pytest -p no:cacheprovider apps/api/app/test_session_turn_persistence.py -k "live_coach" -q</code> 7 passed. 로컬 작업트리 기준이며 배포 전이다.</p>
|
||||
<p class="dg-note">129차 적용(2026-07-13): 재부팅 뒤 Chrome이 기존 <code>/admin</code> 탭의 문서 스크롤을 복원하면서 sticky topbar/sidebar만 남고 관리자 본문은 화면 위로 밀리던 silent blank를 재현·수정했다. RED 재현은 길이 2200px 문서에서 <code>scrollY=900</code>을 만든 뒤 persisted <code>pageshow</code>를 보내 수정 전 <code>scrollY=1300</code>과 빈 main을 확인했다. <code>App.tsx</code>는 <code>history.scrollRestoration=manual</code>, <code>pageshow</code> reset, pathname layout-effect와 다음 frame reset을 함께 적용한다. 로컬 focused E2E는 desktop/mobile route 이동·복원 탭 4 passed, typecheck/build passed. Cloudflare Pages production <code>0daabb1b</code> 배포 뒤 custom domain은 <code>assets/index-BhyOF3rL.js</code>를 서빙하며, 15분 일회성 관리자 세션으로 운영 홈·사용자·권한·티켓과 복원 탭을 공개 사이트에서 확인한 <code>public-admin-visual</code> 3 passed 후 세션을 즉시 삭제했다. 이후 concurrent avatar 변경이 섞인 배포는 Cloudflare Pages rollback API로 <code>0daabb1b</code>에 되돌렸다.</p>
|
||||
<p class="dg-note">130차 적용(2026-07-13): 운영 <code>/voice/health</code>는 OpenAI 설정을 정상으로 보고했고 실제 운영 키 직접 smoke도 98,133-byte/11.68초 MP3를 반환했지만, 운영 로그에는 사용자의 voice WebSocket 연결이 없어 텍스트 턴 AI 응답이 TTS 경로에 연결되지 않은 공백으로 좁혔다. 인증된 <code>POST /voice/speech</code>는 <code>session_id</code>/<code>turn_seq</code>로 소유 회기와 이미 저장된 client-visible 내담자 응답을 다시 검증한 뒤 기존 voice map/OpenAI TTS로 MP3를 반환한다. Session은 텍스트 전송 user gesture에서 AudioContext를 먼저 unlock하고, 합성 Blob을 기존 Web Audio/Analyser 재생기로 보내며 새 턴이 시작되면 이전 요청을 무효화한다. 검증: backend voice 32 passed, API types check, web typecheck, <code>voice-success</code> text TTS+별도 mic 회기 UI focused 1 passed.</p>
|
||||
<p class="dg-note">144차 적용(2026-07-27): 143차 전수 순회에서 소유자 결정 대기로 남긴 7건을 <b>질문 도구로 전건 결정받아 6건 구현 완료</b>(RED→GREEN, 5개 병렬 구현 에이전트). ① <b>설정 아바타 변경</b> — 계정 섹션에 온보딩과 같은 계약(3MB·PNG/JPEG/WebP)의 업로드 컨트롤+미리보기, PATCH /users/me avatar_url 저장 후 refresh로 톱바·레일까지 갱신. ② <b>동의 관리·철회 전체 흐름</b> — 새 <code>#set-consent</code> 섹션(실습 동의 시각·약관/개인정보 버전 표시), learner 철회 버튼(2단계 확인)→차단 안내→"다시 동의" 재동의, 세션 프리스타트의 기존 동의 게이트와 연결(철회 함정 상태 해소, dead code였던 <code>withdrawConsent</code> 실사용화), e2e는 고유 계정으로만 철회 수행. ③ <b>신규 학습자 기초 우선 추천</b> — 회기 0건 학습자의 기본 선택·첫 회기 준비 카드를 난도 오름차순 첫 페르소나로(<code>starterPersona()</code>), 기록 보유·조회 실패 시 기존 규칙 유지. ④ <b>학생 분석 테이블 가상화</b> — <code>@tanstack/react-virtual</code>(신규 의존성) 세로 가상화, 동적 행 높이 measureElement·펼침 재측정, 300행 fixture에서 렌더 행 <60 검증, 데드스페이스 없게 max-height는 내용 이하로. ⑤ <b>저작 모드 좌측 레일 마크업 정리</b> — 어떤 경로에서도 보이지 않던 죽은 DOM(ps-rail)과 전용 CSS 삭제, 특성화 테스트 toHaveCount(0) 강화. ⑥ <b>감정 밸런스 타임라인 차트 구현</b>(143차 미구현 항목) — 혼합 접근: deep 평가 스키마에 <code>turn_valence</code>(seq·v −1~+1, 극단값 회피 지시) 신설 + 저장 데이터 결정론 파생 폴백(counselorBaseline=학습자 턴 rapport_signal 누적 이동평균, clientValence=deep 값 우선/client_state 극성+appropriateness 결합 폴백), 2점 미만 빈 배열·10점 초과 균등 리샘플·축 라벨 4개, hidden_turns 시 비산출로 프라이버시 계약 유지. dev-login 재승인은 현행 유지로 종결. <b>검증</b>: 각 과제 RED 관측→GREEN(에이전트별 증거 로그), 백엔드 pytest <code>421 passed</code>(신규 <code>test_review_valence.py</code> 9 포함), gateway 29, typecheck/build/design-ssot/dead-code/duplication(0.03%) 통과, focused 무회귀 44/42/40/20/14, professor·persona 레이아웃 게이트 통과, 감정 차트는 실DB 공감 5턴 세션에서 baseline·client 각 5포인트/축 4라벨 라이브 실측. 전 스위트 재완주 수치는 체크리스트 문서 §0에 기록. 부수 관찰: <code>smoke-resistance-openness-db.py</code>의 advice_jump turn_client_state ≥5 단언이 엔진 변동성에 민감(결함 로그 #23, 코드 회귀 아님). 체크리스트 415항목 미체크 0 도달. 로컬 작업트리 기준이며 배포 전이다.</p>
|
||||
<p class="dg-note">144차 적용(2026-07-27): <b>브레이크포인트 경계 전수 스윕</b>. 142차 접근성 감사가 1440·390 두 폭만 봤고 기존 <code>layout-visual-gate</code>도 7개 폭(390/720/861/900/1024/1280/1440)만 검사한다는 소유자 지적에서 출발했다. CSS 전체에서 고유 width 브레이크포인트 <b>25개</b>(340~1420)를 추출해 파일→페이지로 매핑하고, 페이지마다 자기에게 영향을 주는 브레이크포인트의 <b>B-1 / B / B+1</b> 과 실기기 대표 폭을 조합해(페이지당 17~36폭 × 높이 2종) 순회하며 <b>요소 겹침 · 텍스트 잘림 · 폭 붕괴 · 화면 밖 이탈 · 문서 오버플로</b>를 계산으로 검출했다. 1차 스윕에서 <b>156개 문제 뷰포트 / 11종 결함</b>이 나왔다. <b>수정한 결함</b>: ① <b>설정 서브네비 라벨 전면 소멸</b>(721~1080px 전 구간) — 공용 <code>@media (max-width:1080px)</code>의 <code>.vg-set__rail{display:grid; grid-template-columns:minmax(220px,280px) minmax(0,1fr)}</code>가 <code>body[data-page="settings"]</code>까지 덮어써 244px 레일 안이 다시 2열로 쪼개졌고 둘째 트랙이 0px로 붕괴, nav 폭 0 · nav-item 28px · 라벨 span 7개(계정/AI 운영/지원 요청/동의/테마/알림/음성) 폭 0이 됐다. 721~980px 는 별개로 <code>.vg-set__nav-item span{display:none}</code>이 라벨을 통째로 숨기고 있었다. 721~1080px 를 상단 가로 탭으로 통일해 라벨을 항상 노출한다. ② <b>세션 프리스타트 목표 fieldset 겹침</b>(전 폭 72뷰포트) — <code>.sx-prestart__note</code>의 <code>margin-top:-12px</code> 음수 마진이 앞 형제 <code>fieldset.sx-goals</code> 마지막 줄을 88x12px 파고들었다. ③ <b>프리스타트 dd·desc 세로 잘림</b> — <code>-webkit-line-clamp:2</code>가 좁은 폭에서 문장을 잘라먹던 것을 해제하고, 데스크톱 한 화면 제약은 <code>max-height + overflow-y:auto</code>로 대체. ④ <b>프리스타트 우측 "진행 초점" 패널 195px 잘림</b>(1041~1240px, 200개 폭) — 3열 <code>minmax(220px,…) minmax(360px,…) minmax(260px,…)</code>는 최소 888px를 요구하는데 이 구간의 실제 컨테이너는 735~886px뿐이라 트랙이 축소되지 못하고 우측 패널이 통째로 잘렸다. <code>overflow-x:hidden</code>이라 스크롤도 안 되고 <b>문서 오버플로는 0</b>이라 기존 "contained" 게이트가 구조적으로 못 잡던 유형이다. 트랙 최소치를 0으로 낮추고 2열 전환점을 1040→1260px로 올려 이중 안전망을 뒀다. ⑤ <b>티켓 필터 "초기화" 버튼 화면 밖 이탈</b>(1180~1257px) — 7트랙 grid가 최소 954px를 요구하는데 셸 사이드바를 뺀 컨테이너가 876~950px라 마지막 트랙이 밀려났다. 4트랙 2줄로 낮추고 유연 트랙 최소치를 0으로. ⑥ <b>페르소나 이름 세로 잘림</b>(320px) — 이름 칸이 150.6px뿐이라 3줄이 필요한데 <code>line-clamp:2</code>에 걸려 3번째 줄이 사라졌다. ≤420px 밴드에서 3줄 허용. <b>오탐으로 판정해 고치지 않은 것</b>: <code>.aic-ledger b</code>·<code>.lh-metric-card b</code>의 2px 세로 초과는 <code>line-height</code>가 Pretendard content-area(ascent+descent≈1.09em)보다 작아 생기는 폰트메트릭 아티팩트다. overflow hidden/visible 6x DPR 캡처를 20개 폭에서 바이트 비교해 <code>pixelDiff=0</code>(잘린 픽셀 0)을 확인했고, 1180/1280px에서는 같은 렌더링인데 반올림 방향만 바뀌어 탐지에서 빠지는 것도 증거다. <code>.vg-set__voice-info .vd</code>(의도된 <code>line-clamp:2</code>)와 <code>.vg-set__skel-sr</code>(visually-hidden), <code>.vg-avatar__stage</code>(<code>border-radius:50%</code> 원형 마스크)도 오탐이다. <b>2차 스윕</b>으로 1차가 못 본 사각지대(높이 브레이크포인트 620/820 경계, 탭 전환 등 인터랙션 후 상태, 와이드 폭 1600~2560, 초협소 320)를 14개 라우트에서 추가 순회했고 <b>새 결함 0</b>. <b>결과</b>: 진짜 결함 0(잔여 66뷰포트는 위 오탐 3종). <b>검증</b>: typecheck · check:design-ssot 통과, session.css raw color 216/216 유지, <code>layout-visual-gate</code> 15/15, session-layout+session-mvp+learner+settings <b>56/56</b>, 앞선 병렬 수리 검증에서 session-layout+settings+admin <b>55/55</b>. <b>미결(소유자 결정)</b>: 프리스타트에서 호소·대상 정보가 <code>.sx-prestart__case</code>(좌측 아바타 카드)와 <code>.sx-prestart__facts</code>(본문)에 <b>중복 렌더</b>된다(3열·2열 양쪽 모두, 이번 변경과 무관한 기존 IA 문제). 로컬 작업트리 기준이며 배포 전이다.</p>
|
||||
<p class="dg-note">143차 적용(2026-07-27): 전 페이지·버튼 단위 <b>전수 E2E 순회 캠페인</b>. IA 전 라우트(로그인/온보딩/승인대기/학습자 3뷰·세션·리뷰/교수자 콘솔·분석·페르소나/관리자 5섹션/설정/아바타 랩)의 기능 412개를 소스 기준 인벤토리로 만들어 <code>docs/ops/e2e-full-sweep-2026-07-27.md</code> 체크리스트 백로그(- [ ]/- [x])로 관리하고, RED→GREEN으로 결함을 수정했다. 신규 스펙 10파일 <code>e2e/full-sweep-*.spec.ts</code>(수집 424의 절반가량)를 추가했고, 소유자 결정 대기 항목은 test.fixme + 백로그 B3-신규 6건으로 분리했다. <b>수정한 결함(RED 재현→GREEN)</b>: ① <code>/admin/ai</code> 부트 watchdog 오탐 오버레이(index.html 셀렉터에 <code>.aic</code> 추가), ② 한국어 PII 마스킹이 "유의점은·방치되는·마무리했을" 같은 일반 단어를 <code>[NAME]</code>으로 치환해 평가 문장을 훼손하던 과잉 마스킹(guardrail 꼬리 글자 가드), ③ 온보딩 연락처 무검증(서버 pydantic 검증+클라이언트 안내), ④ 리뷰 요약 조사 오류("하늘와의"→받침 인식 와/과)와 난도 원문 노출(easy→기초), ⑤ /pending 새로고침 무피드백+아이콘 오용(refresh 아이콘 신설), ⑥ 학습 대시보드 탭 패널 aria-label 고정, ⑦ 회기 종료 다이얼로그 반말 문체, ⑧ 설정 스크롤 스파이 마지막 섹션 미활성(0 임계값+밴드 최하단 규칙+바닥 폴백), ⑨ 모바일 세션 겹침 2건(타임바 <code>:has</code> 4행 템플릿, 코치 넛지 플로우 배치), ⑩ <b>관리자 콘솔 무한 렌더 루프 프리즈</b>(TanStack <code>autoResetPageIndex</code>↔setState — users/services 메모화+<code>autoResetPageIndex:false</code>, 결정적 재현 스펙 2건을 회귀 가드로 유지), ⑪ <b>복수 코호트 조용한 유실</b>(POST/PATCH <code>/admin/users</code>가 cohort_ids 첫 항목만 저장 → 콤마 직렬화+알림 SQL 배열 겹침 비교), ⑫ <b>공개 페르소나 보관 전면 불능</b>(DELETE <code>/personas/{id}</code>가 실DB에서 항상 503 — <code>archive_persona_family</code> UPDATE…FROM RETURNING의 무한정 <code>code</code> 모호성 → card. 한정, 실API RED 503→GREEN archived 실측). 마무리 탐색 순회(실브라우저 6에이전트, 68항목)는 67 GREEN·감정 밸런스 차트 데이터 소스 미구현(서버가 항상 빈 배열 — 사문 렌더 경로, 로드맵 기록) 1건을 추가로 확인. <b>검증</b>: 백엔드 pytest <code>412 passed</code>(신규 회귀 테스트 8개 포함), gateway 29 passed, typecheck/build/check:api-types/design-ssot/dead-code/duplication(0.03%) 통과, layout-visual-gate 15/15, session-layout 8/8, 최종 <code>npm run e2e</code> 재완주 — 병렬 424 수집 그린(fixme 4·모바일 의도 숨김 2 스킵), 직렬 <code>49/49 passed</code>(14.4m), exit 0. 열린 항목: B3-신규 6건(설정 아바타 변경/동의 철회·재동의 흐름/첫 추천 난도/분석 페이지네이션/저작 레일 잔존 마크업/dev-login 재승인 정책), 공개 OAuth 스모크는 기존 B2 유지. 로컬 작업트리 기준이며 배포 전이다.</p>
|
||||
<p class="dg-note">142차 적용(2026-07-27): <code>design-taste-frontend</code> 스킬의 보편 규칙(§4.5 대비 검사, §6.B/6.C 모션·다크모드, §9.F/9.G AI tell)을 기준으로 <b>전 20개 라우트를 3역할·라이트/다크·데스크톱/모바일 54개 조합</b>으로 순회 감사하고 결함을 수정했다. 감사는 눈대중이 아니라 페이지마다 WCAG 대비비를 계산하는 Playwright 스크립트로 측정했다. <b>(A) 라이트 팔레트 AA 미달</b> — <code>--ink-3</code>(캡션·메타)가 모든 라이트 표면에서 2.7~3.1:1, <code>--neutral-400</code>(placeholder)이 2.4:1이었다. 색조를 유지한 채 <code>#6a6c65</code>/<code>#6f6e68</code>로 낮추고 위계 유지를 위해 <code>--ink-2</code>도 <code>#4d514b</code>로 조정했다(강도 13.9 · 본문 6.9 · 캡션 4.6:1). 다크는 <code>--ink-3</code> <code>#979a8f</code>, <code>--neutral-400</code> <code>#949b8f</code>. <b>(B) 다크 토큰 이중 진실원본</b> — 다크 블록이 <code>--text-muted</code> 등을 <code>var(--ink-3)</code> 별칭 대신 값으로 하드코딩해 primitive 수정이 다크에 반영되지 않았다. 라이트와 동일하게 별칭으로 통일했다. <b>(C) 채움색을 글자색으로 전용</b> — <code>--accent</code>는 채움 기준값이라 어두운 표면 위 본문 크기에서 4.3:1이다. <code>--text-accent</code>(= <code>--accent-deep</code>) 별칭을 신설해 kicker·secondary 버튼·역할 라벨 등 텍스트 용도를 옮겼다. <b>(D) 로그인 안내 배너 1.19:1</b> — <code>.lg-config</code>가 다크 패널 전제(반투명 갈색 + 밝은 앰버)라 라이트에서 사실상 읽을 수 없었다. 테마별로 스왑되는 warn 의미 토큰으로 교체(5.3:1). <b>(E) 미정의 CSS 변수 12종</b> — <code>--text-dim</code>·<code>--good-solid</code>·<code>--border-faint</code>·<code>--fs-xl</code> 등이 정의 없이 참조돼 색/배경이 조용히 무효화되고 있었고, <code>learner-home</code>의 <code>--bg-inset</code>/<code>--border-soft</code> 폴백은 다크 전제 값이 라이트 페이지에 적용되고 있었다. 전부 기존 의미 토큰으로 매핑했다. <b>(F) 학습자 분석 테이블 컬럼 침범</b> — <code>.pf-learner-row__id</code>의 암시적 그리드 트랙이 자식의 <code>width:max-content</code>를 수용해 261px 셀이 288px로 늘어나 <code>max-width:100%</code>가 무력화됐고, 긴 이름 28행이 옆 컬럼을 27px 침범했다. <code>minmax(0,1fr)</code>로 고정해 0건. <b>(G) 한글 조판</b> — <code>word-break</code> 기본값 때문에 "오전"이 "오/전", "검토 대기"가 "검/토 대기"로 쪼개졌다(5건). 세션 화면이 쓰던 <code>keep-all</code> + <code>overflow-wrap:break-word</code>를 전역으로 올려 0건. <b>(H) 탭 타깃</b> — WCAG 2.2 SC 2.5.8(24px) 기준으로 약관 동의 라벨 19px→28px, 학습자 이름 버튼 19px→25px, 설정 range 슬라이더 16px→24px(투명 테두리 + <code>background-clip:content-box</code>로 시각 크기는 유지). <b>(I) LCP</b> — 렌더 블로킹 CDN 폰트에 <code>preconnect</code>/<code>dns-prefetch</code> 추가(Pretendard self-host는 별도 과제). <b>결과</b>: 54개 조합 전부 대비 위반 0 · 탭 타깃 위반 0 · 라벨/alt 누락 0 · 가로 오버플로 0(감사 전: 대비 2,043건, 탭 타깃 355건). <b>검증</b>: <code>npm run typecheck</code>, <code>check:design-ssot</code> 통과, <code>layout-visual-gate</code> 15/15, <code>session-layout</code> 8/8, auth-visual·teacher·admin·session-review·settings·learner 포함 E2E 87 passed + 14 passed. <b>미결(소유자 결정 필요)</b>: kicker의 accent dot이 기본 <code>true</code>라 회기 화면 한 곳에 11개 이상 찍히는 점(§9.F는 장식 dot 0을 요구, 다만 DESIGN_CONCEPT가 명시한 강조 장치라 임의 변경하지 않음), 영문 대문자 eyebrow(<code>SPEND CONTROL</code>·<code>RUNTIME ROUTE</code>·<code>DAILY JOURNAL</code>·<code>SESSION</code>·<code>SUPERVISOR</code>)의 한글화, 섹션당 eyebrow 밀도(§4.7은 섹션 3개당 1개), 중점(·) 라인당 다중 사용(<code>/teach</code> 33행), <code>prefers-color-scheme</code> 무시하고 다크 고정인 기본 테마(§8.C), 관리자 AI 비용 표시 정밀도(<code>$37.6560</code>·<code>$0.102885</code>). 로컬 작업트리 기준이며 배포 전이다.</p>
|
||||
<p class="dg-note">141차 적용(2026-07-15): 공통 <code>Surface inset</code>는 중첩 카드처럼 보이던 border와 radius를 제거하고 반투명 광원·blur만 유지한다. 관리자 사용자 목록은 사용자별 <code>article</code> grid와 겹치던 <code>ad-user__meta</code>를 제거하고 <code>@tanstack/react-table</code> 기반 semantic table로 전환했다. 사용자/역할/관리 권한/승인 상태/소속/코호트/활성 회기/최근 접속/작업 열을 고정하고, 헤더 클릭 정렬과 sticky header, 1440px 최소 폭을 제공한다. 좁은 화면에서는 문서가 넓어지지 않고 표 region만 가로 스크롤된다. <b>검증</b>: typecheck, 관리자 사용자 생성·승인·편집·비활성화 및 모바일 스크롤 focused E2E 4/4, layout visual gate 15/15. 로컬 작업트리 기준이며 배포 전이다.</p>
|
||||
<p class="dg-note">136차 적용(2026-07-15): 135차의 학습 대시보드 한정 보태니컬 스타일을 전 페이지 공통 디자인 시스템으로 승격했다. <code>AppShell</code>은 역할·라우트와 무관하게 단일 <code>vg-shell--botanical</code> 크롬을 사용하며, 과거 관리자·교수자·대시보드 전용 톱바/GNB override를 삭제했다. GNB는 라이트/다크 고해상도 투명 원본(846×1858, 922×1706)을 사용하고 이미지 시작점을 메뉴 아래로 내려 텍스트 침범을 막는다. 데스크톱 GNB는 shell body 안에서 <code>top:0</code>, 모바일 drawer에서만 <code>top:var(--topbar-h)</code>를 사용해 상단 빈 공간을 없앴다. 공통 캔버스는 우상단 보태니컬 배경과 같은 이미지를 180° 회전한 좌하단 배경을 함께 사용하며, main은 투명하게 둔다. 표면은 셸 SSOT에서 큰 패널용 glass와 내부 행·필드·요약용 inset glass 두 단계로 통합해 학습자·교수자·관리자·설정·페르소나·회기 리뷰·진행 세션의 모바일 재배치까지 같은 반투명 그라데이션, 저채도 황금 hairline, blur/saturation을 사용한다. 로그인·온보딩·승인대기도 같은 글래스 패널을 쓴다. 라이트 테마는 흰 카드와 흰 캔버스가 겹쳐 유리 효과가 사라지던 토큰을 수정해, 반투명 본체+스페큘러 광원 2층, 안쪽 굴절선, 샴페인 hairline과 세이지/골드 캔버스 광원을 사용한다. 모바일에서도 보태니컬 캔버스를 제거하지 않는다. 학습 대시보드의 <code>오늘의 회기</code>/<code>기록 · 리뷰</code>/<code>성장 지표</code> 탭과 회기 리뷰의 <code>축어록</code>/<code>피드백</code>/<code>워크시트</code> 탭은 모든 폭에서 유지한다. Live2D 주변의 이중 외곽 컨테이너는 제거하고 투명 clipping 영역에서 캐릭터·잎 장식만 우하단으로 잘리게 했다. <code>object-separate --check</code>로 로컬 GPU 분리 런타임을 확인했고, 제공 원본이 정상 RGBA alpha(0–255)라 재분리 없이 원본을 사용했다. <b>검증</b>: <code>npm run typecheck</code>, <code>npm run build</code>, layout-visual-gate <code>15/15</code>, learner/session-layout/session-review desktop+mobile <code>46/46</code>, 라이트·다크·관리자·교수자·설정·리뷰·진행 세션 1440px 및 390px 스크린샷 직접 확인. 로컬 작업트리 기준이며 배포 전이다.</p>
|
||||
<p class="dg-note">135차 적용(2026-07-15): 제공된 <code>Vignette-Asset-Set</code>의 512px 최적화 PNG 14종을 <code>public/design-elements/learner-dashboard/</code>로 자산화하고 학습 대시보드(<code>/learn</code>)에만 보태니컬 시안을 적용했다. 라이트/다크 각각의 사이드바·우상단 배경과 메트릭 카드 4종·AI 코치 장식을 테마별로 교체하며, 카드 표면은 크림/차콜의 비대칭 광원 그라데이션과 저채도 황금 헤어라인을 사용한다. 이 범위 제한은 136차에서 전 페이지 공통 글래스 시스템으로 대체됐다. <code>layout-visual-gate</code>는 라이트 테마 자산 연결까지 computed style로 확인하고 테마를 다크로 복귀한다. <b>검증</b>: <code>npm run typecheck</code>, <code>npm run build</code>, layout-visual-gate <code>12/12</code>, session-layout <code>8/8</code>, learner desktop/mobile <code>14/14</code>, 라이트·다크 1440px 및 다크 390px 스크린샷 직접 확인. 로컬 작업트리 기준이며 배포 전이다.</p>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue