Galloping Academy

승마 아카데미 운영 어드민의 디자인 시스템. 첫인상이 아니라 매일 8시간 켜두는 도구의 100번째 진입 피로도를 설계한다 — 예측 가능성·낮은 시각 소음·4의 배수 정렬 위에 단 한 점의 보라.

React 19 + React Compiler TanStack Router · Query Tailwind v4 (CSS-first) 디자인 시스템 v3 라이트 전용 · WCAG AA 11 screens · 실제 구현 1:1
01 — 컨셉

왜 이렇게 생겼나

미감보다 운영 적합성. 6개의 결정이 모든 화면을 지배한다.

01
운영툴 도메인
소비자 앱의 첫인상이 아니라, 원장·코치가 매일 8시간 켜두는 도구의 100번째 진입 피로도를 설계한다. 화려함 대신 예측 가능성, 장식 대신 정보 밀도.
02
4의 배수 그리드
모든 height·padding·radius·gap을 4의 배수로 강제. 비-4 값이 누적되면 1~2px씩 어긋나 "자동 생성된 듯한" 정렬 붕괴가 생긴다. 4-mult가 그것을 원천 차단한다. font-size만 예외.
03
단일 보라 모먼트
#6B00FF는 페이지당 최대 2회, 표면의 8–12%만 — active nav·취미 티어·차트 한 선. 그라디언트·글로우·메시는 전면 금지. 한 점이 강조로 작동하려면 나머지가 무채색이어야 한다.
04
Hairline = inset shadow
auto-height 컨테이너에 직접 border를 두면 border-box가 1px를 흡수 못 해 렌더 높이가 4-mult를 깬다. 시각적으로 동일한 box-shadow: inset 0 0 0 1px로 그려 레이아웃에 0 영향.
05
medium-gray 사이드바
순흑 사이드바는 캔버스(#DFDFD7)와 명도차 84%로 본문보다 먼저 시선을 끈다. #5B5B59(명도차 ~60%)로 낮춰 사이드바를 배경에 물리고 본문에 주도권을 준다.
06
라이트 전용 · WCAG AA
다크 모드 미지원 — 운영 환경을 단일 톤으로 고정. 모든 텍스트는 캔버스/서피스 위에서 WCAG 2.1 AA(본문 4.5:1, UI 3:1) 이상을 통과한다.
02 — 컬러

토큰과 그 이유

값은 src/index.css:root와 1:1. 모든 색이 데이터 인코딩 또는 상태 의미를 가지며, 장식 목적의 색은 없다.

Surface순백 대신 살짝 데운 회백 — 장시간 응시 눈부심 완화
--canvas
#DFDFD7
앱 배경(따뜻한 오프그레이)
--surface
#FFFFFF
카드·패널·시트 표면
Sidebar명도차 60%로 본문에 양보하는 다크 표면
--sidebar
#5B5B59
사이드바 배경(medium-gray)
--sidebar-border
#4A4A48
사이드바 경계
Ink — 3-tier순흑(#000) 대신 따뜻한 다크. 대비를 단계로 통제
--ink
#141413
본문 텍스트
--text-secondary
#5C5658
보조 텍스트 · 4.7:1
--text-caption-color
#6F6A66
캡션 · 3.1:1 (UI 전용)
Border외곽선과 행 분리선을 분리
--border
#CFCFC4
컨테이너 외곽
--border-s
#D5D5CB
표·리스트 행 분리
Brand페이지당 ≤2회, 표면 8–12%만 등장하는 단일 강조
--brand
#6B00FF
active nav · 취미 티어 · 차트 1선
--brand-tint
#F0E6FF
취미 뱃지·블록 배경
Status — base흰 글씨 페어(KPI 델타·도트·hairline)
--ok
#1F8552
성공·완료·증가
--warn
#B86E00
주의·대기
--dng
#C13B3B
위험·미납·감소
--info
#3F6B7D
정보·중립 강조
Status — strongtint 배경 위 텍스트 (괄호 = tint 대비, 실측 AAA)
--ok-strong
#175D3A
6.95:1
--warn-strong
#7A4900
6.69:1
--dng-strong
#8E2828
7.29:1
--info-strong
#2D4F5C
tint 위 AA
Status — tintpill 배경(흰색 위 pre-blend된 solid)
--ok-tint
#E9F3EE
성공 pill
--warn-tint
#F8F0E6
주의 pill
--dng-tint
#F9EBEB
위험 pill
--info-tint
#ECF0F2
정보 pill
--neutral-tint
#EFEEEE
중립 pill
Age band (5)연령대 데이터 인코딩 도트 — 의미 고정
--age-preschool
#F4A261
미취학
--age-elementary
#06D6A0
초등
--age-middle
#3B82F6
중등
--age-high
#EF476F
고등
--age-family
#FBBF24
성인·가족
Chart & Bar-split차트 시리즈 인코딩 — 보라는 '취미'에만 고정
--chart-elite
#5C5658
엘리트 시리즈
--chart-hobby
#6B00FF
취미 시리즈(보라)
--chart-canteen
#B86E00
매점
--chart-entrance
#9A9590
입장
--bar-new-elite
#5C5658
신규·엘리트
--bar-new-hobby
#A8A4A0
신규·취미
--bar-renewal-elite
#6B00FF
재등록·엘리트
--bar-renewal-hobby
#C5B5F8
재등록·취미
03 — 스페이싱

4의 배수 스케일

모든 layout 차원은 4의 배수. 바는 실제 토큰 px값을 비례 표시한다.

4
8
12
16
24
32
48
사이드바 240 / collapsed 80
main padding 32 · 48 · 96 (반응형)
카드 padding 24
gap 16 · 24 · 32
04 — 라디우스

코너 사다리

0 → 50%의 정해진 단계만 사용. 유니폼 16px 라운드도, 알약형도 임의 값이 아니다.

0
4
8
12
16
24
50% · 도트/아바타

알약형은 rounded-full(=∞)이 아니라 라디우스 사다리로 근사한다 — 뱃지(h24) → 12, 버튼·탭(h36–44) → 24. height의 절반을 사다리 값으로 올림. rounded-full과 비-사다리 임의 라운드는 금지.

05 — 타이포그래피

텍스트 램프

본문 Pretendard Variable, 숫자·ID·금액은 JetBrains Mono(tabular). display는 700이 아니라 600 — 무게로 위계를 만들되 과하지 않게.

rolesamplesize / line-height / weight
caption학생 32명 · 미납 3건12 / 16 / 400
body오늘 등록된 수업 일정입니다14 / 20 / 400
base수강생 관리16 / 24 / 400
heading이번 달 매출18 / 24 / 600 / -.01em
display대시보드24 / 32 / 600 / -.02em
display-lg₩ 12,480,00032 / 40 / 600 / -.02em
06 — 엘리베이션 & HAIRLINE

그림자는 하나, 경계는 inset

엘리베이션은 단일 --shadow-card(spread −16, 8% 불투명) 한 종류뿐. 경계선은 4-mult를 지키기 위해 border가 아닌 inset shadow로 그린다.

--shadow-card  ·  0 12px 32px −16px / 8%
auto-height 컨테이너box-shadow: inset 0 0 0 1px — 높이 불변
고정 height 요소border 허용 — border-box가 흡수
행 분리선inset 0 −1px 0 var(--border-s)
상단 구분선inset 0 1px 0 var(--border)
07 — 뱃지

분류학

높이 24 고정, 라디우스 12(알약). 의미축마다 시각 처리(solid / tint / outline / dot)가 다르다.

티어 엘리트 취미
포맷 이론 실기
상태 완료 대기 미납 정보
연령대
미취학 초등 중등 고등 가족
08 — 아이코노그래피

Solar Bold Duotone

단일 아이콘 체계(Solar Bold Duotone). currentColor로 색을 상속하고, 배경 path의 opacity .4–.7로 듀오톤을 만든다 — 두 색을 칠하지 않는다. 16 / 20 / 24 그리드.

dashboard
users
payment
calendar
search
bell
graduation-cap
package
09 — 모션

세 개의 지속시간

모두 ease-out(감속) 단일 곡선. 짧고 일관되게 — 운영툴에서 모션은 피드백이지 연출이 아니다.

100ms
행 hover · 칩 active
150ms
드로어 · 모달 · 토스트
220ms
사이드바 expand / collapse
10 — NEVER

AI slop 방어선

"그럴듯한 기본값"이 곧 진부함이다. 아래는 전부 금지 — 대표 항목.

×indigo-500 류 기본 보라를 primary로
×보라 그라디언트 · 글로우 · 메시 블롭
×glassmorphism(반투명 블러 카드)
×카드 좌측 컬러 stripe 강조
×전역 rounded-2xl 카드 · rounded-full 버튼
×Inter · Geist 폰트
×shadcn 기본값 그대로(h-9 rounded-md · shadow-sm)
×KPI 델타를 초록 pill로
×Recharts 기본 팔레트
×auto-height 요소에 직접 border
×비-4배수 height · padding
×"Transform" · "AI-powered" · 이모지 · 느낌표 카피