Skip to content

Latest commit

Β 

History

History
522 lines (417 loc) Β· 34.7 KB

File metadata and controls

522 lines (417 loc) Β· 34.7 KB

Design System Inspiration of KTB (μΉ΄μΉ΄μ˜€ν…Œν¬ λΆ€νŠΈμΊ ν”„) β€” for Dev Event Web

1. Visual Theme & Atmosphere

KTB(μΉ΄μΉ΄μ˜€ν…Œν¬ λΆ€νŠΈμΊ ν”„)λŠ” ꡐ윑 ν”Œλž«νΌμ΄μ§€λ§Œ, 비주얼은 ν…Œν¬ μ»΄νΌλ‹ˆμ˜ 신뒰감을 κ°€μ Έκ°„λ‹€. 짙은 넀이비(#000040)와 채도 높은 μ‹œκ·Έλ‹ˆμ²˜ 블루(#0043ff)κ°€ ν•œ 쌍으둜 움직이고, κ·Έ 사이λ₯Ό 흰 μΊ”λ²„μŠ€κ°€ λ– λ°›μΉœλ‹€. KakaoTalk의 λ”°λœ»ν•œ λ…Έλž‘κ³ΌλŠ” λ‹€λ₯Έ κ²° β€” λΆ€νŠΈμΊ ν”„μ˜ 정체성은 "μΉœκ·Όν•¨"이 μ•„λ‹ˆλΌ "단단함"이닀.

The design philosophy is content-forward, token-disciplined, and media-rich. course-card의 썸넀일은 μ˜μƒμ΄ μžλ™ μž¬μƒλ˜κ³ , μΉ΄λ“œ μžμ²΄λŠ” 그림자 없이 λΌμš΄λ””λ“œ λΉ„λ””μ˜€ μ»¨ν…Œμ΄λ„ˆ + 짧은 타이틀 + μΊ˜λ¦°λ” μ•„μ΄μ½˜ ν•œ μ€„λ‘œ λλ‚œλ‹€. μ •λ³΄λŠ” μ‹œκ°μ  λ…Έμ΄μ¦ˆ 없이 μ§μ ‘μ μœΌλ‘œ μ „λ‹¬λœλ‹€ β€” chrome이 μ•„λ‹ˆλΌ contentκ°€ λ¬΄λŒ€ μœ„μ— μ„ λ‹€.

TypographyλŠ” Pretendard ν•œ μ€„λ‘œ ν†΅μΌν•œλ‹€. ν•œκΈ€ 가독성, λͺ¨λ˜ν•œ μžμ†Œ ꡬ쑰, λ‹€κ΅­μ–΄ μΉœν™”μ„±μ„ λͺ¨λ‘ κ°–μΆ˜ Korean OFL 폰트. 영문/μˆ«μžλ„ 같은 κ°€μ‘± μ•ˆμ—μ„œ μ²˜λ¦¬λ˜μ–΄ μ½”λ“œ μŠ€νƒ€μΌμ˜ ad-hoc 폰트 μŠ€μœ„μΉ­μ΄ μ—†λ‹€. ν—€λ”©μ—λŠ” letter-spacing -0.012rem둜 살짝 μ‘°μ—¬ μ•½κ°„μ˜ prose densityλ₯Ό λ§Œλ“ λ‹€ β€” λΆ€νŠΈμΊ ν”„ ν—€λ“œλΌμΈμ΄ "곡식 λ¬Έμ„œ" λŠλ‚ŒμœΌλ‘œ 읽히게.

The overall aesthetic is flat-but-confident: 그림자 거의 μ—†μŒ, λ―Έλ””μ–΄(μ˜μƒ/이미지)와 λΌμš΄λ””λ“œ μ»¨ν…Œμ΄λ„ˆμ˜ λŒ€λΉ„λ‘œ 깊이λ₯Ό λ§Œλ“ λ‹€. λΌμš΄λ””λ“œ μŠ€μΌ€μΌμ€ 두 λ‹¨κ³„λ‘œ μΆ©λΆ„ β€” μΉ΄λ“œ ν‘œλ©΄μ€ 12px (border-radius-400), λ””ν…ŒμΌ νŽ˜μ΄μ§€μ˜ 큰 surfaceλŠ” 24px (border-radius-600). κ·Έ 이상도 κ·Έ μ΄ν•˜λ„ 잘 μ•ˆ μ“΄λ‹€.

Key Characteristics:

  • KTB Tech Blue (#0043ff) as the singular brand accent β€” saturated, confident, not pastel
  • KTB Tech Navy (#000040) as the brand base β€” deeper than black, anchors the visual stack
  • Pretendard as the single typeface family (UI + display + body + caption)
  • Vapor Design System tokens (Goorm GDS v0.21.4) as the spacing/color/radius substrate
  • Course-card pattern: aspect-ratio 5/3 thumbnail + h5 title + icon-prefixed meta line
  • Detail hero: 4-column grid (1/4 square thumb + 3/4 info column) with --border-radius-600 corners
  • Flat surfaces, no decorative shadow β€” depth from background tier shifts (white β†’ gray-050)
  • word-break: keep-all everywhere β€” Korean text never breaks mid-word
  • Status badges with pulse keyframe glow for live/urgent states β€” the one allowed motion flourish

2. Color Palette & Roles

Primary

  • KTB Tech Blue (#0043ff): Primary brand color. Buttons (.btn-ktb), urgent badges, link emphasis, CTA accent. λΆ€νŠΈμΊ ν”„ 라이브 μƒνƒœμ˜ μ‹œκ°μ  액컀.
  • KTB Tech Navy (#000040): Brand base. Wordmark, navy-tier badges, dark UI sections. Deeper than pure black for warmth at scale.
  • KTB Tech Sky (#78CDFF): Supporting accent. Soft callouts, secondary highlights.
  • Pure White (#ffffff): Body background, card surfaces, primary canvas.

KTB Gradient Accents (Display Only)

λͺ¨λ‘ linear-gradient(180deg, A 10%, B 100%) ν˜•νƒœ. Hero copy, marketing banner, featured event heroμ—λ§Œ. 일반 μΉ΄λ“œ/UI ν…μŠ€νŠΈμ— μ ˆλŒ€ μ“°μ§€ 말 것.

  • Yellow: #FFE600 β†’ #FFB900
  • Red/Pink: #FF804E β†’ #FF0073
  • Pink: #F57DF0 β†’ #F000E3
  • Violet: #AF7DEB β†’ #7A0CFF
  • Blue: #00B7F8 β†’ #006EF7
  • Sky: #34B7F9 β†’ #87E8DF

Semantic (Vapor)

  • Primary (rgb(29, 108, 224) = #1D6CE0): Link text, primary text accents. Use with var(--text-primary).
  • Danger (rgb(217, 28, 41)): Error states, destructive actions, deadline-imminent badges.
  • Success (rgb(8, 120, 94)): Confirmed registration, completed states.
  • Warning (rgb(180, 82, 9)): Attention-needed states, soft alerts.

Text Scale (Vapor)

  • Text Normal (rgb(43, 45, 54) = #2B2D36): Body, titles, primary content. The workhorse.
  • Text Secondary (rgb(62, 64, 76) = #3E404C): Card subtitles, secondary labels.
  • Text Hint (rgb(108, 110, 126) = #6C6E7E): Period meta line, helper text, captions.
  • Text Alternative (rgb(82, 84, 99) = #525463): Soft body in alternative surfaces.
  • Text Hint Alternative (rgb(62, 64, 76)): Hint text on dark/colored surfaces.
  • Text Light (#ffffff): Text on dark/colored backgrounds.

Neutral Scale (Vapor gray-*)

Token Value Use
--gray-000 #ffffff Page background, primary card surface
--gray-050 #F7F7FA Alternative background β€” section bands, hover wash
--gray-100 #F0F0F5 Thumbnail placeholder bg, search field bg, soft fill
--gray-200 #E8E8EE Subtle dividers, disabled-field fill
--gray-300 #E1E1E8 Standard border (--border-color)
--gray-400 #CDCED6 Hover border (--border-hover), disabled stroke
--gray-500 #8C8F9F Icon default, placeholder text
--gray-600 #6C6E7E Hint text
--gray-700 #525463 Secondary text on alt bg
--gray-800 #3E404C Secondary text
--gray-900 #2B2D36 Body text, headings
--gray-950 #252730 Strongest text emphasis

Borders & Backgrounds

  • --border-color = #E1E1E8 β€” default 1px borders
  • --border-hover = #CDCED6 β€” hover state borders
  • --background-normal = #ffffff β€” primary surface
  • --background-alternative = #F7F7FA β€” section banding, common-card surface

Dark Mode Palette β€” Wanted Design System

닀크 λͺ¨λ“œλŠ” 라이트의 Vapor μŠ€μΌ€μΌμ„ μ—­μˆœ λ§€ν•‘ν•˜μ§€ μ•ŠλŠ”λ‹€. λŒ€μ‹  Wanted Design System의 닀크 μ‹œλ§¨ν‹± 토큰 (Figma qQPdpnglONbuWul4cvodyj β†’ node 15625:32983 β†’ Color/Semantic/Dark)을 직접 μ±„μš©ν•œλ‹€. μ—­μˆœ 맀핑이 λ§Œλ“€λ˜ 함정(예: --vapor-gray-950 이 닀크에선 ν°μƒ‰μœΌλ‘œ λ’€μ§‘ν˜€ μΉ΄λ“œ active μƒνƒœκ°€ 흰색 λ°•μŠ€κ°€ 되던 버그)을 μ œκ±°ν•˜κΈ° μœ„ν•¨.

Background β€” page + elevated surfaces

Wanted 토큰 hex 우리 λ§€ν•‘ Use
background-normal-normal #1B1C1E --vapor-gray-000, --background-1 νŽ˜μ΄μ§€ 베이슀 μΊ”λ²„μŠ€
background-normal-alternative #0F0F10 (μ˜ˆμ•½) κ°€μž₯ κΉŠμ€ μ•ŒνŠΈ (ν•„μš” μ‹œ)
background-elevated-normal #212225 --vapor-gray-050, --background-2, --toggle-track-bg μΉ΄λ“œ, λͺ¨λ‹¬, alt ν‘œλ©΄
background-elevated-alternative #141415 (μ˜ˆμ•½) κΉŠμ€ alt elevated

Line β€” borders + dividers

Wanted 토큰 hex 우리 λ§€ν•‘ Use
line-solid-normal #37383C --vapor-gray-300, --gray-4, --toggle-active-bg ν‘œμ€€ 1px 보더, ν† κΈ€ active ν‘œλ©΄
line-solid-neutral #333438 --vapor-gray-200 subtle ꡬ뢄선
line-solid-alternative #2E2F33 --vapor-gray-100, --gray-5 placeholder bg, search field bg

Interaction

Wanted 토큰 hex 우리 λ§€ν•‘
interaction-inactive #5A5C63 --vapor-gray-400, --gray-3
interaction-disable #2E2F33 (line-solid-alt와 동일)

Label β€” text scale

Wanted 토큰 hex 우리 λ§€ν•‘ Use
label-strong #FFFFFF --vapor-gray-900, --vapor-gray-950, --gray-1 body, heading, μ΅œκ°• κ°•μ‘°
label-normal #F7F7F8 --vapor-gray-800 secondary ν…μŠ€νŠΈ
label-neutral #C2C4C8 --vapor-gray-700 λŒ€μ²΄ ν‘œλ©΄ μœ„μ˜ 보쑰 ν…μŠ€νŠΈ
label-alternative #AEB0B6 --vapor-gray-600, --gray-2 hint, meta
label-disable #989BA2 --vapor-gray-500 placeholder, icon default

Primary β€” brand blue (dark variant)

λ‹€ν¬μ—μ„œλŠ” KTB Tech Blue (#0043FF)κ°€ μ–΄λ‘μš΄ λ°°κ²½ μœ„μ—μ„œ 가독성이 λ–¨μ–΄μ Έ Wanted primary scale둜 ν•œ 단계 λ°νžŒλ‹€.

Wanted 토큰 hex 우리 λ§€ν•‘
primary-normal #3385FF --ktb-tech-blue (dark only), --primary, --vapor-text-primary
primary-strong #1A75FF --ktb-tech-navy-hover (dark only)
primary-heavy #0066FF (μ˜ˆμ•½)

λΌμ΄νŠΈλŠ” #0043FFλ₯Ό κ·ΈλŒ€λ‘œ μœ μ§€. λΈŒλžœλ“œ 색은 μœ μ§€ν•˜λ˜ λ‹€ν¬μ—μ„œλ§Œ ν•œ 단계 밝힌 변쒅을 μ“°λŠ” νŒ¨ν„΄.

Status β€” saturated for dark legibility

Wanted 토큰 hex 우리 λ§€ν•‘
status-positive #1ED45A --vapor-text-success (dark)
status-cautionary #FFA938 --vapor-text-warning (dark)
status-negative #FF6363 --vapor-text-danger (dark)

Translucent β€” sticky header + glass overlays

닀크 μ „μš© 반투λͺ… 토큰 (light에선 별도 white μ•ŒνŒŒ κ°’ μ‚¬μš©):

토큰 dark κ°’ Use
--header-bg rgba(27, 28, 30, 0.86) sticky 헀더
--glass-overlay rgba(33, 34, 37, 0.72) λͺ¨λ°”일 μΉ΄λ“œ μ•„μ΄μ½˜ κΈ€λž˜μŠ€
--glass-overlay-strong rgba(33, 34, 37, 0.94) κΈ€λž˜μŠ€ hover
--notice-bg rgba(51, 133, 255, 0.12) 상단 곡지 λ°°λ„ˆ ν‹΄νŠΈ

Dark Mode Iteration Notes

  • 닀크 λͺ¨λ“œ 토큰은 styles/_color.scss의 $wanted-dark-* λ³€μˆ˜μ— ν•œ 곳에 λͺ¨μ•„두고, styles/Theme.scss의 html[data-theme='dark'] λΈ”λ‘μ—μ„œ μ‹œλ§¨ν‹± 토큰에 λ§€ν•‘ν•œλ‹€.
  • μƒˆ μ»΄ν¬λ„ŒνŠΈκ°€ 닀크 변쒅이 ν•„μš”ν•˜λ©΄ λ°˜λ“œμ‹œ μ‹œλ§¨ν‹± 토큰(var(--vapor-gray-*), var(--ktb-tech-blue) λ“±)을 톡해 μ ‘κ·Ό. ν•˜λ“œμ½”λ”©ν•œ 흰색(#fff, rgba(255,255,255,...))이 닀크에 λ–¨μ–΄μ§€λ©΄ μ‹œκ°μ  λΆ€μ‘°ν™” λ°œμƒ.
  • μ˜ˆμ™Έ 1 (μ–΄λ‘μš΄ brand surface μœ„ ν…μŠ€νŠΈ): light/dark λ¬΄κ΄€ν•˜κ²Œ 항상 μ–΄λ‘μš΄ SNS λ°°λ„ˆμ˜ 흰 pill 같은 surfaceλŠ” κ·Έ μœ„ ν…μŠ€νŠΈλ„ ν•˜λ“œμ½”λ”©λœ 닀크 κ°’(#2B2D36)을 써야 함. 토큰 inversion이 ν…μŠ€νŠΈλ₯Ό ν°μƒ‰μœΌλ‘œ λ’€μ§‘μ–΄ invisible ν™”ν•˜λŠ” 사고 λ°©μ§€.
  • μ˜ˆμ™Έ 2 (KTB Blue surface μœ„ ν…μŠ€νŠΈ): KTB Tech Blue λ°°κ²½(--ktb-tech-blue / --primary) μœ„ ν…μŠ€νŠΈλŠ” λ°˜λ“œμ‹œ ν•˜λ“œμ½”λ”©λœ #ffffff λ₯Ό μ“΄λ‹€. var(--vapor-gray-000) μ΄λ‚˜ var(--background-1) 을 μ“°λ©΄ λ‹€ν¬μ—μ„œ νŽ˜μ΄μ§€ bg(#1B1C1E)둜 λ’€μ§‘ν˜€ κ²€μ • 글씨가 νŒŒλž€ λ²„νŠΌ μœ„μ— λ‚˜νƒ€λ‚˜λŠ” 사고가 λ°œμƒ. 이 νŒ¨ν„΄μ΄ 적용된 κ³³: FillButton.color--primary, EmailSubscribeButton.
  • μ˜ˆμ™Έ 3 (인라인 동적 색상): μΊ˜λ¦°λ” chip(CalendarGrid.tsx)처럼 인라인 style={{ color: tagHex, background: rgba(tagHex, 0.08) }} 으둜 μΉ΄ν…Œκ³ λ¦¬ 색을 μΉ ν•˜λŠ” μΌ€μ΄μŠ€λŠ” 라이트 bg κ°€μ •μœΌλ‘œ νŠœλ‹λ¨. 닀크에선 dark-on-dark 가독성 λΆ•κ΄΄ β†’ SCSS λͺ¨λ“ˆμ—μ„œ :global(html[data-theme='dark']) & μ…€λ ‰ν„°λ‘œ color/backgroundλ₯Ό !important overrideν•˜μ—¬ λŒ€λΉ„λ₯Ό νšŒλ³΅ν•˜κ³ , μΉ΄ν…Œκ³ λ¦¬ 색은 border-left 만 μœ μ§€ν•˜μ—¬ μ‹œκ°μ  큐둜 남긴닀.

3. Typography Rules

Font Family

  • Single Family: Pretendard, -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo", Roboto, "Noto Sans KR", "Malgun Gothic", sans-serif
  • Monospace (only when code is shown): "SF Mono", SFMono-Regular, Menlo, Consolas, monospace

Pretendard is OFL β€” load via https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css. λͺ¨λ“  weightλ₯Ό ν•œ λ²ˆμ— λ‘œλ“œν•˜μ§€ 말고 μ‚¬μš©ν•˜λŠ” 400/500/700/800만 selectively load.

Hierarchy (Vapor --font-size-* + --line-height-*)

Role Size Line Weight Letter Spacing Notes
Display 2.375rem (38px) 3rem 700-800 normal Marketing hero, gradient-accented copy only
Heading H1 2rem (32px) 2.25rem 700 normal Page title (events λͺ©λ‘, 상세 hero)
Heading H2 1.5rem (24px) 2rem 700 normal Section header (월별 묢음, μΉ΄ν…Œκ³ λ¦¬)
Heading H3 1.25rem (20px) 1.875rem 700 normal Sub-section / event detail tab title
Heading H4 1.125rem (18px) 1.625rem 700 normal Card group titles
Heading H5 (Card Title) 1rem (16px) 1.5rem 700 -0.012rem course-card / event-card 타이틀 β€” single line ellipsis
Body 1rem (16px) 1.5rem 400-500 normal Default body, descriptions
Subtitle 1 (Meta) 0.875rem (14px) 1.375rem 400-500 normal Card period line, secondary meta
Caption 0.75rem (12px) 1.125rem 400-500 normal Timestamps, badge text, smallest labels
Micro 0.625rem (10px) 0.875rem 500 normal Tag chips, tab labels

Principles

  • One family, one rhythm: Pretendard둜 톡일. λ‹€λ₯Έ 폰트λ₯Ό μ„žμ§€ 말 것. 영문 ν—€λ”©λ§Œ 영문 폰트둜 λ°”κΎΈλŠ” μ‹μ˜ ad-hoc μŠ€μœ„μΉ­ κΈˆμ§€.
  • Heading letter-spacing: μΉ΄λ“œ/νŽ˜μ΄μ§€ 헀딩에 -0.012rem μ μš©ν•΄ ν•œκΈ€ μžμ†Œ 사이λ₯Ό 살짝 쑰인닀. λ³Έλ¬Έμ—λŠ” μ μš©ν•˜μ§€ μ•ŠλŠ”λ‹€.
  • Weight discipline: 400(body) / 500(emphasized body, meta) / 700(headings, card titles) / 800(display). 600/900 μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”λ‹€ β€” Pretendard variableμ΄μ§€λ§Œ 토큰에 μ—†λŠ” weightλŠ” shipν•˜μ§€ μ•ŠλŠ”λ‹€.
  • word-break: keep-all: ν•œκΈ€μ΄ 단어 λ‹¨μœ„λ‘œ μ€„λ°”κΏˆλ˜λ„λ‘ body에 κΈ€λ‘œλ²Œ 적용. CJK κ°€λ…μ„±μ˜ κΈ°λ³ΈκΈ°.

4. Component Stylings

Buttons

Primary (.btn-ktb)

  • Background: #0043ff (--ktb-tech-blue)
  • Hover background: #0238D1 (--ktb-tech-navy-hover)
  • Text: #ffffff
  • Padding: var(--space-150) var(--space-300) (12px 24px)
  • Radius: var(--border-radius-400) (12px)
  • Font: 1rem / weight 700
  • Use: Primary CTA β€” "행사 λ“±λ‘ν•˜λŸ¬ κ°€κΈ°", "μ‹ μ²­", "μ°Έμ—¬"

Secondary / Outline

  • Background: transparent
  • Text: #2B2D36 (--text-normal)
  • Border: 1px solid #E1E1E8 (--border-color)
  • Hover border: #CDCED6 (--border-hover)
  • Radius: var(--border-radius-400) (12px)
  • Use: Secondary actions β€” "μ·¨μ†Œ", "ν•„ν„° μ΄ˆκΈ°ν™”"

Ghost / Tertiary

  • Background: transparent
  • Text: #1D6CE0 (--text-primary)
  • Border: none
  • Use: Inline links, tab triggers

Danger

  • Background: #D91C29 (--text-danger)
  • Text: #ffffff
  • Radius: var(--border-radius-400)
  • Use: μ‹ μ²­ μ·¨μ†Œ, μ‚­μ œ

Course / Event Card (Defining Component β€” Hero of the System)

The card is the unit of the events list. Trace this spec exactly.

.event-card                          ← container (a.event-link wraps everything)
β”œβ”€β”€ .event-thumb                     ← media area
β”‚   β”œβ”€β”€ .event-status-badge          ← absolute top-left badge (live/λ§ˆκ°μž„λ°•/λͺ¨μ§‘쀑)
β”‚   β”œβ”€β”€ video.event-video            ← autoplay loop muted playsinline (desktop)
β”‚   └── picture > img                ← static fallback (mobile / no-video)
└── .event-info
    β”œβ”€β”€ .event-name                  ← h5 β€” single-line ellipsis title
    β”œβ”€β”€ .event-period                ← subtitle-1 β€” calendar icon + date range
    └── .badge-container             ← chip row (μΉ΄ν…Œκ³ λ¦¬, μ§€μ—­, 온라인/μ˜€ν”„λΌμΈ)

.event-card

  • Width: 100% of grid cell
  • Background: #ffffff
  • Border: none (the card is shape-less β€” its thumb defines the silhouette)
  • Hover: .event-card:hover .event-video { transform: scale(1.05); } β€” only the media zooms

.event-thumb

  • width: 100%; aspect-ratio: 5 / 3; overflow: hidden;
  • border-radius: var(--border-radius-400) (12px)
  • background-color: var(--gray-100) (#F0F0F5) β€” placeholder while video loads
  • position: relative β€” anchor for absolute badge

.event-status-badge

  • position: absolute; top: var(--space-200); left: var(--space-200); (16px / 16px)
  • z-index: 1
  • Use .badge-ktb-blue (live / 진행쀑), .badge-ktb-navy (μ˜ˆμ •), .badge-ktb-danger (λ§ˆκ°μž„λ°•) with pulse-* keyframe

.event-video

  • width: 100%; height: 100%; object-fit: cover; position: absolute; top: 0; left: 0;
  • transition: transform 0.3s ease; ← THE hover signature
  • Mobile: replace with <picture> static image (no autoplay on cellular)

.event-info (content block below thumb)

  • padding-top: var(--space-150) (12px above title)
  • No padding sides β€” aligns flush with thumb edge

.event-name

  • h5 element
  • Color: var(--text-normal) (#2B2D36)
  • Font: 1rem (16px) / weight 700 / letter-spacing -0.012rem
  • margin-bottom: var(--space-050) (4px)
  • Single-line ellipsis: white-space: nowrap; overflow: hidden; text-overflow: ellipsis;

.event-period (subtitle-1 meta line with calendar icon)

  • Color: var(--text-hint) (#6C6E7E)
  • Font: 0.875rem (14px) / weight 400
  • display: flex; align-items: center; gap: var(--space-050) (4px between icon and text)
  • margin-bottom: var(--space-150) (12px)
  • Icon: 16Γ—16 inline SVG, fill: currentColor

.badge-container

  • display: flex; flex-wrap: wrap; gap: var(--space-050) (4px)
  • Chip child style: see Tags / Badges below

Tags / Badges (chips inside cards)

  • Background: var(--gray-100) (#F0F0F5)
  • Text: var(--text-hint-alternative) (#3E404C)
  • Padding: var(--space-025) var(--space-100) (2px 8px)
  • Radius: var(--border-radius-200) (6px) β€” flatter than card radius, signals "secondary"
  • Font: 0.75rem (12px) / weight 500
  • badge-contrast variant: bg rgba(62, 64, 76, .32) over media

Cards & Containers (.common-card)

For event detail page sections (description, schedule, registration info).

  • Background: var(--background-alternative) (#F7F7FA)
  • Border: none
  • Radius: var(--border-radius-600) (24px) β€” bigger than the list card for hierarchical contrast
  • Padding: var(--space-300) (24px)
  • Shadow: none β€” flat-by-default

Event Detail Hero (.hero-main-row--course pattern)

The signature 4-column grid for /event/detail/[eventId].

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  thumb    β”‚   info-column                    β”‚
β”‚  1/4      β”‚   3/4                            β”‚
β”‚  square   β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”           β”‚
β”‚           β”‚   β”‚ event-title (h1) β”‚           β”‚
β”‚           β”‚   β”‚ event-descriptionβ”‚           β”‚
β”‚           β”‚   β”‚ btn-ktb (primary)β”‚           β”‚
β”‚           β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  • Container: display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); column-gap: var(--space-300); (24px gap)
  • .thumb-container: grid-column: 1 / 2; aspect-ratio: 1 / 1; border-radius: var(--border-radius-600); (24px) background-color: var(--background-alternative);
  • .info-column: grid-column: 2 / 5;
  • .event-header-detail: display: flex; flex-direction: column; gap: var(--space-100); (8px between title and description)
  • .event-title: color: var(--text-normal); margin: 0; β€” page-level h1
  • .event-description: color: var(--text-hint); margin: 0;
  • Mobile: thumb stacks above info, full-width

Inputs & Forms

  • Border: 1px solid var(--border-color) (#E1E1E8)
  • Radius: var(--border-radius-400) (12px)
  • Focus: border becomes var(--text-normal) (#2B2D36) β€” no glow, no shadow
  • Text: var(--text-normal), Placeholder: var(--gray-500) (#8C8F9F)
  • Search bar: var(--gray-100) (#F0F0F5) bg, var(--border-radius-400) radius β€” borderless variant

Navigation

  • Top nav height: 7.5rem (120px) β€” generous, accommodates logo + utility row + tab row
  • Body has padding-top: 7.5rem global offset
  • Tab item: --text-hint default, --text-normal + 2px bottom border on active
  • Font: 1rem / weight 500 / 700 on active

5. Layout Principles

Spacing System (Vapor --space-*)

Token rem px Common Use
--space-000 0 0 Reset
--space-025 0.125 2 Hairline gaps in chips
--space-050 0.25 4 Icon-to-text gap, chip gap
--space-075 0.375 6 Tight chip padding-y
--space-100 0.5 8 Card stack gap, badge padding-x
--space-150 0.75 12 Section internal gap, title-to-meta
--space-175 0.875 14 Off-step adjustments
--space-200 1 16 Standard horizontal padding, badge top/left
--space-225 1.125 18 Off-step adjustments
--space-250 1.25 20 Section padding-y small
--space-300 1.5 24 Card padding, grid column-gap, common-card padding
--space-400 2 32 Section gap medium
--space-500 2.5 40 Section gap large
--space-600 3 48 Hero vertical padding
--space-700 3.5 56 Title margin-bottom on landing
--space-800 4 64 content-section padding-y

Grid & Container

  • Max content width: 1104px (laptop) β€” match existing project token
  • Horizontal padding: 16px (mobile) / 64px (tablet) / 48px (laptop)
  • Events list grid: grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: var(--space-300); β€” responsive course-card row
  • Detail hero: 4-column grid, see Hero spec above

Whitespace Philosophy

  • Card-as-island: Cards float in whitespace, no card-to-card borders. The thumb radius does the visual separation.
  • Section banding: Alternate --background-normal (white) and --background-alternative (#F7F7FA) for scroll rhythm. No 3rd background tier.
  • Generous top padding: 7.5rem body offset for fixed nav β€” never overlap content.
  • word-break: keep-all: ν•œκΈ€ λ¬Έμž₯이 단어 μ€‘κ°„μ—μ„œ λŠκΈ°μ§€ μ•Šκ²Œ. λͺ¨λ“  ν…μŠ€νŠΈ μ»¨ν…Œμ΄λ„ˆμ— 적용.

Border Radius Scale (Vapor --border-radius-*)

  • --border-radius-100 (8px): Chips/tags on solid surfaces
  • --border-radius-200 (6px): Small badge chips
  • --border-radius-400 (12px): Standard for course-card thumb, buttons, inputs β€” THE workhorse radius
  • --border-radius-600 (24px): Common-card / detail hero containers β€” THE elevated radius
  • Pill (9999px): Status badges, count badges

6. Depth & Elevation

Level Treatment Use
Flat (Level 0) No shadow Default β€” everything. Cards, list items, buttons, badges
Pulse Glow (Special) box-shadow: 0 0 0 0 rgba(...0.6) β†’ 0 0 0 8px rgba(...0) keyframe Live/urgent status badges only
Subtle (Level 2) 0px 2px 6px rgba(0,0,0,0.08) Dropdown menus, popovers (rare)
Elevated (Level 3) 0px 4px 12px rgba(0,0,0,0.12) Modal dialogs, bottom sheets (rare)

Shadow Philosophy: KTBλŠ” flat λ””μžμΈ μ‹œμŠ€ν…œμ΄λ‹€. μΉ΄λ“œ, λ²„νŠΌ, 일반 surface에 그림자λ₯Ό μ“°μ§€ μ•ŠλŠ”λ‹€. κΉŠμ΄λŠ” 두 κ°€μ§€ μˆ˜λ‹¨μœΌλ‘œλ§Œ λ§Œλ“ λ‹€ β€” (1) λ°°κ²½ 색 tier μ „ν™˜ (gray-000 β†’ gray-050 β†’ gray-100), (2) pulse-* ν‚€ν”„λ ˆμž„μœΌλ‘œ 라이브 μƒνƒœ κ°•μ‘°. 일반 hover에 box-shadow μΆ”κ°€ κΈˆμ§€ β€” hoverλŠ” λ―Έλ””μ–΄ scale둜만.

7. Do's and Don'ts

Do

  • Use KTB Tech Blue (#0043ff) as the single primary brand accent
  • Use Pretendard as the single typeface family β€” UI / display / body / monospace exempt
  • Use var(--border-radius-400) (12px) for cards/buttons/inputs and var(--border-radius-600) (24px) for detail surfaces
  • Apply letter-spacing: -0.012rem to headings/card titles (not body)
  • Apply word-break: keep-all globally for Korean text integrity
  • Use transform: scale(1.05) on .event-video for the only card-hover signature
  • Use pulse-blue / pulse-navy / pulse-danger keyframe only on status badges that indicate live/urgent state
  • Use Vapor design tokens (--space-*, --gray-*, --text-*, --border-radius-*) β€” never hardcode values when a token exists
  • Stack thumb (1/4 square) + info column (3/4) for detail hero on desktop; collapse to vertical on mobile
  • Render <video autoplay loop muted playsinline> for course/event thumbnails on desktop; fall back to <picture> on mobile (cellular-safe)

Don't

  • Don't add box-shadow to cards or buttons β€” KTB is flat. The pulse keyframe is the only shadow.
  • Don't mix fonts β€” Pretendard handles 영문/숫자/ν•œκΈ€ λͺ¨λ‘. ad-hoc 영문 폰트 μŠ€μœ„μΉ­ κΈˆμ§€.
  • Don't use KTB gradient accents on functional UI β€” gradient은 hero/marketing display μ „μš©. 일반 μΉ΄λ“œ/λ²„νŠΌ/타이틀에 κΈˆμ§€.
  • Don't use pure black (#000000) for text β€” --text-normal (#2B2D36) for body, --ktb-tech-navy (#000040) only for wordmark/brand surfaces.
  • Don't break the card silhouette β€” μΉ΄λ“œμ— borderλ₯Ό 두λ₯΄μ§€ 말 것. thumb의 radius와 whitespace둜 뢄리.
  • Don't add multi-line card titles β€” .event-name은 single-line ellipsis. 두 쀄이 ν•„μš”ν•˜λ©΄ μΉ΄λ“œ gridλ₯Ό λ‹€μ‹œ μ§ λ‹€.
  • Don't autoplay video on mobile β€” cellular cost. Use <picture> with source media="(max-width: 576px)".
  • Don't use weights outside 400/500/700/800 β€” Pretendard variableμ΄μ§€λ§Œ 토큰 λ°– weightλŠ” shipν•˜μ§€ μ•ŠλŠ”λ‹€.
  • Don't replace pulse keyframe with hover shadow β€” 라이브 μƒνƒœμ™€ hoverλŠ” λ‹€λ₯Έ 감각. pulseλŠ” μžλ™ 반볡, hoverλŠ” μ‚¬μš©μž μ˜λ„.

8. Responsive Behavior

Breakpoints

Name Width Key Changes
Mobile <576px Single-column cards, thumb uses <picture> (no autoplay), 16px h-padding
Tablet 576-768px 2-column event grid, video autoplay activates, 64px h-padding
Laptop 768-1104px 3-4 column event grid, full hero 4-col detail layout
Desktop >1104px Content max-width 1104px, generous whitespace outside

Touch Targets

  • Card link: entire .event-card is tappable (anchor wraps everything)
  • Button minimum: 44Γ—44px tap target β€” use min-height: 2.75rem for icon-only buttons
  • Tab item: minimum 56px height with padding

Collapsing Strategy

  • Event detail hero: desktop 4-column grid β†’ mobile vertical stack (thumb full-width, info below)
  • Events list: 4 columns (desktop) β†’ 3 (laptop) β†’ 2 (tablet) β†’ 1 (mobile) β€” via auto-fill, minmax(280px, 1fr)
  • Top nav: full nav on desktop β†’ hamburger on mobile, height stays 7.5rem
  • .common-card padding: --space-300 (24px) desktop β†’ --space-200 (16px) mobile

Image / Video Behavior

  • Thumbnails: aspect-ratio 5/3 (list card) or 1/1 (detail thumb)
  • Desktop: autoplay loop muted video with static <picture> fallback
  • Mobile (<576px): static <picture> only β€” no autoplay
  • Profile/avatar (when applicable): 48px rounded square (12px radius), not circles
  • Decorative event banner imagery: object-fit: cover inside fixed-aspect container

9. Agent Prompt Guide

Quick Color Reference

  • Primary CTA bg: KTB Tech Blue (#0043ff)
  • Primary CTA hover bg: KTB Navy Hover (#0238D1)
  • Primary CTA text: White (#ffffff)
  • Body bg: White (#ffffff = --gray-000)
  • Alternative bg: #F7F7FA (--background-alternative)
  • Card placeholder bg: #F0F0F5 (--gray-100)
  • Heading text: #2B2D36 (--text-normal)
  • Body text: #2B2D36 (--text-normal)
  • Secondary text: #3E404C (--text-secondary)
  • Hint/Meta text: #6C6E7E (--text-hint)
  • Link: #1D6CE0 (--text-primary)
  • Border: #E1E1E8 (--border-color)
  • Border hover: #CDCED6 (--border-hover)
  • Error: #D91C29 (--text-danger)
  • Success: #08785E (--text-success)

Example Component Prompts

  • Event Card: "Create an event card: anchor wrapping .event-thumb (aspect-ratio 5/3, 12px radius, #F0F0F5 placeholder bg, <video autoplay loop muted playsinline> on desktop with <picture> mobile fallback, absolute top-left status badge at 16px) + .event-info (padding-top 12px, h5 .event-name 16px weight 700 #2B2D36 single-line ellipsis with letter-spacing -0.012rem, then .event-period subtitle 14px #6C6E7E with calendar SVG icon 16Γ—16 gap 4px, then .badge-container flex-wrap gap 4px). On hover, only the video transforms scale(1.05) with 0.3s ease transition. No card border, no shadow."

  • Primary Button: "Create a .btn-ktb primary button: bg #0043ff, hover bg #0238D1, text #ffffff weight 700 size 1rem, padding 12px 24px, border-radius 12px. No box-shadow."

  • Detail Hero: "Build the event detail hero: 4-column grid, column-gap 24px. Column 1 (grid-column 1/2): square thumbnail container, aspect-ratio 1/1, border-radius 24px, bg #F7F7FA. Columns 2-4 (grid-column 2/5): info column with vertical stack (gap 8px) β€” h1 .event-title color #2B2D36 margin 0, then .event-description color #6C6E7E margin 0, then .btn-ktb primary button. On mobile, stack thumb full-width above info column."

  • Common Card Container: "Create a .common-card: bg #F7F7FA, border-radius 24px, padding 24px, no border, no shadow. Use for grouping event detail sub-sections (schedule, registration info, requirements)."

  • Status Badge with Pulse: "Create a pulsing .badge-ktb-blue: bg #0043ff, text white, padding 4px 8px, border-radius pill (9999px), font 12px weight 500. Apply animation: pulse-blue 2s infinite; where @keyframes pulse-blue goes from box-shadow: 0 0 0 0 rgba(0, 67, 255, 0.6) to 0 0 0 8px rgba(0, 67, 255, 0) to 0 0 0 0 rgba(0, 67, 255, 0)."

  • Chip / Tag: "Create a chip: bg #F0F0F5, text #3E404C weight 500 size 12px, padding 2px 8px, border-radius 6px. Use inside .badge-container of an event card to show category/region/online tags."

Iteration Guide

  1. Pretendard is the single font β€” UI/display/body/caption all share one family. Never mix fonts.
  2. Two radii do 90% of the work: 12px (--border-radius-400) for list cards/buttons/inputs, 24px (--border-radius-600) for detail surfaces.
  3. The card is shape-less; the thumb carries the silhouette. Don't add borders or shadows to cards.
  4. Hover is media-only: .event-video { transform: scale(1.05); transition: transform 0.3s ease; } β€” nothing else changes on hover.
  5. Status badges pulse, nothing else does: pulse-blue / pulse-navy / pulse-danger keyframes are the only motion language outside of media zoom.
  6. Gradient accents are display-only: hero copy, marketing banner. Never on functional UI.
  7. Section banding: white (--gray-000) ↔ near-white (--background-alternative #F7F7FA). Just two background tiers, alternated.
  8. Korean-first typography: letter-spacing: -0.012rem on headings, word-break: keep-all globally.
  9. Token-discipline: Reach for var(--space-*) / var(--gray-*) / var(--text-*) / var(--border-radius-*) before typing a hex or px. If the value isn't in the token table above, ask before adding.

10. Brand Landing Hero Motion Contract

The / brand landing hero uses its generated desktop/mobile artwork as the complete visual baseline. Three.js may add depth, but it must never carry essential content or replace the static art.

  • Role: a transparent starfield plus low-density cyan, blue, and violet nebula-dust layer. The dust follows visible curl-like paths, drifts as a group, and gently pulses while the stars retain subtle pointer parallax and restrained twinkle; HTML remains responsible for the DEV EVENT title, description, and actions.
  • Visual priority: motion stays behind the shade and content layers. Keep the center readable and avoid bloom, lens distortion, logo deformation, or dense particle trails.
  • Performance: render only while the hero intersects the viewport, cap pixel ratio, prefer low-power WebGL, and dispose GPU resources when the component unmounts.
  • Fallback: disable WebGL decoration at widths up to 600px, when prefers-reduced-motion: reduce is active, or when WebGL initialization fails. The static image must remain visually complete in every fallback.
  • Interaction: pointer movement may shift camera perspective slightly, but the canvas must use pointer-events: none and must not compete with navigation or CTAs.

11. Brand Landing Companion Services Contract

The / brand landing page presents Android, iOS, Instagram, Threads, email subscription, and the Whale browser extension as companion ways to keep using Dev Event beyond the website.

  • Placement: keep companion services in a dedicated section between the brand introduction and footer so they remain visible without competing with the primary event CTA.
  • Card anatomy: each card owns a code-native service icon, service name, one concise benefit-led description, and a directional arrow. Do not reuse third-party promotional banners as the card surface.
  • Visual language: use a flat near-black card surface, 24px radius, and solid color only. Decorative gradients, blurred glows, and card shadows are prohibited in this functional section.
  • Layout: pair services in a two-column grid on desktop/tablet β€” Android with iOS, Instagram with Threads, and email subscription with Whale β€” then collapse to one column on mobile with the same source order and no horizontal scrolling.
  • Interaction: the full card opens the external service in a new tab, provides a descriptive accessible name, and changes only its background and border color on hover. Do not translate, scale, or shadow the card; retain a visible keyboard focus outline.
  • Assets: use accurate Android, Apple, Instagram, and Threads brand glyphs from the existing local icon package. Reuse the repository's official Whale artwork for the browser extension. Email subscription is vendor-neutral, so use a polished generic mail symbol rather than a Gmail or other vendor mark.

12. Brand Landing Supporting Chrome Contract

  • Header: the brand landing header is wordmark-only. Primary event discovery remains in the hero CTA; do not add duplicate navigation links or an empty mobile menu.
  • Supporting CTA: use a solid neutral charcoal surface with a subtle neutral border. Avoid blue-tinted panels, gradients, or decorative glow; the white action button carries the emphasis.
  • Footer: retain the DEV EVENT wordmark, service description, and project copyright with the contributor name linked to the public GitHub repository. Pair these details with compact GitHub and Whale service links, following the information hierarchy of the /events footer while using the brand landing page's flat charcoal surfaces and focus treatment.

13. Brand Landing Route Entry Contract

  • Route ownership: the brand landing page lives at /about; / remains the service entry route and redirects to /events while preserving the existing authentication-token cookie handoff.
  • Service entry point: the shared service header places a compact 데브이벀트 μ†Œκ°œ link immediately after the DEV.EVENT logo. It routes internally to /about and remains visible on desktop and mobile.
  • Hierarchy: style the introduction link as a quiet secondary button so event discovery, theme controls, and account actions retain priority.