CastCanvas Lab: 사이트 전면 리뉴얼 및 브랜드 디자인 시스템 통합
지난 며칠간 서비스의 얼굴인 랜딩 페이지를 전면 리뉴얼하고, 확정된 브랜드 가이드를 실제 앱 UI에 이식하는 작업을 진행했다. 특히 Google Stitch MCP를 활용해 신속하게 고품질의 디자인 초안을 생성하고, 다국어 지원과 모바일 사용성 개선을 통해 서비스의 완성도를 한 단계 높였다.
목표
- 브랜드 정렬: 확정된 브랜드 요소(Indigo #4f46e5, Plus Jakarta Sans, 8px radius)를 사이트와 앱 전반에 통합.
- 다국어 지원: 쿠키 기반의 한/영 전환 기능을 구현하고 SSR 환경에서의 안정성을 확보.
- 모바일 대응: 좁은 화면에서도 캔버스 도구(Inspector)를 쾌적하게 사용할 수 있도록 UI 구조 개선.
핵심 구현 포인트
1) Google Stitch MCP 기반 랜딩 전면 리뉴얼 (SITE)
Stitch MCP를 통해 현대적인 SaaS 랜딩 페이지 초안을 생성하고, 이를 바탕으로 모든 컴포넌트를 재작성했다.
- 컴포넌트 리뉴얼: Hero(SVG 프리뷰 포함), Problem, Features, HowItWorks, CTA, Footer 등을 새 브랜드 톤에 맞춰 구성.
- 브랜드 확정: 메인 컬러 Indigo(#4f46e5)와 Plus Jakarta Sans 폰트, 8px 보더 반경을 전역 디자인 토큰으로 설정.
2) useSyncExternalStore를 활용한 Locale 관리 (SITE)
쿠키 기반의 한/영 전환 기능을 도입하면서 발생한 SSR Hydration 문제를 useSyncExternalStore로 해결했다.
- 안정적인 Hydration: 서버에서는 기본값(‘en’)을 반환하고, 클라이언트에서는 실제 스토어(Cookie) 값을 읽어와 동기화함으로써 렌더링 불일치를 방지했다.
// LocaleContext.tsx 중 일부
export function LocaleProvider({ children }: { children: React.ReactNode }) {
// useSyncExternalStore로 SSR/CSR 불일치 해결
const locale = useSyncExternalStore(
subscribe,
getSnapshot, // 클라이언트: 쿠키 읽기
getServerSnapshot // 서버: 항상 'en'
);
const switchLocale = (newLocale: Locale) => {
setCookie('CC_LOCALE', newLocale);
notify();
};
return (
<LocaleContext.Provider value={{ locale, switchLocale }}>
{children}
</LocaleContext.Provider>
);
}
3) FE 브랜드 정렬 및 모바일 Bottom Sheet (FE)
사이트에서 확정된 브랜드를 FE 앱에도 동일하게 이식하고, 반응형 UI를 강화했다.
- 브랜드 이식: 로그인/회원가입 화면을 Stitch MCP 초안 기반으로 리뉴얼하고, favicon과 로고마크를 사이트와 통일했다.
- Inspector 모바일 대응: 데스크탑의 우측 패널 형식을 모바일에서는 슬라이드 방식의 Bottom Sheet로 전환하여 캔버스 공간을 확보했다.
/* _inspector.module.scss */
.panel {
position: fixed;
bottom: 0; left: 0; right: 0;
height: 50dvh;
transform: translateY(100%);
transition: transform 0.3s ease;
&.open { transform: translateY(0); }
@include md { /* 데스크탑 전용 */
position: static;
width: 320px;
height: 100%;
transform: none;
}
}
트러블슈팅 / 고민 포인트
SSR Hydration 불일치 문제
- 원인:
useState(readCookie)로 locale을 초기화할 때, 서버는 쿠키를 모르는 상태에서 렌더링하고 클라이언트는 쿠키 값을 읽어 렌더링하면서 첫 번째 렌더링 결과가 서로 달라 hydration 에러가 발생했다. - 해결:
useSyncExternalStore를 도입하여 서버 스냅샷은 고정하고, 클라이언트에서만 외부 스토어(Cookie)와 동기화하도록 강제하여 해결했다.
Stitch 캔버스 화면 생성 타임아웃
- 원인: 캔버스의 복잡한 레이아웃(노드, 툴바, 패널 등)을 한 번에 생성하려는 프롬프트가 너무 무거워 타임아웃이 발생했다.
- 해결: 화면을 논리적으로 분리(Toolbar 따로, Inspector 따로)하여 생성하거나 직접 코드로 구현하는 방식으로 우회했다.
결과
- 일관된 브랜드 경험: 사이트와 앱이 동일한 디자인 언어를 공유하게 되어 서비스의 신뢰도가 향상되었다.
- 다국어 접근성: 한/영 전환 기능을 통해 글로벌 사용자 대응이 가능해졌으며, 기술적으로도 견고한 locale 관리 구조를 갖췄다.
- 쾌적한 모바일 UX: 모바일에서도 캔버스의 데이터(Inspector)를 손쉽게 확인하고 제어할 수 있는 구조를 완성했다.
다음 개선 아이디어
- Inspector Bottom Sheet 제스처: 드래그해서 닫는(drag-to-dismiss) 애니메이션 및 제스처 추가.
- 워크스페이스 목록 리뉴얼: 사이트 브랜드 가이드(
SITE_FE_BRAND_GUIDE.md)를 기준으로 워크스페이스 관리 페이지 리뉴얼. - Stitch 캔버스 화면 재도전: 화면 구성을 더 작게 쪼개어 Stitch MCP로 복잡한 캔버스 UI 초안 생성 시도.