Figma 대조 — 기기 · 원본 연결 · 엄격 차이 보고
목표는 화면마다 엄격 픽셀 차이 3% 미만이다(Figma 「Cocode Scaffold App v1.0」 페이지 49:5). 이 문서는 그
차이를 어떤 기기로 찍고, 무엇을 가리고, 어떻게 세고, 어디서 판정하는지를 정한다. 판정 규칙의 정본은
figma-fidelity.json 하나다 — 기준 · 세는 법을 바꾸는 것은 그 파일을 바꾸는 PR 이다.
| 구성 | 자리 | 하는 일 |
|---|---|---|
| 화면 대장 | docs/product/figma-screens.json |
Figma 프레임 80개 — 노드 · 크기 · 기기 · 원본 PNG · insets(띠) |
| 원본 PNG | docs/design/figma/reference/<키>.png |
Figma 에서 1배율로 내보낸 정본. 구현 캡처로 덮어쓰지 않는다 |
| Figma 기기 | FigmaDevices (package:test_driver/golden.dart) |
폰 · 태블릿 · 데스크톱 — DPR 1 |
| 대장 → 골든 | FigmaLedger · FigmaScreen |
키 하나 → 기기 · co_golden 원본(GoldenDesignReference) |
| 화면 등록 | FigmaGoldenScreens |
capture 전용 시나리오 + 대장 연결 기록 |
| 수락 보고 | tool/design/check_visual_acceptance.dart |
화면마다 엄격 차이를 다시 세어 판정 → build/visual-acceptance.json |
| 판정 정책 | docs/product/figma-fidelity.json |
기준 3%(미만) · 세는 법 · Δ 의 N · 글자 밖 판정(선택 textMask) |
| CI | .github/workflows/golden.yml 의 Figma 대조 (수락 보고) |
요약 · 아티팩트 — 지금은 보고만 |
기기
Figma 프레임 그대로 찍는다. 원본 PNG 가 1배율이므로 기기도 DPR 1 이다 — 캡처와 원본이 같은 픽셀 격자에 놓여야
co_golden 이 견준다(크기가 다르면 sizeMismatch 로 견주지 않는다).
| 기기 | 크기 | 플랫폼 | 기본 안전 영역 |
|---|---|---|---|
FigmaDevices.phone (figma-phone) |
390×844 | iOS | 위 44 · 아래 34 |
FigmaDevices.tablet (figma-tablet) |
1024×768 | iOS(가로) | 위 44 · 아래 34 |
FigmaDevices.desktop (figma-desktop) |
1440×900 | macOS(웹 화면) | 없음 |
- 화면마다 대장이 기기를 정한다 —
FigmaScreen.device는 위 기기를 바탕으로 크기를 프레임 크기로, 안전 영역(view padding)을 대장insets로 덮어쓴다. 그래서SafeArea아래 앱 내용이 Figma 와 같은 y 에서 시작하고 끝난다 (예: MK-S1 은 위 44 · 아래 0 — 홈 인디케이터가 없는 프레임). - 긴 프레임은 그 크기 그대로 찍는다(MK-A11 390×1412 등). 앱도 그 높이의 화면에 그려진다.
- 변형은 하나 — 그 기기 · 대장 색 모드(
modes.colorLight →light) ·ko· 글자 배율 1. - CoUI 배율은 1 이다. coui_flutter 0.157 부터
AdaptiveScaler.defaultScaling이 iOS · Android 를 포함한 모든 플랫폼에서 1 이고(AdaptiveScaling.mobile= 1), 앱 셸(app/app·app/console)과 골든 셸(kernelGoldenMatrix)의CoUIApp은scaling을 넘기지 않는다. co_golden 도 배율을 걸지 않는다(기기의 크기 · DPR · 안전 영역 · 플랫폼 · 글자 배율만 시험 화면에 건다). 그래서 iOS 로 찍어도 1배로 그려져 1배율 Figma 와 맞는다. coui 가 기본값을 바꾸거나 셸이 배율을 넘기면package/test_driver/test/figma/figma_scaling_test.dart가 실패한다 — 그때 Figma 기기에도 같은 배율을 줄지(그러면 원본과 어긋난다) 정한다. 큰 배율(1.25 × 글자 배율)의 레이아웃은testScaleInvariant가 따로 본다. - 글자 단계 — CoUI 는 화면 폭으로 글자 단계를 고른다(태블릿 ≥768 · 데스크톱 ≥1024). 390 은 mobile, 1024 · 1440 은 desktop 이다 — Figma 「Semantic/ Typography」 의 Mobile · Desktop 모드와 같다(같은 시험이 지킨다).
가림
가리는 것은 띠 둘뿐이다 — 위 상태 바(insets.top)와 아래 홈 인디케이터(insets.bottom). 둘 다 기기(OS)가
그리고 앱은 그리지 않는다. 띠마다 사유가 기록된다(상태 바 띠(위 44px) — 기기(OS)가 그리고 앱은 그리지 않는다).
- 띠 높이는 화면 대장이 정한다. 대장에 없는 값으로 가리지 않는다 — co_golden 의 기기 안전 영역 자동 가림
(
maskSafeArea)도 끄고 대장 띠만 넘긴다(FigmaGoldenScreens.designAnalysis). - 그 밖을 가리는 것은 금지다. 시계 · 지도 타일처럼 정말 그릴 수 없는 것이 생기면, 먼저 아래 「가림 예외」 표에
화면 · 영역 · 사유 · 이슈를 적는 PR 로 오너 승인을 받는다. 수락 보고 도구는 아직 예외를 받지 않는다 — 대장 띠
밖의 차이는 모두 센다. 첫 예외가 승인되면 그때
figma-fidelity.json에 자리를 만든다. 글자 잉크 상자를 빼는 「글자 밖」 수는 가림 예외가 아니라 세는 법이다(아래 「세는 법」) — 그 글자는 구조 대조가 대신 본다. - 하단 바 구성품(
BottomActionBar · 스캐폴드안·InputBar)은 안에HomeIndicator(바닥 34)를 품고 바탕을 그 밑까지 깐다. 그런 프레임도 바닥 34 가 홈 인디케이터 띠다 — 대장insets.bottom이 34 여야 앱이 그만큼 안전 영역을 두고 바를 그린다(대장이 0 이면 앱 바가 34 짧게 그려진다).
가림 예외
| 화면 | 영역(논리 px) | 사유 | 이슈 |
|---|---|---|---|
| (없음) |
세는 법
분모는 띠 밖의 픽셀(comparable = 전체 − 띠)이다. 두 이미지를 8비트 RGBA 로 풀어 픽셀마다 견준다.
| 이름 | 「다르다」로 세는 픽셀 | 보고 키 |
|---|---|---|
| exact | RGBA 네 채널 중 하나라도 다르다 — 엄격(정확) 차이 | exact |
| Δ≤N 무시 | 네 채널 차이의 최댓값이 N 을 넘는다(N 이하는 세지 않는다) — 기본 N = 16 | delta |
- 판정은 정책의
count(exact·delta)로 한 수만 쓴다. 둘 다 늘 보고한다. 지금 정책은delta(N = 8) · 글자 밖 · 3% 미만(maximumIsExclusive: true— 3.000% 는 넘음)이다 — 오너 확정 2026-11-02(아래 「글자 밖」 · 「보정」). frameExact는 띠를 빼지 않은 정확 차이다 — co_golden 의designComparison.differentPixels와 같아야 하고, 다르면 디코딩 검산 실패로 「판정 못 함」이다.- co_golden 디자인 분석(허용 오차 — CIEDE2000 · 위치 반경 · 안티에일리어싱 제외 · 글자 상자 완화)의 판정 · 비율 ·
안티에일리어싱 픽셀 수(
analysis.antialiasedPixels)는 참고로 싣는다. 판정에는 쓰지 않는다. - 왜 둘인가 — Figma 와 Flutter 는 글자 · 모서리 가장자리를 다르게 래스터한다. 같은 화면을 Figma 에서 두 번 내보내 견줘도 exact 14.1% · Δ≤16 4.7% 였다(오케스트레이터 측정, 2026-11-01). 엄격 3% 를 「모든 RGBA 변화」로 셀지 「작은 채널 차이는 빼고」 셀지는 MK-01 을 재서 정한다(아래 「보정」).
글자 밖 — 글자 잉크 상자를 빼고 세기
같은 글자를 같은 자리에 그려도 두 렌더러가 가장자리를 다르게 칠해, 글자 상자(+2 px) 픽셀의 26–32% 가 Δ>8 로 남는다
(아래 「글자 바닥값」). 그래서 글자는 구조로 엄격하게, 픽셀은 글자 밖에서 센다. 오너가 2026-11-02 에 판정에 쓰기로 했다 —
figma-fidelity.json 의 "textMask": {"padding": 2}.
- 빼는 것: 대장 연결 기록의
spec(docs/design/figma/spec/<키>.design.json)에 있는 TEXT 노드마다 잉크 상자(ink— FigmaabsoluteRenderBounds, 없으면rect)를 사방 N px 넓힌 사각형. 프레임 밖은 자르고, 숨긴 노드는 co_golden 처럼 읽지 않는다. 분모도 그만큼 준다(띠 밖 − 글자 가림). 대신 보는 것: 상자 안의 글자는 co_golden 구조 대조 findings (내용 · 서체 · 굵기 · 크기 · 색 토큰 · 위치)와expectRenderedText가 본다 — 글자 밖 「수락」은 글자 findings 0 과 함께 읽는다. - 보고: 사양이 있는 화면은 판정과 무관하게 늘 글자 밖 exact · Δ>N 을 함께 싣는다(JSON
outsideText·textMask, 표 열 「Δ≤N 글자 밖」, 콘솔Δ≤N글자밖). 사양이 없으면 「사양 없음」, 읽지 못하면 「사양 읽지 못함」이다. - 판정 스위치: 정책의 선택 항목
"textMask": {"padding": N}(N 0–16) 또는 명령줄--text-mask(N 은 정책 값, 없으면- ·
--text-mask-padding <N>이 켜면 판정이 글자 밖 비율(정책의count)을 쓴다. 명령줄로 켠 것은--count·--delta처럼overrides에 남는다(textMask.padding=N). 켜져 있는데 사양이 없는 화면은 띠 밖 전체로 판정하고 사유에 「사양 없음 — 글자 가림 없이 셌다」를 남기며, 사양을 읽지 못하면 「판정 못 함」이다. 정책에 항목이 없으면 판정은 그대로다(글자 밖 수만 참고로 더 보인다 — N 2).
- ·
- 한계: 상자 안의 차이는 원인과 무관하게 빠진다 — 글자에 겹친 다른 부품의 차이도 함께다. 예: 하단 탭처럼 글자 위를 덮는 CoUI 부품이 CoUI 와 Figma 사이에 높이가 다르면 그 글자 상자 안의 차이가 함께 빠진다(scaffold-booking SH-01@1024 의 실측은 그쪽 문서). 그런 차이는 상자 밖에 남은 몫과 구조 대조의 위치 · 크기 findings 로 본다.
- 어림: scaffold-booking 은 구현 전에 Figma 79장의 글자 잉크 면적과 SH-01 의 「글자 바닥값 ÷ 잉크 면적」으로 어느 화면이 완벽히 구현해도 3% 를 넘을지 어림했다(그쪽 문서 「글자 밖」). 이 앱의 어림은 MK-01 을 처음 잰 뒤 같은 방법으로 다시 낸다.
판정
| 상태 | 뜻 |
|---|---|
accepted ✅ |
정책의 세는 법으로 기준 미만 |
above-threshold ⛔ |
기준 이상 |
unverified ⚠️ |
판정 못 함 — 캡처 실패 · 넘침 · 크기 불일치 · 원본 · 대장 없음 · 대장 연결 기록 없는 디자인 대조 · 검산 실패 · 글자 밖으로 판정하는데 사양을 읽지 못함. 통과가 아니다 |
stale 🕰 |
낡음 — 캡처 뒤 원본 PNG 나 대장 항목(노드 · 크기 · 띠 …)이 바뀌었거나 --since 보다 이른 캡처. 다시 찍는다 |
비교는 대장 연결 기록(build/co_golden/figma/**)마다 한 줄이다. 기록은 그리기 전에 남으므로 그리다 실패한 화면도
보고에서 사라지지 않는다. coverage 는 대장 화면 중 몇 개를 견줬는지와 빠진 키를 보인다(대장이 없으면 세지 않는다).
수락은 비교마다의 지표다 — 커버리지 · 실제 앱 동작 · 디자인 승인은 따로 본다.
화면 등록
화면 패키지의 test/golden/ 에서 대장 키로 등록한다. 원본과 같은 상태(같은 데이터 · 선택 · 스크롤)를 만들어 찍는다.
import 'package:test_driver/golden.dart';
final FigmaGoldenScreens figma = FigmaGoldenScreens(suite: 'shop');
void main() {
figma.screen('MK-01@390', build: (_) => const HomePage());
figma.screen('MK-03+MK-04@1440', build: (_) => const ServiceDetailPage(), interact: …);
}
- capture 전용이다. compare(기준 이미지 비교) · 보통
flutter test에서는 건너뛴다 — Figma 변형은 회귀 기준 이미지가 없고 필요 없다(회귀는 커널 매트릭스가 맡는다). 키는 모든 모드에서 대장에서 찾으므로 틀린 키는 바로 실패한다. - 사양 JSON 이
docs/design/figma/spec/<키>.design.json에 있으면 함께 넘겨, co_golden 이 서체 · 색 · 위치 · 컴포넌트 차이를 소스 줄과 함께 낸다(co_golden README 「Design analysis」).
로컬 실행
# 1) 캡처 — 모든 골든 패키지(Figma 대조 포함) → build/co_golden
tool/golden/capture.sh
# Figma 대조만, 한 패키지에서(출력을 저장소 build/co_golden 으로):
(cd <패키지> && TZ=Asia/Seoul CO_GOLDEN_MODE=capture \
CO_GOLDEN_OUTPUT="$(git rev-parse --show-toplevel)/build/co_golden" \
flutter test --no-pub --tags figma test/golden)
# 2) 수락 보고 — 보고만(종료 코드 0) · Markdown 요약까지
tool/design/check_visual_acceptance.sh --report-only --summary build/visual-acceptance.md
# 판정으로(수락이 아닌 비교가 있으면 1): --report-only 를 뺀다
# 보정 탐색 — 정책은 그대로 두고 보고에 덮어쓰기로 남긴다
tool/design/check_visual_acceptance.sh --report-only --count delta --delta 8
# 글자 밖으로 판정(정책에 textMask 가 있으면 이미 켜져 있다 — 「세는 법」의 「글자 밖」)
tool/design/check_visual_acceptance.sh --report-only --count delta --delta 8 --text-mask
# 3) 갤러리
tool/golden/gallery.sh # → build/golden-gallery/index.html
tool/design 은 별도 pub 루트다(PNG 를 푸는 image 의존 — 루트 워크스페이스 의존을 늘리지 않는다). 래퍼
check_visual_acceptance.sh 가 lock 그대로 받고 저장소 루트에서 돌린다. 도구 시험: (cd tool/design && dart test).
출력
build/co_golden/ # capture.sh (co_golden)
├── images/<suite>/<scenario>/<변형>.png 캡처
├── references/<suite>/<scenario>/<변형>.png 원본 사본(바이트 그대로)
├── differences/<suite>/<scenario>/<변형>.png co_golden 정확 차이(띠 안 포함, 자홍)
├── analysis/<suite>/<scenario>/<변형>.{json,png} co_golden 허용 오차 분석 · 지도
├── figma/<suite>/<scenario>/<변형>.json 대장 연결 기록(키 · 대장 · 띠) — FigmaGoldenScreens
└── runs/<suite>/<scenario>.json 실행 기록
build/visual-acceptance.json # 수락 보고(정책 · 수 · 커버리지 · 비교마다 exact · delta · 글자 밖 · 분석)
build/visual-acceptance.md # --summary
build/visual-acceptance/<suite>/<scenario>/<변형>.png # 보정 지도
build/golden-gallery/index.html # gallery.sh
보정 지도는 수락 보고가 쓴다 — 회색 같음 · 파랑 가린 띠 · 노랑 exact 로만 세는 픽셀(Δ≤N) · 자홍 두 규칙 모두 세는 픽셀(Δ>N) · 초록 글자 가림(사양이 있는 화면 — 진한 초록은 그 안의 Δ>N). 노랑이 글자 · 모서리 가장자리뿐이면 Δ 규칙이 래스터 차이만 빼는 것이다.
갤러리 읽는 법
gallery.sh 의 갤러리에서 Figma 대조가 있는 변형은 원본과 캡처를 함께 보인다.
- 디자인 차이만 으로 판정이
fail·undetermined인 변형만 남긴다. 머리의 판정 줄은 co_golden 허용 오차 판정(일치 · 불일치 · 판정 불가)이다 — 이 문서의 엄격 판정이 아니다. 엄격 판정은 수락 보고를 본다. - 보기: 50% 겹쳐 보기(불투명도 막대로 원본 ↔ 구현) · 좌우 비교 · 허용 오차 차이(빨강 차이 · 노랑 안티에일리어싱 · 파랑 가림) · RGBA 차이 이미지(co_golden 정확 차이 — 띠 안도 칠한다).
- 찾은 것(findings)을 고르면 Figma 위치(분홍)와 구현 위치(파랑 점선)가 표시된다. 고칠 곳이 앱 코드인지 디자인 시스템인지 알려 준다. 픽셀 영역·가림 표시 로 차이 영역과 띠를 함께 본다. 분석 리포트 JSON 이 전문이다.
- 화면을 고치면 다시 캡처한다. 원본은 Figma 가 바뀔 때만 다시 내보낸다(캡처로 덮어쓰지 않는다).
CI
golden.yml 의 골든 (compare) 가 PR(준비 완료) · dispatch 에서 확인용 capture 를 돌린 뒤 출력을 아티팩트
co-golden-capture 로 올리고, Figma 대조 (수락 보고) 잡이 그것을 받아 도구 시험 → 수락 보고를 돌려 잡 요약과
아티팩트 visual-acceptance(JSON · Markdown · 보정 지도)로 남긴다.
- 지금은 보고만 — 워크플로 env
FIGMA_ACCEPTANCE_BLOCKING: "false"."true"로 바꾸면 수락이 아닌 비교(기준 넘음 · 판정 못 함 · 낡음)가 하나라도 있을 때 그 잡이 실패한다. 기준 · 세는 법은 이 env 가 아니라figma-fidelity.json이 정한다. - 기존
골든 (compare)판정은 그대로다 — Figma 시나리오는 compare 에서 건너뛰므로 기준 이미지가 필요 없고, 아티팩트 올리기가 실패해도 compare 는 실패하지 않는다. main push 에는 capture 가 없어 이 잡도 없다. - 문서만 바뀐 PR(
docs/**)에는 골든 워크플로가 돌지 않는다 — 정책 · 원본만 바꿨으면 dispatch 로 다시 돌린다.
보정 — MK-01 첫 측정 (2026-11-02)
엄격 3% 를 무엇으로 셀지는 오너가 확정했다(2026-11-02) — 「글자 밖 Δ≤8 3% 미만」(count: delta · maxChannelDelta: 8 · textMask.padding: 2, co_golden 구조 오류 0건 지향). exact · Δ≤8 전체는 참고로 계속 보고한다. 아래는 MK-01(홈) 세 크기를 구현해
처음 잰 값이다 — 로컬 Darwin/arm64 capture(CO_GOLDEN_MODE=capture, --tags figma) · check_visual_acceptance.sh --count delta --delta N --text-mask. 글자 밖 수는 글자 노드의 잉크 상자(Figma absoluteRenderBounds)에 사방 2px 을 더해
뺀 값이다 — 글자 사양은 tool/design/figma/export_text_spec.figma.js 가 글자 노드만 읽어(컴포넌트 · 색 칠 · 레이아웃
사양은 없다) docs/design/figma/spec/MK-01@<크기>.design.json 에 있다.
Δ≤N 표 (화면 대비 %, 띠 밖 · 오른쪽 짝이 글자 밖)
| 화면 | exact | exact 글자 밖 | Δ≤4 | 글자 밖 | Δ≤8 | 글자 밖 | Δ≤16 | 글자 밖 | Δ≤32 | 글자 밖 |
|---|---|---|---|---|---|---|---|---|---|---|
| MK-01@390 | 32.236 | 31.836 | 30.607 | 30.298 | 5.509 | 3.170 | 4.549 | 2.541 | 3.506 | 2.168 |
| MK-01@1024 | 29.465 | 29.131 | 27.386 | 27.037 | 3.043 | 1.533 | 2.139 | 0.750 | 1.371 | 0.332 |
| MK-01@1440 | 32.314 | 32.261 | 30.295 | 30.250 | 1.967 | 0.714 | 1.196 | 0.096 | 0.856 | 0.048 |
Δ≤4 → Δ≤8 에서 30% → 2–6% 로 꺾이는 것은 Figma 의 사진 보정(온도 +0.11 · 채도 −0.02)이 사진 픽셀을 그 정도로 옮기기
때문으로 읽힌다(원본에는 없는 보정이다 — scaffold-booking 이 같은 방식으로 분리했다). 작업 기준(글자 밖 Δ≤8 3% 미만)으로는 1024 · 1440 이 수락이고 390 이 3.17% 로 넘는다 —
아래 원인에서 보듯 그 거의 전부(2.36%)가 CoUI NavigationBar 높이 차이다.
원인별 분해 (Δ≤8 · 글자 밖 · 화면 대비 %)
| 원인 | 390 | 1024 | 1440 |
|---|---|---|---|
CoUI ↔ Figma: NavigationBar — 막대 높이 115 ↔ 103(항목 12px 위) · 선택 라벨 14/600 ↔ 12 |
2.362 | 0.417 | — |
| 사진 — Figma 보정(온도 · 채도) · 리샘플링 · 모서리 안티에일리어싱 | 0.583 | 0.706 | 0.597 |
| 그 밖 — 막대 아이콘 자리(아래) · 칩 · 링크 폭 · 둥근 상자 가장자리 | 0.226 | 0.411 | 0.118 |
| 합계(글자 밖 Δ≤8) | 3.171 | 1.534 | 0.714 |
NavigationBar 를 빼면 390 은 0.81% 다. 높이 차이는 디자인 판단이라(Figma 103 · CoUI 115) 앱에서 맞추지 않고 수치만 보고한다 — scaffold-booking 도 같은 부품 차이를 적었다(그쪽 몫은 글자 밖이 아닌 전체 기준으로 390 1.6% · 1024 2.2%).
co_golden 구조 대조(글자 노드만)
| 화면 | 글자 노드 | 맞춤 | 서체 차이 | 위치 차이 |
|---|---|---|---|---|
| MK-01@390 | 21 | 21 | 1 — 선택 라벨 「홈」 14/600/lh 160% ↔ CoUI 12 | 4 — 하단 탭 라벨 −10.3…−11.8px(막대 높이) |
| MK-01@1024 | 27 | 27 | 1 — 〃 | 7 — 하단 탭 4 + 분류 칩 글자 −2.2…−4.4px 3(칩 폭) |
| MK-01@1440 | 33 | 33 | 0 | 3 — 상단 링크 −3…−5.2px(링크 폭) |
글자 내용 · 크기 · 굵기 · 색 토큰은 모두 일치한다(위 외 서체 차이 없음 · 없는 글자 없음). 남은 위치 차이는 두 가지다 — 하단 탭(CoUI 부품 높이)과, Figma 가 글자 상자 폭을 정수로 올려 줄지어 늘어선 칩 · 링크가 글자마다 1–2px 씩 밀리는 엔진 차이(글자 한 개씩은 맞고 합쳐진 간격만 다르다). 구조 오류 0건 기준은 이 두 CoUI · 엔진 차이 때문에 충족하지 못한다.
글자 가장자리
글자 잉크 상자의 위치를 원본과 견주면 대부분 0px 이고, Body/Small(13px · 행간 150%) 글자(폰의 기간 · 빠른 실행 라벨 ·
후기 수)가 위로 1–2px 높다 — 행간 150% 에서 글자 상자 안 위 여백을 배분하는 방식이 Figma 와 Flutter 가 달라서이며
Label/XS 와 함께 scaffold-booking 이 이미 적은 차이와 같다(앱에서 덮지 않는다).
CoUI · Figma 가 다른 곳 (앱에서 덮지 않음)
NavigationBar높이 — Figma 103px(위 8 · 항목 66 · 아래 28, 홈 인디케이터 34 와 겹침) ↔ CoUI 115px. 막대가 12px 높고 아이콘 · 라벨이 12px 위. 차이 몫: 390 2.36% · 1024 0.42%.NavigationBar선택 라벨 — Figma 14/600/lh 160%(스타일 미연결) ↔ CoUI 모두Label/Small12. 기본labelMode는 아이콘만(none)이라 Figma 와 같게.all로 줬다.Text색 체인 —on-surface-subtle·primary-text·error체인이 없다 →ShopTextTone(.color(CoreColor.token(…))). CoUI 가 체인을 더하면 지운다(CoUI 이슈 #1459).- 상단 막대 행동(폰) 터치 대상 — Figma 의 검색 · 장바구니는 20px 아이콘이 4px 간격이라 두 행동 모두 터치 대상 48(× 배율)을 줄 수 없다. 누를 자리를 48×배율로 넓히고 아이콘은 그 자리의 오른쪽 끝에 둔다 — 장바구니는 Figma 자리 그대로, 검색은 28px 왼쪽(차이 몫 0.1% 미만). 의도한 편차다.
- 막대 이름 줄 — CoUI
AppBar높이가 고정이라 글자 배율 2.0(실효 2.5) 에서 이름이 두 줄로 접히면 넘친다 → 한 줄에 들어가지 않을 때만FittedBox(scaleDown)으로 줄인다(들어가면 그대로). - Figma 사진 보정 — 이미지 칠마다 온도 +0.11 · 채도 −0.02 가 걸려 있다. 원본(rawImages)은 보정 전이라 구현이 조금 차갑다. 끌지 · 시드 사진에 구울지는 오너 결정(scaffold-booking 과 같은 항목).
Figma 안의 불일치 (디자이너 확인 후보)
- 폰만 할인율이
error(빨강) — 태블릿 · 데스크톱 카드는primary-text(주황 갈색)다. 프레임마다 그대로 따랐다. - 카드 안 차례가 다르다 — 폰은 이름 → 값 → 후기, 태블릿 · 데스크톱은 이름 + 표시 → 후기 → 값. 폰 카드에는 표시(인기 · 할인 · 신규)도 없다.
- 같은 할인 표시를 상품마다 다르게 셈한다 — 홈 · 카테고리 · 상세는 가디건 「10% 46,800원」(상세에 52,000원 취소선 = 46,800 은 할인가), 토트백 「20% 28,000원」인데 장바구니(MK-05)는 가디건 46,800원(할인 0) · 토트백 22,400원(−5,600)이다.
- 태블릿 홈은 상품이 3개만 그려져 있다(4번째 머그컵 없음) · 「새로 들어왔어요」 머리가 없다.
다음
글자 밖 Δ≤8 이 390 에서 3% 를 넘는 것은 구현 결함이 아니라 위 NavigationBar 차이 하나로 설명된다. 오너가 세는 법을
정하면(count · maxChannelDelta) figma-fidelity.json 의 calibration 을 바꾸는 PR 로 닫는다.
먼저 잰 앱 — scaffold-booking (2026-11-01)
단골 예약의 SH-01 세 크기를 같은 도구로 잰 결과(Δ≤N 표 · 원인별 분해 · 글자 바닥값 · 사진 보정 · CoUI NavigationBar 높이
차이)와 권고(exact 는 쓰지 않는다 · Δ≤8 을 권한다, 결정은 오너)는 coco-de/scaffold-booking
docs/product/figma-fidelity.md 「보정」에 있다. 같은 Figma 파일 · 같은 CoUI 부품이라 이 앱에도 그대로 들어맞는 것(글자
가장자리 래스터 차이 · 사진 ±1 잡음 · 하단 탭 높이 차이)이 많지만, 숫자는 이 앱의 화면으로 다시 잰다.