/* ═══════════════════════════════════════════════════════════════
   jdent 부품 카탈로그 v0.1 — 기차놀이(reservation-bot v0.1.7) 실측값
   규칙: 화면은 이 파일의 클래스만 조립한다. 여기 없는 값은 쓰지 않는다.
   새 변형이 필요하면 이 파일과 CATALOG.md에 먼저 추가한다(승인 사항).
   ═══════════════════════════════════════════════════════════════ */

/* ── 1. 토큰 ──────────────────────────────────────────────────── */
:root {
  /* 색 — 바탕·글자 */
  --bg:           #F2F4F6;
  --card:         #FFFFFF;
  --fill:         #F2F4F6;                 /* 회색 채움(고스트 버튼·인셋 박스·칩) */
  --fill-2:       #EEF1F4;
  --separator:    rgba(60,66,80,0.08);     /* 0.5px 헤어라인 */
  --border:       #DDE2E7;                 /* 1~1.5px 실선 테두리 */
  --text:         #191F28;
  --text-2:       #4E5968;                 /* 라벨·섹션 제목·보조 버튼 글자 */
  --text-3:       #6B7684;                 /* 세그먼트 비활성·회색 배지 글자 */
  --muted:        #8B95A1;                 /* 힌트·비활성 */
  --faint:        #B0B8C1;                 /* placeholder·빈 값 */
  /* 색 — 포인트 */
  --blue:         #3182F6;
  --blue-deep:    #1B64DA;
  --blue-tint:    rgba(49,130,246,0.10);
  --blue-tint-2:  rgba(49,130,246,0.12);
  --green:        #18B26B;
  --green-text:   #119658;
  --green-tint:   rgba(12,166,120,0.14);
  --green-badge:  #0B7A57;
  --red:          #F04452;
  --red-text:     #E03131;
  --red-tint:     #FFF5F5;
  --red-border:   #FFC9C9;
  --orange:       #EA580C;
  --orange-badge: #C2410C;
  --orange-tint:  rgba(247,103,7,0.13);
  --dark:         #191F28;                 /* 다크 팝오버·토스트 배경 */

  /* 모양 */
  --r-card: 16px;  --r-btn: 14px;  --r-md: 10px;  --r-sm: 8px;  --r-xs: 6px;  --r-pill: 999px;
  --shadow-card:  0 1px 2px rgba(22,28,45,0.04), 0 6px 20px rgba(22,28,45,0.06);
  --shadow-pop:   0 8px 24px rgba(0,0,0,0.22);
  --shadow-btn:   0 8px 18px rgba(49,130,246,0.30);

  /* 간격 — 역할별. 담는 쪽만 쓴다 */
  --page-x:      14px;   /* 화면 좌우(박스 마진) */
  --cell-py:     11px;   /* 행 세로 */
  --cell-px:     16px;   /* 행 좌우 */
  --cell-min:    44px;   /* 행 최소 높이 */
  --gap:          8px;   /* 요소 사이 기본 */
  --gap-btn:     10px;   /* 버튼 사이 */
  --gap-chip:     6px;   /* 칩 사이 */
  --section-gap: 10px;   /* 섹션(박스) 사이 */
  --box-pad:     14px 16px;   /* 행 없는 박스 안쪽 */

  /* 서체 */
  --font: -apple-system, "SF Pro Text", "Pretendard", "Apple SD Gothic Neo", system-ui, sans-serif;
  --font-mono: "SF Mono", Menlo, "Roboto Mono", monospace;
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { background: var(--bg); color: var(--text); font-family: var(--font);
  -webkit-font-smoothing: antialiased; letter-spacing: -0.2px; }
button, input { font-family: inherit; }
button { -webkit-tap-highlight-color: transparent; cursor: pointer; }
* { scrollbar-width: thin; scrollbar-color: rgba(49,130,246,.35) transparent; }

/* ── 2. 텍스트 (8종) ──────────────────────────────────────────── */
.t-title   { font-size: 21px;   font-weight: 800; letter-spacing: -0.5px; line-height: 1.1; color: var(--text); }
.t-heading { font-size: 17px;   font-weight: 800; letter-spacing: -0.3px; color: var(--text); }
.t-section { font-size: 13px;   font-weight: 800; letter-spacing: -0.2px; color: var(--text-2); }
.t-label   { font-size: 14px;   font-weight: 500; letter-spacing: -0.2px; color: var(--text-2); }
.t-body    { font-size: 15px;   font-weight: 500; letter-spacing: -0.2px; color: var(--text); }
.t-value   { font-size: 15.5px; font-weight: 700; letter-spacing: -0.3px; color: var(--blue); }
.t-caption { font-size: 12px;   font-weight: 400; letter-spacing: -0.2px; color: var(--muted); }
.t-num     { font-size: 22px;   font-weight: 800; letter-spacing: -0.8px; color: var(--text);
             font-variant-numeric: tabular-nums; }
.t-strong  { font-weight: 800; color: var(--text); }
.t-mono    { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

/* ── 3. 버튼 (크기 4 × 톤 5) ─────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  border: none; font-weight: 700; white-space: nowrap;
  transition: transform .06s, opacity .15s, background .15s;
}
.btn:active { transform: scale(0.985); }
.btn:disabled { opacity: 0.4; cursor: default; transform: none; box-shadow: none; }
/* 크기 — 높이·radius·글자만. 폭은 담는 쪽이 정한다 */
.btn.lg { height: 52px; border-radius: var(--r-btn); font-size: 16.5px; padding: 0 20px; letter-spacing: -0.3px; }
.btn.md { height: 46px; border-radius: var(--r-btn); font-size: 15px;   padding: 0 16px; letter-spacing: -0.3px; }
.btn.sm { height: 36px; border-radius: var(--r-md);  font-size: 13px;   padding: 0 12px; }
.btn.xs { height: 28px; border-radius: var(--r-sm);  font-size: 12.5px; padding: 0 10px; }
/* 톤 */
.btn.primary { background: linear-gradient(180deg, var(--blue), var(--blue-deep)); color: #fff; }
.btn.primary.lg, .btn.primary.md { box-shadow: var(--shadow-btn); }
.btn.danger  { background: linear-gradient(180deg, #FF5247, #E5342A); color: #fff; }
.btn.danger.lg { box-shadow: 0 6px 16px rgba(255,59,48,0.28); }
.btn.ghost   { background: var(--fill-2); color: var(--text-2); }
.btn.outline { background: var(--card); color: var(--text-2); border: 1px solid var(--border); }
.btn.outline.blue { color: var(--blue); border: 1.5px solid var(--blue); }
.btn.tint    { background: var(--blue-tint-2); color: var(--blue); }
.btn.soft-danger { background: var(--red-tint); color: var(--red-text); border: 1px solid var(--red-border); }
/* 아이콘 정사각 — 크기 클래스와 함께 */
.btn.icon { padding: 0; aspect-ratio: 1; }
.btn.icon.sm { width: 34px; height: 34px; border-radius: 9px; }
.btn.icon.xs { width: 28px; height: 28px; }
.btn.icon.round { border-radius: 50%; }
.btn.icon svg { width: 16px; height: 16px; }
.btn.full { width: 100%; }
/* 텍스트 버튼 — 배경 없음. 섹션 제목 우측·목록 더보기 */
.btn-text { border: none; background: none; padding: 2px 0; font-size: 13px; font-weight: 700;
  color: var(--blue); letter-spacing: -0.2px; }
.btn-text:active { opacity: 0.55; }
.btn-text.danger { color: var(--red-text); font-weight: 400; font-size: 12.5px; }
.btn-text.muted  { color: var(--muted); }
/* 버튼 행 — 간격은 여기서 */
.btn-row { display: flex; gap: var(--gap-btn); }
.btn-row > .btn { flex: 1; }
.btn-row > .btn.icon { flex: none; }

/* ── 4. 박스 (3종) + 섹션 제목 ───────────────────────────────── */
.section { padding: 0 8px 2px; margin: var(--section-gap) 0 4px; }
.section.with-action { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.box { background: var(--card); border-radius: var(--r-card); box-shadow: var(--shadow-card);
  overflow: hidden; margin: 0 var(--page-x); }
.box.pad   { padding: var(--box-pad); }
.box.inset { background: var(--fill); border-radius: var(--r-md); box-shadow: none; margin: 0;
  padding: 10px 12px; }
.box.hero  { background: linear-gradient(135deg, #3182F6 0%, #1B64DA 100%); color: #fff;
  box-shadow: 0 6px 18px rgba(27,100,218,0.28); padding: 15px 16px 16px;
  display: flex; align-items: center; gap: 13px; }
.box.hero .t-caption { color: rgba(255,255,255,0.86); }
/* 상태 띠 — 결과 카드처럼 왼쪽 3px 색 띠 */
.box.edge-blue  { border-left: 3px solid var(--blue); }
.box.edge-green { border-left: 3px solid #0CA678; }
.box.edge-gray  { border-left: 3px solid #C6CDD5; }
/* 박스 사이 간격은 스택이 준다 */
.stack { display: flex; flex-direction: column; gap: var(--section-gap); }
.stack.tight { gap: var(--gap); }

/* ── 5. 행 (4종) ─────────────────────────────────────────────── */
/* 공통: 슬롯 [lead][label][value][trail]. 헤어라인은 형제 사이 자동, 왼쪽 16px 들여쓰기 */
.row, .row-head, .row-stack, .row-item { position: relative; padding: var(--cell-py) var(--cell-px); }
.row + .row, .row + .row-stack, .row-stack + .row, .row-item + .row-item,
.row-head + .row, .row + .row-item, .row-item + .row {
  border-top: 0.5px solid transparent;
}
.row + .row::before, .row + .row-stack::before, .row-stack + .row::before, .row-item + .row-item::before,
.row-head + .row::before, .row + .row-item::before, .row-item + .row::before {
  content: ''; position: absolute; left: var(--cell-px); right: 0; top: -0.5px;
  height: 0.5px; background: var(--separator);
}
/* 5-1 기본 행: 라벨 왼쪽 · 값/컨트롤 오른쪽 */
.row { display: flex; align-items: center; gap: var(--gap); min-height: var(--cell-min); }
.row > .lead  { flex: none; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; }
.row > .label { flex: 1; min-width: 0; font-size: 14px; font-weight: 500; color: var(--text-2); white-space: nowrap; }
.row > .value { flex: none; display: flex; align-items: center; justify-content: flex-end; gap: 6px;
  font-size: 15.5px; font-weight: 700; color: var(--blue); text-align: right; }
.row > .value.plain { color: var(--text); font-weight: 400; font-size: 14px; }
.row > .value.empty { color: var(--faint); font-weight: 500; font-size: 14px; }
.row > .value.wrap  { flex: 1 1 auto; min-width: 0; flex-wrap: wrap; row-gap: 4px; }
.row > .trail { flex: none; display: flex; align-items: center; gap: 6px; }
/* 5-2 머리 행: [배지·점][제목 flex][아이콘 버튼들] */
.row-head { display: flex; align-items: center; gap: var(--gap); padding: 14px var(--cell-px) 12px; }
.row-head > .title { flex: 1; min-width: 0; font-size: 15px; font-weight: 800; letter-spacing: -0.3px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-head > .trail { flex: none; display: flex; gap: 6px; }
/* 5-3 스택 행: 라벨 위 · 내용 아래 */
.row-stack { display: flex; flex-direction: column; align-items: stretch; gap: var(--gap); }
.row-stack > .label { font-size: 14px; font-weight: 500; color: var(--text-2); }
.row-stack > .sub   { font-size: 12px; font-weight: 700; color: var(--muted); }
/* 5-4 항목 행: 누를 수 있는 목록. 가운데 정렬 시트형 / 왼쪽 정렬 목록형 */
.row-item { display: flex; align-items: center; gap: var(--gap); min-height: 46px; cursor: pointer;
  font-size: 15px; color: var(--text); }
.row-item:active { background: rgba(0,0,0,0.04); }
.row-item.center { justify-content: center; font-size: 16px; }
.row-item.on { color: var(--blue); font-weight: 700; }
.row-item.on.fill { background: var(--blue-tint-2); }
.row-item > .label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-item > .meta  { flex: none; font-size: 12px; color: var(--muted); }
.row-item > .when  { flex: none; font-size: 11.5px; font-weight: 700; color: var(--muted); }
/* 2열 반쪽 행 — 날짜|시간처럼 한 행을 둘로 */
.row.half { display: grid; grid-template-columns: 1fr 0.5px 1fr; padding: 0; min-height: 0; }
.row.half > .cell { display: flex; align-items: center; gap: var(--gap); min-height: var(--cell-min);
  padding: var(--cell-py) var(--cell-px); }
.row.half > .vsep { background: var(--separator); }

/* ── 6. 컨트롤 ───────────────────────────────────────────────── */
/* 입력 — 기본은 행 안 민짜(우측 정렬 파란 값). boxed는 테두리 상자 */
.input { border: none; outline: none; background: transparent; text-align: right; min-width: 0; padding: 0;
  font-size: 15.5px; font-weight: 600; color: var(--blue); letter-spacing: -0.3px; }
.input::placeholder { color: #BFC5CE; font-weight: 500; }
.input.boxed { background: #FBFCFD; border: 1.5px solid var(--separator); border-radius: var(--r-btn);
  padding: 8px 12px; text-align: center; font-weight: 700; width: 100%; }
.input.boxed.sm { height: 32px; border-radius: var(--r-sm); border: 1px solid #D1D6DB; background: #fff;
  padding: 0 8px; font-size: 14px; }
.input.boxed:focus { border-color: var(--blue); }
.input-err { font-size: 11.5px; font-weight: 600; color: var(--red); line-height: 1.3; text-align: right; }
/* 스위치 38×22 (2026-09 확정, 구 토글 44×26 초록은 폐기) */
.switch { position: relative; flex: none; width: 38px; height: 22px; border: none; border-radius: var(--r-pill);
  background: #D1D6DB; transition: background .16s; padding: 0; }
.switch::after { content: ''; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.22); transition: transform .16s; }
.switch.on { background: var(--blue); }
.switch.on::after { transform: translateX(16px); }
/* 체크박스 17px */
.check { position: relative; flex: none; width: 17px; height: 17px; border-radius: 5px; border: 1.6px solid #C6CDD5;
  background: #fff; padding: 0; }
.check.on { background: var(--blue); border-color: var(--blue); }
.check.on::after { content: ''; position: absolute; left: 5px; top: 1.5px; width: 4px; height: 9px;
  border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg); }
/* 세그먼트 — 회색 트랙 + 파란 채움. tight는 한 줄 3~4개용 */
.seg { display: flex; background: var(--fill); border-radius: 13px; padding: 5px; gap: 4px; }
.seg > button { flex: 1; height: 40px; border: none; border-radius: var(--r-md); background: transparent;
  font-size: 14px; font-weight: 600; color: var(--text-3); white-space: nowrap; transition: all .18s; }
.seg > button.on { background: var(--blue); color: #fff; font-weight: 700; box-shadow: 0 4px 10px rgba(49,130,246,0.30); }
.seg > button:disabled { opacity: .45; }
.seg.tight { padding: 3px; border-radius: 11px; gap: 3px; }
.seg.tight > button { height: 30px; border-radius: var(--r-sm); font-size: 11px; padding: 0 2px; }
/* 탭형 세그먼트 — 박스 상단에 붙는 노트 인덱스 */
.seg.tabs { padding: 0; gap: 0; border-radius: 0; background: var(--card); border-bottom: 0.5px solid var(--separator); }
.seg.tabs > button { border-radius: 0; height: 44px; box-shadow: none; }
/* 칩 — 회색 채움(md) / 테두리 알약(sm). on = 옅은 파랑 */
.chip { display: inline-flex; align-items: center; gap: 4px; border: none; white-space: nowrap; font-weight: 600;
  background: var(--fill); color: var(--text-2); font-size: 13px; padding: 9px 14px; border-radius: 11px;
  transition: background .12s, color .12s; }
.chip:active { transform: scale(0.97); }
.chip.sm { background: var(--card); border: 1px solid var(--separator); font-size: 11.5px; padding: 6px 9px;
  border-radius: var(--r-pill); line-height: 1; }
.chip.on { background: var(--blue-tint-2); color: var(--blue-deep); border-color: rgba(49,130,246,0.35); font-weight: 700; }
.chip.solid.on { background: var(--blue); color: #fff; border-color: var(--blue); }
.chip.add { background: var(--blue-tint); color: var(--blue); font-weight: 700; }
.chip:disabled { opacity: .4; }
.chip.two { flex-direction: column; gap: 1px; padding: 9px 12px; line-height: 1.32; }
.chip.two > b { font-size: 12px; font-weight: 800; color: var(--text); }
.chip.two > span { font-size: 10px; font-weight: 600; }
.chip.round { width: 27px; height: 27px; padding: 0; justify-content: center; border-radius: 50%;
  background: var(--card); border: 1.5px solid var(--border); font-size: 12px; font-weight: 700; }
.chip.round.on { background: var(--blue); border-color: var(--blue); color: #fff; }
.chips { display: flex; flex-wrap: wrap; gap: var(--gap-chip); }
.chips.scroll { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
.chips.scroll::-webkit-scrollbar { display: none; }
/* 배지 — 상태 표시. 10.5/800, 톤 4 */
.badge { display: inline-flex; align-items: center; flex: none; font-size: 10.5px; font-weight: 800;
  letter-spacing: -0.2px; padding: 3px 8px; border-radius: 7px; white-space: nowrap; }
.badge.blue   { background: var(--blue-tint-2); color: var(--blue-deep); }
.badge.green  { background: var(--green-tint);  color: var(--green-badge); }
.badge.gray   { background: #EDF0F3;            color: var(--text-3); }
.badge.orange { background: var(--orange-tint); color: var(--orange-badge); }
.badge.round  { border-radius: var(--r-pill); padding: 2px 7px; }
/* 상태 필 — 점 + 글자, 26px */
.pill { display: inline-flex; align-items: center; gap: 5px; height: 26px; padding: 0 12px; border-radius: var(--r-pill);
  font-size: 12.5px; font-weight: 700; letter-spacing: -0.1px; white-space: nowrap;
  background: rgba(138,144,155,0.16); color: var(--muted); }
.pill::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.pill.on    { background: rgba(32,189,104,0.14); color: var(--green-text); }
.pill.sched { background: var(--blue-tint-2); color: var(--blue); }
.pill.alert { background: rgba(240,68,56,0.12); color: var(--red); }
.pill.on::before, .pill.alert::before { animation: pulse 1.4s ease-in-out infinite; }
@keyframes pulse { 0%,100% { opacity: 1; transform: scale(1); } 50% { opacity: .4; transform: scale(.82); } }
/* 점 표시등 */
.dot { width: 11px; height: 11px; border-radius: 50%; background: #C2C8D0; flex: none; }
.dot.ok { background: #20BD68; } .dot.err { background: var(--red); } .dot.blue { background: var(--blue); }
.dot.run { background: #20BD68; box-shadow: 0 0 0 4px rgba(32,189,104,0.16); animation: pulse 1.4s infinite; }
/* 스피너 */
.spin { width: 14px; height: 14px; border-radius: 50%; border: 2px solid #D5DBE1; border-top-color: var(--blue);
  animation: spin .7s linear infinite; flex: none; }
.spin.lg { width: 21px; height: 21px; border-width: 2.5px; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ── 7. 안내 문구 (5종) — 행 아래·박스 안 한 줄 ─────────────── */
.msg { line-height: 1.55; letter-spacing: -0.2px; white-space: pre-line; }
.msg.hint { font-size: 12px;   font-weight: 400; color: var(--muted); }
.msg.note { font-size: 13px;   font-weight: 500; color: var(--text-2); text-align: center; }
.msg.ok   { font-size: 13.5px; font-weight: 700; color: var(--green-text); text-align: center; }
.msg.warn { font-size: 13.5px; font-weight: 700; color: var(--orange); text-align: center; }
.msg.err  { font-size: 11.5px; font-weight: 600; color: var(--red); line-height: 1.3; }
.msg.boxed { background: #F7F9FB; padding: 8px 14px 10px; text-align: center; }
/* 빈 상태 */
.empty-state { display: flex; flex-direction: column; align-items: center; gap: 16px; padding: 26px 16px; text-align: center; }
.empty-state > .msg { font-size: 13px; color: var(--muted); }

/* ── 8. 오버레이 (5종) ──────────────────────────────────────── */
.overlay { position: fixed; inset: 0; z-index: 1000; background: rgba(0,0,0,0.4);
  display: flex; flex-direction: column; justify-content: flex-end; align-items: center; padding: 10px; }
.overlay.center { justify-content: center; }
/* 8-1 바텀시트 */
.sheet { width: 100%; max-width: 440px; background: var(--card); border-radius: var(--r-card); overflow: hidden;
  max-height: 84vh; overflow-y: auto; }
.sheet.pad { padding: 20px 18px 12px; }
.sheet > .title { text-align: center; font-size: 16px; font-weight: 800; padding: 18px 14px 14px; letter-spacing: -0.3px; }
.sheet .foot { position: sticky; bottom: 0; background: var(--card); margin-top: 14px; padding: 10px 0 2px;
  box-shadow: 0 -10px 14px -10px rgba(0,0,0,.14); }
.sheet + .sheet { margin-top: 10px; }   /* 취소 버튼 분리 카드 */
/* 8-2 드롭다운 메뉴 — 누른 자리 아래, 입력칸 폭 */
.menu { background: var(--card); border-radius: 12px; overflow: hidden; overflow-y: auto; max-height: 240px;
  box-shadow: 0 8px 30px rgba(0,0,0,0.16), 0 1px 4px rgba(0,0,0,0.08); }
.menu > .row-item { min-height: 0; padding: 12px 16px; font-size: 15.5px; justify-content: center; }
/* 8-3 다크 팝오버 — 안내(note)·툴팁(tip)·토스트(toast). 배경 같고 크기만 다르다 */
.pop { position: relative; background: var(--dark); color: #fff; box-shadow: var(--shadow-pop);
  white-space: pre-line; font-weight: 600; letter-spacing: -0.2px; }
.pop.tip   { border-radius: 9px;  padding: 6px 10px;  font-size: 12px;   white-space: nowrap; }
.pop.note  { border-radius: 12px; padding: 10px 13px; font-size: 13px;   line-height: 1.5; max-width: 300px; }
.pop.toast { border-radius: 14px; padding: 12px 17px; font-size: 13.5px; line-height: 19px; text-align: center;
  max-width: 400px; background: rgba(25,31,40,0.94); backdrop-filter: blur(10px); }
/* 8-4 확인 팝오버 — 흰 배경, 버튼 2개 */
.confirm { background: var(--card); border: 1px solid #E5E8EC; border-radius: 12px; padding: 13px 14px 11px;
  box-shadow: 0 10px 30px rgba(0,0,0,.18); max-width: 300px; }
.confirm > .msg { font-size: 13.5px; font-weight: 600; line-height: 1.55; color: var(--text); text-align: left; }
.confirm > .btn-row { margin-top: 11px; gap: 7px; }
.confirm .btn { height: 36px; border-radius: var(--r-md); font-size: 13px; }
/* 8-5 스포트라이트 안내(튜토리얼) */
.spot { background: var(--card); border-radius: 14px; padding: 13px 48px 14px 16px; position: relative;
  box-shadow: 0 10px 28px rgba(0,0,0,0.26); max-width: 370px; }
.spot > .t { font-size: 14.5px; font-weight: 800; letter-spacing: -0.3px; line-height: 20px; }
.spot > .s { font-size: 12.5px; color: var(--muted); margin-top: 4px; }
.spot > .btn { position: absolute; top: 9px; right: 10px; height: 24px; padding: 0 9px; border-radius: 7px; font-size: 11px; font-weight: 800; }

/* ── 9. 골격 ─────────────────────────────────────────────────── */
.app { width: 100%; max-width: 480px; margin: 0 auto; min-height: 100dvh; position: relative;
  background: radial-gradient(1200px 500px at 50% -120px, #F4F6F8, transparent 70%), linear-gradient(180deg, #F4F6F8, #EAEDF1); }
.app-header { position: sticky; top: 0; z-index: 30; height: 56px; padding: 12px 20px 8px;
  display: flex; align-items: center; justify-content: space-between;
  background: rgba(245,248,251,0.78); backdrop-filter: blur(18px) saturate(180%); border-bottom: 0.5px solid var(--separator); }
.app-header .sub { font-size: 12px; color: var(--muted); margin-top: 1px; }
.tabbar { position: sticky; bottom: 0; z-index: 40; display: flex; padding: 2px 4px env(safe-area-inset-bottom, 12px);
  background: rgba(248,250,252,0.88); backdrop-filter: blur(22px) saturate(180%); border-top: 0.5px solid var(--separator); }
.tab { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 7px 2px 3px; cursor: pointer; }
.tab > .ic { width: 26px; height: 26px; border-radius: var(--r-sm); border: 1.8px solid var(--muted); color: var(--muted);
  display: flex; align-items: center; justify-content: center; position: relative; }
.tab > .ic svg { width: 14px; height: 14px; }
.tab > .lb { font-size: 10px; font-weight: 600; color: var(--muted); letter-spacing: -0.1px; }
.tab.on > .ic { background: var(--blue); border-color: var(--blue); color: #fff; }
.tab.on > .lb { color: var(--blue); }
.tab > .ic .dot { position: absolute; top: -3px; right: -4px; width: 8px; height: 8px; box-shadow: 0 0 0 2px #fff; }
/* 로그 터미널 */
.log { background: #F7F8FA; border-radius: 14px; padding: 12px 14px; height: 150px; overflow-y: auto;
  font-family: var(--font-mono); font-size: 12.5px; line-height: 17px; color: #2B303B;
  box-shadow: inset 0 0 0 1px rgba(60,66,80,0.08); white-space: pre-wrap; word-break: break-all; }
.log .ts  { color: #9AA1AE; margin-right: 7px; }
.log .err { color: #C2453A; } .log .warn { color: #B26B00; } .log .ok { color: #1F8B4C; } .log .dim { color: #9AA1AE; }
/* 통계 3칸 */
.stat3 { display: grid; grid-template-columns: 1fr 1fr 1fr; border-top: 1px solid var(--separator); }
.stat3 > div { padding: 12px 8px; text-align: center; }
.stat3 > div + div { border-left: 1px solid var(--separator); }
.stat3 .v { font-size: 17px; font-weight: 800; letter-spacing: -0.3px; }
.stat3 .l { font-size: 11.5px; color: var(--muted); margin-top: 3px; }

/* ═══ v0.1.1 — 검증(설정·결과·예매 탭 재조립, 2026-09-11)에서 발견한 빠진 변형. 승인 대기 ═══ */
/* (1) 3열 행 — 날짜·시간·인원처럼 값 3개를 가운데 정렬 */
.row.thirds { display: flex; align-items: center; gap: 6px; padding: 14px var(--cell-px) 18px; min-height: 0; }
.row.thirds > .cell { flex: 1; min-width: 0; display: flex; justify-content: center; align-items: center; gap: 5px;
  font-size: 15.5px; font-weight: 700; color: var(--blue); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.row.thirds > .cell.grow { flex: 1.55; }
.caret { font-size: 10px; }
/* (2) 조밀 행 — 카드 안 정보 줄(시간·열차명). 헤어라인 없음 */
.row.dense { min-height: 26px; padding: 3px var(--cell-px); }
.row.dense + .row.dense::before { display: none; }
.row.dense > .label { color: var(--text); font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.dot.sm { width: 7px; height: 7px; background: #C9D2DC; }
/* (3) 보조 줄 — 왼쪽 정렬 12.5 text-2 (카드 본문 부연) */
.msg.sub { font-size: 12.5px; font-weight: 400; color: var(--text-2); text-align: left; }
/* (4) 접히는 상태 바 — 카드 하단, 톤 3 */
.bar { display: flex; align-items: center; gap: 8px; width: 100%; min-height: 36px; padding: 8px 12px; border-radius: var(--r-md);
  border: 1px solid rgba(49,130,246,0.30); background: rgba(49,130,246,0.05); color: var(--blue-deep);
  font-size: 13px; font-weight: 700; line-height: 1.4; text-align: left; cursor: pointer; }
.bar > span { flex: 1; }
.bar::after { content: '⌄'; font-size: 20px; line-height: 1; opacity: .85; margin-top: -6px; }
.bar.green { border-color: rgba(12,166,120,0.30); background: rgba(12,166,120,0.05); color: var(--green-badge); }
.bar.gray  { border-color: #DDE2E7; background: #F7F9FA; color: var(--text-3); }
.bar.orange { border-color: rgba(247,103,7,0.30); background: rgba(247,103,7,0.05); color: var(--orange-badge); }
/* (5) 배경 없는 아이콘 버튼 톤 — 행 끝 톱니·연필·되돌리기 */
.btn.plain { background: transparent; color: var(--muted); }
.btn.plain:active { background: rgba(0,0,0,0.04); }
/* (6) 아이콘 버튼 위 알림 점 */
.btn.icon { position: relative; }
.btn.icon > .dot.alert { position: absolute; top: -2px; right: -2px; width: 8px; height: 8px; background: var(--red); box-shadow: 0 0 0 2px var(--card); }
/* (7) 행 안에 들어가는 작은 세그먼트 — 폭은 내용만큼 */
.seg.inline { display: inline-flex; }
.seg.inline > button { flex: none; padding: 0 14px; }
/* (8) 선택 상자 — 라벨 위·값 아래, 누르면 시트. 주 버튼 옆 */
.pick { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0; flex: none;
  min-width: 78px; height: 52px; padding: 0 10px; border-radius: var(--r-btn); background: var(--card);
  border: 1px solid var(--separator); cursor: pointer; }
.pick > .l { font-size: 11px; color: var(--muted); font-weight: 600; }
.pick > .v { font-size: 17px; font-weight: 800; color: var(--blue); letter-spacing: -0.4px; display: flex; align-items: center; gap: 3px; }
/* (9) 색 글자 유틸 — 소요시간·상태 한 단어 */
.c-green { color: #1F8B4C; } .c-orange { color: var(--orange); } .c-red { color: var(--red); } .c-blue { color: var(--blue); }
/* (10) 섹션 제목 줄에 배지+개수 (결과 탭) */
.section.badged { display: flex; align-items: center; gap: 7px; padding: 0 4px 8px; }
.section.badged > .cnt { font-size: 11.5px; font-weight: 700; color: var(--muted); }
/* (11) outline 아이콘 버튼의 색 — 재개(파랑)·중단·삭제(붉음). 색 유틸은 톤보다 우선한다 */
.btn.outline.c-red  { color: var(--red-text); border-color: rgba(240,68,82,0.35); }
.btn.outline.c-blue { color: var(--blue);     border-color: rgba(49,130,246,0.45); }
