CSS 버튼 세트
다양한 variant, size, 상태를 갖춘 완성형 CSS 버튼 컴포넌트 시스템.
:root {
--btn-radius: 6px;
--btn-font-size: 0.875rem;
--btn-transition: all 0.15s ease;
--color-primary: #2563eb;
--color-primary-hover: #1d4ed8;
--color-primary-active: #1e40af;
--color-success: #16a34a;
--color-danger: #dc2626;
--color-warning: #d97706;
--color-surface: #f3f4f6;
--color-border: #d1d5db;
--color-text: #374151;
}
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
padding: 0.5rem 1rem;
font-size: var(--btn-font-size);
font-weight: 500;
font-family: inherit;
line-height: 1;
border-radius: var(--btn-radius);
border: 1px solid transparent;
cursor: pointer;
text-decoration: none;
white-space: nowrap;
user-select: none;
transition: var(--btn-transition);
-webkit-tap-highlight-color: transparent;
}
.btn:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.btn:active { transform: scale(0.97); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; pointer-events: none; }
/* Variants */
.btn-primary { background: var(--color-primary); color: #fff; border-color: var(--color-primary); }
.btn-primary:hover { background: var(--color-primary-hover); border-color: var(--color-primary-hover); }
.btn-primary:active { background: var(--color-primary-active); }
.btn-success { background: var(--color-success); color: #fff; border-color: var(--color-success); }
.btn-success:hover { filter: brightness(1.1); }
.btn-danger { background: var(--color-danger); color: #fff; border-color: var(--color-danger); }
.btn-danger:hover { filter: brightness(1.1); }
.btn-warning { background: var(--color-warning); color: #fff; border-color: var(--color-warning); }
.btn-warning:hover { filter: brightness(1.1); }
.btn-outline { background: transparent; color: var(--color-primary); border-color: var(--color-primary); }
.btn-outline:hover { background: var(--color-primary); color: #fff; }
.btn-ghost { background: transparent; color: var(--color-text); border-color: transparent; }
.btn-ghost:hover { background: var(--color-surface); border-color: var(--color-border); }
.btn-surface { background: var(--color-surface); color: var(--color-text); border-color: var(--color-border); }
.btn-surface:hover { background: #e5e7eb; }
/* Sizes */
.btn-xs { padding: 0.25rem 0.625rem; font-size: 0.75rem; border-radius: 4px; }
.btn-sm { padding: 0.375rem 0.75rem; font-size: 0.8125rem; }
.btn-md { padding: 0.5rem 1rem; font-size: 0.875rem; }
.btn-lg { padding: 0.625rem 1.25rem; font-size: 1rem; border-radius: 8px; }
.btn-xl { padding: 0.75rem 1.5rem; font-size: 1.0625rem; border-radius: 8px; }
/* Modifiers */
.btn-full { width: 100%; }
.btn-round { border-radius: 999px; }
.btn-icon { padding: 0.5rem; aspect-ratio: 1; }
/* Loading state */
.btn.loading { pointer-events: none; }
.btn.loading::before {
content: '';
display: inline-block;
width: 0.875em; height: 0.875em;
border: 2px solid currentColor;
border-top-color: transparent;
border-radius: 50%;
animation: btn-spin 0.6s linear infinite;
}
@keyframes btn-spin { to { transform: rotate(360deg); } }