Visa
결제창 위 Visa 패스키 창 — 큰 Visa 마크가 비치는 #1434CB 카드 아트에 금·파랑 지문 배지, 남색 6px 「Authorise payment」
Brand DNA
브랜드 DNA
- 브랜드명: Visa (비자) — 이 문서가 다루는 것은 Visa 의 제품 디자인 시스템 VPDS(Visa Product Design System, design.visa.com)와 그것으로 만든 Visa 디지털 제품이다. 그중 중심은 온라인 결제 Click to Pay — 가입·카드 관리 화면 src.visa.com, 결제 중 뜨는 패스키 확인 창 clicktopay.auth.visa.com. 마케팅 사이트 visa.com 은 같은 브랜드지만 행동 버튼 모양이 달라 따로 적었다(⑥·⑨).
- 한 줄 정체성: 200여 개 나라·지역에서 카드 결제망을 운영하는 결제 네트워크. 화면에서는 발급사(은행)와 가맹점 사이에 서서 「이 결제는 안전하다」를 확인해 주는 역할이라, 화면의 주인공은 Visa 가 아니라 고객의 카드와 결제 금액이다.
- 공식 디자인 철학 (확인한 문구 기준):
- VPDS 첫 화면 — 「Powering progress, from first step to final product.」 Visa Flexible Credential 같은 내부 제품에 먼저 쓴 뒤 2025년 4월 23일 바깥에 공개했다. 코드는 Nova 라이브러리(HTML/CSS·React·Angular·Flutter)로 나눠 준다.
- 색 — 「Visa 브랜드 제품은 Visa 테마 팔레트와 alternate 팔레트를 함께 쓴다」. 파란 면(alternate)은 내비게이션 머리띠와 스플래시 화면용이고, 「아껴서, 의도를 갖고」 쓴다.
- 서체 — 2021~22년 Mucho 와 함께한 리브랜딩에서 Commercial Type 이 만든 휴머니스트 산세리프 Visa Dialect. 기준은 접근성·포용성·친근함이고, 획 대비가 낮고 속공간이 넓어 작은 글자에 강하다. 화면에는 폭을 좁힌 Visa Dialect UI 를 쓴다.
- 문장 — VPDS Voice and tone 의 세 기둥 Active(누구나 할 일을 바로 끝내게)·Readable(분명하고 짧게)·Human(활기 있고 진솔하게). 기본 어조는 중립적이고 곧은 말투다.
- 시그니처 요소 1개: 흰 화면에 Visa Blue #1434CB 한 색만 행동을 맡는다 — 6px 버튼, 파란 라디오, 파란 링크. 화면의 그림은 고객의 카드 아트 한 장(발급사 디자인 + 오른쪽 아래 흰 Visa 마크)이 맡는다. 결제를 확인하는 순간에는 그 카드 아트 위에 지문 배지를 겹쳐 「Let’s make sure it’s you」라고 묻는다.
> 현행 기준 메모: 브랜드 표준(2025-09)은 옛 파란 로고(이른바 「Visa Flag」) 대신 2021년 이후의 밝은 Visa Blue 로고만 쓰라고 한다. 흔히 「Visa 금색」으로 인용되는 #F7B600 은 공식 Nova CSS 에도 브랜드 표준에도 나오지 않는다 — 제품 화면의 금색은 VPDS active-accent #FCC015 다. 이름을 글자로 쓸 때는 「VISA」가 아니라 「Visa •••• 9010」 처럼 첫 글자만 대문자로 쓴다.
Tone & Mood
톤 & 무드
- 핵심 키워드 3개: 신뢰, 명료함, 사람다움
- 무드 설명: 흰 바탕(#FFFFFF)과 아주 옅은 회색(#F5F5F5) 위에 검정 글자(#000000), 보조 글자는 #4A4A4A 한 단계뿐이다. 색은 거의 Visa Blue 하나로 끝나고, 화면에서 가장 화려한 것은 고객의 카드 아트다. 결제·인증처럼 긴장되는 순간일수록 문장은 짧고 다정하다 — 「Let’s make sure it’s you」, 「Authenticate another way」, 「Remember me on this device」.
- 비주얼 스타일: 모던 미니멀 + 휴머니즘 — 평면 면과 1px 경계 위에, 손으로 쓴 기운이 남은 휴머니스트 서체와 문장형 표기(sentence case).
- 밀도(Density): Comfortable — 기본 본문 14px/22px, 컨트롤 38px(모바일은 1.25배라 46px 안팎). Click to Pay 로그인은 폭 520px 한 열에 제목·입력 하나·버튼 하나만 둔다.
- 모서리 성향: Soft — 기본 6px(theme-border-radius), 작은 요소 4px, 콘텐츠 카드 10px. visa.com 과 VPDS 소개 화면의 큰 행동 버튼만 알약(1000px·27px).
- 평면성: Subtle — 카드는 1px rgba(0,0,0,.1) 경계 + 얕은 그림자. 눌러서 들어가는 카드와 안내 메시지는 아래쪽에만 3px 색 띠를 그어 상태를 알린다.
Color System
컬러 시스템 (CSS 변수)
실측 출처: 공식 Nova 패키지 @visa/nova-styles 1.6.5 의 visa-light·visa-dark 테마 CSS(npm, 2026-03-19 배포), 브랜드 표준(2025-09, Visa Blue = R20 G52 B203), src.visa.com·visa.com 계산 스타일, Visa 개발자 문서의 Click to Pay 패스키 화면 픽셀. VPDS 는 색을 번호가 아니라 역할(active·surface·text·border·messaging)로 나눈다. 아래 번호는 갤러리 형식에 맞춘 배치이고, 반투명 토큰은 흰 바탕에 합성한 값을 함께 적었다. 컴포넌트는 번호 대신 역할 토큰(--action·--action-hover·--action-pressed)만 쓴다.
:root {
/* Primary — Visa Blue (VPDS 「active」 계열을 밝기 순으로 세운 것) */
--color-primary-50: #E4F1FF; /* surface-highlight rgba(179,215,255,.35) 를 흰 바탕에 합성 — 보조·3차 버튼 hover 면 */
--color-primary-100: #D1E7FF; /* surface-lowlight rgba(179,215,255,.6) 합성 — 눌린 면 */
--color-primary-200: #B3D7FF; /* highlight 원색 */
--color-primary-300: #6589F3; /* (추정) 200~400 사이 보간 — 차트 보조선 */
--color-primary-400: #173BE8; /* active-hover — 버튼 hover·입력 포커스 테두리 */
--color-primary-500: #1434CB; /* active = Visa Blue (브랜드 표준 R20 G52 B203) — 주 버튼·링크·로고 */
--color-primary-600: #122FBA; /* alternate surface-2 — 파란 머리띠 위 겹친 면 */
--color-primary-700: #112AA7; /* alternate surface-3 — Click to Pay 안내 메일 머리띠 실측 */
--color-primary-800: #0F2595; /* active-pressed — 눌림·포커스 점선 */
--color-primary-900: #021E4C; /* alternate text-on-active — 금색 버튼 위 남색 글자 */
/* 역할 토큰 — 컴포넌트는 번호 대신 이것만 쓴다(VPDS active / active-hover / active-pressed) */
--action: #1434CB;
--action-hover: #173BE8;
--action-pressed: #0F2595;
/* Secondary — 금색(active-accent). 파란 alternate 면 위의 행동색, 두 가지 색 아이콘의 보조 경로 */
--color-secondary-400: #FCC936; /* alternate hover */
--color-secondary-500: #FCC015;
--color-secondary-700: #D39D03; /* alternate pressed */
/* Neutral — 무채색. 반투명 토큰은 흰 바탕에 합성한 값 */
--color-neutral-0: #FFFFFF; /* surface-1 */
--color-neutral-50: #F5F5F5; /* surface-2 — 페이지 바탕·푸터 */
--color-neutral-100: #F0F0F0; /* surface-3 — 선택된 탭 면 */
--color-neutral-200: #E6E6E6; /* border rgba(0,0,0,.1) 합성 */
--color-neutral-300: #D9D9D9; /* 다크·파란 면 위 보조 글자 */
--color-neutral-400: #CCCCCC; /* disabled rgba(0,0,0,.2) 합성 */
--color-neutral-500: #808080; /* active-subtle rgba(0,0,0,.5) 합성 — 입력 테두리 */
--color-neutral-700: #4A4A4A; /* text-subtle — 보조 글자·라벨 */
--color-neutral-800: #2E2E2E; /* 다크 surface-3 */
--color-neutral-900: #1A1A1A; /* visa.com 본문 글자·검은 띠 */
--color-neutral-1000: #000000; /* text */
/* Semantic — messaging 계열(메시지 컴포넌트 전용) */
--color-success-bg: #D6F2C4; --color-success-fg: #2C6849; --color-success-graphic: #40996B;
--color-warning-bg: #FFEF99; --color-warning-fg: #875903; --color-warning-graphic: #C38004;
--color-error-bg: #FFD6E9; --color-error-fg: #AD2929; --color-error-graphic: #D65151;
--color-error-hover: #C62F2F; --color-error-pressed: #7C1D1D;
--color-info-bg: #C7EDFF; --color-info-fg: #005E8A; --color-info-graphic: #0088C7;
/* Surface */
--bg-base: #FFFFFF; /* surface-1 — 카드·입력 */
--bg-subtle: #F5F5F5; /* surface-2 — 페이지·푸터 */
--bg-elevated: #FFFFFF; /* content card(테두리+그림자로 띄움) */
--bg-overlay: rgba(20, 34, 57, 0.4); /* overlay — 대화상자 뒤 */
--surface-highlight: rgba(179, 215, 255, 0.35);
--surface-lowlight: rgba(179, 215, 255, 0.6);
/* Text — VPDS 글자색은 두 단계뿐이라 tertiary 는 secondary 와 같다 */
--text-primary: #000000;
--text-secondary: #4A4A4A;
--text-tertiary: #4A4A4A;
--text-on-primary: #FFFFFF;
--text-disabled: rgba(0, 0, 0, 0.2);
/* Border */
--border-default: rgba(0, 0, 0, 0.1); /* 카드·구분선(장식용) */
--border-subtle: #F0F0F0; /* 목록 행 사이 (추정) */
--border-strong: rgba(0, 0, 0, 0.5); /* active-subtle — 입력·라디오 테두리 */
--border-focus: #0F2595; /* *:focus-visible 1px 점선 */
/* alternate 팔레트 — Visa 브랜드 머리띠·스플래시용 파란 면 */
--alt-surface: #1434CB;
--alt-surface-3: #112AA7;
--alt-text: #FFFFFF;
--alt-text-subtle: #D9D9D9;
/* Visa 고유 */
--visa-blue: #1434CB; /* 카드 아트·브랜드 고정색 */
--logo-color: #1434CB; /* 밝은 바탕 위 로고 — 어두운 바탕에서는 #FFFFFF 만 */
--visa-gold: #FCC015;
--visa-navy: #021E4C;
--text-on-gold: #021E4C; /* 금색 버튼 위 글자 */
--ctp-hosted-cta: #022551; /* clicktopay.auth.visa.com 패스키 화면 「Authorise payment」 실측 */
--font-ui: 'Visa Dialect UI', 'Visa Dialect', 'Noto Sans KR', -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
}
### ③.1 사용 컨텍스트 주석
- 파랑의 세 얼굴: ① 행동색 #1434CB — VPDS 버튼·링크·라디오, visa.com 「Contact sales」 알약도 같은 값(실측). ② alternate 면 #1434CB·#122FBA·#112AA7 — 파란 머리띠·스플래시. 그 위 버튼은 금색 #FCC015 + 짙은 남색 글자이고, Visa 가 보내는 Click to Pay 안내 메일 머리띠도 #112AA7 에 금색 밑줄(실측)이다. ③ 짙은 남색 #022551 — clicktopay.auth.visa.com 패스키 화면의 「Authorise payment」(개발자 문서 화면 실측). 카드 미리보기의 결제 확인 버튼이 이 색이다.
- visa.com(마케팅)은 따로: 본문 글자 #1A1A1A, 기능 타일 #F7F7F7, 각주 띠 #EEEEEE, 검은 띠 #1A1A1A, 히어로 오른쪽 남색 면 #020F27 (2026-10-04 계산 스타일 실측). 제품 화면(VPDS)의 #000000·#F5F5F5 와 값이 조금 다르다.
- 금색 쓰는 곳: 파란 alternate 면 위 행동(버튼·선택 표시)과, 「두 가지 색」 아이콘(
.v-icon-two-color)의 보조 경로. 흰 바탕 위 #FCC015 는 대비가 약 1.7:1 이라 글자·버튼에 쓰지 않는다. - 메시지 색: 초록·노랑·분홍·하늘 네 쌍은 Section message·Banner·Flag·Dialog 같은 메시지 컴포넌트 전용이다(VPDS 「다른 용도로 쓰지 말 것」).
- 다크 모드: VPDS 공식 「Visa dark」 테마가 있다(design.visa.com 색 문서·Nova
visa-darkCSS). 바탕 #0A0A0A·#1A1A1A·#2E2E2E, 행동색은 하늘색 #BDEAFF(hover #DBF4FF, 눌림 #80D7FF), 버튼 글자 #2E2E2E. 어두운 바탕 위 로고는 흰색만(브랜드 표준). 카드 아트의 파랑은 테마와 무관하게 그대로 둔다.
Typography
타이포그래피
- 폰트 페어링:
- 영문: Visa Dialect UI (Visa 전용, 비공개 배포 — 「Visa 브랜드 디지털 경험은 Visa Dialect UI」). 브랜드·광고용은 폭이 넓은 Visa Dialect. visa.com 은 Regular·Medium·Semibold·Bold 네 굵기 woff2 를 미리 불러온다(실측).
- 한글: Noto Sans KR (SIL OFL) — 브랜드 표준은 Visa Dialect 를 쓸 수 없는 언어에 Noto Sans(결제 완료 「Approved」 문구는 Noto Sans Medium)를 쓰라고 한다. src.visa.com 은 한국어로도 열리며(「Click to Pay에 오신 것을 환영합니다」) 시스템 서체로 그려진다.
- Visa 브랜드가 아닌 제품: Visa Dialect 를 쓰지 않는다 — VPDS 는 웹이면 Open Sans, 앱이면 플랫폼 기본 서체를 권한다.
- 위계 (VPDS Typography 웹 값 — 크기 / 굵기 / 줄 높이 / 자간. 모바일은 괄호):
- Display: 60px / 600 / 78px / 0 — Display 1 (70/91). Display 2 는 48/62
- H1: 32px / 600 / 42px / 0.5px — Headline 1 (36/47). 「페이지 대부분은 Headline 1 을 가장 큰 제목으로 시작」
- H2: 25px / 500 / 33px / 0 — Headline 2 (28/36)
- H3: 20px / 600 / 26px / 0 — Headline 3 (24/31). Headline 4 는 18/24/600
- Body Large: 16px / 400 / 24px / 0 — Body 1 (18/27)
- Body: 14px / 400 / 22px / 0 — Body 2, 기본 본문·입력 글자 (16/24)
- Body Small: 12px / 400 / 18px / 0 — Body 3
- Caption: 11px / 400 / 14px / 0 — Label small (배지 글자)
- 그 밖: Subtitle 1·2·3 = 16/21/600 · 16/21/500 · 14/18/600, Overline = 10/13/600·자간 1px·대문자, 버튼 = 12/16/600·자간 0.25px(큰 버튼 14/18)
- 운용: 제목은 문장형 표기, 마침표·쌍점을 붙이지 않는다. 제목 줄 높이는 글자의 약 1.3배, 본문은 1.5배. 대문자는 1~3단어짜리 Overline 에만 쓴다. Click to Pay 실서비스(src.visa.com)의 h1 은 24px/31px·600, 라벨 14px/16px·#4A4A4A, 안내문 11px/14px(실측).
Spacing
스페이싱
- Base unit: 4px — VPDS 격자는 「4의 배수」가 기준이다(세로 간격 16·24·32·48px 권장). Nova 는 1px 단위
--size-scalable-1~도 준다. - 토큰:
--space-xs: 4px;
--space-sm: 8px;
--space-md: 16px;
--space-lg: 24px;
--space-xl: 32px;
--space-2xl: 48px;
--space-3xl: 64px;
--space-card: 20px;
--space-control-x: 14px;
- Container: 가로 내비 레이아웃은 4열(16px 여백·16px 열 간격) → 8열(24px 여백) → 12열(24px 여백·24px 열 간격), 큰 화면은 여백을 최소 80px 로 두는 고정 12열. 왼쪽 내비가 있는 레이아웃은 내비 오른쪽부터 12열을 잡는다. 모바일은 크기·모서리를 1.25배로 키운다(
--theme-responsive-factor: 1.25).
Border Radius
Border Radius
Nova --theme-border-radius: 6px 에 배수를 곱한 값이다(small ×2/3, large ×4/3, xlarge ×5/3). 모바일은 여기에 1.25배.
--radius-none: 0;
--radius-sm: 4px;
--radius-md: 6px;
--radius-lg: 8px;
--radius-xl: 10px;
--radius-full: 9999px;
- 알약은 마케팅에만: visa.com 「Contact sales」 는
border-radius: 1000px(높이 40px, 좌우 24px), VPDS 소개 화면의 큰 버튼은 27px(높이 46px). 제품 화면의 버튼·입력·탭은 6px 그대로다.
Shadow / Elevation
Shadow / Elevation
Nova 패키지(1.6.5)의 --elevation-* 값. VPDS Elevation 문서 표는 같은 그림자를 절반 크기로 적어 두었으니, 코드는 패키지 값을 따른다.
--shadow-none: none;
--shadow-xs: 0 1px 3px 0 rgba(0,0,0,0.05);
--shadow-sm: 0 1px 2px -1px rgba(0,0,0,0.1), 0 1px 3px 0 rgba(0,0,0,0.1);
--shadow-md: 0 4px 15px -1px rgba(0,0,0,0.08), 0 4px 2px -2px rgba(0,0,0,0.1);
--shadow-lg: 0 10px 18px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1);
--shadow-xl: 0 20px 25px -5px rgba(0,0,0,0.1), 0 4px 10px 2px rgba(0,0,0,0.1);
--shadow-2xl: 0 25px 50px -12px rgba(0,0,0,0.25);
--shadow-inset: inset 0 0 4px 0 rgba(0,0,0,0.1), inset 0 0 4px 1px rgba(0,0,0,0.2);
- 쓰는 곳: sm(small) = 콘텐츠 카드·Section message, md(medium) = 눌러서 들어가는 카드의 hover·Banner, lg(large) = 드롭다운·패널, xl(xlarge) = Flag(알림)·떠 있는 창, 2xl(xxlarge) = Dialog. 다크에서는 그림자가 거의 안 보여 면 색(#1A1A1A·#2E2E2E)으로 높이를 나눈다.
Iconography
Iconography
- 스타일: Filled — Nova Icons 는 선(stroke) 없이 채운 경로뿐이다. 아이콘마다 주 경로(
v-icon-primary)와 보조 경로(v-icon-secondary)가 나뉜다. - 색: 기본은 파랑 한 색(#1434CB).
.v-icon-two-color를 켜면 주 경로 파랑 + 보조 경로 금색 #FCC015, 파란 alternate 면 위에서는 금색 + 흰색. 지문 아이콘이라면 바깥 두 고리가 금색, 안쪽 획이 파랑이 된다. - Stroke 굵기: 없음(채움). 24px 원본에서 선처럼 보이는 획은 2px 폭이다.
- 모서리 처리: Square에 가까운 반듯한 끝 — 획 끝을 둥글리지 않는다.
- 추천 라이브러리: 공식 Nova Icons(
@visa/nova-icons-svg4.0.0) — Tiny 16px · Low 24px · High 48px, Visa 스타일과 무채색 generic 스타일 두 벌. 결제 화면에 쓰는 fingerprint·auth-face·security-lock·card-·tap·wallet 이 다 들어 있다. 이 문서의 잠금·체크·더하기·지문은 이 패키지 경로를 그대로 썼다. - 결제 기호: 이 문서의 그림은 Click to Pay 아이콘 대신 「Click to Pay」 글자 + 세로선 + Visa 마크로 적었다 — Click to Pay 표준(2026-01)은 결제 버튼이 아닌 자리에서 아이콘·「Click to Pay」 글자·Visa 마크를 어떤 조합으로 써도 된다고 한다. 카드 그림의 비접촉 표시는 실물 카드처럼 위쪽 오른편에 둔다.
Component Guide
컴포넌트 가이드 (상태별 CSS)
클래스 이름은 Nova(@visa/nova-styles)와 같게 맞췄고, 값은 Nova 의 역할 토큰을 풀어 쓴 축약 구현이다. 색은 번호가 아니라 --action·--action-hover·--action-pressed 만 써서 라이트·다크가 같은 코드로 바뀐다.
*:focus-visible { outline: 1px dashed var(--border-focus); outline-offset: 1px; }
.v-button { display: inline-flex; align-items: center; justify-content: center; gap: 4px; min-height: 38px; padding: 0 14px; border: 1px solid transparent; border-radius: var(--radius-md); background: var(--action); color: var(--text-on-primary); font: 600 12px/16px var(--font-ui); letter-spacing: 0.25px; cursor: pointer; text-decoration: none; }
.v-button:hover { background: var(--action-hover); }
.v-button:active { background: var(--action-pressed); }
.v-button:disabled { background: var(--text-disabled); color: var(--text-on-primary); cursor: not-allowed; }
.v-button[aria-busy="true"] { pointer-events: none; }
.v-button[aria-busy="true"]::before { content: ""; width: 12px; height: 12px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: v-spin 0.8s linear infinite; }
.v-button-large { min-height: 46px; padding: 0 20px; font-size: 14px; line-height: 18px; }
.v-button-small { min-height: 32px; padding: 0 10px; font-weight: 500; }
.v-button-secondary { background: transparent; border-color: var(--action); color: var(--action); }
.v-button-secondary:hover { background: var(--surface-highlight); border-color: var(--action-hover); color: var(--action-hover); }
.v-button-secondary:active { background: var(--surface-lowlight); border-color: var(--action-pressed); color: var(--action-pressed); }
.v-button-secondary:disabled { background: transparent; border-color: var(--text-disabled); color: var(--text-disabled); }
.v-button-tertiary { background: transparent; color: var(--action); }
.v-button-tertiary:hover { background: var(--surface-highlight); color: var(--action-hover); }
.v-button-tertiary:active { background: var(--surface-lowlight); color: var(--action-pressed); }
.v-button-tertiary:disabled { background: transparent; color: var(--text-disabled); }
.v-button-destructive { background: var(--color-error-fg); }
.v-button-destructive:hover { background: var(--color-error-hover); }
.v-button-destructive:active { background: var(--color-error-pressed); }
.v-button-alternate { background: var(--visa-gold); color: var(--text-on-gold); }
.v-button-alternate:hover { background: var(--color-secondary-400); }
.v-button-alternate:active { background: var(--color-secondary-700); }
.v-button-pill { border-radius: var(--radius-full); }
@keyframes v-spin { to { transform: rotate(360deg); } }
.v-label { display: block; margin-bottom: 6px; font: 400 14px/16px var(--font-ui); color: var(--text-secondary); }
.v-input-container { display: flex; align-items: center; gap: 6px; min-height: 38px; padding: 3px 6px; border: 1px solid var(--border-strong); border-radius: var(--radius-md); background: var(--bg-base); box-shadow: inset 0 0 0 0 transparent; }
.v-input-container:hover { border-color: var(--action-hover); box-shadow: inset 0 -1px 0 0 var(--action-hover); }
.v-input-container:focus-within { border-color: var(--action-hover); box-shadow: inset 0 -1px 0 0 var(--action-hover); }
.v-input-container[aria-invalid="true"] { border-color: var(--color-error-graphic); box-shadow: inset 0 -1px 0 0 var(--color-error-graphic); }
.v-input-container[aria-disabled="true"] { border-style: dashed; border-color: var(--text-disabled); }
.v-input { flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; font: 400 14px/22px var(--font-ui); color: var(--text-primary); }
.v-input::placeholder { color: var(--text-secondary); }
.v-input-message-error { margin-top: 4px; font: 400 12px/16px var(--font-ui); color: var(--color-error-fg); }
.v-content-card { padding: var(--space-card); border: 1px solid var(--border-default); border-radius: var(--radius-xl); background: var(--bg-elevated); box-shadow: var(--shadow-sm); color: var(--text-primary); }
.v-content-card-title { margin: 0; font: 600 18px/24px var(--font-ui); color: var(--action); }
.v-content-card-subtitle { margin: 0; font: 600 14px/18px var(--font-ui); color: var(--text-secondary); }
.v-content-card-clickable { cursor: pointer; transition: box-shadow var(--duration-slow) var(--ease-out); }
.v-content-card-clickable:hover { box-shadow: var(--shadow-md), inset 0 -3px 0 0 var(--action-hover); }
.v-content-card-outlined { box-shadow: none; }
.v-badge { display: inline-flex; align-items: center; gap: 2px; padding: 4px; border-radius: var(--radius-sm); font: 400 11px/14px var(--font-ui); color: var(--text-primary); white-space: nowrap; }
.v-badge-neutral { background: var(--color-info-bg); }
.v-badge-stable { background: var(--color-success-bg); }
.v-badge-warning { background: var(--color-warning-bg); }
.v-badge-error { background: var(--color-error-bg); }
.v-badge-subtle { background: var(--border-default); color: var(--text-secondary); }
.v-badge-number { justify-content: center; min-width: 16px; height: 16px; padding: 0 4px; border-radius: var(--radius-full); background: var(--color-error-fg); color: var(--bg-base); font-weight: 600; }
.v-link { color: var(--action); font-weight: 500; text-decoration: underline; text-underline-offset: 2px; }
.v-link:hover { color: var(--action-hover); }
.v-radio { flex: none; width: 18px; height: 18px; border: 2px solid var(--action); border-radius: 50%; background: var(--bg-base); }
.v-radio[aria-checked="true"] { box-shadow: inset 0 0 0 3px var(--bg-base), inset 0 0 0 9px var(--action); }
.v-checkbox { flex: none; width: 18px; height: 18px; border: 2px solid var(--action); border-radius: 2px; background: var(--bg-base); display: inline-grid; place-items: center; color: var(--text-on-primary); }
.v-checkbox[aria-checked="true"] { background: var(--action); }
.v-panel { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border: 1px solid var(--border-strong); border-radius: var(--radius-md); background: var(--bg-base); cursor: pointer; }
.v-panel:hover { border-color: var(--action-hover); }
.v-panel[aria-checked="true"] { border-color: var(--action-pressed); box-shadow: inset 0 0 0 1px var(--action-pressed); }
.v-message { display: flex; gap: 8px; padding: 12px 16px; border-bottom: 3px solid var(--color-info-graphic); border-radius: var(--radius-lg); background: var(--color-info-bg); box-shadow: var(--shadow-sm); color: var(--text-primary); }
.v-message-success { background: var(--color-success-bg); border-bottom-color: var(--color-success-graphic); }
.v-message-warning { background: var(--color-warning-bg); border-bottom-color: var(--color-warning-graphic); }
.v-message-error { background: var(--color-error-bg); border-bottom-color: var(--color-error-graphic); }
.v-tabs { display: flex; gap: 6px; border-bottom: 1px solid var(--border-default); }
.v-tab { padding: 11px 12px 9px; border-bottom: 2px solid transparent; border-radius: var(--radius-md) var(--radius-md) 0 0; font: 400 14px/18px var(--font-ui); color: var(--text-secondary); }
.v-tab[aria-selected="true"] { border-bottom-color: var(--action-hover); background: var(--color-neutral-100); color: var(--text-primary); font-weight: 500; }
.v-nav { display: flex; align-items: center; gap: 24px; min-height: 62px; padding: 0 24px; background: var(--bg-base); border-bottom: 1px solid var(--border-default); }
.v-nav.v-alternate { background: var(--alt-surface); border-bottom-color: transparent; color: var(--alt-text); }
.v-alternate .v-tab { color: var(--alt-text-subtle); }
.v-alternate .v-tab[aria-selected="true"] { background: var(--alt-surface-3); border-bottom-color: var(--color-secondary-400); color: var(--alt-text); }
- Button — 기본 38px(큰 버튼 46px, 작은 버튼 32px), 모서리 6px, 좌우 14px, 12px/600·자간 0.25px. Primary = 파랑 채움, Secondary = 1px 파랑 테두리 + 투명, Tertiary = 글자만. hover 면은
surface-highlight(rgba(179,215,255,.35)), 눌림은.6. 비활성 Primary 는 rgba(0,0,0,.2) 바탕에 흰 글자(Click to Pay 「계속」 실측). 파란 alternate 면 위에서는.v-button-alternate(금색 + 남색 글자). - Input — 높이 38px, 1px rgba(0,0,0,.5) 경계, 안쪽 3px·6px. hover·포커스에서 경계가 #173BE8 로 바뀌고 아래쪽에만 1px 선이 더해져 밑변이 두꺼워진다. 오류는 경계 #D65151 + 안내문 #AD2929, 비활성은 점선 경계.
- Card — 콘텐츠 카드는 흰 면, 1px rgba(0,0,0,.1), 10px, small 그림자, 안쪽 20px. 제목은 파랑(Headline 4 = 18/24/600), 부제는 Subtitle 3. 강조형은 눌러서 들어가는 카드 — hover 때 medium 그림자 + 아래 3px 파랑 띠. 테두리만 남긴 판은
.v-content-card-outlined. - Badge — 4px 모서리, 안쪽 4px, 11px/14px. neutral(하늘 #C7EDFF)·stable(초록 #D6F2C4)·warning(#FFEF99)·error(#FFD6E9)·subtle(rgba(0,0,0,.1)) 다섯 가지가 모두 옅은 면이다. 진하게 채운 것은 숫자 배지(빨강 #AD2929 알약, 흰 숫자) 하나뿐.
- Selection — 체크박스·라디오는 꺼져 있어도 2px 파랑 테두리(체크박스 모서리 2px). 카드를 고르는 줄은 패널형: 평소 1px rgba(0,0,0,.5), 고르면 눌림 파랑 #0F2595 두께 2px.
- Navigation — 가로 내비 최소 62px, 좌우 24px, 흰 면. 탭은 글자 #4A4A4A → 선택 시 #000000·500 + 바탕 #F0F0F0 + 아래 2px #173BE8. Visa 브랜드 머리띠는
.v-nav.v-alternate— 파란 면 #1434CB 위 흰 글자, 고른 탭은 #112AA7 면 + 금색 #FCC936 밑줄(다크에서는 파랑 대신 #2E2E2E 회색 면). - Message — Section message 는 채운 면 + 아래쪽 3px 색 띠 + 8px 모서리 + small 그림자, 안쪽 12px·16px. 포커스는 모든 요소 공통 1px 점선 #0F2595, 간격 1px.
Motion
Motion
Nova CSS 에 시간 토큰 표는 없다. 패키지에 실제로 있는 전환(카드 300ms ease-out, 스위치 250ms ease)에 이름을 붙였고, 버튼·입력은 전환 없이 바로 바뀐다.
--duration-fast: 150ms; /* (추정) 링크·아이콘 색 — Nova 버튼은 전환 없이 바로 바뀐다 */
--duration-base: 250ms; /* 스위치 노브 이동 margin-inline-start .25s ease (실측) */
--duration-slow: 300ms; /* 콘텐츠 카드 그림자·화살표 이동 300ms ease-out (실측) */
--ease-out: ease-out;
--ease-in-out: ease;
- 결제 완료의 움직임: 브랜드 표준의 Visa Sensory Branding — Visa 마크가 「V」의 체크 모양으로 들어오고 「ISA」가 뒤따른 뒤, 체크 표시나 「Approved」(Visa Dialect Medium)로 끊는다. 소리·진동과 함께 쓰며, 끝난 로고는 화면 폭의 60% 를 넘지 않는다. 파란 바탕이면 흰 마크, 흰 바탕이면 파란 마크.
prefers-reduced-motion에서는 전환을 끄고, 완료는 정지 화면의 Visa 마크 + 체크로 보여 준다.
Anti-patterns
Anti-patterns
1. 「VISA •••• 1234」로 쓰지 않는다 — 글자 표기는 「Visa •••• 1234」. 카드 아트에는 Visa 마크·네 점·끝 네 자리를 함께 두고, Signature·Infinite 카드는 마크 아래 제품 표기를 빼지 않는다. 2. 로고를 파랑·흰색 말고 다른 색으로 칠하지 않는다 — 밝은 바탕은 #1434CB, 어두운 바탕은 #FFFFFF 만. 옛 「Visa Flag」 로고와 #F7B600 금색도 쓰지 않는다. 3. 흰 바탕에 금색 글자·금색 버튼을 두지 않는다 — #FCC015 는 파란 alternate 면 위 행동과 두 가지 색 아이콘 보조 경로에만 쓴다. 4. 메시지 색을 장식으로 쓰지 않는다 — 초록·노랑·분홍·하늘은 성공·주의·오류·안내 메시지에만. 행동은 언제나 파랑 하나다. 5. 다크 화면 버튼을 #1434CB 로 두지 않는다 — #0A0A0A 위 #1434CB 는 대비가 낮다. 다크 행동색은 하늘색 #BDEAFF 와 #2E2E2E 글자.
Sources
출처
- https://design.visa.com/
- https://design.visa.com/base-elements/color/usage/
- https://design.visa.com/base-elements/typography/usage/
- https://design.visa.com/base-elements/responsive-grid-system.md
- https://design.visa.com/base-elements/elevation/usage.md
- https://design.visa.com/components/button/usage.md
- https://design.visa.com/components/content-card/usage.md
- https://design.visa.com/content/voice-and-tone.md
- https://design.visa.com/patterns/one-time-passcode/
- https://unpkg.com/@visa/nova-styles@1.6.5/styles.css
- https://unpkg.com/@visa/nova-styles@1.6.5/themes/visa-light/index.css
- https://unpkg.com/@visa/nova-styles@1.6.5/themes/visa-dark/index.css
- https://unpkg.com/@visa/nova-icons-svg@4.0.0/visa/fingerprint-low.svg
- https://registry.npmjs.org/@visa%2Fnova-styles
- https://registry.npmjs.org/@visa%2Fnova-angular
- https://github.com/visa/nova-styles
- https://src.visa.com/login
- https://developer.visa.com/capabilities/visa-secure-remote-commerce/uctp-integration-overview
- https://developer.visa.com/images2/products/visa-click-to-pay/Authentication.png
- https://developer.visa.com/images2/products/visa-click-to-pay/Group%203465136.png
- https://www.visa.com/en-us/products/click-to-pay/merchants
- https://usa.visa.com/products/click-to-pay/consumers.html
- https://www.visa.com/en-us/products/visa-payment-passkey
- https://usa.visa.com/pay-with-visa/find-card/apply-credit-card
- https://corporate.visa.com/content/dam/VCOM/corporate/about-visa/documents/visa-brand-standards-sept2025.pdf
- https://corporate.visa.com/content/dam/VCOM/corporate/about-visa/documents/visa-click-to-pay-brand-standards-jan2026.pdf
- https://www.pymnts.com/visa/2025/visa-just-opened-access-to-its-product-design-system-whats-in-it-for-fintechs/
- https://wearemucho.com/work/visa
Visa 이름과 로고는 각 권리자의 상표입니다.