/* b3x 대시보드 — MOPS 토큰 위의 레이아웃 (app 전용). */

body { margin: 0; min-height: 100vh; }

/* ── topbar 요소 ── */
/* 기본 gap(14px)은 항목 사이를 너무 벌린다. 여기선 덩어리끼리만 띄우고
   덩어리 안(메뉴 링크, 아이콘 버튼)은 붙인다. */
.topbar { gap: 10px; }
.brand { display: flex; align-items: center; gap: 8px; text-decoration: none; color: inherit; flex: 0 0 auto; }
.brandmark {
  width: 28px; height: 28px; border-radius: 8px; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--blue-500), var(--blue-700));
  box-shadow: var(--shadow-glow);
}
.brandmark [data-lucide] { width: 16px; height: 16px; color: #fff; }
.brandname { font-size: 16px; letter-spacing: var(--tracking-tight); }
.spacer { flex: 1; }
.topbar .btn [data-lucide] { width: 16px; height: 16px; }

/* 메뉴. MOPS 의 .nav 는 세로 사이드바(components.css)라 이름을 겹치지 않게 둔다. */
.topnav { display: flex; flex-direction: row; align-items: center; gap: 2px; margin-left: 6px; }
.topnav__link {
  display: inline-flex; align-items: center; gap: 6px;
  padding: calc(7px * var(--u)) calc(11px * var(--u));
  border-radius: 8px; border: 1px solid transparent;
  font-size: calc(13px * var(--f)); font-weight: 500;
  color: var(--fg-muted); text-decoration: none; white-space: nowrap;
}
.topnav__link [data-lucide] { width: 15px; height: 15px; }
.topnav__link:hover { color: var(--fg); background: var(--surface-2); }
.topnav__link--active { color: var(--fg); background: var(--surface-2); border-color: var(--border); }

/* 아이콘 버튼 묶음 — 로그아웃이 가장 오른쪽 */
.topbar__actions { display: flex; align-items: center; gap: 2px; }

.sync-last { font-size: calc(11px * var(--f)); color: var(--fg-subtle); white-space: nowrap; }

/* ── 페이지 헤더 (라우터 뷰 상단) ── */
.page-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; margin-bottom: 18px;
}
.page-title { margin: 0; font-size: calc(20px * var(--f)); letter-spacing: var(--tracking-tight); }
.page-desc { margin: 4px 0 0; font-size: calc(13px * var(--f)); color: var(--fg-muted); }
.grid--users { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }

.page-head__acts { display: flex; gap: 6px; flex: 0 0 auto; }
.backlink {
  display: inline-flex; align-items: center; gap: 5px; margin-bottom: 6px;
  font-size: calc(12px * var(--f)); color: var(--fg-muted); text-decoration: none;
}
.backlink [data-lucide] { width: 14px; height: 14px; }
.backlink:hover { color: var(--fg); }

/* ── 필터 바 ── */
.filters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; align-items: center; }
.filters__search { flex: 1 1 220px; min-width: 180px; }
.filters__sel { flex: 0 0 auto; width: auto; padding-right: calc(28px * var(--u)); }

/* 이 모달은 리포 선택기 때문에 길다. 벤더의 .modal 은 max-height 가 없어 화면이 짧으면
   아래(저장 버튼)가 잘린 채 스크롤도 안 된다. 이 모달만 스크롤되게 둔다.
   48px = .modal-scrim 의 상하 padding 24px. */
#projedit .modal { max-height: calc(100vh - 48px); overflow-y: auto; }

/* ── 리포 선택기 (프로젝트 모달) ── */
/* 리포가 많아 목록이 길어진다. 높이를 고정하고 안에서 스크롤한다. */
.picker {
  margin-top: 8px; max-height: 230px; overflow-y: auto;
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface-2);
}
.picker__row {
  display: flex; align-items: center; gap: 10px;
  padding: calc(9px * var(--u)) calc(12px * var(--u));
  border-bottom: 1px solid var(--border); cursor: pointer;
}
.picker__row:last-child { border-bottom: 0; }
.picker__row:hover { background: var(--surface-3, var(--surface-1)); }
.picker__row input { flex: 0 0 auto; }
/* .grow 는 .item 안에서만 정의돼 있다(app.css). 여기서도 이름 칸이 남는 폭을 먹어야
   배지가 오른쪽 끝으로 밀린다. */
.picker__row .grow { flex: 1; min-width: 0; }
.picker__name { font-size: calc(13px * var(--f)); font-weight: 500; }
.picker__url { font-size: calc(11px * var(--f)); color: var(--fg-subtle); }
.picker__empty { padding: 16px; text-align: center; color: var(--fg-subtle); font-size: calc(13px * var(--f)); }

.btn--danger { color: var(--error); }
.btn--danger:hover { background: color-mix(in srgb, var(--error) 12%, transparent); }

/* ── 설정 모달 ── */
.set-tabs { display: flex; gap: 6px; margin: 4px 0 16px; }
.set-note { margin: 0 0 14px; font-size: calc(13px * var(--f)); color: var(--fg-muted); }
/* 구분선은 행 사이에만. :last-of-type 은 형제 중 마지막 div(=modal__foot)를 짚어
   밀도 행 밑에 줄이 남는다 — 인접 선택자로 둔다. */
.set-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: calc(12px * var(--u)) 0;
}
.set-row + .set-row { border-top: 1px solid var(--border); }
.set-row__label { display: flex; flex-direction: column; gap: 2px; }
.set-row__hint { font-size: calc(12px * var(--f)); color: var(--fg-subtle); }
.set-row .chip { display: inline-flex; align-items: center; gap: 5px; }
.set-row .chip [data-lucide] { width: 14px; height: 14px; }
.live.on { --c: var(--success); color: var(--c);
  background: color-mix(in srgb, var(--c) 14%, transparent);
  border-color: color-mix(in srgb, var(--c) 30%, transparent); }
.seg { display: inline-flex; gap: 6px; }

/* ── 레이아웃 ── */
.wrap { max-width: 1280px; margin: 0 auto; padding: 24px clamp(16px, 3vw, 28px) 80px; }
.grid { display: grid; gap: 16px; }
.grid--kpi { grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); margin-bottom: 20px; }
.grid--main { grid-template-columns: 1.7fr 1fr; align-items: start; }
@media (max-width: 960px) { .grid--main { grid-template-columns: 1fr; } }
.stack { display: flex; flex-direction: column; gap: 22px; }
.stack.sm { gap: 8px; }

.eyebrow.sec {
  display: flex; align-items: center; gap: 7px; margin-bottom: 10px;
  text-transform: uppercase;
}
.eyebrow.sec [data-lucide] { width: 14px; height: 14px; color: var(--fg-subtle); }

/* ── 고정폭 영숫자: JetBrains Mono + 자릿수 정렬(자간·자평 정리) ── */
.mono, .dt-cell--mono, .badge, .eyebrow, .chip, .kpi__value, .kpi__delta, .num, code {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "calt" 0;
}
.mono { font-family: var(--font-mono); font-size: calc(12px * var(--f)); letter-spacing: -0.01em; }

/* ── Ready / 프로젝트 카드 ── */
.item {
  display: flex; align-items: center; gap: 10px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); padding: calc(10px * var(--u)) calc(12px * var(--u));
  cursor: pointer; transition: border-color var(--dur) var(--ease-out);
}
.item:hover { border-color: var(--border-strong); }
.item .grow { flex: 1; min-width: 0; }
.item .t { font-weight: 600; font-size: calc(14px * var(--f)); }
.item .s { color: var(--fg-muted); font-size: calc(12px * var(--f));
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.item [data-lucide] { width: 16px; height: 16px; color: var(--fg-subtle); flex: 0 0 auto; }

/* ── 작업 테이블 행 ── */
.dt-row { cursor: pointer; }
.dt-row.active { background: var(--accent-soft); }

/* ── 상세 패널 ── */
.detail-h { display: flex; align-items: center; gap: 10px; margin: 0 0 4px; }
.detail-h h3 { margin: 0; font-size: calc(16px * var(--f)); letter-spacing: var(--tracking-tight); }
.field { margin: 12px 0; }
.field .k {
  font-family: var(--font-mono); font-size: calc(11px * var(--f));
  letter-spacing: 0.06em; color: var(--fg-subtle); text-transform: uppercase; margin-bottom: 3px;
}
.field .v { color: var(--fg); font-size: calc(14px * var(--f)); word-break: break-word; }
.acts { display: flex; gap: 6px; flex-wrap: wrap; margin: 14px 0 4px; }

/* ── 타임라인 ── */
.timeline { border-left: 2px solid var(--border); margin-top: 8px; padding-left: 14px; display: flex; flex-direction: column; gap: 12px; }
.tl { position: relative; }
.tl::before {
  content: ""; position: absolute; left: -21px; top: 5px; width: 8px; height: 8px;
  border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 3px var(--bg);
}
.tl .line { font-size: calc(13px * var(--f)); }
.tl .when { font-family: var(--font-mono); font-size: calc(11px * var(--f)); color: var(--fg-subtle); margin-top: 2px; }
.tl b { color: var(--fg); }

/* ── 이벤트 피드 ── */
.events { display: flex; flex-direction: column; gap: 0; max-height: 340px; overflow-y: auto; }
.ev { display: flex; align-items: center; gap: 8px; padding: 8px 2px; border-top: 1px solid var(--border); font-size: calc(12px * var(--f)); color: var(--fg-muted); }
.ev:first-child { border-top: none; }
.ev [data-lucide] { width: 13px; height: 13px; color: var(--fg-subtle); flex: 0 0 auto; }
.ev .kind { font-family: var(--font-mono); color: var(--fg); }
.ev .when { margin-left: auto; font-family: var(--font-mono); font-size: calc(11px * var(--f)); color: var(--fg-subtle); }

.muted { color: var(--fg-muted); font-size: calc(13px * var(--f)); }
.empty { color: var(--fg-subtle); font-size: calc(13px * var(--f)); padding: 8px 2px; }

/* review 배지(디자인 시스템에 없는 보라 상태) */
.badge--review { --c: #a78bfa; }

/* 섹션 헤더(제목 + 액션) */
.sec-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.sec-head .eyebrow.sec { margin-bottom: 10px; }
.sec-head .btn [data-lucide] { width: 13px; height: 13px; }

/* 체크박스 라벨 */
.acct-check { display: flex; align-items: center; gap: 8px; font-size: calc(13px * var(--f)); color: var(--fg-muted); cursor: pointer; }
.acct-check input { width: 16px; height: 16px; accent-color: var(--accent); }

/* 검증 결과 */
.verify { display: flex; flex-direction: column; gap: 5px; margin-top: 4px; }
.vrow { display: flex; align-items: center; gap: 7px; font-size: calc(12px * var(--f)); }
.vrow [data-lucide] { width: 14px; height: 14px; flex: 0 0 auto; }
.vrow .vt { color: var(--fg-subtle); flex: 0 0 auto; }
.vrow .vd { color: var(--fg-muted); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v-ok [data-lucide] { color: var(--success); }
.v-bad [data-lucide] { color: var(--error); }
.v-manual [data-lucide] { color: var(--fg-subtle); }

/* 계정 관리 */
.acct-sec { margin-top: 18px; }
.acct-list { display: flex; flex-direction: column; gap: 6px; margin-bottom: 10px; }
.acct-row { display: flex; align-items: center; gap: 10px; padding: 8px 10px; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r-md); }
.acct-row .acct-id { flex: 1; font-weight: 600; font-size: calc(13px * var(--f)); }
.acct-row .btn--sm [data-lucide] { width: 13px; height: 13px; }
.acct-form { display: flex; gap: 6px; align-items: center; }
.acct-form .input { flex: 1; }
.acct-form select.input { flex: 0 0 auto; width: auto; }
.token-new {
  padding: 10px; margin-bottom: 10px; border-radius: var(--r-md);
  background: color-mix(in srgb, var(--success) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--success) 30%, transparent);
  font-size: calc(12px * var(--f)); color: var(--fg); word-break: break-all;
}
.token-new code { display: block; margin: 6px 0; color: var(--accent); font-size: calc(13px * var(--f)); }

/* GitHub 토큰 발급 안내 */
.token-help {
  margin-top: 8px; padding: 12px; border: 1px solid var(--border);
  border-radius: var(--r-md); background: var(--surface-2);
}
.token-help__row { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: calc(13px * var(--f)); color: var(--fg-muted); }
.token-help__row .btn [data-lucide] { width: 14px; height: 14px; }
.token-steps { margin: 10px 0 0; padding-left: 18px; display: flex; flex-direction: column; gap: 4px; font-size: calc(12px * var(--f)); color: var(--fg-muted); }
.token-steps b { color: var(--fg); }
.token-steps code { font-family: var(--font-mono); color: var(--accent); }

/* 설정 폼 라벨 */
.field-label {
  display: inline-block; font-family: var(--font-mono);
  font-size: calc(11px * var(--f)); letter-spacing: 0.06em;
  color: var(--fg-subtle); text-transform: uppercase;
}
#settings .modal__foot { margin-top: 20px; }

/* 새 작업 폼: 2열 그리드 */
.nt-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 520px) { .nt-grid { grid-template-columns: 1fr; } }
#newtask .modal, #project .modal { max-height: 88vh; overflow-y: auto; }
textarea.input { resize: vertical; font-family: inherit; line-height: 1.5; }
textarea.input.mono { font-family: var(--font-mono); font-size: calc(12px * var(--f)); }

/* 주의 필요(정체) 큐 */
.att {
  display: flex; align-items: center; gap: 10px;
  background: var(--surface); border: 1px solid var(--border);
  border-left: 3px solid var(--c, var(--warning));
  border-radius: var(--r-md); padding: calc(9px * var(--u)) calc(12px * var(--u));
  cursor: pointer; transition: border-color var(--dur) var(--ease-out);
}
.att:hover { border-color: var(--border-strong); border-left-color: var(--c, var(--warning)); }
.att--blocked { --c: var(--error); }
.att--stale-progress { --c: var(--warning); }
.att--stale-review { --c: #a78bfa; }
.att .grow { flex: 1; min-width: 0; }
.att .t { font-weight: 600; font-size: calc(14px * var(--f));
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.att .s { color: var(--fg-muted); font-size: calc(12px * var(--f)); display: flex; gap: 6px; align-items: center; }
.att .dwell { font-family: var(--font-mono); font-size: calc(11px * var(--f)); color: var(--c, var(--warning)); flex: 0 0 auto; }
.att [data-lucide] { width: 15px; height: 15px; color: var(--c, var(--warning)); flex: 0 0 auto; }

/* 진행 타임라인 차트 */
.tl-card { margin-bottom: 20px; }
.tl-kpis { display: flex; gap: 24px; flex-wrap: wrap; margin: 12px 0 6px; }
.tl-kpi { display: flex; flex-direction: column; gap: 2px; }
.tl-kpi__v { font-family: var(--font-mono); font-size: calc(20px * var(--f)); font-weight: 600;
  color: var(--fg); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.tl-kpi__l { font-size: calc(11px * var(--f)); letter-spacing: 0.04em; color: var(--fg-subtle); text-transform: uppercase; }
.tl-legend { display: flex; gap: 14px; margin: 6px 0 4px; }
.tl-leg { display: inline-flex; align-items: center; gap: 6px; font-size: calc(12px * var(--f)); color: var(--fg-muted); }
.tl-dot { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }
.tl-dot--done { background: var(--success); }
.tl-dot--act { background: var(--accent); }
.tl-chart { width: 100%; overflow-x: auto; }
.tl-chart svg { display: block; width: 100%; height: auto; }
.tl-bar-act { fill: var(--accent); }
.tl-bar-done { fill: var(--success); }
.tl-axis { fill: var(--fg-subtle); font-family: var(--font-mono); font-size: 10px; }
.tl-grid { stroke: var(--border); stroke-width: 1; }
.tl-hit { fill: transparent; cursor: default; }
.tl-hit:hover + .tl-barwrap .tl-bar-act { fill: var(--accent-hover); }
.tl-tip {
  position: fixed; z-index: 50; pointer-events: none; display: none;
  background: var(--surface-2); border: 1px solid var(--border-strong);
  border-radius: var(--r-md); padding: 7px 10px; box-shadow: var(--shadow-md, 0 4px 16px rgba(0,0,0,.4));
  font-size: calc(12px * var(--f)); color: var(--fg); white-space: nowrap;
}
.tl-tip .tl-tip__t { font-family: var(--font-mono); color: var(--fg-subtle); font-size: calc(11px * var(--f)); margin-bottom: 3px; }
.tl-tip .tl-tip__r { display: flex; align-items: center; gap: 6px; }
.tl-empty { color: var(--fg-subtle); font-size: calc(13px * var(--f)); padding: 24px 4px; text-align: center; }

/* 마일스톤 카드 */
.ms {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); padding: calc(11px * var(--u)) calc(12px * var(--u));
}
.ms__head { display: flex; align-items: center; gap: 8px; }
.ms__title { font-weight: 600; font-size: calc(14px * var(--f)); flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ms__goal { color: var(--fg-muted); font-size: calc(12px * var(--f)); margin: 4px 0 8px; }
.ms__bar { height: 6px; border-radius: 999px; background: var(--surface-2);
  border: 1px solid var(--border); overflow: hidden; }
.ms__fill { height: 100%; background: linear-gradient(90deg, var(--blue-500), var(--blue-700)); transition: width var(--dur) var(--ease-out); }
.ms__meta { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 7px; }
.ms__count { font-family: var(--font-mono); font-size: calc(11px * var(--f)); color: var(--fg-subtle); }
.ms__acts { display: flex; gap: 6px; }
.ms__acts .btn--sm [data-lucide] { width: 13px; height: 13px; }
.badge--signed { --c: var(--success); }

/* 디스패치 도우미 */
#dispatch .modal { max-height: 88vh; overflow-y: auto; }
.dp-tabs { display: flex; gap: 6px; margin: 4px 0 14px; }
.dp-block { margin-bottom: 14px; }
.dp-block__head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
.dp-block__head .btn [data-lucide] { width: 13px; height: 13px; }
.dp-code {
  margin: 0; padding: 12px; border-radius: var(--r-md);
  background: var(--surface-2); border: 1px solid var(--border);
  font-family: var(--font-mono); font-size: calc(12px * var(--f));
  line-height: 1.55; color: var(--fg); white-space: pre-wrap; word-break: break-word;
  max-height: 240px; overflow-y: auto;
}
.dp-note { margin: 6px 0 0; font-size: calc(12px * var(--f)); color: var(--fg-muted); }
.dp-note code, .dp-block__head code { font-family: var(--font-mono); color: var(--accent); }
.dp-copy.copied { color: var(--success); border-color: color-mix(in srgb, var(--success) 40%, transparent); }
.acts .btn [data-lucide] { width: 13px; height: 13px; }

/* 토큰 게이트 아이콘 */
.gate-ico {
  width: 40px; height: 40px; border-radius: 10px; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  color: var(--accent); background: var(--accent-soft);
}
.gate-ico [data-lucide] { width: 20px; height: 20px; }
