@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@300;400;500;600;700;800;900&display=swap');

:root {
  --paper: #ECEEF5;
  --surface: #FFFFFF;
  --surface-2: #F5F5F8;
  --ink: #1A1B2E;
  --ink-soft: #8B8FA8;
  --ink-faint: #9CA3AF;
  --line: #F0F0F6;
  --line-strong: #E4E6F0;

  /* khroma-palette.css 여러 조합을 역할별로 다르게 적용 (2026-09-26, color-update
     브랜치, 2차 시도) - "붉은 계열 메인 + 다양한 조합"으로 재요청받아 blue(namvit)
     단일 교체 대신 아래처럼 팔레트 5가지를 서로 다른 역할에 나눠 썼다:
     - accent(메인): radical-red - 붉은 계열
     - teal(보조/완료): java - 기존 민트 자리를 대체할 흰 텍스트 안전 청록
     - amber(강조): corn - 따뜻한 골드 옐로우
     - sat(정보용 파랑): persian-blue - 메인(빨강)과 뚜렷이 구분되는 포인트
     - plum/sun(마감·일요일·미룸 표시): sea-buckthorn - 기존에 좋아했던 주황을
       메인 자리 대신 상태 표시색으로 남겨둠 */
  --accent: #EF4060;
  --accent-strong: #C8294A;
  --accent-soft: #FDEAEF;
  --accent-ink: #7A1830;

  --teal: #1FCBA3;
  --teal-soft: #E1FBF4;
  --slate: #9CA3AF;
  --slate-soft: #F5F5F8;
  --plum: #F2A93C;
  --plum-soft: #FDF1DF;
  --gray: #C0C4D4;
  --gray-soft: #F5F5F8;
  --amber: #F2B705;
  --amber-soft: #FFF8DE;
  --amber-ink: #7A5C04;

  --sat: #2A3FA0;
  --sat-soft: #E7E9F7;
  --sun: #F2A93C;
  --sun-soft: #FDF1DF;

  --shadow-card: 0 1px 2px rgba(26, 27, 46, 0.04), 0 10px 26px -14px rgba(26, 27, 46, 0.14);
  --shadow-lift: 0 20px 45px -20px rgba(26, 27, 46, 0.28);
  --radius: 16px;
  --radius-sm: 10px;
  --radius-lg: 20px;
  --nav-w: 96px;
}

* { box-sizing: border-box; }
html { color-scheme: light; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: 'Noto Sans KR', -apple-system, BlinkMacSystemFont, 'Malgun Gothic', sans-serif;
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, p { margin: 0; }
button { font-family: inherit; }
input, select, textarea { font-family: inherit; font-size: inherit; color: inherit; }
.tabular { font-variant-numeric: tabular-nums; }

/* ---------- App shell ---------- */
.app {
  min-height: 100vh;
  display: flex;
}
.sidenav {
  width: var(--nav-w);
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 22px 0;
  background: var(--surface);
  border-right: 1px solid var(--line);
  position: fixed;
  top: 0; bottom: 0; left: 0;
}
.sidenav-top {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  margin-bottom: 20px;
}
.home-btn {
  display: flex; align-items: center; justify-content: center;
  width: 40px; height: 40px;
  border-radius: 13px;
  background: linear-gradient(135deg, var(--accent), #FF7A8C);
  color: #fff;
  text-decoration: none;
  box-shadow: 0 4px 12px rgba(239, 64, 96, 0.35);
  transition: transform .15s ease;
}
.home-btn:hover { transform: translateY(-1px); }
.brand {
  display: block;
  font-weight: 800;
  font-size: 0.98rem;
  letter-spacing: -0.02em;
  text-align: center;
  color: var(--ink);
  text-decoration: none;
}
.navlink {
  width: 72px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 11px 4px 10px;
  border-radius: var(--radius-sm);
  color: var(--ink-faint);
  text-decoration: none;
  font-size: 0.74rem;
  font-weight: 600;
  transition: color .15s ease, background .15s ease;
}
.navlink:hover { color: var(--ink-soft); background: var(--surface-2); }
.navlink.active { color: var(--accent-strong); background: var(--accent-soft); }
.navlink .icon { display: block; }

.main {
  flex: 1;
  margin-left: var(--nav-w);
  padding: 28px clamp(16px, 4vw, 44px) 100px;
  max-width: 1040px;
}

.bottomnav { display: none; }
.mobile-topbar { display: none; }

@media (max-width: 760px) {
  .sidenav { display: none; }
  /* 상단 오른쪽에 뜨는 .mobile-topbar(홈 아이콘)와 겹치지 않도록 위쪽 여백을
     넉넉히 둔다 - 보상 메뉴 유무와 상관없이 홈은 항상 여기 고정된다. */
  .main { margin-left: 0; padding: 54px 14px 90px; }
  .mobile-topbar {
    display: flex;
    position: fixed;
    top: calc(10px + env(safe-area-inset-top, 0px));
    right: 12px;
    z-index: 41;
  }
  /* 페이지마다 배경이 연한 라벤더색이거나 진한 분홍 히어로 카드거나 달라서, 배경과
     비슷한 톤(흰색+옅은 테두리 등)은 어느 한쪽에서 거의 안 보인다 - 항상 뚜렷하게
     보이도록 진한 남색 배경 + 흰 아이콘으로 대비를 확실히 준다. */
  .mobile-topbar-home {
    display: flex; align-items: center; justify-content: center;
    width: 34px; height: 34px;
    border-radius: 11px;
    background: var(--ink);
    color: #fff;
    text-decoration: none;
    box-shadow: 0 4px 12px rgba(26, 27, 46, 0.35);
  }
  .bottomnav {
    display: flex;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    background: var(--surface);
    border-top: 1px solid var(--line);
    padding: 6px 4px calc(6px + env(safe-area-inset-bottom));
    z-index: 40;
  }
  .bottomnav .navlink { flex: 1; width: auto; }
  .week-page-head { display: flex; justify-content: space-between; }
  .week-page-head > *:last-child { justify-self: auto; }
}

/* ---------- 이동 안내 배너 (기존 주소에만 뜬다 - js/site-banner.js) ----------
   사이드바/모바일 상단 홈 아이콘이 둘 다 position:fixed라 배너 실제 높이만큼
   --site-banner-h로 같이 밀어내야 한다(js가 렌더 후 값을 채운다). */
.site-banner {
  position: fixed; top: 0; left: 0; right: 0; z-index: 50;
  background: var(--ink); color: #fff;
  padding: 10px 14px; padding-top: calc(10px + env(safe-area-inset-top, 0px));
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 6px 14px; font-size: 0.82rem; line-height: 1.5; text-align: center;
}
.site-banner-body { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 4px 10px; }
.site-banner a { color: #fff; text-decoration: underline; font-weight: 700; }
.site-banner-migrate { color: rgba(255, 255, 255, 0.78); }
.site-banner-actions { display: flex; align-items: center; gap: 8px; }
.site-banner-close {
  width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, 0.14); color: #fff; border: none;
  font-size: 1rem; line-height: 1; cursor: pointer;
}
body.has-site-banner .sidenav { top: var(--site-banner-h, 0px); }
body.has-site-banner .main { padding-top: calc(28px + var(--site-banner-h, 0px)); }
@media (max-width: 760px) {
  body.has-site-banner .mobile-topbar { top: calc(var(--site-banner-h, 0px) + 10px + env(safe-area-inset-top, 0px)); }
  body.has-site-banner .main { padding-top: calc(54px + var(--site-banner-h, 0px)); }
}

/* ---------- Page header ---------- */
.page-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 18px;
  flex-wrap: wrap;
}
.page-head h1 { font-size: 1.3rem; font-weight: 800; letter-spacing: -0.01em; }
.page-head .sub { color: var(--ink-soft); font-size: 0.86rem; margin-top: 2px; }
/* 주간 페이지: 이전/이번주/다음/인쇄 버튼 묶음을 제목 폭과 상관없이 줄 한가운데로 놓는다. */
.week-page-head { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; }
.week-page-head > *:first-child { justify-self: start; }
.week-page-head > *:last-child { justify-self: center; }
.clock-live { font-size: 1.1rem; font-weight: 700; color: var(--ink-soft); }
.today-page-head h1 { font-size: 1.8rem; }
.today-head-actions { display: flex; align-items: center; gap: 10px; }
.avatar-chip {
  display: flex; align-items: center; gap: 9px;
  padding: 0 12px 0 6px; height: 44px; border-radius: 12px;
  background: var(--surface); border: 1px solid var(--line-strong);
  cursor: pointer; color: var(--ink);
}
.avatar-chip-img {
  width: 32px; height: 32px; border-radius: 50%; flex-shrink: 0;
  background: var(--amber-soft); overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.avatar-chip-img img { width: 100%; height: 100%; object-fit: cover; }
.avatar-chip-name { font-size: 0.9rem; font-weight: 700; }
@media (max-width: 640px) { .avatar-chip-name, .avatar-chip svg { display: none; } .avatar-chip { padding-right: 6px; } }

/* ---------- Buttons ---------- */
.btn {
  appearance: none;
  border: 1px solid transparent;
  border-radius: 9px;
  padding: 12px 20px;
  font-weight: 700;
  font-size: 0.92rem;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  transition: transform .1s ease, filter .15s ease, background .15s ease;
  min-height: 46px;
  white-space: nowrap;
  flex-shrink: 0;
}
.btn:active { transform: scale(0.97); }
.btn-primary { background: var(--accent); color: #fff; box-shadow: 0 10px 22px -10px rgba(239, 64, 96, 0.55); }
.btn-primary:hover { background: var(--accent-strong); filter: none; }
.btn-ghost { background: var(--surface); border-color: var(--line-strong); color: var(--ink); }
.btn-ghost:hover { background: var(--surface-2); border-color: var(--ink-faint); }
.btn-quiet { background: transparent; color: var(--ink-soft); }
.btn-quiet:hover { color: var(--ink); }
.btn-sm { padding: 8px 14px; min-height: 36px; font-size: 0.82rem; }
.btn-block { width: 100%; }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }

.iconbtn {
  width: 40px; height: 40px; border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--ink-soft);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
}
.iconbtn:hover { color: var(--ink); }

/* ---------- Today: hero focus panel ---------- */
.hero-stats-row { display: grid; grid-template-columns: 3fr 2fr; gap: 14px; align-items: stretch; margin-bottom: 14px; }
@media (max-width: 900px) { .hero-stats-row { grid-template-columns: 1fr; } }

.hero {
  border-radius: var(--radius-lg);
  padding: 22px 24px 20px;
  position: relative;
  overflow: hidden;
  color: var(--accent-ink);
  background: linear-gradient(150deg, #FFF0F2 0%, #FFD3DA 50%, #FFACBA 100%);
  box-shadow: var(--shadow-card);
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 220px;
}
.hero-illust {
  position: absolute; right: 0; bottom: calc(20px);
  width: 60%; height: 100%;
  object-fit: contain; object-position: right bottom;
  pointer-events: none; user-select: none; z-index: 0;
}
/* 좁은 화면에서는 카드가 세로로 길어져서 height:100%를 그대로 두면 그림이 위아래로
   눌린다. 폭 기준 자연 비율로 키우고 아래쪽에 붙인다 - 맨 아래 "다음 일정" 흰 띠가
   z-index로 그림 위에 뜨니(.hero-next) 그림 아랫부분이 살짝 가려지는 건 괜찮지만,
   38%는 카드에 비해 너무 작아 휑해 보였다 - 55%로 키워서 카드와 더 조화롭게 채운다.
   글자 칸(.hero-content)은 그대로 두고(줄여서 글자가 이상하게 줄바꿈되는 문제가
   있었다) 그림이 글자보다 뒤(z-index:0)에서 겹치게만 둔다. */
@media (max-width: 520px) {
  .hero-illust { width: 55%; height: auto; top: auto; bottom: 6px; right: 4px; }
}
.hero-content { position: relative; z-index: 2; max-width: 55%; display: flex; flex-direction: column; gap: 10px; }
@media (max-width: 520px) { .hero-content { max-width: 64%; } }

.hero-eyebrow-row { display: flex; align-items: center; gap: 9px; }
.hero-eyebrow {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--accent-strong); color: #fff;
  font-size: 0.76rem; font-weight: 700; padding: 4px 12px; border-radius: 20px;
  box-shadow: 0 2px 8px rgba(200, 41, 74, 0.4);
}
.hero-eyebrow::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: rgba(255, 255, 255, 0.85); }
.hero-eyebrow .tflag { background: rgba(255, 255, 255, 0.3); color: #fff; margin-left: 2px; }
.hero-clock { font-size: 1rem; font-weight: 700; color: var(--accent-ink); opacity: 0.75; }

.hero-title-row { display: flex; align-items: center; gap: 12px; }
.hero-icon {
  width: 50px; height: 50px; border-radius: 14px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.5rem; line-height: 1;
  background: rgba(255, 255, 255, 0.9);
  box-shadow: 0 3px 10px rgba(200, 41, 74, 0.15);
}
.hero-title { font-size: clamp(1.2rem, 3.2vw, 1.55rem); font-weight: 900; letter-spacing: -0.03em; color: var(--ink); line-height: 1.2; }
.hero-meta { margin-top: 3px; font-size: 0.78rem; font-weight: 600; opacity: 0.7; }
.hero-timer { font-size: clamp(1.7rem, 6vw, 2.6rem); font-weight: 900; letter-spacing: -0.04em; color: var(--ink); line-height: 1; }
.hero-timer span { font-size: 0.92rem; font-weight: 700; opacity: 0.7; margin-left: 5px; }
.hero-actions { display: flex; gap: 10px; margin-top: 4px; flex-wrap: wrap; }
.hero-actions .btn { flex: 1; min-width: 108px; }
.hero-complete-btn { margin-top: 2px; display: flex; align-items: center; justify-content: center; gap: 6px; }
.hero-complete-btn.is-done { background: rgba(255, 255, 255, 0.85); color: var(--accent-strong); }
.hero-empty { padding: 20px 0 4px; position: relative; z-index: 2; }
.hero-empty .hero-title { font-size: 1.3rem; margin-top: 6px; }
.hero-next {
  position: relative; z-index: 2;
  display: flex; align-items: center; gap: 12px;
  margin-top: auto;
  background: rgba(255, 255, 255, 0.85);
  border-radius: 14px;
  padding: 10px 16px;
  box-shadow: 0 2px 14px rgba(0, 0, 0, 0.1);
}
.hero-next-icon {
  width: 42px; height: 42px; border-radius: 12px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.05rem;
}
.hero-next-info { flex: 1; min-width: 0; }
.hero-next-label { font-size: 0.68rem; font-weight: 700; color: var(--accent-ink); opacity: 0.65; margin-bottom: 2px; }
.hero-next-title { font-weight: 800; color: var(--ink); font-size: 0.92rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hero-next-divider { width: 1px; align-self: stretch; background: rgba(0, 0, 0, 0.08); flex-shrink: 0; }
.hero-next-time-col { text-align: right; flex-shrink: 0; padding-left: 2px; }
.hero-next-time { font-size: 1.2rem; font-weight: 900; color: var(--ink); letter-spacing: -0.03em; line-height: 1; }
.hero-next-after { font-size: 0.68rem; color: var(--ink-faint); margin-top: 3px; }

/* ---------- Today: 지금 진행률 바 ---------- */
.hero-progress-label { font-size: 0.76rem; font-weight: 700; opacity: 0.75; margin-bottom: 5px; }
.hero-progress-track { height: 20px; background: rgba(0, 0, 0, 0.12); border-radius: 11px; overflow: hidden; position: relative; }
.hero-progress-fill {
  height: 100%; background: linear-gradient(90deg, var(--accent-strong), var(--accent));
  border-radius: 11px; display: flex; align-items: center; justify-content: flex-end;
  padding-right: 8px; min-width: 34px;
  box-shadow: 0 2px 8px rgba(200, 41, 74, 0.4);
  transition: width .4s ease;
}
.hero-progress-fill span { font-size: 0.7rem; font-weight: 900; color: #fff; white-space: nowrap; }

/* ---------- Today: 오른쪽 통계 2x2 + 오늘 할 일 ---------- */
.hero-side { display: flex; flex-direction: column; gap: 10px; }
.stat-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; flex: 1; }
.stat-card {
  background: var(--surface); border-radius: var(--radius-sm);
  padding: 13px 14px; box-shadow: var(--shadow-card);
  display: flex; align-items: center; gap: 11px;
}
.stat-card-icon {
  width: 38px; height: 38px; border-radius: 11px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
}
.stat-card-value { font-size: 1.15rem; font-weight: 900; color: var(--ink); letter-spacing: -0.02em; line-height: 1; }
.stat-card-label { font-size: 0.68rem; color: var(--ink-soft); font-weight: 600; margin-top: 3px; }

.quicktodo-card { background: var(--surface); border-radius: var(--radius-sm); padding: 13px 14px; box-shadow: var(--shadow-card); }
.quicktodo-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.quicktodo-title { font-size: 0.82rem; font-weight: 700; color: var(--ink); }
.quicktodo-count { font-size: 0.68rem; color: var(--ink-faint); margin-top: 2px; }
.quicktodo-add-btn {
  display: flex; align-items: center; gap: 3px;
  font-size: 0.72rem; font-weight: 700; color: var(--accent);
  background: var(--accent-soft); border: none; padding: 5px 9px; border-radius: 8px; cursor: pointer;
}
.quicktodo-progress { height: 3px; background: var(--line); border-radius: 3px; overflow: hidden; margin-bottom: 10px; }
.quicktodo-progress-fill { height: 100%; background: var(--accent); border-radius: 3px; transition: width .2s; }
.quicktodo-list { display: flex; flex-direction: column; gap: 8px; }
.quicktodo-row { display: flex; align-items: center; gap: 9px; }
.quicktodo-check {
  width: 18px; height: 18px; border-radius: 5px; flex-shrink: 0; padding: 0;
  border: 1.5px solid var(--line-strong); background: transparent;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.quicktodo-check.is-done { border-color: var(--tag-color, var(--accent)); background: var(--tag-color, var(--accent)); color: #fff; }
.quicktodo-text { flex: 1; font-size: 0.8rem; font-weight: 500; color: var(--ink); cursor: pointer; }
.quicktodo-row.is-done .quicktodo-text { color: var(--ink-faint); text-decoration: line-through; }
.quicktodo-tag { font-size: 0.64rem; font-weight: 700; padding: 2px 7px; border-radius: 6px; flex-shrink: 0; }
.quicktodo-del { flex-shrink: 0; width: 22px; height: 22px; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: var(--ink-faint); background: none; border: none; cursor: pointer; }
.quicktodo-del:hover { color: var(--plum); background: var(--plum-soft); }
.quicktodo-empty { font-size: 0.78rem; color: var(--ink-faint); padding: 6px 0; text-align: center; }

/* ---------- Today: 10일 날짜 스트립 ---------- */
.date-strip { background: var(--surface); border-radius: var(--radius-lg); padding: 14px 18px; box-shadow: var(--shadow-card); margin-bottom: 14px; }
.date-strip-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.date-strip-eyebrow { font-size: 0.68rem; font-weight: 600; color: var(--ink-soft); margin-bottom: 1px; }
.date-strip-title { font-size: 0.92rem; font-weight: 800; color: var(--ink); letter-spacing: -0.02em; }
.date-strip-nav { display: flex; gap: 5px; }
.date-strip-nav button {
  width: 30px; height: 30px; border-radius: 7px; background: var(--surface-2); border: none;
  display: flex; align-items: center; justify-content: center; color: var(--ink-soft); cursor: pointer;
}
.date-strip-days { display: grid; grid-template-columns: repeat(10, minmax(0, 1fr)); gap: 6px; }
.date-strip-day {
  min-width: 0; padding: 8px 4px; border-radius: 7px; background: var(--surface-2); border: none; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 3px; color: var(--ink);
}
.date-strip-day span:first-child { font-size: 0.68rem; font-weight: 600; opacity: 0.8; }
.date-strip-day span:last-child { font-size: 1.05rem; font-weight: 800; line-height: 1; }
.date-strip-day.is-sun { color: var(--sun); }
.date-strip-day.is-sat { color: var(--accent); }
.date-strip-day.is-today { background: var(--accent); color: #fff; }
/* 오늘이 아닌 다른 날짜의 흐름을 보는 중이면 채우지 않고 테두리로만 표시한다 -
   box-shadow라 레이아웃(칸 크기)은 그대로 유지된다. */
.date-strip-day.is-viewing:not(.is-today) { box-shadow: inset 0 0 0 2px var(--accent); color: var(--accent-strong); }
@media (max-width: 640px) {
  .date-strip { padding: 12px 12px; }
  .date-strip-days { gap: 3px; }
  .date-strip-day { padding: 7px 1px; }
  .date-strip-day span:first-child { font-size: 0.6rem; }
  .date-strip-day span:last-child { font-size: 0.94rem; }
}

/* ---------- 실행 가능성 경고 배너 ---------- */
.feasibility-banner {
  display: flex; align-items: flex-start; gap: 12px;
  background: var(--amber-soft); color: var(--amber-ink);
  border: 1px solid rgba(245, 166, 35, 0.35);
  border-radius: var(--radius-sm);
  padding: 14px 16px;
  margin-bottom: 18px;
  font-size: 0.86rem;
}
.feasibility-banner svg { flex-shrink: 0; margin-top: 1px; }
.feasibility-banner b { display: block; margin-bottom: 3px; font-size: 0.92rem; }

/* ---------- 오늘의 흐름 카드 (미니 개요 바 + 타임라인) ---------- */
.timeline-card { background: var(--surface); border-radius: var(--radius-lg); padding: 18px 0 4px; box-shadow: var(--shadow-card); overflow: hidden; }
.timeline-card-head { display: flex; align-items: center; justify-content: space-between; padding: 0 20px; margin-bottom: 14px; flex-wrap: wrap; gap: 10px; }
.timeline-card-head .section-title { font-size: 0.95rem; margin-bottom: 0; }
.timeline-card-controls { display: flex; align-items: center; gap: 14px; }

/* ---------- Day bar (지금 앞뒤 5시간 창 + 하루 전체 미니맵) ----------
   하루 전체(06:00~23:00)를 좁은 화면 하나에 다 넣으면 일정이 몇 px짜리 조각이
   되어 안 보였다 - 그래서 지금(또는 골라둔 시각) 앞뒤 5시간만 크게 보여주고,
   화살표/미니맵으로 다른 시간대까지 옮겨보게 한다(js의 renderDaybar 참고). */
.daybar-wrap { padding: 0 20px; margin-bottom: 16px; }
.daybar-window-head { display: flex; align-items: center; justify-content: center; gap: 10px; margin-bottom: 6px; }
.daybar-nav-btn {
  width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0;
  border: 1px solid var(--line-strong); background: var(--surface); color: var(--ink-soft);
  display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.daybar-nav-btn:disabled { opacity: .35; cursor: default; }
.daybar-range { font-size: 0.78rem; font-weight: 700; color: var(--ink-soft); }
.daybar-scale { display: flex; justify-content: space-between; font-size: 0.66rem; color: var(--ink-faint); font-weight: 500; margin-bottom: 4px; }
.daybar {
  position: relative;
  height: 42px;
  border-radius: 999px;
  background: var(--surface-2);
  overflow: visible;
}
.daybar-seg {
  position: absolute; top: 4px; bottom: 4px; border-radius: 999px;
  display: flex; align-items: center; justify-content: center; min-width: 30px;
  overflow: hidden;
}
.daybar-seg span { font-size: 0.74rem; font-weight: 700; color: #fff; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding: 0 8px; }
/* 배경색은 이제 각 일정 고유 카테고리 색(js의 categoryColorOf, 인라인 style로 지정)을
   그대로 쓴다 - 상태별 클래스는 그 위에 얹는 표시(지금 진행 중 강조, 미룸/건너뜀
   흐리게)만 담당한다. */
.daybar-seg.now { box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--ink); }
.daybar-seg.postponed { opacity: .55; }
.daybar-seg.skipped { opacity: .6; }
.daybar-now-mark {
  position: absolute; top: -2px; bottom: -2px; width: 0;
  border-left: 1px dashed var(--ink);
}
/* 지금 보는 5시간 창이 하루 중 어디쯤인지 보여주는 미니맵 - 딱딱한 테두리 박스
   대신 옅은 배경 톤(창 영역)과 점 밝기 차이(창 밖은 흐리게)만으로 표시한다. */
.daybar-minimap { position: relative; height: 14px; margin-top: 10px; background: var(--surface-2); border-radius: 999px; cursor: pointer; }
.daybar-mini-window { position: absolute; top: 0; bottom: 0; background: var(--accent-soft); border-radius: 999px; }
.daybar-mini-item { position: absolute; top: 4px; bottom: 4px; border-radius: 999px; opacity: .32; }
.daybar-mini-item.in-window { opacity: 1; }

/* ---------- Today: 2x2 통계는 .stat-grid/.stat-card (위쪽 정의) 참고 ---------- */

/* ---------- Timeline (spine list) ---------- */
.timeline { border-top: 1px solid var(--line); padding: 0 20px; }
@media (max-width: 640px) { .timeline { padding: 0 14px; } }
.trow {
  display: grid;
  grid-template-columns: 92px 22px 1fr;
  gap: 6px;
  align-items: flex-start;
}
@media (max-width: 640px) { .trow { grid-template-columns: 78px 22px 1fr; } }
.trow .tspine { position: relative; display: flex; justify-content: center; align-self: stretch; }
.trow .tspine::before {
  content: '';
  position: absolute; top: -1px; bottom: -1px; left: 50%;
  width: 2px; background: var(--line-strong); transform: translateX(-50%);
}
.trow:first-child .tspine::before { top: 50%; }
.trow:last-child .tspine::before { bottom: calc(100% - 50%); }
.trow .tdot {
  position: relative; z-index: 1;
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--gray);
  margin-top: 15px;
  border: 3px solid var(--paper);
}
.trow.status-done .tdot { background: var(--teal); }
.trow.status-in_progress .tdot, .trow.status-paused .tdot, .trow.is-now .tdot { background: var(--accent); width: 14px; height: 14px; margin-top: 13.5px; box-shadow: 0 0 0 5px var(--accent-soft); }
.trow.status-postponed .tdot { background: var(--plum); }
.trow.status-skipped .tdot { background: var(--gray); }
.trow .ttime { font-size: 0.72rem; font-weight: 700; color: var(--ink); letter-spacing: -0.02em; padding-top: 14px; text-align: right; white-space: nowrap; }
@media (max-width: 640px) { .trow .ttime { font-size: 0.66rem; } }
.trow .tbody {
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  margin-bottom: 3px;
  border: 1px solid transparent;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  min-height: 20px;
}
.trow.status-in_progress .tbody, .trow.status-paused .tbody, .trow.is-now .tbody {
  background: var(--accent-soft);
  border-color: rgba(239, 64, 96, 0.30);
}
/* 아이콘과 오른쪽 액션 사이의 제목/부제 칸 - flex 기본 최소폭(auto)을 그대로 두면
   좁은 화면에서 옆 요소들에 밀려 한 글자씩 세로로 쪼개지므로 min-width:0으로
   줄여도 되게 풀어준다. */
.trow-main { flex: 1 1 90px; min-width: 90px; }
.trow .temoji {
  width: 38px; height: 38px; border-radius: 11px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.1rem; background: var(--surface-2);
}
.trow .ttitle { font-weight: 700; font-size: 0.94rem; }
.trow .tsub { font-size: 0.76rem; color: var(--ink-soft); margin-top: 1px; }
.trow.status-done .ttitle { color: var(--ink-soft); text-decoration: line-through; text-decoration-color: var(--line-strong); }
.trow.status-skipped .ttitle, .trow.status-postponed .ttitle { color: var(--ink-faint); }
.trow .tflag { font-size: 0.72rem; font-weight: 700; padding: 3px 9px; border-radius: 999px; white-space: nowrap; }
.trow.status-done .tflag { background: var(--teal-soft); color: var(--teal); }
.trow.status-postponed .tflag { background: var(--plum-soft); color: var(--plum); }
.trow.status-skipped .tflag { background: var(--gray-soft); color: var(--ink-faint); }
/* 완료 체크 버튼 + 상태 배지 + 순서 화살표를 한데 묶어 행 오른쪽 끝에 붙인다 -
   여러 요소가 각자 margin-left:auto를 쓰면 서로 밀어내는 폭이 꼬이기 쉬워서 묶었다. */
.trow-trailing { margin-left: auto; display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.check-btn {
  width: 30px; height: 30px; border-radius: 999px; flex-shrink: 0; padding: 0;
  display: flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--line-strong); background: var(--surface); color: var(--ink-faint);
}
.check-btn:hover { border-color: var(--teal); color: var(--teal); }
.check-btn.is-done { background: var(--teal); border-color: var(--teal); color: #fff; }
.trow.kind-protected .tbody, .trow.kind-free .tbody, .trow.kind-freetime .tbody { opacity: 0.72; }
.trow.kind-protected .ttitle, .trow.kind-free .ttitle, .trow.kind-freetime .ttitle { font-weight: 600; font-size: 0.86rem; }
/* 아무도 안 정한 빈 시간 - 옅은 안내문구로만 보여주고, 아직 안 지난 구간이면 눌러서
   바로 자유시간으로 정할 수 있게 한다. */
.trow.is-empty-slot .tbody { opacity: 0.7; }
.trow.is-empty-slot .ttitle-empty { font-weight: 400; font-size: 0.86rem; color: var(--ink-faint); }
.empty-slot-actions { margin-left: auto; display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.empty-slot-actions .btn-sm { padding: 6px 10px; font-size: 0.78rem; min-height: 0; }
.empty-slot-actions .iconbtn { width: 26px; height: 26px; }

/* 오늘의 흐름 상단 "빈 시간 보기" 토글과 하단 "닫아둔 빈 시간" 안내 - 둘 다 목록
   자체와는 다른 옅은 톤으로 눈에 덜 띄게 둔다. */
.empty-gaps-toggle { display: flex; align-items: center; gap: 6px; font-size: 0.8rem; color: var(--ink-soft); cursor: pointer; }
.empty-gaps-toggle input { accent-color: var(--accent); }
.dismissed-gaps-note { margin-top: 10px; font-size: 0.78rem; color: var(--ink-faint); text-align: center; }

/* 왼쪽 손잡이: 드래그로 옮길 수 있는 항목(≡)과 고정이라 못 옮기는 항목(🔒)을 같은
   자리에서 구분해 보여준다. touch-action:none이 없으면 모바일에서 드래그 시작하려다
   페이지 스크롤과 부딪힌다. */
.drag-handle {
  flex-shrink: 0; width: 20px; text-align: center; color: var(--ink-faint);
  font-weight: 700; letter-spacing: -1px; cursor: grab; touch-action: none; user-select: none;
}
.drag-handle:active { cursor: grabbing; }
.lock-badge { flex-shrink: 0; width: 20px; text-align: center; opacity: 0.55; font-size: 0.85rem; }

/* 드래그 중인 행: 집어든 느낌을 주려고 살짝 띄우고 그림자를 준다. transform은
   onDragPointerMove가 손가락/마우스를 따라가도록 매 프레임 바꾼다. */
.trow.is-dragging {
  position: relative; z-index: 5; background: var(--surface);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-lift);
}
/* 드래그 중 놓을 수 있는 자리 표시 - 위/아래 중 어느 쪽에 끼워질지 선으로 보여준다. */
.trow.drop-target-before { box-shadow: inset 0 2px 0 var(--accent); }
.trow.drop-target-after { box-shadow: inset 0 -2px 0 var(--accent); }
/* 지금 드래그 중인 항목이 속하지 않은 구간(고정일정 벽 너머) - 여긴 놓을 수 없다는 걸
   흐리게 보여준다. */
.trow.drop-invalid { opacity: 0.35; }

/* ---------- Sections / cards (used sparingly: forms, settings groups) ---------- */
.section { margin-bottom: 30px; }
.section-title { font-size: 1.02rem; font-weight: 800; margin-bottom: 3px; }
.section-desc { font-size: 0.84rem; color: var(--ink-soft); margin-bottom: 14px; }
.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 18px;
}
.divider-list > * + * { border-top: 1px solid var(--line-strong); }

/* ---------- 접이식 섹션(설정 화면) ----------
   body-outer 높이를 열 때마다 JS가 재서(scrollHeight) 정확한 px로 트랜지션시키고,
   끝나면 다시 인라인 스타일을 지워 CSS 값(0 또는 auto)으로 돌린다(js/views/
   settings.js의 wireAccordion 참고). transitionend 하나만 믿지 않고 타이머로도
   한 번 더 정리한다 - 트랜지션 자체가 안 도는 상황(예: 탭이 화면에 그려지고 있지
   않을 때)에서도 결국 열리고 닫히게 하려는 안전장치다.
   prefers-reduced-motion: reduce면 트랜지션 없이 즉시 열리고 닫힌다(JS가
   matchMedia로 직접 분기해서 애초에 트랜지션을 안 건다 - "no-preference"일 때만
   여기 transition이 걸리는 것과 별개로, JS 쪽도 이중으로 확인한다). */
.accordion-section { border-bottom: 1px solid var(--line-strong); }
.accordion-section:first-child { border-top: 1px solid var(--line-strong); }
.accordion-header {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; padding: 16px 2px; background: none; border: none; cursor: pointer;
  text-align: left; color: var(--ink); font: inherit;
}
.accordion-title { font-size: 1rem; font-weight: 800; }
.accordion-summary { font-size: 0.8rem; color: var(--ink-soft); margin-top: 2px; font-weight: 500; }
.accordion-arrow { flex-shrink: 0; color: var(--ink-faint); display: flex; transform: rotate(0deg); }
.accordion-section.open .accordion-arrow { transform: rotate(90deg); }
.accordion-body-outer { height: 0; overflow: hidden; }
.accordion-section.open .accordion-body-outer { height: auto; }
.accordion-body-content { padding: 2px 2px 22px; }
@media (prefers-reduced-motion: no-preference) {
  .accordion-arrow { transition: transform 0.25s ease; }
  .accordion-body-outer { transition: height 0.25s ease; }
}

/* .row2(1fr 1fr 그리드)는 minmax(0,1fr)이 아니라서, 안에 든 내용(예: 시간 입력칸)이
   넓으면 그리드 칸이 줄어들길 거부하고 조상까지 밀어서 375px에서 가로 스크롤이
   생긴다(실제로 겪음 - 기본 시간 섹션의 기상/취침 시간 칸). .row2 자체는 다른
   화면에서도 널리 쓰는 기존 규칙이라 거기를 고치지 않고, 이 접이식 섹션 안에서만
   그리드 칸의 min-width를 0으로 풀어준다. */
.accordion-body-content .row2 > * { min-width: 0; }
/* min-width:0만으로는 320px 같은 아주 좁은 화면에서 시간 입력칸(<input type="time">)
   자체의 최소 렌더링 폭 때문에 여전히 넘친다 - .row2:has(.daypicker)가 이미 쓰는
   것과 같은 방식으로, 아주 좁을 때만 두 칸을 한 줄로 쌓는다. */
@media (max-width: 340px) {
  .accordion-body-content .row2:has(input[type="time"]) { grid-template-columns: 1fr; }
}

/* 버튼 2개를 같은 너비로 나란히 두되, 들어갈 자리가 없으면(각자 최소폭보다 좁으면)
   미디어 쿼리 없이 자동으로 위아래 꽉 찬 너비로 쌓인다: flex-wrap이 basis 합 기준으로
   줄바꿈을 결정하고, 줄에 혼자 남은 버튼은 flex-grow로 그 줄을 꽉 채우기 때문이다. */
.btn-row { display: flex; flex-wrap: wrap; gap: 8px; }
.btn-row > .btn { flex: 1 1 150px; }

/* ---------- Form elements ---------- */
.field { margin-bottom: 16px; }
.field label { display: block; font-size: 0.84rem; font-weight: 700; margin-bottom: 6px; color: var(--ink); }
.field .hint { font-size: 0.76rem; color: var(--ink-faint); margin-top: 5px; }
.input {
  width: 100%;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  border-radius: 10px;
  padding: 11px 12px;
  font-size: 0.95rem;
  color: var(--ink);
}
.input:focus, .btn:focus-visible, .navlink:focus-visible, .pill:focus-visible, .iconbtn:focus-visible {
  outline: 2px solid var(--accent-strong);
  outline-offset: 2px;
}
.row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.row3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
@media (max-width: 520px) { .row3 { grid-template-columns: 1fr; } }
/* .daypicker(요일 원형 칩 7개, 가로 스크롤/줄바꿈 없음)가 .row2의 절반 폭 칸에
   들어가면 칩이 줄어들지 않고 자기 최소 폭(38px*7+gap)을 그대로 요구해서, 좁은
   화면에서 그 칸이 넘치는 걸 넘어 페이지 전체가 옆으로 밀려버린다(주당 횟수 +
   가능한 요일 조합). 그 조합일 때만 세로로 쌓는다. */
@media (max-width: 640px) {
  .row2:has(.daypicker) { grid-template-columns: 1fr; }
}

.pillgroup { display: flex; gap: 8px; flex-wrap: wrap; }

/* ---------- 재사용 슬라이드 탭 (js/ui.js의 tabsSlideHtml/wireTabsSlide) ----------
   트랙(연한 배경) 안에서 활성 탭 위치로 인디케이터가 미끄러지는 세그먼트 컨트롤.
   탭 버튼은 flex:1로 트랙 폭을 균등하게 나눠 가지므로 탭이 몇 개든, 화면이
   좁아도 트랙 밖으로 삐져나가지 않는다. */
.tabs-slide {
  position: relative;
  display: flex;
  gap: 2px;
  background: var(--surface-2);
  border-radius: 9px;
  padding: 4px;
  margin-bottom: 18px;
}
.tabs-slide-indicator {
  position: absolute;
  top: 4px; bottom: 4px; left: 0;
  background: var(--accent);
  border-radius: 7px;
  box-shadow: 0 4px 10px -4px rgba(0, 0, 0, 0.25);
  transition: transform 0.3s cubic-bezier(0.34, 1.4, 0.64, 1), width 0.3s cubic-bezier(0.34, 1.4, 0.64, 1);
  z-index: 0;
}
.tabs-slide-btn {
  position: relative;
  z-index: 1;
  flex: 1;
  min-width: 0;
  border: none;
  background: transparent;
  padding: 9px 12px;
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--ink-soft);
  cursor: pointer;
  border-radius: 7px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  white-space: nowrap;
  transition: color 0.2s ease;
}
.tabs-slide-btn.active { color: #fff; }
.pill {
  border: 1px solid var(--line-strong);
  background: var(--surface);
  border-radius: 9px;
  padding: 9px 15px;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  color: var(--ink-soft);
}
.pill.active { background: var(--accent); color: #fff; border-color: var(--accent); }

.stepper { display: flex; align-items: center; gap: 8px; }
.stepper-btn {
  flex-shrink: 0;
  width: 38px;
  height: 38px;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  border-radius: 10px;
  font-size: 1.15rem;
  font-weight: 700;
  line-height: 1;
  color: var(--ink-soft);
  cursor: pointer;
}
.stepper-btn:active { background: var(--accent); color: #fff; border-color: var(--accent); }
.stepper-input { text-align: center; flex: 1; min-width: 0; }
.stepper-input::-webkit-inner-spin-button, .stepper-input::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }

/* ---------- Icon picker (일정/할일 아이콘 선택) ---------- */
.icon-picker { display: flex; flex-direction: column; gap: 10px; }
.icon-cat-tabs { display: flex; gap: 6px; overflow-x: auto; padding-bottom: 2px; }
.icon-cat-tabs::-webkit-scrollbar { display: none; }
.icat {
  flex-shrink: 0;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  border-radius: 9px;
  padding: 7px 13px;
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--ink-soft);
  cursor: pointer;
  white-space: nowrap;
}
.icat.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.icon-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(44px, 1fr)); gap: 8px; }
.icell {
  aspect-ratio: 1;
  min-height: 44px;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  border-radius: var(--radius-sm);
  display: flex; align-items: center; justify-content: center;
  font-size: 1.3rem;
  color: var(--ink-soft);
  cursor: pointer;
}
.icell:hover { background: var(--surface-2); }
.icell.active { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-strong); }
.icell[hidden] { display: none; }
.gicon-svg { display: block; width: 1em; height: 1em; }
.inline-gicon { display: inline-flex; vertical-align: -3px; }

.daypicker { display: flex; gap: 6px; }
.daypicker .dchip {
  width: 38px; height: 38px; border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  display: flex; align-items: center; justify-content: center;
  font-size: 0.8rem; font-weight: 700; color: var(--ink-soft);
  cursor: pointer;
}
.daypicker .dchip.active { background: var(--accent); color: #fff; border-color: var(--accent); }

/* ---------- 할일 등록/수정 (한 화면 폼) ---------- */
.goal-form .field { margin-bottom: 14px; }
.goal-form .field label { margin-bottom: 4px; }
.icon-suggest-row { display: flex; gap: 6px; flex-wrap: wrap; }
.icon-suggest-row .icell { width: 36px; height: 36px; min-height: 0; font-size: 1.05rem; flex-shrink: 0; }
.icon-suggest-row .icell-all { flex-direction: column; gap: 1px; font-size: 0.56rem; font-weight: 700; color: var(--ink-soft); }
.goal-form-collapsible-btn { font-size: 0.82rem; font-weight: 700; color: var(--accent); background: none; border: none; cursor: pointer; padding: 4px 0; }
/* 모달 자체의 좌우 패딩을 상쇄해 폭 전체로 퍼지는 하단 고정 바 - 스크롤해도 항상
   요약과 저장 버튼이 보이게 한다. */
.goal-form-summary-bar {
  position: sticky; bottom: 0; left: 0; right: 0;
  margin: 16px -22px -28px; padding: 12px 22px calc(12px + env(safe-area-inset-bottom, 0px));
  background: var(--surface); border-top: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 8px;
}
.goal-form-summary-text { font-size: 0.8rem; color: var(--ink-soft); text-align: center; }

/* ---------- Stat strip (할일 인포그래픽에서만 쓴다 - 오늘 화면은 .stat-grid/.stat-card) ---------- */
.statstrip {
  display: flex;
  margin-top: 18px;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.statstrip .stat { flex: 1; padding: 12px 6px; text-align: center; border-right: 1px solid var(--line); }
.statstrip .stat:last-child { border-right: none; }
.stat b { display: block; font-size: 1.2rem; font-weight: 800; }
.stat span { font-size: 0.72rem; color: var(--ink-soft); }

/* ---------- Goal infographic ---------- */
.goal-infographic {
  margin-bottom: 16px;
  border: none;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  padding: 24px 26px;
}
.goal-infographic .statstrip { margin-top: 0; border: none; padding: 0 0 18px; gap: 8px; }
.goal-infographic .statstrip .stat { border-right: 1px solid var(--line-strong); padding: 0 4px; }
.goal-infographic .statstrip .stat:last-child { border-right: none; }
.goal-infographic .stat b { font-size: 1.4rem; }
.priority-bar-wrap { border-top: 1px solid var(--line); padding-top: 18px; }
.priority-bar { display: flex; gap: 2px; height: 10px; border-radius: 999px; overflow: hidden; background: var(--surface); }
.priority-seg { height: 100%; }
/* must(꼭 해야 해요)는 원래 --plum(주황)을 썼는데 good(하면 좋아요)의 --amber(노란빛
   주황)와 색상환에서 너무 가까워 구분이 잘 안 됐다. must는 원색 계열(--accent, 빨강)로
   바꿔 good/optional과 뚜렷하게 갈라지게 한다. */
.priority-seg.must { background: var(--accent); }
.priority-seg.good { background: var(--amber); }
.priority-seg.optional { background: var(--slate); }
.priority-legend { display: flex; gap: 16px; flex-wrap: wrap; margin-top: 10px; font-size: 0.76rem; color: var(--ink-soft); }
.priority-legend .dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 5px; vertical-align: middle; }
.priority-legend .dot.must { background: var(--accent); }
.priority-legend .dot.good { background: var(--amber); }
.priority-legend .dot.optional { background: var(--slate); }
.category-summary { display: flex; gap: 16px; flex-wrap: wrap; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); font-size: 0.8rem; color: var(--ink-soft); }
.category-summary .category-chip { display: inline-flex; align-items: center; gap: 6px; }
.category-summary b { color: var(--ink); font-weight: 800; margin-left: 1px; }

/* ---------- Goal list ---------- */
.goal-row { display: flex; align-items: center; gap: 14px; padding: 14px 4px; flex-wrap: wrap; }
.goal-row .gicon {
  width: 42px; height: 42px; border-radius: 12px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.25rem;
  background: var(--accent-soft);
}
.goal-row .gcol { flex: 1; min-width: 0; }
/* 아이콘(42px) + 이름 칸(min-width:0이라 얼마든 줄어듦) + 우선순위 배지·수정·정지·삭제
   버튼 4개(flex-shrink:0, 절대 안 줄어듦)가 한 줄에 다 들어가야 하면, 좁은 화면에서는
   버튼들 폭만으로도 이름 칸이 몇 px로 짜부라져서 한글이 한 글자씩 세로로 끊겨 보인다.
   이름 칸에 최소 폭을 주고, 그래도 안 들어가면(flex-wrap) 오른쪽 버튼줄이 통째로
   다음 줄로 넘어가게 한다. */
@media (max-width: 480px) {
  .goal-row .gcol { min-width: 130px; }
}
.goal-row .gname { font-weight: 700; font-size: 0.96rem; }
.goal-row .gmeta { font-size: 0.78rem; color: var(--ink-soft); margin-top: 2px; }
.goal-row .gbar-row { display: flex; align-items: center; gap: 9px; margin-top: 8px; max-width: 260px; }
.goal-row .gbar-wrap { height: 6px; border-radius: 999px; background: var(--gray-soft); overflow: hidden; flex: 1; }
.goal-row .gbar { height: 100%; border-radius: 999px; background: var(--teal); }
.goal-row .gbar-pct { font-size: 0.72rem; font-weight: 700; color: var(--ink-soft); flex-shrink: 0; }
.gwarn { display: flex; align-items: center; gap: 5px; font-size: 0.72rem; color: var(--amber-ink); margin-top: 6px; }
.gwarn svg { flex-shrink: 0; }
.goal-row .gactions { display: flex; gap: 6px; margin-left: auto; flex-shrink: 0; }

/* 아직 아무것도 등록 안 한 목록: 뒤로 예시 행을 블러 처리해 깔아두고(실제 데이터로
   착각하거나 눌리면 안 되므로 pointer-events:none), 그 위에 등록을 부탁하는 안내를
   반투명 레이어로 덮어 씌운다. 안내문이 흐릿한 예시에 묻히지 않도록 오버레이를
   충분히 불투명하게 두고 제목을 굵고 크게 잡는다. */
.routine-empty { position: relative; padding: 20px 4px; overflow: hidden; border-radius: 12px; }
.routine-empty .example-rows { filter: blur(1.5px); }
.example-row { position: relative; display: flex; align-items: center; gap: 14px; padding: 10px 0; pointer-events: none; color: var(--ink-faint); }
.example-row .example-tag {
  position: absolute; top: 2px; right: 4px;
  font-size: 0.64rem; font-weight: 700; color: var(--ink-faint);
  background: var(--surface); border: 1px solid var(--line-strong); border-radius: 999px; padding: 1px 7px;
}
.example-row .gicon { width: 42px; height: 42px; border-radius: 12px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; font-size: 1.25rem; background: var(--gray-soft); color: var(--ink-faint); }
.example-row .gname { font-weight: 700; font-size: 0.96rem; color: var(--ink-soft); }
.example-row .gmeta { font-size: 0.78rem; color: var(--ink-faint); margin-top: 2px; }
.routine-empty-overlay {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center;
  padding: 16px; background: rgba(255, 255, 255, 0.84);
}
.routine-empty-overlay .eicon { color: var(--ink-soft); margin-bottom: 10px; display: flex; }
.routine-empty-title { font-weight: 800; font-size: 1.02rem; color: var(--ink); letter-spacing: -0.01em; }
.badge-priority {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 0.68rem; font-weight: 700; padding: 3px 9px 3px 7px; border-radius: 999px;
}
.badge-priority .gicon-svg { width: 0.95em; height: 0.95em; }
.badge-priority.must { background: var(--accent-soft); color: var(--accent); }
.badge-priority.good { background: var(--amber-soft); color: var(--amber-ink); }
.badge-priority.optional { background: var(--slate-soft); color: var(--slate); }
.badge-priority.paused { background: var(--gray-soft); color: var(--ink-faint); }
.pill-priority { display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
.pill-priority .gicon-svg { width: 1em; height: 1em; }

.empty-state { text-align: center; padding: 50px 20px; color: var(--ink-soft); }
.empty-state .eicon { font-size: 2.4rem; margin-bottom: 10px; }

/* ---------- Wizard (온보딩 / 목표 등록) ---------- */
.wizard { max-width: 480px; margin: 0 auto; }
.wizard-progress { display: flex; gap: 5px; margin-bottom: 26px; }
.wizard-progress i { flex: 1; height: 4px; border-radius: 999px; background: var(--gray-soft); }
.wizard-progress i.done { background: var(--accent); }
.wizard-q { font-size: 1.2rem; font-weight: 800; margin-bottom: 4px; letter-spacing: -0.01em; }
.wizard-sub { font-size: 0.84rem; color: var(--ink-soft); margin-bottom: 20px; }
.wizard-nav { display: flex; gap: 10px; margin-top: 26px; }
/* .btn은 기본이 flex-shrink:0라, wizard-nav 안에서 width:100%짜리 .btn-block과
   나란히 놓이면(예: 취소+등록하기) 폭이 전혀 안 줄어들고 좁은 화면에서 밖으로
   삐져나온다. flex:1로 "남은 공간을 채운다"로 바꿔야 옆 버튼과 함께 줄어든다. */
.wizard-nav .btn-block { flex: 1 1 0; width: auto; min-width: 0; }
.modal-backdrop {
  position: fixed; inset: 0; background: rgba(15, 17, 26, 0.45);
  display: flex; align-items: flex-end; justify-content: center;
  z-index: 60; padding: 0;
}
@media (min-width: 640px) { .modal-backdrop { align-items: center; padding: 20px; } }
.modal-sheet {
  background: var(--surface);
  width: 100%; max-width: 560px;
  border-radius: 20px 20px 0 0;
  padding: 24px 22px 28px;
  max-height: 92vh; overflow-y: auto; overflow-x: hidden;
  box-sizing: border-box;
}
@media (min-width: 640px) { .modal-sheet { border-radius: 20px; } }
.modal-close {
  display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; margin-left: auto; margin-bottom: -34px;
  position: sticky; top: 0;
  border: none; border-radius: 50%;
  background: var(--surface-2); color: var(--ink-soft);
  cursor: pointer; z-index: 5;
}
.modal-close:hover { background: var(--line-strong); color: var(--ink); }

/* ---------- Week view ---------- */

/* ---------- Week view: day tabs (mobile single-day mode) ---------- */
.week-daytabs { display: flex; gap: 6px; margin-bottom: 14px; }
.week-daytabs .wdt {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 8px 2px; border-radius: 12px; border: 1px solid var(--line-strong);
  background: var(--surface); color: var(--ink-soft); cursor: pointer;
}
.week-daytabs .wdt.is-sat:not(.active) { color: var(--sat); border-color: var(--sat-soft); background: var(--sat-soft); }
.week-daytabs .wdt.is-sun:not(.active) { color: var(--sun); border-color: var(--sun-soft); background: var(--sun-soft); }
.week-daytabs .wdt.active { background: var(--accent); border-color: var(--accent); color: #fff; }
.week-daytabs .wdt.is-today:not(.active) { border-color: var(--accent); color: var(--accent-strong); background: var(--surface); }
.week-daytabs .wdt-dow { font-size: 0.64rem; font-weight: 700; }
.week-daytabs .wdt-date { font-size: 0.86rem; font-weight: 800; }

/* ---------- Week view: hour-grid calendar ---------- */
.week-cal {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
}
.week-cal-head, .week-cal-rows { display: grid; }
.week-cal-head { border-bottom: 1px solid var(--line); background: var(--surface); }
.week-cal-head .wh-corner { border-right: 1px solid var(--line); }
.week-cal-head .wh-day { padding: 10px 4px; text-align: center; border-right: 1px solid var(--line); }
.week-cal-head .wh-day:last-child { border-right: none; }
.week-cal-head .wh-day.is-sat { background: var(--sat-soft); }
.week-cal-head .wh-day.is-sat .wh-dow, .week-cal-head .wh-day.is-sat .wh-date { color: var(--sat); }
.week-cal-head .wh-day.is-sun { background: var(--sun-soft); }
.week-cal-head .wh-day.is-sun .wh-dow, .week-cal-head .wh-day.is-sun .wh-date { color: var(--sun); }
.week-cal-head .wh-day.is-today { background: var(--accent-soft); }
.week-cal-head .wh-day.is-today .wh-dow, .week-cal-head .wh-day.is-today .wh-date { color: var(--accent-strong); }
.week-cal-head .wh-dow { font-size: 0.68rem; font-weight: 700; color: var(--ink-faint); }
.week-cal-head .wh-date { font-size: 0.9rem; font-weight: 800; margin-top: 2px; }
.week-cal-head .wh-total { font-size: 0.66rem; color: var(--ink-soft); margin-top: 3px; }

.week-cal-rows { position: relative; }
.week-cal-times { position: relative; border-right: 1px solid var(--line); }
.week-cal-times .wt-hour {
  position: absolute; left: 0; right: 4px; top: 0;
  text-align: right; font-size: 0.64rem; color: var(--ink-faint);
  transform: translateY(-50%);
}
.week-cal-col { position: relative; border-right: 1px solid var(--line); overflow-x: auto; overflow-y: hidden; }
.week-cal-col:last-child { border-right: none; }
.week-cal-col.is-sat { background: rgba(40, 120, 168, 0.035); }
.week-cal-col.is-sun { background: rgba(239, 68, 68, 0.035); }
.week-cal-col.is-today { background: rgba(239, 64, 96, 0.045); }
.week-cal-hourline { position: absolute; left: 0; right: 0; top: 0; border-top: 1px solid var(--line); }
.week-cal-now {
  position: absolute; left: 0; right: 0; top: 0; height: 0;
  border-top: 2px solid var(--plum); z-index: 5; pointer-events: none;
}
.week-cal-now::before {
  content: ''; position: absolute; left: -4px; top: -4px;
  width: 8px; height: 8px; border-radius: 50%; background: var(--plum);
}

.wevent {
  position: absolute;
  border-radius: 0 10px 10px 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  box-shadow: var(--shadow-card);
  padding: 6px 8px;
  display: flex; flex-direction: column; gap: 2px;
  cursor: pointer;
  overflow: hidden;
  transition: box-shadow .15s ease, transform .15s ease;
}
.wevent:hover { box-shadow: var(--shadow-lift); transform: translateY(-1px); }
.wevent.kind-recurring { border-left-color: var(--plum); }
.wevent .we-tag { display: flex; align-items: center; gap: 5px; font-size: 0.62rem; font-weight: 700; color: var(--ink-soft); flex-shrink: 0; }
.wevent .we-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); flex-shrink: 0; }
.wevent.kind-recurring .we-dot { background: var(--plum); }
.wevent .we-title-row { display: flex; flex: 1; align-items: flex-start; gap: 5px; min-height: 0; }
.wevent .we-icon { flex-shrink: 0; line-height: 1.3; font-size: 0.8rem; }
/* 제목과 그 아래 시간이 같은 세로 칸에 있어야 왼쪽 정렬이 맞는다 - 아이콘만큼 밀린
   제목과 달리 시간을 별도 줄로 두면 아이콘 자리만큼 어긋나 보였다. */
.wevent .we-body { display: flex; flex-direction: column; flex: 1; min-width: 0; height: 100%; }
.wevent .we-title-text {
  font-size: 0.76rem; font-weight: 700; line-height: 1.3;
  word-break: keep-all; overflow-wrap: break-word;
}
.wevent .we-time { font-size: 0.62rem; color: var(--ink-faint); flex-shrink: 0; margin-top: auto; padding-top: 2px; }
/* 자리가 좁아 태그/제목/시간을 다 못 보여줄 때는 제목만이라도 온전히 보이도록 나머지를 숨긴다. */
.wevent.is-compact { padding: 3px 6px; gap: 0; }
.wevent.is-compact .we-tag, .wevent.is-compact .we-time { display: none; }
.wevent.is-compact .we-title-row { align-items: center; height: 100%; min-width: 0; }
.wevent.is-compact .we-title-text {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
}
.week-legend { display: flex; justify-content: flex-end; gap: 16px; margin: 14px 0 16px; font-size: 0.76rem; color: var(--ink-soft); flex-wrap: wrap; }
.week-legend span { display: inline-flex; align-items: center; gap: 6px; }
.week-legend i { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }

/* ---------- Month view ---------- */
.month-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
.month-dow { text-align: center; font-size: 0.72rem; font-weight: 700; color: var(--ink-faint); padding-bottom: 6px; }
.month-cell {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 7px;
  min-height: 88px;
  cursor: pointer;
  /* 그리드 칸의 기본 최소 폭(min-width:auto)은 안에 든 내용의 "줄바꿈 없는" 최소
     크기를 그대로 요구한다 - .mpill에 white-space:nowrap을 주면 그 최소 크기가
     배지 전체 글자 폭이 되어 7칸짜리 월간 그리드 전체가 옆으로 넘친다. 칸 자체는
     "내용 때문에 넓어지지 마라"로 두고, 실제 잘림은 .mpill 쪽에서 처리한다. */
  min-width: 0;
}
.month-cell.outside { opacity: 0.35; }
.month-cell.is-today { border-color: var(--accent); }
.month-cell.selected { outline: 2px solid var(--ink); outline-offset: -2px; }
.month-cell .mnum { font-size: 0.78rem; font-weight: 700; }
/* 한글은 공백 없이도 아무 글자 사이에서나 줄바꿈이 허용돼서, 이 배지가 좁은
   월간 달력 칸(모바일에서 7칸으로 나뉨) 폭보다 길면(예: "고정 일정 2", 목표
   이름이 긴 마감일 배지) 줄바꿈 대신 세로로 한 글자씩 끊겨 보인다. block+너비
   100%로 칸 폭에 맞추고 그 안에서 말줄임표로 자른다(위 .month-cell의
   min-width:0과 짝을 이뤄야 칸 자체가 넓어지지 않는다). */
.month-cell .mpill { font-size: 0.62rem; font-weight: 700; padding: 2px 6px; border-radius: 6px; margin-top: 4px; display: block; width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.month-cell .mpill.goal { background: var(--accent-soft); color: var(--accent-ink); }
.month-cell .mpill.recurring { background: var(--plum-soft); color: var(--plum); }
.month-detail { margin-top: 18px; }
.week-item { display: flex; align-items: center; gap: 10px; }
.week-item .wt { flex-shrink: 0; font-size: 0.8rem; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.week-item.is-editable { cursor: pointer; border-radius: var(--radius-sm); margin: 0 -8px; padding-left: 8px !important; padding-right: 8px !important; }
.week-item.is-editable:hover { background: var(--surface-2); }

/* ---------- Misc ---------- */
.toast {
  position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%);
  background: var(--ink); color: var(--surface);
  padding: 12px 18px; border-radius: 999px; font-size: 0.85rem; font-weight: 600;
  z-index: 80; box-shadow: var(--shadow-lift);
}
@media (max-width: 760px) { .toast { bottom: 84px; } }

/* ---------- Stats screen ---------- */
.stat-card-sub { font-size: 0.64rem; color: var(--ink-faint); margin-top: 1px; }
.stats-current-tag {
  display: inline-block; font-size: 0.58rem; font-weight: 700; color: var(--ink-faint);
  background: var(--surface-2); border-radius: 5px; padding: 1px 5px; margin-left: 5px; vertical-align: middle;
}

.stats-range-picker { display: flex; gap: 12px; flex-wrap: wrap; }
.stats-range-picker .field { flex: 1; min-width: 140px; }

.stats-weekday-bars { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; }
.stats-weekday-col { display: flex; flex-direction: column; align-items: center; gap: 4px; min-width: 0; }
.stats-weekday-track { position: relative; width: 100%; height: 64px; background: var(--surface-2); border-radius: 6px; overflow: hidden; }
.stats-weekday-fill { position: absolute; left: 0; right: 0; bottom: 0; background: var(--accent); border-radius: 6px 6px 0 0; transition: height .2s; }
.stats-weekday-pct { font-size: 0.68rem; font-weight: 700; color: var(--ink); }
.stats-weekday-label { font-size: 0.68rem; color: var(--ink-soft); }

.stats-daylist { display: flex; flex-wrap: wrap; gap: 8px; }
.stats-day-chip {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  min-width: 52px; padding: 6px 6px; border-radius: 9px; background: var(--surface-2);
  font-size: 0.68rem; font-weight: 700; color: var(--ink); text-align: center;
}
.stats-day-chip.ok { background: var(--teal-soft); color: var(--ink); }
.stats-day-chip.no-record, .stats-day-chip.before-log { color: var(--ink-faint); }
.stats-day-date { font-variant-numeric: tabular-nums; }
.stats-day-tag { font-size: 0.6rem; font-weight: 600; color: var(--ink-faint); }
.stats-day-tag.rest { color: var(--amber-ink); }

.stats-row { padding: 14px 4px; }
.stats-row-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.stats-row-name { font-weight: 700; font-size: 0.92rem; }
.stats-kind-badge { font-size: 0.66rem; font-weight: 700; padding: 3px 8px; border-radius: 6px; background: var(--slate-soft); color: var(--ink-soft); flex-shrink: 0; }
.stats-row-metrics { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 8px; font-size: 0.78rem; color: var(--ink-soft); }
.stats-row-metrics b { color: var(--ink); font-weight: 800; }

.stats-goal-late { color: var(--amber-ink); }

.timeuse-bar { display: flex; height: 14px; border-radius: 8px; overflow: hidden; background: var(--surface-2); }
.timeuse-seg { height: 100%; }
.timeuse-legend { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 12px; font-size: 0.78rem; color: var(--ink-soft); }
.timeuse-legend .dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 5px; vertical-align: middle; }

.stats-pattern-body { margin-top: 6px; font-size: 0.86rem; color: var(--ink); line-height: 1.55; }
.stats-pattern-muted { color: var(--ink-faint); font-size: 0.84rem; }

.stats-trend-bars { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; max-width: 280px; }
.stats-trend-col { display: flex; flex-direction: column; align-items: center; gap: 4px; min-width: 0; }
.stats-trend-track { position: relative; width: 100%; height: 56px; background: var(--surface-2); border-radius: 6px; overflow: hidden; }
.stats-trend-fill { position: absolute; left: 0; right: 0; bottom: 0; background: var(--teal); border-radius: 6px 6px 0 0; transition: height .2s; }
.stats-trend-pct { font-size: 0.68rem; font-weight: 700; color: var(--ink); }
.stats-trend-label { font-size: 0.62rem; color: var(--ink-soft); }

/* ---------- Reward screen ---------- */
.reward-pin-gate { text-align: center; padding: 32px 20px; }
.reward-pin-gate-title { font-weight: 700; margin-bottom: 14px; }
.reward-pin-input {
  display: block; text-align: center; letter-spacing: 10px; font-size: 1.3rem; font-weight: 800;
  max-width: 160px; margin: 0 auto 12px;
}
.reward-parentmode-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  flex-wrap: wrap; margin-bottom: 14px;
}
.reward-toast {
  position: fixed; left: 50%; bottom: 64px; transform: translateX(-50%);
  display: flex; align-items: center; gap: 7px;
  background: var(--ink); color: var(--surface);
  padding: 8px 14px 8px 8px; border-radius: 999px; font-size: 0.8rem; font-weight: 700;
  z-index: 81; box-shadow: var(--shadow-lift);
  animation: toast-in 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}
@media (max-width: 760px) { .reward-toast { bottom: 124px; } }
.reward-toast-icon {
  width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; font-size: 0.85rem;
}
.reward-badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 16px; height: 16px; padding: 0 4px; margin-left: 4px;
  border-radius: 999px; background: var(--accent); color: #fff;
  font-size: 0.62rem; font-weight: 800; vertical-align: middle;
}
.reward-request-note { margin-top: 6px; font-size: 0.78rem; color: var(--ink-soft); }
.reward-recovery-code {
  text-align: center; font-size: 1.4rem; font-weight: 900; letter-spacing: 4px;
  padding: 18px; background: var(--surface-2); border-radius: var(--radius-sm);
  font-variant-numeric: tabular-nums;
}

.flexbetween { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.mt-8 { margin-top: 8px; } .mt-16 { margin-top: 16px; } .mt-24 { margin-top: 24px; }
.link-quiet { color: var(--ink-soft); font-size: 0.8rem; text-decoration: underline; cursor: pointer; background: none; border: none; padding: 0; }

/* ---------- 백업 권유 배너 (작게 띄우는 카드, 강제로 안 닫으면 화면 아무 데나
   떠 있을 수 있어 토스트보다 크고 하단 네비 위에 고정된다) ---------- */
.backup-notice {
  position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%);
  width: min(360px, calc(100vw - 32px));
  background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--radius);
  box-shadow: var(--shadow-lift); padding: 14px 16px; z-index: 79;
  display: flex; flex-direction: column; gap: 10px;
  animation: toast-in 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}
@media (max-width: 760px) { .backup-notice { bottom: 84px; } }
.backup-notice-body { font-size: 0.84rem; color: var(--ink); line-height: 1.5; padding-right: 22px; }
.backup-notice-actions { display: flex; gap: 8px; justify-content: flex-end; }
.backup-notice-close {
  position: absolute; top: 10px; right: 10px; width: 22px; height: 22px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; color: var(--ink-faint);
  background: none; border: none; cursor: pointer;
}

@media print {
  .sidenav, .bottomnav, .page-head .clock-live, .no-print { display: none !important; }
  .main { margin-left: 0; padding: 8px; max-width: none; }
  body { background: #fff; }
  .week-cal { border-color: #999; }
  .week-daytabs { display: none; }
  @page { size: A4 landscape; margin: 10mm; }
}
