/**
 * MyWorks 대시보드 스타일
 * pms 프로젝트의 JIO 디자인 시스템 토큰을 가져다 쓴다. 규칙과 색표는
 * 저장소 루트의 STYLE_GUIDE.md 에 있다 — 색을 여기 하드코딩하지 않는다.
 *
 * pms 와 달리 Bootstrap 을 쓰지 않는다. CDN 을 부르지 않는다는 약속
 * (tests/test_web_assets.py::test_no_external_origins)을 지키려면 정적
 * 파일을 저장소에 통째로 넣어야 하는데, 화면 하나에 그럴 값어치가 없다.
 * 그래서 토큰과 컴포넌트 규격만 손으로 옮겼다.
 */

/* ===== JIO 디자인 시스템 토큰 (라이트) ===== */
:root {
  /* Pretendard 가 깔려 있으면 쓰고, 없으면 시스템 한글 폰트로 떨어진다.
     폰트 파일은 저장소에 넣지 않는다. */
  --ff-base: 'Pretendard Variable', 'Pretendard', -apple-system,
             BlinkMacSystemFont, 'Apple SD Gothic Neo', system-ui, sans-serif;

  --primary-main: #323f53;
  --primary-light: #4c5e78;
  --primary-dark: #192332;
  --primary-50: #d3d6dd;
  --primary-100: #bdc2cc;

  --secondary-main: #fd3a00;

  --tertiary-900: #1f95ec;
  --tertiary-800: #36a0ee;
  --tertiary-700: #4caaf0;
  --tertiary-500: #79bff4;
  --tertiary-300: #a5d5f7;
  --tertiary-100: #d2eafb;

  --success-main: #00db40;
  --success-dark: #00cd3c;
  --warning-main: #ff9500;
  --error-main: #e42b2e;
  --info-main: #4b66d0;

  --grey-900: #212121;
  --grey-800: #303334;
  --grey-700: #46494b;
  --grey-600: #606365;
  --grey-500: #7e8184;
  --grey-200: #d8dadb;
  --grey-100: #ebebeb;
  --grey-50: #f8f8f8;

  --app-bg: var(--grey-50);
  --app-header-bg: #ffffff;
  --app-card-bg: #ffffff;
  --app-text: var(--grey-900);
  --app-text-muted: var(--grey-600);
  --app-border: var(--grey-200);
  --app-hover-bg: var(--grey-100);

  /* 차트 팔레트 — chart.js 가 getComputedStyle 로 읽어 간다. 그래야 테마를
     바꿀 때 색이 따라온다. var() 별칭이 아니라 실제 값으로 적는다. */
  --chart-1: #1f95ec;
  --chart-2: #fd3a00;
  --chart-3: #00cd3c;
  --chart-4: #4b66d0;
  --chart-5: #ff9500;
  --chart-6: #e42b2e;
  --chart-7: #79bff4;
  --chart-8: #7e8184;
  --chart-9: #323f53;
  --chart-10: #a5d5f7;
  --chart-line: #1f95ec;
  /* 도넛의 '기타' 전용. 팔레트(1~10) 밖의 값이어야 한다 — 팔레트에서 색을
     빼는 방식으로 겹침을 피하면 같은 프로젝트가 누적막대와 도넛에서 다른
     색이 되어 더 나쁘다. 가장 흐린 회색이라 '나머지'로 읽힌다. */
  --chart-rest: #c1c3c5;
}

/* ===== 다크 모드 ===== */
[data-bs-theme="dark"] {
  --primary-main: #7a85ff;
  --primary-light: #9ba4ff;
  --primary-dark: #5967ff;
  --primary-50: #2c3242;
  --primary-100: #3a4257;

  --app-bg: #121212;
  --app-header-bg: #1e1e1e;
  --app-card-bg: #1e1e1e;
  --app-text: #ffffff;
  --app-text-muted: var(--grey-200);
  --app-border: var(--grey-700);
  --app-hover-bg: var(--grey-800);

  /* 어두운 배경에 묻히는 둘만 바꾼다 — 남색(#323f53)과 중간 회색. */
  --chart-8: #9c9fa1;
  --chart-9: #7a85ff;
  --chart-line: #63b5f2;
  --chart-rest: #606365;
}

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

/* #login 의 ID 선택자(display:grid)와 .app-layout(display:flex)이 UA 의
   [hidden] 규칙보다 우선순위가 높아, hidden 속성만으로는 로그인 후에도
   화면이 겹쳐 보인다. 명시로 이긴다. */
[hidden] { display: none !important; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--app-bg);
  color: var(--app-text);
  font-family: var(--ff-base);
  font-size: 14px;
  line-height: 1.6;
}

h1, h2, h3 { margin: 0; }

input, select, button {
  font: inherit;
  padding: .35rem .6rem;
  border: 1px solid var(--app-border);
  border-radius: 6px;
  background: var(--app-card-bg);
  color: var(--app-text);
}
button { cursor: pointer; }
input:focus-visible, select:focus-visible, button:focus-visible {
  outline: 2px solid var(--tertiary-700);
  outline-offset: 1px;
}

/* ===== 로그인 ===== */
#login { display: grid; place-items: center; min-height: 100vh; padding: 1.5rem; }
#login-form {
  display: grid;
  gap: .6rem;
  width: min(340px, 90vw);
  padding: 1.75rem;
  background: var(--app-card-bg);
  border: 1px solid var(--app-border);
  border-radius: 8px;
}
#login-form h1 {
  font-size: 22px;
  font-weight: 700;
  color: var(--primary-main);
  letter-spacing: -.5px;
  margin-bottom: .5rem;
}
#login-form button {
  background: var(--primary-main);
  border-color: var(--primary-main);
  color: #fff;
  font-weight: 600;
  padding: .5rem;
}
#login-form button:hover { background: var(--primary-light); border-color: var(--primary-light); }
#login-error { color: var(--error-main); min-height: 1.4em; margin: 0; font-size: 13px; }

/* ===== 앱 셸 ===== */
.app-layout {
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
}

.app-header {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 20px;
  background: var(--app-header-bg);
  border-bottom: 1px solid var(--app-border);
  flex-wrap: wrap;
}

.app-logo {
  display: flex;
  flex-direction: column;
  justify-content: center;
  margin-right: 8px;
  padding-right: 16px;
  border-right: 1px solid var(--app-border);
  flex-shrink: 0;
  line-height: 1.05;
}
.app-logo h1 {
  font-size: 21px;
  font-weight: 700;
  color: var(--primary-main);
  letter-spacing: -.5px;
}
.app-logo .app-sub {
  align-self: stretch;
  text-align: right;
  font-size: 10px;
  font-weight: 700;
  color: var(--app-text-muted);
  letter-spacing: .3px;
  margin-top: 1px;
}

.header-right {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
  flex-shrink: 0;
}

.theme-toggle-btn {
  background: transparent;
  border: 1px solid var(--app-border);
  border-radius: 50%;
  width: 34px;
  height: 34px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--app-text);
  transition: background .2s ease;
}
.theme-toggle-btn:hover { background: var(--app-hover-bg); }
.theme-toggle-btn svg { width: 17px; height: 17px; fill: currentColor; }
/* 켜져 있는 테마의 아이콘만 보여 준다 — 누르면 무엇으로 바뀌는지가 아니라
   지금 무엇인지를 표시한다(pms 와 같다). */
[data-bs-theme="dark"] .icon-light { display: none; }
:root:not([data-bs-theme="dark"]) .icon-dark { display: none; }

.app-main {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  background: var(--app-bg);
}

.page-container {
  padding: 16px 20px 24px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.app-footer {
  padding: 6px 20px;
  background: var(--app-header-bg);
  border-top: 1px solid var(--app-border);
  text-align: center;
  font-size: 12px;
  color: var(--app-text-muted);
  flex-shrink: 0;
}

/* ===== 필터 ===== */
#filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  flex: 1 1 320px;
  min-width: 0;
}
#f-q { flex: 1 1 180px; min-width: 140px; }

.btn-quiet { background: var(--app-card-bg); color: var(--app-text); }
.btn-quiet:hover { background: var(--app-hover-bg); }

/* ===== 통계 카드 ===== */
.stat-cards {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

.stat-card {
  flex: 1;
  min-width: 140px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* 부제(.stat-note)가 flex-basis:100% 로 다음 줄에 떨어지려면 wrap 이 필요하다. */
  flex-wrap: wrap;
  gap: 8px;
  padding: 10px 14px;
  background: var(--app-card-bg);
  border: 1px solid var(--app-border);
  border-radius: 6px;
}
/* 톤 — pms 의 stat-total/completed/… 자리다. MyWorks 에는 완료·지연 같은
   상태가 없어서 상태 이름 대신 톤 이름을 쓴다. */
.stat-card.tone-primary { background: var(--primary-50); border-color: var(--primary-100); }
.stat-card.tone-blue    { background: rgba(76, 170, 240, .1);  border-color: rgba(76, 170, 240, .3); }
.stat-card.tone-green   { background: rgba(0, 219, 64, .1);    border-color: rgba(0, 219, 64, .3); }
.stat-card.tone-grey    { background: var(--grey-50);          border-color: var(--grey-200); }
[data-bs-theme="dark"] .stat-card.tone-grey {
  background: var(--app-card-bg);
  border-color: var(--app-border);
}

.stat-card.tone-orange  { background: rgba(253, 58, 0, .08);   border-color: rgba(253, 58, 0, .3); }

.stat-card .stat-label { font-size: 14px; font-weight: 600; color: var(--app-text-muted); }
/* 환산가 카드의 부제. 값 오른쪽 아래에 붙어 라벨과 겹치지 않는다. */
.stat-card .stat-note {
  flex-basis: 100%;
  text-align: right;
  font-size: 11px;
  color: var(--app-text-muted);
  margin-top: -2px;
}
.stat-card .stat-value {
  font-size: 20px;
  font-weight: 700;
  color: var(--primary-main);
  font-variant-numeric: tabular-nums;
}

/* ===== 카드 ===== */
.card {
  background: var(--app-card-bg);
  border: 1px solid var(--app-border);
  border-radius: 6px;
  min-width: 0;
}

.card-header {
  padding: 8px 14px;
  border-bottom: 1px solid var(--app-border);
  font-size: 13px;
  font-weight: 600;
  color: var(--app-text-muted);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.card-body { padding: 12px 14px; }

/* 차트의 viewBox 는 760×240 이다. 트랙이 그보다 한참 좁으면 x축 눈금이
   서로 붙어 읽히지 않는다 — 1440px 화면에서 4열로 갈리던 것을 2열로 묶는다.
   min(100%, …) 은 트랙 최소폭보다 좁은 화면에서 그리드가 넘치지 않게 한다. */
.charts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 460px), 1fr));
  gap: 16px;
}
figure.card { margin: 0; }
/* 트랙 최소폭(320px)보다도 더 좁은 화면(예: 아이폰 SE)에서는 카드 안쪽만
   가로로 스크롤시킨다 — 페이지 몸통이 통째로 옆으로 밀리면 안 된다. */
.card-body > div { overflow-x: auto; }

/* ===== 차트 ===== */
svg { width: 100%; height: auto; display: block; }
.grid { stroke: var(--app-border); stroke-width: 1; }
.tick { fill: var(--app-text-muted); font-size: 11px; }
.line { fill: none; stroke: var(--chart-line); stroke-width: 2; }
.dot { fill: var(--chart-line); }
.legend {
  display: flex;
  flex-wrap: wrap;
  gap: .6rem;
  margin-top: .5rem;
  font-size: 12px;
  color: var(--app-text-muted);
}
.lg i {
  display: inline-block;
  width: .7em;
  height: .7em;
  border-radius: 2px;
  margin-right: .3em;
}
.empty { color: var(--app-text-muted); text-align: center; padding: 2rem 0; margin: 0; }

/* ===== 도넛 ===== */
.donut-wrap {
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
}
/* 도넛은 줄어들되 너무 작아지지 않는다. 범례가 붙을 자리가 없으면 아래로
   떨어진다(flex-wrap). */
.donut { flex: 0 1 240px; max-width: 240px; min-width: 160px; }
.donut-cap {
  fill: var(--app-text-muted);
  font-size: 11px;
  font-weight: 600;
}
.donut-total {
  fill: var(--app-text);
  font-size: 15px;
  font-weight: 700;
}

.legend-detail {
  flex: 1 1 220px;
  min-width: 0;
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 12px;
}
.legend-detail li {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 3px 0;
  border-bottom: 1px solid var(--app-border);
}
.legend-detail li:last-child { border-bottom: none; }
.legend-detail i {
  flex: 0 0 auto;
  width: .7em;
  height: .7em;
  border-radius: 2px;
}
/* 이름만 늘었다 줄었다 한다 — 숫자 칸이 흔들리면 세로로 읽을 수 없다. */
.lg-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lg-val, .lg-pct {
  flex: 0 0 auto;
  color: var(--app-text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.lg-pct { width: 3.4em; text-align: right; }
.lg-cost { width: 4.6em; text-align: right; }

/* ===== 추정 배지 ===== */
/* 정확한 값과 추정값이 눈으로 구분되지 않으면 배지가 없느니만 못하다. */
.badge {
  display: inline-block;
  margin-left: 6px;
  padding: 0 5px;
  border-radius: 3px;
  font-size: 10px;
  font-weight: 600;
  line-height: 1.5;
  vertical-align: 1px;
  background: rgba(255, 149, 0, .15);
  color: var(--warning-main);
  border: 1px solid rgba(255, 149, 0, .35);
}
[data-bs-theme="dark"] .badge { color: #ffb340; }

/* ===== 세션 목록 ===== */
.count { color: var(--app-text-muted); font-size: 12px; font-weight: 400; }

.task-list { max-height: 420px; overflow-y: auto; }

.task-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.task-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--app-hover-bg);
  color: var(--app-text-muted);
  font-weight: 600;
  text-align: left;
  white-space: nowrap;
  padding: 7px 10px;
  border-bottom: 1px solid var(--app-border);
}
.task-table tbody td {
  padding: 6px 10px;
  border-bottom: 1px solid var(--app-border);
  vertical-align: middle;
}
.task-table tbody tr.clickable-row { cursor: pointer; }
.task-table tbody tr.clickable-row:hover { background: rgba(76, 170, 240, .1); }
[data-bs-theme="dark"] .task-table tbody tr.clickable-row:hover {
  background: rgba(122, 133, 255, .15);
}
.task-table .col-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.task-table .col-sum {
  color: var(--app-text-muted);
  max-width: 460px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ===== 상세 다이얼로그 ===== */
dialog {
  max-width: min(820px, 92vw);
  /* 프롬프트가 수백 개인 세션이 있다. 높이를 묶고 안에서 스크롤시킨다 —
     .dialog-head 의 sticky 도 스크롤 컨테이너가 있어야 붙어 있는다. */
  max-height: 88vh;
  overflow-y: auto;
  padding: 0;
  border: 1px solid var(--app-border);
  border-radius: 8px;
  background: var(--app-card-bg);
  color: var(--app-text);
}
dialog::backdrop { background: rgba(0, 0, 0, .45); }
.dialog-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--app-border);
  position: sticky;
  top: 0;
  background: var(--app-card-bg);
}
.dialog-head h2 { font-size: 16px; font-weight: 700; color: var(--primary-main); }
.dialog-body { padding: 12px 16px 16px; }
.dialog-body h3 {
  font-size: 12px;
  font-weight: 600;
  color: var(--app-text-muted);
  margin: 16px 0 6px;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--app-border);
}
.dialog-body h3:first-child { margin-top: 0; }
.meta { color: var(--app-text-muted); font-size: 13px; margin: 4px 0 0; }
.summary { white-space: pre-wrap; font: inherit; margin: 0; }
.prompts li, .files li, .commits li {
  white-space: pre-wrap;
  word-break: break-all;
  margin-bottom: .35rem;
  font-size: 13px;
}

/* ===== 좁은 화면 ===== */
@media (max-width: 768px) {
  .app-header { padding: 8px 14px; }
  .app-logo { margin-right: 4px; padding-right: 10px; }
  .app-logo h1 { font-size: 18px; }
  .page-container { padding: 12px 14px 20px; }
  .task-table .col-sum { max-width: 180px; }
  /* 좁으면 라벨과 값이 한 줄에 안 들어간다 — "작업 시간"이 두 줄로 쪼개지는
     대신 라벨을 값 위로 올린다. */
  .stat-card {
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 2px;
    /* column + wrap 은 다음 '열'로 감는다 — 부제가 값보다 위로 올라간다.
       세로로 쌓는 순간 감쌀 이유가 없으므로 끈다. */
    flex-wrap: nowrap;
  }
  .stat-card .stat-label { font-size: 13px; }
  .stat-card .stat-note { flex-basis: auto; text-align: left; margin-top: 0; }
}
