← 모든 글

스타트업을 위한 디자인 시스템: 내가 거꾸로 구축한 방법

저는 디자인 시스템을 거꾸로 구축했습니다. 대부분의 조언은 “제품-시장 적합성을 찾을 때까지 기다리라”고 합니다. 저는 첫날부터 CSS 커스텀 프로퍼티로 시작했습니다. 개인 사이트에서 발생한 CLS 버그가 토큰을 건너뛴 대가를 가르쳐주었기 때문입니다. 일관되지 않은 간격 값으로 인해 Cumulative Layout Shift가 0.493까지 치솟았고, 이를 추적하는 데 두 번의 디버깅 세션이 필요했습니다. 수정은 15분이 걸렸습니다. 조사에는 3시간이 걸렸습니다. 토큰이 있었다면 이 버그는 처음부터 발생하지 않았을 것입니다.1

TL;DR

디자인 시스템은 조율 문제를 해결합니다. 하나의 프로젝트를 진행하는 1인 개발자에게는 사람 간의 조율 문제는 없지만, 과거의 자신과 미래의 자신 사이의 조율 문제는 존재합니다. blakecrosley.com을 위한 디자인 토큰 시스템 — 10개의 색상 토큰, 13단계 타이포그래피 스케일, 8개의 간격 값 — 을 구축한 후, 올바른 순서는 다음과 같다는 것을 배웠습니다: 토큰은 즉시(첫날), 패턴은 세 번 반복될 때, 공식 시스템은 절대 만들지 않는 것(1인 프로젝트의 경우). 토큰 투자는 간격 불일치가 레이아웃 버그를 유발하는 첫 번째 순간에 이미 본전을 뽑습니다.


나의 디자인 시스템: 토큰, 그것만으로 충분합니다

색상 넌-팔레트

사이트 전체가 브랜드 색상 없이 10개의 CSS 커스텀 프로퍼티로 운영됩니다:

:root {
  --color-bg-dark:        #000000;
  --color-bg-elevated:    #111111;
  --color-bg-surface:     #1a1a1a;
  --color-text-primary:   #ffffff;
  --color-text-secondary: rgba(255,255,255,0.65);
  --color-text-tertiary:  rgba(255,255,255,0.4);
  --color-border:         rgba(255,255,255,0.1);
  --color-border-subtle:  rgba(255,255,255,0.05);
  --color-accent:         #ffffff;
}

4단계의 투명도(100%, 65%, 40%, 10%)가 전체 시각적 계층 구조를 담당합니다. 모든 텍스트 단계는 #000000 배경에 대해 WCAG AAA 대비를 통과합니다. 그라디언트 없음, 시맨틱 색상 없음, 다크/라이트 모드 전환 없음. 이 제약이 컴포넌트 라이브러리로도 개선할 수 없는 일관된 시스템을 만들어냅니다.2

브랜드 색상을 건너뛴 결정은 기술적 선택이 아니라 디자인적 선택이었습니다. 16개 제품 디자인 스터디를 진행하면서, 제가 가장 존경하는 제품들(Linear, Vercel, Raycast)이 타이포그래피가 계층 구조를 담당하는 절제된 팔레트를 사용한다는 것을 발견했습니다.

8포인트 간격 시스템

모든 간격 값은 8포인트 기본 단위에서 파생됩니다:

:root {
  --spacing-xs:  0.5rem;  /* 8px */
  --spacing-sm:  1rem;    /* 16px */
  --spacing-md:  1.5rem;  /* 24px */
  --spacing-lg:  2rem;    /* 32px */
  --spacing-xl:  3rem;    /* 48px */
  --spacing-2xl: 4rem;    /* 64px */
  --spacing-3xl: 6rem;    /* 96px */
  --spacing-4xl: 8rem;    /* 128px */
}

임의의 값은 없습니다. 이 시스템은 8단계로 구성되어 있습니다. 레이아웃에 시스템에 존재하지 않는 간격이 필요하다면, 시스템이 잘못된 것이 아니라 디자인이 잘못된 것입니다.

--spacing-2xs 버그

이 규칙을 어렵게 배웠습니다. 자막의 margin-top에 --spacing-2xs를 사용했습니다. 이 토큰은 :root 정의에 존재하지 않았습니다. CSS 커스텀 프로퍼티는 조용히 실패합니다 — 브라우저는 에러를 던지는 대신 마진을 적용하지 않았습니다. 자막이 헤드라인에 붙어버렸고, 로드 시 레이아웃이 이동했으며, Cumulative Layout Shift 점수가 0.493으로 급등했습니다.3

디버깅 경로: Lighthouse가 CLS를 플래그했습니다. DevTools가 이동하는 요소를 식별했습니다. 계산된 스타일을 검사하니 예상했던 4px 대신 margin-top: 0이 나타났습니다. 스타일시트에서 --spacing-2xs를 검색하니 사용은 1건, 정의는 0건이었습니다.

수정: --spacing-2xs--spacing-xs로 변경했습니다. 더 근본적인 수정: 예외 없이 토큰 시스템을 엄격히 준수하는 것입니다.

타이포그래피 스케일

12px에서 80px까지 13단계, 시스템 폰트 사용:

:root {
  --font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text",
                 "SF Pro Display", "Helvetica Neue", Arial, sans-serif;
  --font-size-xs:      0.75rem;   /* 12px */
  --font-size-sm:      0.875rem;  /* 14px */
  --font-size-base:    1rem;      /* 16px */
  --font-size-lg:      1.125rem;  /* 18px */
  --font-size-xl:      1.3125rem; /* 21px */
  --font-size-2xl:     1.5625rem; /* 25px */
  --font-size-3xl:     1.875rem;  /* 30px */
  --font-size-4xl:     2.25rem;   /* 36px */
  --font-size-5xl:     2.7rem;    /* 43.2px */
  --font-size-6xl:     3.25rem;   /* 52px */
  --font-size-7xl:     3.875rem;  /* 62px */
  --font-size-display: 5rem;      /* 80px */
}

시스템 폰트는 폰트 로딩 지연을 완전히 제거합니다. FOIT(Flash of Invisible Text) 없음, FOUT(Flash of Unstyled Text) 없음, 폰트를 위한 네트워크 요청 제로. 이 선택은 Lighthouse 성능 점수 100/100에 기여합니다.4


타이밍 문제

너무 이르게: 성급한 추상화의 함정

시드 단계 스타트업은 제품이 무엇이 될지에 대한 극심한 불확실성에 직면합니다. 디자인 시스템은 인터랙션 패턴, 컴포넌트 계층 구조, 시각적 언어에 대한 가정을 내포합니다. 제품이 피봇하면 디자인 시스템은 변화에 저항하는 부채가 됩니다.5

3명의 엔지니어와 1명의 디자이너로 구성된 팀에는 문서화, 버전 관리, Storybook 인스턴스를 갖춘 컴포넌트 라이브러리가 필요하지 않습니다. 조율에 드는 오버헤드가 조율 문제 자체를 초과합니다.

그러나 토큰은 다릅니다. 토큰은 추상화가 아니라 값입니다. 색상 토큰은 컴포넌트 구조를 강제하지 않습니다. 간격 토큰은 인터랙션 패턴을 제약하지 않습니다. 토큰은 컴포넌트 레이어 아래에서 작동하기 때문에 피봇에서도 살아남습니다.

너무 늦게: 디자인 부채의 악순환

30명의 엔지니어가 있지만 공유 디자인 패턴이 없는 시리즈 B 기업은 반대 문제에 직면합니다. 모든 기능 팀이 각자의 버튼 스타일, 폼 레이아웃, 간격 값을 만들어냅니다. 제품이 서로 다른 세 개의 애플리케이션을 이어 붙인 것처럼 느껴집니다.6

저는 제 프로젝트에서도 더 작은 규모로 같은 패턴을 목격합니다. :root 토큰을 복사하지 않고 새 프로젝트를 시작하면, 첫 주 안에 불일치가 나타납니다. 토큰은 되돌리기에 비용이 많이 드는 부채 악순환에 대한 저렴한 보험입니다.


점진적 투자 프레임워크

1단계: 토큰만 (첫날, 팀 규모 무관)

기초적인 값만 정의하고 공유합니다. 제 구현:

토큰 카테고리 개수 용도
색상 10 배경, 텍스트, 테두리, 강조
타이포그래피 13 xs부터 display까지의 폰트 크기
간격 8 8px 기본 단위 스케일
테두리 둥글기 4 sm (8px), md (16px), lg (32px), xl (48px)
트랜지션 3 fast (150ms), base (300ms), slow (600ms)
레이아웃 3 max-width narrow (800px), default (1400px), wide (1600px)

총 41개 토큰. 컴포넌트 제로. 문서화 사이트 제로. 목표는 값 수준에서의 분기를 방지하면서 실험을 위한 최대한의 유연성을 보존하는 것입니다.7

2단계: 패턴 추출 (패턴이 3번 반복될 때)

동일한 UI 요소가 세 개의 서로 다른 기능에 나타나면 패턴을 추출합니다. 제 사이트에서 추출한 패턴: - 카드 레이아웃 (프로젝트 카드, 블로그 카드, 소셜 카드): 일관된 패딩, 테두리 둥글기, 호버 상태 - 네비게이션 밑줄 (네비게이션 링크, 브레드크럼): 호버 시 scaleX(0) → scaleX(1) 트랜지션 - 글래스모피즘 헤더: backdrop-filter: blur(20px) + border-bottom

각 패턴은 같은 것을 세 번 만들고 중복을 발견했기 때문에 존재합니다. 사전에 설계하는 것이 아니라 프로덕션 코드에서 패턴을 추출합니다. 프로덕션 패턴은 실제 요구사항을 반영합니다.8

3단계: 공식 시스템 (25명 이상의 엔지니어, 1인 프로젝트에서는 절대 불필요)

대규모에서는 조율 문제가 컴포넌트 라이브러리, Figma 미러링, 기여 프로세스, 버전 관리된 변경 로그를 정당화합니다. 저는 어떤 개인 프로젝트에서도 이 단계에 도달한 적이 없으며 도달할 것으로 예상하지도 않습니다. 1인 개발자에게는 토큰 + 추출된 패턴이 공식 시스템의 유지보수 오버헤드 없이 충분한 구조를 제공합니다.


완전히 건너뛴 것들

문서화 사이트

공개용 디자인 시스템 문서화 사이트는 1인 프로젝트에서 사용자 가치를 전혀 만들어내지 않는 엔지니어링 시간을 소비합니다. 제 “문서”는 critical.css:root 블록입니다. 파일을 읽는 어떤 개발자(또는 AI 에이전트)든 시스템을 즉시 이해할 수 있습니다.

멀티 프레임워크 지원

제 사이트는 순수 CSS를 사용합니다. React 컴포넌트도, Vue 래퍼도, Web Components도 없습니다. CSS 커스텀 프로퍼티는 프레임워크에 구애받지 않기 때문에 토큰은 어떤 프레임워크에서든 작동합니다. 추상화 레이어는 CSS 그 자체입니다.

성급한 접근성 극장

접근성은 중요합니다 — 제 사이트는 모든 텍스트 단계에서 WCAG AAA 대비를 달성합니다. 그러나 먼저 대비 시스템을 구축하고(알려진 비율을 가진 토큰) 그다음에 준수 여부를 검증했습니다. 내장된 접근성을 가진 토큰(모든 텍스트 단계가 7:1 대비를 초과)으로 시작하는 것이, 임의의 색상 선택을 사후에 감사하는 것보다 더 효과적입니다.9


핵심 정리

1인 개발자를 위한 조언: - 색상, 타이포그래피, 간격, 트랜지션에 대한 CSS 커스텀 프로퍼티를 첫날에 정의하세요. 41개 토큰 투자가 나중에 디버깅하는 데 수 시간이 걸리는 버그와 불일치를 방지합니다 - 컴포넌트 라이브러리, 문서화 사이트, Storybook은 건너뛰세요. 1인 프로젝트에서는 유지보수 오버헤드가 조율의 이점을 초과합니다 - 동일한 요소가 세 곳에 나타날 때 프로덕션 코드에서 패턴을 추출하세요. 성급한 추출은 다음 이터레이션에서 살아남지 못할 수 있는 패턴에 노력을 낭비합니다

스타트업 디자인 리드를 위한 조언: - 제품-시장 적합성을 찾기 전에 토큰부터 시작하세요. 토큰은 컴포넌트 레이어 아래에서 작동하기 때문에 피봇에서도 살아남습니다 - 25명 이상의 엔지니어가 진정한 조율 문제를 만들어낼 때까지 공식 시스템 도입을 참으세요. 그 임계점 이전의 공식화는 이터레이션을 늦추는 유지보수 오버헤드를 만듭니다


참고 자료


  1. 저자의 CLS 디버깅 경험. 정의되지 않은 --spacing-2xs 토큰으로 추적된 Cumulative Layout Shift 0.493. MEMORY.md 에러 항목에 기록됨. 

  2. 저자의 critical.css CSS 커스텀 프로퍼티. 10개의 색상 토큰, 모두 흰색-검정 불투명도 관계에서 파생됨. 

  3. 저자의 디버깅 경험. --spacing-2xs가 사용되었으나 :root에 정의되지 않음. CSS 커스텀 프로퍼티는 조용히 실패하여 예상 값 대신 마진 제로를 생성함. 

  4. 저자의 타이포그래피 시스템. 13단계 폰트 스케일, 시스템 폰트 스택. Lighthouse 성능 100/100에 기여하는 폰트 로딩 지연 제로. 

  5. Cagan, Marty, Inspired: How to Create Tech Products Customers Love, Wiley, 2017. 제품-시장 적합성과 성급한 최적화. 

  6. Curtis, Nathan, “Adopting Design Systems,” EightShapes, 2018. 성장하는 기업에서의 디자인 부채 측정. 

  7. 저자의 토큰 인벤토리. critical.css에 정의된 6개 카테고리에 걸친 41개 CSS 커스텀 프로퍼티. 

  8. Frost, Brad, Atomic Design, 자가 출판, 2016. 점진적 컴포넌트 추상화 방법론. 

  9. 저자의 접근성 접근 방식. 토큰 정의에 내장된 WCAG AAA 대비 (primary 21:1, secondary 13.7:1, tertiary 8.4:1).