@charset "UTF-8";
/* AIAP 콘솔 화면 — 출시 전 검사(/demo)·승인(/approvals, /approvals/{run_id}) (aiap-ui §3·§4-3·§4-4).
 *
 * 색은 tokens.css의 토큰만 쓴다. 판정·등급 색(--outcome-*, --tier-*)은 서버가 준 판정 값의 배지에만 쓴다
 * (RunStatus.decision.outcome·ApprovalView.gate_outcome·ApprovalRecord.gate_outcome·AgentSummary.tier).
 * 진행 단계·일반 점검 도구 목록·오류는 판정이 아니다 — 잉크·강조색·점선으로만 구분한다.
 * 왼쪽 일반 점검 도구 목록은 일부러 밋밋하게 둔다(답변만 본 '통했다/안 통했다' 목록 — 오른쪽 보고서와의 대비가 시연의 요점).
 * 인라인 style 속성을 쓰지 않는다(CSP style-src 'self') — 상태는 클래스·hidden·data 속성으로.
 */

.console .wrap { width: min(1440px, 100% - 32px); }
.console-main { display: flex; flex-direction: column; gap: 20px; padding: 26px 0 56px; }
.console-intro h1, .approval-intro h1 { margin: 0 0 8px; font-size: clamp(1.45rem, 1.05rem + 1.3vw, 2rem); }
.mono { font-family: var(--font-mono); overflow-wrap: anywhere; }
/* 표 안의 화면 밖 글자(.sr-only, position: absolute)가 가로 스크롤 틀을 벗어나 화면 전체를 넓히지 않게 */
.console .table-scroll { position: relative; }
.muted { color: var(--muted); }

/* ───────────── 판정·등급 배지 — 값의 출처는 서버가 준 판정·위험등급 */
.outcome-pass { --outcome-color: var(--outcome-pass); }
.outcome-pass-with-advice { --outcome-color: var(--outcome-advice); }
.outcome-conditional { --outcome-color: var(--outcome-conditional); }
.outcome-block { --outcome-color: var(--outcome-block); }
.tier-low { --tier-color: var(--tier-low); }
.tier-mid { --tier-color: var(--tier-mid); }
.tier-high { --tier-color: var(--tier-high); }
.outcome-chip, .tier-chip {
  display: inline-block;
  padding: 1px 10px;
  font-weight: 800;
  font-size: 0.92em;
  line-height: 1.5;
  white-space: nowrap;
  border-radius: 999px;
}
.outcome-chip { color: var(--surface); background: var(--outcome-color, var(--muted)); }
.tier-chip {
  color: var(--tier-color, var(--muted));
  background: var(--surface);
  border: 1.5px solid var(--tier-color, var(--muted));
  cursor: help;
}

/* ───────────── 상태 줄·오류(판정 아님 — 점선) */
.run-status, .pane-status, .field-status, .list-status, .form-status, .report-status {
  margin: 0;
  font-size: 0.9rem;
  color: var(--muted);
}
.pane-status:empty, .field-status:empty, .form-status:empty, .report-status:empty { display: none; }
/* 공격 실행기를 고를 수 없는 이유 — 선택지마다 한 줄(쉬운 말 + 서버 사유 원문 작게) */
.engine-reason { display: block; }
.is-error {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px 14px;
  color: var(--text);
  background: var(--surface);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-s);
}
.status-reason { color: var(--text); overflow-wrap: anywhere; }

/* ───────────── 검사 설정 */
.run-form {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) repeat(2, minmax(0, 1fr)) auto;
  gap: 16px 20px;
  align-items: start;
  padding: 18px 20px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow-1);
}
.run-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.run-field label { font-size: 0.85rem; font-weight: 700; color: var(--muted); }
.run-field select {
  width: 100%;
  padding: 9px 10px;
  font: inherit;
  font-size: 0.95rem;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-s);
}
.run-field select:disabled { opacity: 0.6; cursor: progress; }
.agent-card {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px 12px;
  font-size: 0.88rem;
  background: var(--surface-sunken);
  border-radius: var(--radius-s);
}
.agent-card p { margin: 0; }
.agent-name { font-weight: 700; }
.agent-registered { color: var(--muted); }
.tier-reasons { margin: 2px 0 0; padding-left: 1.1em; color: var(--text); }
.tier-reasons li + li { margin-top: 2px; }
.tier-rules { list-style: none; margin-left: -1.1em; color: var(--muted); }
.run-actions { display: flex; flex-direction: column; align-items: stretch; gap: 10px; padding-top: 22px; }
.btn-run { padding: 12px 22px; font-size: 1.02rem; }
.site-links { margin: 0; font-size: 0.82rem; color: var(--muted); }

/* ───────────── 진행 상황 */
.progress {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 18px 20px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-l);
}
.progress-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 8px 20px; }
.progress-head h2 { margin: 0; font-size: 1.1rem; }
.run-summary { display: flex; flex-wrap: wrap; gap: 6px 18px; margin: 0; font-size: 0.88rem; }
.run-summary div { display: flex; align-items: baseline; gap: 6px; }
.run-summary dt { color: var(--muted); font-weight: 700; }
.run-summary dd { margin: 0; }
.run-summary dd.mono { font-size: 0.82rem; }
.run-status-word { font-weight: 700; }
/* 상태 줄 + '다시 확인'(자동 확인을 멈췄을 때만 보인다 — Step 15.5 U4) */
.run-message-row { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 8px 12px; }
.run-message-row .run-status { flex: 1 1 320px; min-width: 0; }
/* 관리자 확인 링크 버튼(D74) — 권한이 없어 잠긴 버튼 옆. 누르는 것(D62 보조 단계 테두리·그림자)에 포인트 색 테두리·글자로
   꺼진 버튼 옆에서 눈에 띄게. 판정 색이 아니다(동사가 적힌 알약 — D58). 빈 자리는 자리를 차지하지 않는다 */
.login-slot { display: inline-flex; }
.login-slot:empty { display: none; }
.btn-login { padding: 8px 16px; font-size: 0.92rem; color: var(--point-ink); border-color: var(--point); }
.btn-login::after { content: "→"; }
.btn-login:hover { border-color: var(--point-ink); }
.run-config-apply-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.run-config-apply-row > .btn-primary { flex: 1 1 auto; }
.agent-actions { align-items: center; }
.cancel-lock .login-slot { margin-left: 6px; vertical-align: middle; }
/* 검사 시작 잠금 줄(D75) — 문장 폭이 검사 설정 격자의 넷째 열(auto)을 밀지 않게 고유 폭을 0으로 두고 열 폭만큼만 채운다
   (QA F1 — 넓은 화면에서 잠긴 상태의 열 폭이 열린 상태와 같아야 한다). 좁은 화면(가로 줄)은 줄 전체 폭 */
.run-lock { box-sizing: border-box; width: 0; min-width: 100%; }
.btn-run[data-locked="true"]:disabled { cursor: not-allowed; }
.agent-win-note { margin: 0; }
.agent-win-note code { overflow-wrap: anywhere; }
.btn-recheck { flex: 0 0 auto; padding: 8px 16px; font-size: 0.92rem; }
.btn-recheck[hidden] { display: none; }
/* 검사 중단(D72) — 평소엔 보조 버튼, 확인 단계(한 번 더 누르면 중단)는 포인트 색 채움으로 눈에 띄게. 판정 색(--cp-*·
   --outcome-*)은 쓰지 않는다 — 중단은 판정이 아니다 */
.btn-cancel { flex: 0 0 auto; padding: 8px 16px; font-size: 0.92rem; }
.btn-cancel[hidden] { display: none; }
.btn-cancel[data-phase="confirm"] { color: var(--btn-primary-text); background: var(--btn-primary-bg); border-color: transparent; }
.btn-cancel[data-phase="confirm"]:hover { background: var(--btn-primary-hover); }
.btn-cancel[data-phase="requested"], .btn-cancel[data-phase="sending"] { cursor: progress; }
.btn-cancel[data-locked="true"]:disabled { cursor: not-allowed; }
.cancel-lock { margin: 8px 0 0; }
.cancel-lock[hidden] { display: none; }
/* 진행률 칸(D53) — 전체 %·걸린 시간·공격 진행. 전체 막대는 포인트 색(D62 — 판정 색이 아니다: 판정은 배지 + 글자),
   공격 막대는 회색 */
.run-progress { display: flex; flex-direction: column; gap: 6px; margin: 4px 0 12px; }
.run-progress[hidden], .progress-line[hidden] { display: none; }
.progress-line { display: grid; grid-template-columns: minmax(150px, auto) minmax(0, 1fr) auto; align-items: center; gap: 10px; }
.progress-line--attack { grid-template-columns: minmax(150px, auto) minmax(0, 1fr) auto; }
.progress-basis { font-size: 0.74rem; color: var(--muted); white-space: nowrap; }
.btn-engine-recheck { align-self: flex-start; margin-top: 6px; padding: 4px 12px; font-size: 0.84rem; }
.progress-label { font-size: 0.88rem; color: var(--text); white-space: nowrap; }
.progress-label strong { font-size: 1.05rem; font-variant-numeric: tabular-nums; }
.progress-elapsed { font-size: 0.82rem; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.progress-bar {
  appearance: none;
  width: 100%;
  height: 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-sunken);
  overflow: hidden;
}
.progress-bar--attack { height: 8px; }
.progress-bar::-webkit-progress-bar { background: var(--surface-sunken); border-radius: 999px; }
.progress-bar::-webkit-progress-value { background: var(--point); border-radius: 999px; transition: width 0.4s ease; }
.progress-bar::-moz-progress-bar { background: var(--point); border-radius: 999px; }
.progress-bar--attack::-webkit-progress-value { background: var(--faint); }
.progress-bar--attack::-moz-progress-bar { background: var(--faint); }
.step-list {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 8px;
  margin: 0;
  padding: 0;
}
.step {
  display: flex;
  gap: 8px;
  min-width: 0;
  padding: 10px;
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  border-top: 4px solid var(--border);
  border-radius: var(--radius-s);
}
.step-no {
  flex: none;
  display: inline-grid;
  place-items: center;
  width: 22px;
  height: 22px;
  font-size: 0.74rem;
  font-weight: 800;
  color: var(--muted);
  border: 1.5px solid var(--border-strong);
  border-radius: 50%;
}
.step-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.step-name { font-weight: 700; font-size: 0.9rem; }
.step-name .tech { display: block; }
.step-state { font-size: 0.8rem; color: var(--muted); }
.step-detail { font-size: 0.78rem; color: var(--text); overflow-wrap: anywhere; }
.step[data-state="started"] { border-top-color: var(--accent); background: var(--surface); }
.step[data-state="started"] .step-no { color: var(--accent-contrast); background: var(--accent); border-color: var(--accent); }
.step[data-state="started"] .step-state { color: var(--text); font-weight: 700; }
.step[data-state="completed"] { border-top-color: var(--ink); background: var(--surface); }
.step[data-state="completed"] .step-no { color: var(--ink-text); background: var(--ink); border-color: var(--ink); }
/* 끝난 단계는 번호 대신 체크(D53) — 번호 글자는 남겨 두고 겹쳐 그린다 */
.step-no { position: relative; }
.step[data-state="completed"] .step-no { color: transparent; }
.step[data-state="completed"] .step-no::after { content: "✓"; position: absolute; inset: 0; display: grid; place-items: center; color: var(--ink-text); }
.step[data-state="failed"] { border: 1px dashed var(--text); border-top: 4px dashed var(--text); background: var(--surface); }
.step[data-state="failed"] .step-state { color: var(--text); font-weight: 800; }
.is-running .step[data-state="started"] { animation: step-pulse 1.2s ease-in-out infinite; }
@keyframes step-pulse { 50% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent); } }

/* ───────────── 좌 일반 점검 도구 목록 / 우 검사 결과 보고서 */
.split {
  display: grid;
  grid-template-columns: minmax(360px, 0.75fr) minmax(0, 1.7fr);
  gap: 18px;
  align-items: start;
}
.pane {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
  padding: 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-l);
}
.pane-head { display: flex; flex-direction: column; gap: 4px; }
.pane-head h2 { margin: 0; font-size: 1.05rem; }
.pane-desc { margin: 0; font-size: 0.86rem; color: var(--muted); }
.oss-legend { margin: 0; }
.pane-oss { background: var(--surface-sunken); }
.oss-scroll { max-height: 72vh; overflow-y: auto; }
.oss-table { width: 100%; border-collapse: collapse; font-family: var(--font-mono); font-size: 0.84rem; }
.oss-table th, .oss-table td {
  padding: 7px 10px;
  text-align: left;
  vertical-align: middle;
  border-bottom: 1px solid var(--border);
}
.oss-table th {
  position: sticky;
  top: 0;
  z-index: 1;
  font-family: var(--font-sans);
  font-size: 0.78rem;
  color: var(--muted);
  background: var(--surface);
  box-shadow: inset 0 -1px 0 var(--border);
}
.oss-table tbody tr:last-child td { border-bottom: 0; }
/* 공격 번호·회차·시도는 한 줄로(번호가 'C1-/001'처럼 쪼개지지 않게) */
.oss-table th, .oss-table td:not(.oss-result) { white-space: nowrap; }
.oss-row { cursor: pointer; }
.oss-row:hover { background: var(--surface-sunken); }
/* 진행 중 새로 나타난 회차 줄(D53) — 잠깐 강조(판정 색 아님) */
.oss-row.is-new { animation: row-new 2.4s ease-out; }
@keyframes row-new { 0%, 30% { background: var(--notice-bg); box-shadow: inset 4px 0 0 var(--accent); } }
.oss-row[hidden] { display: none; }
.oss-hint { margin: 0 0 8px; padding: 8px 12px; font-size: 0.86rem; color: var(--notice-text); background: var(--notice-bg); border: 1px solid var(--notice-border); border-radius: var(--radius-s); }
.oss-hint[hidden] { display: none; }
.oss-row.is-selected { background: var(--notice-bg); box-shadow: inset 4px 0 0 var(--accent); }
.oss-open {
  padding: 0;
  font: inherit;
  font-weight: 700;
  color: var(--link);
  background: none;
  border: 0;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}
/* 공격 항목 묶음 머리 — 칸 전체가 버튼(키보드로 누를 수 있게). 아래 회차 줄은 들여 쓴다 */
.oss-group { cursor: pointer; }
/* .oss-table th(제목 줄: 고정·작은 글자)를 묶음 머리에서는 되돌린다 */
.oss-table .oss-group-cell {
  position: static;
  padding: 0;
  font-size: inherit;
  color: var(--text);
  white-space: normal;
  background: var(--surface);
  border-top: 2px solid var(--border-strong);
  box-shadow: none;
}
.oss-table tbody tr.oss-group:first-child .oss-group-cell { border-top: 0; }
.oss-group-open {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 10px;
  width: 100%;
  padding: 8px 10px;
  font: inherit;
  text-align: left;
  color: var(--text);
  background: none;
  border: 0;
  cursor: pointer;
}
.oss-group-id { font-weight: 700; color: var(--link); text-decoration: underline; text-underline-offset: 3px; }
.oss-group-count { font-family: var(--font-sans); font-size: 0.8rem; color: var(--muted); white-space: normal; }
.oss-group-open .tech { font-size: 0.72rem; }
/* 뚫림이 있는 묶음 — 오픈소스 도구 결과일 뿐 우리 판정이 아니라 빨강 없이 중립색 굵게(회차 줄의 밑줄과 같은 결) */
.oss-group.has-breached .oss-group-count { font-weight: 700; color: var(--text); }
.oss-table .oss-group:hover .oss-group-cell { background: var(--surface-sunken); }
.oss-table .oss-group.is-selected .oss-group-cell { background: var(--notice-bg); box-shadow: inset 4px 0 0 var(--accent); }
.oss-group-open:focus-visible, .oss-open:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.oss-table .oss-turn { padding-left: 22px; }
.oss-word { font-family: var(--font-sans); font-weight: 700; }
.oss-breached .oss-word { text-decoration: underline; text-decoration-thickness: 2px; }
.oss-result .tech { display: block; }
.num { white-space: nowrap; }
.pane-report .report-link { align-self: flex-start; font-size: 0.86rem; font-weight: 700; }
.report-frame {
  width: 100%;
  height: 78vh;
  min-height: 480px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-m);
}

/* ───────────── 승인 */
.auth-notice {
  margin: 0;
  padding: 12px 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 4px solid var(--text); /* 안내이지 경고가 아니다 — 붉은 포인트를 쓰지 않는다(D58) */
  border-radius: var(--radius-s);
}
.filter-note {
  margin: 12px 0 0;
  padding: 8px 12px;
  font-size: 0.88rem;
  color: var(--notice-text);
  background: var(--notice-bg);
  border: 1px solid var(--notice-border);
  border-radius: var(--radius-s);
}
.run-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.run-table th, .run-table td {
  padding: 10px 12px;
  text-align: left;
  vertical-align: middle;
  border-bottom: 1px solid var(--border);
}
.run-table th { font-size: 0.8rem; color: var(--muted); background: var(--surface-sunken); }
.run-table tbody tr:last-child td { border-bottom: 0; }
.run-table td .tech { display: block; }
.run-table td.when time { white-space: nowrap; cursor: help; border-bottom: 1px dotted var(--border-strong); }
.run-table td.open { text-align: right; }
.run-table td.status-failed span:first-child { font-weight: 700; text-decoration: underline dashed; }
.approval-main { max-width: 1040px; }
.run-facts { display: flex; flex-wrap: wrap; gap: 8px 28px; margin: 14px 0 0; }
.run-facts div { display: flex; flex-direction: column; gap: 2px; }
.run-facts dt { font-size: 0.78rem; font-weight: 700; color: var(--muted); }
.run-facts dd { margin: 0; }
/* D42 — 보고서 없는 실행은 반려만(보고서 확인이 404일 때만 JS가 보인다). 판정 색 없이 글자로 */
.no-report-note:not([hidden]) { display: block; max-width: 44em; margin-top: 8px; font-size: 0.88rem; font-weight: 700; color: var(--text); }
.report-link { font-weight: 700; }
.approval-panel {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 20px 22px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow-1);
}
.panel-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 6px 18px; }
.panel-head h2 { margin: 0; font-size: 1.2rem; }
.panel-outcome { margin: 0; font-weight: 700; }
.approval-form { display: flex; flex-direction: column; gap: 14px; }
.decision-group { display: flex; flex-wrap: wrap; gap: 10px; margin: 0; padding: 0; border: 0; }
.decision-group legend { width: 100%; margin-bottom: 8px; font-weight: 700; }
.decision-group legend .hint { margin-left: 8px; font-weight: 400; }
.decision-option {
  flex: 1 1 200px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 14px;
  background: var(--surface-sunken);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-m);
}
/* 고른 결정 — 짙은 회색 테두리(붉은 포인트를 쓰면 '승인'을 골라도 위험 동작처럼 보인다) */
.decision-option:has(input:checked) { background: var(--surface); border-color: var(--text); box-shadow: 0 0 0 1px var(--text); }
.decision-choice { display: flex; align-items: baseline; gap: 8px; font-size: 1.02rem; cursor: pointer; }
.decision-choice input { accent-color: var(--text); transform: translateY(1px); }
.decision-word { font-weight: 800; }
.due-field, .field { display: flex; flex-direction: column; gap: 4px; }
.due-field .hint { margin: 0; }
.due-field:not(.is-needed) { opacity: 0.7; }
.field-name { font-size: 0.85rem; font-weight: 700; color: var(--muted); }
.due-field input, .field input, .field textarea {
  padding: 9px 11px;
  font: inherit;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-s);
}
.field textarea { resize: vertical; min-height: 4.5em; }
.form-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; }
.form-actions .form-status { flex: 1 1 240px; }
.approval-records h3 { margin: 0; font-size: 1.02rem; }
.approval-records .hint { margin: 4px 0 10px; }
.record-list { list-style: none; display: flex; flex-direction: column; gap: 8px; margin: 0; padding: 0; counter-reset: record; }
.record {
  position: relative;
  padding: 10px 14px 10px 44px;
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  border-radius: var(--radius-m);
  counter-increment: record;
  scroll-margin-top: 16px;
}
.record::before {
  content: counter(record);
  position: absolute;
  left: 12px;
  top: 11px;
  display: inline-grid;
  place-items: center;
  width: 22px;
  height: 22px;
  font-size: 0.74rem;
  font-weight: 800;
  color: var(--muted);
  border: 1.5px solid var(--border-strong);
  border-radius: 50%;
}
.record:target, .record.is-new { background: var(--notice-bg); border-color: var(--notice-border); }
.record p { margin: 0; }
.record-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; }
.record-who { font-weight: 600; }
.record-head time { margin-left: auto; font-size: 0.82rem; color: var(--muted); }
.record-reason { margin-top: 4px !important; white-space: pre-wrap; overflow-wrap: anywhere; }
.record-meta { display: flex; flex-wrap: wrap; gap: 4px 20px; margin: 6px 0 0; font-size: 0.84rem; }
.record-meta div { display: flex; align-items: baseline; gap: 6px; }
.record-meta dt { color: var(--muted); }
.record-meta dd { margin: 0; }
.not-found { display: flex; flex-direction: column; gap: 10px; padding: 24px; background: var(--surface); border: 1px dashed var(--border-strong); border-radius: var(--radius-l); }
.not-found h1 { margin: 0; font-size: 1.4rem; }
.not-found p { margin: 0; }
.not-found-links { display: flex; flex-wrap: wrap; gap: 10px; }
.back-link { margin: 0; }

/* ───────────── 좁은 화면 */
@media (max-width: 1100px) {
  .run-form { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .run-field--agent { grid-column: 1 / -1; }
  .run-actions { grid-column: 1 / -1; padding-top: 0; flex-direction: row; flex-wrap: wrap; align-items: center; }
  .step-list { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .split { grid-template-columns: minmax(0, 1fr); }
  .oss-scroll { max-height: 46vh; }
}
@media (max-width: 640px) {
  .run-form { grid-template-columns: minmax(0, 1fr); }
  .progress-line, .progress-line--attack { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  .step-list { grid-template-columns: minmax(0, 1fr); }
  .report-frame { height: 70vh; min-height: 360px; }
  .record-head time { margin-left: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .is-running .step[data-state="started"] { animation: none; }
  .oss-row.is-new { animation: none; background: var(--notice-bg); }
  .progress-bar::-webkit-progress-value { transition: none; }
}

/* ───────────── D58 — 사이트와 같은 컨셉(흰 카드·넉넉한 여백·알약 입력). 구조·동작은 그대로, 모양만 덧입힌다.
   이 화면들에는 판정의 빨강(출시 차단)이 나온다 — 붉은 포인트는 주 버튼·진행 막대의 채움과 진행 중 단계·고른 줄의 강조선에 쓴다(D62).
   판정은 작은 배지 + 글자라 모양으로 갈린다. 링크 밑줄·고른 결정·안내 띠는 회색 계열로 둔다 */
.console a { text-decoration-color: var(--border-strong); }
.console-main { gap: 24px; padding: 36px 0 64px; }
/* 정보 판(설정·진행·목록·보고서 틀)은 평평하게 — 그림자는 누를 수 있는 것에만(D62) */
.run-form, .progress, .pane { padding: 22px 24px; box-shadow: none; }
/* 선택 칸은 누르는 것 — 보조 버튼과 같은 굵은 테두리·그림자 */
.run-field select { padding: 10px 14px; border: 1.5px solid var(--btn-secondary-border); border-radius: 999px; box-shadow: var(--btn-shadow); cursor: pointer; transition: border-color 0.2s, box-shadow 0.2s; }
.run-field select:hover:not(:disabled) { border-color: var(--text); box-shadow: var(--btn-shadow-hover); }
.run-field select:disabled { box-shadow: none; }
/* 결정 고르기 — 칸 전체가 누르는 것 */
.decision-option { border-color: var(--btn-secondary-border); box-shadow: var(--btn-shadow); cursor: pointer; transition: border-color 0.2s, box-shadow 0.2s, background-color 0.2s; }
.decision-option:hover { border-color: var(--text); background: var(--surface); }
.btn-run { box-shadow: var(--btn-shadow-hover); }
.agent-card { padding: 14px 16px; border-radius: var(--radius-m); }
.step { border-radius: var(--radius-m); transition: background-color 0.3s, border-color 0.3s; }
@media (prefers-reduced-motion: reduce) {
  .step, .run-field select { transition: none; }
}
/* 등록 이름에 붙어 온 표시(예: 초안 버전) — 큰 이름 옆 작은 알약. 판정이 아니다(회색) */
.agent-note { padding: 2px 10px; font-size: 0.78rem; font-weight: 700; color: var(--text); background: var(--surface); border: 1px solid var(--border-strong); border-radius: 999px; }
.agent-note[hidden] { display: none; }

/* ───────────── 실행 구성(Step 17) — 콘솔 맨 위. 선택지는 누르는 칸(보조 버튼 테두리), 적용은 주 버튼 */
.run-config { display: grid; gap: 14px; padding: 22px 24px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-l); }
.run-config-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 18px; }
.run-config-head h2 { margin: 0; font-size: 1.1rem; }
.run-config-status { margin: 0; font-size: 0.92rem; color: var(--muted); }
.run-config-status strong { color: var(--text); }
.run-config-degraded { display: block; margin-top: 2px; color: var(--text); }
.run-config-form { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr) minmax(220px, 0.8fr); gap: 16px 20px; align-items: start; }
.run-config-group { display: grid; gap: 8px; margin: 0; padding: 0; border: 0; min-width: 0; }
.run-config-group legend { margin-bottom: 8px; font-size: 0.85rem; font-weight: 700; color: var(--muted); }
.run-config-option {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: baseline;
  gap: 2px 10px;
  padding: 10px 14px;
  background: var(--surface);
  border: 1.5px solid var(--btn-secondary-border);
  border-radius: var(--radius-m);
  box-shadow: var(--btn-shadow);
  cursor: pointer;
  transition: border-color 0.2s, box-shadow 0.2s;
}
.run-config-option:hover { border-color: var(--text); }
.run-config-option:has(input:checked) { border-color: var(--text); box-shadow: 0 0 0 1px var(--text); }
.run-config-option:has(input:disabled) { opacity: 0.5; cursor: not-allowed; box-shadow: none; }
.run-config-option input { grid-row: span 2; accent-color: var(--text); }
.run-config-word { font-weight: 800; }
.run-config-hint { grid-column: 2; font-size: 0.8rem; color: var(--muted); }
.run-config-side { display: grid; gap: 8px; align-content: start; padding-top: 26px; }
.run-config-note, .run-config-lock, .run-config-result { margin: 0; font-size: 0.86rem; }
.run-config-note { color: var(--text); }
.run-config-note[hidden] { display: none; }
.run-config-lock { padding: 8px 12px; color: var(--text); background: var(--surface-sunken); border-radius: var(--radius-s); }
.run-config-result.is-error strong { display: block; }
@media (max-width: 980px) { .run-config-form { grid-template-columns: minmax(0, 1fr); } .run-config-side { padding-top: 0; } }
@media (prefers-reduced-motion: reduce) { .run-config-option { transition: none; } }

/* ───────────── 브라우저 도우미(D64) — 실행 구성 패널과 같은 판 */
.agent-desc { margin: 0; }
.agent-actions { display: flex; flex-wrap: wrap; gap: 10px; }
.agent-command-box { display: grid; gap: 8px; padding: 14px 16px; background: var(--surface-sunken); border-radius: var(--radius-m); }
.agent-command-box[hidden] { display: none; }
.agent-made { margin: 0; font-size: 0.9rem; }
.agent-command-row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
/* 한 줄 명령(D69) — ① uv 설치(처음 한 번) ② 주 명령 ③ 저장소용(접힘). 정보 상자는 평평하게, 누르는 것은 버튼만(D62) */
.agent-step { display: grid; gap: 8px; }
.agent-step + .agent-step { padding-top: 12px; border-top: 1px solid var(--border); }
.agent-step-title { display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px; margin: 0; font-size: 0.9rem; font-weight: 700; }
.agent-step-title .agent-made { font-weight: 700; }
.agent-step-num { display: inline-grid; place-items: center; flex: none; width: 1.5em; height: 1.5em; font-size: 0.8rem; color: var(--surface); background: var(--text); border-radius: 50%; }
.agent-copy-group { display: grid; gap: 6px; }
.agent-os { margin: 0; font-size: 0.82rem; font-weight: 700; color: var(--muted); }
.agent-command--setup { font-size: 0.8rem; }
.agent-notes { display: grid; gap: 2px; margin: 0; padding-left: 1.2em; }
.agent-repo { padding-top: 12px; border-top: 1px solid var(--border); }
.agent-repo[hidden] { display: none; }
.agent-repo > summary { cursor: pointer; font-size: 0.86rem; font-weight: 700; color: var(--muted); }
.agent-repo[open] > summary { margin-bottom: 8px; }
.agent-repo > .agent-command-row + .run-config-result { margin-top: 6px; }
.agent-command-box .run-config-result:empty { display: none; }
/* OS별 한 줄 명령(D70) — 탭은 누르는 것(테두리·그림자·hover, D62), 고른 탭은 판(surface)으로 떠 있다. 포인트 색은 쓰지 않는다 */
.agent-launch[hidden], .agent-legacy[hidden], .agent-os-panel[hidden] { display: none; }
.agent-legacy { display: grid; gap: 8px; }
.agent-os-tabs { display: inline-flex; flex-wrap: wrap; gap: 4px; justify-self: start; padding: 4px; background: var(--btn-quiet-bg); border-radius: var(--radius-m); }
.agent-os-tab { display: inline-flex; align-items: baseline; gap: 6px; padding: 7px 14px; font: inherit; font-size: 0.88rem; font-weight: 700; color: var(--muted); cursor: pointer; background: transparent; border: 1px solid transparent; border-radius: var(--radius-s); transition: background-color 0.15s, box-shadow 0.15s, color 0.15s; }
.agent-os-tab:hover { color: var(--text); border-color: var(--btn-secondary-border); }
.agent-os-tab[aria-selected="true"] { color: var(--text); background: var(--surface); border-color: var(--btn-secondary-border); box-shadow: var(--btn-shadow); }
.agent-os-tab:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 2px; }
.agent-os-tab small { font-weight: 400; }
.agent-launch-notes { padding-left: 1.4em; }
.agent-command-box > .agent-notes { padding-top: 4px; }
@media (prefers-reduced-motion: reduce) { .agent-os-tab { transition: none; } }
.agent-command { flex: 1 1 360px; min-width: 0; padding: 10px 14px; font-size: 0.86rem; overflow-wrap: anywhere; user-select: all; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-s); }
/* 잠금 안내 속 '관리자 확인(/login)' 링크(D67) */
.run-config-lock-link { font-weight: 700; color: var(--link); text-decoration: underline; text-underline-offset: 2px; }
