/* 소리튠 3분 영어 소리진단
   토큰은 블록챌린지 디자인 시스템(docs/design-system.md)을 그대로 따른다.
   추가된 건 '소리블록' 계열 accent 셋뿐이다 — 스펙 §14 가 소리블록에 한해 허용한 색이다. */

:root {
  --brand-500: #fe6400;
  --brand-600: #e55a00;
  --brand-700: #c84e00;
  --brand-100: #ffe7d5;
  --brand-050: #fff3ea;
  --ink: #17171c;
  --ink-soft: #55555f;
  --muted: #85858f;
  --line: #e4e5e8;
  --surface-soft: #f5f6f8;
  --surface: #ffffff;
  --success: #168a57;
  --success-bg: #e8f7ef;
  --danger: #d93d47;
  --danger-bg: #fdecee;
  --info: #2563b9;
  --info-bg: #eef4fd;
  --focus: #1d4ed8;

  /* 소리블록 전용 accent. 게임/키즈 앱처럼 보이지 않도록 채도를 낮춘 3색만 쓴다. */
  --block-a: linear-gradient(135deg, #4f8ef7, #2f6fe0);
  --block-b: linear-gradient(135deg, #8b5cf6, #6d3fd4);
  --block-c: linear-gradient(135deg, #f062a8, #d63f8f);

  --space-1: 4px;  --space-2: 8px;  --space-3: 12px; --space-4: 16px;
  --space-5: 20px; --space-6: 24px; --space-8: 32px; --space-10: 40px;
  --space-12: 48px; --space-14: 56px;

  --radius-sm: 10px; --radius-md: 13px; --radius-lg: 16px;
  --radius-xl: 20px; --radius-2xl: 28px; --radius-pill: 999px;

  --shadow-float: 0 12px 30px rgb(23 23 28 / 12%);
  --shadow-soft: 0 8px 24px rgb(23 23 28 / 8%);

  --shell-max: 480px;
  --env-banner-h: 0px;

  --motion-fast: 120ms;
  --motion-base: 220ms;
  --motion-slow: 340ms;
  --ease-out: cubic-bezier(0.2, 0.8, 0.3, 1);
  --ease-soft: cubic-bezier(0.22, 0.85, 0.3, 1);
  /* 블록이 '착' 하고 붙는 느낌. 되튐이 있어야 자석처럼 읽힌다(스펙 §15 magnetic snap). */
  --ease-snap: cubic-bezier(0.34, 1.56, 0.64, 1);
}

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; scrollbar-gutter: stable; }

body {
  margin: 0;
  font-family: "Pretendard Variable", Pretendard, "Apple SD Gothic Neo",
    "Malgun Gothic", system-ui, sans-serif;
  font-size: 16px; font-weight: 500; line-height: 1.6;
  color: var(--ink);
  background: var(--surface-soft);
  word-break: keep-all;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, p, figure { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }
button, input, textarea, select { font: inherit; color: inherit; }
img, video { max-width: 100%; }

:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: var(--radius-sm); }
.tnum { font-variant-numeric: tabular-nums; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ── 타이포 ───────────────────────────────────────────────── */

.t-display { font-size: 34px; font-weight: 800; line-height: 1.14; letter-spacing: -0.03em; }
.t-h1  { font-size: 27px; font-weight: 800; line-height: 1.26; letter-spacing: -0.025em; }
.t-h2  { font-size: 22px; font-weight: 750; line-height: 1.32; letter-spacing: -0.02em; }
.t-h3  { font-size: 18px; font-weight: 700; line-height: 1.4; letter-spacing: -0.01em; }
.t-body-l { font-size: 17px; line-height: 1.6; }
.t-body { font-size: 15px; line-height: 1.6; }
.t-label { font-size: 14px; font-weight: 700; line-height: 1.4; }
.t-caption { font-size: 12.5px; line-height: 1.5; color: var(--muted); }
.t-soft { color: var(--ink-soft); }
.t-muted { color: var(--muted); }
.t-brand { color: var(--brand-600); }
.t-center { text-align: center; }

/* 영어 문장. 한글 본문과 다른 리듬으로 읽혀야 해서 자간·굵기를 따로 준다. */
.t-en {
  font-size: 21px; font-weight: 600; line-height: 1.45;
  letter-spacing: -0.01em; word-break: normal;
}

/* ── 셸 ───────────────────────────────────────────────────── */

.env-banner {
  --env-banner-h: 34px;
  display: flex; align-items: center; justify-content: center; gap: var(--space-2);
  height: 34px; background: #17171c; color: #fff; font-size: 12.5px; font-weight: 600;
}
.env-banner__tag {
  background: var(--brand-500); border-radius: var(--radius-pill);
  padding: 1px 8px; font-size: 11px; letter-spacing: .04em;
}
body.has-env-banner { --env-banner-h: 34px; }

.shell {
  width: 100%; max-width: var(--shell-max); margin: 0 auto;
  padding: 0 var(--space-4);
}
@media (max-width: 359px) { .shell { padding: 0 14px; } }

.page {
  min-height: 100dvh;
  display: flex; flex-direction: column;
  background: var(--surface);
}
/**
 * 🔴 여기서 `padding` 단축을 쓰면 안 된다.
 *
 * 이 클래스는 늘 `.shell` 과 **같은 요소**에 붙는다(`class="page__body shell"`).
 * `.shell` 이 좌우 16px 을 주는데, 단축 padding 은 좌우까지 함께 쓰므로 0 으로 덮어 버린다.
 * 둘은 특이도가 같고 이 규칙이 뒤에 있어서 이쪽이 이긴다 →
 * **모든 화면의 본문이 화면 끝에 딱 붙는다.**
 *
 * 2026-09-16 에 실제로 그렇게 나갔다. 카드에는 안쪽 여백이 있어 스크린샷으로는 멀쩡해 보이고,
 * 가로 오버플로 검사(scrollWidth === clientWidth)도 통과한다 — 글자가 끝에 붙는 건
 * 넘치는 게 아니기 때문이다. 여백은 눈이 아니라 **숫자로** 확인할 것:
 *   getComputedStyle(document.querySelector('.page__body')).paddingLeft
 */
.page__body {
  flex: 1;
  padding-block: var(--space-6) var(--space-4);
  animation: page-in var(--motion-base) var(--ease-out) both;
}
@keyframes page-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* 하단 고정 행동. 엄지로 누르는 자리라 항상 화면 아래에 붙어 있다. */
.page__action {
  position: sticky; bottom: 0;
  /* 🔴 padding 단축을 쓰지 않는다 — .shell 과 같이 붙는 요소라 좌우가 0 으로 덮인다. */
  padding-block: var(--space-3) calc(var(--space-4) + env(safe-area-inset-bottom));
  background: linear-gradient(to top, var(--surface) 72%, rgb(255 255 255 / 0));
}

.stack { display: flex; flex-direction: column; gap: var(--space-4); }
.stack-2 { display: flex; flex-direction: column; gap: var(--space-2); }
.stack-3 { display: flex; flex-direction: column; gap: var(--space-3); }
.stack-6 { display: flex; flex-direction: column; gap: var(--space-6); }
.stack-8 { display: flex; flex-direction: column; gap: var(--space-8); }
/* 🔑 그룹 사이 간격. 그룹 '안'(12~16px)의 2배 이상이어야 덩어리로 읽힌다 —
   24px 이었을 땐 내부 16~20px 와 1.2~1.5배 차이뿐이라 전부 한 줄로 뭉개져 보였다. */
.stack-10 { display: flex; flex-direction: column; gap: var(--space-10); }

/* ── 상단 진행 ────────────────────────────────────────────── */

.topbar { position: sticky; top: 0; z-index: 20; background: var(--surface); }
.topbar__bar { height: 3px; background: var(--line); }
.topbar__bar > span {
  display: block; height: 100%; background: var(--brand-500);
  border-radius: 0 var(--radius-pill) var(--radius-pill) 0;
  transition: width var(--motion-slow) var(--ease-out);
}
.topbar__row {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  gap: var(--space-2);
  max-width: var(--shell-max); margin: 0 auto;
  padding: var(--space-3) var(--space-4);
}
.topbar__step { font-size: 13px; font-weight: 700; color: var(--muted); }
.topbar__exit { justify-self: end; font-size: 13px; font-weight: 600; color: var(--muted); }

/* ── 로고 ─────────────────────────────────────────────────── */

/* 공식 워드마크 이미지. width/height 속성은 비율만 알려 주고, 실제 크기는 높이로 정한다. */
.logo { display: block; width: auto; }
.logo--xs { height: 17px; }
.logo--sm { height: 24px; }
.logo--lg { height: 38px; }

/* 🔴 :hover 는 전부 `@media (hover: hover)` 안에 둔다(2026-09-23).
   안드로이드 브라우저는 마지막으로 누른 요소에 :hover 를 **계속 남긴다** — 누르고 새 탭에서 돌아오면
   그 버튼만 brand-600(#E55A00)으로 10% 어둡게 보여 "여기만 색이 다르다"로 읽혔다(실기기 픽셀로 확인).
   터치 피드백은 :active(scale)가 맡는다. 새 :hover 규칙도 같은 방식으로 감쌀 것. */
/* ── 버튼 ─────────────────────────────────────────────────── */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  min-height: 54px; padding: 0 var(--space-5);
  border: 0; border-radius: var(--radius-md);
  font-size: 16px; font-weight: 700; letter-spacing: -0.01em;
  cursor: pointer; text-align: center;
  transition: transform var(--motion-fast) var(--ease-out),
              background-color var(--motion-fast) var(--ease-out),
              opacity var(--motion-fast) var(--ease-out);
}
.btn:active:not(:disabled) { transform: scale(0.985); }
.btn:disabled { cursor: not-allowed; }

.btn--block { display: flex; width: 100%; }
.btn--primary { background: var(--brand-500); color: #fff; }
@media (hover: hover) { .btn--primary:hover:not(:disabled) { background: var(--brand-600); } }
.btn--primary:disabled { background: #d7d8dc; color: #fff; }
.btn--ghost {
  background: var(--surface); color: var(--brand-600);
  box-shadow: inset 0 0 0 1.5px var(--brand-500);
}
@media (hover: hover) { .btn--ghost:hover { background: var(--brand-050); } }
.btn--quiet { background: var(--surface-soft); color: var(--ink-soft); }
@media (hover: hover) { .btn--quiet:hover { background: #ececf0; } }
.btn--dark { background: var(--ink); color: #fff; }
/* 흰 보조 버튼 — 주 버튼 아래에 두는 '덜 눈에 띄는' 선택지(엔딩 '소리튠 둘러보기') */
.btn--white { background: var(--surface); color: var(--ink-soft); border: 1px solid var(--line); }
@media (hover: hover) { .btn--white:hover { background: var(--surface-soft); } }
.btn--text {
  min-height: 44px; background: none; color: var(--muted);
  font-size: 14px; font-weight: 600; text-decoration: underline; text-underline-offset: 3px;
}
.btn--sm { min-height: 44px; font-size: 14.5px; padding: 0 var(--space-4); }

/* ── 카드 ─────────────────────────────────────────────────── */

.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-xl); padding: var(--space-5);
}
.card--soft { background: var(--surface-soft); border-color: transparent; }
.card--brand { background: var(--brand-050); border-color: #ffdcc2; }

.hint {
  display: flex; gap: var(--space-3); align-items: flex-start;
  background: var(--info-bg); border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-4);
  font-size: 14px; line-height: 1.55; color: #2a4a77;
}
.hint__icon { flex: none; font-size: 15px; line-height: 1.5; }

.notice {
  background: var(--brand-050); border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-4);
  font-size: 14px; color: var(--brand-700); font-weight: 600;
}

/* ── 시작 화면 ────────────────────────────────────────────── */

.start { background: linear-gradient(180deg, var(--brand-050) 0%, var(--surface) 46%); }
.start__hero { margin-top: var(--space-4); }
.start__hero em {
  display: block; font-style: normal;
  font-size: 42px; font-weight: 800; line-height: 1.05; letter-spacing: -0.04em;
  color: var(--brand-500);
}
.start__hero strong {
  display: block; font-size: 34px; font-weight: 800; line-height: 1.16;
  letter-spacing: -0.035em; margin-top: 2px;
}

/* 2×2 격자(2026-09-17) — 세로 4줄이 화면의 1/3 을 먹어 진단 버튼이 아래로 밀렸다.
   🔑 칸이 좁아(≈171px) 아이콘을 줄이고 글자는 한 줄씩만 쓴다. 문구를 늘리면 줄바꿈이 생긴다. */
/* 1×4 세로 목록(2026-09-21 복귀). 2×2 는 세로를 아꼈지만 칸이 좁아(≈171px) 아이콘·글자를
   줄여야 했고, 그래서 네 항목이 카드처럼 보였다. 한 줄에 하나면 폭 제약이 사라져 원래 크기로 돌아간다.
   🔴 카드가 아니다 — 이건 '읽을 것'이라 테두리·배경·radius 를 주면 아래 track-btn(누를 것)과
   구분이 사라진다(DS §2.2 "페이지 구획을 위해 카드를 남발하지 않는다"). 아이콘칩만 남긴다. */
.features { display: flex; flex-direction: column; gap: var(--space-3); }
.features li {
  display: flex; align-items: center; gap: var(--space-4); min-width: 0;
}
.feature__icon {
  flex: none; width: 40px; height: 40px; border-radius: var(--radius-md);
  display: grid; place-items: center;
  background: var(--brand-050); color: var(--brand-600);
}
.feature__icon svg { width: 20px; height: 20px; }
.feature__title { display: block; font-size: 16px; line-height: 1.35; font-weight: 700; letter-spacing: -0.02em; }
.feature__sub { display: block; font-size: 13px; line-height: 1.4; color: var(--muted); }

/* 지난 기록 카드 — 진행 중 / 완료 결과가 한 카드에 같이 들어갈 수 있다. */
.recent { display: flex; flex-direction: column; gap: var(--space-4); padding: var(--space-4) var(--space-5); }
.recent__item { display: flex; flex-direction: column; gap: var(--space-2); }
.recent__item + .recent__item { padding-top: var(--space-4); border-top: 1px solid var(--line); }
/* 제목 오른쪽에 시각을 붙인다 — 타입 줄과 섞이지 않게 줄을 나눈다. */
.recent__head { display: flex; align-items: baseline; gap: var(--space-2); }
.recent__type { font-size: 16px; font-weight: 700; letter-spacing: -0.02em; margin-bottom: 2px; }

/* 떠다니는 말풍선 + 버튼. 5days(.count-bubble)와 같은 색·움직임이다.
   ⚠️ 말풍선은 가운데 정렬 — 버튼 왼쪽 끝에 붙이면 좁은 화면에서 꼬리가 버튼 밖으로 나간다(5days 실측). */
.float-cta { display: flex; flex-direction: column; align-items: center; gap: var(--space-2); margin-top: var(--space-2); }
.float-cta > .btn { width: 100%; }
.float-tip {
  position: relative;
  padding: 6px var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--ink); color: #fff;
  font-size: 13px; font-weight: 700; line-height: 1.45;
}
.float-tip::after {
  content: '';
  position: absolute; left: 50%; bottom: -5px;
  width: 12px; height: 8px; margin-left: -6px;
  background: inherit;
  clip-path: polygon(0 0, 100% 0, 50% 100%);
}

/* 갈래 선택 — 이 화면이 "녹음하기 싫다"는 사람을 놓치지 않는 유일한 지점이다.
   카드였던 것을 CTA 크기로 줄였다(2026-09-17). 무엇을·몇 분인지만 남긴다. */
.tracks { display: flex; flex-direction: column; gap: var(--space-2); }
.track-btn {
  display: flex; align-items: center; gap: var(--space-3);
  width: 100%; min-height: 62px; padding: var(--space-3) var(--space-4) var(--space-3) var(--space-5);
  border: 0; border-radius: var(--radius-md);
  background: var(--surface); color: var(--brand-600);
  box-shadow: inset 0 0 0 1.5px var(--brand-500);
  text-align: left; cursor: pointer;
  transition: transform var(--motion-fast) var(--ease-out),
              background-color var(--motion-fast) var(--ease-out);
}
@media (hover: hover) { .track-btn:hover { background: var(--brand-050); } }
.track-btn:active { transform: scale(0.985); }
.track-btn--primary { background: var(--brand-500); color: #fff; box-shadow: none; }
@media (hover: hover) { .track-btn--primary:hover { background: var(--brand-600); } }
.track-btn__main { flex: 1; min-width: 0; }
/* 🔴 아래 span 들은 block 이어야 한다. 기본 inline 이면 제목과 설명이 한 줄로 이어 붙는다. */
.track-btn__title { display: block; font-size: 17px; font-weight: 750; line-height: 1.3; letter-spacing: -0.02em; }
.track-btn__desc { display: block; margin-top: 1px; font-size: 12.5px; font-weight: 500; line-height: 1.4; color: var(--ink-soft); }
.track-btn--primary .track-btn__desc { color: rgb(255 255 255 / 86%); }
.track-btn__time {
  flex: none; border-radius: var(--radius-pill); padding: 4px 10px;
  font-size: 12.5px; font-weight: 700;
  background: var(--brand-050); color: var(--brand-700);
}
.track-btn--primary .track-btn__time { background: rgb(255 255 255 / 22%); color: #fff; }

/* ── 시작 화면: 상세 카드 + 플로팅 선택 바 (2026-09-23) ──────────── */
/* 옛 1×4 기능 목록(.features)과 본문 속 갈래 버튼(.track-btn)을 대신한다.
   진단 선택을 화면 아래에 띄워 두었으니 본문은 '무엇을 하게 되는지' 보여 주는 데만 쓴다. */

/* 🔴 플로팅 바가 마지막 카드를 가리지 않게 본문 아래를 바 높이만큼 비운다. */
.start .page__body { padding-block-end: calc(112px + env(safe-area-inset-bottom)); }
/* 여백 두 선(2026-09-23 실기기 피드백): **글자 24px · 카드 16px**.
   테두리 없는 글자(로고·제목·소제목)가 16px 이면 화면 끝에 붙어 보였다. 카드는 테두리가 있어 16px 로도
   한 덩어리로 읽히고, 넓어야 미리보기(파형·블록)가 산다 — 24px 로 맞췄더니 설명이 어색하게 끊겼다.
   🔑 차이는 8px 로 확실히 둔다. 4px 처럼 어중간하면 맞추려다 틀린 것으로 보인다.
   🔴 padding-inline 만 쓴다 — .shell 과 같은 요소라 단축 padding 은 세로 여백까지 덮는다(위 .page__body 주석).
   플로팅 바는 카드 선(16px)에 맞춘다(.float-bar__inner). */
.start .page__body { padding-inline: var(--space-6); }
.start .step-card, .start .recent { margin-inline: calc(var(--space-2) * -1); }
@media (max-width: 359px) {
  .start .page__body { padding-inline: 18px; }
  .start .step-card, .start .recent { margin-inline: -4px; }
}

.steps-intro { display: flex; flex-direction: column; gap: var(--space-4); }
.steps-intro__head { display: flex; flex-direction: column; gap: var(--space-2); margin-bottom: var(--space-2); }

.step-card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-2xl); padding: var(--space-5);
  box-shadow: 0 2px 10px rgb(23 23 28 / 4%);
}
.step-card__top { display: flex; align-items: center; justify-content: space-between; }
.step-card__num { font-size: 15px; font-weight: 800; color: var(--brand-500); letter-spacing: -0.01em; }
.step-card__tag {
  border-radius: var(--radius-pill); padding: 3px 10px;
  font-size: 12px; font-weight: 700; line-height: 1.5;
  background: var(--surface-soft); color: var(--ink-soft);
}
/* 리스닝 진단에는 없는 단계 — 녹음이 싫은 사람이 '이건 안 해도 되는구나'를 알아야 한다. */
.step-card__tag--full { background: var(--info-bg); color: var(--info); }
.step-card__title { margin-top: var(--space-3); font-size: 24px; font-weight: 800; line-height: 1.3; letter-spacing: -0.03em; }
.step-card__desc { margin-top: var(--space-1); font-size: 15px; line-height: 1.6; color: var(--ink-soft); }

/* 미리보기 — 실제 진단 화면 부품의 축소판. 눌러지면 안 된다. */
.step-card__preview {
  margin-top: var(--space-4); padding: var(--space-4);
  border-radius: var(--radius-xl); background: var(--brand-050);
  display: flex; flex-direction: column; gap: var(--space-3);
  pointer-events: none; user-select: none;
}
.pv-player { display: flex; align-items: center; gap: var(--space-3); }
.pv-player .wave { flex: 1; }
.pv-play {
  flex: none; width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center; background: var(--brand-500); color: #fff;
}
.pv-field {
  background: var(--surface); border: 1.5px solid var(--line); border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-4); font-size: 14px; color: var(--muted);
}
.pv-caret { display: inline-block; width: 1.5px; height: 15px; margin-left: 2px; vertical-align: -2px; background: var(--brand-500); animation: pv-blink 1s steps(1) infinite; }
@keyframes pv-blink { 50% { opacity: 0; } }

.pv-speak { align-items: center; background: var(--surface-soft); }
.pv-sentence {
  align-self: stretch; text-align: center;
  font-size: 17px; font-weight: 600; line-height: 1.45; letter-spacing: -0.01em; word-break: normal;
}
.pv-mic {
  width: 64px; height: 64px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--surface); color: var(--ink); box-shadow: var(--shadow-soft);
}

.pv-compare { background: var(--surface-soft); }
.pv-row { display: flex; align-items: center; gap: var(--space-3); }
.pv-row .wave { flex: 1; height: 26px; }
.pv-row__label { flex: none; width: 62px; display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 700; color: var(--ink-soft); }
.pv-dot { width: 7px; height: 7px; border-radius: 50%; }
.pv-dot--native { background: var(--brand-500); }
.pv-dot--mine { background: var(--info); }
.pv-wave--mine i { background: var(--info); opacity: .45; }

.pv-blocks { background: var(--surface-soft); gap: var(--space-2); }
.pv-block {
  display: flex; align-items: center; gap: var(--space-3);
  border-radius: var(--radius-lg); padding: var(--space-3) var(--space-4);
  color: #fff; font-size: 16px; font-weight: 700; letter-spacing: -0.01em; word-break: normal;
}
.pv-block[data-accent="a"] { background: var(--block-a); }
.pv-block[data-accent="b"] { background: var(--block-b); }
.pv-block[data-accent="c"] { background: var(--block-c); }

/* ── 미리보기 애니메이션 ─────────────────────────────────────
   카드마다 6초 한 바퀴. 멈춰 있으면 눌러야 할 버튼처럼 보였다(2026-09-23 사용자 피드백) —
   실제 진단이 '진행되는' 모습을 보여 주면 시연으로 읽힌다. CSS 만 쓴다(첫 화면 JS 금지, 스펙 §20).
   🔑 keyframes 의 % 가 곧 대본이다. 같은 카드 안의 요소는 같은 길이(--pv-loop)를 써야 박자가 안 어긋난다. */
.step-card__preview { --pv-loop: 6s; }

/* 재생 진행 파형 — 흐린 파형 위에 진한 파형을 겹쳐 왼쪽부터 드러낸다. */
.pv-wave { position: relative; flex: 1; display: block; min-width: 0; }
.pv-wave .wave { height: 28px; }
.pv-wave__top { position: absolute; inset: 0; clip-path: inset(0 100% 0 0); }
.pv-wave--brand .pv-wave__base i { background: var(--brand-500); opacity: .25; }
.pv-wave--brand .pv-wave__top i { background: var(--brand-500); opacity: 1; }
.pv-wave--mine .pv-wave__base i { background: var(--info); opacity: .22; }
.pv-wave--mine .pv-wave__top i { background: var(--info); opacity: 1; }

@keyframes pv-sweep-a {   /* 8%→55% 재생, 95% 까지 유지 */
  0%, 8%   { clip-path: inset(0 100% 0 0); opacity: 1; }
  55%, 94% { clip-path: inset(0 0 0 0); opacity: 1; }
  100%     { clip-path: inset(0 0 0 0); opacity: 0; }
}
@keyframes pv-sweep-b {   /* 비교 2번째 줄: 52%→92% */
  0%, 52%  { clip-path: inset(0 100% 0 0); opacity: 1; }
  92%, 96% { clip-path: inset(0 0 0 0); opacity: 1; }
  100%     { clip-path: inset(0 0 0 0); opacity: 0; }
}
@keyframes pv-sweep-c {   /* 비교 1번째 줄: 6%→46% */
  0%, 6%   { clip-path: inset(0 100% 0 0); opacity: 1; }
  46%, 96% { clip-path: inset(0 0 0 0); opacity: 1; }
  100%     { clip-path: inset(0 0 0 0); opacity: 0; }
}

/* 01 듣고 — 재생 → 파형이 차오름 → 받아쓰기 칸에 글자가 찍힌다 */
.pv-play { position: relative; }
.pv-play__i { position: absolute; inset: 0; display: grid; place-items: center; }
.pv-play__i--pause { opacity: 0; }
.pv-listen .pv-play { animation: pv-press var(--pv-loop) var(--ease-out) infinite; }
.pv-listen .pv-play__i--play  { animation: pv-off-mid var(--pv-loop) steps(1) infinite; }
.pv-listen .pv-play__i--pause { animation: pv-on-mid var(--pv-loop) steps(1) infinite; }
.pv-listen .pv-wave__top { animation: pv-sweep-a var(--pv-loop) linear infinite; }
@keyframes pv-press { 0%, 4% { transform: scale(1); } 6% { transform: scale(.88); } 9%, 100% { transform: scale(1); } }
@keyframes pv-on-mid  { 0% { opacity: 0; } 7% { opacity: 1; } 56% { opacity: 0; } }
@keyframes pv-off-mid { 0% { opacity: 1; } 7% { opacity: 0; } 56% { opacity: 1; } }

.pv-field { position: relative; }
.pv-field__typed {
  position: absolute; left: var(--space-4); top: 50%; transform: translateY(-50%);
  color: var(--ink); font-weight: 600; white-space: nowrap; word-break: normal;
  clip-path: inset(0 100% 0 0);
}
.pv-listen .pv-field__ph    { animation: pv-ph var(--pv-loop) steps(1) infinite; }
.pv-listen .pv-field__typed { animation: pv-type var(--pv-loop) steps(24) infinite; }
@keyframes pv-ph   { 0% { opacity: 1; } 58% { opacity: 0; } 97% { opacity: 1; } }
@keyframes pv-type {
  0%, 58%  { clip-path: inset(0 100% 0 0); opacity: 1; }
  88%, 96% { clip-path: inset(0 0 0 0); opacity: 1; }
  100%     { clip-path: inset(0 0 0 0); opacity: 0; }
}

/* 02 말하고 — 마이크가 눌려 녹음 중(주황·맥놀이·실시간 파형) → 완료 */
.pv-mic { position: relative; animation: pv-rec var(--pv-loop) var(--ease-out) infinite; }
.pv-mic svg { position: relative; }
.pv-mic__ring { position: absolute; inset: 0; opacity: 0; animation: pv-on-rec var(--pv-loop) steps(1) infinite; }
.pv-mic__ring i {
  position: absolute; inset: -8px; border-radius: 50%; border: 2px solid var(--brand-500);
  animation: mic-pulse 1.2s var(--ease-out) infinite;
}
@keyframes pv-rec {
  0%, 12%  { background: var(--surface); color: var(--ink); transform: scale(1); }
  14%      { transform: scale(.92); }
  17%, 72% { background: var(--brand-500); color: #fff; transform: scale(1); }
  76%, 100%{ background: var(--surface); color: var(--ink); }
}
@keyframes pv-on-rec { 0% { opacity: 0; } 16% { opacity: 1; } 73% { opacity: 0; } }

.wave.pv-live { height: 26px; width: 120px; justify-content: center; opacity: .25; animation: pv-live-win var(--pv-loop) steps(1) infinite; }
.pv-live i { background: var(--brand-500); max-width: 4px; animation: pv-bounce .7s var(--ease-soft) infinite alternate; animation-delay: calc(var(--i) * -110ms); transform-origin: center; }
@keyframes pv-live-win { 0% { opacity: .25; } 16% { opacity: 1; } 73% { opacity: .25; } }
@keyframes pv-bounce { from { transform: scaleY(.35); } to { transform: scaleY(1.1); } }

.pv-status { display: grid; font-size: 13px; font-weight: 700; color: var(--ink-soft); }
.pv-status__s { grid-area: 1 / 1; text-align: center; opacity: 0; display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
.pv-status__s--1 { animation: pv-st1 var(--pv-loop) steps(1) infinite; }
.pv-status__s--2 { animation: pv-st2 var(--pv-loop) steps(1) infinite; color: var(--brand-600); }
.pv-status__s--3 { animation: pv-st3 var(--pv-loop) steps(1) infinite; color: var(--success); }
@keyframes pv-st1 { 0% { opacity: 1; } 16% { opacity: 0; } }
@keyframes pv-st2 { 0% { opacity: 0; } 16% { opacity: 1; } 73% { opacity: 0; } }
@keyframes pv-st3 { 0% { opacity: 0; } 73% { opacity: 1; } }
.pv-rec-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--brand-500); animation: pv-blink 1s steps(1) infinite; }

/* 03 비교하고 — 원어민 줄이 재생되고, 이어서 내 소리 줄이 재생된다(번갈아 듣기) */
.pv-row { padding: 6px var(--space-2); margin: 0 calc(var(--space-2) * -1); border-radius: var(--radius-md); }
.pv-row--1 { animation: pv-row1 var(--pv-loop) steps(1) infinite; }
.pv-row--2 { animation: pv-row2 var(--pv-loop) steps(1) infinite; }
.pv-row--1 .pv-wave__top { animation: pv-sweep-c var(--pv-loop) linear infinite; }
.pv-row--2 .pv-wave__top { animation: pv-sweep-b var(--pv-loop) linear infinite; }
@keyframes pv-row1 { 0% { background: transparent; } 6% { background: var(--surface); } 47% { background: transparent; } }
@keyframes pv-row2 { 0% { background: transparent; } 52% { background: var(--surface); } 93% { background: transparent; } }

/* 04 소리블록 — 블록이 하나씩 재생되고, 마지막에 '착' 붙어 한 문장이 된다 */
.pv-block { opacity: .4; }
.pv-block .block__wave i { animation: pv-bounce .6s var(--ease-soft) infinite alternate; animation-delay: calc(var(--i) * -120ms); }
.pv-block--1 { animation: pv-blk1 var(--pv-loop) var(--ease-snap) infinite; }
.pv-block--2 { animation: pv-blk2 var(--pv-loop) var(--ease-snap) infinite; }
.pv-block--3 { animation: pv-blk3 var(--pv-loop) var(--ease-snap) infinite; }
@keyframes pv-blk1 {
  0%, 4%   { opacity: .4; transform: none; }
  6%, 22%  { opacity: 1; transform: scale(1.02); }
  25%, 74% { opacity: .4; transform: none; }
  80%, 94% { opacity: 1; transform: none; }
  100%     { opacity: .4; }
}
@keyframes pv-blk2 {
  0%, 26%  { opacity: .4; transform: none; }
  28%, 44% { opacity: 1; transform: scale(1.02); }
  47%, 74% { opacity: .4; transform: none; }
  80%, 94% { opacity: 1; transform: translateY(-8px); }
  100%     { opacity: .4; transform: none; }
}
@keyframes pv-blk3 {
  0%, 48%  { opacity: .4; transform: none; }
  50%, 66% { opacity: 1; transform: scale(1.02); }
  69%, 74% { opacity: .4; transform: none; }
  80%, 94% { opacity: 1; transform: translateY(-16px); }
  100%     { opacity: .4; transform: none; }
}

/* 모션 줄이기 — 멈춘 '완료' 상태로 보여 준다(파형은 다 찬 채, 블록은 모두 선명하게). */
@media (prefers-reduced-motion: reduce) {
  .step-card__preview *, .step-card__preview { animation: none !important; }
  .pv-wave__top, .pv-field__typed { clip-path: none; }
  .pv-field__ph { opacity: 0; }
  .pv-block { opacity: 1; }
  .pv-status__s--3 { opacity: 1; }
}

/* 플로팅 선택 바. 두 버튼을 가로로 — 세로로 쌓으면 화면 아래 ~140px 을 계속 가린다. */
.float-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  padding: var(--space-5) 0 calc(var(--space-3) + env(safe-area-inset-bottom));
  background: linear-gradient(to top, var(--surface) 70%, rgb(255 255 255 / 0));
}
.float-bar__inner {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2);
  max-width: var(--shell-max); margin: 0 auto; padding: 0 var(--space-4);
}
@media (max-width: 359px) { .float-bar__inner { padding: 0 14px; } }
.float-bar__btn {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
  min-height: 62px; padding: var(--space-2) var(--space-2);
  border: 0; border-radius: var(--radius-md);
  background: var(--surface); color: var(--ink);
  box-shadow: inset 0 0 0 1.5px var(--ink), var(--shadow-soft);
  cursor: pointer; text-align: center;
  transition: transform var(--motion-fast) var(--ease-out), background-color var(--motion-fast) var(--ease-out);
}
.float-bar__btn:active { transform: scale(0.97); }
.float-bar__btn--primary { background: var(--brand-500); color: #fff; box-shadow: var(--shadow-soft); }
@media (hover: hover) { .float-bar__btn--primary:hover { background: var(--brand-600); } }   /* 터치에서 :hover 가 남지 않게(fix/touch-hover-sticky) */
.float-bar__title { font-size: 16px; font-weight: 750; line-height: 1.3; letter-spacing: -0.02em; }
.float-bar__sub { font-size: 12px; font-weight: 600; line-height: 1.4; color: var(--ink-soft); }
.float-bar__btn--primary .float-bar__sub { color: rgb(255 255 255 / 88%); }
/* 전체 소리진단 = 소리블록 블루(--block-a). 2026-10-07 디자인 피드백 — 흰 버튼은 '덜 중요한 쪽'으로 읽혀
   두 갈래가 대등하게 보이도록 채웠다. 주황은 여전히 리스닝 하나뿐(DS §2.1). */
.float-bar__btn--full { background: var(--block-a); color: #fff; box-shadow: var(--shadow-soft); }
.float-bar__btn--full .float-bar__sub { color: rgb(255 255 255 / 88%); }

/* ── 오디오 플레이어 ──────────────────────────────────────── */

.player {
  display: flex; align-items: center; gap: var(--space-4);
  background: var(--surface-soft); border-radius: var(--radius-xl);
  padding: var(--space-4);
}
.player--hero { background: var(--brand-050); padding: var(--space-5); }

.play-btn {
  flex: none; width: 52px; height: 52px; border: 0; border-radius: 50%;
  background: var(--brand-500); color: #fff; cursor: pointer;
  display: grid; place-items: center;
  transition: transform var(--motion-fast) var(--ease-out), background-color var(--motion-fast);
}
@media (hover: hover) { .play-btn:hover { background: var(--brand-600); } }
.play-btn:active { transform: scale(0.94); }
/* 보조 재생 컨트롤. 주 행동(btn--primary)과 오렌지로 경쟁하지 않게 한 단계 낮춘다(DS §2.1).
   ⚠️ 38px 이었다 — DS §10 터치 타깃 최소 44px 에 미달했다. */
.play-btn--sm {
  width: 44px; height: 44px;
  background: var(--surface); color: var(--ink);
  box-shadow: inset 0 0 0 1.5px var(--line);
}
@media (hover: hover) { .play-btn--sm:hover { background: var(--surface-soft); } }
.play-btn[aria-pressed="true"] { background: var(--ink); }
/* 🔴 --sm 은 평상시 글자색이 ink 라, 재생 중 배경이 ink 가 되면 아이콘이 사라진다. 같이 뒤집는다. */
.play-btn--sm[aria-pressed="true"] { color: #fff; box-shadow: none; }

.player__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.player__time { font-size: 12px; font-weight: 600; color: var(--muted); }

/* 파형. 이 제품에서 가장 중요한 UI 자산이라 모든 주요 화면에 같은 형태로 나온다(스펙 §14). */
/* 🔑 막대 너비를 고정하고 space-between 으로 양 끝까지 편다(2026-10-07 피드백). 예전엔 flex:1 + max-width 4px
   이라 막대가 4px 에서 멈추고 오른쪽이 텅 비어, 라운드 박스 안에서 미완성처럼 보였다. */
.wave { display: flex; align-items: center; justify-content: space-between; gap: 2px; height: 30px; }
.wave i {
  /* 좁은 폰(320px)에선 줄어들 수 있게 — 고정이면 넘쳐서 미리보기 진행 막대가 끝까지 안 칠해졌다(자체 검수 #3) */
  display: block; flex: 0 1 3px; min-width: 1.5px;
  height: var(--h, 40%); border-radius: var(--radius-pill);
  background: #c9cad0;
  transition: background-color 90ms linear, transform 90ms linear;
}
.wave--brand i { background: var(--brand-500); opacity: .35; }
/* 재생 위치까지의 막대만 진하게 — 진행 상태가 곧 파형이다 */
.wave i.is-played { background: var(--brand-500); opacity: 1; }
.wave--live i { background: var(--brand-500); transform-origin: center; }

.player.is-playing .wave i { animation: wave-idle 1.1s var(--ease-out) infinite; }
@keyframes wave-idle { 0%, 100% { transform: scaleY(1); } 50% { transform: scaleY(1.35); } }

/* ── 입력 ─────────────────────────────────────────────────── */

.field {
  width: 100%; min-height: 108px; resize: none;
  border: 1.5px solid var(--line); border-radius: var(--radius-lg);
  padding: var(--space-4);
  font-size: 17px; line-height: 1.55; background: var(--surface);
  transition: border-color var(--motion-fast) var(--ease-out);
}
.field::placeholder { color: #b4b5bc; }
.field:focus { outline: none; border-color: var(--brand-500); }

/* ── 정답 공개 (STEP 2) ───────────────────────────────────── */

.reveal-row { display: flex; flex-direction: column; gap: var(--space-2); }
.reveal-row__label { font-size: 12.5px; font-weight: 700; color: var(--muted); }
.reveal-box {
  background: var(--surface-soft); border-radius: var(--radius-lg);
  padding: var(--space-4);
}
.reveal-box--answer { background: var(--brand-050); }
/* 다 맞았거나 비워 두고 넘어간 경우 — 강조할 '놓친 소리'가 없으니 주황 배경도 쓰지 않는다 */
.reveal-box--plain { background: var(--surface-soft); }
/* 실제 문장이 먼저 읽히게: 실제 = 굵고 크게, 내가 적은 문장 = 한 단계 작게(2026-10-07 피드백) */
.t-en--answer { font-weight: 750; }
.t-en-sub {
  font-size: 17px; font-weight: 500; line-height: 1.5; color: var(--ink-soft);
  letter-spacing: -0.01em; word-break: normal;
}
.reveal-perfect {
  display: flex; align-items: center; gap: 6px;
  font-size: 17px; font-weight: 750; color: var(--success);
}

/* 놓친 단어. 사용자가 "틀렸다"가 아니라 "이 소리를 놓쳤다"로 읽어야 한다. */
.w-miss {
  background: var(--brand-500); color: #fff;
  border-radius: 6px; padding: 1px 6px; margin: 0 1px;
  font-weight: 700;
}
.w-extra { color: var(--muted); text-decoration: line-through; text-decoration-color: #c9cad0; }

/* ── 녹음 (STEP 3) ────────────────────────────────────────── */

.recorder { display: flex; flex-direction: column; align-items: center; gap: var(--space-4); }

.mic-btn {
  position: relative; width: 88px; height: 88px; border: 0; border-radius: 50%;
  background: var(--surface); color: var(--ink); cursor: pointer;
  display: grid; place-items: center;
  /* 주황 테두리(2026-10-07 피드백) — 흰 원만 있으면 회색 배경 위에서 '누르는 곳'인지 애매했다.
     채움은 녹음 중(.is-recording)에만 쓴다 — 주황 채움 CTA 와 경쟁하지 않게(DS §2.1). */
  box-shadow: inset 0 0 0 2px var(--brand-500), var(--shadow-float);
  transition: transform var(--motion-fast) var(--ease-out), background-color var(--motion-base);
}
.mic-btn:active { transform: scale(0.96); }
.mic-btn:disabled { background: #d7d8dc; box-shadow: none; cursor: not-allowed; }

/* 녹음 중 맥놀이. 하나의 링만 쓴다 — 여러 겹이면 시끄럽다(스펙 §15). */
.mic-btn::before {
  content: ""; position: absolute; inset: -10px; border-radius: 50%;
  border: 2px solid var(--brand-500); opacity: 0;
}
/* DS §7.4 — Listening 상태가 Orange 채움이다. 빨강(danger)이 아니다.
   ⚠️ 링은 하나만 유지한다 — DS 는 2개라고 하지만 diagnosis 스펙 §15 가 "여러 겹이면 시끄럽다"로
      1개를 명시했다. 프로젝트 스펙이 더 구체적이라 그쪽을 따른다. */
.mic-btn.is-recording { background: var(--brand-500); color: #fff; box-shadow: var(--shadow-float); }
.mic-btn.is-recording::before { animation: mic-pulse 1.5s var(--ease-out) infinite; }
@keyframes mic-pulse {
  0%   { transform: scale(0.94); opacity: .55; }
  100% { transform: scale(1.25); opacity: 0; }
}

.rec-timer { font-size: 26px; font-weight: 800; letter-spacing: -0.02em; }
.rec-hint { font-size: 14px; color: var(--muted); }

/* ── 비교 (STEP 4) ────────────────────────────────────────── */

.compare { display: flex; flex-direction: column; gap: var(--space-3); }
.compare__card { border: 1px solid var(--line); border-radius: var(--radius-xl); padding: var(--space-4); }
.compare__card.is-active { border-color: var(--brand-500); background: var(--brand-050); }
.compare__label {
  display: flex; align-items: center; gap: var(--space-2);
  font-size: 13px; font-weight: 700; color: var(--ink-soft); margin-bottom: var(--space-3);
}
.compare__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--muted); }
.compare__card--native .compare__dot { background: var(--brand-500); }
.compare__card--mine .compare__dot { background: var(--info); }

.choices { display: flex; flex-direction: column; gap: var(--space-2); }
.choice {
  display: flex; align-items: center; gap: var(--space-3);
  border: 1.5px solid var(--line); border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4); cursor: pointer;
  font-size: 15px; font-weight: 600;
  transition: border-color var(--motion-fast), background-color var(--motion-fast);
}
@media (hover: hover) { .choice:hover { border-color: #ffcaa4; } }
.choice input { position: absolute; opacity: 0; pointer-events: none; }
.choice__box {
  flex: none; width: 21px; height: 21px; border-radius: 6px;
  border: 1.5px solid #c9cad0; display: grid; place-items: center;
  transition: background-color var(--motion-fast), border-color var(--motion-fast);
}
.choice__box svg { opacity: 0; color: #fff; transition: opacity var(--motion-fast); }
.choice:has(input:checked) { border-color: var(--brand-500); background: var(--brand-050); }
.choice:has(input:checked) .choice__box { background: var(--brand-500); border-color: var(--brand-500); }
.choice:has(input:checked) .choice__box svg { opacity: 1; }

/* ── AI 차이 (STEP 5) ─────────────────────────────────────── */

.finding { border: 1px solid var(--line); border-radius: var(--radius-xl); padding: var(--space-4); }
.finding__tag {
  display: inline-block; border-radius: var(--radius-pill); padding: 3px 10px;
  font-size: 11.5px; font-weight: 700;
  background: var(--brand-100); color: var(--brand-700);
}
.finding__title { margin-top: var(--space-3); font-size: 16px; font-weight: 700; line-height: 1.45; }
.finding__rows { margin-top: var(--space-3); display: flex; flex-direction: column; gap: var(--space-2); }
.finding__row { display: flex; gap: var(--space-3); font-size: 14px; line-height: 1.5; }
.finding__who { flex: none; width: 56px; font-weight: 700; color: var(--muted); font-size: 13px; }
.finding__what { flex: 1; color: var(--ink-soft); }
.finding__row--native .finding__what { color: var(--brand-700); font-weight: 600; }

/* ── 소리블록 (STEP 6·7) ──────────────────────────────────── */

.blocks { display: flex; flex-direction: column; gap: var(--space-3); }

.block {
  position: relative;
  display: flex; align-items: center; gap: var(--space-3);
  border: 0; border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-4);
  color: #fff; cursor: pointer; text-align: left;
  box-shadow: var(--shadow-soft);
  transition: transform var(--motion-base) var(--ease-snap),
              box-shadow var(--motion-base) var(--ease-out),
              opacity var(--motion-base) var(--ease-out);
}
.block[data-accent="a"] { background: var(--block-a); }
.block[data-accent="b"] { background: var(--block-b); }
.block[data-accent="c"] { background: var(--block-c); }
.block:active { transform: scale(0.985); }

.block__wave { display: flex; align-items: center; gap: 2px; height: 20px; width: 26px; flex: none; }
.block__wave i { display: block; flex: 1; height: var(--h, 50%); border-radius: var(--radius-pill); background: rgb(255 255 255 / 75%); }
.block.is-playing .block__wave i { animation: wave-idle .9s var(--ease-out) infinite; }
.block__text { flex: 1; font-size: 17px; font-weight: 700; letter-spacing: -0.01em; word-break: normal; }
.block__state { flex: none; width: 26px; height: 26px; display: grid; place-items: center; }
.block__state svg { position: absolute; opacity: 0; transition: opacity var(--motion-base) var(--ease-out); }
.block__state { position: relative; }
.block__state [data-state-play] { opacity: .85; }
.block.is-done .block__state [data-state-play] { opacity: 0; }
.block.is-done .block__state [data-state-check] { opacity: 1; }
.block.is-done { opacity: .82; }
/* 지금 따라 말하는 블록 / 다음에 누를 블록 — 남은 게 무엇인지 화면만 보고 알게(2026-09-29) */
.block.is-active { box-shadow: 0 0 0 3px var(--surface), 0 0 0 5px var(--ink); }
@media (prefers-reduced-motion: no-preference) {
  .block.is-next { animation: block-nudge 1.6s var(--ease-soft) infinite; }
}
@keyframes block-nudge { 0%, 100% { transform: none; } 50% { transform: translateX(4px); } }
/* 리스닝 STEP 6 — 차례로 열기(2026-10-07 디자인 피드백). 지금 블록만 색, 남은 블록은 회색으로 잠근다.
   🔑 다 들은 블록은 '연한 색 + 체크' — 지우지 않는다(다시 들을 수 있어야 한다). */
.block__main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.block__main .block__text { flex: none; }
.block__sub { font-size: 12px; font-weight: 600; line-height: 1.4; color: rgb(255 255 255 / 82%); }
.block__sub:empty { display: none; }
.block__state [data-state-lock] { opacity: 0; }
.block.is-locked[data-accent] {
  background: var(--surface-soft); color: #a3a4ab; box-shadow: none; cursor: default;
}
.block.is-locked .block__wave i { background: #cfd0d5; }
.block.is-locked .block__sub { color: #a3a4ab; }
.block.is-locked .block__state [data-state-play] { opacity: 0; }
.block.is-locked .block__state [data-state-lock] { opacity: 1; }
.block.is-locked:active { transform: none; }
.blocks--seq .block.is-done { opacity: .5; }
.blocks--seq .block.is-done.is-playing { opacity: .8; }
.blocks--seq.is-snapping .block.is-done { opacity: .82; }   /* 셋이 붙는 순간은 다시 선명하게 */
.block-panel { scroll-margin-bottom: 120px; }
.blocks-progress { margin: 0 0 var(--space-2); text-align: center; font-size: 13px; color: var(--ink-soft); }
.blocks-progress[hidden] { display: none; }
/* 전체 STEP 3 — 녹음할 수 없을 때의 출구. 마이크가 막히면 버튼처럼 보이게 올린다(2026-09-30) */
.speak-skip { display: flex; flex-direction: column; align-items: center; gap: var(--space-1); }
.speak-skip[hidden] { display: none; }
.speak-skip.is-emph .btn { background: var(--ink); color: var(--surface); text-decoration: none; border-radius: var(--radius-pill); padding-inline: var(--space-5); }

/* 영어를 아직 감추는 상태(STEP 7 초반) */
.block.is-masked .block__text {
  filter: blur(7px);
  user-select: none;
  transition: filter var(--motion-slow) var(--ease-out);
}

/* STEP 7 판정 뒤 — 바뀐 블록 표시 · 그대로인 블록은 한 단계 흐리게 */
.block.is-kept { opacity: .5; }
.block__badge {
  flex: none; border-radius: var(--radius-pill); padding: 3px 9px;
  background: rgb(255 255 255 / 24%); color: #fff;
  font-size: 12px; font-weight: 800; letter-spacing: -0.01em;
  animation: rise-in var(--motion-base) var(--ease-out) both;
}

/* STEP 7 판정 뒤 순서 — 결과 문구 → 블록 → 두 줄 비교. 제목·한국어 문장(order 0)은 위에 둔 채 스크롤로 넘긴다. */
.transfer--revealed .transfer-head { order: 1; scroll-margin-top: 64px; display: flex; flex-direction: column; gap: var(--space-4); }
.transfer--revealed [data-transfer-blocks] { order: 2; }
.transfer--revealed .transfer-rows { order: 3; }
.transfer-rows { gap: var(--space-5); }
.transfer-bridge { margin-top: var(--space-4); text-align: center; font-size: 15px; font-weight: 700; color: var(--ink-soft); }

/* 블록 교체 — 위로 굴러 나가고 새 블록이 아래에서 올라온다(스펙 §15 block rolling) */
.block.is-rolling-out { animation: roll-out 320ms var(--ease-out) forwards; }
.block.is-rolling-in  { animation: roll-in 380ms var(--ease-snap) both; }
@keyframes roll-out {
  to { transform: translateY(-14px) rotateX(38deg); opacity: 0; }
}
@keyframes roll-in {
  from { transform: translateY(18px) rotateX(-32deg); opacity: 0; }
  to   { transform: none; opacity: 1; }
}

/* 착 -> 착 -> 탁. 세 블록이 차례로 붙고 마지막에 한 번 더 조여진다(스펙 §10·§15). */
.blocks.is-snapping { gap: 3px; transition: gap 280ms var(--ease-snap); }
.blocks.is-snapping .block { box-shadow: none; border-radius: var(--radius-md); }
.blocks.is-snapping .block:nth-child(1) { animation: snap 260ms var(--ease-snap) 0ms both; }
.blocks.is-snapping .block:nth-child(2) { animation: snap 260ms var(--ease-snap) 130ms both; }
.blocks.is-snapping .block:nth-child(3) { animation: snap 300ms var(--ease-snap) 280ms both; }
@keyframes snap {
  0%   { transform: translateY(0) scale(1); }
  55%  { transform: translateY(2px) scale(0.975); }
  100% { transform: none; }
}

.merged {
  background: var(--brand-050); border-radius: var(--radius-xl);
  padding: var(--space-5); text-align: center;
  animation: rise-in var(--motion-slow) var(--ease-out) both;
}
@keyframes rise-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* 성공 — confetti 없이. 성인 대상이라 과하면 싸구려로 읽힌다(스펙 §11). */
.success-mark {
  width: 56px; height: 56px; margin: 0 auto; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--success-bg); color: var(--success);
  animation: success-pop 560ms var(--ease-snap) both;
}
@keyframes success-pop {
  0%   { transform: scale(0.4); opacity: 0; }
  60%  { transform: scale(1.08); opacity: 1; }
  100% { transform: scale(1); }
}

.ko-prompt {
  background: var(--surface-soft); border-radius: var(--radius-xl);
  padding: var(--space-5); text-align: center;
  font-size: 19px; font-weight: 700; line-height: 1.5; letter-spacing: -0.02em;
}
.ko-prompt::before, .ko-prompt::after { color: var(--muted); font-weight: 500; }
.ko-prompt::before { content: "\201C"; }
.ko-prompt::after  { content: "\201D"; }

/* ── 결과 ─────────────────────────────────────────────────── */

/* 섹션 = 20px 제목 + 카드. 제목이 14px 라벨이면 본문보다 약해 섹션 경계가 사라진다(2026-09-23). */
.result-sec { display: flex; flex-direction: column; gap: var(--space-3); }
.result-sec__title { font-size: 20px; font-weight: 800; line-height: 1.35; letter-spacing: -0.025em; }
.result-sec__body { padding: var(--space-5); }
.result-sec__note { margin-top: var(--space-4); }
/* 카드 안 마지막 항목은 아래 선이 필요 없다 — 카드 테두리가 끝을 알린다. */
.result-sec__body .findings-list > :last-child { border-bottom: 0; padding-bottom: 0; }
.result-sec__body .axis--text:last-child { border-bottom: 0; }

.type-card {
  background: var(--brand-050); border-radius: var(--radius-2xl);
  padding: var(--space-5); border: 1px solid #ffdcc2;
}
.type-card__eyebrow { font-size: 12.5px; font-weight: 700; color: var(--brand-600); }
.type-card__label {
  margin-top: var(--space-2);
  font-size: 22px; font-weight: 800; line-height: 1.34; letter-spacing: -0.03em;
  color: var(--brand-700);
}
.type-card__desc { margin-top: var(--space-3); font-size: 15px; line-height: 1.62; color: var(--ink-soft); }

.axes { display: flex; flex-direction: column; gap: var(--space-4); }
.axis__top { display: flex; align-items: baseline; gap: var(--space-2); margin-bottom: 7px; }
.axis__label { font-size: 14.5px; font-weight: 700; }
.axis__score { margin-left: auto; font-size: 16px; font-weight: 800; }
.axis__score small { font-size: 11px; font-weight: 700; color: var(--muted); }
.axis__na { margin-left: auto; font-size: 12.5px; font-weight: 700; color: var(--muted); }
.axis__track { height: 8px; background: var(--surface-soft); border-radius: var(--radius-pill); overflow: hidden; }
.axis__fill {
  height: 100%; border-radius: var(--radius-pill); background: var(--brand-500);
  width: 0; transition: width 720ms var(--ease-out);
}
/* 본인 체감 축(리스닝 '블록으로 들은 뒤') — 점수가 아니므로 막대가 없다. 답에 따라 글자색만 바꾼다. */
.axis--text { padding-bottom: var(--space-1); border-bottom: 1px solid var(--line); }
.axis__text { margin-left: auto; font-size: 14.5px; font-weight: 800; color: var(--ink); }
.axis--much .axis__text { color: var(--brand-600); }
.axis--none .axis__text { color: var(--ink-soft); }
.axis--na .axis__track { background: repeating-linear-gradient(90deg, #eceef1 0 6px, transparent 6px 12px); }

.findings-list { display: flex; flex-direction: column; gap: var(--space-3); }
.discovery {
  display: flex; gap: var(--space-3); align-items: flex-start;
  border-bottom: 1px solid var(--line); padding-bottom: var(--space-3);
}
.discovery:last-child { border-bottom: 0; padding-bottom: 0; }
.discovery__check { flex: none; color: var(--success); margin-top: 2px; }
.discovery__label { display: block; font-size: 12.5px; font-weight: 700; color: var(--muted); }
.discovery__value { display: block; font-size: 15.5px; font-weight: 650; line-height: 1.45; margin-top: 2px; word-break: normal; }

/* ── 최종 CTA ─────────────────────────────────────────────── */

.cta-page { background: linear-gradient(180deg, var(--surface) 0%, var(--brand-050) 100%); }
.cta-hero {
  font-size: 28px; font-weight: 800; line-height: 1.32; letter-spacing: -0.035em; text-align: center;
}
/* "툭 치면 탁!" — 손글씨 느낌을 폰트 없이 기울기와 밑줄로만 낸다 */
.cta-stamp {
  display: inline-block; position: relative;
  font-size: 30px; font-weight: 800; letter-spacing: -0.03em;
  color: var(--brand-600); transform: rotate(-3.5deg);
}
.cta-stamp::after {
  content: ""; position: absolute; left: -4px; right: -4px; bottom: 2px; height: 9px;
  background: var(--brand-100); border-radius: var(--radius-pill); z-index: -1;
}

.sub-actions { display: flex; gap: var(--space-2); }

/* 리스닝 STEP 6 — 붙은 문장 카드 안에서 전체 문장 다시 듣기 + 체감 묻기 (2026-09-23 2차)
   🔑 여백: 덩어리 사이 32 · 덩어리 안 12~16. 1차에서 질문이 재생기에 8px 로 붙어 한 덩어리로 뭉개졌다. */
.merged--replay { padding: var(--space-6) var(--space-5) var(--space-5); }
.merged__note { margin-top: var(--space-2); font-size: 14px; line-height: 1.55; color: var(--ink-soft); }
.merged__listen {
  margin-top: var(--space-5); padding-top: var(--space-5);
  border-top: 1px dashed #ffcfa9;
  display: flex; flex-direction: column; gap: var(--space-3);
}
.merged__cue { font-size: 14px; font-weight: 700; color: var(--brand-700); }
.replay-player { background: var(--surface); padding: var(--space-4); text-align: left; box-shadow: var(--shadow-soft); }
.replay-player .play-btn { width: 56px; height: 56px; position: relative; }
/* 첫 재생 전까지만 숨 쉬는 링 — 글 없이 "여기를 누르세요". 한 겹만(스펙 §15). */
.replay-player.is-inviting .play-btn::after {
  content: ""; position: absolute; inset: -6px; border-radius: 50%;
  border: 2px solid var(--brand-500); opacity: 0;
  animation: mic-pulse 1.6s var(--ease-out) infinite;
}

.replay-ask {
  margin-top: var(--space-2);   /* stack-6(24) + 8 = 32 */
  display: flex; flex-direction: column; gap: var(--space-4);
  animation: rise-in var(--motion-slow) var(--ease-out) both;
}
.replay-ask__head { display: flex; flex-direction: column; gap: var(--space-1); }
.replay-ask__options { display: flex; flex-direction: column; gap: var(--space-2); }
.replay-opt {
  display: flex; align-items: center; gap: var(--space-4);
  min-height: 60px; padding: 0 var(--space-4);
  border: 1.5px solid var(--line); border-radius: var(--radius-lg);
  background: var(--surface); color: var(--ink);
  font-size: 16px; font-weight: 700; text-align: left; cursor: pointer;
  transition: border-color var(--motion-fast), background-color var(--motion-fast), transform var(--motion-fast) var(--ease-out);
}
@media (hover: hover) { .replay-opt:hover { border-color: #ffcaa4; } }   /* 터치에서 :hover 가 남지 않게(fix/touch-hover-sticky) */
.replay-opt:active { transform: scale(0.985); }
.replay-opt[aria-checked="true"] { border-color: var(--brand-500); background: var(--brand-050); color: var(--brand-700); }

/* 선명도 막대 — 칸 수가 곧 보기의 뜻(3 훨씬 · 2 조금 · 1 아직). 이모지 대신 소리 막대로. */
.clarity-bars { flex: none; display: flex; align-items: flex-end; gap: 3px; width: 22px; height: 20px; }
.clarity-bars i { flex: 1; border-radius: 2px; background: #e1e2e6; }
.clarity-bars i:nth-child(1) { height: 40%; }
.clarity-bars i:nth-child(2) { height: 70%; }
.clarity-bars i:nth-child(3) { height: 100%; }
.clarity-bars[data-level="1"] i:nth-child(1),
.clarity-bars[data-level="2"] i:nth-child(-n+2),
.clarity-bars[data-level="3"] i { background: var(--ink-soft); }
.replay-opt[aria-checked="true"] .clarity-bars[data-level="1"] i:nth-child(1),
.replay-opt[aria-checked="true"] .clarity-bars[data-level="2"] i:nth-child(-n+2),
.replay-opt[aria-checked="true"] .clarity-bars[data-level="3"] i { background: var(--brand-500); }

/* 답한 직후 한 줄 반응. */
.replay-ask__feedback {
  display: flex; gap: var(--space-2); align-items: flex-start;
  padding: var(--space-3) var(--space-4); border-radius: var(--radius-lg);
  background: var(--brand-050); color: var(--brand-700);
  font-size: 14.5px; font-weight: 700; line-height: 1.55;
  animation: rise-in var(--motion-base) var(--ease-out) both;
}
.replay-ask__feedback[data-tone="none"] { background: var(--surface-soft); color: var(--ink-soft); }
@media (prefers-reduced-motion: reduce) {
  .replay-player.is-inviting .play-btn::after { animation: none; }
}
.sub-actions .btn { flex: 1; }

/* ── 오류 ─────────────────────────────────────────────────── */

.error-box {
  background: var(--danger-bg); border-radius: var(--radius-lg);
  padding: var(--space-4); font-size: 14.5px; line-height: 1.55; color: #8f2730;
}

/* ── 로딩 ─────────────────────────────────────────────────── */

.spinner {
  width: 20px; height: 20px; border-radius: 50%;
  border: 2.5px solid rgb(255 255 255 / 35%); border-top-color: #fff;
  animation: spin .7s linear infinite;
}
.spinner--ink { border-color: var(--line); border-top-color: var(--brand-500); }
@keyframes spin { to { transform: rotate(360deg); } }

.analyzing { display: flex; flex-direction: column; align-items: center; gap: var(--space-4); padding: var(--space-10) 0; }

/* ── 모션 줄이기 ──────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ── 큰 화면 ──────────────────────────────────────────────── */

@media (min-width: 600px) {
  body { background: var(--surface-soft); }
  .page {
    max-width: 520px; margin: 0 auto; min-height: 100dvh;
    box-shadow: 0 0 0 1px var(--line);
  }
  .t-en { font-size: 23px; }
}

/* ── 바깥 링크 (2026-09-30 hyeonsu 요청) ─────────────────── */

.logo-link { display: inline-block; border-radius: var(--radius-sm); }
.logo-link:focus-visible { outline: 2px solid var(--focus); outline-offset: 4px; }

/* 시작 화면 — 여행 영어 포켓북. 로고·"3분" 오른쪽 모서리에 **스티커처럼** 얹는다(2026-09-30 A안).
   페이지와 같은 살구색이면 제목과 한 덩어리로 읽혔다 → 흰 바탕 + 흰 테두리(다이컷) + 그림자 + 기울임으로 떼어 낸다.
   🔴 "영어 소리진단" 줄과 겹치면 안 된다(index.php 주석). 기울이면 모서리가 내려오므로
      top·height 를 바꾸면 320~430px 에서 **회전 후 경계**로 다시 잴 것. */
.start__intro { position: relative; }
.pocketbook {
  position: absolute; top: -2px; right: -4px;
  display: flex; align-items: center; gap: var(--space-2);
  width: 180px; height: 80px; padding: 0 var(--space-3) 0 0;
  border: 3px solid #fff; border-radius: 18px; outline: 1px solid rgb(23 23 28 / 8%);
  background: #fff; color: var(--ink); text-decoration: none;
  box-shadow: 0 10px 22px rgb(23 23 28 / 16%), 0 2px 4px rgb(23 23 28 / 10%);
  transform: rotate(3deg); transform-origin: 60% 40%;
  transition: transform var(--motion-fast) var(--ease-out);
}
.pocketbook__cover {
  flex: none; width: 60px; height: auto; margin: -12px 0 -6px -12px;
  filter: drop-shadow(0 4px 6px rgb(23 23 28 / 18%));
  transform: rotate(-6deg);
}
.pocketbook__body { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; min-width: 0; }
.pocketbook__title { font-size: 14px; font-weight: 800; line-height: 1.25; letter-spacing: -0.03em; }
.pocketbook__btn {
  padding: 4px 10px; border-radius: var(--radius-pill);
  background: var(--brand-500); color: #fff; font-size: 12px; font-weight: 700; white-space: nowrap;
}
.pocketbook:active { transform: rotate(3deg) scale(0.97); }
.pocketbook:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
@media (max-width: 339px) {
  .pocketbook { width: 158px; height: 76px; }
  .pocketbook__cover { width: 52px; }
  .pocketbook__title { font-size: 13px; }
}

/* 엔딩 주 버튼 — 두 줄 + 아이콘. 2026-10-07 부터 소리튠 챌린지(5일 비주얼). 클래스 이름 lab-cta 는 옛 영어 연구소 시절 그대로 */
.lab-cta { gap: var(--space-3); min-height: 72px; padding-block: var(--space-3); }
.lab-cta__icon { flex: none; display: grid; place-items: center; }
.lab-cta__icon svg, .lab-cta__icon img { display: block; width: 40px; height: 40px; }
.lab-cta__text { display: flex; flex-direction: column; align-items: flex-start; text-align: left; line-height: 1.3; }
.lab-cta__sub { font-size: 13.5px; font-weight: 600; opacity: .92; }
.lab-cta__main { font-size: 17px; font-weight: 800; letter-spacing: -0.02em; }

/* ── 진단 중 하단 띠배너 — 여행 영어 포켓북 (2026-09-30) ──────────
   화면 맨 아래 고정. '다음' 바(.page__action, sticky bottom)는 배너 바로 위로 올린다.
   🔑 높이는 --ad-h 하나로 맞춘다 — 바 위치 · 문서 끝 여백 · 자동 스크롤 여백이 모두 이 값을 쓴다. */
body.has-ad { --ad-h: calc(58px + env(safe-area-inset-bottom)); padding-bottom: var(--ad-h); }
body.has-ad .page__action { bottom: var(--ad-h); padding-block-end: var(--space-3); }
/* scrollIntoView(패널·출구 버튼)가 배너 밑으로 들어가지 않게 */
html:has(body.has-ad) { scroll-padding-bottom: calc(58px + env(safe-area-inset-bottom)); }

.ad-strip {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 25;
  display: flex; align-items: stretch;
  height: var(--ad-h, 58px); padding-bottom: env(safe-area-inset-bottom);
  background: #fff; border-top: 1px solid var(--line);
  box-shadow: 0 -6px 18px rgb(23 23 28 / 7%);
}
.ad-strip[hidden] { display: none; }
.ad-strip__link {
  flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--space-3);
  max-width: var(--shell-max); margin-inline: auto; padding-inline: var(--space-4) 0;
  color: var(--ink); text-decoration: none;
}
.ad-strip__cover {
  flex: none; width: 34px; height: auto;
  filter: drop-shadow(0 2px 3px rgb(23 23 28 / 18%)); transform: rotate(-5deg);
}
.ad-strip__title { flex: 1; min-width: 0; font-size: 14.5px; font-weight: 800; letter-spacing: -0.03em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ad-strip__btn {
  flex: none; padding: 6px 12px; border-radius: var(--radius-pill);
  background: var(--brand-500); color: #fff; font-size: 12.5px; font-weight: 700; white-space: nowrap;
}
.ad-strip__close {
  flex: none; width: 44px; border: 0; background: none; color: var(--muted); cursor: pointer;
  display: grid; place-items: center;
}
.ad-strip__link:active { opacity: .85; }
