모든 도구 디자인 시스템 갤러리

CLASS101 (클래스101)

흰 화면 위 오렌지 #FF5D00 한 점 — 구독은 오렌지, 개별 구매는 바이올렛으로 가르는 Vibrant 토큰

한국소비자라이프스타일따뜻한modern-minimal고딕comfortablesoftsubtle라이트다크한글 지원출시 2022개정 2023

갤러리에서 열기 — 적용 예시 · 가이드 다운로드

Brand DNA

브랜드 DNA

  • 브랜드명: CLASS101 (클래스101, 운영사 ㈜클래스101 · 구 페달링)
  • 한 줄 정체성: 취미·부업·재테크·AI 까지 "원하는 모든 것, 나답게 배우다"(사이트 <title>)를 내건 한국 온라인 클래스 플랫폼. 2022년 8월 말 월 구독형 CLASS101+ 로 사업 모델을 바꿨고, 지금은 첫 화면이 구독(svod)이며 개별 구매(tvod)는 헤더의 전환 링크로 따로 연다.
  • 공식 디자인 철학: 사내 디자인 시스템 Vibrant Design System(구 One Product System, 구독 런칭에 맞춰 개편 · 2023-01 공개 글). 핵심 가치는 Cross Platform · Productive · Consistent. Foundation → Tokens → Core Systems → Components 4층을 Assets · Documentation · Process 세 파트가 공유하는 "양파 구조". 구독 제품 원칙은 "콘텐츠에 집중할 수 있게" — 띠배너를 줄이고, 다크 모드를 들이고, 기기별로 같은 경험을 준다. 문서화 글에서 "왜 우리는 하필 오렌지 색상을 프라이머리로 지정했고, 왜 그 HEX 값이어야 하는지"를 Foundation 의 몫으로 적었다.
  • 시그니처 요소 1개: 흰(또는 #0C0C0C) 화면 위 오렌지 #FF5D00 한 점. 오렌지는 구독(plusColor)과 주요 CTA 에만 쓰고, 개별 구매 모드는 바이올렛 #A839FD(masterColor)로 칠해 두 사업을 색으로 가른다. 할인율은 오렌지가 아니라 빨강 #E30F32.

Tone & Mood

톤 & 무드

  • 핵심 키워드 3개: 선명, 몰입, 친근
  • 무드 설명: 넓은 흰 바탕과 거의 검정(#0C0C0C) 글자, 그 위에 오렌지 CTA 하나와 사진 썸네일이 화면을 채운다. 장식 테두리·그림자는 거의 없고, 색은 "구독=오렌지 / 개별 구매=바이올렛 / 할인=빨강 / 별점=노랑"처럼 의미마다 한 가지다. 구독 헤드라인 "무제한 구독"만 오렌지→갈색 방사형 그라데이션 글자로 힘을 준다.
  • 비주얼 스타일: 모던 미니멀
  • 밀도(Density): Comfortable — 클래스 카드 4열 그리드(썸네일 280×158)에 본문 14px/18px, 한 카드에 제목·크리에이터·할인가·별점을 촘촘히 담되 카드 사이 여백은 넉넉하다.
  • 모서리 성향: Soft(4~8px) — 버튼·로그인·「참여하기」·썸네일 8px, 개별 구매 썸네일 4px. 구독 CTA·비교 카드만 12px.
  • 평면성: Subtle — 카드는 테두리·그림자 없이 썸네일과 글자로만 구분하고, 그림자(--vb-e-1~4)는 떠 있는 바(하단 고정 구독 바)·드롭다운에만 쓴다.

Color System

컬러 시스템 (CSS 변수)

class101.net 이 SSR 로 심는 Vibrant 토큰(--vb-c-*)과 _app 번들의 원자 팔레트(orange·red·yellow·green·blue·violet·magenta·neutral 5~95 단계)를 그대로 옮겼다. (추정) 표시가 없는 값은 전부 실측이다.

:root {
  /* Primary - Vibrant orange (orange 60 = primary · plusColorVibrant) */
  --color-primary-50:  #FCF5F1;  /* orange 95 · primaryContainer · 구독 섹션 옅은 배경 */
  --color-primary-100: #FBE2D7;  /* orange 90 */
  --color-primary-200: #FCCFB9;  /* orange 85 */
  --color-primary-300: #FDBA9A;  /* orange 80 · plusColorSoft */
  --color-primary-400: #FF8D57;  /* orange 70 · 구독 CTA 그라데이션 윗단 */
  --color-primary-500: #FF5D00;  /* orange 60 · primary (기본) */
  --color-primary-600: #E35200;  /* orange 55 · hover 대응 (추정 용도) */
  --color-primary-700: #CD4900;  /* orange 50 · orangeContrast · 옅은 면 위 오렌지 글자 */
  --color-primary-800: #A33800;  /* orange 40 */
  --color-primary-900: #371A07;  /* orange 15 · orangeInverse · 헤드라인 그라데이션 끝 */

  /* Secondary - 개별 구매(masterColor) 바이올렛 */
  --color-secondary-50:  #F8F1FC;  /* violet 95 · masterColorMuted */
  --color-secondary-300: #E2B8FD;  /* violet 80 · masterColorSoft */
  --color-secondary-500: #A839FD;  /* violet 50 · masterColorVibrant · 「개별 구매」 모드 라벨 */
  --color-secondary-700: #8A04E4;  /* violet 40 · masterColorContrast */

  /* Neutral - Vibrant neutral */
  --color-neutral-0:    #FFFFFF;  /* background · surface2 */
  --color-neutral-50:   #F3F3F3;  /* neutral 95 · neutralMuted */
  --color-neutral-100:  #E5E5E5;  /* neutral 90 */
  --color-neutral-300:  #C7C7C7;  /* neutral 80 · surface4 */
  --color-neutral-500:  #949494;  /* neutral 60 · onView3 (보조 글자) */
  --color-neutral-700:  #5B5B5B;  /* neutral 40 · neutralContrast */
  --color-neutral-900:  #0C0C0C;  /* neutral 5 · onView1 (본문 글자·로고) */
  --color-neutral-1000: #000000;

  /* Semantic */
  --color-success-bg: #DBFCE1;  /* successContainer */
  --color-success-fg: #078641;  /* success */
  --color-warning-bg: #FCF2E7;  /* warningContainer */
  --color-warning-fg: #B27307;  /* onWarningContainer (warning 원색은 #FCA50E · 별점) */
  --color-error-bg:   #FCF1F0;  /* errorContainer */
  --color-error-fg:   #E30F32;  /* error · 할인율 숫자 */
  --color-info-bg:    #F3F3FC;  /* informativeContainer */
  --color-info-fg:    #376DFA;  /* informative · AI 스킬업 아이콘 */

  /* Surface (배경 위계) */
  --bg-base:     #FFFFFF;    /* background */
  --bg-subtle:   #00000008;  /* surface1 · 로그인·「참여하기」 버튼 면 */
  --bg-elevated: #FFFFFF;    /* surface2 · 카드 */
  --bg-overlay:  #FFFFFF;    /* surface3 · 모달·드롭다운 (뒤 딤 #000000B2) */

  /* Text 위계 */
  --text-primary:    #0C0C0C;    /* onView1 */
  --text-secondary:  #373737CC;  /* onView2 */
  --text-tertiary:   #949494;    /* onView3 · 크리에이터명·개월 수 */
  --text-on-primary: #FFFFFF;    /* onPrimary */
  --text-disabled:   #C7C7C7;    /* (추정) disable 면 #0000001A 위 글자 */

  /* Border */
  --border-default: #0000001A;  /* outline2 */
  --border-subtle:  #0000000D;  /* outline1 */
  --border-strong:  #0C0C0C;    /* outlineNeutral */
  --border-focus:   #00000033;  /* outlineFocus */

  /* 상태 레이어 (Vibrant opacity 토큰) */
  --overlay-hover:  0.025;  /* --vb-o-overlay-hover */
  --overlay-active: 0.075;  /* --vb-o-overlay-active · focus 도 같음 */
  --text-active:    0.6;    /* --vb-o-text-active */
}

[data-theme="dark"] {
  --color-primary-50:  #1C1008;  /* orange 10 · 다크 primaryContainer */
  --color-primary-500: #FF5D00;  /* primary 는 다크에서도 그대로 */
  --color-primary-700: #FF7430;  /* orange 65 · 다크 onViewPrimary */
  --color-secondary-500: #A839FD;
  --color-neutral-0:   #0C0C0C;
  --color-neutral-50:  #171717;
  --color-neutral-100: #2B2B2B;
  --color-neutral-500: #747474;
  --color-neutral-900: #F3F3F3;
  --color-success-bg: #071309; --color-success-fg: #0CA954;
  --color-warning-bg: #1A1308; --color-warning-fg: #FCA50E;
  --color-error-bg:   #200D08; --color-error-fg:   #FD5B59;
  --color-info-bg:    #0E142A; --color-info-fg:    #788BFB;
  --bg-base:     #0C0C0C;
  --bg-subtle:   #FFFFFF0D;
  --bg-elevated: #171717;
  --bg-overlay:  #000000;
  --text-primary:   #F3F3F3;
  --text-secondary: #F3F3F3A6;
  --text-tertiary:  #747474;
  --text-disabled:  #FFFFFF26;
  --border-default: #FFFFFF26;
  --border-subtle:  #FFFFFF14;
  --border-strong:  #F3F3F3;
  --border-focus:   #FFFFFF26;
}

### ③.1 사용 컨텍스트 주석

  • 오렌지는 구독 전용 신호다. 헤더의 「구독」 라벨(20px/700), 「구독 시작하기」 CTA(linear-gradient(0deg, #FF5D00 40%, #FF8D57 100%), 240×50, radius 12px), 비교표의 CLASS101+ 열이 오렌지다. 개별 구매 모드로 넘어가면 같은 자리의 라벨이 바이올렛 #A839FD 로 바뀐다.
  • 할인율은 빨강(error #E30F32, 14px/600), 가격은 #0C0C0C 굵게, 「12개월」 할부 표기는 #949494. 별점 별은 노랑 계열(#FCA50E).
  • 면 색은 불투명 회색 대신 검정 알파(#00000008·#0000000D·#0000001A)로 쌓는다. 다크에서는 같은 자리를 흰색 알파로 뒤집는다.
  • 다크 모드는 시스템 설정을 따르며(쿠키 theme_preference, 기본 system), meta[name=theme-color] 를 #0C0C0C 로 바꾼다. 2022년 구독 런칭 당시 구독 제품은 다크로만 디자인됐고 이때 Vibrant 컬러 체계를 다크 대응으로 전면 개편했다. 현행 웹은 라이트가 기본, 시스템이 다크면 다크로 그린다.

Typography

타이포그래피

  • 폰트 페어링:
    • 한글: Pretendard Variable / Pretendard JP Variable (SIL OFL) — 사이트가 jsDelivr 에서 dynamic subset 으로 불러온다
    • 영문: 같은 Pretendard. 폴백 system-ui, -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", "Segoe UI", "Noto Sans KR", "Malgun Gothic", sans-serif (실측 font-family)
  • 위계 (font-size / font-weight / line-height / letter-spacing):
    • Display: 40px / 800 / 50px / -0.02em — 구독 첫 화면 H1 「무제한 구독으로 더하는 가능성」 (실측)
    • H1: 32px / 700 / 40px / -0.02em (추정)
    • H2: 24px / 700 / 32px / -0.018em (추정) — 「구독 인기 클래스」 섹션 제목
    • H3: 20px / 700 / 26px / -0.018em — 헤더 「구독」·「개별 구매」 모드 라벨 (실측 -0.36px)
    • Body Large: 18px / 700 / 22px / -0.016em — 「지금 인기 있는」 섹션 제목 (실측 -0.288px)
    • Body: 14px / 400~700 / 18px / -0.012em — 카드 제목·할인가·「참여하기」 (실측 -0.168px)
    • Body Small: 13px / 500 / 18px / -0.01em — 별점·수강 정보 (실측)
    • Caption: 11px / 500 / 14px / 0 (추정, 0.6875rem 사용 확인)

Spacing

스페이싱

  • Base unit: 4px (Tailwind 유틸이 p-4·gap-10·gap-16·px-16·h-160 처럼 px 숫자 그대로다)
  • 토큰: ``css --space-xs: 4px; --space-sm: 8px; --space-md: 16px; /* 카드 안 여백·모바일 좌우 */ --space-lg: 24px; --space-xl: 32px; --space-2xl: 48px; /* 섹션 사이 (추정) */ --space-3xl: 64px; ``
  • Container: 데스크톱 1280 뷰포트에서 좌우 40px, 콘텐츠 폭 약 1184px(카드 280px × 4 + 간격 20px). 모바일 좌우 20px (추정).

Border Radius

Border Radius

--radius-none: 0;
--radius-sm: 4px;      /* 개별 구매 카드 썸네일 */
--radius-md: 8px;      /* 버튼·로그인·「참여하기」·검색창·카테고리 타일 */
--radius-lg: 12px;     /* 구독 CTA·구독 비교 카드 */
--radius-xl: 16px;     /* 바텀시트·모달 (추정) */
--radius-full: 9999px; /* 원형 아이콘 버튼 (코드상 10000px) */

Shadow / Elevation

Shadow / Elevation

--shadow-none: none;
--shadow-sm: 0px 2px 6px 0px rgba(0,0,0,.04), 0px 2px 1px 0px rgba(0,0,0,.04);        /* --vb-e-1 · 칩·작은 버튼 */
--shadow-md: 0px 5px 8px -1px rgba(0,0,0,.06), 0px 1px 4px 0px rgba(0,0,0,.04);       /* --vb-e-2 · 떠 있는 구독 바·비교 카드 */
--shadow-lg: 0px 20px 20px -4px rgba(0,0,0,.10), 0px 12px 12px -2px rgba(0,0,0,.04), 0px 2px 7px 1px rgba(0,0,0,.04);  /* --vb-e-3 · 드롭다운·카테고리 메뉴 */
--shadow-xl: 0px 28px 28px -4px rgba(0,0,0,.16), 0px 16px 16px -2px rgba(0,0,0,.06), 0px 2px 8px 1px rgba(0,0,0,.04);  /* --vb-e-4 · 모달 */

클래스 카드 자체에는 그림자를 쓰지 않는다. 이미지 위 글자 가독성은 그림자 대신 --vb-g-linearBottom 같은 16단계 흰/검 그라데이션 스크림으로 푼다.

Iconography

Iconography

  • 스타일: Outline 기본 + Filled 혼합. 자체 아이콘 세트가 search-thin·chevrondown-regular·linkoutside-regular·gridsqaure2x2-fill 처럼 이름 뒤에 굵기(thin/regular/fill) 를 붙인다. 카테고리 내비는 색이 든 채움 아이콘(AI 스킬업=파랑 별, 창업·부업=보라 상점, 디지털 드로잉=오렌지 화면, 라이프스타일=초록).
  • Stroke 굵기: thin ≈1.25px, regular ≈1.75px (24px 기준, 추정)
  • 모서리 처리: Round
  • 추천 라이브러리: Phosphor (thin/regular/fill 굵기 체계가 가장 가깝다)

Component Guide

컴포넌트 가이드 (상태별 CSS)

Vibrant 는 hover·pressed 에 색을 바꾸지 않고 상태 레이어(검정 2.5% / 7.5%)를 덮는다. 전환은 160ms cubic-bezier(0.5, 1, 0.89, 1).

Button

.c1-btn { position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: 38px; padding: 0 16px; border: 0; border-radius: var(--radius-md);
  font: 700 14px/18px Pretendard, sans-serif; letter-spacing: -0.012em; cursor: pointer; overflow: hidden;
  transition: opacity 160ms cubic-bezier(0.5,1,0.89,1); }
.c1-btn::after { content: ""; position: absolute; inset: 0; background: #000; opacity: 0; transition: opacity 160ms cubic-bezier(0.5,1,0.89,1); }
.c1-btn:hover::after { opacity: var(--overlay-hover); }
.c1-btn:active::after { opacity: var(--overlay-active); }
.c1-btn:disabled { background: var(--border-default); color: var(--text-disabled); cursor: not-allowed; }
.c1-btn:disabled::after { opacity: 0; }
.c1-btn.is-loading { color: transparent; pointer-events: none; }
.c1-btn.is-loading::before { content: ""; position: absolute; width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid currentColor; border-color: var(--text-on-primary) transparent var(--text-on-primary) var(--text-on-primary); animation: c1-spin .8s linear infinite; }
@keyframes c1-spin { to { transform: rotate(360deg); } }

/* Primary — 구독 CTA */
.c1-btn--primary { height: 50px; padding: 0 32px; border-radius: var(--radius-lg); font-size: 16px; line-height: 20px;
  color: var(--text-on-primary); background: linear-gradient(0deg, var(--color-primary-500) 40%, var(--color-primary-400) 100%); }
/* Secondary — 「참여하기」·「로그인」 회색 면 */
.c1-btn--secondary { background: var(--bg-subtle); color: var(--text-primary); }
/* Ghost — 「포함된 모든 클래스 보기 >」 */
.c1-btn--ghost { background: transparent; color: var(--text-primary); font-weight: 500; padding: 0 4px; border-radius: var(--radius-sm); }
.c1-btn--ghost:active { opacity: var(--text-active); }
/* Danger */
.c1-btn--danger { background: var(--color-error-fg); color: #FFFFFF; }

Input

.c1-search { display: flex; align-items: center; gap: 8px; height: 44px; padding: 0 16px;
  border-radius: var(--radius-md); background: var(--bg-base); box-shadow: inset 0 0 0 1px var(--border-subtle);
  font: 400 14px/18px Pretendard, sans-serif; color: var(--text-primary); }
.c1-search::placeholder { color: var(--text-tertiary); }         /* 「클래스, 크리에이터」 */
.c1-search:focus { outline: none; box-shadow: inset 0 0 0 1px var(--border-focus); }
.c1-search.is-error { box-shadow: inset 0 0 0 1px var(--color-error-fg); }
.c1-search:disabled { background: var(--bg-subtle); color: var(--text-disabled); }

Card

/* 기본형 — 클래스 카드: 테두리·그림자 없음 */
.c1-class { display: flex; flex-direction: column; gap: 4px; }
.c1-class__thumb { aspect-ratio: 16 / 9; border-radius: var(--radius-sm); overflow: hidden; position: relative; background: var(--bg-subtle); }
.c1-class__title { font: 400 14px/18px Pretendard, sans-serif; color: var(--text-primary); margin-top: 8px; }
.c1-class__meta  { font: 400 13px/18px Pretendard, sans-serif; color: var(--text-tertiary); }
.c1-class__price b { color: var(--color-error-fg); font-weight: 600; }   /* 할인율 */
.c1-class__price strong { color: var(--text-primary); font-weight: 700; }
/* 강조형 — CLASS101+ 비교 카드 */
.c1-card--plus { border-radius: var(--radius-lg); color: #FFFFFF;
  background: linear-gradient(180deg, var(--color-primary-500) 0%, #2A1A10 45%, #1C1C1C 100%);
  box-shadow: inset 0 0 0 2px var(--color-primary-500); }
/* Outlined — 라이브 특강 카드 */
.c1-card--outlined { border-radius: var(--radius-md); padding: 8px; background: var(--bg-elevated); box-shadow: inset 0 0 0 1px var(--border-subtle); }

Badge / Tag

.c1-badge { display: inline-flex; align-items: center; height: 20px; padding: 0 6px; border-radius: var(--radius-sm); font: 700 11px/14px Pretendard, sans-serif; }
.c1-badge--solid   { background: var(--color-error-fg); color: #FFFFFF; }            /* 「● 09.28 라이브」 */
.c1-badge--subtle  { background: var(--color-primary-50); color: var(--color-primary-500); }
.c1-badge--outline { box-shadow: inset 0 0 0 1px var(--border-default); color: var(--text-secondary); }
.c1-badge--new     { background: #FCA50E; color: #0A0703; }                          /* 「NEW」 */

Navigation

.c1-gnb { height: 72px; display: flex; align-items: center; gap: 16px; padding: 0 40px; background: var(--bg-base); }
.c1-gnb__mode { font: 700 20px/26px Pretendard, sans-serif; letter-spacing: -0.018em; color: var(--color-primary-500); } /* 구독 */
.c1-gnb__mode--tvod { color: var(--color-secondary-500); }                                                               /* 개별 구매 */
.c1-gnb__switch { font: 500 16px/20px Pretendard, sans-serif; color: var(--text-secondary); padding-left: 16px; box-shadow: inset 1px 0 0 var(--border-default); }
.c1-catnav { display: flex; gap: 24px; height: 44px; align-items: center; font: 600 14px/18px Pretendard, sans-serif; }
.c1-catnav a { display: flex; gap: 6px; align-items: center; color: var(--text-primary); }

Motion

Motion

--duration-fast: 160ms;   /* 버튼·링크 상태 레이어 (가장 많이 쓰임) */
--duration-base: 200ms;   /* 로고 링크 opacity */
--duration-slow: 300ms;
--ease-out: cubic-bezier(0.5, 1, 0.89, 1);      /* easeOutQuad — 기본 */
--ease-in-out: cubic-bezier(0.25, 0.46, 0.45, 0.94);
--ease-expo: cubic-bezier(0.16, 1, 0.3, 1);     /* 캐러셀·패널 */

숫자는 rolling-number 컴포넌트로 굴러 올라가며 바뀐다(할인율·수강 인원).

Anti-patterns

Anti-patterns

1. 할인율을 브랜드 오렌지로 칠하지 않는다 — 할인율은 error 빨강 #E30F32, 오렌지는 구독·CTA 의 신호로 남겨 둔다. 2. 구독(오렌지)과 개별 구매(바이올렛)를 한 화면에 섞지 않는다 — 두 사업 모드를 색으로 구분하는 것이 토큰의 존재 이유(plusColor·masterColor)다. 3. 클래스 카드에 테두리·그림자를 두르지 않는다 — 썸네일과 글자만으로 카드가 되고, 그림자는 떠 있는 요소에만 쓴다. 4. hover 에 새 색을 만들지 않는다 — 검정 2.5%·7.5% 상태 레이어와 글자 opacity 0.6 으로만 반응한다. 5. 띠배너·광고성 메시지로 콘텐츠를 덮지 않는다 — 구독 제품 원칙("콘텐츠로 가치를 느낄 수 있게")에 따라 첫 화면은 헤드라인·CTA 하나·클래스 이미지뿐이다. 본문은 순검정 대신 #0C0C0C.

Sources

출처

  1. https://class101.net/ko
  2. https://class101.net/ko?viewMode=tvod
  3. https://class101.net/_next/static/css/15c96241106c1dd0.css
  4. https://class101.net/_next/static/chunks/pages/_app-fb46b184dc28db7b.js
  5. https://medium.com/class101/vibrant-design-system%EC%9D%84-%EC%86%8C%EA%B0%9C%ED%95%A9%EB%8B%88%EB%8B%A4-e66ba0ae1dc3
  6. https://medium.com/class101/%EA%B5%AC%EB%8F%85%EA%B3%BC-%ED%95%A8%EA%BB%98-%EC%99%84%EC%A0%84%ED%9E%88-%EC%83%88%EB%A1%9C%EC%9B%8C%EC%A7%84-%ED%81%B4%EB%9E%98%EC%8A%A4101-b1beb363aa91
  7. https://medium.com/class101/%ED%81%B4%EB%9E%98%EC%8A%A4101%EC%9D%98-%EB%94%94%EC%9E%90%EC%9D%B8-%EC%8B%9C%EC%8A%A4%ED%85%9C-one-product-system-35681c551343