/*
데모 화면 스타일(디자인) 파일입니다.
리허설·검증 로그·매핑 카드 등 UI 모양을 정의합니다.
*/

:root {
  /* ── 브랜드 팔레트 (딥그린) — docs/design_improvement/06_saas_shift.md §1 ──
     초록은 「주 액션」과 「판정 상태」에만 쓴다. 테두리·칩·연한 면에서는 뺐다.
     그전까지 초록이 브랜드색이 아니라 배경색처럼 화면에 깔려 있었다 */
  --navy: #064E3B;          /* 메인 초록. 가장 진한 브랜드 면 */
  --navy-deep: #043027;
  /* 06 §1 은 #0D9F6E 였는데 한 칸 내렸다. 흰 글씨를 얹으면 3.39:1 로 WCAG AA
     (4.5:1) 에 못 미친다 — 부스 조명 아래 태블릿에서 CTA 글씨가 제일 먼저
     날아가는 대비다. #0A8459 는 4.71:1 로 통과하면서 딥에메랄드는 그대로다 */
  /* 2026-08-07: 화면에 힘이 없다는 지적으로 한 단계 올렸다. 다만 위 4.5:1 규칙은
     그대로다 — 흰 글씨를 얹는 면이라 여기가 천장이다. #0E8850 은 4.51:1 로 아슬하게
     통과하는 가장 밝은 값이고, 파랑기를 빼서 같은 밝기라도 더 초록으로 읽힌다.
     부스 조명에서 CTA 글씨가 날아가 보이면 이 한 줄만 #0A8459 로 되돌린다. */
  --brand: #0E8850;         /* 주 액션 */
  --brand-strong: #0A8459;  /* 주 액션 hover·active — 이전 브랜드값이 그대로 눌린 색이 된다 */
  --brand-weak: #E7FBF0;    /* 연한 민트 — 주 액션 배경 */
  --cyan: #3fd599;          /* 어두운 면 위 강조 */
  --mint: #aeefd5;
  --yellow: #F0B429;        /* 주의·초과 */

  /* ── 면에 따라 바뀌는 강조색 슬롯 ──────────────────────────────────
     밝은 면에서는 브랜드 딥그린, 어두운 면에서는 --cyan 이 된다
     (design-system.css 의 .home-verdict 가 이 한 줄만 갈아 끼운다).
     예전 이름은 --blue 였다. 값은 처음부터 초록이었는데 이름만 파랑이라,
     2026-08-08 에 「선택 색이 초록·파랑 두 갈래」라는 오진이 실제로 나왔다.
     토큰 이름이 거짓말을 하면 코드를 읽는 사람이 화면을 잘못 본다. */
  --accent: var(--brand);
  --accent-strong: var(--brand-strong);
  --accent-weak: var(--brand-weak);

  /* 배경보다 카드가 밝다. 그 관계는 유지하되 크림을 뺐다 — 크림이 「유아교육」
     인상의 큰 지분이었다. 거의 흰색이되 순백은 아닌 회색으로 간다 (06 §1) */
  --canvas: #FAFAF9;        /* 페이지 배경 */
  --surface: #FFFFFF;       /* 카드 */
  --paper: #FFFFFF;         /* 리포트 패널 */
  --fill: #F4F4F5;          /* 카드 안 면 · 칩 배경 */
  /* 화면 전체에 초록을 깔고 있던 민트 테두리다. 여기 한 줄이 가장 큰 변화다 */
  --border: #E4E4E7;        /* 카드 1.5px 보더 */
  --line: rgba(24, 24, 27, .10);
  /* 행에 손이 닿았을 때. 색이 아니라 농도라서 크림 배경 위에서도, 흰 카드
     위에서도 같은 세기로 보인다 — 배경 토큰을 바꿔도 따라 움직인다 */
  --hover: rgba(24, 24, 27, .045);
  --text: #18181B;          /* 본문 — 초록기 뺀 중립 먹색 */
  --text-2: #52525B;
  --text-3: #71717A;        /* 메타데이터 */

  --ok: #0A8F68;   --ok-bg: #E9F7EF;
  --mid: #B45309;  --mid-bg: #FDF6E3;
  --no: #DC2626;   --no-bg: #FDF0EF;
  --ct: #9333EA;   --ct-bg: #F6EDFD;
  --om: #8A6A15;   --om-bg: #F7F1DE;
  /* 판정 om 의 연한 표현(점·썸네일 테두리)과 연한 초록 면의 테두리.
     리터럴로 흩어져 있던 값을 이름만 붙여 모았다 — 픽셀은 그대로다 */
  --om-soft: #B3C0B8;
  --mint-line: #C4E2D2;
  --green: #0A8F68; --green-bg: #E9F7EF;

  /* radius 4종 — 지면 / 컨트롤 / 알약 / 원. 이 밖의 값은 쓰지 않는다.
     20/16/12 은 「부드러운 노트」를 노린 값이었는데 그게 소비자 앱 문법이다.
     도구는 모서리를 세우고 테두리로 면을 나눈다 (Linear·Vercel 계열) */
  --r-print: 10px;     /* 카드·패널 */
  --r-inner: 8px;      /* 카드 안의 작은 면 */
  --r-ctl: 8px;        /* 버튼·입력 */
  --r-pill: 999px;     /* 칩·탭 */
  --r-dot: 50%;        /* 아바타·상태 점 */

  /* ── 아트보드 ────────────────────────────────────────────────────
     데스크톱은 1336×1024 한 판을 통째로 축소해서 보여준다. 기기마다 요소를
     제각각 압축하면 같은 화면이 노트북과 모니터에서 다른 물건이 되는데,
     발표 자료를 놓고 대조하는 화면에서 그건 «어디를 보라» 를 매번 새로 배우게
     하는 일이다. 스케일은 app.js 의 syncArtboard() 가 매겨 준다.
     기본값 1 이라 <900px 모바일은 지금과 완전히 같다. */
  --artboard-w: 1336px;
  --artboard-h: 1024px;
  --artboard-scale: 1;
  /* 화면 단위의 단일 출처. 아트보드 안에서 vw·vh 를 직접 쓰면 실제 창 크기를
     읽어서, 한 판을 같은 비율로 줄인다는 전제가 그 자리에서만 깨진다
     («2.8vw» 는 1920 모니터에서 54px, 아트보드 기준으로는 37px 이다) */
  --vw: 100vw;
  /* dvh 인 이유: 아이패드 사파리 주소창이 접혔다 펴지는 만큼을 따라와야 한다.
     아트보드 안에서는 이 줄이 1024px 로 덮인다 */
  --vh: 100dvh;

  /* 앱 셸의 좌측 내비 폭. 기본이 0 이라 좁은 화면은 지금과 완전히 같다.
     tablet.css 가 >=900px 에서만 값을 준다 — 전면폭 요소(.verdict·.t-band)가
     이 값을 타고 따라오므로 사이드바가 생겨도 가로 스크롤이 안 난다 */
  --nav-w: 0px;
  /* 레거시 별칭 — 기존 var(--r-card|btn) 사용처가 따라온다 */
  --r-card: var(--r-print); --r-btn: var(--r-ctl);

  /* font-weight 4단 — 미세 차이는 의미를 만들지 않는다 */
  --w-body: 500; --w-med: 650; --w-bold: 750; --w-display: 830;
  /* 타이포 스케일 — 위계가 없으면 어디부터 읽을지 정해지지 않는다.
     화면 제목 / 구역 / 카드 제목 / 본문 / 메타 다섯 단만 쓴다 */
  --t-h1: 24px; --t-h2: 15px; --t-card: 17px; --t-body: 14px; --t-meta: 12px;
  /* 도구는 그림자보다 테두리로 면을 나눈다. 그림자는 떠 있는 것에만 */
  --shadow: 0 1px 2px rgba(24, 24, 27, .04);
  --shadow-panel: 0 4px 16px rgba(24, 24, 27, .06);
  --ease: cubic-bezier(.22, 1, .36, 1);
  --font: "Pretendard Variable", "Pretendard", "Apple SD Gothic Neo", "Noto Sans KR", system-ui, sans-serif;
}

* { box-sizing: border-box; }
html, body { margin: 0; }
body {
  font-family: var(--font);
  /* TDS Typography6 = 15/22.5 → 행간 1.5. 1.6 은 본문이 흩어져 보였다 */
  font-size: 15px; line-height: 1.5;
  color: var(--text); background: var(--canvas);
  -webkit-font-smoothing: antialiased;
  /* 한글은 어절 단위로만 접는다 (keep-all). 다만 이 앱은 발표 자료라
     'Self-Supervised Learning'·'IMU2CLIP_Pulbic.pdf' 같은 긴 영문·파일명이
     그대로 들어온다 — keep-all 만 두면 그런 문자열이 카드를 뚫고 나간다.
     overflow-wrap 이 그때만 강제로 접어 주는 안전망이다. */
  word-break: keep-all;
  overflow-wrap: break-word;
}

/* 제목은 마지막 줄에 한 단어만 남지 않게 균형을 잡는다.
   '발표 자료와 발표를 대조한\n결과예요' 처럼 끊기면 읽는 리듬이 깨진다. */
h1, h2, h3, .page-title, .section-title, .verdict-title, .block-head h2 {
  text-wrap: balance;
}
button, input, select { font: inherit; color: inherit; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, p { margin: 0; }
.num { font-variant-numeric: tabular-nums; }

/* 아트보드 스크롤 자리. 데스크톱에서만 상자가 생긴다 (tablet.css).
   여기서는 레이아웃에서 빼 둬서 좁은 화면이 지금과 한 픽셀도 안 달라지게 한다 */
.artboard-scroll { display: contents; }

/* ── 상단 바 ── */
.topbar {
  position: sticky; top: 0; z-index: 20;
  /* 64px — 44px 버튼 기준 위아래 10px. 56px 일 땐 6px 뿐이라 버튼이 바를 꽉
     채워 보였다. #rtabs sticky top · tablet.css --topbar-h 와 같이 움직인다 */
  height: 64px; padding: 0 24px;
  display: flex; align-items: center; justify-content: space-between;
  background: var(--surface); border-bottom: 1px solid rgba(0, 0, 0, .04);
}
.brand { display: flex; align-items: center; gap: 9px; font-size: 16px; font-weight: 700; letter-spacing: -.2px; }
/*
 * 브랜드 마크 — 말풍선 + 체크. "질문에 답할 수 있게 됐다" 는 제품의 결과다.
 * (예전엔 둥근 사각 + 흰 줄 두 개였는데, 그건 자료를 뜻할 뿐 무엇을 해 주는지는
 *  말하지 않았다.)
 *
 * 색을 SVG 에 박지 않고 CSS 가 쥔다 — 어두운 면에서 --accent 를 갈아 끼우는
 * 스코프(.home-verdict 등)가 있어서, 인라인 fill 로 두면 거기서 안 따라온다.
 */
.brand-mark { width: 24px; height: 24px; display: block; flex: none; }
.brand-mark .bm-bg { fill: var(--accent); }
.brand-mark .bm-bubble { fill: #fff; }
.brand-mark .bm-tick { stroke: var(--accent); }
.brand-app-icon {
  display: block; width: 28px; height: 28px; flex: none; object-fit: cover;
  border-radius: 8px; box-shadow: 0 2px 7px rgba(6, 48, 39, .16);
}
.topbar-right { display: flex; align-items: center; gap: 14px; }
.avatar {
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--fill);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 600; color: var(--text-2);
}

/* ── 레이아웃 ── */
main { max-width: 980px; margin: 0 auto; padding: 24px 24px 48px; }
main.wide { max-width: 1080px; }
main.narrow { max-width: 640px; }
@media (prefers-reduced-motion: reduce) {
  #app.in > *, .fill-bar i, .ring-fg,
  .voice-chart .vbar, .filler-chip, .slide-pill, .stat-card.pop-in {
    animation: none !important; transition: none !important;
  }
}

.page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; margin-bottom: 22px; }
.page-title { font-size: 22px; font-weight: 700; letter-spacing: -.3px; line-height: 1.35; }
.page-sub { font-size: 15px; color: var(--text-3); margin-top: 4px; }
.section-title { font-size: 16px; font-weight: 600; margin-bottom: 14px; letter-spacing: -.2px; }
.section-title .soft { color: var(--text-3); font-weight: 400; font-size: 13px; margin-left: 6px; }

/* ── 버튼 ── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: 46px; padding: 0 20px;
  border-radius: var(--r-btn); border: 0;
  font-size: 15px; font-weight: 600; cursor: pointer;
  transition: background .15s ease, color .15s ease, transform .1s ease;
  background: none;
}
.btn:active { transform: scale(.97); }
/* 키보드로 탐색할 때 지금 어디인지 보여야 한다. 예전엔 일부 버튼에만 있었다 */
.btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.btn-primary {
  background: var(--accent);
  color: #fff;
}
.btn-primary:hover { background: var(--accent-strong); }
.btn-primary:disabled { background: #E3EDE6; color: var(--text-3); cursor: not-allowed; transform: none; }
.btn-secondary { background: var(--fill); color: var(--text); }
.btn-secondary:hover { background: #E2EFE7; }
.btn-tint { background: var(--accent-weak); color: var(--accent); }
.btn-tint:hover { background: var(--mint-line); }
/* 손가락으로 누르는 화면이라 모든 버튼의 최소 높이를 44px 로 맞춘다 */
.btn-text { color: var(--text-3); padding: 0 12px; height: 44px; font-weight: 500; }
.btn-text:hover { color: var(--text-2); }
.btn-sm { height: 44px; padding: 0 16px; font-size: 14px; border-radius: var(--r-ctl); }

/* ── 카드 ── */
/* 보더 1.5px 은 장식이 아니라 크림 배경(--canvas) 위에서 흰 카드의 경계를 잡아 준다.
   그림자만으로는 두 밝은 면이 뭉개진다 (docs/design_improvement/03_components.md §1) */
.card {
  background: var(--paper); border-radius: var(--r-card);
  border: 1px solid var(--border);
  padding: 24px; box-shadow: var(--shadow-panel);
}
.card + .card, .card + details.fold, details.fold + .card, details.fold + details.fold { margin-top: 14px; }
.clickable { cursor: pointer; transition: transform .15s var(--ease), box-shadow .15s ease; }
.clickable:hover { transform: translateY(-1px); box-shadow: 0 8px 20px rgba(24, 24, 27, .1); }
.note { font-size: 13px; color: var(--text-3); }

/* 말풍선 */
.bubble {
  border-radius: var(--r-print); padding: 12px 16px; font-size: 14px;
  background: var(--fill); color: var(--text-2);
  border-top-left-radius: 6px; max-width: 92%;
}
.bubble time { color: var(--text-3); font-size: 12px; margin-left: 6px; }
.bubble.fixup {
  background: var(--accent-weak); color: var(--text);
  border-top-left-radius: 16px; border-top-right-radius: 6px;
  margin-left: auto;
}
.bubble-label { display: block; font-size: 12px; font-weight: 600; color: var(--text-3); margin: 10px 0 4px; }
.bubble.fixup + .bubble-label, .bubble-label.right { text-align: right; }
.bubble-label.blue { color: var(--accent); }

/* ── 칩 / 상태 ── */
.chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 4px 10px; border-radius: 999px;
  font-size: 13px; font-weight: 600; white-space: nowrap;
}
.chip-sm { padding: 2px 8px; font-size: 12px; }
.st-ok  { color: var(--ok);  background: var(--ok-bg); }
.st-mid { color: var(--mid); background: var(--mid-bg); }
.st-no  { color: var(--no);  background: var(--no-bg); }
.st-ct  { color: var(--ct);  background: var(--ct-bg); }
.st-om  { color: var(--om);  background: var(--om-bg); }
.st-fast { color: var(--mid); background: var(--mid-bg); }
/* 판정 안 함 (녹음이 이 자료의 발표가 아닐 때) — 판정이 아니라서 판정 색 5종을 쓰지 않고 중립 회색 (09-30 REC-10) */
.st-na  { color: var(--text-3); background: var(--fill); }
.chip-plain { color: var(--text-2); background: var(--fill); font-weight: 500; }
.chip-up { color: var(--green); background: var(--green-bg); }
.dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; flex: none; }
.dot.st-ok { background: var(--ok); } .dot.st-mid { background: var(--mid); }
.dot.st-no { background: var(--no); } .dot.st-ct { background: var(--ct); }
.dot.st-om { background: var(--om-soft); } .dot.st-fast { background: var(--mid); }
.dot.st-na { background: var(--border); box-shadow: inset 0 0 0 1px var(--text-3); }

/* 선택형 칩 */
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chips button {
  display: inline-flex; align-items: center; gap: 7px;
  height: 40px; padding: 0 16px 0 13px; border-radius: 999px;
  border: 0; background: var(--fill);
  font-size: 14px; font-weight: 500; color: var(--text-2); cursor: pointer;
  transition: all .15s ease;
}
/* 상황을 갈라 주는 표식이다. currentColor 라 칩이 선택되면 글자와 같이 물든다.
   토스 그래픽 가이드는 24~40px 을 권하는데, 칩 높이가 40 이라 글자와 균형이
   맞는 18 로 두고 선 두께로 또렷함을 지킨다 (항목당 하나만 쓴다) */
.chips .chip-ico { flex: none; width: 18px; height: 18px; opacity: .85; }
.chips button.on .chip-ico { opacity: 1; }
/* 고른 것은 확실히 골라 보여야 한다. 연한 민트 면에 초록 글씨는 「눌렀나?」를
   한 번 더 확인하게 만들었다 — 고른 칩은 브랜드 면을 통째로 입는다.
   (시간 프리셋이 이미 그렇게 하고 있어서 둘의 말이 서로 달랐다) */
.chips button:hover { background: var(--border); }
.chips button:active { transform: scale(.96); }
.chips button.on,
.chips button.on:hover {
  background: var(--brand); color: #fff;
  box-shadow: 0 2px 10px rgba(10, 132, 89, .28);
}
/* 카운트업이 굴리는 숫자. em 은 의미상 강조라 쓰되 기울이지는 않는다 */
.time-detail em { font-style: normal; font-variant-numeric: tabular-nums; }
.time-presets button { transition: transform .12s var(--ease), background .15s ease, color .15s ease; }
.time-presets button:hover { background: var(--border); }
.time-presets button.on:hover { background: var(--brand-strong); }
.time-presets button:active { transform: scale(.94); }
/* 주 버튼은 눌리는 게 손끝에 잡혀야 한다 */
.btn-primary { transition: transform .12s var(--ease), background .15s ease; }
.btn-primary:active { transform: scale(.985); }

/* ── 채움 바 (애니메이션 공용) ── */
.fill-bar { height: 8px; border-radius: 4px; background: var(--fill); overflow: hidden; }
.fill-bar i {
  display: block; height: 100%; border-radius: 4px; background: var(--accent);
  width: 0; transition: width .8s var(--ease);
}
.fill-bar i.red { background: var(--no); }
.fill-bar i.gray { background: var(--border); }

/* ── 홈 ── */
.greet { margin-bottom: 24px; }
.greet h1 { font-size: 26px; font-weight: 700; letter-spacing: -.3px; line-height: 1.4; }
.greet p { color: var(--text-3); margin-top: 4px; }
.stat-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-bottom: 14px; }
.stat-card { background: var(--surface); border-radius: var(--r-card); padding: 20px 22px; box-shadow: var(--shadow); }
.stat-card small { display: block; font-size: 13px; color: var(--text-3); font-weight: 500; margin-bottom: 6px; }
.stat-card strong { font-size: 26px; font-weight: 700; letter-spacing: -.3px; }
.stat-card .unit { font-size: 15px; font-weight: 600; color: var(--text-2); margin-left: 1px; }
.stat-card .chip { margin-left: 8px; vertical-align: 3px; }
.stat-card svg { display: block; margin-top: 8px; }
.sess-row {
  display: flex; align-items: center; gap: 14px;
  padding: 16px 12px; border-radius: var(--r-inner);
  cursor: pointer; transition: background .15s ease;
}
.sess-row:hover { background: var(--hover); }
.sess-row + .sess-row { border-top: 1px solid var(--fill); }
.sess-main { flex: 1; min-width: 0; }
.sess-main b { display: block; font-size: 15px; font-weight: 600; }
.sess-main span { font-size: 13px; color: var(--text-3); }
.sess-score { text-align: right; }
.sess-score strong { font-size: 20px; font-weight: 700; }
.sess-score small { font-size: 13px; font-weight: 400; color: var(--text-3); }
.sess-score .up { display: block; font-size: 12px; font-weight: 600; color: var(--green); }
.chev { color: var(--border); font-size: 18px; font-weight: 500; }
.about-link { display: inline-block; margin-top: 28px; font-size: 13px; color: var(--text-3); }
.about-link:hover { color: var(--text-2); }
.empty { text-align: center; padding: 56px 20px; color: var(--text-2); }
.resume-card {
  position: relative; display: block; margin-bottom: 14px; padding: 22px 150px 22px 24px;
  border-radius: var(--r-card); background: var(--text); color: #fff;
}
.resume-card > span { display: block; margin-bottom: 3px; color: #9FBFF5; font-size: 12px; font-weight: 700; }
.resume-card strong { display: block; font-size: 18px; }
.resume-card p { margin-top: 3px; color: var(--text-3); font-size: 13px; }
.resume-card i { position: absolute; right: 24px; top: 50%; transform: translateY(-50%); font-style: normal; font-weight: 700; }

/* ── 새 발표: 스텝 ── */
.flow-toolbar { margin-bottom: 26px; }
/* 단계 표시. 알약 카드 넷을 나란히 두면 화면의 주인공이 「진행 표시」가 된다 —
   여기서 봐야 할 건 지금 할 일이지 몇 단계인지가 아니다. 면·그림자를 걷고
   현재 칸 아래 밑줄 하나로만 말한다 (홈의 표 문법과 같은 규율) */
.steps {
  display: flex; gap: 2px; margin-bottom: 18px;
  border-bottom: 1px solid var(--border);
}
/* 지나온 단계는 <button> 으로 그려서 눌러 되돌아갈 수 있다.
   생김새는 <span> 과 같아야 한다 — 되돌아갈 수 있다는 신호는 커서와 hover 다 */
.steps span,
.steps button {
  position: relative; display: flex; align-items: center; gap: 7px;
  font-family: inherit; text-align: left; border: 0; background: none;
  font-size: var(--t-meta); font-weight: 500; color: var(--text-3);
  padding: 0 14px 10px; border-radius: 0; box-shadow: none;
}
.steps span i,
.steps button i {
  font-style: normal; width: 17px; height: 17px; border-radius: 50%; flex: none;
  background: var(--fill); color: var(--text-3);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 10px; font-weight: 600;
}
.steps span.done, .steps button.done { color: var(--text-2); }
.steps span.done i, .steps button.done i { background: var(--brand-weak); color: var(--brand-strong); }
.steps span.cur { color: var(--text); font-weight: 650; }
.steps span.cur i { background: var(--brand); color: #fff; }
/* 지금 칸에만 밑줄. 리포트 탭(#rtabs)과 같은 문법이라 화면끼리 말이 맞는다 */
.steps span.cur::after {
  content: ""; position: absolute; left: 14px; right: 14px; bottom: -1px;
  height: 2px; background: var(--brand); border-radius: 1px;
}
.steps button { cursor: pointer; transition: color .15s ease; }
.steps button:hover { color: var(--text); }
.steps button:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 4px; }
.flow-save { display: flex; align-items: center; justify-content: flex-end; gap: 12px; min-height: 22px; font-size: 12px; }
.flow-save span { color: var(--text-3); }
.flow-save a { color: var(--text-2); font-weight: 600; }
.flow-save a:hover { color: var(--accent); }

.dropzone {
  background: var(--surface); border-radius: var(--r-card);
  border: 1.5px dashed var(--border);
  padding: 40px 20px; text-align: center;
  transition: border-color .15s ease, background .15s ease;
}
.dropzone.hover { border-color: var(--accent); background: #FBFCFE; }
.dropzone h3 { font-size: 16px; font-weight: 600; margin-bottom: 4px; }
.dz-actions { margin-top: 20px; display: flex; flex-direction: column; align-items: center; gap: 8px; }
.dz-copy { min-width: 0; }
.dz-kicker {
  display: block; margin-bottom: 10px;
  color: var(--brand); font-size: var(--t-meta); font-weight: 700;
}
.dropzone .dz-copy h1 {
  margin: 0; font-size: clamp(24px, 4vw, 34px); line-height: 1.28;
  font-weight: 700; letter-spacing: -.035em;
}
.dz-note {
  max-width: 34ch; margin: 14px 0 8px;
  color: var(--text-2); font-size: var(--t-body); line-height: 1.65;
}
.dz-or { color: var(--text-3); font-size: var(--t-meta); line-height: 1.5; }
/* 학습 동의 — 기본 꺼짐. 드롭존의 주인공은 자료 올리기라 작게, 아래에 둔다 */
.dz-consent {
  display: inline-flex; align-items: flex-start; gap: 8px; margin-top: 22px;
  color: var(--text-2); font-size: var(--t-meta); line-height: 1.5; text-align: left; cursor: pointer;
}
.dz-consent input { margin: 3px 0 0; accent-color: var(--brand); flex: none; }
.dz-consent-note { margin: 6px auto 0; max-width: 40ch; color: var(--text-3); font-size: 12px; line-height: 1.5; }
.session-delete { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--border); }
/* 피드백 — 근거 줄 아래 작게. 판정을 가리지 않는다 (연출이 데이터를 가리면 연출을 버린다) */
.fb-row { display: inline-flex; align-items: center; gap: 6px; margin-top: 4px; color: var(--text-3); font-size: 12px; line-height: 1.5; }
.fb-btn {
  border: 1px solid var(--border); border-radius: var(--r-pill); background: transparent;
  color: var(--text-2); font: inherit; font-size: 12px; padding: 2px 10px; cursor: pointer;
}
.fb-btn:hover { border-color: var(--brand); color: var(--brand); }
.fb-btn:disabled { opacity: .5; cursor: default; }
.fb-thanks { color: var(--brand); font-size: 12px; font-weight: 600; }
.filler-row .fb-row { flex-basis: 100%; }
.session-delete .btn-text { padding-left: 0; }
.sample-analysis-note {
  margin: 0 0 16px;
  padding: 12px 14px;
  border: 1px solid #cfe9db;
  border-radius: var(--r-print);
  background: linear-gradient(145deg, #f4fbf7, #edf8f2);
  color: var(--text-2);
  font-size: 12px;
}
.sample-analysis-note b { color: var(--accent); }
.progress { height: 8px; border-radius: 4px; background: var(--fill); overflow: hidden; margin-top: 16px; position: relative; }
.progress i { display: block; width: 100%; height: 100%; background: var(--accent); border-radius: 4px; }
/* 결정론적 막대는 1초마다 폭이 바뀐다. 전환이 없으면 뚝뚝 끊기고,
   길면 실제 진행보다 늦게 도착해 옆 숫자와 어긋난다 — 1초 틱과 같은 길이로 맞춘다 */
.pipe-status-bar .progress i { transition: width 1s linear; }

/* 파이프라인 상태 줄 — 단계와 무관하게 항상 떠 있다 (UI_REDESIGN §14 정직한 상태 유지) */
.pipe-status-bar {
  margin: 0 0 14px; padding: 14px 16px;
  border-radius: var(--r-inner); background: var(--fill); border: 1px solid var(--border);
}
.pipe-status-bar .progress { margin-top: 10px; background: rgba(255, 255, 255, .7); }
.psb-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.psb-head .pipe-phase { font-size: 15px; font-weight: var(--w-med); color: var(--text); }
.psb-pct { font-size: 18px; font-weight: var(--w-bold); color: var(--brand); font-variant-numeric: tabular-nums; }
.psb-meta { margin: 8px 0 0; font-size: 13px; color: var(--text-3); }
.psb-meta b { color: var(--text-2); font-variant-numeric: tabular-nums; }
.pipe-status-bar.is-final .psb-pct { color: var(--text-2); }

/* 녹음 화면의 선분석 한 줄 — 주인공은 슬라이드다. 눈에 안 띄게 둔다 */
.pre-note {
  margin: 6px 0 0; font-size: 12.5px; color: var(--text-3);
  display: flex; align-items: center; gap: 6px;
}
.pre-note::before {
  content: ''; width: 6px; height: 6px; border-radius: var(--r-dot);
  background: var(--text-3); flex: none;
}
.pre-note.is-done { color: var(--brand); }
.pre-note.is-done::before { background: var(--brand); }

/* ─── 분석 타임라인 — 영상 편집기처럼 단계가 시간축 위에 놓인다 ───────────
   폭은 실측 초에 비례한다. 완료는 채움, 진행은 채워지는 중, 예상은 빗금 —
   실측과 예상이 같은 질감으로 보이면 그 순간부터 막대가 거짓말이 된다 (§14). */
.pipe-tl { margin: 0 0 14px; }
.tl-pre-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.tl-pre-chips:not(:empty) { margin-bottom: 8px; }
.tl-chip {
  font-size: 12px; padding: 3px 10px; border-radius: var(--r-pill);
  background: var(--brand-weak); color: var(--brand); font-weight: var(--w-med);
  font-variant-numeric: tabular-nums;
}
.tl-ruler { position: relative; height: 16px; }
.tl-tick {
  position: absolute; top: 0; transform: translateX(-50%);
  font-size: 10px; color: var(--text-3); font-variant-numeric: tabular-nums;
  transition: left .45s var(--ease);
}
.tl-band { position: relative; }
.tl-track {
  position: relative; display: flex; height: 46px;
  border-radius: var(--r-ctl); background: var(--surface);
  border: 1px solid var(--border); overflow: hidden;
}
.tl-seg { position: relative; height: 100%; flex: none; overflow: hidden; transition: width 1s linear; }
.tl-seg + .tl-seg { border-left: 1px solid var(--border); }
.tl-seg[data-state="off"] { display: none; }
.tl-fill {
  position: absolute; inset: 0 auto 0 0; width: 0; display: block;
  background: var(--brand); opacity: .16; transition: width 1s linear;
}
.tl-seg[data-state="done"] .tl-fill { opacity: .26; }
.tl-seg[data-state="error"] .tl-fill { background: var(--no); opacity: .14; }
.tl-ghost {
  position: absolute; inset: 0 0 0 auto; width: 0; display: block;
  background: repeating-linear-gradient(-45deg, transparent 0 5px, var(--fill) 5px 9px);
  transition: width 1s linear;
}
.tl-name {
  position: absolute; left: 9px; top: 7px; font-size: 11.5px;
  font-weight: var(--w-med); color: var(--text-2); white-space: nowrap;
}
.tl-seg[data-state="active"] .tl-name { color: var(--text); font-weight: var(--w-bold); }
.tl-seg[data-state="est"] .tl-name, .tl-seg[data-state="idle"] .tl-name { color: var(--text-3); }
.tl-sec {
  position: absolute; left: 9px; bottom: 6px; font-size: 11px;
  color: var(--text-3); font-variant-numeric: tabular-nums; white-space: nowrap;
}
.tl-seg[data-state="error"] .tl-sec { color: var(--no); }
/* 칸이 좁으면 이름·초를 지운다. 잘린 글자는 정보가 아니라 고장으로 읽힌다 */
.tl-seg.is-tight .tl-name, .tl-seg.is-tight .tl-sec { display: none; }
.tl-seg.is-overrun .tl-fill { animation: tl-overrun 1.6s ease-in-out infinite; }
@keyframes tl-overrun { 50% { opacity: .3; } }
.tl-playhead {
  position: absolute; top: -3px; bottom: -3px; left: 0; width: 2px;
  background: var(--brand); border-radius: 1px;
  transition: transform 1s linear; pointer-events: none;
}
.tl-playhead::before {
  content: ''; position: absolute; top: -5px; left: -3px;
  border: 4px solid transparent; border-top-color: var(--brand);
}
.tl-after { margin: 8px 0 0; }

/* 라이브 피드 — 분석이 지금까지 실제로 한 일의 기록. 지어낸 줄은 없다 */
.pipe-feed {
  margin: 0 0 14px; padding: 10px 14px;
  border: 1px solid var(--border); border-radius: var(--r-inner); background: var(--surface);
}
.feed-list { margin: 0; padding: 0; list-style: none; }
.feed-row {
  display: flex; gap: 10px; padding: 6px 0; font-size: 13px; color: var(--text-2);
  border-bottom: 1px solid var(--fill); line-height: 1.45;
}
.feed-time {
  flex: none; width: 40px; padding-top: 1px;
  color: var(--text-3); font-size: 12px; font-variant-numeric: tabular-nums;
}
.feed-row[data-kind="error"] span:last-child { color: var(--no); }
.feed-row[data-kind="pre"] span:last-child { color: var(--brand); font-weight: var(--w-med); }
.feed-old summary { padding: 4px 0; font-size: 12px; color: var(--text-3); cursor: pointer; }
.feed-now {
  display: flex; gap: 10px; align-items: center; padding-top: 8px;
  font-size: 13.5px; font-weight: var(--w-med); color: var(--text);
}
.feed-now i {
  flex: none; width: 8px; height: 8px; border-radius: var(--r-dot);
  background: var(--brand); animation: pulse 1s infinite;
}
.feed-now.is-final i { animation: none; background: var(--text-3); }
.feed-now-sec {
  margin-left: auto; color: var(--text-3); font-size: 12px;
  font-weight: var(--w-body); font-variant-numeric: tabular-nums;
}

/* F-11 띠 안에서는 낮게 눕는다 — 그 화면의 주인공은 아래 연출이다 */
.f11-chrome .pipe-status-bar { margin-bottom: 10px; padding: 10px 14px; }
.f11-chrome .pipe-tl { margin-bottom: 10px; }
.pipe-tl[data-variant="compact"] .tl-track { height: 30px; }
.pipe-tl[data-variant="compact"] .tl-name { top: 50%; transform: translateY(-50%); font-size: 11px; }
.pipe-tl[data-variant="compact"] .tl-sec { display: none; }
.pipe-tl[data-variant="compact"] .tl-ruler { height: 14px; }
@media (max-height: 780px) {
  .pipe-tl[data-variant="compact"] .tl-ruler,
  .pipe-tl[data-variant="compact"] .tl-pre-chips { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .tl-seg, .tl-fill, .tl-ghost, .tl-tick, .tl-playhead { transition: none; }
  .tl-seg.is-overrun .tl-fill, .feed-now i { animation: none; }
}
.progress.indeterminate i {
  width: 40%;
  animation: progress-slide 1.2s ease-in-out infinite;
}
@keyframes progress-slide {
  0% { transform: translateX(-120%); }
  100% { transform: translateX(280%); }
}
.parse-meta { margin-top: 10px; font-size: 13px; color: var(--gray); line-height: 1.5; }
.parse-meta b { color: var(--text); font-variant-numeric: tabular-nums; }
.gate-ok { display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: 16px; }
.gate-ok::before {
  content: "✓"; width: 24px; height: 24px; border-radius: 50%; flex: none;
  background: var(--accent); color: #fff; font-size: 13px;
  display: inline-flex; align-items: center; justify-content: center;
}
.thumbs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 16px; }
.thumb {
  aspect-ratio: 16 / 10; border-radius: var(--r-print);
  background: var(--fill); padding: 12px;
  display: flex; flex-direction: column; justify-content: space-between;
}
.thumb b { font-size: 12px; color: var(--text-3); font-weight: 600; }
.thumb span { font-size: 12px; color: var(--text-2); line-height: 1.4; }
.thumb.warn { background: var(--mid-bg); }
.thumb.warn b { color: var(--mid); }
.warn-note { display: flex; gap: 6px; margin-top: 12px; font-size: 13px; color: var(--mid); }
.fail-box { background: var(--no-bg); border-radius: var(--r-card); padding: 20px; color: var(--no); font-size: 14px; font-weight: 500; }
.step-actions { display: flex; align-items: center; gap: 10px; margin-top: 22px; }

/* 발표 정보 */
.field { margin-bottom: 22px; }
.field label { display: block; font-size: 13px; font-weight: 600; color: var(--text-2); margin-bottom: 8px; }
.field input[type=text] {
  width: 100%; height: 50px; padding: 0 16px;
  border: 1.5px solid transparent; border-radius: var(--r-inner);
  background: var(--fill); outline: none;
  transition: border-color .15s ease, background .15s ease;
}
.field input[type=text]:focus { border-color: var(--accent); background: var(--surface); }
.field input::placeholder { color: var(--text-3); }
.stepper { display: inline-flex; align-items: center; background: var(--fill); border-radius: var(--r-inner); overflow: hidden; }
.stepper button { width: 46px; height: 46px; border: 0; background: none; cursor: pointer; font-size: 18px; color: var(--text-2); }
.stepper button:hover { background: var(--hover); }
.stepper b { min-width: 68px; text-align: center; font-size: 15px; font-weight: 600; }
.time-presets { display: grid; grid-template-columns: repeat(6, 1fr); gap: 7px; }
.time-presets button {
  height: 42px; padding: 0; border: 0; border-radius: var(--r-print); background: var(--fill);
  color: var(--text-2); font-size: 14px; font-weight: 600; cursor: pointer;
}
.time-presets button.on { background: var(--accent); color: #fff; }
/* 안내 줄의 면은 위 입력창과 같은 --fill 을 쓴다.
   여기만 파르스름한 #F8F9FA 였어서 입력창만 초록기가 도는 것처럼 보였다 */
.time-detail { display: flex; align-items: center; gap: 14px; margin-top: 12px; padding: 14px; border-radius: var(--r-print); background: var(--fill); }
.time-detail p { display: flex; min-width: 0; flex-direction: column; font-size: 13px; }
.time-detail p b { color: var(--text-2); }
.time-detail p span { color: var(--text-3); font-size: 12px; }

/* 리허설 녹음 */
.rec-grid { display: grid; grid-template-columns: 1.4fr 1fr; gap: 14px; align-items: start; }
.viewer { padding: 0; overflow: hidden; }
.viewer-stage { background: var(--fill); margin: 8px; border-radius: var(--r-print); padding: 26px 24px; min-height: 190px; }
.viewer-stage small { font-size: 12px; color: var(--text-3); font-weight: 600; }
.viewer-stage h3 { font-size: 18px; font-weight: 700; margin-top: 6px; letter-spacing: -.2px; }
.viewer-lines { margin-top: 18px; display: flex; flex-direction: column; gap: 8px; }
.viewer-lines i { display: block; height: 8px; border-radius: 4px; background: #E2E6EA; }
.viewer-nav { display: flex; gap: 8px; padding: 8px 16px 16px; }
.rec-clock { font-size: 30px; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -.5px; }
.rec-live { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; color: var(--no); }
.rec-live::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--no); }
.meter { display: inline-flex; align-items: flex-end; gap: 3px; height: 20px; margin-left: 10px; }
.meter i { width: 3px; border-radius: 2px; background: var(--accent); }
.meter i:nth-child(1) { height: 8px; } .meter i:nth-child(2) { height: 15px; }
.meter i:nth-child(3) { height: 11px; } .meter i:nth-child(4) { height: 17px; }
.meter i:nth-child(5) { height: 9px; }
.rehearsal-control.is-live .meter i { transform-origin: center bottom; animation: rec-wave .88s ease-in-out infinite alternate; }
.rehearsal-control.is-live .meter i:nth-child(2) { animation-delay: -.42s; }
.rehearsal-control.is-live .meter i:nth-child(3) { animation-delay: -.68s; }
.rehearsal-control.is-live .meter i:nth-child(4) { animation-delay: -.22s; }
.rehearsal-control.is-live .meter i:nth-child(5) { animation-delay: -.55s; }
@keyframes rec-wave { from { transform: scaleY(.45); opacity: .62; } to { transform: scaleY(1.08); opacity: 1; } }
.trans-log { margin-top: 14px; max-height: 150px; overflow-y: auto; display: flex; flex-direction: column; gap: 4px; }
.trans-log span { font-size: 13px; color: var(--text-2); font-variant-numeric: tabular-nums; }
.trans-log span.re { color: var(--mid); }
.mic-denied { background: var(--fill); border-radius: var(--r-inner); padding: 16px; font-size: 13px; color: var(--text-2); }
.rehearsal-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; margin: -4px 0 16px; }
.rehearsal-head .mode-label { color: var(--accent); font-size: 12px; font-weight: 700; }
.rehearsal-head h1 { margin-top: 2px; font-size: 21px; line-height: 1.4; }
.rehearsal-head > p { color: var(--text-3); font-size: 12px; }
.rehearsal-shell { display: flex; flex-direction: column; gap: 12px; padding-bottom: 24px; }
.rehearsal-side { display: flex; flex-direction: column; gap: 12px; }
.rehearsal-nav { display: flex; align-items: stretch; gap: 10px; padding: 12px; }
.rehearsal-nav .btn { flex: 1 1 0; }
.rehearsal-nav .btn[hidden], .stage-nav[hidden] { display: none !important; }
.rehearsal-slide-meta { display: flex; flex-direction: column; align-items: center; justify-content: center; min-width: 92px; }
.rehearsal-slide-meta span { color: var(--text-3); font-size: 11px; font-weight: 600; }
.rehearsal-slide-meta strong { margin-top: 2px; font-size: 16px; }
.presentation-viewer { width: 100%; }
.presentation-viewer .viewer-stage { position: relative; }
.presentation-viewer .viewer-stage {
  border: 1px solid rgba(25, 37, 31, .09);
  box-shadow: 0 14px 34px rgba(24, 36, 30, .11), 0 2px 8px rgba(24, 36, 30, .06);
}
.stage-nav {
  /* 진회색 큰 알약이 슬라이드 위에 얹혀 있으면 자료보다 버튼이 먼저 읽힌다.
     흰 원 + 옅은 그림자로 낮춰서 슬라이드가 주인공을 되찾게 한다 */
  position: absolute; top: 50%; width: 44px; height: 44px; transform: translateY(-50%);
  display: flex; align-items: center; justify-content: center;
  border: 0; border-radius: var(--r-pill); background: var(--surface); color: var(--text-2);
  box-shadow: 0 2px 10px rgba(24, 24, 27,.16);
  font-size: 20px; line-height: 1; cursor: pointer; opacity: .9; transition: opacity .15s ease, background .15s ease;
  z-index: 6; pointer-events: auto;
}
.stage-nav:focus-visible { opacity: 1; }
/* 터치 화면에는 hover 가 없다. 마우스가 있는 환경에서만 hover 로 강조한다 */
@media (hover: hover) {
  .viewer-stage:hover .stage-nav { opacity: 1; }
  .stage-nav:hover { background: var(--fill); }
}
.stage-prev { left: 14px; } .stage-next { right: 14px; }
.viewer-caption {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 10px 16px; border-top: 1px solid var(--border, var(--border));
}
.viewer-caption .caption-nav { display: flex; gap: 6px; }
.viewer-caption strong { flex: 1; min-width: 120px; }
.slide-film { position: relative; z-index: 3; }
/* 시작/녹음 컨트롤은 제목 바로 아래 — 16:9 뷰어·필름 아래로 밀리지 않게 */
.rehearsal-control {
  position: relative; z-index: 5; left: auto; bottom: auto; width: 100%; max-width: none;
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap; min-height: 86px; padding: 18px 20px;
  transform: none; border: 1px solid rgba(229,232,235,.9); box-shadow: 0 8px 24px rgba(24, 24, 27, .08);
  /* 이 화면의 주인공은 슬라이드다. 녹음 컨트롤은 그 아래 얇은 띠로 둔다
     (MVP_SPEC §5.2 "녹음은 아래의 얇은 발표 컨트롤로 둔다").
     DOM 은 컨트롤이 먼저라 order 로 뒤로 보낸다 */
  order: 1;
}
.rehearsal-control > .btn { margin-left: auto; flex: none; }
/* 발표 중에는 화면 하단에 고정해 슬라이드를 보며 타이머를 본다 */
.rehearsal-control.is-live {
  position: fixed; z-index: 12; left: 50%; bottom: 16px; width: calc(100% - 48px); max-width: 932px;
  transform: translateX(-50%); order: 0;
  box-shadow: 0 12px 36px rgba(24, 24, 27, .15);
}
.rehearsal-shell:has(.rehearsal-control.is-live) { padding-bottom: 104px; }
.rec-copy { min-width: 0; }
.rec-copy span { display: block; font-weight: 700; }
.rec-copy p { color: var(--text-3); font-size: 13px; }
.rec-status { display: flex; align-items: center; gap: 14px; flex: none; }
.rec-status > div { display: flex; align-items: center; gap: 12px; }
.rehearsal-control .rec-clock { font-size: 22px; }
.rec-log-fold { flex: 1; min-width: 170px; }
.rec-log-fold summary { color: var(--text-3); font-size: 12px; font-weight: 600; cursor: pointer; }
/* 펼친 기록은 떠 있지 않고 제자리에서 아래로 늘어난다. 떠 있는 팝오버(absolute·z-index 5)였을 때
   바로 아래 「발표 마치고 질문 준비하기」를 덮어 발표를 끝낼 수 없었다 (2026-09-23 사용자 제보) */
.rec-log-fold .trans-log { position: static; width: 100%; max-height: min(132px, 18vh); margin-top: 8px; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--r-inner); background: #fff; }
/* 리허설 대신 이미 녹음한 파일을 올리는 진입점 */
/* 제목과 무대(슬라이드) 사이 숨통 — 붙어 있으면 제목이 무대 캡션처럼 읽힌다 */
.rehearsal-head { margin-bottom: 20px; }
.rec-upload { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 0; max-width: 240px; }
.rec-upload .btn-text { height: 44px; padding: 0; }
/* 형식 안내는 화면 하단으로 갔다 — 이 줄은 업로드 상태가 생길 때만 보인다 */
#recUploadNote:empty { display: none; }
.rec-upload .note { margin: 0; color: var(--text-3); font-size: 11px; text-align: right; }
.rehearsal-control .mic-denied { display: flex; flex: 1; flex-direction: column; padding: 0; background: none; }
.rehearsal-control .mic-denied b { color: var(--text); }
.privacy-note { margin-top: 10px; color: var(--text-3); font-size: 12px; text-align: right; }

/* 분석 체크리스트 */
.checklist { padding: 0; margin: 0; }
.checklist li {
  list-style: none; display: flex; align-items: center; gap: 12px;
  padding: 15px 4px; font-size: 15px;
}
.checklist li + li { border-top: 1px solid var(--fill); }
.checklist li i {
  font-style: normal; width: 24px; height: 24px; border-radius: 50%; flex: none;
  display: inline-flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 600;
  background: var(--fill); color: var(--text-3);
}
.checklist li.done { color: var(--text); }
.checklist li.done i { background: var(--accent-weak); color: var(--accent); }
.checklist li.doing { color: var(--text); font-weight: 600; }
.checklist li.doing i { background: var(--accent); color: #fff; }
.checklist li.todo { color: var(--text-3); }

/* ── 리포트 ── */
.report-head { margin-bottom: 16px; }
.report-meta { font-size: 14px; color: var(--text-3); margin-top: 4px; }
.tabs {
  position: sticky; top: 56px; z-index: 10;
  display: inline-flex; gap: 2px; padding: 4px;
  background: var(--fill); border-radius: var(--r-ctl); margin-bottom: 20px;
}
.tabs button {
  padding: 8px 16px; border: 0; border-radius: 8px; background: none; cursor: pointer;
  font-size: 14px; font-weight: 500; color: var(--text-2);
  transition: all .15s ease;
}
.tabs button.on { background: var(--surface); color: var(--text); font-weight: 600; box-shadow: 0 1px 3px rgba(24, 24, 27, .08); }

/* 요약: 히어로 */
.hero-card { display: flex; gap: 32px; align-items: center; }
.ring-wrap { position: relative; width: 132px; height: 132px; flex: none; }
.ring-wrap svg { transform: rotate(-90deg); }
.ring-bg { fill: none; stroke: var(--fill); stroke-width: 11; }
.ring-fg {
  fill: none; stroke: var(--accent); stroke-width: 11; stroke-linecap: round;
  transition: stroke-dashoffset 1s var(--ease);
}
.ring-num {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.ring-num strong { font-size: 26px; font-weight: 700; letter-spacing: -1px; line-height: 1.1; }
.ring-num span { font-size: 13px; color: var(--text-3); font-weight: 500; }
.hero-body { flex: 1; min-width: 0; }
.hero-body h2 { font-size: 18px; font-weight: 700; letter-spacing: -.2px; line-height: 1.5; margin: 8px 0 16px; }
.dims { display: flex; flex-direction: column; gap: 10px; }
/* 라벨 열은 채점표 클러스터 이름이 들어갈 만큼 준다 — '목적·청중 적합성' 이 가장 길다.
   그래도 넘치면 word-break:keep-all 로 어절 단위로만 접는다 (한글을 글자 중간에서
   끊으면 못 읽는다). align-items:center 라 두 줄이 돼도 막대와 가운데가 맞는다. */
.dim-row { display: grid; grid-template-columns: 104px 1fr 40px; align-items: center; gap: 12px; font-size: 13px; }
.dim-row .lb { color: var(--text-2); font-weight: 500; word-break: keep-all; }
.dim-row .vl { text-align: right; font-weight: 700; font-size: 14px; }

/* 요약: 슬라이드 맵 */
/* 슬라이드별 상태 — 실제 썸네일 + 상태 테두리 */
.slidethumb-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(88px, 1fr)); gap: 8px; }
.slidethumb {
  position: relative; padding: 0; overflow: hidden;
  aspect-ratio: 4 / 3; border-radius: var(--r-ctl);
  border: 2px solid var(--border); background: var(--fill);
  cursor: default; transition: transform .12s var(--ease), box-shadow .12s ease;
}
.slidethumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.slidethumb .stnum {
  position: absolute; top: 5px; left: 5px;
  min-width: 19px; height: 19px; padding: 0 5px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 6px; background: rgba(255, 255, 255, .92);
  font-size: 11px; font-weight: 700; color: var(--text);
  box-shadow: 0 1px 2px rgba(24, 24, 27, .12);
}
/* 테두리 전체를 판정 색으로 칠하고 있었다. 그러면 «지금 보는 칸»(선택)과
   «이 장의 판정»(상태)이 테두리 색 하나를 두고 다툰다 — 스물세 칸이 저마다 다른
   색 테두리를 두르면 선택된 칸이 그중 하나로 묻힌다.
   테두리는 중립으로 두고 판정은 모서리 점이 맡는다 (§17). 필름(.deck-film)이
   먼저 이 방식으로 갔고, 격자도 같은 규칙을 따라야 한 화면에서 말이 하나가 된다 */
.slidethumb::before {
  content: ""; position: absolute; right: 5px; bottom: 5px; z-index: 2;
  width: 8px; height: 8px; border-radius: var(--r-dot);
  box-shadow: 0 0 0 1.5px rgba(255, 255, 255, .9);
}
.slidethumb.st-ok::before { background: var(--ok); }
.slidethumb.st-mid::before { background: var(--mid); }
.slidethumb.st-no::before { background: var(--no); }
.slidethumb.st-ct::before { background: var(--ct); }
.slidethumb.st-om::before { background: var(--om); }
.slidethumb.st-none::before { display: none; }
.slidethumb.st-na::before { background: var(--text-3); }
.slidethumb.has { cursor: pointer; }
.slidethumb.has:hover { transform: translateY(-2px); box-shadow: 0 6px 18px rgba(24, 24, 27, .12); }
.slidethumb.has::after {
  content: ""; position: absolute; inset: 0;
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .5); border-radius: var(--r-ctl); pointer-events: none;
}
.legend { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 14px; }
.legend span { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--text-3); font-weight: 500; }

/* 요약: 타임라인 */
.tl-track { position: relative; height: 44px; background: var(--fill); border-radius: var(--r-ctl); margin: 6px 0 14px; }
.tl-range { position: absolute; top: 0; bottom: 0; background: var(--mid-bg); border-radius: var(--r-ctl); }
.tl-dot {
  position: absolute; top: 50%; width: 12px; height: 12px; border-radius: 50%;
  transform: translate(-50%, -50%); border: 2.5px solid #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .15);
}
.tl-time { position: absolute; top: -22px; transform: translateX(-50%); font-size: 11px; color: var(--text-3); font-weight: 500; font-variant-numeric: tabular-nums; }
.tl-ends { display: flex; justify-content: space-between; font-size: 11px; color: var(--text-3); font-weight: 500; margin-top: -8px; margin-bottom: 12px; }
.tl-event {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; border-radius: var(--r-inner);
  cursor: pointer; transition: background .15s ease; font-size: 14px;
}
.tl-event:hover { background: var(--hover); }
.tl-event time { flex: none; width: 74px; font-size: 13px; color: var(--text-3); font-weight: 500; font-variant-numeric: tabular-nums; }
.tl-event .lbl { flex: 1; }

/* 요약: 우선 보완 */
.prio-card { padding: 20px 22px; }
.prio-head { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
.prio-head .n {
  width: 26px; height: 26px; border-radius: 50%; flex: none;
  background: var(--text); color: #fff; font-size: 13px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
}
.prio-head h3 { font-size: 16px; font-weight: 600; flex: 1; letter-spacing: -.2px; }
.prio-desc { font-size: 14px; color: var(--text-2); margin-bottom: 6px; }
.prio-gain { color: var(--green); background: var(--green-bg); }

/* 다음 연습 CTA */
.next-card { background: var(--accent-weak); box-shadow: none; }
.next-card h3 { font-size: 16px; font-weight: 700; letter-spacing: -.2px; }
.next-card p { font-size: 14px; color: var(--text-2); margin-top: 4px; }
.next-card .step-actions { margin-top: 18px; }

/* 접힘 */
details.fold { background: var(--surface); border-radius: var(--r-card); box-shadow: var(--shadow); }
details.fold summary {
  cursor: pointer; padding: 18px 24px; font-size: 15px; font-weight: 600;
  list-style: none; display: flex; justify-content: space-between; align-items: center;
}
/* 접힌 채로 "안에 뭐가 몇 개 있는지" 를 말하는 줄. 열어 볼 값어치를
   열어 보기 전에 알 수 있어야 한다 (app.js rSummary judgeMeta) */
details.fold summary .fold-meta {
  margin-left: auto; margin-right: 12px;
  color: var(--text-3); font-size: 13px; font-weight: 500;
}
details.fold summary::-webkit-details-marker { display: none; }
details.fold summary::after { content: "＋"; color: var(--text-3); font-weight: 400; font-size: 16px; }
details.fold[open] summary::after { content: "－"; }
details.fold .fold-body { padding: 0 24px 20px; }

/* 탭 진단 블록 — 가장 큰 문제 한 줄 + 처방 한 줄. 판정 헤드와 같은 규율로
   "판단은 헤드, 단서는 아래 작은 줄". 근거가 없으면 JS 가 블록째 생략한다 */
.tab-verdict {
  background: var(--surface); border-radius: var(--r-card);
  box-shadow: var(--shadow); padding: 22px 24px; margin-bottom: 14px;
}
.tab-verdict h2 { font-size: 16px; font-weight: var(--w-bold); letter-spacing: -.3px; margin: 0 0 6px; }
.tab-verdict .tv-action { font-size: 14px; color: var(--text-2); line-height: 1.6; margin: 0; }
.tab-verdict .bubble { margin-top: 12px; }
.mini-row { display: flex; align-items: center; gap: 10px; padding: 10px 8px; border-radius: var(--r-ctl); font-size: 14px; cursor: pointer; }
.mini-row:hover { background: var(--hover); }
.mini-row .lbl { font-weight: 500; flex: 1; }
.mini-row .sl { color: var(--text-3); font-size: 13px; font-variant-numeric: tabular-nums; }

/* 개념별 판정 */
.judge-grid { display: grid; grid-template-columns: 300px 1fr; gap: 14px; align-items: start; }
.filter-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.filter-chips button {
  height: 32px; padding: 0 12px; border-radius: 999px; font-size: 13px; font-weight: 500;
  border: 0; background: var(--surface); color: var(--text-2); cursor: pointer;
  box-shadow: var(--shadow); transition: all .15s ease;
}
.filter-chips button.on { background: var(--text); color: #fff; }
.tree { display: flex; flex-direction: column; gap: 2px; padding: 10px; }
.tree button {
  display: flex; align-items: center; gap: 9px; text-align: left;
  padding: 11px 12px; border: 0; background: none; border-radius: var(--r-print); cursor: pointer;
  font-size: 14px; font-weight: 500; transition: background .15s ease;
}
.tree button:hover { background: var(--hover); }
.tree button.sel { background: var(--accent-weak); color: var(--accent-strong); }
.tree button.child { margin-left: 18px; font-weight: 400; }
.tree button small { margin-left: auto; color: var(--text-3); font-size: 12px; font-weight: 500; font-variant-numeric: tabular-nums; }
.detail-top { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 4px; }
.detail-top h3 { font-size: 18px; font-weight: 700; letter-spacing: -.2px; }
.detail-meta { font-size: 13px; color: var(--text-3); margin-bottom: 14px; }
/* 판정 상세: 해당 슬라이드 크게 */
.judge-slide { margin: 0 0 18px; border: 2px solid var(--border); border-radius: var(--r-print); overflow: hidden; }
/* 캔버스는 올린 PDF 원본 렌더다 — 썸네일을 늘리면 부스 화면에서 뭉갠다 */
.judge-slide img, .judge-slide canvas { width: 100%; height: auto; display: block; }
.judge-slide figcaption { display: flex; align-items: center; gap: 8px; padding: 8px 12px; font-size: 12px; font-weight: 500; color: var(--text-2); background: var(--fill); }
.judge-slide figcaption .num { color: var(--text-3); }
.judge-slide.st-ok { border-color: var(--ok); }
.judge-slide.st-mid { border-color: var(--mid); }
.judge-slide.st-no { border-color: var(--no); }
.judge-slide.st-ct { border-color: var(--ct); }
.judge-slide.st-om { border-color: var(--text-3); }
.judge-slide.st-na { border-color: var(--border); }

.slide-strip { display: flex; gap: 4px; margin-bottom: 18px; }
.slide-strip i {
  flex: 1; height: 6px; border-radius: 3px; background: var(--fill);
}
.slide-strip i.cur { background: var(--accent); }
.confbar { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--text-3); margin-bottom: 14px; font-weight: 500; }
.confbar .fill-bar { width: 130px; height: 6px; }
.confbar b { color: var(--text-2); font-variant-numeric: tabular-nums; }
.checks { display: flex; gap: 8px; margin-bottom: 18px; flex-wrap: wrap; }
.checks span {
  display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 500;
  padding: 6px 12px; border-radius: 999px; background: var(--fill); color: var(--text-3);
}
.checks span.y { color: var(--accent); background: var(--accent-weak); }
.drow { padding: 14px 0 0; font-size: 14px; }
.drow > b { display: block; font-size: 13px; color: var(--text-3); font-weight: 600; margin-bottom: 6px; }
.fixbox { background: var(--accent-weak); border-radius: var(--r-inner); padding: 16px 18px; margin-top: 16px; }
.fixbox b { display: block; font-size: 13px; color: var(--accent); font-weight: 600; margin-bottom: 4px; }
.fixbox p { font-size: 15px; font-weight: 500; line-height: 1.6; }
.ai-note { font-size: 13px; color: var(--text-3); margin-top: 14px; }

/* 논리 흐름 */
.flow-vis { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.flow-vis .slide-chip {
  padding: 6px 12px; border-radius: var(--r-ctl); background: var(--fill);
  font-size: 13px; font-weight: 600; color: var(--text-2); white-space: nowrap;
}
.flow-line { flex: 1; position: relative; height: 2px; min-width: 60px; }
.flow-line::before { content: ""; position: absolute; inset: 0; border-top: 2px dashed var(--no); }
.flow-line.good::before { border-top: 2px solid var(--ok); }
.flow-line em {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  font-style: normal; width: 22px; height: 22px; border-radius: 50%;
  background: var(--no); color: #fff; font-size: 12px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
}
.flow-line.good em { background: var(--ok); }
.logic-note { font-size: 14px; color: var(--text-2); margin-bottom: 8px; }

/* 흐름 탭 주인공 카드 — 텍스트 칩 대신 실제 슬라이드 두 장을 나란히 보여준다
   (2026-08-12 다시 그림). 나머지(접힌 목록)는 위 .flow-vis 텍스트 칩을 그대로 쓴다. */
.flow-feature-slides { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.flow-feature-slide { flex: 1; min-width: 0; margin: 0; }
.flow-feature-slide img {
  display: block; width: 100%; aspect-ratio: 16/9; object-fit: cover;
  border-radius: var(--r-inner); border: 1px solid var(--border); background: var(--fill);
}
.flow-feature-slide figcaption {
  margin-top: 6px; font-size: 12px; font-weight: 600; color: var(--text-3); text-align: center;
}
.flow-feature-gap { flex: none; display: flex; flex-direction: column; align-items: center; gap: 6px; width: 64px; }
.flow-feature-gap em {
  font-style: normal; width: 26px; height: 26px; border-radius: 50%;
  background: var(--no); color: #fff; font-size: 13px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
}
.flow-feature-gap em.good { background: var(--ok); }
.flow-feature-skip {
  font-size: 11px; font-weight: 600; color: var(--text-3); text-align: center; white-space: nowrap;
}

/* 말 속도 */
.pace-rows { padding-top: 26px; position: relative; }
.pace-row { display: grid; grid-template-columns: 110px 1fr 132px; align-items: center; gap: 12px; padding: 5px 0; font-size: 13px; }
.pace-row .nm { color: var(--text-2); font-weight: 500; }
.pace-row .vl { text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--text-2); }
.pace-row.fast .vl { color: var(--no); }
.speech-stat-row .pace-word { font-size: 23px; letter-spacing: -.035em; }
.pace-row .fill-bar { height: 14px; border-radius: 7px; }
.pace-row .fill-bar i { border-radius: 7px; background: #C9DDFC; }
.pace-row.fast .fill-bar i { background: var(--no); opacity: .75; }
.pace-base { position: absolute; top: 22px; bottom: 4px; border-left: 2px dashed var(--text-3); z-index: 1; }
.pace-base em { position: absolute; top: -20px; left: 50%; transform: translateX(-50%); font-style: normal; font-size: 11px; font-weight: 600; color: var(--text-2); white-space: nowrap; background: var(--surface); padding: 0 4px; }
.alloc-row { display: grid; grid-template-columns: 110px 1fr 96px; gap: 12px; align-items: center; padding: 9px 0; font-size: 13px; }
.alloc-row .nm { color: var(--text-2); font-weight: 500; }
.alloc-bars { display: flex; flex-direction: column; gap: 4px; }
.alloc-bars .fill-bar { height: 8px; }
.alloc-lgd { display: flex; gap: 14px; margin-bottom: 10px; }
.alloc-lgd span { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--text-3); font-weight: 500; }
.alloc-lgd i { width: 10px; height: 6px; border-radius: 3px; display: inline-block; }
.alloc-st { text-align: right; font-weight: 600; font-size: 12px; }
.alloc-st.warn { color: var(--no); }
.alloc-st.fine { color: var(--text-3); font-weight: 400; }

/* ── 음성 습관 리포트 (쉬운 설명 + 시간 그래프 + 간투어 칩)
   callers: index.html → css/app.css; app.js voiceTimeChartHtml / rPace / rSummary / animateViz
   data: /data/voice_report_live.json (pace.slides actual_sec/recommended_sec, habits.spans_sample FIL)
   user: "레포트에서 잘 시각적으로도 보여줘야지 … 뾰로롱 애니메이션도 넣고 … 간투어까지 키워드 상자로"
── */
.voice-easy-card { background:
  radial-gradient(120% 80% at 0% 0%, rgba(3, 178, 108, .08), transparent 55%),
  radial-gradient(90% 70% at 100% 20%, rgba(63, 213, 153, .10), transparent 50%),
  var(--surface);
}
.voice-lead { font-size: 15px; color: var(--text-2); margin: -4px 0 16px; line-height: 1.65; }
.voice-h4 { font-size: 13px; font-weight: 700; color: var(--text-3); margin: 0 0 10px; letter-spacing: -.1px; }
.voice-split { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.voice-actions { margin: 14px 0 0; padding-left: 20px; color: var(--text-2); }
.voice-actions li { padding: 4px 0; font-size: 14px; }
.linkish {
  display: inline; padding: 0; border: 0; background: none; cursor: pointer;
  color: var(--accent); font-weight: 600; text-decoration: underline; text-underline-offset: 2px;
}
.voice-stat-row .stat-card.pop-in {
  opacity: 0; transform: translateY(10px) scale(.97);
  animation: voicePop .55s var(--ease) forwards;
  animation-delay: calc(var(--i, 0) * 70ms);
}
@keyframes voicePop {
  0% { opacity: 0; transform: translateY(12px) scale(.94); }
  60% { opacity: 1; transform: translateY(-3px) scale(1.02); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

.slide-pill-row { display: flex; flex-wrap: wrap; gap: 8px; }
/* 음성 습관 탭은 세로 한 줄이다 — 접어 둔 칸 없이 위에서 아래로 읽힌다 */
.voice-stack { display: flex; flex-direction: column; gap: 14px; }
/* gap 이 간격을 맡으므로 .card + .card 의 14px 를 여기서만 끈다 (안 그러면 28px 가 된다) */
.voice-stack > *, .voice-stack > .card + .card { margin-top: 0; }
.slide-pill {
  display: inline-flex; align-items: center; gap: 10px;
  border: 0; cursor: pointer; text-align: left;
  padding: 10px 12px 10px 10px; border-radius: var(--r-print);
  background: var(--fill); color: var(--text);
  opacity: 0; transform: translateY(8px) scale(.96);
  transition: transform .15s ease, box-shadow .15s ease, background .15s ease;
}
.slide-pill.is-on {
  animation: voicePop .55s var(--ease) forwards;
  animation-delay: calc(var(--i, 0) * 55ms);
}
.slide-pill:hover { transform: translateY(-1px); box-shadow: 0 4px 14px rgba(24, 24, 27, .08); }
.slide-pill .sp-no {
  width: 32px; height: 32px; border-radius: var(--r-ctl);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 14px; font-weight: 700; background: #fff; color: var(--text);
  box-shadow: inset 0 0 0 1px var(--border);
}
.slide-pill .sp-body { display: flex; flex-direction: column; gap: 1px; line-height: 1.25; }
.slide-pill .sp-body b { font-size: 12px; font-weight: 700; color: var(--text-3); }
.slide-pill .sp-body em { font-style: normal; font-size: 13px; font-weight: 600; }
.slide-pill .sp-body i { font-style: normal; color: var(--text-3); font-weight: 400; }
.slide-pill.tone-short { background: var(--mid-bg); }
.slide-pill.tone-short .sp-no { color: var(--mid); }
.slide-pill.tone-long { background: var(--no-bg); }
.slide-pill.tone-long .sp-no { color: var(--no); }

.voice-chart-card { overflow: hidden; }
.voice-chart-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 8px;
}
.voice-lgd { display: flex; gap: 12px; flex-shrink: 0; padding-top: 2px; }
.voice-lgd span {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 600; color: var(--text-3);
}
.voice-lgd i { width: 12px; height: 12px; border-radius: 4px; display: inline-block; }
.voice-lgd i.rec { background: var(--border); }
.voice-lgd i.act { background: var(--accent); }
.voice-tip {
  margin-top: 14px; padding: 12px 14px; border-radius: var(--r-print);
  background: var(--accent-weak); color: var(--accent-strong);
  font-size: 14px; font-weight: 500; line-height: 1.55;
}
.voice-plot-wrap {
  display: grid; grid-template-columns: 44px 1fr; gap: 8px;
  min-height: 220px; margin-top: 8px;
}
.voice-y {
  display: flex; flex-direction: column; justify-content: space-between;
  align-items: flex-end; padding: 4px 0 28px;
  font-size: 11px; font-weight: 600; color: var(--text-3);
}
.voice-plot {
  position: relative;
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(28px, 1fr);
  gap: 6px; align-items: end;
  min-height: 200px; padding: 8px 4px 0;
  border-radius: var(--r-print);
  background:
    linear-gradient(to top, transparent 27px, rgba(0,0,0,.04) 27px, rgba(0,0,0,.04) 28px, transparent 28px),
    linear-gradient(to top, transparent calc(50% + 14px), rgba(0,0,0,.035) calc(50% + 14px), rgba(0,0,0,.035) calc(50% + 15px), transparent calc(50% + 15px)),
    linear-gradient(180deg, #F7FAF8 0%, #EDF2EE 100%);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.03);
}
.voice-col {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  height: 100%; justify-content: flex-end; min-width: 0;
}
.voice-bars {
  display: flex; align-items: flex-end; justify-content: center; gap: 3px;
  width: 100%; height: 160px;
}
.vbar {
  width: 42%; max-width: 14px; min-width: 6px;
  height: 0;
  border-radius: 6px 6px 3px 3px;
  transform-origin: bottom center;
}
.vbar.rec { background: #B9DCC9; }
.vbar.act {
  background: linear-gradient(180deg, var(--cyan) 0%, var(--accent) 70%, var(--accent-strong) 100%);
  box-shadow: 0 4px 10px rgba(3, 178, 108, .28);
}
.voice-chart.is-on .vbar {
  height: var(--h);
  animation: plorongBar .75s cubic-bezier(.34, 1.56, .64, 1) both;
  animation-delay: calc(var(--i, 0) * 48ms + var(--bar-lag, 0ms));
}
.voice-col .vbar.rec { --bar-lag: 0ms; }
.voice-col .vbar.act { --bar-lag: 70ms; }
@keyframes plorongBar {
  0% { height: 0; filter: brightness(1.15); }
  70% { filter: brightness(1.05); }
  100% { height: var(--h); filter: brightness(1); }
}
.voice-col.status-short .vbar.act {
  background: linear-gradient(180deg, #F0B27A 0%, var(--mid) 100%);
  box-shadow: 0 4px 10px rgba(178, 94, 9, .22);
}
.voice-col.status-long .vbar.act {
  background: linear-gradient(180deg, #F08A8A 0%, var(--no) 100%);
  box-shadow: 0 4px 10px rgba(217, 58, 58, .22);
}
.voice-col.is-core .vx { color: var(--accent); font-weight: 700; }
.vx {
  font-size: 11px; font-weight: 600; color: var(--text-3);
  font-variant-numeric: tabular-nums;
}
.vcore {
  font-size: 11px; font-weight: 700; color: var(--accent);
  letter-spacing: -.2px; line-height: 1; min-height: 10px;
}
.vcore.v-hide { visibility: hidden; }

.filler-cloud { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.filler-chip {
  display: inline-flex; align-items: baseline; gap: 8px;
  padding: 10px 14px; border-radius: var(--r-print);
  background: #FFF7ED; color: #9A3412;
  box-shadow: inset 0 0 0 1px rgba(154, 52, 18, .12);
  opacity: 0; transform: scale(.7) rotate(-2deg);
}
.filler-chip.is-on {
  animation: plorongChip .65s cubic-bezier(.34, 1.7, .45, 1) forwards;
  animation-delay: calc(var(--i, 0) * 80ms + 120ms);
}
.filler-chip b { font-size: 15px; font-weight: 700; letter-spacing: -.2px; }
.filler-chip small { font-size: 12px; font-weight: 600; opacity: .75; }
.filler-chip.size-1 { font-size: 13px; padding: 8px 12px; }
.filler-chip.size-2 { font-size: 14px; }
.filler-chip.size-3 { font-size: 16px; padding: 12px 16px; background: #FFEDD5; }
.filler-chip.size-4 {
  font-size: 18px; padding: 14px 18px;
  background: linear-gradient(135deg, #FFEDD5, #FED7AA);
  box-shadow: 0 6px 16px rgba(154, 52, 18, .12), inset 0 0 0 1px rgba(154, 52, 18, .14);
}
@keyframes plorongChip {
  0% { opacity: 0; transform: scale(.55) rotate(-6deg) translateY(8px); }
  55% { opacity: 1; transform: scale(1.08) rotate(1.5deg) translateY(-2px); }
  100% { opacity: 1; transform: scale(1) rotate(0) translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .voice-stat-row .stat-card.pop-in,
  .slide-pill.is-on,
  .voice-chart.is-on .vbar,
  .filler-chip.is-on {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
    height: var(--h, auto);
  }
}
@media (max-width: 680px) {
  .voice-split { grid-template-columns: 1fr; }
  .voice-plot { gap: 3px; }
  .voice-bars { height: 130px; }
  .voice-plot-wrap { min-height: 180px; }
}

/* 연습 도구 — 안쪽 세그먼트 메뉴를 없앤 뒤로 네 도구가 한 화면에 세로로 이어진다.
   제목이 구분선을 겸해야 어디서 도구가 바뀌는지 보인다 */
.tool-sec + .tool-sec { margin-top: 28px; padding-top: 26px; border-top: 1px solid var(--border); }
.tool-sec-title { font-size: 18px; font-weight: 700; margin-bottom: 4px; }
/* 무엇에 쓰는 도구인지는 제목 바로 밑에서 말한다. 예전엔 카드 꼬리에 달려 있어서
   다 읽고 나서야 용도를 알았다 (토스 Predictable hint) */
.tool-sec-sub { font-size: 13.5px; color: var(--text-2); margin-bottom: 14px; }
.map-tools { display: flex; align-items: center; gap: 14px; margin-bottom: 14px; }
.toggle { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 500; color: var(--text-2); cursor: pointer; user-select: none; }
.map-box {
  background: linear-gradient(180deg, #fff 0%, #fbfdfc 100%);
  border: 1px solid rgba(6, 78, 59, .08); border-radius: var(--r-print);
  overflow: hidden; box-shadow: 0 8px 24px rgba(6, 48, 39, .06);
}
.map-box svg { display: block; width: 100%; height: auto; }
.punch-card .phrase { font-size: 16px; font-weight: 600; letter-spacing: -.2px; line-height: 1.55; }
.punch-card .pos { font-size: 13px; color: var(--accent); font-weight: 600; margin-top: 8px; }
.punch-card .why { font-size: 13px; color: var(--text-2); margin-top: 6px; }
.term-top { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.term-top h3 { font-size: 16px; font-weight: 700; }
.term-top .sl { margin-left: auto; font-size: 12px; color: var(--text-3); font-weight: 500; }
.term-def { font-size: 15px; }
.term-q { font-size: 13px; color: var(--text-2); margin-top: 10px; }
.term-f { font-size: 13px; color: var(--text-3); margin-top: 2px; }

/* ── Q&A ── */
.coach-nav { display: flex; align-items: center; justify-content: space-between; margin: -6px 0 18px; font-size: 12px; }
.coach-nav a { color: var(--text-2); font-weight: 600; }
.coach-nav a:hover { color: var(--accent); }
.coach-nav span { color: var(--text-3); }
.qa-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.qa-prog-bar { height: 6px; border-radius: 3px; background: var(--fill); margin-bottom: 20px; overflow: hidden; }
.qa-prog-bar i { display: block; height: 100%; background: var(--accent); border-radius: 3px; transition: width .5s var(--ease); }
.aud-row { display: flex; gap: 8px; }
.aud-row button {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  border: 0; background: none; cursor: pointer; padding: 4px 6px; border-radius: var(--r-print);
  font-size: 12px; font-weight: 500; color: var(--text-3);
  transition: all .15s ease;
}
.aud-row button i {
  font-style: normal; width: 40px; height: 40px; border-radius: 50%;
  background: var(--fill); color: var(--text-2); font-size: 15px; font-weight: 600;
  display: inline-flex; align-items: center; justify-content: center;
  transition: all .15s ease;
}
.aud-row button.on { color: var(--accent); }
.aud-row button.on i { background: var(--accent); color: #fff; }
.aud-select { display: flex; align-items: center; gap: 7px; color: var(--text-3); font-size: 12px; font-weight: 600; }
.aud-select select { height: 38px; padding: 0 30px 0 12px; border: 0; border-radius: var(--r-ctl); outline: none; background: var(--surface); font-size: 13px; font-weight: 600; box-shadow: var(--shadow); }
.coach-summary { margin-bottom: 22px; padding: 18px 18px 16px; border-radius: var(--r-print); background: var(--surface); box-shadow: var(--shadow); }
.coach-goal { display: flex; flex-direction: column; }
.coach-goal span { color: var(--accent); font-size: 11px; font-weight: 700; }
.coach-goal strong { margin-top: 2px; font-size: 15px; }
.coach-stats { display: flex; gap: 14px; margin-top: 9px; color: var(--text-3); font-size: 12px; }
.coach-stats b { color: var(--text); font-size: 14px; }
.concept-track { position: relative; display: grid; grid-template-columns: repeat(3,1fr); gap: 8px; margin-top: 16px; }
.concept-track::before { content:""; position: absolute; left: 15%; right: 15%; top: 11px; height: 2px; background: var(--fill); }
.concept-track::after { content:""; position: absolute; left: 15%; top: 11px; width: calc(var(--coach-progress) * .7); max-width: 70%; height: 2px; background: var(--accent); transition: width .4s var(--ease); }
.concept-track > div { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; gap: 5px; color: var(--text-3); font-size: 11px; font-weight: 600; text-align: center; }
.concept-track i { width: 24px; height: 24px; border: 3px solid #fff; border-radius: 50%; background: var(--fill); font-style: normal; line-height: 18px; }
.concept-track .current, .concept-track .review, .concept-track .done { color: var(--text); }
.concept-track .current i { background: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); }
.concept-track .done i { background: var(--accent-weak); color: var(--accent); }
.concept-track .review i { background: var(--mid-bg); color: var(--mid); box-shadow: 0 0 0 3px #FFF9F0; }
.crumb { font-size: 13px; color: var(--text-3); margin-bottom: 12px; font-weight: 500; }
.crumb b { color: var(--text); }
.q-bubble-row { display: flex; gap: 12px; align-items: flex-start; margin-bottom: 8px; }
.q-avatar {
  width: 42px; height: 42px; border-radius: 50%; flex: none;
  background: var(--accent-weak); color: var(--accent); font-size: 15px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
}
.q-bubble {
  background: var(--surface); border-radius: var(--r-print); border-top-left-radius: 6px;
  padding: 16px 20px; box-shadow: var(--shadow);
  font-size: 16px; font-weight: 600; line-height: 1.55; letter-spacing: -.2px;
}
.coach-question { margin-bottom: 14px; padding: 20px; border-radius: var(--r-print); background: var(--surface); box-shadow: var(--shadow); }
.coach-question.is-review { border: 1px solid #FFE1B8; background: #FFFCF8; }
.question-meta { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.question-meta .q-avatar { width: 30px; height: 30px; font-size: 12px; }
.question-meta b { font-size: 12px; color: var(--text-2); }
.question-meta em { margin-left: auto; color: var(--text-3); font-size: 11px; font-style: normal; }
.coach-question .q-bubble { padding: 0; background: none; box-shadow: none; font-size: 18px; }
.qa-basis { font-size: 12px; color: var(--text-3); margin-top: 12px; }
.qa-answer { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; min-height: 54px; margin-bottom: 12px; }
.qa-answer .qa-speak { min-width: 170px; }
.mic-icon { font-size: 11px; color: #fff; }
.mic-svg { flex: none; }
.qa-recording { display: inline-flex; align-items: center; gap: 8px; margin-right: auto; font-size: 13px; color: var(--text-2); font-weight: 500; }
.qa-recording small { color: var(--text-3); font-weight: 400; }
.hint-box { background: var(--accent-weak); border-radius: var(--r-inner); padding: 14px 16px; font-size: 14px; color: var(--text); margin-bottom: 14px; }
.hint-box b { display: block; font-size: 12px; color: var(--accent); font-weight: 600; margin-bottom: 2px; }
.judge-card { margin-top: 18px; }
.judge-card .jrow { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.judge-card p { font-size: 15px; }
.judge-actions { display: flex; gap: 10px; margin-top: 16px; flex-wrap: wrap; }
.qa-end-ring { display: flex; align-items: center; gap: 24px; }
.qa-end-ring .txt h3 { font-size: 18px; font-weight: 700; }
.qa-end-ring .txt p { font-size: 14px; color: var(--text-2); margin-top: 4px; }
.qa-end-list { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
.qa-end-list .row { display: flex; align-items: center; gap: 10px; font-size: 14px; }

/* ── 질문 공방 · 대화형 ─────────────────────────────── */
.persuade-track { margin-bottom: 18px; padding: 16px 18px; border-radius: var(--r-print); background: var(--surface); box-shadow: var(--shadow); }
.pt-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 13px; }
.pt-head span { font-size: 13px; font-weight: 700; }
.pt-head b { font-size: 13px; color: var(--text-3); font-weight: 600; }
.pt-head b i { font-style: normal; font-weight: 500; }
.pt-head em { font-style: normal; color: var(--no); font-weight: 700; }
.pt-items { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.pt { display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 11px 6px; border-radius: var(--r-print); background: var(--fill); text-align: center; transition: background .3s var(--ease); }
.pt i { width: 22px; height: 22px; border-radius: 50%; background: #DDE1E6; color: #fff; font-style: normal; font-size: 12px; line-height: 22px; font-weight: 700; }
.pt span { font-size: 12px; font-weight: 600; color: var(--text-2); }
.pt small { font-size: 11px; font-weight: 600; color: var(--text-3); }
.pt.current { background: var(--accent-weak); }
.pt.current i { background: var(--accent); box-shadow: 0 0 0 3px #fff, 0 0 0 5px var(--accent-weak); }
.pt.current span { color: var(--accent-strong); }
.pt.current small { color: var(--accent); }
.pt.won i, .pt.review i { background: var(--green); }
.pt.won span, .pt.review span { color: var(--text); }
.pt.won small, .pt.review small { color: var(--green); }
.pt.lost { background: var(--no-bg); }
.pt.lost i { background: var(--no); }
.pt.lost span { color: var(--text); }
.pt.lost small { color: var(--no); }

/* 상대(페르소나) 카드 — 흰 카드 + 타이포 위계, 색 스트라이프 없이 아바타 톤으로만 구분 */
.persona-card { display: flex; align-items: center; gap: 14px; margin-bottom: 16px; padding: 16px 20px; border-radius: var(--r-print); background: var(--surface); box-shadow: var(--shadow); }
.persona-av { width: 44px; height: 44px; flex: none; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 16px; font-weight: 700; background: var(--fill); color: var(--text-2); }
.pc-txt { flex: 1; min-width: 0; }
.pc-txt b { display: block; font-size: 16px; font-weight: 700; letter-spacing: -.2px; }
.pc-txt .pc-style { font-size: 13px; color: var(--text-3); }
.pc-pass { flex: none; text-align: right; }
.pc-pass span { display: block; font-size: 11px; font-weight: 600; color: var(--text-3); margin-bottom: 1px; }
.pc-pass b { font-size: 13px; font-weight: 700; color: var(--text-2); }
/* 아바타 톤 (은은하게) — 메시지 아바타·페르소나 아바타 공용 */
.av-blue { background: var(--accent-weak); color: var(--accent); }
.av-purple { background: #F3E9FF; color: #8B2FC9; }
.av-green { background: var(--green-bg); color: var(--ok); }
.av-orange { background: #FFF1E0; color: var(--mid); }
.cap-timer { flex: none; margin-left: auto; align-self: center; font-size: 13px; font-weight: 700; color: var(--mid); font-variant-numeric: tabular-nums; }
.cap-timer.urgent { color: var(--no); }

.qa-stream { display: flex; flex-direction: column; gap: 14px; }
.msg { display: flex; gap: 10px; align-items: flex-start; }
.msg-avatar { width: 34px; height: 34px; flex: none; border-radius: 50%; background: var(--accent-weak); color: var(--accent); font-size: 13px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; }
.msg-bubble { max-width: 82%; padding: 13px 16px; border-radius: var(--r-print); border-top-left-radius: 5px; background: var(--surface); box-shadow: var(--shadow); font-size: 15px; line-height: 1.6; }
.msg.me { justify-content: flex-end; }
.msg.me .msg-bubble { border-top-left-radius: 16px; border-top-right-radius: 5px; background: var(--accent); color: #fff; }
.msg.me.partial .msg-bubble { background: var(--mid); }
.mb-tag { display: block; margin-top: 4px; font-size: 11px; font-weight: 600; opacity: .82; }

.msg-meta { display: block; font-size: 11px; font-weight: 700; color: var(--text-3); margin-bottom: 5px; }
.msg-q { font-size: 16px; font-weight: 600; letter-spacing: -.2px; line-height: 1.5; }
.msg-basis { display: block; margin-top: 9px; font-size: 12px; color: var(--text-3); }
/* 「이 질문의 근거」 — 접혀 있다가 누르면 자리·근거 한 줄과 자료 인용이 나온다 (qa_live.js questionOriginHtml) */
.msg-origin { margin-top: 9px; font-size: 12px; color: var(--text-3); }
.msg-origin summary { cursor: pointer; font-weight: var(--w-med); }
.msg-origin p { margin: 6px 0 0; }
.msg-origin .qa-evidence { font-size: 13px; }
/* 근거 장 번호 — 인용은 싣지 않는다 (함정은 인용이 곧 정답이다 · 09-30 C-03) */
.msg-origin .msg-origin-slides { color: var(--text-2); font-weight: var(--w-med); }
/* 안내 한 줄 (qa_live kind 'note') — 폴백 재료로 만든 질문·자료 본문 없이 한 판정·요청 제한. 판정 표식(✓·✕)이 아니다 */
.qa-note-line {
  align-self: center; max-width: 90%; margin: 0; padding: 6px 12px; border-radius: var(--r-pill);
  background: var(--fill); color: var(--text-2); font-size: 12px; line-height: 1.5; text-align: center;
}
/* 논문을 근거로 든 질문 — 문장 속 인용과 아래 줄 둘 다 그 논문으로 간다 (qa_live.js questionPapersHtml) */
.msg-paper-link { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px; }
.msg-paper-link:hover { text-decoration-thickness: 2px; }
.msg-papers { display: block; margin-top: 9px; font-size: 12px; font-weight: var(--w-med); color: var(--text-3); overflow-wrap: anywhere; }
.msg.ai.trap .msg-avatar { background: var(--mid-bg); color: var(--mid); }
.msg.ai.trap .msg-bubble { border: 1px solid #FFE1B8; }
.msg.ai.trap .msg-meta { color: var(--mid); }
.msg.ai.review .msg-avatar { background: var(--mid-bg); color: var(--mid); }
.msg.ai.review .msg-bubble { border: 1px solid #FFE1B8; background: #FFFCF8; }
.msg.ai.cut .msg-avatar { background: var(--no-bg); color: var(--no); }
.msg.ai.cut .msg-bubble { background: var(--no-bg); color: var(--text); font-weight: 500; }
.msg.ai.hint .msg-bubble { background: var(--accent-weak); color: var(--text); font-size: 14px; box-shadow: none; }

/* ── 판정 말풍선의 점수 ─────────────────────────────────────────────────────
   되묻기가 길어질 때 버티게 하는 건 격려가 아니라 오르는 숫자다. 여기 뜨는 값은
   전부 서버가 실제로 매긴 것이고, 진전이 없으면 델타를 아예 안 그린다. */
.react-head { display: flex; align-items: baseline; gap: 6px; margin-bottom: 6px; }
.react-head .msg-score { margin-left: auto; font-size: 17px; font-weight: 700; letter-spacing: -.02em; }
.react-head small { font-size: 11px; font-weight: 600; color: var(--text-3); }
.msg-delta { font-style: normal; font-size: 12px; font-weight: 700; }
.msg-delta.up { color: var(--ok); }
.msg-delta.dn { color: var(--text-3); }

/* ── 「듣고 있어요」 ────────────────────────────────────────────────────────
   답을 보낸 직후가 반응이 가장 필요한 순간인데 예전엔 그 몇 초가 완전히
   정적이었다. 대화가 끊긴 것처럼 보이면 사용자는 다음 답을 준비하지 않는다. */
.msg.ai.thinking .msg-bubble { display: flex; align-items: center; gap: 8px; background: var(--fill); box-shadow: none; font-size: 13px; color: var(--text-3); }
.msg.ai.thinking .dots { display: inline-flex; gap: 3px; font-style: normal; }
.msg.ai.thinking .dots b { width: 5px; height: 5px; border-radius: 50%; background: var(--text-3); animation: coachDot 1.1s var(--ease) infinite; }
.msg.ai.thinking .dots b:nth-child(2) { animation-delay: .15s; }
.msg.ai.thinking .dots b:nth-child(3) { animation-delay: .3s; }
@keyframes coachDot { 0%, 60%, 100% { opacity: .3; } 30% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .msg.ai.thinking .dots b { animation: none; opacity: .6; } }

/* 답을 보고 다시 말하는 카드. 같은 자리에 같은 문구를 두면 방금 답을 본 사람이
   무엇을 해야 하는지 모른다 — 라벨만으로 다음 행동이 예측돼야 한다 (§3-1) */
.qa-input-label.is-retell b { color: var(--brand); }
.msg.ai.hint b { display: block; font-size: 11px; color: var(--accent); font-weight: 700; margin-bottom: 2px; }

/* 힌트가 부르는 장을 조그맣게 같이 띄운다 — 장 번호만 부르면 그 장에 뭐가 있는지
   아는 사람에게만 힌트다. 말풍선 안이라 작게 두고, 넘치면 가로로 민다. */
/* 코칭 자료 인용 카드 · 둘 중 하나 선택 칩 (2026-09-10) */
.qa-evidence { margin: 8px 0 0; padding: 10px 12px; border-left: 3px solid var(--accent); border-radius: var(--r-ctl); background: var(--accent-weak); font-size: 14px; line-height: 1.55; color: var(--text); }
.qa-evidence span { display: block; margin-bottom: 2px; font-size: 11px; font-weight: 700; color: var(--text-3); }
.qa-choices { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.qa-choice-chip { font: inherit; font-size: 14px; font-weight: 600; padding: 7px 12px; border: 1px solid var(--accent); border-radius: var(--r-pill); background: var(--surface); color: var(--accent); cursor: pointer; }
.qa-choice-chip:hover, .qa-choice-chip:focus-visible { background: var(--accent-weak); outline: none; }
.hint-slides { display: flex; gap: 8px; margin-top: 8px; overflow-x: auto; padding-bottom: 2px; }
.hint-slides figure { margin: 0; flex: 0 0 auto; width: 116px; }
.hint-slides img {
  display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover;
  border-radius: var(--r-ctl); border: 1px solid var(--line, #D5E2DA); background: #fff;
}
.hint-slides figcaption { margin-top: 3px; font-size: 11px; font-weight: 600; color: var(--text-3, var(--muted)); text-align: center; }

/* 판정이 짚은 '빠진 지점'. 되물을 때 무엇을 보완해야 하는지 눈에 보이게 한다. */
.msg.ai.miss .msg-bubble { background: var(--mid-bg, #FFF6E5); box-shadow: none; }
.miss-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }

/* 기대했던 답. 대화가 끝났는데 답을 모른 채면 코칭이 실패한 것이라 눈에 띄게 둔다. */
.msg.ai.gist .msg-bubble { background: var(--green-bg, var(--ok-bg)); box-shadow: none; }
.msg.ai.gist p { margin: 4px 0 0; font-size: 14px; line-height: 1.55; }

/* 리포트 한 줄 요약 아래 붙는 '몇 턴 만에 방어했나'. 취약 개념 신호다. */
.qsum-meta { display: block; margin-top: 4px; font-size: 12px; color: var(--muted, var(--text-3)); font-weight: 500; }
.msg.ai.react .chip { margin-bottom: 7px; }
.msg.ai.react p { margin: 0; }

.qa-flag { display: flex; align-items: center; gap: 8px; align-self: center; max-width: 90%; padding: 9px 16px; border-radius: 999px; font-size: 13px; font-weight: 600; }
.qa-flag i { width: 18px; height: 18px; flex: none; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-style: normal; font-size: 11px; color: #fff; }
.qa-flag.won { background: var(--green-bg); color: var(--ok); }
.qa-flag.won i { background: var(--green); }
.qa-flag.lost { background: var(--no-bg); color: var(--no); }
.qa-flag.lost i { background: var(--no); }
.qa-flag.combo { background: #FFF4E5; color: var(--mid); }
.qa-flag.combo i { background: none; width: auto; height: auto; font-size: 15px; }

/* ── 게임 레이어 ── */
.pt-right { display: inline-flex; align-items: center; gap: 10px; }
.combo-live { font-size: 12px; font-weight: 700; color: var(--mid); padding: 4px 9px; border-radius: 999px; background: #FFF4E5; white-space: nowrap; animation: comboPop .3s var(--ease); }
@keyframes comboPop { from { transform: scale(.8); opacity: 0; } to { transform: none; opacity: 1; } }

.xp-card { border: 1px solid var(--accent-weak); margin-bottom: 14px; display: flex; align-items: center; gap: 20px; }
.xp-earned { flex: none; display: flex; flex-direction: column; align-items: center; padding-right: 20px; border-right: 1px solid var(--border); }
.xp-earned span { font-size: 12px; font-weight: 600; color: var(--text-3); }
.xp-earned strong { font-size: 26px; font-weight: 700; color: var(--accent); line-height: 1.1; }
.xp-earned small { font-size: 12px; font-weight: 600; color: var(--accent); }
.xp-body { flex: 1; min-width: 0; }
.xl-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.xl-head b { font-size: 15px; font-weight: 700; }
.combo-chip { font-size: 12px; font-weight: 700; color: var(--mid); padding: 4px 10px; border-radius: 999px; background: #FFF4E5; }

.game-card { padding: 18px 20px; }
.game-top { display: flex; align-items: center; gap: 20px; }
.game-streak { flex: none; display: flex; align-items: baseline; gap: 6px; padding-right: 20px; border-right: 1px solid var(--border); }
.game-streak strong { font-size: 26px; font-weight: 700; color: var(--mid); line-height: 1; }
.game-streak span { font-size: 12px; font-weight: 600; color: var(--text-3); line-height: 1.25; }
.game-level { flex: 1; min-width: 0; }
.gl-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 8px; }
.gl-head b { font-size: 15px; font-weight: 700; }
.gl-head .soft-x { font-size: 12px; color: var(--text-3); font-weight: 600; }
.review-list { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--border); }
.review-list h4 { margin: 0 0 10px; font-size: 14px; font-weight: 700; }
.review-list h4 span { display: block; font-size: 12px; font-weight: 400; color: var(--text-3); margin-top: 2px; }
.rev-row { display: flex; align-items: center; gap: 10px; padding: 9px 0; font-size: 14px; font-weight: 500; }
.rev-row + .rev-row { border-top: 1px solid var(--fill); }
.rev-row i { width: 8px; height: 8px; flex: none; border-radius: 50%; background: var(--fill); }
.rev-row.due i { background: var(--mid); }
.rev-row span { flex: 1; }
.rev-row em { font-style: normal; font-size: 12px; font-weight: 600; color: var(--text-3); }
.rev-row.due em { color: var(--mid); }
.review-list .btn { margin-top: 12px; }

/* ── 홈 히어로: 완성도 게이지 + 성장 area 차트 ── */
.home-hero { display: flex; align-items: center; gap: 24px; margin-bottom: 14px; }
.hero-gauge { flex: none; display: flex; flex-direction: column; align-items: center; gap: 12px; padding-right: 24px; border-right: 1px solid var(--border); }
.hero-gauge .ring-num strong { font-size: 30px; }
.hg-cap { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.hg-cap b { font-size: 13px; color: var(--text-2); font-weight: 600; }
.hero-growth { flex: 1; min-width: 0; }
.hg-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 2px; }
.hg-head span { font-size: 13px; color: var(--text-3); font-weight: 500; }
.hg-head b { font-size: 15px; font-weight: 700; }
.growth-svg { width: 100%; height: auto; display: block; overflow: visible; }
.hg-foot { display: flex; gap: 28px; margin-top: 4px; }
.hg-foot strong { font-size: 20px; font-weight: 700; }
.hg-foot small { display: block; font-size: 12px; color: var(--text-3); font-weight: 500; margin-top: 1px; }

.growth-line { stroke-dasharray: var(--len); stroke-dashoffset: var(--len); animation: growthDraw 1.1s var(--ease) .15s forwards; }
@keyframes growthDraw { to { stroke-dashoffset: 0; } }
.growth-area, .growth-dot-last, .growth-val { opacity: 0; animation: growthFade .55s ease forwards; }
.growth-area { animation-delay: .5s; }
.growth-dot-last, .growth-val { animation-delay: 1.05s; }
@keyframes growthFade { to { opacity: 1; } }
.growth-val { font-size: 13px; font-weight: 700; fill: var(--accent); }

@media (max-width: 640px) {
  .home-hero { flex-direction: column; align-items: stretch; gap: 16px; }
  .hero-gauge { flex-direction: row; justify-content: center; gap: 16px; padding-right: 0; padding-bottom: 16px; border-right: 0; border-bottom: 1px solid var(--border); }
}
@media (prefers-reduced-motion: reduce) {
  .growth-line { animation: none; stroke-dashoffset: 0; }
  .growth-area, .growth-dot-last, .growth-val { animation: none; opacity: 1; }
}

@media (max-width: 640px) {
  .xp-card, .game-top { flex-direction: column; align-items: stretch; gap: 14px; }
  .xp-earned, .game-streak { flex-direction: row; align-items: baseline; gap: 8px; padding-right: 0; padding-bottom: 14px; border-right: 0; border-bottom: 1px solid var(--border); justify-content: center; }
}

.typing-dots { display: inline-flex; gap: 4px; align-items: center; padding: 15px 16px; }
.typing-dots i { width: 7px; height: 7px; border-radius: 50%; background: var(--text-3); animation: blink 1.2s infinite; }
.typing-dots i:nth-child(2) { animation-delay: .2s; }
.typing-dots i:nth-child(3) { animation-delay: .4s; }
@keyframes blink { 0%, 60%, 100% { opacity: .25; transform: translateY(0); } 30% { opacity: 1; transform: translateY(-3px); } }

.qa-live { margin-top: 16px; }
.caption { display: flex; gap: 12px; align-items: flex-start; padding: 14px 16px; border-radius: var(--r-print); background: var(--fill); }
/* 답변을 끊는 버튼. 자막 아래 오른쪽에 둔다 — 자막을 가리지 않으면서
   말을 마친 순간 손이 가는 자리다 */
.cap-actions { display: flex; justify-content: flex-end; margin-top: 10px; }

/* F-11 연출 위에 남기는 띠 — 단계 표시줄 + 진행 체크리스트.
   연출이 화면을 다 먹으면 "어디까지 됐나"가 사라진다. 제일 궁금한 구간에서
   그 표지를 치우면 안 된다. 연출은 남은 자리를 쓴다 (§14 — 연출은 얹는 층이다). */
.f11-chrome {
  flex: none;
  padding: 14px max(20px, calc(calc(var(--vw) * 0.5) - 490px)) 12px;
  background: var(--canvas);
  border-bottom: 1px solid var(--border);
}
.f11-chrome .flow-toolbar { margin-bottom: 10px; }
/* 띠에 상태 줄·타임라인이 얹히면서 세로 체크리스트는 연출 자리를 다 먹는다.
   띠 안에서는 언제나 한 줄로 눕힌다 — 연출은 남은 자리를 쓰는 층이다 (§14) */
.f11-chrome .checklist { margin: 0; display: flex; flex-wrap: wrap; gap: 6px 18px; }
/* 한 줄에 여럿을 눕히면 아이콘과 글이 서로 다른 줄로 갈라진다 —
   「말한 내용을 글로 옮겼어요 / ✓ / 슬라이드별로…」처럼 읽혔다.
   항목 하나를 통째로 한 덩어리(inline-flex + nowrap)로 묶는다 */
.f11-chrome .checklist li {
  margin: 0; padding: 4px 0; font-size: 13px; border-top: 0;
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
}
.cap-live { flex: none; display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 700; color: var(--accent); padding-top: 2px; }
.cap-live::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); animation: pulse 1s infinite; }
.caption p { flex: 1; margin: 0; font-size: 15px; color: var(--text); min-height: 24px; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .3; } }
.live-actions { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.live-tip { display: block; margin-top: 9px; font-size: 12px; color: var(--text-3); }
.qa-speak { min-width: 160px; }
/* 회색 캔버스 위 버튼은 흰 배경 + 테두리로 분리 */
.qa-live .btn-secondary { background: var(--surface); border: 1px solid var(--border); }
.qa-live .btn-secondary:hover { background: #F0F2F4; }
.trap-choices { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.trap-choices .btn { height: 54px; background: var(--surface); border: 1px solid var(--border); font-weight: 600; }
.trap-choices .btn:hover { background: var(--accent-weak); color: var(--accent-strong); border-color: var(--accent-weak); }

/* ── QA 시간 모드 선택 ── */
.qa-mode-pick { margin-top: 22px; display: flex; flex-direction: column; gap: 12px; }
/* 제목과 설명을 한 줄에 나란히 두면 어디까지가 제목인지 안 읽힌다. 위아래로 쌓는다 */
.qm-head { display: flex; flex-direction: column; gap: 2px; margin-bottom: 2px; }
.qm-head b { font-weight: 700; }
.qm-head span { font-size: 13px; color: var(--text-3); }
.qa-modes { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.qa-mode {
  font-family: inherit; text-align: left; cursor: pointer;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-btn);
  padding: 11px 13px; display: flex; flex-direction: column; gap: 3px;
  transition: border-color .15s, background .15s;
}
.qa-mode b { font-size: 14px; font-weight: 700; }
.qa-mode span { font-size: 12px; color: var(--text-2); line-height: 1.45; }
.qa-mode em { font-style: normal; font-size: 12px; font-weight: 600; color: var(--text-3); }
.qa-mode.on { border-color: var(--accent); background: var(--accent-weak); }
.qa-mode.on em { color: var(--accent-strong); }
.qa-mode:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.qa-mode-pick .btn { align-self: flex-start; }
@media (max-width: 720px) { .qa-modes { grid-template-columns: 1fr; } }

.qa-quick { display: flex; flex-direction: column; gap: 12px; padding: 18px 20px; }
/* 왼쪽 아래 구석의 작은 버튼이 이 화면의 유일한 다음 행동이었다.
   카드 폭을 다 쓰는 CTA 로 세운다 (TDS BottomCTA) */
.qa-quick .btn { align-self: stretch; margin-top: 4px; }

/* ── 실전 모드 입력 ── */
.qa-live-input { display: flex; flex-direction: column; gap: 10px; padding: 14px 16px; margin-top: 14px; }
.qa-live-input textarea {
  font: inherit; font-size: 14px; line-height: 1.6; padding: 10px 12px; resize: vertical;
  border: 1px solid var(--border); border-radius: var(--r-btn); color: var(--text);
}
.qa-live-input textarea:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ── 스트림 안 실시간 총평 카드 ── */
.qa-sum {
  align-self: stretch; border: 1px solid var(--border); border-left: 3px solid var(--accent);
  background: var(--surface); border-radius: var(--r-inner); padding: 11px 14px;
}
.qa-sum .qs-eyebrow { display: block; font-size: 12px; font-weight: 700; letter-spacing: .04em; color: var(--accent-strong); margin-bottom: 3px; }
.qa-sum .qs-name { font-size: 13px; font-weight: 700; }
.qa-sum .qs-text { margin: 3px 0 0; font-size: 13px; color: var(--text-2); line-height: 1.55; min-height: 1.4em; }

/* ── 질문 하나가 닫히는 마무리 카드 ──
   말풍선이 아니다. 아바타를 안 달고 스트림 폭을 꽉 채워서, 대화가 이어지는 게
   아니라 «여기서 한 덩어리가 끝났다» 로 읽히게 한다. 위아래 여백을 말풍선 간격
   (14px)보다 넓혀 다음 질문과 시각적으로 끊는다. */
.qa-done {
  align-self: stretch; margin: 6px 0; padding: 14px 16px 12px;
  border: 1px solid var(--border); border-radius: var(--r-inner);
  background: var(--surface); border-left: 3px solid var(--ok);
}
.qa-done.is-lost { border-left-color: var(--no); }
.qa-done .qd-head { display: flex; align-items: center; gap: 8px; }
.qa-done .qd-head i {
  width: 18px; height: 18px; flex: none; border-radius: 50%; background: var(--ok);
  display: inline-flex; align-items: center; justify-content: center;
  font-style: normal; font-size: 11px; color: #fff;
}
.qa-done.is-lost .qd-head i { background: var(--no); }
.qa-done .qd-head b { font-size: 14px; font-weight: 700; }
.qa-done .qd-sec { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); }
.qa-done .qd-sec h4 {
  margin: 0 0 3px; font-size: 12px; font-weight: 700; letter-spacing: .02em; color: var(--text-3);
}
.qa-done .qd-sec p { margin: 0; font-size: 13px; line-height: 1.6; color: var(--text-2); }
.qa-done .qd-foot { margin: 10px 0 0; font-size: 12px; color: var(--text-3); }

/* 질문을 다 마친 자리. 다음 행동은 아래 입력 카드의 버튼이 맡으므로 여기선 조용히 선다. */
.qa-finale {
  align-self: center; max-width: 92%; margin: 10px 0 2px; padding: 12px 18px;
  border-radius: var(--r-inner); background: var(--fill); text-align: center;
}
.qa-finale b { display: block; font-size: 14px; font-weight: 700; }
.qa-finale p { margin: 3px 0 0; font-size: 12px; color: var(--text-3); }
.qa-input-label.is-end b { color: var(--brand); }
.qa-end-note { margin: 8px 0 0; font-size: 13px; color: var(--text-2); line-height: 1.55; }

.cere-sums { display: flex; flex-direction: column; gap: 0; margin-top: 10px; }
.qsum-row { border-top: 1px solid var(--border); padding: 10px 0; font-size: 13px; }
.qsum-row:first-child { border-top: none; padding-top: 0; }
.qsum-row b { display: block; font-weight: 700; margin-bottom: 2px; }
.qsum-row p { margin: 0; color: var(--text-2); }

/* 실전 질문 대신 데모 질문으로 되돌아갔을 때의 안내 */
.qa-notice {
  margin: 0 0 12px; padding: 10px 13px; font-size: 13px; line-height: 1.55;
  color: var(--text-2); background: var(--surface);
  border: 1px solid var(--border); border-left: 3px solid var(--amber, #d98324);
  border-radius: var(--r-inner);
}

/* 질문 만드는 동안의 대기 화면 */
.qa-building { margin-top: 14px; text-align: center; padding: 26px 18px; }
.qa-building b { display: block; font-size: 15px; font-weight: 700; margin-bottom: 6px; }
.qa-building .note { margin: 0 0 16px; }
.qb-bar { height: 4px; border-radius: 999px; background: var(--border); overflow: hidden; }
.qb-bar i { display: block; height: 100%; width: 40%; border-radius: 999px; background: var(--accent);
  animation: qbSlide 1.3s ease-in-out infinite; }
@keyframes qbSlide { 0% { transform: translateX(-100%); } 100% { transform: translateX(250%); } }
@media (prefers-reduced-motion: reduce) { .qb-bar i { animation: none; width: 100%; } }

.msg.enter { animation: msgIn .32s var(--ease) both; }
@keyframes msgIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

@media (max-width: 640px) {
  .msg-bubble { max-width: 88%; }
  .trap-choices { grid-template-columns: 1fr; }
  .persona-card { flex-wrap: wrap; }
  .pc-pass { width: 100%; margin-left: 58px; text-align: left; }
}
@media (prefers-reduced-motion: reduce) {
  .msg.enter { animation: none; }
  .typing-dots i, .cap-live::before { animation: none; }
}

/* ── 서비스 정보 ── */
/* 제목 아래 한 줄 — 이 화면이 왜 있는지 먼저 말한다 */
.about-lead {
  margin: -14px 0 22px; max-width: 62ch;
  font-size: 15px; line-height: 1.65; color: var(--text-2);
}
.about-sec { margin-bottom: 16px; }
.about-sec p.lead { font-size: 14px; color: var(--text-2); margin-bottom: 14px; }
table.plain { width: 100%; border-collapse: collapse; font-size: 14px; }
table.plain th { text-align: left; color: var(--text-3); font-weight: 500; font-size: 13px; padding: 10px; border-bottom: 1px solid var(--border); }
table.plain td { padding: 12px 10px; border-bottom: 1px solid var(--fill); vertical-align: top; }
table.plain tr:last-child td { border-bottom: 0; }
/* 원칙·정책 — 문장 앞의 굵은 한 마디가 결론이고 뒤가 부연이다.
   불릿 점을 지웠다. 세 줄짜리 목록에서 점은 정보를 더하지 않는다.
   화면이 칙칙해 보이던 건 색이 없어서가 아니라 먹이 다 같은 세기였기 때문이다 —
   결론은 진한 먹(--text)으로 올리고 부연만 흐리게 두면 위계가 산다.
   초록은 CTA 와 판정에만 쓴다 (design_improvement/06 §1) */
.principles { padding: 0; margin: 0; list-style: none; }
.principles li {
  padding: 12px 0; font-size: 13.5px; line-height: 1.65; color: var(--text-3);
}
.principles li + li { border-top: 1px solid var(--fill); }
.principles li b {
  display: block; margin-bottom: 2px;
  color: var(--text); font-weight: var(--w-bold); font-size: 14.5px; letter-spacing: -.2px;
}

/* 분석 파이프라인 8단계 — 번호 · 하는 일 · 쓰는 기술. 상태 라벨은 두지 않는다.
   번호를 세로선으로 이어 여덟 개가 한 흐름으로 읽히게 한다. 회색 알약 여덟 개가
   따로 떠 있으면 목록이지 과정이 아니다 */
.about-steps { padding: 0; margin: 0; list-style: none; }
.about-steps li {
  position: relative; display: flex; gap: 14px;
  padding: 12px 0; align-items: flex-start;
}
.about-steps li + li { border-top: 1px solid var(--fill); }
/* 번호끼리 잇는 실선. 첫 줄 위와 마지막 줄 아래로는 넘기지 않는다 */
.about-steps li::before {
  content: ''; position: absolute; left: 11px; top: 0; bottom: 0;
  width: 1px; background: var(--border);
}
.about-steps li:first-child::before { top: 14px; }
.about-steps li:last-child::before { bottom: calc(100% - 26px); }
.about-steps li > i {
  position: relative; z-index: 1;
  flex: none; width: 23px; height: 23px; margin-top: 1px;
  border-radius: var(--r-dot); background: var(--surface);
  border: 1px solid var(--border); color: var(--text-2);
  font-size: 12px; font-weight: var(--w-bold); font-style: normal;
  font-variant-numeric: tabular-nums;
  display: flex; align-items: center; justify-content: center;
}
.about-steps li > div { min-width: 0; padding-top: 1px; }
.about-steps p {
  margin: 0; font-size: 14.5px; line-height: 1.5;
  color: var(--text); font-weight: var(--w-med); letter-spacing: -.2px;
}
.about-steps span { display: block; margin-top: 4px; font-size: 12.5px; color: var(--text-3); }

/* 이 화면의 유일한 초록. 여기까지 읽은 사람에게 다음 행동을 준다 —
   설명만 있고 나갈 곳이 없던 막다른 화면이었다 */
.about-cta {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  margin-bottom: 16px; padding: 18px 22px;
  border: 1px solid var(--border); border-radius: var(--r-card);
  background: var(--paper); box-shadow: var(--shadow-panel);
}
.about-cta p { margin: 0; font-size: 15px; font-weight: var(--w-med); color: var(--text); }

/* ── 반응형 ── */
@media (max-width: 900px) {
  .judge-grid { grid-template-columns: 1fr; }
  .rec-grid { grid-template-columns: 1fr; }
  .thumbs { grid-template-columns: repeat(2, 1fr); }
  .hero-card { flex-direction: column; align-items: flex-start; }
  .stat-row { grid-template-columns: 1fr; }
  .slidethumb-grid { grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); }
}

/* 실제 발표자료 뷰어 */
.viewer-stage { margin: 0; padding: 0; min-height: 0; aspect-ratio: 16 / 9; background: #111; border-radius: 0; }
.viewer-stage img { display: block; width: 100%; height: 100%; object-fit: contain; background: #fff; }
.viewer-stage.has-pdf {
  background: #1a1a1a;
  overflow: auto;
  display: flex;
  align-items: center;
  justify-content: center;
}
.slide-pdf-canvas {
  display: block;
  max-width: 100%;
  height: auto;
  background: #fff;
}
.resume-row {
  display: flex; flex-direction: column; gap: 10px; margin-bottom: 16px;
}
.resume-row .resume-card { margin: 0; }
.pipe-inspect { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--line, var(--border)); }
.pipe-h { margin: 0 0 6px; font-size: 15px; font-weight: 700; display: flex; align-items: center; gap: 8px; }
.pipe-status {
  display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 999px;
  font-size: 11px; font-weight: 600;
}
.pipe-status.run { background: var(--brand-weak); color: var(--brand); }
.pipe-status.ok { background: var(--ok-bg); color: var(--ok); }
.pipe-status.err { background: var(--no-bg); color: var(--no); }
.pipe-loading { margin-top: 10px; padding: 12px; border-radius: var(--r-print); background: var(--fill); border: 1px dashed var(--border); }
.pipe-loading .progress { margin-top: 0; margin-bottom: 10px; }

/* 기다리는 동안 얹는 층. 아래 진행률·경과 초가 주인공이라 캐릭터는 작게 둔다
   (docs/design_improvement/03_components.md §6) */
.pipe-bird-row { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.pipe-bird-row .ch-chick { width: 44px; display: block; cursor: default; }
.pipe-bird-line { font-size: 13px; font-weight: 600; color: var(--text-2); }

/* 빈 화면 — 캐릭터 한 마리 + 해요체 한 줄 + 다음 행동 */
.empty-card .empty-bird { display: block; margin-bottom: 10px; }
.empty-card .empty-bird .ch-chick { width: 72px; display: block; cursor: default; }
.pipe-phase { font-weight: 600; color: var(--text); }
.pipe-detail { color: var(--text-2); }
.pipe-block { margin: 12px 0; border: 1px solid var(--line, var(--border)); border-radius: var(--r-print); padding: 10px 12px; background: #fafbfc; }
.pipe-block summary { cursor: pointer; font-weight: 600; font-size: 14px; }
.pipe-table { width: 100%; border-collapse: collapse; font-size: 13px; margin-top: 8px; }
.pipe-table th, .pipe-table td { text-align: left; padding: 6px 8px; border-bottom: 1px solid var(--border); }
.pipe-table th { color: var(--text-3); font-weight: 500; }
.pipe-uilog { margin: 8px 0 0; padding-left: 18px; font-size: 13px; line-height: 1.5; }
.pipe-uilog .re { color: var(--no); }
.pipe-speech { margin-top: 10px; padding: 10px 12px; border-radius: var(--r-ctl); background: #fff; border: 1px solid var(--border); }
.pipe-speech header { font-size: 12px; color: var(--text-3); margin-bottom: 6px; }
.pipe-speech p { margin: 0; font-size: 14px; line-height: 1.5; white-space: pre-wrap; }
.pipe-map { margin-top: 8px; display: flex; flex-direction: column; gap: 10px; }
.pipe-map-lead { margin: 0 0 4px; font-size: 13px; color: var(--text-2); }
.pipe-map-row {
  display: grid;
  grid-template-columns: minmax(140px, 38%) 1fr;
  gap: 12px;
  padding: 10px;
  border-radius: var(--r-print);
  background: #fff;
  border: 1px solid var(--border);
  align-items: stretch;
}
.pipe-map-row.is-empty { opacity: .72; }
.pipe-map-slide { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.pipe-map-thumb {
  border-radius: var(--r-ctl); overflow: hidden; background: var(--fill);
  border: 1px solid var(--border); aspect-ratio: 16 / 9;
}
.pipe-map-img, .pipe-map-canvas { display: block; width: 100%; height: 100%; object-fit: cover; }
.pipe-map-ph {
  display: flex; align-items: center; justify-content: center;
  height: 100%; min-height: 72px; font-weight: 700; color: var(--text-3); font-size: 22px;
}
.pipe-map-meta { min-width: 0; }
.pipe-map-title {
  font-size: 13px; font-weight: 600; color: var(--text);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.pipe-map-title b { color: var(--brand); margin-right: 4px; }
.pipe-map-preview {
  margin: 4px 0 0; font-size: 12px; line-height: 1.4; color: var(--text-3);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.pipe-map-speech { min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.pipe-map-speech header { font-size: 12px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.pipe-map-speech p { margin: 0; font-size: 14px; line-height: 1.55; white-space: pre-wrap; color: var(--text); }
.pipe-map-speech p.empty { color: var(--text-3); font-style: italic; }
@media (max-width: 640px) {
  .pipe-map-row { grid-template-columns: 1fr; }
}
.pipe-full { margin-top: 10px; font-size: 13px; }
.pipe-concepts { margin: 8px 0 0; padding-left: 18px; font-size: 13px; }
.pipe-concepts li { margin-bottom: 6px; }
.pipe-concepts span { display: block; color: var(--text-3); }
.flow-save { display: flex; align-items: center; gap: 10px; }
.table-wrap { overflow-x: auto; }
.slide-doc-wrap { width: 100%; height: 100%; overflow: auto; background: var(--fill); }
.slide-doc-card {
  box-sizing: border-box;
  min-height: 100%;
  margin: 0 auto;
  padding: 28px 36px 36px;
  background: #fff;
  color: var(--text);
}
.slide-doc-card header {
  display: flex; align-items: baseline; gap: 12px;
  margin-bottom: 16px; padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}
.slide-doc-no {
  font-size: 15px; font-weight: 600; color: var(--text-3);
  font-variant-numeric: tabular-nums;
}
.slide-doc-card h2 {
  margin: 0; font-size: 28px; font-weight: 700; letter-spacing: -.3px; line-height: 1.3;
}
.slide-doc-body { font-size: 16px; line-height: 1.55; color: #333d4b; }
.slide-doc-body p { margin: 0 0 10px; }
.slide-doc-empty { color: var(--text-3); }
.slide-film-text {
  display: flex; gap: 8px; overflow-x: auto; padding: 10px 12px;
}
.slide-film-text button {
  flex: none; width: 132px; height: 74px;
  border: 1px solid var(--border); border-radius: var(--r-ctl);
  background: #fff; padding: 8px 10px;
  display: flex; flex-direction: column; gap: 4px;
  text-align: left; cursor: pointer;
}
.slide-film-text button.on { border-color: var(--brand); box-shadow: 0 0 0 2px rgba(3, 178, 108, .25); }
.slide-film-text .film-no { font-size: 11px; font-weight: 600; color: var(--text-3); }
.slide-film-text .film-title {
  font-size: 12px; font-weight: 500; color: var(--text);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.viewer-caption { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 16px 0; }
.viewer-caption strong { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; }
.viewer-caption small { color: var(--text-3); flex: none; }
.slide-film { display: flex; gap: 7px; overflow-x: auto; padding: 0 16px 16px; scrollbar-width: thin; }
.slide-film button { flex: 0 0 92px; padding: 2px; border: 2px solid transparent; border-radius: 7px; background: #fff; cursor: pointer; }
.slide-film button.on { border-color: var(--accent); }
.slide-film img { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; border-radius: 4px; }

/* 원본 PDF 를 올린 리허설 필름 — 번호 대신 실제 페이지를 보여준다 */
.slide-film-deck { display: flex; gap: 8px; overflow-x: auto; padding: 10px 12px; }
.slide-film-deck button {
  flex: none; width: 132px; padding: 0; overflow: hidden;
  border: 1px solid var(--border); border-radius: var(--r-ctl);
  background: #fff; display: flex; flex-direction: column;
  text-align: left; cursor: pointer;
}
.slide-film-deck button.on { border-color: var(--brand); box-shadow: 0 0 0 2px rgba(3, 178, 108, .25); }
.slide-film-deck .film-thumb {
  display: block; width: 100%; aspect-ratio: 16 / 9;
  object-fit: contain; border-radius: 0; background: var(--fill);
}
.slide-film-deck .film-cap { display: flex; align-items: baseline; gap: 5px; min-width: 0; padding: 5px 7px; }
.slide-film-deck .film-no {
  flex: none; font-size: 11px; font-weight: 600; color: var(--text-3);
  font-variant-numeric: tabular-nums;
}
.slide-film-deck .film-title {
  flex: 1; min-width: 0; font-size: 11px; font-weight: 500; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* 업로드 결과의 실제 슬라이드 썸네일 */
.thumbs { grid-template-columns: repeat(4, 1fr); max-height: 470px; overflow-y: auto; padding-right: 4px; }
.thumb { aspect-ratio: auto; padding: 0; overflow: hidden; border: 1px solid var(--border); background: var(--surface); display: block; }
.thumb img { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }
.thumb span { display: flex; gap: 6px; align-items: baseline; padding: 8px 9px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.thumb span b { color: var(--text-3); }
.thumb.warn { border: 2px solid var(--mid); background: var(--mid-bg); }

/* Q&A에서 최종 분석으로 이어지는 변화 */
.judge-card .bubble { margin-bottom: 12px; }
.judge-card > p { margin-top: 12px; }
.qa-end-result { border: 1px solid var(--accent); }
.qa-change { display: flex; align-items: baseline; gap: 10px; margin-bottom: 18px; }
.qa-change span { font-size: 13px; color: var(--text-3); }
.qa-change strong { font-size: 28px; color: var(--text); font-variant-numeric: tabular-nums; }
.qa-change strong:last-child { color: var(--accent); }
.qa-change i { font-style: normal; color: var(--accent); font-weight: 700; }
.qa-end-result .txt h3 { font-size: 18px; }
.qa-end-result .txt p { margin-top: 5px; color: var(--text-2); font-size: 14px; }

/* 최종 분석만 결과 중심의 강한 시각적 강조를 허용 */
.final-label { display: inline-flex; padding: 4px 9px; margin-bottom: 8px; border-radius: 999px; background: var(--accent-weak); color: var(--accent); font-size: 12px; font-weight: 700; }
.final-insight { display: grid; grid-template-columns: auto 28px auto 1fr; align-items: center; gap: 18px; padding: 24px 26px; margin-bottom: 14px; border-radius: var(--r-card); color: var(--text); background: var(--surface); box-shadow: var(--shadow); animation: finalRise .45s ease both; }
.final-insight > div { display: flex; flex-direction: column; }
.final-insight span { font-size: 12px; font-weight: 500; color: var(--text-3); }
.final-insight strong { display: flex; align-items: baseline; gap: 8px; font-size: 26px; font-weight: 700; line-height: 1.1; color: var(--text-2); font-variant-numeric: tabular-nums; }
.final-insight .after strong { color: var(--accent); }
.final-insight .fi-delta { font-style: normal; font-size: 13px; font-weight: 700; color: var(--accent); background: var(--accent-weak); padding: 3px 9px; border-radius: 999px; }
.final-insight > i { font-style: normal; font-size: 20px; color: var(--text-3); }
.final-insight p { padding-left: 20px; border-left: 1px solid var(--border); font-size: 14px; color: var(--text-2); }
.final-insight p b, .final-insight p small { display: block; }
.final-insight p b { color: var(--accent-strong); font-size: 13px; margin-bottom: 2px; }
.final-insight p small { color: var(--text-3); margin-top: 4px; }
.final-score-card { border: 1px solid var(--mint-line); }
@keyframes finalRise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* ── 코칭 마무리 세리머니 ── */
.cere-head { margin-bottom: 20px; }
.cere-eyebrow { display: inline-block; margin-bottom: 6px; font-size: 12px; font-weight: 700; color: var(--accent); }
.cere-card { animation: cereRise .5s var(--ease) both; }
.cere-card.c1 { animation-delay: .05s; }
.cere-card.c2 { animation-delay: .45s; }
.cere-card.c3 { animation-delay: .9s; }
@keyframes cereRise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
.cere-label { display: block; font-size: 12px; font-weight: 700; color: var(--text-3); margin-bottom: 14px; }

/* 카드1 — 오늘 만든 문장 */
.cere-card.c1 { background: var(--brand-weak); border: 1px solid var(--mint-line); }
.cere-diff { }
.cd-before { font-size: 15px; color: var(--text-3); }
.cd-before span { display: inline-block; margin-right: 8px; padding: 2px 8px; border-radius: 6px; background: var(--fill); font-size: 12px; font-weight: 600; color: var(--text-3); vertical-align: middle; }
.cd-arrow { display: block; margin: 12px 0 10px; font-size: 12px; font-weight: 700; color: var(--accent); }
.cd-after { font-size: 21px; font-weight: 700; line-height: 1.5; letter-spacing: -.3px; color: var(--text); }
.cere-hint { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border); font-size: 13px; font-weight: 500; color: var(--accent-strong); }

/* 카드2 — 개념 점등 */
.cere-row-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.cere-row-head .cere-label { margin-bottom: 0; }
.cere-count { font-size: 22px; font-weight: 700; color: var(--accent); }
.cere-count i { font-style: normal; color: var(--text-3); margin: 0 4px; }
.cere-concepts { list-style: none; padding: 0; margin: 8px 0 0; }
.cere-concepts li { display: flex; align-items: center; gap: 10px; padding: 9px 0; font-size: 15px; }
.cere-concepts li + li { border-top: 1px solid var(--fill); }
.cere-concepts li i { width: 22px; height: 22px; flex: none; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-style: normal; font-size: 12px; font-weight: 700; }
.cere-concepts li.pre i { background: var(--fill); color: var(--text-3); }
.cere-concepts li.pre span { color: var(--text-2); }
.cere-concepts li.neo { animation: conceptPop .4s var(--ease) both; }
.cere-concepts li.neo i { background: var(--green); color: #fff; }
.cere-concepts li.neo span { font-weight: 600; }
.cere-concepts li.neo em { margin-left: auto; font-style: normal; font-size: 12px; font-weight: 700; color: var(--ok); background: var(--green-bg); padding: 3px 9px; border-radius: 999px; }
@keyframes conceptPop { from { opacity: 0; transform: translateX(-6px); } to { opacity: 1; transform: none; } }
.cere-sub { margin-top: 14px; font-size: 13px; font-weight: 500; }
.cere-sub.good { color: var(--ok); }
.cere-sub.warn { color: var(--no); }

/* 카드3 — 보상 + 다음 목표 */
.cere-reward { display: flex; align-items: center; gap: 20px; }
.cr-xp { flex: none; display: flex; flex-direction: column; gap: 3px; padding-right: 20px; border-right: 1px solid var(--border); }
.cr-xp span { font-size: 12px; font-weight: 600; color: var(--text-3); }
.cr-amount { display: flex; align-items: baseline; gap: 1px; color: var(--accent); }
.cr-amount b { font-size: 20px; font-weight: 700; }
.cr-amount strong { font-size: 30px; font-weight: 700; }
.cr-facts { display: flex; flex-wrap: wrap; gap: 8px; }
.cr-facts span { font-size: 12px; font-weight: 600; color: var(--text-2); background: var(--fill); padding: 5px 10px; border-radius: 999px; }
.cere-next { display: flex; align-items: center; gap: 10px; margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--border); }
.cere-next span { font-size: 12px; font-weight: 700; color: var(--text-3); }
.cere-next b { font-size: 15px; font-weight: 600; }
.cere-actions { display: flex; align-items: center; gap: 10px; margin-top: 20px; }

/* ── 리포트: 오늘 만든 문장 스트립 ── */
.trophy-strip { width: 100%; text-align: left; border: 1px solid var(--mint-line); background: var(--brand-weak); cursor: pointer; transition: transform .12s var(--ease), box-shadow .12s ease; }
.trophy-strip:hover { transform: translateY(-1px); box-shadow: 0 6px 18px rgba(24, 24, 27, .08); }
.ts-label { display: block; font-size: 12px; font-weight: 700; color: var(--accent); margin-bottom: 8px; }
.ts-quote { font-size: 18px; font-weight: 700; line-height: 1.5; letter-spacing: -.2px; }
.ts-go { display: inline-block; margin-top: 12px; font-style: normal; font-size: 13px; font-weight: 600; color: var(--text-3); }

/* ── 리포트: 슬라이드 덱 뷰 ── */
.deck-main { display: grid; grid-template-columns: 1.25fr 1fr; gap: 18px; align-items: start; }
.deck-stage { margin: 0; border: 2px solid var(--border); border-radius: var(--r-print); overflow: hidden; }
.deck-stage img, .deck-stage canvas { width: 100%; height: auto; display: block; }
.deck-stage figcaption { display: flex; align-items: center; gap: 8px; padding: 9px 12px; font-size: 12px; font-weight: 500; color: var(--text-2); background: var(--fill); }
.deck-stage figcaption .num { color: var(--text-3); }
.deck-stage figcaption em { margin-left: auto; font-style: normal; font-weight: 700; }
.deck-stage.st-ok { border-color: var(--ok); } .deck-stage.st-ok em { color: var(--ok); }
.deck-stage.st-mid { border-color: var(--mid); } .deck-stage.st-mid em { color: var(--mid); }
.deck-stage.st-no { border-color: var(--no); } .deck-stage.st-no em { color: var(--no); }
.deck-stage.st-ct { border-color: var(--ct); } .deck-stage.st-ct em { color: var(--ct); }
.deck-stage.st-om { border-color: var(--text-3); } .deck-stage.st-om em { color: var(--om); }
.deck-stage.st-none { border-color: var(--border); } .deck-stage.st-none em { color: var(--text-3); }
.deck-stage.st-na { border-color: var(--border); } .deck-stage.st-na em { color: var(--text-3); }
.deck-panel .dp-top { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.deck-panel .dp-top b { font-size: 15px; font-weight: 700; }
.dp-fix { margin-top: 12px; padding: 12px 14px; border-radius: var(--r-print); background: var(--accent-weak); }
.dp-fix b { display: block; font-size: 12px; font-weight: 700; color: var(--accent); margin-bottom: 3px; }
.dp-fix p { font-size: 14px; color: var(--text); }
.deck-panel .btn { margin-top: 12px; }
.dp-none { font-size: 14px; color: var(--text-3); }
.dp-moments { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: 8px; }
/* align-items:center 였다. 라벨이 두 줄로 접히면 시각·칩이 두 줄의 **가운데**에
   떠서, 시작점이 어긋난 것처럼 보였다 (좁은 칸에서 늘 접힌다).
   격자로 자리를 고정한다: 시각·칩은 폭이 정해진 칸, 라벨은 남는 칸 전부.
   셋 다 첫 줄에 맞춰 서고(start), line-height 를 맞춰 밑줄이 같이 간다. */
.dp-moment {
  display: grid; grid-template-columns: auto auto minmax(0, 1fr);
  align-items: start; gap: 8px;
  font-size: 13px; line-height: 1.55; color: var(--text-2);
}
.dp-moment time { color: var(--text-3); font-weight: 600; line-height: inherit; }
/* chip 은 제 line-height 를 들고 오므로 첫 줄에 맞춰 세운다 */
.dp-moment .chip { align-self: start; }
/* 안내문 속 키 표시. 장식이 아니라 «이 키를 누르면 된다» 는 말이라
   본문보다 작게 두고 면만 옅게 깐다 */
.section-title .soft kbd {
  display: inline-block; min-width: 17px; margin: 0 1px; padding: 0 4px;
  border: 1px solid var(--border); border-radius: 5px; background: var(--fill);
  font-family: inherit; font-size: 11px; font-weight: 600; line-height: 1.6;
  color: var(--text-2); text-align: center;
}
/* ── 시간 분배: 이상 vs 실제 가로 100% 막대 ────────────────────────────
   장별 막대 33개를 두 줄로 줄인 자리다 (app.js timeSplitHtml). 같은 구간이
   같은 색이라 두 줄의 「같은 색 폭 차이」가 곧 결론이다. */
.tsplit-legend { display: flex; flex-wrap: wrap; gap: 7px 14px; margin-bottom: 16px; }
.tsplit-legend span { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--text-2); }
.tsplit-legend i { width: 9px; height: 9px; border-radius: 3px; flex: none; box-shadow: inset 0 0 0 1px rgba(0,0,0,.06); }
.tsplit-legend small {
  margin-left: 1px; padding: 1px 5px; border-radius: var(--r-pill);
  background: var(--fill); color: var(--text-3); font-size: 9px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.tsplit-legend small.is-more { background: var(--mid-bg); color: var(--mid); }
.tsplit-legend small.is-less { background: var(--brand-weak); color: var(--brand-strong); }
.tsplit-row { display: grid; grid-template-columns: 78px minmax(0, 1fr); align-items: center; gap: 12px; margin-top: 10px; }
.tsplit-lb { font-size: 12px; font-weight: 600; color: var(--text-3); word-break: keep-all; }
/* 내가 한 발표가 주인공이다 — 이상적인 배분은 대조군이라 한 단계 낮춘다 */
.tsplit-row.is-mine .tsplit-lb { color: var(--text); font-weight: 700; }
.tsplit-bar { display: flex; height: 30px; border-radius: 9px; overflow: hidden; background: var(--fill); box-shadow: inset 0 0 0 1px rgba(6, 48, 39, .05); }
/* 48px — 퍼센트와 실제 시간 두 줄이 들어가는 최소 높이이자, 위 30px 대조군보다
   확실히 무거워 보이는 높이다. 실제 데이터가 주인공이라는 걸 크기로 말한다 */
.tsplit-row.is-mine .tsplit-bar { height: 48px; border-radius: 11px; box-shadow: 0 5px 14px rgba(6, 48, 39, .10), inset 0 0 0 1px rgba(255,255,255,.18); }
.tsplit-seg {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 1px; min-width: 0; background: var(--c);
  transition: width .7s cubic-bezier(.22, .61, .36, 1);
}

/* 글자색은 칸이 들고 온다 — 옅은 칸에 흰 글씨를 얹으면 %가 안 읽힌다 */
.tsplit-seg b { font-size: 11px; font-weight: 700; color: var(--tc, #fff); letter-spacing: -.02em; }
/* 실제 시간. 퍼센트보다 한 단계 작고 옅다 — 둘이 같은 무게면 어느 쪽이 답인지 흐려진다 */
.tsplit-seg i {
  font-size: 10px; font-style: normal; font-weight: 600; letter-spacing: -.02em;
  color: var(--tc, #fff); opacity: .78; font-variant-numeric: tabular-nums;
}
/* 단색 계조라 칸 경계가 인접색끼리 붙어 보인다. 머리카락만큼만 띄운다 */
.tsplit-seg + .tsplit-seg { box-shadow: inset 1px 0 0 rgba(255, 255, 255, .5); }
.tsplit-row.is-mine .tsplit-seg b { font-size: 12px; }
.tsplit-time {
  margin-top: 1px; color: var(--tc, #fff); font-size: 10px; font-weight: 650;
  line-height: 1.05; letter-spacing: .01em; font-variant-numeric: tabular-nums;
  opacity: .88;
}
.tsplit-total {
  display: grid; grid-template-columns: 78px minmax(0, 1fr); gap: 12px;
  align-items: center; margin-top: 14px; padding-top: 13px; border-top: 1px solid var(--line);
}
.tsplit-total-copy { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.tsplit-total-copy span { color: var(--text-3); font-size: 11px; font-weight: 600; }
.tsplit-total-copy b { color: var(--text); font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums; }
.tsplit-delta { margin-left: 5px; color: var(--mid); font-style: normal; }
.tsplit-delta.is-short { color: var(--brand); }
.tsplit-total-track {
  position: relative; height: 7px; margin-top: 7px; overflow: visible;
  border-radius: 999px; background: var(--fill);
}
.tsplit-total-fill { display: block; height: 100%; border-radius: inherit; background: linear-gradient(90deg, var(--navy), #4fa982); }
.tsplit-target-mark { position: absolute; top: -4px; width: 2px; height: 15px; border-radius: 2px; background: var(--text); transform: translateX(-1px); }
@media (prefers-reduced-motion: reduce) { .tsplit-seg { transition: none; } }
/* 범례의 «몇 %p 어긋났나» 배지. 숫자는 tabular 로 세로줄을 맞춘다 */
.tsplit-legend em {
  font-style: normal; font-weight: 700; font-size: 11px; color: var(--text-3);
  font-variant-numeric: tabular-nums; letter-spacing: -.02em;
}
.tsplit-say { margin-top: 14px; }
.tsplit-say b { color: var(--text); font-weight: 700; }

/* ── 총 발표 길이 (두 100% 막대가 말하지 못하는 총량) ── */
.tsplit-total { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border); }
.tst-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.tst-lb { font-size: 12px; font-weight: 600; color: var(--text-3); }
.tst-nums { font-size: 13px; color: var(--text-2); font-variant-numeric: tabular-nums; }
.tst-nums b { color: var(--text); font-weight: 700; }
.tst-nums em { font-style: normal; font-weight: 700; margin-left: 8px; }
.tst-nums em.over { color: var(--mid); }
.tst-nums em.under { color: var(--text-2); }
.tst-track {
  position: relative; height: 10px; margin-top: 9px;
  border-radius: var(--r-pill); background: var(--fill); overflow: hidden;
}
.tst-fill { display: block; height: 100%; border-radius: var(--r-pill); background: var(--brand); }
/* 목표 위치 눈금. 채움 위에 얹어야 «넘었나 못 미쳤나» 가 한눈에 읽힌다 */
.tst-mark {
  position: absolute; top: -2px; bottom: -2px; width: 2px;
  background: var(--text); border-radius: 1px; transform: translateX(-1px);
}
@media (prefers-reduced-motion: reduce) { .tst-fill { transition: none; } }
.deck-film { display: flex; gap: 8px; overflow-x: auto; padding: 16px 2px 6px; scrollbar-width: thin; }
/* 필름은 키보드로 드나드는 자리다 — 초점이 어디 있는지 보여야 한다 */
.deck-film .slidethumb:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.deck-film .slidethumb { width: 80px; flex: none; }
.slidethumb.on { box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--accent); }

@media (max-width: 720px) {
  .deck-main { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  .cere-reward { flex-direction: column; align-items: flex-start; gap: 14px; }
  .cr-xp { padding-right: 0; border-right: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .cere-card, .cere-concepts li.neo { animation: none; }
}

/* 목록의 과거 발표별 맞춤 리포트 */
.history-head .back-link { display: block; width: max-content; margin-bottom: 14px; color: var(--text-3); font-size: 13px; font-weight: 600; }
.history-head .back-link:hover { color: var(--accent); }
.profile-score { display: grid; grid-template-columns: 150px 1fr; gap: 30px; align-items: center; border: 1px solid var(--mint-line); }
.profile-score-main { display: flex; flex-wrap: wrap; align-items: baseline; align-content: center; min-height: 126px; padding-right: 24px; border-right: 1px solid var(--border); }
.profile-score-main strong { font-size: 30px; line-height: 1; }
.profile-score-main > span { margin-left: 3px; color: var(--text-3); font-weight: 600; }
.profile-score-main small { display: block; flex-basis: 100%; margin-top: 10px; color: var(--green); font-size: 12px; font-weight: 700; }
.profile-score-body h2 { margin-bottom: 18px; font-size: 18px; line-height: 1.55; }
.history-section-title { margin: 28px 0 12px; }
.history-evidence { display: grid; grid-template-columns: repeat(3,1fr); gap: 14px; }
.history-evidence-card { margin-top: 0!important; padding: 20px; }
.history-evidence-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 12px; }
.history-evidence-top > span { color: var(--text-3); font-size: 12px; font-weight: 500; }
.history-evidence-card h3 { margin-bottom: 10px; font-size: 16px; }
.history-evidence-card blockquote { margin: 0 0 12px; padding: 10px 12px; border-left: 2px solid var(--accent); background: var(--fill); color: var(--text-2); font-size: 13px; }
.history-evidence-card p { color: var(--text-2); font-size: 13px; }
.history-priorities { margin-top: 14px; }
.history-priorities ol { margin: 0; padding-left: 22px; }
.history-priorities li { padding: 7px 0 7px 6px; font-size: 14px; }

/* 장식성 페이지·프로그레스·파형 애니메이션은 MVP에서 사용하지 않아요 */
#app.in > *, .progress i, .rec-live::before, .meter i, .checklist li.doing i, .judge-card { animation: none; }
.fill-bar i { width: var(--bar-width, 0); }

@media (max-width: 900px) {
  .thumbs { grid-template-columns: repeat(3, 1fr); }
  .final-insight { grid-template-columns: 1fr 24px 1fr; }
  .final-insight p { grid-column: 1 / -1; border-left: 0; border-top: 1px solid var(--border); padding: 14px 0 0; }
  .history-evidence { grid-template-columns: 1fr; }
  .profile-score { grid-template-columns: 1fr; }
  .profile-score-main { min-height: 0; padding: 0 0 18px; border-right: 0; border-bottom: 1px solid var(--border); }
}
@media (max-width: 680px) {
  .thumbs { grid-template-columns: repeat(2, 1fr); }
  .slide-film button { flex-basis: 74px; }
  .steps span, .steps button { justify-content: center; padding: 9px 4px; font-size: 0; }
  .steps span i, .steps button i { margin: 0; }
  .time-presets { grid-template-columns: repeat(3, 1fr); }
  .time-detail { align-items: flex-start; flex-direction: column; }
  .rehearsal-head { align-items: flex-start; flex-direction: column; gap: 4px; }
  .rehearsal-head > p { display: none; }
  .stage-nav { width: 36px; height: 58px; opacity: .7; }
  .rehearsal-control { align-items: stretch; flex-direction: column; }
  .rehearsal-control.is-live { left: 12px; right: 12px; width: auto; max-width: none; transform: none; }
  .rehearsal-control > .btn { width: 100%; margin-left: 0; }
  .rec-log-fold .trans-log { position: static; width: 100%; box-shadow: none; }
  .qa-top { align-items: stretch; flex-direction: column; }
  .aud-select { justify-content: space-between; }
  .coach-question .q-bubble { font-size: 16px; }
  .qa-answer { align-items: stretch; flex-direction: column; }
  .qa-answer .btn { width: 100%; }
  .resume-card { padding-right: 24px; }
  .resume-card i { position: static; display: block; margin-top: 12px; transform: none; }
}

/* ── QA 시간 모드 선택 (질문 준비 완료 화면) ── */
.qa-mode-pick { margin-top: 22px; display: flex; flex-direction: column; gap: 12px; }
/* 제목과 설명을 한 줄에 나란히 두면 어디까지가 제목인지 안 읽힌다. 위아래로 쌓는다 */
.qm-head { display: flex; flex-direction: column; gap: 2px; margin-bottom: 2px; }
.qm-head b { font-weight: 700; }
.qm-head span { font-size: 13px; color: var(--text-3); }
.qa-modes { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.qa-mode {
  font-family: inherit; text-align: left; cursor: pointer;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-btn);
  padding: 11px 13px; display: flex; flex-direction: column; gap: 3px;
  transition: border-color .15s, background .15s;
}
.qa-mode b { font-size: 14px; font-weight: 700; }
.qa-mode span { font-size: 12px; color: var(--text-2); line-height: 1.45; }
.qa-mode em { font-style: normal; font-size: 12px; font-weight: 600; color: var(--text-3); }
.qa-mode.on { border-color: var(--accent); background: var(--accent-weak); }
.qa-mode.on em { color: var(--accent-strong); }
.qa-mode:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.qa-mode-pick .btn { align-self: flex-start; }
@media (max-width: 720px) { .qa-modes { grid-template-columns: 1fr; } }

/* ── 홈: 질문 코칭 바로 시작 카드 ── */
.qa-quick { display: flex; flex-direction: column; gap: 12px; padding: 18px 20px; }
/* 왼쪽 아래 구석의 작은 버튼이 이 화면의 유일한 다음 행동이었다.
   카드 폭을 다 쓰는 CTA 로 세운다 (TDS BottomCTA) */
.qa-quick .btn { align-self: stretch; margin-top: 4px; }

/* ── 실전 모드 패널 + 입력 ── */
.qa-live-body { display: flex; flex-direction: column; gap: 10px; }
.ql-row { display: flex; align-items: center; gap: 12px; font-size: 13px; }
.ql-row > span { flex: 0 0 150px; font-weight: 600; color: var(--text-2); }
.ql-row input[type="text"] {
  flex: 1; font: inherit; font-size: 13px; padding: 7px 10px;
  border: 1px solid var(--border); border-radius: var(--r-btn); color: var(--text);
}
.ql-row input[type="text"]:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.qa-live-input { display: flex; flex-direction: column; gap: 10px; padding: 14px 16px; margin-top: 14px; }
.qa-live-input textarea {
  font: inherit; font-size: 14px; line-height: 1.6; padding: 10px 12px; resize: vertical;
  border: 1px solid var(--border); border-radius: var(--r-btn); color: var(--text);
}
.qa-live-input textarea:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* 음성 입력 버튼. 아이콘만 두었더니 마이크인 줄 몰라서 이름을 글자로 같이 낸다 */
.qa-live-input .btn-voice { display: inline-flex; align-items: center; gap: 6px; }
.qa-live-input .btn-voice .ic-i { width: 18px; height: 18px; flex: none;
  /* 선 아이콘이다. 선 규칙(.ic-i)이 landing.css 에만 있어서 앱 화면에서는 채움 기본값(검정)으로 칠해져
     마이크가 까만 덩어리로 보였다 (2026-09-28 실험실 사진). 여기서 직접 준다 */
  fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
/* 녹음 중. 색에만 기대지 않는다 — 아이콘이 정지(■)로 바뀌고 이름도 함께 바뀐다 */
.qa-live-input .btn-voice.is-rec { color: var(--red, #d92d20); }
@media (max-width: 720px) { .ql-row { flex-direction: column; align-items: stretch; gap: 4px; } .ql-row > span { flex: none; } }

/* ── 스트림 안 실시간 총평 카드 ── */
.qa-sum {
  align-self: stretch; border: 1px solid var(--border); border-left: 3px solid var(--accent);
  background: var(--surface); border-radius: var(--r-inner); padding: 11px 14px;
}
.qa-sum .qs-eyebrow { display: block; font-size: 12px; font-weight: 700; letter-spacing: .04em; color: var(--accent-strong); margin-bottom: 3px; }
.qa-sum .qs-name { font-size: 13px; font-weight: 700; }
.qa-sum .qs-text { margin: 3px 0 0; font-size: 13px; color: var(--text-2); line-height: 1.55; min-height: 1.4em; }

/* ── 세리머니: 오늘의 총평 ── */
.cere-sums { display: flex; flex-direction: column; gap: 0; margin-top: 10px; }
.qsum-row { border-top: 1px solid var(--border); padding: 10px 0; font-size: 13px; }
.qsum-row:first-child { border-top: none; padding-top: 0; }
.qsum-row b { display: block; font-weight: 700; margin-bottom: 2px; }
.qsum-row p { margin: 0; color: var(--text-2); }

/* ── 실전 질문 대신 데모 질문으로 되돌아갔을 때의 안내 ──
 * 조용히 넘어가면 데모 질문이 내 발표 질문처럼 보인다. 눈에 띄되 막지는 않는다. */
.qa-notice {
  margin: 0 0 12px; padding: 10px 13px; font-size: 13px; line-height: 1.55;
  color: var(--text-2); background: var(--surface);
  border: 1px solid var(--border); border-left: 3px solid var(--amber, #d98324);
  border-radius: var(--r-inner);
}

/* ── 질문 만드는 동안의 대기 화면 ── */
.qa-building { margin-top: 14px; text-align: center; padding: 26px 18px; }
.qa-building b { display: block; font-size: 15px; font-weight: 700; margin-bottom: 6px; }
.qa-building .note { margin: 0 0 16px; }
.qb-bar { height: 4px; border-radius: 999px; background: var(--border); overflow: hidden; }
.qb-bar i { display: block; height: 100%; width: 40%; border-radius: 999px; background: var(--accent);
  animation: qbSlide 1.3s ease-in-out infinite; }
@keyframes qbSlide { 0% { transform: translateX(-100%); } 100% { transform: translateX(250%); } }
@media (prefers-reduced-motion: reduce) { .qb-bar i { animation: none; width: 100%; } }

/* ── 실전 질문 코칭 결과 ──────────────────────────────────────
   예전엔 「0 / 6」 하나에 긴 질문 원문 여섯 줄이었다. 숫자만으로는 뭘 해야
   할지 모르고, 여섯 줄이 다 "…설명해 주시겠어요?" 로 끝나 벽처럼 읽혔다.
   변화를 문장으로 말하고, 상태로 묶고, 행은 TDS ListRow 처럼 누를 수 있게 한다 */
.qres-eyebrow { margin: 0 0 10px; font-size: 12px; font-weight: 700; color: var(--text-3); }
.qres-head { margin: 0; font-size: 22px; font-weight: 700; line-height: 1.45; letter-spacing: -.02em; }
.qres-head b { font-size: 26px; color: var(--brand); }
.qres-head b.qres-redo { color: var(--mid); }
/* 한 일을 먼저 말한 뒤, 숫자 둘을 나란히 놓는다. 「지킨 것」과 「찾은 것」은
   우열이 아니라 둘 다 이번 연습의 결과다 — 같은 크기로 나란히 둔다 */
.qres-stats {
  display: flex; gap: 10px; margin: 16px 0 0;
}
.qres-stats > div {
  flex: 1 1 0; min-width: 0; padding: 14px 16px;
  border: 1px solid var(--border); border-radius: var(--r-inner); background: var(--surface);
}
.qres-stats b {
  display: block; font-size: 28px; line-height: 1.1; color: var(--brand);
  font-weight: var(--w-display); font-variant-numeric: tabular-nums;
}
.qres-stats b.qres-redo { color: var(--mid); }
.qres-stats span { display: block; margin-top: 4px; font-size: 13px; color: var(--text-3); }
/* 네 묶음(스스로·도움·답 보고·넘김)이 다 서면 폰에서는 두 줄로 — 칸 이름이 한 글자씩 끊기지 않게 */
@media (max-width: 520px) {
  .qres-stats { flex-wrap: wrap; }
  .qres-stats > div { flex: 1 1 calc(50% - 5px); }
}

/* 질문을 고르는 동안 이미 손에 쥔 숫자 — 후보 목록이 못 뜰 때 화면을 메운다 */
.qb-facts { display: flex; gap: 10px; margin: 14px 0 0; }
.qb-facts > div {
  flex: 1 1 0; padding: 12px 14px; text-align: center;
  border: 1px solid var(--border); border-radius: var(--r-inner); background: var(--surface);
}
.qb-facts b {
  display: block; font-size: 22px; line-height: 1.15; color: var(--text);
  font-weight: var(--w-bold); font-variant-numeric: tabular-nums;
}
.qb-facts span { display: block; margin-top: 3px; font-size: 12px; color: var(--text-3); }

/* 파싱을 기다리는 동안 브라우저가 직접 연 첫 장 — 서버가 준 게 아니라 여기서 연 것이다 */
.parse-peek {
  display: flex; gap: 16px; align-items: center;
  margin: 16px 0 0; padding: 14px; border-radius: var(--r-inner);
  border: 1px solid var(--border); background: var(--fill);
}
.parse-peek img {
  flex: none; width: 132px; border-radius: 8px; display: block;
  border: 1px solid var(--border); background: var(--surface);
}
.parse-peek > div { min-width: 0; }
.parse-peek b {
  font-size: 26px; font-weight: var(--w-display); color: var(--text);
  font-variant-numeric: tabular-nums;
}
.parse-peek .parse-peek-unit { margin-left: 3px; font-size: 14px; color: var(--text-2); }
.parse-peek p { margin: 6px 0 0; font-size: 12.5px; line-height: 1.55; color: var(--text-3); }

/* 대기 막대에 빛이 한 번씩 지나간다. 흐르는 막대만으로는 「멈춘 건지」가
   구분이 안 되는데, 이 빛이 지나가면 살아 있다는 신호가 된다 */
.progress.indeterminate::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  background: linear-gradient(100deg, transparent 20%, rgba(255, 255, 255, .75) 50%, transparent 80%);
  transform: translateX(-100%);
  animation: cc-shimmer 1.9s ease-in-out infinite;
}
@keyframes cc-shimmer { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) {
  .progress.indeterminate::after { animation: none; opacity: 0; }
}
.qres-sub { margin: 8px 0 0; font-size: 14px; color: var(--text-2); }

.qres-group { margin-top: 22px; }
.qres-gh {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  padding-bottom: 8px; border-bottom: 1px solid var(--border);
}
.qres-gh b { font-size: 15px; font-weight: 700; }
.qres-gh .num { font-size: 15px; font-weight: 700; color: var(--brand); }
.qres-gh small { color: var(--text-3); font-size: 13px; font-weight: 500; }

.qres-row {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 12px 4px; border: 0; border-bottom: 1px solid var(--fill);
  background: none; text-align: left; cursor: pointer; font: inherit; color: inherit;
  min-height: 44px; transition: background .14s ease;
}
.qres-row:hover, .qres-row:focus-visible { background: var(--fill); }
.qres-main { flex: 1; min-width: 0; }
.qres-main b { display: block; font-size: 15px; font-weight: 600; }
.qres-main small { display: block; margin-top: 2px; font-size: 13px; color: var(--text-3); }
.qres-side { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 3px; }
.qres-meta { font-style: normal; font-size: 12px; color: var(--text-3); }
.qres-chev { flex: none; color: var(--text-3); font-size: 20px; }

/* ── 질문 코칭 시간 고르기 — TDS ListRow 3영역 ─────────────────
   예전엔 세 장이 같은 무게의 네모라 무엇이 골라져 있는지 안 보였다.
   left(시간) / contents(무엇을 하는지) / right(범위·선택) 으로 나눈다 */
.qa-mode { display: flex; flex-direction: row; align-items: center; gap: 14px; text-align: left; min-height: 44px; padding: 12px 14px; }
.qm-time {
  flex: none; min-width: 52px; text-align: center;
  font-size: 16px; font-weight: 700; color: var(--text-2); letter-spacing: -.02em;
}
.qa-mode.on .qm-time { color: var(--brand); }
.qm-body { flex: 1; min-width: 0; }
.qm-body b { display: block; font-size: 15px; font-weight: 600; }
.qm-body > span { display: block; margin-top: 2px; font-size: 13px; color: var(--text-3); line-height: 1.5; }
.qm-right { flex: none; display: flex; align-items: center; gap: 10px; }
.qm-right em { font-style: normal; font-size: 12px; font-weight: 500; color: var(--text-3); }
.qm-check {
  width: 20px; height: 20px; border-radius: 50%; display: grid; place-items: center;
  font-style: normal; font-size: 12px; font-weight: 700;
  border: 1.5px solid var(--border); color: transparent;
}
.qa-mode.on .qm-check { background: var(--brand); border-color: var(--brand); color: #fff; }
/* 3열 그리드로는 left/contents/right 가 안 읽힌다. 한 줄에 하나씩 쌓는다 */
.qa-modes { grid-template-columns: 1fr; gap: 8px; }

/* ── 질문 코치 학습 루프 ──────────────────────────────────────
   대화창의 기능 목록을 보여 주는 대신, 지금 무엇을 배우는지 한눈에 보이게 한다. */
.qa-loop-card {
  padding: 24px; border-radius: 24px; background: var(--surface);
  box-shadow: 0 10px 34px rgba(20, 33, 61, .08);
}
/* 위 퀘스트 목록이 자리와 숫자를 다 말하게 된 뒤로 이 카드는 «지금 이 질문을
   어떻게 푸는가» 만 맡는다. 제목이 더는 화면의 주인공이 아니라 한 단 낮췄다.
   .qa-loop-kicker·.qa-loop-score 는 그 목록에 흡수돼 마크업에서 사라졌다. */
.qa-loop-card h2 { margin: 0; font-size: 17px; line-height: 1.45; letter-spacing: -.02em; word-break: keep-all; }
.qa-loop-card h2 b { color: var(--brand); }
.qa-loop-steps { display: flex; flex-direction: column; gap: 6px; margin-top: 24px; }
.qa-loop-steps > div {
  display: flex; align-items: center; gap: 12px; padding: 11px 10px;
  border-radius: 14px; color: var(--text-3); transition: .2s ease;
}
.qa-loop-steps i {
  display: grid; place-items: center; width: 28px; height: 28px; flex: none;
  border-radius: 50%; background: var(--fill); font-size: 12px; font-style: normal; font-weight: 700;
}
.qa-loop-steps span { display: flex; flex-direction: column; }
.qa-loop-steps b { font-size: 14px; }
.qa-loop-steps small { margin-top: 1px; font-size: 12px; }
.qa-loop-steps > .on { background: var(--accent-weak); color: var(--text); }
.qa-loop-steps > .on i { background: var(--brand); color: #fff; }
.qa-loop-steps > .on small { color: var(--accent-strong); }
/* 지금 서 있는 칸. 지나온 칸(.on)과 구분이 없으면 «어디까지 좁혀졌나» 가 안 읽힌다.
   테두리 하나로만 가른다 — 한 화면의 주인공은 스트림이지 이 목록이 아니다 */
.qa-loop-steps > .at { box-shadow: inset 0 0 0 1.5px var(--brand); }
/* ── 개념 퀘스트 ──────────────────────────────────────────────
   왼쪽 칸의 주인공. 오늘 채울 개념을 순서대로 세우고 지나온 줄·지금 줄·남은
   줄을 무게로 가른다. 판정 색 다섯은 뜻이 붙어 있어 그대로 쓴다 (CLAUDE.md §3-3).
   게임 느낌은 이모지가 아니라 줄 세우기와 현재 표식으로 낸다 — #/qa 는 앱
   화면이라 장식 이모지를 쓰지 않는다 (MVP_SPEC §3). */
.quest {
  padding: 20px; border-radius: 24px; background: var(--surface);
  box-shadow: 0 10px 34px rgba(20, 33, 61, .08);
}
.quest-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.quest-title { font-size: 14px; font-weight: 700; letter-spacing: -.02em; }
.quest-count { font-size: 14px; font-weight: 700; color: var(--brand); }
.quest-count i { margin-left: 2px; font-style: normal; font-size: 12px; font-weight: 600; color: var(--text-3); }
.quest-bar { height: 3px; margin: 12px 0 14px; border-radius: 999px; background: var(--fill); overflow: hidden; }
.quest-bar > i { display: block; width: var(--p); height: 100%; border-radius: 999px; background: var(--brand); transition: width .35s var(--ease); }
/* 연속 정복. 진짜로 센 수만 띄운다 — 2개 미만이면 아예 안 그린다 (§14 숫자는 신성) */
.quest-streak { margin: -6px 0 12px; font-size: 12px; font-weight: 600; color: var(--text-3); }
.quest-streak b { color: var(--brand); font-weight: 700; }
.quest-list { display: flex; flex-direction: column; gap: 2px; margin: 0; padding: 0; list-style: none; }
/* 「힌트 없이」는 results[].hintLevel 이 0일 때만 붙는 사실 표식이다 */
.qrow-clean { margin-left: 6px; font-style: normal; font-size: 10.5px; font-weight: 700; color: var(--brand); }
.qrow { display: flex; align-items: center; gap: 10px; padding: 9px 8px; border-radius: 12px; transition: background .2s var(--ease); }

/* 개념 그래프의 위계를 목록에 그대로 입힌다 (ConceptNode.depth — f07 이 parent
   간선에서 파생해 실어 준다). 실측 깊이가 1~3 이라 두 칸이면 다 담긴다.
   따로 패널을 만들지 않는 이유: 노드는 이 목록이 이미 보여주고 있어서, 새로
   얻는 정보는 위계뿐이다. 대화가 주인공인 화면에 그림을 하나 더 얹지 않는다. */
.quest-list .qrow { position: relative; margin-left: calc(var(--d, 0) * 15px); }
/* 부모가 목록 밖일 때 그 이름. 「무엇 아래 개념인지」는 자료 구조에서 온 사실이고,
   질문이 걸러져 부모 줄이 없어도 그 사실은 남는다 — 들여쓰기로는 못 하는 말이다. */
.qrow-up {
  display: block; font-style: normal; font-size: 10.5px; font-weight: 700;
  color: var(--text-3); letter-spacing: -.01em; margin-bottom: 1px;
}
.qrow.is-now .qrow-up { color: var(--brand); }
.quest-list .qrow[data-d="1"]::before,
.quest-list .qrow[data-d="2"]::before {
  content: ''; position: absolute; left: -9px; top: 9px; bottom: 9px;
  border-left: 1px solid var(--line, #D5E2DA); border-bottom-left-radius: 2px;
}
/* 지금 묻는 개념과 relates 로 이어진 줄. 자료에서 옆에 붙어 있던 개념이라
   「아까 그거랑 연결돼 있구나」가 보인다. 전부 그리면 실측 최대 112개 선이
   겹쳐 아무것도 안 읽히므로 현재 것만 표시한다. */
.quest-list .qrow.is-kin .qrow-body b::after {
  content: '관련'; margin-left: 6px; padding: 1px 5px; border-radius: 999px;
  font-size: 10px; font-weight: 700; color: var(--brand);
  background: var(--accent-weak); vertical-align: middle;
}
.qrow-mark {
  display: grid; place-items: center; width: 22px; height: 22px; flex: none;
  border-radius: 50%; background: var(--fill); color: var(--text-3);
  font-style: normal; font-size: 11px; font-weight: 700;
}
.qrow-body { display: flex; flex-direction: column; min-width: 0; }
/* keep-all 로 한국어 개념 이름이 어절 중간에서 안 끊기게 하되, 300px 칸을
   혼자 넘기는 긴 영어 용어(Temperature Parameter 류)는 끊어서 넘치지 않게 한다 */
.qrow-body b { font-size: 13.5px; font-weight: 600; letter-spacing: -.01em; word-break: keep-all; overflow-wrap: break-word; }
.qrow-body small { margin-top: 1px; font-size: 11.5px; font-weight: 600; color: var(--text-3); }

.qrow.is-won .qrow-mark { background: var(--ok); color: #fff; }
.qrow.is-won .qrow-body small { color: var(--ok); }
.qrow.is-part .qrow-mark { background: var(--mid); color: #fff; }
.qrow.is-part .qrow-body small { color: var(--mid); }
.qrow.is-lost .qrow-mark { background: var(--no); color: #fff; }
.qrow.is-lost .qrow-body small { color: var(--no); }
.qrow.is-skip .qrow-mark { background: var(--om); color: #fff; }
.qrow.is-skip .qrow-body small { color: var(--om); }

/* 지금 줄에만 색을 얹는다 — 둘을 강조하면 강조가 아니다 */
.qrow.is-now { background: var(--accent-weak); }
.qrow.is-now .qrow-mark {
  background: var(--brand); color: #fff;
  box-shadow: 0 0 0 3px var(--surface), 0 0 0 5px var(--accent-weak);
  animation: questNow 2.4s var(--ease) infinite;
}
.qrow.is-now .qrow-body b { color: var(--accent-strong); }
.qrow.is-now .qrow-body small { color: var(--brand); }
@keyframes questNow {
  0%, 68%, 100% { box-shadow: 0 0 0 3px var(--surface), 0 0 0 5px var(--accent-weak); }
  84% { box-shadow: 0 0 0 3px var(--surface), 0 0 0 8px var(--accent-weak); }
}

/* 아직 안 온 줄은 흐리게 — 목록의 무게 중심이 «지금» 에 남는다 */
.qrow.is-next { opacity: .5; }

@media (prefers-reduced-motion: reduce) {
  .qrow.is-now .qrow-mark { animation: none; }
}
/* 코칭 중 왼쪽 칸의 개념 진행 표시. 얇은 막대(`> i`)를 의도한 규칙이었는데
   trackerHTML() 은 .pt-head 와 .pt-items 를 그린다 — 직접 자식 i 가 없어서
   막대는 한 번도 안 그려졌고, height:6px + overflow:hidden 만 남아 117px 짜리
   내용을 6px 로 눌러 「잘린 줄 하나」로 만들고 있었다.
   왼쪽 칸이 있는 이유가 이 표시라서(대화가 길어져도 안 사라진다) 블록으로 되돌리고,
   진행률은 머리줄 아래 가로선으로 그린다 — 마크업은 그대로 둔다 */
.qa-context > .persuade-track {
  height: auto; padding: 0; overflow: visible; background: none; border-radius: 0;
}
.qa-context > .persuade-track > .pt-head { position: relative; padding-bottom: 11px; }
.qa-context > .persuade-track > .pt-head::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  height: 3px; border-radius: 999px; background: var(--fill);
}
.qa-context > .persuade-track > .pt-head::before {
  content: ""; position: absolute; left: 0; bottom: 0; z-index: 1;
  width: var(--p); height: 3px; border-radius: 999px; background: var(--brand);
  transition: width .35s ease;
}
.qa-input-label { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.qa-input-label b { font-size: 15px; }
.qa-input-label span { color: var(--text-3); font-size: 12px; }
.qa-live-input textarea { min-height: 82px; background: #F8F9FA; border-color: transparent; }
.qa-live-input textarea:focus { background: var(--surface); border-color: var(--brand); }
.qa-live-input .step-actions .qa-exit-action { margin-left: auto; color: var(--text-3); }

/* 입력 카드는 줄이 둘이다 — 주 행동(답 보내기·마이크)과 보조(모르겠어요·힌트·
   답 보기·여기까지). 예전엔 여섯이 한 줄에 섰는데, .step-actions 에 flex-wrap 이
   없어 좁은 화면에서 서로를 눌러 버렸다. 무엇이 주인공인지 사라지고 실제로
   마이크가 안 눌렸다 (MVP_SPEC §3 「한 화면의 주인공은 하나」).

   보조 줄도 step-actions 클래스를 그대로 다는 이유: 판정 중 잠금이
   `.qa-live-input .step-actions button` 으로 걸린다 (qa_live.js setLiveBusy).
   떼면 판정 중에 「모르겠어요」·힌트가 계속 눌린다. */
.qa-live-input .step-actions-sub { margin-top: 10px; flex-wrap: wrap; }

/* 한 문제를 끝낼 때마다 멈추는 변화 확인 화면. */
.qa-checkpoint { width: min(680px, calc(100% - 32px)); margin: 18px auto 44px; }
.qa-check-hero { text-align: center; padding: 24px 12px 20px; }
.qa-check-icon {
  display: grid; place-items: center; width: 52px; height: 52px; margin: 0 auto 14px;
  border-radius: 50%; background: var(--ok-bg); color: var(--ok); font-size: 22px; font-weight: 800;
  animation: qaCheckPop .35s cubic-bezier(.2, .8, .2, 1);
}
.qa-check-hero.is-learn .qa-check-icon { background: var(--accent-weak); color: var(--brand); }
.qa-check-hero p { margin: 0 0 5px; color: var(--text-2); font-size: 14px; font-weight: 600; }
.qa-check-hero h1 { margin: 0; font-size: clamp(24px, calc(var(--vw) * 0.04), 34px); line-height: 1.3; letter-spacing: -.04em; }
.qa-score-pill {
  display: inline-flex; align-items: center; gap: 6px; margin-top: 13px; padding: 7px 12px;
  border-radius: 999px; background: var(--fill); color: var(--text-2); font-size: 13px;
}
.qa-score-pill b { color: var(--brand); }
.qa-compare-card {
  padding: 22px; border-radius: 24px; background: var(--surface);
  box-shadow: 0 12px 38px rgba(20, 33, 61, .09);
}
.qa-compare-row > span {
  display: block; margin-bottom: 7px; color: var(--text-3);
  font-size: 12px; font-weight: 700;
}
.qa-compare-row p { margin: 0; font-size: 16px; line-height: 1.65; word-break: keep-all; }
.qa-compare-row.mine p { color: var(--text-2); }
.qa-compare-row.coach {
  padding: 17px 18px; border-radius: 16px; background: var(--accent-weak);
}
.qa-compare-row.coach > span { color: var(--accent-strong); }
.qa-compare-row.coach p { color: var(--text); font-weight: 650; }
.qa-compare-arrow { padding: 10px 0; color: var(--brand); text-align: center; font-size: 20px; }
.qa-memory-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 14px; }
.qa-memory-chips span { padding: 6px 9px; border-radius: 8px; background: var(--fill); color: var(--text-2); font-size: 12px; }
.qa-check-note { margin: 14px 0 0; color: var(--text-3); text-align: center; font-size: 13px; }
.qa-check-actions { display: flex; flex-direction: column; gap: 7px; margin-top: 18px; }
.qa-check-actions .btn-primary { width: 100%; }
@keyframes qaCheckPop { from { opacity: 0; transform: scale(.65); } to { opacity: 1; transform: scale(1); } }

@media (max-width: 760px) {
  .qa-loop-card { padding: 18px; }
  .qa-loop-card h2 { font-size: 18px; }
  .qa-input-label { align-items: flex-start; flex-direction: column; gap: 2px; }
  .qa-live-input .step-actions .qa-exit-action { margin-left: 0; }
  .qa-checkpoint { width: calc(100% - 24px); }
  .qa-compare-card { padding: 16px; border-radius: 20px; }
}

/* ── 버튼 위계 ────────────────────────────────────────────────
   TDS 는 size 4단(small·medium·large·xlarge)이다 (TDS.md:2412).
   우리는 3단이면 충분한데, 지금까지 .btn(46) 과 .btn-sm(44) 뿐이라
   2px 차이여서 위계가 아예 없었다. 44 는 손가락 최소값이라 못 내린다.

     44px  small   보조 액션 · 상단 바
     48px  medium  기본
     52px  주요    화면에 하나뿐인 fill (TDS "한 화면에 fill 은 하나")

   fill 이 화면당 하나라는 건 실측으로 확인했다 —
   #/new · #/qa · #/report 각 1개, 홈은 상단 바, 판단 방식은 CTA 없음 */
.btn { height: 48px; }
.btn-primary:not(.btn-sm) { height: 52px; padding: 0 24px; font-size: 15px; }

/* ── 채점표 탭 — 39개 항목을 근거와 함께 편다 ──────────────────
   히트맵을 안 쓰는 이유는 js/app.js 의 rRubric() 주석에 적어 뒀다.
   상태 3종은 색이 아니라 말로 구분한다 — 색만으로는 '낮은 점수'와
   '안 봄'이 같은 회색으로 읽힌다 */
/* 묶음은 접힌다 (app.js rRubric). 접힌 줄 하나가 결론이고, 펼치면 근거다 —
   39개 항목과 39줄의 근거를 한꺼번에 펴 두면 「내 점수가 왜 42인가」를 찾을 수 없다. */
.rb-cluster { margin-top: 0; border-bottom: 1px solid var(--border); }
.rb-cluster:last-of-type { border-bottom: 0; }
.rb-cluster > summary {
  display: flex; align-items: center; gap: 10px;
  padding: 15px 2px; cursor: pointer; list-style: none;
  font-size: 15px; font-weight: 700;
}
.rb-cluster > summary::-webkit-details-marker { display: none; }
.rb-cluster > summary:hover .rb-cname { color: var(--accent); }
.rb-cname { min-width: 0; }
/* 몇 개를 실제로 쟀는지 — 접힌 채로도 「다 못 쟀다」가 보여야 한다 (§4) */
.rb-cmeta { margin-left: auto; font-size: 12px; font-weight: 500; color: var(--text-3); }
.rb-cluster > summary b { flex: none; font-size: 17px; color: var(--brand-strong); }
.rb-cluster > summary::after {
  content: "＋"; flex: none; width: 14px; text-align: center;
  color: var(--text-3); font-size: 14px; font-weight: 400;
}
.rb-cluster[open] > summary::after { content: "－"; }
.rb-cluster[open] > summary { border-bottom: 1px solid var(--border); }
.rb-cluster .rb-list { padding: 4px 0 14px; }
.rb-list { list-style: none; margin: 0; padding: 0; }
.rb-item { padding: 9px 0; border-bottom: 1px solid var(--border); }
.rb-item:last-child { border-bottom: 0; }
.rb-line { display: flex; align-items: baseline; gap: 10px; }
.rb-no { flex: none; width: 22px; font-size: 12px; color: var(--text-3); }
.rb-name { flex: 1; min-width: 0; font-size: 14px; font-weight: 600; }
.rb-src {
  flex: none; padding: 2px 8px; border-radius: var(--r-pill);
  background: var(--fill); font-size: 11px; font-weight: 600; color: var(--text-3);
}
.rb-line b { flex: none; font-size: 15px; font-weight: 700; }
.rb-flag { flex: none; font-size: 12px; font-weight: 600; }
/* 근거가 이 탭의 본체다. 점수보다 읽기 편해야 한다 */
.rb-why {
  margin: 5px 0 0 32px; font-size: 12.5px; line-height: 1.5; color: var(--text-2);
  overflow-wrap: break-word;
}
/* 채점 못 한 항목은 흐리게 두되 지우지 않는다 — 있었다는 사실이 정보다 */
.rb-item.is-situation_excluded .rb-name,
.rb-item.is-unmeasured .rb-name { color: var(--text-3); font-weight: 500; }


/* ══ 앱 셸: 좌측 내비 ═══════════════════════════════════════════════
   좌측 내비 없이 탑바 하나뿐이면 "제품"이 아니라 "페이지"로 보인다.
   기본은 숨김이고 tablet.css 가 >=900px 에서만 켠다 — 좁은 화면의
   흐름(탑바 + 세로 스택)은 한 픽셀도 안 바뀐다. */
.sidenav { display: none; }

/* ══ 질문 준비 중 — 10초를 비워 두지 않는다 ═══════════════════════════
   ⚠️ .qa-building · .qb-bar 규칙은 이 파일 안에 두 벌 있다(1418·1898).
   새로 얹는 건 여기 한 번만 둔다 — 위쪽 두 벌을 고치면 어느 쪽이 이기는지
   헷갈린다. 파일 끝이라 둘 다 이긴다.

   가운데 정렬을 푼 이유: 굵은 글씨 한 줄 · 설명 한 줄 · 막대 하나를 가운데
   모아 두면 카드가 넓을수록 더 비어 보인다. 왼쪽 정렬이면 읽는 눈이 한 축에
   머물러서 같은 내용이 덜 허전하다. */
.qa-building { text-align: left; padding: 24px 22px; }
.qa-building b { font-size: 18px; line-height: 1.45; margin-bottom: 4px; }
.qa-building .note { margin: 0 0 14px; }

/* 남은 시간을 지어내지 않는다. 지난 시간만 센다 (§14 진행률은 정직하게) */
.qb-elapsed {
  margin: 8px 0 0; color: var(--text-3);
  font-size: 12px; font-variant-numeric: tabular-nums;
}

/* 지금 질문 후보에 올라 있는 개념. 연출이 아니라 F-08 이 받는 그 목록이다 */
.qb-pool { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--border); }
.qb-pool-head {
  display: flex; align-items: baseline; gap: 8px; margin: 0 0 8px;
  color: var(--text-2); font-size: 13px; font-weight: 600;
}
.qb-pool-head span { color: var(--text-3); font-size: 12px; font-weight: 500; }
.qb-pool ul { margin: 0; padding: 0; list-style: none; }
.qb-pool li {
  display: flex; align-items: center; gap: 10px;
  min-height: 40px; padding: 6px 0;
  border-bottom: 1px solid var(--border);
}
.qb-pool li:last-child { border-bottom: 0; }
/* 개념 이름이 길어도 배지를 밀어내지 않는다 */
.qb-pool li b {
  flex: 1 1 auto; min-width: 0; font-size: 15px; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.qb-pool li .chip { flex: none; }
.qb-pool-more { margin: 8px 0 0; color: var(--text-3); font-size: 12px; }

/* 「기다리지 않고」는 빠져나가는 길이지 주인공이 아니다. 왼쪽 아래에 둔다 */
.qb-actions { justify-content: flex-start; margin-top: 16px; }

/* 코칭 결과 — 리포트에서 짚어 줄 개념을 못 찾은 행은 누를 수 없다.
   화살표만 달아 두고 같은 곳으로 보내면 그게 거짓말이다 */
.qres-row.is-flat { cursor: default; }

/* ═══ 연습·코칭 화면을 홈의 문법으로 ═══════════════════════════════
   홈을 「할 일 한 줄 + 표」로 갈아엎고 나니 나머지 화면만 카드 문법으로 남아,
   내비를 눌러 옮길 때마다 다른 제품처럼 보였다. 여기서 맞춘다.

   원칙 하나: 면 위에 면을 얹지 않는다. 상자 안의 상자는 「무엇이 주인공인가」를
   지운다 — 테두리가 둘이면 눈은 바깥 테두리를 먼저 읽는다. 구분이 필요하면
   면이 아니라 머리카락 선 하나와 여백으로 한다. */

/* ── 1. 새 발표 연습 ──────────────────────────────────────────
   1·2단계와 파싱·완료 상태가 전부 흰 카드에 담겨 있었다. 카드를 벗기면
   폼이 바탕 위에 바로 눕는다.
   4단계(.pipe-inspect)는 다른 세션이 두 단 격자로 만들어 둔 화면이고
   카드가 그 격자의 컨테이너다 — 건드리면 배치가 무너지므로 제외한다 */
#nf > .card:not(:has(.pipe-inspect)) {
  background: none; border: 0; box-shadow: none; padding: 0;
}

/* 카드를 벗기면 제목이 기댈 데가 없어진다. 홈의 h1 과 같은 무게를 준다 */
.nf-head {
  font-size: var(--t-h1); font-weight: 700; letter-spacing: -.02em; color: var(--text);
}
.nf-head-sub { margin: 6px 0 24px; }

/* 드롭존 — 점선 상자가 화면 한가운데 떠 있고 글 폭보다 좁아, 위의 단계 표시줄과
   왼쪽 끝이 안 맞았다. 읽는 칸에 맞춰 눕히고 점선을 얇게 한다 */
.dropzone {
  border-width: 1px; padding: 56px 24px;
}

/* 자료를 다 읽은 뒤의 상태도 카드가 아니라 구역이다 */
.gate-ok { font-size: var(--t-card); }

/* ── 2. 질문 코칭 시간 고르기 ──────────────────────────────────
   흰 카드 안에 테두리 있는 선택지가 셋 — 상자 안의 상자였다.
   카드를 벗기고, 선택지는 머리카락 선으로만 나눈다 */
.card.qa-quick {
  background: none; border: 0; box-shadow: none; padding: 0;
}
.qa-quick .qa-modes { gap: 0; }
.qa-mode {
  border: 0; border-radius: 0; background: none; box-shadow: none;
  border-bottom: 1px solid var(--border);
  padding: 15px 6px; transition: background .14s ease;
}
.qa-mode:hover { background: var(--hover); }
/* 골라 둔 줄은 테두리가 아니라 옅은 면과 왼쪽 기둥으로 말한다.
   테두리로 말하면 옆 줄과 높이가 1.5px 씩 어긋나 목록이 떨린다 */
.qa-mode.on { background: var(--brand-weak); box-shadow: inset 2px 0 0 var(--brand); }
.qa-mode:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
.qa-quick .qa-mode-pick .btn { align-self: stretch; }

/* ── 3. 코칭 중 ────────────────────────────────────────────────
   왼쪽 칸의 상대 소개가 또 흰 카드였다. 대화(오른쪽)가 주인공인 화면에서
   보조 칸이 면을 갖고 있으면 무게가 뒤집힌다 */
.persona-card {
  background: none; box-shadow: none; padding: 14px 0;
  border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
  border-radius: 0; margin-bottom: 0;
}
/* 제목은 인라인 크기를 걷어냈으니 여기서 준다 */
.qa-top .page-title { font-size: var(--t-card); font-weight: 700; letter-spacing: -.02em; }
.qa-top .page-sub { font-size: var(--t-meta); color: var(--text-3); margin-top: 3px; }

/* ── 4. 코칭을 마친 화면 ───────────────────────────────────────
   흰 카드 셋을 쌓아 877px 이 됐다. 예산은 690px 이라 193px 이 넘쳐
   맨 아래 「다음」 줄이 화면 밖에 있었다 — 시연의 마지막 화면인데.
   1366x1024 에서는 세로가 넉넉해 우연히 들어맞아서 안 보이던 것이다.
   카드를 벗기고 구역 사이는 머리카락 선으로 나눈다 */
.cere-card {
  background: none; border: 0; box-shadow: none;
  border-radius: 0; padding: 14px 0;
}
.cere-card + .cere-card { margin-top: 0; border-top: 1px solid var(--border); }
/* c1 은 「이번에 이긴 것」이라 면이 뜻을 갖는다 — 지우지 않고 안쪽으로만 물린다 */
.cere-card.c1 {
  background: var(--brand-weak); border: 0;
  padding: 14px 16px; border-radius: var(--r-inner);
}
.cere-head { margin-bottom: 12px; }
/* 개념 목록이 이 화면에서 제일 길다(326px). 줄 높이만 조여도 카드를 안 지우고
   50px 가 돌아온다 — 줄 수를 줄이면 「무엇을 이겼나」가 사라지므로 여백만 만진다 */
.cere-concepts li { padding: 5px 0; font-size: var(--t-body); }
/* 아직 100px 이 남았다. 줄을 지우면 「무엇을 이겼나」가 사라지므로 활자와 여백만
   조인다 — 오늘 만든 문장은 이 화면의 주인공이라 크기를 지키고, 그 위아래
   장식(라벨·화살표·힌트)에서 걷는다 */
.cere-label { margin-bottom: 8px; }
.cd-arrow { margin: 8px 0 6px; }
.cere-hint { margin-top: 10px; padding-top: 10px; }
.cere-sub { margin-top: 8px; }
.cere-next { margin-top: 10px; padding-top: 10px; }
.cere-head { margin-bottom: 10px; }
.cere-eyebrow { margin-bottom: 2px; }

/* ── 5. 리포트 ─────────────────────────────────────────────────
   홈·연습·코칭을 전부 이 문법으로 옮기고 나니 리포트만 카드로 남았다.
   내비의 마지막 칸이라, 여기서 톤이 끊기면 「앞의 셋만 새로 만든 제품」이 된다.

   여기는 특히 카드를 벗겨야 하는 화면이다. 판정 헤드가 이미 왼쪽에 면을 하나
   깔고 있어서, 오른쪽 본문의 흰 카드는 면 위의 면이 아니라 「면 옆의 면」으로
   경쟁한다 — 어느 쪽이 결론인지 흐려진다. 결론은 헤드다.

   면이 뜻을 갖는 둘은 색만 남기고 테두리·그림자만 걷는다(.cere-card.c1 과 같은
   판단): trophy-strip 은 「오늘 만든 문장」이고 next-card 는 「다음에 할 일」이라
   본문 흐름에서 떠 있어야 한다. */
#rbody > .card,
#rbody .fold-body > .card {
  background: none; border: 0; box-shadow: none;
  border-radius: 0; padding: 0;
}
/* 카드를 벗기면 구역이 서로 붙는다. 구분은 머리카락 선과 여백으로 한다.
   색면이 남는 둘(trophy-strip·next-card)은 제 색으로 이미 구분되므로 선을 긋지
   않는다 — :not() 으로 애초에 빼 둔다. 뒤에서 덮으려 하면 같은 명시도끼리
   순서 다툼이 되고, 실제로 next-card 에 선이 하나 남아 있었다 */
#rbody > .card + .card:not(.trophy-strip):not(.next-card),
#rbody > details.fold + .card:not(.trophy-strip):not(.next-card) {
  margin-top: 0; padding-top: 18px; border-top: 1px solid var(--border);
}
#rbody > .card + details.fold {
  margin-top: 0; padding-top: 18px; border-top: 1px solid var(--border);
}
/* 뜻을 가진 면 둘 — 색은 지키고 테두리만 걷는다 */
#rbody > .card.trophy-strip,
#rbody > .card.next-card {
  border: 0; box-shadow: none;
  padding: 14px 16px; border-radius: var(--r-inner);
  border-top: 0;
}
#rbody > .card.trophy-strip { background: var(--brand-weak); }
#rbody > .card.next-card { background: var(--accent-weak); }
/* 면이 남은 칸 다음 줄에 선을 또 그으면 테두리가 둘로 보인다 */
#rbody > .card.trophy-strip + .card,
#rbody > .card.next-card + .card { border-top: 0; padding-top: 0; }
/* 누를 수 있다는 신호는 면이 아니라 움직임으로 남긴다 */
#rbody > .card.trophy-strip:hover { transform: translateY(-1px); box-shadow: none; }
/* 슬라이드 묶음은 안에 필름·범례를 담는 컨테이너다. 면은 걷되 묶음은 유지한다 */
#rbody > .card.rep-deck > .section-title { margin-bottom: 12px; }

/* ── 6. 좁은 화면의 리포트 판정 헤드 ───────────────────────────
   tablet.css 가 리포트를 두 기둥으로 세우는 건 @media (min-width:900px) 안이다.
   그 아래에서는 예전 세로 한 줄 배치가 그대로 남아, 820 높이에서 헤드가 801px 을
   깔고 탭 7개가 y=865 — 접힌 선 아래에서 시작한다. 본문은 945 다.
   두 기둥을 여기까지 내리면 오른쪽 칸이 490px 로 눌려 개념 이름이 줄마다 접힌다.
   배치는 그대로 두고 헤드만 접힌 선 위로 들어오게 깎는다.

   무엇을 깎는가: 숫자 7개와 막대는 전부 남긴다(§14 — 숫자는 신성하다).
   항목마다 붙던 설명 한 줄만 접는다. 그건 측정값이 아니라 고정 안내문이고,
   「제일 낮은 항목」에는 그대로 남으므로 무엇부터 볼지는 여전히 읽힌다.

   2026-08-08 — 설명 줄을 접는 일은 이제 마크업이 한다 (app.js dimsHtml 이
   최약 항목에만 .hint 를 낸다). 여기 남은 건 간격을 깎는 몫뿐이다. */
@media (max-width: 899px) {
  main.wide:has(#rbody) > .verdict { padding-top: 16px; }
  main.wide:has(#rbody) > .verdict .verdict-dims {
    gap: 11px; margin-top: 14px; padding-top: 12px;
  }
  main.wide:has(#rbody) > .verdict .vd-rest { gap: 0; }
  main.wide:has(#rbody) > .verdict .vd-rest .vd { padding: 9px 2px; }
  main.wide:has(#rbody) > .verdict .verdict-dims .vd-weak .vl { margin: 2px 0 8px; }
  main.wide:has(#rbody) > .verdict .verdict-basis { margin-top: 12px; padding-bottom: 16px; }
  main.wide:has(#rbody) > .verdict .verdict-grid { gap: 12px; margin-top: 12px; }
  main.wide:has(#rbody) > .verdict .verdict-title { margin-top: 4px; }
  /* 파형은 절대 배치라 높이를 안 먹지만, 헤드가 얕아지면 아래로 흘러 넘친다 */
  /* 탭이 접힌 선 바로 위에 오면 「더 있다」가 안 읽힌다. 붙여 둔다 */
  main.wide > #rtabs.tabs { position: sticky; top: 0; z-index: 5; background: var(--canvas); }
  /* 여기까지 깎으면 탭은 들어오는데 본문 첫 줄이 25px 모자란다. 탭과 본문
     사이 여백에서 마저 걷는다 — 접힌 선 위에 본문이 한 줄이라도 보여야
     「탭을 누르면 여기가 바뀐다」가 읽힌다 */
  main.wide > #rtabs.tabs { margin-bottom: 10px; }
  main.wide:has(#rbody) > .verdict .verdict-note { padding-bottom: 12px; }
  main.wide:has(#rbody) > .verdict .verdict-score .vs-body { padding-top: 6px; }
}

/* ═══ 질문 코칭 진입 두 화면 — 색으로 말하지 않고 크기로 말한다 ═════════
   왼쪽에 세로 색 기둥을 세우고 줄 전체를 민트로 칠하던 방식을 버린다.
   TDS ListRow 는 고른 줄을 면으로 칠하지 않는다 — 오른쪽 체크 하나로 말하고,
   나머지는 여백과 글씨 크기로 위계를 만든다. 면을 칠하면 고르기 전부터
   화면이 시끄럽고, 세로 기둥은 어느 디자인 시스템에도 없는 장식이다.
   이 절은 파일 끝이라 위쪽 세 벌(1393·1916·2081·2348)을 모두 이긴다. */

/* ── 시간 고르기 ─────────────────────────────────────────────── */
.qa-quick .qa-modes { gap: 0; }
.qa-mode {
  gap: 18px;
  min-height: 76px; padding: 18px 4px;
  border-bottom: 1px solid var(--border);
  background: none; box-shadow: none; border-radius: 0;
}
.qa-mode:last-child { border-bottom: 0; }
.qa-mode:hover { background: var(--hover); }
/* 고른 줄: 면도 기둥도 없다. 시간 숫자가 진해지고 체크가 채워질 뿐이다 */
.qa-mode.on { background: none; box-shadow: none; }
.qa-mode.on .qm-body b { font-weight: var(--w-bold); }

/* `.qa-mode span` (1406·1929행) 이 클래스1+타입1 로 `.qm-time` 하나를 이긴다.
   그래서 22px 를 적어도 12px 로 그려졌다 — 클래스 둘로 올려 확실히 이긴다 */
.qa-mode .qm-time {
  min-width: 78px;
  font-size: 22px; font-weight: var(--w-bold); color: var(--text-3);
  line-height: 1.2;
}
.qa-mode.on .qm-time { color: var(--text); }

.qa-mode .qm-body b { font-size: 17px; font-weight: var(--w-med); }
.qa-mode .qm-body > span { margin-top: 5px; font-size: 14px; line-height: 1.55; color: var(--text-3); }

/* 화면의 주인공은 질문이지만, 물어보는 문장이 본문과 같은 크기면 화면에 주인이 없다 */
.qa-quick .qm-head { gap: 6px; margin-bottom: 10px; }
.qa-quick .qm-head b { font-size: 24px; font-weight: var(--w-bold); line-height: 1.35; letter-spacing: -.02em; }
.qa-quick .qm-head span { font-size: 15px; line-height: 1.55; }
.qa-quick .btn-primary { margin-top: 22px; min-height: 56px; font-size: 17px; }

.qm-check {
  width: 26px; height: 26px; font-size: 14px;
  border-width: 2px;
}

/* ── 준비 중 ─────────────────────────────────────────────────── */
.qa-building { padding: 30px 26px; }
.qa-building b { font-size: 22px; line-height: 1.4; margin-bottom: 8px; }
.qa-building .note { font-size: 15px; line-height: 1.6; margin: 0 0 20px; }
.qb-elapsed { margin-top: 12px; font-size: 14px; }

/* 숫자 셋을 각각 테두리 상자에 넣으면 카드 안에 카드가 셋이다.
   상자를 벗기고 숫자를 키운다 — 구분은 사이의 머리카락 선 하나면 된다 */
.qb-facts { gap: 0; margin-top: 22px; }
.qb-facts > div {
  padding: 4px 16px;
  border: 0; border-radius: 0; background: none;
  border-left: 1px solid var(--border);
}
.qb-facts > div:first-child { border-left: 0; padding-left: 0; }
.qb-facts b { font-size: 30px; }
.qb-facts span { margin-top: 6px; font-size: 14px; }

.qb-pool { margin-top: 26px; padding-top: 20px; }
.qb-pool-head { margin-bottom: 4px; font-size: 15px; }
.qb-pool-head span { font-size: 14px; }
.qb-pool li { min-height: 56px; padding: 10px 0; gap: 12px; }
.qb-pool li b { font-size: 17px; }
.qb-pool-more { margin-top: 12px; font-size: 14px; }
.qb-actions { margin-top: 24px; }

/* 17px 줄 옆에 12px 배지를 달면 배지가 주석처럼 보인다 — 줄과 같은 무게로 올린다 */
.qb-pool li .chip { font-size: 13px; padding: 5px 10px; }
/* 빠져나가는 길은 왼쪽 세로선을 본문과 맞춘다 — btn-text 의 좌우 여백이 혼자 들여쓰기를 만들었다 */
.qb-actions .btn-text { padding-left: 0; padding-right: 0; font-size: 15px; }

/* ── 개념 전달 한눈에 ──────────────────────────────────────────────────
   누적 막대였다가 목록으로 내렸다. 판정 5색을 큰 면에 채우니 무지개가 되고
   화면에서 제일 튀는 게 그 막대가 됐다 — 토스 그래픽 가이드 3·4번 위반.
   색은 점으로만 남기고 비율은 숫자로 읽는다. */
.jsplit-card { grid-column: 1 / -1; }
.jsplit-head { font-size: 17px; font-weight: 600; letter-spacing: -.02em; color: var(--text); }
.jsplit-head b { font-weight: 700; }
.jsplit-head .jsplit-ok { color: var(--ok); }
/* 잘한 쪽만 크게 쓰지 않는다 — 못 한 쪽도 같은 줄에 적는다 (§4) */
.jsplit-redo {
  margin-left: 10px; padding: 4px 10px; border-radius: 999px;
  background: var(--no-bg); color: var(--no);
  font-size: 12px; font-weight: 700; white-space: nowrap;
}
/* 기둥의 항목 줄과 같은 문법 — 머리카락 선으로 묶고 값은 오른쪽 끝에 모은다 */
.jsplit-rows { margin-top: 12px; }
.jsplit-row {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center; gap: 10px;
  padding: 10px 2px; border-top: 1px solid var(--border);
}
.jsplit-row:first-child { border-top: 0; }
.jsplit-name { font-size: 14px; font-weight: 500; color: var(--text-2); }
.jsplit-row b { font-size: 16px; font-weight: 700; color: var(--text); }

/* ── 말하기: 숫자는 지키고 무게만 뺀 한 줄 ────────────────────────────
   카드 세 장이었다. 바로 위 시간 분배 막대가 같은 이야기를 그림으로 하고 있어서
   카드까지 세우면 비슷한 크기의 그래픽이 둘이 된다 (토스 그래픽 3번). */
.voice-facts {
  display: flex; flex-wrap: wrap; gap: 8px 28px;
  margin: 0 0 4px; padding: 14px 2px;
  border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
}
.voice-facts span {
  display: inline-flex; align-items: baseline; gap: 7px;
  font-size: 15px; font-weight: 700; color: var(--text); letter-spacing: -.02em;
}
.voice-facts i { font-style: normal; font-size: 12px; font-weight: 500; color: var(--text-3); }
.voice-facts em { font-style: normal; font-size: 12px; font-weight: 500; color: var(--text-3); }

/* ── 간투어: 구름 대신 목록 ──────────────────────────────────────────
   크기로 빈도를 말하면 몇 배인지 못 읽는다 — 옆의 숫자가 더 정확하다 */
.filler-list { margin-top: 4px; }
.filler-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 11px 2px; border-top: 1px solid var(--border);
}
.filler-row:first-child { border-top: 0; }
.filler-row span { font-size: 15px; font-weight: 600; color: var(--text); }
.filler-row b { font-size: 15px; font-weight: 700; color: var(--text-2); }
/* 태그(간투어·반복)를 <i> 기울임으로 구분하던 것을 걷는다 — 이탤릭이 아니라
   구분선(|)으로 나눈다 (2026-08-12 지적: "기울기 말고 구분되게") */
.filler-row .ftag { font-size: 13px; font-weight: 600; font-style: normal; color: var(--text-3); }
.filler-row .fsep { margin: 0 7px; color: var(--border); font-weight: 400; }

/* ── 필름: 컬러 테두리 23개 → 중립 테두리 + 모서리 점 ──────────────────
   저마다 2px 컬러 테두리를 두르고 있었다. 정보는 맞지만 비슷한 크기의 그래픽
   23개가 한 줄에 서는 셈이라 시선이 갈 곳을 잃는다 (토스 그래픽 3번).
   판정은 점 하나로 남기고, 테두리는 «지금 보는 칸» 하나만 쓴다 —
   선택 표시와 판정 표시가 같은 채널(테두리 색)을 다투고 있었다. */
.deck-film .slidethumb { border-color: var(--border); }
.deck-film .slidethumb::before {
  content: ""; position: absolute; right: 5px; bottom: 5px; z-index: 2;
  width: 8px; height: 8px; border-radius: 50%;
  box-shadow: 0 0 0 1.5px rgba(255, 255, 255, .9);
}
.deck-film .slidethumb.st-ok::before { background: var(--ok); }
.deck-film .slidethumb.st-mid::before { background: var(--mid); }
.deck-film .slidethumb.st-no::before { background: var(--no); }
.deck-film .slidethumb.st-ct::before { background: var(--ct); }
.deck-film .slidethumb.st-om::before { background: var(--om); }
.deck-film .slidethumb.st-none::before { display: none; }
.deck-film .slidethumb.st-na::before { background: var(--text-3); }

/* ══ 누르는 느낌 — 터치 피드백 ═══════════════════════════════════════════
   시연은 아이패드에서 한다. 그런데 아이패드에는 hover 가 없다. 지금 누를 수
   있는 줄들(기둥 항목·필름·채점 묶음·접기·개념 행)은 hover 상태만 갖고 있어서,
   손가락으로 누르면 화면이 아무 답을 하지 않는다.

   토스 인터랙션 글이 「가장 작은 공수로 가장 큰 반응」으로 꼽는 자리가 정확히
   여기다 — 「유저가 화면을 누를 때 회색 배경만 나오는 것이 아니라 더욱 눌리는
   느낌이 나도록」. 그리고 이건 장식이 아니라 **피드백**이다: 눌렸는지 아닌지를
   화면이 답해 준다. 같은 글의 기준 — 「정적인 UI 로도 전달할 수 있는 가치라면
   인터랙션은 Good to have」 — 에서 이건 Good to have 가 아니라 없으면 안 되는
   쪽이다.

   값은 하나로 통일한다. 누르는 느낌이 자리마다 다르면 그 자체가 소음이다. */
:root { --press: 90ms cubic-bezier(.2, .9, .3, 1); }

.vd-rest button.vd,
.rb-cluster > summary,
details.fold summary,
.mini-row,
.jsplit-row,
.filter-chips button,
.tree button,
#rbody > .card.trophy-strip {
  -webkit-tap-highlight-color: transparent;
  transition: transform var(--press), background-color .12s ease, box-shadow .12s ease;
}
.vd-rest button.vd:active,
.rb-cluster > summary:active,
details.fold summary:active,
.mini-row:active,
.jsplit-row:active,
.filter-chips button:active,
.tree button:active { transform: scale(.985); }
/* 색면이 남은 카드는 살짝 더 눌린다 — 면적이 클수록 같은 배율이 덜 느껴진다 */
#rbody > .card.trophy-strip:active { transform: scale(.99); }
/* 필름은 hover 에서 이미 떠 있다. 누를 때는 그 반대로 «내려앉게» 한다 */
.deck-film .slidethumb.has { -webkit-tap-highlight-color: transparent; }
.deck-film .slidethumb.has:active { transform: translateY(0) scale(.96); box-shadow: none; }

/* 모션을 원치 않는 사용자에게는 크기 변화를 주지 않는다. 다만 «눌렸다» 는
   사실은 남겨야 하므로 면 색으로만 답한다 (피드백은 취향이 아니다) */
@media (prefers-reduced-motion: reduce) {
  .vd-rest button.vd:active,
  .rb-cluster > summary:active,
  details.fold summary:active,
  .mini-row:active,
  .jsplit-row:active,
  .filter-chips button:active,
  .tree button:active,
  #rbody > .card.trophy-strip:active,
  .deck-film .slidethumb.has:active { transform: none; }
  .rb-cluster > summary:active,
  details.fold summary:active,
  .mini-row:active,
  .jsplit-row:active { background: var(--hover); }
}

/* ══ 연출 (Good to have) ═══════════════════════════════════════════════
   앞의 「누르는 느낌」은 정적 UI 가 답할 수 없는 피드백이라 넣었고, 여기부터는
   토스 기준으로 Good to have 다 — 없어도 정보는 다 전달된다. 그래서 규칙을
   세 개 건다 (UI_REDESIGN §14):

     1. 짧다. 정보를 기다리게 만들면 연출이 아니라 지연이다.
     2. 데이터를 가리지 않는다. 숫자는 처음부터 제자리에 적혀 있고 움직이는 건
        면과 위치뿐이다 — 차오르는 중에 봐도 틀린 값을 보여주지 않는다.
     3. prefers-reduced-motion 이면 전부 꺼진다. 하나도 남기지 않는다.

   그래서 이 블록 전체가 no-preference 안에 있다. */
@media (prefers-reduced-motion: no-preference) {

  /* ── 탭을 바꾸면 본문이 촤라락 들어온다 ──────────────────────────
     지금은 내용이 즉시 갈려서 «바뀌었다» 는 사실을 눈이 놓친다. 카드가 차례로
     들어오면 어디부터 읽어야 하는지가 순서로 보인다.
     #rbody 자체가 아니라 자식에게 건다 — 스크롤 컨테이너에 transform 을 걸면
     안쪽 sticky 가 기준을 잃는다. */
  #rbody > * { animation: rb-card-in .26s var(--ease) both; }
  #rbody > *:nth-child(2) { animation-delay: .045s; }
  #rbody > *:nth-child(3) { animation-delay: .09s; }
  #rbody > *:nth-child(4) { animation-delay: .13s; }
  #rbody > *:nth-child(5) { animation-delay: .165s; }
  #rbody > *:nth-child(n+6) { animation-delay: .195s; }

  /* ── 시간 분배 막대가 왼쪽에서 드러난다 ──────────────────────────
     width 를 키우지 않고 clip-path 로 «덮개를 걷는다». 폭을 키우면 조각과 숫자가
     같이 늘어나 읽는 동안 값이 틀려 보인다 — 이건 규칙 2를 어긴다.
     이상적인 배분이 먼저, 내가 한 발표가 뒤에 드러나서 비교 순서가 만들어진다. */
  .tsplit-bar { animation: bar-reveal .7s var(--ease) both; }
  .tsplit-row.is-mine .tsplit-bar { animation-delay: .14s; }

  /* ── 슬라이드를 넘기면 무대가 갈아 끼워진다 ──────────────────────
     ←→ 로 넘길 때 그림이 즉시 바뀌어서 «넘어갔다» 가 안 읽혔다. 아주 짧게
     겹쳐 주면 넘어간 사실이 보인다 (selectDeckSlide 가 매번 다시 그린다). */
  .deck-main { animation: stage-in .22s var(--ease) both; }

  /* ── 기둥 항목·개념 줄도 차례로 ──────────────────────────────── */
  .vd-rest .vd { animation: rb-card-in .3s var(--ease) both; }
  .vd-rest .vd:nth-child(2) { animation-delay: .04s; }
  .vd-rest .vd:nth-child(3) { animation-delay: .08s; }
  .vd-rest .vd:nth-child(4) { animation-delay: .12s; }
  .vd-rest .vd:nth-child(5) { animation-delay: .16s; }
  .vd-rest .vd:nth-child(6) { animation-delay: .2s; }
  .jsplit-row { animation: rb-row-in .28s var(--ease) both; }
  .jsplit-row:nth-child(2) { animation-delay: .05s; }
  .jsplit-row:nth-child(3) { animation-delay: .1s; }
  .jsplit-row:nth-child(4) { animation-delay: .15s; }
  .jsplit-row:nth-child(5) { animation-delay: .2s; }
}

@keyframes rb-card-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes rb-row-in  { from { opacity: 0; transform: translateX(-6px); } to { opacity: 1; transform: none; } }
@keyframes bar-reveal { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes stage-in   { from { opacity: 0; } to { opacity: 1; } }


/* 못 잰 항목은 줄 대신 개수 한 줄로 (app.js rRubric) — 사실은 남기고 반복만 지운다 */
.rb-unmeasured { padding: 12px 2px 4px; font-size: 13px; color: var(--text-3); }

/* 서버 연결 배너 (conn_watch.js) — 포트 연결이 끊기면 화면 위에 한 줄. 연결되면 「다시 연결됐어요」 뒤 사라진다 */
.conn-banner { position: fixed; top: 12px; left: 50%; transform: translateX(-50%); z-index: 9999; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; max-width: min(640px, calc(100vw - 32px)); padding: 12px 16px; border-radius: var(--r-inner); background: var(--surface); box-shadow: var(--shadow); font-size: 14px; line-height: 1.5; }
.conn-banner b { font-weight: var(--w-bold); }
.conn-banner span { color: var(--text-3); font-size: 13px; }
.conn-banner.is-down { border: 1px solid var(--no); }
.conn-banner.is-down b { color: var(--no); }
.conn-banner.is-back { border: 1px solid var(--ok); }
.conn-banner.is-back b { color: var(--ok); }
.conn-retry { margin-left: auto; padding: 6px 12px; border: 0; border-radius: var(--r-ctl); background: var(--accent-weak); color: var(--accent); font: inherit; font-size: 13px; font-weight: var(--w-med); cursor: pointer; }
