/* Verbault Quiet Scholarship - Reader destination styles.
   Scope: .verbault-reader root. Tokens: var(--vb-*) only.
   See: docs/superpowers/specs/2026-05-18-design-system-C-reader-design.md */

/* Section 1: Reader root + container baseline */
.verbault-reader.vb-reader-card {
  background: var(--vb-bg-page);
  border: 0.5px solid var(--vb-border);
  border-radius: var(--vb-radius-lg);
  padding: var(--vb-space-6);
  margin: 0 auto;
  max-width: min(100%, 980px);
  font-family: var(--vb-font-sans);
  color: var(--vb-text-primary);
  overflow: visible;
}

.verbault-reader .vb-reader-app {
  display: flex;
  flex-direction: column;
  gap: var(--vb-space-4);
}

/* Section 2: Reader head + title + upload */
.verbault-reader .vb-reader-head {
  display: flex;
  flex-wrap: nowrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--vb-space-3);
  padding-bottom: var(--vb-space-3);
  border-bottom: 0.5px solid var(--vb-border);
}

.verbault-reader .vb-reader-head > div:first-child {
  flex: 1 1 0;
  min-width: 0;
}

.verbault-reader .vb-reader-head > .vb-reader-tts-badge {
  flex: 0 0 auto;
  align-self: flex-start;
}

.vb-reader-save-mybook {
  flex: none; padding: 6px 14px; border-radius: 999px;
  border: 1px solid var(--vb-border, #d8d2c4); background: var(--vb-surface, #fff);
  color: var(--vb-text-primary, #2a2a2a); font-size: 13px; font-weight: 600; cursor: pointer;
  align-self: flex-start;
}
.vb-reader-save-mybook:hover { background: var(--vb-surface-hover, #f3efe6); }
.vb-reader-save-mybook[hidden] { display: none; }
.vb-reader-save-mybook.is-saved { opacity: .6; cursor: default; }

.verbault-reader .vb-reader-title {
  font-family: var(--vb-font-serif);
  font-size: var(--vb-text-2xl);
  font-weight: 500;
  color: var(--vb-text-primary);
  margin: 0;
  letter-spacing: -0.01em;
}

.verbault-reader .vb-reader-upload {
  display: flex;
  align-items: center;
  gap: var(--vb-space-2);
  flex-wrap: wrap;
}

.verbault-reader .vb-reader-file {
  display: inline-flex;
  align-items: center;
  gap: var(--vb-space-2);
}

.verbault-reader .vb-reader-file input[type="file"] {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.verbault-reader .vb-reader-file-btn {
  display: inline-flex;
  align-items: center;
  padding: var(--vb-space-2) var(--vb-space-4);
  background: var(--vb-aubergine);
  color: var(--vb-text-on-accent);
  border: 0.5px solid var(--vb-aubergine);
  border-radius: var(--vb-radius-md);
  font-family: var(--vb-font-sans);
  font-size: var(--vb-text-sm);
  cursor: pointer;
  transition: background-color var(--vb-dur-fast) var(--vb-ease);
}

.verbault-reader .vb-reader-file-btn:hover {
  background: color-mix(in srgb, var(--vb-aubergine), black 18%);
}

.verbault-reader .vb-reader-file-name {
  font-size: var(--vb-text-sm);
  color: var(--vb-text-secondary);
}

/* Section 3: Upload row */
.verbault-reader .vb-reader-upload-row {
  display: flex;
  align-items: center;
  gap: var(--vb-space-2);
  flex-wrap: nowrap;
  padding: var(--vb-space-2) var(--vb-space-3);
  border: 0.5px solid var(--vb-border);
  border-radius: var(--vb-radius-md);
  background: var(--vb-bg-page);
}

.verbault-reader .vb-reader-upload-row .vb-reader-file {
  display: inline-flex;
  align-items: center;
  gap: var(--vb-space-3);
  flex: 1 1 auto;
  min-width: 0;
}

/* TTS 상태 배지는 업로드 행 오른쪽 끝에 고정 (제목 아래에서 이동). */
.verbault-reader .vb-reader-upload-row > .vb-reader-tts-badge {
  flex: 0 0 auto;
  margin-left: auto;
  white-space: nowrap;
}

/* Section 4: Voice picker */
.verbault-reader .vb-reader-voice-group {
  display: inline-flex;
  align-items: center;
  gap: var(--vb-space-1);
  padding: 2px;
  background: var(--vb-bg-page);
  border: 0.5px solid var(--vb-border);
  border-radius: var(--vb-radius-md);
}

.verbault-reader .vb-reader-voice-btn {
  padding: var(--vb-space-1) var(--vb-space-3);
  background: transparent;
  color: var(--vb-text-secondary);
  border: 0;
  border-radius: var(--vb-radius-sm);
  font-family: var(--vb-font-sans);
  font-size: var(--vb-text-sm);
  cursor: pointer;
  transition: background-color var(--vb-dur-fast) var(--vb-ease), color var(--vb-dur-fast) var(--vb-ease);
}

.verbault-reader .vb-reader-voice-btn[aria-pressed="true"] {
  background: var(--vb-aubergine);
  color: var(--vb-text-on-accent);
}

.verbault-reader .vb-reader-voice-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* Section 5: Meta + status */
.verbault-reader .vb-reader-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--vb-space-3);
  font-family: var(--vb-font-sans);
  font-size: var(--vb-text-sm);
  color: var(--vb-text-secondary);
}

.verbault-reader .vb-reader-meta span {
  display: inline-flex;
  align-items: center;
  gap: var(--vb-space-1);
}

/* Section 5a: Chapter navigation (pill + popup) — sticky at viewport top */
.verbault-reader .vb-reader-chapter-nav {
  position: sticky;
  top: var(--vb-nav-h, 64px);
  z-index: 30;
  background: var(--vb-bg-page);
  display: flex;
  align-items: center;
  gap: var(--vb-space-2);
  margin: 0 calc(-1 * var(--vb-space-6)) var(--vb-space-2);
  padding: var(--vb-space-2) var(--vb-space-6);
  border-bottom: 1px solid var(--vb-border);
}

.verbault-reader .vb-reader-chapter-nav[hidden] {
  display: none;
}

.verbault-reader .vb-reader-chapter-arrow {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: var(--vb-bg-page);
  color: var(--vb-text-secondary);
  border: 0.5px solid var(--vb-border);
  border-radius: var(--vb-radius-full);
  cursor: pointer;
  transition: background-color var(--vb-dur-fast) var(--vb-ease),
              color var(--vb-dur-fast) var(--vb-ease),
              border-color var(--vb-dur-fast) var(--vb-ease);
}
.verbault-reader .vb-reader-chapter-arrow:hover:not(:disabled) {
  background: var(--vb-aubergine-soft);
  color: var(--vb-aubergine);
  border-color: var(--vb-aubergine);
}
.verbault-reader .vb-reader-chapter-arrow:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

/* 북마크 버튼 — chapter-arrow 톤 공유 + 카운트 배지 */
.verbault-reader .vb-reader-bookmark-btn {
  position: relative;
}
.verbault-reader .vb-reader-bookmark-btn[aria-pressed="true"] {
  background: var(--vb-aubergine-soft);
  color: var(--vb-aubergine);
  border-color: var(--vb-aubergine);
}
.verbault-reader .vb-reader-bookmark-btn[aria-pressed="true"] svg {
  fill: currentColor;
}
.verbault-reader .vb-reader-bookmark-count {
  position: absolute;
  top: -5px;
  right: -5px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--vb-aubergine);
  color: var(--vb-text-on-accent, #fff);
  font-family: var(--vb-font-sans);
  font-size: 10px;
  font-weight: 600;
  line-height: 1;
  border-radius: var(--vb-radius-full);
}
.verbault-reader .vb-reader-bookmark-count[hidden] {
  display: none;
}

.verbault-reader .vb-reader-chapter-pill {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: var(--vb-space-2) var(--vb-space-4);
  background: var(--vb-bg-page);
  border: 0.5px solid var(--vb-border);
  border-radius: var(--vb-radius-md);
  color: var(--vb-text-primary);
  font-family: var(--vb-font-sans);
  cursor: pointer;
  transition: background-color var(--vb-dur-fast) var(--vb-ease),
              border-color var(--vb-dur-fast) var(--vb-ease);
}
.verbault-reader .vb-reader-chapter-pill:hover,
.verbault-reader .vb-reader-chapter-pill[aria-expanded="true"] {
  background: var(--vb-aubergine-soft);
  border-color: var(--vb-aubergine);
}

.verbault-reader .vb-reader-chapter-pill__title {
  font-family: var(--vb-font-serif);
  font-size: var(--vb-text-lg);
  font-weight: 500;
  color: var(--vb-text-primary);
  line-height: 1.2;
}

.verbault-reader .vb-reader-chapter-pill__meta {
  font-family: var(--vb-font-sans);
  font-size: var(--vb-text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--vb-text-tertiary);
}

.verbault-reader .vb-reader-chapter-popup {
  position: absolute;
  top: calc(100% + 8px);
  left: 36px;
  right: 36px;
  z-index: 60;
  max-height: 360px;
  overflow-y: auto;
  background: var(--vb-bg-page);
  border: 0.5px solid var(--vb-border);
  border-radius: var(--vb-radius-md);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
}

.verbault-reader .vb-reader-chapter-popup[hidden] {
  display: none;
}

.verbault-reader .vb-reader-chapter-popup ul {
  list-style: none;
  margin: 0;
  padding: var(--vb-space-1) 0;
}

.verbault-reader .vb-reader-chapter-popup li {
  display: flex;
  align-items: baseline;
  gap: var(--vb-space-3);
  padding: var(--vb-space-2) var(--vb-space-4);
  cursor: pointer;
  font-family: var(--vb-font-sans);
  font-size: var(--vb-text-sm);
  color: var(--vb-text-primary);
  transition: background-color var(--vb-dur-fast) var(--vb-ease);
}
.verbault-reader .vb-reader-chapter-popup li:hover {
  background: var(--vb-aubergine-soft);
}
.verbault-reader .vb-reader-chapter-popup li[aria-current="true"] {
  background: var(--vb-aubergine-soft);
  color: var(--vb-aubergine);
  font-weight: 500;
}
.verbault-reader .vb-reader-chapter-popup li .num {
  flex: 0 0 24px;
  color: var(--vb-text-tertiary);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.verbault-reader .vb-reader-chapter-popup li.vb-reader-popup-empty {
  color: var(--vb-text-tertiary);
  cursor: default;
  justify-content: center;
}
.verbault-reader .vb-reader-chapter-popup li .ch-page {
  margin-left: auto;
  opacity: .65;
  font-size: .85em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Section 6: Reading canvas + sentences + words */
.verbault-reader .vb-reader-content {
  font-family: var(--vb-font-serif);
  /* --vb-reader-font-scale 는 #reader-content 에 인라인으로 세팅(JS), 기본 1.
     모바일 override(아래 @media 720px)에도 동일 곱을 적용해야 스케일이 먹는다. */
  font-size: calc(var(--vb-text-reading) * var(--vb-reader-font-scale, 1));
  line-height: 1.7;
  /* Reader-scoped text dimming only: light falls back to --vb-text-primary; both dark
     paths (explicit + auto @media) pick up the warm dimmed body text from one definition.
     Background stays identical to the app surface (--vb-bg-page) — no separate reader canvas. */
  color: var(--vb-reader-text, var(--vb-text-primary));
  background: var(--vb-bg-page);
  padding: var(--vb-space-5) var(--vb-space-4);
  border: 0.5px solid var(--vb-border);
  border-radius: var(--vb-radius-md);
}

.verbault-reader .vb-reader-empty {
  color: var(--vb-text-tertiary);
  font-style: italic;
  text-align: center;
  padding: var(--vb-space-6) 0;
}

.verbault-reader .vb-reader-paragraph {
  margin: 0 0 var(--vb-space-4) 0;
}

.verbault-reader .vb-reader-paragraph:last-child {
  margin-bottom: 0;
}

.verbault-reader .vb-reader-sentence {
  display: inline;
  border-radius: 2px;
  transition: background-color 160ms ease;
  cursor: pointer;
}

/* 북마크/저장 문장 — 호박색 형광펜 배경 + 왼쪽 3px 엣지. inline span 이라
   기본(slice) 동작: 배경은 줄바꿈 전체에 깔리고 border-left 는 시작점에만 1회. */
.verbault-reader .vb-reader-sentence--bookmarked {
  background: var(--hl-bookmark-bg);
  color: var(--hl-bookmark-text);
  border-left: 3px solid var(--hl-bookmark-edge);
  padding-left: var(--vb-space-2);
}

/* 낭독 중(활성) 문장 — 부드러운 보라. 북마크 뒤에 선언해 배경/텍스트는 덮되,
   border-left 는 미설정이라 북마크 엣지가 활성 중에도 유지된다. */
.verbault-reader .vb-reader-sentence--active {
  background: var(--hl-speaking-bg);
  color: var(--hl-speaking-text);
}

/* A2: 카라오케 활성 단어 — 형광펜 배경 + 강조 글자색 + paint-only 굵기. 라이트=밝은 앰버
   배경 위 딥 앰버 글자, 다크=어두운 골드 배경 위 밝은 골드 글자 (토큰 SOT 가 모드별 매핑).
   문장밴드(--hl-speaking-bg) 위에 단어 배경이 겹쳐 2단 포커스(밴드=문맥 / 단어=지금 읽는 곳).
   ⚠ font-weight 로 굵게 하면 글자 advance 폭이 바뀌어 활성 단어가 이동할 때마다 줄 폭이
   흔들린다(reflow jitter, 실측 ~16px). 배경/색/-webkit-text-stroke 는 레이아웃 박스를 안
   바꾸는 paint 효과라 폭 불변 → reflow 0. padding+음수 margin 은 배경 breathing room 을
   주되 advance 를 상쇄해 폭 불변(.vb-reader-word 와 동일 패턴). .vb-reader-token 기준이라
   top-N cap 밖 plain 토큰도 강조됨. */
.verbault-reader .vb-reader-sentence--active .vb-reader-token--speaking {
  background: var(--hl-speaking-word-bg);
  color: var(--hl-speaking-word);
  border-radius: 4px;
  padding: 0 3px;
  margin: 0 -3px;
  -webkit-text-stroke: 0.3px currentColor;
  /* 활성화는 즉시 — .vb-reader-word 가 물려준 background 0.15s 가 단어 싱크(75ms 단어)에
     맞춰 형광펜이 따라붙는 걸 늦춘다. transition:none 으로 스냅 인. (비활성화 페이드아웃은
     base 규칙의 0.15s 가 가벼운 트레일을 남기지만 "지금 단어"는 항상 즉시 켜진다.) */
  transition: none;
}

.verbault-reader .vb-reader-token {
  border-radius: 4px;
}

.verbault-reader .vb-reader-sentence--active .vb-reader-token {
  cursor: pointer;
}

.verbault-reader .vb-reader-word {
  border-radius: 4px;
  /* padding 은 hard-레벨/flash/hover 배경의 breathing room 용. 단, 음수 margin 으로
     레이아웃 advance 를 상쇄해 본문 단어 간격이 일정하고 구두점 앞 가짜 공백
     ("sailor ," 처럼 보이던 현상) 이 생기지 않게 한다 (배경만 텍스트 밖으로 확장). */
  padding: 0 3px;
  margin: 0 -3px;
  cursor: pointer;
  transition: background 0.15s;
}

/* Vocab "Open in Reader" 진입 시 대상 단어 강조 — 2.4s 후 자동 해제. */
.verbault-reader .vb-reader-word--flash {
  background: var(--vb-aubergine-soft, rgba(120, 88, 140, 0.22));
  border-radius: 3px;
  padding: 0 2px;
  animation: vb-reader-word-flash 2.4s ease-out;
}
@keyframes vb-reader-word-flash {
  0%   { background: var(--vb-ember, #d97757); color: var(--vb-text-on-accent, #fff); }
  20%  { background: var(--vb-ember, #d97757); color: var(--vb-text-on-accent, #fff); }
  100% { background: transparent; color: inherit; }
}

/* Section 6a: CEFR 밴드별 단어 표시 — Settings 의 "CEFR level highlight" 밴드
   체크에 연동. #reader-content 는 applyDefaultsToReader() 가 reader-cefr-{band}
   클래스를 토글하므로, 체크된 밴드의 단어만 밑줄이 그어진다 (컨테이너 클래스
   게이팅 → 설정 변경 시 재렌더 없이 즉시 반영). 6 sub-band 은 과granular 라 혼동의
   원인 → color+saturation+line-style 로 3 tier 로 묶는다 (2026-06-17 §5.2): A(A1,A2)
   =점선 muted-blue, B(B1,B2)=실선 vivid-blue, C(C1,C2)=실선 brick. status(warm 배경)
   와 hue 온도(cool→brick)·채널(underline) 둘 다 분리돼 같은 단어에 둘이 겹쳐도 명확.
   6 컨테이너 클래스는 모두 유지 → per-band on/off 그대로. tier 색 토큰은 다크에서
   밝아져 C-band 다크 가독성도 함께 해결. */
.verbault-reader .vb-reader-content.reader-cefr-A1 .vb-reader-word[data-cefr-band="A1"],
.verbault-reader .vb-reader-content.reader-cefr-A2 .vb-reader-word[data-cefr-band="A2"] {
  text-decoration: underline dotted var(--vb-reader-cefr-a);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
.verbault-reader .vb-reader-content.reader-cefr-B1 .vb-reader-word[data-cefr-band="B1"],
.verbault-reader .vb-reader-content.reader-cefr-B2 .vb-reader-word[data-cefr-band="B2"] {
  text-decoration: underline solid var(--vb-reader-cefr-b);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
.verbault-reader .vb-reader-content.reader-cefr-C1 .vb-reader-word[data-cefr-band="C1"],
.verbault-reader .vb-reader-content.reader-cefr-C2 .vb-reader-word[data-cefr-band="C2"] {
  text-decoration: underline solid var(--vb-reader-cefr-c);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

/* Word-status tints — background channel (composes with CEFR underline). Each
   state is independently selectable (§349): the container carries reader-status-new
   and/or reader-status-learning per the user's Settings choices. `known` has no
   rule → always clean. Exact alpha confirmed in both themes at the visual gate. */
.verbault-reader .vb-reader-content.reader-status-new .vb-reader-token[data-status="new"] {
  background: color-mix(in srgb, var(--vb-sage) var(--vb-reader-status-mix), transparent);
  border-radius: 2px;
}
.verbault-reader .vb-reader-content.reader-status-learning .vb-reader-token[data-status="learning"] {
  background: color-mix(in srgb, var(--vb-ember) var(--vb-reader-status-mix), transparent);
  border-radius: 2px;
}
/* data-status="known": no rule → clean text */

/* === §355 Reader onboarding coachmark ===
   Suppression is NOT a CSS override: maybeShowReaderCoachmark removes the
   reader-cefr-* / reader-status-* container classes during the calm moment and
   restores them on dismiss (saved settings untouched, transient). A CSS !important
   override does not work here because the CEFR color lives in a var() inside the
   text-decoration shorthand, which becomes a pending-substitution value that Chromium
   lets ignore the !important suppression (verified at the visual gate).
   Pulse = a soft aubergine background highlight (the background channel renders like the
   status tints; box-shadow/outline at the target's low specificity lose to the base
   .vb-reader-word rule). The selector is lifted to
   .vb-reader-content .vb-reader-word.<target> (0,4,0) to beat the base word rule, and the
   keyframes animate opacity only (color-mix in keyframes breaks the animated property). */
.verbault-reader .vb-reader-content .vb-reader-word.vb-reader-coachmark-target {
  position: relative;
  border-radius: 5px;
  background-color: color-mix(in srgb, var(--vb-aubergine) 30%, transparent);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--vb-aubergine) 65%, transparent),
              0 0 12px 2px color-mix(in srgb, var(--vb-aubergine) 42%, transparent);
}
/* Radiating "ping" ring on a pseudo so the @keyframes animate transform + opacity (plain
   numbers). color-mix in @keyframes breaks the animated property (verified at the visual
   gate), so the ring COLOR is set statically on the pseudo; only scale/opacity animate. */
.verbault-reader .vb-reader-content .vb-reader-word.vb-reader-coachmark-target::before {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: 7px;
  pointer-events: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--vb-aubergine) 60%, transparent),
              0 0 16px 4px color-mix(in srgb, var(--vb-aubergine) 48%, transparent);
  animation: vb-coach-ping 1.5s ease-out infinite;
}
@keyframes vb-coach-ping {
  0%   { transform: scale(0.9);  opacity: 0.9; }
  70%  { transform: scale(1.28); opacity: 0; }
  100% { transform: scale(1.28); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .verbault-reader .vb-reader-content .vb-reader-word.vb-reader-coachmark-target::before { animation: none; opacity: 0; }
}

/* Inline coachmark bubble — anchored to the pulse word (position:fixed, JS-placed). */
#reader-coachmark {
  position: fixed;
  z-index: 80;
  max-width: 300px;
  padding: 12px 15px;
  background: var(--vb-bg-elevated);
  color: var(--vb-text-primary);
  border: 1.5px solid color-mix(in srgb, var(--vb-aubergine) 50%, var(--vb-border));
  border-radius: 14px;
  box-shadow: 0 12px 34px rgba(0, 0, 0, 0.24),
              0 0 0 4px color-mix(in srgb, var(--vb-aubergine) 12%, transparent);
  font-size: 0.92rem;
  line-height: 1.4;
  font-weight: 500;
  display: none;
}
#reader-coachmark[data-open="1"] { display: block; animation: vb-coach-bob 1.9s ease-in-out infinite; }
@keyframes vb-coach-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-4px); }
}
@media (prefers-reduced-motion: reduce) {
  #reader-coachmark[data-open="1"] { animation: none; }
}
/* Caret pointing at the pulse word — direction via data-pos, x via --vb-coach-caret-x (JS). */
#reader-coachmark::after {
  content: "";
  position: absolute;
  left: var(--vb-coach-caret-x, 26px);
  width: 13px;
  height: 13px;
  background: var(--vb-bg-elevated);
  border: 1.5px solid color-mix(in srgb, var(--vb-aubergine) 50%, var(--vb-border));
  transform: rotate(45deg);
}
#reader-coachmark[data-pos="below"]::after { top: -7.5px; border-right: 0; border-bottom: 0; }
#reader-coachmark[data-pos="above"]::after { bottom: -7.5px; border-left: 0; border-top: 0; }
#reader-coachmark .vb-coach-bubble-row { display: flex; align-items: center; gap: 9px; }
#reader-coachmark svg { flex: 0 0 auto; width: 19px; height: 19px; color: var(--vb-aubergine); }

/* 체인 넛지 한 줄 (Save) — 팝업 내부. */
.vb-coach-nudge {
  margin-top: 6px;
  font-size: 0.72rem;
  color: var(--vb-text-secondary);
}

/* Review 넛지 토스트 — 저장 성공 직후 하단(플레이바 위). */
.vb-coach-toast {
  position: fixed;
  left: 50%;
  bottom: 92px;
  transform: translateX(-50%);
  z-index: 70;
  max-width: 320px;
  padding: 10px 14px;
  background: var(--vb-bg-elevated);
  color: var(--vb-text-primary);
  border: 1px solid var(--vb-border);
  border-radius: 10px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.18);
  font-size: 0.8rem;
  display: none;
}
.vb-coach-toast[data-open="1"] { display: block; }
.vb-coach-toast a { color: var(--vb-aubergine); font-weight: 600; text-decoration: none; }

/* 영구 미세 어포던스 — 리더 헤더. */
.vb-reader-tap-hint {
  display: flex;
  align-items: center;
  gap: 5px;
  margin: 3px 0 0;
  font-size: 0.74rem;
  color: var(--vb-text-tertiary);
}
.vb-reader-tap-hint svg { width: 13px; height: 13px; flex: 0 0 auto; }
.vb-reader-tap-hint[hidden] { display: none; }

/* Section 6a: Drop-cap on first paragraph of each chapter */
.verbault-reader .vb-reader-content .vb-reader-paragraph:first-of-type::first-letter {
  font-family: var(--vb-font-serif);
  font-size: 4em;
  line-height: 0.85;
  float: left;
  padding: 0.08em 0.12em 0 0;
  color: var(--vb-aubergine);
  font-weight: 500;
}

/* Section 8: TTS badge + loading overlay */
.verbault-reader .vb-reader-tts-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--vb-space-1);
  padding: 2px var(--vb-space-2);
  background: var(--vb-bg-page);
  color: var(--vb-text-secondary);
  border: 0.5px solid var(--vb-border);
  border-radius: var(--vb-radius-full);
  font-family: var(--vb-font-sans);
  font-size: var(--vb-text-xs);
}

.verbault-reader .vb-reader-tts-badge--ok {
  background: color-mix(in srgb, var(--vb-sage) 12%, transparent);
  color: var(--vb-sage);
  border-color: var(--vb-sage);
}

.verbault-reader .vb-reader-tts-badge--warn {
  background: color-mix(in srgb, var(--vb-ember) 12%, transparent);
  color: var(--vb-ember);
  border-color: var(--vb-ember);
}

.vb-reader-tts-overlay {
  position: fixed;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  background: color-mix(in srgb, var(--vb-ink) 60%, transparent);
  z-index: 1000;
}

.vb-reader-tts-overlay--open {
  display: flex;
}

.vb-reader-tts-overlay__box {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--vb-space-3);
  padding: var(--vb-space-6) var(--vb-space-8);
  background: var(--vb-bg-page);
  border: 0.5px solid var(--vb-border);
  border-radius: var(--vb-radius-lg);
  width: min(440px, calc(100vw - 32px));
  min-width: 320px;
  text-align: center;
}

.vb-reader-tts-overlay__title {
  font-family: var(--vb-font-serif);
  font-size: var(--vb-text-lg);
  color: var(--vb-text-primary);
  margin: 0;
}

.vb-reader-tts-overlay__message {
  font-family: var(--vb-font-sans);
  font-size: var(--vb-text-sm);
  color: var(--vb-text-secondary);
}

.vb-reader-tts-overlay__cancel {
  padding: var(--vb-space-2) var(--vb-space-4);
  background: transparent;
  color: var(--vb-text-secondary);
  border: 0.5px solid var(--vb-border);
  border-radius: var(--vb-radius-md);
  font-family: var(--vb-font-sans);
  font-size: var(--vb-text-sm);
  cursor: pointer;
  transition: background-color var(--vb-dur-fast) var(--vb-ease);
}

.vb-reader-tts-overlay__cancel:hover {
  background: var(--vb-aubergine-soft);
  color: var(--vb-aubergine);
  border-color: var(--vb-aubergine);
}

/* Section 9: Reader handoff bar */
.verbault-reader .vb-reader-handoff-bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--vb-space-2);
  margin: var(--vb-space-3) 0;
}

.verbault-reader .vb-reader-handoff-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--vb-space-2);
  padding: var(--vb-space-2) var(--vb-space-4);
  background: var(--vb-aubergine-soft);
  color: var(--vb-aubergine);
  border: 0.5px solid var(--vb-aubergine);
  border-radius: var(--vb-radius-full);
  font-family: var(--vb-font-sans);
  font-size: var(--vb-text-sm);
  font-weight: 500;
  cursor: pointer;
  transition: background-color var(--vb-dur-fast) var(--vb-ease),
              color var(--vb-dur-fast) var(--vb-ease),
              border-color var(--vb-dur-fast) var(--vb-ease);
}

.verbault-reader .vb-reader-handoff-icon {
  flex: 0 0 auto;
  font-size: 16px;
  line-height: 1;
}

.verbault-reader .vb-reader-handoff-label {
  line-height: 1;
  white-space: nowrap;
}

.verbault-reader .vb-reader-handoff-btn:hover:not(:disabled) {
  background: var(--vb-aubergine);
  color: var(--vb-text-on-accent);
}

.verbault-reader .vb-reader-handoff-btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
  background: transparent;
  color: var(--vb-text-tertiary);
  border-color: var(--vb-border);
}

/* Section 9a: Sticky bottom playbar (viewport-fixed) */
.vb-reader-playbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 50;
  padding: var(--vb-space-3) var(--vb-space-4);
  background: var(--vb-bg-page);
  border-top: 0.5px solid var(--vb-border);
  box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.04);
}

.vb-reader-playbar[hidden] {
  display: none;
}

@media (max-width: 640px) {
  .vb-reader-playbar {
    bottom: calc(56px + env(safe-area-inset-bottom));
  }
}

.vb-reader-playbar__inner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--vb-space-4);
  max-width: 980px;
  margin: 0 auto;
}

.vb-reader-playbar__transport {
  display: inline-flex;
  align-items: center;
  gap: var(--vb-space-2);
}

.vb-reader-play-circle {
  width: 56px;
  height: 56px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: var(--vb-aubergine);
  color: var(--vb-text-on-accent);
  border: 0;
  border-radius: 50%;
  font-size: var(--vb-text-xl);
  line-height: 1;
  cursor: pointer;
  transition: background-color var(--vb-dur-fast) var(--vb-ease);
}
.vb-reader-play-circle:hover:not(:disabled) {
  background: color-mix(in srgb, var(--vb-aubergine), black 14%);
}
.vb-reader-play-circle:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
/* Play/pause icons are inline SVG (fill:currentColor) so they match the theme
   identically on desktop and mobile. .is-playing swaps which one is shown.
   (Unicode media glyphs were emoji-rendered on mobile, off-theme + inconsistent.) */
.vb-reader-play-icon { display: block; }
.vb-reader-play-icon--pause { display: none; }
.vb-reader-play-circle.is-playing .vb-reader-play-icon--play { display: none; }
.vb-reader-play-circle.is-playing .vb-reader-play-icon--pause { display: block; }

.vb-reader-playbar__icon {
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: var(--vb-bg-page);
  color: var(--vb-text-secondary);
  border: 0.5px solid var(--vb-border);
  border-radius: var(--vb-radius-full);
  font-size: var(--vb-text-base);
  cursor: pointer;
  transition: background-color var(--vb-dur-fast) var(--vb-ease),
              color var(--vb-dur-fast) var(--vb-ease),
              border-color var(--vb-dur-fast) var(--vb-ease);
}
.vb-reader-playbar__icon:hover:not(:disabled) {
  background: var(--vb-aubergine-soft);
  color: var(--vb-aubergine);
  border-color: var(--vb-aubergine);
}
.vb-reader-playbar__icon:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Text-size stepper: __row, +/- step buttons, value display, and reset live
   inside #reader-controls-popover (unified settings popover). */
.vb-reader-font-popover__row {
  display: flex;
  align-items: center;
  gap: var(--vb-space-2);
}
.vb-reader-font-step {
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: var(--vb-bg-page);
  color: var(--vb-text-secondary);
  border: 0.5px solid var(--vb-border);
  border-radius: var(--vb-radius-full);
  font-weight: 600;
  cursor: pointer;
  transition: background-color var(--vb-dur-fast) var(--vb-ease),
              color var(--vb-dur-fast) var(--vb-ease),
              border-color var(--vb-dur-fast) var(--vb-ease);
}
.vb-reader-font-step--lg {
  font-size: var(--vb-text-lg);
}
.vb-reader-font-step:hover:not(:disabled) {
  background: var(--vb-aubergine-soft);
  color: var(--vb-aubergine);
  border-color: var(--vb-aubergine);
}
.vb-reader-font-step:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.vb-reader-font-step:focus-visible,
.vb-reader-font-reset:focus-visible {
  outline: 2px solid var(--vb-aubergine);
  outline-offset: 2px;
}
.vb-reader-font-value {
  min-width: 3.4em;
  text-align: center;
  font-size: var(--vb-text-sm);
  color: var(--vb-text-secondary);
  font-variant-numeric: tabular-nums;
}
.vb-reader-font-reset {
  background: none;
  border: 0;
  padding: var(--vb-space-1) var(--vb-space-2);
  color: var(--vb-aubergine);
  font-size: var(--vb-text-sm);
  cursor: pointer;
  border-radius: var(--vb-radius-sm);
}
.vb-reader-font-reset:hover {
  text-decoration: underline;
}

.vb-reader-playbar__voice {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 2px;
  background: var(--vb-bg-page);
  border: 0.5px solid var(--vb-border);
  border-radius: var(--vb-radius-md);
}
.vb-reader-playbar__voice button {
  padding: var(--vb-space-1) var(--vb-space-3);
  background: transparent;
  color: var(--vb-text-secondary);
  border: 0;
  border-radius: var(--vb-radius-sm);
  font-family: var(--vb-font-sans);
  font-size: var(--vb-text-sm);
  cursor: pointer;
  transition: background-color var(--vb-dur-fast) var(--vb-ease),
              color var(--vb-dur-fast) var(--vb-ease);
}
.vb-reader-playbar__voice button[aria-pressed="true"] {
  background: var(--vb-aubergine);
  color: var(--vb-text-on-accent);
}
.vb-reader-playbar__voice button:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.vb-reader-playbar__speed {
  display: inline-flex;
  align-items: center;
  align-self: center;
  gap: var(--vb-space-3);
  flex: 1 1 200px;
  max-width: 320px;
  margin: 0;
  font-family: var(--vb-font-sans);
  font-size: var(--vb-text-sm);
  color: var(--vb-text-secondary);
  line-height: 1;
}
.vb-reader-playbar__speed input[type="range"] {
  flex: 1 1 auto;
  width: 100%;
  margin: 0;
  padding: 0;
  vertical-align: middle;
  accent-color: var(--vb-aubergine);
}
.vb-reader-playbar__speed-label {
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-size: var(--vb-text-xs);
  color: var(--vb-text-tertiary);
}

.vb-reader-playbar__status {
  display: inline-flex;
  align-items: baseline;
  gap: var(--vb-space-2);
  font-family: var(--vb-font-sans);
  font-size: var(--vb-text-sm);
  color: var(--vb-text-secondary);
  font-variant-numeric: tabular-nums;
}
.vb-reader-playbar__status .wpm-unit {
  color: var(--vb-text-tertiary);
  font-size: var(--vb-text-xs);
  letter-spacing: 0.05em;
}
.vb-reader-playbar__status .progress {
  color: var(--vb-text-tertiary);
}

/* 본문이 playbar 에 가려지지 않도록 view 자체에 padding 부여 */
body[data-view="reader"] {
  padding-bottom: 96px;
}


/* Section 9c: Unified reading-controls popover (settings ⋯) + slim mobile row */
.vb-reader-settings-control { position: relative; }

.vb-reader-controls-popover {
  position: absolute;
  bottom: calc(100% + var(--vb-space-2));
  right: 0;
  z-index: 60;
  min-width: 240px;
  display: flex;
  flex-direction: column;
  gap: var(--vb-space-3);
  padding: var(--vb-space-4);
  background: var(--vb-bg-elevated);
  border: 0.5px solid var(--vb-border);
  border-radius: var(--vb-radius-md);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.12);
}
.vb-reader-controls-popover[hidden] { display: none; }
.vb-reader-controls-popover__group {
  display: flex; align-items: center; gap: var(--vb-space-2); flex-wrap: wrap;
}
.vb-reader-controls-popover__label {
  flex: 0 0 64px;
  font-size: var(--vb-text-sm);
  color: var(--vb-text-secondary);
}
.vb-reader-controls-popover__group input[type="range"] { flex: 1 1 90px; }
.vb-reader-controls-popover__readout {
  font-size: var(--vb-text-sm); color: var(--vb-text-secondary);
}
.vb-reader-controls-popover__footer {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--vb-space-3);
  border-top: 0.5px solid var(--vb-border);
  padding-top: var(--vb-space-3);
}
.vb-reader-settings-btn:focus-visible { outline: 2px solid var(--vb-aubergine); outline-offset: 2px; }

/* Section 9b: Keyboard focus rings for new interactive elements */
.verbault-reader .vb-reader-chapter-arrow:focus-visible,
.verbault-reader .vb-reader-chapter-pill:focus-visible,
.vb-reader-play-circle:focus-visible,
.vb-reader-playbar__icon:focus-visible,
.vb-reader-playbar__voice button:focus-visible {
  outline: 2px solid var(--vb-aubergine);
  outline-offset: 2px;
}

/* Section 10: Responsive (max-width: 720px, 420px) */
@media (max-width: 720px) {
  .verbault-reader.vb-reader-card {
    padding: var(--vb-space-4);
  }

  .verbault-reader .vb-reader-head {
    flex-direction: column;
    align-items: flex-start;
  }

  /* 좁은 화면에서는 TTS 배지가 업로드 행 다음 줄로 줄바꿈되도록 허용. */
  .verbault-reader .vb-reader-upload-row {
    flex-wrap: wrap;
  }

  .verbault-reader .vb-reader-content {
    font-size: calc(var(--vb-text-base) * var(--vb-reader-font-scale, 1));
    padding: var(--vb-space-4) var(--vb-space-3);
  }

  .verbault-reader .vb-reader-content .vb-reader-paragraph:first-of-type::first-letter {
    font-size: 3em;
  }

  .verbault-reader .vb-reader-chapter-nav {
    margin: 0 calc(-1 * var(--vb-space-4)) var(--vb-space-2);
    padding: var(--vb-space-2) var(--vb-space-4);
  }

  .verbault-reader .vb-reader-chapter-popup {
    left: 0;
    right: 0;
  }

  .vb-reader-playbar__inner { gap: var(--vb-space-2); }
  .vb-reader-playbar__transport {
    width: 100%; justify-content: space-between; flex-wrap: nowrap;
  }
  /* Popover is position:absolute inside the ~40px ⋯ button container. Setting
     BOTH left:0 and right:0 pinned its width to that 40px → content overflowed
     off the right edge. Anchor the right edge (near the screen edge) and size to
     content leftward, capped to the viewport so it never clips. */
  .vb-reader-controls-popover {
    left: auto; right: 0; min-width: 0; max-width: calc(100vw - 24px);
  }

  body[data-view="reader"] {
    padding-bottom: 84px;
  }
}

@media (max-width: 420px) {
  .verbault-reader.vb-reader-card {
    padding: var(--vb-space-3);
    border-radius: var(--vb-radius-md);
  }

  .verbault-reader .vb-reader-chapter-nav {
    margin: 0 calc(-1 * var(--vb-space-3)) var(--vb-space-2);
    padding: var(--vb-space-2) var(--vb-space-3);
  }

  .verbault-reader .vb-reader-title {
    font-size: var(--vb-text-xl);
  }

  .vb-reader-play-circle {
    width: 48px;
    height: 48px;
    font-size: var(--vb-text-lg);
  }
}

/* Section 9: Bookmark chip + sentence flash */
/* 북마크 칩 — 문장 끝에 append, 하이라이트/저장 시 표시.
   margin-left 로 앞 단어와 띄운다 (firstChild 시절 margin-right 잔재 제거 — 끝으로 이동). */
.vb-reader-bookmark-chip {
  display: none;
  align-items: center;
  gap: 4px;
  margin-left: var(--vb-space-1);
  padding: 2px 7px;
  font-family: var(--vb-font-sans);
  font-size: var(--vb-text-xs);
  line-height: 1.4;
  border: 1.5px solid var(--vb-aubergine);
  border-radius: var(--vb-radius-full);
  /* 불투명 배경 — tan 활성 하이라이트 위에서 칩이 또렷하게 떠 보이도록 */
  background: var(--vb-bg-elevated);
  color: var(--vb-aubergine);
  cursor: pointer;
  vertical-align: middle;
  user-select: none;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
  transition: background-color var(--vb-dur-fast) var(--vb-ease),
              color var(--vb-dur-fast) var(--vb-ease);
}
.vb-reader-bookmark-chip svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 2; }
.vb-reader-bookmark-chip:hover { background: var(--vb-aubergine-soft); }

/* 저장된 문장 — solid aubergine + 밝은 아이콘으로 활성 탭에서 "켜짐" 명확화.
   ⚠ display 는 설정하지 않는다(§265): 비활성 저장문장의 칩을 inline 으로 띄우면
   탭 토글 reflow 의 원인 → 비활성 표시는 문장 border-left+배경(.--bookmarked, 위)
   이 담당하고, 칩은 활성 문장 고정 탭에서만 보인다. 활성+저장 시 이 색이 적용돼
   filled 탭이 된다. */
.vb-reader-sentence--bookmarked .vb-reader-bookmark-chip {
  background: var(--vb-aubergine);
  border-color: var(--vb-aubergine);
  color: var(--vb-text-on-accent);
}
.vb-reader-sentence--bookmarked .vb-reader-bookmark-chip svg { fill: currentColor; }
.vb-reader-sentence--bookmarked .vb-reader-bookmark-chip:hover {
  background: color-mix(in srgb, var(--vb-aubergine), black 12%);
}

/* 활성 문장 — 저장 여부와 무관하게 칩 표시 (저장 안 됨: 불투명 아웃라인 형태) */
.vb-reader-sentence--active .vb-reader-bookmark-chip { display: inline-flex; }

/* ═══ §265 chip word-jump fix ═══════════════════════════════════════════════
   The active sentence's bookmark chip renders as a FIXED right-edge tab
   below the Vocabulary ribbon — styled to match it (vertical, rounded left,
   aubergine-medium).
   position:fixed takes the chip OUT of inline flow, so showing/hiding it on
   sentence (de)activation no longer toggles inline width → the text never
   reflows and the tapped word never jumps left. Only one sentence is active at
   a time, so exactly one chip is ever fixed-positioned. Non-active state is
   shown without the chip (bookmark=border-left+bg). The chip click handler is
   unchanged — these are the same per-sentence elements, only repositioned.
   ⚠ §277: the chip sits BELOW the centered Vocabulary ribbon. On phones it must
   clear the playbar's band on viewports ≤~700px (playbar is position:fixed
   bottom:56px on mobile, ~137px tall, equal z-index and later in DOM → it would
   paint over a chip placed too low; verified occluded via elementFromPoint).
   Below the ribbon there is ~72px to the playbar, enough for one 46px tab down
   to a 640px-tall phone.
   ⚠ top offset assumes the centered ribbon (~108px tall, English "Vocabulary");
   verify alignment on deploy. position:fixed is viewport-relative here — no
   reader ancestor establishes a containing block (.verbault-reader is only
   position:relative, which traps absolute not fixed). */
.verbault-reader .vb-reader-sentence--active .vb-reader-bookmark-chip {
  position: fixed;
  right: max(0px, calc((100vw - 1000px) / 2));
  z-index: 50;
  box-sizing: border-box;
  width: 31px;          /* match the Vocabulary ribbon width exactly (no protrusion) */
  height: 46px;
  margin: 0;
  padding: 0;
  justify-content: center;
  writing-mode: vertical-rl;
  text-orientation: mixed;
  border: 0;
  border-radius: 10px 0 0 10px;
  background: var(--vb-aubergine-medium);
  color: var(--vb-aubergine);
  letter-spacing: .04em;
  box-shadow: none;
}
/* bookmark chip: fixed right-edge tab, positioned below the Vocabulary ribbon. */
.verbault-reader .vb-reader-sentence--active .vb-reader-bookmark-chip { top: calc(50% + 60px); }
.verbault-reader .vb-reader-sentence--active .vb-reader-bookmark-chip:hover {
  background: var(--vb-aubergine);
  color: var(--vb-text-on-accent);
}
/* active + saved → filled tab (must out-specify the fixed-tab bg above). */
.verbault-reader .vb-reader-sentence--active.vb-reader-sentence--bookmarked .vb-reader-bookmark-chip {
  background: var(--vb-aubergine);
  color: var(--vb-text-on-accent);
}
/* Reader BODY only: never float the tabs while the Vocabulary word-list panel is
   open. showReaderVocabPanel() already hides #reader-content (display:none cascades
   to these descendants), but this guards independent of the hide mechanism — a
   fixed-positioned chip is easy to leak onto the wrong surface. (Other views hide
   via section.view[hidden]{display:none}, which also removes them.) */
.verbault-reader:has(#reader-vocab-ribbon[aria-pressed="true"]) .vb-reader-sentence--active .vb-reader-bookmark-chip {
  display: none;
}

/* 점프 시 일시 플래시 (2400ms) */
.vb-reader-sentence--flash { animation: vb-reader-sentence-flash 2.4s var(--vb-ease-out); }
@keyframes vb-reader-sentence-flash {
  0%   { background: var(--vb-aubergine-medium); }
  100% { background: transparent; }
}

/* ── Vocabulary collector ribbon + panel (Reader §) ──────────────────────── */
.verbault-reader { position: relative; }            /* anchor for the ribbon */
/* 리본: 뷰포트 고정 오버레이(스크롤해도 항상 보임, 데스크탑/모바일 동일 위치).
   데스크탑은 980px 리더 컬럼 우측 가장자리에, 모바일(좁은 화면)은 화면 우측 끝에 clamp. */
.vb-reader-vocab-ribbon {
  position: fixed; top: 50%; transform: translateY(-50%);
  right: max(0px, calc((100vw - 1000px) / 2));
  z-index: 50;
  writing-mode: vertical-rl; text-orientation: mixed;
  padding: 16px 8px; border-radius: 10px 0 0 10px;   /* 오른쪽 가장자리에 붙은 탭 */
  background: var(--vb-aubergine-medium); color: var(--vb-aubergine);
  font-weight: 600; letter-spacing: .04em; cursor: pointer; user-select: none;
  border: 0; transition: background .15s ease, color .15s ease;
}
.vb-reader-vocab-ribbon:hover,
.vb-reader-vocab-ribbon[aria-pressed="true"] {
  background: var(--vb-aubergine); color: var(--vb-text-on-accent);
}
.vb-reader-vocab-panel[hidden] { display: none; }   /* hidden attr beats display:flex */
.vb-reader-vocab-panel { display: flex; flex-direction: column; gap: 18px; padding: 4px 2px; }
/* First-open loading placeholder — centered, not a left-aligned group header. */
.vb-reader-vocab-loading {
  font-family: var(--vb-font-sans);
  font-size: var(--vb-text-sm);
  color: var(--vb-text-secondary);
  text-align: center;
  padding: 32px 0;
}
.vb-reader-vocab-group-title {
  font-family: var(--vb-font-sans);
  font-weight: 700;
  font-size: var(--vb-text-sm);
  letter-spacing: .1em;
  text-transform: uppercase;
}
/* 6-band CEFR group titles. A=easy / B=medium / C=hard hue (theme-safe reuse of
   the proven reader-level vars); the band code in the title text disambiguates the
   two sub-bands per tier, so colour need not be unique — same colourblind-safe
   philosophy as the .cefr--tag badges. */
.vb-reader-vocab-group--A1 .vb-reader-vocab-group-title,
.vb-reader-vocab-group--A2 .vb-reader-vocab-group-title { color: var(--vb-reader-level-easy); }
.vb-reader-vocab-group--B1 .vb-reader-vocab-group-title,
.vb-reader-vocab-group--B2 .vb-reader-vocab-group-title { color: var(--vb-reader-level-medium); }
.vb-reader-vocab-group--C1 .vb-reader-vocab-group-title,
.vb-reader-vocab-group--C2 .vb-reader-vocab-group-title { color: var(--vb-reader-level-hard); }
.vb-reader-vocab-group--other .vb-reader-vocab-group-title { color: var(--vb-text-secondary); }
/* 단어 = 격자 테이블 (셀 경계선). 레벨 섹션은 세로로 적층. */
.vb-reader-vocab-words {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  border-top: 1px solid var(--vb-border);
  border-left: 1px solid var(--vb-border);
}
.vb-reader-vocab-word {
  display: flex; align-items: center; gap: 6px; cursor: pointer;
  padding: 5px 8px;
  border-right: 1px solid var(--vb-border);
  border-bottom: 1px solid var(--vb-border);
  font-family: var(--vb-font-sans);
  font-weight: 400;                  /* BOLD 해제 */
  font-size: var(--vb-text-sm);
  color: var(--vb-text-primary);
}
/* 이미 단어장에 저장된 단어 — 식별력 강한 테마색(sage) + 틴트 배경, 재선택 불가 */
.vb-reader-vocab-word--saved { background: var(--vb-highlight-learned); }
.vb-reader-vocab-word--saved span { color: var(--vb-sage); font-weight: 600; }
.vb-reader-vocab-word--saved input { cursor: default; }
/* 도움말 + 레벨별 전체 선택/해제/저장 */
.vb-reader-vocab-help {
  font-size: var(--vb-text-sm); color: var(--vb-text-secondary); line-height: 1.5;
}
.vb-reader-vocab-caveat { font-style: italic; opacity: .85; }
.vb-reader-vocab-group-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding-bottom: 6px;
  border-bottom: 2px solid var(--vb-border);   /* 테마 섹션 언더라인 */
}
.vb-reader-vocab-bulk { display: inline-flex; gap: 8px; align-items: center; }
/* 토글(전체 선택⇄해제)·저장은 동일 base — min-width 로 같은 폭, 중앙 정렬 */
.vb-reader-vocab-bulk button {
  box-sizing: border-box;
  min-width: 6.75em; text-align: center;
  font-family: var(--vb-font-sans);
  font-size: var(--vb-text-xs);
  color: var(--vb-aubergine);
  background: var(--vb-aubergine-soft);
  border: 1px solid var(--vb-aubergine-medium);
  border-radius: var(--vb-radius-full);
  padding: 3px 12px; cursor: pointer; text-decoration: none;
  transition: background .12s ease, color .12s ease;
}
.vb-reader-vocab-bulk button:hover {
  background: var(--vb-aubergine); color: var(--vb-text-on-accent);
}
.vb-reader-vocab-bulk button:disabled {
  opacity: .4; cursor: not-allowed;
}
.vb-reader-vocab-bulk button:disabled:hover {
  background: var(--vb-aubergine-soft); color: var(--vb-aubergine);
}
/* 레벨별 저장 = 채워진 강조 액션(선택 pill 과 구분), 클러스터 맨 오른쪽 */
.vb-reader-vocab-bulk .vb-reader-vocab-save,
.vb-reader-vocab-bulk .vb-reader-vocab-save:hover {
  color: var(--vb-text-on-accent);
  background: var(--vb-aubergine);
  border-color: var(--vb-aubergine);
  font-weight: 600;
}
.vb-reader-vocab-bulk .vb-reader-vocab-save:disabled {
  opacity: .4; cursor: not-allowed;
}

/* ── Chapter quiz button + progress badge (§151) ────────────────────────── */
.vb-reader-quiz-btn {
  position: relative;
  font-weight: 600;
  gap: 2px;
  /* Override .vb-reader-playbar__icon's fixed 36px width so the progress
     count (e.g. "13/3691" for books with many chapters) grows as a pill
     instead of being clipped inside the 36px circle. */
  width: auto;
  min-width: 36px;
  padding: 0 10px;
}
.vb-reader-quiz-btn[hidden] { display: none; }
.vb-reader-quiz-progress {
  font-size: var(--vb-text-sm);
  line-height: 1;
  max-width: 7em;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.vb-reader-quiz-btn.is-complete {
  background: var(--vb-aubergine-soft);
  color: var(--vb-aubergine);
  border-color: var(--vb-aubergine);
}

/* ── Chapter quiz modal overlay + panel ─────────────────────────────────── */
.vb-quiz-modal {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: color-mix(in srgb, var(--vb-ink) 55%, transparent);
  z-index: 9900;
}
.vb-quiz-modal[hidden] { display: none; }
.vb-quiz-modal__panel {
  display: flex;
  flex-direction: column;
  background: var(--vb-bg-page);
  border: 0.5px solid var(--vb-border);
  border-radius: var(--vb-radius-lg);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.18);
  width: min(520px, calc(100vw - 32px));
  max-height: 85vh;
  overflow-y: auto;
}
.vb-quiz-modal__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--vb-space-3);
  padding: var(--vb-space-4) var(--vb-space-5);
  border-bottom: 0.5px solid var(--vb-border);
}
.vb-quiz-modal__head h2 {
  margin: 0;
  font-size: var(--vb-text-lg, 1.125rem);
  font-family: var(--vb-font-serif, serif);
  color: var(--vb-text-primary);
}
.vb-quiz-modal__close {
  background: none;
  border: none;
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  color: var(--vb-text-secondary);
  padding: 4px 8px;
  border-radius: var(--vb-radius-full);
  transition: background var(--vb-dur-fast) var(--vb-ease);
}
.vb-quiz-modal__close:hover { background: var(--vb-aubergine-soft); color: var(--vb-aubergine); }
.vb-quiz-modal__body {
  padding: var(--vb-space-4) var(--vb-space-5);
  display: flex;
  flex-direction: column;
  gap: var(--vb-space-3);
}
.vb-quiz-modal__foot {
  padding: var(--vb-space-3) var(--vb-space-5);
  border-top: 0.5px solid var(--vb-border);
  display: flex;
  justify-content: flex-end;
}
.vb-quiz-q {
  margin: 0;
  padding: var(--vb-space-3);
  border: 0.5px solid var(--vb-border);
  border-radius: var(--vb-radius-md, 8px);
}
.vb-quiz-q legend {
  font-size: var(--vb-text-sm);
  font-weight: 500;
  padding: 0 4px;
  color: var(--vb-text-primary);
}
.vb-quiz-choice {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 4px 0;
  font-size: var(--vb-text-sm);
  color: var(--vb-text-primary);
  cursor: pointer;
}

/* Section 11: Scroll-driven chrome auto-hide (Reader view only).
   transform(=not display) keeps position:fixed chip anchors stable. */
body[data-view="reader"] .verbault-reader .vb-reader-chapter-nav,
body[data-view="reader"] .vb-reader-playbar {
  transition: transform var(--vb-dur-base, 220ms) var(--vb-ease, ease);
  will-change: transform;
}
body[data-view="reader"].reader-chrome-hidden .verbault-reader .vb-reader-chapter-nav {
  transform: translateY(calc(-100% - var(--vb-nav-h, 64px)));
}
body[data-view="reader"].reader-chrome-hidden .vb-reader-playbar {
  transform: translateY(100%);
}
/* Masthead auto-hide is DESKTOP-ONLY: on mobile (<=640px) .vb-nav contains the
   position:fixed bottom tab bar (.vb-nav-items); a transform/will-change on
   .vb-nav would become that child's containing block and break its bottom:0
   positioning (tab bar jumps to the top). At >=641px the nav items are inline
   children, so the masthead can hide safely. On mobile the masthead stays; the
   chapter-nav, playbar, and tab bar still hide. */
@media (min-width: 641px) {
  body[data-view="reader"] .vb-nav {
    transition: transform var(--vb-dur-base, 220ms) var(--vb-ease, ease);
    will-change: transform;
  }
  body[data-view="reader"].reader-chrome-hidden .vb-nav {
    transform: translateY(-100%);
  }
}
@media (prefers-reduced-motion: reduce) {
  body[data-view="reader"] .verbault-reader .vb-reader-chapter-nav,
  body[data-view="reader"] .vb-reader-playbar { transition: none; }
}
@media (min-width: 641px) and (prefers-reduced-motion: reduce) {
  body[data-view="reader"] .vb-nav { transition: none; }
}

/* Mobile: the playbar sits above the bottom tab bar (bottom:56px), so it must
   translate by its own height PLUS that offset to fully clear the viewport. */
@media (max-width: 640px) {
  body[data-view="reader"].reader-chrome-hidden .vb-reader-playbar {
    transform: translateY(calc(100% + 56px + env(safe-area-inset-bottom)));
  }
}

/* Section 12: Sentence shuttle — minimal prev/next, floats bottom-center ONLY
   while the reading chrome is auto-hidden, so the reader can step through
   sentences without restoring the full chrome. It is a sibling of (not nested
   in) the transformed playbar, so its position:fixed resolves against the
   viewport (the transform-ancestor containing-block trap). Visibility is driven
   purely by the body.reader-chrome-hidden class; visibility:hidden also removes
   it from tab order and the a11y tree when not shown (no JS aria toggling). */
.vb-reader-sentence-shuttle {
  position: fixed;
  left: 50%;
  bottom: calc(var(--vb-space-4) + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%) translateY(10px);
  display: flex;
  gap: 2px;
  padding: 4px;
  background: var(--vb-bg-elevated);
  border: 0.5px solid var(--vb-border);
  border-radius: var(--vb-radius-full);
  box-shadow: var(--vb-shadow-lg, 0 6px 20px rgba(0, 0, 0, 0.18));
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  z-index: 55;
  transition: opacity var(--vb-dur-fast) var(--vb-ease),
              transform var(--vb-dur-fast) var(--vb-ease),
              visibility var(--vb-dur-fast) var(--vb-ease);
}
body[data-view="reader"].reader-chrome-hidden .vb-reader-sentence-shuttle {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
  pointer-events: auto;
}
.vb-reader-shuttle-btn {
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: transparent;
  color: var(--vb-text-secondary);
  border: 0;
  border-radius: var(--vb-radius-full);
  cursor: pointer;
  transition: background-color var(--vb-dur-fast) var(--vb-ease),
              color var(--vb-dur-fast) var(--vb-ease);
}
.vb-reader-shuttle-btn:hover:not(:disabled) {
  background: var(--vb-aubergine-soft);
  color: var(--vb-aubergine);
}
.vb-reader-shuttle-btn:disabled {
  opacity: 0.32;
  cursor: default;
}
.vb-reader-shuttle-btn:focus-visible {
  outline: 2px solid var(--vb-aubergine);
  outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  .vb-reader-sentence-shuttle,
  body[data-view="reader"].reader-chrome-hidden .vb-reader-sentence-shuttle {
    transition: opacity var(--vb-dur-fast) var(--vb-ease);
    transform: translateX(-50%);
  }
}
