369 lines
8.7 KiB
CSS
369 lines
8.7 KiB
CSS
/* =====================================================================
|
|
UI 프리미티브 스타일 — 토큰 변수만 참조(tokens.css).
|
|
철칙: border-left 강조선 0 · 카드 상단 강조선 0 · 알약 radius 금지(원형은 dot/오브/아바타만).
|
|
강조 = weight + accent 텍스트 + accent-tint 배경 + kicker(+dot).
|
|
===================================================================== */
|
|
|
|
/* ── Kicker (상단 소제목, 양산형 좌측바 대체 위계 신호) §3.6 ── */
|
|
.vg-kicker {
|
|
font-family: var(--font-num);
|
|
font-size: var(--fs-kicker);
|
|
font-weight: 600;
|
|
letter-spacing: 0.08em;
|
|
color: var(--text-accent);
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
text-transform: none;
|
|
}
|
|
.vg-kicker__dot {
|
|
width: 6px;
|
|
height: 6px;
|
|
border-radius: 50%;
|
|
background: var(--accent-bright);
|
|
flex: none;
|
|
}
|
|
|
|
/* ── SectionHead ── */
|
|
.vg-sechead {
|
|
margin-bottom: var(--sp-5);
|
|
}
|
|
.vg-sechead__kicker {
|
|
margin-bottom: 6px;
|
|
}
|
|
.vg-sechead__title {
|
|
font-size: var(--fs-h2);
|
|
font-weight: 600;
|
|
letter-spacing: 0;
|
|
color: var(--text-strong);
|
|
line-height: 1.35;
|
|
}
|
|
.vg-sechead__desc {
|
|
font-size: var(--fs-xs);
|
|
color: var(--text-muted);
|
|
margin-top: 4px;
|
|
}
|
|
|
|
/* ── Button (위계 3단 + danger). radius 8px, 알약 금지 §7.1 ── */
|
|
.vg-btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 8px;
|
|
font: 600 var(--fs-sm) / 1 var(--font-sans);
|
|
padding: 10px 18px;
|
|
border-radius: var(--radius);
|
|
border: 1px solid transparent;
|
|
transition:
|
|
background var(--dur-base) var(--ease-out),
|
|
border-color var(--dur-base) var(--ease-out),
|
|
transform var(--dur-fast) var(--ease-spring),
|
|
box-shadow var(--dur-fast) var(--ease-out);
|
|
cursor: pointer;
|
|
white-space: nowrap;
|
|
user-select: none;
|
|
}
|
|
.vg-btn:active {
|
|
transform: translateY(1px) scale(0.98);
|
|
}
|
|
.vg-btn:disabled {
|
|
opacity: 0.5;
|
|
cursor: not-allowed;
|
|
transform: none;
|
|
}
|
|
.vg-btn--block {
|
|
width: 100%;
|
|
}
|
|
.vg-btn--sm {
|
|
padding: 7px 13px;
|
|
font-size: var(--fs-xs);
|
|
}
|
|
.vg-btn--lg {
|
|
padding: 13px 22px;
|
|
font-size: var(--fs-body);
|
|
}
|
|
|
|
.vg-btn--primary {
|
|
background: linear-gradient(105deg, color-mix(in srgb, var(--accent) 90%, var(--bg-surface)), var(--accent));
|
|
color: var(--text-on-accent);
|
|
border-color: color-mix(in srgb, var(--botanical-gold) 24%, var(--accent));
|
|
box-shadow: inset 0 1px 0 color-mix(in srgb, var(--bg-surface) 32%, transparent);
|
|
}
|
|
.vg-btn--primary:hover:not(:disabled) {
|
|
background: var(--accent-deep);
|
|
}
|
|
.vg-btn--secondary {
|
|
background: var(--surface-gradient);
|
|
color: var(--text-accent);
|
|
border-color: color-mix(in srgb, var(--accent) 62%, var(--botanical-hair));
|
|
}
|
|
.vg-btn--secondary:hover:not(:disabled) {
|
|
background: var(--accent-tint);
|
|
}
|
|
.vg-btn--ghost {
|
|
background: transparent;
|
|
color: var(--text-body);
|
|
}
|
|
.vg-btn--ghost:hover:not(:disabled) {
|
|
background: var(--bg-surface-2);
|
|
color: var(--text-strong);
|
|
}
|
|
.vg-btn--danger {
|
|
background: var(--crit-solid);
|
|
color: var(--text-on-accent);
|
|
}
|
|
.vg-btn--danger:hover:not(:disabled) {
|
|
background: var(--crit-text);
|
|
}
|
|
|
|
/* ── Surface SSOT ── */
|
|
.vg-surface.vg-surface--panel {
|
|
background: var(--glass-surface);
|
|
border: 1px solid var(--glass-border);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: var(--glass-shadow);
|
|
}
|
|
.vg-surface.vg-surface--inset {
|
|
background: var(--bg-surface-2);
|
|
border: 1px solid var(--border-subtle);
|
|
border-radius: var(--radius-sm);
|
|
box-shadow: var(--glass-inset-shadow);
|
|
}
|
|
.vg-surface.vg-surface--interactive {
|
|
background: var(--bg-surface);
|
|
border: 1px solid var(--border-subtle);
|
|
border-radius: var(--radius);
|
|
box-shadow: var(--shadow-sm);
|
|
transition:
|
|
background var(--dur-base) var(--ease-out),
|
|
border-color var(--dur-base) var(--ease-out),
|
|
box-shadow var(--dur-fast) var(--ease-out),
|
|
transform var(--dur-fast) var(--ease-out);
|
|
}
|
|
.vg-surface.vg-surface--interactive:hover {
|
|
border-color: color-mix(in srgb, var(--accent) 48%, var(--glass-border));
|
|
background: var(--glass-surface-strong);
|
|
box-shadow: var(--shadow-island);
|
|
transform: translateY(-1px);
|
|
}
|
|
/* 포커스 가시성 — outline 채널로 링을 그린다(WCAG 2.4.7). */
|
|
.vg-surface.vg-surface--interactive:focus-visible {
|
|
outline: 3px solid var(--focus-ring);
|
|
outline-offset: 2px;
|
|
}
|
|
.vg-surface.vg-surface--flat {
|
|
box-shadow: none;
|
|
}
|
|
.vg-surface.vg-surface--tint {
|
|
background: var(--bg-tint);
|
|
border-color: transparent;
|
|
box-shadow: none;
|
|
}
|
|
|
|
/* ── Tabs behavior primitive. 시각 표면은 만들지 않는다. ── */
|
|
.vg-tabs,
|
|
.vg-tabs__panel {
|
|
min-width: 0;
|
|
}
|
|
.vg-tabs__trigger:focus-visible {
|
|
outline: 2px solid var(--focus-ring);
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
/* ── Card / Panel 크기 계약. 표면은 위 Surface만 소유한다. ── */
|
|
.vg-card {
|
|
padding: var(--sp-5);
|
|
}
|
|
.vg-panel {
|
|
border-radius: var(--radius-lg);
|
|
padding: var(--sp-6);
|
|
}
|
|
|
|
/* ── Badge (배경 틴트 + 텍스트, 좌측바 없음) ── */
|
|
.vg-badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
font-family: var(--font-num);
|
|
font-size: var(--fs-xs);
|
|
font-weight: 600;
|
|
letter-spacing: 0.01em;
|
|
padding: 2px 9px;
|
|
border-radius: 100px; /* 칩/배지만 100px 관용 (DESIGN_CONCEPT 데모 일치) */
|
|
line-height: 1.5;
|
|
}
|
|
.vg-badge--neutral {
|
|
color: var(--ink-2);
|
|
background: var(--paper-2);
|
|
}
|
|
.vg-badge--accent {
|
|
color: var(--accent-deep);
|
|
background: var(--accent-tint);
|
|
}
|
|
.vg-badge--pos {
|
|
color: var(--pos-text);
|
|
background: var(--pos-tint);
|
|
}
|
|
.vg-badge--warn {
|
|
color: var(--warn-text);
|
|
background: var(--warn-tint);
|
|
}
|
|
.vg-badge--crit {
|
|
color: var(--crit-text);
|
|
background: var(--crit-tint);
|
|
}
|
|
.vg-badge--info {
|
|
color: var(--info-text);
|
|
background: var(--info-tint);
|
|
}
|
|
|
|
/* ── Dot (상태 점). 원형 예외 허용 대상 ── */
|
|
.vg-dot {
|
|
display: inline-block;
|
|
width: 8px;
|
|
height: 8px;
|
|
border-radius: 50%;
|
|
flex: none;
|
|
background: var(--neutral-200);
|
|
}
|
|
.vg-dot--accent {
|
|
background: var(--accent);
|
|
}
|
|
.vg-dot--pos {
|
|
background: var(--pos-solid);
|
|
}
|
|
.vg-dot--warn {
|
|
background: var(--warn-solid);
|
|
}
|
|
.vg-dot--crit {
|
|
background: var(--crit-solid);
|
|
}
|
|
.vg-dot--info {
|
|
background: var(--info-solid);
|
|
}
|
|
.vg-dot--muted {
|
|
background: var(--ink-3);
|
|
}
|
|
|
|
/* ── StatLine (요약 스탯, tabular) ── */
|
|
.vg-statline {
|
|
display: flex;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
gap: var(--sp-5);
|
|
}
|
|
.vg-statline__item {
|
|
display: inline-flex;
|
|
align-items: baseline;
|
|
gap: 7px;
|
|
}
|
|
.vg-statline__num {
|
|
font-size: 20px;
|
|
font-weight: 700;
|
|
color: var(--text-strong);
|
|
font-variant-numeric: tabular-nums;
|
|
letter-spacing: 0;
|
|
}
|
|
.vg-statline__lab {
|
|
font-size: var(--fs-xs);
|
|
color: var(--text-muted);
|
|
}
|
|
.vg-statline__sep {
|
|
width: 1px;
|
|
height: 18px;
|
|
background: var(--hair);
|
|
}
|
|
|
|
/* ── ProgressBar (가로 게이지, 라운드 없는 사각 트랙) §5.5/§6.4 ── */
|
|
.vg-progress {
|
|
width: 100%;
|
|
height: 8px;
|
|
background: var(--paper-2);
|
|
border-radius: 4px;
|
|
overflow: hidden;
|
|
}
|
|
.vg-progress--slim {
|
|
height: 4px;
|
|
}
|
|
.vg-progress__fill {
|
|
height: 100%;
|
|
border-radius: 4px;
|
|
background: var(--accent);
|
|
transition: width var(--dur-slow) var(--ease-out);
|
|
}
|
|
.vg-progress__fill--muted {
|
|
background: var(--neutral-200);
|
|
}
|
|
.vg-progress__fill--warn {
|
|
background: var(--warn-solid);
|
|
}
|
|
.vg-progress__fill--crit {
|
|
background: var(--crit-solid);
|
|
}
|
|
.vg-progress__fill--clay {
|
|
background: var(--clay);
|
|
}
|
|
|
|
/* ── Field / Input §7.2 (radius 6px, 포커스 보더색+ring, 좌측바 X) ── */
|
|
.vg-field {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 6px;
|
|
}
|
|
.vg-field__label {
|
|
font-size: var(--fs-sm);
|
|
font-weight: 600;
|
|
color: var(--text-strong);
|
|
}
|
|
.vg-field__hint {
|
|
font-size: var(--fs-xs);
|
|
color: var(--text-muted);
|
|
}
|
|
.vg-field__error {
|
|
font-size: var(--fs-xs);
|
|
color: var(--crit-text);
|
|
}
|
|
.vg-input {
|
|
width: 100%;
|
|
background: var(--bg-surface-2);
|
|
color: var(--text-strong);
|
|
border: 1px solid var(--border-strong);
|
|
border-radius: var(--radius-sm);
|
|
padding: 10px 12px;
|
|
font: var(--fs-body) / 1.5 var(--font-sans);
|
|
transition:
|
|
border-color var(--dur-fast) var(--ease-out),
|
|
box-shadow var(--dur-fast) var(--ease-out);
|
|
}
|
|
.vg-input::placeholder {
|
|
color: var(--neutral-400);
|
|
}
|
|
.vg-input:focus {
|
|
border-color: var(--border-focus);
|
|
outline: none;
|
|
box-shadow: 0 0 0 3px var(--focus-ring);
|
|
}
|
|
.vg-input[aria-invalid="true"] {
|
|
border-color: var(--crit-solid);
|
|
}
|
|
|
|
/* ── 빈/준비중 상태 (스텁 페이지 공통) ── */
|
|
.vg-empty {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: flex-start;
|
|
gap: var(--sp-3);
|
|
max-width: var(--maxw-read);
|
|
}
|
|
.vg-empty__title {
|
|
font-size: var(--fs-h1);
|
|
font-weight: 700;
|
|
letter-spacing: 0;
|
|
color: var(--text-strong);
|
|
line-height: 1.3;
|
|
}
|
|
.vg-empty__desc {
|
|
font-size: var(--fs-lead);
|
|
color: var(--text-body);
|
|
line-height: 1.6;
|
|
}
|