/* Immersion Atlas — "cave dark" theme. Palette sampled from the brand moodboard:
   terracotta #b85227, teal #5d8277, purple #64516c, cream #ede3d3, on a warm
   charcoal ground with a soft lantern glow. Colours live in CSS variables so a
   future light ("parchment") mode is just a second block. */
@font-face {
  font-family: "Poppins"; font-style: normal; font-weight: 600; font-display: optional;
  src: url("/fonts/poppins-600.woff2") format("woff2");
}
@font-face {
  font-family: "Poppins"; font-style: normal; font-weight: 700; font-display: optional;
  src: url("/fonts/poppins-700.woff2") format("woff2");
}

:root {
  color-scheme: light dark;
  /* Default = light "parchment": warm paper, terracotta, lantern-gold — the
     brand mockup look. The dark "cave" palette follows in a media query below;
     every colour is a variable so components adapt to either with no rule edits. */
  --bg:        #f2e8d6;   /* warm paper floor */
  --bg-glow:   #fbf5e9;   /* soft lantern glow / raised strips */
  --card:      #fffdf8;   /* cards sit just above the paper */
  --card-2:    #f1e7d3;   /* inputs, insets */
  --border:    #e5d9bd;
  --border-2:  #ece2cd;
  --text:      #33281d;   /* warm near-black ink */
  --muted:     #7c6d57;   /* warm grey-brown */
  --faint:     #a89876;
  --accent:    #c0532b;   /* terracotta */
  --accent-hi: #a8471f;   /* on light, hover deepens */
  --accent-lo: #8f3c19;
  --teal:      #4f766b;
  --teal-hi:   #3d6157;
  --purple:    #7a6383;
  --gold:      #a9761f;   /* darker gold so it reads on cream */
  --ruby:      #3f8b78;   /* furigana */
  /* Ruby type must stay readable even inside compact 12–15px learning UI. The
     relative component preserves hierarchy; the pixel floor prevents Chrome's
     default half-size ruby from collapsing to 6–8px. */
  --ruby-reading-size: max(.66em, 10px);
  --ruby-compact-size: max(.7em, 9px);
  --ruby-large-size: max(.52em, 11px);
  --ruby-weight: 500;
  /* themed component tints (extension gate, secondary/disabled buttons, shadow) */
  --ok-bg:     #e6f0e5; --ok-border: #b6cfb2; --ok-text: #2f5535;
  --warn-bg:   #f7ecd6; --warn-border: #e0c489; --warn-text: #7a561c;
  --btn-2:     #ebe0c9; --btn-2-hi: #e1d3b5;
  --btn-off-bg:#e3d9c4; --btn-off-text: #a89a80;
  --shadow:    0 1px 2px rgba(60,42,24,.06), 0 6px 18px rgba(60,42,24,.07);
  --brand-font: "Poppins", "Segoe UI", system-ui, sans-serif;
}
/* Dark "cave" values. Applied in two cases: (a) the OS is in dark mode AND the
   user hasn't explicitly forced light via the toggle; (b) the user explicitly
   chose dark via the toggle (data-theme="dark"), regardless of OS. The var list
   is duplicated because a media block and a plain selector can't be merged. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg:#1c1815; --bg-glow:#2a221b; --card:#262019; --card-2:#1b1712;
    --border:#3a3128; --border-2:#2e271f; --text:#ece3d0; --muted:#a89a86;
    --faint:#7d7263; --accent:#c0532b; --accent-hi:#d9663a; --accent-lo:#a8471f;
    --teal:#5d8277; --teal-hi:#6f9a8d; --purple:#9c86a8; --gold:#e0a860; --ruby:#86c0b0;
    --ok-bg:#1b2620; --ok-border:#315041; --ok-text:#cfe9d6;
    --warn-bg:#2a211a; --warn-border:#5a4326; --warn-text:#f0dcc4;
    --btn-2:#3a332b; --btn-2-hi:#484036; --btn-off-bg:#45403a; --btn-off-text:#8f867b;
    --shadow:0 1px 2px rgba(0,0,0,.2), 0 6px 18px rgba(0,0,0,.22);
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg:#1c1815; --bg-glow:#2a221b; --card:#262019; --card-2:#1b1712;
  --border:#3a3128; --border-2:#2e271f; --text:#ece3d0; --muted:#a89a86;
  --faint:#7d7263; --accent:#c0532b; --accent-hi:#d9663a; --accent-lo:#a8471f;
  --teal:#5d8277; --teal-hi:#6f9a8d; --purple:#9c86a8; --gold:#e0a860; --ruby:#86c0b0;
  --ok-bg:#1b2620; --ok-border:#315041; --ok-text:#cfe9d6;
  --warn-bg:#2a211a; --warn-border:#5a4326; --warn-text:#f0dcc4;
  --btn-2:#3a332b; --btn-2-hi:#484036; --btn-off-bg:#45403a; --btn-off-text:#8f867b;
  --shadow:0 1px 2px rgba(0,0,0,.2), 0 6px 18px rgba(0,0,0,.22);
}

* { box-sizing: border-box; }
/* Always reserve the scrollbar gutter so the centered layout doesn't shift
   sideways when a page grows tall enough to scroll (or when moving between a
   short tab and a scrolling one) — this is what made the header "jump" on load. */
html { scrollbar-gutter: stable; }
/* The [hidden] attribute must win over our display:flex labels/rows (author
   `display` otherwise overrides the UA `[hidden]{display:none}`). */
[hidden] { display: none !important; }
body {
  font-family: "Segoe UI", system-ui, sans-serif;
  max-width: 1120px; margin: 0 auto; padding: 24px 24px 48px;
  color: var(--text); line-height: 1.5;
  background:
    radial-gradient(1100px 460px at 50% -80px, var(--bg-glow), transparent 70%),
    var(--bg);
  background-attachment: fixed;
}

/* ---- header / brand ---- */
.site-header {
  display: flex; align-items: center; gap: 18px; margin-bottom: 8px;
}
.brand { min-width: 0; }
.wordmark {
  /* clamp, not a breakpoint: "ImmersionAtlas" is 14 glyphs where the old
     wordmark was 6, so a fixed 40px overflowed a ~390px viewport. The upper
     bound is reached by ~470px, leaving every desktop rendering unchanged. */
  font-family: var(--brand-font); font-weight: 700;
  font-size: clamp(28px, 8.5vw, 40px);
  letter-spacing: -.01em; line-height: 1; margin: 0;
}
.wordmark .im { color: var(--accent); }
.wordmark .atlas { color: var(--text); }
.wordmark .spark { color: var(--gold); font-size: 20px; vertical-align: super; margin-left: 2px; }
.tagline {
  margin: 8px 0 0; font-size: 12px; letter-spacing: .13em; text-transform: uppercase;
  color: var(--muted); font-weight: 600;
}
.sub { margin: 14px 0 18px; color: var(--muted); font-size: 14px; max-width: 640px; }

/* ---- top nav ---- */
.site-nav { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; margin: 4px 0 12px; }
.site-nav a {
  font-family: var(--brand-font); font-weight: 600; font-size: 13px;
  letter-spacing: .02em; text-decoration: none; color: var(--muted);
  padding: 6px 14px; border-radius: 999px; border: 1px solid transparent;
}
.site-nav a:hover { color: var(--text); background: var(--card); }
.site-nav a.active {
  color: var(--text); background: var(--card); border-color: var(--border);
}
/* right-hand nav group (streak + theme toggle), pushed to the far right */
.nav-right { margin-left: auto; display: inline-flex; align-items: center; gap: 8px; }
/* immersion streak chip (rendered by userstats.js; hidden until it has a value) */
.streak {
  display: inline-flex; align-items: center; gap: 4px;
  font-family: var(--brand-font); font-weight: 600; font-size: 12.5px;
  color: var(--accent); background: var(--card); border: 1px solid var(--border);
  border-radius: 999px; padding: 5px 11px; white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
/* dark/light toggle */
.theme-toggle {
  align-self: center; width: 38px; height: 34px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--card); color: var(--text); border: 1px solid var(--border);
  border-radius: 999px; font-size: 15px; line-height: 1; cursor: pointer;
}
.theme-toggle:hover { background: var(--card-2); border-color: var(--accent); }
@media (max-width: 600px) {
  .site-nav { gap: 4px; }
  .site-nav a { padding: 6px 9px; font-size: 12.5px; }
  .nav-right { gap: 5px; }
}

/* ---- Discover home: hero ---- */
/* Two columns: copy on the left, the lantern mascot on the right. The mascot is
   decorative, so on narrow screens it drops out entirely (copy goes full width). */
/* align-items:flex-start (not center) so the mascot stays pinned to the top of
   the hero while the level chooser changes between its unset and compact states. */
.hero { margin: 2px 0 14px; display: flex; align-items: flex-start; gap: 40px; }
.hero-copy { flex: 1 1 auto; min-width: 0; }
.hero-copy > :last-child { margin-bottom: 0; }   /* kill the search's trailing gap */
.hero-art {
  flex: 0 0 auto; align-self: flex-start;
  display: flex; justify-content: center;
}
.hero-art img {
  display: block; width: 184px; max-width: 19.5vw; height: auto;
  filter: drop-shadow(0 10px 22px rgba(0, 0, 0, .22));
}
@media (max-width: 760px) {
  .hero { gap: 0; }
  .hero-art { display: none; }
}
.hero-h {
  font-family: var(--brand-font); font-weight: 700; font-size: 34px;
  line-height: 1.12; letter-spacing: -.01em; margin: 0 0 8px; color: var(--text);
  max-width: 620px;
}
.hero-sub { margin: 0 0 12px; font-size: 15px; color: var(--muted); max-width: 620px; }

/* The anonymous homepage's activation control. It disappears after a profile
   exists; profile editing belongs under You → Personalization. */
.hero-level { max-width: 640px; margin: 14px 0 12px; }
.hero-level-ask {
  padding: 13px 14px 12px; border: 1px solid color-mix(in srgb, var(--gold) 40%, var(--border));
  border-radius: 14px; background: linear-gradient(135deg,
    color-mix(in srgb, var(--gold) 8%, var(--card)), var(--card));
  box-shadow: var(--shadow);
}
.hero-level-head { display: flex; flex-wrap: wrap; align-items: baseline;
  gap: 3px 7px; margin-bottom: 9px; }
.hero-level-head strong { color: var(--text); font-size: 14.5px; }
.hero-level-head span { color: var(--muted); font-size: 12.5px; }
.hero-level-options { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 7px; }
.hero-level-option {
  min-width: 0; height: 52px; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 1px; padding: 6px 5px;
  border: 1px solid var(--border); border-radius: 10px; cursor: pointer;
  background: var(--card); color: var(--text); font-family: var(--brand-font);
  align-self: stretch;
  transition: border-color .15s ease, background .15s ease, transform .08s ease;
}
.hero-level-option:hover { border-color: var(--accent); background: var(--card-2);
  transform: translateY(-1px); }
.hero-level-option:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.hero-level-option:disabled { cursor: wait; opacity: .55; transform: none; }
.hero-level-option[aria-pressed="true"], .hero-level-option.is-busy {
  border-color: var(--accent); background: var(--accent); color: #fff6ea; opacity: 1;
}
.hero-level-code { font-size: 14px; font-weight: 800; line-height: 1.1; }
.hero-level-label { min-width: 0; min-height: 24px; display: flex; align-items: center;
  font-size: 10.5px; font-weight: 600; line-height: 1.15;
  color: var(--muted); text-align: center; }
.hero-level-option[aria-pressed="true"] .hero-level-label,
.hero-level-option.is-busy .hero-level-label { color: rgba(255, 246, 234, .84); }
.hero-level-payoff { display: flex; flex-wrap: wrap; align-items: center;
  gap: 4px 9px; margin: 9px 0 0; color: var(--muted); font-size: 11.5px; }
.hero-level-payoff b { color: var(--gold); font-weight: 700; }
.hero-level-payoff a { color: var(--teal-hi); }
@media (max-width: 620px) {
  .hero-level-options { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* "Our database" proof strip: real directory totals under the hero, ONE line.
   Filled by library.js (renderDbStats); starts hidden so it never flashes
   placeholders. Deliberately compact — the hero must leave room for a card row
   above the fold. (The .db-stat tile classes below survive for me.html's
   immersion stat tiles.) */
.db-statline { margin: 0 0 12px; font-size: 13.5px; color: var(--muted);
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px;
  font-variant-numeric: tabular-nums; }
.db-statline-label { font-size: 11px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--accent); margin-right: 4px; }
.db-statline-item b { color: var(--gold); font-weight: 700; font-size: 14.5px; }
.db-statline-sep { color: var(--faint); }

.db-stats { margin: 0 0 12px; }
.db-stats-label {
  margin: 0 0 6px; font-size: 11px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--accent);
}
.db-stats-grid { display: flex; flex-wrap: wrap; gap: 10px; }
.db-stat {
  flex: 1 1 150px; min-width: 0; display: flex; align-items: center; gap: 9px;
  background: var(--card); border: 1px solid var(--border); border-radius: 12px;
  padding: 9px 13px;
}
.db-stat-ic {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 9px;
  color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent);
}
.db-stat-ic svg { width: 20px; height: 20px; }
.db-stat-body { display: flex; flex-direction: column; line-height: 1.2; min-width: 0; }
.db-stat-num { font-size: 22px; font-weight: 800; color: var(--text); }
.db-stat-cap { font-size: 12px; color: var(--muted); }
.hero-search {
  display: flex; align-items: center; gap: 10px; max-width: 640px;
  background: var(--card); border: 1px solid var(--border); border-radius: 999px;
  padding: 4px 6px 4px 18px; box-shadow: var(--shadow);
}
.hero-search:focus-within { border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(192, 83, 43, .12); }
.hero-search-icon { font-size: 16px; opacity: .7; flex: none; }
.hero-search input {
  flex: 1; min-width: 0; border: 0; background: transparent; padding: 9px 8px;
  font-size: 16px; color: var(--text);
}
.hero-search input:focus { outline: none; }

/* ---- Browse: discovery layout ---- */
.browse-head { margin: 4px 0 14px; }
.browse-head .hero-h { margin-bottom: 6px; }
.browse-sub { color: var(--muted); font-size: 15px; margin: 0; max-width: 620px; }
body[data-page="browse"] .hero-search { margin-bottom: 26px; }
.section-sub { color: var(--muted); font-size: 13px; margin: -6px 0 14px; }

/* "Explore by topic" cards (reuse the .topic-grid container) */
.topic-card { display: flex; align-items: center; gap: 12px; padding: 14px 16px;
  background: var(--card); border: 1px solid var(--border); border-radius: 12px;
  text-decoration: none; box-shadow: var(--shadow); transition: transform .08s, border-color .15s; }
.topic-card:hover { border-color: var(--accent); transform: translateY(-2px); }
.topic-ic-lg { font-size: 24px; line-height: 1; flex: none; }
.topic-meta { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.topic-meta b { color: var(--text); font-size: 15px; }
.topic-count { color: var(--muted); font-size: 12px; }

/* "Recently added" row */
.rec-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.recent-card { display: flex; flex-direction: column; background: var(--card);
  border: 1px solid var(--border); border-radius: 12px; overflow: hidden; box-shadow: var(--shadow); }
.recent-thumb { display: block; aspect-ratio: 16 / 9; background: var(--card-2); }
.recent-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.recent-name { display: block; padding: 10px 12px 4px; font-weight: 600; color: var(--text);
  text-decoration: none; font-size: 14px; line-height: 1.25; }
.recent-name:hover { color: var(--accent); }
.recent-foot { display: flex; align-items: center; justify-content: space-between;
  gap: 8px; padding: 2px 12px 12px; margin-top: auto; }
.recent-time { color: var(--muted); font-size: 12px; white-space: nowrap; }

/* All-channels bar: filters button + sort */
.count-badge { color: var(--gold); font-weight: 600; font-size: 14px; font-variant-numeric: tabular-nums; }
.browse-bar { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin: 4px 0 14px; flex-wrap: wrap; }
.filters-btn { display: inline-flex; align-items: center; gap: 6px; }
.filters-btn.open { background: var(--accent); color: #fff; }
.sort-label { color: var(--muted); font-size: 13px; display: inline-flex; align-items: center; gap: 8px; }
/* Sort by + Order, kept as one right-hand group in the browse bar. */
.browse-sorts { display: inline-flex; align-items: center; gap: 8px 16px; flex-wrap: wrap; }
.filters-panel { display: flex; flex-wrap: wrap; gap: 12px 18px; margin: 0 0 16px; }

@media (max-width: 760px) { .rec-row { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 460px) { .rec-row { grid-template-columns: 1fr; } }

/* ---- Browse: category header (a topic selected) ---- */
.category-head { margin: 4px 0 18px; }
.crumbs { font-size: 13px; color: var(--muted); margin-bottom: 10px; }
.crumbs a { color: var(--muted); text-decoration: none; }
.crumbs a:hover { color: var(--accent); }
.crumbs span[aria-hidden] { margin: 0 6px; opacity: .6; }
#crumbGenre { color: var(--text); font-weight: 600; }
.cat-title-row { display: flex; align-items: center; gap: 14px; }
.cat-title-ic { font-size: 40px; line-height: 1; flex: none; }
.cat-title-row .hero-h { margin: 0; }
.cat-count { color: var(--muted); font-size: 14px; margin: 2px 0 0; }

/* ---- Browse: contextual Tier-2 sub-filter pills (shown on the category page) ---- */
.sub-filters { display: flex; flex-wrap: wrap; gap: 7px; margin: 14px 0 0; }
.sub-chip {
  font-family: var(--brand-font); font-weight: 600; font-size: 13px;
  padding: 5px 12px; border-radius: 999px; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--card); color: var(--muted); border: 1px solid var(--border);
}
.sub-chip:hover { color: var(--text); background: var(--card-2); }
.sub-chip.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.sub-chip.active:hover { background: var(--accent-hi); }
.sf-n { font-size: 11px; opacity: .6; font-weight: 700; font-variant-numeric: tabular-nums; }
.sub-chip.active .sf-n { opacity: .85; }

/* clickable subtopic pills on the channel detail page (deep-link to Browse) */
.chip.tag { text-transform: none; letter-spacing: 0; text-decoration: none;
  color: var(--accent); border-color: color-mix(in srgb, var(--accent) 35%, transparent); }
.chip.tag:hover { background: color-mix(in srgb, var(--accent) 12%, transparent); }

/* ---- Browse: numbered pagination ---- */
.pager { display: flex; justify-content: center; align-items: center; gap: 6px;
  margin: 22px 0 8px; flex-wrap: wrap; }
.pager:empty { display: none; }
.pg-num, .pg-arrow { min-width: 34px; height: 34px; padding: 0 8px; border-radius: 8px;
  background: var(--card); border: 1px solid var(--border); color: var(--muted);
  font-size: 14px; font-weight: 600; cursor: pointer; }
.pg-num:hover:not(.active), .pg-arrow:hover:not(:disabled) { color: var(--text); background: var(--card-2); }
.pg-num.active { background: var(--accent); color: #fff; border-color: var(--accent); cursor: default; }
.pg-arrow:disabled { opacity: .4; cursor: default; }
.pg-gap { color: var(--muted); padding: 0 2px; }

/* ---- Discover home: browse header + filters ---- */
.browse-head { margin: 22px 0 12px; }
.browse-h { margin: 0 0 10px; }
.filters { display: flex; flex-wrap: wrap; gap: 12px; align-items: end; }

/* ---- Discover home: explore by category grid ---- */
.explore { margin: 30px 0 8px; }
.explore-cats {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 12px; margin-top: 12px;
}
.explore-cat {
  display: flex; flex-direction: column; align-items: flex-start; gap: 4px;
  text-align: left; cursor: pointer; padding: 14px 16px; border-radius: 14px;
  background: var(--card); border: 1px solid var(--border); align-self: auto;
  box-shadow: var(--shadow);
  transition: box-shadow .15s ease, border-color .15s ease;
}
.explore-cat:hover { border-color: var(--accent);
  box-shadow: 0 2px 4px rgba(60,42,24,.08), 0 10px 26px rgba(60,42,24,.1); }
.explore-cat-name {
  font-family: var(--brand-font); font-weight: 700; font-size: 15px; color: var(--text);
}
.explore-cat-blurb { font-size: 12px; color: var(--muted); font-weight: 400; }
a.explore-cat { text-decoration: none; }

/* ---- Discover home: curated sections (rows) ---- */
.home-section { margin: 18px 0 8px; }
.home-section[hidden] { display: none; }
.section-head { display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; margin: 0 0 12px; }

/* Personalized home sections resolve after local scoring and API requests. Their
   loading shells use the same geometry as the finished cards, reserving the rows'
   space before content arrives instead of pushing everything below them down. */
.home-skeleton {
  border-radius: 7px;
  background: color-mix(in srgb, var(--muted) 15%, var(--card-2));
}

/* One episode above the recommendation rows. It appears only after its local,
   mined-video candidate has resolved. Eligible profiles get a reserved shell
   while that work runs; profiles without enough local data keep it hidden. */
.next-watch { margin-top: 18px; }
.next-watch.is-loading { pointer-events: none; }
.nw-heading { margin-bottom: 9px; }
.nw-card { display: flex; flex-direction: column; gap: 14px; padding: 16px;
  min-height: 478px;
  border: 1px solid color-mix(in srgb, var(--gold) 34%, var(--border));
  border-radius: 16px; background: color-mix(in srgb, var(--gold) 7%, var(--card));
  box-shadow: 0 8px 24px rgba(0, 0, 0, .08); overflow: hidden; }
.nw-study-shell { min-width: 0; display: grid;
  grid-template-columns: minmax(250px, .88fr) minmax(0, 1.12fr);
  grid-template-areas: "media guide"; gap: 20px; }
.nw-media { grid-area: media; min-width: 0; }
.nw-stage { position: relative; width: 100%;
  aspect-ratio: 16 / 9; overflow: hidden; border-radius: 11px; background: #000; }
.nw-loading-stage { width: 100%; aspect-ratio: 16 / 9; border-radius: 11px; }
.nw-loading-meta { width: 42%; height: 10px; margin: 12px 0 10px; }
.nw-loading-title { width: 88%; height: 16px; margin-bottom: 9px; }
.nw-loading-copy { width: 70%; height: 28px; }
.nw-loading-guide { gap: 13px; }
.nw-loading-tabs { width: 138px; height: 31px; }
.nw-loading-kicker { width: 116px; height: 10px; }
.nw-loading-words { display: grid; gap: 10px; margin-top: 2px; }
.nw-loading-words .home-skeleton { width: 100%; height: 24px; }
.nw-loading-primary { width: 100%; height: 36px; margin-top: auto; }
.nw-loading-discovery-copy { width: 190px; height: 13px; }
.nw-loading-buttons { display: flex; flex-wrap: wrap; gap: 7px; }
.nw-loading-buttons .home-skeleton { width: 112px; height: 34px; border-radius: 999px; }
.nw-stage iframe, #nwPlayerFrame { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.nw-poster, .nw-poster:hover, .nw-poster:focus, .nw-poster:active {
  background-color: #000; background-size: cover; background-position: center; }
.nw-poster { position: absolute; inset: 0; width: 100%; height: 100%; padding: 0;
  border: 0; border-radius: 0; cursor: pointer; }
.nw-poster:hover { filter: brightness(1.04); }
.nw-play { position: absolute; left: 50%; top: 50%; translate: -50% -50%;
  display: grid; place-items: center; width: 52px; height: 52px; padding-left: 3px;
  border-radius: 50%; color: #fff; background: rgba(0, 0, 0, .68); font-size: 20px;
  transition: transform .15s, background .15s; }
.nw-poster:hover .nw-play { transform: scale(1.06); background: var(--accent); }
.nw-media-meta { display: flex; align-items: center; justify-content: space-between;
  gap: 8px; margin: 9px 0 4px; }
.nw-creator { min-width: 0; color: var(--muted); font-size: 12px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nw-media-meta .chip { flex: none; }
.nw-title { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  margin: 0; max-width: 100%; overflow: hidden; color: var(--text); font-size: 15px;
  font-weight: 650; line-height: 1.35; overflow-wrap: anywhere; }
.nw-description { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  margin: 6px 0 0; overflow: hidden; color: var(--muted); font-size: 12px;
  line-height: 1.4; }
.nw-guide { grid-area: guide; min-width: 0; display: flex; flex-direction: column; }
/* These two properties date from when the tabs sat directly in .nw-guide, a
   COLUMN flex. They now live in .study-mode-toolbar, a ROW flex, where
   align-self:flex-start pins the pill to the top of the line and the bottom
   margin pads the line taller — so the centered Study fullscreen button sank
   below the tabs it should sit level with. The toolbar owns this spacing. */
.nw-guide-tabs { min-width: 0; }
.nw-guide-preview[hidden], .nw-live[hidden] { display: none; }
.nw-live { min-height: 0; }
.nw-guide-head { display: flex; justify-content: space-between; align-items: flex-start;
  gap: 12px; margin-bottom: 11px; }
.nw-guide-kicker { display: block; margin-bottom: 3px; color: var(--gold); font-size: 11px;
  font-weight: 700; letter-spacing: .07em; text-transform: uppercase; }
.nw-guide-context { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; }
.nw-comp { color: var(--muted); font-size: 13px; }
.nw-comp b { color: var(--accent); font-size: 15px; }
.nw-axes { width: 100%; margin: -2px 0 10px; }
.nw-guide-body { min-height: 124px; }
.nw-guide-label { margin-bottom: 6px; color: var(--muted); font-size: 11px;
  font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
.nw-vocab-item { display: flex; align-items: center; justify-content: space-between;
  gap: 8px; padding: 5px 0; border-bottom: 1px solid var(--border); }
.nw-vocab-main { flex: 1 1 auto; min-width: 0; display: grid;
  grid-template-columns: auto auto minmax(0, 1fr); align-items: baseline; gap: 5px 8px; }
.nw-vocab-word { color: var(--text); font-size: 15px; font-weight: 700; }
.nw-vocab-reading { color: var(--faint); font-size: 11px; }
/* Two lines at rest, not one: this preview carries the full ①②③ gloss like the keyness
   table, and a single clipped line could cut the sense the speaker actually meant (得意
   hides "one's strong point" at ③). Two keeps the row compact while letting a second
   sense through. */
.nw-vocab-meaning { min-width: 0; overflow: hidden; color: var(--muted); font-size: 12px;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  line-clamp: 2; overflow-wrap: anywhere; }
/* …and a row whose gloss runs past those two lines is a tap target (pointer + hover
   tint). markExpandableGlosses measures which rows those are and puts .is-gloss-toggle
   on the gloss itself, so the affordance never lies. Expanding just drops the clamp —
   the whole gloss is already in the span. */
.nw-vocab-item:has(.is-gloss-toggle) { cursor: pointer; }
.nw-vocab-item:has(.is-gloss-toggle):hover {
  background: color-mix(in srgb, var(--card-2) 55%, transparent); }
/* Shared by all three gloss surfaces (this card, .sh-preview-row, .comp-item): the
   measured-truncated gloss is the keyboard-reachable disclosure, so it needs a focus
   ring. The offset is NEGATIVE — the gloss sits inside clipping ancestors (the
   preview's scroll box, the clamp itself), where an outset ring gets cropped. */
.is-gloss-toggle:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px;
  border-radius: 4px; }
.nw-vocab-item.nw-vocab-open .nw-vocab-meaning {
  -webkit-line-clamp: unset; line-clamp: unset; color: var(--text); }
.nw-vocab-actions { flex: none; display: flex; gap: 5px; }
.nw-vocab-action { appearance: none; min-height: 36px; padding: 5px 8px;
  border: 1px solid var(--border-2); border-radius: 8px; background: transparent;
  color: var(--faint); font: inherit; font-size: 10px; font-weight: 700;
  white-space: nowrap; cursor: pointer; touch-action: manipulation;
  transition: color .12s, border-color .12s, background .12s; }
.nw-vocab-known:hover, .nw-vocab-known.is-known { color: var(--teal-hi); border-color: var(--teal);
  background: color-mix(in srgb, var(--teal) 12%, transparent); }
.nw-vocab-save:hover, .nw-vocab-save.is-saved { color: var(--gold); border-color: var(--gold);
  background: color-mix(in srgb, var(--gold) 12%, transparent); }
.nw-vocab-action:focus-visible { outline: 3px solid color-mix(in srgb, var(--gold) 72%, transparent);
  outline-offset: 2px; }
.nw-vocab-action:disabled { opacity: .75; cursor: default; }
.nw-language-list { display: grid; grid-template-columns: minmax(0, 1fr);
  gap: 8px; margin-top: 8px; }
.nw-language-item { display: grid; grid-template-columns: auto minmax(0, 1fr);
  align-items: baseline; gap: 2px 9px; padding: 6px 8px;
  border: 1px solid color-mix(in srgb, var(--border) 38%, transparent);
  border-radius: 8px; background: color-mix(in srgb, var(--card) 88%, var(--card-2)); }
.nw-language-label { grid-column: 1 / -1; color: var(--gold); font-size: 10px;
  font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
.nw-language-expression { min-width: 0; color: var(--text); font-size: 15px;
  font-weight: 700; line-height: 1.45; overflow-wrap: anywhere; }
.nw-language-expression rt { color: var(--ruby); font-size: var(--ruby-reading-size);
  font-weight: var(--ruby-weight); }
.nw-language-gloss { min-width: 0; overflow: hidden; color: var(--muted);
  font-size: 12px; line-height: 1.4; text-overflow: ellipsis; white-space: nowrap; }
.nw-guide-empty, .nw-guide-capabilities { margin: 0; color: var(--muted); font-size: 12px; }
.nw-guide-capabilities { margin-top: 10px; color: var(--faint); }
.nw-guide-skeleton-row { min-height: 46px; display: flex; align-items: center;
  gap: 10px; border-bottom: 1px solid var(--border); }
.nw-guide-skeleton-word, .nw-guide-skeleton-meaning {
  height: 8px; border-radius: 999px;
  background: color-mix(in srgb, var(--muted) 17%, transparent);
}
.nw-guide-skeleton-word { width: min(28%, 86px); }
.nw-guide-skeleton-meaning { flex: 1; max-width: 190px; }
.nw-guide-loading-status { position: absolute; width: 1px; height: 1px; padding: 0;
  margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap;
  border: 0; }
.nw-reasons { list-style: none; display: flex; flex-direction: column; gap: 5px;
  margin: 4px 0 15px; padding: 0; }
.nw-reasons li { position: relative; padding-left: 19px; color: var(--text); font-size: 13px; }
.nw-reasons li::before { content: "✓"; position: absolute; left: 0; color: var(--teal); font-weight: 700; }
.nw-actions { display: flex; flex-direction: column; align-items: stretch; gap: 9px;
  margin-top: 13px; }
.nw-discovery-column { grid-area: discovery; min-width: 0; display: flex;
  flex-direction: column; gap: 9px; margin: 0 -16px -16px; padding: 14px 16px 13px;
  border-top: 1px solid color-mix(in srgb, var(--gold) 18%, var(--border));
  background: color-mix(in srgb, var(--gold) 4%, var(--card-2)); }
.nw-discovery { min-width: 0; }
.nw-discovery-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 9px;
  margin-bottom: 9px; }
.nw-discovery-copy { display: flex; flex-wrap: wrap; align-items: baseline; gap: 7px; }
.nw-discovery-label { color: var(--text); font-size: 13px; font-weight: 750; }
.nw-discovery-subtitle { color: var(--muted); font-size: 11px; }
.nw-primary { display: inline-flex; flex: 1 1 auto; align-items: center; justify-content: center;
  min-height: 36px; padding: 8px 14px;
  border: 1px solid var(--teal); border-radius: 8px; color: #fff;
  background: var(--teal); font-size: 13px; font-weight: 700; text-decoration: none;
  white-space: nowrap; }
/* .nw-primary is an <a> on picks with no stored distribution and a <button>
   otherwise, so restate :active — the base button rule's own :active
   out-specifies a plain class (same trap as .sh-companion-toggle). */
.nw-primary:hover, .nw-primary:active { border-color: var(--teal-hi); color: #fff;
  background: var(--teal-hi); }
.nw-companion-action { display: flex; flex-wrap: wrap; align-items: center;
  justify-content: flex-end; gap: 7px 12px; padding: 0 2px; }
.nw-active-topic { min-height: 30px; padding: 4px 9px;
  border: 1px solid color-mix(in srgb, var(--gold) 60%, var(--border));
  border-radius: 999px; color: var(--text);
  background: color-mix(in srgb, var(--gold) 10%, var(--card)); font-size: 12px; }
.nw-active-topic:hover { border-color: var(--gold);
  background: color-mix(in srgb, var(--gold) 16%, var(--card)); }
/* The refinement choices stay visible as one low-friction discovery strip. */
.nw-tune-controls { min-width: 0; display: flex; flex-direction: column; gap: 9px; }
.nw-tune-strip { min-width: 0; display: flex; flex-wrap: wrap; gap: 7px; }
.nw-tune-group { display: contents; }
.nw-tune-group[hidden] { display: none; }
.nw-tune-group-label { display: none; }
.nw-tune-buttons { display: contents; }
.nw-tune-controls button { min-height: 34px; padding: 6px 13px;
  border: 1px solid color-mix(in srgb, var(--text) 18%, var(--border));
  border-radius: 999px; color: var(--text); background: var(--card); font-size: 12px;
  font-weight: 650; white-space: nowrap; }
.nw-tune-controls button:hover { border-color: var(--gold);
  background: color-mix(in srgb, var(--gold) 10%, var(--card)); }
.nw-tune-controls button:disabled { opacity: .55; cursor: wait; }
/* The undo beside a mute notice. Inline in the status line, so it is a link in
   everything but semantics — hiding a channel for a week must stay one click
   from reversible. */
.nw-mute-undo { padding: 0; border: 0; background: none; color: var(--gold);
  font: inherit; font-weight: 650; text-decoration: underline; cursor: pointer; }
.nw-mute-undo:disabled { opacity: .55; cursor: default; }
.nw-tune-difficulty button { border-color: color-mix(in srgb, var(--gold) 45%, var(--border)); }
.nw-tune-similar button { border-color: color-mix(in srgb, var(--gold) 62%, var(--border));
  margin-right: 4px; background: color-mix(in srgb, var(--gold) 10%, var(--card));
  font-weight: 750; }
.nw-topic-chips { min-width: 0; display: flex; flex-wrap: wrap;
  gap: 6px; padding: 2px 0; }
.nw-topic-chips[hidden] { display: none; }
.nw-topic-hint { flex: 1 0 100%; margin: 0; color: var(--muted); font-size: 12px; }
.nw-topic-chips button.nw-topic-chip { min-width: 0; max-width: 100%; min-height: 30px;
  padding: 4px 9px; border-radius: 999px; overflow-wrap: anywhere;
  white-space: normal; font-size: 12px; }
.nw-topic-chips button.nw-topic-chip[aria-pressed="true"] {
  border-color: var(--gold); color: var(--text);
  background: color-mix(in srgb, var(--gold) 14%, var(--card-2)); }
.nw-status { min-height: 1.4em; margin-left: auto; max-width: 55%; color: var(--muted);
  font-size: 12px; text-align: right; }
.nw-status[data-busy="1"] { color: var(--text); }
.nw-status[data-busy="1"]::before { content: ""; display: inline-block; width: 11px; height: 11px;
  margin-right: 7px; vertical-align: -1px; border: 2px solid var(--border);
  border-top-color: var(--gold); border-radius: 50%; animation: nw-spin .7s linear infinite; }
@keyframes nw-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .nw-status[data-busy="1"]::before { animation: none; } }
.nw-title:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; border-radius: 3px; }
@media (max-width: 720px) {
  .nw-card { gap: 14px; padding: 13px; min-height: 760px; }
  .nw-study-shell { grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "media" "guide"; gap: 14px; }
  .nw-discovery-column { margin: 0 -13px -13px; padding: 14px 13px 13px; }
  .nw-guide { padding-top: 2px; }
  .nw-guide-body { min-height: 0; }
  .nw-language-list { grid-template-columns: minmax(0, 1fr); }
  .nw-status:not(:empty), .nw-status[data-busy="1"] { flex: 1 0 100%; max-width: 100%;
    margin-left: 0; text-align: left; }
  .nw-companion-action { align-items: flex-start; }
}
.section-h2 { margin: 0; font-family: var(--brand-font); font-weight: 600;
  font-size: 19px; color: var(--text); }
.section-h2.rec::before { content: "✦ "; color: var(--gold); }
.section-h2.gems::before { content: "💎 "; }
.section-h2.bylevel::before { content: "📚 "; }
.view-all { font-size: 13px; font-weight: 600; color: var(--accent);
  text-decoration: none; white-space: nowrap; flex: none; }
.view-all:hover { text-decoration: underline; }
.ladder-note { margin: 0 0 12px; }

/* trending — a compact ranked list */
.trend-list { display: grid; gap: 2px; }
.trend-row { display: flex; align-items: center; gap: 12px; padding: 8px 10px;
  border-radius: 10px; border: 1px solid transparent; }
.trend-row:hover { background: var(--card); border-color: var(--border); }
.trend-rank { flex: none; width: 22px; text-align: center; font-family: var(--brand-font);
  font-weight: 700; font-size: 16px; color: var(--faint); font-variant-numeric: tabular-nums; }
.trend-thumb { flex: none; width: 64px; height: 36px; border-radius: 6px;
  overflow: hidden; background: var(--card-2); }
.trend-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.trend-name { flex: 1; min-width: 0; font-weight: 600; color: var(--text);
  text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.trend-name:hover { color: var(--accent-hi); }
.trend-genre { flex: none; font-size: 11px; letter-spacing: .03em; text-transform: uppercase;
  color: var(--muted); }
.trend-level { flex: none; font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .04em; white-space: nowrap; }
.trend-level.beg { color: var(--teal); }
.trend-level.int { color: var(--gold); }
.trend-level.adv { color: var(--accent); }
.trend-row .bookmark { flex: none; font-size: 16px; }
@media (max-width: 560px) {
  .trend-genre { display: none; }
}

/* browse "show more" */
.more-wrap { display: flex; justify-content: center; margin: 16px 0 4px; }
.more-wrap button[hidden] { display: none; }

/* ---- Discover home: demoted analyzer strip ---- */
.analyze-strip {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 16px; margin: 30px 0 8px; padding: 18px 20px;
  background: var(--bg-glow); border: 1px solid var(--border); border-radius: 14px;
}
.analyze-strip-copy { min-width: 240px; flex: 1 1 260px; }
.analyze-strip-copy h3 { margin: 0 0 4px; font-size: 16px; color: var(--text); font-weight: 600; }
.analyze-strip-copy p { margin: 0; font-size: 13px; color: var(--muted); max-width: 420px; }
.analyze-strip-form { display: flex; gap: 8px; flex: 1 1 320px; }
.analyze-strip-form input { flex: 1; min-width: 0; }
.analyze-strip-form button { white-space: nowrap; }
@media (max-width: 560px) {
  .hero-h { font-size: 27px; }
  .analyze-strip-form { flex-direction: column; align-items: stretch; }
}

/* ---- channel directory ---- */
/* personalized "your next step" ladder above the grid */
.ladder-section { margin: 8px 0 28px; }
.ladder-section:empty { display: none; }
.ladder-h { margin: 0; font-size: 18px; font-weight: 600; color: var(--text); }
.ladder-h::before { content: "✦ "; color: var(--gold); }
.ladder-note { margin: 3px 0 14px; font-size: 13px; color: var(--muted); max-width: 640px; }
.ladder-note a { color: var(--gold); }
/* "Recommended for you" — a horizontal carousel of channel cards (thumbnail +
   mini vocab/speed meters + your coverage), matching the browse card styling. */
.ladder { display: grid; grid-auto-flow: column; grid-auto-columns: 236px;
  gap: 12px; overflow-x: auto; padding: 2px 2px 12px;
  scroll-snap-type: x proximity; scrollbar-width: thin; }
.ladder-compact { width: fit-content; max-width: 100%; }
/* Hold the rail at its settled card height so the loading shell and the real
   cards occupy the same space — otherwise the section jumps when they swap.
   Was 418px while the bookend cards carried a "Feeling relaxed?" caption; that
   caption's box (11px text at line-height 1.5, plus 5px padding top and bottom)
   came off the tallest card when the captions were dropped. */
.home-section[data-sec="rec"] .ladder { min-height: 392px; }
.rec-loading-card { box-shadow: none; }
.rec-loading-card:hover { border-color: var(--border); box-shadow: none; }
.rec-loading-thumb { width: 100%; aspect-ratio: 16 / 9; border-radius: 0; }
.rec-loading-title { width: 82%; height: 38px; }
.rec-loading-chips { width: 58%; height: 22px; border-radius: 999px; }
.rec-loading-axes { display: grid; gap: 11px; margin: 4px 0; }
.rec-loading-axes .home-skeleton { width: 100%; height: 8px; border-radius: 999px; }
.rec-loading-copy { width: 100%; height: 54px; }
.rec-loading-action { width: 100%; height: 34px; margin-top: auto; }

/* "Browse by level" shelf tabs (home). One persistent section, three shelves;
   the estimated starting band gets a quiet "Suggested" marker. */
.bylevel-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 12px; }
.bylevel-tab { font-family: var(--brand-font); font-weight: 600; font-size: 13.5px;
  padding: 6px 16px; border-radius: 999px; cursor: pointer;
  background: transparent; color: var(--muted); border: 1px solid var(--border); }
.bylevel-tab:hover { color: var(--text); background: var(--card-2); }
.bylevel-tab:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.bylevel-tab.on { background: var(--card); color: var(--text);
  border-color: var(--faint); }
.bylevel-suggested { font-size: 11px; font-weight: 700; color: var(--gold);
  margin-left: 7px; }
.rec-card { display: flex; flex-direction: column; scroll-snap-align: start;
  background: var(--card); border: 1px solid var(--border); border-radius: 14px;
  overflow: hidden; box-shadow: var(--shadow);
  transition: box-shadow .15s ease, border-color .15s ease; }
.rec-card:hover { border-color: var(--accent);
  box-shadow: 0 2px 4px rgba(60,42,24,.08), 0 10px 26px rgba(60,42,24,.1); }
.rec-thumb { display: block; width: 100%; aspect-ratio: 16 / 9; background: var(--card-2); }
.rec-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.rec-body { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px 14px; flex: 1; }
.rec-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
/* Title clamps to a FIXED two lines (ellipsis past that) and always reserves that
   height, so every card's genre chips, meters and summary line up with its
   neighbours regardless of how long or short the channel name is. */
.rec-name { margin: 0; font-size: 15px; font-weight: 600; line-height: 1.25;
  color: var(--text); overflow-wrap: anywhere; flex: 1; min-width: 0;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; min-height: 2.5em; }
.rec-name a { color: inherit; text-decoration: none; }
.rec-name a:hover { color: var(--accent-hi); }
/* The rail is a fixed 236px column, so a long genre + a long band ("Japanese
   Learning" + "Intermediate") overflows the row and wraps. Never let it: a
   two-line chips row is taller than its neighbours' and knocks this card's
   meters, summary and CTA out of alignment — the same misalignment .rec-name
   and .rec-desc reserve fixed heights to prevent. Tighter padding reclaims most
   of the overflow; past that only the genre chip shrinks (it never grows, so
   short genres are unchanged), keeping the difficulty band whole and clipping
   just the tail of the longest labels. rungCard puts the full text on hover. */
.rec-body .chips { margin: 0; align-items: center; flex-wrap: nowrap; gap: 5px; }
.rec-body .chip { padding: 2px 7px; }
.rec-body .chip.genre { flex: 0 1 auto; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rec-body .axes-mini { width: 100%; margin: 2px 0; }
/* "What is this channel" line on recommendation cards (fast path, no coverage %).
   Fixed height (3 lines reserved) so the comprehension line below stays aligned. */
.rec-desc { margin: 0; font-size: 12.5px; line-height: 1.45; color: var(--muted);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden; min-height: 4.35em; }
/* Slot the exact "you follow ~N%" line fills in after render; takes no room empty. */
.rec-metric:empty { display: none; }
.rec-metric { margin-top: 2px; }
.cov-bar.small { height: 6px; margin: 2px 0 0; max-width: none; }
.rung-cov { display: block; font-size: 12px; color: var(--muted); }
.rung-cov b { color: var(--gold); font-variant-numeric: tabular-nums; }
.rung-learn { display: block; font-size: 11px; color: var(--muted); margin-top: 1px; }
.rung-learn b { color: var(--text); font-variant-numeric: tabular-nums; }
/* Honest comprehension band pill — translucent tint + accent text, both themes. */
.comp-pill { display: inline-block; font-size: 10px; font-weight: 700; line-height: 1.4;
  padding: 0 6px; border-radius: 999px; vertical-align: middle; white-space: nowrap; }
.comp-pill.comf    { background: rgba(79,118,107,.20); color: var(--teal); }
.comp-pill.ready   { background: rgba(120,150,190,.22); color: #6a8fc0; }
.comp-pill.stretch { background: rgba(169,118,31,.20);  color: var(--gold); }
.comp-pill.chal    { background: rgba(198,110,50,.18);  color: #cf7a3f; }
.comp-pill.hard    { background: rgba(178,70,70,.18);   color: #c56b6b; }
.rec-body .cta { margin-top: auto; display: inline-block; text-align: center;
  padding: 8px 14px; border-radius: 8px; background: var(--teal); color: #fff;
  font-weight: 600; font-size: 13px; text-decoration: none; }
.rec-body .cta:hover { background: var(--teal-hi); }
.diff-badge.mini { flex: none; padding: 4px 7px; border-radius: 8px; }
.diff-badge.mini .diff-band { font-size: 10px; }

/* save/bookmark star (browse card + recommendation card) */
.bookmark {
  background: transparent; border: 0; padding: 2px 4px; margin: 0; cursor: pointer;
  font-size: 18px; line-height: 1; color: var(--faint); flex: none;
}
.bookmark:hover { color: var(--gold); }
.bookmark.on { color: var(--gold); }

.channels { display: grid; gap: 12px; }
.channel {
  display: flex; gap: 16px; justify-content: space-between; align-items: stretch;
  background: var(--card); border: 1px solid var(--border); border-radius: 14px;
  padding: 14px 16px; box-shadow: var(--shadow);
  transition: box-shadow .15s ease, border-color .15s ease, transform .15s ease;
}
.channel:hover { border-color: var(--accent);
  box-shadow: 0 2px 4px rgba(60,42,24,.08), 0 10px 26px rgba(60,42,24,.1); }
/* flex:1 so the middle column always fills the space between thumbnail and side
   — otherwise it shrinks to its widest line (usually the name) and space-between
   floats it at a different x per card, shifting the meters + centering the name. */
.chan-main { flex: 1; min-width: 0; }
/* "What is this channel" blurb under the meters. Width-capped for readability;
   clamped so a wordy description can't balloon the row. */
.chan-blurb { margin: 8px 0 0; font-size: 12.5px; line-height: 1.5; color: var(--muted);
  max-width: 72ch; display: -webkit-box; -webkit-line-clamp: 3;
  -webkit-box-orient: vertical; overflow: hidden; }
/* Slot the per-page "you follow ~N%" fill writes into; takes no room empty. */
.chan-metric { margin-top: 8px; }
.chan-metric:empty { display: none; }
.chan-metric .cov-bar.small { max-width: 320px; }
.chan-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
.chan-name { margin: 0; font-size: 17px; color: var(--text); font-weight: 600;
  overflow-wrap: anywhere; }
.chan-handle { font-size: 12px; color: var(--faint); }
.chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0; }
.chip { font-size: 11px; letter-spacing: .03em; text-transform: uppercase;
  color: var(--muted); background: var(--card-2); border: 1px solid var(--border-2);
  padding: 2px 9px; border-radius: 999px; }
.chip.cat { color: var(--teal); border-color: rgba(79, 118, 107, .4); }
.chan-stats { display: flex; flex-wrap: wrap; gap: 4px 16px; font-size: 13px;
  color: var(--muted); }
.chan-stats b { color: var(--text); font-variant-numeric: tabular-nums; font-weight: 600; }
.chan-side { display: flex; flex-direction: column; align-items: flex-end;
  justify-content: space-between; gap: 10px; flex: none; text-align: right; }
.diff-badge { display: inline-flex; align-items: center; justify-content: center;
  padding: 6px 12px; border-radius: 10px; border: 1px solid var(--border);
  background: var(--card-2); }
.diff-band { font-size: 12px; text-transform: uppercase; letter-spacing: .05em;
  font-weight: 700; color: var(--muted); }
.diff-badge.beg { border-color: rgba(79, 118, 107, .5); }
.diff-badge.beg .diff-band { color: var(--teal); }
.diff-badge.int { border-color: rgba(180, 130, 50, .5); }
.diff-badge.int .diff-band { color: var(--gold); }
.diff-badge.adv { border-color: rgba(192, 83, 43, .5); }
.diff-badge.adv .diff-band { color: var(--accent); }
.diff-badge.na .diff-band { color: var(--faint); }
.chan-side .cta { display: inline-block; padding: 8px 14px; border-radius: 7px;
  background: var(--teal); color: #fff; font-weight: 600; font-size: 13px;
  text-decoration: none; white-space: nowrap; }
.chan-side .cta:hover { background: var(--teal-hi); }
.count a { color: var(--gold); }
.chan-name a { color: inherit; text-decoration: none; }
.chan-name a:hover { color: var(--accent-hi); }
a.diff-badge { text-decoration: none; }
a.diff-badge:hover { border-color: var(--accent); }
@media (max-width: 560px) {
  .channel { flex-direction: column; }
  .chan-side { flex-direction: row; align-items: center; text-align: left; }
  /* Stacked rows get long on phones — tighten the blurb to two lines. */
  .chan-blurb { -webkit-line-clamp: 2; }
}

/* ---- channel detail view ---- */
.back { display: inline-block; margin: 0 0 14px; font-size: 13px; font-weight: 600;
  color: var(--muted); text-decoration: none; }
.back:hover { color: var(--text); }
.chan-detail { background: var(--card); border: 1px solid var(--border);
  border-radius: 14px; padding: 20px; }
.detail-head { display: flex; flex-wrap: wrap; gap: 16px; align-items: flex-start;
  justify-content: space-between; }
.detail-id .chan-name { font-size: 24px; }
/* Name / handle / chips stack tight enough to clear the 90px thumbnail beside them:
   the save toggle used to sit between handle and chips, costing a whole row and
   pushing the chips past the thumbnail's bottom edge. */
.detail-id .chips { margin: 6px 0 0; }
/* Labeled save toggle in the detail header (same store as the card star). It is the
   header row's third flex child — alone in the top-right corner, so it can be a
   larger tap target without moving anything else. */
.save-cta {
  flex: none; align-self: flex-start; margin-top: 2px; padding: 9px 17px;
  border-radius: 999px; white-space: nowrap;
  background: transparent; border: 1px solid var(--border-2); cursor: pointer;
  font-family: inherit; font-size: 14px; font-weight: 600; color: var(--muted);
}
.save-cta:hover { color: var(--gold); border-color: var(--gold); }
.save-cta.on { color: var(--gold); border-color: rgba(169, 118, 31, .5);
  background: rgba(169, 118, 31, .08); }
.chan-desc { margin: 10px 0 4px; color: var(--text); font-size: 15px;
  line-height: 1.5; max-width: 680px; }

/* Cold-start panel — the one remaining top-of-page mining action: "Fetch latest
   episodes" for a channel we don't have in the directory yet. (The old per-channel
   Fetch-latest / Add-video panel moved into the Start-Here section as .sh-pick.) */
.update-panel { margin: 14px 0 2px; display: flex; flex-direction: column; gap: 10px; }
.update-status { font-size: 13px; color: var(--muted); min-height: 1em; }
.update-status.ok { color: var(--ok-text); }
.update-status.error { color: var(--warn-text); }
.update-status a { color: var(--accent); }
.chan-detail.cold { padding: 8px 2px; }

/* Compact entity glossary used inside the learner-orientation card. */
.entities { list-style: none; padding: 0; margin: 0; display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 4px 18px; }
.entities li { display: flex; gap: 8px; align-items: baseline; font-size: 13px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 55%, transparent); padding: 3px 0; }
.ent-name { font-weight: 600; color: var(--text); white-space: nowrap; }
.ent-gloss { color: var(--muted); }

/* ---- "Start here" + Companion Guide ---- */
.start-here { margin: 22px 0 8px; }
.sh-head { display: flex; gap: 10px; align-items: baseline; margin-bottom: 12px; }
.sh-head .section-h { margin: 0; }
.sh-head .section-note { margin: 0; }
.sh-star { color: var(--gold); font-size: 20px; line-height: 1.2; }
.sh-loading { color: var(--muted); font-size: 14px; padding: 8px 0; }
/* The picked video and its guide are ONE thing, so they share ONE card: a single
   gold surface with a single header, halved by a hairline rule rather than by a gap
   between two competing borders. The gold belongs to the whole card — tinting only
   the video half demoted the guide, which is the part that carries the value. */
.sh-card { padding: 15px; border-radius: 14px;
  border: 1px solid color-mix(in srgb, var(--gold) 34%, var(--border));
  background: color-mix(in srgb, var(--gold) 7%, var(--card)); }
.sh-card-head { margin-bottom: 10px; padding-bottom: 9px;
  border-bottom: 1px solid color-mix(in srgb, var(--gold) 20%, var(--border)); }
/* "Start here" and its note share ONE baseline row instead of stacking: the note
   still carries where the shown video came from (see setStartHeadSource), so it is
   inlined rather than dropped or hidden behind a hover. It wraps back under the
   title on narrow viewports, where the card is single-column anyway. */
.sh-head-text { flex: 1 1 auto; min-width: 0; display: flex; flex-wrap: wrap;
  align-items: baseline; gap: 2px 9px; }
/* Guard so the note drops WHOLE onto the next line rather than being squeezed into a
   narrow ragged column beside the title on phones. */
.sh-head-text .section-note { min-width: 30ch; }
.sh-grid { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
  gap: 0; align-items: stretch; }
.sh-player, .sh-side { min-width: 0; }
.sh-player { padding-right: 17px; }
.sh-side { padding-left: 17px;
  border-left: 1px solid color-mix(in srgb, var(--gold) 22%, var(--border)); }
@media (max-width: 720px) {
  .sh-card { padding: 12px; }
  .sh-grid { grid-template-columns: 1fr; }
  .sh-player { padding-right: 0; }
  .sh-side { padding: 14px 0 0; border-left: 0;
    border-top: 1px solid color-mix(in srgb, var(--gold) 22%, var(--border)); }
}
.sh-stage { position: relative; aspect-ratio: 16 / 9; border-radius: 10px; overflow: hidden;
  background: #000; }
.sh-stage iframe, #shPlayerFrame { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
/* NOTE: .sh-poster is a <button>, so these MUST out-specify the base button:hover
   rule (0,1,1) or its `background` shorthand resets size/position on hover and the
   image jumps to natural size top-left (the "black bar on hover" bug). Hence the
   :hover/:focus/:active variants re-asserting cover/center. */
.sh-poster, .sh-poster:hover, .sh-poster:focus, .sh-poster:active {
  background-color: #000; background-size: cover; background-position: center; }
.sh-poster { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; cursor: pointer;
  display: flex; align-items: center; justify-content: center; padding: 0; }
.sh-play { width: 62px; height: 62px; border-radius: 50%; background: rgba(0,0,0,.62);
  color: #fff; font-size: 24px; display: flex; align-items: center; justify-content: center;
  padding-left: 4px; transition: background .15s; }
.sh-poster:hover .sh-play { background: var(--accent); }
.sh-meta { display: flex; flex-direction: column; gap: 2px; margin-top: 8px; }
.sh-title { font-weight: 600; color: var(--text); font-size: 14px; line-height: 1.35; }
.sh-date { font-size: 12px; color: var(--faint); }
.sh-side { display: flex; flex-direction: column; gap: 10px; min-height: 0; }
/* The guide names itself on its toolbar line instead of in a second <h3>: one row
   instead of a 46px title block, and no heading competing with "Start here". */
.sh-side .study-mode-toolbar { margin-bottom: 0; }
.sh-guide-label { min-width: 0; color: var(--text); font-family: var(--brand-font);
  font-size: 13px; font-weight: 600; }
.study-shell.is-study-mode .sh-guide-label { display: none; }
.sh-side-tabs { display: flex; align-items: center; gap: 4px; padding: 3px;
  width: fit-content; border-radius: 9px; background: color-mix(in srgb, var(--card-2) 78%, transparent);
  border: 1px solid var(--border); }
.sh-side-tab { appearance: none; border: 0; border-radius: 6px; padding: 5px 10px;
  background: transparent; color: var(--muted); font: inherit; font-size: 12px;
  font-weight: 600; cursor: pointer; }
.sh-side-tab:hover { background: color-mix(in srgb, var(--btn-2) 70%, transparent); color: var(--text); }
.sh-side-tab.is-active { background: var(--btn-2); color: var(--text); }
.sh-overview { display: flex; flex-direction: column; gap: 10px; }
.sh-overview[hidden], .sh-live[hidden] { display: none; }
.sh-preview-facts { display: flex; flex-wrap: wrap; gap: 6px; }
.sh-preview-fact { padding: 4px 8px; border: 1px solid var(--border-2); border-radius: 999px;
  color: var(--muted); font-size: 11px; white-space: nowrap; }
.sh-preview-fact b { color: var(--text); font-size: 12px; }
/* Fills whatever the shared tab box (--sh-guide-h) leaves under the fact pills, so
   Preview and Live guide occupy the same height and switching tabs never resizes
   the card. Only the row list scrolls; the category tabs stay pinned. */
.sh-preview-content { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.sh-preview-loading, .sh-preview-empty { min-height: 176px; margin: 0; display: grid;
  place-items: center; padding: 18px; color: var(--muted); font-size: 12px; text-align: center;
  border: 1px dashed var(--border); border-radius: 10px; }
/* Matches .nw-guide-label on the homepage card — the two previews are one
   component wearing each host's row style. */
.sh-preview-label { margin-bottom: 5px; color: var(--muted); font-size: 11px;
  font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
.sh-preview-row + .sh-preview-label { margin-top: 11px; }
.sh-preview-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; scrollbar-gutter: stable; }
/* The divider is what tells the eye "word ends here, next word starts there", so it
   is a visible hairline rather than a 62%-transparent one — at that strength it
   vanished against the card's gold-tinted ground. Tinted to match the card's other
   rules (.sh-card-head, .sh-side) so the card keeps one hairline language. */
.sh-preview-row { min-width: 0; padding: 8px 2px;
  border-bottom: 1px solid color-mix(in srgb, var(--gold) 18%, var(--border)); }
.sh-preview-row:last-child { border-bottom: 0; }
.sh-preview-row-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
/* Two lines, matching .nw-vocab-meaning — the two previews are one component, and a
   single ellipsised line cut most multi-sense glosses mid-first-sense. */
.sh-preview-meaning { display: -webkit-box; min-width: 0; margin-top: 3px;
  overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2;
  overflow-wrap: anywhere; color: var(--muted); font-size: 12px; }
/* A row the clamp is ACTUALLY cutting is a tap target (pointer + hover tint); one that
   fits is left inert, so the affordance never lies. Expanding just drops the clamp. */
.sh-preview-row:has(.is-gloss-toggle) { cursor: pointer; }
.sh-preview-row:has(.is-gloss-toggle):hover {
  background: color-mix(in srgb, var(--card-2) 55%, transparent); }
.sh-preview-row.sh-preview-open .sh-preview-meaning {
  -webkit-line-clamp: unset; line-clamp: unset; color: var(--text); }
/* The card's drawer handle: a full-width bar spanning BOTH halves at the card's
   foot, so the full guide it opens reads as this card's contents rather than as
   the next band of the channel page. Open, it joins the panel below it.
   Styled as the card's primary action, matching the homepage's "Watch with
   companion" (.nw-primary): same teal, same weight. It opens the thing this
   whole card is preparing you for, so a neutral button undersold it. */
.sh-companion-toggle { display: block; width: 100%; margin-top: 13px;
  background: var(--teal); color: #fff; font-size: 13px; font-weight: 700;
  padding: 9px 12px; }
/* :active must be restated — the base button rule's own :active out-specifies a
   plain class and would flash accent orange through the teal. */
.sh-companion-toggle:hover, .sh-companion-toggle:active { background: var(--teal-hi); }
.sh-companion-toggle.is-open { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }

/* Live companion: one card per noteworthy timed subtitle cue. The scroll area is
   deliberately bounded so the guide accompanies the video instead of growing the
   whole Start Here row. */
.sh-live { min-height: 0; display: flex; flex-direction: column; overflow: hidden;
  border: 1px solid var(--border); border-radius: 11px;
  background: color-mix(in srgb, var(--card) 78%, #000); }
.sh-live-loading, .sh-live-empty { flex: 1 1 auto; min-height: 210px;
  display: flex; flex-direction: column;
  justify-content: center; align-items: center; gap: 5px; padding: 18px;
  text-align: center; color: var(--muted); font-size: 13px; }
.sh-live-empty b { color: var(--text); font-size: 14px; }
/* The cue stream is flex:1 inside a fixed-height box (see --sh-guide-h /
   --nw-guide-h below), so every pixel this row costs comes straight out of the
   scrolling text. Keep the controls pill-sized; nothing here should set its own
   height. Wrapping is the safety valve for a narrow phone with Follow video
   showing — better a second line than a squashed row. */
.sh-live-head { position: relative; z-index: 10; display: flex; flex-wrap: wrap;
  justify-content: space-between; align-items: center; gap: 6px 10px;
  padding: 7px 11px; border-bottom: 1px solid var(--border);
  background: color-mix(in srgb, var(--card-2) 68%, transparent); }
.sh-live-status { color: var(--gold); font-size: 12px; font-weight: 700;
  font-variant-numeric: tabular-nums; }
.sh-live-actions { display: inline-flex; align-items: center; gap: 6px; }
/* Was a 36px circle, which single-handedly set this row ~14px taller than its
   own contents needed. Now a pill the size of its neighbours, and labelled:
   with the explainer no longer opening by itself, this label is the only thing
   telling a first-time viewer the explanation exists. */
.sh-live-help { position: relative; z-index: 1; appearance: none; cursor: pointer;
  flex: none; display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; touch-action: manipulation;
  border: 1px solid var(--border-2); border-radius: 999px; background: transparent;
  color: var(--muted); font: inherit; font-size: 11px; font-weight: 600; }
.sh-live-help > .sh-live-help-mark { display: inline-flex; align-items: center;
  justify-content: center; width: 14px; height: 14px; border-radius: 50%;
  border: 1px solid currentColor; font-size: 9px; font-weight: 700; line-height: 1; }
.sh-live-help:hover, .sh-live-help[aria-expanded="true"] { background: transparent;
  border-color: var(--gold); color: var(--gold); }
.sh-live-furigana { appearance: none; cursor: pointer; border: 1px solid var(--border-2);
  border-radius: 999px; padding: 3px 9px; background: transparent; color: var(--muted);
  font: inherit; font-size: 11px; font-weight: 600; }
.sh-live-furigana:hover { background: transparent; border-color: var(--teal); color: var(--text); }
.sh-live-furigana[aria-pressed="true"] { border-color: color-mix(in srgb, var(--teal) 72%, var(--border));
  background: color-mix(in srgb, var(--teal) 14%, transparent); color: var(--teal-hi); }
.sh-live-follow { appearance: none; cursor: pointer; border: 1px solid var(--gold);
  border-radius: 999px; padding: 3px 9px; background: transparent; color: var(--gold);
  font: inherit; font-size: 11px; font-weight: 600; }
.sh-live-follow:hover { background: color-mix(in srgb, var(--gold) 12%, transparent); }
.sh-live-intro { display: grid; grid-template-columns: minmax(0, 1fr) auto;
  gap: 4px 12px; padding: 10px 11px; border-bottom: 1px solid var(--border);
  background: color-mix(in srgb, var(--teal) 7%, var(--card)); }
.sh-live-intro[hidden] { display: none; }
.sh-live-intro p { grid-column: 1; margin: 0; color: var(--muted); font-size: 11px;
  line-height: 1.45; }
.sh-live-intro p b { color: var(--text); }
.sh-live-intro-dismiss { grid-column: 2; grid-row: 1 / span 2; align-self: center;
  padding: 5px 9px; border: 1px solid var(--teal); border-radius: 7px;
  background: transparent; color: var(--teal-hi); font: inherit; font-size: 11px;
  font-weight: 700; cursor: pointer; }
.sh-live-intro-dismiss:hover { background: color-mix(in srgb, var(--teal) 13%, transparent); }
.sh-live-stream { height: clamp(240px, 27vw, 340px); min-height: 0; overflow-y: auto;
  scroll-behavior: smooth; padding: 10px; scrollbar-gutter: stable; }
.sh-live-cue { position: relative; margin: 0 0 9px; padding: 10px 10px 11px 13px;
  border: 1px solid transparent; border-left: 2px solid var(--border-2);
  border-radius: 8px; opacity: .66; transition: opacity .18s, border-color .18s, background .18s; }
.sh-live-cue:last-child { margin-bottom: 0; }
/* Dimming makes every cue its own stacking context, so a word tip's z-index only
   orders it inside its own cue — later cues in the DOM painted over the popup.
   Lift the whole cue whenever one of its tips can be open (hover, keyboard
   focus, or a tapped-open popover). */
.sh-live-cue:hover, .sh-live-cue:focus-within,
.sh-live-cue:has(.sh-live-word[aria-expanded="true"]) { z-index: 2; }
.sh-live-cue:hover { opacity: .86; background: color-mix(in srgb, var(--card-2) 48%, transparent); }
.sh-live-cue.is-current, .sh-live-cue.is-upcoming { opacity: 1;
  border-color: color-mix(in srgb, var(--gold) 42%, var(--border));
  border-left-color: var(--gold); background: color-mix(in srgb, var(--gold) 7%, var(--card)); }
/* A cue that has just finished: still legible, no longer claiming to be the video's
   current moment. Sits deliberately between the resting .66 and the current 1. */
.sh-live-cue.is-recent { opacity: .88;
  border-color: color-mix(in srgb, var(--gold) 20%, var(--border));
  border-left-color: color-mix(in srgb, var(--gold) 55%, var(--border-2));
  background: color-mix(in srgb, var(--gold) 4%, var(--card)); }
.sh-live-cue.is-keyboard-focus:focus-within { opacity: 1; border-left-color: var(--teal); }
.sh-live.is-browsing .sh-live-cue.is-current,
.sh-live.is-browsing .sh-live-cue.is-upcoming { border-left-color: var(--teal); }
.sh-live.is-browsing .sh-live-cue.is-recent {
  border-left-color: color-mix(in srgb, var(--teal) 55%, var(--border-2)); }
.sh-live.is-browsing .sh-live-cue { opacity: .9; }
.sh-live-cue-head { display: flex; align-items: baseline; justify-content: space-between;
  gap: 8px; }
.sh-live-kind { flex: none; color: var(--faint); font-size: 9px; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; }
.sh-live-time { appearance: none; cursor: pointer; border: 0; padding: 0;
  background: transparent; color: var(--accent); font: inherit; font-size: 11px;
  font-weight: 700; font-variant-numeric: tabular-nums; }
/* Re-declare background on these ghost buttons' :hover — the global
   `button:hover{background:var(--accent-hi)}` (specificity 0,1,1) otherwise wins
   over their single-class base and fills them with accent orange; on .sh-live-time
   that hid the timestamp entirely (orange text on an orange fill). */
.sh-live-time:hover { background: transparent; color: var(--accent-hi); text-decoration: underline; }
.sh-live-sentence { margin: 5px 0 8px; color: var(--text); font-size: 15px; line-height: 1.75; }
.sh-live-sentence ruby { ruby-position: over; }
.sh-live-sentence rt { color: var(--ruby); font-size: var(--ruby-reading-size);
  font-weight: var(--ruby-weight); }
.sh-live:not(.show-furigana) .sh-live-sentence rt { display: none; }
.sh-live-token { position: relative; }
.sh-live-word, .sh-live-word:hover, .sh-live-word:focus, .sh-live-word:active {
  appearance: none; border: 0; border-radius: 3px; margin: 0; padding: 0;
  background: transparent; color: inherit; font: inherit; line-height: inherit;
  text-align: left; vertical-align: baseline; }
.sh-live-word { cursor: help; }
.sh-live-word:not(.sh-live-mark):hover,
.sh-live-word:not(.sh-live-mark):focus-visible,
.sh-live-word[aria-expanded="true"] { background: color-mix(in srgb, var(--teal) 14%, transparent);
  box-shadow: inset 0 -1px color-mix(in srgb, var(--teal) 62%, transparent); }
.sh-live-word-tip { display: none; position: absolute; z-index: 8; left: 0;
  top: calc(100% + 7px); width: max-content; max-width: min(290px, 78vw);
  padding: 11px 12px; border: 1px solid var(--border-2); border-radius: 9px;
  background: var(--card-2); box-shadow: 0 7px 22px rgba(0,0,0,.28);
  color: var(--text); font-size: 13px; font-weight: 400; line-height: 1.45;
  text-align: left; white-space: normal; }
.sh-live-word.is-tip-right .sh-live-word-tip { right: 0; left: auto; }
.sh-live-word.is-tip-up .sh-live-word-tip { top: auto; bottom: calc(100% + 7px); }
.sh-live-word:hover .sh-live-word-tip,
.sh-live-word:focus-visible .sh-live-word-tip,
.sh-live-word[aria-expanded="true"] .sh-live-word-tip { display: flex; flex-direction: column; gap: 5px; }
.sh-live-word-head { color: var(--text); font-size: 15px; font-weight: 700; }
.sh-live-word-head rt { display: revert !important; color: var(--ruby);
  font-size: var(--ruby-compact-size); font-weight: var(--ruby-weight); }
.sh-live-word-meaning { color: var(--muted); }
.sh-live-word-senses-label { color: var(--faint); font-size: 10px; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; }
.sh-live-word-meanings { margin: 0; padding-left: 20px; color: var(--muted); }
.sh-live-word-meanings li + li { margin-top: 3px; }
.sh-live-word-meanings li::marker { color: var(--gold); font-size: 11px; font-weight: 700; }
.sh-live-word-context { color: var(--faint); font-size: 10px; line-height: 1.35; }
.sh-live-word-pos { color: var(--faint); font-size: 11px; }
.sh-live-mark { --live-mark-color: var(--gold); color: inherit;
  background: color-mix(in srgb, var(--live-mark-color) 16%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--live-mark-color) 55%, transparent);
  border-radius: 3px; padding: 0 1px; box-decoration-break: clone; -webkit-box-decoration-break: clone;
  transition: background .12s, border-color .12s; }
.sh-live-mark[data-live-mark-types~="vocabulary"] { --live-mark-color: var(--accent); }
.sh-live-mark[data-live-mark-types~="grammar"] { --live-mark-color: var(--teal); }
.sh-live-mark[data-live-mark-types~="expression"] { --live-mark-color: var(--gold); }
.sh-live-mark.is-selected {
  background: color-mix(in srgb, var(--live-mark-color) 34%, transparent);
  border-bottom-color: var(--live-mark-color); }
.sh-live-cue[data-live-selected-type="vocabulary"] .sh-live-mark.is-selected {
  --live-mark-color: var(--accent); }
.sh-live-cue[data-live-selected-type="grammar"] .sh-live-mark.is-selected {
  --live-mark-color: var(--teal); }
.sh-live-cue[data-live-selected-type="expression"] .sh-live-mark.is-selected {
  --live-mark-color: var(--gold); }
.sh-live-items { display: flex; flex-wrap: wrap; gap: 5px; }
.sh-live-item { appearance: none; cursor: pointer; display: inline-flex; align-items: baseline;
  gap: 5px; max-width: 100%; border: 1px solid var(--border-2); border-radius: 999px;
  padding: 3px 8px; background: transparent; color: var(--text); font: inherit;
  font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sh-live-item > span:first-child { color: var(--faint); font-size: 9px; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; }
.sh-live-item rt { color: var(--ruby); font-size: var(--ruby-compact-size);
  font-weight: var(--ruby-weight); }
.sh-live-item:hover { background: transparent; border-color: var(--gold); }
.sh-live-item.is-active { border-color: color-mix(in srgb, var(--gold) 70%, var(--border));
  background: color-mix(in srgb, var(--gold) 11%, transparent); }
.sh-live-detail { margin-top: 7px; padding-top: 7px; border-top: 1px solid var(--border-2); }
.sh-live-meaning { color: var(--muted); font-size: 12px; line-height: 1.45; }
/* Multi-sense form of the same block: a chosen word gets the popover's short list. */
.sh-live-meaning-senses { margin: 0; padding-left: 1.15em; }
.sh-live-meaning-senses li { margin: 0; }
.sh-live-lead-row { color: var(--muted); font-size: 12px; line-height: 1.45; }
/* The word a single-item cue is about, leading its meaning line in place of the
   chip that used to repeat it on its own row. */
.sh-live-lead { color: var(--text); font-weight: 700; }
.sh-live-dot { color: var(--faint); }
.sh-live-facts { color: var(--faint); font-size: 10px; }
.sh-live-vocab-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.sh-live-vocab-action { appearance: none; min-height: 36px; padding: 6px 10px;
  border: 1px solid var(--border-2); border-radius: 8px; background: transparent;
  color: var(--muted); font: inherit; font-size: 11px; font-weight: 700;
  white-space: nowrap; cursor: pointer; touch-action: manipulation;
  transition: color .12s, border-color .12s, background .12s; }
.sh-live-vocab-action:hover { background: color-mix(in srgb, var(--card-2) 70%, transparent); }
.sh-live-known:hover, .sh-live-known.is-known { color: var(--teal-hi); border-color: var(--teal);
  background: color-mix(in srgb, var(--teal) 12%, transparent); }
.sh-live-save:hover, .sh-live-save.is-saved { color: var(--gold); border-color: var(--gold);
  background: color-mix(in srgb, var(--gold) 12%, transparent); }
.sh-live-vocab-action:focus-visible { outline: 3px solid color-mix(in srgb, var(--gold) 72%, transparent);
  outline-offset: 2px; }
.sh-live-vocab-action:disabled { opacity: .75; cursor: default; }
@media (max-width: 720px) {
  .sh-live-stream { height: min(340px, 58vh); }
}
@media (max-width: 560px) {
  .chan-detail { padding: 14px 12px; }
  .sh-live-intro { grid-template-columns: 1fr; }
  .sh-live-intro-dismiss { grid-column: 1; grid-row: auto; justify-self: start; }
  /* Narrow enough that the status, help, Furigana and Follow video pills stop
     fitting on one line. Drop to the mark alone — the button keeps its
     aria-label, so the accessible name survives the shortening. */
  .sh-live-help > .sh-live-help-text { display: none; }
  .sh-live-help { padding: 4px 7px; }
}

/* Shared video + Live Guide study surface. Native element fullscreen is used
   where available; the fixed focus variant is the same layout for iPhone and
   browsers that reject Fullscreen API requests. */
.study-shell { min-width: 0; }
.study-mode-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 7px 10px;
  margin-bottom: 11px; }
.study-mode-title { display: none; min-width: 0; color: var(--text);
  font-family: var(--brand-font); font-size: 14px; font-weight: 600; }
.study-mode-status { position: absolute; width: 1px; height: 1px; padding: 0;
  margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap;
  border: 0; }
.study-mode-toggle { flex: none; min-height: 32px; margin-left: auto; padding: 5px 10px;
  border: 1px solid color-mix(in srgb, var(--teal) 72%, var(--border));
  border-radius: 8px; background: color-mix(in srgb, var(--teal) 10%, transparent);
  color: var(--teal-hi); font: inherit; font-size: 11px; font-weight: 700; cursor: pointer; }
.study-mode-toggle:hover, .study-mode-toggle:active {
  border-color: var(--teal); background: color-mix(in srgb, var(--teal) 18%, transparent);
  color: var(--text); }
.study-mode-toggle:focus-visible { outline: 3px solid color-mix(in srgb, var(--gold) 72%, transparent);
  outline-offset: 2px; }
.study-mode-toggle:disabled { opacity: .7; cursor: wait; }
.sh-player-fallback { position: absolute; inset: 0; display: grid; place-content: center;
  gap: 10px; padding: 20px; background: #111; color: #fff; text-align: center; }
.sh-player-fallback p { margin: 0; font-size: 13px; }
.sh-player-fallback a { justify-self: center; padding: 8px 12px; border-radius: 7px;
  background: var(--teal); color: #fff; font-size: 13px; font-weight: 700;
  text-decoration: none; }
.sh-player-fallback a:hover { background: var(--teal-hi); color: #fff; }

.study-shell.is-study-focus { position: fixed; inset: 0; z-index: 1000;
  width: 100vw; height: 100dvh; }
.study-shell.is-study-fullscreen { width: 100%; height: 100%; }
.study-shell.is-study-mode { padding: calc(10px + env(safe-area-inset-top))
    calc(10px + env(safe-area-inset-right)) calc(10px + env(safe-area-inset-bottom))
    calc(10px + env(safe-area-inset-left)); overflow: hidden; color: var(--text);
  background: var(--bg); box-shadow: 0 0 0 100vmax var(--bg); }
.study-shell::backdrop { background: var(--bg); }
.nw-study-shell.is-study-mode { grid-template-columns: minmax(200px, 1.65fr) minmax(260px, .75fr);
  grid-template-areas: "media guide"; align-items: stretch; gap: 16px; }
.sh-study-shell.is-study-mode .sh-grid { height: 100%;
  grid-template-columns: minmax(200px, 1.65fr) minmax(260px, .75fr);
  align-items: stretch; gap: 16px; }
.study-shell.is-study-mode .study-mode-toolbar { flex: none; margin-bottom: 9px;
  justify-content: space-between; }
.study-shell.is-study-mode .study-mode-title { display: inline; }
.study-shell.is-study-mode .sh-side-tabs { display: none; }
.study-shell.is-study-mode .nw-media-meta,
.study-shell.is-study-mode .nw-title,
.study-shell.is-study-mode .nw-description,
.study-shell.is-study-mode .nw-actions,
.study-shell.is-study-mode .sh-card-head,
.study-shell.is-study-mode .sh-pick,
.study-shell.is-study-mode .sh-pick-panel,
.study-shell.is-study-mode .sh-meta,
.study-shell.is-study-mode .sh-card > .companion,
.study-shell.is-study-mode .sh-companion-toggle { display: none; }
.study-shell.is-study-mode .sh-card,
.study-shell.is-study-mode .sh-player,
.study-shell.is-study-mode .sh-side { padding: 0; border: 0; border-radius: 0;
  background: transparent; }
.sh-study-shell.is-study-mode .sh-card { height: 100%; }
.study-shell.is-study-mode .nw-media,
.study-shell.is-study-mode .sh-player { display: flex; min-width: 0; min-height: 0;
  flex-direction: column; justify-content: center; }
.study-shell.is-study-mode .nw-stage,
.study-shell.is-study-mode .sh-stage { width: 100%; max-width: 165vh; margin: auto;
  flex: none; }
.study-shell.is-study-mode .nw-guide,
.study-shell.is-study-mode .sh-side { min-width: 0; min-height: 0; height: 100%; overflow: hidden; }
.study-shell.is-study-mode .sh-live { flex: 1 1 auto; min-height: 0; }
.study-shell.is-study-mode .sh-live-stream { flex: 1 1 auto; height: auto; min-height: 0; }

/* Keep the embedded channel guide useful without letting it dictate a nearly
   600px card. ONE height for BOTH tabs — Preview and Live guide share the same box,
   so switching them never resizes the card and shoves the page. Fullscreen study
   mode replaces this fixed surface with flex sizing. */
.sh-study-shell { --sh-guide-h: clamp(268px, 24vw, 320px); }
/* flex-grow lets whichever tab is showing absorb the slack beside a taller video
   half. Both tabs share the one slot, so they still end up identical. */
.sh-study-shell:not(.is-study-mode) .sh-overview,
.sh-study-shell:not(.is-study-mode) .sh-live { flex: 1 1 auto; height: var(--sh-guide-h); }
.sh-study-shell:not(.is-study-mode) .sh-live-stream { flex: 1 1 auto; height: auto; min-height: 0; }

/* Next Watch solves the same "switching tabs resizes the card" problem the other
   way round, because its Preview carries real content (key words, an expression)
   that must not be clipped to a shared constant. Preview is the ANCHOR and keeps
   its natural height; syncNextWatchGuideHeight() measures it while visible and
   publishes it as --nw-guide-h, and only the Live guide is constrained to that
   box. This matters most on play: the player auto-switches to Live, so without it
   the card resizes with no user action at all. The clamp is the fallback for the
   first paint, before any measurement has happened. As on the channel page, the
   cue stream absorbs the box instead of asserting its own height, and fullscreen
   study mode keeps its own flex sizing. */
.nw-study-shell:not(.is-study-mode) .nw-live {
  height: var(--nw-guide-h, clamp(268px, 24vw, 320px)); }
.nw-study-shell:not(.is-study-mode) .sh-live-stream {
  flex: 1 1 auto; height: auto; min-height: 0; }

/* Embedded, the cue stream is only ~268–320px tall, and a card with a two-line
   sentence used to fill all of it. That hides the cadence work: the waiting state
   scrolls to the boundary between a finished note and the next one, which cannot
   read as "one card out, one card in" when one card is taller than the viewport.
   Tighten the CHROME only — never the sentence, the meaning, or the 36px action
   targets. Fullscreen study mode has the room and keeps the roomier spacing. */
.sh-study-shell:not(.is-study-mode) .sh-live-cue,
.nw-study-shell:not(.is-study-mode) .sh-live-cue {
  margin-bottom: 7px; padding: 7px 9px 8px 11px; }
.sh-study-shell:not(.is-study-mode) .sh-live-sentence,
.nw-study-shell:not(.is-study-mode) .sh-live-sentence { margin: 3px 0 6px; }
.sh-study-shell:not(.is-study-mode) .sh-live-detail,
.nw-study-shell:not(.is-study-mode) .sh-live-detail { margin-top: 5px; padding-top: 5px; }
.sh-study-shell:not(.is-study-mode) .sh-live-vocab-actions,
.nw-study-shell:not(.is-study-mode) .sh-live-vocab-actions { margin-top: 6px; }

/* YouTube requires embedded players to remain at least 200×200 CSS pixels. On
   narrow cards, trade the exact 16:9 frame for a little black letterboxing. */
@media (max-width: 720px) {
  .nw-stage, .sh-stage { min-height: 200px; aspect-ratio: auto; }
}

/* Portrait study mode stacks video above the guide. Landscape phones retain the
   two-column layout, keeping the guide useful without shrinking the video below
   YouTube's supported viewport. */
@media (orientation: portrait) {
  .nw-study-shell.is-study-mode { grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "media" "guide"; grid-template-rows: auto minmax(0, 1fr); }
  .sh-study-shell.is-study-mode .sh-grid { grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr); }
  .study-shell.is-study-mode .nw-media,
  .study-shell.is-study-mode .sh-player { display: block; }
  .study-shell.is-study-mode .nw-stage,
  .study-shell.is-study-mode .sh-stage { min-height: 200px; max-height: min(38dvh, 360px); }
}

@media (prefers-reduced-motion: reduce) {
  .study-shell.is-study-mode .sh-live-stream { scroll-behavior: auto; }
}

/* Secondary video chooser. It lives in the card header as card CHROME, not under the
   video title where a gold link out-shouted the title it was captioning, and its panel
   drops full-width beneath the header rather than stretching the video half. */
.sh-pick { flex: none; margin-left: auto; }
.sh-pick-toggle { appearance: none; padding: 4px 9px; border: 1px solid var(--border-2);
  border-radius: 8px; background: transparent; color: var(--muted); font: inherit;
  font-size: 11px; font-weight: 600; white-space: nowrap; cursor: pointer; }
.sh-pick-toggle:hover { border-color: var(--gold); color: var(--text);
  background: color-mix(in srgb, var(--gold) 10%, transparent); }
.sh-pick-panel { display: flex; flex-direction: column; gap: 7px; margin: -2px 0 13px;
  padding: 11px; border: 1px solid var(--border); border-radius: 10px;
  background: color-mix(in srgb, var(--card-2) 55%, transparent); }
.sh-pick-panel[hidden] { display: none; }
.sh-pick-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.sh-pick-or { font-size: 12px; color: var(--faint); }
.sh-pick-row input[type=text] { flex: 1 1 200px; min-width: 160px; }
.sh-pick-status { font-size: 12px; color: var(--muted); }
.sh-pick-status:empty { display: none; }
.sh-pick-status.ok { color: var(--ok-text); }
.sh-pick-status.error { color: var(--warn-text); }
.sh-pick-status a { color: var(--accent); }

.companion { margin-top: 16px; border-top: 1px solid var(--border); padding-top: 14px; }
/* Inside the Start-Here card the full guide is an inset well, not a page band: it
   hangs off the drawer handle above it and sits visibly WITHIN the gold surface. */
.sh-card > .companion { margin-top: 0; padding: 14px;
  border: 1px solid color-mix(in srgb, var(--gold) 22%, var(--border));
  border-top: 0; border-radius: 0 0 11px 11px;
  background: color-mix(in srgb, var(--card-2) 78%, transparent); }
.comp-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 18px; }
.comp-col h4 { margin: 0 0 2px; font-size: 14px; color: var(--gold); }
.comp-note { margin: 0 0 8px; font-size: 12px; color: var(--faint); }
.comp-empty { font-size: 13px; color: var(--muted); }
.comp-list { display: flex; flex-direction: column; gap: 8px; }
.comp-col:not(.show-all) .comp-item.extra { display: none; }
.comp-item { display: flex; flex-direction: column; gap: 1px; font-size: 13px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 60%, transparent); padding-bottom: 6px; }
.cv-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.cv-word { font-size: 15px; color: var(--text); }
.cv-word rt, .cc-text rt, .ent-name rt { color: var(--ruby);
  font-size: var(--ruby-reading-size); font-weight: var(--ruby-weight); }
.cv-word.is-known { opacity: .55; }
.cv-word .chk { color: var(--teal); font-size: 12px; }
/* Gloss truncated to one line with an ellipsis (like td.mean on the channel table),
   so hidden senses show as a trailing "…". min-width:0 lets the flex item shrink so
   the ellipsis actually engages. */
.cv-mean { color: var(--muted); font-size: 12px; flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* A vocab card the ellipsis is actually cutting is a whole-card tap target (handled in
   library.js) — pointer cursor + a hover tint mirror the keyness table's row hover.
   Cards whose gloss fits get neither, so the cursor stops promising a reveal that
   isn't there. */
.comp-item:has(.is-gloss-toggle) { cursor: pointer; }
.comp-item:has(.is-gloss-toggle):hover {
  background: color-mix(in srgb, var(--card-2) 55%, transparent); }
/* Expanded panel: the full numbered senses, wrapped (mirrors .wd-mean). */
.cv-detail { color: var(--text); font-size: 12px; line-height: 1.5; margin-top: 4px;
  white-space: normal; }
.cv-aside { display: flex; align-items: baseline; gap: 6px; flex: none; }
.cv-freq { color: var(--faint); font-size: 12px; font-variant-numeric: tabular-nums;
  white-space: nowrap; }
.cv-dot { color: var(--faint); font-size: 12px; }
/* Line 2 of a vocab card: meaning on the left, the know-it / save actions demoted
   to the right so they don't crowd the word on line 1 (Option A layout). */
.cv-foot { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-top: 2px; }
.cv-acts { display: flex; align-items: baseline; gap: 6px; flex: none; }
/* "✓ know it" — mark-as-known on a companion vocab card. Muted until hovered so it
   doesn't compete with the word itself. */
.cv-known { appearance: none; cursor: pointer; font: inherit; font-size: 11px;
  white-space: nowrap; color: var(--faint); background: transparent;
  border: 1px solid var(--border-2); border-radius: 999px; padding: 2px 8px;
  transition: color .12s, border-color .12s; }
.cv-known:hover { color: var(--teal); border-color: var(--teal); }
.cg-pat { font-weight: 600; color: var(--text); }
.cg-gloss { color: var(--muted); font-size: 12px; }
/* JLPT level chip on a grammar pattern — quiet, sits with the ×N / ▶ in .cv-aside */
.cg-lv { font-size: 10px; font-weight: 700; color: var(--faint);
  border: 1px solid var(--border-2); border-radius: 999px; padding: 0 5px;
  vertical-align: middle; }
.cc-text { color: var(--text); font-size: 14px; }
.cc-mean { color: var(--muted); font-size: 12px; }
/* ▶ seek link on a word / grammar pattern → jumps the embedded player */
a.ts { color: var(--accent); font-weight: 600; font-size: 12px; white-space: nowrap;
  text-decoration: none; flex: none; }
a.ts:hover { text-decoration: underline; }
.see-all { margin-top: 8px; background: transparent; color: var(--accent); border: 1px solid var(--border);
  font-size: 12px; padding: 6px 10px; font-weight: 600; }
.see-all:hover { background: var(--card-2); }

/* The coverage bar, its label and the channel description read as one "what is this
   channel" block, so they sit closer than two separate sections would. */
.coverage { margin: 12px 0 4px; }
.cov-bar { height: 8px; border-radius: 5px; background: var(--card-2);
  border: 1px solid var(--border-2); overflow: hidden; }
.cov-fill { height: 100%; background: linear-gradient(90deg, var(--teal), var(--gold));
  border-radius: 5px; transition: width .4s ease; }
.cov-label { display: block; margin-top: 7px; font-size: 13px; color: var(--muted); }
.cov-label b { color: var(--gold); font-variant-numeric: tabular-nums; }
.cov-none { display: block; margin-top: 4px; font-size: 13px; color: var(--faint); }
.cov-none a, .cov-label a { color: var(--gold); }
/* Ambient progress delta ("↑ 6 pts since May 3") — derived from the local
   progress.js snapshots; same quiet-pill voice as .comp-pill. */
.cov-delta { display: inline-block; font-size: 11px; font-weight: 600;
  padding: 0 7px; border-radius: 999px; vertical-align: middle; white-space: nowrap;
  background: rgba(79,118,107,.14); color: var(--teal); cursor: help; }

/* difficulty axes — the multi-dimensional breakdown (Vocabulary, Speed, …). */
.axes { margin: 6px 0 4px; max-width: 560px; }
/* Fixed columns (label · bar · band word) so every row lines up identically
   regardless of the band word's length — bars are all the same width and the
   words align in a column across all channels. */
.axis { display: grid; grid-template-columns: 92px 1fr 90px;
  align-items: center; gap: 6px 12px; margin: 9px 0; }
.axis-label { font-size: 11px; letter-spacing: .05em; text-transform: uppercase;
  color: var(--muted); white-space: nowrap; }
.axis-bar { height: 8px; border-radius: 5px; background: var(--card-2);
  border: 1px solid var(--border-2); overflow: hidden; }
.axis-fill { min-width: 6px; height: 100%; border-radius: 5px; transition: width .4s ease; }
.axis-fill.beg { background: var(--teal); }
.axis-fill.int { background: var(--gold); }
.axis-fill.adv { background: var(--accent); }
.axis-band { font-size: 12px; font-weight: 600; justify-self: start;
  white-space: nowrap; font-variant-numeric: tabular-nums; }
.axis-band.beg { color: var(--teal-hi); }
.axis-band.int { color: var(--gold); }
.axis-band.adv { color: var(--accent-hi); }
.axis-note { grid-column: 2 / -1; font-size: 12px; color: var(--faint); margin-top: -2px; }
.axis.facet .facet-v { font-size: 13px; font-weight: 600; color: var(--text);
  justify-self: start; white-space: nowrap; }
.axis.facet .facet-v.formal { color: var(--gold); }
.axis.facet .facet-v.casual { color: var(--teal-hi); }
.axis.facet .facet-v.mixed { color: var(--muted); }

/* Difficulty details and qualitative context share the row on wide screens. */
.difficulty-grid { display: grid; grid-template-columns: minmax(0, 560px) minmax(260px, 1fr);
  gap: 22px; align-items: start; }
.difficulty-grid .axes { width: 100%; max-width: none; margin-top: 6px; }
/* Deliberately NOT gold. This is the qualitative half of "How hard is it?", so it
   should read as the difficulty section's second column — a quiet neutral panel
   beside the meters. Gold is the page's "do this next" signal and belongs to
   Start Here; wearing it here made a supporting note compete with the hero. */
.good-to-know { margin-top: 6px; padding: 12px 14px; border-radius: 10px;
  border: 1px solid var(--border); background: var(--card-2); }
.good-title { margin: 0 0 6px; color: var(--text); font-size: 14px; font-weight: 600; }
.good-to-know > p { margin: 0; color: var(--text); font-size: 13px; line-height: 1.5; }
.good-entities { margin-top: 11px; padding-top: 9px; border-top: 1px solid var(--border); }
.good-entities-label { display: block; margin-bottom: 4px; color: var(--faint);
  font-size: 10px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; }
.good-entities .entities { grid-template-columns: 1fr; }
.good-entities .entities li:last-child { border-bottom: 0; }
@media (max-width: 800px) {
  .difficulty-grid { grid-template-columns: 1fr; gap: 10px; }
  .good-to-know { margin-top: 0; }
}

/* compact meters on the browse card — same fixed-column idea, tighter sizes */
.axes-mini { margin: 8px 0; width: 340px; max-width: 100%; }
.axes-mini .axis { grid-template-columns: 48px 1fr 74px; gap: 4px 8px; margin: 4px 0; }
.axes-mini .axis-label { font-size: 10px; }
.axes-mini .axis-bar { height: 6px; }
.axes-mini .axis-band { font-size: 11px; }

.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 10px; margin: 18px 0 4px; }
.tile { background: var(--card-2); border: 1px solid var(--border-2);
  border-radius: 10px; padding: 12px 14px; }
.tile-v { display: block; font-family: var(--brand-font); font-weight: 700;
  font-size: 20px; color: var(--text); font-variant-numeric: tabular-nums; }
.tile-l { display: block; margin-top: 3px; font-size: 11px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--faint); }

.section-h { margin: 26px 0 4px; font-size: 16px; color: var(--text); font-weight: 600; }
.section-note { margin: 0 0 14px; font-size: 13px; color: var(--muted); max-width: 620px; }
table.vocab { width: 100%; border-collapse: collapse; font-size: 14px; }
table.vocab th { text-align: left; font-size: 11px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--faint); font-weight: 600;
  border-bottom: 1px solid var(--border); padding: 6px 10px; }
table.vocab td { padding: 7px 10px; border-bottom: 1px solid var(--border-2); }
table.vocab td.num { text-align: right; font-variant-numeric: tabular-nums; color: var(--muted); }
table.vocab td.jp { font-size: 16px; color: var(--text); }
table.vocab td.jp rt { color: var(--ruby); font-size: var(--ruby-reading-size);
  font-weight: var(--ruby-weight); }
table.vocab td.mean { color: var(--muted); max-width: 380px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
table.vocab tbody tr:hover { background: var(--card-2); }

/* ---- key-word section: header row, click-to-expand rows, clip timestamps ---- */
.section-head-row { display: flex; align-items: center; justify-content: space-between;
  gap: 6px 16px; flex-wrap: wrap; margin-top: 26px; }
.section-head-row .section-h { margin: 0; }
/* The band badge is the one-word ANSWER to "How hard is it?", so it sits with the
   question instead of at the far edge of the row — the meters underneath are the
   detail you read after it. The row's default space-between still applies where
   the trailing item is an action (the deck CTA), not an answer. */
.difficulty-head { justify-content: flex-start; gap: 6px 11px; }
/* "Build a deck of the useful words" — a <button> now (builds the .apkg inline),
   styled to match the CTA anchors elsewhere. */
.section-head-row .cta { display: inline-block; padding: 9px 15px; border-radius: 7px;
  background: var(--teal); color: #fff; font-weight: 600; font-size: 13px;
  text-decoration: none; border: 0; cursor: pointer; font-family: inherit; }
.section-head-row .cta:hover { background: var(--teal-hi); }
.section-head-row .cta:disabled { opacity: .6; cursor: default; }
/* Progress line under the key-word heading while a deck builds. */
.deck-status { font-size: 13px; color: var(--muted); min-height: 1em; margin: 2px 0 6px; }
.deck-status.ok { color: var(--ok-text); }
.deck-status.error { color: var(--warn-text); }

/* The Examples column holds each key word's clip count, filled from the server's
   prebuilt clip index (no tokenizer, no button). */
th.clip-col { text-align: right; }
.clip-cell { text-align: right; white-space: nowrap; }
.clip-count { color: var(--accent); font-weight: 600; font-size: 13px; }
.clip-none { color: var(--faint); }
.vocab-loading td { color: var(--muted); padding: 14px 10px; }

/* Every key-word row expands on click (full meaning + where it's heard). */
table.vocab tr[data-clip] { cursor: pointer; }
table.vocab tr[data-clip].expanded { background: var(--card-2); }
tr.word-detail > td { background: var(--card-2); padding: 9px 12px 13px; }
.wd-mean { color: var(--text); font-size: 14px; line-height: 1.5; }
.wd-mean.wd-muted { color: var(--muted); }
.wd-clips { margin-top: 11px; }
.wd-label { font-size: 11px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--faint); font-weight: 600; margin-bottom: 5px; }
.clip-occ { display: flex; gap: 10px; align-items: baseline; padding: 5px 0;
  border-bottom: 1px solid var(--border-2); font-size: 13px; flex-wrap: wrap; }
.clip-occ:last-child { border-bottom: none; }
.clip-time { flex: 0 0 auto; font-variant-numeric: tabular-nums; font-weight: 600;
  color: var(--accent); text-decoration: none; }
.clip-time:hover { color: var(--accent-hi); text-decoration: underline; }
.clip-line { flex: 1 1 260px; color: var(--text); font-size: 15px; }
.clip-line mark { background: rgba(224, 168, 96, .3); color: inherit;
  border-radius: 3px; padding: 0 2px; }
.clip-src { flex: 0 0 auto; color: var(--faint); font-size: 11px; }
/* Inline per-row actions in the key-word table: mark known / save to review.
   The cell itself may wrap (buttons stack on narrow screens); each button stays
   on one line so its label never breaks mid-word. */
.vocab th.act-col, .vocab td.act-cell { text-align: right; }
.row-known, .row-save { appearance: none; cursor: pointer; font: inherit; font-size: 12px;
  color: var(--muted); background: transparent; border: 1px solid var(--border-2);
  border-radius: 999px; padding: 3px 10px; margin: 2px 0 2px 6px; white-space: nowrap;
  transition: color .12s, border-color .12s, background .12s; }
.row-known:hover { color: var(--teal); border-color: var(--teal); }
.row-save:hover { color: var(--gold); border-color: var(--gold); }
.row-save.is-saved { color: var(--gold); border-color: var(--gold);
  background: color-mix(in srgb, var(--gold) 14%, transparent); }
/* Save toggle on a compact companion vocab card (icon-only). */
.cv-save { appearance: none; cursor: pointer; font: inherit; font-size: 12px; line-height: 1;
  color: var(--faint); background: transparent; border: 1px solid var(--border-2);
  border-radius: 999px; padding: 2px 7px; white-space: nowrap;
  transition: color .12s, border-color .12s; }
.cv-save:hover, .cv-save.is-saved { color: var(--gold); border-color: var(--gold); }
/* "You moved up a band" toast, flashed when a mark tips the level into a new JLPT band. */
.levelup-toast { position: fixed; left: 50%; bottom: 24px; transform: translate(-50%, 16px);
  z-index: 60; max-width: min(92vw, 420px); padding: 12px 18px; border-radius: 12px;
  background: var(--card-2); color: var(--text); border: 1px solid var(--teal);
  box-shadow: 0 8px 28px rgba(0, 0, 0, .28); font-size: 14px; text-align: center;
  opacity: 0; pointer-events: none; transition: opacity .3s, transform .3s; }
.levelup-toast.show { opacity: 1; transform: translate(-50%, 0); }
.levelup-toast b { color: var(--teal); }

/* ---- recent episodes: per-video comprehension breakdown ------------------- */
.episode-list { display: flex; flex-direction: column; gap: 2px; margin-bottom: 8px; }
.episode-loading { color: var(--muted); font-size: 13px; padding: 10px 6px; }
.episode-row { display: flex; align-items: center; gap: 12px; padding: 8px 6px;
  border-radius: 8px; text-decoration: none; color: inherit; }
.episode-row:hover { background: var(--card-2); }
.ep-thumb { width: 96px; height: 54px; object-fit: cover; border-radius: 6px;
  background: var(--card-2); flex: 0 0 auto; }
.ep-info { flex: 1 1 220px; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ep-title { font-size: 14px; color: var(--text); white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; }
.ep-date { font-size: 12px; color: var(--faint); }
.ep-comp { flex: 0 0 160px; }
.ep-comp .cov-bar.small { max-width: 140px; }
.ep-pct { display: block; margin-top: 4px; font-size: 12px; color: var(--muted);
  white-space: nowrap; }
.ep-pct b { color: var(--gold); font-variant-numeric: tabular-nums; }
.ep-none { font-size: 12px; color: var(--faint); white-space: nowrap; }

@media (max-width: 560px) {
  .detail-head { flex-direction: column; }
  table.vocab { table-layout: fixed; font-size: 13px; }
  table.vocab th, table.vocab td { padding-left: 5px; padding-right: 5px; }
  table.vocab th:nth-child(1), table.vocab td:nth-child(1) { width: 24px; }
  table.vocab th:nth-child(2), table.vocab td:nth-child(2) { width: 27%; }
  table.vocab th.act-col, table.vocab td.act-cell { width: 34px; }
  table.vocab td.jp { font-size: 14px; overflow-wrap: anywhere; }
  table.vocab td.mean { max-width: none; }
  .row-known, .row-save { display: block; width: 30px; padding: 3px 0;
    margin: 2px 0 2px auto; overflow: hidden; font-size: 0; }
  .row-known::before { content: "✓"; font-size: 14px; }
  .row-save::before { content: "🔖"; font-size: 13px; }
  .detail-thumb { width: 100%; height: auto; aspect-ratio: 16 / 9; }
  .episode-row { flex-wrap: wrap; }
  .ep-thumb { width: 84px; height: 47px; }
}

/* ---- thumbnails (hotlinked from YouTube's CDN, linked back to the channel) ---- */
.chan-thumb { flex: 0 0 auto; display: block; width: 128px; height: 72px;
  border-radius: 8px; overflow: hidden; background: var(--card-2); }
.chan-thumb img, .detail-thumb img { width: 100%; height: 100%;
  object-fit: cover; display: block; }
.detail-thumb { flex: 0 0 auto; display: block; width: 160px; height: 90px;
  border-radius: 10px; overflow: hidden; background: var(--card-2); }
.detail-id { flex: 1 1 auto; min-width: 0; }
a.chan-handle { text-decoration: none; }
a.chan-handle:hover { color: var(--muted); text-decoration: underline; }
.chip.genre { color: var(--accent-hi); border-color: var(--accent-lo);
  background: rgba(192, 83, 43, .12); }
/* Non-standard regional variety (e.g. Kansai) — a distinct teal so it reads as a
   different kind of facet from the orange genre chip. */
.chip.dialect { color: var(--teal-hi); border-color: rgba(79, 118, 107, .4);
  background: color-mix(in srgb, var(--teal-hi) 12%, transparent); }
/* Defunct channel (creator removed every video — see library.js channelCard).
   Also rendered inside the detail page's <h2> title, so it resets the heading's
   weight and centers on the taller line. */
.chip.defunct { color: var(--muted); border-style: dashed;
  font-weight: 500; vertical-align: middle; }
@media (max-width: 560px) {
  .chan-thumb { width: 100%; height: auto; aspect-ratio: 16 / 9; }
}
/* Broken thumbnail: the sample video was deleted/privatised on YouTube, so its
   hotlinked image 404s. thumbHtml's onerror tags the <a> with .thumb-broken —
   rather than hide the card image and leave a gap, show a muted play-glyph in the
   same box. Self-heals on the next poll (poll_episodes repoints sample_video_id
   to a live video). Must come after the `.*-thumb img` rules so it wins on order. */
.thumb-broken { position: relative; background: var(--card-2); }
.thumb-broken img { display: none; }
.thumb-broken::after {
  content: ""; position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  border: solid transparent; border-width: 8px 0 8px 13px;
  border-left-color: var(--muted); opacity: .4;
}

/* ---- FIND → MINE → REFINE → MASTER strip ---- */
.steps {
  display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 20px;
  list-style: none; padding: 0;
}
.steps li {
  flex: 1 1 150px; background: var(--card); border: 1px solid var(--border);
  border-radius: 10px; padding: 10px 12px;
}
.steps .k {
  font-family: var(--brand-font); font-weight: 700; font-size: 12px;
  letter-spacing: .08em; text-transform: uppercase; color: var(--accent);
}
.steps .k .n { color: var(--faint); margin-right: 7px; }
.steps .d { font-size: 12px; color: var(--muted); margin-top: 3px; }

/* ---- cards / controls ---- */
.card { background: var(--card); border: 1px solid var(--border); border-radius: 14px;
  padding: 14px 16px; margin-bottom: 14px; box-shadow: var(--shadow); }
.controls, .thresholds, .known, .build { display: flex; flex-wrap: wrap; gap: 12px; align-items: end; }
label { display: flex; flex-direction: column; font-size: 13px; color: var(--muted); gap: 4px; }
input, select { padding: 8px 10px; border-radius: 7px; border: 1px solid var(--border);
  background: var(--card-2); color: var(--text); font-size: 14px; }
input:focus, select:focus { outline: none; border-color: var(--accent); }
input[type=text] { min-width: 180px; }
input[type=number] { width: 90px; }
button { padding: 9px 16px; border: 0; border-radius: 7px; cursor: pointer;
  background: var(--accent); color: #fff; font-size: 14px; font-weight: 600; align-self: end; }
button:hover { background: var(--accent-hi); }
button:active { background: var(--accent-lo); }
button:disabled { background: var(--btn-off-bg); color: var(--btn-off-text); cursor: default; }
button.secondary { background: var(--btn-2); color: var(--text); }
button.secondary:hover { background: var(--btn-2-hi); }
/* declared after .secondary so disabled wins the equal-specificity tie —
   without this a disabled secondary button keeps its active look (seen on
   the ?demo account card's Sign out) */
button.secondary:disabled { background: var(--btn-off-bg); color: var(--btn-off-text); }
#buildBtn { background: var(--teal); }
#buildBtn:hover { background: var(--teal-hi); }
label.check { flex-direction: row; align-items: center; gap: 6px; color: var(--text); }
label.check input { width: auto; }
.note { font-size: 12px; color: var(--faint); align-self: center; max-width: 420px; }
.note code, code { background: var(--card-2); padding: 1px 5px; border-radius: 4px; }

/* ---- extension gate ---- */
.ext-gate { border-radius: 12px; padding: 12px 16px; margin-bottom: 14px;
  border: 1px solid var(--border); font-size: 14px; }
.ext-gate.ok { background: var(--ok-bg); border-color: var(--ok-border); color: var(--ok-text); }
.ext-gate.warn { background: var(--warn-bg); border-color: var(--warn-border); color: var(--warn-text); }
.ext-gate .dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  background: var(--teal-hi); margin-right: 7px; vertical-align: middle; }
.ext-gate-head strong { font-size: 15px; color: var(--gold); }
.ext-gate p { margin: 6px 0 10px; color: inherit; }
.ext-gate .muted { color: var(--muted); }
.ext-gate code { background: var(--card-2); padding: 1px 5px; border-radius: 4px; }
.ext-gate-actions { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.ext-gate .cta { display: inline-block; padding: 9px 16px; border-radius: 7px;
  background: var(--accent); color: #fff; font-weight: 600; text-decoration: none; }
.ext-gate .cta:hover { background: var(--accent-hi); }

/* ---- status / results ---- */
.status { font-size: 14px; min-height: 22px; margin-bottom: 10px; }
.status.ok { color: var(--teal-hi); }
.status.error { color: #c34524; }
.count { color: var(--muted); font-size: 13px; margin: 0 0 8px; }
/* "Building a deck of the N useful words from <channel>" scope banner + its
   "use all channel words instead" escape hatch (deck handoff from the channel page). */
.deck-scope { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px;
  margin: 4px 0 14px; padding: 10px 14px; border-radius: 10px; font-size: 14px;
  border: 1px solid color-mix(in srgb, var(--teal) 40%, var(--border));
  background: color-mix(in srgb, var(--teal) 10%, transparent); color: var(--text); }
.linklike { background: none; border: 0; padding: 0; font: inherit; cursor: pointer;
  color: var(--accent); text-decoration: underline; }
.linklike:hover { color: var(--accent-hi); }
table { width: 100%; border-collapse: collapse; font-size: 15px; }
th, td { text-align: left; padding: 6px 10px; border-bottom: 1px solid var(--border-2); }
th { color: var(--muted); font-size: 12px; text-transform: uppercase; letter-spacing: .04em; }
td.jp { font-size: 21px; }
td.jp ruby rt { font-size: var(--ruby-large-size); color: var(--ruby);
  font-weight: var(--ruby-weight); }
td.pos { color: var(--muted); font-size: 12px; }
td.num { text-align: right; color: var(--text); font-variant-numeric: tabular-nums; }
td.key { color: var(--gold); }
td.mean { color: var(--muted); font-size: 14px; max-width: 360px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
tbody tr:hover { background: var(--card-2); }

/* ---- footer ---- */
.site-footer { margin-top: 28px; padding-top: 14px; border-top: 1px solid var(--border-2);
  font-size: 13px; color: var(--faint); }
.site-footer a { color: var(--gold); text-decoration: none; }
.site-footer a:hover { text-decoration: underline; }

/* "You" page CTA (formerly grouped with the removed onboarding banner's) */
.me-cta { display: inline-block; padding: 9px 16px; border-radius: 8px;
  background: var(--accent); color: #fff; font-weight: 600; font-size: 14px;
  white-space: nowrap; text-decoration: none;
  /* button-safe: the class is used on both <a> and <button> */
  appearance: none; border: 0; cursor: pointer; font-family: inherit; }
.me-cta:hover { background: var(--accent-hi); }

/* ---- personalize page ----------------------------------------------------- */
.pz-hero { margin: 8px 0 22px; }
.pz-hero-h { font-size: 26px; margin: 0 0 6px; color: var(--text); line-height: 1.2; }
.pz-hero-sub { color: var(--muted); margin: 0 0 8px; max-width: 46ch; }

/* Steps stack vertically: the vocabulary step gets the full width, and interests
   sit BELOW it so step 2 never competes with the primary choice. */
.pz-grid { display: grid; grid-template-columns: 1fr; gap: 18px; align-items: start; }
.pz-step { padding: 20px 22px; }
.pz-step-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 4px; }
.pz-step-head h3 { font-size: 17px; margin: 0; color: var(--text); flex: 1; min-width: 0; }
.pz-num { display: inline-grid; place-items: center; width: 26px; height: 26px;
  border-radius: 50%; background: var(--accent); color: #fff; font-weight: 700; font-size: 14px; }
.pz-tag { font-size: 11px; font-weight: 700; padding: 2px 9px; border-radius: 999px;
  background: var(--card-2); color: var(--muted); }
.pz-hint { color: var(--muted); font-size: 13px; margin: 2px 0 12px; }
/* The "Current setting: …" readout — what this device is already personalized as */
.pz-current { color: var(--teal); font-size: 13px; font-weight: 600; margin: -4px 0 12px; }

/* Vocabulary METHOD picker: three stacked selectable cards; picking one expands
   only its panel (see personalize.js selectMethod), so no two interfaces show
   at once. A group = the card button + its collapsed control panel. */
.pz-methods { display: flex; flex-direction: column; gap: 10px; margin-top: 6px; }
.pz-method-group { border: 1.5px solid var(--border); border-radius: 12px;
  background: var(--card); overflow: hidden; transition: border-color .12s, box-shadow .12s; }
.pz-method-group:hover { border-color: var(--border-2); }
.pz-method-group.on { border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold) inset; }
.pz-method { display: grid; grid-template-columns: 1fr auto; gap: 3px 12px;
  width: 100%; text-align: left; background: transparent; border: 0; border-radius: 0;
  padding: 14px 16px; cursor: pointer; color: var(--text); font-family: inherit; }
.pz-method-group.on .pz-method { background: rgba(169,118,31,.06); }
.pz-method-title { grid-column: 1; grid-row: 1; font-weight: 700; font-size: 15px; color: var(--text); }
.pz-method-desc { grid-column: 1; grid-row: 2; color: var(--muted); font-size: 12.5px; line-height: 1.35; }
.pz-method-badge { grid-column: 2; grid-row: 1 / 3; align-self: center; white-space: nowrap;
  font-size: 10.5px; font-weight: 800; letter-spacing: .04em; padding: 3px 9px; border-radius: 999px;
  background: rgba(169,118,31,.16); color: var(--gold); }
.pz-method-badge.alt { background: var(--card-2); color: var(--muted); }
.pz-method-panel { padding: 4px 16px 16px; border-top: 1px dashed var(--border); }

.pz-upload { display: flex; align-items: center; gap: 14px; padding: 14px 16px;
  border: 1px dashed var(--border-2); border-radius: 12px; background: var(--card-2); }
/* Active-path highlight: mirrors .lvl-chip.on, so whichever door is in effect
   (saved decks OR a level estimate) is the one glowing */
.pz-upload.on { border: 1.5px solid var(--gold); background: rgba(169,118,31,.12);
  box-shadow: 0 0 0 1px var(--gold) inset; }
.pz-upload-main { flex: 1; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pz-upload-main b { color: var(--text); }
.pz-upload-main span { color: var(--muted); font-size: 12.5px; }
.pz-support { color: var(--muted); font-size: 12px; margin: 8px 0 0; }
.pz-status { color: var(--teal); font-size: 13px; min-height: 18px; margin: 6px 0 0; font-weight: 600; }
.pz-status.error { color: var(--accent-hi); }
.pz-anki-meta { margin: 10px 0 0; padding: 9px 12px; border: 1px solid var(--border);
  border-radius: 9px; background: var(--card-2); color: var(--muted); font-size: 12.5px; }
.pz-anki-meta b { color: var(--text); }
.pz-anki-disconnect { margin-top: 2px; color: var(--muted); font-size: 12px; }

/* Uploaded-files panel: one row per file + tap-to-correct column picker */
.pz-files { display: flex; flex-direction: column; gap: 6px; margin: 10px 0 0; }
.pz-file { border: 1px solid var(--border); border-radius: 10px; background: var(--card-2);
  padding: 8px 12px; font-size: 13px; }
.pz-file-line { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.pz-file-name { color: var(--text); font-weight: 600; overflow-wrap: anywhere; }
.pz-file-meta { color: var(--muted); flex: 1; min-width: 140px; }
.pz-file-sample { font-size: 12px; }
.pz-file-warn { color: var(--accent-hi); }
.pz-file-actions { display: flex; gap: 12px; white-space: nowrap; align-items: center; }
.pz-file-actions .linklike { font-size: 12px; color: var(--teal); }
.pz-colpick { margin-top: 8px; border-top: 1px dashed var(--border); padding-top: 8px; }
.pz-colpick p { margin: 0 0 6px; font-size: 12px; color: var(--muted); }
.pz-colpick-scroll { overflow-x: auto; }
.pz-colpick table { border-collapse: collapse; font-size: 12px; }
.pz-colpick th, .pz-colpick td { border: 1px solid var(--border); padding: 4px 8px;
  cursor: pointer; white-space: nowrap; color: var(--muted); }
.pz-colpick th { color: var(--teal); font-weight: 600; font-size: 11px; }
.pz-colpick th.on, .pz-colpick td.on { border-color: var(--teal); color: var(--text);
  background: var(--card); }

/* "Where do I find this file?" exporter walkthrough (collapsed by default) */
.pz-howto { margin: 8px 0 0; font-size: 13px; color: var(--muted); }
.pz-howto summary { cursor: pointer; color: var(--teal); font-weight: 600; font-size: 12.5px; }
.pz-howto summary:hover { text-decoration: underline; }
.pz-howto[open] { padding: 10px 14px; border: 1px solid var(--border); border-radius: 10px;
  background: var(--card-2); }
.pz-howto ol { margin: 10px 0 0; padding-left: 20px; display: flex; flex-direction: column; gap: 5px; }
.pz-howto b { color: var(--text); }
.pz-howto-note { margin: 8px 0 0; font-size: 12px; }

.lvl-row { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; margin-top: 6px; }
.lvl-chip { display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 12px 4px; background: var(--card); border: 1.5px solid var(--border);
  border-radius: 10px; color: var(--text); }
.lvl-chip:hover { border-color: var(--gold); background: var(--card-2); }
.lvl-chip.on { border-color: var(--gold); background: rgba(169,118,31,.12);
  box-shadow: 0 0 0 1px var(--gold) inset; }
.lvl-code { font-weight: 700; font-size: 15px; }
.lvl-label { font-size: 10px; color: var(--muted); text-align: center; line-height: 1.2; }

.topic-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-top: 4px; }
.topic { display: flex; flex-direction: column; align-items: center; gap: 5px;
  padding: 12px 4px; background: var(--card); border: 1.5px solid var(--border);
  border-radius: 10px; color: var(--text); font-size: 12px; }
.topic:hover { border-color: var(--teal); background: var(--card-2); }
.topic.on { border-color: var(--teal); background: rgba(79,118,107,.14);
  box-shadow: 0 0 0 1px var(--teal) inset; }
.topic-ic { font-size: 18px; }
.topic-hidden { display: none; }
/* "Show all (N)" / "Show less" — a topic cell dressed as a quiet toggle */
.topic-more { justify-content: center; font-weight: 600; color: var(--teal);
  border-style: dashed; background: transparent; cursor: pointer; }
.topic-more:hover { border-color: var(--teal); background: var(--card-2); }
.pz-topics-foot { display: flex; justify-content: space-between; color: var(--muted);
  font-size: 12px; margin: 12px 0 0; }

.pz-actions { display: flex; justify-content: flex-end; align-items: center; gap: 12px; }
/* Autosave status next to Continue — quiet by default, muted while a save runs */
.pz-saved { color: var(--teal); font-size: 12.5px; font-weight: 600; min-height: 16px; }
.pz-saved[data-state="saving"] { color: var(--muted); }
.pz-later { text-align: right; color: var(--muted); font-size: 12px; margin: 8px 0 24px; }

@media (max-width: 760px) {
  .pz-grid { grid-template-columns: 1fr; }
  .topic-grid { grid-template-columns: repeat(3, 1fr); }
}
/* the personalize step-1 "start the check" link, dressed as a button */
.pz-check-go { flex: 0 0 auto; padding: 9px 16px; border-radius: 7px;
  background: var(--accent); color: #fff; font-size: 14px; font-weight: 600;
  text-decoration: none; white-space: nowrap; }
.pz-check-go:hover { background: var(--accent-hi); }

/* ---- the 30-second check (check.html/check.js) ---------------------------- */
/* The narrow card morphs through intro → words → result. On wide screens only,
   a contextual mascot accompanies the intro/result; the quiz itself stays focused. */
.ck-wrap { max-width: 846px; margin: 18px auto 40px; display: grid;
  grid-template-columns: minmax(0, 560px) minmax(0, 260px); gap: 26px; align-items: center; }
.ck-card { display: block; padding: 26px 28px 24px; }
.ck-mascot-shell { min-width: 0; }
.ck-mascot { display: block; width: 100%; height: auto; }
.ck-wrap[data-screen="item"] { max-width: 560px; display: block; }
.ck-wrap[data-screen="item"] .ck-mascot-shell { display: none; }
.ck-eyebrow { font-size: 11px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--accent); margin: 0 0 8px; }
.ck-h { font-family: var(--brand-font); font-size: 24px; line-height: 1.2;
  margin: 0 0 12px; color: var(--text); }
.ck-def { font-size: 17px; font-weight: 700; color: var(--text); line-height: 1.45;
  margin: 0 0 14px; padding: 12px 16px; border-left: 3px solid var(--accent);
  background: var(--card-2); border-radius: 0 10px 10px 0; }
.ck-rules { list-style: none; padding: 0; margin: 0 0 6px; }
.ck-rules li { color: var(--muted); font-size: 13.5px; margin: 0 0 7px; }
.ck-rules li::before { content: "✓ "; color: var(--teal); font-weight: 700; }
.ck-rules b { color: var(--text); }
.ck-caution { color: var(--gold); font-size: 13px; margin: 10px 0 0;
  padding: 10px 12px; border: 1px dashed color-mix(in srgb, var(--gold) 45%, var(--border));
  border-radius: 10px; }
.ck-actions { display: flex; align-items: center; gap: 12px; margin-top: 18px; }
.ck-actions button { align-self: auto; padding: 12px 22px; font-size: 15px; }

/* words screen */
.ck-progress { height: 6px; border-radius: 999px; background: var(--card-2);
  overflow: hidden; }
.ck-bar { height: 100%; background: var(--accent); border-radius: 999px;
  transition: width .15s ease; }
.ck-count { margin: 8px 0 0; font-size: 12px; color: var(--faint);
  font-variant-numeric: tabular-nums;
  display: flex; align-items: center; justify-content: space-between; }
.ck-sound { align-self: auto; padding: 2px 8px; font-size: 15px; line-height: 1;
  background: transparent; border: 1px solid var(--border); border-radius: 999px; }
.ck-sound:hover, .ck-sound:active { background: var(--card-2); }
.ck-word { font-size: 52px; font-weight: 600; line-height: 1.25; color: var(--text);
  text-align: center; margin: 34px 0 8px; overflow-wrap: anywhere; cursor: default; }
.ck-word[data-replay] { cursor: pointer; }
.ck-word rt { font-size: 15px; font-weight: 400; color: var(--muted);
  padding-bottom: 6px; }
.ck-word.long { font-size: 36px; }
.ck-word.long rt { font-size: 13px; }
.ck-meaning-slot { min-height: 28px; margin: 0 0 4px; display: flex;
  align-items: center; justify-content: center; text-align: center; }
.ck-meaning-toggle { align-self: auto; padding: 4px 11px; border: 1px solid var(--border);
  border-radius: 999px; background: transparent; color: var(--muted); font-size: 12.5px;
  font-weight: 600; }
.ck-meaning-toggle:hover, .ck-meaning-toggle:active { color: var(--text); background: var(--card-2); }
.ck-meaning { margin: 0; color: var(--muted); font-size: 13.5px; line-height: 1.35; }
.ck-btns { display: flex; gap: 12px; justify-content: center; }
.ck-btns button { flex: 1 1 0; max-width: 210px; align-self: auto;
  padding: 14px 10px; font-size: 15px; border-radius: 10px; }

/* busy + result screens */
.ck-busy { text-align: center; color: var(--muted); font-size: 14.5px;
  padding: 44px 8px; margin: 0; }
.ck-body { color: var(--muted); font-size: 14.5px; line-height: 1.55; margin: 0; }
.ck-body b { color: var(--gold); }
.ck-note { color: var(--faint); font-size: 12.5px; margin: 14px 0 0; }

@media (max-width: 840px) {
  .ck-wrap { max-width: 560px; display: block; }
  .ck-mascot-shell { display: none; }
}
@media (max-width: 560px) {
  .ck-card { padding: 20px 18px 18px; }
  .ck-word { font-size: 42px; margin: 32px 0 8px; }
  .ck-word.long { font-size: 30px; }
}

/* ---- stats page (immersion tracking; stats.html/stats.js) ---------------- */
a.streak { text-decoration: none; }
.stats-gate h3 { margin: 0 0 6px; }
.stats-gate p { margin: 0; color: var(--muted); }
.stats-tiles-label { margin: 0 0 8px; font-size: 11px; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase; color: var(--muted); }
.stats-tiles { margin-bottom: 24px; }
.stats-emoji { font-size: 16px; }
.stats-note { color: var(--muted); font-size: 12.5px; margin: 8px 0 0; }
.stats-off-note { margin: 0 0 14px; }

/* chart header: title left, "View as table" toggle right */
.stats-chart-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.stats-table-btn { font-size: 13px; color: var(--accent); font-weight: 600; white-space: nowrap; }
.stats-table-btn:hover { color: var(--accent-hi); text-decoration: underline; }

/* daily bars: thin marks, rounded data-end, 2px gaps, recessive baseline.
   Subtle horizontal guide lines (every quarter of the plot area) give scale
   without labelling each bar — clipped to the content box so they sit in the
   bar region, above the top padding. */
.stats-chart {
  display: flex; align-items: stretch; gap: 2px; height: 150px;
  padding: 18px 4px 0; border-bottom: 1px solid var(--border);
  background:
    repeating-linear-gradient(to top,
      color-mix(in srgb, var(--border) 55%, transparent) 0 1px,
      transparent 1px 25%) content-box;
}
.stats-col {
  flex: 1 1 0; min-width: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: flex-end; gap: 0; cursor: default;
}
.stats-bar {
  width: 60%; max-width: 26px; background: var(--accent);
  border-radius: 4px 4px 0 0; transition: filter .1s;
}
.stats-col:hover .stats-bar { filter: brightness(1.12); }
.stats-col.today .stats-bar { background: var(--accent-hi); }
.stats-val { font-size: 11px; color: var(--muted); line-height: 1.6; white-space: nowrap; }
.stats-day { font-size: 11.5px; color: var(--muted); line-height: 1.9; }
.stats-tip {
  position: absolute; transform: translate(-50%, -100%); z-index: 30;
  background: var(--card); border: 1px solid var(--border); border-radius: 8px;
  padding: 4px 9px; font-size: 12px; color: var(--text);
  box-shadow: var(--shadow); pointer-events: none; white-space: nowrap;
}
.stats-table { border-collapse: collapse; margin-top: 10px; width: 100%; font-size: 13.5px; }
.stats-table th { text-align: left; color: var(--muted); font-weight: 600; font-size: 12px;
  padding: 4px 10px 4px 0; border-bottom: 1px solid var(--border); }
.stats-table td { padding: 6px 10px 6px 0; border-bottom: 1px solid var(--border-2, var(--border)); }

/* most-watched channels: avatar+label | track | minutes+share rows, single-hue bars */
.stats-chan-list { display: flex; flex-direction: column; gap: 9px; }
.stats-chan-row { display: grid; grid-template-columns: minmax(150px, 230px) 1fr 118px;
  align-items: center; gap: 10px; }
.stats-chan-name { display: flex; align-items: center; gap: 9px; min-width: 0;
  color: var(--text); text-decoration: none; font-size: 13.5px; }
.stats-chan-nm { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.stats-chan-name:hover .stats-chan-nm { color: var(--accent); }
/* circular video-still avatar; on a load failure the <img> removes itself,
   leaving the span's muted circle (we have no real channel avatars) */
.stats-chan-av { flex: none; width: 28px; height: 28px; border-radius: 50%;
  overflow: hidden; background: var(--card-2); border: 1px solid var(--border); }
.stats-chan-av img { width: 100%; height: 100%; object-fit: cover; display: block; }
.stats-chan-track { background: color-mix(in srgb, var(--accent) 10%, transparent);
  border-radius: 4px; height: 12px; }
.stats-chan-bar { background: var(--accent); border-radius: 4px; height: 100%; }
.stats-chan-mins { color: var(--muted); font-size: 12.5px; text-align: right;
  white-space: nowrap; font-variant-numeric: tabular-nums; }

/* recently watched videos: compact media rows (thumbnail · title · meta · Resume)
   replacing the old dense table — long Japanese titles clamp to two lines and
   never break the layout. */
.stats-vid-list { display: flex; flex-direction: column; gap: 2px; }
.svid { display: grid; grid-template-columns: 112px 1fr auto; align-items: center;
  gap: 13px; padding: 8px 6px; border-radius: 10px; text-decoration: none;
  color: var(--text); }
.svid + .svid { border-top: 1px solid var(--border-2, var(--border)); }
.svid:hover { background: color-mix(in srgb, var(--accent) 7%, transparent); }
.svid-thumb { width: 112px; aspect-ratio: 16 / 9; border-radius: 8px; overflow: hidden;
  background: var(--card-2); border: 1px solid var(--border); }
.svid-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.svid-body { min-width: 0; }
.svid-title { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; font-size: 14px; line-height: 1.35; color: var(--text);
  overflow-wrap: anywhere; }
.svid:hover .svid-title { color: var(--accent); }
.svid-meta { display: block; margin-top: 3px; font-size: 12.5px; color: var(--muted); }
.svid-resume { flex: none; color: var(--accent); font-weight: 600; font-size: 13px;
  white-space: nowrap; }
.svid:hover .svid-resume { color: var(--accent-hi); text-decoration: underline; }

@media (max-width: 560px) {
  .stats-chan-row { grid-template-columns: minmax(120px, 160px) 1fr 96px; }
  .svid { grid-template-columns: 88px 1fr; gap: 11px; }
  .svid-thumb { width: 88px; }
  .svid-resume { grid-column: 2; margin-top: 4px; }   /* stacks under the meta */
}

/* monthly recap card (recap.js) — the one deliberately ornamental block on the
   page: gold-tinted border + wash so it reads as a keepsake, not another table */
.recap-card { border: 1px solid color-mix(in srgb, var(--gold) 34%, var(--border));
  border-radius: 14px; padding: 16px 20px 14px;
  background: linear-gradient(135deg, color-mix(in srgb, var(--gold) 7%, var(--card)), var(--card) 62%); }
.recap-card.has-celebration { display: grid; grid-template-columns: minmax(0, 1fr) 112px;
  align-items: center; gap: 18px; }
.recap-main { min-width: 0; }
.recap-mascot { display: block; width: auto; height: 144px; justify-self: center; }
.recap-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.recap-title { margin: 0; font-size: 17px; color: var(--gold); }
/* three headline figures, spaced apart and slightly larger than the tiles */
.recap-stats { display: flex; flex-wrap: wrap; gap: 8px 34px; margin: 14px 0 4px; }
.recap-stat { font-size: 12.5px; color: var(--muted); white-space: nowrap; }
.recap-stat b { display: block; font-size: 26px; color: var(--text);
  font-variant-numeric: tabular-nums; line-height: 1.2; }
.recap-lines { margin: 12px 0 0; padding: 0 0 0 18px; font-size: 13.5px; color: var(--muted); }
.recap-lines li { margin: 4px 0; }
.recap-lines b { color: var(--text); }
@media (max-width: 560px) {
  .recap-card.has-celebration { display: block; position: relative; padding-right: 20px; }
  .recap-card.has-celebration .recap-head,
  .recap-card.has-celebration .recap-stats { padding-right: 64px; }
  .recap-mascot { position: absolute; top: 12px; right: 10px;
    width: auto; height: 84px; }
}

/* ---- Insights articles (/insights/) — data journalism from the corpus ------- */
.insight { max-width: 720px; margin: 0 auto; padding: 8px 18px 40px; }
.insight-kicker { display: inline-block; margin: 18px 0 2px; font-size: 12px;
  font-weight: 700; color: var(--gold); text-transform: uppercase; letter-spacing: .1em;
  text-decoration: none; }
.insight-kicker:hover { color: var(--accent-hi); }
.insight-h1 { margin: 0 0 10px; font-size: 30px; line-height: 1.2; }
.insight-dek { margin: 0 0 6px; font-size: 16.5px; line-height: 1.5; color: var(--muted); }
.insight-byline { margin: 0 0 22px; font-size: 12.5px; color: var(--faint, var(--muted)); }
.insight-byline b { color: var(--muted); }
.insight-hero { margin: 0 0 26px; }
.insight-hero img { display: block; width: 100%; height: auto; border: 1px solid var(--border);
  border-radius: 12px; background: #111; }
.insight-hero figcaption { margin: 8px 1px 0; color: var(--muted); font-size: 12.5px;
  line-height: 1.5; }
.insight-jumpnav { display: flex; flex-wrap: wrap; align-items: center; gap: 5px 14px;
  margin: -5px 0 22px; padding: 10px 0; border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border); font-size: 12px; }
.insight-jumpnav span { color: var(--faint); font-size: 10.5px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; }
.insight-jumpnav a { color: var(--muted); text-decoration: none; white-space: nowrap; }
.insight-jumpnav a:hover { color: var(--teal-hi); text-decoration: underline;
  text-underline-offset: 3px; }
.insight p { line-height: 1.65; }
.insight p a, .insight-method a { color: var(--teal-hi); text-underline-offset: 2px; }
.insight abbr { text-decoration-color: var(--faint); text-underline-offset: 2px; }
.insight h2 { margin: 30px 0 8px; font-size: 20px; }
.insight h2[id], .insight section[id] { scroll-margin-top: 14px; }
/* key-findings box — the quotable block (featured snippets + LLMs lift this) */
.insight-findings { border: 1px solid color-mix(in srgb, var(--gold) 34%, var(--border));
  border-radius: 14px; padding: 14px 18px 6px; margin: 0 0 22px;
  background: linear-gradient(135deg, color-mix(in srgb, var(--gold) 7%, var(--card)), var(--card) 62%); }
.insight-findings-h { margin: 0 0 6px; font-size: 14px; color: var(--gold);
  text-transform: uppercase; letter-spacing: .06em; }
.insight-findings ul { margin: 0 0 10px; padding-left: 20px; }
.insight-findings li { margin: 7px 0; line-height: 1.55; font-size: 14.5px; }
.insight-figure { margin: 26px 0; }
.insight-figure figcaption { margin-top: 8px; font-size: 12.5px; color: var(--muted); line-height: 1.5; }
.insight-scroll-hint { display: none; }
.insight-chart { width: 100%; height: auto; display: block; }
.insight-chartwrap { max-width: 100%; overflow-x: auto; overflow-y: hidden;
  overscroll-behavior-inline: contain; padding-bottom: 4px; }
.insight-chartwrap:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }
.insight-chart text { font-family: inherit; }
.ic-label { font-size: 12.5px; fill: var(--text); }
.ic-n { fill: var(--faint, var(--muted)); font-size: 11px; }
.ic-tick, .ic-axis { font-size: 11px; fill: var(--muted); }
.ic-med { font-size: 10.5px; fill: var(--muted); font-variant-numeric: tabular-nums; }
.insight-chart-key { display: flex; gap: 18px; align-items: center; margin: 0 0 4px;
  font-size: 12px; color: var(--muted); }
.ick-dot, .ick-band, .ick-tick { display: inline-block; vertical-align: middle; margin-right: 5px; }
.ick-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent);
  box-shadow: 0 0 0 1.4px var(--card); }
.ick-band { width: 22px; height: 10px; border-radius: 5px; background: var(--accent); opacity: .16; }
.ick-tick { width: 2px; height: 14px; border-radius: 1px; background: var(--accent-hi); }
.insight-compare { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px; margin: 14px 0 16px; }
.insight-compare > div { display: flex; flex-direction: column; gap: 2px; padding: 14px 16px;
  border: 1px solid var(--border); border-radius: 12px; background: var(--card); }
.insight-compare span { color: var(--muted); font-size: 12px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .04em; }
.insight-compare b { color: var(--gold); font-size: 25px; line-height: 1.25;
  font-variant-numeric: tabular-nums; }
.insight-compare small { color: var(--faint); font-size: 12px; }
.insight-compare-three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.insight-benchmarks { display: grid; gap: 10px; margin: 14px 0 8px; padding: 18px;
  border: 1px solid var(--border); border-radius: 14px; background: var(--card); }
.insight-benchmark { display: grid; grid-template-columns: 130px minmax(90px, 1fr) 34px;
  gap: 12px; align-items: center; font-size: 12.5px; }
.insight-benchmark-label { color: var(--muted); }
.insight-benchmark-track { display: block; height: 9px; overflow: hidden;
  border-radius: 999px; background: var(--card-2); }
.insight-benchmark-track i { display: block; height: 100%; border-radius: inherit;
  background: color-mix(in srgb, var(--teal) 58%, var(--border)); }
.insight-benchmark b { text-align: right; color: var(--muted);
  font-variant-numeric: tabular-nums; }
.insight-benchmark.is-focus .insight-benchmark-label,
.insight-benchmark.is-focus b { color: var(--gold); font-weight: 700; }
.insight-benchmark.is-focus .insight-benchmark-track i { background: var(--gold); }
.insight-steps { margin: 10px 0 18px; padding-left: 22px; }
.insight-steps li { margin: 10px 0; padding-left: 3px; line-height: 1.6; }
.insight-tablewrap { overflow-x: auto; }
.insight-table { font-size: 13.5px; }
.insight-table th, .insight-table td { vertical-align: top; }
.insight-table a { color: var(--teal-hi); text-underline-offset: 2px; }
.insight-table th:first-child, .insight-table td:first-child { position: sticky; left: 0;
  z-index: 1; background: var(--card); box-shadow: 1px 0 0 var(--border); }
.insight-table thead th:first-child { background: var(--card-2); z-index: 2; }
.insight-table td b { font-variant-numeric: tabular-nums; }
.insight-note { font-size: 12.5px; color: var(--faint, var(--muted)); }
.insight-list-count { margin: 18px 0 10px; color: var(--muted); font-size: 13.5px; }
.insight-keyness { margin: 20px 0 26px; padding: 16px 18px; border: 1px solid
  color-mix(in srgb, var(--teal) 36%, var(--border)); border-radius: 13px;
  background: linear-gradient(135deg, color-mix(in srgb, var(--teal) 6%, var(--card)), var(--card)); }
.insight-keyness h3 { margin: 0 0 4px; font-size: 16px; }
.insight-keyness > p { margin: 0 0 12px; color: var(--muted); font-size: 13px; }
.insight-keyness ol { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 22px; margin: 0; padding-left: 23px; }
.insight-keyness li { padding: 7px 0 8px 3px; border-top: 1px solid var(--border);
  font-size: 12.5px; }
.insight-keyness li > span { display: block; }
.insight-keyness li > span:first-child { display: flex; gap: 7px; align-items: baseline; }
.insight-keyness li > span:first-child small { color: var(--faint); }
.insight-keyness li > small { display: block; margin-top: 2px; color: var(--faint);
  font-size: 10.5px; }
.insight-word-group { margin: 19px 0 26px; }
.insight-word-group h3, .insight-channel-pair h3 { margin: 0 0 8px; font-size: 15px; }
.insight-vocab-table { width: 100%; }
.insight-vocab-table th:nth-child(3), .insight-vocab-table th:nth-child(4),
.insight-vocab-table td:nth-child(3), .insight-vocab-table td:nth-child(4) {
  text-align: right; white-space: nowrap; }
.insight-vocab-table td:first-child { min-width: 110px; }
.insight-vocab-table td:first-child small { display: block; margin-top: 2px;
  color: var(--faint); font-size: 11px; font-weight: 400; }
.insight-expression-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px; margin: 16px 0 20px; }
.insight-expression { min-width: 0; padding: 13px 15px; border: 1px solid var(--border);
  border-radius: 11px; background: var(--card); }
.insight-expression h3 { margin: 0; font-size: 17px; }
.insight-expression p { margin: 3px 0; font-size: 13px; line-height: 1.4; }
.insight-expression .insight-reading { margin-top: 0; color: var(--faint); font-size: 11px; }
.insight-expression small { display: block; margin-top: 7px; color: var(--muted);
  font-size: 10.5px; font-variant-numeric: tabular-nums; }
.insight-channel-pair { display: grid; gap: 28px; margin-top: 16px; }
.insight-channel-pair > section { min-width: 0; }
.insight-rank { display: inline-flex; width: 19px; height: 19px; align-items: center;
  justify-content: center; margin-right: 4px; border: 1px solid var(--border);
  border-radius: 50%; color: var(--faint); font-size: 10px; }
.insight-method { margin-top: 34px; padding-top: 4px; border-top: 1px solid var(--border); }
.insight-method p { font-size: 13.5px; color: var(--muted); }
.insight-method h2 { font-size: 16px; }
.insight-funnel { margin-top: 30px; }
.insight-funnel .cta { display: inline-block; padding: 9px 16px; border-radius: 8px;
  background: var(--teal); color: #fff; font-weight: 600; font-size: 14px; text-decoration: none; }
.insight-funnel .cta:hover { background: var(--teal-hi); }
.insight-actions { display: flex; flex-wrap: wrap; gap: 9px; align-items: center; }
.insight-funnel .cta.secondary { color: var(--teal-hi); background: transparent;
  border: 1px solid color-mix(in srgb, var(--teal) 50%, var(--border)); }
.insight-funnel .cta.secondary:hover { color: var(--text); background: var(--card); }
@media (max-width: 640px) {
  .insight { padding-left: 0; padding-right: 0; }
  .insight-h1 { font-size: 28px; }
  .insight-jumpnav { flex-wrap: nowrap; margin-left: -24px; margin-right: -24px;
    padding-left: 24px; padding-right: 24px; overflow-x: auto;
    overscroll-behavior-inline: contain; scrollbar-width: none; }
  .insight-jumpnav::-webkit-scrollbar { display: none; }
  .insight-findings { padding-left: 15px; padding-right: 15px; }
  .insight-chart { min-width: 680px; }
  .insight-chart-key { flex-wrap: wrap; gap: 4px 14px; }
  .insight-scroll-hint { display: inline; }
  .insight-compare { grid-template-columns: 1fr; }
  .insight-benchmark { grid-template-columns: 105px minmax(70px, 1fr) 30px; gap: 8px; }
  .insight-benchmarks { padding: 14px; }
  .insight-keyness ol { grid-template-columns: 1fr; }
  .insight-expression-grid { grid-template-columns: 1fr; }
  .insight-actions { flex-direction: column; align-items: stretch; }
  .insight-actions .cta { text-align: center; }
}
/* index cards */
.insights-index { max-width: 900px; margin: 0 auto; padding: 22px 18px 48px; }
.insights-index-head { max-width: 720px; margin-bottom: 36px; }
.insights-index-kicker { margin: 0 0 8px; color: var(--gold); font-size: 11px;
  font-weight: 700; letter-spacing: .09em; text-transform: uppercase; }
.insights-index-head h1 { margin: 0 0 10px; font-family: var(--brand-font);
  font-size: clamp(34px, 5vw, 48px); line-height: 1.05; }
.insights-index-head > p:last-child { max-width: 66ch; margin: 0; color: var(--muted);
  font-size: 15.5px; line-height: 1.65; }
.insight-list { margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.insight-list-title { margin: 0 0 2px; color: var(--muted); font-size: 12px;
  font-weight: 700; letter-spacing: .07em; text-transform: uppercase; }
.insight-card { display: block; border: 1px solid var(--border); border-radius: 14px;
  padding: 16px 18px; background: var(--card); text-decoration: none; color: var(--text); }
.insight-card:hover { border-color: color-mix(in srgb, var(--gold) 48%, var(--border));
  box-shadow: var(--shadow); }
.insight-card-featured { display: grid; grid-template-columns: 54px minmax(0, 1fr);
  gap: 22px; padding: 28px 30px 24px;
  background: linear-gradient(135deg, color-mix(in srgb, var(--gold) 6%, var(--card)), var(--card) 56%); }
.insight-card-number { color: color-mix(in srgb, var(--gold) 48%, var(--border));
  font-family: var(--brand-font); font-size: 30px; font-weight: 700; line-height: 1; }
.insight-card-body { display: block; min-width: 0; }
.insight-card-label { display: block; margin-bottom: 5px; color: var(--gold);
  font-size: 11px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; }
.insight-card-title { display: block; max-width: 22ch; margin-bottom: 10px;
  font-family: var(--brand-font); font-size: clamp(23px, 3vw, 31px); font-weight: 700;
  line-height: 1.2; }
.insight-card-summary { display: block; max-width: 65ch; color: var(--muted);
  font-size: 14px; line-height: 1.6; }
.insight-card-stats { display: flex; flex-wrap: wrap; gap: 8px 26px; margin: 22px 0 18px;
  color: var(--muted); font-size: 12.5px; }
.insight-card-stats b { display: block; color: var(--text); font-size: 19px;
  font-variant-numeric: tabular-nums; line-height: 1.2; }
.insight-card-footer { display: flex; justify-content: space-between; gap: 18px;
  align-items: center; padding-top: 14px; border-top: 1px solid var(--border); }
.insight-card-read { color: var(--teal-hi); font-size: 13px; font-weight: 700; }
.insight-card .insight-when { display: block; margin-top: 8px; font-size: 11.5px;
  color: var(--faint, var(--muted)); }
.insight-card-featured .insight-when { margin-top: 0; }
.insight-archive { margin-top: 30px; }
.insight-card-compact { display: grid; grid-template-columns: 42px minmax(0, 1fr);
  gap: 16px; padding: 20px 22px 18px; }
.insight-card-compact .insight-card-number { font-size: 22px; }
.insight-card-compact .insight-card-title { max-width: none; margin-bottom: 6px; font-size: 21px; }
.insight-card-compact .insight-card-summary { max-width: 70ch; }
.insight-card-compact .insight-card-footer { margin-top: 13px; padding-top: 12px; }
.insight-card-compact .insight-when { margin-top: 0; }
/* card hero thumbnails — inserted by tools/insights/bake_index_thumbs.mjs */
.insight-card-media { display: block; overflow: hidden; border-radius: 10px;
  border: 1px solid var(--border); min-height: 160px; }
.insight-card-media img { display: block; width: 100%; height: 100%; object-fit: cover; }
.insight-card-featured:has(.insight-card-media) { grid-template-columns: 54px minmax(0, 1fr) 228px; }
.insight-card-compact:has(.insight-card-media) { grid-template-columns: 42px minmax(0, 1fr) 116px; }
.insight-card-compact .insight-card-media { min-height: 0; height: 78px; align-self: center; }
@media (max-width: 640px) {
  .insights-index { padding: 16px 0 40px; }
  .insights-index-head { margin-bottom: 28px; }
  .insights-index-head > p:last-child { font-size: 14.5px; }
  .insight-card-featured { grid-template-columns: 1fr; gap: 10px; padding: 22px 20px 19px; }
  .insight-card-featured:has(.insight-card-media) { grid-template-columns: 1fr; }
  .insight-card-media { min-height: 0; aspect-ratio: 16 / 9; order: -1; margin-bottom: 6px; }
  .insight-card-compact { grid-template-columns: 1fr; gap: 8px; padding: 18px; }
  .insight-card-compact:has(.insight-card-media) { grid-template-columns: 1fr; }
  .insight-card-compact .insight-card-media { display: none; }
  .insight-card-number { font-size: 18px; }
  .insight-card-stats { gap: 10px 20px; margin-top: 19px; }
  .insight-card-footer { align-items: flex-end; }
}

/* ---- "You" hub (me.html: immersion + saved + vocabulary + settings) -------- */
/* You-area tab bar — Overview / Library / Personalization / Settings, one per page */
.me-tabs { display: flex; flex-wrap: wrap; gap: 2px; margin: 2px 0 22px;
  border-bottom: 1px solid var(--border); }
.me-tabs a { padding: 9px 15px; color: var(--muted); font-weight: 600; font-size: 14px;
  text-decoration: none; border-bottom: 2px solid transparent; margin-bottom: -1px; }
.me-tabs a:hover { color: var(--text); }
.me-tabs a.active { color: var(--text); border-bottom-color: var(--accent); }
/* anchored jumps land with a little air above the section heading */
#immersion, #saved, #vocab, #settings, #account, #data, #byChannel { scroll-margin-top: 14px; }

.me-card { padding: 16px 18px; }
.me-row { display: flex; align-items: baseline; gap: 14px; padding: 10px 0; font-size: 13.5px; }
.me-row + .me-row { border-top: 1px solid var(--border-2, var(--border)); }
.me-k { flex: 0 0 150px; color: var(--muted); font-weight: 600; font-size: 12px;
  text-transform: uppercase; letter-spacing: .04em; }
.me-v { flex: 1; color: var(--text); min-width: 0; line-height: 1.55; }
.me-v.me-muted { color: var(--muted); }
/* compact vocab + interests readout on the personalization card */
.me-summary { border: 1px solid var(--border); border-radius: 12px; padding: 2px 14px;
  background: var(--card-2); }
.me-summary .me-row:first-child { border-top: 0; }
.me-empty { color: var(--muted); margin: 0 0 12px; max-width: 60ch; }
.me-actions { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-top: 14px; }
.saved-empty { display: flex; align-items: center; gap: 8px; max-width: 720px; }
.saved-empty .count { margin: 0; }
.saved-empty-mascot { flex: 0 0 auto; width: 116px; height: auto; margin: -8px 0 -8px -5px; }
/* saved-words review list on /me — click a row to expand (like the channel word list) */
.sw-list { list-style: none; margin: 0; padding: 0; }
.sw-item { font-size: 14px; border-bottom: 1px solid var(--border-2, var(--border)); }
.sw-item:last-child { border-bottom: none; }
.sw-row { display: flex; align-items: baseline; gap: 10px; padding: 9px 4px; cursor: pointer; }
.sw-row:hover { background: var(--card-2); }
.sw-item.expanded .sw-row { background: var(--card-2); }
.sw-jp { flex: 0 0 auto; color: var(--text); font-size: 16px; }
.sw-read { color: var(--faint); font-size: 12px; margin-left: 4px; }
/* single-line meaning preview → ellipsis when it's too long; full text on expand */
.sw-mean { flex: 1; min-width: 0; color: var(--muted); font-size: 13px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sw-muted { color: var(--faint); font-style: italic; }
.sw-more { flex: 0 0 auto; color: var(--faint); font-size: 11px; transition: transform .15s; }
.sw-item.expanded .sw-more { transform: rotate(180deg); }
.sw-del { flex: 0 0 auto; appearance: none; cursor: pointer; border: none; background: transparent;
  color: var(--faint); font-size: 18px; line-height: 1; padding: 0 4px; transition: color .12s; }
.sw-del:hover { color: var(--danger, #d9534f); }
/* expanded detail: full meaning + where it was heard */
.sw-detail { padding: 4px 8px 12px; }
.sw-full-mean { color: var(--text); font-size: 14px; line-height: 1.5; }
.sw-where { margin-top: 10px; }
.sw-from { font-size: 12px; color: var(--faint); margin-bottom: 6px; }
.sw-from .sw-src { color: var(--muted); text-decoration: none; }
.sw-from .sw-src:hover { color: var(--accent); text-decoration: underline; }
.sw-clabel { font-size: 11px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--faint); font-weight: 600; margin-bottom: 5px; }
.sw-clip { display: flex; gap: 10px; align-items: baseline; padding: 4px 0; }
.sw-clip-t { flex: 0 0 auto; color: var(--accent); font-weight: 600;
  font-variant-numeric: tabular-nums; text-decoration: none; }
.sw-clip-t:hover { color: var(--accent-hi); text-decoration: underline; }
.sw-clip-x { color: var(--muted); font-size: 13px; }
@media (max-width: 640px) {
  .me-k { flex-basis: 104px; }
  .me-cta { white-space: normal; }   /* long action labels wrap instead of overflowing */
  .saved-empty-mascot { width: 88px; margin: -5px 0 -5px -4px; }
}

/* ---- creator pages (static, generated by tools/gen-creator-pages.mjs) ------
   Self-contained per-creator SEO pages under /creators/. Theme-aware via the
   shared vars so they read as native Immersion Atlas in light + dark. */
.creator-page { max-width: 820px; margin: 0 auto; padding: 1.5rem 1.25rem 3rem; }
.creator-head { margin: .5rem 0 1.5rem; }
.creator-sub { display: flex; flex-wrap: wrap; gap: .4rem; margin: .6rem 0; }
.creator-desc { color: var(--muted); line-height: 1.6; max-width: 64ch; }
.creator-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: .75rem; margin: 1.5rem 0; }
.cr-tile { display: flex; flex-direction: column; gap: .2rem; padding: .8rem .9rem; border: 1px solid var(--border); border-radius: 12px; }
.cr-k { font-size: .78rem; text-transform: uppercase; letter-spacing: .03em; color: var(--faint); }
.cr-v { font-size: 1.05rem; font-weight: 700; }
.creator-note, .creator-vocab, .creator-cta { margin: 1.75rem 0; }
.creator-page h3 { margin: 0 0 .4rem; }
.cr-vocab-list { margin: .5rem 0; padding-left: 1.2rem; line-height: 1.9; }
.cr-vocab-list b { font-size: 1.05rem; }
.cr-read { color: var(--faint); font-size: .9rem; }
.cr-stopwords { display: flex; flex-wrap: wrap; gap: .4rem; }
.creator-cta .btn { display: inline-block; padding: .6rem 1rem; border-radius: 10px; border: 1px solid var(--border); text-decoration: none; margin: .2rem .3rem .2rem 0; }
.creator-cta .btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
.cr-index { line-height: 2.2; list-style: none; padding: 0; }
.cr-index .chip { margin-left: .5rem; }
