-
01
Problem
화면별로 제작한 초기 UI에는 반복 요소의 스타일 차이가 있었고, 같은 색이 버튼과 경기 상태를 함께 나타내고 있었습니다.
The initial UI, designed screen by screen, had inconsistent styles across repeated elements. The same colors were also used to represent both actions and game states.
-
02
Approach
행동과 상태의 색 역할을 분리하고, 타이포그래피 · 간격 · 컴포넌트를 공통 규칙으로 정리했습니다. 예측 정보는 확정된 경기 정보와 구별되도록 표현해, 사용자가 정보의 성격을 직관적으로 이해할 수 있도록 했습니다.
I separated color roles for actions and states, and established shared rules for typography, spacing, and components. I also differentiated predicted information from confirmed game information so users could intuitively understand the nature of each piece of information.
-
03
Deliverables
색상 · 타이포그래피 · 간격을 아우르는 디자인 토큰, 컴포넌트 26그룹, 브랜드 자산과 화면 적용 시안을 제작했습니다. 이후 HTML/CSS 구현에 자동 검사 스크립트를 적용해, 정의한 디자인 규칙이 실제 코드에서도 유지되는지 확인했습니다.
Built design tokens covering color, typography, and spacing, 26 component groups, brand assets, and screen applications. I then applied an automated validator to the HTML/CSS implementation to verify that the defined design rules were also maintained in the actual code.
Shoot Shoot Penguin
Design System
Shoot Shoot Penguin은 농구 경기의
게스트 모집과 운영을 돕는 서비스입니다.
모집과 입금 확인이 여러 채널에 흩어져 있던 문제에서 출발했고,
이 케이스스터디에서는 그중 디자인 시스템을 다룹니다.
Reviewing the first screens of Shoot Shoot Penguin, I found that repeated elements were styled differently from screen to screen, and that color meant something different in each one.
Separating how controls and game state were expressed, then settling the tokens and components, gave one standard both sides of the app could be built on.
두 사용자의 다른 목표를
하나의 UI 시스템으로 연결했습니다
Two users, two different goals
connected by one UI system
Shoot Shoot Penguin은 서로 다른 목표를 가진 두 사용자를 연결합니다.
경기를 관리하는 팀 리드와, 참여할 경기를 찾는 플레이어입니다. 같은 경기 정보도 관리 화면에서는 비교하기 쉽게, 탐색 화면에서는 빠르게 구별되게 보여야 합니다. 공통 UI 시스템으로 경험의 일관성을 유지하면서, 각 쓰임에 맞게 정보 위계와 상태 표현을 조정했습니다.
Shoot Shoot Penguin connects two users with different goals:
team leads managing games and players searching for games to join. The same game information needs different priorities: easy comparison for management and quick recognition for exploration. A shared UI system was built to keep the experience consistent while adapting information hierarchy and state representation to each use case.
경기 정보를 관리합니다 Take attendance and guest needs,
and manage game details
-
출석 Attendance 확정 · 예상 인원 확인 Check confirmed and expected players
-
게스트 모집 Guest needs 필요한 게스트 수 확인 See how many guests are needed
-
경기 정보 Game details 시간 · 장소 · 규칙 관리 Manage time, location, and rules
-
팀 관리 Team management 경기 정보 수정 · 공유 Edit and share game information
출석 · 경기 상태 Game details · Location · Time
Attendance · Game status
UI 시스템 Shared
UI System
컴포넌트 · 상태 체계 Colors · Typography · Spacing
Components · State system
빠르게 비교합니다 Find games to join on a map
and quickly compare options.
-
경기 위치 Game location 지도에서 가까운 경기 찾기 Find nearby games on a map
-
경기 상태 Game status 모집 중인 경기 빠르게 구별 Quickly identify open games
-
핵심 정보 Key information 시간 · 거리 · 게스트 자리 확인 Check time, distance, and guest spots
-
비교 Compare options 경기 둘러보고 저장하기 Browse and save games
화면마다 달랐던 표현을
공통 규칙으로 정리했습니다
Screen-by-screen variations
were consolidated into shared rules
화면 뼈대(와이어프레임)와 1차 UI는 있었지만,
반복 요소의 스타일과 색상 기준이 화면마다 달랐습니다.
The initial UI had inconsistent styles across repeated elements,
and the same colors were used for both actions and game states.
기존 화면을 검토해 반복 요소와 상태 표현을 분류하고,
공통 토큰과 컴포넌트를 정의했습니다.
먼저 버튼과 경기 상태에 혼용되던 색상의 역할을 분리했습니다.
I reviewed the screens, grouped repeated elements and state patterns,
and defined shared tokens and components.
The first priority was separating color roles to distinguish actions from game states.
리디자인 전의 관찰
Pre-Redesign Observations
세 가지 문제는 별개의 증상처럼 보이지만, 색의 역할과 사용 규칙이 명확히 정의되지 않은 데서 비롯됐습니다.
The three issues may appear to be separate symptoms, but the roles and usage rules for color were not clearly defined.
-
01
같은 목적에 서로 다른 색을 썼습니다.
Different colors were used for the same purpose.
주요 버튼이 화면마다 네 가지 색으로 쓰였습니다. 같은 기능의 버튼이 색에 따라 서로 다른 중요도를 가진 것처럼 보일 수 있었습니다.
The main buttons used four different colors across the interface. This could make buttons with the same function appear to have different levels of importance based on their color.
→ 주요 버튼을 Grey/900으로 통일했습니다.
→ I unified the primary buttons using Grey/900.
-
02
같은 색을 서로 다른 목적에 썼습니다.
The same color was used for different purposes.
하나의 색이 난이도 · 시간 · 권한 · 인원 · 내비게이션을 모두 나타냈습니다. 그 결과 색만으로는 각각의 의미를 알 수 없었습니다.
A single color was used to represent difficulty, time, permissions, people, and navigation. As a result, the meaning of each color could not be understood on its own.
→ 색이 아니라 역할과 정보 유형을 기준으로 디자인 토큰을 분리했습니다.
→ I separated design tokens based on roles and information types rather than color.
-
03
상태와 액션에 같은 색을 썼습니다.
The same color was used for both status and actions.
‘신청마감’, ‘현재 부족인원 2명’처럼 상태와 예측 정보 모두에 강한 색을 썼습니다. 그 결과 색의 강도가 정보의 중요도와 조작 가능 여부를 동시에 전달하고 있었습니다.
Strong colors were used for both status and predictive information, such as “Registration Closed” and “2 spots needed.” As a result, color intensity was being used to communicate both information importance and whether an element was actionable.
→ 색은 상태와 피드백에 한정하고, 조작 요소는 무채색으로 분리했습니다.
→ Color is reserved for status and feedback, while interactive elements are separated using neutral colors.
색상 역할을 분리해
경기 상태를 구분했습니다
Color’s roles separated,
so game state reads on its own
초기 화면에서는 오렌지가 신청 버튼과 마감임박 배지에 함께 사용되었습니다. 신청이 종료된 요소도 강한 채움색으로 표시되어, 행동 유도와 경기 상태가 구분되지 않았습니다.
In the first screens, orange was used for the apply button and for the closing-soon badge alike. Elements whose applications had already closed were filled just as strongly, so a call to action and a game state could not be told apart.
이를 개선하기 위해 주요 조작 요소에는 무채색을, 경기 상태에는 구분 색상을 적용했습니다. 색상은 상태 정보에 집중해 버튼과 상태가 서로 다른 신호를 전달하도록 했습니다.
To fix it, I let the main controls take neutral color and game states take distinguishing color. Color concentrates on state information, so a button and a state carry different signals.
행동과 상태에 모두 강한 색을 썼습니다
Strong colors were used for both actions and statuses
신청 버튼과 상태 배지가 모두 오렌지 계열이나 강한 채움색을 썼습니다.
Both the application buttons and status badges used orange tones or strong fill colors.
기능마다 색을 따로 지정해, 정보의 시각적 위계가 일관되지 않았습니다.
Colors were applied individually to each function, resulting in an inconsistent visual hierarchy of information.
행동과 상태의 색 역할을 분리했습니다
Color roles were separated for actions and statuses.
주요 조작 요소를 무채색 버튼으로 통일해, 의도한 행동이 분명히 드러나도록 했습니다.
Primary interaction elements were unified with neutral-colored buttons to make the intended action clear.
신청이 마감된 요소는 채도가 낮은 색으로 표현해, 비활성 상태가 분명히 구분되도록 했습니다.
Closed applications are represented with low-saturation colors to clearly distinguish their inactive state.
경기 상태를 기준으로 색 체계를 세워, 상태 정보가 직관적으로 전달되도록 했습니다.
A color system based on match status was established to communicate status information intuitively.
정보를
의미와 맥락에
맞게 표현합니다.
Express information
according to its meaning
and context.
행동 · 상태 · 예측처럼 성격이 다른 정보를 분명히 구분하고, 관리 화면부터 지도와 외부 공유까지 각 맥락에 맞는 정보와 시각 언어를 정의합니다. 표현 규칙을 명확히 세워, 사용자가 인터페이스를 해석하지 않아도 의미와 확실성을 한눈에 알 수 있도록 합니다.
Clearly distinguish information types such as actions, states, and predictions, while defining the appropriate information and visual language for each context, from management screens to maps and external sharing. Establish clear rules for representation so that meaning and certainty can be understood at a glance, without requiring users to interpret the interface.
-
01
행동과 상태를 구분합니다
Separate action from state
버튼 · 필터 · 탭은 무채색을 기본으로 사용하고, 경기 상태는 색과 상태명으로 구별합니다.
Buttons, filters and tabs default to neutral; game state is told apart by color together with the name of the state.
-
02
예측과 확정을 구분합니다
Separate a prediction from a fact
예상 인원에는 점선 테두리와 범위 표기를 사용해, 확정된 정보와 다르게 읽히도록 설계합니다.
A predicted headcount takes a dashed border and a range, so it reads differently from information that is settled.
-
03
사용 맥락에 맞게 표현합니다
Express it to fit where it is used
관리 화면의 정보 밀도, 지도 위 요소의 식별, 외부 공유 시 필요한 정보를 각 환경에 맞게 정의합니다.
Density on the management screens, legibility on the map, and what a shared post needs are each defined for their own setting.
왜 무채색인가?
Why neutral color?
무채색 체계를 선택한 이유는 두 가지입니다. 첫째, 기본 지도 화면에는 25개가 넘는 POI 아이콘이 여러 색으로 표시됩니다. UI 요소에 같은 색을 쓰면 지도 아이콘과 구별하기 어려워집니다. 둘째, 색은 경기 신청 상태를 나타내는 데 쓰이므로 상태 정보를 위해 남겨두어야 했습니다.
그래서 버튼 · 칩 · 탭을 무채색으로 설계해, 강조색이 상태 정보에만 주목을 모으도록 했습니다.
A neutral color system was chosen for two reasons. First, the default map screen carries 25+ POI icons in various colors; using those same colors for UI elements would make the two hard to tell apart. Second, color indicates the status of a match application, so it had to be reserved for status information.
Buttons, chips and tabs were therefore designed in neutral color, leaving the key colors to draw attention to status information alone.
- 0
- 50
- 100
- 200
- 300
- 400
- 500
- 600
- 700
- 800
- 900
- 950
경기 상태에 따른 색 구분Color-coded by game state
다섯 가지 상태색은 배경(tint) · 핀과 점(solid) · 텍스트(text) 세 단계로 구성했습니다. 판단에 필요한 정보는 7:1 이상의 명도 대비를 유지하고, 상태명과 표시를 함께 사용해 어떤 상태도 색에만 의존하지 않도록 했습니다.
Each of the five state colors is structured across three levels: background (tint), pins and dots (solid), and text. Decision-critical information maintains a contrast ratio of at least 7:1, while labels and markers ensure that no state relies on color alone.
-
tint #E4F5ECsolid #0B8A57text #085C2E
모집중Recruiting
플레이어가 지도에서 가장 먼저 찾는 상태이므로, 텍스트는 배경과 7.20:1의 명도 대비를 확보했습니다.
As this is the state players scan the map for first, its text maintains a 7.20:1 contrast against the background.
-
tint #FBF0D6solid #C2700Atext #6B4606
마감임박Closing Soon
부족한 것은 자리가 아니라 시간입니다. 신청은 아직 열려 있으므로 빨강 대신 앰버를 사용했습니다. 명도 대비는 7.40:1입니다.
Time, not availability, is running out. Amber is used instead of red because applications are still open. The contrast ratio is 7.40:1.
-
tint #E7EFFBsolid #1B62D6text #12448C
확정Confirmed
다섯 상태 중 대비가 가장 높아, 확정된 경기가 자신의 경기임을 분명히 알아볼 수 있습니다. 명도 대비는 8.13:1입니다.
The highest contrast of the five makes confirmed games clearly identifiable as the user’s own. The contrast ratio is 8.13:1.
-
tint #FBEAE8solid #C7302Atext #8A1C14
취소Cancelled
빨강은 파괴적 동작과 공유해, 되돌릴 수 없는 상태를 일관되게 전달합니다. 명도 대비는 7.99:1입니다.
Red is shared with destructive actions to consistently communicate an irreversible state. The contrast ratio is 7.99:1.
-
tint #EFF1F4solid #6E7884text #454D56
마감Closed
마감된 상태는 무채색을 유지해, 아직 행동할 수 있는 상태로 주의가 향하도록 했습니다. 명도 대비는 7.58:1입니다.
The closed state remains colorless, keeping users’ attention on states where they can still take action. The contrast ratio is 7.58:1.
반복되는 시각적 결정을
토큰으로 정리했습니다
The visual decisions that repeat,
settled into tokens
색상, 타이포그래피, 간격, 모서리 반경을 공통 값으로 정의했습니다.
각 값에는 사용 목적을 함께 기록해, 화면을 추가하거나 수정할 때 같은 기준을 적용할 수 있도록 했습니다.
Color, typography, spacing and corner radius are defined as shared values.
Each value carries a note on what it is for, so the same standard applies when a screen is added or changed.
Typography
크기, 굵기, 행간의 조합만으로 정보의 층위를 구분했습니다. 색상 없이도 제목부터 본문까지 위계가 명확하게 읽히도록 타이포그래피 체계를 설계했습니다.
Information is separated into layers by size, weight and leading alone. The type system was designed so that the hierarchy from heading to body reads clearly without color.
Pretendard
브랜드 성격과 구현 조건을 함께 만족하는 서체를 선택했습니다
Selected a typeface for both brand character and implementation
브랜드 키워드인 ‘정확한, 단단한, 빠른, 야외의, 활기찬’ 이미지를 기준으로 서체를 검토했습니다. 먼저 세리프를 제외하고, 산세리프 중에서도 정확하고 단단한 인상이 부족한 둥근 기하학 서체를 후보에서 제외했습니다.
The typeface was evaluated against five brand attributes: precise, solid, fast, outdoorsy and energetic. Serif typefaces were excluded first, followed by rounded geometric sans-serifs that lacked the precision and solidity the brand required.
남은 후보를 실제 화면에 적용해 비교한 결과, 한글 · 영문 · 숫자의 균형이 가장 자연스럽고 안정적인 Pretendard를 선택했습니다.
After testing the remaining candidates across actual screens, Pretendard was selected for its natural, stable balance between Hangul, Latin characters and numerals.
액센트 색이 없는 시스템에서는 굵기가 시각적 위계를 만듭니다. 다양한 웨이트를 지원하고, 오픈 라이선스로 개발자와 제약 없이 공유할 수 있어 앱과 문서 전반에 일관되게 적용했습니다.
With no accent color in the system, font weight creates the visual hierarchy. Pretendard offers a wide range of weights and an open licence, allowing it to be shared easily with developers and applied consistently across the app and documentation.
Display 1 style
-
01 13
Display / Large
- Size
- 34px
- Line height
- 120%
- Letter spacing
- -2%
- Weight
- Semibold, Bold, Extra Bold
- Used in
- Onboarding, Empty state
-
Semibold
모집은 짧게
-
Bold
모집은 짧게
-
Extra Bold
모집은 짧게
Number 2 styles
-
02 13
Number / Large
- Size
- 28px
- Line height
- 120%
- Letter spacing
- -2%
- Weight
- Semibold, Bold, Extra Bold
- Used in
- Prediction value
-
Semibold
게스트 3~5명
-
Bold
게스트 3~5명
-
Extra Bold
게스트 3~5명
-
03 13
Number / Medium
- Size
- 20px
- Line height
- 120%
- Letter spacing
- 0%
- Weight
- Semibold, Bold, Extra Bold
- Used in
- Price, Seats Left
-
Semibold
12,000원 · 3/5명
-
Bold
12,000원 · 3/5명
-
Extra Bold
12,000원 · 3/5명
Heading 3 styles
-
04 13
Heading / Large
- Size
- 24px
- Line height
- 130%
- Letter spacing
- -2%
- Weight
- Semibold, Bold, Extra Bold
- Used in
- Screen title
-
Semibold
오늘 뛸 경기
-
Bold
오늘 뛸 경기
-
Extra Bold
오늘 뛸 경기
-
05 13
Heading / Medium
- Size
- 20px
- Line height
- 130%
- Letter spacing
- -2%
- Weight
- Semibold, Bold, Extra Bold
- Used in
- Section title
-
Semibold
다음 경기 준비
-
Bold
다음 경기 준비
-
Extra Bold
다음 경기 준비
-
06 13
Heading / Small
- Size
- 18px
- Line height
- 130%
- Letter spacing
- -2%
- Weight
- Semibold, Bold, Extra Bold
- Used in
- Card title, Venue
-
Semibold
역삼 실내체육관
-
Bold
역삼 실내체육관
-
Extra Bold
역삼 실내체육관
Body 3 styles
-
07 13
Body / Large
- Size
- 16px
- Line height
- 150%
- Letter spacing
- 0%
- Weight
- Regular, Medium, Semibold
- Used in
- Section title
-
Regular
출석 응답 8명이 도착했습니다
-
Medium
출석 응답 8명이 도착했습니다
-
Semibold
출석 응답 8명이 도착했습니다
-
08 13
Body / Medium
- Size
- 14px
- Line height
- 150%
- Letter spacing
- 0%
- Weight
- Regular, Medium, Semibold
- Used in
- Supporting text
-
Regular
최근 6경기 평균 기준
-
Medium
최근 6경기 평균 기준
-
Semibold
최근 6경기 평균 기준
-
09 13
Body / Small
- Size
- 12px
- Line height
- 150%
- Letter spacing
- 0%
- Weight
- Regular, Medium, Semibold
- Used in
- Meta information
-
Regular
중급 · 5v5 · 12,000원
-
Medium
중급 · 5v5 · 12,000원
-
Semibold
중급 · 5v5 · 12,000원
Label & Caption 4 styles
-
10 13
Label / Large
- Size
- 14px
- Line height
- 130%
- Letter spacing
- 0%
- Weight
- Regular, Medium, Semibold
- Used in
- Button label
-
Regular
이 경기 신청하기
-
Medium
이 경기 신청하기
-
Semibold
이 경기 신청하기
-
11 13
Label / Medium
- Size
- 12px
- Line height
- 130%
- Letter spacing
- 0%
- Weight
- Semibold, Bold, Extra Bold
- Used in
- Filter chip
-
Semibold
오늘 · 저녁 · 초중급
-
Bold
오늘 · 저녁 · 초중급
-
Extra Bold
오늘 · 저녁 · 초중급
-
12 13
Label / Small
- Size
- 11px
- Line height
- 130%
- Letter spacing
- 2%
- Weight
- Semibold, Bold, Extra Bold
- Used in
- Status badge · Section header
-
Semibold
모집 중 3자리
-
Bold
모집 중 3자리
-
Extra Bold
모집 중 3자리
-
13 13
Caption
- Size
- 11px
- Line height
- 130%
- Letter spacing
- 2%
- Weight
- Regular, Medium, Semibold
- Used in
- Time stamp · Source note
-
Regular
2시간 전 업데이트
-
Medium
2시간 전 업데이트
-
Semibold
2시간 전 업데이트
Spacing
간격은 0–12에서 2px, 12–24에서 4px, 24–48에서 8px, 그 이상에서 16px씩 커집니다. 작은 간격은 세밀한 조정을, 큰 간격은 일정한 리듬을 맡아 밀도와 구조를 함께 지킵니다.
The scale increases by 2px from 0–12, 4px from 12–24, 8px from 24–48, and 16px beyond. Smaller spaces allow precise adjustments, while larger spaces follow a consistent rhythm to maintain both density and structure.
- 4px
- 8px
- 12px
- 16px
- 20px
- 24px
- 32px
- 48px
- 64px
Radius
각 값은 표준보다 한 단계 크게 잡아, 브랜드의 따뜻함을 강조색이 아니라 형태로 전달합니다.
Each value is one step larger than the standard, preserving the brand’s warmth through form rather than accent color.
- Badge 6
- Thumbnail 10
- Button · Input 12
- Card 16
- Sheet 20
- Chip full
Shadows
색을 걷어낸 자리에서 그림자가 시각적 위계의 주요 단서가 되었습니다. 다섯 단계의 elevation을 정의하고, 각 단계를 특정 UI 역할에 대응시켰습니다.
With color removed, shadows became the primary cue for visual hierarchy. We defined five elevation levels, each mapped to a specific UI role.
- Surface GameCard (default), Input, AppHeader
- Raised SearchBar, FilterChip (on map), Snackbar
- Floating FAB, GameCard (on map), Dropdown
- Anchored BottomSheet, BottomNav
- Overlay Modal, ConfirmDialog
Icon
본문 텍스트인 Pretendard와 시각적 무게가 맞도록 Material Symbols Outlined 400을 선택했습니다.
모든 상태에는 아이콘이나 레이블을 함께 사용해, 정보가 색에만 의존하지 않도록 했습니다.
Material Symbols Outlined 400 was selected to match the visual weight of Pretendard body text.
Every state is also paired with an icon or label, ensuring that information never relies on color alone.
- chevron_right chevron_right GameCard, 목록 행 진입 GameCard, list row
- chevron_left chevron_left AppHeader 뒤로 AppHeader, back
- more_horiz more_horiz AppHeader 더보기 AppHeader, overflow
- home home BottomNav 홈 BottomNav, home
- groups groups BottomNav 나의팀, 참여자 BottomNav, my team
- calendar_month calendar_month BottomNav 캘린더, 날짜 필터 BottomNav, date filter
- notifications notifications AppHeader 알림 AppHeader, alerts
- menu menu AppHeader 메뉴 AppHeader, menu
- my_location my_location 지도 현재 위치 Map, recenter
- search search SearchBar SearchBar
- remove remove 인원 스테퍼 감소 Stepper, decrease
- add add FAB 경기 생성, 스테퍼 증가 FAB, new game
- check check 확정 배지, 선택 완료 Confirmed badge
- close close Modal · BottomSheet 닫기 Modal, dismiss
- sports_basketball sports_basketball 지도 핀, 경기 카드 Map pin, GameCard
- edit edit 경기 수정 Edit game
- content_copy content_copy 모집 글 복사 Copy recruiting post
- filter_list filter_list FilterChip, 목록 필터 FilterChip, list filter
- schedule schedule 경기 시간 Game time
- location_on location_on 경기 장소, 지도 핀 Venue, map pin
- lock lock 팀장 권한, 비공개 경기 Lead-only, private
- person person 팀장, 프로필 Team lead, profile
반복 요소를 정의하고
화면의 맥락에 맞게 조합했습니다
Components built from shared rules,
then adapted to each screen
버튼, 필터, 배지 등 공통 요소는 재사용할 수 있는 컴포넌트로 정리하고,
지도 핀, 수요 예측 카드 등 서비스 고유 요소는 각각의 쓰임에 맞게 구성했습니다.
Figma Variables로 컴포넌트를 정의된 디자인 토큰에 연결해,
시스템의 규칙이 실제 화면까지 그대로 이어지도록 했습니다.
Shared elements such as buttons, filters, and badges were organized into reusable components,
while service-specific elements such as map pins and prediction cards were structured for their respective use cases.
Figma Variables connected these components to the defined design tokens,
allowing the same rules to carry through from the system to the actual screens.
Figma Variables로 디자인 토큰을 연결했습니다
Design tokens were connected through Figma Variables
컴포넌트 — 버튼, 필터, 배지
Components - buttons, filters, badges
컴포넌트를 조합해 각 화면을 구성했습니다
composed these components into each screen
디자인 시스템의 규칙이
실제 코드에서도 지켜지는지 확인했습니다
I verified that the design system rules
were followed in the actual code.
왜 검증이 필요했나요?
Why was validation necessary?
디자인 토큰과 컴포넌트를 정의하는 것만으로는 구현 과정에서도 같은 기준이 유지된다고 보장할 수 없습니다.
실제 구현 화면에서 시스템과 다른 부분을 발견한 뒤, 디자인 시스템을 MD 파일로 정리해 이를 기준으로 코드를 점검하도록 검사 스크립트를 만들었습니다.
HTML/CSS 구현에 검사 스크립트를 적용해,
디자인 시스템에서 정의한 규칙이 코드에서도 지켜지는지 확인했습니다.
Defining design tokens and components alone does not guarantee that the same standards are maintained during implementation.
After spotting parts of the live screens that differed from the system, I documented the design system in an MD file and built a validation script that checks the code against it.
I applied a validation script to the HTML/CSS implementation to check
whether the rules defined in the design system were also being followed in code.
일관되게 지켜야 하는 규칙은 자동으로 검사했습니다.
I automated checks for rules that needed to be consistently enforced.
주요 버튼이 화면마다 네 가지 색으로 쓰였습니다. 같은 기능의 버튼이 색에 따라 서로 다른 중요도를 가진 것처럼 보일 수 있었습니다.
The main buttons used four different colors across the interface. This could make buttons with the same function appear to have different levels of importance based on their color.
- Color 디자인 시스템에 정의되지 않은 색상을 쓰고 있지 않은가? Were any colors outside the defined design system being used?
- Effect 의도적으로 제외한 효과가 적용되어 있지 않은가? Were any effects that were intentionally excluded being applied?
- Size 정의된 크기 단계 밖의 값을 쓰고 있지 않은가? Were any values outside the defined size scale being used?
- Copy 임시 문구가 코드에 남아 있지 않은가? Were any placeholder texts left in the code?
구현에서 두 건의 규칙 위반을 발견했습니다.
The implementation revealed two rule violations.
샘플 코드로 검사를 실행한 결과, 정의되지 않은 색상 하나와 크기 하나를 찾아냈습니다.
Running the check on sample code turned up one undefined color and one undefined size.
이 값들을 새 토큰으로 추가하지 않고, 기존 색상 · 크기 단계의 값으로 교체했습니다.
정의되지 않은 값이 나올 때마다 예외를 추가하면 디자인 시스템의 일관성이 점점 약해지기 때문입니다.
Instead of adding these values as new tokens, I replaced them with values from the existing color and size scales.
Adding a new exception every time an undefined value is found would gradually weaken the consistency of the design system.
규칙을 정의하는 데서 그치지 않고
구현으로 검증했습니다
I went beyond defining rules and
validated them through implementation.
검사 스크립트 자체를 시험하기 위해, 더 다양한 값이 쓰인 코드에도 적용해 보았습니다.
샘플 코드로 범위를 넓혀 실행해 보니, 색상은 정의된 27개 값 안에서 일관되게 관리되고 있었지만,
크기는 51개 값으로 늘어나 있어 속성별로 더 세분화된 단계가 필요하다는 것을 확인했습니다.
To test the validator itself, I also applied it to code containing a wider range of values.
Widening the run with sample code showed that colors were consistently managed within the defined set of 27 values,
while sizes had expanded to 51 values, revealing the need for more granular scales by property.
디자인 시스템은 규칙을 정의하는 데서 그치지 않고,
그 규칙이 실제 코드에서 유지되는지 확인할 방법까지 제공해야 한다는 것을 알게 되었습니다.
I found that a design system should not only define rules,
but also provide a way to verify that those rules are maintained in actual code.
HTML/CSS를 직접 점검하고 구현 오류를 고치면서,
디자인 기준이 개발 과정에서 어떻게 적용되고 유지되는지도 실제로 이해하게 되었습니다.
By directly inspecting HTML/CSS and fixing implementation errors,
I also gained a practical understanding of how design standards are applied and maintained throughout the development process.