/* cloud/public/new/app/styles.css — 새 셸 디자인 토큰 (설계도 v3 §4.4)
   · 서체 Noto Sans KR · 숫자 tabular-nums · 라이트/다크 2모드
   · 근거 색 의미(--iv-*): teal=자체 실측, orange=외부, amber=합성 */
:root {
  /* ★메인 화면(로그인 전) 바탕 — bg.js 의 GROUND_LIGHT / GROUND_DARK 와 같은 값이다. canvas 를 못 쓸 때 이 단색이 남는다.
     셸 다크 --bg(#101214)와 «다른» 토큰이며, 어두운 테마에서 두 값이 다른 것은 의도다(design/tokens.json intendedDifferences). */
  --main-ground: #f7f7f5;
  --main-glow: 0 0 28px rgba(94,234,212,.30), 0 0 70px rgba(129,140,248,.22);
  /* 브랜드 글자를 입자에서 띄우는 좁은 테 — glow 는 blur 가 커서(28·70px) 획 자리 알파가 0.07·0.02 로 뭐고
     색도 입자 팔레트 양 끕이라 뒤를 가리지 못한다. blur 2px 은 σ = 1px 이라 획 중심 알파가 1.00 이다.
     색은 --main-ground 를 «참조» 하므로 테마마다 캔버스 바탕과 같은 값이 된다 — 새 색을 만들지 않는다. */
  --main-ink-edge: 0 0 2px var(--main-ground), 0 0 2px var(--main-ground), 0 0 2px var(--main-ground);
  /* 강조색 바탕 위 글자 — 어두운 테마의 강조색은 밝아서 흰 글자가 4.5:1 에 못 미친다 */
  --on-teal: #fff;
  --backdrop: rgba(0,0,0,.35);
  --bg: #f7f7f5; --fg: #17191c; --mute: #6b7078; --line: #e3e4e0; --card: #ffffff;
  --teal: #0f766e; --orange: #c2410c; --amber: #b45309; --teal-soft: #e6f4f2;
  /* 글자 크기 기준(타입 스케일) — 박스마다 즉흥으로 정하지 않고 이 네 값만 쓴다.
     읽는 본문/발췌 15 · 카드 항목·값 14 · 항목 이름 13 · 출처·시점·캡션 12 */
  --fs-read: 15px; --fs-ui: 14px; --fs-label: 13px; --fs-meta: 12px;
  /* 가독성 하한 — 본문·캡션·상태·경고의 최소 크기와 글자색. 상태·경고는 캡션 크기나 흐린 글자색(--mute)으로 쓰지 않는다.
     좁은 레일 칸의 상태 글자는 아이콘·낱말·화면낭독기 이름을 함께 두므로 따로 --fs-rail-status 를 쓴다 */
  --fs-body: var(--fs-read); --fs-caption: var(--fs-label); --fs-status: var(--fs-ui); --fs-warn: var(--fs-ui);
  --ink-body: var(--fg); --ink-caption: var(--mute); --ink-status: var(--fg); --ink-warn: var(--fg);
  /* 상태 표시 토큰(설계 03 §7.2·§7.4) — 새 색을 만들지 않고 셸 토큰에 뜻 이름만 붙인다. 테마·STEP 강조색이 바뀌면 함께 따라간다.
     상태는 낱말·아이콘이 먼저이고 색은 보조다. 상태 글자는 캡션(--fs-meta)보다 작게 두지 않는다. */
  --st-ok: var(--teal); --st-warn: var(--amber); --st-text: var(--fg); --st-quiet: var(--mute); --fs-rail-status: var(--fs-meta);
  --radius: 12px; --rail-h: 56px; --rail-w: 64px; --max: 960px; --max-wide: 1200px;
  --ease: cubic-bezier(.2,.8,.2,1);
  /* 지금 단계 점의 반채움(◐) — 강조색·옅은 강조색만 쓰므로 테마·STEP 강조색이 :root 에서 바뀌면 함께 따라간다 */
  --dot-now: linear-gradient(to right, var(--teal) 0 50%, var(--teal-soft) 50% 100%);
  /* 모션 토큰 — 설계도 D1-8 이 값을 준 것은 페이지 전환 240ms 하나다 */
  --dur-page: 240ms;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --main-ground: #06070b; --on-teal: #101214; --bg: #101214; --fg: #e8e9e6; --mute: #9aa0a6; --line: #262a2e; --card: #171a1d;
    --teal: #2dd4bf; --orange: #fb923c; --amber: #fbbf24; --teal-soft: #0f2a27;
  }
}
:root[data-theme="dark"] {
  --main-ground: #06070b; --on-teal: #101214; --bg: #101214; --fg: #e8e9e6; --mute: #9aa0a6; --line: #262a2e; --card: #171a1d;
  --teal: #2dd4bf; --orange: #fb923c; --amber: #fbbf24; --teal-soft: #0f2a27;
}

/* ── STEP 별 강조색 (설계도 §4.7-1 팔레트) — shell.js render() 가 페이지 전환마다 <html data-step="n"> 을 붙이면
   --teal 이 그 단계 색이 되어 레일 점·연결선·버튼·칩·포커스·배너가 한꺼번에 따라간다.
   8색은 입자 팔레트(48단, 가까운 청록 → 먼 보라)에서 같은 간격으로 뽑은 것 — STEP 0 이 가장 가깝고 STEP 7 이 가장 멀다.
   밝은 테마는 같은 색상(hue)·채도에서 밝기만 낮춘 값이다 — 바탕(#f7f7f5) 대비·흰 글자 대비에 더해
   «그 단계의 --teal-soft 위» 대비까지 세 자리 모두 4.5:1 을 넘는 «가장 밝은» 값으로 잡는다.
   세 번째 자리가 가장 빡빡하다(4.61~4.65). --teal-soft 는 강조색을 바탕에 옅게 섞은 색이라 둘이 가까워서다.
   --teal-soft 는 기존 쌍과 같은 혼합비(어두운 12% · 밝은 9%)로 바탕에 섞은 값이다.
   로그인 전 메인 화면과 My 화면에는 data-step 이 없어 기본 청록이 남는다. ── */
:root[data-step="0"] { --teal: #0f7565; --teal-soft: #e2ece9; }
:root[data-step="1"] { --teal: #1a7472; --teal-soft: #e3ecea; }
:root[data-step="2"] { --teal: #1c727e; --teal-soft: #e3eceb; }
:root[data-step="3"] { --teal: #1c7091; --teal-soft: #e3eced; }
:root[data-step="4"] { --teal: #1b6bac; --teal-soft: #e3ebf0; }
:root[data-step="5"] { --teal: #1a63d3; --teal-soft: #e4eaf3; }
:root[data-step="6"] { --teal: #2a5aeb; --teal-soft: #e6eaf4; }
:root[data-step="7"] { --teal: #4252f4; --teal-soft: #e8e9f5; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"])[data-step="0"] { --teal: #5eead4; --teal-soft: #192c2b; }
  :root:not([data-theme="light"])[data-step="1"] { --teal: #63dcd9; --teal-soft: #1a2a2c; }
  :root:not([data-theme="light"])[data-step="2"] { --teal: #68d0de; --teal-soft: #1b292c; }
  :root:not([data-theme="light"])[data-step="3"] { --teal: #6dc2e3; --teal-soft: #1b272d; }
  :root:not([data-theme="light"])[data-step="4"] { --teal: #72b4e9; --teal-soft: #1c252e; }
  :root:not([data-theme="light"])[data-step="5"] { --teal: #77a6ee; --teal-soft: #1c242e; }
  :root:not([data-theme="light"])[data-step="6"] { --teal: #7c9af3; --teal-soft: #1d222f; }
  :root:not([data-theme="light"])[data-step="7"] { --teal: #818cf8; --teal-soft: #1e212f; }
}
:root[data-theme="dark"][data-step="0"] { --teal: #5eead4; --teal-soft: #192c2b; }
:root[data-theme="dark"][data-step="1"] { --teal: #63dcd9; --teal-soft: #1a2a2c; }
:root[data-theme="dark"][data-step="2"] { --teal: #68d0de; --teal-soft: #1b292c; }
:root[data-theme="dark"][data-step="3"] { --teal: #6dc2e3; --teal-soft: #1b272d; }
:root[data-theme="dark"][data-step="4"] { --teal: #72b4e9; --teal-soft: #1c252e; }
:root[data-theme="dark"][data-step="5"] { --teal: #77a6ee; --teal-soft: #1c242e; }
:root[data-theme="dark"][data-step="6"] { --teal: #7c9af3; --teal-soft: #1d222f; }
:root[data-theme="dark"][data-step="7"] { --teal: #818cf8; --teal-soft: #1e212f; }

* { box-sizing: border-box; }
html, body { margin: 0; background: var(--bg); color: var(--fg); }
body { font-family: 'Noto Sans KR', system-ui, -apple-system, sans-serif; font-feature-settings: 'tnum'; line-height: 1.55; }
a { color: inherit; text-decoration: none; }

/* ── 상단 레일 ─────────────────────────────────────────────────────── */
/* ★열이 «자식 수» 만큼 있어야 한다 — 로고·단계·근거등급·밝기·My. 모자라면 마지막 것이 다음 줄로 떨어진다. */
.rail { position: sticky; top: 0; z-index: 10; min-height: var(--rail-h); height: auto; display: grid; grid-template-columns: minmax(100px, auto) 1fr auto auto auto;
        align-items: start; gap: 16px; padding: 10px 20px; background: var(--bg); border-bottom: 1px solid var(--line); }
.rail[hidden] { display: none; } /* ★로그인 전에는 레일이 없다 — display:grid 를 덮어야 실제로 사라진다 */
.brand { font-weight: 700; letter-spacing: .04em; }
.myLink { font-size: 13px; color: var(--mute); border: 1px solid var(--line); border-radius: 999px; padding: 5px 12px; }
.myLink:hover { color: var(--fg); border-color: var(--teal); }
.theme-btn { font: inherit; font-size: 12px; color: var(--mute); background: transparent; border: 1px solid var(--line); border-radius: 999px; padding: 4px 10px; cursor: pointer; margin-left: 8px; }
.theme-btn:hover { color: var(--fg); }
.theme-btn:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }
.myLink:focus-visible { color: var(--fg); border-color: var(--teal); outline: 2px solid var(--teal); outline-offset: 2px; }
/* 본문 바로가기(03 §7.4) — 키보드·낭독기 사용자가 레일을 건너 #view 로 간다. 초점을 받을 때만 화면에 보인다.
   z-index 11 은 레일(10) 위, 모달(20) 아래다 */
.skip-link { position: absolute; left: 8px; top: 8px; z-index: 11; padding: 8px 12px; border: 1px solid var(--teal); border-radius: var(--radius); background: var(--card); color: var(--fg); font-size: var(--fs-ui); text-decoration: none; transform: translateY(-200%); }
.skip-link:focus, .skip-link:focus-visible { transform: none; outline: 2px solid var(--teal); outline-offset: 2px; }
/* 포커스 표시 공통 — 윤곽선(강조색, 비텍스트 3:1 이상)과 옅은 테두리 빛 두 가지가 함께 바뀐다. 색 하나로 세우지 않는다 */
:where(a[href], button, summary, [role="button"], [role="tab"], input[type="checkbox"]):focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; box-shadow: 0 0 0 5px var(--teal-soft); }
/* 입력칸에도 같은 윤곽선을 쓴다 — 옅은 링(--teal-soft)은 바탕과의 대비가 1.05~1.28 이라 3:1 에 못 미쳐 표시를 세우지 못한다.
   윤곽선(--teal)은 두 테마의 바탕·카드·링 어느 쪽에 닿아도 4:1 을 넘는다. */
:where(input:not([type="checkbox"]):not([type="radio"]), textarea, select):focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }
/* 스크롤 컨테이너는 안쪽 여백 밖을 자른다 — 단계 링크의 포커스 표시(바깥 5px)가 잘리지 않도록 여백 7px 을 두고 같은 크기의 음수 바깥 여백으로 자리를 되돌린다 */
.steps { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 0; overflow: visible; scrollbar-width: none; padding: 7px; margin: -7px; }
.steps::-webkit-scrollbar { display: none; }
.step { display: flex; align-items: center; gap: 8px; padding: 6px 10px; border-radius: 999px; color: var(--mute); white-space: nowrap; font-size: 13px; }
.step .dot { width: 10px; height: 10px; border-radius: 50%; border: 1.5px solid currentColor; background: transparent; }
/* ★도달할 수 없는 단계 — 포커스는 받되 누를 수 없다. 기본 `.step` 도 --mute 라 색만으로는 갈리지 않으므로
   점을 점선으로 돌려 형태로 가른다(`.vstep.none .dot` 과 같은 어휘다). 흐리게 하지 않는 까닭은 위 버튼과 같다. */
.step[aria-disabled="true"] { cursor: not-allowed; }
.step[aria-disabled="true"] .dot { border-style: dashed; }
.step.done { color: var(--teal); }
.step.done .dot { background: var(--teal); border-color: var(--teal); }
.step.now { color: var(--fg); }
/* 지금 보고 있는 단계 — 점 모양(진행 상태)과 별개로 바탕으로 표시한다. 완료 단계를 다시 볼 때도 어디를 보는지 보인다 */
.step.viewing { color: var(--fg); background: var(--teal-soft); }
/* 지금 단계는 반채움(◐) — 끝난 단계(●)와 색이 아니라 형태로 구분된다. reduced-motion 에서 맥동이 꺼져도 구분이 남는다. */
.step.now .dot { background: var(--dot-now); border-color: var(--teal); animation: pulse 1.2s ease-in-out infinite; }
/* 멈춘 단계 — 진행 중(◐ 맥동)과 색이 아니라 형태로 갈린다. 맥동을 주지 않는 것이 뜻이다: 움직이지 않는다.
   가운데를 비운 두꺼운 테두리로 「자리는 여기인데 아무 일도 없다」를 보인다. 낱말은 aria-label 의 「멈춤」이 맡는다. */
.step.stalled { color: var(--amber); }
.step.stalled .dot { background: transparent; border-color: var(--amber); border-width: 3px; animation: none; }
/* 진행 여부를 알 수 없는 단계 — 점선으로 「판정 없음」을 보인다(.step[aria-disabled] 와 같은 어휘다) */
.step.unsure { color: var(--mute); }
.step.unsure .dot { background: transparent; border-style: dashed; animation: none; }
/* 흐리게 하는 것은 점뿐이다 — 링크 전체에 opacity 를 걸면 이동 가능한 단계 라벨의 글자 대비가 4.5:1 아래로 떨어진다 */
.step.wait .dot { opacity: .85; }
/* 연결선은 SVG — motion.js drawProgress 가 stroke-dashoffset 24→0 으로 그린다. 움직임이 없으면 dashoffset 0 이라 그대로 보인다. */
.link { width: 22px; height: 2px; flex: none; overflow: visible; }
.link line { stroke: var(--line); stroke-width: 1; stroke-dasharray: 24; stroke-dashoffset: 0; vector-effect: non-scaling-stroke; }
.link.done line { stroke: var(--teal); }
@keyframes pulse { 0%,100% { opacity: 1 } 50% { opacity: .3 } }
/* 레일 요약과 펼침 패널(설계 03 U02) — 위 줄은 큰 구간·지금·다음·펼침 단추, 아래 패널은 구간별 줄이다. */
.rail-sum { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; font-size: var(--fs-label); }
.rail-segs { display: flex; gap: 4px; margin: 0; padding: 0; list-style: none; }
.rail-seg { padding: 3px 10px; border: 1px solid var(--line); border-radius: 999px; color: var(--st-quiet); }
/* 지금 구간 — 바탕색에 더해 ▸ 표시·굵기·테두리로 가른다. 글자·바탕은 .step.viewing 과 같은 쌍(--fg × --teal-soft)이다 */
.rail-seg.is-current { color: var(--fg); background: var(--teal-soft); border-color: var(--teal); font-weight: 600; }
.rail-now, .rail-next { margin: 0; color: var(--st-text); }
.rail-k { color: var(--st-quiet); margin-right: 4px; }
.rail-st { font-size: var(--fs-rail-status); color: var(--st-text); white-space: nowrap; margin-left: 4px; }
.rail-st[data-lifecycle="done"] { color: var(--st-ok); }
.rail-st[data-lifecycle="failed"], .rail-st[data-lifecycle="blocked"] { color: var(--st-warn); }
.step .st { font-size: var(--fs-rail-status); }
.rail-toggle { font: inherit; font-size: var(--fs-label); color: var(--fg); background: transparent; border: 1px solid var(--line); border-radius: 999px; padding: 4px 12px; cursor: pointer; }
.rail-toggle[aria-expanded="true"] { border-color: var(--teal); }
.rail-all { flex-basis: 100%; display: grid; gap: 6px; margin-top: 8px; }
.rail-all[hidden] { display: none; }
.rail-grp { display: grid; grid-template-columns: 3.5em 1fr; align-items: center; gap: 0 6px; }
.rail-grp-name { font-size: var(--fs-meta); font-weight: 600; color: var(--st-quiet); }
.rail-cells { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 0; }
.rail-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.grade { font-size: 12px; color: var(--amber); border: 1px solid var(--line); padding: 4px 10px; border-radius: 999px; }
/* ── 화면 ──────────────────────────────────────────────────────────── */
.view { min-height: calc(100vh - var(--rail-h) - 48px); }
.page { max-width: var(--max); margin: 0 auto; padding: 48px 20px; }
.page.wide { max-width: var(--max-wide); }
.page.center { min-height: calc(100vh - var(--rail-h) - 48px); display: flex; flex-direction: column; justify-content: center; }
h1 { font-weight: 600; font-size: 28px; margin: 0 0 8px; letter-spacing: -.01em; }
h2 { font-weight: 600; font-size: 18px; margin: 28px 0 10px; }
.lead { color: var(--mute); margin: 0 0 24px; }

/* STEP 0 — 중앙 입력창 하나 */
.ask { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }
.ask textarea { width: 100%; min-height: 160px; resize: vertical; font: inherit; font-size: 16px; color: var(--fg);
  background: var(--card); border: 1px solid var(--mute); border-radius: 16px; padding: 18px 20px; outline: none; }
.ask textarea:focus { border-color: var(--teal); box-shadow: 0 0 0 3px var(--teal-soft); }
/* 테두리 색 변화(mute→teal)와 옅은 고리만으로는 바탕 대비가 1.1 안팎이라 포커스가 보이지 않는다 — 다른 입력칸과 같은 윤곽을 둔다 */
.ask textarea:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }
.askbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; }
.tools { display: flex; gap: 8px; }
.tools button, .btn { font: inherit; font-size: 14px; padding: 8px 14px; border-radius: 999px; border: 1px solid color-mix(in srgb, var(--fg) 22%, var(--line)); background: color-mix(in srgb, var(--fg) 7%, var(--card)); color: var(--fg); cursor: pointer; }
.btn.primary { background: var(--teal); border-color: var(--teal); color: var(--on-teal); font-weight: 600; padding: 10px 22px; }
/* 비활성 버튼 — 흐리게(opacity) 하지 않고 점선 테두리 · --mute 글자 · not-allowed 커서로 알린다.
   opacity .5 합성은 강조 버튼 글자 대비를 밝은 테마 2.14 · 어두운 테마 3.39 까지 떨어뜨린다(--mute / --card 는 4.98 · 6.62). */
.btn[disabled], .tools button[disabled] { border-style: dashed; border-color: var(--line); background: var(--card); color: var(--mute); cursor: not-allowed; }
.btn.primary[disabled] { background: var(--card); border-color: var(--line); color: var(--mute); cursor: not-allowed; }
/* ★aria-disabled 는 «잠겼지만 포커스는 받는» 상태다 — `disabled` 버튼은 포커스를 받지 못해 잠긴 까닭을 읽을 길이 없다.
   보이는 대우는 `[disabled]` 와 같게 둔다(점선 테두리 · --mute 글자 · not-allowed 커서). 강조 버튼은 배경까지 눌러야
   «눌리는 것처럼» 보이지 않는다.
   ★pointer-events 는 끄지 않는다. 끄면 잠긴 까닭을 마우스로 읽을 길이 사라져, 이 상태를 쓰는 뜻이 없어진다.
   ★opacity 를 쓰지 않는 것도 뜻이 있다 — 흐리게 하면 글자 대비가 합성으로 떨어져 사유를 읽기 어려워진다.
   비활성 요소라 WCAG 1.4.3 예외에 들지만, 읽으라고 두는 글자를 굳이 흐리게 할 까닭이 없다. */
.btn[aria-disabled="true"] { border-style: dashed; border-color: var(--line); background: var(--card); color: var(--mute); cursor: not-allowed; }
.btn.primary[aria-disabled="true"] { background: var(--card); border-color: var(--line); color: var(--mute); }
.recent { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 28px; }
.chip { font-size: 12px; padding: 4px 10px; border-radius: 999px; border: 1px solid var(--line); color: var(--mute); background: var(--card); }
.chip.syn { color: var(--amber); }

/* 인라인 안내 배너 — 요청 성공과 결과 성공이 다를 때(예: STEP0 자료 업로드 부분 실패) alert() 대신 화면에 남긴다 */
.notice { border: 1px solid var(--line); border-left: 3px solid var(--amber); border-radius: var(--radius); padding: 12px 16px; margin-bottom: 16px; font-size: 14px; }
.notice b { color: var(--fg); font-weight: 500; }
.notice ul { margin: 6px 0 0; padding-left: 18px; color: var(--mute); }

/* 결과 카드 */
.card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 18px 20px; }
.grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr)); }
.empty { border: 1px dashed var(--line); border-radius: var(--radius); padding: 18px; color: var(--mute); }
.empty b { color: var(--fg); font-weight: 500; }
.status { display: flex; align-items: center; gap: 10px; color: var(--mute); font-size: 14px; }
.status .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--teal); animation: pulse 1.2s ease-in-out infinite; }
.kv { display: grid; grid-template-columns: 120px 1fr; gap: 6px 12px; font-size: var(--fs-ui); }
.kv dt { color: var(--mute); } .kv dd { margin: 0; }
.kv > div { display: contents; }   /* dt/dd 한 쌍을 묶는 div(원문 title 을 다는 자리)는 격자 칸을 차지하지 않는다 */
.gate { margin-top: 28px; display: flex; justify-content: flex-end; align-items: center; gap: 12px; }
/* 상단 배치 — 실행 버튼을 제목·부제 바로 아래에 두어 스크롤 없이 바로 누르게 한다(내용은 아래로) */
.gate-top { margin-top: 4px; margin-bottom: 18px; }
.gate { flex-wrap: wrap; }
.gate-note { flex-basis: 100%; text-align: right; }
/* 공용 대기창(ui.js openWait) — 오래 걸리는 작업을 기다리는 동안 화면을 덮는다. 색은 토큰, 글자는 사이트 기준이다 */
/* 대기 카드는 화면 구석에 놓이고 나머지 화면은 그대로 눌린다 — 전체를 덮는 막이 아니다(진행 중에도 메뉴 이동이 되어야 한다) */
.vpr-wait { position: fixed; right: 16px; bottom: 16px; left: auto; z-index: 900; display: block; background: none; pointer-events: none; }
.vpr-wait-card { pointer-events: auto; max-width: 320px; width: calc(100vw - 32px); padding: 18px 20px; border-radius: 14px; background: var(--card); border: 1px solid var(--line); text-align: center; color: var(--fg); box-shadow: 0 20px 60px var(--backdrop); }
.vpr-wait-spin { width: 40px; height: 40px; margin: 0 auto 18px; border: 3px solid var(--line); border-top-color: var(--teal); border-radius: 50%; animation: vpr-spin .9s linear infinite; }
@keyframes vpr-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .vpr-wait-spin { animation: none; } }
.vpr-wait-title { display: block; font-size: 18px; margin-bottom: 8px; }
.vpr-wait-note { margin: 0 0 18px; color: var(--mute); font-size: var(--fs-ui); line-height: 1.6; }
.vpr-wait-track { height: 8px; border-radius: 4px; background: color-mix(in srgb, var(--fg) 9%, var(--card)); overflow: hidden; margin-bottom: 8px; }
/* 끝을 모르는 기다림이라 막대는 채워지지 않고 왕복만 한다 — 너비가 진행률로 읽히지 않게 한다 */
.vpr-wait-bar { height: 100%; width: 30%; background: var(--teal); border-radius: 4px; animation: vpr-wait-slide 1.4s ease-in-out infinite alternate; }
@keyframes vpr-wait-slide { from { transform: translateX(-10%); } to { transform: translateX(243%); } }
@media (prefers-reduced-motion: reduce) { .vpr-wait-bar { animation: none; width: 100%; opacity: .35; } }
.vpr-wait-meta { display: flex; justify-content: space-between; color: var(--mute); font-size: var(--fs-label); font-variant-numeric: tabular-nums; }
.gate-top:empty { margin: 0; }

/* 장치 B — 앞 단계 산출물을 머리에 고정 */
.carry { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }
.carry-item { font-size: 12px; color: var(--mute); border: 1px solid var(--line); border-radius: 999px; padding: 4px 10px; background: var(--card); }
.carry-item b { color: var(--teal); font-weight: 500; margin-right: 4px; }

/* STEP 1 — 문서처럼 고치는 브리프 (Tally 방식) */
.brief { display: grid; gap: 14px; }
.fld label { display: block; font-size: 13px; color: var(--mute); margin-bottom: 6px; }
.fld textarea { width: 100%; font: inherit; font-size: 15px; color: var(--fg); background: transparent; border: 0; border-bottom: 1px solid var(--mute);
  padding: 6px 2px; resize: vertical; outline: none; }
.fld textarea:focus { border-bottom-color: var(--teal); box-shadow: 0 1px 0 0 var(--teal); }
.fld.is-empty textarea { border-bottom-style: dashed; }
/* 분류 칩 — 채워진 칸(●)과 빈 칸(○)을 기호와 테두리 모양으로 가른다. 누르면 그 칸으로 간다 */
.brief-cats { margin: 0 0 14px; }
.chip.cat { font: inherit; font-size: 12px; cursor: pointer; }
.chip.cat.is-filled { color: var(--teal); border-color: var(--teal); }
.chip.cat.is-empty { border-style: dashed; }
/* 제품 사실(확인됨)과 제품 측 설명(확인 안 됨) — 나란히 두고, 확인 안 됨 쪽은 점선 테두리로 형태를 바꾼다 */
.fact-split { margin: 0; }
.fact-col { border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 14px; }
.fact-col[data-verified="false"] { border-style: dashed; }
/* 게이트 — 확인 버튼 하나만 크게 */
.btn.lg { font-size: 16px; padding: 14px 36px; }
.gate-msg { flex: 1 1 auto; }
/* STEP 0 을 다시 열었을 때의 입력 원문 */
.brief-raw { white-space: pre-wrap; font: inherit; font-size: 14px; margin: 0; padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); }

/* 페이지 전환(F1.5) — 1순위 View Transition: 본문(#view)만 전환 대상이다(레일은 제자리).
   이전 페이지는 왼쪽으로 12px 이동하며 투명해지고, 새 페이지는 오른쪽 12px 에서 들어온다. 240ms. */
.view { view-transition-name: page; }
::view-transition-old(page) { animation: vt-out var(--dur-page) var(--ease) both; }
::view-transition-new(page) { animation: vt-in var(--dur-page) var(--ease) both; }
@keyframes vt-out { to { opacity: 0; transform: translateX(-12px) } }
@keyframes vt-in { from { opacity: 0; transform: translateX(12px) } }
@media (prefers-reduced-motion: reduce) { ::view-transition-old(page), ::view-transition-new(page) { animation: none } }
/* View Transition 도 Motion 도 없을 때의 CSS 폴백 — 새 페이지 진입만 있다. View Transition 을 지원하면 두 번 움직이지 않게 끈다 */
.page { animation: enter var(--dur-page) var(--ease); }
@keyframes enter { from { opacity: 0; transform: translateX(12px) } to { opacity: 1; transform: none } }
@supports (view-transition-name: none) { .page { animation: none } }
@media (prefers-reduced-motion: reduce) { .page { animation: none } .step.now .dot, .status .dot, .vstep.now .dot { animation: none } }

.foot { max-width: var(--max-wide); margin: 0 auto; padding: 12px 20px; color: var(--mute); font-size: 12px; display: flex; justify-content: space-between; }

/* 좁은 화면 — 상단 가로 레일이 왼쪽 세로 레일이 된다 (장치 Q · 설계도 F1.4·F1.6 임계 720px)
   레일 자식 5개(로고·단계·근거등급·밝기·My)가 위에서 아래로 한 열에 놓인다 — 행 수 = 자식 수.
   단계 라벨은 보이지 않게 접고(링크 aria-label 이 이름을 가진다) 점과 연결선만 남긴다. 본문·꼬리말은 레일 폭만큼 오른쪽으로 민다.
   로그인 전(레일 hidden)에는 밀지 않는다 — 없는 레일 폭만큼 본문이 넘치지 않게 한다. 입력창은 .page.center 로 중앙에 남는다. */
@media (max-width: 720px) {
  .rail { position: fixed; top: 0; bottom: 0; left: 0; width: var(--rail-w); height: auto; grid-template-columns: 1fr; grid-template-rows: auto 1fr auto auto auto;
          justify-items: center; align-items: start; gap: 10px; padding: 12px 6px; border-bottom: 0; border-right: 1px solid var(--line); }
  .brand, .grade, .theme-btn, .myLink { writing-mode: vertical-rl; }
  .brand { font-size: 12px; }
  .grade { font-size: 11px; padding: 8px 3px; }
  .theme-btn, .myLink { margin-left: 0; padding: 8px 3px; }
  .steps { flex-direction: column; overflow-x: hidden; overflow-y: auto; max-height: 100%; }
  .step { padding: 6px; }
  .step > span:not(.dot) { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .link { width: 16px; transform: rotate(90deg); margin: 7px 0; }
  .view, .foot { margin-left: var(--rail-w); }
  .rail[hidden] ~ .view, .rail[hidden] ~ .foot { margin-left: 0; }
  .page.center { min-height: calc(100vh - 48px); }
  .abar-grid { grid-template-columns: 1fr; }
}
/* 좁은 화면의 레일 요약 — 세로 막대에는 구간·지금·다음 글을 보이지 않게 접고(화면낭독기는 그대로 읽는다) 펼침 단추만 세로로 둔다.
   펼친 패널은 구간 이름 아래로 점을 한 열로 잇는다. */
@media (max-width: 720px) {
  .rail-sum { flex-direction: column; gap: 8px; }
  .rail-segs, .rail-now, .rail-next { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .rail-toggle { writing-mode: vertical-rl; padding: 8px 3px; }
  .rail-grp { grid-template-columns: 1fr; justify-items: center; gap: 4px; }
  .rail-grp-name { writing-mode: vertical-rl; }
  .rail-cells { flex-direction: column; }
}
.status .elapsed { font-variant-numeric: tabular-nums; }
/* 꼬리말이 비어 있으면(로그인 전 메인) 안쪽 여백만 남아 화면 높이를 넘긴다 — 자리를 차지하지 않게 한다 */
.foot:empty { display: none; }

/* ── 페이지(2·3·5·7)·차트·장치 C/D/H/I/K·로그인 모달 ─────────────────────────── */
.mute { color: var(--mute); font-size: var(--fs-label); }
.k { font-size: var(--fs-label); color: var(--mute); margin: 0 0 6px; display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.sect { margin: 0 0 26px; }
/* ★비어 있는 칸은 자리만 차지하고 여백을 남긴다 — 개입 칸은 «있다가 없는» 자리라
   render 가 컨테이너를 항상 두고 hidden 으로 감춘다. .modal[hidden] 과 같은 방식이다. */
.sect[hidden] { display: none; }
.sect.two { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0; }
.chip.tier { color: var(--teal); }
.row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 10px; }
.kv-inline { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.step.t2 .dot { opacity: .8; }
.step.t2 .dot { border-style: dashed; }
.step small { font-size: 10px; color: var(--mute); margin-left: 4px; }

/* 장치 C — 회색 점선 칸 + «무엇이 있으면 채워지는가» */
.empty-cell { border: 1px dashed var(--line); border-radius: var(--radius); padding: 14px 16px; color: var(--mute); display: grid; gap: 4px; }
.empty-cell b { color: var(--fg); font-weight: 500; }
.empty-cell span { font-size: 12.5px; }
.empty-cell.small { padding: 8px 10px; font-size: var(--fs-meta); }
.empty-cell.chart-empty { display: flex; flex-direction: column; justify-content: center; }
/* 장치 C — 안내가 있는 빈 칸은 눌러서 펼친다 */
.empty-cell[role="button"] { cursor: pointer; }
.empty-cell[role="button"]:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }
.empty-cell[role="button"] > b::after { content: ' ⓘ'; color: var(--mute); font-weight: 400; }
/* 공통 UI — 사유 말풍선. 비활성 button 은 포커스를 받지 못해 사유가 키보드에 닿지 않으므로
   tabindex="0" 래퍼로 감싸고 aria-describedby 로 잇는다(규격 tip).
   설명문은 aria-describedby 가 가리키는 대상이라 보조기술에는 늘 읽혀야 한다 —
   display:none · visibility:hidden 이면 읽히지 않으므로 opacity 로만 감춘다. */
.tip { position: relative; display: inline-block; }
.tip:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; border-radius: 4px; }
.tip-text { position: absolute; left: 50%; bottom: calc(100% + 8px); z-index: 15; transform: translateX(-50%); width: max-content; max-width: 260px; padding: 6px 8px; border: 1px solid var(--line); border-radius: 8px; background: var(--card); color: var(--fg); font-size: 12px; line-height: 1.45; font-weight: 400; text-align: left; white-space: normal; box-shadow: 0 6px 20px var(--backdrop); pointer-events: none; opacity: 0; }
.tip:hover .tip-text, .tip:focus-visible .tip-text, .tip:focus-within .tip-text { opacity: 1; }
.asknote { margin-top: 10px; }
.cell-empty { color: var(--mute); border-bottom: 1px dashed var(--line); }

/* 장치 D·K — 배지 */
.grade-badge { font-size: 12px; color: var(--amber); border: 1px solid var(--line); padding: 2px 8px; border-radius: 999px; }
.llm-badge { font-size: 11px; color: var(--mute); border: 1px dashed var(--line); padding: 1px 7px; border-radius: 999px; }

/* 장치 L — 지금 무엇을 하는가 한 줄. 상태 문구(.nl-note)는 제 줄을 차지하므로 줄바꿈을 연다 */
.status#nowLine { margin: 6px 0 12px; flex-wrap: wrap; }
/* 진행률 — 분모를 아는 구간에만 그려진다. 경과 시계와 같은 tabular-nums 로 자릿수가 흔들리지 않게 한다 */
.status .nl-pct { font-size: 13px; font-variant-numeric: tabular-nums; color: var(--fg); white-space: nowrap; flex-shrink: 0; }
/* 상태 문구 — 오래 걸림·재시도·멈춤을 적는다. 색은 보조이고 구분은 문구가 한다 */
.status .nl-note { flex-basis: 100%; font-size: 12.5px; line-height: 1.5; }
.status[data-state="slow"] .nl-note { color: var(--amber); }
.status[data-state="retry"] .nl-note, .status[data-state="stopped"] .nl-note { color: var(--orange); }
.status[data-state="stopped"] .dot { animation: none; background: transparent; border: 2px solid var(--orange); }
/* 경과 시간 — 자릿수가 늘어도 옆 글자가 밀리지 않게 tabular-nums 를 쓴다.
   nowrap·flex-shrink:0 이 없으면 좁은 폭에서 본문이 공간을 다 먹고 «7분 42 / 초 경 / 과» 로 쪼개진다(실측). */
.status .elapsed { margin-left: auto; font-size: 13px; font-variant-numeric: tabular-nums; color: var(--mute); white-space: nowrap; flex-shrink: 0; }

/* 차트 */
.chart { margin: 0; }
.chart svg { display: block; max-width: 100%; height: auto; }
.chart-ring svg { width: auto; }
.ch-grid { stroke: var(--line); stroke-width: 1; }
.ch-lab { font-size: var(--fs-meta); fill: var(--mute); }
.ch-big { font-size: 20px; font-weight: 600; fill: var(--fg); }
.ch-legend { display: flex; gap: 12px; font-size: 12px; color: var(--mute); margin-top: 4px; }
.ch-legend i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 5px; vertical-align: middle; }
.ch-legend .ch-key { margin-right: 5px; vertical-align: middle; }
/* 관중 분포 HTML 막대 — SVG 축소로 글자가 작아지지 않게 실제 DOM 막대로 그린다(칸 폭을 채운다) */
.abar { margin-top: 4px; }
/* 구간을 박스로 묶고 좌우 2열 격자에 놓는다 — 한 열로 길게 쌓지 않아 시인성이 좋다 */
.abar-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 16px; }
.abar-box { border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px; display: grid; gap: 11px; }
.abar-row { display: grid; grid-template-columns: minmax(84px, 40%) 1fr auto; gap: 10px; align-items: center; font-size: var(--fs-label); }
.abar-label { color: var(--mute); overflow-wrap: anywhere; }
.abar-track { height: 15px; background: color-mix(in srgb, var(--fg) 9%, var(--card)); border-radius: 5px; overflow: hidden; }
.abar-fill { display: block; height: 100%; border-radius: 5px; min-width: 2px; }
.abar-row[data-series="0"] .abar-fill { background: var(--teal); }
.abar-row[data-series="1"] .abar-fill { background: var(--orange); }
.abar-row[data-series="2"] .abar-fill { background: var(--amber); }
/* 계열은 색 말고도 무늬로 갈린다 — 관중 할당은 민무늬, 앵커 비율은 빗금, 토론자 구성은 세로 줄 */
.abar-row[data-series="1"] .abar-fill, .abar-legend span[data-series="1"]::before { background-image: repeating-linear-gradient(45deg, transparent 0 4px, color-mix(in srgb, var(--bg) 45%, transparent) 4px 6px); }
.abar-row[data-series="2"] .abar-fill, .abar-legend span[data-series="2"]::before { background-image: repeating-linear-gradient(90deg, transparent 0 4px, color-mix(in srgb, var(--bg) 45%, transparent) 4px 6px); }
.abar-val { font-variant-numeric: tabular-nums; color: var(--fg); white-space: nowrap; }
.abar-legend { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 8px; font-size: var(--fs-meta); color: var(--mute); }
.abar-legend span { display: inline-flex; align-items: center; gap: 6px; }
.abar-legend span::before { content: ''; width: 12px; height: 12px; border-radius: 3px; }
.abar-legend span[data-series="0"]::before { background: var(--teal); }
.abar-legend span[data-series="1"]::before { background: var(--orange); }
.abar-legend span[data-series="2"]::before { background: var(--amber); }

/* STEP 5 토론 — 글자 크기는 사이트 기준(--fs-*)만 쓴다 */
.phase-edge { list-style: none; font-size: var(--fs-label); font-weight: 600; color: var(--mute); padding: 8px 2px 2px; }
.utt-head { font-size: var(--fs-label); align-items: center; margin-bottom: 6px; }
.utt-head b { font-size: var(--fs-ui); color: var(--fg); }
.utt .chip { font-size: var(--fs-meta); }
.anon-name { color: var(--mute); font-weight: 600; }
.slot-meta { align-items: center; font-size: var(--fs-label); margin-top: -4px; }
/* 대상 집단별 질문 수 · 신뢰도 항목 — 라벨과 값을 한 줄에 가로로 놓는다(라벨이 한 줄을 통째로 차지하지 않게) */
.plan-slots li, .rel-row, .rel-sub li { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; padding: 4px 0; }
.plan-slots .k, .rel-row .k, .rel-sub .k { margin: 0; }
.rel-row > .rel-sub { flex-basis: 100%; margin: 2px 0 0 12px; }
/* 관중 분포 막대 — 선택지 이름이 길 수 있어 이름 칸을 조금 넓힌다 */
.aud-bars { --bbar-name: 7.5em; --bbar-val: 9.5em; margin: 8px 0 14px; }
/* 제목 곁의 칩이 제목 높이만큼 늘어나 원이 되지 않게 가운데 줄에 맞춘다 */
.plan-title { align-items: center; }
.plan-title h2 { margin: 18px 0 8px; }
/* 토론 전후 입장 — 한 사람을 한 줄에 적는다 */
.post-row > span { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.mode-arrow { color: var(--mute); }
/* 토론 전후 입장 — 선택지별 인원 그래프(토론 전 청록 · 토론 후 주황 빗금)와 참가자 표 */
.post-dist { display: grid; gap: 8px; max-width: 620px; margin: 12px 0 10px; }
.pd-legend { display: flex; gap: 14px; font-size: var(--fs-meta); color: var(--mute); }
.pd-legend span { display: inline-flex; align-items: center; gap: 6px; }
.pd-legend span::before { content: ''; width: 12px; height: 12px; border-radius: 3px; background: var(--teal); }
.pd-legend span[data-when="post"]::before, .pd-bar[data-when="post"] i { background: var(--orange); background-image: repeating-linear-gradient(45deg, transparent 0 4px, color-mix(in srgb, var(--bg) 45%, transparent) 4px 6px); }
.pd-row { display: grid; grid-template-columns: 9em 1fr; gap: 10px; align-items: center; font-size: var(--fs-label); }
.pd-name { color: var(--fg); overflow-wrap: anywhere; }
.pd-bars { display: grid; gap: 4px; }
.pd-bar { display: grid; grid-template-columns: 1fr 3.5em; gap: 8px; align-items: center; }
.pd-track { height: 10px; background: color-mix(in srgb, var(--fg) 9%, var(--card)); border-radius: 3px; overflow: hidden; }
.pd-track i { display: block; height: 100%; min-width: 2px; border-radius: 3px; background: var(--teal); }
.pd-bar b { font-weight: 600; font-variant-numeric: tabular-nums; }
/* 참가자 표는 사이트 비교표(table.cmp)와 같은 규칙 — 전체 폭, 왼쪽 맞춤, 줄마다 밑줄, 머리글은 흐린 색 */
.post-table { margin-top: 10px; width: 100%; max-width: 720px; border-collapse: collapse; table-layout: fixed; font-size: var(--fs-ui); }
.post-table th, .post-table td { text-align: left; padding: 7px 10px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.post-table th { color: var(--mute); font-weight: 500; font-size: var(--fs-label); }
.post-table th:first-child, .post-table td:first-child { width: 30%; }
.post-table tr.post-row { display: table-row; }
.aud-arrived { align-items: center; gap: 4px 10px; margin: 6px 0; }
.aud-arrived .k, .aud-progress .k { margin: 0; }   /* 옛 목록용 .post-row(flex) 규칙이 표 줄을 쪼개지 않게 한다 */
.post-table .pc-changed { color: var(--amber); }
/* 대상 집단 머리줄 — 누가(대상 집단)·어떤 조건으로·어느 자리에서 말했는지를 모양과 색으로 가른다 */
.slot-title { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin: 28px 0 10px; }
.slot-title h2 { margin: 0; }
.slot-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; margin: 22px 0 8px; }
.slot-head-name { font-size: var(--fs-read); font-weight: 700; color: var(--teal); }
.slot-head-cond { font-size: var(--fs-label); color: var(--fg); padding: 2px 10px; border: 1px solid var(--teal); border-radius: 999px; background: var(--teal-soft); }
.slot-head-q { font-size: var(--fs-label); font-weight: 600; color: var(--amber); }
.slot-head-meta { font-size: var(--fs-label); color: var(--mute); }
.slot-head-q::before, .slot-head-meta::before { content: '·'; margin-right: 8px; color: var(--mute); font-weight: 400; }
/* 토론 자리 막대 — 맨 위 단계 막대(.step)와 같은 점·색 규칙을 따른다 */
.seat-sect { margin-top: 8px; }
.seat-sect h2 { margin: 18px 0 8px; }
.seat-rail { list-style: none; margin: 6px 0 8px; padding: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 0; }
.seat { display: inline-flex; align-items: center; gap: 8px; padding: 6px 10px; border-radius: 999px; color: var(--mute); font-size: var(--fs-label); white-space: nowrap; }
.seat + .seat::before { content: ''; width: 16px; height: 1px; background: var(--line); margin: 0 6px 0 -10px; }
.seat .dot { width: 10px; height: 10px; border-radius: 50%; border: 1.5px solid currentColor; flex: none; }
.seat.done { color: var(--teal); }
.seat.done .dot { background: var(--teal); border-color: var(--teal); }
.seat.now { color: var(--fg); background: var(--teal-soft); font-weight: 600; }
.seat.now .dot { background: var(--dot-now); border-color: var(--teal); animation: pulse 1.2s ease-in-out infinite; }
.seat.stalled { color: var(--amber); font-weight: 600; }
.seat.stalled .dot { border-color: var(--amber); border-width: 3px; }
.seat-who { font-size: var(--fs-meta); font-weight: 600; color: var(--amber); }
.seat.stalled .seat-who { color: var(--amber); }
.seat-rail.is-single { margin: 0 0 12px; }
@media (prefers-reduced-motion: reduce) { .seat.now .dot { animation: none; } }
.slot-meta .k { margin: 0; }
/* 사람별 발언 수 — 본문 폭에 맞춘 HTML 막대. 기준선은 막대 칸 위에 한 번씩 긋는다 */
.bbar { position: relative; display: grid; gap: 12px; max-width: 560px; margin: 16px 0 18px; --bbar-name: 6.5em; --bbar-val: 9em; }
.bbar-row { display: grid; grid-template-columns: var(--bbar-name) 1fr var(--bbar-val); gap: 10px; align-items: center; font-size: var(--fs-label); }
.bbar-name { color: var(--fg); overflow-wrap: anywhere; }
.bbar-track { height: 14px; background: color-mix(in srgb, var(--fg) 9%, var(--card)); border-radius: 4px; overflow: hidden; }
.bbar .ch-bar { display: block; height: 100%; background: var(--teal); border-radius: 4px; min-width: 2px; }
.bbar-val { font-variant-numeric: tabular-nums; white-space: nowrap; display: inline-flex; gap: 6px; align-items: center; }
.bbar-mark { font-size: var(--fs-meta); color: var(--amber); }
.bbar-lines { position: absolute; top: -4px; bottom: -4px; left: calc(var(--bbar-name) + 10px); right: calc(var(--bbar-val) + 10px); pointer-events: none; }
.bbar-lines .ch-baseline { position: absolute; top: 0; bottom: 0; width: 0; border-left: 1.5px dashed var(--mute); }
.bbar-lines .ch-baseline[data-kind="over"] { border-left-color: var(--orange); }
.bbar-rule { display: flex; flex-wrap: wrap; gap: 4px 14px; }
.bbar-rule span { display: inline-flex; align-items: center; gap: 6px; }
.bbar-rule span::before { content: ''; width: 0; height: 12px; border-left: 1.5px dashed var(--mute); }
.bbar-rule span[data-kind="over"]::before { border-left-color: var(--orange); }
.ch-draw { stroke-dasharray: 2000; stroke-dashoffset: 2000; animation: draw 1.1s var(--ease) forwards; }
.chart-ring .ch-draw { animation: none; }   /* 링은 stroke-dasharray 가 값 자체다 */
.ch-live { animation: pulse 1.2s ease-in-out infinite; }
/* 차트 값 상자(A-UX-7) — 포커스·포인터로 값·단위·근거 종류·기준 시점을 읽는다. 레일(10) 위, 모달(20) 아래다. */
.ch-tip { position: fixed; z-index: 15; transform: translate(-50%, calc(-100% - 10px)); max-width: 260px; padding: 6px 8px; border: 1px solid var(--line); border-radius: 8px; background: var(--card); color: var(--fg); font-size: 12px; line-height: 1.45; box-shadow: 0 6px 20px var(--backdrop); pointer-events: none; }
.ch-tip[hidden] { display: none; }
.chart [data-tip]:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }
@keyframes draw { to { stroke-dashoffset: 0 } }
@media (prefers-reduced-motion: reduce) { .ch-draw { animation: none; stroke-dashoffset: 0 } .ch-live { animation: none } }

/* STEP 2 — 벤치마크 */
.hits { display: grid; gap: 8px; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
.hit { border: 1px solid var(--line); border-radius: var(--radius); padding: 10px 12px; display: grid; gap: 2px; font-size: 13px; }
.hit.ok { border-color: var(--teal); }
.hit.ok b { color: var(--teal); }
.hit.nokey, .hit.failed, .hit.unusable, .hit.skipped { border-style: dashed; color: var(--mute); }
/* 쓸 수 없음 — 「실패」와 달리 다시 눌러도 같다. 점선은 같게 두되 이름을 흐리게 해 성공과 구분한다 */
.hit.unusable b, .hit.skipped b { color: var(--mute); }
/* 수집 소스 상태를 테두리 모양으로도 가른다 — 성공 실선 · 실패 이중선 · 건너뜀 점 · 쓸 수 없음 점선. 키 없음은 장치 C 빈 칸으로 그린다 */
.hit.failed { border-style: double; border-width: 3px; }
.hit.skipped { border-style: dotted; }
/* 근거를 고른 과정 — 「수집 소스」가 아니라 «조용히 줄어든 것을 말로 만든 자리» 다.
   한 줄에 하나씩 세로로 쌓는다 — 소스 칸처럼 격자로 두면 다시 «소스 목록» 으로 읽힌다. */
.proc { display: grid; gap: 8px; }
.proc-line { border: 1px solid var(--line); border-radius: var(--radius); padding: 10px 12px; display: grid; gap: 3px; font-size: var(--fs-ui); }
.proc-line b { color: var(--fg); font-weight: 600; }
.proc-line .mute { font-size: var(--fs-meta); }
/* 발췌 문단은 읽는 본문이다 — 출처·시점 같은 메타(span.mute)와 달리 읽는 크기·본문색으로 둔다 */
.proc-line p.mute { font-size: var(--fs-read); color: var(--fg); margin: 0; }
.proc-line .cell-empty { font-size: var(--fs-meta); justify-self: start; }
.bcard { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px; display: grid; gap: 8px; }
.bcard header { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.bcard .src { font-size: 12.5px; color: var(--mute); display: flex; gap: 6px; align-items: center; }
.bcard .src a { color: var(--teal); }
.bcard .price { font-weight: 600; }
.bcard .excerpt { margin: 0; font-size: 13px; color: var(--mute); }
/* 제외한 후보 — 흐림을 «글자» 에 걸지 않는다. 흐리면 읽을 수 있는 대비가 나오지 않고,
   제외한 까닭을 적은 본문과 출처가 가장 먼저 안 보이게 된다. 상태는 상자가 알린다:
   가라앉은 배경 + 점선 테두리, 그리고 체크박스와 칩이 글자로 같은 말을 한다. */
.bcard.is-excluded { background: var(--bg); border-style: dashed; }
.tgl { font-size: 12.5px; color: var(--mute); display: flex; gap: 6px; align-items: center; }
.tbl-wrap { overflow-x: auto; }
table.cmp { border-collapse: collapse; width: 100%; font-size: 13px; }
table.cmp th, table.cmp td { text-align: left; padding: 6px 10px; border-bottom: 1px solid var(--line); vertical-align: top; }
table.cmp th { color: var(--mute); font-weight: 500; }
/* 행 머리 칸(항목 이름)은 열 머리와 달리 읽는 내용이라 본문 색으로 둔다 */
table.cmp th[scope="row"], table.tbl th[scope="row"] { color: var(--ink-body); }
/* 페이지 공용 표(table.tbl) — table.cmp 와 같은 틀. 칸 안의 긴 ID·영문 키는 어디서든 줄을 바꿔 375px 에서도 가로로 넘치지 않는다 */
table.tbl { border-collapse: collapse; width: 100%; font-size: 13px; }
table.tbl th, table.tbl td { text-align: left; padding: 6px 10px; border-bottom: 1px solid var(--line); vertical-align: top; overflow-wrap: anywhere; }
table.tbl th { color: var(--mute); font-weight: 500; }
table.tbl caption { text-align: left; padding: 0 0 4px; color: var(--mute); font-size: var(--fs-label); }
/* 작은 화면의 표 카드 모양(설계 03 §7.4) — table.stack(tbl·cmp 공통)은 560px 이하에서 행을 카드로 쌓고, 칸마다 data-label 의 열 이름을 앞에 적는다.
   머리 행은 화면에서 숨기되 화면낭독기에는 남긴다. data-label 이 없는 칸은 열 이름 없이 값만 보인다 */
@media (max-width: 560px) {
  table.stack, table.stack tbody, table.stack tr, table.stack td, table.stack th[scope="row"] { display: block; width: 100%; }
  table.stack thead tr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  table.stack tr { border-bottom: 1px solid var(--line); padding: 6px 0; }
  table.stack td, table.stack th[scope="row"] { border-bottom: 0; padding: 2px 0; }
  table.stack td[data-label]::before { content: attr(data-label) " · "; color: var(--mute); font-size: var(--fs-label); }
}
.proscons { display: grid; gap: 10px; }
.pc-row { display: grid; grid-template-columns: 160px 1fr 1fr; gap: 12px; border: 1px solid var(--line); border-radius: var(--radius); padding: 10px 12px; }
.pc-row ul { margin: 0; padding-left: 16px; font-size: 13px; }
.pc-row .pros li::marker { color: var(--teal); } .pc-row .cons li::marker { color: var(--orange); }
/* 빈 상태 칸은 항목이 아니다 — 불릿을 주지 않는다 */
.pc-row li.pc-none { list-style: none; margin-left: -16px; }
.pc-name { font-weight: 500; }

/* STEP 3 — 지표·슬롯 */
.siggrid { grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); }
.metric-strip { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; margin-bottom: 14px; }
.metric-tile { min-height: 78px; display: grid; align-content: center; gap: 5px; padding: 13px 15px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); }
.metric-tile span { color: var(--mute); font-size: 12px; }
.metric-tile b { font-size: 22px; line-height: 1.1; font-weight: 600; }
.metric-tile em { min-width: 0; color: var(--mute); font-size: 12px; font-style: normal; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.metric-tile.ok { border-color: color-mix(in srgb, var(--teal) 42%, var(--line)); background: var(--teal-soft); }
/* 옅은 강조 바탕 위 보조 글자 — 밝은 테마 --mute / --teal-soft 는 4.41 이라 글자색을 --fg 쪽으로 25% 당겨 4.5:1 을 넘긴다 */
.metric-tile.ok span, .metric-tile.ok em, .metric-tile.ok .mt-label { color: color-mix(in srgb, var(--mute) 75%, var(--fg)); }
.metric-tile.warn { border-color: color-mix(in srgb, var(--amber) 48%, var(--line)); background: color-mix(in srgb, var(--amber) 8%, var(--card)); }
.p3-signal-groups { display: grid; gap: 14px; }
.p3-signal-group { display: grid; gap: 8px; }
.p3-signal-group h3 { margin: 0; color: var(--mute); font-size: 12px; font-weight: 600; letter-spacing: 0; }
.sig { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 14px; display: grid; gap: 4px; }
.sig .v { font-size: 26px; font-weight: 600; line-height: 1.2; }
.sig .v small { font-size: 12px; color: var(--mute); margin-left: 4px; font-weight: 400; }
.sig .meta { display: flex; gap: 8px; flex-wrap: wrap; font-size: 12px; align-items: center; }
/* 상관 목록 — 좁은 화면에서도 읽히게 항목마다 가로줄(박스)로 나눈다. 글머리표 대신 이름 한 줄·값 한 줄 */
.sig-corr { margin-top: 4px; }
.sig-corr > b { display: block; font-size: var(--fs-meta); color: var(--mute); font-weight: 600; margin-bottom: 4px; }
.sig-corr ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
/* 한 항목을 이름 · 값 · 표본 세 줄로 왼쪽에 가지런히 쌓는다 — 좁은 카드에서 가장 읽기 쉽다 */
.sig-corr li { display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  padding: 8px 11px; background: color-mix(in srgb, var(--fg) 5%, var(--card)); border-radius: 8px; }
.sig-corr .corr-with { font-weight: 600; font-size: var(--fs-ui); }
.sig-corr .corr-val { font-size: var(--fs-ui); }
.sig-corr li .mute { font-size: var(--fs-meta); }
/* 카드가 넓어져도 작은 추세 그림은 커지지 않게 폭을 고정한다 */
.sig-trend { max-width: 340px; }
.sig-trend svg { max-width: 100%; height: auto; }
.delta.up { color: var(--teal); } .delta.down { color: var(--orange); }
.tv { display: grid; gap: 8px; max-width: 260px; }
.hold { margin-top: 12px; }
.hold input { font: inherit; padding: 8px 10px; border: 1px solid var(--mute); border-radius: 8px; background: var(--card); color: var(--fg); }
.slotgrid { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
/* STEP 4 슬롯 탭·토론자 카드 — 카드는 .slot 의 뒤집기 규칙을 그대로 쓴다 */
.ptabs { display: flex; gap: 6px; flex-wrap: wrap; margin: 4px 0 12px; }
.ptabs [role="tab"] { font: inherit; font-size: 13px; padding: 6px 12px; border-radius: 999px; border: 1px solid var(--line); background: var(--card); color: var(--mute); cursor: pointer; }
.ptabs [role="tab"][aria-selected="true"] { color: var(--fg); border-color: var(--teal); background: var(--teal-soft); }
.pgrid { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); margin-top: 12px; }
.pcard { min-height: 320px; }
.fitf td, .fitf th { font-size: 12px; }
.slot { position: relative; cursor: pointer; perspective: 1000px; outline: none; }
.slot:focus-visible .face { outline: 2px solid var(--teal); outline-offset: 2px; box-shadow: 0 0 0 5px var(--teal-soft); }
/* 앞면이 카드 높이를 정하고(내용에 딱 맞게), 뒷면은 그 위에 겹쳐 얹는다 — 앞면에 빈 공간이 생기지 않는다 */
.slot .face { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px; backface-visibility: hidden; transition: transform .5s var(--ease); }
.slot .face.front { position: relative; }
.slot .kv dd, .slot .cmp td, .slot .proc-line { overflow-wrap: anywhere; }
.slot .face.back { position: absolute; inset: 0; overflow: auto; transform: rotateY(180deg); font-size: 14px; }
.slot.is-flipped .face.front { transform: rotateY(180deg); }
.slot.is-flipped .face.back { transform: rotateY(0); }
@media (prefers-reduced-motion: reduce) { .slot .face { transition: none } }
.slot .kv { grid-template-columns: 56px 1fr; font-size: var(--fs-ui); }
.share { margin-top: 10px; display: flex; gap: 8px; align-items: baseline; }
.share b { font-size: 22px; color: var(--teal); }
/* ★.share 는 «값이 있을 때» 큰 숫자를 보이는 자리다. 빈 칸(emptyCell)에는 그 규칙을 적용하지 않는다.
   가로 배치(flex) + 22px 는 좁은 슬롯 카드에서 「미앵커」를 「미앵」으로 자른다. */
.empty-cell.share { display: grid; }
.empty-cell.share b { font-size: inherit; color: var(--fg); }
.flip-hint { margin-top: 10px; font-size: 11px; }
.un { margin: 0; padding-left: 16px; }

/* STEP 5 — FGI */
.fgi-head { margin-bottom: 8px; }
.vsteps { display: grid; gap: 8px; }
.vstep { display: flex; gap: 8px; align-items: center; color: var(--mute); font-size: var(--fs-label); }
.vstep .dot { width: 10px; height: 10px; border-radius: 50%; border: 1.5px solid currentColor; }
.vstep.done { color: var(--teal); } .vstep.done .dot { background: var(--teal); border-color: var(--teal); }
.vstep.now { color: var(--fg); } .vstep.now .dot { background: var(--dot-now); border-color: var(--teal); animation: pulse 1.2s ease-in-out infinite; }
/* 끝난 조사의 단계 — ★now 는 점이 깜빡여«지금 하고 있다»고 말한다. 실패한 조사에서 그것은 거짓이다.
   stopped = 마지막으로 확인된 단계(amber · 주의) · none = 진행되지 않은 단계(점선 · 대기와 다르게 보인다) */
.vstep.stopped { color: var(--amber); } .vstep.stopped .dot { border-color: var(--amber); }
/* 서버가 보낸 오류 원문 — 접어 두고 펼치면 전문을 복사할 수 있게 줄바꿈을 살린다 */
.err-detail { margin-top: 8px; font-size: 12.5px; color: var(--mute); }
.err-detail summary { cursor: pointer; }
.err-detail pre { white-space: pre-wrap; word-break: break-word; margin: 6px 0 0; padding: 8px 10px; border: 1px dashed var(--line); border-radius: 8px; font: inherit; }
/* 진행되지 않은 단계 — 흐림을 걷는다. 점선 점이 모양으로 가르고, 줄 끝에 «진행되지 않았습니다» 가 글자로 붙는다. */
.vstep.none { color: var(--mute); } .vstep.none .dot { border-style: dashed; }
.stage-note { font-size: var(--fs-label); margin-top: 8px; }
.stage-banner { border-left: 3px solid var(--teal); background: var(--teal-soft); border-radius: 0 var(--radius) var(--radius) 0; padding: 10px 12px; margin: 10px 0; font-size: var(--fs-ui); }
.ticker { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; max-height: 60vh; overflow: auto; }
.utt { border: 1px solid var(--line); border-radius: var(--radius); padding: 10px 12px; background: var(--card); }
.utt .who { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; font-size: var(--fs-label); margin-bottom: 4px; }
.utt p { margin: 0; font-size: var(--fs-read); }
.stance { font-size: var(--fs-meta); padding: 0 6px; border-radius: 999px; border: 1px solid var(--line); }
.stance.pos { color: var(--teal); } .stance.neg { color: var(--orange); }
.intervene textarea { width: 100%; font: inherit; font-size: var(--fs-read); color: var(--fg); background: var(--bg); border: 1px solid var(--mute); border-radius: 10px; padding: 10px 12px; resize: vertical; }

/* STEP 7 — 결과 */
.rep-sec { margin: 0 0 18px; }
.rep-body { white-space: pre-wrap; overflow-wrap: anywhere; font: inherit; font-size: 14px; margin: 0; }
.evid summary { cursor: pointer; }
.dl { gap: 8px; }

/* 장치 I — 부족한 정보 질문 카드 */
.askq { border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px; margin-bottom: 16px; background: var(--teal-soft); display: grid; gap: 8px; }
.qcard { display: grid; gap: 4px; font-size: 13.5px; }
.qcard input { font: inherit; padding: 8px 10px; border: 1px solid var(--mute); border-radius: 8px; background: var(--card); color: var(--fg); }

/* 장치 — STEP 0 고객 자료 추가(§7.6) */
.askassets { border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 16px; margin-top: 14px; display: grid; gap: 8px; }
.askassets summary { cursor: pointer; font-size: 13.5px; color: var(--mute); }
.askassets label { display: block; font-size: 13px; color: var(--mute); margin-bottom: 4px; }
.askassets textarea, .askassets input, .askassets select { font: inherit; font-size: 13.5px; padding: 8px 10px; border: 1px solid var(--mute); border-radius: 8px; background: var(--card); color: var(--fg); width: 100%; margin-top: 4px; }
/* 자료 추가 입구 — 형식 고르기 줄. 고른 형식은 테두리 굵기로도 갈린다(색만으로 가르지 않는다) */
.askassets .addkinds { display: flex; flex-wrap: wrap; gap: 8px; }
.askassets .addkinds label { display: inline-flex; align-items: center; gap: 6px; margin: 0; padding: 6px 12px; border: 1px solid var(--line); border-radius: 999px; color: var(--fg); cursor: pointer; }
.askassets .addkinds label:has(input:checked) { border-width: 2px; border-color: var(--fg); }
.askassets .addkinds input[type="radio"] { width: auto; margin: 0; padding: 0; }
.askassets .addpane { display: grid; gap: 8px; }
.askassets .addpane[hidden] { display: none; }
.chip .item-state { font-weight: 600; }
/* 글자 수 묶음 — 숫자·막대·상태 문구를 세로로 쌓아 서로 겹치지 않게 한다. 게이지 안의 글자는 숫자 칸과 겹치므로 감춘다 */
.askmeter { display: grid; gap: 4px; flex: 1 1 240px; min-width: 0; }
.askmeter .char-gauge svg { display: block; max-width: 100%; height: auto; }
#askGauge .ch-lab { display: none; }
.askmeter .char-state:empty { display: none; }
.askmeter .char-state { font-size: 13px; }
.btn.sm { font-size: 11px; padding: 2px 6px; }
/* 첨부 줄 — 파일 입력칸이 그리는 기본 버튼은 문구를 바꿀 수 없으므로 감추고 label 을 버튼으로 쓴다 */
.askfile { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 4px; }
.askfile input[type="file"] { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.askfile label.btn { display: inline-block; width: auto; margin: 0; cursor: pointer; color: var(--fg); }
.askfile input[type="file"]:focus-visible + label.btn { outline: 2px solid var(--fg); outline-offset: 2px; }
.askfile .name { font-size: 12.5px; color: var(--mute); }

/* 로그인 모달 */
.modal { position: fixed; inset: 0; z-index: 20; background: var(--backdrop); display: flex; align-items: center; justify-content: center; padding: 20px; }
.modal[hidden] { display: none; }
.modal-card { position: relative; background: var(--card); border: 1px solid var(--line); border-radius: 16px; padding: 24px; width: min(420px, 100%); display: grid; gap: 12px; }
.modal-card h2 { margin: 0; padding-right: 36px; }
.modal-close { position: absolute; top: 12px; right: 12px; width: 32px; height: 32px; border-radius: 999px; border: 1px solid var(--line);
  background: transparent; color: var(--fg); font: inherit; font-size: 18px; line-height: 1; cursor: pointer; }
.modal-card label { display: grid; gap: 4px; font-size: 13px; color: var(--mute); }
.modal-card input { font: inherit; padding: 9px 11px; border: 1px solid var(--mute); border-radius: 8px; background: var(--bg); color: var(--fg); }
.modal-card a[data-auth] { color: var(--teal); font-weight: 700; text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1.5px; }
.modal-card a[data-auth]:hover { color: var(--fg); }

/* ── 메인 화면(로그인 전) — 설계도 D1-6·F1.6 ─────────────────────────
   ★배경은 «이 화면에만» 깔린다. STEP 0~7 작업 화면에는 깔지 않는다.
   ★z-index 0 이라 .rail(10)·.modal(20) 아래에 깔린다.
   ★★overflow:hidden 을 셸 body 에 «걸지 않는다» — 걸면 다른 페이지의 스크롤이 죽는다. 이 컨테이너에만 건다. */
.mainbg { position: fixed; inset: var(--rail-h) 0 0 0; z-index: 0; overflow: hidden; pointer-events: none; background: var(--main-ground); }
/* ★레일이 없는 화면(로그인 전 — shell.js 가 .full 을 붙인다)에서는 배경이 위까지 찬다. */
.mainbg.full { inset: 0; }
.mainbg[hidden] { display: none; }
.mainbg canvas { display: block; width: 100%; height: 100%; }

/* ★글자는 입자 위에 «바로» 놓인다 — 글자 뒤에 어둠막을 두지 않는다. */
.mainpage { position: relative; z-index: 1; min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 20px; }
/* ★Michroma 는 «브랜드 로고 한 곳»에만 쓴다(D1-3). 본문·부제는 Noto Sans KR 다. */
.mainbrand { margin: 0; font-family: Michroma, 'Noto Sans KR', sans-serif;
  font-size: clamp(28px, 7.2vw, 76px); letter-spacing: .30em; text-indent: .30em;
  font-weight: 400; line-height: 1; white-space: nowrap; color: var(--fg); text-shadow: var(--main-ink-edge), var(--main-glow); }
/* 부제는 자체 배경을 깔아 입자 위에서도 대비가 --mute/--main-ground 로 고정된다. 여백·반경은 .chip 과 같은 값이다. */
.mainlead { margin: 18px 0 0; font-size: 12px; font-weight: 400; letter-spacing: .22em; color: var(--mute); display: inline-block; padding: 4px 10px; border-radius: 999px; background: var(--main-ground); }
.mainact { margin: 40px 0 0; }
.main-theme-btn { position: fixed; top: 24px; right: 24px; z-index: 2; margin-left: 0; background: var(--card); backdrop-filter: blur(10px); }
/* 움직임을 줄인 화면에서도 입자는 계속 그려진다(bg.js 는 목표 수만 낮춘다).
   그래서 화려한 glow 만 끄고 가독성을 맡는 테는 남긴다. */
@media (prefers-reduced-motion: reduce) { .mainbrand { text-shadow: var(--main-ink-edge); } }

/* ── D1-12 ㉢ 매체 게시 상태 배지 — 상태는 표식(.pj-mark) 모양으로 가르고 색은 보조다 ── */
.pj-badge { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; padding: 3px 10px; border: 1px solid var(--line); border-radius: 999px; color: var(--fg); background: var(--card); }
.pj-badge b { font-weight: 500; }
.pj-badge > span { color: var(--mute); }
/* 외부 심사·직접 조치는 정상 대기다 — 실패색을 쓰지 않고 점선 테두리로만 구분한다 */
.pj-badge[data-tone="wait"] { border-style: dashed; border-color: var(--mute); }
.pj-badge[data-tone="attn"] { border-color: var(--amber); }
.pj-badge[data-tone="fail"] { border: 2px solid var(--orange); }
.pj-badge[data-tone="fail"] b { color: var(--orange); }
.pj-mark, .st-mark { position: relative; display: inline-block; flex: none; width: 10px; height: 10px; box-sizing: border-box; vertical-align: middle; color: var(--teal); }
.pj-badge[data-tone="wait"] .pj-mark, .status-badge[data-tone="wait"] .st-mark { color: var(--mute); }
.pj-badge[data-tone="attn"] .pj-mark, .status-badge[data-tone="attn"] .st-mark { color: var(--amber); }
.pj-badge[data-tone="fail"] .pj-mark, .status-badge[data-tone="fail"] .st-mark { color: var(--orange); }
.pj-mark[data-shape="ring"], .st-mark[data-shape="ring"] { border: 1.5px solid currentColor; border-radius: 50%; }
.pj-mark[data-shape="ring-dash"], .st-mark[data-shape="ring-dash"] { border: 1.5px dashed currentColor; border-radius: 50%; }
.pj-mark[data-shape="ring-dot"], .st-mark[data-shape="ring-dot"] { border: 2px dotted currentColor; border-radius: 50%; }
.pj-mark[data-shape="half"], .st-mark[data-shape="half"] { border: 1.5px solid currentColor; border-radius: 50%; box-shadow: inset 4px 0 0 0 currentColor; }
.pj-mark[data-shape="dot"], .st-mark[data-shape="dot"] { border-radius: 50%; box-shadow: inset 0 0 0 5px currentColor; }
.pj-mark[data-shape="dot-ring"], .st-mark[data-shape="dot-ring"] { width: 12px; height: 12px; border: 1.5px solid currentColor; border-radius: 50%; box-shadow: inset 0 0 0 2px var(--card), inset 0 0 0 5px currentColor; }
.pj-mark[data-shape="bars"], .st-mark[data-shape="bars"] { width: 9px; border-left: 3px solid currentColor; border-right: 3px solid currentColor; }
.pj-mark[data-shape="square"], .st-mark[data-shape="square"] { border: 1.5px solid currentColor; }
.pj-mark[data-shape="square-dash"], .st-mark[data-shape="square-dash"] { border: 1.5px dashed currentColor; }
.pj-mark[data-shape="square-double"], .st-mark[data-shape="square-double"] { border: 3px double currentColor; }
.pj-mark[data-shape="diamond"], .st-mark[data-shape="diamond"] { width: 8px; height: 8px; margin: 1px; border: 1.5px solid currentColor; transform: rotate(45deg); }
.pj-mark[data-shape="cross"]::before, .pj-mark[data-shape="cross"]::after, .st-mark[data-shape="cross"]::before, .st-mark[data-shape="cross"]::after { content: ''; position: absolute; left: 4px; top: -1px; width: 2px; height: 12px; box-shadow: inset 0 0 0 1px currentColor; transform: rotate(45deg); }
.pj-mark[data-shape="cross"]::after, .st-mark[data-shape="cross"]::after { transform: rotate(-45deg); }
.pj-mark[data-shape="triangle"], .st-mark[data-shape="triangle"] { width: 0; height: 0; border-left: 5px solid transparent; border-right: 5px solid transparent; border-bottom: 10px solid currentColor; }
.pj-mark[data-shape="none"], .st-mark[data-shape="none"] { display: none; }

/* 제4부 4.6 evidence_type 배지 — 실측=실선 · 계산=점선 · AI 분석=빗금. 섞인 입력은 이중선 오류 칸 */
.ev-badge { display: inline-flex; align-items: center; gap: 4px; font-size: 11.5px; padding: 1px 8px; border: 1.5px solid var(--mute); border-radius: 4px; color: var(--fg); }
.ev-badge b { font-weight: 600; letter-spacing: .02em; }
.ev-badge[data-shape="dashed"] { border-style: dashed; }
.ev-badge[data-shape="hatch"] { background-image: repeating-linear-gradient(135deg, var(--line) 0 2px, transparent 2px 6px); }
.ev-badge[data-shape="empty"] { border-style: dotted; color: var(--mute); }
.ev-badge[data-shape="error"] { border: 3px double var(--orange); }
.ev-badge[data-shape="error"] b { color: var(--orange); }


/* ── 공통 UI 컴포넌트 (ui.js statusBadge·gradeChip·evidenceChip·metricTile·copyButton·sourceDrawer) ──
   ★표식(.st-mark)은 .pj-mark 와 «같은 규칙» 을 쓴다. 도형 정의를 두 벌로 두지 않는다.
   ★새 테두리는 색 토큰 대신 currentColor 를 상속받는다 — 테두리 색 분류 사전(design/border-classes.json)은
     이 파일 밖이라 새 선언을 등록할 수 없다. 톤은 color 한 줄로 바뀌고 테두리가 따라간다. */
.status-badge { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px; max-width: 100%; font-size: 12px; padding: 3px 10px; border: 1px solid currentColor; border-radius: 999px; color: var(--line); background: var(--card); }
.status-badge b { color: var(--fg); font-weight: 500; }
/* 사전에 없는 상태에 덧붙는 원래 값 — 문구가 아니라 받은 값이므로 본문과 무게를 달리한다 */
.status-badge > span { color: var(--mute); }
/* 대기·사람 손이 필요한 상태를 실패색으로 그리지 않는다. 선 «모양» 과 굵기가 함께 가른다 */
.status-badge[data-tone="wait"] { color: var(--mute); border-style: dashed; }
.status-badge[data-tone="attn"] { color: var(--amber); }
.status-badge[data-tone="fail"] { color: var(--orange); border-width: 2px; }
.status-badge[data-tone="fail"] b { color: var(--orange); }

/* 등급 칩 — data-steps 0~7 은 «순서» 일 뿐 좋고 나쁨이 아니다.
   그래서 단계마다 색을 달리하지 않고 한 색조로 두어 «개수» 로만 읽히게 한다. */
.grade-chip { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; padding: 1px 8px; border: 1px solid currentColor; border-radius: 999px; color: var(--line); background: var(--card); }
.grade-chip b { color: var(--fg); font-weight: 600; letter-spacing: .02em; }
.gc-steps { color: var(--mute); font-size: 9px; line-height: 1; letter-spacing: .06em; white-space: nowrap; font-style: normal; }
/* E0 은 단계 표식이 없다(빈 문자열) — 빈 칸이 간격만 남기지 않게 지운다 */
.grade-chip[data-steps="0"] .gc-steps { display: none; }

/* 근거 한 칸 — 종류 배지·출처·기준 시점·등급이 한 줄에 선다. 좁은 폭에서는 줄이 바뀐다 */
.evidence-chip { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px; max-width: 100%; font-size: 12px; color: var(--fg); }
.ev-src { overflow-wrap: anywhere; }
.ev-at { color: var(--mute); font-variant-numeric: tabular-nums; }
/* 「출처 없음」·「기준 시점 없음」은 값이 아니라 빈 칸이다 — 점선 밑줄로 실제 값과 갈라 둔다 */
.evidence-chip .ev-gap { color: var(--mute); border-bottom: 1px dashed currentColor; }

/* 지표 한 칸 — 칸 자체(.metric-tile)는 이미 있는 규칙을 쓰고 여기서는 자식만 정한다.
   delta 의 오르내림을 색으로 말하지 않는다 — 마크업에 방향이 없고 좋고 나쁨은 화면이 정할 값이 아니다. */
.metric-tile .mt-label { color: var(--mute); font-size: 12px; line-height: 1.3; }
.metric-tile .mt-value { font-variant-numeric: tabular-nums; }
.metric-tile .mt-unit { margin-left: 3px; }
.metric-tile .mt-delta { color: var(--fg); font-size: 12.5px; font-variant-numeric: tabular-nums; }
.metric-tile .mt-baseline { font-size: 11.5px; }
/* 값이 없는 칸 — 0 으로 그리지 않는다. 빈 칸임이 점선으로 보인다 */
.metric-tile .mt-value.is-empty { font-size: 13px; font-weight: 400; justify-self: start; border-bottom: 1px dashed currentColor; }

/* 복사 단추 — 요청·성공·실패를 같은 표시로 쓰지 않는다. 결과는 옆 칸에 글자로 남는다(role="status") */
.copy-button { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 8px; max-width: 100%; }
.copy-btn { flex: none; }
.copy-state { font-size: 12px; color: var(--mute); overflow-wrap: anywhere; }
/* 아직 누르지 않았으면 칸이 비어 있다 — 빈 칸이 자리를 먹지 않게 둔다 */
.copy-state:empty { display: none; }

/* 근거 드로어 — 오른쪽에서 열린다. 테두리는 box-shadow 로 그어 카드 바탕과 갈린다 */
.source-drawer { position: fixed; inset: 0 0 0 auto; z-index: 20; width: min(380px, 100vw); display: flex; flex-direction: column; gap: 10px; padding: 16px; overflow-y: auto; background: var(--card); color: var(--fg); box-shadow: -1px 0 0 var(--line), -8px 0 24px var(--backdrop); }
/* ★hidden 을 display:flex 가 덮으면 닫아도 남는다 */
.source-drawer[hidden] { display: none; }
.sd-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding-bottom: 8px; box-shadow: inset 0 -1px 0 var(--line); }
.sd-head b { font-weight: 600; }
.sd-close { flex: none; }
.sd-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.sd-list li { display: grid; gap: 4px; padding: 10px 12px; border-radius: var(--radius); box-shadow: inset 0 0 0 1px var(--line); }
.sd-id { font-size: 12px; font-weight: 600; color: var(--mute); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.sd-label { font-size: 13px; }
.sd-empty { margin: 0; font-size: 13px; color: var(--mute); }

/* D1-12 ㉠ 검사 6항목 — 통과·실패·판정 없음을 표식 모양과 문구로 가른다 */
.check-sum { list-style: none; margin: 10px 0; padding: 0; display: grid; gap: 4px; font-size: 12.5px; }
.check-sum .ck { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
table.checks caption { text-align: left; padding: 0 0 4px; }
table.checks td.ck { white-space: nowrap; }
.ck b { font-weight: 500; margin-left: 4px; }
.ck span { color: var(--mute); margin-left: 4px; }
.ck[data-check="fail"] .pj-mark, .ck[data-check="fail"] b { color: var(--orange); }
.ck[data-check="unknown"] .pj-mark, .ck[data-check="unknown"] b { color: var(--mute); }

/* D1-12 ㉡ 토론자 미달 — 부족분과 제안 문구만 둔다 */
.shortfall { border: 1px dashed var(--mute); border-radius: var(--radius); padding: 10px 12px; margin-top: 10px; display: grid; gap: 4px; font-size: 13px; }
.shortfall b { font-weight: 500; }
.shortfall .suggest { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }

/* 장치 N — 다음에 확인할 것. 열리는 화면이 없는 버튼은 점선 테두리로 형태를 바꾼다 */
.next-card { display: grid; gap: 8px; align-content: start; }
.next-card .btn { justify-self: start; }
.next-card .btn[disabled] { border-style: dashed; color: var(--mute); cursor: not-allowed; }
.mix-entry-panel { display: grid; gap: 8px; align-content: start; padding: 18px 20px; border: 1px solid var(--line); border-radius: 8px; background: var(--card); }
.mix-entry-panel .btn { justify-self: start; }

/* MIX 운영 화면 */
.mix-root { display: grid; gap: 18px; }
.mix-stage-shell { display: grid; gap: 18px; }
.mix-stage-head { display: grid; grid-template-columns: minmax(0, 1fr) minmax(240px, 340px); gap: 18px; align-items: end; padding: 22px 24px; border: 1px solid var(--line); border-radius: 8px; background: color-mix(in srgb, var(--card) 86%, var(--teal-soft)); }
.mix-stage-head h1 { margin: 0 0 8px; font-size: 30px; line-height: 1.15; }
.mix-stage-head .lead { max-width: 720px; margin: 0; }
.mix-stage-meta { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 5px 12px; padding: 14px; border: 1px solid var(--line); border-radius: 8px; background: var(--card); font-size: 13px; }
.mix-stage-meta span { color: var(--mute); }
.mix-stage-meta b { min-width: 0; overflow-wrap: anywhere; font-weight: 600; }
.mix-stage-body { display: grid; gap: 16px; }
.mix-stage-actions { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding-top: 4px; }
.mix-stage-actions span { color: var(--mute); font-size: 13px; }
.mix-ops { display: grid; gap: 12px; }
.mix-ops-head { display: flex; align-items: start; justify-content: space-between; gap: 14px; }
.mix-ops-head h2 { margin: 0 0 6px; }
.mix-ops-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: stretch; }
.mix-ops-grid > .card { height: 100%; }
.mix-cost-editor { display: grid; gap: 12px; }
.mix-form-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.mix-form-row label, .mix-cost-fields label, .mix-full-label { display: grid; gap: 6px; min-width: 0; color: var(--mute); font-size: 12px; }
.mix-form-row select, .mix-form-row input, .mix-cost-fields input, .mix-full-label input { width: 100%; min-height: 38px; font: inherit; color: var(--fg); background: var(--card); border: 1px solid var(--mute); border-radius: 8px; padding: 8px 10px; }
.mix-cost-fields { display: grid; grid-template-columns: repeat(5, minmax(92px, 1fr)); gap: 10px; }
.mix-cost-fields input::placeholder { color: var(--mute); }
.mix-advanced-json { border-top: 1px solid var(--line); padding-top: 10px; }
.mix-advanced-json summary { cursor: pointer; color: var(--mute); font-size: 13px; }
.mix-advanced-json[open] summary { margin-bottom: 8px; color: var(--fg); }
.mix-json { width: 100%; min-height: 180px; resize: vertical; font: 12px/1.45 ui-monospace, SFMono-Regular, Consolas, monospace; color: var(--fg); background: var(--bg); border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px; }
.mix-select { width: 100%; font: inherit; color: var(--fg); background: var(--card); border: 1px solid var(--line); border-radius: 8px; padding: 9px 10px; }
.mix-channel-picker { display: grid; gap: 12px; }
.mix-channel-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.mix-channel-choice { position: relative; display: grid; grid-template-columns: 20px minmax(0, 1fr); gap: 10px; align-items: start; min-height: 76px; padding: 12px; border: 1px solid var(--line); border-radius: 8px; background: var(--bg); cursor: pointer; }
.mix-channel-choice input { position: absolute; opacity: 0; pointer-events: none; }
.mix-channel-check { width: 18px; height: 18px; border: 2px solid var(--mute); border-radius: 3px; background: var(--card); margin-top: 2px; }
.mix-channel-choice input:checked + .mix-channel-check { border-color: var(--teal); background: var(--teal); box-shadow: inset 0 0 0 3px var(--card); }
.mix-channel-choice:has(input:checked) { border-color: var(--teal); background: color-mix(in srgb, var(--teal) 10%, var(--card)); }
.mix-channel-copy { display: grid; gap: 4px; min-width: 0; }
.mix-channel-copy b { font-size: 14px; font-weight: 650; overflow-wrap: anywhere; }
.mix-channel-copy em { width: fit-content; font-style: normal; color: var(--teal); font-size: 11px; border: 1px solid color-mix(in srgb, var(--teal) 36%, var(--line)); border-radius: 999px; padding: 2px 7px; background: var(--teal-soft); }
.mix-channel-copy small { color: var(--mute); font-size: 12px; line-height: 1.35; }
/* 고를 수 없는 매체 — 흐림을 걷는다. 라디오에 disabled 가 걸려 있고 까닭이 말풍선으로 붙으므로
   상태는 이미 전해진다. 점선 테두리를 더해 제외한 후보 카드와 같은 어휘로 한눈에 갈린다. */
.mix-channel-choice.is-disabled { cursor: not-allowed; border-style: dashed; }
.mix-channel-confirm { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 10px 12px; border: 1px solid color-mix(in srgb, var(--teal) 34%, var(--line)); border-radius: 8px; background: var(--teal-soft); color: color-mix(in srgb, var(--mute) 75%, var(--fg)); font-size: 13px; }
.mix-channel-confirm-btn { min-height: 42px; padding-inline: 18px; font-weight: 700; box-shadow: 0 0 0 3px color-mix(in srgb, var(--teal) 18%, transparent); }
.mix-driver-status, .mix-driver-empty { display: grid; gap: 10px; }
.mix-driver-empty { padding: 12px; border: 1px solid var(--line); border-radius: 8px; background: var(--bg); }
.mix-driver-empty b { font-size: 15px; }
.mix-driver-empty p { margin: 0; color: var(--mute); line-height: 1.55; }
.mix-driver-empty ul { margin: 0; padding-left: 18px; color: var(--mute); font-size: 13px; }
.mix-driver-empty details { border-top: 1px solid var(--line); padding-top: 8px; color: var(--mute); font-size: 12px; }
.mix-driver-empty summary { cursor: pointer; }
.mix-driver-empty code { display: block; margin-top: 7px; overflow-wrap: anywhere; color: var(--fg); }
.mix-op-result { margin: 0; max-height: 220px; overflow: auto; white-space: pre-wrap; overflow-wrap: anywhere; font: 12px/1.45 ui-monospace, SFMono-Regular, Consolas, monospace; border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px; background: var(--bg); }
.mix-kpi-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.mix-kpi-grid div { min-height: 66px; display: grid; align-content: center; gap: 3px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 8px; background: var(--bg); }
.mix-kpi-grid span { color: var(--mute); font-size: 12px; }
.mix-kpi-grid b { min-width: 0; font-size: 15px; overflow-wrap: anywhere; }
.mix-rule-note { margin: 8px 0 0; color: var(--mute); font-size: 12px; line-height: 1.5; }
.mix-pending-list, .mix-safety-list { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
.mix-pending-list li, .mix-safety-list div { display: grid; grid-template-columns: minmax(112px, 1fr) auto; gap: 4px 10px; align-items: center; min-height: 58px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 8px; background: var(--bg); }
.mix-pending-list small, .mix-safety-list span { grid-column: 1 / -1; color: var(--mute); font-size: 12px; line-height: 1.4; }
.mix-pending-list span { color: var(--teal); font-size: 12px; font-weight: 700; }
.mix-utm-builder { display: grid; gap: 10px; }
.mix-utm-presets { display: flex; flex-wrap: wrap; gap: 6px; }
.mix-utm-presets .btn[aria-pressed="true"] { border-color: var(--teal); color: var(--fg); background: var(--teal-soft); }
.mix-utm-output { display: block; min-height: 42px; padding: 10px 12px; border: 1px solid color-mix(in srgb, var(--teal) 34%, var(--line)); border-radius: 8px; background: var(--bg); color: var(--fg); font: 12px/1.5 ui-monospace, SFMono-Regular, Consolas, monospace; overflow-wrap: anywhere; }
.mix-limit-table td:last-child { color: var(--mute); font-size: 12px; line-height: 1.45; }
.mix-hero { display: grid; grid-template-columns: minmax(0, 1fr) minmax(360px, .85fr); gap: 18px; align-items: end; padding: 22px; border: 1px solid var(--line); border-radius: 8px; background: var(--card); }
.mix-hero h1 { margin: 4px 0 8px; font-size: 34px; line-height: 1.08; }
.mix-summary { display: grid; grid-template-columns: repeat(5, minmax(84px, 1fr)); gap: 8px; }
.mix-summary div { min-height: 70px; padding: 12px; border: 1px solid var(--line); border-radius: 8px; background: color-mix(in srgb, var(--card) 82%, var(--bg)); display: grid; align-content: center; gap: 3px; }
.mix-summary span { color: var(--mute); font-size: 12px; }
.mix-summary b { font-size: 16px; word-break: keep-all; overflow-wrap: anywhere; }
.mix-strategy .card, .content-grid .card { min-height: 150px; }
.content-cell strong { font-size: 14px; }
.cost-list { list-style: none; margin: 10px 0; padding: 0; display: grid; gap: 5px; }
.cost-list li { display: flex; justify-content: space-between; gap: 12px; color: var(--mute); font-size: 13px; }
.cost-list b { color: var(--fg); font-weight: 600; }
.funnel .pill.now { border-color: var(--teal); color: var(--fg); background: color-mix(in srgb, var(--teal) 16%, var(--card)); }
.mix-monitor-grid { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.mix-rings { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); margin-top: 10px; }
.monitor-tabs { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 12px; }
.monitor-tabs .card { overflow: auto; }
.shape-row { display: flex; align-items: end; gap: 10px; min-height: 72px; padding: 12px 0 2px; }
.metric-dot { width: var(--size); height: var(--size); border-radius: 50%; background: color-mix(in srgb, var(--teal) 34%, var(--card)); border: 1px solid var(--teal); box-shadow: 0 0 0 6px var(--teal-soft); }
.mini-bars { display: grid; gap: 8px; }
.mini-bars div { display: grid; grid-template-columns: minmax(88px, 120px) 1fr 42px; gap: 8px; align-items: center; font-size: 12px; color: var(--mute); }
.mini-bars b { display: block; height: 10px; min-width: 4px; border-radius: 999px; background: var(--teal); }
.mini-bars em { font-style: normal; color: var(--fg); text-align: right; }
.mini-ring { width: 120px; aspect-ratio: 1; margin: 0 auto; border-radius: 50%; display: grid; place-items: center; text-align: center; background-image: conic-gradient(var(--teal) calc(var(--pct) * 1%), var(--line) 0); position: relative; }
.mini-ring::after { content: ""; position: absolute; inset: 12px; border-radius: 50%; background: var(--card); }
.mini-ring b, .mini-ring span { position: relative; z-index: 1; }
.mini-ring b { font-size: 18px; }
.mini-ring span { grid-row: 2; margin-top: -34px; color: var(--mute); font-size: 12px; }
@media (max-width: 1000px) { .mix-hero, .mix-stage-head, .mix-ops-grid { grid-template-columns: 1fr; } .mix-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); } .mix-cost-fields, .mix-kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .mix-stage-actions { align-items: stretch; flex-direction: column; } .mix-form-row, .mix-cost-fields, .mix-channel-list, .mix-kpi-grid { grid-template-columns: 1fr; } }

/* My 페이지 */
.mypage-shell { display: grid; gap: 16px; }
.mypage-account-stack { display: grid; gap: 16px; }
.mypage-title { display: grid; gap: 0; margin: 0 0 2px; }
.mypage-title h1 { margin: 0 0 8px; font-size: 28px; font-weight: 600; letter-spacing: -.01em; line-height: 1.25; }
.mypage-title .lead { margin: 0 0 8px; max-width: 720px; }
.mypage-hero { display: grid; gap: 14px; padding: 18px 20px; border-radius: var(--radius); background: var(--card); }
.eyebrow { margin: 0 0 8px; color: var(--teal); font-size: 12px; font-weight: 700; letter-spacing: .08em; }
.my-summary-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
.my-summary-grid div { min-height: 76px; display: grid; align-content: center; gap: 4px; padding: 14px 16px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); }
.my-summary-grid b { font-size: 22px; line-height: 1.15; font-weight: 600; }
.my-summary-grid span { color: var(--mute); font-size: 12px; }
.mypage-block { margin: 0; padding: 18px 20px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); }
.mypage-block h2 { margin: 0; font-size: 18px; font-weight: 600; letter-spacing: 0; }
.mypage-block h3 { margin: 0; font-size: 15px; letter-spacing: 0; }
.mypage-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 16px; }
.mytag, .myhint, .my-step { flex: none; font-size: 12px; line-height: 1; color: var(--mute); border: 1px solid var(--line); border-radius: 999px; padding: 6px 9px; background: var(--bg); }
.mytag { color: var(--teal); border-color: color-mix(in srgb, var(--teal) 42%, var(--line)); background: var(--teal-soft); }
.my-kv { grid-template-columns: 140px minmax(0, 1fr); align-items: center; margin: 4px 0 18px; }
.my-kv dd { min-width: 0; overflow-wrap: anywhere; font-size: 14px; font-weight: 500; }
.my-form { display: grid; gap: 12px; }
.my-form label { display: grid; grid-template-columns: 140px minmax(0, 1fr); align-items: center; gap: 12px; min-width: 0; color: var(--mute); font-size: 12.5px; }
.my-form label span { min-width: 0; }
.my-form input { width: 100%; min-width: 0; height: 42px; font: inherit; color: var(--fg); background: var(--bg); border: 1px solid var(--mute); border-radius: 8px; padding: 9px 11px; }
.my-form input:focus { border-color: var(--teal); box-shadow: 0 0 0 3px var(--teal-soft); }
.my-form .my-actions, .my-form #myPwMsg { margin-left: 152px; }
.my-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 2px; }
.my-actions .btn[disabled], .support-card[disabled], .terms-grid .btn[disabled] { border-style: dashed; }
.credit-grid, .plan-grid, .report-grid, .support-grid, .terms-grid { display: grid; gap: 10px; }
.credit-overview { display: grid; grid-template-columns: minmax(180px, 240px) minmax(0, 1fr); align-items: center; gap: 14px; margin-bottom: 12px; padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg); }
.credit-overview .credit-meter { width: min(100%, 150px); justify-self: center; }
.credit-overview > div:last-child { display: grid; gap: 5px; min-width: 0; }
.credit-overview > div:last-child b { font-size: 20px; font-weight: 600; }
.credit-overview > div:last-child span { color: var(--mute); font-size: 13px; line-height: 1.55; }
.credit-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); margin-bottom: 12px; }
.credit-grid div { display: grid; gap: 4px; min-height: 76px; padding: 14px 16px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); }
.credit-grid span { color: var(--mute); font-size: 12px; }
.credit-grid b { font-size: 18px; font-weight: 600; }
.usage-table { display: grid; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.usage-table [role="row"] { display: grid; grid-template-columns: 1fr 1fr 90px 90px; gap: 10px; padding: 11px 14px; border-bottom: 1px solid var(--line); font-size: 13px; }
.usage-table [role="row"]:last-child { border-bottom: 0; color: var(--mute); }
.usage-table [role="row"]:first-child { background: var(--bg); color: var(--fg); }
.my-toolbar { display: flex; flex-wrap: wrap; gap: 8px; margin: -4px 0 12px; color: var(--mute); font-size: 12px; }
.my-toolbar span { border: 1px solid var(--line); border-radius: 999px; padding: 5px 9px; background: var(--bg); }
.my-history-list { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
.my-history-list .utt { min-height: 56px; display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 12px; padding: 14px 16px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); }
.my-history-list .utt b { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 15px; font-weight: 600; }
.my-history-list .utt div { min-width: 0; display: grid; gap: 3px; }
.my-history-list .utt div span { min-width: 0; color: var(--mute); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.history-actions { margin-top: 12px; }
.plan-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.plan-card, .report-card { display: grid; align-content: space-between; gap: 12px; min-height: 160px; padding: 16px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); }
.plan-card > b { font-size: 20px; font-weight: 600; }
.plan-card p, .report-card p { margin: 0; color: var(--mute); font-size: 13px; }
.billing-card { border-color: color-mix(in srgb, var(--teal) 22%, var(--line)); }
.billing-card .plan-card { position: relative; overflow: hidden; border-color: color-mix(in srgb, var(--plan-accent) 54%, var(--line)); background: var(--card); }
.billing-card .plan-card::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 4px; background: var(--plan-accent); }
.billing-card .plan-card > * { position: relative; }
.billing-card .plan-tone-1 { --plan-accent: #5eead4; }
.billing-card .plan-tone-2 { --plan-accent: #fbbf24; }
.billing-card .plan-tone-3 { --plan-accent: #818cf8; }
.billing-card .plan-card .myhint { color: var(--plan-accent); border-color: color-mix(in srgb, var(--plan-accent) 58%, var(--line)); background: color-mix(in srgb, var(--plan-accent) 13%, var(--card)); }
.billing-card .plan-card > b { color: var(--plan-accent); text-shadow: 0 0 18px color-mix(in srgb, var(--plan-accent) 36%, transparent); }
.billing-card .plan-card .btn { border-color: color-mix(in srgb, var(--plan-accent) 42%, var(--line)); background: color-mix(in srgb, var(--plan-accent) 8%, var(--card)); }
.billing-card .my-policy-note { border-color: color-mix(in srgb, var(--amber) 46%, var(--line)); background: color-mix(in srgb, var(--amber) 8%, var(--card)); }
.report-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.report-card .my-actions { justify-content: space-between; }
.support-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.support-card { min-height: 116px; display: grid; gap: 6px; align-content: start; padding: 15px; text-align: left; font: inherit; color: var(--fg); border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); cursor: not-allowed; }
.support-card span { color: var(--mute); font-size: 12.5px; }
.support-card em { align-self: end; color: var(--teal); font-size: 12px; font-style: normal; }
.terms-grid { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.policy-list { margin: 0; padding-left: 18px; color: var(--mute); }
.policy-list li + li { margin-top: 6px; }
.my-policy-note { margin-top: 12px; }
.mypage-withdraw-host { display: contents; }

@media (max-width: 720px) { .sect.two, .pc-row { grid-template-columns: 1fr; } }
@media (max-width: 980px) {
  .metric-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mypage-hero, .plan-grid, .report-grid, .support-grid { grid-template-columns: 1fr 1fr; }
  .credit-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 860px) {
  .my-history-list .utt { grid-template-columns: 1fr; align-items: start; }
  .my-step { justify-self: start; }
}
@media (max-width: 560px) {
  .metric-strip, .credit-overview { grid-template-columns: 1fr; }
  .mypage-hero, .my-summary-grid, .plan-grid, .report-grid, .support-grid, .credit-grid { grid-template-columns: 1fr; }
  .mypage-hero { padding: 20px; }
  .usage-table [role="row"] { grid-template-columns: 1fr; }
  .my-kv, .my-form label { grid-template-columns: 1fr; gap: 6px; }
  .my-form .my-actions, .my-form #myPwMsg { margin-left: 0; }
}
/* 좁은 폭에서는 상태 줄을 접고 경과를 다음 줄 왼쪽에 둔다 — 오른쪽 끝으로 밀면 본문과 멀어져 같이 읽히지 않는다 */
@media (max-width: 560px) {
  .status { flex-wrap: wrap; }
  .status > span:not(.dot):not(.elapsed) { flex: 1 1 0; min-width: 0; }   /* 점 옆에 붙어 남은 폭 안에서 접히게 한다 */
  .status .elapsed { flex-basis: 100%; margin-left: 18px; }               /* 본문이 폭을 다 쓰고, 경과는 아래 줄로 내린다 */
}

/* 명령 팔레트(Ctrl+K) — 모달 막 위에 목록 카드. 활성 항목은 색만이 아니라 윤곽선으로도 구분한다 */
.cmdk { align-items: flex-start; padding-top: 12vh; }
.cmdk-card { width: min(560px, 100%); gap: 8px; padding: 12px; }
.cmdk-input { width: 100%; font-size: 15px; }
.cmdk-list { list-style: none; margin: 0; padding: 0; max-height: 50vh; overflow-y: auto; display: grid; gap: 2px; }
.cmdk-item { padding: 9px 11px; border-radius: 8px; cursor: pointer; color: var(--fg); }
.cmdk-item small { color: var(--mute); margin-left: 6px; }
.cmdk-item.is-active { background: var(--bg); outline: 1px solid var(--line); }
.cmdk-item[aria-disabled="true"] { color: var(--mute); cursor: default; opacity: .6; }
.cmdk-empty { padding: 9px 11px; color: var(--mute); }

/* 장치 E 봉인 카드 — 서버가 입장 저장을 알리기 전에는 점선으로 닫혀 있다 */
.seal-cards { list-style: none; margin: 8px 0 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 8px; }
.seal-card { min-height: 88px; }
.seal-card.is-sealed { border-style: dashed; color: var(--mute); display: flex; align-items: center; justify-content: center; }
.seal-card.is-open p { margin: 6px 0 0; font-size: var(--fs-read); }
/* 공개된 의견은 한 줄에 한 장씩 넓게 놓는다 — 좁은 칸에 나누면 글이 세로로 길어져 읽기 어렵다 */
.seal-group[data-sealed="false"] .seal-cards { grid-template-columns: 1fr; }
.seal-card.is-open { min-height: 0; padding: 12px 14px; }
.seal-card.is-open > b { font-size: var(--fs-ui); }
@media (prefers-reduced-motion: no-preference) { .seal-card.is-open { animation: seal-open .24s ease-out both; } }
@keyframes seal-open { from { transform: rotateY(90deg); opacity: 0; } to { transform: none; opacity: 1; } }
/* STEP 6 하위 탭 · 장치 J 시나리오 3열과 가지 */
.tabs { gap: 6px; margin-bottom: 12px; }
.tabs .btn.sm { font-size: var(--fs-ui); padding: 6px 14px; }
[data-panel] .empty-cell b { font-size: var(--fs-ui); }
[data-panel] .empty-cell span { font-size: var(--fs-label); }
.p6-line { margin: 6px 0 0; font-size: var(--fs-ui); color: var(--mute); line-height: 1.6; }
.h2-sub { font-size: var(--fs-label); font-weight: 400; color: var(--mute); margin-left: 8px; }
.cmp-counts { align-items: center; gap: 4px 10px; margin: 6px 0 10px; font-size: var(--fs-ui); }
.cmp-counts .k { margin: 0; }
.notice ul.cmp-caveats { margin: 0; padding-left: 18px; color: var(--fg); font-size: var(--fs-ui); line-height: 1.7; }
.cmp-exposures { align-items: center; gap: 6px; margin-bottom: 6px; }
/* 차트는 원래 좌표 폭 이하로만 그린다 — 본문 폭으로 늘리면 차트 안 글자까지 1.7~2.6배 커진다(charts.js 기본 폭: 히트맵·산키 640, 레이더 420) */
[data-panel="compare"] .chart-heatmap svg, [data-panel="compare"] .chart-sankey svg { max-width: 640px; }
[data-panel="compare"] .chart-radar svg { max-width: 420px; }
[data-panel="compare"] .ch-legend { font-size: var(--fs-meta); margin-top: 10px; }
.ch-sub { margin: -4px 0 12px; font-size: var(--fs-label); color: var(--mute); line-height: 1.6; }
.ch-keylist { list-style: none; margin: 12px 0 4px; padding: 0; display: grid; gap: 6px; max-width: 760px; }
.ch-keylist li { display: grid; grid-template-columns: 5.5em minmax(0, max-content) auto; justify-content: start; gap: 12px; align-items: baseline; font-size: var(--fs-ui); line-height: 1.5; }
.ch-keylist li > span { font-weight: 400; color: var(--fg); }
.ch-keylist li > span.mute { color: var(--mute); }
.ch-keylist li b { font-size: var(--fs-label); font-weight: 600; color: var(--teal); white-space: nowrap; }
.ch-keylist li .mute { font-size: var(--fs-label); white-space: nowrap; }
.ch-keymore { margin: 6px 0 4px; max-width: 760px; }
.ch-keymore > summary { cursor: pointer; font-size: var(--fs-label); color: var(--fg); padding: 4px 0; }
.p6-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 24px; align-items: start; }
@media (max-width: 720px) { .p6-pair { grid-template-columns: 1fr; } }
.scen-vars { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px; }
.scen-vars input[type="range"] { width: 100%; }
.scen-cols { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
@media (max-width: 900px) { .scen-cols { grid-template-columns: 1fr; } }
.scen-col h3 { font-size: var(--fs-label); color: var(--mute); margin: 12px 0 4px; font-weight: 500; }
.scen-col li { font-size: var(--fs-ui); }
/* 시나리오 만들기 폼 — 제목은 입력칸 «위» 에 따로 두고, 칸 사이를 띄운다 */
.scen-create-form { display: grid; gap: 14px; align-content: start; }
.scen-create-form > .k { font-size: var(--fs-ui); font-weight: 600; color: var(--fg); margin: 0; }
.scen-field { display: grid; gap: 6px; }
.scen-field > label { font-size: var(--fs-label); color: var(--fg); font-weight: 500; }
.scen-field > label .mute { font-size: var(--fs-meta); font-weight: 400; }
.scen-create-form textarea, .scen-create-form input {
  width: 100%; box-sizing: border-box; font: inherit; font-size: var(--fs-ui); line-height: 1.5; color: var(--fg);
  background: var(--bg); border: 1px solid var(--mute); border-radius: 8px; padding: 8px 10px; }
.scen-create-form textarea { resize: vertical; min-height: 64px; }
.scen-create-form textarea::placeholder, .scen-create-form input::placeholder { color: var(--mute); }
.scen-create-form textarea:focus, .scen-create-form input:focus { outline: none; border-color: var(--teal); box-shadow: 0 0 0 1px var(--teal); }
.scen-range > summary { cursor: pointer; font-size: var(--fs-label); color: var(--fg); padding: 4px 0; }
.scen-range[open] > summary { margin-bottom: 8px; }
.scen-range > p.mute { margin: 0 0 10px; font-size: var(--fs-meta); line-height: 1.6; }
.scen-var-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px 10px; margin: 0 0 14px; }
.scen-var-row > b { grid-column: 1 / -1; font-size: var(--fs-ui); }
.scen-cell { display: grid; gap: 4px; min-width: 0; }
.scen-cell > label { font-size: var(--fs-meta); color: var(--mute); margin: 0; }
.scen-save { justify-self: start; font-size: var(--fs-ui); }
.scen-col ul, .branch ul { margin: 0; padding-left: 18px; }
.price-note { margin: 6px 0 0; }
.branch-row { align-items: start; }
.chip.branch-badge { border-color: var(--amber); }
/* 장치 M 비교 · 장치 P 읽기 전용 공유 */
.cmp-side .rep-body { max-height: 60vh; overflow: auto; }
.share-status { margin-bottom: 12px; }
/* 장치 F 입장 변화·지표 · 장치 G 관중 누적 — 값이 없는 지표는 점선 빈 칸이다 */
.metric-v { font-weight: 600; margin-right: 6px; }
.metric-v.is-empty { display: inline-block; min-width: 3.5em; height: 1.2em; border: 1px dashed var(--line); border-radius: 4px; vertical-align: middle; margin-right: 6px; }
.post-round, .aud-group { margin-top: 12px; }
.post-metrics, .aud-progress { gap: 6px 10px; align-items: center; flex-wrap: wrap; margin: 8px 0; }
.post-list { list-style: none; margin: 8px 0 0; padding: 0; }
.post-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; padding: 4px 0; border-bottom: 1px solid var(--line); }
.post-row .mute { color: var(--mute); }
.aud-accept { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 8px 0; }
.aud-accept .empty-cell { flex: 1 1 100%; }
.live-age { margin-top: 6px; font-variant-numeric: tabular-nums; }
.live-age .metric-v.is-empty { display: inline-block; min-width: 3em; }

/* ── A-UX-19 로딩 표시 — 내용이 «올 자리»만 잡아 둔다 ──────────────────────
   ui.js nowLine(장치 L) 규약: 가짜 진행 바는 두지 않는다. 그래서 이 칸은
   ① 너비·높이가 시간에 따라 자라지 않고 ② 안이 일부만 채워지는 일이 없다.
   칸 전체가 한 덩어리로 옅어졌다 진해질 뿐이며, 이것은 「무언가 오고 있다」는 표시지 진행률이 아니다.
   남은 시간·비율은 적지 않는다(화면이 받는 실측 값이 없다).
   맥동은 .status .dot 과 같은 pulse 를 쓴다 — 움직임을 끄면 색만 남고 자리는 그대로다. */
.skeleton { display: block; width: 100%; height: 1em; border-radius: 6px; background: var(--line);
            animation: pulse 1.2s ease-in-out infinite; }
.skeleton + .skeleton { margin-top: 8px; }
/* 글줄 자리 — 문단 끝 줄만 짧게 둔다. 길이는 글자 수를 뜻하지 않는다 */
.skeleton.short { width: 60%; }
/* 카드·차트 자리 — 높이만 잡고 안은 비운다 */
.skeleton.block { height: 120px; border-radius: var(--radius); }
.skeleton.chart { height: 180px; border-radius: var(--radius); }
/* 자리표시는 읽어 줄 내용이 없다 — 무엇을 기다리는지는 .status(nowLine) 한 줄이 말한다 */
.skeleton[aria-hidden="true"] { pointer-events: none; }
@media (prefers-reduced-motion: reduce) { .skeleton { animation: none } }

/* ══ FrontEnd — 화면 전용 선택자 (1.4 영역 분할: STEP 0~7 · MIX · My 페이지 전용) ═══════
   차트·장치·모달·빈 칸 규칙은 UI/UX 영역이라 여기 두지 않는다. 새 규칙은 이 블록 끝에 붙인다. */

/* ── STEP 0 최근 조사 재진입 카드 (W-1) ──────────────────────────────────
   받지 못한 칸은 비운 채 사유가 그 자리에 남으므로, 빈 칸도 자리를 지키도록 두 열 격자로 그린다. */
.recent { align-items: flex-start; }
.recent-card { flex: 1 1 220px; min-width: 200px; display: grid; gap: 6px; }
.recent-card > .chip { justify-self: start; max-width: 100%; }
.recent-meta { display: grid; grid-template-columns: auto 1fr; gap: 2px 8px; margin: 0; font-size: 12px; }
.recent-meta dt { color: var(--mute); }
.recent-meta dd { margin: 0; }
.recent-meta dd b { color: var(--fg); font-weight: 500; }
/* 멈춘 조사 — 색만으로 가르지 않는다. 낱말이 「멈춤」이고 경과 시간이 함께 붙는다. */
.recent-meta dd b.flow-stalled { color: var(--amber); font-weight: 600; }
.recent-meta dd small { color: var(--mute); font-size: 11px; }

/* ── STEP 0 파일·URL·음성 패널 상태 칩 (W-2) ───────────────────────────── */
.panel-slot { margin-left: 6px; }

/* ── STEP 1 확인 자리의 「비어 있는 칸」 목록 (W-7) — 확인 단추 위에 한 줄을 통째로 쓴다 ── */
.brief-empty-slot { flex: 0 0 100%; }
/* 점선 테두리 칸은 이미 있는 .empty-cell 을 쓴다 — 새 테두리를 만들지 않는다 */
.brief-empty-note { font-size: var(--fs-warn); color: var(--ink-warn); }
.brief-empty-note b { color: var(--fg); font-weight: 500; }
.brief-empty-note ul { margin: 6px 0; padding-left: 18px; }
.brief-empty-note span { display: block; font-size: var(--fs-warn); }
/* STEP 1 — 원문 펼침 · 두 수의 관계 문장 · 본문 끝 확정 자리. 상태 문구는 상태 토큰, 원문은 본문 토큰을 쓴다 */
.brief-source { margin: 0 0 16px; display: grid; gap: 6px; }
.brief-source summary { font-size: var(--fs-status); color: var(--ink-status); cursor: pointer; }
.brief-source summary:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }
.brief-source .brief-raw { margin-top: 8px; font-size: var(--fs-body); color: var(--ink-body); }
.brief-trace { font-size: var(--fs-status); color: var(--ink-status); margin: 0; }
.brief-count { font-size: var(--fs-status); color: var(--ink-status); margin: 0 0 14px; }
.brief-count .k { font-size: var(--fs-caption); color: var(--ink-caption); margin: 4px 0 0; }
.askq > .k { font-size: var(--fs-status); color: var(--ink-status); }
.brief-domain [data-scope-note] { font-size: var(--fs-status); color: var(--ink-status); }
.brief-confirm-scope { flex: 0 0 100%; font-size: var(--fs-status); color: var(--ink-status); }

/* ── STEP 2 소스 칸의 상태 배지·사유 tip (W-8) ─────────────────────────── */
.hit .status-badge, .hit .tip { justify-self: start; max-width: 100%; }

/* ── STEP 3 설계 모드 세그먼트 (W-10) — select 를 대신하는 라디오 묶음.
   ★고름 표시를 색에 기대지 않는다 — ◆ · ◇ 도형이 글자와 함께 있고 색은 보조다. */
.design-input { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin: 10px 0; }
.design-input .seg-label, .design-input label { color: var(--mute); font-size: 12px; }
.design-input #p3axis { min-width: 160px; padding: 6px 9px; border: 1px solid var(--mute); border-radius: 8px; background: var(--card); color: var(--fg); font: inherit; font-size: 13px; }
.design-input .rerun-note { flex-basis: 100%; font-size: 12px; line-height: 1.5; }
.seg { display: inline-flex; flex-wrap: wrap; gap: 2px; padding: 2px; border: 1px solid var(--line); border-radius: 10px; background: var(--card); }
.seg-item { display: inline-flex; align-items: center; gap: 5px; padding: 5px 10px; border-radius: 8px; color: var(--mute); font-size: 13px; line-height: 1.3; cursor: pointer; user-select: none; }
.seg-item i { font-style: normal; font-size: 11px; line-height: 1; }
.seg-item[aria-checked="true"] { background: var(--teal-soft); border: 1px solid color-mix(in srgb, var(--teal) 42%, var(--line)); padding: 4px 9px; color: var(--fg); font-weight: 600; }
.seg-item:focus-visible { outline: 2px solid var(--teal); outline-offset: 1px; }
@media (forced-colors: active) { .seg-item[aria-checked="true"] { border: 1px solid CanvasText; } }

/* ── STEP 3 신호 카드 (W-11 · W-12) — 카드가 이미 테두리를 가지므로 겹쳐 그리지 않는다 ── */
.sig .metric-tile { min-height: 0; padding: 0; border: 0; gap: 4px; }
.sig .metric-tile .mt-value { font-size: 26px; }
.sig .metric-tile .mt-value.is-empty { font-size: 13px; }
.sig-trend { margin-top: 2px; }
.sig-trend svg, .sig-trend figure { width: 100%; height: auto; max-width: 100%; display: block; }
.sig-trend .ch-lab { font-size: 9px; }
.empty-cell.sig-trend { margin-top: 2px; }

/* ── STEP 5 실시간 발언·봉인·도착 선 (W-15 · W-16 · W-18 · F-FE-19) ────────
   「새 발언 n」 단추는 목록 «위에» 뜬다 — 목록을 밀어내면 읽던 줄이 움직인다. */
.ticker-wrap { position: relative; }
.ticker-new { position: sticky; top: 0; z-index: 2; display: flex; justify-content: center; pointer-events: none; min-height: 0; }
.ticker-new:empty { display: none; }
.ticker-new > button { pointer-events: auto; margin: 4px 0; box-shadow: var(--shadow-1, 0 2px 8px rgba(0, 0, 0, .18)); }
.seal-wait { align-items: center; gap: 8px; margin: 6px 0; }
/* 점이 늘어도 칸 높이가 튀지 않게 자리를 먼저 잡는다 — mountLive 가 붙기 전에도 자리는 있다. */
#audLive { min-height: 160px; }
#audLive:empty { display: none; }

/* ── STEP 7 공유 링크 복사 (W-23) ──────────────────────────────────────
   복사가 실패해도 주소는 화면에 남는다 — 사용자가 손으로 고를 수 있어야 한다. */
.share-links { display: grid; gap: 10px; margin: 10px 0 0; padding: 0; list-style: none; }
.share-link { display: grid; gap: 8px; }
.share-link code, .share-created code { display: block; overflow-wrap: anywhere; font-size: 12.5px; color: var(--fg); user-select: all; }
.share-created { display: grid; gap: 8px; margin-top: 10px; }
.share-link .copy-button, .share-created .copy-button { justify-self: start; }

/* ── STEP 7 입력 칸·긴 글자 (사람 응답 넣기 · 읽기 전용 링크 · 진행 판단 기록) ──────────────────────────
   칸이 기본 브라우저 모양으로 남으면 어두운 화면에서 밝은 칸이 튀고, 글자 수(cols)만큼만 좁게 열린다.
   슬롯·문항 번호처럼 공백 없는 긴 글자는 200% 확대(뷰포트 폭 절반)에서 표·목록 밖으로 넘치므로 어디서든 줄을 바꾼다. */
.human-sample .hold, .share-owner .hold { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); gap: 10px; align-items: end; }
.human-sample .hold label, .share-owner .hold label { display: grid; gap: 4px; min-width: 0; font-size: var(--fs-label); color: var(--mute); }
.human-sample .hold input, .human-sample .hold select, .share-owner .hold input,
.judge-form textarea { width: 100%; min-width: 0; box-sizing: border-box; font: inherit; color: var(--fg); background: var(--card); border: 1px solid var(--mute); border-radius: 8px; padding: 8px 10px; }
.human-sample .hold .btn, .share-owner .hold .btn { grid-column: 1 / -1; justify-self: start; }
.judge-form { display: grid; gap: 10px; }
.judge-form textarea { resize: vertical; min-height: 72px; }
.judge-opts { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; border: 0; min-width: 0; }
.judge-opts legend { padding: 0 0 6px; font-size: var(--fs-label); color: var(--mute); }
.judge-opt { display: inline-flex; align-items: center; gap: 6px; padding: 8px 12px; border: 1px solid var(--line); border-radius: 8px; background: var(--card); cursor: pointer; }
.judge-opt:has(input:focus-visible) { outline: 2px solid var(--teal); outline-offset: 2px; box-shadow: 0 0 0 5px var(--teal-soft); }
.hs-table th, .hs-table td { overflow-wrap: anywhere; }
.hs-staged { display: grid; gap: 6px; margin: 8px 0 0; padding: 0; list-style: none; }
.hs-staged li { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.hs-staged code { min-width: 0; overflow-wrap: anywhere; }
.utt p { overflow-wrap: anywhere; }

/* ── My 최근 조사 줄·보관함 판단 (W-26 · A-FE-46) ───────────────────────
   「다음 행동」 사유는 한 줄로 잘리면 안 된다 — 잘린 사유는 사유가 아니다. */
.my-history-list .utt [data-hist="meta"] { display: flex; flex-wrap: wrap; gap: 4px 8px; white-space: normal; overflow: visible; }
.my-history-list .utt [data-hist="meta"] span { white-space: normal; overflow: visible; text-overflow: clip; }
.my-history-list .utt [data-next-action] { flex: none; }
.my-history-list .utt .my-step.cell-empty { border-style: dashed; }
.report-card [data-decision] { margin: 6px 0 0; font-size: 12.5px; }
.report-card [data-decision="saved"] { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.report-card [data-decision="saved"] b { font-size: 13px; font-weight: 600; }

/* ── MIX 지표 추세·소재 통합 편집 (W-28 · A-FE-19) ─────────────────────── */
.mix-metric-trend { display: grid; gap: 8px; }
.mix-metric-trend svg { width: 100%; height: auto; }
.mix-studio-edit-list { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.mix-studio-editor { display: grid; gap: 12px; align-content: start; }
.mix-studio-row { display: grid; gap: 6px; padding: 10px 0; }
.mix-studio-row h4 { margin: 0; font-size: 13px; }
.mix-studio-meta { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; font-size: 12px; color: var(--mute); }
.mix-studio-row label { display: grid; gap: 6px; min-width: 0; color: var(--mute); font-size: 12px; }
.mix-studio-row textarea, .mix-studio-row input { width: 100%; min-height: 38px; font: inherit; color: var(--fg); background: var(--card); border: 1px solid var(--mute); border-radius: 8px; padding: 8px 10px; }
.mix-studio-row textarea { min-height: 84px; resize: vertical; line-height: 1.5; }
.mix-studio-brief { display: grid; gap: 4px; font-size: 12px; color: var(--mute); }
.mix-studio-brief code { overflow-wrap: anywhere; font-size: 11px; }
.mix-studio-save { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-top: 12px; }
@media (max-width: 560px) { .mix-studio-edit-list { grid-template-columns: 1fr; } }

/* ── STEP 1 채움 링·분야·필수 항목 진실성 상태·근거 충분성 요약 (p1.js) ─────────────
   항목 이름과 원문 근거는 길 수 있어 어디서든 줄을 바꾼다. 상태 구분은 선택 글자로 하고 색에 기대지 않는다. */
.brief-completeness { display: flex; justify-content: flex-start; margin: 0 0 12px; }
.brief-domain-box { margin: 16px 0 0; }
.brief-domain-box:empty { display: none; }
.brief-domain { display: grid; gap: 8px; border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 14px; background: var(--card); }
.brief-domain > label { margin-bottom: 0; }
.brief-domain select { font: inherit; font-size: var(--fs-ui); padding: 6px 9px; border: 1px solid var(--mute); border-radius: 8px; background: var(--card); color: var(--fg); max-width: 100%; }
.brief-domain > select { justify-self: start; min-width: 180px; }
.brief-domain select:disabled { opacity: .7; cursor: not-allowed; }
.truth-group { margin: 4px 0 0; padding: 8px 0 0; border: 0; border-top: 1px solid var(--line); min-width: 0; }
.truth-group legend { padding: 0 0 6px; font-size: var(--fs-label); font-weight: 500; color: var(--fg); }
.truth-group ul { display: grid; gap: 6px; margin: 0; padding: 0; list-style: none; }
.truth-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 10px; align-items: center; font-size: var(--fs-ui); }
.truth-row label { min-width: 0; margin: 0; overflow-wrap: anywhere; color: var(--fg); }
.truth-row .k { grid-column: 1 / -1; margin: 0; overflow-wrap: anywhere; font-size: var(--fs-meta); }
.suf-summary { overflow-wrap: anywhere; }
.suf-summary .k { margin: 6px 0 0; }
.suf-status { margin: 6px 0 0; font-size: var(--fs-label); color: var(--mute); }
.suf-status b { color: var(--fg); font-weight: 600; }
@media (max-width: 560px) { .truth-row { grid-template-columns: 1fr; } .brief-domain > select { min-width: 0; width: 100%; } }

/* ── 설계 03 단계 화면 공통 보조 영역 — 상태·사유·한계·감사 상세. 상태 글자는 --fs-status·--ink-status 로 쓰고
   접히는 감사 상세는 본문보다 뒤에 둔다(§7.1 여섯째 영역). 새 색을 만들지 않고 셸 토큰만 쓴다. ── */
.gate-why, .bmeta, .p3-limit, .p3-hold-record, .gaps { font-size: var(--fs-status); color: var(--ink-status); }
.bmeta { display: flex; flex-wrap: wrap; gap: 4px 12px; margin: 4px 0 0; }
.gate-why { display: block; margin-top: 6px; }
.tech, .p3-method, .p3-op, .audit, .asset-scope { margin: 10px 0 0; border-top: 1px solid var(--line); padding-top: 8px; }
.tech > summary, .p3-method > summary, .p3-op > summary, .audit > summary, .asset-scope > summary { cursor: pointer; font-size: var(--fs-status); color: var(--ink-status); }
.tech > summary:focus-visible, .p3-method > summary:focus-visible, .p3-op > summary:focus-visible,
.audit > summary:focus-visible, .asset-scope > summary:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }
.tech pre { white-space: pre-wrap; word-break: break-word; font-size: var(--fs-meta); color: var(--mute); }
.asset-scope { flex-basis: 100%; }
.excluded-default { opacity: 1; border: 1px dashed var(--line); border-radius: var(--radius); padding: 8px 10px; }
.p3-axis, .p3-data, .evidence-axes { font-size: var(--fs-status); color: var(--ink-status); margin: 6px 0 0; }
.p3-data table, .evidence-axes table { border-collapse: collapse; width: 100%; }
.p3-data th, .p3-data td, .evidence-axes th, .evidence-axes td { border-bottom: 1px solid var(--line); padding: 4px 6px; text-align: left; }
.p3-role { font-size: var(--fs-ui); color: var(--fg); margin: 0 0 6px; }
.p3-hold-record, .p3-limit, .gaps { border-left: 3px solid var(--amber); padding: 4px 0 4px 10px; margin: 8px 0; }
.targets { display: grid; gap: 6px; margin: 8px 0; }
@media (max-width: 720px) {
  .p3-data, .evidence-axes { overflow-x: auto; }
}

/* STEP 0 — 늘 보이는 예시 블록과 외부 전송·기밀 안내(설계 03 U03·§3.1 화면 3번). 안내는 경고 토큰으로 작게 숨기지 않는다 */
.askexample { border: 1px dashed var(--line); border-radius: var(--radius); padding: 10px 12px; margin: 8px 0; font-size: var(--fs-status); color: var(--ink-status); }
.askexample p { margin: 4px 0; }
.asknotice { border-left: 3px solid var(--amber); padding: 6px 0 6px 10px; margin: 12px 0; font-size: var(--fs-warn); color: var(--ink-warn); }
.asknotice p { margin: 4px 0; }
/* STEP 0 입력 구조화 — 시장·기업/제품·조사 세 구역을 위아래로 쌓고, 구역 안 항목도 한 줄에 하나씩 둔다 */
.askstructs { margin: 12px 0; }
.askstruct-grid { display: grid; gap: 12px; margin-top: 8px; }
.askstruct { display: grid; grid-template-columns: minmax(0, 1fr); align-items: start;
  border: 1px solid var(--line); border-radius: var(--radius); padding: 10px 14px 14px; margin: 0; min-width: 0; }
.askstruct > legend { padding: 0 6px; font-size: var(--fs-ui); }
.askstruct > legend b { color: var(--fg); }
.askstruct-lead { grid-column: 1 / -1; margin: 2px 0 0; font-size: var(--fs-status); }
.askstruct label { display: block; margin: 10px 0 0; font-size: var(--fs-status); color: var(--fg); min-width: 0; }
.askstruct-hint { display: block; margin: 2px 0 0; font-size: var(--fs-meta); color: var(--ink-status); }
.ask .askstruct textarea { min-height: 140px; margin-top: 4px; font-size: 16px; }
/* STEP0 미확인·누락 요약(§3.1 화면 5번) — 안내와 같은 위계로 두되 경고색은 쓰지 않는다 */
.askgaps { border-left: 3px solid var(--line); padding: 6px 0 6px 10px; margin: 12px 0; font-size: var(--fs-status); color: var(--ink-status); }
.askgaps ul { margin: 4px 0; padding-left: 18px; }
/* 자료별 복구 선택(G0) — 상태 칩 아래 한 줄로, 작은 화면에서는 줄바꿈된다 */
.item-recover { display: inline-flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 4px 0 0 4px; font-size: var(--fs-status); }
