/* ===== 채팅 문서 카드 패널 (BD-C1 Phase 1) =====
   .artifact-card(chat.css:350, background: var(--surface-panel)) 안에 붙는 문서 상태 패널.
   부모 카드가 이미 테두리·그림자·패딩을 갖고 있으므로 여기서는 상자를 한 겹 더 그리지 않고
   구분선 + 미묘한 표면 톤만 쓴다 — 카드 안의 카드는 채팅 흐름에서 소음이다.

   프리미티브 재선언 금지: .ui-btn 베이스(ui-primitives.css)의 appearance/cursor/focus-visible
   reset 을 이 시트에서 다시 선언하지 않는다. Phase 2 가 액션 버튼을 추가할 때도 마찬가지다 —
   sizing/shape 특수화만 허용된다(ui-primitives-guard.test.ts 계약 1).

   토큰만 쓴다: test/css-token-guard.test.ts 는 public/css 를 글롭하므로(:67-72) 이 시트는
   생성 즉시 raw hex·raw rgba·named color·미정의 var 네 규칙에 편입된다. */

/* 문서 카드는 일반 아티팩트 카드(max-width 400px, chat.css:552)보다 넓다 — 본문 폼의 필수
   필드 10개+ 가 400px 에서는 어떤 그리드로도 1열로 접힌다(2026-08-29 사용자 실측 "한 행 한 행").
   :has(.bdc-panel) 게이팅은 아래 파일 링크 흡수 절(:184)과 같은 선례다 — JS 가 클래스를 붙일
   필요가 없다. */
.artifact-card:has(.bdc-panel) {
  max-width: 560px;
}

.bdc-panel {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border-light);
}

.bdc-panel-head {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

/* 초안 배지는 아티팩트 스냅샷 사실(payload.isDraft)이다 — 문서의 현재 상태 pill 옆에 서지만
   같은 어휘가 아니므로 pill 모양을 흉내내지 않는다. 대문자 라틴 라벨 + 경고 톤. */
.bdc-draft-badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 6px;
  border: 1px solid var(--status-warning-border);
  border-radius: var(--radius-sm);
  background: var(--warning-soft);
  color: var(--warning);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  line-height: 1.2;
}

/* ===== 여정 스테퍼 (UX 개편 P2) =====
   상태 pill 을 정상 경로 4걸음(초안 → 승인 대기 → 승인 → 발행)으로 편다. void·미지 상태·
   로딩·실패는 pill 폴백 그대로다. 현재 걸음 라벨은 상태 라벨(_STATE_LABELS)이라
   "입력 필요" 같은 어휘가 사라지지 않는다. */
.bdc-stepper {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 2px 0;
  padding: 2px 0;
}

.bdc-step {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}

.bdc-step-node {
  display: inline-flex;
  width: 13px;
  height: 13px;
  border: 1.5px solid var(--border);
  border-radius: var(--radius-full);
  background: var(--surface-panel);
  flex: 0 0 auto;
}

.bdc-step-label {
  font-size: 10.5px;
  font-weight: 500;
  color: var(--text-muted);
  white-space: nowrap;
}

.bdc-step[data-step-state="done"] > .bdc-step-node {
  border-color: var(--accent);
  background: var(--accent);
}

.bdc-step[data-step-state="done"] > .bdc-step-label {
  color: var(--muted);
}

.bdc-step[data-step-state="now"] > .bdc-step-node {
  border-color: var(--accent);
  background: var(--accent);
  box-shadow: inset 0 0 0 2.5px var(--surface-panel);
}

.bdc-step[data-step-state="now"] > .bdc-step-label {
  color: var(--text);
  font-weight: 700;
}

.bdc-step-conn {
  width: 14px;
  height: 1.5px;
  margin: 0 5px;
  background: var(--border);
  flex: 0 0 auto;
}

.bdc-step-conn[data-done="true"] {
  background: var(--accent);
  opacity: 0.5;
}

/* ===== 완성도 카운터 (P3) =====
   왜 지금 액센트가 [수정]인지(또는 [승인 요청]인지)를 설명하는 한 줄. 미완성은 주의 톤,
   완성은 성공 톤 — 비어 있는 것은 고장이 아니라 아직 하지 않은 일이다(폼 미입력 표시와 동일). */
.bdc-progress {
  font-size: 11.5px;
  line-height: 1.45;
}

.bdc-progress[data-bdc-complete="false"] {
  color: var(--warning);
  font-weight: 600;
}

.bdc-progress[data-bdc-complete="true"] {
  color: var(--success);
}

.bdc-meta {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.bdc-meta-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 12px;
  line-height: 1.4;
}

.bdc-meta-label {
  flex: 0 0 auto;
  min-width: 48px;
  color: var(--muted);
}

.bdc-meta-value {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--text);
  overflow-wrap: anywhere;
}

/* 번호 부재의 의미는 상태마다 다르다(inbox.ts:111-118).
   expected = 설계된 정상이라 조용히, pending = 곧 닫혀야 할 창, anomaly = 발행 사고다.
   같은 회색으로 그리면 셋이 한 표기로 붕괴한다. */
.bdc-meta-value[data-unassigned="expected"] {
  color: var(--muted);
}

.bdc-meta-value[data-unassigned="pending"] {
  color: var(--warning);
}

.bdc-meta-value[data-unassigned="anomaly"] {
  color: var(--error);
  font-weight: 600;
}

/* 로딩·실패 문구. 실패해도 부모 카드의 제목과 PDF 링크는 그대로 남으므로
   패널만 조용히 무엇이 안 됐는지 말한다. */
.bdc-message {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.45;
}

.bdc-draft-warning {
  padding: 6px 8px;
  border-radius: var(--radius-sm);
  background: var(--warning-soft);
  color: var(--warning);
  font-size: 11px;
  line-height: 1.45;
}

/* ===== 액션 스트립 (BD-C1 Phase 2) =====
   프리미티브 재선언 금지: .ui-btn(ui-primitives.css:20-44)이 appearance / cursor / font /
   transition / :focus-visible / :disabled 를 이미 소유한다. 여기서는 sizing·shape·color 만
   특수화한다 — 그것이 .ui-btn 베이스가 색을 선언하지 않는 이유다. */

/* 스트립 문법(P1, 사용자 승인 2026-08-29): 보조·후퇴는 왼쪽, 전진 액센트는 오른쪽 끝.
   구조 변경 없이 .bdc-action-primary 의 margin-left:auto 가 양끝 정렬을 만든다 —
   어느 상태에서든 "오른쪽 끝 = 다음 단계" 가 성립한다. */
.bdc-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-top: 2px;
}

/* 반려 미니폼이 열려 있는 동안 스트립을 숨긴다(P5). display:flex 가 UA [hidden] 규칙을
   이기므로 여기서 명시적으로 닫는다. */
.bdc-actions[hidden] {
  display: none;
}

.bdc-action-btn {
  padding: 5px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-panel);
  color: var(--text);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.3;
  text-decoration: none;
  white-space: nowrap;
}

.bdc-action-btn:hover:not(:disabled) {
  background: var(--bg-hover);
}

/* 단일 액센트는 "다음에 통제할 수 있는 행동" 하나에만 쓴다(design tokens §Signature).
   상태마다 강조 액션은 하나뿐이다 — 두 개를 강조하면 어느 쪽이 다음 단계인지 사라진다. */
.bdc-action-primary {
  margin-left: auto;
  border-color: var(--accent);
  background: var(--accent);
  color: var(--text-on-card);
}

.bdc-action-primary:hover:not(:disabled) {
  border-color: var(--accent-hover);
  background: var(--accent-hover);
}

/* 후퇴·파기(반려·폐기)는 조용한 위험 톤(P1) — 전진 액센트와 시각적으로 분리해
   승인·반려 오클릭 인접성을 없앤다. 배경은 중립 그대로, 글자색만 가른다. */
.bdc-action-danger {
  color: var(--error);
}

/* 다운로드 불가 사유·발행 안내처럼 실패가 아닌 상태 설명. 오류 톤을 쓰지 않는다 —
   초안 스냅샷 카드는 고장난 것이 아니라 설계된 정상이다. */
.bdc-notice {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.45;
}

/* 액션 실패는 카드 안에 남긴다. 토스트만 쓰면 방에 카드가 여럿일 때 어느 카드의 실패인지
   사라진다(§6). */
.bdc-action-error {
  padding: 6px 8px;
  border: 1px solid var(--status-error-border);
  border-radius: var(--radius-sm);
  background: var(--error-soft);
  color: var(--error);
  font-size: 12px;
  line-height: 1.45;
}

.bdc-missing-list {
  margin: 4px 0 0;
  padding-left: 16px;
}

/* ===== 반려 표시 (라운드2) =====
   반려로 돌아온 문서의 카드가 사유를 직접 그린다 — "작성자에게 전달되고" 라는 미니폼의
   약속을 카드가 지키는 자리다. 사건(반려)이므로 미입력(주의 톤)과 다른 오류 톤을 쓴다. */
.bdc-rejected-note {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 6px 8px;
  border: 1px solid var(--status-error-border);
  border-radius: var(--radius-sm);
  background: var(--error-soft);
}

.bdc-rejected-title {
  color: var(--error);
  font-size: 11px;
  font-weight: 700;
}

.bdc-rejected-reason {
  color: var(--text);
  font-size: 12px;
  line-height: 1.45;
  overflow-wrap: anywhere;
}

/* ===== 반려 사유 미니폼 (P5) =====
   window.prompt 를 대체하는 카드 안 인라인 폼. 이력에 영속되는 값을 받으므로 여러 줄
   textarea 를 준다. 열려 있는 동안 액션 스트립은 [hidden] 으로 자리를 비켜 준다. */
.bdc-reject-form {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px;
  border: 1px solid var(--status-error-border);
  border-radius: var(--radius-sm);
  background: var(--surface-panel);
}

.bdc-reject-title {
  font-size: 11px;
  font-weight: 600;
  color: var(--error);
  line-height: 1.4;
}

.bdc-reject-reason {
  min-height: 44px;
  resize: vertical;
}

.bdc-reject-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* 반려 확정은 위험 톤 확정 버튼 — 액센트(전진)와 구분한다. */
.bdc-reject-confirm {
  border-color: var(--status-error-border);
  background: var(--error-soft);
  color: var(--error);
  font-weight: 600;
}

/* ===== 이동 안내 (P6) =====
   같은 문서의 새 카드가 도착해 패널이 은퇴한 자리에 남는 한 줄. 오류 톤이 아니다 —
   설계된 정상이고, 최신 카드의 위치만 가리킨다. */
.bdc-moved-note {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--border-light);
  color: var(--muted);
  font-size: 11.5px;
  line-height: 1.4;
}

/* 기존 파일 링크 흡수 (§5).
   chat.ts:574 renderArtifactFileLink 의 <a class="artifact-card-file"> 는 이 트랙 이전의
   동작이라 상태로 게이팅하지 않는다. 다만 패널이 명시적 다운로드 버튼을 소유하면 같은 카드에
   다운로드 어포던스가 둘로 보이므로, 링크 쪽의 액센트 색과 밑줄을 걷어 제목 줄로 되돌린다.
   기능(클릭 시 열림)은 그대로다 — 시각적 흡수만 한다. */
.artifact-card:has(.bdc-panel) .artifact-card-file {
  color: var(--muted);
  font-size: 12px;
}

.artifact-card:has(.bdc-panel) .artifact-card-file:hover {
  text-decoration: none;
  color: var(--text);
}

/* ===== 본문 입력 폼 (BD-C1 Phase 3) =====
   [수정] 이 카드 **안에서** 펼치는 인라인 폼이다. 모달이 아닌 이유는 카드가 대화 맥락 안에
   있어야 하기 때문이고, 그래서 이 블록도 상자를 한 겹 더 그리지 않고 구분선 + 표면 톤만 쓴다
   (.bdc-panel 이 같은 이유로 그렇게 했다).

   프리미티브 재선언 금지: 폼 버튼은 .ui-btn 을 그대로 쓰고 여기서는 sizing/shape 만 특수화한다.
   토큰만 쓴다 — css-token-guard.test.ts 가 public/css 를 글롭한다. */

.bdc-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 8px;
  padding-top: 10px;
  border-top: 1px solid var(--border-light);
}

.bdc-form-fields {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* 칸을 2열(좁으면 1열)로 흘린다 — 세로 1열 나열은 필수 필드 10개+ 에서 카드를 화면 밖으로
   밀어낸다(2026-08-29 사용자 실측). 열 수를 고정하지 않고 auto-fill 로 두는 이유: 카드 폭이
   방/패널 상태에 따라 달라지므로 고정 2열은 좁은 폭에서 입력을 짓누른다. */
.bdc-form-section {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 6px 12px;
}

.bdc-form-section-title {
  grid-column: 1 / -1;
  color: var(--muted);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
}

/* details/summary 는 브라우저 기본 마커를 그대로 둔다 — 접힘 어포던스를 다시 발명하지 않는다.
   그리드(.bdc-form-section)는 details 가 아니라 안쪽 본문 div 에 있다 — Chrome 의
   ::details-content 래퍼가 details 직속 그리드를 무력화해 펼쳤을 때 1열로 쌓이기 때문이다. */
.bdc-form-filled > .bdc-form-section-title {
  cursor: pointer;
}

.bdc-form-filled > .bdc-form-section {
  margin-top: 6px;
}

.bdc-field {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.bdc-field-label {
  color: var(--muted);
  font-size: 11px;
  line-height: 1.3;
}

/* 미입력 항목은 "아직 비어 있는 항목" 섹션에 모이지만, 배열 행 안에서는 섹션이 나눠지지
   않으므로 칸 자체에도 표시가 필요하다. 오류 톤이 아니라 주의 톤이다 — 비어 있는 것은
   고장이 아니라 아직 하지 않은 일이다. */
.bdc-field[data-bdc-missing="true"] > .bdc-field-label {
  color: var(--warning);
  font-weight: 600;
}

.bdc-field-input {
  width: 100%;
  min-width: 0;
  padding: 4px 7px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-panel);
  color: var(--text);
  font-family: inherit;
  font-size: 12px;
  line-height: 1.4;
}

.bdc-field-input:focus-visible {
  border-color: var(--accent);
  outline: none;
}

.bdc-field-textarea {
  min-height: 54px;
  resize: vertical;
}

.bdc-form-array {
  display: flex;
  flex-direction: column;
  gap: 6px;
  /* 섹션 그리드 안에서 배열 그룹(품목·지급 일정 등)은 전폭이다 — 행 내부가 자체 2열이다. */
  grid-column: 1 / -1;
}

/* 안내문("모두 채워져 있습니다" 등)도 칸 하나로 접히면 문장이 세로로 꺾인다. */
.bdc-form-section > .bdc-form-note {
  grid-column: 1 / -1;
}

.bdc-form-array-title {
  color: var(--text);
  font-size: 12px;
  font-weight: 600;
}

/* 배열 한 행은 patch 에서 통째로 다시 실린다(배열 전체 교체). 그 단위가 눈에 보이도록
   행마다 옅은 표면을 준다 — 어디까지가 한 줄인지 모르면 "행 삭제" 가 무엇을 지우는지 모른다.
   행 안의 칸도 섹션과 같은 2열 흐름이다(품목 한 행 = 필드 7개). */
.bdc-form-row {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  grid-column: 1 / -1;
  gap: 5px 12px;
  padding: 7px 8px;
  border: 1px solid var(--border-light);
  border-radius: var(--radius-sm);
  background: var(--surface-panel-soft);
}

.bdc-form-row-title {
  grid-column: 1 / -1;
  color: var(--muted);
  font-size: 11px;
  font-weight: 600;
}

/* 긴 입력(textarea 등)은 열 흐름에서 빼 전폭을 쓴다 — 폼 스크립트가 서술자 kind 로 마킹한다. */
.bdc-field[data-bdc-wide="true"] {
  grid-column: 1 / -1;
}

/* 행 삭제 버튼은 칸 흐름을 끊고 제 줄에 둔다 — 칸 옆에 끼면 어떤 칸의 버튼처럼 읽힌다. */
.bdc-form-row > .bdc-form-row-remove {
  grid-column: 1 / -1;
  justify-self: start;
}

/* 서버가 형식 위반으로 되돌린 칸(invalid_body fields). 비어 있음(주의 톤)과 달리 이것은
   고쳐야 저장되는 상태라 오류 톤을 쓴다. */
.bdc-field[data-bdc-invalid="true"] > .bdc-field-label {
  color: var(--error);
  font-weight: 600;
}

.bdc-field[data-bdc-invalid="true"] > .bdc-field-input {
  border-color: var(--status-error-border);
  background: var(--error-soft);
}

.bdc-form-btn {
  align-self: flex-start;
  padding: 4px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-panel);
  color: var(--text);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.3;
  white-space: nowrap;
}

.bdc-form-btn:hover:not(:disabled) {
  background: var(--bg-hover);
}

/* 저장이 이 폼의 단일 액센트다 — 줄 추가·행 삭제·취소는 전부 중립으로 남는다
   (design tokens §Signature: 액센트는 "다음에 통제할 수 있는 행동" 하나에만). */
.bdc-form-save {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--text-on-card);
}

.bdc-form-save:hover:not(:disabled) {
  border-color: var(--accent-hover);
  background: var(--accent-hover);
}

/* 하단 우측 정렬(2026-08-30 사용자 결정): [닫기] [저장] [승인 요청]. 전진이 오른쪽 끝 —
   카드 스트립과 같은 문법이다. */
.bdc-form-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 6px;
}

/* 폼 하단의 전진 버튼 — 저장(액센트 채움)과 구분되는 외곽 액센트. 액션 하나가 아니라
   "저장하고 다음 단계로" 라는 복합 행동이라 채움 액센트를 저장과 다투게 하지 않는다. */
.bdc-form-submit {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--surface-panel);
  font-weight: 600;
}

.bdc-form-submit:hover:not(:disabled) {
  background: var(--accent-light);
}

/* 자동 계산 값은 입력이 아니다 — 서버가 저장 시점에 다시 계산해 덮으므로 폼은 표시만 하고
   patch 에 싣지 않는다. 입력 칸과 같은 상자를 주면 고칠 수 있는 값으로 읽힌다. */
.bdc-form-derived {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 6px 8px;
  border-radius: var(--radius-sm);
  background: var(--surface-panel-muted);
}

.bdc-form-derived-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  font-size: 12px;
  line-height: 1.4;
}

.bdc-form-derived-value {
  color: var(--text);
  overflow-wrap: anywhere;
}

.bdc-form-note {
  color: var(--muted);
  font-size: 11px;
  line-height: 1.45;
}

/* 저장 성공 + 미입력 잔존 안내(P4). 폼이 닫히지 않았음을 성공 톤으로 말한다 —
   오류 상자와 별개 요소라 다음 저장의 실패와 상자를 다투지 않는다. */
.bdc-form-saved {
  padding: 6px 8px;
  border: 1px solid var(--status-warning-border);
  border-radius: var(--radius-sm);
  background: var(--warning-soft);
  color: var(--warning);
  font-size: 12px;
  line-height: 1.45;
}

.bdc-form-saved[data-bdc-visible="false"] {
  display: none;
}

/* 저장 실패는 폼 안에 남긴다 — 폼을 닫고 카드 오류로 보내면 사용자가 입력하던 값을 잃는다.
   빈 상자를 그리지 않기 위해 문구가 있을 때만 보인다. */
.bdc-form-error[data-bdc-visible="false"] {
  display: none;
}

.bdc-form-error {
  padding: 6px 8px;
  border: 1px solid var(--status-error-border);
  border-radius: var(--radius-sm);
  background: var(--error-soft);
  color: var(--error);
  font-size: 12px;
  line-height: 1.45;
}

/* ===== 인테이크 (BD-C1 Phase 4) =====
   `/견적서` 한 줄에서 초안까지의 진입 표면이다. 위 두 블록과 달리 이 요소들은 .artifact-card
   **밖**에서 타임라인에 직접 서므로 상자를 스스로 그려야 한다 — 형태는 같은 자리에 서는
   .work-inline-card(chat-work-cards.css:9-19)를 미러한다. 토큰만 쓴다. */

.bdc-intake {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 10px 0;
  padding: 12px;
  /* 타임라인 직속 요소라 캡이 없으면 전폭으로 퍼진다(2026-08-29 사용자 실측 "좌우로 꽉 차서
     가시성이 떨어진다"). 아티팩트 문서 카드와 같은 560px — 세 표면(아티팩트 카드·독립 카드·
     인테이크)의 폭이 갈리면 같은 문서가 다른 물건으로 읽힌다. */
  max-width: 560px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm);
  background: var(--bg-secondary);
}

/* 서버가 준 안내 문장(next.message). 세크리터리 말풍선이 아니라 폼의 머리글이다 —
   말풍선 모양을 흉내내면 대화 발화로 읽힌다. */
.bdc-intake-message {
  color: var(--text);
  font-size: 13px;
  line-height: 1.45;
}

.bdc-intake-options {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* 종류 선택 버튼에는 액센트를 주지 않는다 — 두 선택지 중 어느 쪽도 "다음에 통제할 수 있는
   행동" 이 아니다(design tokens §Signature). 액센트는 [초안 만들기] 하나가 갖는다. */

/* 아티팩트 없이 문서 레코드만 가리키는 독립 카드(초안 생성 직후 · 방 재진입 복원).
   .bdc-panel 은 부모 카드가 상자를 그려 준다는 전제로 구분선만 쓰므로, 부모가 없는 이 카드는
   여기서 상자를 얻고 그 구분선을 걷어낸다. */
.bdc-panel.bdc-standalone {
  margin: 10px 0 0;
  padding: 12px;
  /* .bdc-intake 와 같은 이유·같은 값의 폭 캡 — 타임라인 직속이라 없으면 전폭이다. */
  max-width: 560px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-secondary);
}
