/* 스토리 개발 Beta 전용 스타일.

   기존 `styles.css` 의 색·폰트 토큰을 재사용한다. 값을 다시 정하지 않는 이유:
   두 화면이 같은 제품으로 보여야 하고, 브랜드 색이 바뀔 때 한 곳만 고쳐야 한다.

   토큰이 없는 경우를 대비해 var() 의 두 번째 인자로 대체값을 둔다 — styles.css 가
   먼저 로드되지 않는 상황(캐시 실패)에서도 화면이 읽힌다.
*/

:root {
  --sd-ink: var(--ink, #2c2c33);
  --sd-dim: var(--muted, #6f6f78);
  --sd-line: var(--line, #d8d8de);
  --sd-accent: var(--accent, #5234c1);
  --sd-surface: var(--surface, #ffffff);
  --sd-bg: var(--bg, #f6f6f8);
  --sd-radius: 10px;
  --sd-gap: 16px;
}

.sd-body {
  margin: 0;
  background: var(--sd-bg);
  color: var(--sd-ink);
  font-family: "Pretendard Variable", Pretendard, -apple-system, system-ui, sans-serif;
  line-height: 1.6;
}

.sd-skip {
  position: absolute;
  left: -9999px;
}
.sd-skip:focus {
  left: 12px;
  top: 12px;
  z-index: 10;
  padding: 8px 12px;
  background: var(--sd-surface);
  border: 1px solid var(--sd-line);
  border-radius: var(--sd-radius);
}

.sd-root { min-height: 100vh; }

/* 메인 화면 안에 붙는 자리 (index.html 의 #storyDevHost).

   `.sd-root` 와 달리 `min-height: 100vh` 를 주지 않는다 — 이 자리는 이미 상단바
   아래에 있어서 100vh 를 주면 화면 밖으로 넘친다.

   안쪽 `.sd-page` 의 여백과 최대폭을 지우는 이유: 그 값들은 **별 페이지**를 위한
   것이다. 메인 셸의 `.workspace` 가 이미 여백과 폭을 정하므로, 그대로 두면 여백이
   두 번 들어가고 다른 화면(프로젝트 목록 · 영상 라이브러리)과 좌우 정렬이 어긋난다. */
.story-dev-host { min-height: 50vh; }
.story-dev-host .sd-page { max-width: none; margin: 0; padding: 0; }
.sd-page { max-width: 1280px; margin: 0 auto; padding: 24px; }

/* --- 머리 --- */
.sd-page-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}
.sd-page-title { font-size: 22px; margin: 0; }
/* 머리 오른쪽 끝으로 밀어 두는 항목("기존 화면으로" 링크). flex-wrap 이 켜져 있어
   좁은 화면에서는 다음 줄로 떨어지고, 그때 margin-left:auto 는 무해하다. */
.sd-page-head-right { margin-left: auto; }
.sd-beta-tag {
  font-size: 12px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--sd-accent);
  color: #fff;
}

/* --- 진입 차단 화면 --- */
.sd-gate {
  max-width: 560px;
  margin: 15vh auto;
  padding: 32px;
  background: var(--sd-surface);
  border: 1px solid var(--sd-line);
  border-radius: var(--sd-radius);
  text-align: center;
}
.sd-gate-title { font-size: 20px; margin: 0 0 8px; }
.sd-gate-detail { color: var(--sd-dim); margin: 0 0 20px; }

/* --- 2단 레이아웃 --- */
.sd-layout {
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr);
  gap: var(--sd-gap);
  align-items: start;
}
@media (max-width: 900px) {
  .sd-layout { grid-template-columns: 1fr; }
}

.sd-panel {
  background: var(--sd-surface);
  border: 1px solid var(--sd-line);
  border-radius: var(--sd-radius);
  padding: 16px;
  position: sticky;
  top: 16px;
}
.sd-panel-title { font-size: 13px; color: var(--sd-dim); margin: 0 0 12px; font-weight: 600; }

.sd-stage {
  background: var(--sd-surface);
  border: 1px solid var(--sd-line);
  border-radius: var(--sd-radius);
  padding: 24px;
  min-width: 0; /* grid 안에서 긴 텍스트가 칸을 밀지 않게 한다 */
}
.sd-stage-head { margin-bottom: 24px; }
.sd-stage-title { font-size: 20px; margin: 0 0 6px; }
.sd-stage-hint { color: var(--sd-dim); margin: 0; }
.sd-stage-meta { color: var(--sd-dim); font-size: 13px; margin: 8px 0 0; }

/* --- 스테퍼 --- */
.sd-steps { display: flex; flex-direction: column; gap: 4px; }
.sd-step {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  width: 100%;
  padding: 10px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: none;
  cursor: pointer;
  text-align: left;
  font: inherit;
  color: inherit;
}
.sd-step:hover { background: var(--sd-bg); }
.sd-step.is-active { border-color: var(--sd-accent); background: var(--sd-bg); }
.sd-step.is-locked { opacity: 0.5; }
.sd-step-no {
  flex: 0 0 22px;
  height: 22px;
  border-radius: 999px;
  background: var(--sd-line);
  color: var(--sd-ink);
  font-size: 12px;
  display: grid;
  place-items: center;
}
.sd-step.is-active .sd-step-no { background: var(--sd-accent); color: #fff; }
.sd-step-body { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.sd-step-label { font-size: 14px; }
.sd-step-meta { display: flex; gap: 6px; flex-wrap: wrap; }
.sd-step-count { font-size: 11px; color: var(--sd-dim); }

/* --- 배지 --- */
.sd-badge {
  display: inline-block;
  font-size: 11px;
  padding: 1px 7px;
  border-radius: 999px;
  border: 1px solid var(--sd-line);
  color: var(--sd-dim);
  white-space: nowrap;
}
.sd-badge-confirmed { border-color: #2f855a; color: #2f855a; }
.sd-badge-stale { border-color: #b7791f; color: #b7791f; }
.sd-badge-needs_review { border-color: #c53030; color: #c53030; }
.sd-badge-draft { border-color: var(--sd-line); color: var(--sd-dim); }

/* --- 섹션 · 입력 --- */
.sd-section { margin-bottom: 28px; }
.sd-section-title { font-size: 15px; margin: 0 0 12px; }
.sd-row { display: flex; gap: 12px; flex-wrap: wrap; }
.sd-row > .sd-field { flex: 1 1 180px; }

.sd-field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.sd-field-label { font-size: 12px; color: var(--sd-dim); font-weight: 600; }
.sd-field-hint { font-size: 12px; color: var(--sd-dim); margin: 4px 0 0; }

.sd-input {
  font: inherit;
  color: inherit;
  padding: 9px 11px;
  border: 1px solid var(--sd-line);
  border-radius: 8px;
  background: var(--sd-surface);
  width: 100%;
  box-sizing: border-box;
}
.sd-input:focus-visible { outline: 2px solid var(--sd-accent); outline-offset: 1px; }
.sd-textarea { resize: vertical; min-height: 54px; }

.sd-check { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }

/* --- 칩 --- */
.sd-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.sd-chips-tight { gap: 4px; }
.sd-chip {
  font: inherit;
  font-size: 13px;
  padding: 5px 11px;
  border-radius: 999px;
  border: 1px solid var(--sd-line);
  background: var(--sd-surface);
  color: var(--sd-dim);
  cursor: pointer;
}
.sd-chip-sm { font-size: 12px; padding: 3px 9px; }
.sd-chip.is-on { border-color: var(--sd-accent); color: var(--sd-accent); }
.sd-chip.is-warn { border-color: #c53030; color: #c53030; }

/* --- 버튼 --- */
.sd-button {
  font: inherit;
  font-size: 14px;
  padding: 9px 16px;
  border-radius: 8px;
  border: 1px solid var(--sd-line);
  background: var(--sd-surface);
  color: var(--sd-ink);
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
}
.sd-button:hover { background: var(--sd-bg); }
.sd-button:disabled { opacity: 0.55; cursor: default; }
.sd-button-primary {
  background: var(--sd-accent);
  border-color: var(--sd-accent);
  color: #fff;
}
.sd-button-primary:hover { filter: brightness(1.08); background: var(--sd-accent); }
.sd-button-ghost { border-color: transparent; color: var(--sd-accent); }

.sd-actions { border-top: 1px solid var(--sd-line); padding-top: 16px; }
.sd-actions-hint { font-size: 12px; color: var(--sd-dim); margin: 8px 0 0; }
.sd-toolbar { display: flex; gap: 12px; align-items: flex-start; margin-bottom: 16px; }
.sd-toolbar .sd-textarea { flex: 1; }
/* 기획안처럼 입력이 본문일 때. 칸을 폭 전체로 두고 버튼을 아래에 놓는다 —
   한 줄에 나란히 두면 라벨과 예시가 들어갈 자리가 없다. */
.sd-toolbar-stacked { flex-direction: column; align-items: stretch; }
.sd-toolbar-stacked .sd-field { margin-bottom: 0; }
.sd-toolbar-stacked .sd-button { align-self: flex-start; }
/* 세로로 쌓인 툴바 안에서 버튼 몇 개를 한 줄에 둔다. 버튼을 stacked 의 직접 자식으로
   두면 각각 한 줄을 차지해 "직접 쓴 안 추가" 가 저 아래로 내려간다. */
.sd-toolbar-row { display: flex; gap: 8px; flex-wrap: wrap; }

/* 범위가 다른 동작을 선으로 가른다 (tasks 2.10).
   S7 의 "대본 만들기 / 전체 다시" 는 **이 회차**이고 "모든 회차 대본 만들기" 는
   시리즈 전체다. 같은 줄에 두면 둘이 같은 범위처럼 보이고, 12부작에서 그 착각의
   값은 차감 36건이다. */
.sd-toolbar-divided {
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  border-top: 1px solid var(--sd-line);
  padding-top: 12px;
  margin-top: 4px;
}
.sd-toolbar-divided .sd-field-hint { margin: 0; }

/* --- 분량 예산 --- */
.sd-budget {
  border: 1px solid var(--sd-line);
  border-radius: 8px;
  padding: 14px;
  background: var(--sd-bg);
}
.sd-budget-title { font-size: 13px; margin: 0 0 10px; }
.sd-budget-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 10px;
}
.sd-metric { display: flex; flex-direction: column; }
.sd-metric-label { font-size: 11px; color: var(--sd-dim); }
.sd-metric-value { font-size: 16px; }

/* --- 유형 카드 --- */
.sd-type-cards { display: flex; gap: 12px; flex-wrap: wrap; }
.sd-type-card {
  flex: 1 1 240px;
  text-align: left;
  padding: 18px;
  border: 1px solid var(--sd-line);
  border-radius: var(--sd-radius);
  background: var(--sd-surface);
  cursor: pointer;
  font: inherit;
  color: inherit;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.sd-type-card:hover { border-color: var(--sd-accent); }
.sd-type-label { font-size: 15px; }
.sd-type-hint { font-size: 13px; color: var(--sd-dim); }

/* --- 프로젝트 목록 --- */
.sd-project-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.sd-project {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border: 1px solid var(--sd-line);
  border-radius: var(--sd-radius);
  background: var(--sd-surface);
  cursor: pointer;
  font: inherit;
  color: inherit;
  text-align: left;
}
.sd-project:hover { border-color: var(--sd-accent); }
.sd-project-title { flex: 1; }
.sd-project-meta { font-size: 12px; color: var(--sd-dim); }

/* --- 기획방향 카드 --- */
.sd-direction-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 12px;
}
.sd-direction {
  border: 1px solid var(--sd-line);
  border-radius: var(--sd-radius);
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
.sd-direction.is-selected { border-color: var(--sd-accent); box-shadow: inset 0 0 0 1px var(--sd-accent); }
.sd-direction-head { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.sd-direction-id { font-size: 12px; color: var(--sd-dim); font-weight: 700; }
.sd-axis {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--sd-bg);
  color: var(--sd-accent);
  border: 1px solid var(--sd-line);
}
.sd-direction-parent { font-size: 11px; color: var(--sd-dim); }
.sd-direction-title { font-size: 15px; margin: 0; }
.sd-direction-logline { margin: 0; }
.sd-direction-details { display: flex; flex-direction: column; gap: 10px; }
.sd-direction-field p { margin: 2px 0 0; }
.sd-direction-field ul { margin: 2px 0 0; padding-left: 18px; }
.sd-direction-actions { display: flex; gap: 8px; margin-top: auto; padding-top: 8px; }

.sd-axis-summary { margin-top: 24px; }

/* --- 캐릭터 목록 (S3) ---

   **가로 행 목록이다.** 예전에는 300px 카드 그리드였는데, 12명이면 카드가 세 줄로
   쌓여 이름을 나란히 훑을 수 없었다. 이 화면에서 가장 자주 하는 일이 "누가 있었지" 를
   확인하는 것이라, 한 줄에 한 명씩 두고 이름을 같은 열에 세운다.

   잠금 테두리와 "저장 안 됨" 표시는 그대로 둔다. 그 둘이 이 화면의 핵심 상태다. */
.sd-character-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.sd-character {
  border: 1px solid var(--sd-line);
  border-radius: var(--sd-radius);
  padding: 10px 14px;
  min-width: 0;
}
/* 잠긴 인물은 재생성에서 지켜진다. 테두리로 그것을 계속 보이게 한다. */
.sd-character.is-locked { border-color: var(--sd-accent); box-shadow: inset 0 0 0 1px var(--sd-accent); }
/* 아직 저장하지 않은 잠금. 점선이라 "확정 아님" 이 한눈에 보인다. */
.sd-character.is-dirty { border-style: dashed; }

/* 한 인물 = 한 행. 이름까지는 고정 폭을 줘서 행마다 같은 열에 선다. */
.sd-character-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.sd-character-id { font-size: 12px; color: var(--sd-dim); font-weight: 700; }
/* 고정 폭은 **행 안에서만** 준다. 이 클래스는 분기 카드에서도 쓰이고(treatment.js),
   거기 id 는 `bp_synopsis_2` 처럼 길어서 34px 에 넣으면 잘린다. */
.sd-character-row > .sd-character-id { flex: 0 0 34px; }
.sd-character-name { font-size: 15px; margin: 0; flex: 0 0 auto; min-width: 96px; }
.sd-role-chip {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--sd-bg);
  color: var(--sd-accent);
  border: 1px solid var(--sd-line);
  flex: 0 0 auto;
}
/* 나이·성별·직업. 남는 폭을 먹고, 좁아지면 여기가 먼저 줄어든다. */
.sd-character-line {
  margin: 0;
  color: var(--sd-dim);
  font-size: 13px;
  flex: 1 1 120px;
  min-width: 0;
}

.sd-character-details {
  display: flex;
  flex-direction: column;
  gap: 10px;
  /* 행 아래에 펼쳐진다. 들여쓰기로 어느 인물의 것인지 보이게 한다. */
  margin: 10px 0 2px 44px;
  padding-left: 10px;
  border-left: 2px solid var(--sd-line);
}
.sd-character-field p { margin: 2px 0 0; }
.sd-character-field ul { margin: 2px 0 0; padding-left: 18px; }
/* 액션 4개(자세히·잠금·수정·삭제)는 행 오른쪽 끝에 모은다. */
.sd-character-actions {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-left: auto;
  flex: 0 0 auto;
}

/* 원작 매핑은 읽기 전용이다(서버가 계산한다). 편집 가능한 필드와 구별되게 눕혀 둔다. */
.sd-source-map { border-left: 2px solid var(--sd-line); padding-left: 10px; }

.sd-character-summary { margin-top: 24px; }

/* --- 부분 수정 패널 (한 명의 지정된 필드만) ---

   카드 안에서 열린다. 별 화면으로 빼지 않는 이유: 고칠 값이 바로 위에 보여야
   "무엇이 아쉬운지" 를 적을 수 있다. */
.sd-refine {
  border-top: 1px dashed var(--sd-line);
  margin-top: 8px;
  padding-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.sd-check-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
  gap: 4px 10px;
}

/* 필드마다 [라벨] [직접 입력 칸] [AI 가 다시] 세 칸.
   라벨을 고정폭으로 두어 칸이 세로로 정렬되게 한다 — 값이 긴 필드에서 입력 칸이
   들쭉날쭉하면 어느 줄이 어느 필드인지 읽기 어렵다. */
.sd-edit-grid { display: flex; flex-direction: column; gap: 6px; }
.sd-edit-row {
  display: grid;
  grid-template-columns: 92px minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
}
.sd-edit-row .sd-field-label { margin: 0; }
.sd-edit-row .sd-textarea { min-height: 40px; }
.sd-edit-row.is-disabled { opacity: 0.55; }
/* 잠금 안내는 세 칸 아래에 한 줄로 붙는다. */
.sd-edit-row > .sd-field-hint:last-child { grid-column: 2 / -1; margin: 0; }
@media (max-width: 520px) {
  .sd-edit-row { grid-template-columns: 1fr auto; }
  .sd-edit-row .sd-field-label { grid-column: 1 / -1; }
}
.sd-check-item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  cursor: pointer;
}
/* 잠긴 인물의 이름·나이·성별·역할. 눌러 본 뒤 거부당하는 것보다 낫다. */
.sd-check-item.is-disabled { opacity: 0.5; cursor: default; }

/* --- 확정 바 ---

   단계 잠금 판정이 "바로 위 단계의 확정본" 이라, 이것이 없으면 다음 단계가 영원히
   열리지 않는다. 화면 아래에 두고 테두리로 눈에 띄게 한다. */
.sd-confirm-host { margin-top: 24px; }
.sd-confirm {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  border: 1px solid var(--sd-accent);
  border-radius: var(--sd-radius);
  padding: 14px 16px;
  background: var(--sd-bg);
}
/* 이미 확정된 뒤에는 강조하지 않는다. 할 일이 남아 있는 것처럼 보이면 안 된다. */
.sd-confirm.is-confirmed { border-color: var(--sd-line); }
.sd-confirm-body { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 200px; }
.sd-confirm-body .sd-field-hint { margin: 0; }
.sd-badge-confirmed { border-color: var(--sd-accent); color: var(--sd-accent); }

/* --- 회차 목록 (S5) ---

   **한 회차 = 한 줄.** 카드 그리드가 아니다.

   예전에는 `repeat(auto-fill, minmax(280px, 1fr))` 카드 그리드였고 카드 안의 내용이
   세로로 쌓여 있었다. 그래서 12부작을 읽으려면 카드마다 위아래로 눈을 움직이고 다시
   옆 칸으로 넘어가야 했다. 회차는 **순서대로 읽는** 것이므로 그 동선이 내용과 맞지
   않는다 — 흐름을 보려면 1화부터 12화까지 한 방향으로 내려가야 한다.

       [번호·상태]  [제목 / 한 줄 / 엔딩 훅 / 사건]  [분 · 확정 · 버튼]

   좁은 화면에서는 아래 미디어 쿼리가 다시 세로로 쌓는다. */
.sd-episode-grid {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.sd-episode {
  border: 1px solid var(--sd-line);
  border-radius: var(--sd-radius);
  padding: 14px 16px;
  display: grid;
  /* 번호·상태 칸은 내용만큼, 본문이 남은 폭을 전부, 오른쪽 조작 칸은 고정에 가깝게.
     `minmax(0, 1fr)` 이어야 긴 한 줄 요약이 칸을 밀어내지 않는다. */
  grid-template-columns: minmax(120px, auto) minmax(0, 1fr) minmax(230px, auto);
  align-items: start;
  column-gap: 18px;
  row-gap: 8px;
  min-width: 0;
}
/* 상세가 있는 회차. 다음 단계로 넘어갈 수 있는 회차라는 뜻이다. */
.sd-episode.has-detail { border-color: var(--sd-accent); }
/* 확정된 회차. 대본을 만들 수 있는 상태이고, 이 화면에서 가장 중요한 신호다 —
   상세를 만들었는데 확정하지 않아 대본 단계가 열리지 않는 일이 실제로 있었다. */
.sd-episode.is-confirmed { border-left: 4px solid var(--sd-accent); }
/* 구조표가 바뀌어 상세가 옛 근거로 만들어진 상태. */
.sd-episode.is-stale { border-style: dashed; border-color: #b7791f; }
.sd-episode.is-picked { box-shadow: inset 0 0 0 2px var(--sd-accent); }

/* 세 칸. 상세 패널만 전체 폭을 쓴다. */
.sd-episode-lead {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  min-width: 0;
}
.sd-episode-main { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.sd-episode-side {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  min-width: 0;
}
.sd-episode-detail { grid-column: 1 / -1; }
/* 확정 상태와 버튼. 문구가 왜 확정이 필요한지 말한다. */
.sd-episode-confirm { display: flex; flex-direction: column; gap: 4px; align-items: flex-start; }
.sd-episode-confirm .sd-field-hint { margin: 0; }

/* 좁은 화면에서는 세 칸을 다시 쌓는다. 가로 배치는 폭이 있을 때만 읽기 쉽다. */
@media (max-width: 1000px) {
  .sd-episode { grid-template-columns: minmax(0, 1fr); }
  .sd-episode-lead { flex-direction: row; align-items: center; flex-wrap: wrap; }
}

/* 옛 이름. 다른 화면이 아직 쓸 수 있어 남겨 둔다. */
.sd-episode-head { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.sd-episode-title { font-size: 15px; margin: 0; }
.sd-episode-line { margin: 0; color: var(--sd-dim); font-size: 13px; }
/* 엔딩 훅은 이 단계의 핵심이다. 눈에 띄게 둔다. */
.sd-episode-hook {
  border-left: 2px solid var(--sd-accent);
  padding-left: 10px;
}
.sd-episode-hook p { margin: 2px 0 0; }
.sd-episode-events { margin: 0; padding-left: 18px; font-size: 13px; color: var(--sd-dim); }
.sd-episode-detail { border-top: 1px dashed var(--sd-line); padding-top: 10px; }
.sd-sequence-list { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 8px; }
.sd-sequence-list p { margin: 2px 0; }

/* 회차 상세 직접 편집. 시퀀스마다 fieldset 으로 묶어 어느 시퀀스의 칸인지 보이게 한다. */
.sd-detail-form { display: flex; flex-direction: column; gap: 10px; }
.sd-detail-form .sd-field { margin-bottom: 0; gap: 4px; }
.sd-seq-edit {
  border: 1px solid var(--sd-line);
  border-radius: 8px;
  padding: 10px 12px;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.sd-seq-edit legend { font-size: 12px; color: var(--sd-dim); font-weight: 600; padding: 0 4px; }
/* 순서 변경 버튼. 좁게 둬야 액션 줄이 넘치지 않는다(회차 카드에 버튼이 3개다). */
.sd-button-icon { padding: 9px 10px; line-height: 1; }

/* --- 잡 진행 (S5 회차 상세, N-04) ---

   회차 하나가 1~3분이라 퍼센트만 보여 주면 멈춘 것처럼 보인다. 그래서 회차별 칩을
   함께 둔다 — 어느 회차가 됐고 어느 회차가 실패했는지가 재시도 판단의 근거다. */
.sd-job {
  border: 1px solid var(--sd-line);
  border-radius: 8px;
  padding: 14px;
  background: var(--sd-bg);
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 16px;
}
.sd-job-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.sd-job-head .sd-field-hint { margin: 0; }
.sd-progress {
  height: 6px;
  border-radius: 999px;
  background: var(--sd-line);
  overflow: hidden;
}
.sd-progress-fill { height: 100%; background: var(--sd-accent); transition: width 0.3s; }
.sd-unit.is-done { border-color: var(--sd-accent); color: var(--sd-accent); }
.sd-unit.is-failed { border-color: #c53030; color: #c53030; }
.sd-unit.is-queued { opacity: 0.6; }

/* --- 전체 흐름 갈림길 (S5 구조표와 같은 응답에서 온다) --- */
.sd-branch-host { margin-top: 24px; }
.sd-branch-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 12px;
}
.sd-branch {
  border: 1px solid var(--sd-line);
  border-radius: var(--sd-radius);
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
.sd-branch ul { margin: 0; padding-left: 18px; font-size: 13px; }
/* 앞선 선택과 모순되어 고를 수 없는 갈림길. 지우지 않고 남기는 이유는 "왜 못 고르나" 를
   보여 주기 위해서다(`branch_points.disable_conflicts`). */
.sd-branch.is-disabled { opacity: 0.55; }
.sd-branch-options { display: flex; flex-direction: column; gap: 8px; }
/* 라디오를 첫 줄에 맞춘다. 기본 정렬이면 여러 줄 요약에서 가운데로 내려간다. */
.sd-branch-option { display: grid; grid-template-columns: auto 1fr; gap: 8px; align-items: start; }
.sd-branch-option p { margin: 2px 0 0; font-size: 13px; }
.sd-branch-option .sd-field-hint { margin: 2px 0 0; }
.sd-check-item .sd-field-hint { margin: 0; }
.sd-checkbox { accent-color: var(--sd-accent); margin: 0; }
.sd-refine-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.sd-refine-actions .sd-field-hint { margin: 0; }

/* 삭제는 되돌리기 어렵다(버전 복원 경로가 이 화면에 없다). 색으로 구별한다. */
.sd-button-danger { border-color: #c53030; color: #c53030; }
.sd-button-danger:hover { background: #fff5f5; }

/* 인원 수 입력. 툴바 안에서 폭을 차지하지 않게 한다. */
.sd-field-inline { flex-direction: column; gap: 4px; margin-bottom: 0; min-width: 132px; }
.sd-input-num { width: 92px; }
/* 나이 칸. 숫자만 받지 않는다 — "알 수 없음" 도 들어가야 하므로 조금 넓다. */
.sd-input-age { width: 140px; }

/* --- 시놉시스 문단 (S4) ---

   카드 그리드가 아니라 한 줄씩 쌓는다. 문단은 순서가 의미이고(발단→결말),
   나란히 놓으면 읽는 순서가 흐트러진다. */
.sd-para-list { display: flex; flex-direction: column; gap: 14px; margin-bottom: 28px; }
.sd-para {
  border: 1px solid var(--sd-line);
  border-radius: var(--sd-radius);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
/* 분기 적용으로 다시 써진 문단. 어디가 바뀌었는지 즉시 보여야 한다. */
.sd-para.is-rewritten { border-color: var(--sd-accent); }
.sd-para-head { display: flex; align-items: center; gap: 8px; }
.sd-para-no {
  font-size: 11px;
  font-weight: 700;
  color: var(--sd-dim);
  min-width: 16px;
}
.sd-para-tag {
  font-size: 12px;
  font-weight: 700;
  padding: 2px 10px;
  border-radius: 999px;
  background: var(--sd-bg);
  border: 1px solid var(--sd-line);
}
.sd-para-count { font-size: 11px; color: var(--sd-dim); margin-left: auto; }
.sd-para-text { min-height: 110px; }
.sd-para-actions { display: flex; gap: 8px; flex-wrap: wrap; }

/* --- 분기점 카드 (S4) --- */
.sd-branch-list { display: flex; flex-direction: column; gap: 14px; }
.sd-branch {
  border: 1px solid var(--sd-line);
  border-radius: var(--sd-radius);
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.sd-branch.is-applied { border-color: var(--sd-accent); }
/* 모순으로 비활성된 분기점. 지우지 않고 흐리게 남긴다 — 왜 못 누르는지 보여야 한다. */
.sd-branch.is-disabled { opacity: 0.55; }
.sd-branch-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.sd-branch-scope {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--sd-bg);
  color: var(--sd-accent);
  border: 1px solid var(--sd-line);
}
.sd-branch-question { font-size: 15px; margin: 0; }
.sd-branch-options {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 10px;
}
.sd-option {
  text-align: left;
  border: 1px solid var(--sd-line);
  border-radius: 8px;
  padding: 12px;
  background: var(--sd-surface);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 6px;
  font: inherit;
  color: inherit;
}
.sd-option:hover:not(:disabled) { border-color: var(--sd-accent); }
.sd-option:disabled { cursor: default; }
.sd-option.is-picked { border-color: var(--sd-accent); box-shadow: inset 0 0 0 1px var(--sd-accent); }
.sd-option:focus-visible { outline: 2px solid var(--sd-accent); outline-offset: 1px; }
.sd-option-head { display: flex; align-items: baseline; gap: 6px; }
.sd-option-label { font-size: 12px; font-weight: 700; color: var(--sd-accent); }
.sd-option-title { font-size: 13px; }
.sd-option-summary { margin: 0; font-size: 13px; color: var(--sd-dim); }
/* impact 가 카드의 존재 이유다. 요약보다 눈에 먼저 들어와야 한다. */
.sd-option-impact {
  margin: 0;
  font-size: 13px;
  border-top: 1px solid var(--sd-line);
  padding-top: 6px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.sd-branch-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }

/* --- 레퍼런스 --- */
.sd-reference-list { display: flex; flex-direction: column; gap: 10px; }
.sd-reference {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 8px;
  align-items: center;
  padding: 10px;
  border: 1px solid var(--sd-line);
  border-radius: 8px;
}
.sd-reference > .sd-chips { grid-column: 1 / -1; }

/* --- 상태 · 알림 --- */
.sd-status { min-height: 24px; margin-bottom: 12px; }
.sd-status-line { display: flex; align-items: center; gap: 8px; margin: 0; }

.sd-spinner {
  width: 13px;
  height: 13px;
  border: 2px solid var(--sd-line);
  border-top-color: var(--sd-accent);
  border-radius: 50%;
  animation: sd-spin 0.9s linear infinite;
  flex: 0 0 auto;
}
@keyframes sd-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .sd-spinner { animation-duration: 3s; }
}

.sd-notice {
  border: 1px solid var(--sd-line);
  border-left-width: 3px;
  border-radius: 8px;
  padding: 12px 14px;
  margin: 0 0 16px;
  background: var(--sd-surface);
}
.sd-notice-warn { border-left-color: #b7791f; }

.sd-notes {
  border: 1px solid #c53030;
  border-radius: 8px;
  padding: 12px 14px;
  margin-bottom: 16px;
}
.sd-notes-title { font-size: 13px; margin: 0 0 8px; color: #c53030; }
.sd-notes ul { margin: 0; padding-left: 18px; }
.sd-note-fix { color: var(--sd-dim); font-style: normal; }

/* 확인 사항. **경고가 아니다.**
   고쳐야 하는 메모는 빨간 테두리(.sd-notes)로 두고, 이쪽은 색을 빼서 "읽고 넘기면
   되는 것" 으로 보이게 한다. 단역 이름 안내처럼 회차마다 붙는 항목이 빨갛게 보이면
   사용자가 검수 표시 자체를 무시하게 된다. */
.sd-notes-info { margin-top: 10px; }
.sd-notes-info > .sd-notes-title {
  color: var(--sd-dim);
  cursor: pointer;
  margin: 0;
}
.sd-notes-info[open] > .sd-notes-title { margin-bottom: 8px; }
.sd-notes-info ul { color: var(--sd-dim); }

/* 고칠 것이 없고 확인 사항만 있으면 바깥 테두리도 빨갛지 않아야 한다.
   `:has()` 를 쓰는 이유: 그 판정을 JS 로 하면 클래스를 붙이는 코드가 한 곳 더 늘고,
   두 곳이 어긋나면 테두리와 내용이 다른 말을 한다. */
.sd-notes:not(:has(> ul)) {
  border-color: var(--sd-line);
}

.sd-empty { color: var(--sd-dim); padding: 20px 0; }

.sd-toast {
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%) translateY(8px);
  padding: 11px 18px;
  border-radius: 999px;
  background: var(--sd-ink);
  color: #fff;
  font-size: 14px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s, transform 0.18s;
  z-index: 20;
  max-width: 90vw;
}
.sd-toast.is-visible { opacity: 1; transform: translateX(-50%) translateY(0); }
.sd-toast.is-error { background: #c53030; }

/* --------------------------------------------------------------------------
   버전 패널 · 비교 (versions.js, tasks 1.39~1.43)
   -------------------------------------------------------------------------- */

.sd-button-small { padding: 6px 10px; font-size: 13px; }

/* --- 회차별 분 · 목표 분량 (R-13, tasks 2.11) ---
   회차 카드 안의 한 줄. 입력 칸을 좁게 두는 이유: 값이 두세 자리이고, 넓으면
   제목과 한 줄 요약보다 눈에 먼저 들어온다. 이 칸은 대부분 비어 있다(틀의 분을 쓴다). */
.sd-episode-minutes {
  display: flex;
  gap: 10px;
  align-items: baseline;
  flex-wrap: wrap;
  margin: 8px 0 4px;
}
.sd-episode-minutes .sd-field { margin-bottom: 0; }
.sd-episode-minutes .sd-field-hint { flex: 1 1 240px; margin: 0; }
.sd-minutes-input { width: 84px; }

.sd-error-text { color: #c53030; margin: 0; }

.sd-versions-host { margin-top: 16px; }

.sd-versions {
  border: 1px solid var(--sd-line);
  border-radius: var(--sd-radius);
  background: var(--sd-surface);
}

/* 접힌 상태가 기본이다. 버전이 20개까지 쌓이므로 펼친 채로 두면 본문이 밀린다. */
.sd-versions-summary {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  cursor: pointer;
  font-weight: 600;
  font-size: 14px;
}
.sd-versions-summary::-webkit-details-marker { color: var(--sd-dim); }
.sd-versions-summary .sd-field-hint { margin-left: auto; font-weight: 400; }
.sd-versions[open] .sd-versions-summary { border-bottom: 1px solid var(--sd-line); }

.sd-versions-body { padding: 12px 14px 14px; }

.sd-version-list {
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.sd-version {
  border: 1px solid var(--sd-line);
  border-radius: var(--sd-radius);
  padding: 10px 12px;
}
/* 지금 보고 있는 버전. 목록에서 자기 위치를 잃지 않게 표시한다. */
.sd-version.is-current { border-color: var(--sd-accent); background: var(--sd-bg); }
.sd-version.is-confirmed { border-left: 3px solid #2f855a; }

.sd-version-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.sd-version-no { font-size: 15px; }
.sd-version-meta { color: var(--sd-dim); font-size: 12px; }
.sd-version-summary { margin: 6px 0 0; font-size: 14px; }
/* 사람이 기억하는 것은 본문이 아니라 자기가 쓴 지시다. 눈에 띄게 둔다. */
.sd-version-instruction { margin: 6px 0 0; font-size: 13px; color: var(--sd-accent); }
.sd-version-actions { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }

.sd-diff-host { margin-top: 12px; border-top: 1px dashed var(--sd-line); padding-top: 10px; }
.sd-diff-list { list-style: none; margin: 8px 0 0; padding: 0; }
.sd-diff-row { padding: 8px 0; border-bottom: 1px solid var(--sd-line); }
.sd-diff-row:last-child { border-bottom: none; }
/* 같은 항목도 남긴다(서버 `_diff_rows`). 다른 것만 눈에 들어오게 색으로 가른다. */
.sd-diff-row.is-changed .sd-diff-label { color: var(--sd-accent); }
.sd-diff-label { font-size: 13px; }

.sd-diff-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 6px; }
.sd-diff-side { border: 1px solid var(--sd-line); border-radius: 8px; padding: 8px 10px; }
.sd-diff-side p { margin: 4px 0 0; font-size: 13px; white-space: pre-wrap; }
.sd-diff-left { background: #fffaf0; }
.sd-diff-right { background: #f0fff4; }
.sd-diff-tag { font-size: 11px; color: var(--sd-dim); }

@media (max-width: 720px) {
  /* 좁은 화면에서 두 칸을 나란히 두면 한 칸이 3~4단어로 줄어 읽을 수 없다. */
  .sd-diff-pair { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   변경 이력 (history.js)
   -------------------------------------------------------------------------- */

/* 이력은 스테퍼 없이 본문만 쓴다. 단계가 아니라 프로젝트 전체 축이다. */
.sd-stage-wide { width: 100%; }

.sd-history-search { display: flex; gap: 8px; margin: 16px 0; flex-wrap: wrap; }
.sd-history-search .sd-input { flex: 1 1 240px; }

.sd-history-list {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.sd-history-item {
  border: 1px solid var(--sd-line);
  border-radius: var(--sd-radius);
  padding: 10px 12px;
  background: var(--sd-surface);
}
/* 두 종류가 한 줄기에 섞인다(history.js 주석). 왼쪽 색선으로 종류를 구별한다. */
.sd-history-artifact { border-left: 3px solid var(--sd-line); }
.sd-history-decision { border-left: 3px solid var(--sd-accent); }

.sd-history-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.sd-history-at { color: var(--sd-dim); font-size: 12px; font-variant-numeric: tabular-nums; }
.sd-history-what { font-size: 14px; }
.sd-history-meta { color: var(--sd-dim); font-size: 12px; }
.sd-history-summary { margin: 6px 0 0; font-size: 14px; }
.sd-history-instruction { margin: 6px 0 0; font-size: 13px; color: var(--sd-accent); }
.sd-history-item .sd-button { margin-top: 8px; }

.sd-badge-decision { border-color: var(--sd-accent); color: var(--sd-accent); }

/* --------------------------------------------------------------------------
   S6 마무리 (stages/finish.js, R-12)
   -------------------------------------------------------------------------- */

/* 두 옵션을 같은 무게로 둔다. 한쪽을 크게 만들면 "고르기" 로 읽히는데,
   R-12 는 둘이 배타가 아니라고 명시한다. */
.sd-finish-option {
  border: 1px solid var(--sd-line);
  border-radius: var(--sd-radius);
  padding: 16px;
  margin-top: 16px;
}

.sd-finish-parts { list-style: none; margin: 12px 0; padding: 0; }

.sd-finish-part {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 6px 0;
  border-bottom: 1px solid var(--sd-line);
  /* 빠진 절이 기본 모양이다. 준비된 것만 색을 준다 — 무엇이 빠졌는지가 이 목록의 정보다. */
  color: var(--sd-dim);
}
.sd-finish-part:last-child { border-bottom: none; }
.sd-finish-part.is-ready { color: var(--sd-ink); }

.sd-finish-mark {
  flex: 0 0 auto;
  font-size: 11px;
  padding: 2px 7px;
  border: 1px solid var(--sd-line);
  border-radius: 999px;
  color: var(--sd-dim);
}
.sd-finish-part.is-ready .sd-finish-mark { border-color: #2f855a; color: #2f855a; }

.sd-finish-detail { margin-left: auto; font-size: 13px; }

.sd-finish-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

/* 확정 뒤의 배지 + "다시 만들기". 확정이 끝이 아니라는 것을 나란히 보여 준다. */
.sd-confirm-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* --------------------------------------------------------------------------
   S7 대본 (stages/script.js, R-13)
   -------------------------------------------------------------------------- */

/* 회차 탭. 숏폼은 80부작이라 가로로 흐르게 두고 줄바꿈을 허용한다 —
   스크롤 컨테이너로 만들면 40화가 화면 밖에 숨고, 그것을 찾을 방법이 없다. */
.sd-ep-tabs {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 20px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--sd-line);
}
.sd-ep-tab {
  font: inherit;
  font-size: 13px;
  padding: 5px 12px;
  border-radius: 999px;
  border: 1px solid var(--sd-line);
  background: var(--sd-surface);
  color: var(--sd-dim);
  cursor: pointer;
}
.sd-ep-tab:hover { background: var(--sd-bg); }
/* 대본이 있는 회차. 이 화면에서 가장 중요한 상태다. */
.sd-ep-tab.has-script { color: var(--sd-accent); border-color: var(--sd-accent); }
.sd-ep-tab.is-active {
  background: var(--sd-accent);
  border-color: var(--sd-accent);
  color: #fff;
}
.sd-ep-tab.is-stale { border-style: dashed; }
/* 트리트먼트가 확정되지 않아 아직 쓸 수 없는 회차. 누르면 이유를 보여 준다 —
   막지 않는 이유: 왜 못 쓰는지 읽을 수 있어야 한다. */
.sd-ep-tab.is-locked { opacity: 0.55; }

.sd-field-inline { margin-bottom: 0; max-width: 200px; }

/* --- 분량 게이지 ---
   대본은 "됐다/안 됐다" 가 아니라 얼마나 썼는가가 판정 기준이다. 허용 구간(±15%)을
   막대 안에 함께 그리는 이유: 퍼센트만 보여 주면 92% 가 통과인지 알 수 없다. */
.sd-gauge-host { margin-bottom: 20px; }
.sd-gauge { display: flex; flex-direction: column; gap: 4px; margin: 10px 0; }
.sd-gauge-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.sd-gauge-head strong { font-size: 13px; }
.sd-gauge-value { font-size: 13px; color: var(--sd-dim); }
.sd-gauge-value.is-ok { color: #2f855a; }
.sd-gauge-value.is-under { color: #b7791f; }
.sd-gauge-value.is-over { color: #c53030; }
.sd-gauge-bar {
  position: relative;
  height: 8px;
  border-radius: 999px;
  background: var(--sd-bg);
  border: 1px solid var(--sd-line);
  overflow: hidden;
}
/* 허용 구간. 채움 막대 아래에 깔린다. */
.sd-gauge-band {
  position: absolute;
  top: 0;
  bottom: 0;
  background: rgba(47, 133, 90, 0.18);
}
.sd-gauge-fill {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  border-radius: 999px;
  background: var(--sd-dim);
  transition: width 0.3s;
}
.sd-gauge-fill.is-ok { background: #2f855a; }
.sd-gauge-fill.is-under { background: #b7791f; }
.sd-gauge-fill.is-over { background: #c53030; }

/* --- 블록 카드 ---
   회차 카드(S5)와 달리 그리드가 아니라 한 열이다. 블록은 순서대로 읽는 것이고,
   본문을 펼치면 수만 자가 되므로 나란히 둘 이유가 없다. */
.sd-block-list { display: flex; flex-direction: column; gap: 12px; }
.sd-script-block {
  border: 1px solid var(--sd-line);
  border-radius: var(--sd-radius);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
.sd-script-block.has-text { border-color: var(--sd-accent); }
.sd-script-block.is-picked { box-shadow: inset 0 0 0 2px var(--sd-accent); }
/* 회차 분이 줄어 예산 밖으로 밀린 블록. 다음 생성에서 버려진다. */
.sd-script-block.is-orphan { border-style: dashed; border-color: #b7791f; }

/* 씬 목차. 번호가 왼쪽에 붙어야 블록 경계에서 이어지는 것이 보인다. */
.sd-scene-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 13px;
}
.sd-scene-list li { display: flex; gap: 8px; }
.sd-scene-list strong { flex: 0 0 56px; color: var(--sd-dim); font-weight: 600; }

/* 대본 본문. `pre` 로 그린다 — 줄바꿈과 들여쓰기가 형식의 일부다(부록 B).
   `white-space: pre-wrap` 이라 긴 지문도 가로 스크롤 없이 접힌다. */
.sd-script-text {
  margin: 0;
  padding: 14px;
  background: var(--sd-bg);
  border: 1px solid var(--sd-line);
  border-radius: 8px;
  white-space: pre-wrap;
  word-break: break-word;
  font-family: "Pretendard Variable", Pretendard, -apple-system, system-ui, sans-serif;
  font-size: 14px;
  line-height: 1.75;
  max-height: 60vh;
  overflow-y: auto;
}
/* 편집 칸은 본문과 같은 줄 간격이어야 한다. 다르면 고치는 동안 분량 감각이 어긋난다. */
.sd-script-edit { line-height: 1.75; min-height: 320px; }

/* 블록 안에 붙는 검수 메모. 회차 하나가 블록 수만큼 저장되므로 정점의 메모만 보면
   어느 블록이 반려됐는지 알 수 없다. 그래서 블록 카드 안에도 둔다. */
.sd-notes-inline { margin-bottom: 0; padding: 10px 12px; }
.sd-notes-inline .sd-notes-title { font-size: 12px; }
.sd-notes-inline ul { font-size: 13px; }

/* --------------------------------------------------------------------------
   상위 변경됨 패널 (stepper.js, tasks 1.39)
   --------------------------------------------------------------------------
   전에는 문장 한 줄이었다. 그 문장은 무엇을 해야 하는지 말하지 않아서, 사용자가
   할 수 있는 두 가지(그대로 쓰기 / 다시 만들기)에 화면상 길이 없었다. */
.sd-stale { margin-bottom: 20px; }
.sd-stale-title { font-size: 14px; margin: 0 0 4px; }
.sd-stale-list { list-style: none; margin: 12px 0 0; padding: 0; }
.sd-stale-item {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  flex-wrap: wrap;
  padding: 10px 0;
  border-top: 1px solid var(--sd-line);
}
.sd-stale-body { display: flex; flex-direction: column; gap: 2px; flex: 1 1 240px; min-width: 0; }
.sd-stale-body .sd-field-hint { margin: 0; }
/* 무엇 때문에 stale 이 됐는가. 이 줄이 판단의 근거다 — 없으면 "왜 확인해야 하나" 를
   알 수 없어 사용자가 그냥 다시 만든다(차감이 생긴다). */
.sd-stale-reason { font-size: 13px; color: #b7791f; }
.sd-stale-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

/* --------------------------------------------------------------------------
   AI 코멘트 (comment.js, R-19)
   --------------------------------------------------------------------------
   왼쪽 패널의 스테퍼 아래. 단계 화면 6개에 각각 붙이면 같은 코드가 여섯 벌이 되고
   차감 안내가 조금씩 갈린다. */
.sd-comment-host { margin-top: 24px; border-top: 1px solid var(--sd-line); padding-top: 16px; }
.sd-comment-host .sd-panel-title { margin-bottom: 6px; }
.sd-comment-host .sd-input { margin-bottom: 8px; }
.sd-comment-host .sd-button { width: 100%; }
.sd-comment-body { margin-top: 12px; }
.sd-comment { display: flex; flex-direction: column; gap: 10px; font-size: 13px; }
.sd-comment-lines { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 4px; }
/* 가장 약한 지점은 **하나**다. 여러 개를 지적하면 무엇을 먼저 고칠지 알 수 없다 —
   프롬프트가 그것을 요구하고 화면도 하나만 그린다. */
.sd-comment-weak { border-left: 2px solid #c53030; padding-left: 10px; }
.sd-comment-weak p { margin: 2px 0 0; }
.sd-comment-fix { border-left: 2px solid var(--sd-accent); padding-left: 10px; }
.sd-comment-fix ol { margin: 2px 0 0; padding-left: 18px; }

/* --------------------------------------------------------------------------
   원작 업로드 · 요약 카드 (source.js, R-14)
   --------------------------------------------------------------------------
   틀(S1) 화면의 저장 버튼 뒤에 온다. 원작 카드는 S1 산출물이고, 원작 기반 프로젝트는
   그 카드를 확정해야 S2 가 열린다 — 그 순서가 화면에도 보여야 한다. */
.sd-source-host { border-top: 1px solid var(--sd-line); padding-top: 20px; }
.sd-source-upload {
  border: 1px solid var(--sd-line);
  border-radius: 8px;
  padding: 14px;
  background: var(--sd-bg);
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 16px;
}
.sd-source-upload .sd-field { margin-bottom: 0; }
.sd-source-upload .sd-button { align-self: flex-start; }

.sd-source-list { display: flex; flex-direction: column; gap: 10px; margin-bottom: 16px; }
.sd-source {
  border: 1px solid var(--sd-line);
  border-radius: 8px;
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.sd-source.is-ready { border-color: var(--sd-accent); }
.sd-source.is-failed { border-color: #c53030; border-style: dashed; }
/* 파싱 경고는 **실패가 아니다.** 인코딩·표·건너뛴 페이지를 알려 주는 것이라
   빨강이 아니라 주의색을 쓴다 — 빨강으로 두면 정상 업로드가 실패처럼 보인다. */
.sd-source-warn { font-size: 13px; color: #b7791f; margin: 0; }

/* 읽은 본문 미리보기. **앞부분만**이다(N-11) — 전문을 내려보내면 브라우저 캐시와
   프록시 로그에 원작이 남는다. */
.sd-source-preview {
  margin: 8px 0 0;
  padding: 12px;
  background: var(--sd-bg);
  border: 1px solid var(--sd-line);
  border-radius: 8px;
  white-space: pre-wrap;
  word-break: break-word;
  font-family: inherit;
  font-size: 13px;
  line-height: 1.7;
  max-height: 260px;
  overflow-y: auto;
}
.sd-source-card-host { margin-top: 8px; }

/* 프로젝트 한 줄: 열기 버튼(넓게) + 파생 버튼(오른쪽). 파생을 카드 안에 넣으면
   카드를 누르려다 파생이 눌린다 — 두 동작의 무게가 다르다. */
.sd-project-row { display: flex; align-items: center; gap: 8px; }
.sd-project-row .sd-project { flex: 1 1 auto; min-width: 0; }
.sd-project-row > .sd-button { flex: 0 0 auto; }

/* ==========================================================================
   사용자 확정 기록 (story memory)

   표식은 눈에 띄되 결과물을 가리지 않아야 한다. 기획방향 카드에서 축 배지 옆에
   붙으므로 같은 높이·같은 라운드를 쓰고 색만 다르다.
   ========================================================================== */

.sd-memory-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px solid var(--sd-accent-border, #b7c8e8);
  background: var(--sd-accent-soft, #eef3fc);
  color: var(--sd-accent-text, #2b4b86);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}

.sd-memory-note {
  margin: 0 0 12px;
  color: var(--sd-muted, #5b6472);
  font-size: 13px;
}

.sd-memory-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 0 0 14px;
  padding: 10px 12px;
  border: 1px solid var(--sd-accent-border, #b7c8e8);
  border-radius: 10px;
  background: var(--sd-accent-soft, #eef3fc);
}

.sd-memory-banner-text {
  color: var(--sd-accent-text, #2b4b86);
  font-size: 13px;
}

.sd-memory-details {
  flex: 1 1 100%;
}

.sd-memory-details > summary {
  cursor: pointer;
  color: var(--sd-accent-text, #2b4b86);
  font-size: 12px;
}

.sd-memory-refs {
  margin: 8px 0 0;
  padding-left: 18px;
  color: var(--sd-muted, #5b6472);
  font-size: 12px;
  line-height: 1.6;
}

.sd-memory-ref-stage {
  font-weight: 600;
  color: var(--sd-accent-text, #2b4b86);
}

/* --- 기록 관리 패널 --------------------------------------------------------- */

.sd-memory-wrap {
  margin-top: 12px;
  border: 1px solid var(--sd-border, #dde2ea);
  border-radius: 10px;
  background: #fff;
}

.sd-memory-wrap > summary {
  padding: 10px 12px;
  cursor: pointer;
  font-weight: 600;
  font-size: 13px;
}

.sd-memory-slot {
  padding: 0 12px 12px;
}

.sd-memory-header h3 {
  margin: 0 0 4px;
  font-size: 14px;
}

.sd-memory-tabs {
  display: flex;
  gap: 6px;
  margin: 10px 0;
  flex-wrap: wrap;
}

.sd-memory-tab {
  padding: 4px 10px;
  border: 1px solid var(--sd-border, #dde2ea);
  border-radius: 999px;
  background: #fff;
  cursor: pointer;
  font-size: 12px;
}

.sd-memory-tab.is-active {
  border-color: var(--sd-accent-border, #b7c8e8);
  background: var(--sd-accent-soft, #eef3fc);
  color: var(--sd-accent-text, #2b4b86);
  font-weight: 600;
}

.sd-memory-tools {
  margin-bottom: 8px;
}

.sd-memory-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 8px;
}

.sd-memory-item {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  justify-content: space-between;
  padding: 8px 10px;
  border: 1px solid var(--sd-border, #dde2ea);
  border-radius: 8px;
}

/* 정지된 기록은 목록에 남지만 생성에 쓰이지 않는다. 흐리게 하되 읽을 수는 있어야
   한다 — 무엇을 정지했는지 확인하려고 여는 화면이다. */
.sd-memory-item.is-paused {
  background: var(--sd-surface-muted, #f7f8fa);
  color: var(--sd-muted, #5b6472);
}

.sd-memory-item-summary {
  margin: 0 0 4px;
  font-size: 13px;
  line-height: 1.5;
}

.sd-memory-item-meta {
  margin: 0;
  color: var(--sd-muted, #5b6472);
  font-size: 11px;
}

.sd-memory-paused {
  display: inline-block;
  margin-top: 4px;
  font-size: 11px;
  color: var(--sd-muted, #5b6472);
}

.sd-memory-item-actions {
  display: flex;
  gap: 4px;
  flex-shrink: 0;
}
