디자인 시스템 갤러리 Shopify Polaris

Shopify Polaris

잉크 블랙 액션과 상태 중심 컬러의 커머스 어드민

서양디자인 시스템이커머스중립modern-minimalhumanism고딕comfortablesoftsubtle라이트공식한글 지원출시 2017개정 2024

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

Brand DNA

브랜드 DNA

  • 브랜드명: Shopify Polaris
  • 한 줄 정체성: 머천트(상점주)의 일을 자신감 있게 해내도록 돕는 커머스 어드민 시스템
  • 공식 디자인 철학: "Build for merchants — empower them to focus on what matters"
  • 시그니처 요소 1개: 잉크 블랙(#303030) 핵심 액션과 의미가 있을 때만 쓰는 상태 컬러가 만드는 커머스 어드민 위계

Tone & Mood

톤 & 무드

  • 핵심 키워드 3개: 신뢰, 효율, 따뜻함
  • 무드 설명: 밝은 중성 캔버스와 선명한 잉크 블랙 액션으로 업무 우선순위를 즉시 드러낸다. 그린·옐로·레드는 브랜드 장식이 아니라 완료·주의·오류처럼 뜻이 분명한 상태에만 사용해 머천트의 판단을 돕는다.
  • 비주얼 스타일: 모던 미니멀 + 휴머니즘 (부드러운 모서리, 친근한 안내 문장)
  • 밀도(Density): Comfortable — 다양한 숙련도의 머천트를 위해 여유 있는 라인
  • 모서리 성향: Soft (8px 기본 컴포넌트, 12px 카드)
  • 평면성: Subtle — 옅은 중성 배경 위 surface, 1px border, 최소 그림자의 조합

Color System

컬러 시스템 (CSS 변수)

:root {
  /* Primary - Polaris Ink: 핵심 액션과 선택 위계 */
  --color-primary-50:  #F7F7F7;
  --color-primary-100: #F1F1F1;
  --color-primary-200: #E3E3E3;
  --color-primary-300: #CCCCCC;
  --color-primary-400: #8A8A8A;
  --color-primary-500: #303030;  /* primary action */
  --color-primary-600: #252525;  /* hover */
  --color-primary-700: #1A1A1A;  /* active / admin top bar */
  --color-primary-800: #111111;
  --color-primary-900: #0A0A0A;

  /* Secondary - Shopify Green은 완료·성공에 제한 */
  --color-secondary-500: #29845A;

  /* Neutral - current Polaris admin */
  --color-neutral-0:    #FFFFFF;
  --color-neutral-50:   #F7F7F7;  /* surface hover */
  --color-neutral-100:  #F1F1F1;  /* page / subdued */
  --color-neutral-200:  #E3E3E3;  /* divider */
  --color-neutral-300:  #CCCCCC;
  --color-neutral-500:  #8A8A8A;
  --color-neutral-700:  #616161;  /* subdued text */
  --color-neutral-800:  #4A4A4A;
  --color-neutral-900:  #303030;  /* primary text */
  --color-neutral-1000: #000000;

  /* Semantic - 컬러와 레이블/아이콘을 함께 사용 */
  --color-success-bg: #CDFEE1;
  --color-success-fg: #0C5132;
  --color-warning-bg: #FFF1E3;
  --color-warning-fg: #5E4200;
  --color-error-bg:   #FEE9E8;
  --color-error-fg:   #8E1F0B;
  --color-info-bg:    #EAF4FF;
  --color-info-fg:    #005BD3;

  /* Surface */
  --bg-base:     #F1F1F1;        /* Shopify Admin page */
  --bg-subtle:   #F7F7F7;
  --bg-elevated: #FFFFFF;        /* card */
  --bg-overlay:  #FFFFFF;

  /* Text */
  --text-primary:    #303030;
  --text-secondary:  #616161;
  --text-tertiary:   #8A8A8A;
  --text-on-primary: #FFFFFF;
  --text-disabled:   #B5B5B5;

  /* Border */
  --border-default: #CCCCCC;
  --border-subtle:  #E3E3E3;
  --border-strong:  #8A8A8A;
  --border-focus:   #005BD3;
}

Typography

타이포그래피

  • 폰트 페어링:
    • 영문: system-ui / San Francisco / Segoe UI / Roboto (플랫폼 기본 라이선스)
    • 한글: Pretendard (OFL) 또는 플랫폼 시스템 고딕 폴백
  • 위계 (관리 화면의 높은 정보 밀도 기준):
    • Display: 32px / 700 / 1.20 / -0.02em
    • H1: 20px / 650 / 1.40 / -0.01em
    • H2: 16px / 650 / 1.50 / 0
    • H3: 14px / 650 / 1.43 / 0
    • Body Large: 15px / 400 / 1.53 / 0
    • Body: 13px / 400 / 1.54 / 0
    • Body Small: 12px / 400 / 1.50 / 0
    • Caption: 11px / 400 / 1.45 / 0.01em

Spacing

스페이싱

  • Base unit: 4px
  • 토큰: ``css --space-xs: 4px; --space-sm: 8px; --space-md: 16px; --space-lg: 20px; /* Polaris는 20px도 자주 사용 */ --space-xl: 32px; --space-2xl: 48px; --space-3xl: 64px; ``
  • Container: max-width 1140px (admin 기본), 좌우 패딩 16px (mobile) / 32px (desktop)

Border Radius

Border Radius

--radius-none: 0;
--radius-sm: 4px;
--radius-md: 8px;     /* 버튼, 입력 */
--radius-lg: 12px;    /* 카드 */
--radius-xl: 16px;
--radius-full: 9999px;

Shadow / Elevation

Shadow / Elevation

--shadow-none: none;
--shadow-sm: 0 1px 0 rgba(0,0,0,0.05);                                  /* resting card */
--shadow-md: 0 2px 4px rgba(0,0,0,0.10), 0 1px 0 rgba(0,0,0,0.05);      /* floating action */
--shadow-lg: 0 8px 20px rgba(0,0,0,0.14);                               /* popover */
--shadow-xl: 0 16px 40px rgba(0,0,0,0.18);                              /* modal */

Iconography

Iconography

  • 스타일: Outline 중심 + 선택·상태에서만 Filled
  • Stroke 굵기: 1.5px (16px 기본) / 2px (20px 강조)
  • 모서리 처리: Round
  • 추천 라이브러리: Shopify Polaris Icons / Lucide (대체 시 의미와 16px 그리드 유지)

Component Guide

컴포넌트 가이드

Button

.btn {
  font: 650 13px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", "Pretendard", sans-serif;
  border-radius: var(--radius-md);
  padding: 7px 12px;
  min-height: 32px;
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid transparent;
  justify-content: center;
  transition: background var(--duration-fast) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out);
}
.btn-primary { background: var(--color-primary-500); color: var(--text-on-primary); box-shadow: inset 0 1px 0 rgba(255,255,255,0.18), 0 1px 0 rgba(0,0,0,0.20); }
.btn-primary:hover { background: var(--color-primary-600); }
.btn-primary:active { background: var(--color-primary-700); box-shadow: inset 0 1px 2px rgba(0,0,0,0.32); }
.btn:disabled { background: var(--color-neutral-100); color: var(--text-disabled); border-color: var(--border-subtle); box-shadow: none; cursor: not-allowed; }
.btn.is-loading { color: transparent; position: relative; pointer-events: none; }
.btn.is-loading::after { content: ""; position: absolute; width: 12px; height: 12px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; color: var(--text-on-primary); }

.btn-secondary { background: var(--bg-elevated); color: var(--text-primary); border-color: var(--border-default); box-shadow: var(--shadow-sm); }
.btn-secondary:hover { background: var(--bg-subtle); }
.btn-secondary:active { background: var(--color-neutral-100); box-shadow: inset 0 1px 1px rgba(0,0,0,0.08); }
.btn-ghost { background: transparent; color: var(--text-primary); }
.btn-ghost:hover { background: var(--color-neutral-100); }
.btn-danger { background: var(--color-error-fg); color: #fff; box-shadow: inset 0 1px 0 rgba(255,255,255,0.18); }

Input

.input {
  background: var(--bg-elevated);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  padding: 6px 10px;
  height: 32px;
  color: var(--text-primary);
  font: 400 13px/1.4 inherit;
  box-shadow: 0 0 0 1px transparent inset;
}
.input:focus {
  outline: none;
  border-color: var(--border-focus);
  box-shadow: 0 0 0 1px var(--border-focus) inset;
}
.input[aria-invalid="true"] { border-color: var(--color-error-fg); box-shadow: 0 0 0 1px var(--color-error-fg) inset; }
.input:disabled { background: var(--color-neutral-100); color: var(--text-disabled); border-color: var(--border-subtle); }

Card

.card { background: var(--bg-elevated); border-radius: var(--radius-lg); padding: 20px; box-shadow: var(--shadow-sm); border: 1px solid var(--border-subtle); }
.card-emphasized { border-color: var(--border-strong); box-shadow: var(--shadow-md); }
.card-outlined { background: transparent; box-shadow: none; }

Badge

.badge { padding: 2px 8px; border-radius: var(--radius-sm); font-size: 12px; font-weight: 500; display: inline-flex; align-items: center; gap: 4px; }
.badge-solid   { background: var(--color-primary-500); color: #fff; }
.badge-subtle  { background: var(--color-neutral-100); color: var(--text-primary); }
.badge-outline { border: 1px solid var(--border-default); color: var(--text-primary); }
.badge-success { background: var(--color-success-bg); color: var(--color-success-fg); }
.badge-warning { background: var(--color-warning-bg); color: var(--color-warning-fg); }

Navigation (Admin Shell)

.topbar { height: 44px; background: var(--color-primary-700); color: #F7F7F7; display: flex; align-items: center; padding: 0 12px; gap: 12px; box-shadow: 0 1px 0 rgba(0,0,0,0.28); }
.sidebar { width: 224px; background: #EBEBEB; border-right: 1px solid var(--border-subtle); padding: 12px; }
.nav-item { min-height: 32px; border-radius: var(--radius-md); padding: 6px 8px; color: var(--text-secondary); display: flex; align-items: center; gap: 8px; }
.nav-item:hover, .nav-item[aria-current="page"] { background: #D4D4D4; color: var(--text-primary); }

Motion

Motion

--duration-fast: 100ms;
--duration-base: 200ms;
--duration-slow: 300ms;
--ease-out: cubic-bezier(0.4, 0.22, 0.28, 1);
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);

Anti-patterns

Anti-patterns

1. 초록색을 기본 CTA나 장식에 사용 금지 — 현재 Polaris에서 초록은 성공·완료 의미에 집중 2. 어드민 화면에 채도 높은 그라데이션 배경 금지 — 데이터와 작업 흐름을 방해 3. 상태를 색만으로 전달 금지 — 배지 문구와 아이콘을 함께 제공 4. 같은 작업 영역에 primary 버튼을 둘 이상 배치 금지 — 행동 위계가 흐려짐 5. 카드마다 강한 그림자를 반복 사용 금지 — 1px border와 surface 위계를 우선

Sources

출처

  1. https://polaris.shopify.com/
  2. https://polaris.shopify.com/tokens/colors
  3. https://polaris.shopify.com/design/typography
  4. https://shopify.dev/docs/apps/design/visual-design
  5. https://shopify.dev/docs/api/app-home/web-components