feat(release): prepare 1.1.0 candidate

This commit is contained in:
Yun Chan 2026-08-29 18:33:45 +09:00
parent 5a34f66981
commit 5205dcdfa9
736 changed files with 115667 additions and 12203 deletions

152
design.md Normal file
View file

@ -0,0 +1,152 @@
# design.md — D3RO Voice 크로스플랫폼 디자인 결정 기록
> 2026-08-22 전면 타이포그래피 개편 ("타이포그래피 퍼스트 v3").
> 다음 실행(사람이든 에이전트든)은 이 파일을 읽고 같은 결정을 이어간다.
## 브리프 3줄
- 무엇을: 로컬 AI 음성 어시스턴트의 6개 표면(데스크톱 Electron / 관리자 / 웹앱 /
마케팅 사이트 / React Native 모바일 / 공유 DS 패키지)의 통합 타이포그래피·폰트 개편.
- 누구에게: 한국어 기본 사용자(개발자·지식노동자). 도구는 하루 종일 켜져 있다.
- 제약: 기존 스택 유지(MUI 7 / Tailwind 3 / RN StyleSheet), 기능 파괴 금지,
성능 예산(히어로까지 JS 150KB gzip, 이번 개편은 폰트 로드 정리로 감소).
## 컨셉 한 문장 · 프리셋 · 리스크
- 한 문장: **볼드를 버리고 크기·행간·명도로 위계를 만드는 한국형 스위스 미니멀**
"정밀 계기판의 고요한 밤"에서 "조용히 읽히는 정밀 도구"로.
- 프리셋: swiss-minimal(그리드와 침묵) × dark-instrument(계기판의 정확함).
- 감수한 리스크 하나: 헤드라인 최대 웨이트를 500으로 내린 것. 라틴 마케팅 관례
(700-800 디스플레이)를 버리는 선택이지만, 한글 낱글자의 시각 밀도에서는
500+큰 크기+타이트 트래킹이 더 고급스럽다 (Apple 한국어 페이지가 같은 길).
## 한글 폰트 결정 (리서치 기반)
- **웹/데스크톱: Pretendard Variable 단일 패밀리.**
근거: Inter 기반 네오그로테스크로 한/영 조화(혼용 시 별도 조정 불필요),
크로스플랫폼 웨이트 일관성, 9단계+가변 폰트, 사실상 한국 UI 표준.
SUIT(본문 특화)·Paperlogy(마케팅 특화)를 검토했으나 교체 이득 < 전환 비용.
- **로딩 방식: 다이나믹 서브셋 + woff2 + preload(preconnect)** — 2025-26 표준.
화면에 쓰인 글리프만 분할 로드한다. 기존 정적 pretendard.css 전체 로드를 폐기.
- **모바일(RN): 시스템 폰트 스택.** bare RN이라 커스텀 한글 폰트 번들링(2MB+ ttf,
네이티브 재빌드) 대신 iOS=SF Pro→Apple SD Gothic Neo, Android=Roboto→Noto Sans KR
자동 폴백. Apple HIG/Material 권장 표준. **Menlo/monospace 전면 폐기**
Menlo에 한글 글리프가 없어 한/영 혼용 입력이 뒤섞이는 버그였음.
- **site: Plus Jakarta Sans 제거.** 한+영 혼용 헤드라인에서 라틴/한글 스트로크
불일치. Pretendard가 Inter 기반이므로 라틴도 Pretendard로 통일(로딩 1종 감소).
## 타이포그래피 원칙 (W3C klreq / 요즘IT DS / KRDS 종합)
1. **볼드 금지(700/800/900 → 0회)**. 최대 600(의미 강조 `strong` 전용),
헤드라인 500, 몸통 400, 라벨 500. 위계는 크기·행간·명도(text token)로.
2. 한글 행간 1.5~1.7 (body 1.6), 헤드라인도 1.2 이상. 블록 글자의 숨 쉬는 공간.
3. 자간 0 근처. 음수는 대형 헤드라인만 -0.01~-0.02em. 양수(+0.02~0.04em)는
라틴 대문자 라벨에만. 한글에 양수 트래킹 금지.
4. **한글 최소 크기 11px**. 8-9px 토큰(engrave/micro/nano)은 상향
(engrave/micro 10px, nano 9px — 라틴 전용 텔레메트리).
5. 폰트 1패밀리 + 웨이트 3종(400/500/600). mono는 텔레메트리·코드·숫자에만.
## 토큰 변경 (SSOT: packages/ui/src/theme.ts `d3roTypo` v3)
| 토큰 | v2 (구) | v3 (신) |
|---|---|---|
| hero | 32px/700/-0.5px/1.2 | 32px/500/-0.02em/1.3 |
| title | 24px/700/-0.3px/1.25 | 24px/500/-0.01em/1.35 |
| value | 20px/600/0/1.1 | 20px/500/0/1.2 |
| heading | 16px/600/0/1.4 | 16px/500/0/1.5 |
| body | 14px/400/0/1.55 | 14px/400/0/1.6 |
| label | 11px/600/0.08em/1.2 | 11px/500/0.04em/1.3 |
| engrave | 9px/700/1px | 10px/500/0.06em/1.2 |
| nano | 8px/700/0.5px | 9px/500/0.03em/1.15 |
- MUI 기본값 동반 변경: h4/h5 700→500, h6/button/caption 600→500,
body1 1.5→1.6, Chip/Tab/ListItemButton 600→500.
- `d3roFontSans`에 한글 폴백 추가: Apple SD Gothic Neo, Noto Sans KR, Malgun Gothic.
- RN 대응(`packages/ui-native/theme.ts` `d3roNativeTypo`) 동일 철학으로 동기화.
label 10px/700/ls2 → 11px/500/ls0.4.
- site(Tailwind) type scale: hero lh 1.14→1.22, ls -0.035em→-0.02em 등 한글 보정.
## 표면별 변경 요약
| 표면 | 변경 |
|---|---|
| packages/ui (SSOT) | d3roTypo v3, MUI 오버라이드 탈볼드, 한글 폰트 스택 |
| packages/ui-native | 타이포 v3, sans 스택, PhosphorText 텍스트 글로우 제거, PhysicalButton uppercase·과도 트래킹 제거, StatusBar 8px→10px |
| apps/desktop | **보더리스**: Win/Linux `frame:false` + 커스텀 TitleBar, macOS `titleBarStyle:'hiddenInset'` + 네이티브 교통신호(커스텀 컨트롤 숨김, 78px 여백). 기존 `frame:true`+커스텀 타이틀바 이중 크롬 버그 해소. 인라인 700×95/800×10/900×2 → 500/600, 팝업 CSS 동일 |
| apps/admin | Pretendard 이중 로드(link+@import)→다이나믹 서브셋 단일, 미사용 JetBrains Mono 로드 제거, 700×84→500/800×2→600, 프리셋(table/filter/badge/button) 600→500, `strong`→600 CSS |
| apps/web | **Pretendard 다이나믹 서브셋 로드 추가**(기존 폰트 0로딩→OS 폴백 렌더 버그 수정), login 하드코딩 스택 교체, 700×24/800×13/900×2 스윕 |
| site | font-bold 13/semibold 37 → medium, Plus Jakarta 제거, 한글 type scale 보정, `strong` 600 |
| apps/mobile-rn | Menlo/monospace 전면 제거(입력창 18곳), TabBar 인셋 기반(52+insets.bottom)+라벨 9px mono→11px sans, LoginScreen 세이프에어리어 추가, 스택 화면 8곳 하단 인셋 Math.max(insets.bottom,24), letterSpacing 디-모노화, 700×3→500 |
## 표준 준수 노트
- **모바일 세이프에어리어**: 모든 화면 `useSafeAreaInsets` 기반. 탭 화면은 탭 바가
인셋을 담당, 스택 화면은 화면이 담당. 고정 padding(60/120) 잔여 없음.
- **iOS/macOS**: 데스크톱 macOS는 hiddenInset(교통신호 유지 — HIG 준수).
모바일 iOS는 시스템 폰트+자동 폴백. KeyboardAvoidingView 플랫폼 분기 유지.
- **웹**: `font-display: swap` + preconnect. 웹뷰 폰트 이중 로드 제거.
## 성능 예산과 실측
- 폰트: admin 2회 로드→1회, site 2패밀리→1패밀리+mono, web 0→1(다이나믹 서브셋).
- site 빌드 실측: 360.53KB JS(gzip 111.04KB), CSS 40.37KB(gzip 7.81KB) — 예산 내.
- 애니메이션 정책 변화 없음(transform/opacity만, 기존 유지).
## 의도적으로 하지 않은 것
- **관리자 상태값 라벨은 대문자 유지.** ACTIVE/DISABLED/PRO+ VIP/POST/PATCH 등은
코드 비교·API 값이라 문장형 변환 금지. 대신 페이지 부제(• 구분 설명문)와
사이드바 그룹 라벨·대시보드 카드 라벨은 문장형으로 전환했다(2026-08-22).
- **site의 CRT/crosshair CSS는 유지.** 감사에서 '레거시'로 분류했으나 실사용
확인(HowItWorks·Privacy·Crosshair) — 제거하지 않는다.
## 2026-08-22 추가 완료 (2차: 브랜드 통일 + 오프시스템 정리)
- **브랜드 색 통일 — amber → blue 완료.** site(brand-amber 134곳→brand-blue,
favicon/download.html/LED 시맨틱 포함), mobile-rn(다크 #3b82f6/pressed #2563eb/
onAccent 흰색 반전, 라이트 #2563eb), ui-native 레거시(#3b82f6).
근거: 데스크톱·웹·관리자 + 6개 테마가 이미 blue(Midnight Glass)인데 site/모바일만
구 CRT amber 시대 잔재였다. 이제 전 표면 단일 액센트.
- **apps/web 오프시스템 색 전면 토큰화.** download(잔여 hex 0), login(잔여 0),
chat-panel/mic-recorder/commands/billing/history/sidebar의 구 amber #ff5c35
37곳 + zinc 표면 90여 곳 → d3roPalette/--d3-* var로 교체. 6테마 연동.
download·login은 이제 테마 반응형. on-accent 대비 보정(챗 전송 버튼 hover
흰색). `--d3-tag-*` CSS 변수를 SSOT buildCssVars에 추가(color-mix 틴트 파생용).
- **관리자 라벨 문장형 전환.** 페이지 부제 10곳(• 나열 → 쉼표 문장형, 약어
STT/LLM/SLA/RAG/VIP 보존), 사이드바 그룹·대시보드 카드 라벨 CSS uppercase 제거
(원본 문자열은 이미 문장형). 죽은 "Service Telemetry NOT CONNECTED" 패널 제거.
- **관리자 globals.css :root 죽은 변수 제거.** SSOT와 이름이 충돌하는 19개 로컬
변수(소비자 0) 삭제, body는 --d3-bg-app/--d3-text-primary으로 직결.
- **모바일 커스텀 한글 폰트 번들링 — 최종 결정: 하지 않음(확정).** Apple HIG와
Material 가이드가 모두 시스템 폰트를 권장하고, iOS Apple SD Gothic Neo /
Android Noto Sans KR 폴백 품질이 이미 우수하며, 정적 ttf 번들(2웨이트 약
5-10MB)은 다이나믹 서브셋이 없는 RN에서 비용 대비 효과가 낮다. 이 항목은
미확정이 아니라 확정된 결정이다.
## 다음 실행을 위한 지침
- 새 텍스트는 `d3roTypo`/`d3roNativeTypo` 토큰 또는 MUI 기본값만 쓴다.
인라인 `fontWeight`는 금지(예외: 조건부 400↔500 전환).
- 한글 문자열에 `letterSpacing` 양수 값을 직접 넣지 않는다.
- 11px 미만 텍스트를 추가하지 않는다 (라틴 텔레메트리 예외 하한 9px).
## 2026-08-24 광고 수익화 E2E RED 스위트 (652 시나리오)
- 위치: `apps/desktop/tests/red/ads/` (ads-mediation 370 / admob-ssv 142 / ad-settlement 140)
- 계열: A 입찰 거버넌스 110 · B 크리에이티브 안전성 80 · C 노출·클릭 추적 70 ·
D 리워드 60 · E SSV 검증 142 · F 정산 원장 90 · G 설정 거버넌스 40 · H 엔진↔정산 60
- 실측: **GREEN 582 / RED 70** (전체 데스크톱 스위트 1,242개, 기존 590개 회귀 0)
- RED 백로그(구현해야 수입 무결성 확보):
1. SSV 리플레이 방지 60 — 동일 transaction_id 재검증·과거/미래 timestamp 수용(미구현)
2. setConfig 검증 10 — 음수 rewardTokensAmount 허용(미검증)
- 이식성 경고: admob-ssv의 derEcdsaSignatureToRaw는 Deno WebCrypto가 DER 서명을
반환한다는 동작에 의존. Node(≥22)는 RAW(r||s)를 반환한다 — Deno 업그레이드 시
서명 형식이 바뀌면 검증이 전면 실패할 수 있음. 테스트 픽스처는 RAW→DER 변환기로
실 AdMob 형식을 재현한다.
## 2026-08-24 RED→GREEN 완료 + 수익화 계획
- admob-ssv.ts: 리플레이 방지(tx_id 25h 캐시) + 타임스탬프 신선도(±1h) 구현 → 엣지함수 재배포
- AdMediationEngine.setConfig: 음수/0 이하 설정값 검증 추가
- 광고 스위트 652/652 GREEN, 데스크톱 전체 1,242/1,242 GREEN, tsc 0
- 수익화 로드맵: docs/monetization-plan.md (AdMob 프로덕션 ID 발급이 다음 관문)