/* ============================================================
   디자인 토큰
   컴포넌트 CSS는 색/간격/모서리를 여기 정의된 변수로만 참조한다.
   다크모드는 이 변수 값만 바꾸고 레이아웃 규칙은 건드리지 않는다.
   ============================================================ */
:root {
  --bg: #F5F6F8;
  --surface: #FFFFFF;
  --primary: #4F6BED;
  --food: #FF7A59;
  --attraction: #2BB0A0;
  --waypoint: #9B6DD6;
  --text: #1B1F27;
  --muted: #6B7280;
  --border: #E5E7EB;
  --danger: #DC2626;
  --radius: 16px;
  --radius-sm: 10px;
  --slot-h: 28px;        /* 타임테이블 30분 슬롯 높이 — timegrid.js의 SLOT_H와 같아야 한다 */
  --tabbar-h: 56px;
  --sheet-mid: 40%;      /* 2단에서 시트가 시작하는 높이 — shell.js의 MID_RATIO와 같아야 한다 */
  --shadow: 0 1px 3px rgb(0 0 0 / .06), 0 1px 2px rgb(0 0 0 / .04);
  --on-accent: #FFFFFF;  /* primary/장소 종류 색 배경 위의 글자색 */

  /* 예산 카테고리 7색 — 도넛과 그룹 머리글에 쓴다 */
  --cat-flight: #4F6BED;
  --cat-hotel: #9B6DD6;
  --cat-food: #FF7A59;
  --cat-transit: #2BB0A0;
  --cat-activity: #E8B33C;
  --cat-shopping: #E0619B;
  --cat-etc: #7B8794;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #14161A;
    --surface: #1E2127;
    --primary: #7C90F5;
    --food: #FF9273;
    --attraction: #48C7B7;
    --waypoint: #B794E8;
    --text: #ECEEF2;
    --muted: #9AA1AD;
    --border: #2E323A;
    --danger: #F87171;
    --shadow: 0 1px 3px rgb(0 0 0 / .4);
    --on-accent: #10131A;

    --cat-flight: #7C90F5;
    --cat-hotel: #B794E8;
    --cat-food: #FF9273;
    --cat-transit: #48C7B7;
    --cat-activity: #F0C662;
    --cat-shopping: #F084B4;
    --cat-etc: #9AA1AD;
  }
}

/* ---- 기본 ---- */
* { box-sizing: border-box; }

/* 브라우저 기본 [hidden] { display: none } 은 UA 스타일이라 작성자 스타일의
   display 선언에 무조건 진다. .view 처럼 display 를 잡는 규칙이 있으면
   el.hidden = true 가 무시돼 숨긴 요소가 그대로 그려진다. */
[hidden] { display: none !important; }

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans KR", sans-serif;
  font-size: 15px;
  line-height: 1.5;
  background: var(--bg);
  color: var(--text);
  -webkit-text-size-adjust: 100%;
  /* 셸은 전부 fixed 배치라 문서가 스크롤될 일이 없다.
     100vh 는 모바일에서 주소창 뒤 영역까지 포함해 실제로 보이는 높이보다 크다.
     dvh 를 아는 브라우저는 그쪽을 쓰고, 모르면 위의 vh 로 남는다. */
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}

/* 안쪽 스크롤이 끝에 닿은 뒤에도 계속 밀면 그 스크롤이 문서로 넘어간다.
   그러면 모바일 브라우저가 페이지를 튕기면서 fixed 로 붙여둔 하단 탭바가
   화면 밖으로 밀려난다. 전파를 각 스크롤 영역 안에서 끊는다. */
html, body { overscroll-behavior: none; }

.view,
#source-list,
#source-rail,
#timetable-scroll,
#day-timetable-scroll,
.sheet,
.chip-row,
.date-strip { overscroll-behavior: contain; }

h1 { font-size: 20px; margin: 16px; }
h2 { font-size: 17px; margin: 16px 16px 8px; }
h3 { font-size: 16px; margin: 0 0 12px; }

.muted { color: var(--muted); font-size: 13px; }
.error { color: var(--danger); font-size: 14px; margin: 8px 16px; }

/* ---- 컴포넌트 ---- */
.card {
  background: var(--surface);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 14px 16px;
  margin: 8px;
}

.btn {
  min-height: 44px;
  padding: 0 16px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  cursor: pointer;
}
.btn--primary {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--on-accent);
  font-weight: 600;
}
.btn--ghost { background: transparent; border-color: transparent; color: var(--muted); }
.btn--danger { color: var(--danger); border-color: var(--border); background: transparent; }
.btn--block { display: block; width: 100%; }

.badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px;
  border-radius: var(--radius-sm);
  font-size: 12px; font-weight: 600;
  color: var(--on-accent);
}
.badge--food { background: var(--food); }
.badge--attraction { background: var(--attraction); }
.badge--waypoint { background: var(--waypoint); }
.badge--reservation {
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--border);
  font-weight: 500;
}

/* 정산 상태 */
.badge--settle-done { background: var(--attraction); }
.badge--settle-na { background: var(--muted); }
.badge--settle-pending {
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--border);
  font-weight: 500;
}

.chip {
  flex: 0 0 auto;   /* 칩이 늘면 줄에 안 맞는다. 눌러 담지 말고 가로로 넘겨 스크롤한다 */
  min-height: 44px;
  padding: 0 14px;
  border-radius: 22px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--muted);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
  white-space: nowrap;
}
.chip--on {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--on-accent);
  font-weight: 600;
}

.chip-row {
  display: flex; gap: 8px;
  overflow-x: auto;
  padding: 8px;
  scrollbar-width: none;
}
.chip-row::-webkit-scrollbar { display: none; }

/* ---- 날짜 스트립 ---- */
.date-strip {
  flex: 0 0 auto;   /* 타임테이블이 남은 높이를 다 가져가도 눌리지 않게 */
  display: flex; gap: 8px;
  overflow-x: auto;
  padding: 8px;
  scrollbar-width: none;
}
.date-strip::-webkit-scrollbar { display: none; }

/* 날짜 칸은 개수를 적지 않고 한 줄로 낮게 둔다. 아낀 높이는 타임테이블이 쓴다. */
.date-strip__item {
  flex: 0 0 auto;
  min-width: 52px; min-height: 40px;
  display: flex; align-items: center; justify-content: center;
  gap: 4px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}
.date-strip__item--on {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--on-accent);
}
/* 선택된 날짜 안의 보조 텍스트는 강조 배경 위에 놓이므로 대비를 되돌린다 */
.date-strip__item--on .muted { color: var(--on-accent); opacity: .75; }

/* ---- 폼 ---- */
input, select, textarea {
  width: 100%;
  min-height: 44px;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font: inherit;
}
textarea { min-height: 60px; resize: vertical; }
label { display: block; margin: 12px 0 4px; font-size: 14px; color: var(--muted); }
label.inline { display: flex; align-items: center; gap: 8px; }
label.inline input[type="checkbox"],
label.inline input[type="radio"] { width: auto; min-height: auto; }
fieldset { border: 1px solid var(--border); border-radius: var(--radius-sm); margin: 12px 0; }
legend { font-size: 14px; color: var(--muted); padding: 0 6px; }

/* ---- 하단 시트 ---- */
.sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
  background: var(--surface);
  border-radius: var(--radius) var(--radius) 0 0;
  padding: 20px 16px calc(20px + env(safe-area-inset-bottom));
  max-height: 85vh;
  max-height: 85dvh;
  overflow-y: auto;
  transform: translateY(100%);
  transition: transform .25s ease;
}
.sheet.sheet--open { transform: translateY(0); }

.sheet__backdrop {
  position: fixed; inset: 0; z-index: 10;
  background: rgb(0 0 0 / .4);
  opacity: 0; pointer-events: none;
  transition: opacity .25s ease;
}
.sheet__backdrop.sheet--open { opacity: 1; pointer-events: auto; }

/* ---- FAB ---- */
.fab {
  position: fixed; right: 16px; z-index: 15;
  bottom: calc(var(--tabbar-h) + 16px + env(safe-area-inset-bottom));
  width: 56px; height: 56px; border-radius: 28px; border: 0;
  background: var(--primary); color: var(--on-accent);
  font-size: 28px; line-height: 1;
  box-shadow: var(--shadow);
  cursor: pointer;
}

/* ---- 드래그 고스트 ----
   pointer-events: none 이 없으면 고스트가 드롭 대상 판정을 가로챈다. */
.drag-ghost {
  position: fixed; z-index: 100;
  pointer-events: none;
  transform: translate(-50%, -50%);
  opacity: .85;
  box-shadow: 0 8px 24px rgb(0 0 0 / .25);
}

/* 꾹 눌러 집힌 원본. 손가락에 가려 고스트가 안 보여도 어느 것이 들렸는지 알 수 있다. */
.drag-armed { opacity: .35; }

/* ============================================================
   셸 — 지도는 화면 전체에 깔려 있고, 시트가 그 위를 2단으로 오르내린다
   ============================================================ */

/* 지도는 처음부터 화면 전체 크기다. 크기를 바꾸지 않기 때문에
   구글맵 타일이 깨질 일이 없고, 시트는 그 위를 덮기만 하면 된다. */
#map-panel {
  position: fixed; inset: 0; z-index: 0;
}
#map { height: 100%; width: 100%; }

/* 시트는 바닥(탭바 위)에 고정된 채 윗변만 오르내린다.
   transform 으로 통째로 밀면 높이가 그대로라 아래에 지도가 드러난다.
   top 을 움직여야 시트가 실제로 늘어난다. 여기 값은 shell.js 가 자리를 잡기 전
   첫 화면용이고, 그 뒤로는 JS 가 px 로 덮어쓴다. */
#sheet-area {
  position: fixed; z-index: 1;
  top: var(--sheet-mid);
  left: 0; right: 0;
  bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom));
  background: var(--bg);
  border-radius: var(--radius) var(--radius) 0 0;
  box-shadow: 0 -2px 12px rgb(0 0 0 / .12);
  display: flex; flex-direction: column;
  transition: top .25s ease;
  will-change: top;
}

#map-handle {
  flex: 0 0 auto;
  width: 100%; min-height: 28px;
  display: flex; align-items: center; justify-content: center;
  background: transparent; border: 0;
  cursor: grab;
  touch-action: none;
}
#map-handle-bar {
  width: 44px; height: 5px; border-radius: 3px;
  background: var(--border);
}

#views {
  flex: 1;
  overflow: hidden;
  display: flex; flex-direction: column;
}
.view {
  flex: 1;
  overflow-y: auto;
  display: flex; flex-direction: column;
  min-height: 0;
}

/* ============================================================
   장소 추가
   ============================================================ */
/* 뷰 전체가 스크롤되면 목록이 길어질 때 여행기간 카드와 필터 칩까지 같이
   밀려 올라가 가려진다. 뷰는 고정하고 목록만 스크롤시킨다. */
#view-add { overflow: hidden; }
#trip-widget, #view-add .chip-row { flex: 0 0 auto; }
#source-list {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding-bottom: 8px;
}

/* 수정/삭제는 설명 아래가 아니라 카드 오른쪽 끝 위에 붙인다.
   설명이 두 줄만 돼도 버튼 줄만큼의 높이를 통째로 아낀다. */
#source-list .source-card {
  display: flex; align-items: flex-start; gap: 12px;
}
#source-list .source-card__body { flex: 1 1 auto; min-width: 0; }
#source-list .source-card__actions {
  flex: 0 0 auto;
  display: flex; gap: 6px;
}
#source-list .source-card__actions .btn {
  min-height: 36px;
  padding: 0 12px;
  font-size: 13px;
}

/* ============================================================
   동선 변경 (편집)
   ============================================================ */
#planner {
  flex: 1;
  display: flex;
  gap: 8px;
  padding: 0 8px 8px;
  min-height: 0;
}

#source-rail {
  flex: 0 0 34%;
  overflow-y: auto;
  display: flex; flex-direction: column; gap: 8px;
}
#source-rail .source-card {
  /* flex 항목 기본 shrink 를 끄지 않으면 카드가 많아질 때 스크롤 대신 납작해진다 */
  flex: 0 0 auto;
  margin: 0;
  padding: 10px 12px;
  font-size: 13px;
  cursor: grab;
}
#source-rail:empty::after {
  content: '미배정 소스가 없습니다';
  color: var(--muted);
  font-size: 12px;
  padding: 8px;
}

/* 지도 밖에 있는 미배정 장소도 감추지 않고 구분선 아래에 흐리게 남긴다 */
.rail-divider {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 6px;
  color: var(--muted); font-size: 11px;
  padding-top: 4px;
}
.rail-divider::after {
  content: ''; flex: 1;
  border-top: 1px solid var(--border);
}
#source-rail .source-card--outside { opacity: .55; }

#timetable-scroll {
  flex: 1;
  overflow-y: auto;
  background: var(--surface);
  border-radius: var(--radius);
  border: 1px solid var(--border);
}

#timetable {
  position: relative;
  /* 48슬롯(04:00~28:00) × 슬롯 높이 */
  height: calc(48 * var(--slot-h));
}

.hour-line {
  position: absolute; left: 0; right: 0;
  border-top: 1px solid var(--border);
  font-size: 11px; color: var(--muted);
  padding-left: 4px;
  pointer-events: none;
}

/* 시간 라벨(40px) 오른쪽이 블록 영역이다 */
#blocks { position: absolute; inset: 0; margin-left: 40px; }

.tt-block {
  position: absolute;
  border-radius: var(--radius-sm);
  padding: 3px 6px;
  font-size: 11px; line-height: 1.3;
  color: var(--on-accent);
  overflow: hidden;
  border-left: 4px solid transparent;
  cursor: grab;
}
.tt-block--food { background: var(--food); }
.tt-block--attraction { background: var(--attraction); }
.tt-block--waypoint { background: var(--waypoint); }
.tt-block--reserved { border-left-color: var(--on-accent); }

#drop-preview {
  position: absolute; left: 40px; right: 0;
  background: var(--primary);
  opacity: .35;
  border-radius: var(--radius-sm);
  pointer-events: none;
  font-size: 11px; color: var(--on-accent); padding: 2px 6px;
}

/* ============================================================
   계획 보기 (읽기 전용) — 소스 레일이 없어 타임테이블이 폭을 다 쓴다
   ============================================================ */
#day-timetable-scroll {
  flex: 1;
  overflow-y: auto;
  background: var(--surface);
  border-radius: var(--radius);
  border: 1px solid var(--border);
  margin: 0 8px 8px;
  min-height: 0;
}
#day-timetable {
  position: relative;
  height: calc(48 * var(--slot-h));
}
#day-blocks { position: absolute; inset: 0; margin-left: 40px; }
#day-blocks .tt-block { cursor: pointer; font-size: 12px; padding: 4px 8px; }

/* ============================================================
   참고사항 (접힘/펼침)
   ============================================================ */
.daynote { padding: 0; overflow: hidden; }

.daynote__header {
  width: 100%; min-height: 44px;
  display: flex; align-items: center; gap: 8px;
  padding: 0 16px;
  background: transparent; border: 0;
  color: var(--text); font: inherit; font-size: 14px;
  text-align: left; cursor: pointer;
}
.daynote__preview {
  flex: 1;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.daynote__caret { margin-left: auto; }
.daynote__dirty { color: var(--primary); font-size: 10px; }

.daynote__text { margin: 0 16px; width: calc(100% - 32px); }
.daynote__read { margin: 0 16px 14px; white-space: pre-wrap; }

/* 저장 버튼을 전체 폭으로 두면 그 날 메모가 아니라 전체 계획을 저장하는 것처럼 보인다.
   내용 폭으로 오른쪽에 붙인다. */
.daynote__actions {
  display: flex; justify-content: flex-end;
  padding: 8px 16px 14px;
}
.daynote__save { min-height: 36px; padding: 0 20px; font-size: 14px; }

/* ---- 하단 탭바 ---- */
footer {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 5;
  background: var(--surface);
  border-top: 1px solid var(--border);
  padding-bottom: env(safe-area-inset-bottom);
}
footer nav { display: flex; }
footer nav a {
  flex: 1; min-height: var(--tabbar-h);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px;
  text-decoration: none; color: var(--muted); font-size: 11px;
}
footer nav a.active { color: var(--primary); font-weight: 600; }

/* 양 끝 화살표는 이웃 섹션으로 간다. footer nav a 의 flex:1 을 그대로 두면
   화살표가 탭만큼 넓어져 탭 이름이 눌린다. */
.nav-arrow {
  flex: 0 0 32px;
  display: flex; align-items: center; justify-content: center;
  min-height: var(--tabbar-h);
  color: var(--muted); font-size: 22px; line-height: 1;
  text-decoration: none;
}
/* 끝 섹션에는 갈 곳이 없다. <span> 이라 눌리지 않지만 자리는 남겨야
   탭 위치가 섹션을 옮길 때마다 좌우로 흔들리지 않는다. */
.nav-arrow--off { opacity: .25; }

/* ---- 지도가 없는 섹션(예산·체크리스트)의 본문 ---- */
/* 셸은 지도 위에 시트를 덮지만 여기는 덮을 게 없다. 탭바 높이만 남기고 화면을 채운다. */
.section-body {
  position: fixed; inset: 0;
  bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom));
  display: flex; flex-direction: column;
}

/* ============================================================
   예산
   ============================================================ */
.budget-rate { display: flex; flex-direction: column; }
.budget-rate label { margin-top: 0; }
.budget-rate__row { display: flex; align-items: center; gap: 8px; }
/* 환율은 네 자리면 충분하다. 전체 폭으로 늘리면 입력칸만 덩그러니 커 보인다. */
.budget-rate__row input { width: 100px; }

.budget-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.budget-table th,
.budget-table td {
  padding: 8px 4px;
  border-bottom: 1px solid var(--border);
  text-align: left; vertical-align: top;
  font-weight: 400;
}
.budget-table thead th { color: var(--muted); font-size: 12px; }
/* 숫자는 오른쪽으로 맞춰야 자릿수를 눈으로 비교할 수 있다 */
.budget-table .num { text-align: right; white-space: nowrap; }
.budget-table tfoot th,
.budget-table tfoot td { font-weight: 700; border-bottom: 0; }
.budget-converted { margin: 12px 0 0; }

.budget-group__head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 8px; flex-wrap: wrap;
  font-size: 15px;
  margin: 16px 16px 4px;
}
.budget-card__head { margin-bottom: 4px; }
.budget-card__meta { display: flex; align-items: center; gap: 8px; }
.budget-card__amount {
  display: flex; align-items: baseline; gap: 10px;
  margin-top: 6px;
}
.budget-card__memo { margin: 6px 0 0; white-space: pre-wrap; }

.budget-chart { display: flex; flex-direction: column; align-items: center; gap: 12px; }
.donut { width: 160px; height: 160px; }
.donut__label { fill: var(--text); font-size: 15px; font-weight: 700; }

.donut-legend {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 6px 12px;
  font-size: 12px; color: var(--muted);
}
.donut-legend__item { display: inline-flex; align-items: center; gap: 5px; }
.donut-legend__dot { width: 9px; height: 9px; border-radius: 50%; }

/* 카드를 누르면 편집 시트가 열린다는 걸 손끝에 알린다 */
.budget-card { cursor: pointer; }

.budget-amount { display: flex; align-items: center; gap: 12px; }
.budget-amount__currency { display: flex; gap: 12px; flex: 0 0 auto; }
.budget-amount input { flex: 1 1 auto; }
#budgetPerPerson { margin: 6px 0 0; }

/* ---- 로그인 ---- */
/* body 가 100dvh/overflow:hidden 이므로 그 안에서 가운데로만 잡으면 된다 */
.auth-page {
  height: 100%;
  display: flex; align-items: center; justify-content: center;
  padding: 16px;
}
.auth-card {
  width: 100%; max-width: 320px;
  background: var(--surface);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 24px 20px;
}
.auth-title { font-size: 20px; margin: 0 0 20px; text-align: center; }
.auth-error { color: var(--danger); font-size: 14px; margin: 8px 0 0; }
.auth-submit { width: 100%; margin-top: 20px; }
