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-600corners - Flat surfaces, no decorative shadow β depth from background tier shifts (white β gray-050)
word-break: keep-alleverywhere β Korean text never breaks mid-word- Status badges with
pulsekeyframe glow for live/urgent states β the one allowed motion flourish
- 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.
λͺ¨λ 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
- Primary (
rgb(29, 108, 224)=#1D6CE0): Link text, primary text accents. Use withvar(--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 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.
| 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 |
--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
λ€ν¬ λͺ¨λλ λΌμ΄νΈμ Vapor μ€μΌμΌμ μμ λ§€ννμ§ μλλ€. λμ Wanted Design Systemμ λ€ν¬ μλ§¨ν± ν ν° (Figma qQPdpnglONbuWul4cvodyj β node 15625:32983 β Color/Semantic/Dark)μ μ§μ μ±μ©νλ€. μμ λ§€νμ΄ λ§λ€λ ν¨μ (μ: --vapor-gray-950 μ΄ λ€ν¬μμ ν°μμΌλ‘ λ€μ§ν μΉ΄λ active μνκ° ν°μ λ°μ€κ° λλ λ²κ·Έ)μ μ κ±°νκΈ° μν¨.
| 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 |
| 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 |
| Wanted ν ν° | hex | μ°λ¦¬ λ§€ν |
|---|---|---|
interaction-inactive |
#5A5C63 |
--vapor-gray-400, --gray-3 |
interaction-disable |
#2E2F33 |
(line-solid-altμ λμΌ) |
| 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 |
λ€ν¬μμλ 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λ₯Ό κ·Έλλ‘ μ μ§. λΈλλ μμ μ μ§νλ λ€ν¬μμλ§ ν λ¨κ³ λ°ν λ³μ’
μ μ°λ ν¨ν΄.
| Wanted ν ν° | hex | μ°λ¦¬ λ§€ν |
|---|---|---|
status-positive |
#1ED45A |
--vapor-text-success (dark) |
status-cautionary |
#FFA938 |
--vapor-text-warning (dark) |
status-negative |
#FF6363 |
--vapor-text-danger (dark) |
λ€ν¬ μ μ© λ°ν¬λͺ ν ν° (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) |
μλ¨ κ³΅μ§ λ°°λ ν΄νΈ |
- λ€ν¬ λͺ¨λ ν ν°μ
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λ₯Ό!importantoverrideνμ¬ λλΉλ₯Ό ν볡νκ³ , μΉ΄ν κ³ λ¦¬ μμborder-leftλ§ μ μ§νμ¬ μκ°μ νλ‘ λ¨κΈ΄λ€.
- 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.
| 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 |
- 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 κ°λ μ±μ κΈ°λ³ΈκΈ°.
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: μ μ² μ·¨μ, μμ
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 loadsposition: 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(λ§κ°μλ°) withpulse-*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
h5element- 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
- 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-contrastvariant: bgrgba(62, 64, 76, .32)over media
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
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
- 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
- Top nav height: 7.5rem (120px) β generous, accommodates logo + utility row + tab row
- Body has
padding-top: 7.5remglobal offset - Tab item:
--text-hintdefault,--text-normal+ 2px bottom border on active - Font: 1rem / weight 500 / 700 on active
| 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 |
- 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
- 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-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
| 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λ‘λ§.
- 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 andvar(--border-radius-600)(24px) for detail surfaces - Apply
letter-spacing: -0.012remto headings/card titles (not body) - Apply
word-break: keep-allglobally for Korean text integrity - Use
transform: scale(1.05)on.event-videofor the only card-hover signature - Use
pulse-blue/pulse-navy/pulse-dangerkeyframe 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 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>withsource 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λ μ¬μ©μ μλ.
| 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 |
- Card link: entire
.event-cardis tappable (anchor wraps everything) - Button minimum: 44Γ44px tap target β use
min-height: 2.75remfor icon-only buttons - Tab item: minimum 56px height with padding
- 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-cardpadding:--space-300(24px) desktop β--space-200(16px) mobile
- 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: coverinside fixed-aspect container
- 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)
-
Event Card: "Create an event card: anchor wrapping
.event-thumb(aspect-ratio 5/3, 12px radius,#F0F0F5placeholder 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-name16px weight 700#2B2D36single-line ellipsis with letter-spacing -0.012rem, then.event-periodsubtitle 14px#6C6E7Ewith calendar SVG icon 16Γ16 gap 4px, then.badge-containerflex-wrap gap 4px). On hover, only the video transformsscale(1.05)with 0.3s ease transition. No card border, no shadow." -
Primary Button: "Create a
.btn-ktbprimary button: bg#0043ff, hover bg#0238D1, text#ffffffweight 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-titlecolor#2B2D36margin 0, then.event-descriptioncolor#6C6E7Emargin 0, then.btn-ktbprimary 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. Applyanimation: pulse-blue 2s infinite;where@keyframes pulse-bluegoes frombox-shadow: 0 0 0 0 rgba(0, 67, 255, 0.6)to0 0 0 8px rgba(0, 67, 255, 0)to0 0 0 0 rgba(0, 67, 255, 0)." -
Chip / Tag: "Create a chip: bg
#F0F0F5, text#3E404Cweight 500 size 12px, padding 2px 8px, border-radius 6px. Use inside.badge-containerof an event card to show category/region/online tags."
- Pretendard is the single font β UI/display/body/caption all share one family. Never mix fonts.
- Two radii do 90% of the work: 12px (
--border-radius-400) for list cards/buttons/inputs, 24px (--border-radius-600) for detail surfaces. - The card is shape-less; the thumb carries the silhouette. Don't add borders or shadows to cards.
- Hover is media-only:
.event-video { transform: scale(1.05); transition: transform 0.3s ease; }β nothing else changes on hover. - Status badges pulse, nothing else does:
pulse-blue/pulse-navy/pulse-dangerkeyframes are the only motion language outside of media zoom. - Gradient accents are display-only: hero copy, marketing banner. Never on functional UI.
- Section banding: white (
--gray-000) β near-white (--background-alternative#F7F7FA). Just two background tiers, alternated. - Korean-first typography:
letter-spacing: -0.012remon headings,word-break: keep-allglobally. - 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.
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 EVENTtitle, 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: reduceis 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: noneand must not compete with navigation or CTAs.
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.
- 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 EVENTwordmark, 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/eventsfooter while using the brand landing page's flat charcoal surfaces and focus treatment.
- Route ownership: the brand landing page lives at
/about;/remains the service entry route and redirects to/eventswhile preserving the existing authentication-token cookie handoff. - Service entry point: the shared service header places a compact
λ°λΈμ΄λ²€νΈ μκ°link immediately after theDEV.EVENTlogo. It routes internally to/aboutand 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.