/* ══════════════════════════════════════════════════════════════
   shadowee — Path page (mockup 23a "Illustrated journey")
   Loaded after home-calm.css by path.html only.

   Every number below comes from the mockup source
   (mockup/English learning app home screen/English App Home.dc.html):
   the 23a markup, j23()/j23Pal() (map) and lsnVals() (hop overlay).
   Colour/shadow tokens are organic.css verbatim; type uses the app's own
   fonts (Nunito headings, Plus Jakarta Sans body — the same as every other
   page) instead of the mockup's Caprasimo/Figtree. The map is drawn on the mockup's 390 x 2790 design
   canvas and scaled to the column width (pixel-exact at 390px).
   ══════════════════════════════════════════════════════════════ */

.path-body {
  /* organic.css tokens */
  --color-bg: #f5ead8;
  --color-surface: #ebddc5;
  --color-text: #201e1d;
  --color-accent: #c67139;
  --color-accent-2: #7a8a5e;
  --color-divider: color-mix(in srgb, #201e1d 16%, transparent);

  --color-neutral-100: #f9f4ed;
  --color-neutral-200: #eee7db;
  --color-neutral-300: #dcd3c4;
  --color-neutral-400: #c0b6a5;
  --color-neutral-500: #a19786;
  --color-neutral-600: #82796a;
  --color-neutral-700: #645c50;
  --color-neutral-800: #474238;
  --color-neutral-900: #2e2b25;

  --color-accent-100: #fff2eb;
  --color-accent-200: #ffe1d0;
  --color-accent-300: #ffc6a5;
  --color-accent-400: #f6a06b;
  --color-accent-500: #d67f48;
  --color-accent-600: #b2622d;
  --color-accent-700: #8c491a;
  --color-accent-800: #643312;
  --color-accent-900: #402310;

  --color-accent-2-100: #f0fae1;
  --color-accent-2-200: #e1eecc;
  --color-accent-2-300: #ccdbb2;
  --color-accent-2-400: #aebf92;
  --color-accent-2-500: #8fa073;
  --color-accent-2-600: #728157;
  --color-accent-2-700: #56633f;
  --color-accent-2-800: #3d472b;
  --color-accent-2-900: #272e1b;

  /* the app's fonts (home-calm.css): Nunito headings, Plus Jakarta Sans body */
  --font-heading: var(--cg-font-heading, 'Nunito', system-ui, sans-serif);
  --font-body: var(--cg-font-body, 'Plus Jakarta Sans', system-ui, sans-serif);

  --shadow-sm: 0 1px 2px color-mix(in srgb, #2e2b25 14%, transparent);
  --shadow-md: 0 3px 10px color-mix(in srgb, #2e2b25 16%, transparent);
  --shadow-lg: 0 12px 32px color-mix(in srgb, #2e2b25 22%, transparent);

  /* set per level by path.js (j23Pal().page) */
  --pt-page: var(--color-bg);

  background: var(--pt-page);
  color: var(--color-text);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
}

.path-body *,
.path-body *::before,
.path-body *::after { box-sizing: border-box; }
.path-body [hidden] { display: none !important; }
.path-body button { font-family: inherit; }
.path-body ::-webkit-scrollbar { display: none; }

/* Modals / toast must sit above the practice overlay (z-index 600). */
.path-body .modal-backdrop { z-index: 700; }
.path-body #toast { z-index: 800; }

@keyframes om-breathe { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }
@keyframes om-glow {
  0%, 100% { box-shadow: 0 0 0 0 rgba(198, 113, 57, .35); }
  50%      { box-shadow: 0 0 0 14px rgba(198, 113, 57, 0); }
}
/* Whole-passage row states (23a mockup revision 2) */
@keyframes om-eq { 0%, 100% { transform: scaleY(.35); } 50% { transform: scaleY(1); } }
@keyframes om-turn {
  0%, 100% { box-shadow: inset 0 0 0 2px rgba(198, 113, 57, .25); }
  50%      { box-shadow: inset 0 0 0 2px rgba(198, 113, 57, .75); }
}

/* ─── Shell ────────────────────────────────────────────────── */
.pt-main {
  position: relative;
  width: 100%;
  max-width: 480px;
  margin: 0 auto;
}
.pt-status {
  padding: 60px 16px;
  text-align: center;
  color: var(--color-neutral-700);
  font: 500 14px var(--font-body);
}
.pt-status.error { color: var(--color-accent-700); }
.pt-status button {
  margin-left: 6px;
  padding: 6px 14px;
  border: 0;
  border-radius: 999px;
  background: var(--color-accent-700);
  color: #fff;
  font: 800 12px var(--font-body);
  cursor: pointer;
}
.pt-login {
  margin: 40px 16px;
  padding: 40px 20px;
  text-align: center;
  background: var(--color-neutral-100);
  border-radius: 28px;
  box-shadow: var(--shadow-md);
}
.pt-login-title { font: 800 20px var(--font-heading); margin-bottom: 8px; }
.pt-login-sub { font: 400 13px/1.5 var(--font-body); color: var(--color-neutral-700); margin-bottom: 18px; }
.pt-login-btn {
  padding: 14px 24px;
  border: 0;
  border-radius: 999px;
  background: var(--color-accent-700);
  color: #fff;
  font: 800 13px var(--font-body);
  cursor: pointer;
}
.pt-login-btn:hover { background: var(--color-accent-800); }

/* ─── Journey map ──────────────────────────────────────────── */
#path-content {
  position: fixed;
  inset: 0;
  max-width: 480px;
  margin: 0 auto;
  z-index: 1;
}
.pt-scroll {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  background: var(--pt-page);
}
/* The design canvas is 390 x 2790; --pt-s (set by path.js) scales it to the column. */
.pt-sizer { position: relative; width: 100%; height: calc(2790px * var(--pt-s, 1)); }
.pt-canvas {
  position: absolute;
  left: 0;
  top: 0;
  width: 390px;
  height: 2790px;
  transform-origin: 0 0;
  transform: scale(var(--pt-s, 1));
}
.pt-terrain-wrap svg { position: absolute; left: 0; top: 0; display: block; }
.pt-map {
  position: absolute;
  inset: 0;
  transition: transform .42s cubic-bezier(.35, 0, .2, 1), opacity .3s ease;
}

/* Hop node: 72px (current 86, checkpoint 80), 5px ring, bottom-right badge, name pill below */
.pt-hop {
  position: absolute;
  padding: 0;
  border-radius: 999px;
  border-style: solid;
  border-width: 5px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.pt-hop:hover { filter: brightness(1.07); }
.pt-hop:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 3px; }
.pt-hop-halo {
  position: absolute;
  width: 116px;
  height: 116px;
  border-radius: 999px;
  background: var(--color-accent-200);
  opacity: .8;
  animation: om-breathe 2.6s ease-in-out infinite;
  pointer-events: none;
}
.pt-hop-badge {
  position: absolute;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
.pt-hop-badge.done { width: 26px; height: 26px; background: var(--color-neutral-100); box-shadow: var(--shadow-sm); }
.pt-hop-badge.locked { width: 26px; height: 26px; background: var(--color-neutral-100); box-shadow: var(--shadow-sm); }
.pt-hop-badge.current { width: 30px; height: 30px; background: var(--color-accent-300); border: 3px solid var(--color-neutral-100); }
.pt-hop-name {
  position: absolute;
  width: 190px;
  display: flex;
  justify-content: center;
  pointer-events: none;
}
.pt-hop-name span {
  padding: 6px 14px;
  border-radius: 999px;
  box-shadow: var(--shadow-sm);
  font: 700 12px var(--font-body);
}

/* Unit pill + arrows (scroll with the map) */
.pt-unit-pill {
  position: absolute;
  left: 20px;
  top: 144px;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 9px 16px 9px 13px;
  border-radius: 14px;
  background: var(--color-accent-800);
  box-shadow: var(--shadow-md);
}
.pt-unit-pill span { font: 800 14px var(--font-heading); color: #f5ead8; }
.pt-nav {
  position: absolute;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  text-align: left;
  -webkit-tap-highlight-color: transparent;
}
.pt-nav.locked { cursor: default; }
.pt-nav:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; border-radius: 26px; }
.pt-nav-disc {
  position: absolute;
  width: 52px;
  height: 52px;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.pt-nav.up { left: 169px; top: 60px; width: 212px; height: 52px; }
.pt-nav.up .pt-nav-disc { left: 0; top: 0; background: var(--color-neutral-100); box-shadow: var(--shadow-md); }
.pt-nav.up:hover .pt-nav-disc { background: var(--color-accent-100); }
.pt-nav.up .pt-nav-label {
  position: absolute;
  left: 60px;
  top: 6px;
  width: 152px;
  font: 700 11.5px/1.3 var(--font-body);
  color: var(--pt-ink, var(--color-text));
}
.pt-nav.up:hover .pt-nav-label { color: var(--color-accent-700); }
.pt-nav.down { left: 0; top: 2482px; width: 390px; height: 80px; }
.pt-nav.down .pt-nav-disc { left: 169px; top: 0; }
.pt-nav.down:not(.locked) .pt-nav-disc { background: var(--color-accent-700); box-shadow: var(--shadow-md); }
.pt-nav.down:not(.locked):hover .pt-nav-disc { background: var(--color-accent-800); }
.pt-nav.down.locked .pt-nav-disc { background: var(--color-neutral-300); box-shadow: var(--shadow-sm); }
.pt-nav.down .pt-nav-label {
  position: absolute;
  left: 0;
  top: 62px;
  width: 390px;
  text-align: center;
  font: 700 12px var(--font-body);
  color: var(--color-accent-800);
}
.pt-nav.down:not(.locked):hover .pt-nav-label { opacity: .75; }
.pt-nav.down .pt-nav-note {
  position: absolute;
  left: 0;
  top: 62px;
  width: 390px;
  text-align: center;
  font: 600 11.5px var(--font-body);
  color: var(--pt-muted, var(--color-neutral-700));
}
.pt-nav-lock {
  position: absolute;
  left: 206px;
  top: -10px;
  width: 24px;
  height: 24px;
  border-radius: 999px;
  background: var(--color-neutral-100);
  border: 2px solid var(--color-bg);
  box-shadow: var(--shadow-sm);
  display: flex;
  align-items: center;
  justify-content: center;
}
.pt-end-note {
  position: absolute;
  left: 0;
  top: 2544px;
  width: 390px;
  text-align: center;
  font: 600 11.5px var(--font-body);
  color: var(--pt-muted, var(--color-neutral-700));
}

/* Floating chrome over the map */
.pt-topfade {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 104px;
  z-index: 5;
  pointer-events: none;
  background: linear-gradient(var(--pt-fade-1, rgba(245, 234, 216, .94)), var(--pt-fade-0, rgba(245, 234, 216, 0)));
}
.pt-levels {
  position: absolute;
  left: 50%;
  bottom: calc(92px + max(0px, env(safe-area-inset-bottom) - 24px));
  transform: translateX(-50%);
  z-index: 6;
  display: flex;
  gap: 3px;
  padding: 5px;
  border-radius: 999px;
  background: var(--color-neutral-100);
  box-shadow: var(--shadow-lg);
}
.pt-level {
  padding: 7px 10px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--color-neutral-800);
  font: 800 12px var(--font-body);
  cursor: pointer;
}
.pt-level:hover { filter: brightness(1.06); }
.pt-level.active { background: var(--color-accent-700); color: #fff; }

/* Tab bar: deliberately no path-specific styling — uses css/home-calm.css's
   shared .cg-tabbar/.cg-tab rules unmodified, exactly like every other page. */

/* ─── Table of contents icon + popup (23a's j23Toc) ──────────── */
.pt-toc-btn {
  position: absolute;
  top: calc(50px + env(safe-area-inset-top, 0px));
  left: 18px;
  z-index: 7;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 999px;
  background: var(--color-neutral-100);
  box-shadow: var(--shadow-md);
  color: var(--color-accent-700);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
}
.pt-toc-btn:hover { background: var(--color-accent-100); }

/* Popup: a near-full-height inset panel, the mockup's own exact numbers
   (left/right:16, top:64, bottom:64, radius:28, dim:.42) — distinct from
   the setup popups' own panel (css/path.css's .pt-setup-panel, which
   uses the "ob" flow's own slightly different numbers). */
.pt-toc-backdrop { align-items: stretch; background: rgba(32, 30, 29, .42); backdrop-filter: none; }
.pt-toc-panel {
  position: fixed;
  left: 16px;
  right: 16px;
  top: 64px;
  bottom: 64px;
  max-width: 480px;
  max-height: none;
  margin: 0 auto;
  padding: 0;
  border-radius: 28px;
  background: var(--color-bg);
  box-shadow: var(--shadow-lg);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  font-family: var(--font-body);
}
.pt-toc-head {
  flex: none;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 22px 20px 12px 24px;
}
.pt-toc-header-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.pt-toc-eyebrow {
  font: 800 10px var(--font-body);
  letter-spacing: .14em;
  color: var(--color-accent-700);
}
.pt-toc-title { font: 400 22px/1.2 var(--font-heading); color: var(--color-text); }
.pt-toc-close {
  flex: none;
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: 999px;
  background: var(--color-neutral-200);
  color: var(--color-neutral-800);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
}
.pt-toc-close:hover { background: var(--color-accent-200); }

.pt-toc-list {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 4px 14px 28px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
/* The background + rounded corners belong to the whole unit (head + its
   expanded hops together), only tinted for the unit currently being
   viewed — not every unit, and not just its head row. */
.pt-toc-unit {
  display: flex;
  flex-direction: column;
  border-radius: 20px;
  background: transparent;
}
.pt-toc-unit.viewing { background: var(--color-neutral-100); }
.pt-toc-unit-head {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 14px;
  border: 0;
  border-radius: 20px;
  background: none;
  cursor: pointer;
  text-align: left;
}
.pt-toc-unit-head:hover { filter: brightness(.98); }
.pt-toc-unit-head-locked { opacity: .7; }
.pt-toc-unit-dot {
  flex: none;
  width: 40px;
  height: 40px;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  font: 800 14px var(--font-body);
  color: #fff;
  background: var(--color-neutral-200);
}
.pt-toc-unit-dot-done { background: var(--color-accent-2-600); }
.pt-toc-unit-dot-current { background: var(--color-accent-700); }
.pt-toc-unit-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.pt-toc-unit-title { font: 700 15px/1.3 var(--font-body); color: var(--color-text); }
.pt-toc-unit-meta { font: 600 12px var(--font-body); }
.pt-toc-unit-meta-current { color: var(--color-accent-700); }
.pt-toc-unit-meta-done { color: var(--color-accent-2-800); }
.pt-toc-unit-meta-locked { color: var(--color-neutral-600); }
.pt-toc-viewing {
  flex: none;
  padding: 5px 10px;
  border-radius: 999px;
  background: var(--color-accent-200);
  font: 800 10.5px var(--font-body);
  color: var(--color-accent-800);
}
.pt-toc-chev { flex: none; display: flex; transition: transform .2s ease; color: var(--color-neutral-700); }
.pt-toc-chev.open { transform: rotate(180deg); }

.pt-toc-hops { display: flex; flex-direction: column; gap: 2px; padding: 0 10px 12px 30px; }
.pt-toc-hop {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 10px;
  border: 0;
  border-radius: 14px;
  background: none;
  cursor: pointer;
  text-align: left;
}
.pt-toc-hop:hover:not(:disabled) { background: var(--color-accent-100); }
.pt-toc-hop:disabled { cursor: default; opacity: .7; }
.pt-toc-hop-dot {
  flex: none;
  width: 24px;
  height: 24px;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-neutral-200);
}
.pt-toc-hop-done .pt-toc-hop-dot { background: var(--color-accent-2-600); }
.pt-toc-hop-current .pt-toc-hop-dot { background: var(--color-accent-700); }
.pt-toc-hop-name { flex: 1; min-width: 0; font: 600 13.5px/1.3 var(--font-body); color: var(--color-text); }
.pt-toc-hop-locked .pt-toc-hop-name { color: var(--color-neutral-700); }
.pt-toc-hop-current .pt-toc-hop-name { font-weight: 800; }

/* ─── First-visit setup: language + level (23a's "ob" flow) ──────
   Shared outer panel for both steps — a near-full-height inset panel
   (the mockup's own onboarding chrome), not a small centered dialog.
   Replaces an earlier, unrelated "18a bottom sheet" reskin of the
   shared translate-sheet — see the block below for the language step. */
.pt-setup-backdrop { align-items: stretch; background: rgba(32, 30, 29, .5); backdrop-filter: none; }
.pt-setup-panel {
  position: fixed;
  left: 14px;
  right: 14px;
  top: 56px;
  bottom: 40px;
  max-width: 480px;
  max-height: none;
  margin: 0 auto;
  padding: 0;
  border-radius: 32px;
  background: var(--color-bg);
  box-shadow: var(--shadow-lg);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  font-family: var(--font-body);
}
.pt-setup-close {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 1;
}

/* Step 2: level (new — path's level is its own preference, see
   PT_LEVEL_KEY in path.js). Title/level-labels/Go button are localized
   to whichever language was just picked in step 1 — ptSetupI18n(). */
.pt-setup-step-head {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 18px 18px 4px;
}
.pt-setup-back {
  flex: none;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 999px;
  background: var(--color-neutral-200);
  color: var(--color-neutral-800);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
}
.pt-setup-back:hover { background: var(--color-accent-200); }
.pt-setup-panel[dir="rtl"] .pt-setup-back svg { transform: scaleX(-1); }
.pt-setup-lang-name { font: 700 14px var(--font-body); color: var(--color-neutral-700); }

.pt-setup-level-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 14px 20px 12px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.pt-setup-level-title { font: 400 26px/1.2 var(--font-heading); color: var(--color-text); }
.pt-level-setup-list { display: flex; flex-direction: column; gap: 8px; }
.pt-setup-level-row {
  width: 100%;
  min-height: 62px;
  padding: 0 18px;
  border-radius: 20px;
  background: var(--color-neutral-100);
  border: 2px solid transparent;
  display: flex;
  align-items: center;
  gap: 16px;
  cursor: pointer;
  text-align: left;
}
.pt-setup-level-row:hover { filter: brightness(.97); }
.pt-setup-level-row.selected { background: var(--color-accent-100); border-color: var(--color-accent); }
.pt-setup-level-bars { flex: none; display: flex; align-items: flex-end; gap: 3px; height: 22px; }
.pt-setup-level-bar { width: 5px; border-radius: 999px; background: var(--color-neutral-300); }
.pt-setup-level-bar.on { background: var(--color-accent); }
.pt-setup-level-label { flex: 1; min-width: 0; font: 700 18px var(--font-body); color: var(--color-text); }
.pt-setup-level-code { flex: none; font: 800 12px var(--font-body); color: var(--color-neutral-600); }

.pt-setup-go-wrap { flex: none; padding: 10px 20px 22px; }
.pt-setup-go {
  width: 100%;
  height: 58px;
  border: 0;
  border-radius: 999px;
  background: var(--color-accent);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  cursor: pointer;
  font: 800 18px var(--font-body);
}
.pt-setup-go:hover { background: var(--color-accent-600); }
.pt-setup-go:disabled { cursor: default; }
.pt-setup-panel[dir="rtl"] .pt-setup-go svg { transform: scaleX(-1); }

/* ─── Hop practice overlay (23a "lsn" screen) ──────────────── */
.pt-overlay:focus { outline: none; }
.pt-overlay {
  position: fixed;
  inset: 0;
  z-index: 600;
  background: var(--color-bg);
  display: flex;
  justify-content: center;
  font-family: var(--font-body);
}
.pt-ov-inner {
  position: relative;
  width: 100%;
  max-width: 480px;
  height: 100%;
  display: flex;
  flex-direction: column;
}
.pt-ov-head {
  flex: none;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  /* 23a draws a 37.7px status bar above the header; keep that rhythm (more on notched phones) */
  padding: max(47.7px, calc(env(safe-area-inset-top) + 14px)) 22px 0;
}
.pt-ov-titles { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pt-ov-unit { font: 600 12.5px/1.3 var(--font-body); color: var(--color-neutral-700); text-wrap: pretty; }
.pt-ov-hop { margin: 0; font: 800 21px/1.15 var(--font-heading); letter-spacing: normal; color: var(--color-text); text-wrap: pretty; }
.pt-ov-actions { flex: none; display: flex; align-items: center; gap: 8px; }
.pt-chip {
  flex: none;
  display: flex;
  align-items: center;
  gap: 6px;
  height: 40px;
  padding: 0 12px;
  border: 0;
  border-radius: 999px;
  background: var(--color-accent-2-100);
  color: var(--color-accent-2-800);
  cursor: pointer;
}
.pt-chip:hover { background: var(--color-accent-2-200); }
.pt-chip span { font: 800 11.5px var(--font-body); color: var(--color-accent-2-900); }
.pt-close {
  flex: none;
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: 999px;
  background: var(--color-neutral-100);
  box-shadow: var(--shadow-sm);
  color: var(--color-neutral-800);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.pt-close:hover { background: var(--color-accent-100); }

/* Step strip: numbered 30px pills joined by 2px lines */
.pt-steps { flex: none; display: flex; align-items: center; padding: 18px 22px 2px; }
.pt-step { display: flex; align-items: center; flex: 1; min-width: 0; }
.pt-step:first-child { flex: none; }
.pt-step-line { flex: 1; height: 2px; }
.pt-step-dot {
  flex: none;
  width: 30px;
  height: 30px;
  padding: 0;
  border-radius: 999px;
  border-style: solid;
  border-width: 2px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: default;
  font-family: var(--font-body);
}
.pt-step-dot.reach { cursor: pointer; }
.pt-step-dot.reach:hover { filter: brightness(1.07); }

/* Phase 1: stacked card deck */
.pt-phase { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.pt-p1 { flex: 1; min-height: 0; position: relative; padding: 16px 22px 10px; }
.pt-ghost { position: absolute; border-radius: 30px; background: var(--color-neutral-100); }
.pt-ghost.g1 { left: 44px; right: 44px; top: 30px; bottom: 34px; opacity: .45; }
.pt-ghost.g2 { left: 34px; right: 34px; top: 24px; bottom: 28px; opacity: .7; }
.pt-card {
  position: absolute;
  left: 22px;
  right: 22px;
  top: 16px;
  bottom: 16px;
  border-radius: 30px;
  background: var(--color-neutral-100);
  box-shadow: var(--shadow-lg);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 24px 22px;
}
.pt-card-top { display: flex; align-items: center; justify-content: space-between; }
.pt-card-meta { font: 800 10px var(--font-body); letter-spacing: .14em; color: var(--color-accent-700); }
.pt-card-right { display: flex; align-items: center; gap: 12px; }
.pt-dots { display: flex; gap: 6px; }
.pt-mic {
  width: 34px;
  height: 34px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  background: var(--color-accent-200);
  color: var(--color-accent-800);
  -webkit-tap-highlight-color: transparent;
}
.pt-mic { position: relative; }
.pt-mic:hover { filter: brightness(.96); }
/* Blinking red dot: the mic is off although the learner didn't just switch it off here
   (saved choice, blocked, or unavailable). */
.pt-mic-dot {
  display: none;
  position: absolute;
  top: -1px;
  right: -1px;
  width: 10px;
  height: 10px;
  border-radius: 999px;
  background: #e5372f;
  box-shadow: 0 0 0 2px var(--color-neutral-100);
  animation: pt-mic-blink 1.1s ease-in-out infinite;
  pointer-events: none;
}
.pt-mic[data-dot="1"] .pt-mic-dot { display: block; }
@keyframes pt-mic-blink { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
.pt-mic:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.pt-mic[data-on="0"] { background: var(--color-neutral-200); color: var(--color-neutral-700); }
.pt-mic[data-on="1"] .pt-mic-off, .pt-mic[data-on="0"] .pt-mic-on { display: none; }
.pt-dots i { display: block; width: 11px; height: 11px; border-radius: 999px; background: var(--color-neutral-300); }
.pt-dots i.on { background: var(--color-accent-700); }
.pt-dots i.now { background: var(--color-accent-300); }
/* No gap here — like shadowee.html's .tx-line-text + .tx-line-translation,
   the translation's own margin-top is the only space above it, so it can
   match that rule exactly (a flex `gap` would stack on top of it). */
.pt-card-mid { display: flex; flex-direction: column; }
.pt-card-en { font: 700 25px/1.32 var(--font-body); color: var(--color-text); text-wrap: pretty; }
/* Exactly shadowee.html's .tx-line-translation (css/player.css) — same
   font stack, size, weight, colour and hairline rule, not the Path/Organic
   tokens used elsewhere on this page. --font/--text-3/--border-sub/--t-fast
   are global (css/base.css, loaded via styles.css) and already resolve to
   their light-theme values here (path.html sets data-theme="light").
   .pt-line-tr (the passage list) has its own rule now, further down —
   23a mockup revision 2 gave the passage list its own Organic-token
   translation style (no hairline separator, flex `gap` spacing instead). */
.pt-card-tr {
  display: block; /* a <span>, blockified by its flex parent already */
  font: 400 12.5px/1.4 var(--font);
  color: var(--text-3);
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid var(--border-sub);
  transition: filter var(--t-fast);
}
.pt-card-bot { display: flex; flex-direction: column; gap: 14px; }
.pt-state {
  display: flex;
  align-items: center;
  gap: 9px;
  align-self: flex-start;
  padding: 9px 14px;
  border-radius: 999px;
}
.pt-state-dot { width: 9px; height: 9px; border-radius: 999px; }
.pt-state span:last-child { font: 800 12px var(--font-body); }
.pt-wave { display: flex; align-items: flex-end; gap: 4px; height: 34px; }
.pt-wave i { display: block; flex: 1; border-radius: 999px; }

/* Side arrows (already-completed hops) */
.pt-side {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 3;
  width: 36px;
  height: 58px;
  padding: 0;
  border: 0;
  background: var(--color-neutral-100);
  box-shadow: var(--shadow-md);
  color: var(--color-neutral-800);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.pt-side:hover { background: var(--color-accent-100); }
.pt-side.prev { left: 0; border-radius: 0 999px 999px 0; }
.pt-side.next { right: 0; border-radius: 999px 0 0 999px; }

/* Phase 2: the whole passage — 23a mockup revision 2. Each row now carries
   its own live state instead of a shared status banner above the list (see
   ptRender()'s full-phase branch in path.js): the row currently playing
   gets a colored background + bold text, its line number swaps for an
   animated equalizer, and an inline cue label appears; every other row
   dims while something plays. This supersedes the earlier "match
   shadowee.html's plain .tx-line transcript" design — Organic-palette
   tokens (--color-*) throughout, not the global --text-N or --mono tokens
   that design used. */
.pt-p2 { flex: 1; min-height: 0; position: relative; display: flex; flex-direction: column; padding: 16px 22px 18px; }
/* The card itself — this was missing entirely in the first pass at this
   redesign (everything sat directly on the overlay's bare background with
   no gutter), which is what actually made it "look broken". Lighter shadow
   than .pt-card's (--shadow-lg): this card sits in normal flex flow, not
   floating over stacked ghost cards like phase 1's does. */
.pt-passage-card {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  background: var(--color-neutral-100);
  border-radius: 28px;
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.pt-passage-head {
  flex: none;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 16px 20px 6px;
}
.pt-passage-eyebrow {
  font: 800 10px var(--font-body);
  letter-spacing: .14em;
  color: var(--color-accent-700);
}
.pt-passage-note { margin-left: auto; font: 700 11px var(--font-body); color: var(--color-neutral-700); }
.pt-listwrap { flex: 1; min-height: 0; display: flex; }
.pt-list {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 6px 10px 14px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.pt-line {
  display: flex;
  gap: 10px;
  padding: 11px 12px;
  border-radius: 18px;
  border: 1.5px solid transparent;
  background: transparent;
  opacity: 1;
  transition: background .35s ease, opacity .35s ease, border-color .35s ease;
}
.pt-list.playing .pt-line:not(.active) { opacity: .6; }
/* Stopped: outline the line that Play will resume from, so the queued-up
   line is clear before tapping Play. Once it's actually playing, the fill
   background (below) already carries that meaning, so the outline steps
   aside rather than doubling up. */
.pt-line.current:not(.active) { border-color: var(--color-accent-700); }
.pt-line.active { background: var(--color-accent-2-100); }
.pt-line.active.echo { background: var(--color-accent-100); animation: om-turn 1.4s ease-in-out infinite; }
.pt-line-lead {
  flex: none;
  width: 18px;
  height: 23px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2px;
}
.pt-line-num {
  font: 700 11px var(--font-body);
  color: var(--color-neutral-600);
}
/* A <span>, defaulting to display:inline — without this, its 3 block-level
   <i> bar children just stack vertically (a tall dashed-looking line)
   instead of laying out side-by-side. The mockup avoids this entirely by
   making the bars direct children of .pt-line-lead (already flex); this
   wrapper needs its own flex context instead, same visual result. */
.pt-line-bars { display: flex; align-items: center; gap: 2px; }
.pt-line-bars i {
  display: block;
  width: 3px;
  height: 14px;
  border-radius: 999px;
  background: var(--color-accent-2-600);
  transform-origin: center;
  animation: om-eq .8s ease-in-out infinite;
}
.pt-line.echo .pt-line-bars i { background: var(--color-accent); }
.pt-line-bars i:nth-child(2) { animation-delay: .18s; }
.pt-line-bars i:nth-child(3) { animation-delay: .36s; }
.pt-line-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.pt-line-en {
  font: 500 16px/1.4 var(--font-body);
  color: var(--color-neutral-800);
  text-wrap: pretty;
}
.pt-line.active .pt-line-en { font: 700 17px/1.4 var(--font-body); color: var(--color-text); }
.pt-line-tr { font: 500 13px/1.45 var(--font-body); color: var(--color-neutral-700); text-wrap: pretty; }
.pt-line-cue {
  font: 800 10px var(--font-body);
  letter-spacing: .12em;
  color: var(--color-accent-2-800);
  padding-top: 2px;
}
.pt-line.echo .pt-line-cue { color: var(--color-accent-700); }

/* Word-highlight-during-playback (ptStartWordHighlight() in path.js) —
   shared by both .pt-card-en's line-phase spans and .pt-line-en's
   full-passage ones. A path-scoped equivalent of player.css's
   .tx-word/.word-active — not a reuse of those, since their color tokens
   (--tx-word-active/--tx-current-hl) are scoped to .main-content[data-mode],
   which doesn't exist on this page. Same orange accent as .pt-line.active.echo. */
.pt-word {
  border-radius: 3px;
  padding: 0 1px;
  transition: background var(--t-fast);
}
.pt-word.word-active {
  background: rgba(198, 113, 57, 0.28);
}

.pt-note {
  flex: none;
  margin: 8px 22px 0;
  padding: 10px 14px;
  border-radius: 16px;
  background: var(--color-accent-100);
  color: var(--color-accent-800);
  font: 600 13px/1.4 var(--font-body);
  text-align: center;
}

/* Footer: Play / Stop / Resume, or restart + gate button */
.pt-ov-foot {
  flex: none;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 22px max(26px, env(safe-area-inset-bottom));
  background: var(--color-neutral-100);
  border-top: 1px solid var(--color-divider);
}
.pt-play, .pt-gate {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 56px;
  border: 0;
  border-radius: 999px;
  background: var(--color-accent-700);
  box-shadow: var(--shadow-sm);
  color: #fff;
  font: 800 13.5px var(--font-body);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.pt-play { gap: 10px; }
.pt-gate { gap: 9px; }
.pt-play:hover, .pt-gate:hover { background: var(--color-accent-800); }
.pt-play:disabled { opacity: .45; cursor: default; }
.pt-play:disabled:hover { background: var(--color-accent-700); }
.pt-play.glow { animation: om-glow 1.8s ease-out infinite; }
.pt-play-icon { display: inline-flex; }
.pt-restart {
  flex: none;
  width: 56px;
  height: 56px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: var(--color-neutral-200);
  color: var(--color-neutral-800);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.pt-restart:hover { background: var(--color-neutral-300); }
.pt-play:focus-visible, .pt-gate:focus-visible, .pt-restart:focus-visible,
.pt-chip:focus-visible, .pt-close:focus-visible, .pt-step-dot:focus-visible, .pt-side:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* "Microphone is blocked" dialog */
.pt-mic-scrim { position: absolute; inset: 0; z-index: 33; background: rgba(32, 30, 29, .42); }
.pt-mic-card {
  position: absolute;
  left: 22px;
  right: 22px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 34;
  padding: 24px 22px;
  background: var(--color-bg);
  border-radius: 28px;
  box-shadow: var(--shadow-lg);
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.pt-mic-head { display: flex; align-items: center; gap: 12px; }
.pt-mic-disc {
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 999px;
  background: var(--color-accent-200);
  display: flex;
  align-items: center;
  justify-content: center;
}
.pt-mic-title { font: 800 20px/1.2 var(--font-heading); color: var(--color-text); text-wrap: pretty; }
.pt-mic-body { font: 500 14px/1.5 var(--font-body); color: var(--color-neutral-800); text-wrap: pretty; }
.pt-mic-hint {
  padding: 10px 14px;
  border-radius: 16px;
  background: var(--color-accent-100);
  color: var(--color-accent-800);
  font: 600 12.5px/1.45 var(--font-body);
}
.pt-mic-actions { display: flex; flex-direction: column; gap: 9px; padding-top: 2px; }
.pt-mic-allow, .pt-mic-close {
  height: 48px;
  border: 0;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font: 800 14px var(--font-body);
}
.pt-mic-allow { background: var(--color-accent); color: #fff; }
.pt-mic-allow:hover { background: var(--color-accent-600); }
.pt-mic-close { background: var(--color-neutral-100); color: var(--color-neutral-800); }
.pt-mic-close:hover { background: var(--color-accent-100); }
.pt-mic-allow:focus-visible, .pt-mic-close:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }

/* "Hop complete" dialog */
.pt-dialog-backdrop {
  position: absolute;
  inset: 0;
  z-index: 33;
  background: rgba(32, 30, 29, .5);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 28px;
}
.pt-dialog {
  width: 100%;
  max-width: 390px;
  padding: 30px 26px 26px;
  border-radius: 28px;
  background: var(--color-bg);
  box-shadow: var(--shadow-lg);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}
.pt-dialog-badge {
  width: 78px;
  height: 78px;
  border-radius: 999px;
  background: var(--color-accent-2-600);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
}
.pt-dialog.error .pt-dialog-badge { background: var(--color-accent-600); }
.pt-dialog-title { font: 800 22px var(--font-heading); color: var(--color-text); text-align: center; }
.pt-dialog-sub { font: 400 13px/1.5 var(--font-body); color: var(--color-neutral-700); text-align: center; }
.pt-dialog-back, .pt-dialog-retry {
  width: 100%;
  padding: 14px;
  border: 0;
  border-radius: 999px;
  font: 800 13px var(--font-body);
  text-align: center;
  cursor: pointer;
}
.pt-dialog-back { margin-top: 6px; background: var(--color-accent-700); color: #fff; }
.pt-dialog-back:hover { background: var(--color-accent-800); }
.pt-dialog-retry { margin-top: 6px; background: var(--color-neutral-200); color: var(--color-neutral-800); }
.pt-dialog-retry:hover { background: var(--color-neutral-300); }
.pt-dialog-retry:not([hidden]) + .pt-dialog-back { margin-top: 0; }

/* Step 1: language — the app's shared translate-sheet (translation.js's
   renderTranslateSheetRows(), same JS/markup every page uses), reskinned
   for path.html only to match the mockup's own onboarding language list
   exactly: centered icon + multi-script label instead of a modal-header,
   big native+English rows instead of the generic native-over-English
   stack, no selected-checkmark (the mockup's list doesn't have one). */
.pt-setup-lang-head {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 28px 22px 16px;
}
.pt-setup-lang-icon {
  width: 64px;
  height: 64px;
  border-radius: 999px;
  background: var(--color-accent-2-200);
  color: var(--color-accent-2-800);
  display: flex;
  align-items: center;
  justify-content: center;
}
.pt-setup-lang-label { font: 700 13px/1.4 var(--font-body); color: var(--color-neutral-700); text-align: center; }

.path-body .translate-lang-list {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 0 12px 16px;
  margin-top: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
/* 23a lists the languages first and "No translation" last */
.path-body .translate-lang-row[data-lang=""] { order: 99; }
.path-body .translate-lang-row {
  flex: none;
  min-height: 58px;
  padding: 0 18px;
  border-radius: 20px;
  background: var(--color-neutral-100);
  border: none;
  display: flex;
  align-items: center;
  gap: 12px;
}
.path-body .translate-lang-row:hover { background: var(--color-accent-200); }
.path-body .translate-lang-row:active,
.path-body .translate-lang-row.selected { background: var(--color-accent-300); }
.path-body .translate-lang-text { flex: 1; min-width: 0; display: flex; flex-direction: row; align-items: baseline; gap: 12px; }
.path-body .translate-lang-native { flex: 1; min-width: 0; font: 700 18px var(--font-body); color: var(--color-text); }
.path-body .translate-lang-row[data-lang=""] .translate-lang-native { font-size: 0; }
.path-body .translate-lang-row[data-lang=""] .translate-lang-native::before { content: "No translation"; font: 700 18px var(--font-body); }
.path-body .translate-lang-english { flex: none; font: 600 12px var(--font-body); color: var(--color-neutral-700); }
.path-body .translate-lang-check { display: none; }

@media (prefers-reduced-motion: reduce) {
  .pt-hop-halo, .pt-play.glow, .pt-state-dot, .pt-wave i, .pt-mic-dot, .pt-line-bars i, .pt-line.echo { animation: none !important; }
  .pt-map, .pt-line { transition: none !important; }
}
