Impeccable 디자인 원칙 & 안티패턴 가이드

Impeccable이 AI에게 주입하는 7가지 디자인 레퍼런스와, AI Slop을 방지하기 위한 구체적 안티패턴 목록입니다.


7가지 디자인 레퍼런스

Impeccable의 frontend-design 스킬은 7개의 레퍼런스 파일로 구성됩니다. 각 레퍼런스는 AI가 코드를 생성할 때 참조하는 디자인 원칙을 담고 있습니다.

1. Typography (타이포그래피)

타이포그래피는 UI의 가독성과 시각적 계층을 결정하는 가장 중요한 요소입니다.

  • 모듈러 스케일: 1.25(Major Third) 또는 1.333(Perfect Fourth) 비율로 일관된 크기 체계를 구성합니다. 임의의 px 값을 나열하지 않습니다
  • 폰트 페어링: 헤딩과 본문에 서로 다른 서체를 조합할 때, 대비(contrast)와 조화(harmony)를 동시에 고려합니다. Sans-serif + Serif 조합이 기본입니다
  • OpenType 기능: font-feature-settings를 활용하여 올드스타일 숫자(onum), 리가처(liga), 커닝(kern) 등을 적절히 사용합니다
  • 유동적 사이징: clamp() 함수로 뷰포트에 따라 자연스럽게 스케일되는 폰트 크기를 구현합니다. 미디어 쿼리 브레이크포인트마다 하드코딩하지 않습니다
1
2
3
/* 유동적 타이포그래피 예시 */
font-size: clamp(1rem, 0.5rem + 1.5vw, 1.5rem);
line-height: clamp(1.4, 1.2 + 0.5vw, 1.6);

2. Color & Contrast (색상과 대비)

색상은 브랜드 아이덴티티와 접근성을 동시에 만족해야 합니다.

  • OKLCH 색상 공간: sRGB 대신 OKLCH를 사용하면 지각적으로 균일한(perceptually uniform) 색상 팔레트를 생성할 수 있습니다. 채도와 명도 조절이 직관적입니다
  • 틴티드 뉴트럴(Tinted Neutrals): 순수한 그레이 대신, 브랜드 색상을 미세하게 섞은 뉴트럴을 사용합니다. gray-500 대신 브랜드 블루가 살짝 들어간 뉴트럴이 훨씬 정교해 보입니다
  • 다크모드: 단순히 색상을 반전하지 않습니다. 명도(Lightness)를 조절하되, 채도(Chroma)는 낮추고, 배경은 순수 검정이 아닌 매우 어두운 회색을 사용합니다
  • 접근성 (WCAG AA): 일반 텍스트는 최소 4.5:1, 대형 텍스트는 3:1의 대비율을 보장합니다. 색상만으로 정보를 전달하지 않습니다
1
2
3
4
/* OKLCH 기반 색상 팔레트 예시 */
--color-primary: oklch(55% 0.15 250);
--color-surface: oklch(98% 0.005 250); /* 틴티드 뉴트럴 */
--color-surface-dark: oklch(15% 0.005 250); /* 다크모드 배경 */

3. Spatial Design (공간 디자인)

일관된 간격 시스템은 UI의 질서와 리듬을 만듭니다.

  • 스페이싱 시스템: 4px 또는 8px 기반 그리드를 사용합니다. 모든 여백, 패딩, 갭은 이 시스템의 배수로 설정합니다(4, 8, 12, 16, 24, 32, 48, 64…)
  • 그리드 시스템: CSS Grid를 활용하여 콘텐츠 영역을 체계적으로 분할합니다. 12컬럼 그리드가 범용적이며, subgrid로 중첩 그리드를 깔끔하게 처리합니다
  • 비대칭 레이아웃: 모든 것을 정중앙에 배치하지 않습니다. 의도적 비대칭은 시각적 긴장감과 흥미를 만들어냅니다. 골든 레이시오(1:1.618)를 참고합니다
  • Container Queries: 뷰포트가 아닌 컨테이너 크기에 따라 레이아웃을 조절합니다. 재사용 가능한 컴포넌트에 필수입니다
1
2
3
4
5
6
7
/* 스페이싱 시스템 예시 */
--space-1: 0.25rem; /* 4px */
--space-2: 0.5rem; /* 8px */
--space-3: 0.75rem; /* 12px */
--space-4: 1rem; /* 16px */
--space-6: 1.5rem; /* 24px */
--space-8: 2rem; /* 32px */

4. Motion Design (모션 디자인)

모션은 상태 변화를 사용자에게 자연스럽게 전달합니다.

  • 이징 커브: linearease를 피하고, 용도별 커스텀 이징을 사용합니다. 진입은 ease-out, 퇴장은 ease-in, 상태 변화는 ease-in-out이 기본입니다
  • 스태거링(Staggering): 리스트 항목이 순차적으로 나타나도록 딜레이를 줍니다. animation-delaycalc(var(--index) * 50ms) 패턴으로 구현합니다
  • Reduced Motion: prefers-reduced-motion 미디어 쿼리를 반드시 존중합니다. 모션을 완전히 제거하거나, 지속시간을 대폭 줄입니다
  • 성능 원칙: 애니메이션은 transformopacity만 사용합니다. width, height, top, left 등을 애니메이션하면 레이아웃 리플로우가 발생합니다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* 모션 디자인 예시 */
--ease-out: cubic-bezier(0.16, 1, 0.3, 1);
--ease-in: cubic-bezier(0.7, 0, 0.84, 0);
--duration-fast: 150ms;
--duration-normal: 250ms;

@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}

5. Interaction Design (인터랙션 디자인)

사용자가 UI와 상호작용하는 모든 순간을 세심하게 설계합니다.

  • 폼 디자인: 레이블은 항상 입력 필드 위에 배치합니다. 플레이스홀더를 레이블 대용으로 사용하지 않습니다. 실시간 유효성 검사는 사용자가 입력을 마친 후(blur)에 표시합니다
  • 포커스 상태: 모든 인터랙티브 요소에 명확한 포커스 링을 제공합니다. outline: none으로 제거하지 않습니다. focus-visible을 사용하여 키보드 사용자에게만 표시할 수 있습니다
  • 로딩 패턴: 스켈레톤 UI를 기본으로 사용합니다. 스피너는 최후의 수단입니다. 낙관적 업데이트(optimistic update)를 적극 활용합니다
  • 키보드 네비게이션: 모든 기능이 키보드만으로 접근 가능해야 합니다. 탭 순서가 논리적이어야 하고, 커스텀 컴포넌트는 ARIA 역할과 키보드 핸들러를 구현합니다

6. Responsive Design (반응형 디자인)

모든 화면 크기에서 최적의 경험을 제공합니다.

  • 모바일 퍼스트: 작은 화면부터 스타일을 작성하고, min-width 미디어 쿼리로 확장합니다. 데스크톱부터 시작하면 모바일에서 불필요한 오버라이드가 쌓입니다
  • Fluid Design: 고정 브레이크포인트 대신 clamp(), min(), max() 함수로 연속적으로 반응하는 레이아웃을 구현합니다
  • Container Queries: 미디어 쿼리가 뷰포트 기준인 반면, 컨테이너 쿼리는 부모 요소 기준입니다. 컴포넌트의 재사용성을 높여줍니다
  • 터치 타겟: 모바일 터치 타겟은 최소 44x44px을 보장합니다. 이보다 작으면 오탭이 빈번하게 발생합니다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* 반응형 디자인 예시 */
.container {
width: clamp(320px, 90vw, 1200px);
padding: clamp(1rem, 3vw, 3rem);
}

/* Container Queries */
.card-container {
container-type: inline-size;
}
@container (min-width: 400px) {
.card {
flex-direction: row;
}
}

7. UX Writing (UX 라이팅)

인터페이스의 모든 텍스트는 사용자의 행동을 돕습니다.

  • 버튼 레이블: “확인”, “제출” 대신 행동을 구체적으로 명시합니다. “변경사항 저장”, “계정 생성”, “결제 진행” 등 사용자가 클릭 결과를 예측할 수 있어야 합니다
  • 에러 메시지: “오류가 발생했습니다” 대신, 무엇이 잘못되었고 어떻게 해결하는지 안내합니다. "이메일 형식이 올바르지 않습니다. example@email.com 형식으로 입력해주세요"가 좋은 예시입니다
  • 빈 상태(Empty State): 데이터가 없을 때 단순히 "데이터 없음"이 아니라, 다음 행동을 유도합니다. "아직 프로젝트가 없습니다. 첫 번째 프로젝트를 만들어보세요"가 올바른 패턴입니다
  • 마이크로카피: 툴팁, 도움말 텍스트, 성공 메시지 등 작은 텍스트도 일관된 톤을 유지합니다. 브랜드 보이스 가이드라인을 따릅니다

AI Slop 안티패턴 목록

AI가 프론트엔드 코드를 생성할 때 빈번하게 발생하는 안티패턴입니다. Impeccable의 /audit 명령어가 이런 패턴을 자동으로 탐지합니다.

Typography 안티패턴

DO DON’T
프로젝트에 맞는 서체를 의도적으로 선택합니다 Inter, Roboto, Arial을 아무 생각 없이 기본값으로 사용합니다
모듈러 스케일로 일관된 크기 체계를 구성합니다 임의의 px 값을 그때그때 지정합니다
코드 표시 등 실제 용도에 맞게 모노스페이스를 사용합니다 모노스페이스를 “기술적/해커 느낌” 연출 목적으로 남용합니다
line-height를 서체와 크기에 맞게 세밀히 조절합니다 모든 텍스트에 line-height: 1.5를 일괄 적용합니다

Color 안티패턴

DO DON’T
틴티드 뉴트럴로 정교한 배경/텍스트 색상을 사용합니다 순수 검정(#000000)과 순수 흰색(#ffffff)을 사용합니다
프로젝트 브랜드에 맞는 고유한 팔레트를 설계합니다 AI가 기본으로 생성하는 cyan-on-dark, 보라-파랑 그라데이션을 그대로 사용합니다
컬러 배경 위 텍스트의 대비율(4.5:1)을 확인합니다 회색 텍스트를 컬러 배경 위에 올려 가독성을 해칩니다
색상은 의미 전달과 계층 구분에 사용합니다 그라데이션 텍스트로 “화려한” 느낌을 연출합니다
의도적으로 제한된 색상 팔레트를 유지합니다 5가지 이상의 액센트 컬러를 무분별하게 사용합니다

Layout 안티패턴

DO DON’T
콘텐츠 성격에 맞는 레이아웃 패턴을 선택합니다 모든 것을 카드(.card)로 감쌉니다
계층 구조를 시각적 여백과 타이포그래피로 표현합니다 카드 안에 카드를 중첩하여 불필요한 시각적 노이즈를 만듭니다
콘텐츠에 충분한 여백(whitespace)을 제공합니다 화면을 빈틈없이 채우려고 합니다
자연스러운 문서 흐름(document flow)을 존중합니다 모든 요소에 position: absolute를 남발합니다

Motion 안티패턴

DO DON’T
ease-out, ease-in-out 등 자연스러운 이징을 사용합니다 bounce, elastic 이징을 사용합니다
상태 전환에만 짧은 애니메이션을 적용합니다 모든 요소에 호버 애니메이션을 추가합니다
transformopacity만 애니메이션합니다 width, margin, padding을 애니메이션합니다
prefers-reduced-motion을 존중합니다 모션 설정을 무시합니다

Dark Mode 안티패턴

DO DON’T
라이트모드를 기본으로, 다크모드를 옵션으로 제공합니다 다크모드를 글로잉 액센트(neon glow)와 함께 기본값으로 사용합니다
다크모드에서 채도를 낮추고 명도 차이를 줄입니다 라이트모드의 색상을 단순히 반전합니다
매우 어두운 회색(oklch(15% ...))을 배경으로 사용합니다 순수 검정(#000)을 배경으로 사용합니다

종합 안티패턴

DO DON’T
의미 있는 요소만 추가합니다 장식적 그라데이션, 불필요한 보더 라디우스, 과한 그림자를 남발합니다
적은 요소로 최대한의 효과를 냅니다 "비어 보인다"는 이유로 장식을 추가합니다
디자인 시스템의 토큰을 일관되게 사용합니다 하드코딩된 값을 컴포넌트마다 다르게 설정합니다

출처: github.com/pbakaus/impeccable | impeccable.style

공유하기