# antipatterns.md — 점검 후보 AI가 만든 티는 **못 만들어서** 나는 게 아니라 결정을 설명·검증하지 않을 때 난다. 보라 그라디언트, Inter, 3열 아이콘 카드, `rounded-2xl shadow-lg`, "Get Started"는 반복될 수 있는 출발점이다. 존재만으로 미결정이라고 단정하지 않고, 브리프·프로젝트 계약·실제 렌더로 판단한다. 프리플라이트에서 이 문서를 훑어 후보를 찾는다. 검출은 실패가 아니다. 브리프·프로젝트 계약·실제 렌더를 대조해 유지·수정·제거를 결정하고 그 근거를 남긴다. **Simplicity 는 Minimalism 이 아니다** [SKILL-APPLE-DESIGN]. 요소를 지우는 것 자체가 단순함을 만들지는 않는다. **관찰 후보** — 정보·행동이 사라져 과업이 더 어려워졌다면 그것은 단순화가 아니라 손실이다. 무엇을 남길지는 과업이 정하고, 화면에 무엇이 없다는 사실만으로 단순하다고 주장하지 않는다. 아래 지문들도 같은 기준으로 읽는다 — 비어 보이거나 장식이 없다고 해서 자동으로 통과가 아니고, 요소가 많다고 자동으로 실패도 아니다. --- ## 0. 먼저 보는 반복 후보 원자료와 재현 가능한 표본이 없는 빈도 수치는 규칙의 근거가 될 수 없다. 아래 항목은 흔한 기본값을 찾는 검색 후보이며, 색·대문자·번호가 존재한다는 사실만으로 실패가 아니다. | 후보 | 확인할 질문 | |---|---| | 보라·인디고 CTA | 브랜드 팔레트·상태 구분·대비·목표 행동을 설명하는가? | | 전체 대문자 라벨 | 언어·가독성·정보 위계에 맞는가? | | 번호 매긴 단계 | 사용자가 실제 순서로 수행하는 과업인가? | --- ## 1. 컬러 다크·그라디언트·강한 색은 그 자체로 실패가 아니다. 화면 역할, 브랜드, 대비, 실제 기기 렌더에서 이유를 설명할 수 있는지 점검한다. | 지문 | 왜 문제 | 대신 | |---|---|---| | **다크 모드를 브리프 근거 없이 기본값으로** (`bg-slate-900`, `#0B0B0F`) | 대상 환경·브랜드·콘텐츠에 맞는지 설명하지 못하면 선택이 기본값처럼 보일 수 있다 | 라이트·다크의 역할 토큰, 실제 기기 대비, 사용자 설정·테마 전환 필요성을 비교한다 | | **보라→파랑 그라디언트 히어로** (`from-purple-600 to-blue-500`, `#6366f1→#a855f7`) | 제품·브랜드·정보 역할과 무관하면 배경 장식만 남을 수 있다 | 단색·동일 hue 변화·다중 hue를 같은 콘텐츠에서 비교하고, 텍스트 대비와 행동 위계를 확인한다 | | **라벤더 퍼플이 어디에나** (`#a78bfa`, `#c4b5fd`) | 맥락 없는 반복은 기본값처럼 보일 수 있음 | 브랜드·접근성·표면 역할을 설명하고 실제 렌더에서 위계를 확인 | | **네온 온 다크** — 시안(`#22d3ee`)·바이올렛이 검정 위에서 발광 | 색의 의미·대비·주변광에서의 읽기 비용을 확인해야 한다 | 상태·행동·콘텐츠 역할과 연결하고, 저채도/고채도·명도 대비를 실제 기기에서 비교한다 | | **컬러 글로우** (`box-shadow: 0 0 80px rgba(139,92,246,.5)`) | 깊이·계층·상태를 글로우만으로 표현하면 의미가 모호해질 수 있다 | 그림자·경계·여백·글로우 후보 중 실제 계층과 성능을 가장 잘 드러내는 것을 선택한다 | | **히어로 뒤 방사형 그라디언트 오브·헤일로** | 메시지·제품 증거·구도보다 장식이 먼저 읽히는지 점검한다 | 배경·제품 화면·타입 중심 구도를 같은 콘텐츠로 비교한다 | | **순백 `#ffffff` / 순흑 `#000000`** 을 배경·텍스트로 | 극단값이 브랜드·매체·환경에 맞는지 점검한다 | 대상 기기·주변광·텍스트 대비와 실제 렌더의 눈부심을 확인한다. 색 자체를 실패로 취급하지 않는다. 출처: [WCAG 2.2 Contrast](https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html)와 프로젝트 브리프 | | **Tailwind 기본 토큰 그대로** (`slate-900`, `gray-500`, `emerald-500`) | 역할·브랜드·상태가 토큰 이름과 값에서 드러나는지 점검한다 | 기본 토큰을 유지·확장·교체할 수 있다. 의미 역할과 실제 렌더 근거를 기록한다 | | **코드에서 색 이름을 직접 호출** (`purple-500`) | 색이 역할을 못 가짐 | 의미 토큰: `--color-action-primary`, `--color-surface-elevated`, `--color-text-secondary` | | **그라디언트 텍스트** (`background-clip: text`) | 작은 크기·이미지 배경·공유 이미지에서 읽기와 fallback을 점검한다 | 단색·그라디언트·다른 위계 수단을 비교하고, 실제 export와 대비를 확인한다 | | **크림/베이지(`#FDF8F3`)를 "고급"의 기본값으로** | 보라를 대체한 신종 슬롭 | 크림을 쓸 거면 왜 크림인지 브리프와 연결하고 텍스트·액센트를 그에 맞춰 재설계 | | **여러 hue가 경쟁함** | 행동·상태·정보의 우선순위가 색 때문에 흐려질 수 있다 | 색 역할과 화면 면적을 실제 상태에서 비교한다. hue 수·60/30/10은 출발 가설일 뿐 통과 기준이 아니다 | | **다크에서 본문 대비 미달** | 적용 WCAG 성공 기준을 실제 배경 합성값으로 충족하는지 점검한다 | `#0f172a` 위 `#94a3b8`의 WCAG 대비는 약 **6.96:1**이므로 미달 사례가 아니다. WCAG 2.2 AA 본문 판정에는 contrast ratio를 사용하며 APCA는 이를 대체하지 않는다. 반투명·이미지 배경은 실제 렌더에서 계산한다. 출처: [WCAG 2.2 Contrast](https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html) | | **웜크림 배경 + 하이컨트라스트 세리프 + 테라코타 액센트** (배경 `#F4F1EA` 부근, 세리프 디스플레이, 액센트 `#D97757` 부근) | **관찰 후보** — 지금 AI 생성 디자인이 가장 자주 수렴하는 클러스터 중 하나다. `#D97757` 부근은 Anthropic 자체 상호작용 액센트와 겹쳐, 사용자 브리프에서는 Claude 계열 도구가 만들었다는 티로 먼저 읽힐 수 있다(자기지시적 경고) | 이 조합을 브랜드·업종 근거로 골랐는지 확인한다. 근거가 없으면 다른 웜톤이나 다른 액센트 hue를 브리프에서 다시 끌어온다. 브리프가 정확히 이 룩을 요구하면 그대로 쓴다. 출처: [SKILL-FRONTEND-DESIGN] | | **거의 검정 배경 + 단일 비비드 애시드그린·버미리언 액센트** | **관찰 후보** — 대비되는 두 번째 흔한 클러스터. 다크 배경 자체는 문제가 아니지만 "네온 액센트 하나"라는 조합이 브랜드와 무관하게 반복된다 | 브랜드·상태 역할과 실제 렌더 대비로 액센트 선택의 근거를 남긴다. 출처: [SKILL-FRONTEND-DESIGN] | | **뷰 하나에 여러 요소가 동시에 채색됨** (버튼·배지·아이콘·텍스트 링크가 한 화면에서 전부 강조색) | **관찰 후보** — 강조색이 여러 곳에 흩어지면 "지금 할 행동"을 색만으로 구분하기 어려워진다 | 뷰당 주요 행동 하나에만 채운 강조색을 쓰고, 나머지는 중성 톤이나 다른 상태 표시로 구분한다. 색 체계 상세는 `references/color.md`. 출처: [SKILL-BETTER-COLORS] | --- ## 2. 타이포그래피 | 지문 | 왜 문제 | 대신 | |---|---|---| | **Inter 선택** (특히 중앙 정렬 히어로) | 서체가 언어·정보 밀도·브랜드 톤에 맞는지 점검한다 | 후보 서체와 숫자·한글·긴 제목을 같은 viewport에서 비교하고, 라이선스·fallback metric을 기록한다. Inter 자체를 실패로 취급하지 않는다. 출처: `references/typography.md`와 프로젝트 브리프 | | **Space Grotesk + Instrument Serif + Geist 조합** | 조합이 실제 위계와 브랜드 톤을 만드는지 점검한다 | 서체 수가 아니라 역할·fallback·가독성을 실제 렌더에서 비교한다. 조합의 구성원 수만으로 실패시키지 않는다. 출처: `references/typography.md` | | **헤드라인 한 단어만 세리프 이탤릭** (`Build better products`) | 강조가 브랜드 언어·문장 의미·읽기 순서를 실제로 돕는지 점검한다 | 이탤릭·줄바꿈·크기·색·여백을 같은 문구에서 비교하고 선택 이유를 기록한다 | | **페이지 전체에 폰트 패밀리 1개** | 서체 수와 무관하게 제목·본문·데이터의 위계가 읽히는지 점검한다 | 한 패밀리 또는 여러 패밀리를 같은 콘텐츠·viewport·확대 상태에서 비교하고, 역할과 fallback을 기록한다. 출처: `references/typography.md` | | **타입 스케일이 평평해 보임** | 최대/본문 배율이 아니라 실제 과업의 위계·읽기 폭·언어 적합성을 점검한다 | 제목·본문·보조 정보의 역할과 렌더된 우선순위를 비교한다. 배율·단계 수는 관찰값으로 기록하되 최대/본문 4배나 특정 비율을 보편 통과 조건으로 쓰지 않는다. 출처: `references/design-foundations.md`, `references/typography.md` | | **타입 스케일 단계가 많음** | 같은 역할에 여러 크기가 섞이면 읽기 순서가 흐려질 수 있다 | 각 단계에 역할을 이름 붙이고, 대표 폭·확대 상태에서 실제 위계를 확인한다. 단계 수 자체로 실패시키지 않는다 | | **히어로 = pill 배지 + 거대 헤드라인** (`✨ Now in beta` + H1) | 배지가 실제 상태·시간성·제약을 설명하는지 점검한다 | 배지·문장 안 상태·내비 상태·생략을 비교하고, 첫 행동에 필요한 경우만 남긴다 | | **`_01_ _02_ _03_` 장식 번호 라벨** | 에디토리얼 흉내인데 구조는 없음 | 번호가 순서를 의미할 때만 | | **본문/헤드라인 자간이 읽기를 방해함** | 글꼴·언어·크기·폭에 따라 글리프 충돌, 단어 인식, 줄바꿈이 달라진다 | 0, 양수, 음수 자간을 대표 문구·지원 viewport·200% 확대에서 비교한다. 단일 `em` 수치를 보편 기준으로 쓰지 않는다 | | **본문 크기·행간이 과업에 맞지 않음** | 작은 글자나 촘촘한 행간은 읽기·확대·오류 복구 비용을 높일 수 있다 | 글꼴·언어·콘텐츠 밀도별 후보를 실제 기기·200% 확대·긴 문단에서 검증한다. 16px이나 고정 line-height를 보편 하한으로 선언하지 않는다 | | **모노스페이스를 장식으로 사용** | 코드·데이터 외 용도에서도 의미·가독성·브랜드 톤을 돕는지 점검한다 | 대상 언어·크기·대비·긴 문자열을 실제 렌더에서 비교한다. 모노스페이스 자체나 용도만으로 실패시키지 않는다. 출처: `references/typography.md` | --- ## 3. 레이아웃 · 구조 | 지문 | 왜 문제 | 대신 | |---|---|---| | **표준 골격**: 히어로 → 3열 피처 → 로고월 → 요금제 → FAQ → 푸터 | shadcn/ui 예제·Tailwind UI·Vercel 템플릿의 순서 그대로 | 섹션 순서를 브리프의 설득 논리로 재배열. 예: 문제 제시 → 실제 사용 화면 → 반론 처리 → 가격 | | **중앙 정렬 히어로** (텍스트 가운데 + CTA 2개 + 아래 스크린샷) | 목표 행동·읽기 폭·브랜드의 구도를 돕는지 점검한다 | 중앙·비대칭·좌측 정렬 후보를 같은 콘텐츠와 viewport에서 비교하고, 선택 근거를 기록한다. 중앙 정렬 자체를 실패로 취급하지 않는다. 출처: `references/design-foundations.md`, 프로젝트 브리프 | | **균등 카드 grid** | 항목 중요도·비교 과업·작은 폭 재배치가 균등 구조와 맞는지 점검한다 | 3열/비대칭/목록을 콘텐츠와 대표 과업에서 비교한다 | | **아이콘 중심 피처 카드** | 아이콘이 실제 기능 이해를 돕는지, 이미지·수치·UI 증거가 더 나은지 점검한다 | 아이콘 위치·라벨·실제 제품 조각을 비교하고, 전체 카드 hitbox와 접근 가능한 이름을 확인한다 | | **컬러 스트립·중첩 카드** | 경계와 깊이가 실제 정보 묶음을 나타내는지 점검한다 | 여백·선·표면·중첩을 비교한다. 중첩 횟수와 border 폭은 통과 기준이 아니다 | | **근거 없는 지표 배너** (`10,000+ users · 99.9% uptime · 4.9★`) | 검증할 수 없는 수치는 사실처럼 제시하면 안 된다 | 출처·측정 조건·기간이 있는 수치만 쓰고, 수가 여러 개여도 목적에 맞는 묶음과 출처를 제시한다 | | **여백 리듬이 정보 관계를 가림** | 같은/다른 간격이 관련성과 우선순위를 드러내지 못할 수 있다 | 토큰 수·비율을 고정하지 말고, 실제 콘텐츠와 회색조 렌더에서 그룹·섹션 관계를 확인한다 | | **벤토 그리드를 기본 선택지로** | 타일 크기 차이가 정보 위계나 과업을 설명하지 못할 수 있다 | 벤토·단순 목록·비교 grid를 콘텐츠와 작은 폭 재배치에서 비교한다. 연도별 트렌드 주장은 근거가 아니다 | | **콘텐츠 여백·본문 폭이 읽기를 방해함** | viewport·글꼴·언어·확대에 따라 줄 길이와 행동 영역이 달라진다 | gutter와 measure 후보를 320px·200% 확대·넓은 폭에서 렌더해 검증한다. 고정 px·ch 범위는 출발값일 뿐이다 | | **푸터가 링크 4열 + 소셜 아이콘 + 카피라이트뿐** | AI가 가장 성의 없이 만드는 곳 | 실제 정보(연락처, 주소, 사업자 정보)를 넣어라. 링크가 4개뿐이면 4열로 만들지 마라 | | **브로드시트 클러스터** (헤어라인 룰 전체, `border-radius: 0` 전면 적용, 신문형 조밀 컬럼) | **관찰 후보** — 세 번째로 흔한 AI 생성 클러스터. 헤어라인·radius 0 자체가 나쁜 것은 아니지만 브랜드·매체 근거 없이 반복되면 에디토리얼 흉내로 읽힌다 | 브랜드·콘텐츠 밀도와 연결해 근거를 남기고, 좁은 컬럼에서 실제 가독성을 검증한다. 출처: [SKILL-FRONTEND-DESIGN] | | **섹션마다 페이드업 리빌 + 모든 카드에 호버 전환** (예외 없이 전부) | **관찰 후보** — 섹션 단위 등장과 카드 호버를 빠짐없이 걸면 "하나의 오케스트레이션된 모먼트"가 아니라 흩어진 장식 모션의 기본값으로 읽힌다 | 모션은 중요한 변화 한둘에만 걸고 나머지는 정적으로 둔다. `references/motion.md`의 저비용 기본·결정 표와 일관되게 선택한다. 출처: [SKILL-FRONTEND-DESIGN] | | **본문 전체를 justify 정렬** | **관찰 후보** — 자동 하이픈 없이 본문 전체를 양쪽 정렬하면 단어 사이 공백이 불규칙해져 읽기가 나빠질 수 있다. 한글은 어절 단위 줄바꿈이라 영향이 다르게 나타난다 | 왼쪽 정렬을 기본으로 하고, justify가 필요하면 하이픈네이션과 좁은 컬럼에서 실제 렌더로 확인한다. 세부는 `references/typography.md`. 출처: [SKILL-BETTER-TYPE] | --- ## 4. 컴포넌트 | 지문 | 왜 문제 | 대신 | |---|---|---| | **기본 radius·shadow·padding 조합을 그대로 사용** | 컴포넌트 역할·밀도·브랜드 표면이 토큰과 맞는지 점검한다 | radius·선·그림자·여백 후보를 실제 상태에서 비교하고, 역할 토큰으로 기록한다 | | **여러 깊이 표현을 겹침** | 경계·그림자·표면 차이가 같은 계층을 중복 설명하는지 점검한다 | 하나 또는 여러 단서를 쓸 수 있다. 포커스·상태·인접 표면에서 계층이 읽히는지 검증한다 | | **글래스모피즘 전면 사용** (`backdrop-blur` 카드 다수) | backdrop filter의 성능·대비·reduced-transparency 대안이 필요할 수 있다 | 대상 기기의 performance, fallback 표면, 텍스트 대비를 측정하고 역할이 있을 때만 채택한다 | | **이모지를 아이콘 대신** (🚀 ⚡ 🎯 ✨) | 의미·locale·플랫폼 렌더링·접근 가능한 이름이 역할을 돕는지 점검한다 | 이모지·아이콘 세트·텍스트를 실제 대상과 보조기술에서 비교한다 | | **여러 CTA가 같은 무게로 경쟁함** | 사용자가 다음 행동을 선택하기 어려울 수 있다 | 행동 우선순위·위험·되돌림에 맞춰 주/보조 CTA와 배치를 정하고 과업 테스트한다 | | **로고월·후기·FAQ·요금제 템플릿** | 사실·질문·가격 구조가 현재 제품의 증거인지 점검한다 | 검증 가능한 출처와 실제 고객 질문·요금 조건을 사용한다. 개수·열 수·배지 존재로 실패시키지 않는다 | | **펄스 애니메이션 상태 점** (초록 원 깜빡임 + "All systems operational") | 정적 정보에 장식 애니메이션 | 상태가 실제로 바뀔 때만 | | **자동 스크롤 마퀴** (로고·후기·태그가 끝없이 흐름) | 읽기·움직임 민감도·입력과 충돌할 수 있음 | 목적·정지 수단·감소 모션·성능을 검증하고, 정적 그리드 또는 페이지네이션과 비교 | | **hover 상태가 과업을 돕지 않음** | 포인터 반응이 행동 가능성·현재 상태·위험을 설명하지 못할 수 있다 | 링크·카드·버튼의 상태를 역할별로 설계하고, touch/keyboard에서도 같은 핵심 단서를 제공한다 | | **편집 불가 히어로 카피 뒤 깜빡이는 커서 `|`** | 타이핑 흉내. 정보 없음 | 삭제 | | **균일 radius + 흐린 동일 회색 그림자 카드 키트** (모든 카드가 같은 `border-radius`, 같은 `rgba(0,0,0,.1)` 그림자) | **관찰 후보** — SaaS 카드 키트 클러스터. 콘텐츠를 위계 없이 동일 규격 카드로 자르고 장식용 그라디언트 워시를 더하는 조합이 반복된다 | 카드 역할·중요도에 따라 radius·그림자·여백을 다르게 주거나, 카드가 아닌 다른 구조를 검토한다. 깊이 체계는 `references/elevation.md`. 출처: [SKILL-FRONTEND-DESIGN] | | **가운뎃점으로 이은 메타 문자열** (`A · B · C`) | **관찰 후보** — 어떤 주제에도 나타나는 템플릿 장식. 항목이 실제로 같은 범주인지, 구분자가 정보를 돕는지 점검한다 | 항목 성격이 다르면 구분자를 바꾸거나 줄을 나눈다. 실제 같은 범주라면 가운뎃점 자체는 문제가 아니다. 출처: [SKILL-FRONTEND-DESIGN] | | **버튼·링크 텍스트 뒤 `→` 접미사 남용** | **관찰 후보** — 모든 CTA·링크에 화살표를 붙이면 정보가 아니라 장식이 된다 | 실제로 다음 화면·다운로드·외부 이동처럼 방향성이 있는 경우에만 쓰고, 나머지는 텍스트만으로 충분한지 확인한다. 출처: [SKILL-FRONTEND-DESIGN] | | **작은 데이터 라벨에 장식용 모노스페이스** (자릿수 정렬이 의미 없는 라벨에 "테크 느낌"으로만 사용) | **관찰 후보** — §2의 모노스페이스 규칙(본문·제목 맥락)과 달리, 여기서는 실제 tabular 데이터인지부터 먼저 구분한다 | 숫자·코드·ID처럼 자릿수 정렬이 의미 있는 데이터에만 모노스페이스를 쓰고, 장식이면 본문 서체로 되돌린다. 출처: [SKILL-FRONTEND-DESIGN] | | **컨트롤처럼 보이는 정적 요소, 정적처럼 보이는 컨트롤** | **관찰 후보** — 배경·테두리·배치 구역 같은 시각 신호가 없는 상호작용 요소는 컨트롤로 보이지 않는다. 반대로 클릭할 수 없는 배지·라벨이 버튼처럼 생기면 헛클릭을 모은다 | 상호작용 요소마다 일관된 시각 신호(배경·테두리·배치 구역)를 주고, 비활성 정보는 그 신호를 빼서 구분한다. 출처: [SKILL-BETTER-LAYOUT] | | **테마화하지 않은 브라우저 표면** (`::selection`, `caret-color`, 스크롤바 색) | **관찰 후보** — 직접 그리지 않은 부분도 디자인의 일부다. 팔레트로 테마화하지 않으면 브라우저 기본값(파란 선택 영역, 회색 스크롤바)이 그대로 남아 "조립됐다"는 티가 가장 싸게 난다 | `::selection{background;color}`와 `caret-color`로 선택·캐럿을 팔레트에 맞춘다. `scrollbar-color`(2026-09-24 기준 Baseline Newly available — Chrome·Edge·Firefox·Safari 최신 버전은 지원하나 아직 Widely는 아니다)로 스크롤바를 테마화하고, 미지원 브라우저에서는 기본 스크롤바로 자연 열화되는지 확인한다. 출처: [SKILL-IMPECCABLE], [WEB-BASELINE] | | **비밀번호·OTP 필드의 붙여넣기 차단** (`onpaste=`, `addEventListener('paste', ...)`로 `preventDefault`) | **하드 게이트** — 비밀번호 관리자·2FA 자동 입력과 충돌해 WCAG 3.3.8(Accessible Authentication)이 요구하는, 인지 부담 없는 인증 경로를 막는다 | 붙여넣기를 막지 않는다. 진짜 `