/* ============================================================================
   v2 리뉴얼 공통 컴포넌트 — 골격 (정본 docs/planning/APP_RENEWAL_V2_DESIGN_GUIDE.md §10·§14)
   값은 tokens.css 변수만 쓴다. 페이지 CSS에는 페이지 고유 배치만 남긴다.
   지금은 첫 페이지를 올리는 데 필요한 최소(레이아웃·헤더·카드·버튼·칩·배지)만 있다. §14 결정란이 채워지면 늘린다.
   ============================================================================ */
body.v2 {background: var(--bg-body); color: var(--text-primary); font-family: var(--font-base); font-size: var(--text-md); line-height: var(--leading-body); -webkit-font-smoothing: antialiased;}
body.v2 * {box-sizing: border-box;}
/* 스크롤바 숨김 (디자인 가이드 §9 결정): 시안의 ID 선택자·후속 CSS보다 우선한다. 페이지와 내부 영역의 스크롤 동작은 그대로 유지한다. */
html:has(body.v2), body.v2, body.v2 * {scrollbar-width: none !important; -ms-overflow-style: none !important;}
html:has(body.v2)::-webkit-scrollbar, body.v2::-webkit-scrollbar, body.v2 *::-webkit-scrollbar {display: none !important; width: 0 !important; height: 0 !important;}

/* ── 레이아웃 ─────────────────────────────────────────────────────── */
body.v2 .v2-page {min-height: 100vh; padding: var(--page-top) var(--page-x) var(--page-bottom);}
body.v2 .v2-container {max-width: var(--content-max); margin: 0 auto;}
body.v2 .v2-container.wide {max-width: var(--wide-max);}
body.v2 .v2-section {margin-bottom: var(--section-gap);}
body.v2 .v2-section-head {display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--section-y);}
body.v2 .v2-section-head h2 {margin: 0; font-size: var(--text-xl); font-weight: var(--font-bold); color: var(--color-gray-900); line-height: var(--leading-tight); letter-spacing: -.02em;}
body.v2 .v2-section-head .more {font-size: var(--text-base); color: var(--text-secondary); text-decoration: none;}
body.v2 .v2-grid {display: grid; grid-template-columns: repeat(var(--grid-cols), minmax(0, 1fr)); gap: var(--grid-gap);}
body.v2 .v2-stack {display: flex; flex-direction: column; gap: var(--space-3);}
body.v2 .v2-row {display: flex; align-items: center; gap: var(--space-2);}
body.v2 .v2-divider {height: 1px; background: var(--border-light); margin: var(--space-4) 0;}

/* ── 상단 헤더 ────────────────────────────────────────────────────── */
body.v2 .v2-header {position: sticky; top: 0; z-index: var(--z-header); display: flex; align-items: center; gap: var(--space-2); height: var(--header-h); margin: calc(var(--page-top) * -1) calc(var(--page-x) * -1) var(--space-4); padding: 0 var(--page-x); background: var(--bg-card); border-bottom: 1px solid var(--border-light);}
body.v2 .v2-header .logo {font-size: var(--text-xl); font-weight: var(--font-bold); color: var(--color-gray-900); text-decoration: none; letter-spacing: -.02em;}
body.v2 .v2-header .logo b {color: var(--color-primary-500);}
body.v2 .v2-header .title {flex: 1; min-width: 0; font-size: var(--text-lg); font-weight: var(--font-semibold); color: var(--color-gray-900); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;}
body.v2 .v2-header .actions {display: flex; gap: var(--space-1); margin-left: auto;}
body.v2 .v2-iconbtn {display: inline-flex; align-items: center; justify-content: center; width: var(--touch-min); height: var(--touch-min); border: 0; border-radius: var(--radius-full); background: transparent; color: var(--text-primary); cursor: pointer;}
body.v2 .v2-iconbtn:hover {background: var(--color-gray-100);}

/* ── 글자: 요소 기본 규칙 (디자인 가이드 §8-1). 페이지 CSS는 이걸 덮어쓰지 않는다 ── */
body.v2 h1, body.v2 h2, body.v2 h3, body.v2 h4 {margin: 0; color: var(--color-gray-900);}
body.v2 h1 {font-size: var(--text-3xl); line-height: var(--leading-h1); letter-spacing: var(--tracking-h1); font-weight: var(--font-bold);}
body.v2 h2 {font-size: var(--text-2xl); line-height: var(--leading-h2); letter-spacing: var(--tracking-h2); font-weight: var(--font-bold);}
body.v2 h3 {font-size: var(--text-xl); line-height: var(--leading-h3); letter-spacing: var(--tracking-h3); font-weight: var(--font-semibold);}
body.v2 h4 {font-size: var(--text-lg); line-height: var(--leading-h4); letter-spacing: var(--tracking-h4); font-weight: var(--font-semibold);}
body.v2 p {margin: 0; font-size: var(--text-md); line-height: var(--leading-body); letter-spacing: var(--tracking-body); color: var(--text-primary);}
body.v2 small {font-size: var(--text-base); line-height: var(--leading-small); color: var(--text-secondary);}
body.v2 b, body.v2 strong {font-weight: var(--font-medium);}
body.v2 .v2-display {font-size: var(--text-display); line-height: var(--leading-display); letter-spacing: var(--tracking-display); font-weight: var(--font-bold); color: var(--color-gray-900);}
body.v2 .v2-num {font-variant-numeric: tabular-nums;}
body.v2.font-locale-global h1, body.v2.font-locale-global h2, body.v2.font-locale-global h3, body.v2.font-locale-global h4, body.v2.font-locale-global .v2-display {letter-spacing: 0;}
body.v2 .v2-h1 {font-size: var(--text-3xl); line-height: var(--leading-h1); letter-spacing: var(--tracking-h1); font-weight: var(--font-bold); color: var(--color-gray-900); margin: 0 0 var(--space-3);}
body.v2 .v2-h2 {font-size: var(--text-2xl); line-height: var(--leading-h2); letter-spacing: var(--tracking-h2); font-weight: var(--font-bold); color: var(--color-gray-900); margin: 0 0 var(--space-2);}
body.v2 .v2-h3 {font-size: var(--text-xl); line-height: var(--leading-h3); letter-spacing: var(--tracking-h3); font-weight: var(--font-semibold); color: var(--color-gray-900);}
body.v2 .v2-text {font-size: var(--text-md); line-height: var(--leading-body); color: var(--text-primary); margin: 0;}
body.v2 .v2-text-lg {font-size: var(--text-lg); line-height: var(--leading-body); letter-spacing: var(--tracking-body-lg); color: var(--text-primary);}
body.v2 .v2-small {font-size: var(--text-base); line-height: var(--leading-small); color: var(--text-secondary);}
body.v2 .v2-caption {font-size: var(--text-base); line-height: var(--leading-caption); font-weight: var(--font-medium); color: var(--text-muted);}

/* ── 버튼 ─────────────────────────────────────────────────────────── */
body.v2 .v2-btn {display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); height: var(--btn-h-md); padding: 0 var(--btn-px-md); border: 1px solid transparent; border-radius: var(--radius-btn); font: inherit; font-size: var(--text-md); font-weight: var(--font-semibold); line-height: 1; text-decoration: none; cursor: pointer; transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease); white-space: nowrap;}
body.v2 .v2-btn.primary {background: var(--color-primary-500); color: var(--color-white);}
body.v2 .v2-btn.primary:hover {background: var(--color-primary-600);}
body.v2 .v2-btn.primary:active {background: var(--color-primary-700);}
body.v2 .v2-btn.secondary {background: var(--color-primary-50); color: var(--color-primary-500);}
body.v2 .v2-btn.secondary:hover {background: var(--color-primary-100);}
body.v2 .v2-btn.outline {background: transparent; color: var(--color-primary-500); border-color: var(--color-primary-500);}
body.v2 .v2-btn.outline:hover {background: var(--color-primary-50);}
body.v2 .v2-btn.ghost {background: transparent; color: var(--text-secondary);}
body.v2 .v2-btn.ghost:hover {background: var(--color-gray-100);}
body.v2 .v2-btn.danger {background: var(--color-error); color: var(--color-white);}
body.v2 .v2-btn.danger:hover {background: var(--color-error-hover);}
body.v2 .v2-btn.lg {height: var(--btn-h-lg); padding: 0 var(--btn-px-lg); font-size: var(--text-lg);}
body.v2 .v2-btn.sm {height: var(--btn-h-sm); padding: 0 var(--btn-px-sm); font-size: var(--text-base); border-radius: var(--radius-btn-sm);}
body.v2 .v2-btn.block {display: flex; width: 100%;}
body.v2 .v2-btn:disabled, body.v2 .v2-btn.disabled {background: var(--color-gray-100); color: var(--color-gray-300); border-color: transparent; cursor: not-allowed;}
body.v2 .v2-btn:focus-visible {outline: 2px solid var(--border-focus); outline-offset: 2px;}

/* ── 카드 ─────────────────────────────────────────────────────────── */
body.v2 .v2-card {background: var(--bg-card); border: 1px solid var(--border-light); border-radius: var(--radius-card); padding: var(--box-py) var(--box-px);}
body.v2 .v2-card.flat {border: 0; background: var(--color-gray-100);}
body.v2 .v2-card.clickable {cursor: pointer; transition: box-shadow var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);}
body.v2 .v2-card.clickable:hover {box-shadow: var(--shadow-md); border-color: var(--border-medium);}
body.v2 .v2-card.selected {background: var(--color-primary-50); border-color: var(--color-primary-500);}
body.v2 .v2-thumb {display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; border-radius: var(--radius-thumb); background: var(--color-gray-100);}

/* ── 리스트 컨테이너(여러 줄을 한 박스로) ─────────────────────────── */
body.v2 .v2-list {background: var(--bg-card); border: 1px solid var(--border-light); border-radius: var(--radius-card); overflow: hidden;}
body.v2 .v2-list .row {display: flex; align-items: center; gap: var(--space-3); min-height: 56px; padding: var(--space-3) var(--box-px); border-top: 1px solid var(--border-light); color: inherit; text-decoration: none;}
body.v2 .v2-list .row:first-child {border-top: 0;}
body.v2 .v2-list .row:hover {background: var(--color-gray-100);}
body.v2 .v2-list .row .grow {flex: 1; min-width: 0;}
body.v2 .v2-list .row .chev {color: var(--text-muted);}

/* ── 칩 · 배지 ────────────────────────────────────────────────────── */
body.v2 .v2-chips {display: flex; gap: var(--space-2); overflow-x: auto; scrollbar-width: none; margin: 0 calc(var(--page-x) * -1); padding: 0 var(--page-x) var(--space-1);}
body.v2 .v2-chips::-webkit-scrollbar {display: none;}
body.v2 .v2-chip {display: inline-flex; align-items: center; min-height: var(--chip-h); padding: var(--chip-py) var(--chip-px); border: 1px solid var(--border-light); border-radius: var(--radius-chip); background: var(--bg-card); color: var(--text-secondary); font: inherit; font-size: var(--text-base); font-weight: var(--font-medium); white-space: nowrap; cursor: pointer; text-decoration: none;}
body.v2 .v2-chip.on {background: var(--color-primary-500); color: var(--color-white); border-color: var(--color-primary-500);}
body.v2 .v2-badge {display: inline-flex; align-items: center; height: 20px; padding: 0 var(--space-2); border-radius: var(--radius-badge); font-size: var(--text-base); font-weight: var(--font-semibold); line-height: 1; background: var(--color-primary-50); color: var(--color-primary-800);}
body.v2 .v2-badge.success {background: var(--color-success-light); color: var(--color-success-dark);}
body.v2 .v2-badge.warning {background: var(--color-warning-light); color: var(--color-warning-dark);}
body.v2 .v2-badge.danger {background: var(--color-error-light); color: var(--color-error-dark);}
body.v2 .v2-badge.neutral {background: var(--color-gray-100); color: var(--text-secondary);}

/* ── 빈 상태 ──────────────────────────────────────────────────────── */
body.v2 .v2-empty {padding: var(--space-10) var(--space-4); text-align: center; color: var(--text-muted); background: var(--bg-card); border: 1px dashed var(--border-medium); border-radius: var(--radius-card);}
