Skip to content

웹 = 디자인 source of truth

결정일: 2026-05-09 (PR #63 작업 중 사용자 결정) 적용 대상: frontend/ (Next.js 16) + mobile/

정책

웹 (Next.js) 이 디자인 변경의 source of truth. 모든 시각 변경은 웹에서 먼저 적용 → 검증 후 Flutter 로 역포팅.

왜?

  • 웹 iteration 사이클이 빠름 (hot reload + DevTools + 즉시 deploy preview)
  • 디자인 시안 → 적용 → 평가 루프가 모바일보다 짧음
  • 단일 사람 (junhyeon) 운영 환경에서 양쪽 동시 디자인 변경은 비용 큼

운영 룰

  1. 모든 시각 변경은 frontend/ 부터 — Flutter 직접 수정 X
  2. 웹 토큰 = Flutter 토큰 — 1:1 동기화. 변경 시 양쪽 같은 PR 또는 즉시 후속 PR
  3. 모바일 전용 뷰포트max-w-[420px] 컨테이너로 데스크톱에서도 모바일 폭 고정. 데스크톱 별도 디자인 없음
  4. 컴포넌트 매핑 — 가능한 한 Flutter widget 1개 = 웹 component 1개 (예: analysis_card.dartAnalysisCard.tsx, disclosure_item.dartDisclosureItem.tsx)

토큰 동기화

Flutter 토큰 (mobile/lib/shared/theme/) → Tailwind v4 @theme (frontend/src/styles/globals.css).

Flutter
AppColors.primary--color-primary 등 (TW @theme color 네임스페이스)
AppSpacing.xs..xxxl (4/8/12/16/20/24/32 px)TW 기본 스케일 p-1..p-8 (4/8/12/16/20/24/32 px) — 자연 정렬
AppRadius.sm..xl (8/12/16/20 px)rounded-lg (8) / rounded-xl (12) / rounded-2xl (16) / rounded-[20px] (20) — TW 기본 일치
AppTypography.xs..xxxl (11/13/14/16/18/22/28 px)text-sm (14) / text-base (16) / text-lg (18) 만 정렬, 나머지는 arbitrary text-[11px]

⚠️ TW v4 한계: --spacing-X/--text-X/--radius-X 같은 커스텀 네임스페이스는 utility 자동 생성 보장 X. color 외에는 TW 기본 스케일 + arbitrary 값으로 처리. 자세한 함정은 docs/platform/tailwind-v4-gotchas.md.

데이터 정책 (웹 vs 앱)

웹은 anonymous lazy-auth 응답 만 사용:

  • GET /api/v1/ai/analyze/{rceptNo}userID=0 일 때 result 필드 omit, summary 만 동봉. 웹은 이 응답 그대로 노출.
  • 본문 reveal (전체 분석) 은 quota 정책상 앱에서만 — 웹은 "앱에서 보기" CTA 로 유도
  • 관심 종목/알림/설정 등 auth 필요 기능은 웹에서 모두 "앱에서" 모달로 안내

데스크톱 뷰포트

frontend/src/app/layout.tsx 의 body 안에 mx-auto max-w-[420px] 컨테이너로 고정. 데스크톱 사용자에게도 모바일 디자인이 보이고, 좌우 여백은 background 색 노출.

추후 작업

  • 웹에서 디자인 변경 → Flutter 토큰 + widget 으로 역포팅 시점에 PR title 에 (↩ web mirror) prefix 약속
  • 웹 디자인 변경 시 Flutter 측 follow-up 누락 방지 위해 PR template 에 체크 항목 추가 검토