/* frontend/assets/css/cost.css — cost.html 블록 레이아웃.
   색 토큰(--cost-series-1~6, --cost-up/warn/down 9개)은 assets/css/theme.css에 있다
   (docs/비용_개발문서/03_데이터계약_표시규칙.md §8-1, 조은솔님 협의 완료 2026-09-18).
   여기서는 이 화면에서만 쓰는 블록 클래스만 정의한다 — theme.css·shell.css는 건드리지 않는다.
   쓸 수 있는 class 목록은 docs/비용_개발문서/04_화면명세_cost.md §1-3이 정본이다. */

h1, h2, h3, p { margin: 0; }
h2 { font-size: 16px; letter-spacing: -.02em; }
h3 { font-size: 15px; }

button, input, select, textarea { font: inherit; }
button, select { cursor: pointer; }
button:disabled { cursor: not-allowed; opacity: .55; }
button:focus-visible, a:focus-visible, select:focus-visible {
  outline: 3px solid var(--sky); outline-offset: 3px;
}
[hidden] { display: none !important; }

.muted { color: var(--muted-foreground); }
.tiny { font-size: 11px; }
.small { font-size: 12px; }

select, input, textarea {
  background: var(--surface); color: var(--foreground);
  border: 1px solid var(--border); border-radius: 7px; padding: 7px 10px;
  min-width: 0; max-width: 100%;
}

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  padding: 8px 12px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface); color: var(--foreground);
  text-decoration: none; font-weight: 600; font-size: 12px;
}
.btn.primary { background: var(--primary); color: var(--surface); border-color: var(--primary); }
[data-theme="dark"] .btn.primary { color: var(--background); }
.btn.yellow { background: var(--yellow); color: var(--cta-text); border-color: var(--yellow); }
.btn.disabled, .btn:disabled { cursor: not-allowed; opacity: .55; }
.button-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 12px; }

/* 탭 */
.tabs { display: flex; gap: 5px; border-bottom: 1px solid var(--border); margin: 20px 0 18px; }
.tabs button {
  background: transparent; border: 0; border-bottom: 3px solid transparent;
  padding: 12px 18px; color: var(--muted-foreground); font-weight: 650;
}
.tabs [aria-selected="true"] { color: var(--primary); border-bottom-color: var(--primary); }

/* 블록 그리드 — 4열, kpi=1칸, 일반=2칸, wide=전체 */
.grid { display: grid; gap: 16px; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.block {
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
  padding: 18px; min-width: 0; grid-column: span 2;
}
.block.kpi { grid-column: span 1; }
.block.wide { grid-column: 1 / -1; }
.block-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; margin-bottom: 14px; }
.block-id { display: block; font-size: 10px; color: var(--muted-foreground); margin-bottom: 3px; }
.kpi .block-head { display: block; }

.value {
  font-size: 29px; line-height: 1.2; font-weight: 750; letter-spacing: -.04em;
  margin: 12px 0 6px; font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}
.kpi .value { font-size: 25px; }
.badge {
  display: inline-flex; align-items: center; gap: 4px;
  border: 1px solid var(--border); background: var(--muted); color: var(--primary);
  font-size: 11px; padding: 3px 7px; border-radius: 5px;
}
.dash { font-size: 27px; line-height: 1; }
.note { font-size: 11px; color: var(--muted-foreground); margin-top: 10px; }
/* 04 §1-3 경고 배너 — 원래 여백이 없어 바로 위 요소(예: CF-001의 meta-grid)와 맞닿아
   보였다(2026-09-19 실사용 중 발견). 패딩·글자 크기도 줄여 전체폭 블록 안에서 덩치가
   과하지 않게 한다 — 문구+버튼 한 줄이면 그 이상 차지할 이유가 없다. */
.warning {
  border-left: 3px solid var(--cost-warn); background: var(--muted); padding: 8px 12px;
  border-radius: 5px; margin-top: 10px; font-size: 12px; line-height: 1.5;
}
.warning + .warning { margin-top: 8px; }
.warning .btn { margin-left: 4px; padding: 3px 9px; font-size: 11px; }

/* 상태 6종(금액 칸을 비우는 상태) 공통 뷰 */
.state-view {
  padding: 16px; background: var(--muted); border-radius: 8px; min-height: 134px;
  display: flex; flex-direction: column; justify-content: center; gap: 9px;
}
.state-view strong { font-size: 16px; }
.state-view .dash { font-size: 27px; line-height: 1; }
.state-view p { font-size: 12px; overflow-wrap: anywhere; }
.state-view .btn { align-self: flex-start; }

.meta-grid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 12px; }
.meta-grid dt { font-size: 11px; color: var(--muted-foreground); margin-bottom: 4px; }
.meta-grid dd { margin: 0; font-size: 12px; font-weight: 600; }
.contract-row {
  padding-top: 10px; margin-top: 10px; border-top: 1px solid var(--border);
  font-size: 11px; color: var(--muted-foreground);
}

.filter-grid { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-end; }
.filter-grid label, .filter-grid .filter-field { display: flex; flex-direction: column; gap: 4px; font-size: 11px; }
/* 시작일·종료일·CSP·계정·통화·요금 분류 — 상자 크기를 모두 맞추고(2026-09-19 요청), 한 줄에
   다 들어오도록 폭도 줄인다(2026-09-19 후속 요청). 고정 너비를 주면 안의 <input>·<select>
   (dropdown.js가 씌운 버튼 포함)·커스텀 드롭다운 div가 전부 column flex의 기본 정렬
   (align-items: stretch)로 그 너비를 그대로 채운다 — 컨트롤마다 따로 폭을 맞출 필요가 없다.
   버튼 여러 개인 "기간 프리셋"은 이 클래스를 붙이지 않는다. */
.filter-grid .filter-box { flex: 0 0 108px; }
/* 필터 줄의 컨트롤 종류가 제각각(button/input[date]/드롭다운 버튼)이라 높이 계산 방식이
   서로 달라 1~3px씩 어긋났다(2026-09-19 발견) — 전부 같은 고정 높이로 맞춘다. */
.filter-grid .btn, .filter-grid input[type="date"], .filter-grid .mc-dd > button { height: 34px; box-sizing: border-box; }
.chip {
  display: inline-flex; align-items: center; background: var(--muted); padding: 4px 8px;
  border-radius: 6px; color: var(--primary); font-size: 11px;
  /* .note·.contract-row와 같은 10px 규칙 — 원래 여백이 없어 바로 위 필터 줄과 붙어 보였다
     (2026-09-19 발견, .warning 때와 같은 종류의 버그). */
  margin-top: 10px;
}

/* CSP·계정처럼 다중 선택이 필요한 필터 — dropdown.js(MCDropdown)는 단일 <select>만 다루므로
   같은 .mc-dd/.mc-dd__menu/.mc-dd__item 모양(다른 화면의 단일 선택 드롭다운과 동일한 룩)을
   재사용해 cost.js가 직접 그린다. 체크박스 없이 행 자체가 선택되면 배경이 강조된다(Tailwind
   유틸리티 클래스는 cost.js가 인라인으로 붙인다). 클래스가 같아서 dropdown.js의 바깥 클릭·Esc
   닫기 전역 리스너가 이 메뉴도 그대로 닫아준다. */

.cloud-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.cloud-card { border: 1px solid var(--border); border-radius: 9px; padding: 14px; }
.cloud-card h3 { display: flex; align-items: center; gap: 8px; }
.dot { display: inline-block; width: 8px; height: 8px; border-radius: 3px; background: var(--primary); }
.dot.gcp { background: var(--sky); }
.dot.azure { background: var(--yellow); }
.status-list { font-size: 11px; display: grid; gap: 6px; margin-top: 12px; }
.status-list div { display: flex; justify-content: space-between; gap: 8px; border-bottom: 1px solid var(--border); padding-bottom: 5px; }
.support { font-size: 11px; margin: 10px 0; color: var(--muted-foreground); }

.table-wrap { width: 100%; overflow: auto; }
table { border-collapse: collapse; width: 100%; font-size: 12px; }
th { text-align: left; background: var(--muted); color: var(--muted-foreground); font-size: 11px; font-weight: 600; }
th, td { padding: 11px 9px; border-bottom: 1px solid var(--border); vertical-align: top; }
td.num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }

.bar-track { height: 6px; background: var(--muted); border-radius: 2px; overflow: hidden; margin-top: 9px; }
.bar-fill { height: 100%; background: var(--primary); }
.service-row { padding: 12px 0; border-bottom: 1px solid var(--border); }
.service-row > div:first-child { display: flex; justify-content: space-between; gap: 10px; }

.chart { display: block; width: 100%; height: auto; color: var(--muted-foreground); font-size: 11px; }
.chart .dot { width: 10px; height: 10px; border-radius: 2px; }
.legend { display: flex; gap: 18px; justify-content: center; flex-wrap: wrap; font-size: 11px; margin: 7px 0; }
.legend .dot { display: inline-block; }

.cta-row { display: flex; align-items: center; justify-content: space-between; gap: 18px; flex-wrap: wrap; }
.paired { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

.source-note { font-size: 10px; margin-top: 12px; color: var(--muted-foreground); }
.money-positive { color: var(--cost-up); }
.money-negative { color: var(--cost-down); }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.print-only { display: none; }

/* 모달 상단 바(#cost-dialog·#agent-chat-modal 공용 — modal.js가 열고 닫는다) */
.dialog-top { display: flex; align-items: center; justify-content: space-between; gap: 20px; }

/* 토스트 — modal.js와 별개로 cost.js가 직접 hidden을 토글한다(PR 6) */
.toast {
  position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%);
  background: var(--foreground); color: var(--background);
  padding: 12px 20px; border-radius: 9px; z-index: 100; font-size: 13px; max-width: 85vw;
}

/* (2026-09-21) 예전엔 넓은 화면에서 추이 3/4 + 분포 1/4로 나눠 도넛이 작았다. 이제 추이는 전체폭,
   분포·증가액이 반폭씩 나란히 — 빈 오른쪽 칸이 생기지 않는다(cost.html 블록 순서 참고). */
@media (max-width: 1050px) {
  .block.kpi { grid-column: span 2; }
  .meta-grid { grid-template-columns: repeat(3, 1fr); }
  .cloud-grid { grid-template-columns: 1fr; }
}
@media (max-width: 760px) {
  .grid { grid-template-columns: 1fr; }
  .block, .block.kpi, #CF-013, #CF-016 { grid-column: 1; }
  .meta-grid { grid-template-columns: 1fr 1fr; }
  .tabs button { padding: 10px 8px; font-size: 12px; }
  .cta-row { display: block; }
  .paired { grid-template-columns: 1fr; }
}

/* ═══════════════════════════════════════════════════════════════════════════════
   2026-09-20 비용 개요 다듬기(seunghyun/fe-cost-polish) — 기존 토큰·컴포넌트만 쓴다.
   ═══════════════════════════════════════════════════════════════════════════════ */

/* 기능 ID(CF-001 등)는 개발 추적용 — DOM엔 남기고 화면에서만 숨긴다 */
.block-id { display: none; }

/* 공통 영역(조회 기준 + 조회 조건)은 카드 두 장이 아니라 한 덩어리처럼 붙여 세로 공간을 줄인다 */
.common-stack { gap: 8px; }
.common-stack .block { padding: 12px 18px; }
.common-stack .block-head { margin-bottom: 8px; }
.common-stack .block-head h2 { font-size: 13px; }
#CF-001 .block-head { display: none; }          /* 조회 기준은 제목 없이 한 줄 요약이 곧 제목이다 */

/* 조회 기준 한 줄 요약 */
.summary-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; font-size: 12px; }
.summary-bar .sb-item { display: inline-flex; align-items: center; gap: 5px; }
.summary-bar .sb-label { color: var(--muted-foreground); }
.summary-bar .sb-value { font-weight: 650; font-variant-numeric: tabular-nums; }
.summary-bar .button-row { margin: 0 0 0 auto; }
.summary-bar .btn { padding: 6px 10px; }
.summary-bar .busy { color: var(--muted-foreground); }

/* 원인별 경고 — 경고는 최대 2줄, 나머지는 "상세 보기" */
.warning-list { display: grid; gap: 6px; margin-top: 8px; }
.warning-list .warning { margin-top: 0; }
.warning.info { border-left-color: var(--sky); }

/* 접이식 조회 조건 — 접혀 있어도 적용된 조건·오류는 항상 보인다 */
.filter-panel > summary { list-style: none; cursor: pointer; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.filter-panel > summary::-webkit-details-marker { display: none; }
.filter-panel > summary .chip { max-width: 100%; white-space: normal; }
.filter-panel > summary .toggle { margin-left: auto; }
.filter-panel[open] > summary .toggle::after { content: " ▴"; }
.filter-panel:not([open]) > summary .toggle::after { content: " ▾"; }
.filter-panel .filter-grid { margin-top: 12px; }
.filter-dirty { color: var(--cost-warn); font-weight: 600; }
.filter-error { color: var(--cost-up); }
.filter-grid .input-error { border-color: var(--cost-up) !important; }

/* KPI 카드 — 제목/금액/배지/근거/보조 행동의 세로 순서를 고정한다 */
.kpi .value { margin: 8px 0 4px; }
.kpi .kpi-basis { font-size: 11px; color: var(--muted-foreground); margin-top: 6px; line-height: 1.5; }
.kpi .kpi-note { font-size: 11px; margin-top: 6px; }
.kpi .button-row { margin-top: 10px; }
.kpi .badge.est { color: var(--cost-warn); }

/* 계정별 비용 및 수집 상태 — 데스크톱 표 */
.account-table th, .account-table td { padding: 9px 8px; vertical-align: middle; }
.account-table td.num { font-weight: 650; }
/* "행동" 버튼은 옆 칼럼들이 넓어지며 좁아져도 여러 줄로 깨지지 않는다 — 표가 컨테이너보다
   넓어지면 .table-wrap이 가로 스크롤을 대신 낸다(이미 있는 패턴). */
.account-table td.actions .btn { white-space: nowrap; }
/* CF-018 계정별 비용 표 — auto 표 레이아웃에서는 칸 하나를 내용 폭으로 줄일 때마다(계정→
   행동→기간 비용 순으로 시도) "표는 항상 컨테이너 폭 100%를 채워야 한다"는 규칙 때문에 그
   남는 폭이 매번 옆의 다른 칸으로 옮겨붙었다(계정↔기간 비용, 기간 비용↔비중 사이가 번갈아
   벌어짐). table-layout:fixed로 바꿔 다섯 칸 모두 고정 rem 폭을 주더라도, 표 자체의 width가
   여전히 100%(공용 table 규칙)면 그 다섯 폭의 합보다 컨테이너가 넓을 때 브라우저가 남는 폭을
   다시 칼럼들에 나눠 줘 버린다 — width:auto로 바꿔도 마찬가지였다(이 표의 shrink-to-fit
   계산이 기대와 달리 컨테이너 폭에 그대로 맞춰졌다). 그래서 표 폭 자체를 다섯 칼럼 합계와
   똑같은 절대값(62rem)으로 못박는다 — 컨테이너가 이보다 넓어도 표는 62rem 그대로이고, 더
   좁으면 늘 있던 .table-wrap 가로 스크롤로 넘어간다(칸이 짓눌리지 않는다). */
.account-cost-table { table-layout: fixed; width: 62rem; }
.account-cost-table .account-name-cell { width: 17rem; white-space: nowrap; }
.account-cost-table .account-period-cell { width: 12rem; }
.account-cost-table .account-share-col { width: 20rem; }
.account-cost-table .account-team-cell { width: 4rem; white-space: nowrap; }
.account-cost-table .account-actions-cell { width: 9rem; white-space: nowrap; }
/* CF-018 계정별 비용 — 헤더는 기본이 왼쪽 정렬이라 오른쪽 정렬인 금액 칸과 제목 위치가 어긋나
   보였다. td.num처럼 헤더도 num을 붙이면 오른쪽 기준으로 맞는다(값이 없는 다른 account-table
   헤더는 num을 안 붙이므로 영향 없음). */
.account-table th.num { text-align: right; }
/* "비중" 칸 — 바를 퍼센트 왼쪽에 두는 한 줄 배치(inline-flex). 퍼센트는 고정 폭(.pct-value)으로
   예약해 둬서 칼럼이 좁아져도 잘리거나 바와 겹치지 않는다. */
.account-share-cell { display: inline-flex; align-items: center; justify-content: flex-end; gap: 6px; width: 100%; }
.account-share-cell .pct-value { display: inline-block; min-width: 3.4em; text-align: right; }
.account-table .account-share-cell .bar-track { max-width: 140px; flex: 1 1 auto; margin-top: 0; }
.provider-cell { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; vertical-align: middle; }
.provider-logo { height: 14px; width: auto; flex: none; }
.account-table .status-cell { display: flex; flex-direction: column; gap: 2px; }
.account-table .status-cell .tiny { line-height: 1.4; }
.account-table td .btn { padding: 5px 9px; font-size: 11px; }
.status-tag { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 600; }
.status-tag::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--muted-foreground); flex: 0 0 auto; }
.status-tag.data::before { background: var(--cost-down); }
.status-tag.attention::before { background: var(--cost-up); }
.status-tag.unsupported::before { background: var(--muted-foreground); }
.status-tag.waiting::before { background: var(--cost-warn); }

/* 준비 중 블록은 KPI와 같은 덩치로 반복하지 않는다 */
.pending-note { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--muted-foreground); padding: 6px 0; }

/* CF-007 Owner 미지정 리소스 모달 — "정가 추정" 칼럼이 .changes-table td.num의 white-space:
   nowrap을 그대로 물려받아 "정가표에 없음 — 카드 금액에 미포함(0원 아님)" 한 문장이 한 줄로
   퍼지면서 옆 "행동" 칼럼(인벤토리에서 보기 버튼)이 밀려 깨졌다. price-unknown은 JS에서 이미
   <br>로 "정가표에 없음" / "카드 금액에 미포함(0원 아님)" 두 줄로 고정해 보내므로, 여기서는
   그 줄바꿈이 실제로 적용되게 nowrap을 풀어주고 칼럼 폭에 상한만 둔다. 13rem은 2번째 줄(가장
   긴 줄, 실측 188px + 좌우 패딩 18px)이 한 줄에 다 들어가고도 옆 칼럼에 여유가 남는 값이다 —
   이보다 좁으면 "아님)"이 세 번째 줄로 밀려 다시 깨진다. 버튼은 폭이 줄어도 항상 한 줄로 남긴다. */
.unassigned-table th:nth-child(3), .unassigned-table td:nth-child(3) { max-width: 13rem; }
.unassigned-table .price-unknown { white-space: normal; display: inline-block; }
.unassigned-table td.actions .btn { white-space: nowrap; }

/* 모바일: 표를 세로 카드로 */
@media (max-width: 720px) {
  .summary-bar .button-row { margin-left: 0; width: 100%; }
  .account-table thead { display: none; }
  .account-table tr { display: block; border: 1px solid var(--border); border-radius: 9px; padding: 8px 10px; margin-bottom: 8px; }
  .account-table td { display: flex; justify-content: space-between; gap: 10px; border: 0; padding: 4px 0; text-align: left; }
  .account-table td.num { text-align: right; }
  .account-table td::before { content: attr(data-label); color: var(--muted-foreground); font-size: 11px; flex: 0 0 auto; }
  .account-table td.actions { justify-content: flex-start; padding-top: 8px; }
  .account-table td.actions::before { content: none; }
  .filter-grid .filter-box { flex: 1 1 140px; }
  /* CF-018 표는 데스크톱에서만 table-layout:fixed·칼럼별 고정 rem 폭을 쓴다(카드 레이아웃까지
     새어 들어가면 각 칸이 좁은 카드 폭보다 넓은 rem 값을 그대로 고집해 "prod-aws-01"·결측
     안내·버튼이 카드 밖으로 넘친다). 카드 레이아웃에서는 tr/td가 block·flex이므로 표 자체는
     auto로 되돌리고, 칸별 폭·nowrap도 모두 되돌린다 — 데스크톱 규칙(.account-cost-table
     .xxx-cell)과 명시도를 맞춰야 이 규칙이 실제로 이긴다(클래스 하나짜리로는 미디어쿼리
     안이어도 안 이긴다). */
  .account-cost-table { table-layout: auto; width: 100%; }
  .account-cost-table .account-name-cell { width: auto; white-space: normal; }
  .account-cost-table .account-period-cell { width: auto; }
  .account-cost-table .account-share-col { width: auto; }
  .account-cost-table .account-team-cell { width: auto; white-space: normal; }
  .account-cost-table .account-actions-cell { width: auto; white-space: normal; }
}

/* ═══ ② 비용 분석 탭 (2026-09-21) ═══ */
/* 기간 비교 — 압축 스트립: 이전 / 현재 / 증감 세 칸 */
.compare-strip { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 12px; align-items: end; }
.compare-strip .cs-label { font-size: 11px; color: var(--muted-foreground); }
.compare-strip .value { margin: 4px 0 0; font-size: 22px; }
.compare-strip .cs-delta .value { font-size: 20px; }
.compare-compact { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; font-size: 12px; }

/* 서비스별 분포 — 가로 막대 목록(이름·금액·비중을 한 줄에서 읽는다) */
.share-list { display: grid; gap: 8px; }
.share-row { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 4px 10px; align-items: center; font-size: 12px; }
.share-row .sr-name { min-width: 0; overflow-wrap: anywhere; }
.share-row .sr-amount { font-variant-numeric: tabular-nums; white-space: nowrap; text-align: right; }
.share-row .sr-pct { width: 52px; text-align: right; font-variant-numeric: tabular-nums; color: var(--muted-foreground); }
.share-row .bar-track { grid-column: 1 / -1; margin-top: 0; height: 8px; }
.share-row.residual .bar-fill { background: var(--muted-foreground); }
.share-row.residual .sr-name { color: var(--muted-foreground); }

/* 증가액 표 — 서비스명 열은 줄바꿈, 숫자 열은 오른쪽 정렬·고정폭 숫자 */
.changes-table td.num, .changes-table th.num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.changes-table td:first-child { min-width: 9rem; word-break: keep-all; overflow-wrap: anywhere; }
/* 한글 단어는 통째로(keep-all), 끊을 데 없는 긴 영문 서비스명(AmazonCloudFront 등)만 접는다 —
   4단계 실측: 반폭 카드에서 표가 120px 넘쳐 가로로 스크롤되던 것을 줄인다. 그래도 넘치면 .table-wrap 안에서만 스크롤된다. */
.sub-amount { display: block; font-size: 11px; color: var(--muted-foreground); }

/* 집계 단위 토글 — 눌린 버튼 */
.btn[aria-pressed="true"] { background: var(--primary); color: var(--surface); border-color: var(--primary); }

@media (max-width: 720px) {
  .compare-strip { grid-template-columns: 1fr; }
}

/* (2026-09-21 마무리) 분석 탭 카드는 옆 카드 높이에 맞춰 늘리지 않는다 — 빈 표 아래 큰 여백 방지 */
#panel-analysis.grid { align-items: start; }
/* 차트: viewBox 너비 = 실제 픽셀 너비라 height:auto가 곧 설계 높이(200~260px)다. 비율은 왜곡하지 않는다 */
.chart { max-width: 100%; }

/* ═══ ③ 예산·검토 탭 (2026-09-21) ═══ */
.start-guide { display: grid; gap: 10px; }
.start-steps { margin: 0; padding-left: 20px; display: grid; gap: 6px; font-size: 12px; }
.start-steps li::marker { color: var(--primary); font-weight: 700; }
.budget-form > summary { list-style: none; }
.budget-form > summary::-webkit-details-marker { display: none; }
.budget-form > summary::after { content: " ▾"; color: var(--muted-foreground); }
.budget-form[open] > summary::after { content: " ▴"; }
.budget-form .filter-grid { margin-top: 10px; }
.budget-form .filter-grid .filter-box { flex: 1 1 120px; }
/* CF-025 예산 설정 표 — 첫 칼럼은 "주기"(월간·분기·연간·사용자 지정 4종뿐)라 짧다. 공용
   .changes-table의 첫 칼럼 min-width: 9rem은 원래 리소스·서비스 이름처럼 긴 텍스트용이라,
   이 표에 그대로 두면 팀 생성 후 값이 채워질 때 적용 시작·종료·한도·상태 칼럼이 좁아져
   글자가 깨진다 — 이 표만 첫 칼럼 폭을 내용에 맞게 줄인다(다른 칼럼 폭은 그대로 둔다). */
#CF-025 .changes-table td:first-child, #CF-025 .changes-table th:first-child {
  min-width: 0; width: 1%; white-space: nowrap;
}
/* ③ 마무리(2026-09-21): 팀 삭제 확인 박스·상태 태그가 status-list 안에서도 정렬되게 */
#team-delete-confirm { margin-top: 10px; }
.status-list .status-tag { justify-content: flex-end; }
/* 배지 여러 개를 나란히 — 붙지 않게 gap, 좁으면 줄바꿈 */
.status-row { display: flex; flex-wrap: wrap; gap: 6px 16px; margin-bottom: 8px; }

/* 조회 중: 이전 조건의 숫자가 새 조건 결과처럼 읽히지 않게 흐리게 + 블록마다 표시. 값은 지우지 않는다(04 §3-2). */
.block-content[aria-busy="true"] { opacity: .55; position: relative; }
.block-content[aria-busy="true"]::after { content: "조회 중…"; position: absolute; top: 0; right: 0; font-size: 11px; color: var(--muted-foreground); background: var(--surface); padding: 1px 6px; border-radius: 4px; }
/* CF-018 통화별 묶음 머리줄 */
.account-table tr.group-head td,
.changes-table tr.group-head td { background: var(--muted); font-weight: 600; font-size: 12px; }
.account-table td .bar-track { max-width: 120px; margin-top: 4px; }


/* ── 4단계: ① 개요 KPI 그룹 ─────────────────────────────────────────────────────
   카드를 늘리지 않고 그룹 제목으로만 "실측 / 정가 추정"을 가른다. 그룹은 4열 그리드에서 2열을
   차지해 두 그룹이 한 줄에 들어가고, 안에서 카드 2장이 다시 나뉜다. 좁아지면 그룹이 전폭이 되고
   그다음 카드가 세로로 쌓인다(기존 중단점과 같은 값). */
.kpi-group { grid-column: span 2; display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.kpi-group-title { margin: 0; font-size: 12px; font-weight: 700; color: var(--muted-foreground); letter-spacing: -.01em; }
.kpi-group-note { margin: 0 0 2px; font-size: 11px; color: var(--muted-foreground); line-height: 1.5; }
.kpi-group-cards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; align-items: stretch; }
.kpi-group-cards .block { height: 100%; }
@media (max-width: 1050px) { .kpi-group { grid-column: 1 / -1; } }
@media (max-width: 760px) { .kpi-group-cards { grid-template-columns: 1fr; } }
/* 카드 제목 아래 범위 배지 — "이 카드의 값이 어느 기간·어느 기준인가"를 제목과 분리해 적는다 */
.kpi .kpi-scope { margin-top: 2px; }

/* CF-018 — 금액 없는 행은 맨 뒤(03 §8). 순위 행과 구분되게 톤만 낮추고 지우지는 않는다 */
.account-table tr.no-amount td { color: var(--muted-foreground); }
.account-table tr.no-amount-fold td { background: transparent; padding: 6px 0; }

/* 5단계: 조건 링크 복사 — 자동 복사가 막힌 브라우저에서 주소를 직접 고를 수 있게 */
.share-url { width: 100%; margin-top: 6px; font-size: 11px; padding: 4px 6px; border: 1px solid var(--border); border-radius: 5px; background: var(--surface); color: var(--foreground); }
