/* ================================================================
   PLAN — quiz/exam modals,
           dashboard accordion, add-topic modal
   ================================================================ */

.gym-sp { padding: 0; background: transparent; border: none; }

/* ── Add Topic Modal ── */
/* ── Filter bar: chapter tabs + search (sits between header and body) ── */
.add-topic-filter-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 16px 8px; border-bottom: 1px solid var(--border-default);
  flex-shrink: 0; background: var(--surface-subtle); flex-wrap: wrap;
}
/* Chapter pill-tabs */
.atct-tabs {
  display: flex; gap: 4px; flex-wrap: nowrap;
  overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; flex-shrink: 0;
}
.atct-tabs::-webkit-scrollbar { display: none; }
.atct-tab {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 5px 13px; border: 1.5px solid var(--border-default); border-radius: 99px;
  background: var(--surface-card); color: var(--text-secondary);
  font-family: var(--font-display); font-size: 0.8rem; font-weight: 600;
  cursor: pointer; transition: border-color 0.15s, color 0.15s, background 0.15s, box-shadow 0.15s;
  white-space: nowrap; flex-shrink: 0; user-select: none;
}
.atct-tab:hover { border-color: var(--accent); color: var(--accent-strong); background: var(--surface-accent-soft); }
.atct-tab.active {
  background: linear-gradient(135deg, var(--accent-strong), var(--accent));
  color: var(--white); border-color: transparent;
  box-shadow: 0 2px 8px rgba(124,58,237,0.30);
}
/* Search box */
.atc-search-wrap {
  position: relative; flex: 1; min-width: 130px; max-width: 210px;
  display: flex; align-items: center; margin-left: auto;
}
.atc-search-icon {
  position: absolute; left: 9px; font-size: 16px !important; color: var(--text-tertiary); pointer-events: none;
}
.atc-search-input {
  width: 100%; padding: 6px 28px 6px 30px;
  border: 1.5px solid var(--border-default); border-radius: 99px;
  font-family: var(--font-display); font-size: 0.82rem;
  background: var(--surface-card); color: var(--text-body); outline: none;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.atc-search-input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(168,85,247,0.12); }
.atc-search-input::placeholder { color: var(--purple-300); font-size: 0.78rem; }
.atc-search-clear {
  position: absolute; right: 7px; background: none; border: none; cursor: pointer;
  color: var(--text-tertiary); padding: 2px; display: flex; align-items: center;
  border-radius: 50%; transition: color 0.15s;
}
.atc-search-clear:hover { color: var(--text-secondary); }
.atc-search-clear .material-icons-round { font-size: 14px; }
/* Highlight match in topic name */
.atc-hl { background: rgba(168,85,247,0.18); color: var(--accent-deep); border-radius: 3px; padding: 0 1px; font-weight: 700; }
/* Empty filter state */
.add-topic-filter-empty {
  padding: 32px 16px; text-align: center; color: var(--text-tertiary); font-size: 0.84rem; line-height: 1.6;
}
.add-topic-filter-empty .material-icons-round { font-size: 1.8rem; display: block; margin-bottom: 6px; color: var(--text-disabled); }
.add-topic-filter-empty strong { color: var(--text-secondary); }

/* ── Filter mode toggle: ตามบทเรียน / ตามคอร์ส (segmented control) ── */
.atf-mode {
  display: inline-flex; align-items: center; gap: 2px;
  padding: 3px; border: 1px solid var(--gray-border);
  border-radius: var(--r-pill, 999px); background: var(--surface-page);
  flex-shrink: 0;
}
.atf-mode:empty { display: none; }
.atf-mode:not(:has(.atf-mode-btn)) { display: none; }
.atf-mode-btn {
  border: none; background: transparent;
  min-height: 28px; padding: 4px 14px;
  border-radius: var(--r-pill, 999px);
  font-family: var(--font-display); font-size: var(--text-caption-sm, 0.78rem); font-weight: 600;
  color: var(--text-secondary); white-space: nowrap; cursor: pointer; user-select: none;
  transition: background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}
.atf-mode-btn:hover { color: var(--accent-strong); }
.atf-mode-btn:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--purple-300); }
.atf-mode-btn.active {
  background: linear-gradient(135deg, var(--purple-dark), var(--purple));
  color: var(--white);
  box-shadow: 0 2px 8px rgba(124,58,237,0.25);
}
/* ── Rails wrapper: chapter rail / course rail — JS swaps them via [hidden] ── */
.atf-rails { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.atf-rails > [hidden], .atcr-summary[hidden] { display: none !important; }
/* ── Course rail: multi-select chips (soft selected state + check, vs. solid exclusive chapter chips) ── */
.atcr-tabs:not([hidden]) { display: flex; flex-wrap: wrap; gap: 8px; }
.atcr-tab {
  display: inline-flex; align-items: center; gap: 5px;
  min-height: 34px; padding: 0 13px;
  border: 1px solid var(--gray-border); border-radius: var(--r-pill, 999px);
  background: var(--surface-card); color: var(--text-body);
  font-family: var(--font-display); font-size: var(--text-caption-sm, 0.78rem); font-weight: 800;
  box-shadow: var(--shadow-soft, 0 1px 2px rgba(124,58,237,0.08));
  white-space: nowrap; flex-shrink: 0; cursor: pointer; user-select: none;
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
}
.atcr-tab:hover { border-color: var(--accent); color: var(--accent-strong); background: var(--surface-accent-soft); }
.atcr-tab:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--purple-300); }
.atcr-check { display: none; font-size: 15px !important; color: var(--accent-strong); margin-left: -4px; }
.atcr-tab.active {
  background: var(--surface-accent-soft);
  border-color: var(--accent);
  color: var(--accent-deep);
  /* inset half-pixel ring reads as the spec's 1.5px border without shifting layout */
  box-shadow: inset 0 0 0 0.5px var(--accent), var(--shadow-soft, 0 1px 2px rgba(124,58,237,0.08));
}
.atcr-tab.active .atcr-check { display: inline-flex; }
.atcr-lock { font-size: 13px !important; color: var(--text-tertiary); margin-right: -3px; }
.atcr-tab.locked { color: var(--text-tertiary); box-shadow: none; }
.atcr-tab.locked .atcr-label { color: inherit; }
.atcr-tab.locked:hover { color: var(--text-secondary); }
/* ── Course selection summary row ── */
.atcr-summary:not([hidden]) {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  padding-top: 2px;
  font-family: var(--font-display); font-size: var(--text-caption-sm, 0.78rem); font-weight: 600;
  color: var(--text-secondary);
}
.atcr-clear {
  border: none; background: none; padding: 2px 4px; border-radius: 6px;
  font-family: var(--font-display); font-size: var(--text-caption-sm, 0.78rem); font-weight: 600;
  color: var(--accent); cursor: pointer;
  transition: color 0.15s ease;
}
.atcr-clear:hover { color: var(--accent-strong); }
.atcr-clear:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--purple-300); }

.add-topic-modal { position: fixed; inset: 0; z-index: 1200; display: flex; align-items: center; justify-content: center; padding: 16px; }
.add-topic-backdrop { position: absolute; inset: 0; background: var(--scrim); backdrop-filter: blur(4px); }
.add-topic-content { position: relative; z-index: 1; background: var(--surface-card); border-radius: var(--radius-lg); box-shadow: 0 24px 64px rgba(0,0,0,0.2); width: 100%; max-width: 780px; max-height: 88vh; display: flex; flex-direction: column; overflow: hidden; }
.add-topic-header { display: flex; align-items: flex-start; justify-content: space-between; padding: 20px 24px 16px; border-bottom: 1px solid var(--border-default); flex-shrink: 0; }
.add-topic-title { display: flex; align-items: center; gap: 8px; font-size: 1.1rem; font-weight: 700; color: var(--text-ink); }
.add-topic-title .material-icons-round { color: var(--accent); }
.add-topic-sub { font-size: 0.85rem; color: var(--text-secondary); margin-top: 4px; }
.add-topic-body { display: flex; flex: 1; overflow: hidden; }
.add-topic-left { width: 260px; flex-shrink: 0; overflow-y: auto; border-right: 1px solid var(--border-default); padding: 8px 0; }
.add-topic-right { flex: 1; overflow-y: auto; padding: 12px 16px; }
.add-topic-placeholder { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; color: var(--text-tertiary); gap: 8px; text-align: center; }
.add-topic-placeholder .material-icons-round { font-size: 2rem; }
.add-topic-main-item { display: flex; align-items: center; gap: 8px; padding: 10px 16px; cursor: pointer; transition: background 0.15s; border-left: 3px solid transparent; }
.add-topic-main-item:hover { background: var(--surface-subtle); }
.add-topic-main-item.active { background: rgba(168,85,247,0.07); border-left-color: var(--accent); }
.add-topic-main-name { flex: 1; font-size: 0.87rem; font-weight: 500; color: var(--text-body); line-height: 1.3; }
.add-topic-main-item.active .add-topic-main-name { color: var(--accent-strong); font-weight: 600; }
.add-topic-main-arrow { font-size: 1rem !important; color: var(--text-tertiary); flex-shrink: 0; transition: transform 0.2s, color 0.15s; }
.add-topic-main-item.active .add-topic-main-arrow { color: var(--accent-strong); }
.add-topic-badge-sel { background: var(--surface-accent); color: var(--accent-strong); }
.add-topic-badge { font-size: 0.68rem; background: var(--success-surface); color: var(--success-fg-strong); padding: 2px 6px; border-radius: 99px; font-weight: 600; white-space: nowrap; }
.add-topic-sub-title { font-size: 0.9rem; font-weight: 700; color: var(--text-ink); margin-bottom: 10px; }
.add-topic-check-label { display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 0.85rem; font-weight: 600; color: var(--text-body); }
.add-topic-check-label input[type=checkbox] { accent-color: var(--accent); width: 15px; height: 15px; cursor: pointer; }
.add-topic-sub-item { display: flex; align-items: flex-start; gap: 10px; padding: 8px 6px; border-radius: 6px; cursor: pointer; transition: background 0.12s; }
.add-topic-sub-item:hover { background: var(--surface-sunken); }
.add-topic-sub-item.no-bank { opacity: 0.5; }
.add-topic-sub-item input[type=checkbox] { accent-color: var(--accent); width: 15px; height: 15px; cursor: pointer; flex-shrink: 0; margin-top: 2px; }
.add-topic-sub-info { flex: 1; }
.add-topic-sub-name { font-size: 0.85rem; color: var(--text-body); line-height: 1.4; display: block; }
.add-topic-sub-tag { display: inline-block; font-size: 0.68rem; padding: 1px 6px; border-radius: 99px; margin-top: 3px; font-weight: 600; }
.add-topic-sub-tag.added      { background: var(--success-surface); color: var(--success-fg-strong); }
.add-topic-sub-tag.nobank     { background: var(--danger-surface); color: var(--danger-fg-strong); }
.add-topic-sub-tag.locked-tag { background: var(--surface-sunken); color: var(--text-tertiary); }
/* Locked main topic — muted, not hidden (user sees what requires more courses) */
.add-topic-main-item.locked { opacity: 0.55; }
.add-topic-main-item.locked .add-topic-main-name { color: var(--text-tertiary); }
.add-topic-lock-icon { font-size: 14px !important; color: var(--text-disabled); flex-shrink: 0; }
/* Locked subtopic row */
.add-topic-sub-item.locked { opacity: 0.5; cursor: default; }
.add-topic-sub-item.locked:hover { background: transparent; }
.add-topic-sub-item.locked input[type=checkbox] { cursor: not-allowed; }
.add-topic-footer { display: flex; align-items: center; justify-content: space-between; padding: 14px 24px; border-top: 1px solid var(--border-default); flex-shrink: 0; background: var(--surface-subtle); }
.add-topic-count { font-size: 0.88rem; color: var(--text-secondary); font-weight: 500; }
@media (max-width: 600px) { .add-topic-content { max-height: 95vh; } .add-topic-left { width: 180px; } .add-topic-header { padding: 16px 18px 12px; } .add-topic-title { font-size: 1rem; } .add-topic-sub { font-size: 0.8rem; } .add-topic-main-name { font-size: 0.82rem; } .add-topic-main-item { padding: 8px 12px; } .add-topic-sub-name { font-size: 0.8rem; } .add-topic-footer { padding: 10px 16px; } .add-topic-footer .btn { padding: 9px 16px; font-size: 0.88rem; } .add-topic-count { font-size: 0.8rem; }
  .add-topic-filter-bar { padding: 8px 12px 6px; gap: 8px; }
  .atct-tab { padding: 4px 10px; font-size: 0.75rem; }
  .atc-search-wrap { max-width: 160px; }
}
@media (max-width: 440px) {
  .add-topic-modal { padding: 8px; }
  .add-topic-content { max-height: 97vh; border-radius: 16px; }
  .add-topic-header { padding: 14px 16px 10px; gap: 8px; }
  .add-topic-title { font-size: 0.92rem; gap: 6px; }
  .add-topic-title .material-icons-round { font-size: 20px; }
  .add-topic-sub { font-size: 0.75rem; margin-top: 2px; line-height: 1.4; }
  .add-topic-header .quiz-modal-close { width: 30px; height: 30px; min-width: 30px; }
  .add-topic-header .quiz-modal-close .material-icons-round { font-size: 18px; }
  .add-topic-filter-bar { flex-wrap: nowrap; padding: 6px 10px 5px; gap: 6px; }
  .atct-tabs { gap: 3px; }
  .atct-tab { padding: 4px 9px; font-size: 0.72rem; }
  .atc-search-wrap { min-width: 0; max-width: none; flex: 1; margin-left: 0; }
  .add-topic-body { flex-direction: column; }
  .add-topic-left { width: 100%; max-height: none; border-right: none; border-bottom: none; flex: 1; min-height: 0; }
  .add-topic-right { display: none; }
  .add-topic-accordion-subs { padding: 4px 10px 10px 28px; background: rgba(168,85,247,0.03); border-bottom: 1px solid var(--divider); }
  .add-topic-accordion-subs .add-topic-sub-item { padding: 5px 4px; }
  .add-topic-main-item { padding: 8px 14px; border-left-width: 2px; }
  .add-topic-main-name { font-size: 0.82rem; }
  .add-topic-main-arrow { font-size: 0.85rem !important; }
  .add-topic-badge { font-size: 0.62rem; padding: 1px 5px; }
  .add-topic-placeholder { gap: 4px; font-size: 0.82rem; }
  .add-topic-placeholder .material-icons-round { font-size: 1.4rem; transform: rotate(90deg); }
  .add-topic-placeholder p { font-size: 0.82rem; }
  .add-topic-placeholder p { visibility: hidden; position: relative; }
  .add-topic-placeholder p::after { content: 'เลือกหัวข้อหลักด้านบน'; visibility: visible; position: absolute; left: 50%; transform: translateX(-50%); white-space: nowrap; }
  .add-topic-sub-title { font-size: 0.82rem; margin-bottom: 6px; }
  .add-topic-sub-name { font-size: 0.8rem; }
  .add-topic-sub-tag { font-size: 0.62rem; }
  .add-topic-check-label { font-size: 0.8rem; gap: 6px; }
  .add-topic-check-label input[type=checkbox], .add-topic-sub-item input[type=checkbox] { width: 14px; height: 14px; }
  .add-topic-sub-item { gap: 8px; padding: 6px 4px; }
  .add-topic-footer { padding: 10px 14px; gap: 8px; flex-wrap: wrap; }
  .add-topic-count { font-size: 0.75rem; }
  .add-topic-footer .btn { padding: 8px 14px; font-size: 0.82rem; gap: 4px; }
  .add-topic-footer .btn .material-icons-round { font-size: 16px; }
}

/* ── Manual topic picker v2: token-aligned mobile + desktop production layout ── */
.add-topic-content-v2 {
  max-width: 940px; max-height: min(92dvh, 800px);
  background: var(--gm-surface-card); border: 1px solid var(--gm-border-default);
  border-radius: 26px; box-shadow: var(--gm-shadow-panel);
}
.add-topic-content-v2:is(.is-subject-step, .is-template-step) { max-width: 800px; }
.add-topic-content-v2 .add-topic-header { padding: 18px 28px 12px; background: var(--gm-surface-card); border-bottom: 0; }
.add-topic-content-v2 .add-topic-title { font-family: var(--font-display); font-size: .95rem; font-weight: 500; line-height: 1.5; color: var(--gm-text-secondary); }
.add-topic-content-v2 .add-topic-title .material-icons-round { display: none; }
.add-topic-content-v2:is(.is-subject-step, .is-template-step) .add-topic-sub { display: none; }
.add-topic-content-v2 .add-topic-sub { margin-top: 4px; color: var(--gm-text-secondary); font-size: .75rem; line-height: 1.5; }
.add-topic-content-v2 .quiz-modal-close { min-width: 44px; min-height: 44px; background: var(--gm-surface-support); color: var(--gm-text-secondary); }
.add-topic-content-v2 .quiz-modal-close:hover { background: var(--gm-surface-selected); color: var(--gm-action-primary); }
.add-topic-content-v2 .btn { min-height: 44px; box-shadow: none; }
.add-topic-content-v2 .btn-primary { background: var(--gm-action-primary); color: var(--gm-on-action); }
.add-topic-content-v2 .btn-outline { border-color: var(--gm-border-default); color: var(--gm-text-ink); background: var(--gm-surface-card); }
.add-topic-content-v2 .btn-primary:hover { background: var(--gm-action-hover); }
.add-topic-modal { margin: 0; width: 100%; height: 100%; max-width: none; max-height: none; border: 0; color: var(--gm-text-ink); background: transparent; }
.add-topic-modal::backdrop { background: transparent; }
/* Bar layout: control strip (mode + search) on top, rails get the full width
   below so 6+ chips wrap cleanly; summary auto-places as a full-width last row
   (kept out of grid-template-areas so its [hidden] state doesn't leave a gap). */
.add-topic-content-v2 .add-topic-filter-bar {
  display: grid;
  grid-template-columns: 1fr minmax(220px, 300px);
  grid-template-areas:
    "mode  search"
    "rails rails";
  gap: 12px 14px;
  align-items: center;
  padding: 14px 24px 12px;
  background: var(--surface-card);
  border-bottom-color: var(--border-card, rgba(30,19,51,0.09));
}
.add-topic-content-v2 .atf-mode { grid-area: mode; justify-self: start; }
.add-topic-content-v2 .atf-rails { grid-area: rails; }
.add-topic-content-v2 .atc-search-wrap { grid-area: search; }
.add-topic-content-v2 .atcr-summary { grid-column: 1 / -1; }
.add-topic-content-v2 .atct-tabs { gap: 8px; flex-wrap: wrap; }
.add-topic-content-v2 .atct-tab {
  min-height: 34px;
  padding: 0 13px;
  border: 1px solid var(--gray-border);
  border-radius: var(--r-pill, 999px);
  color: var(--text-body);
  background: var(--surface-card);
  font-size: var(--text-caption-sm, 0.78rem);
  font-weight: 800;
  box-shadow: var(--shadow-soft, 0 1px 2px rgba(124,58,237,0.08));
}
.add-topic-content-v2 .atct-tab.active {
  color: var(--white);
  background: linear-gradient(135deg, var(--purple-dark), var(--purple));
  border-color: transparent;
  box-shadow: 0 8px 18px rgba(124,58,237,0.18);
}
.add-topic-content-v2 .atc-search-wrap {
  min-width: 0;
  max-width: none;
  margin-left: 0;
}
.add-topic-content-v2 .atc-search-input {
  min-height: 42px;
  border-color: rgba(168,85,247,0.18);
  border-radius: var(--radius-sm, 12px);
  background: var(--surface-page);
  color: var(--text-body);
  font-size: var(--text-sm, 0.85rem);
  font-weight: 700;
}
.add-topic-content-v2 .atc-search-input::placeholder {
  color: var(--gray-cool);
  font-size: var(--text-sm, 0.85rem);
}
.add-topic-guidance {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 12px;
  align-items: center;
  margin: 16px 16px 0;
  padding: 12px;
  border: 1px solid rgba(255,94,145,0.18);
  border-radius: var(--radius, 20px);
  background: linear-gradient(135deg, rgba(255,255,255,0.94), rgba(255,232,245,0.72));
  background: linear-gradient(135deg, light-dark(rgba(255,255,255,0.94), rgba(34,29,51,0.94)), light-dark(rgba(255,232,245,0.72), rgba(44,27,40,0.72)));
}
/* display:grid above would otherwise beat the UA rule for [hidden] — and the
   banner is hidden for every learner with nothing locked (plan-topics.js). */
.add-topic-guidance[hidden] { display: none; }
.add-topic-guidance strong {
  display: block;
  color: var(--text-ink);
  font-size: var(--text-body-sm, 0.9rem);
  line-height: var(--leading-tight, 1.25);
  font-weight: 800;
}
.add-topic-guidance span:not(.add-topic-progress-pill) {
  display: block;
  margin-top: 3px;
  color: var(--gray);
  font-size: var(--text-2xs, 0.72rem);
  line-height: var(--leading-snug, 1.35);
  font-weight: 600;
}
.add-topic-progress-pill {
  min-width: 50px;
  min-height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-pill, 999px);
  color: var(--pink-deeper);
  background: var(--pink-light);
  font-size: var(--text-caption-sm, 0.78rem);
  font-weight: 900;
}
.add-topic-content-v2 .add-topic-body {
  min-height: 0;
  display: grid;
  grid-template-columns: 360px minmax(0, 1fr);
  background: var(--surface-page-tint);
}
.add-topic-content-v2 .add-topic-left {
  width: auto;
  min-height: 0;
  padding: 16px;
  border-right: 1px solid var(--border-card, rgba(30,19,51,0.09));
  background: color-mix(in srgb, var(--surface-card) 72%, transparent);
}
.add-topic-content-v2 .add-topic-right {
  min-height: 0;
  padding: 18px;
  background: transparent;
}
.add-topic-content-v2 .add-topic-main-item {
  position: relative;
  /* A flex row, not the five-column grid it was: the trailing columns (lock,
     badge, count) are usually absent, and an empty `auto` track still keeps
     its gap — up to 20px of nothing before the chevron. */
  display: flex;
  gap: 10px;
  align-items: center;
  min-height: 64px;
  margin-bottom: 8px;
  padding: 10px 11px;
  overflow: hidden;
  border: 1px solid var(--border-card, rgba(30,19,51,0.09));
  border-left: 1px solid var(--border-card, rgba(30,19,51,0.09));
  border-radius: var(--radius, 20px);
  background: var(--surface-card);
  box-shadow: var(--shadow-soft, 0 1px 2px rgba(124,58,237,0.08));
}
.add-topic-content-v2 .add-topic-main-item::before {
  content: "";
  position: absolute;
  left: 0;
  top: 12px;
  bottom: 12px;
  width: 4px;
  border-radius: 0 999px 999px 0;
  background: linear-gradient(180deg, rgba(168,85,247,0.7), rgba(124,58,237,0.36));
}
.add-topic-content-v2 .add-topic-main-item.active {
  border-color: rgba(255,94,145,0.36);
  background: var(--surface-card);
  box-shadow: 0 10px 24px rgba(255,94,145,0.12);
}
.add-topic-content-v2 .add-topic-main-item.active::before {
  background: linear-gradient(180deg, var(--pink), var(--pink-dark));
}
.add-topic-content-v2 .add-topic-main-item.locked {
  opacity: 1;
  background: color-mix(in srgb, var(--surface-card) 64%, transparent);
  box-shadow: none;
}
.add-topic-content-v2 .add-topic-main-item.locked::before { background: transparent; }
.add-topic-main-icon {
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-sm, 12px);
  color: var(--purple-dark);
  background: var(--purple-light);
  font-size: var(--text-sm, 0.85rem);
  font-weight: 900;
}
.add-topic-main-item.active .add-topic-main-icon {
  color: var(--white);
  background: linear-gradient(135deg, var(--pink), var(--pink-dark));
}
.add-topic-main-item.locked .add-topic-main-icon {
  color: var(--gray-dim);
  background: var(--gray-light);
}
.add-topic-main-copy { flex: 1; min-width: 0; }
.add-topic-content-v2 .add-topic-main-name {
  color: var(--text-ink);
  font-size: var(--text-body-sm, 0.9rem);
  line-height: var(--leading-snug, 1.35);
  font-weight: 800;
}
/* The English name as its own quieter line — under a card's Thai name and
   under the sub-panel's title alike — so the Thai stays one line and the
   list shows twice the topics. The same line the topic editor draws. */
.add-topic-title-en {
  display: block;
  margin-top: 1px;
  color: var(--gray);
  font-size: var(--text-2xs, 0.72rem);
  line-height: var(--leading-snug, 1.35);
  font-weight: 600;
}
.add-topic-content-v2 .add-topic-main-item.locked .add-topic-main-name {
  color: var(--gray-cool);
}
.add-topic-main-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 3px;
  color: var(--gray);
  font-size: var(--text-2xs, 0.72rem);
  font-weight: 700;
}
.add-topic-main-meta .locked { color: var(--gray-cool); }
.add-topic-content-v2 .add-topic-main-arrow {
  color: var(--gray-cool);
  font-size: 18px !important;
}
.add-topic-content-v2 .add-topic-badge {
  align-self: center;
  border-radius: var(--r-pill, 999px);
  font-size: var(--text-2xs, 0.72rem);
  font-weight: 800;
}
.add-topic-sub-panel-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
  margin-bottom: 14px;
  padding: 14px;
  border: 1px solid var(--border-card, rgba(30,19,51,0.09));
  border-radius: var(--radius, 20px);
  background: linear-gradient(135deg, color-mix(in srgb, var(--surface-card) 96%, transparent), color-mix(in srgb, var(--surface-page) 94%, transparent));
  box-shadow: var(--shadow-soft, 0 1px 2px rgba(124,58,237,0.08));
}
.add-topic-sub-panel-copy { min-width: 0; }
.add-topic-content-v2 .add-topic-sub-title {
  margin: 0;
  color: var(--text-ink);
  font-size: var(--text-ui, 0.95rem);
  line-height: var(--leading-tight, 1.25);
  font-weight: 800;
  letter-spacing: 0;
}
.add-topic-sub-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}
.add-topic-sub-stats span {
  padding: 7px 10px;
  border-radius: var(--r-pill, 999px);
  color: var(--pink-deeper);
  background: var(--pink-light);
  font-size: var(--text-2xs, 0.72rem);
  font-weight: 900;
}
.add-topic-sub-stats .locked {
  color: var(--gray-strong);
  background: var(--gray-light);
}
.add-topic-content-v2 .add-topic-check-label {
  color: var(--text-body);
  font-size: var(--text-sm, 0.85rem);
  font-weight: 800;
}
.add-topic-check-label--all {
  height: 40px;
  padding: 0 14px;
  border: 1px solid rgba(124,58,237,0.22);
  border-radius: var(--radius-sm, 12px);
  color: var(--purple-dark) !important;
  background: var(--surface-card);
  white-space: nowrap;
}
.add-topic-sub-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  align-content: start;
}
.add-topic-content-v2 .add-topic-sub-item {
  min-height: 70px;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 10px;
  align-items: start;
  padding: 12px;
  border: 1px solid var(--border-card, rgba(30,19,51,0.09));
  border-radius: var(--radius, 20px);
  background: var(--surface-card);
  box-shadow: var(--shadow-soft, 0 1px 2px rgba(124,58,237,0.08));
}
.add-topic-content-v2 .add-topic-sub-item.checked {
  border-color: rgba(255,94,145,0.35);
  background: linear-gradient(180deg, var(--surface-card), rgba(255,232,245,0.52));
  background: linear-gradient(180deg, var(--surface-card), light-dark(rgba(255,232,245,0.52), rgba(44,27,40,0.52)));
  box-shadow: 0 8px 18px rgba(255,94,145,0.10);
}
.add-topic-content-v2 .add-topic-sub-item.locked,
.add-topic-content-v2 .add-topic-sub-item.no-bank {
  opacity: 0.64;
}
.add-topic-content-v2 .add-topic-sub-name {
  color: var(--text-ink);
  font-size: var(--text-sm, 0.85rem);
  line-height: var(--leading-snug, 1.35);
  font-weight: 800;
}
.add-topic-content-v2 .add-topic-footer {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 10px;
  align-items: center;
  padding: 14px 24px;
  background: var(--surface-card);
  border-top-color: var(--border-card, rgba(30,19,51,0.09));
}
.add-topic-count-wrap { min-width: 0; }
.add-topic-count-label {
  display: block;
  color: var(--gray);
  font-size: var(--text-2xs, 0.72rem);
  font-weight: 800;
}
.add-topic-content-v2 .add-topic-count {
  display: block;
  margin-top: 2px;
  color: var(--text-ink);
  font-size: var(--text-body-sm, 0.9rem);
  line-height: var(--leading-tight, 1.25);
  font-weight: 900;
  background: transparent;
  border: 0;
  border-radius: 0;
  padding: 0;
}
.add-topic-actions {
  display: flex;
  gap: 10px;
  align-items: center;
}
.add-topic-content-v2 .add-topic-actions .btn {
  min-height: 44px;
  border-radius: var(--radius-sm, 12px);
  font-size: var(--text-sm, 0.85rem);
  font-weight: 800;
}

@media (max-width: 759px) {
  .add-topic-modal { padding: 0; }
  .add-topic-content-v2 {
    width: 100%;
    height: 100dvh;
    max-height: none;
    border-radius: 0;
  }
  .add-topic-content-v2 .add-topic-header {
    padding: 16px 16px 12px;
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 10px;
    align-items: start;
  }
  .add-topic-content-v2 .add-topic-title {
    font-size: .95rem;
  }
  .add-topic-content-v2 .add-topic-sub {
    font-size: var(--text-caption-sm, 0.78rem);
  }
  .add-topic-content-v2 .quiz-modal-close {
    width: 44px;
    height: 44px;
    min-width: 44px;
    border-radius: var(--radius-sm, 12px);
    background: var(--surface-card);
    box-shadow: var(--shadow-raise, 0 2px 8px rgba(124,58,237,0.08));
  }
  /* Two rows, not three: the search shares its row with the mode switch, the
     chips take the second. With the mode switch on a row of its own the list's
     first card began 366px down a 727px phone; the switch is two short words
     and the search field does not need the width it was given alone. */
  .add-topic-content-v2 .add-topic-filter-bar {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "search mode"
      "rails  rails";
    gap: 8px 10px;
    padding: 10px 14px 8px;
  }
  /* A subject with no courses draws no switch — the search takes the row. */
  .add-topic-content-v2 .add-topic-filter-bar:not(:has(.atf-mode-btn)) {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "search"
      "rails";
  }
  .add-topic-content-v2 .atf-mode { justify-self: end; }
  .add-topic-content-v2 .atct-tabs {
    flex-wrap: nowrap;
    overflow-x: auto;
  }
  .add-topic-content-v2 .atf-mode-btn { min-height: 32px; padding: 4px 11px; }
  .add-topic-content-v2 .atcr-tabs:not([hidden]) {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .add-topic-content-v2 .atcr-tabs::-webkit-scrollbar { display: none; }
  .add-topic-content-v2 .atcr-tab { min-height: 32px; padding: 0 11px; }
  .add-topic-content-v2 .atcr-summary:not([hidden]) { padding-top: 0; }
  .add-topic-guidance {
    margin: 0 14px 10px;
  }
  .add-topic-content-v2 .add-topic-body {
    display: block;
    overflow-y: auto;
    background: transparent;
  }
  .add-topic-content-v2 .add-topic-left {
    width: 100%;
    padding: 0 14px 116px;
    border-right: 0;
    border-bottom: 0;
    background: transparent;
  }
  .add-topic-content-v2 .add-topic-right { display: none; }
  .add-topic-content-v2 .add-topic-main-item { margin-bottom: 8px; }
  .add-topic-content-v2 .add-topic-accordion-subs {
    margin: -2px 0 10px 0;
    padding: 0;
    background: transparent;
    border: 0;
  }
  /* Under the card it opens from, the accordion's head is that card again —
     same name, same count, one tap apart. On a phone the head keeps only the
     control the card does not have: «เลือกทั้งหมด». (Desktop keeps the copy:
     there the right pane stands beside the list, not under one card.) */
  .add-topic-content-v2 .add-topic-accordion-subs .add-topic-sub-panel-head {
    padding: 0;
    margin-bottom: 8px;
    justify-content: flex-end;
    border: 0;
    background: transparent;
    box-shadow: none;
  }
  .add-topic-content-v2 .add-topic-accordion-subs .add-topic-sub-panel-copy { display: none; }
  .add-topic-content-v2 .add-topic-accordion-subs .add-topic-check-label--all {
    height: 36px;
    padding: 0 10px;
  }
  .add-topic-sub-grid {
    grid-template-columns: 1fr;
    gap: 8px;
  }
  .add-topic-content-v2 .add-topic-sub-item {
    min-height: 0;
    border-radius: var(--radius-sm, 12px);
  }
  .add-topic-content-v2 .add-topic-footer {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    grid-template-columns: 1fr auto;
    padding: 12px 14px 16px;
    background: linear-gradient(180deg, rgba(255,255,255,0), var(--surface-card) 22%, var(--surface-card));
    box-shadow: 0 -10px 30px rgba(124,58,237,0.08);
  }
  .add-topic-actions {
    gap: 8px;
  }
  .add-topic-content-v2 .add-topic-actions .btn {
    min-height: 46px;
    padding: 0 14px;
  }
  .add-topic-content-v2 .add-topic-actions .btn .material-icons-round {
    font-size: 17px;
  }
}

/* ── Live practice trend modal (exam-history-ui.js) ──
   Shared chart ink follows semantic tokens in both themes. */
.xh { max-height: 85vh; display: flex; flex-direction: column; --xh-accent: var(--indigo); }
.xh-title { font-size: var(--text-md); font-weight: 800; color: var(--text-ink); margin-bottom: 12px; padding-right: 32px; }
.xh-title-ico { vertical-align: middle; font-size: 20px; color: var(--xh-accent); }
.xh-body { overflow-y: auto; flex: 1; }
.xh-body--pad { padding: 4px 0; }
.xh-sub { font-size: 0.76rem; color: var(--text-secondary); margin-bottom: 10px; }
.xh-legend { display: flex; align-items: center; gap: 16px; margin-bottom: 12px; font-size: var(--text-caption-sm); font-weight: 600; color: var(--text-secondary); }
.xh-legend--wrap { gap: 14px; margin-bottom: 10px; font-size: 0.76rem; flex-wrap: wrap; }
.xh-legend-item { display: flex; align-items: center; gap: 5px; }
.xh-empty { color: var(--text-tertiary); text-align: center; padding: 32px 0; font-size: var(--text-body-sm); }
/* SVG ink */
.xh-svg { width: 100%; height: auto; display: block; }
.xh-grid { stroke: var(--border-faint); }
.xh-axis { stroke: var(--border-default); }
.xh-axis-lbl { fill: var(--text-tertiary); }
.xh-pass-line { stroke: var(--success-fg); }
.xh-pass-lbl { fill: var(--success-fg); }
.xh-line-main { stroke: var(--xh-accent); }
.xh-stop { stop-color: var(--xh-accent); }

/* ── Quiz Modal — redesign (spec: mockups/quiz-redesign-mockup.html) ── */
/* --vv-bottom-inset (declared in tokens.css, synced by core/iab-viewport.js)
   is how far the layout viewport's bottom edge sits below the visible one —
   keyboard or in-app-browser toolbar. The sheet subtracts it so its footer
   stays on screen. */
/* `container-type: size` makes this box a query container for the sheet inside
   it (see the short-sheet block at the end of this section). It is declared on
   the BACKDROP, not on .quiz-modal-content, and that placement is the whole
   trick: this element is `position: fixed; inset: 0` and so its height never
   depends on its contents, which is what makes a size container legal here and
   makes collapsing chrome inside it unable to feed back into the query. The
   sheet itself is content-sized at >768px (`height: auto`), so it could not
   host the container without collapsing. */
.quiz-modal { container-type: size; container-name: quizsheet; position: fixed; inset: 0; z-index: var(--z-quiz-modal); display: flex; align-items: center; justify-content: center; padding: 20px; padding-bottom: calc(20px + env(safe-area-inset-bottom, 0px)); box-sizing: border-box; }
.quiz-modal-backdrop { position: absolute; inset: 0; background: var(--scrim-brand); backdrop-filter: blur(5px); }
/* `overflow: clip` is load-bearing, not a synonym for the `hidden` above it.
   `hidden` clips AND makes the box a scroll container — one that refuses
   gestures but not script — and this box gains real scrollable overflow the
   moment its unshrinkable chrome (header + toolbar + footer ≈ 256px at 375px
   wide) outgrows the sheet. Anything that scrolls an ancestor chain then
   scrolls the sheet itself: scrollIntoView on a question card did exactly
   that (header off the top, submit bar stranded mid-screen), and UA focus
   scrolling can reach it the same way. `clip` clips identically — same
   border-radius, same corners — without ever being scrollable, which closes
   the whole class instead of one caller. The `hidden` declaration stays as
   the fallback for engines that do not parse `clip` (pre-Safari 16); there
   Quiz.shared.scrollSheetIntoView is what holds the line. */
.quiz-modal-content { position: relative; z-index: 1; background: var(--learner-surface-workspace); border: 1px solid var(--learner-border-default); border-radius: 24px; width: 100%; max-width: 1160px; max-height: min(90vh, calc(100dvh - env(safe-area-inset-bottom, 0px) - var(--vv-bottom-inset, 0px) - 32px)); height: auto; display: flex; flex-direction: column; box-shadow: 0 18px 44px rgba(121,86,190,0.18), 0 10px 30px rgba(15,23,42,0.12); overflow: hidden; overflow: clip; min-height: 0; flex: 0 1 auto; font-family: var(--font-display); color: var(--learner-text-ink); }
/* Gradient hero header */
/* The header wraps intrinsically — that is a correctness rule, not a breakpoint
   decision. `flex-wrap: wrap` plus the heading's flex-basis floor makes the chip
   row drop to its own line the moment it stops fitting, at ANY width, with no
   media query involved. It must work that way: in-app browsers (LINE, FB, IG)
   report a layout viewport wider than the usable one (that is why
   core/iab-viewport.js and html.iab-compact exist), so a viewport-gated rule
   silently misses there and the chips — which cannot shrink past their content —
   starve the heading to ~0px. The <=768px block below only tunes the result. */
.quiz-modal-header { flex: 0 0 auto; display: flex; flex-wrap: wrap; align-items: center; gap: 16px; padding: 16px 20px; color: var(--white); background: var(--learner-quiz-header); } /* on-accent */
/* 12rem is a floor, not a width: the heading still grows to fill a wide header,
   but can never be squeezed below a legible size. Kept well under the narrowest
   phone's inner width so the close button still shares row 1 at 320px. */
.quiz-modal-heading { min-width: 0; flex: 1 1 12rem; }
/* All three heading lines clamp to one line each: the header is a fixed-height
   band above a scrollable body, so a wrapping topic name must not be allowed to
   eat the question area. Thai has no inter-word spaces, so an over-constrained
   box breaks it one syllable per line — ellipsis instead of that. */
.quiz-modal-maintopic { font-family: var(--font-display); font-size: 0.75rem; font-weight: 700; letter-spacing: 0.02em; color: rgba(255,255,255,0.85); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.quiz-modal-title { font-family: var(--font-display); font-size: clamp(1rem, 2.2vw, 1.22rem); font-weight: 600; line-height: 1.3; color: var(--white); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.quiz-modal-sub { color: var(--white); font-size: 0.8rem; font-weight: 500; margin-top: 2px; line-height: 1.35; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Shrinkable on purpose: on a narrow row the chips wrap inside .quiz-modal-meta
   instead of overflowing the header's right edge. */
.quiz-modal-meta { display: flex; align-items: center; gap: 8px; flex: 0 1 auto; flex-wrap: wrap; }
/* Theme-stable white counters on the canonical berry header. */
/* The pill is deliberately white in BOTH themes — it rides the header's berry
   surface, which does not flip either. Its label must therefore be a
   theme-stable ink: --text-ink inverts to near-white under [data-theme="dark"],
   which rendered the counters as white-on-white. --dark is a Tier 1 scale value
   the dark block never redeclares, same reasoning as the --white background. */
.quiz-hchip { display: flex; align-items: center; gap: 8px; min-height: 44px; padding: 5px 14px 5px 6px; background: var(--white); border: none; border-radius: 999px; font-family: var(--font-display); font-weight: 600; font-size: 0.92rem; color: var(--dark); box-shadow: none; font-variant-numeric: tabular-nums; } /* on-accent */
.quiz-hchip svg { display: block; flex: none; }
.quiz-hchip .qic { width: 26px; height: 26px; border-radius: 50%; flex: none; display: grid; place-items: center; color: var(--white); }
.qic-grad { background: var(--learner-action-primary); color: var(--learner-on-action); }
.qic-pink { background: var(--learner-action-primary); color: var(--learner-on-action); }
.qic-flame { background: linear-gradient(135deg, var(--amber-300), var(--orange)); }
.qic-green { background: linear-gradient(135deg, var(--green), var(--green-dark)); }
/* `display: flex` above is an author rule, so it beats the UA's `[hidden]`
   rule — without this the streak chip JS hides via `chip.hidden = true`
   (_syncStreakChip) stayed on screen showing a stale "x2" from question 1. */
.quiz-hchip[hidden] { display: none; }
/* chip-as-button (exam PDF export) — same chrome, adds press feedback */
button.quiz-hchip { cursor: pointer; transition: transform 0.15s var(--ease-out-soft), box-shadow 0.15s var(--ease-out-soft); }
button.quiz-hchip:hover { background: var(--white); }
button.quiz-hchip:active { transform: scale(0.98); }
.quiz-hchip.pop, .quiz-tstat.pop { animation: chipPop 0.3s var(--ease-out-soft); }
@keyframes chipPop { 0% { transform: scale(0.6); } 60% { transform: scale(1.15); } 100% { transform: scale(1); } }
/* Chip info tooltip — hover/keyboard-focus on desktop, tap (JS toggles .tip-open) on touch.
   Anchored to the chip's right edge: the chips sit at the header's right, so a centered
   bubble would clip against the modal's overflow:hidden on narrow screens. */
.quiz-hchip { position: relative; }
.quiz-hchip[data-info]::after, .quiz-tstat[data-info]::after { content: attr(data-info); position: absolute; top: calc(100% + 8px); right: 0; z-index: 2; background: var(--learner-text-ink); color: var(--surface-page); font-size: 0.75rem; font-weight: 500; line-height: 1.3; padding: 5px 10px; border-radius: 8px; white-space: nowrap; box-shadow: 0 6px 16px rgba(15,23,42,0.25); opacity: 0; visibility: hidden; transform: translateY(-2px); transition: opacity 0.15s var(--ease-out-soft), transform 0.15s var(--ease-out-soft), visibility 0.15s; pointer-events: none; }
.quiz-hchip[data-info]:hover::after, .quiz-hchip[data-info]:focus-visible::after, .quiz-hchip[data-info].tip-open::after,
.quiz-tstat[data-info]:hover::after, .quiz-tstat[data-info]:focus-visible::after, .quiz-tstat[data-info].tip-open::after { opacity: 1; visibility: visible; transform: translateY(0); }
.quiz-sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.quiz-modal-close { width: 44px; height: 44px; border-radius: 50%; border: 1px solid rgba(255,255,255,0.3); background: rgba(255,255,255,0.12); color: var(--white); cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.18s var(--ease-out-soft); flex-shrink: 0; } /* on-accent */
.quiz-modal-close:hover { background: rgba(255,255,255,0.28); color: var(--white); transform: rotate(90deg); } /* on-accent */
.quiz-modal-close .material-icons-round { font-size: 22px; }
/* Toolbar: mode switch + mobile palette strip */
.quiz-modal-toolbar { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 12px 20px 0; flex-wrap: wrap; }
.quiz-mode-switch { display: inline-flex; gap: 4px; padding: 4px; background: var(--learner-surface-card); border: 1px solid var(--learner-border-default); border-radius: 999px; box-shadow: var(--shadow-soft); }
.quiz-mode-switch button { border: none; background: transparent; border-radius: 999px; padding: 8px 16px; font-family: var(--font-display); font-weight: 500; font-size: 0.88rem; color: var(--learner-text-secondary); cursor: pointer; transition: all 0.18s var(--ease-out-soft); }
.quiz-mode-switch button.on { background: var(--learner-action-primary); color: var(--learner-on-action); box-shadow: none; }
/* The round's status, at the right of the mode switch (moved out of the berry
   header so that band is one row). Quiet on purpose: this is elapsed time in a
   practice round, not a countdown, and a loud clock adds pressure without
   helping anyone learn. It sits on the workspace surface, which flips with the
   theme, so every colour here is a learner token that flips with it. Still a
   44px tap target — a tap opens the same tooltip the header chips had. */
.quiz-toolbar-status { display: flex; align-items: center; gap: 2px; margin-left: auto; }
.quiz-tstat { position: relative; display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 8px; border-radius: 999px; font-family: var(--font-display); font-weight: 600; font-size: 0.88rem; color: var(--learner-text-secondary); font-variant-numeric: tabular-nums; }
.quiz-tstat svg { display: block; flex: none; }
.quiz-tstat[hidden] { display: none; }
.quiz-tstat--streak { color: var(--learner-text-ink); }
.quiz-tstat--streak svg { color: var(--orange); }
/* With a status cluster in the row, the strip takes a row of its own wherever it
   shows (<1020px): beside the switch and the clock it would start mid-row. */
.quiz-toolbar-status ~ .quiz-palette-strip { flex-basis: 100%; }
.quiz-palette-strip { display: none; gap: 8px; overflow-x: auto; scrollbar-width: none; }
.quiz-palette-strip::-webkit-scrollbar { display: none; }
/* No overscroll-behavior on this scroller. A swipe reaching its edge must not
   pan the page behind the sheet (that chained scroll once dragged the fixed
   sheet off-screen in iOS in-app browsers) — and the lock that stops it is
   Quiz.shared.lockSheetScroll, which holds <html> and <body> at overflow:hidden
   for as long as the sheet is open. `overscroll-behavior: contain` used to sit
   here as a second guard, and it was not free: it also swallows the pan of a
   pinch-zoomed visual viewport (Chrome ≥144; CSSWG issue 12919), so a learner who
   zoomed in on a question could not move sideways across it. One lock, not two
   half-locks. Same rule on .qres-overlay in gym-quiz-result.css; pinned by
   tests/sheet-scroll-lock-contract.test.js. */
.quiz-modal-body { padding: 16px 20px 28px; overflow-y: auto; flex: 1 1 auto; min-height: 0; -webkit-overflow-scrolling: touch; background: var(--learner-surface-workspace); }
/* Sheet footer — a static flex row of .quiz-modal-content, below the
   scrolling body. Never position:fixed: a viewport-anchored bar sinks below
   the visible area inside in-app browsers whose layout viewport over-reports
   (core/iab-viewport.js), and it forces guessed padding-bottom compensation
   on the body. As a flow row it cannot cover content and needs neither. */
.quiz-modal-footer { flex: 0 0 auto; padding: 10px 16px calc(10px + env(safe-area-inset-bottom, 0px)); border-top: 1px solid var(--learner-border-default); background: var(--learner-surface-card); backdrop-filter: blur(10px); }
.quiz-modal-footer:empty { display: none; }
/* Action area reads as a dialog footer at any sheet width */
.quiz-modal-footer > * { max-width: 560px; margin-inline: auto; }
/* ── Loading shell (show-first open) — on screen only while the draw is in
   flight. Self-contained in this sheet's own stylesheet on purpose: the
   ec-sk-* skeletons live in gym-exam.css, which is not guaranteed loaded on
   every tab a quiz can open from. */
.quiz-sk { display: flex; flex-direction: column; gap: 14px; max-width: 560px; margin: 8px auto 0; }
.quiz-sk-pulse {
  background: linear-gradient(90deg, var(--surface-sunken) 12%, var(--surface-sunken-strong) 44%, var(--surface-sunken) 88%);
  background-size: 200% 100%;
  animation: quiz-sk-shimmer 1.05s ease-in-out infinite;
  border-radius: 14px;
}
.quiz-sk-stem { height: 72px; }
.quiz-sk-line { height: 14px; width: 62%; }
.quiz-sk-choice { height: 52px; }
@keyframes quiz-sk-shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) {
  .quiz-sk-pulse { animation: none; background: var(--surface-sunken-strong); opacity: 0.8; }
}
/* Arena layout: stage + sticky rail */
.quiz-arena { display: grid; grid-template-columns: minmax(0, 1fr) 290px; gap: 18px; align-items: start; }
.quiz-stage { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.quiz-rail { position: sticky; top: 0; display: flex; flex-direction: column; gap: 14px; }
.quiz-rail-card { background: var(--learner-surface-card); border: 1px solid var(--learner-border-default); border-radius: var(--r-card); padding: 16px; box-shadow: var(--shadow-soft); }
.quiz-rail-card h4 { margin: 0 0 10px; font-family: var(--font-display); font-weight: 600; font-size: 0.9rem; color: var(--learner-text-ink); }
.quiz-palette { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; }
.quiz-pal { aspect-ratio: 1; border-radius: 12px; border: 1.5px solid var(--learner-border-default); background: var(--learner-surface-card); padding: 0; font-family: var(--font-display); font-weight: 700; font-size: 0.95rem; color: var(--learner-text-secondary); display: grid; place-items: center; position: relative; cursor: pointer; transition: all 0.16s var(--ease-out-soft); font-variant-numeric: tabular-nums; }
.quiz-pal:hover { border-color: var(--learner-action-primary); }
.quiz-pal.answered { background: var(--learner-surface-selected); border-color: var(--learner-action-primary); color: var(--learner-action-primary); }
.quiz-pal.revealed { background: var(--amber-light); border-color: var(--amber-300); color: var(--amber-deeper); }
.quiz-pal.current { box-shadow: 0 0 0 2px var(--learner-action-primary); border-color: var(--learner-action-primary); color: var(--learner-action-primary); }
/* Text on the raw -50 tints is the 700 shade: --green-dark (Green-600) read
   3.15:1 and --red-dark 4.41:1 here. The tints do not change in dark, so the
   pair holds in both themes. Mirrored by .qres-pal, .quiz-vchip, .xr-qdot. */
.quiz-pal.right { background: var(--green-50); border-color: var(--green); color: var(--green-deep); }
.quiz-pal.miss { background: var(--red-50); border-color: var(--red); color: var(--red-deep); }
.quiz-pal-flag { position: absolute; top: -4px; right: -4px; width: 12px; height: 12px; background: var(--amber); border: 2px solid var(--white); border-radius: 50%; }
.quiz-palette-strip .quiz-pal { flex: none; width: 44px; height: 44px; aspect-ratio: auto; }
.quiz-legend { display: flex; flex-wrap: wrap; gap: 8px 14px; margin-top: 12px; }
.quiz-legend span { display: inline-flex; align-items: center; gap: 6px; font-size: 0.72rem; color: var(--learner-text-secondary); }
.quiz-legend i { width: 10px; height: 10px; border-radius: 4px; display: inline-block; }
.quiz-legend .ql-answered { background: var(--learner-surface-selected); border: 1px solid var(--learner-action-primary); }
.quiz-legend .ql-revealed { background: var(--amber-light); border: 1px solid var(--amber-300); }
.quiz-legend .ql-none { background: var(--learner-surface-card); border: 1px solid var(--learner-border-default); }
.quiz-legend .ql-flag { background: var(--amber); border-radius: 50%; }
.quiz-stat-row { display: flex; justify-content: space-between; align-items: center; padding: 6px 0; font-size: 0.86rem; color: var(--learner-text-secondary); }
.quiz-stat-row + .quiz-stat-row { border-top: 1px dashed var(--purple-light); }
.quiz-stat-row b { color: var(--learner-text-ink); font-variant-numeric: tabular-nums; }
/* Submit stays in the existing static sheet footer. */
.quiz-fab-submit { width: 100%; display: flex; justify-content: center; align-items: center; gap: 8px; min-height: 52px; padding: 0 20px; border: none; border-radius: 999px; background: var(--learner-action-primary); color: var(--learner-on-action); font-family: var(--font-display); font-weight: 600; font-size: 1rem; cursor: pointer; white-space: nowrap; transition: background 0.16s var(--ease-out-soft); }
.quiz-fab-submit svg { display: block; flex: none; transition: transform 0.18s var(--ease-out-soft); }
.quiz-fab-submit:hover { background: var(--learner-action-hover); }
.quiz-fab-submit:hover svg { transform: translateX(2px) rotate(-12deg); }
.quiz-fab-submit:active { transform: scale(0.99); }
.quiz-fab-submit .material-icons-round { font-size: 20px; }
.quiz-submit-hint { font-size: 0.75rem; color: var(--learner-text-secondary); text-align: center; margin-top: 8px; line-height: 1.5; }
/* The answered count leads the hint and is the one part that never gives way:
   it is the learner's only aggregate count once the header lost its chip. */
.quiz-submit-count { color: var(--learner-text-ink); font-variant-numeric: tabular-nums; }
.quiz-kbd-hints { display: flex; flex-wrap: wrap; gap: 6px 10px; }
.quiz-kbd-hints span { font-size: 0.72rem; color: var(--learner-text-secondary); display: inline-flex; gap: 5px; align-items: center; }
.quiz-kbd-hints kbd { font-family: var(--font-sans); font-size: 0.68rem; font-weight: 700; border: 1px solid var(--learner-border-default); border-bottom-width: 2px; border-radius: 5px; padding: 1px 6px; background: var(--surface-subtle); color: var(--learner-text-ink); }
.quiz-modal:not(.mode-focus) .quiz-focus-only { display: none !important; }
/* Question card */
.quiz-q { background: var(--learner-surface-card); border: 1px solid var(--learner-border-default); border-radius: 24px; box-shadow: var(--shadow-soft); padding: clamp(18px, 2.6vw, 28px); animation: quizCardIn 0.28s var(--ease-out-soft); }
@keyframes quizCardIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.quiz-q-top { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 14px; }
.quiz-q-eyebrow { font-family: var(--font-display); font-weight: 600; font-size: 0.82rem; color: var(--learner-on-action); background: var(--learner-action-primary); padding: 5px 14px; border-radius: 999px; letter-spacing: 0.03em; }
.quiz-diff-pill { display: inline-flex; align-items: center; gap: 6px; font-size: 0.78rem; font-weight: 700; padding: 5px 12px; border-radius: 999px; }
.quiz-diff-pill.qdiff-1 { color: var(--green-700); background: var(--green-50); }
.quiz-diff-pill.qdiff-2 { color: var(--green-deep); background: var(--green-100); }
.quiz-diff-pill.qdiff-3 { color: var(--amber-deeper); background: var(--amber-light); }
.quiz-diff-pill.qdiff-4 { color: var(--red-deep); background: var(--red-50); }
.quiz-diff-pill.qdiff-5 { color: var(--purple-dark); background: var(--purple-light); }
/* Spaced-repetition chip. Same geometry as .quiz-diff-pill on purpose — it sits
   beside it, and a second pill shape would read as a second kind of thing.
   Indigo is deliberately outside the qdiff-1..5 severity ramp: this is not a
   harder question, it is a returning one. */
.quiz-review-pill { display: inline-flex; align-items: center; gap: 5px; font-size: 0.78rem; font-weight: 700; padding: 5px 12px; border-radius: 999px; }
.quiz-review-pill .material-icons-round { font-size: 15px; }
.quiz-review-pill.qrev-pending { color: var(--indigo-700); background: var(--indigo-50); }
/* The payoff state: a question they once missed, now cleared. Same green the
   card already uses for a correct choice, so the meaning needs no learning. */
.quiz-review-pill.qrev-correct { color: var(--green-700); background: var(--green-50); }
/* Missed again — forward-looking, never alarm red: it is still in the queue.
   The notice text/surface pair, not the qdiff-3 amber it first used: that one
   fails WCAG AA in both themes, which the contrast ratchet caught here. */
.quiz-review-pill.qrev-wrong { color: var(--orange-800); background: var(--orange-light); }
.quiz-review-note { font-weight: 600; opacity: 0.75; }
@media (max-width: 420px) { .quiz-review-note { display: none; } }
.quiz-diff-bars { display: inline-flex; gap: 2px; align-items: flex-end; }
.quiz-diff-bars i { width: 3.5px; border-radius: 2px; background: currentColor; opacity: 0.28; }
.quiz-diff-bars i.on { opacity: 1; }
.quiz-diff-bars i:nth-child(1) { height: 5px; }
.quiz-diff-bars i:nth-child(2) { height: 8px; }
.quiz-diff-bars i:nth-child(3) { height: 11px; }
.quiz-diff-bars i:nth-child(4) { height: 14px; }
.quiz-diff-bars i:nth-child(5) { height: 17px; }
.quiz-q-bookmark { margin-left: auto; flex-shrink: 0; width: 44px; height: 44px; border-radius: 50%; border: 1px solid var(--learner-border-default); background: var(--learner-surface-card); color: var(--learner-text-secondary); cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background 0.15s, color 0.15s; padding: 0; }
.quiz-q-bookmark:hover { background: var(--learner-surface-selected); color: var(--learner-action-primary); }
.quiz-q-bookmark.active { color: var(--learner-action-primary); border-color: var(--learner-action-primary); background: var(--learner-surface-selected); }
.quiz-q-bookmark .material-icons-round { font-size: 24px; }
.quiz-q-text { font-family: var(--font-sans); font-weight: 700; font-size: clamp(1.02rem, 2vw, 1.16rem); line-height: 1.65; color: var(--learner-text-ink); margin: 0 0 16px; }
.quiz-q-text .katex-display { min-height: 1.5em; }
/* Outlined choice rows keep short options in the existing two-column layout. */
.quiz-q-choices { display: grid; gap: 10px; }
.quiz-q-choices.cols-2 { grid-template-columns: 1fr 1fr; gap: 10px; }
/* Half a phone-width card leaves a choice roughly 8 glyphs once the label circle
   and gutter are removed, so only the .cols-2--tight set (see choiceGridClass in
   lib/quiz-pure.js) still reads well two-up here. Anything longer wrapped to
   three cramped lines per choice, which is why this used to drop every set to a
   single column — including "ถูก / ผิด". */
@media (max-width: 560px) { .quiz-q-choices.cols-2:not(.cols-2--tight) { grid-template-columns: 1fr; } }
.quiz-choice { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 56px; text-align: left; padding: 11px 12px; border: 1px solid var(--learner-border-interactive); background: var(--learner-surface-card); border-radius: 14px; cursor: pointer; font-family: var(--font-sans); font-size: 1rem; font-weight: 600; line-height: 1.5; color: var(--learner-text-ink); transition: background var(--duration-fast) var(--ease-out-soft); }
.quiz-choice:hover:not(.locked) { background: var(--learner-surface-selected); }
.quiz-choice-label { width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--learner-border-interactive); background: var(--learner-surface-card); color: var(--learner-text-secondary); font-family: var(--font-display); font-weight: 600; font-size: 0.82rem; line-height: 1; display: grid; place-items: center; flex: none; transition: all 0.18s var(--ease-out-soft); }
.quiz-choice:hover:not(.locked) .quiz-choice-label { border-color: var(--learner-action-primary); color: var(--learner-action-primary); }
.quiz-choice.selected { background: var(--learner-surface-selected); border-color: var(--learner-action-primary); }
.quiz-choice.selected .quiz-choice-label { background: var(--learner-action-primary); border-color: var(--learner-action-primary); color: var(--learner-on-action); animation: radioPop 0.25s var(--ease-out-soft); }
@keyframes radioPop { 0% { transform: scale(0.7); } 60% { transform: scale(1.15); } 100% { transform: scale(1); } }
.quiz-choice.selected .quiz-choice-text { color: var(--learner-text-ink); font-weight: 700; }
.quiz-choice.correct { background: var(--success-surface); }
.quiz-choice.correct .quiz-choice-label { background: var(--green); border-color: var(--green); color: var(--white); }
.quiz-choice.wrong { background: var(--danger-surface); }
.quiz-choice.wrong .quiz-choice-label { background: var(--red); border-color: var(--red); color: var(--white); }
.quiz-choice.locked { pointer-events: none; cursor: default; }
.quiz-choice.locked:not(.correct):not(.wrong) { opacity: 1; color: var(--learner-text-secondary); }
.quiz-choice-tag { margin-left: auto; font-size: 0.74rem; font-weight: 700; flex: none; padding-left: 8px; }
.quiz-choice.correct .quiz-choice-tag { color: var(--green-dark); }
.quiz-choice.wrong .quiz-choice-tag { color: var(--red-dark); }
/* Card footer nav — pill buttons */
.quiz-qnav { display: flex; align-items: center; gap: 10px; margin-top: 18px; flex-wrap: wrap; }
.quiz-btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; border-radius: 999px; padding: 11px 20px; font-family: var(--font-display); font-weight: 500; font-size: 0.95rem; border: 1.5px solid transparent; cursor: pointer; transition: all 0.16s var(--ease-out-soft); }
.quiz-btn svg { display: block; flex: none; transition: transform 0.18s var(--ease-out-soft); }
.quiz-btn--ghost { background: var(--learner-surface-card); border-color: var(--learner-border-default); color: var(--learner-text-secondary); box-shadow: var(--shadow-soft); }
.quiz-btn--ghost:hover:not(:disabled) { border-color: var(--learner-action-primary); color: var(--learner-action-primary); }
.quiz-btn--ghost:hover:not(:disabled) svg { transform: translateX(-3px); }
.quiz-btn--ghost:disabled { opacity: 0.4; cursor: default; }
.quiz-btn--reveal { background: var(--learner-surface-support); border-color: var(--learner-border-default); color: var(--learner-text-ink); }
.quiz-btn--reveal:hover:not(:disabled) { background: var(--learner-surface-selected); border-color: var(--learner-action-primary); }
.quiz-btn--reveal:disabled { opacity: 0.45; cursor: default; }
.quiz-btn--next { margin-left: auto; color: var(--learner-on-action); background: var(--learner-action-primary); box-shadow: none; }
.quiz-btn--next:hover { background: var(--learner-action-hover); }
.quiz-btn--next:hover svg { transform: translateX(3px); }
.quiz-btn--next:active { transform: scale(0.99); }
/* Post-submit review actions in the sheet footer: primary CTA spans the full
   row, the redo pair shares one, and the exit rides the saved-note line as a
   text link — two button rows total, so the footer stops crowding out the
   review content it sits under. One layout at every width — the footer caps
   its own width, so no breakpoint variant is needed. */
.quiz-review-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.quiz-review-actions .quiz-btn { width: 100%; margin-left: 0; padding: 10px 12px; font-size: 0.88rem; }
.quiz-review-actions .quiz-btn--next { grid-column: 1 / -1; }
/* Redo-all spans the row on a perfect round, when no "retry wrong" sits beside it */
.quiz-review-actions > .quiz-btn--ghost { grid-column: 1 / -1; }
.quiz-review-actions .quiz-btn--reveal + .quiz-btn--ghost { grid-column: auto; }
/* Status line, not a control — it owns a full grid row so nothing can ever be
   laid beside it. That is a correctness rule here, not spacing taste: it used
   to sit in a wrapping flex row next to a "กลับแดชบอร์ด" link, and Thai has no
   inter-word spaces, so the row broke mid-word and orphaned its separator on
   phone widths.
   This reports submission only; it makes no claim about server persistence. */
.quiz-saved-note { grid-column: 1 / -1; text-align: center; font-size: 0.78rem; line-height: 1.5; font-weight: 700; color: var(--learner-text-secondary); }
/* Tutor chat-bubble explanation */
.quiz-explain { display: flex; gap: 12px; margin-top: 18px; animation: quizCardIn 0.25s var(--ease-out-soft); }
.quiz-tutor-avatar { flex: none; width: 44px; height: 44px; border-radius: 50%; background: var(--gradient-brand); display: grid; place-items: center; font-size: 1.3rem; box-shadow: 0 4px 12px rgba(236,72,153,0.3); }
.quiz-bubble { flex: 1; min-width: 0; background: linear-gradient(180deg, var(--surface-accent-soft), var(--learner-surface-card) 70%); border: 1px solid var(--purple-light); border-radius: 6px 20px 20px 20px; padding: 14px 16px 16px; box-shadow: var(--shadow-raise); }
.quiz-bubble-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.quiz-tutor-name { font-family: var(--font-display); font-weight: 600; font-size: 0.82rem; background: var(--gradient-brand-text); -webkit-background-clip: text; background-clip: text; color: transparent; }
.quiz-vchip { font-size: 0.75rem; font-weight: 700; padding: 3px 12px; border-radius: 999px; }
.quiz-vchip.good { background: var(--green-50); color: var(--green-deep); border: 1px solid var(--green-200); }
.quiz-vchip.bad { background: var(--red-50); color: var(--red-deep); border: 1px solid var(--red-200); }
.quiz-bubble-tldr { font-family: var(--font-display); font-weight: 600; font-size: 1.02rem; color: var(--learner-text-ink); margin: 0 0 10px; }
.quiz-bubble-tldr .ans { color: var(--learner-action-primary); }
.quiz-bubble-body p { margin: 0; font-size: 0.93rem; line-height: 1.75; color: var(--learner-text-ink); font-family: var(--font-sans); font-weight: 500; }
.quiz-bubble-cheer { margin-top: 10px; padding-top: 9px; border-top: 1px dashed var(--purple-200); font-size: 0.85rem; font-weight: 700; color: var(--learner-action-primary); }
/* Rail collapses under 1020px: horizontal palette strip; the submit CTA and
   review actions already live in the sheet footer at every width. */
@media (max-width: 1019px) {
  .quiz-arena { grid-template-columns: 1fr; }
  .quiz-rail { position: static; }
  .quiz-rail-card { display: none; }
  .quiz-palette-strip { display: flex; }
}
.quiz-result { flex: 1; display: flex; align-items: center; gap: 10px; }
@keyframes pulse-correct { 0% { transform: scale(1); } 40% { transform: scale(1.04); } 75% { transform: scale(0.98); } 100% { transform: scale(1); } }
@keyframes shake-wrong { 0%,100% { transform: translateX(0); } 20% { transform: translateX(-8px); } 40% { transform: translateX(8px); } 60% { transform: translateX(-6px); } 80% { transform: translateX(4px); } }
.quiz-choice.correct { animation: pulse-correct 0.4s cubic-bezier(0.34,1.56,0.64,1); }
.quiz-choice.wrong   { animation: shake-wrong 0.38s ease; }
.quiz-choice:active:not(.locked) { transform: scale(0.98); }
@media (max-width: 640px) { .topic-cards { grid-template-columns: 1fr; } }
@media (max-width: 768px) {
  /* Full-bleed sheet. An inset rounded card cannot coexist with the
     viewport-fixed submit bar from the <=1019px block: the bar spans the whole
     width and covered the card's bottom corners. `align-items: stretch` on the
     inset:0 backdrop sizes the sheet to the exact viewport — no dvh guesswork —
     and the keyboard inset is taken off the flex container instead. */
  .quiz-modal { padding: 0; padding-bottom: var(--vv-bottom-inset, 0px); align-items: stretch; }
  .quiz-modal-content { border-radius: 0; border-width: 0; max-width: none; max-height: none; height: auto; min-height: 0; }
  /* Pure tuning on top of the base layout, which already wraps the chips onto
     their own row on its own. The only structural bit left is the order: it
     lifts the close button above the chips so it keeps the top-right corner
     next to the title. A browser that never matches this query (see the
     in-app-browser note on .quiz-modal-header) still gets a legible header —
     the close button just sits below the chip row instead of beside the title. */
  .quiz-modal-header { padding: 14px 16px; gap: 10px; }
  .quiz-modal-meta { order: 1; }
  .quiz-modal-title { font-size: 1.05rem; }
  .quiz-modal-sub { font-size: 0.78rem; }
  .quiz-modal-close { width: 44px; height: 44px; }
  .quiz-modal-close .material-icons-round { font-size: 20px; }
  /* Mode switch + palette each take a row here, so trim both: every pixel of
     chrome comes straight out of the visible question. */
  .quiz-modal-toolbar { padding: 10px 14px 0; gap: 8px; }
  .quiz-mode-switch button { padding: 7px 14px; font-size: 0.84rem; }
  .quiz-palette-strip .quiz-pal { width: 44px; height: 44px; font-size: 0.9rem; }
  .quiz-modal-body { padding: 14px; }
  .quiz-q { border-radius: 20px; padding: 16px; }
  .quiz-q-text { font-size: 1rem; line-height: 1.6; }
  .quiz-q-eyebrow { font-size: 0.78rem; }
  .quiz-q-bookmark { width: 44px; height: 44px; }
  .quiz-q-bookmark .material-icons-round { font-size: 22px; }
  .quiz-choice { padding: 10px; font-size: 0.95rem; gap: 10px; }
  .quiz-choice-label { width: 30px; height: 30px; font-size: 0.78rem; }
  /* Two-up on a phone leaves a choice row about 130px of content box, and the
     "คำตอบที่ถูก" chip alone is half of that. Let the chip take its own line
     under the answer rather than squeeze the answer to a sliver — only in the
     tight grid, since a full-width row has ample space for both. */
  .quiz-q-choices.cols-2--tight .quiz-choice { flex-wrap: wrap; }
  .quiz-q-choices.cols-2--tight .quiz-choice-tag { flex-basis: 100%; margin-left: 40px; padding-left: 0; }
  .quiz-btn { padding: 10px 16px; font-size: 0.9rem; }
  .quiz-explain { gap: 9px; }
  .quiz-tutor-avatar { width: 38px; height: 38px; font-size: 1.1rem; }
}

/* ── Short sheet: the chrome gives way before the primary action does ──
   None of the three chrome bands can yield: the header and footer are
   `flex: 0 0 auto`, and the toolbar declares no `flex` at all, so it is
   nominally shrinkable but held at its content height by `min-height: auto`,
   the automatic minimum size of a flex item. .quiz-modal-body is therefore the
   only band that gives, and once it bottoms out at its own padding (28px at
   <=768px) the chrome overflows the sheet and is clipped from the BOTTOM —
   which is where the submit button lives. Measured at 375 wide: chrome is
   313.7px before submit and 356.4px in review, so the review sheet starts
   losing its footer below 384px of height and the learner has no way to send
   their answers. (Widths 320-412 all measure the same; at 430 the header stops
   wrapping and the floor drops to 338.)

   Why a container query and not `@media (max-height:)`: the two numbers are
   not the same one. `innerHeight` is the LAYOUT viewport, which in-app browsers
   (LINE, FB, IG) over-report — that is why core/iab-viewport.js exists and why
   the .quiz-modal-header comment above refuses a width breakpoint for the same
   reason. --vv-bottom-inset is this app's correction, and .quiz-modal already
   subtracts it, so the query container's own height IS the usable height even
   where the media query would be reading a lie.

   The unit is `rem` on purpose. Every band here is sized by rem-based type, so
   a learner's larger text setting grows the chrome (313.7 -> 417.9px at a 28px
   root) while the viewport does not move. A px threshold would stop engaging in
   time exactly when the chrome needs it most; `rem` in a container query
   resolves against the root font size, so the trigger grows with what it is
   protecting against. 27rem is 432px at the default root — above the 384px
   where the tallest state breaks, and far below the ~577px a phone still has in
   portrait behind an in-app-browser toolbar, so ordinary use never sees this.

   What gives way is chosen by what a learner loses. The palette strip is a
   jump-to-any-question shortcut: flow mode has every question in the body, and
   focus mode carries its own prev/next inside the card, so dropping it costs a
   shortcut, not a capability — and the mode switch beside it, which is the
   escape hatch back to flow, is deliberately kept. The other two are advisory
   prose whose actions remain on screen either way. Measured against the reasons
   NOT to touch the rest: the header's .quiz-modal-sub and .quiz-modal-maintopic
   look like the obvious candidates and are worth 6.7px and 0px respectively —
   the header is sized by its wrapped chip row, not by its text lines — and the
   chips themselves are the learner's only answered-count. This buys back 72px
   before submit and 73px in review, moving the no-clip floors from 342 -> 270
   and 384 -> 312, and the height at which the primary action goes off screen
   from 306 -> 260 and 297 -> 251. Rejected on measurement rather than taste:
   giving a chrome band `min-height: 0` so flex can shrink it clips the toolbar
   at EVERY height (100 -> 33.1px at a 700px viewport), because flex shares
   shrinkage in proportion to each item's basis and the body's basis is the
   full height of every question card — flex cannot express "shrink me only
   after the body is exhausted".

   2026-11-03: the header chips left the header (it is now one row of title +
   ✕; the clock moved to the toolbar, the answered count to the head of the
   submit hint). So the hint no longer goes whole: its advice gives way and its
   count stays, because the count is now what the chips were — the learner's
   only aggregate answered-count. */
@container quizsheet (max-height: 27rem) {
  .quiz-palette-strip { display: none; }
  .quiz-submit-advice,
  .quiz-saved-note { display: none; }
}

/* ── Topic cards (used by gym-dashboard-main-grid.js) ── */
.topic-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; margin-bottom: 24px; }
.topic-card { background: var(--surface-card); border: 2px solid var(--border-default); border-radius: var(--radius-md); padding: 20px; transition: var(--transition); display: flex; flex-direction: column; gap: 12px; position: relative; }
.topic-card:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(0,0,0,0.08); }
.topic-card-head     { display: flex; align-items: center; gap: 10px; }
.topic-icon          { font-size: 28px; flex-shrink: 0; }
.topic-icon.passed   { color: var(--green); }
.topic-icon.inprogress { color: var(--danger); }
.topic-icon.new      { color: var(--blue-400); }
.topic-icon.empty    { color: var(--text-tertiary); }
.topic-card-title    { font-weight: 600; color: var(--text-ink); font-size: 1rem; flex: 1; }
.topic-card-sub      { font-size: 0.85rem; color: var(--text-secondary); font-weight: 500; }
.topic-card-btn      { flex: 1; justify-content: center; }
.topic-card-actions  { display: flex; gap: 8px; align-items: center; margin-top: 2px; }
.btn-youtube         { display: inline-flex; align-items: center; gap: 5px; padding: 6px 12px; border-radius: 8px; font-size: 0.82rem; font-weight: 600; background: var(--youtube); color: var(--white); text-decoration: none; transition: 0.2s; white-space: nowrap; flex-shrink: 0; }
.btn-youtube:hover   { background: var(--youtube-dark); transform: translateY(-1px); }

/* ── Dashboard accordion ── */
.dash-accordion { display: flex; flex-direction: column; gap: 10px; margin-bottom: 24px; }
.dac-item {
  background: color-mix(in srgb, var(--surface-card) 78%, transparent);
  border-radius: 24px;
  border: 1px solid rgba(214, 207, 226, 0.62);
  border: 1px solid light-dark(rgba(214, 207, 226, 0.62), rgba(59, 52, 86, 0.62));
  box-shadow: 0 12px 25px rgba(110, 92, 150, 0.05);
  overflow: hidden;
  transition: box-shadow 0.2s, background 0.2s;
}
.dac-item.open {
  background: rgba(248, 244, 255, 0.95);
  background: light-dark(rgba(248, 244, 255, 0.95), rgba(38, 30, 61, 0.95));
  box-shadow: 0 16px 32px rgba(110, 92, 150, 0.1);
}
.dac-header {
  display: grid;
  grid-template-columns: 58px minmax(0, 1fr) 34px;
  align-items: center;
  gap: 17px;
  padding: 24px 23px 22px;
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.dac-icon-wrap { width: 58px; height: 58px; border-radius: 13px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.dac-icon-wrap .material-icons-round { font-size: 34px; }
.dac-icon-wrap[data-course="calc1"] { background: var(--course-calc1-surface); color: var(--course-calc1-fg); }
.dac-icon-wrap[data-course="calc2"] { background: var(--course-calc2-surface); color: var(--course-calc2-fg); }
.dac-icon-wrap[data-course="calc3"] { background: var(--course-calc3-surface); color: var(--course-calc3-fg); }
.dac-header-text { min-width: 0; }
.dac-title { font-size: 21px; font-weight: 900; color: var(--text-ink); line-height: 1.25; }
.dac-chevron { color: var(--text-tertiary); background: transparent; display: inline-flex; justify-content: center; align-items: center; flex-shrink: 0; font-size: 32px; transition: transform 0.25s, color 0.2s; }
.dac-item.open .dac-chevron { transform: rotate(180deg); color: var(--accent-strong); }
.dac-body { padding: 4px 10px 10px; }
/* Subtopic status icon (no-bank rows only) */
.dac-sub-status { width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.dac-sub-status .material-icons-round { font-size: 17px; }
.dac-sub-nobank .dac-sub-status { background: var(--surface-subtle); color: var(--text-disabled); }
.dac-sub-nobank .dac-sub-title { color: var(--text-tertiary); }
.exam-scope-badges { display: inline-flex; align-items: center; gap: 2px; flex-shrink: 0; }
.esb-badge { display: inline-flex; align-items: center; justify-content: center; width: 15px; height: 15px; border-radius: 50%; font-size: 8px; font-weight: 700; line-height: 1; flex-shrink: 0; }
.esb-badge.esb-m    { background: var(--blue-light); color: var(--blue-600); border: 1.5px solid var(--blue-300); }
.esb-badge.esb-f    { background: var(--yellow-100); color: var(--amber-deep); border: 1.5px solid var(--amber-300); }
.esb-badge.esb-none { border: 1.5px solid var(--border-strong); background: transparent; }
.dac-sub-right { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
.dac-no-quiz   { color: var(--text-disabled); font-size: 0.78rem; text-align: center; padding: 8px 0 4px; }

/* ── Dashboard search (used by gym-dashboard-search.js) ── */
.dash-sr-header { padding: 10px 14px 6px; font-size: 0.78rem; font-weight: 700; color: var(--text-tertiary); text-transform: uppercase; letter-spacing: 0.05em; border-bottom: 1px solid var(--border-faint); }
.dash-sr-card { padding: 12px 14px; border-bottom: 1px solid var(--border-faint); transition: background 0.12s; }
.dash-sr-card:last-child { border-bottom: none; }
.dash-sr-card:hover { background: var(--surface-subtle); }
.dash-sr-name { font-size: 0.9rem; font-weight: 700; color: var(--text-ink); line-height: 1.35; }
.dash-sr-name mark { background: rgba(168,85,247,0.18); color: var(--accent-deep); border-radius: 3px; padding: 0 1px; font-weight: 700; }
.dash-sr-en { display: block; font-size: 0.75rem; font-weight: 500; color: var(--text-tertiary); }
.dash-sr-main { font-size: 0.73rem; color: var(--text-tertiary); margin-top: 2px; font-weight: 500; }
.dash-sr-tags { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 5px; }
.dash-sr-tag { font-size: 0.65rem; padding: 1px 6px; border-radius: 99px; font-weight: 600; }
.dash-sr-tag.in-plan { background: var(--success-surface); color: var(--success-fg-strong); }
.dash-sr-tag.mid     { background: var(--surface-accent); color: var(--accent-deep); }
.dash-sr-tag.fin     { background: var(--warning-surface); color: var(--warning-fg); }
.dash-sr-actions { display: flex; align-items: center; gap: 7px; margin-top: 10px; flex-wrap: wrap; }
.dash-sr-add-label { font-size: 0.75rem; color: var(--text-secondary); font-weight: 500; }
.dash-sr-act-btn { display: inline-flex; align-items: center; gap: 5px; padding: 7px 13px; border-radius: 10px; border: none; font-size: 0.78rem; font-weight: 700; cursor: pointer; font-family: inherit; transition: all 0.13s; }
.dash-sr-act-btn .material-icons-round { font-size: 15px; }
.dash-sr-quiz-btn { background: linear-gradient(135deg,var(--accent-strong),var(--accent-deep)); color: var(--white); box-shadow: 0 2px 8px rgba(124,58,237,0.25); }
.dash-sr-quiz-btn:hover { box-shadow: 0 3px 12px rgba(124,58,237,0.35); transform: translateY(-1px); }
.dash-sr-vid-btn { background: linear-gradient(135deg,var(--rose-500),var(--rose-600)); color: var(--white); box-shadow: 0 2px 8px rgba(244,63,94,0.25); }
.dash-sr-vid-btn:hover { box-shadow: 0 3px 12px rgba(244,63,94,0.35); transform: translateY(-1px); }
.dash-sr-no-bank { font-size: 0.73rem; color: var(--text-disabled); }
.dash-exam-pick-btn { padding: 5px 10px; border-radius: 8px; border: 1.5px solid var(--border-default); background: var(--surface-card); font-size: 0.75rem; font-weight: 600; cursor: pointer; font-family: inherit; transition: all 0.13s; }
.dash-exam-pick-btn:hover { border-color: var(--accent); color: var(--accent-strong); background: var(--surface-accent-soft); }
.dash-exam-pick-btn.mid  { border-color: var(--accent); background: var(--surface-accent); color: var(--accent-deep); }
.dash-exam-pick-btn.fin  { border-color: var(--amber); background: var(--warning-surface); color: var(--warning-fg); }
.dash-exam-pick-btn.both { border-color: var(--green); background: var(--green-100); color: var(--green-800); }
.dash-sr-loading { text-align: center; padding: 16px; color: var(--text-tertiary); font-size: 0.85rem; }
.dash-sr-empty   { text-align: center; padding: 24px 16px; color: var(--text-tertiary); font-size: 0.85rem; }

@media (prefers-reduced-motion: reduce) {
  .quiz-choice.correct,
  .quiz-choice.wrong { animation: none !important; }
  .quiz-choice-label, .quiz-hchip, .quiz-tstat, .quiz-q, .quiz-explain { animation: none !important; }
  .quiz-hchip[data-info]::after, .quiz-tstat[data-info]::after { transition: none !important; }
  .quiz-choice:active:not(.locked) { transform: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   SUBJECT STEP — manual plan creation, step 1 of 2
   A plan belongs to exactly one subject, so the subject is a scope decision
   taken before topics, not a filter sitting next to the chapter chips.
   Shared semantic colour roles are checked by scripts/css-hex-guard.js.
   ═══════════════════════════════════════════════════════════════════════════ */

.add-topic-header-side {
  display: flex;
  align-items: center;
  gap: var(--space-2-5);
  flex-shrink: 0;
}

/* Subject context pill — step 2, so the active subject stays visible while
   picking topics, with the way back to step 1 attached to it. */
.add-topic-subject-ctx {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1-5);
  padding: var(--space-1) var(--space-1) var(--space-1) var(--space-2-5);
  border-radius: var(--r-pill);
  border: 1px solid var(--gm-border-default);
  background: var(--gm-surface-selected);
  color: var(--gm-action-primary);
  font-family: var(--font-display);
  font-size: var(--text-sm);
  font-weight: 700;
  white-space: nowrap;
}
.add-topic-subject-ctx[hidden] { display: none; }
.add-topic-subject-ctx .material-icons-round { font-size: 16px; }
.atsc-change {
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: var(--text-xs);
  font-weight: 600;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--r-pill);
  text-decoration: underline;
  cursor: pointer;
  min-height: 44px;
  transition: opacity 0.15s ease, background 0.15s ease;
}
.atsc-change:hover { opacity: 1; background: var(--surface-accent); }

/* ── Stage ───────────────────────────────────────────────────────────────── */
.add-topic-subject-stage {
  flex: 1; min-height: 0; overflow-y: auto;
  padding: 10px 28px 24px;
}
.add-topic-subject-stage[hidden] { display: none; }
.atss-progress { display: flex; gap: 12px; list-style: none; margin: 0 0 24px; padding: 0; }
.atss-progress li { display: flex; align-items: center; flex: 1; gap: 8px; color: var(--gm-text-secondary); font-size: 12px; }
.atss-progress li:not(:last-child)::after { content: ''; flex: 1; height: 1px; background: var(--gm-border-default); }
.atss-progress li > span { display: grid; place-items: center; flex-shrink: 0; width: 29px; height: 29px; border-radius: var(--r-pill); background: var(--gm-surface-support); }
.atss-progress b { font-weight: 500; }
.atss-progress [aria-current="step"] { color: var(--gm-action-primary); }
.atss-progress [aria-current="step"] > span { background: var(--gm-action-primary); color: var(--gm-on-action); }
/* A step already taken wears a check, so step 2 reads as «one of two, one done». */
.atss-progress .is-done > span { background: var(--success-surface); color: var(--success-fg-strong); }
.atss-progress .is-done .material-icons-round { font-size: 15px; }

/* ── The lead ─────────────────────────────────────────────────────────────
   The step's heading, and — on the account's FIRST plan — an eyebrow, one
   reassurance and a small code-native illustration beside the copy. Which
   variant shows is read off `data-first-plan`, which plan-subject-stage.js
   writes on the dialog's content on every open; nothing is stored. */
.atss-lead { text-align: start; margin-bottom: 20px; }
.atss-lead h3 { margin: 0; font-family: var(--font-display); font-size: 1.8rem; font-weight: 500; line-height: 1.45; color: var(--gm-text-ink); text-wrap: balance; }
/* The heading takes focus when a stage is entered (an announcement, not a control). */
.atss-lead h3:focus { outline: none; box-shadow: none; }
.atss-lead p { margin: 6px 0 0; color: var(--gm-text-secondary); font-size: 0.875rem; line-height: 1.7; }
.atss-eyebrow, .atss-lead-note, .atss-art { display: none; }
.add-topic-content[data-first-plan="true"] .add-topic-subject-stage .atss-lead {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0 24px; align-items: center;
}
.add-topic-content[data-first-plan="true"] .atss-eyebrow {
  display: block; margin-bottom: 4px;
  font-family: var(--font-display); font-size: var(--text-xs); font-weight: 600; color: var(--gm-action-primary);
}
.add-topic-content[data-first-plan="true"] .atss-lead-note {
  display: flex; align-items: flex-start; gap: 6px; margin-top: 10px;
  font-size: var(--text-xs); line-height: 1.6; color: var(--gm-text-secondary);
}
.atss-lead-note .material-icons-round { font-size: 16px; color: var(--gm-action-primary); flex-shrink: 0; }
.add-topic-content[data-first-plan="true"] .atss-art { display: block; width: 168px; height: auto; grid-column: 2; grid-row: 1; }
.atss-art-wash { fill: var(--gm-surface-selected); }
.atss-art-tint { fill: var(--gm-surface-support); }
.atss-art-paper { fill: var(--gm-surface-card); stroke: var(--gm-border-default); stroke-width: 1.5; }
.atss-art-axis { fill: none; stroke: var(--gm-border-interactive); stroke-width: 1.5; stroke-linecap: round; }
.atss-art-line { fill: none; stroke: var(--gm-action-primary); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.atss-art-curve { fill: none; stroke: var(--gm-action-primary); stroke-width: 2.5; stroke-linecap: round; }
.atss-art-solid { fill: var(--gm-action-primary); }

/* ── The cards ───────────────────────────────────────────────────────────── */
.atss-grid { display: grid; grid-template-columns: 1fr; gap: 12px; width: 100%; }
.atss-card {
  position: relative; display: grid; grid-template-columns: 52px minmax(0, 1fr) 24px;
  gap: 6px 16px; align-items: center; text-align: start;
  padding: 20px; border: 1px solid var(--gm-border-default); border-radius: 18px;
  background: var(--gm-surface-card); color: var(--gm-text-ink); font: inherit;
  box-shadow: var(--gm-shadow-card); cursor: pointer;
  transition: border-color .18s, background .18s, box-shadow .18s, transform .18s;
}
.atss-card:hover { border-color: var(--gm-action-primary); transform: translateY(-2px); box-shadow: 0 10px 24px color-mix(in srgb, var(--gm-action-primary) 14%, transparent); }
.atss-card:focus-visible { outline: 3px solid var(--gm-focus-ring); outline-offset: 3px; }
.atss-card[aria-current="true"] { border-color: var(--gm-action-primary); background: var(--gm-surface-selected); box-shadow: inset 0 0 0 1px var(--gm-action-primary); }
.atss-card.is-loading { opacity: .65; pointer-events: none; }
.atss-icon { grid-column: 1; grid-row: 1 / 6; display: grid; place-items: center; width: 52px; height: 56px; border-radius: 16px; background: var(--gm-surface-support); color: var(--gm-action-primary); }
.atss-icon .material-icons-round { font-size: 26px; }
.atss-name { grid-column: 2; font-family: var(--font-display); font-size: 1.15rem; font-weight: 500; line-height: 1.5; }
.atss-meta { grid-column: 2; display: flex; flex-wrap: wrap; gap: 8px; }
.atss-stat { font-size: .8rem; color: var(--gm-text-secondary); font-variant-numeric: tabular-nums; }
.atss-stat b { font-weight: 600; }
.atss-chapters { grid-column: 2; display: flex; flex-wrap: wrap; gap: 4px; }
.atss-chip { color: var(--gm-text-secondary); font-size: .75rem; }
.atss-chip:not(:last-child)::after { content: ' ·'; }
/* The step's one action, inside the card button itself (the card is what
   advances; a second control would compete with it). */
.atss-cta {
  grid-column: 2; justify-self: start; display: inline-flex; align-items: center; gap: 6px;
  margin-top: 6px; min-height: 36px; padding: 0 14px 0 16px; border-radius: var(--r-pill);
  background: var(--gm-action-primary); color: var(--gm-on-action);
  font-family: var(--font-display); font-size: .85rem; font-weight: 500; transition: background .18s;
}
.atss-card:hover .atss-cta { background: var(--gm-action-hover); }
.atss-cta .material-icons-round { font-size: 17px; }
.atss-check { grid-column: 3; grid-row: 1 / 6; display: grid; place-items: center; width: 22px; height: 22px; border-radius: var(--r-pill); border: 1px solid var(--gm-border-default); background: var(--gm-surface-card); color: transparent; }
.atss-card[aria-current="true"] .atss-check { background: var(--gm-action-primary); color: var(--gm-on-action); border-color: var(--gm-action-primary); }
.atss-check .material-icons-round { font-size: 16px; }
/* Locked: still listed with its real counts, secondary in weight, never a target. */
.atss-card.locked { grid-template-columns: 40px minmax(0, 1fr); gap: 4px 12px; padding: 14px 16px; cursor: not-allowed; background: var(--gm-surface-workspace); box-shadow: none; }
.atss-card.locked:hover { border-color: var(--gm-border-default); transform: none; box-shadow: none; }
.atss-card.locked .atss-icon { width: 40px; height: 44px; color: var(--gm-text-secondary); background: var(--gm-surface-card); }
.atss-card.locked .atss-icon .material-icons-round { font-size: 22px; }
.atss-card.locked .atss-name { font-size: 1rem; color: var(--gm-text-secondary); }
.atss-card.locked .atss-check { display: none; }
.atss-lock { grid-column: 2; grid-row: 1; display: flex; gap: 4px; align-items: center; color: var(--gm-text-secondary); font-size: .75rem; }
.atss-lock .material-icons-round { font-size: 14px; }

/* ── Step-1 state: the topic-picking chrome has nothing to act on yet; the
   footer keeps its left half to say what a tap does. ─────────────────────── */
.add-topic-content.is-subject-step .add-topic-filter-bar,
.add-topic-content.is-subject-step .add-topic-guidance,
.add-topic-content.is-subject-step .add-topic-body { display: none; }
.add-topic-content-v2.is-subject-step .add-topic-count { font-size: var(--text-sm); font-weight: 500; color: var(--gm-text-secondary); }

@media (max-width: 759px) {
  .add-topic-subject-stage { padding: 8px 16px 20px; }
  .atss-progress { margin-bottom: 12px; }
  .atss-lead { margin-bottom: 14px; }
  .atss-lead h3 { font-size: 1.4rem; }
  .atss-card { padding: 16px 12px; gap: 5px 10px; grid-template-columns: 42px minmax(0, 1fr) 22px; }
  .atss-icon { width: 42px; height: 48px; }
  .atss-name { font-size: 1rem; }
  /* The welcome stays compact: a small figure beside the eyebrow, the heading
     at full width under it — never a band above the cards. */
  .add-topic-content[data-first-plan="true"] .add-topic-subject-stage .atss-lead { gap: 0 12px; align-items: center; }
  .add-topic-content[data-first-plan="true"] .add-topic-subject-stage .atss-lead-copy { display: contents; }
  .add-topic-content[data-first-plan="true"] .atss-eyebrow { grid-column: 1; grid-row: 1; margin-bottom: 0; }
  .add-topic-content[data-first-plan="true"] .atss-art { width: 64px; grid-column: 2; grid-row: 1; }
  .add-topic-content[data-first-plan="true"] .add-topic-subject-stage .atss-lead :is(h3, p) { grid-column: 1 / -1; }
}
@media (max-width: 359px) {
  .add-topic-content[data-first-plan="true"] .add-topic-subject-stage .atss-lead { grid-template-columns: minmax(0, 1fr); }
  .add-topic-content[data-first-plan="true"] .atss-art { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .atss-card, .atss-cta { transition: none; }
  .atss-card:hover { transform: none; }
}

/* `hidden` must win over .btn { display:inline-flex } for the step-swapped
   footer buttons — attribute selectors lose to the class rule otherwise. */
.add-topic-actions .btn[hidden] { display: none; }

/* Narrow screens: the subject pill must not squeeze the title into a one-word
   column. Grid re-flow — title | close on row 1, pill on its own full row. */
@media (max-width: 700px) {
  .add-topic-content-v2 .add-topic-header {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: start;
    gap: var(--space-2) var(--space-2-5);
  }
  .add-topic-header-side { display: contents; }
  .add-topic-subject-ctx {
    grid-column: 1 / -1;
    order: 3;
    justify-self: start;
  }
}

/* ── Step 2: the template picker (features/shell/plan-template-step.js) ──────
   Two groups of tap-to-select cards using shared semantic colour roles. */
.add-topic-template-stage {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 10px 28px 24px;
}
.add-topic-template-stage[hidden] { display: none; }
.ptp-groups {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  max-width: 760px;
  width: 100%;
  margin: 0 auto;
}
.ptp-group-h {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0 var(--space-1) var(--space-2);
}
.ptp-group-h b {
  font-family: var(--font-display);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gm-action-primary);
}
.ptp-group-h span { font-size: var(--text-xs); color: var(--gm-text-secondary); font-weight: 500; }
.ptp-grid { display: grid; grid-template-columns: 1fr; gap: var(--space-2); }
.ptp-card {
  display: grid;
  grid-template-columns: 42px minmax(0, 1fr) 28px;
  gap: var(--space-3);
  align-items: center;
  width: 100%;
  text-align: left;
  padding: 16px;
  border-radius: 18px;
  background: var(--gm-surface-card);
  border: 1.5px solid var(--gm-border-default);
  box-shadow: none;
  color: inherit;
  font: inherit;
  font-family: var(--font-sans);
  cursor: pointer;
  transition: transform 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease, background-color 0.18s ease;
}
.ptp-card:hover:not([disabled]) {
  transform: translateY(-2px);
  border-color: color-mix(in srgb, var(--gm-action-primary) 45%, transparent);
  box-shadow: 0 10px 24px color-mix(in srgb, var(--gm-action-primary) 14%, transparent);
}
.ptp-card:focus-visible { outline: 2px solid var(--gm-action-primary); outline-offset: 2px; }
.ptp-card[aria-checked="true"] {
  border-color: var(--gm-action-primary); background: var(--gm-surface-selected);
  box-shadow: inset 0 0 0 1px var(--gm-action-primary);
}
/* Locked: still listed and named as locked, never hidden — and not a target. */
.ptp-card[disabled] { cursor: not-allowed; background: var(--surface-sunken); border-color: transparent; box-shadow: none; }
.ptp-tile {
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--text-sm);
  letter-spacing: -0.02em;
  color: var(--gm-action-primary);
  border-radius: var(--radius-sm);
  background: var(--gm-surface-support);
  border: 1px solid transparent;
}
/* A chapter's tile is round, a course's square — the kind, said without a word. */
.ptp-card[data-kind="chapter"] .ptp-tile { border-radius: var(--r-pill); }
.ptp-card[disabled] .ptp-tile { color: var(--gm-text-secondary); background: var(--gm-surface-card); border-color: var(--border-default); }
.ptp-copy { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.ptp-label {
  font-family: var(--font-display);
  font-size: 0.95rem;
  font-weight: 500;
  line-height: 1.5;
  color: var(--gm-text-ink);
  display: flex;
  align-items: center;
  gap: var(--space-1-5);
}
.ptp-label em {
  font-style: normal;
  font-family: var(--font-sans);
  font-size: 0.68rem;
  font-weight: 700;
  padding: 1px 7px;
  border-radius: var(--r-pill);
  background: var(--success-surface);
  color: var(--success-fg-strong);
  border: 1px solid var(--success-border);
}
/* The second line: a course's title on one line, a chapter's first topics on up to two. */
.ptp-title {
  font-size: var(--text-xs);
  color: var(--gm-text-secondary);
  font-weight: 500;
  line-height: var(--leading-snug);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.ptp-card[data-kind="course"] .ptp-title { -webkit-line-clamp: 1; }
.ptp-meta {
  font-size: 0.72rem;
  color: var(--gm-text-secondary);
  font-weight: 600;
  margin-top: 2px;
  font-variant-numeric: tabular-nums;
}
.ptp-meta .ptp-part { color: var(--warning-fg); }
.ptp-card[disabled] .ptp-label, .ptp-card[disabled] .ptp-title { color: var(--gm-text-secondary); }
.ptp-state {
  width: 28px;
  height: 28px;
  border-radius: var(--r-pill);
  display: grid;
  place-items: center;
  color: var(--gm-text-secondary);
  border: 1.5px solid var(--border-default);
  background: var(--gm-surface-card);
}
.ptp-state .material-icons-round { font-size: 17px; }
.ptp-card[aria-checked="true"] .ptp-state {
  background: var(--gm-action-primary);
  border-color: var(--gm-action-primary);
  color: var(--gm-on-action);
}
.ptp-card[disabled] .ptp-state { border-color: transparent; background: transparent; }
/* The by-hand picker, one link away — a text button, never a card. */
.ptp-alt {
  display: block;
  margin: var(--space-6) auto 0;
  padding: var(--space-2) var(--space-3);
  min-height: 44px;
  border: none;
  background: transparent;
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--gm-action-primary);
  cursor: pointer;
  border-radius: var(--r-control);
}
.ptp-alt:hover { background: var(--surface-accent); }
.ptp-alt:focus-visible { outline: 2px solid var(--accent-strong); outline-offset: 2px; }
.ptp-alt .material-icons-round { font-size: 16px; vertical-align: -3px; }
/* Template-step state: the picker's chrome is idle, the footer stays. */
.add-topic-content.is-template-step .add-topic-filter-bar,
.add-topic-content.is-template-step .add-topic-guidance,
.add-topic-content.is-template-step .add-topic-body { display: none; }
.add-topic-count-note { display: block; font-size: var(--text-xs); color: var(--warning-fg); font-weight: 600; }
.add-topic-count-note[hidden] { display: none; }
@media (min-width: 760px) {
  .ptp-grid { grid-template-columns: 1fr 1fr; gap: var(--space-2-5); }
  .ptp-group-h { flex-direction: row; align-items: baseline; justify-content: space-between; gap: var(--space-2-5); }
}
/* Phone (the modal's own breakpoint, where its footer becomes a grid): the
   lead sits tighter so the first card begins in the top third, and the
   summary line — the point of this step — takes a row of its own with the
   two buttons sharing the next. */
@media (max-width: 759px) {
  /* Keep real choices high on the phone; the steps share the header row. */
  .add-topic-content.is-template-step .add-topic-title { visibility: hidden; }
  .add-topic-template-stage .atss-progress { position: absolute; top: 24px; left: 16px; right: 76px; margin: 0; }
  .add-topic-template-stage .ptp-group-h span { display: none; }
  .add-topic-template-stage { padding: 8px 16px 20px; }
  .add-topic-content-v2:is(.is-subject-step, .is-template-step) .add-topic-footer { position: static; background: var(--gm-surface-card); }
  .add-topic-template-stage .atss-lead { margin-bottom: var(--space-2); }
  .add-topic-template-stage .atss-lead p { margin-top: var(--space-1); }
  .add-topic-template-stage .ptp-group-h { margin-bottom: var(--space-1-5); }
  .add-topic-content.is-template-step .add-topic-footer { grid-template-columns: 1fr; }
  .add-topic-content.is-template-step .add-topic-actions { display: flex; gap: var(--space-2); }
  .add-topic-content.is-template-step .add-topic-actions .btn { flex: 1 1 0; justify-content: center; }
}
@media (prefers-reduced-motion: reduce) {
  .ptp-card { transition: none; }
  .ptp-card:hover:not([disabled]) { transform: none; }
}
