/* ============================================================
   Jobburg UI kit — jobburg-blocks.css
   Единый источник стилей всех блоков. Подключается один раз
   на весь фронтенд; эталонные страницы и спецификации — в
   jobburg-ui-kit.md. Не редактировать значения токенов локально.
   Разделы:
     1. Токены        2. База и типографика   3. Кнопки
     4. Бейджи        5. Формы                6. Таблицы
     7. Алерты        8. SectionCard/Collapse 9. PageHeader/Footer
    10. ActionBanner 11. StatStrip           12. Funnel/Bars/Chips
    13. KeyValueRow  14. ApplicationCard     15. StepsNav
    16. AuthScreens  17. EmptyState/CheckRow/Switch/SelectBar
    18. Утилиты и адаптив                     19. Онбординг (TourStep/CoachHint)
    20. Помощник (HelperPanel)              21. Tabs (вкладки кейса)
    22. TaskStrip    23. ChipEditor         24. Modal
    25. NavMenu (меню разделов)  26. Breadcrumbs (путь до страницы)
   ============================================================ */

/* 1. ТОКЕНЫ ---------------------------------------------------- */
:root {
  --jb-blue: #2E5CFF;
  --jb-blue-hover: #2149DB;
  --jb-blue-active: #1B3DBE;
  --jb-blue-bg: #EAF0FF;
  --jb-blue-border: #C9D7FF;
  --jb-amber: #FFB020;          /* декоративный акцент; для кнопок — ТОЛЬКО CTA внутри .jb-hero (ревизия 14.08.2026, раздел 25) */
  --jb-ink: #0F172A;
  /* Размер заголовка третьего уровня. Токеном, а не числом в правиле: экранам
     иногда нужно приравнять к подзаголовку НЕ-заголовочный элемент (должность
     в шапке разбора оценки — решение владельца 18.08.2026), и без токена они
     держали бы копию этого числа у себя. Копия разъезжается молча. */
  --jb-h3-size: 19px;

  --jb-text: #0F172A;
  --jb-text-secondary: #475569;
  --jb-text-muted: #64748B;
  --jb-border: #E2E8F0;
  --jb-border-strong: #CBD5E1;
  --jb-bg: #F4F6FA;
  --jb-surface: #FFFFFF;

  --jb-success: #16A34A; --jb-success-bg: #E8F7EE; --jb-success-border: #B7E4C7;
  --jb-warning: #B45309; --jb-warning-bg: #FFF4DC; --jb-warning-border: #FFDD99;
  --jb-danger:  #DC2626; --jb-danger-bg:  #FDECEC; --jb-danger-border:  #F5B5B5;
  --jb-info:    #2E5CFF; --jb-info-bg:    #EAF0FF; --jb-info-border:    #C9D7FF;

  --jb-radius-sm: 6px;
  --jb-radius-md: 10px;
  --jb-radius-lg: 14px;
  --jb-shadow-sm: 0 1px 3px rgba(15, 23, 42, .07);
  --jb-shadow-md: 0 6px 24px rgba(15, 23, 42, .10);
  --jb-focus-ring: 0 0 0 3px rgba(46, 92, 255, .35);

  --jb-font: 'Montserrat', -apple-system, 'Segoe UI', Helvetica, Arial, sans-serif;
}

/* 2. БАЗА И ТИПОГРАФИКА ---------------------------------------- */
.jb-body,
body.jb {
  margin: 0;
  font-family: var(--jb-font);
  font-size: 15px;
  line-height: 1.6;
  color: var(--jb-text);
  background: var(--jb-bg);
}
/* обязательный резет: без него input/textarea со width:100% вылезают за карточки */
.jb, .jb *, .jb *::before, .jb *::after { box-sizing: border-box; }
.jb h1, .jb-h1 { font-size: 32px; font-weight: 800; letter-spacing: -.5px; line-height: 1.2; }
.jb h2, .jb-h2 { font-size: 24px; font-weight: 700; letter-spacing: -.3px; line-height: 1.25; }
.jb h3, .jb-h3 { font-size: var(--jb-h3-size); font-weight: 700; line-height: 1.3; }
.jb a { color: var(--jb-blue); text-decoration: none; }
.jb a:hover { color: var(--jb-blue-hover); text-decoration: underline; }
.jb-num  { font-variant-numeric: tabular-nums; }
.jb-tiny { font-size: 13px; color: var(--jb-text-muted); }
.jb-logo { font-weight: 800; letter-spacing: -.5px; }
.jb-logo span { color: var(--jb-blue); }

/* 3. КНОПКИ (Button) ------------------------------------------- */
.jb-btn {
  font: 600 15px var(--jb-font);
  border-radius: var(--jb-radius-md);
  padding: 10px 20px;
  border: none;
  cursor: pointer;
  display: inline-block;
  text-decoration: none;
  text-align: center;
  transition: background .15s, color .15s;
}
.jb-btn:focus-visible { outline: none; box-shadow: var(--jb-focus-ring); }
.jb-btn:disabled { opacity: .45; pointer-events: none; }
.jb-btn--primary   { background: var(--jb-blue); color: #fff; }
.jb-btn--primary:hover { background: var(--jb-blue-hover); }
.jb-btn--secondary { background: var(--jb-surface); color: var(--jb-blue); border: 1px solid var(--jb-blue-border); }
.jb-btn--secondary:hover { background: var(--jb-blue-bg); }
.jb-btn--ghost { background: transparent; color: var(--jb-text-secondary); }
.jb-btn--ghost:hover { background: var(--jb-blue-bg); color: var(--jb-blue); }
.jb-btn--danger { background: var(--jb-danger); color: #fff; }
.jb-btn--danger:hover { background: #B91C1C; }
/* danger-outline: отклоняющие, но обратимые действия («Пропустить вакансию») */
.jb-btn--danger-outline { background: var(--jb-surface); color: var(--jb-danger); border: 1px solid var(--jb-danger); }
.jb-btn--danger-outline:hover { background: var(--jb-danger-bg); }
.jb-btn--sm { padding: 8px 14px;  font-size: 13px; }
.jb-btn--lg { padding: 13px 26px; font-size: 16px; font-weight: 700; }
.jb-btn--block { display: block; width: 100%; }
/* ссылки-кнопки: побеждаем базовое правило `.jb a` */
.jb a.jb-btn--primary, a.jb-btn--primary,
.jb a.jb-btn--danger,  a.jb-btn--danger  { color: #fff; }
.jb a.jb-btn--secondary, a.jb-btn--secondary { color: var(--jb-blue); }
/* Янтарная кнопка-ССЫЛКА: без этой строки её текст красит общее правило `.jb a`
   — на янтарном фоне выходил синий текст вместо чернильного (найдено сверкой с
   эталоном 17.08.2026). В эталонах кита кнопка стоит <button>, поэтому дефект
   жил только в продукте: CTA дашборда и кнопка плана — ссылки (react-router). */
.jb a.jb-btn--amber, a.jb-btn--amber, .jb a.jb-btn--amber:hover, a.jb-btn--amber:visited { color: var(--jb-ink); }
.jb a.jb-btn--danger-outline, a.jb-btn--danger-outline { color: var(--jb-danger); }
.jb a.jb-btn--ghost, a.jb-btn--ghost { color: var(--jb-text-secondary); }
.jb a.jb-btn:hover, a.jb-btn:hover { text-decoration: none; }
.jb a.jb-btn--primary:hover { color: #fff; }
.jb a.jb-btn--danger:hover  { color: #fff; }
.jb a.jb-btn--secondary:hover, .jb a.jb-btn--ghost:hover { color: var(--jb-blue); }

/* 4. БЕЙДЖИ (Badge) -------------------------------------------- */
.jb-badge {
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  padding: 3px 10px;
  display: inline-block;
  white-space: nowrap;
}
.jb-badge--info    { background: var(--jb-info-bg);    color: var(--jb-info); }
.jb-badge--success { background: var(--jb-success-bg); color: var(--jb-success); }
.jb-badge--warning { background: var(--jb-warning-bg); color: var(--jb-warning); }
.jb-badge--danger  { background: var(--jb-danger-bg);  color: var(--jb-danger); }
.jb-badge--amber   { background: var(--jb-amber);      color: var(--jb-ink); }
.jb-badge--muted   { background: var(--jb-bg); color: var(--jb-text-secondary); border: 1px solid var(--jb-border); }

/* 5. ФОРМЫ ------------------------------------------------------ */
.jb-label {
  font-size: 13px; font-weight: 600; color: var(--jb-text-secondary);
  margin-bottom: 6px; display: block;
}
.jb-input, .jb-select, .jb-textarea {
  width: 100%;
  padding: 10px 14px;
  font: 400 15px var(--jb-font);
  color: var(--jb-text);
  background: var(--jb-surface);
  border: 1px solid var(--jb-border-strong);
  border-radius: var(--jb-radius-md);
}
.jb-input::placeholder, .jb-textarea::placeholder { color: var(--jb-text-muted); }
.jb-input:focus, .jb-select:focus, .jb-textarea:focus {
  border-color: var(--jb-blue); box-shadow: var(--jb-focus-ring); outline: none;
}
.jb-input.is-error, .jb-textarea.is-error { border-color: var(--jb-danger); }
/* селект: своя стрелка всегда справа (не зависит от резетов фреймворка) */
select.jb-select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 38px;
  cursor: pointer;
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="10" height="6"><path d="M1 1l4 4 4-4" fill="none" stroke="%230F172A" stroke-width="1.6"/></svg>');
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 10px 6px;
}
.jb-textarea { min-height: 300px; resize: vertical; line-height: 1.6; }
/* Свёрнутое длинное поле: показываем ПЯТЬ строк, остальное человек
   разворачивает ссылкой `.jb-exp-toggle` рядом. Родня `.jb-exp-preview`
   (раздел 31) — тот же приём «длинный текст занимает пять-десять строк, пока
   его не развернули», но там текст статичный и обрезает его `line-clamp`, а
   поле остаётся полем: клампить `<textarea>` нельзя, поэтому здесь высота.
   Лимит строк объявлен ЗДЕСЬ и только здесь: второе число в JS было бы копией,
   которая молча разъедется с настоящей высотой.
   Селектор из ДВУХ классов (0-2-0) намеренно: `min-height` полю задают экраны
   своим одиночным классом (`.letters-jd` — 180px), и правило в один класс
   проигрывало бы им по порядку подключения, а не по смыслу. Тот же приём у
   ширины `.jb-modal-card` (раздел 24).
   `resize` снят, пока поле свёрнуто: ручка изменения размера обещает второй
   способ развернуть, который спорит со ссылкой и не переключает `aria-expanded`. */
.jb-textarea.jb-textarea--clamped {
  --jb-textarea-clamp-lines: 5;
  min-height: 0;
  height: calc(var(--jb-textarea-clamp-lines) * 1.6em + 22px);
  resize: none;
  overflow-y: auto;
}
.jb-hint       { font-size: 13px; color: var(--jb-text-muted);  margin-top: 5px; }
.jb-error-text { font-size: 13px; color: var(--jb-danger); margin-top: 5px; font-weight: 500; }
.jb-checkbox, .jb-radio { accent-color: var(--jb-blue); width: 17px; height: 17px; }
/* Поле формы целиком: лейбл + контрол + подсказка/ошибка. Отступ между полями
   задаётся здесь, а не марджинами у каждого контрола — иначе он оказывался бы
   разным у input, textarea и select. */
.jb-field { margin-bottom: 16px; }
.jb-field:last-child { margin-bottom: 0; }
/* Поле «только чтение» (email в профиле меняется отдельным сценарием). */
.jb-input[readonly] { background: var(--jb-bg); color: var(--jb-text-secondary); }
/* селект-фильтр с кастомной стрелкой (Select) */
.jb-select--filter {
  width: auto;
  font: 600 13.5px var(--jb-font);
  padding: 8px 30px 8px 12px;
  appearance: none;
  cursor: pointer;
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="10" height="6"><path d="M1 1l4 4 4-4" fill="none" stroke="%230F172A" stroke-width="1.6"/></svg>');
  background-repeat: no-repeat;
  background-position: right 11px center;
}

/* 6. ТАБЛИЦЫ (DataTable) ---------------------------------------- */
.jb-table {
  width: 100%; border-collapse: collapse;
  background: var(--jb-surface);
  border-radius: var(--jb-radius-lg);
  overflow: hidden;
  box-shadow: var(--jb-shadow-sm);
}
.jb-table th {
  text-align: left; font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; color: var(--jb-text-muted); background: var(--jb-bg);
  padding: 12px 16px; border-bottom: 1px solid var(--jb-border);
}
.jb-table td { padding: 13px 16px; font-size: 14px; border-bottom: 1px solid var(--jb-border); }
.jb-table tr:last-child td { border-bottom: none; }
.jb-table tbody tr:hover { background: var(--jb-blue-bg); }
.jb-table .r, .jb-table th.r { text-align: right; font-variant-numeric: tabular-nums; }
/* Плотный вариант — для служебных таблиц на десять столбцов (админка). Обычный
   размер там даёт строку шире экрана, и крайние столбцы («Статус», меню
   действий) уезжают за край: администратор видит данные, но не видит, что с
   ними можно сделать. Значения выверены на боевых таблицах админки. */
.jb-table--dense { font-size: 13.3px; }
.jb-table--dense th { font-size: 11px; padding: 12px 16px; }
.jb-table--dense td { font-size: 13.3px; padding: 12px 16px; }

/* 7. АЛЕРТЫ И ТОСТЫ --------------------------------------------- */
.jb-alert {
  border-radius: var(--jb-radius-lg);
  padding: 14px 16px; font-size: 14px;
  border: 1px solid;
  display: flex; gap: 10px; align-items: flex-start;
}
.jb-alert b { display: block; font-weight: 700; }
.jb-alert--info    { background: var(--jb-info-bg);    border-color: var(--jb-info-border);    color: var(--jb-info); }
.jb-alert--success { background: var(--jb-success-bg); border-color: var(--jb-success-border); color: var(--jb-success); }
.jb-alert--warning { background: var(--jb-warning-bg); border-color: var(--jb-warning-border); color: var(--jb-warning); }
.jb-alert--danger  { background: var(--jb-danger-bg);  border-color: var(--jb-danger-border);  color: var(--jb-danger); }
/* Алерт с действием: текст слева, кнопка(и) справа, перенос под текст на узком
   экране. Общая раскладка калибровки поиска (`.search-calibration`) без
   привязки к одному разделу — плашка «временно закрыто» стоит и в карьере, и
   в интервью, и в аналитике, и в кабинете ментора (PiiLockedNotice). */
/* Внешних отступов у `.jb-alert` нет намеренно — расстояние между блоками
   страницы задаёт композиция. Две плашки подряд поэтому встают ВСТЫК, и
   одинаковый вариант (`--info` + `--info`) читается как один блок с волоском
   посередине: так 29.08.2026 слились итог прогона и планка калибровки на
   `/search`. Тот же случай, что был у пары «алерт + hero» 25.08.2026. Лекарство
   — правило соседства в композиции приложения (`layout.css`), а не отступ
   здесь: у одних экранов плашки идут стопкой, у других поодиночке. */
.jb-alert-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; }
.jb-alert-row-text { flex: 1 1 320px; min-width: 0; }
.jb-alert-row-text b { display: inline; }
/* `flex-shrink: 0` бережёт кнопки от сплющивания на широком экране, но на узком
   он же и ломал блок: ужаться нельзя, переносить внутри себя нечем — и пара
   кнопок вылезала за край. Замер 12.09.2026 на эталоне поиска при 375px: перелив
   8px, scrollWidth 383. Лечится не снятием запрета, а двумя строками: внутренний
   перенос + потолок в ширину строки. */
.jb-alert-row-actions { display: flex; gap: 8px; flex-shrink: 0; flex-wrap: wrap; max-width: 100%; }
.jb-toast {
  background: var(--jb-surface); box-shadow: var(--jb-shadow-md);
  border-radius: var(--jb-radius-lg); padding: 14px 16px; font-size: 14px;
  border-left: 4px solid var(--jb-blue);
}
.jb-toast--success { border-left-color: var(--jb-success); }
.jb-toast--warning { border-left-color: var(--jb-warning); }
.jb-toast--danger  { border-left-color: var(--jb-danger); }

/* 8. SECTIONCARD И COLLAPSE ------------------------------------- */
.jb-section {
  background: var(--jb-surface);
  border-radius: var(--jb-radius-lg);
  padding: 24px;
  box-shadow: var(--jb-shadow-sm);
}
.jb-section--amber { border-left: 6px solid var(--jb-amber); } /* только actionable-блоки */
/* Секция-ПРЕДЛОЖЕНИЕ инструмента: синий рейл и светлый синий фон (18.08.2026,
   «Подготовка к интервью» на разборе вакансии). Янтарь для этого не годится:
   на экране он значит «самое срочное действие» и занят одной кнопкой — CTA
   раздела; третье янтарное пятно перестало бы выделять что-либо вовсе. Синий
   уже несёт этот смысл в ките — приглашение к соседнему инструменту
   (`.jb-exp-cta`) и предложение калибровки (`jb-alert--info`) выглядят так же.
   Рейл той же толщины, что у янтарной: это одна семья модификаторов. */
.jb-section--blue {
  border-left: 6px solid var(--jb-blue);
  background: var(--jb-blue-bg);
  border-top: 1px solid var(--jb-blue-border);
  border-right: 1px solid var(--jb-blue-border);
  border-bottom: 1px solid var(--jb-blue-border);
}
.jb-section-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; }
details.jb-collapse { padding: 0; }
details.jb-collapse summary {
  list-style: none; cursor: pointer;
  padding: 18px 24px; font-size: 17px; font-weight: 700;
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
}
details.jb-collapse summary::-webkit-details-marker { display: none; }
details.jb-collapse summary::after { content: '▾'; color: var(--jb-text-muted); transition: transform .15s; }
details.jb-collapse[open] summary::after { transform: rotate(180deg); }
details.jb-collapse .jb-collapse-inner { padding: 0 24px 22px; }

/* 9. PAGEHEADER И PAGEFOOTER ------------------------------------ */
.jb-pagehead { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; }
.jb-pagehead .jb-logo { font-size: 21px; }
/* Размер h1 НЕ переопределяется: он задан один раз в разделе 2 (32px/800) и
   один и тот же на всём продукте. До 10.08.2026 здесь стояло 28px — из-за чего
   заголовок раздела в эталонах был мельче, чем в приложении, хотя спецификация
   называет 32px единственным видом H1. Остаётся только отступ: он относится к
   композиции шапки, а не к самому заголовку. */
.jb-pagehead h1 { margin: 10px 0 4px; }
/* Пояснение под заголовком — секции или страницы. 14px/secondary: крупнее
   подсказки поля (`jb-hint`, 13px muted), потому что это не служебная реплика, а
   объяснение самого блока. В шапке страницы у него нет отступов, в остальных
   местах отступ задаёт композиция. */
.jb-sub { color: var(--jb-text-secondary); font-size: 14px; }
.jb-pagehead .jb-sub { margin: 0; }
.jb-iconbtn {
  position: relative;                      /* якорь для счётчика (.jb-count) */
  width: 38px; height: 38px; border-radius: 50%;
  border: 1px solid var(--jb-border); background: var(--jb-surface);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; color: var(--jb-text-secondary);
}
/* Счётчик на иконке: сколько дел ждёт за ней. Красный — единственное место в
   шапке, где цвет означает «требует действия»; поэтому он и заметен. Ставится
   ТОЛЬКО при ненулевом значении: кружок с нулём приучает не смотреть на него.
   Число дублируется в aria-label кнопки — цвет и позиция не должны быть
   единственными носителями смысла. */
.jb-count {
  position: absolute; top: -3px; right: -3px;
  min-width: 18px; height: 18px; padding: 0 5px; box-sizing: border-box;
  border-radius: 999px; background: var(--jb-danger); color: #fff;
  font-size: 11px; font-weight: 700; line-height: 18px; text-align: center;
  font-variant-numeric: tabular-nums;
}
.jb-iconbtn:focus-visible { outline: none; box-shadow: var(--jb-focus-ring); }
/* Кнопка-переключатель в шапке (помощник): открытая панель видна по самой
   кнопке. Без этого человек, промахнувшись мимо панели, жмёт ту же кнопку
   снова и закрывает то, что хотел открыть. */
.jb-iconbtn.is-open { background: var(--jb-blue-bg); color: var(--jb-blue); border-color: var(--jb-blue-border); }
/* Кнопка шапки, которая является ССЫЛКОЙ, — с тегом в селекторе. Базовое
   `.jb a { color: var(--jb-blue) }` имеет специфичность (0,1,1) и перебивает
   одиночный класс: в продукте «Вопросы и ответы» и «Напоминания» — это
   `<Link>`, и обе иконки были СИНИМИ, пока компас и меню (настоящие
   `<button>`) оставались чернильными — четыре кнопки одного ряда в двух
   разных цветах (найдено 18.08.2026 при сверке макета разбора). В эталонах
   дефект не виден вовсе: там все четыре — `<button>`, поэтому проверка живёт
   тестом, а не глазами. Тот же капкан уже срабатывал на логотипе, пунктах
   меню, строках «Инструментов», карточках-дверях и янтарной кнопке-ссылке. */
a.jb-iconbtn, .jb a.jb-iconbtn { color: var(--jb-text-secondary); text-decoration: none; }
/* Наведение — состояние БЛОКА, поэтому живёт здесь, а не в CSS экрана: до
   18.08.2026 оно стояло в `layout.css` (`.shell-actions .jb-iconbtn:hover`),
   и эталоны про наведение не знали вовсе. */
.jb-iconbtn:hover { border-color: var(--jb-blue); color: var(--jb-blue); }
.jb a.jb-iconbtn:hover { color: var(--jb-blue); text-decoration: none; }
.jb-pagefoot { color: var(--jb-text-muted); font-size: 13px; }

/* 10. ACTIONBANNER ---------------------------------------------- */
/* Отступа у блока НЕТ намеренно: баннер комбинируется с разными контейнерами
   — на карточке секции (`jb-section jb-banner`: дашборд, запуск поиска) он
   получает её 24px, внутри чужого блока (предложения калибровки) остаётся без
   отступа вовсе. Свой padding здесь сделал бы вторую форму баннера. */
.jb-banner { display: flex; justify-content: space-between; align-items: center; gap: 16px; flex-wrap: wrap; }
.jb-banner-title { font-size: 17px; font-weight: 700; }
.jb-banner--hero .jb-banner-title { font-size: 19px; }
.jb-banner-count { font-size: 14px; color: var(--jb-text-secondary); font-weight: 500; margin-left: 10px; }
/* Пояснение баннера — вторая строка под заголовком: ЧТО произойдёт по нажатию.
   Заведено 25.08.2026 вместе с вопросом «Вы отправили отклик?»: до него баннер
   умел только заголовок и счётчик, а вопрос без объяснения последствия читается
   как требование. В витрине кита такая строка уже рисовалась инлайн-стилями
   (образец «SearchPage v2 — ActionBanner запуска») — то есть класс был нужен
   ещё тогда, просто его не завели. */
.jb-banner-sub { display: block; font-size: 14px; color: var(--jb-text-secondary); margin-top: 4px; }

/* 11. STATSTRIP ------------------------------------------------- */
.jb-statstrip {
  display: flex; gap: 14px 28px; flex-wrap: wrap;
  background: var(--jb-surface); border-radius: var(--jb-radius-lg);
  box-shadow: var(--jb-shadow-sm); padding: 16px 22px;
}
/* flex:none + nowrap-лейбл — метрика не сжимается и не переносит текст внутри;
   при нехватке ширины flex-wrap переносит метрику ЦЕЛИКОМ (лейбл не обрезается). */
.jb-stat { display: flex; align-items: baseline; gap: 8px; flex: none; }
.jb-stat-v { font-size: 21px; font-weight: 800; font-variant-numeric: tabular-nums; }
.jb-stat-l { font-size: 13px; color: var(--jb-text-secondary); white-space: nowrap; }
button.jb-stat { background: none; border: none; cursor: pointer; font-family: var(--jb-font); padding: 0; }
button.jb-stat .jb-stat-v { color: var(--jb-blue); }        /* кликабельная метрика-фильтр */
button.jb-stat:hover .jb-stat-l { color: var(--jb-blue); }
button.jb-stat.is-active .jb-stat-l { color: var(--jb-blue); font-weight: 600; }
button.jb-stat:focus-visible { outline: none; box-shadow: var(--jb-focus-ring); border-radius: 6px; }

/* 12. FUNNELCHART, BARCHART, CONVERSIONCHIPS -------------------- */
.jb-funnel-row {
  display: grid; grid-template-columns: 110px 1fr 46px; gap: 12px;
  align-items: center; margin-bottom: 9px;
}
.jb-funnel-label { font-size: 13.5px; font-weight: 600; color: var(--jb-text-secondary); }
/* `display: block` обязателен: без него блок работает только на <div>, а на
   <span> высота не применяется и полоса остаётся пустым треком — блок кита не
   должен зависеть от того, каким тегом его нарисовал экран. */
.jb-funnel-track { display: block; height: 14px; background: var(--jb-bg); border: 1px solid var(--jb-border); border-radius: 8px; overflow: hidden; }
.jb-funnel-fill  { display: block; height: 100%; background: var(--jb-blue); border-radius: 7px; }
.jb-funnel-value { font-size: 14px; font-weight: 700; font-variant-numeric: tabular-nums; text-align: right; }
.jb-funnel-value--zero { color: var(--jb-text-muted); font-weight: 600; }
.jb-convs { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.jb-conv {
  font-size: 12.5px; font-weight: 500; padding: 5px 12px; border-radius: 999px;
  background: var(--jb-blue-bg); border: 1px solid var(--jb-blue-border); color: var(--jb-ink);
}
.jb-bars { display: flex; gap: 14px; align-items: flex-end; padding-top: 8px; }
.jb-bar { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; min-width: 0; }
.jb-bar-v { font-size: 12.5px; font-weight: 700; margin-bottom: 4px; font-variant-numeric: tabular-nums; }
.jb-bar-fill { width: 62%; max-width: 46px; background: var(--jb-blue); border-radius: 6px 6px 0 0; }
.jb-bar-l { font-size: 11.5px; color: var(--jb-text-muted); margin-top: 7px; white-space: nowrap; }

/* 13. KEYVALUEROW ----------------------------------------------- */
/* строка «имя · значение · бейдж» (каналы, пробелы) */
.jb-kvrow {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  padding: 12px 2px; border-bottom: 1px solid var(--jb-border); flex-wrap: wrap;
}
/* Нижняя граница снимается только у СТРОЧНОГО варианта — того, что рисует
   список разделителями. У «коробочного» (`a`, `button`, `--link`) рамка идёт по
   всем четырём сторонам, и снятая нижняя оставляет открытый короб. Дефект был и
   до 31.08.2026: последняя строка-инструмент на «Моей карьере» стояла без низа,
   просто в глаза не бросалось; перенос истории на этот блок сделал его видным
   сразу в трёх местах. */
.jb-kvrow:not(a):not(button):not(.jb-kvrow--link):last-child { border-bottom: none; }
.jb-kv-name { font-weight: 600; font-size: 14px; }
.jb-kv-value { font-size: 14px; font-weight: 700; font-variant-numeric: tabular-nums; margin-left: auto; }
.jb-kv-value--zero { color: var(--jb-text-secondary); }
/* вариант-ссылка (строка-инструмент на CareerPage) */
a.jb-kvrow, .jb-kvrow--link {
  border: 1px solid var(--jb-border); border-radius: var(--jb-radius-md);
  padding: 14px 16px; margin-bottom: 10px; text-decoration: none;
  color: var(--jb-text); background: var(--jb-surface);
}
/* Подсветка при наведении — только у того, что ДЕЙСТВИТЕЛЬНО кликабельно:
   у ссылки и у кнопки. Довод прежний и верный — тем же `--link` рисуется
   неактивный пункт (инструмент, которого ещё нет), и он отзываться не должен,
   иначе обещает переход, которого не будет. Но граница до 31.08.2026 шла не по
   тому признаку: «якорь против всего остального» вместо «интерактивный против
   неинтерактивного». Неактивный пункт — это `div.jb-kvrow--link.is-pending`, а
   кнопка кликабельна по определению.
   Цена прежней границы: строки-кнопки в «Написать» (`write-card`) подсветки не
   получали, хотя эталон `jobburg-write.html` её обещал, а экраны истории завели
   ради неё СВОЮ копию блока (`.tl-history-row`). */
a.jb-kvrow:hover, button.jb-kvrow:hover { background: var(--jb-blue-bg); border-color: var(--jb-blue-border); }
a.jb-kvrow:focus-visible, button.jb-kvrow:focus-visible { outline: none; box-shadow: var(--jb-focus-ring); }
/* Имя в коробочной строке крупнее — и у ссылки, и у кнопки: граница здесь та
   же, что у подсветки, и по той же причине (31.08.2026). Правка подсветки эту
   строку сначала пропустила, и кнопка получала имя на кегль мельче ссылки. */
a.jb-kvrow .jb-kv-name, button.jb-kvrow .jb-kv-name { font-weight: 700; font-size: 15px; }
/* block, а не inline: пояснение стоит ПОД именем, и отступ у inline не
   применился бы вовсе. Раньше строка держалась на <br> в разметке — то есть на
   том, что каждый экран не забудет его поставить. */
.jb-kv-name, .jb-kv-note { display: block; }
.jb-kv-note { font-size: 13px; color: var(--jb-text-muted); margin-top: 2px; }
.jb-kvrow .jb-arr { color: var(--jb-blue); font-weight: 700; flex: none; }
/* Строка-инструмент, который ещё не готов: приглушена, но видна — список
   инструментов не должен молча менять длину от захода к заходу. */
.jb-kvrow.is-pending { opacity: .65; }

/* 14. APPLICATIONCARD ------------------------------------------- */
.jb-card {
  background: var(--jb-surface); border-radius: var(--jb-radius-lg);
  box-shadow: var(--jb-shadow-sm); overflow: hidden;
  border-left: 6px solid var(--jb-blue);   /* рейл: blue — в работе */
}
.jb-card--offer    { border-left-color: var(--jb-success); }       /* оффер */
.jb-card--archived { border-left-color: var(--jb-border-strong); } /* отказ/архив */
/* Карточка целиком открывает свою страницу. Состояние, а не отдельный блок:
   карточка остаётся той же, меняется только то, что по ней можно нажать.
   Кольцо фокуса обязательно — карточка объявлена role="button" и обязана быть
   видна тому, кто ходит с клавиатуры. Действия ВНУТРИ такой карточки (ссылка на
   вакансию, селект статуса) гасят всплытие сами: иначе нажатие на них заодно
   уводило бы на страницу карточки. */
.jb-card.is-clickable { cursor: pointer; }
.jb-card.is-clickable:hover { box-shadow: var(--jb-shadow-md); }
.jb-card.is-clickable:focus-visible { outline: none; box-shadow: var(--jb-focus-ring); }
.jb-card-head {
  border-bottom: 1px solid var(--jb-border);
  padding: 18px 24px; display: flex; gap: 16px;
  justify-content: space-between; align-items: center; flex-wrap: wrap;
}
/* Левая зона шапки (название, должность, служебная строка) забирает остаток
   ширины и СЖИМАЕТСЯ; правая — статус или действия — остаётся на своём месте.
   Без `min-width: 0` flex-элемент не сжимается ниже своего содержимого: длинная
   должность распирала левую зону на всю строку, и статус переносился под неё —
   карточки в одном списке выглядели по-разному (замечено 10.08.2026 на
   «Директор по трансформации / операционный директор для дистрибьюторской
   компании федерального масштаба»). Теперь длинный текст переносится внутри
   своей колонки, а раскладка карточки не меняется. */
.jb-card-head > :first-child { flex: 1 1 260px; min-width: 0; }
.jb-card-id { font-size: 12px; font-weight: 600; color: var(--jb-text-muted); letter-spacing: .06em; display: flex; gap: 12px; align-items: baseline; }
.jb-card-head h3 { font-size: 19px; font-weight: 800; letter-spacing: -.3px; margin: 2px 0; }
.jb-card-rating { background: var(--jb-amber); color: var(--jb-ink); font-size: 12px; font-weight: 700; border-radius: 999px; padding: 3px 10px; vertical-align: 2px; margin-left: 8px; }
/* Должность переносится по словам, а сплошная строка без пробелов — по месту:
   иначе одно длинное слово снова распёрло бы колонку. */
.jb-card-pos { font-size: 14px; font-weight: 500; color: var(--jb-text-secondary); overflow-wrap: break-word; }
.jb-remind {
  display: inline-flex; gap: 8px; align-items: center;
  font-size: 13px; font-weight: 600; color: var(--jb-ink);
  background: var(--jb-success-bg); border: 1px solid var(--jb-success-border);
  border-radius: 999px; padding: 7px 14px;
}
.jb-remind .jb-dot, .jb-status-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--jb-success); }
.jb-status {
  font: 700 13.5px var(--jb-font); color: var(--jb-ink);
  background: var(--jb-success-bg); border: 1px solid var(--jb-success-border);
  border-radius: 999px; padding: 8px 32px 8px 28px;
  appearance: none; cursor: pointer;
  background-image:
    radial-gradient(circle, var(--jb-success) 4px, transparent 5px),
    url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="10" height="6"><path d="M1 1l4 4 4-4" fill="none" stroke="%230F172A" stroke-width="1.6"/></svg>');
  background-repeat: no-repeat;
  background-size: 14px 14px, 10px 6px;
  background-position: 9px center, right 12px center;
}
.jb-status:focus-visible { outline: none; box-shadow: var(--jb-focus-ring); }
/* Состояния статуса. Зелёный по умолчанию — это «в работе», и на карточке
   активного отклика другого не бывает по построению. В списке «Оценки
   совместимости» бывает: там же лежат отказы и архив, и зелёная плашка на
   отказе говорила бы цветом ровно обратное тому, что говорит слово.
   Точка слева перекрашивается вместе с плашкой — иначе она остаётся зелёной
   на красном фоне. Новых цветов не заводим: те же семьи, что у бейджей. */
/* Только ДЛИННЫЕ свойства. Шорткат `background` сбрасывает `background-repeat`,
   `-size` и `-position` в initial — точка-градиент замащивает всю плашку, и
   текст становится нечитаем (поймано осмотром эталона 12.08.2026). Базовое
   правило выше задаёт раскладку фонов один раз, модификатор меняет только цвет
   заливки и цвет точки. */
.jb-status--danger {
  background-color: var(--jb-danger-bg); border-color: var(--jb-danger-border);
  background-image:
    radial-gradient(circle, var(--jb-danger) 4px, transparent 5px),
    url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="10" height="6"><path d="M1 1l4 4 4-4" fill="none" stroke="%230F172A" stroke-width="1.6"/></svg>');
}
.jb-status--muted {
  background-color: var(--jb-bg); border-color: var(--jb-border-strong);
  background-image:
    radial-gradient(circle, var(--jb-text-muted) 4px, transparent 5px),
    url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="10" height="6"><path d="M1 1l4 4 4-4" fill="none" stroke="%230F172A" stroke-width="1.6"/></svg>');
}
.jb-card-body { padding: 20px 24px; }
.jb-card-foot {
  display: flex; gap: 12px; align-items: center; justify-content: flex-end;
  flex-wrap: wrap; border-top: 1px solid var(--jb-border); padding: 16px 24px;
}
/* шкала этапов — горизонтальный режим */
.jb-timeline { list-style: none; margin: 0 0 4px; padding: 0; display: flex; counter-reset: step; }
.jb-timeline li { flex: 1; position: relative; text-align: center; min-width: 0; }
.jb-timeline li::before {
  counter-increment: step; content: counter(step);
  width: 30px; height: 30px; line-height: 26px; border-radius: 50%;
  display: block; margin: 0 auto 7px;
  font-size: 13px; font-weight: 700;
  background: var(--jb-surface); color: var(--jb-text-muted);
  border: 2px solid var(--jb-border-strong);
  position: relative; z-index: 1;
}
.jb-timeline li::after {
  content: ''; position: absolute; top: 15px;
  left: calc(50% + 17px); right: calc(-50% + 17px);
  height: 2px; background: var(--jb-border-strong);
}
.jb-timeline li:last-child::after { display: none; }
.jb-timeline li.current::before { content: '●'; background: var(--jb-blue); border-color: var(--jb-blue); color: #fff; font-size: 10px; }
.jb-timeline li.done::before { background: var(--jb-blue-bg); border-color: var(--jb-blue-border); color: var(--jb-blue); }
.jb-timeline .lbl {
  font-size: 12.5px; font-weight: 600; color: var(--jb-text-secondary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding: 0 4px; display: block;
}
.jb-timeline li.current .lbl { color: var(--jb-blue); }
/* Панель отметки этапа (30.08.2026). Клик по кружку больше не пишет строку в
   журнал сразу — он спрашивает ДАТУ события, а поле уже заполнено сегодняшним
   днём. Панель стоит ПОД шкалой, а не внутри `li`: шкала это flex-строка из
   пяти равных колонок, и панель внутри колонки сплющила бы её.
   Тексты и правило даты — в ките (`JBStates.stageMarkTitle`,
   `stageDateProblem`), разметка их не собирает. */
.jb-stagemark {
  margin: 10px 0 4px; padding: 12px 14px;
  background: var(--jb-surface); border: 1px solid var(--jb-blue-border);
  border-radius: var(--jb-radius-md);
}
.jb-stagemark-title { font-weight: 700; font-size: 13.5px; margin: 0 0 10px; }
.jb-stagemark-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.jb-stagemark-date { width: 160px; padding: 7px 12px; font-variant-numeric: tabular-nums; }
.jb-stagemark .jb-hint { margin: 8px 0 0; }

/* 15. STEPSNAV (шкала этапов, вертикальный режим; CareerPage) --- */
.jb-steps { list-style: none; margin: 0; padding: 0; }
.jb-steps li {
  display: flex; gap: 12px; align-items: flex-start; position: relative;
  padding: 7px 8px; border-radius: var(--jb-radius-md); cursor: pointer;
}
.jb-steps li:hover { background: var(--jb-blue-bg); }
.jb-steps .n {
  flex: none; width: 28px; height: 28px; line-height: 24px; text-align: center;
  border-radius: 50%; font-size: 12.5px; font-weight: 700;
  background: var(--jb-surface); color: var(--jb-text-muted);
  border: 2px solid var(--jb-border-strong); position: relative; z-index: 1;
}
.jb-steps li:not(:last-child)::after {
  content: ''; position: absolute; left: 21px; top: 37px; bottom: -9px;
  width: 2px; background: var(--jb-border-strong);
}
.jb-steps .t { font-size: 13.5px; font-weight: 600; color: var(--jb-text-secondary); padding-top: 4px; }
.jb-steps li.current { background: var(--jb-blue-bg); }
.jb-steps li.current .n { background: var(--jb-blue); border-color: var(--jb-blue); color: #fff; }
.jb-steps li.current .t { color: var(--jb-blue); }
.jb-steps li.done .n { background: var(--jb-blue-bg); border-color: var(--jb-blue-border); color: var(--jb-blue); }

/* 16. AUTHSCREENS ----------------------------------------------- */
.jb-auth-logo { font-size: 30px; font-weight: 800; letter-spacing: -1px; text-align: center; }
/* Селектор с тегом обязателен: слоган — это <h1> страницы входа, а правило
   `.jb h1` (0,1,1) специфичнее одиночного класса и вернуло бы ему 32px. */
.jb-auth-slogan, .jb h1.jb-auth-slogan { text-align: center; font-size: 26px; font-weight: 800; letter-spacing: -.5px; margin: 10px 0 28px; }
.jb-auth-card {
  background: var(--jb-surface); border-radius: var(--jb-radius-lg);
  box-shadow: var(--jb-shadow-sm); padding: 36px;
  max-width: 560px; margin: 0 auto;
}
.jb-auth-card h2 { font-size: 24px; font-weight: 800; letter-spacing: -.3px; margin: 0 0 20px; }
.jb-auth-aux { text-align: center; font-size: 14px; margin-top: 18px; color: var(--jb-text-secondary); }
.jb-auth-aux + .jb-auth-aux { margin-top: 10px; }
/* И `button` наравне со ссылкой: действие внутри страницы — это кнопка, а не
   ссылка, притворяющаяся кнопкой (Б-84). Правило кита «кнопки-ссылки» велит
   `.jb-link-blue` на `<button>`; он даёт сброс обвязки, а цвет и наведение —
   отсюда, чтобы вид совпал с прежней ссылкой ровно, а не примерно. */
.jb-auth-aux a, .jb-auth-aux button { color: var(--jb-blue); font-weight: 600; text-decoration: none; }
.jb-auth-aux a:hover, .jb-auth-aux button:hover { color: var(--jb-blue-hover); text-decoration: underline; }
/* Согласие с условиями — своя строка блока, а не мелкий текст под кнопкой:
   галочка и ссылки на документы должны читаться до нажатия «Зарегистрироваться».
   14px, а не 13: это юридически значимый текст, и мельчить его нельзя. */
.jb-auth-consent { display: flex; gap: 10px; align-items: flex-start; font-size: 14px; margin: 4px 0 18px; }
.jb-auth-consent input { accent-color: var(--jb-blue); width: 18px; height: 18px; margin-top: 2px; flex: none; }
.jb-auth-consent a { color: var(--jb-blue); text-decoration: none; }
.jb-auth-consent a:hover { color: var(--jb-blue-hover); text-decoration: underline; }
/* Поля внутри — обычный `jb-field` (раздел 5), своего варианта у экранов входа
   нет. Выравнивание задаётся здесь, а не контейнером: логотип и слоган над
   карточкой центрированы, а форма внутри неё читается только слева. */
.jb-auth-card { text-align: left; }

/* 17. EMPTYSTATE И CHECKROW ------------------------------------- */
/* пустое состояние секции: иконка в голубом круге + заголовок + подсказка */
.jb-empty { text-align: center; padding: 34px 20px; color: var(--jb-text-secondary); }
.jb-empty .jb-empty-ico {
  width: 52px; height: 52px; border-radius: 50%;
  background: var(--jb-blue-bg); color: var(--jb-blue);
  display: inline-flex; align-items: center; justify-content: center;
  margin-bottom: 12px;
}
.jb-empty .jb-empty-title { font-weight: 700; font-size: 15px; color: var(--jb-text); }
.jb-empty p { margin: 6px 0 0; font-size: 14px; }
/* строка-настройка: чекбокс + название + бейдж режима справа */
.jb-checkrow {
  display: flex; align-items: center; gap: 12px;
  padding: 13px 2px; border-bottom: 1px solid var(--jb-border); flex-wrap: wrap;
}
.jb-checkrow:last-of-type { border-bottom: none; }
.jb-checkrow label { display: flex; gap: 11px; align-items: center; font-weight: 700; font-size: 15px; cursor: pointer; }
.jb-checkrow .jb-checkrow-note { font-size: 13px; color: var(--jb-text-muted); font-weight: 500; }
.jb-checkrow .jb-checkrow-side { margin-left: auto; }

/* Switch — тумблер вкл/выкл (настройки); текст состояния чернильный, не цветной */
.jb-switch { position: relative; display: inline-flex; align-items: center; gap: 9px; cursor: pointer; font-size: 13.5px; font-weight: 600; }
.jb-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.jb-switch .jb-switch-track {
  width: 38px; height: 21px; border-radius: 999px;
  background: var(--jb-border-strong); position: relative; transition: background .15s; flex: none;
}
.jb-switch .jb-switch-track::after {
  content: ''; position: absolute; top: 2px; left: 2px; width: 17px; height: 17px;
  border-radius: 50%; background: #fff; transition: left .15s;
  box-shadow: 0 1px 2px rgba(15, 23, 42, .2);
}
.jb-switch input:checked + .jb-switch-track { background: var(--jb-blue); }
.jb-switch input:checked + .jb-switch-track::after { left: 19px; }
.jb-switch input:focus-visible + .jb-switch-track { box-shadow: var(--jb-focus-ring); }
.jb-switch .jb-switch-label { color: var(--jb-text-secondary); }
.jb-switch input:checked ~ .jb-switch-label { color: var(--jb-text); }

/* SelectBar — липкая панель массового выбора (поиск, списки) */
.jb-selbar {
  display: flex; justify-content: space-between; align-items: center;
  gap: 12px; flex-wrap: wrap;
  background: var(--jb-blue-bg); border: 1px solid var(--jb-blue-border);
  border-radius: var(--jb-radius-md); padding: 10px 14px;
  position: sticky; top: 10px; z-index: 5;
}
.jb-selbar label { display: flex; gap: 10px; align-items: center; font-weight: 600; font-size: 14px; cursor: pointer; }
.jb-selbar .jb-selbar-count { font-size: 13px; color: var(--jb-text-secondary); font-variant-numeric: tabular-nums; }
/* выбранная карточка списка: синий рейл + голубая подсветка */
.jb-card--selected { border-left-color: var(--jb-blue); background: var(--jb-blue-bg); }

/* 18. УТИЛИТЫ И АДАПТИВ ----------------------------------------- */
/* Три утилиты, поднятые в кит 09.08.2026. Все три уже применялись обоими
   фронтами по имени `jb-*`, но объявлены были только в CSS кабинета — в
   React-приложении элементы с ними оставались без вида: сообщение об успехе
   печаталось чернильным вместо зелёного, приглушённая строка — обычным
   цветом, а ссылка-действие теряла курсор-палец (цвет ей давало общее
   правило `.jb a`, поэтому дефект был почти незаметен глазом). Имя с
   префиксом `jb-` — обещание, что правило живёт в ките; теперь так и есть. */
/* Ссылка-действие. Работает и на <button>: браузер рисует кнопке рамку, фон и
   свой шрифт, и без сброса «Дозаполнить информацию» выглядело обведённой
   кнопкой посреди текста. Сброс здесь, а не в экране: правило одно на всех. */
.jb-link-blue {
  color: var(--jb-blue); font-weight: 600; font-size: 14px; text-decoration: none; cursor: pointer;
  background: none; border: none; padding: 0; font-family: var(--jb-font); text-align: left;
}
.jb-link-blue:hover { text-decoration: underline; }
/* Та же ссылка-действие, но необратимая (удалить фото, удалить запись).
   Красный здесь — не украшение: он отличает действие, которое нельзя отменить,
   от обычного перехода. Инлайн-стилем это писалось в трёх экранах. */
.jb-link-danger, .jb a.jb-link-danger { color: var(--jb-danger); font-weight: 600; font-size: 14px; text-decoration: none; cursor: pointer; }
.jb-link-danger:hover { text-decoration: underline; }
.jb-success-text { font-size: 13px; color: var(--jb-success); margin-top: 5px; font-weight: 500; }
.jb-text-muted { color: var(--jb-text-muted); }
/* Подпись, которой на экране НЕТ, а у поля она есть (29.08.2026). Повод —
   «Профессиональная цель»: заголовок блока и подпись единственного вопроса в
   нём говорят одно слово, и на экране оно печаталось дважды. Убрать подпись
   совсем нельзя — `<label for>` это ИМЯ поля для читающего с экрана, и
   заголовок блока его не заменяет.
   `display:none` для этого не годится: движки расходятся в том, берут ли они
   имя из скрытой таким образом подписи. Здесь подпись остаётся в потоке
   доступности и лишь вынесена за пределы видимого — приём стандартный. */
.jb-sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden; white-space: nowrap;
  clip-path: inset(50%);
}

@media (max-width: 640px) {
  /* Заголовок страницы на узком экране: 32px хватает, чтобы одно длинное слово
     («Сопроводительное») не поместилось в 284px и распёрло документ — по
     горизонтали начинал ездить весь экран (поймано обходом на 360px
     10.08.2026). Уменьшаем кегль и разрешаем перенос ВНУТРИ слова: заголовок
     важнее целостности слова, а горизонтальная прокрутка страницы недопустима. */
  .jb h1, .jb-h1 { font-size: 26px; overflow-wrap: anywhere; }
  .jb h2, .jb-h2 { font-size: 21px; overflow-wrap: anywhere; }
  .jb-section { padding: 18px; }
  /* На телефоне баннер это СТОЛБИК: заголовок строкой, действия строкой под
     ним. Так он и выглядел — но получалось это переносом (`flex-wrap`), а
     перенос не делает часть строкой во всю ширину. Пока действий одно, разницы
     не видно; как только их завернули в свой ряд, ряд встал по содержимому и
     распёр страницу: на «Моём опыте» баннер разбора резюме с двумя кнопками
     давал 421px при окне 375 — вся страница ездила вбок (найдено замером
     29.08.2026). Кнопкам при этом `width: 100%` уже стоял, и ряд из двух
     таких кнопок как раз и вырастал вдвое.

     `flex-direction: column` говорит то же самое прямо, и `flex: none`, которым
     экранная композиция держит ряд действий справа на десктопе, ему больше не
     мешает: во что вырастет часть поперёк столбика, решает `align-items`, а не
     `flex`. Поэтому чинится это здесь, одним свойством, а не оговоркой в
     каждом экране, который заворачивает свои кнопки в ряд. */
  .jb-banner { flex-direction: column; align-items: stretch; }
  .jb-banner .jb-btn { width: 100%; }
  .jb-funnel-row { grid-template-columns: 84px 1fr 40px; }
  .jb-bars { gap: 4px; }
  /* `anywhere`, а не `break-all` (17.08.2026): на диапазонных подписях вроде
     «600–1000» жёсткий разрыв рубил число посреди разряда — «600–10 / 00»,
     и подписи превращались в кашу. `anywhere` переносит по тире, а рвёт слово
     только когда иначе не влезает. Поводом стали семь бинов зарплатной
     гистограммы: с пятью тесноты не было. */
  .jb-bar-l { font-size: 9.5px; line-height: 1.25; white-space: normal; overflow-wrap: anywhere; text-align: center; }
  .jb-table th, .jb-table td { padding: 8px 7px; font-size: 12.5px; }
  /* ApplicationCard: шкала этапов становится вертикальной */
  .jb-timeline { flex-direction: column; gap: 12px; }
  .jb-timeline li { display: flex; gap: 12px; align-items: center; text-align: left; }
  .jb-timeline li::before { margin: 0; }
  .jb-timeline li::after { left: 14px; top: 32px; bottom: -14px; right: auto; width: 2px; height: auto; }
  .jb-timeline .lbl { white-space: normal; }
  .jb-card-foot { flex-direction: column; align-items: stretch; }
}

/* 19. ОНБОРДИНГ (TourStep / CoachHint) --------------------------- */
/* Эталон — jobburg-onboarding.html, описание — jobburg-ui-kit.md.
   Тёмный поповер выбран как единый вариант обоих блоков: он уже есть в
   продукте (.jb-card-hint) и по правилам доступности белый текст на
   --jb-ink разрешён. Своих цветов у блока нет — только токены. */

/* Слой тура: ловит клики, чтобы страница под ним не реагировала.
   Затемнение рисует не он, а сам прожектор — огромной тенью, поэтому
   «окно» всегда совпадает с подсвеченным элементом. */
.jb-tour-overlay { position: fixed; inset: 0; z-index: 100; background: transparent; }
.jb-tour-spot {
  position: fixed; z-index: 101; pointer-events: none;
  border: 2px solid var(--jb-blue); border-radius: var(--jb-radius-md);
  box-shadow: 0 0 0 9999px rgba(15, 23, 42, .55), var(--jb-focus-ring);
}
/* Подсветка якоря для подсказки первого захода: та же рамка, но без
   затемнения страницы — подсказка не блокирует работу. */
.jb-coach-target {
  outline: 2px solid var(--jb-blue); outline-offset: 2px;
  border-radius: var(--jb-radius-md); box-shadow: var(--jb-focus-ring);
}

.jb-tour-pop, .jb-coach-pop {
  position: fixed; z-index: 102; max-width: 320px;
  background: var(--jb-ink); color: var(--jb-surface);
  border-radius: var(--jb-radius-lg); box-shadow: var(--jb-shadow-md);
  padding: 14px 16px; font: 500 13.5px/1.45 var(--jb-font);
}
/* Стрелка — как у тултипа .jb-card-hint: квадрат под 45° цветом поповера.
   Смещение задаётся из JS переменной --jb-pop-arrow, чтобы остриё смотрело
   на якорь и когда поповер прижат к краю экрана. */
.jb-tour-pop::before, .jb-coach-pop::before {
  content: ''; position: absolute; left: var(--jb-pop-arrow, 20px);
  width: 10px; height: 10px; background: var(--jb-ink); transform: rotate(45deg);
}
.jb-tour-pop--below::before, .jb-coach-pop--below::before { top: -5px; }
.jb-tour-pop--above::before, .jb-coach-pop--above::before { bottom: -5px; }
/* Якорь уехал за пределы окна: человек прокрутил страницу, чтобы её прочитать.
   Поповер прижимается к низу окна и остаётся читаемым — до 25.08.2026 он
   уезжал за верхний край вместе с якорем, и подсказка «исчезала сама», хотя
   закрыть её можно только кнопкой. Стрелки нет: указывать ей больше не
   на что. Приём тот же, что у узкого экрана ниже, поэтому второго языка
   позиционирования блок не заводит. */
.jb-tour-pop--pinned, .jb-coach-pop--pinned { top: auto; bottom: 12px; }
.jb-tour-pop--pinned::before, .jb-coach-pop--pinned::before { display: none; }

.jb-tour-title, .jb-coach-title {
  font-size: 15px; font-weight: 700; line-height: 1.3; margin: 0 0 4px; color: var(--jb-surface);
}
/* Приглушённый текст на тёмном — токен --jb-border-strong (#CBD5E1), тот же
   приём, что у подзаголовка тёмного hero лендинга. Новых значений нет. */
.jb-tour-text, .jb-coach-text { margin: 0; color: var(--jb-border-strong); }

.jb-tour-foot, .jb-coach-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-top: 14px;
}
.jb-coach-foot { justify-content: flex-end; }
.jb-tour-count { font-size: 12.5px; color: var(--jb-border-strong); font-variant-numeric: tabular-nums; }
.jb-tour-acts { display: flex; gap: 8px; align-items: center; }
.jb-tour-pop .jb-btn, .jb-coach-pop .jb-btn { min-height: 36px; }

/* «Пропустить» — ghost на тёмном фоне: прозрачная кнопка с белым текстом по
   образцу «Войти» в тёмном hero лендинга. Обычный ghost кита здесь нечитаем —
   у него текст --jb-text-secondary. */
.jb-tour-skip {
  background: transparent; color: var(--jb-surface);
  border: 1px solid var(--jb-text-secondary); border-radius: var(--jb-radius-md);
  font: 600 13px var(--jb-font); padding: 8px 14px; min-height: 36px; cursor: pointer;
  transition: border-color .15s;
}
.jb-tour-skip:hover { border-color: var(--jb-surface); }
.jb-tour-skip:focus-visible { outline: none; box-shadow: var(--jb-focus-ring); }

/* На узком экране поповер прижимается к низу на всю ширину: рядом с якорем
   ему там не хватает места, а стрелка теряет смысл. */
@media (max-width: 640px) {
  .jb-tour-pop, .jb-coach-pop {
    left: 10px; right: 10px; bottom: 10px; top: auto; max-width: none;
  }
  .jb-tour-pop::before, .jb-coach-pop::before { display: none; }
  .jb-tour-acts { flex: 1; }
  .jb-tour-acts .jb-btn, .jb-tour-skip { flex: 1; }
}

/* 20. ПОМОЩНИК (HelperPanel) ------------------------------------ */
/* Эталон — jobburg-helper.html, описание — jobburg-ui-kit.md.
   Панель «веду за руку»: где я, что делать здесь, что дальше и сколько
   пройдено. В отличие от TourStep/CoachHint — светлая и вызывается по
   требованию, поэтому и выглядит как обычная карточка продукта. */
.jb-helper {
  position: fixed; z-index: 120; right: 16px; top: 76px; width: 340px; max-height: calc(100vh - 96px);
  display: flex; flex-direction: column;
  background: var(--jb-surface); border: 1px solid var(--jb-border);
  border-radius: var(--jb-radius-lg); box-shadow: var(--jb-shadow-md);
}
.jb-helper-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 14px 16px; border-bottom: 1px solid var(--jb-border);
}
.jb-helper-title { font-size: 15px; font-weight: 700; color: var(--jb-text); }
.jb-helper-close {
  background: none; border: none; cursor: pointer; font-size: 22px; line-height: 1;
  color: var(--jb-text-muted); width: 36px; height: 36px; border-radius: var(--jb-radius-md);
}
.jb-helper-close:hover { background: var(--jb-bg); color: var(--jb-text); }
.jb-helper-close:focus-visible { outline: none; box-shadow: var(--jb-focus-ring); }
.jb-helper-body { padding: 16px; overflow-y: auto; }

.jb-helper-where { margin: 0 0 6px; font-size: 13px; color: var(--jb-text-muted); }
.jb-helper-where b { color: var(--jb-text); }
.jb-helper-text { margin: 0; font-size: 14px; line-height: 1.5; color: var(--jb-text-secondary); }

/* Следующий шаг — единственный акцентный блок панели. */
.jb-helper-next {
  margin-top: 14px; padding: 12px 14px;
  background: var(--jb-blue-bg); border: 1px solid var(--jb-blue-border);
  border-radius: var(--jb-radius-md);
}
.jb-helper-next-label {
  margin: 0 0 4px; font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; color: var(--jb-blue);
}
.jb-helper-next-text { margin: 0 0 10px; font-size: 14px; line-height: 1.5; color: var(--jb-text); }
.jb-helper-next .jb-btn { margin: 0; }

.jb-helper-path-label {
  margin: 18px 0 8px; font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; color: var(--jb-text-muted);
}
.jb-helper-path { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.jb-helper-path li {
  display: flex; align-items: center; gap: 10px;
  font-size: 13.5px; color: var(--jb-text-muted);
}
/* Кружок состояния. Пройденный шаг несёт галочку, а не только цвет: состояние
   не должно передаваться одним цветом (правило доступности кита). */
.jb-helper-step-mark {
  flex: none; width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid var(--jb-border-strong); position: relative;
}
.jb-helper-path li.is-done { color: var(--jb-text-secondary); }
.jb-helper-path li.is-done .jb-helper-step-mark { border-color: var(--jb-success); background: var(--jb-success); }
.jb-helper-path li.is-done .jb-helper-step-mark::after {
  content: ''; position: absolute; left: 4px; top: 1px; width: 4px; height: 8px;
  border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg);
}
.jb-helper-path li.is-current { color: var(--jb-blue); font-weight: 700; }
.jb-helper-path li.is-current .jb-helper-step-mark { border-color: var(--jb-blue); background: var(--jb-blue-bg); }
.jb-helper-step-note { margin-left: auto; font-size: 12.5px; color: var(--jb-text-muted); font-variant-numeric: tabular-nums; }

/* Иконка вызова помощника — это `jb-iconbtn` (раздел 9) с состоянием
   `.is-open`, а НЕ отдельный блок. Свой `.jb-helper-btn` (36px) существовал до
   10.08.2026 и был вторым размером той же круглой кнопки: в шапке приложения
   помощник стоит в одном ряду с FAQ, колокольчиком и меню — на 2px мельче
   соседей он бы просто выпадал из ряда. */

@media (max-width: 640px) {
  .jb-helper { left: 10px; right: 10px; top: auto; bottom: 10px; width: auto; max-height: 78vh; }
}

/* 21. TABS (вкладки кейса) -------------------------------------- */
/* Ряд вкладок под шапкой кейса ментора. Эталон — jobburg-mentor-case.html,
   описание — раздел «Кабинет ментора — Кейс (MentorCasePage)» кита.
   На узких экранах ряд прокручивается ГОРИЗОНТАЛЬНО целиком: вкладки не
   переносятся на вторую строку и не обрезаются многоточием — иначе на 360px
   часть разделов кейса просто исчезала бы из виду. */
.jb-tabs {
  display: flex; gap: 24px; border-bottom: 1px solid var(--jb-border);
  margin: 0 0 20px; overflow-x: auto; scrollbar-width: none;
}
.jb-tabs::-webkit-scrollbar { display: none; }
/* Весь ряд синий, текущий раздел отличается ЛИНИЕЙ под ним — так вкладки
   выглядят в эталонах кита (там они ссылки и попадают под `.jb a`), и это
   состояние согласовано как целевое.
   border-radius: 0 обязателен: вкладка бывает <button>, а страницы кабинета
   скругляют кнопки глобально — со скруглением подчёркивание превращалось
   в «скобку» вместо прямой линии. */
.jb-tab {
  padding: 11px 2px; font-size: 14px; font-weight: 600;
  color: var(--jb-blue); text-decoration: none; white-space: nowrap;
  border-bottom: 2px solid transparent; border-radius: 0; flex: none;
  background: none; border-left: none; border-right: none; border-top: none;
  cursor: pointer; font-family: var(--jb-font);
}
.jb-tab:hover { color: var(--jb-blue); text-decoration: underline; }
.jb-tab.active { color: var(--jb-blue); border-bottom-color: var(--jb-blue); }
.jb-tab:focus-visible { outline: none; box-shadow: var(--jb-focus-ring); }


/* 22. TASKSTRIP (полоска фоновой задачи) ------------------------- */
/* Тонкая строка вверху экрана: долгая операция не запирает интерфейс модалкой,
   человек видит прогресс и продолжает работать. Логика — uikit/jobburg-taskstrip.js,
   контейнер #task-strips первым элементом body. */
/* ===== Универсальные фоновые полоски долгих задач (оценка/разбор/red-flags/add/offer) =====
   Все долгие фоновые задачи показывают прогресс одинаковой полоской вверху страницы.
   #task-strips — фиксированный стек: несколько задач кладутся друг под друга; JS ставит
   body.padding-top = высоте стека, чтобы полоски ничего не перекрывали (syncTaskStripsPadding).
   Светло-рыжий фон (uikit --jb-warning-bg) с тёмным читаемым текстом. */
#task-strips { position: fixed; top: 0; left: 0; right: 0; z-index: 900; display: flex; flex-direction: column; }
.task-strip { background: var(--jb-warning-bg); border-bottom: 1px solid var(--jb-warning-border); box-shadow: var(--jb-shadow-md); }
.task-strip-inner { max-width: 1280px; margin: 0 auto; padding: 9px 24px; display: flex; align-items: center; gap: 14px; }
.task-strip-title { font: 700 13px var(--jb-font); color: var(--jb-ink); white-space: nowrap; flex: 0 0 auto; }
.task-strip-track { flex: 0 0 200px; height: 6px; background: rgba(180,83,9,0.14); border-radius: 999px; overflow: hidden; }
.task-strip-fill { height: 100%; width: 0; background: var(--jb-warning); border-radius: 999px; transition: width .3s ease; }
/* Неопределённый прогресс: пока задача идёт, сегмент едет по дорожке (чтобы бар «двигался»). */
.task-strip-fill.busy { width: 35% !important; animation: task-strip-indeterminate 1.1s ease-in-out infinite; }
@keyframes task-strip-indeterminate { 0% { margin-left: -35%; } 100% { margin-left: 100%; } }
.task-strip-label { font: 500 13px var(--jb-font); color: var(--jb-ink); flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.task-strip-label.is-error { color: var(--jb-danger); font-weight: 600; }
.task-strip-label.is-done { cursor: pointer; text-decoration: underline; }
.task-strip-close { flex: 0 0 auto; background: none; border: none; color: var(--jb-ink); font-size: 17px; line-height: 1; cursor: pointer; padding: 4px 9px; border-radius: 6px; }
.task-strip-close:hover { background: rgba(0,0,0,0.10); color: var(--jb-ink); }
/* На узком экране полоска идёт В ДВЕ СТРОКИ: сверху заголовок, дорожка и
   крестик, метка — своей строкой во всю ширину. Одной строкой она не помещалась
   и обрезалась многоточием до двух символов («Ан…»): на 375px от «Анализирую
   резюме · осталось ~39 с» не оставалось ни задачи, ни отсчёта, то есть полоска
   переставала сообщать хоть что-то (найдено 15.08.2026 живым прогоном). */
@media (max-width: 640px) {
  .task-strip-inner { flex-wrap: wrap; padding: 9px 16px; gap: 8px 10px; }
  .task-strip-track { flex-basis: 72px; }
  .task-strip-close { order: 3; }
  .task-strip-label { order: 4; flex: 1 1 100%; white-space: normal; overflow: visible; text-overflow: clip; }
}

/* 23. CHIPEDITOR (редактор списков-чипов) ------------------------ */
/* Поле со значениями-чипами: Enter добавляет, крестик удаляет, снизу подсказки
   из словаря. Логика — uikit/jobburg-chipeditor.js. */
.kc-editor { display: flex; flex-direction: column; gap: 10px; }
.kc-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.kc-chips:empty { display: none; }
.kc-chip { display: inline-flex; align-items: center; gap: 6px; padding: 6px 10px; border-radius: 999px; background: var(--jb-blue-bg); color: var(--jb-blue); font-size: 13px; font-weight: 500; }
.kc-chip-x { cursor: pointer; border: none; background: none; color: inherit; font-size: 15px; line-height: 1; padding: 0; opacity: 0.7; }
.kc-chip-x:hover { opacity: 1; }
.kc-input-wrap { position: relative; flex: 1 1 auto; min-width: 0; }
/* Строка ввода: поле + кнопка подтверждения. Кнопка добавлена 11.08.2026 —
   до неё чип заводился только Enter'ом или выбором из подсказки, и это было
   ниоткуда не видно: человек вводил текст, уходил на «Далее» и терял его
   (спасал только commitPending). `align-items: flex-start` — чтобы кнопка
   держалась у верхнего края, когда под полем раскрыт список подсказок. */
.kc-input-row { display: flex; gap: 8px; align-items: flex-start; }
/* Повтор: значение уже в списке. Предупреждение, а не ошибка — человек ничего
   не сломал, просто действие не имеет смысла; поле при этом НЕ очищается. */
.kc-dup { margin: 6px 0 0; font-size: 13px; font-weight: 500; color: var(--jb-warning); }
.kc-suggest { position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 20; max-height: 240px; overflow-y: auto; background: var(--jb-surface); border: 1px solid var(--jb-border); border-radius: var(--jb-radius-md); box-shadow: var(--jb-shadow-md); }
.kc-suggest-item { padding: 9px 14px; font-size: 13.5px; cursor: pointer; }
.kc-suggest-item:hover, .kc-suggest-item.active { background: var(--jb-blue-bg); }
.kc-suggest-add { color: var(--jb-text-secondary); }

/* 24. MODAL (диалог поверх страницы) ----------------------------- */
/* Блок появился в ките 2026-08-08: модалки были в трёх эталонных страницах, но
   стилей у них не было — каждый фронт держал свою копию из dashboard.css.
   Ширину сверх базовой задаёт ЭКРАН своим классом поверх .jb-modal-card
   (специфичность 0-2-0 — иначе базовое правило побеждает по порядку). */
.jb-modal-overlay {
  position: fixed; inset: 0; z-index: 50;
  display: flex; align-items: center; justify-content: center; padding: 20px;
  background: rgba(20, 25, 28, .5);
}
.jb-modal-card {
  width: 100%; max-width: 420px; max-height: 90vh; overflow-y: auto;
  padding: 28px 32px;
  background: var(--jb-surface);
  border: 1px solid var(--jb-border);
  border-radius: var(--jb-radius-lg);
  box-shadow: var(--jb-shadow-md);
}
.jb-modal-card h2 { margin: 0 0 18px; font-size: 19px; font-weight: 700; }

/* Подтверждение — модалка с вопросом и РОВНО двумя ответами (25.08.2026).
   Заведено, потому что паттерн повторяющийся, а верстался он каждым экраном
   заново: у одних ряд кнопок звался `apply-actions`, у других `prof-actions`,
   и порядок ответов на узком экране получался разный.
   Ответов именно два: вопрос закрытый, третий вариант означал бы, что вопрос
   задан неправильно. Primary одна — утвердительный ответ; отказ уводить в
   ghost нельзя, он равноправный выход, поэтому secondary.
   На узком экране кнопки в колонку и во всю ширину, порядок DOM сохраняется:
   утвердительный ответ сверху, как читается сам вопрос. */
.jb-confirm-text { margin: 0 0 20px; color: var(--jb-text-secondary); font-size: 14px; }
.jb-confirm-actions { display: flex; gap: 10px; justify-content: flex-end; flex-wrap: wrap; }
@media (max-width: 480px) {
  .jb-confirm-actions { flex-direction: column; }
  .jb-confirm-actions .jb-btn { width: 100%; }
}

/* 25. NAVMENU (меню разделов в шапке) ---------------------------- */
/* Выпадает из иконки-гамбургера, лежит поверх содержимого и закрывается кликом
   мимо. До 10.08.2026 блока в ките не было вовсе: кабинет рисовал `.menu-*`,
   React — свои `.shell-menu-*`, и они разошлись (радиус, кегль пункта, наличие
   разделителя под адресом почты).
   ГЛАВНОЕ — селектор с тегом у пункта. Пункт меню это <a>, а базовое правило
   кита `.jb a` имеет специфичность (0,1,1) и перебивает одиночный класс: без
   `a.jb-menu-item` ВСЕ пункты красятся синим, меню превращается в список ссылок
   и «Выйти» перестаёт читаться как опасное действие. Тот же капкан уже сработал
   на логотипе (`a.shell-logo`) и на строках «Инструментов» (`a.tools-item`). */
.jb-menu {
  position: absolute; right: 0; top: 48px; z-index: 50; min-width: 220px;
  display: flex; flex-direction: column; padding: 8px;
  background: var(--jb-surface); border: 1px solid var(--jb-border);
  border-radius: var(--jb-radius-lg); box-shadow: var(--jb-shadow-md);
}
/* Адрес почты — не пункт, а подпись «чей это аккаунт»: приглушён и отделён
   линией, иначе читается как первый пункт списка. */
.jb-menu-user {
  padding: 8px 10px; font-size: 12.5px; color: var(--jb-text-muted);
  border-bottom: 1px solid var(--jb-border); margin-bottom: 6px; word-break: break-all;
}
.jb-menu-item, a.jb-menu-item, .jb a.jb-menu-item {
  display: block; width: 100%; text-align: left; font: inherit; font-size: 14px;
  padding: 9px 10px; border: none; background: none; color: var(--jb-text);
  text-decoration: none; border-radius: var(--jb-radius-sm); cursor: pointer;
}
.jb-menu-item:hover, .jb a.jb-menu-item:hover { background: var(--jb-bg); color: var(--jb-text); text-decoration: none; }
.jb-menu-item:focus-visible { outline: none; box-shadow: var(--jb-focus-ring); }
/* Текущий раздел (добавлено 11.08.2026). До этого меню не отвечало на вопрос
   «где я»: все пункты выглядели одинаково, и на глубоких экранах человек терял
   раздел. Признак не только цветом — ещё и насыщенностью шрифта, а в разметке
   `aria-current="page"`.
   Селектор с тегом обязателен по той же причине, что и у самого пункта: `.jb a`
   имеет специфичность (0,1,1) и перебивает одиночный класс. */
.jb-menu-item.is-active,
a.jb-menu-item.is-active,
.jb a.jb-menu-item.is-active {
  background: var(--jb-blue-bg); color: var(--jb-blue); font-weight: 600;
}
/* Выход — единственное необратимое действие в меню, поэтому единственное
   цветное. */
.jb-menu-item--logout, .jb a.jb-menu-item--logout { color: var(--jb-danger); }
.jb-menu-divider { height: 1px; background: var(--jb-border); margin: 6px 4px; }

/* 26. BREADCRUMBS (путь до страницы) ----------------------------- */
/* Строка под шапкой на КАЖДОЙ странице кабинета, кроме корня и нулевого
   экрана; путь полный — от корня до текущей страницы, звеньев столько, сколько
   у неё уровней (решение владельца 26.08.2026). Паттерн жил только в эталонах
   (career-analytics, mentor-overview, search-v2) локальными копиями `.crumbs`,
   а в приложении его не было вовсе.
   Слева путь, справа «← Назад»: путь отвечает на «где я», ссылка — на «как
   вернуться», и это разные вопросы.
   Звенья — <a>, поэтому селектор с тегом обязателен: `.jb a` иначе перекрасит
   и текущую страницу, которая ссылкой НЕ является. */
.jb-crumbs {
  display: flex; justify-content: space-between; align-items: center;
  gap: 12px; flex-wrap: wrap; margin: 14px 0 12px; font-size: 14px;
}
/* Путь переносится по звеньям и НЕ распирает страницу: на узком экране длинное
   название («Сопроводительное письмо») выталкивало документ на 11px, и по
   горизонтали ездил весь экран, а не крошки (поймано обходом на 360px). */
.jb-crumbs-path { min-width: 0; display: inline-flex; flex-wrap: wrap; align-items: baseline; }
.jb-crumbs-path > span { min-width: 0; }
.jb-crumbs-path a, .jb a.jb-crumbs-link { color: var(--jb-blue); text-decoration: none; }
.jb-crumbs-path a:hover, .jb a.jb-crumbs-link:hover { text-decoration: underline; }
/* Разделитель приглушён: он служебный и не должен спорить со звеньями. */
.jb-crumbs-sep { color: var(--jb-text-muted); margin: 0 6px; }
/* Текущая страница — не ссылка: вести с неё некуда. */
.jb-crumbs-current { font-weight: 600; color: var(--jb-text); }
.jb-crumbs-back, .jb a.jb-crumbs-back { color: var(--jb-text-secondary); text-decoration: none; white-space: nowrap; }
.jb-crumbs-back:hover, .jb a.jb-crumbs-back:hover { color: var(--jb-text); text-decoration: underline; }

/* 27. BULLETLIST (список выводов) -------------------------------- */
/* Маркированный список коротких утверждений: рекомендации на дашборде, выводы
   разбора вакансии, советы карьерной аналитики. Блока в ките не было, и одно и
   то же успело развестись в ТРИ вида: `eval-list` (14px), `ca-recs` (без
   размера), `jb-insights` в эталоне дашборда (14.5px). Здесь один.
   Маркер оставлен родным (`padding-left` вместо своих значков): список читают
   как перечень, и подмена маркера ничего не добавляет, зато ломает выделение
   и копирование текста. */
.jb-bullets {
  margin: 0; padding-left: 20px;
  display: flex; flex-direction: column; gap: 6px;
  font-size: 14px; line-height: 1.5;
}

/* 28. CHANNELS (список Telegram-каналов) ------------------------- */
/* Эталон — jobburg-search-channels.html. Блок жил ДВУМЯ копиями: в dashboard.css
   и в стилях React-экрана поиска, причём вторая копия успела потерять и тематику
   канала, и ссылку «Удалить» — ровно тот случай, когда расхождение видно только
   рядом. Здесь один источник; экраны задают лишь своё место в потоке.
   jb-collapse, jb-switch и jb-badge берутся из своих разделов выше. */
.tg-collapse {
  border: 1px solid var(--jb-border);
  border-radius: var(--jb-radius-lg);
  margin-bottom: 12px;
}
.tg-collapse summary { padding: 14px 20px; font-size: 14px; }
.tg-collapse .jb-collapse-inner { padding: 0 20px 16px; }
/* Капс-подзаголовок группы: он маркирует раздел, а не заявляет заголовок.
   Одно правило на два адреса: группы каналов (здесь) и группы источников в
   «Настройке поиска» (`.jb-subhead`, 24.08.2026). Вид у них один, и второй
   экземпляр объявления разъехался бы — как уже разъезжались копии самого
   блока каналов. */
.jb-subhead,
.tg-collapse .ch-sub {
  font-size: 12px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .05em;
  color: var(--jb-text-muted);
}
/* Подзаголовок как САМОСТОЯТЕЛЬНАЯ строка (вне summary) нуждается в своих
   отступах: внутри Collapse их задаёт сам summary. */
.jb-subhead { display: block; margin: 18px 0 2px; }
.jb-subhead:first-child { margin-top: 0; }
/* Счётчик прижат к подзаголовку, стрелка Collapse остаётся у правого края. */
.tg-collapse summary .jb-badge { margin-left: 8px; margin-right: auto; }
.chrow {
  display: flex; gap: 14px; align-items: center;
  padding: 11px 2px;
  border-bottom: 1px solid var(--jb-border);
  flex-wrap: wrap;
}
.chrow:last-of-type { border-bottom: none; }
/* Выключенный канал приглушается целиком — вместе с тематикой. */
.chrow.off .chname, .chrow.off .chdesc { color: var(--jb-text-muted); }
.chname { font-weight: 700; font-size: 14px; }
.chhandle { font-size: 12.5px; color: var(--jb-text-muted); }
.chdesc { font-size: 12.5px; color: var(--jb-text-secondary); }
.chrow .right { margin-left: auto; display: flex; gap: 14px; align-items: center; flex: none; }
/* «Удалить» — опасное действие, но не кнопка: оно вторично рядом с тумблером. */
.del, .jb a.del {
  font-size: 13px; font-weight: 600;
  color: var(--jb-danger); text-decoration: none; cursor: pointer;
  background: none; border: none; font-family: var(--jb-font);
}
.del:hover, .jb a.del:hover { text-decoration: underline; }
/* Форма добавления: два поля тянутся, кнопка прижата к их нижней линии. */
.tg-addform { display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end; margin-top: 14px; }
.tg-addform > div { flex: 1; min-width: 160px; }
.tg-addform .tg-addform-btn { flex: 0 0 auto; min-width: 0; }

/* 29. RESUMEIMPORT (карточка загрузки резюме) -------------------- */
/* Эталон — jobburg-career.html, шаг 1. Блок жил в CSS экрана (career.css), и
   эталонного рендера у него не было: сверить вид глазами было негде — ровно
   тот путь, которым копии расходятся (перенесён в кит 11.08.2026 вместе с
   переездом карточки внутрь шага 1).
   Прогресс показывается ПОЛОСКОЙ В КАРТОЧКЕ, а не полоской задачи вверху
   страницы (раздел 22) и не модалкой: разбор идёт секунды и относится к полю,
   рядом с которым стоит. Реального прогресса сервер не отдаёт — полоска ползёт
   к 90 %, рядом идёт обратный отсчёт до жёсткого предела ожидания. */
.resume-import {
  border: 1px solid var(--jb-border);
  border-radius: var(--jb-radius-lg);
  background: var(--jb-surface);
  padding: 16px 18px;
}
/* Название действия слева, кнопка справа; на узком экране кнопка уходит вниз. */
.resume-import-main {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
}
.resume-import-title { display: block; font-weight: 600; margin-bottom: 2px; }
.resume-progress { margin-top: 14px; }
.resume-progress-track {
  height: 6px; border-radius: 999px;
  background: var(--jb-bg); overflow: hidden;
}
.resume-progress-fill { height: 100%; background: var(--jb-blue); transition: width .2s linear; }
/* Ошибку красит и полоска, и текст под ней: одним цветом состояние не
   передаётся (правило доступности кита). */
.resume-progress-fill.is-error { background: var(--jb-danger); }
.resume-progress-status { font-size: 13px; color: var(--jb-text-secondary); margin-top: 8px; }
.resume-progress-status.is-error { color: var(--jb-danger); }
/* Несохранённые расхождения с прежним резюме: сверка не потеряна, к ней можно
   вернуться. Блок стоит на уровне МАСТЕРА, а не внутри карточки загрузки:
   после разбора мастер прыгает к первому незаполненному шагу, шаг 1 вместе с
   карточкой уходит с экрана — и напоминание о незакрытой сверке исчезло бы
   вместе с ним. */
.resume-diff-pending {
  margin-top: 14px;
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
  font-size: 13px; color: var(--jb-text-secondary);
}

/* 30. BLACKLIST (чёрный список компаний) ------------------------- */
/* Эталон — jobburg-career.html, шаг «Отрасли и ограничения». Блок жил в CSS
   экрана (career.css) и эталонного рендера не имел — тот же путь, которым
   расходятся копии; перенесён в кит 11.08.2026 вместе с переездом списка
   внутрь шага. Своей карточки у списка больше нет: это ограничение поиска,
   такое же как целевые отрасли, и отдельной секцией под мастером он читался
   как самостоятельный инструмент.
   Поля «Причина» в ФОРМЕ нет — необязательное поле заставляло думать над тем,
   что системе не нужно; уже сохранённая причина показывается в строке. */
.blacklist-rows { display: flex; flex-direction: column; margin-top: 12px; }
.blacklist-row {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--jb-border);
}
.blacklist-row:last-child { border-bottom: none; }
.blacklist-company { font-weight: 600; font-size: 14px; }
/* Мета забирает остаток строки — кнопка удаления прижата к правому краю. */
.blacklist-meta { font-size: 13px; color: var(--jb-text-muted); margin-right: auto; }
/* Форма добавления: поле тянется, но умеет и сжиматься (`min-width: 0`) — без
   этого кнопка «Добавить» выдавливалась за край карточки. */
.blacklist-add-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end; margin-top: 12px; }
.blacklist-add-row .jb-field { flex: 1 1 180px; min-width: 0; margin-bottom: 0; }
.blacklist-add-row .jb-btn { flex: 0 0 auto; }
/* Ряд кнопок в модалке подтверждения: отмена слева, удаление справа. */
.blacklist-confirm-actions { display: flex; gap: 12px; align-items: center; margin-top: 20px; }

/* 31. EXPERIENCEBLOCK (строка анкеты «Моего опыта») --------------- */
/* Эталон — jobburg-career.html, состояние «резюме заполнено».
   С 25.08.2026 (выбор владельца — комбинация двух вариантов из трёх) блок это
   СТРОКА: название поля слева, ответ по центру, действие справа. Прежде он был
   карточкой «заголовок сверху, превью под ним», и одиннадцать таких карточек
   читались как одиннадцать разделов; в строке видно и ответ, и то, что поле
   пустое, не вчитываясь.

   Пустая строка не молчит: вместо ответа она говорит, ЧТО включит заполненное
   поле (`JBCareer.FIELD_EFFECT`) — «дозаполнить информацию» отвечало на
   вопрос «что сделать», но не на «зачем».

   Строки собраны в группы по смыслу (`.jb-exp-group` + счётчик), потому что
   одиннадцать полей подряд не отвечают, зачем их спрашивают. */
.jb-exp-list { display: flex; flex-direction: column; }
/* Три колонки: имя поля фиксированной ширины (чтобы ответы стояли столбцом и
   читались вертикально), ответ и действие. На узком — один столбец. */
.jb-exp {
  display: grid; grid-template-columns: 220px 1fr auto; gap: 14px;
  align-items: start; padding: 12px 0; border-bottom: 1px solid var(--jb-border);
}
.jb-exp:last-child { border-bottom: none; }
@media (max-width: 700px) { .jb-exp { grid-template-columns: 1fr; gap: 6px; } }
/* 14/700 — строка списка, а не заголовок раздела. Селектор с тегом обязателен:
   `.jb-section h2` имеет специфичность (0,1,1) и перебивает одиночный класс —
   заголовок печатался кеглем секции и превращал строку в отдельный раздел.

   Тегов ДВА, и это не небрежность, а иерархия. С 29.08.2026 группа анкеты «Моего
   опыта» стоит в своей карточке и несёт собственный заголовок `h2` — строка под ним
   стала `h3`. Там, где заголовка над строками нет вовсе — сводка «Профессиональной
   цели» и принятый ввод «Красных флагов», — строка осталась `h2` под `h1` страницы.
   Без `h3` в селекторе строка печаталась бы кеглем `.jb h3` — 19px, КРУПНЕЕ заголовка
   своей группы. */
h2.jb-exp-title, .jb-section h2.jb-exp-title,
h3.jb-exp-title, .jb-section h3.jb-exp-title {
  font-size: 14px; font-weight: 700; color: var(--jb-text); margin: 0;
}
/* У пустой строки имя поля приглушено: заполненное важнее незаполненного. */
.jb-exp.is-empty h2.jb-exp-title, .jb-exp.is-empty .jb-exp-title { color: var(--jb-text-secondary); }
.jb-exp-actions { display: flex; align-items: center; gap: 10px; flex: none; }
/* «развернуть»/«свернуть» — действие-ссылка: оно ничего не меняет в данных. */
.jb-exp-toggle, .jb a.jb-exp-toggle {
  font-size: 13px; font-weight: 600; color: var(--jb-blue);
  background: none; border: none; padding: 0; cursor: pointer; font-family: var(--jb-font);
}
.jb-exp-toggle:hover { text-decoration: underline; }
.jb-exp-toggle:focus-visible, .jb-exp-edit:focus-visible { outline: none; box-shadow: var(--jb-focus-ring); }
/* Карандашик «изменить» — кнопка-иконка, подпись у неё в aria-label: в списке
   из одиннадцати одинаковых кнопок «изменить» без предмета бесполезно. */
.jb-exp-edit {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; flex: none;
  border: 1px solid var(--jb-border); border-radius: var(--jb-radius-sm);
  background: var(--jb-surface); color: var(--jb-text-secondary); cursor: pointer;
}
.jb-exp-edit:hover { background: var(--jb-blue-bg); border-color: var(--jb-blue-border); color: var(--jb-blue); }
/* Ответ: сколько строк видно в закрытом виде. Лимит объявлен ЗДЕСЬ и только
   здесь — обрезает строки браузер, и второе число в JS было бы копией,
   которая молча разъедется с настоящим обрезанием. */
.jb-exp-preview {
  --jb-exp-preview-lines: 3;
  margin: 0;
  font-size: 14px; color: var(--jb-text-secondary);
  white-space: pre-wrap; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-box-orient: vertical;
  -webkit-line-clamp: var(--jb-exp-preview-lines);
  overflow: hidden;
}
/* Длинное превью — принятый ввод (текст вакансии в «Красных флагах»). Это не
   строка анкеты, а целый документ, который человек вставил и должен узнать в
   свёрнутом виде: трёх строк для этого мало, десяти хватает. Модификатор
   меняет ТОЛЬКО число строк — обрезание, разворот и `.is-open` те же самые. */
.jb-exp-preview--long { --jb-exp-preview-lines: 10; }
/* Развёрнутый блок показывает ответ целиком — на том же месте, без перехода. */
.jb-exp-preview.is-open { -webkit-line-clamp: unset; display: block; overflow: visible; }
/* Пустое поле на месте ответа: «не заполнено — и вот что это включит». */
.jb-exp-empty { margin: 0; font-size: 13.5px; color: var(--jb-text-muted); }
/* СОВМЕСТИМОСТЬ: тем же блоком показывают ПРИНЯТЫЙ ВВОД — целый текст
   вакансии в «Красных флагах» и записи истории проверок. Там форма другая:
   заголовок с действием сверху (`.jb-exp-head`), документ под ним. Такая
   разметка занимает всю ширину строки и ведёт себя как прежде, поэтому один
   блок обслуживает оба случая: строку анкеты и вставленный документ. */
.jb-exp-head {
  grid-column: 1 / -1; display: flex; align-items: center;
  justify-content: space-between; gap: 12px; flex-wrap: wrap;
}
.jb-exp-head ~ .jb-exp-preview, .jb-exp-head ~ .jb-link-blue { grid-column: 1 / -1; margin-top: 6px; }
/* Форма правки раскрывается на всю ширину строки, а не в колонку ответа. */
.jb-exp-form { grid-column: 1 / -1; margin-top: 10px; }
.jb-exp-save { display: flex; align-items: center; gap: 12px; margin-top: 16px; }
/* Заголовок группы полей: имя, зачем эта группа нужна, и счётчик заполненного.
   Счётчик — обычный `jb-badge`: он сообщает состояние, а не зовёт нажать.

   С 29.08.2026 (решение владельца) каждая группа анкеты «Моего опыта» стоит в
   ОТДЕЛЬНОЙ карточке-секции — тот же приём и тот же довод, что у блоков
   «Профессиональной цели» и у пары «сводка + анкета» 26.08: линия внутри одной
   карточки читается как граница СТРОКИ, а не как граница разговора. Своего
   правила вида блоку для этого не нужно вовсе: карточку даёт `.jb-section`,
   расстояние между карточками — зазор колонки экрана. */
.jb-exp-group {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 12px; flex-wrap: wrap; margin: 0 0 6px;
}
/* Селектор с тегом — по той же причине, что у `jb-exp-title` выше: с
   29.08.2026 заголовок блока это `h2` (страница цели), а `.jb-section h2`
   эталонов имеет специфичность (0,1,1) и печатал бы его кеглем секции. */
.jb-exp-group-title,
h2.jb-exp-group-title,
.jb-section h2.jb-exp-group-title { font-size: 15px; font-weight: 700; margin: 0; }
.jb-exp-group-why { font-size: 12.5px; color: var(--jb-text-muted); margin: 3px 0 0; }
/* НИ ЛИНИИ, НИ ОТСТУПА между группами у блока нет — и это не пропуск.
   Их было два: волосяная линия сверху у второй и следующих групп
   (`:not(:first-child)`) и 22px под списком предыдущей. Оба разделяли группы
   ВНУТРИ одной карточки, и оба удалены 30.08.2026 по решению владельца вместе
   с переходом на «одна группа — одна карточка».

   Удалены, а не оставлены про запас, потому что оставшись они лгали бы дважды.
   Во-первых, ни одного потребителя у них не осталось: каждая группа стала
   первым ребёнком своей секции, а её список — последним, и замер показал ноль
   срабатываний на всех эталонах. Во-вторых, композицию «несколько групп в
   одной карточке» кит-док теперь называет прямо отвергнутой: линия внутри
   карточки читается как граница СТРОКИ, а не как граница разговора — тем же
   путём 26.08 развели сводку и анкету, а 29.08 блоки «Профессиональной цели».
   Правило, обслуживающее запрещённую композицию, — это приглашение её вернуть.

   Разделяет группы теперь композиция экрана: карточку даёт `.jb-section`,
   расстояние между карточками — зазор колонки (14px). Понадобится обратное —
   возвращать придётся осознанно, а не обнаружить, что оно всё это время
   лежало наготове. */

/* Сводка «Профессиональной цели» — БЕЗЫМЯННЫЙ блок над первой группой анкеты
   (26.08.2026, решение владельца; эталон jobburg-career.html, состояние 4).
   Шесть условий, которые человек правит уже не здесь: профессия, зарплата, тип
   занятости, локация, формат работы, командировки. Целевых ролей в сводке нет
   намеренно — они есть на самой странице цели.

   Своего грида блок НЕ заводит: строки те же `.jb-exp` раздела выше, только
   без третьей ячейки — правки на месте у них нет, и действие тут одно на всю
   сводку. Заголовка у секции нет: она отвечает на «что система про вас знает»
   тем же, чем группы ниже, и второй заголовок сделал бы из неё пятую группу.

   Отделена сводка от анкеты НЕ ЛИНИЕЙ, а собственной карточкой-секцией
   (26.08.2026, решение владельца): сводка стоит в своём `.jb-section`, анкета —
   в следующем. Своего правила вида блоку для этого не нужно вовсе, поэтому его
   здесь и нет: расстояние между карточками держит колонка экрана.
   Путь сюда стоит помнить. Сперва границы не было заведено вообще — её рисовало
   групповое правило (`.jb-exp-group:not(:first-child)` срабатывало само, потому
   что первым ребёнком секции стала сводка; самого правила с 30.08.2026 уже нет,
   см. выше), и линия секции выходила неотличима
   от волосяной линии между строками: безымянный блок читался как продолжение
   списка. Следующая попытка — своя линия потолще и потемнее — лечила симптом:
   линия внутри одной карточки в любом виде читается как граница СТРОКИ, а не
   как граница разговора. Две карточки отвечают на это без единого правила вида.
   Поэтому у самого блока остались только шапка со счётчиком и ссылка. */
/* Шапка сводки: заголовка у блока нет намеренно, поэтому в строке стоит один
   счётчик заполненного (`JBCareer.goalSummaryCount`, тот же `jb-badge--muted`,
   что у групп) — прижатый вправо, на ту же вертикаль, где счётчики групп ниже.
   Пустая слева половина строки — это и есть отсутствующий заголовок: писать
   его нельзя, иначе сводка становится пятой группой анкеты. */
.jb-exp-summary-head { display: flex; justify-content: flex-end; margin-bottom: 2px; }
/* Ссылка-действие с карандашом. Сам вид ссылки — утилита `.jb-link-blue`;
   здесь только раскладка «иконка + слово», чтобы они стояли на одной линии.

   Мест таких два, и раскладка у них одна: ссылка под сводкой
   (`.jb-exp-summary-edit`) и ссылка в ячейке действий строки анкеты
   (`.jb-exp-link`, 26.08.2026 — строка CV уводит на свою страницу
   `/experience/cv`). Отступ сверху есть только у первой: она стоит ПОД
   списком строк, а вторая — внутри строки, на одной линии с её ответом, и
   там отступ сдвинул бы её вниз относительно превью. Поэтому общая часть
   объявлена один раз, а различие — отдельной строкой ниже. */
.jb-exp-summary-edit, .jb-exp-link { display: inline-flex; align-items: center; gap: 6px; }
.jb-exp-summary-edit { margin-top: 12px; }

/* SYSTEMSTATUS (панель «Что уже работает») ----------------------- */
/* Правая колонка «Моего опыта» (25.08.2026): три подсистемы, которые живут от
   анкеты, — поиск, оценка, двойник. Точка слева говорит состояние, строка под
   названием — ЧЕМ именно плохо («не работает без: CV / опыт работы»), а не
   «заполните профиль». Состояние считает кит (`JBCareer.expSystems`), а не
   экран: правило «что от чего зависит» обязано быть одно на два фронта.
   Цвет — не единственный носитель смысла: та же причина написана словами. */
.jb-sys-row { display: flex; gap: 10px; align-items: flex-start; padding: 9px 0; }
.jb-sys-dot { flex: none; width: 10px; height: 10px; border-radius: 50%; margin-top: 6px; background: var(--jb-border-strong); }
.jb-sys-dot.is-ok { background: var(--jb-success); }
.jb-sys-dot.is-warn { background: var(--jb-amber); }
.jb-sys-name { font-size: 14px; font-weight: 700; }
.jb-sys-note { font-size: 13px; color: var(--jb-text-secondary); margin-top: 1px; }
/* Ближайшие шаги — нумерованный список в той же панели. Номера мелкие: это
   подсказка, а не очередь дня (та живёт блоком DayQueue и несёт кнопки). */
.jb-sys-step { display: flex; gap: 10px; align-items: flex-start; padding: 8px 0; font-size: 13.5px; }
.jb-sys-step-n {
  flex: none; width: 22px; height: 22px; border-radius: 50%;
  background: var(--jb-blue-bg); color: var(--jb-blue);
  font-weight: 800; font-size: 12px; display: flex; align-items: center; justify-content: center;
}

/* Приглашение к соседнему инструменту прямо из блока («Проанализировать опыт
   на смежные роли» у целевых ролей). Строка, а не карточка: это не ещё один
   раздел анкеты, а дверь наружу. Стоит и в блоке «Моего опыта», и на шаге
   мастера — вид у неё один, поэтому живёт в ките, а не в CSS экрана. */
.jb-exp-cta {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-top: 12px;
  padding: 10px 12px;
  background: var(--jb-blue-bg); border: 1px solid var(--jb-blue-border);
  border-radius: var(--jb-radius-sm);
}
.jb-exp-cta-text { font-size: 14px; color: var(--jb-text); }

/* Раздел 32 (HUBCARD, карточка подраздела) снят 18.08.2026 вместе с редизайном
   «Моей карьеры»: оглавление стало hero-паспортом (раздел 25) и маршрутом
   (раздел 28), карточек-дверей больше нет нигде. Капкан, который здесь жил,
   остаётся правилом кита: вложенные интерактивные элементы внутри ссылки —
   неверная разметка и непредсказуемый клик; карточка со своими ссылками —
   div, дверью служит заголовок. */

/* ---------- 24. Последние оценки (блок на месте списка) ---------- */
/* Пять последних разборов под фильтрами; полный список раскрывает кнопка.
   Своего вида плашки у блока НЕТ — это те же карточки `.vac-list`, что и в
   полном списке: иначе одна и та же вакансия выглядела бы по-разному в
   зависимости от того, свёрнут список или нет. Здесь только подпись блока.
   Подпись — ЗАГОЛОВОК (h2, 19px/700, как заголовки секций), а не серое
   пояснение: блок открывает раздел страницы, и серый `jb-sub` читался как
   комментарий к фильтрам, а не как его начало (правка владельца 13.08.2026). */
.eval-recent-title { font-size: 19px; font-weight: 700; margin: 6px 0 12px; }

/* ---------- 25. Hero раздела (тёмная шапка с числами) ---------- */
/* Тёмный градиент ink→blue — шапка-«кокпит» раздела: заголовок и пояснение
   слева, ЧИСЛА раздела в ряд под ними, главное действие справа. Введён
   14.08.2026 (выбор владельца, вариант «Матч-центр» из трёх предложенных):
   раздел «Вакансии» получает лицо, а четыре сервисных блока перед находками
   сжимаются в один.

   Главное действие в hero — ЯНТАРНАЯ кнопка (jb-btn--amber). Это осознанная
   ревизия правила токенов «янтарь не для кнопок» (см. комментарий к --jb-amber):
   на тёмном фоне синяя primary тонула, а янтарь — единственный цвет палитры,
   который на ink читается как акцент. Правило после ревизии: янтарная CTA
   разрешена ТОЛЬКО внутри .jb-hero и она же считается единственной primary
   экрана — синей jb-btn--primary рядом с hero быть не должно.

   Числа: кликабельная метрика — button.jb-hero-stat, значение янтарное
   (та же семантика, что у синих значений button.jb-stat в StatStrip:
   цвет = «можно нажать»); некликабельная — span, значение белое. Ноль у
   кликабельной метрики не рисуется вовсе — правило то же, что у счётчика
   шапки (.jb-count): кружок с нулём приучает не смотреть. */
.jb-hero {
  background: linear-gradient(120deg, var(--jb-ink) 30%, #1B2E7A 82%, var(--jb-blue) 118%);
  color: #fff; border-radius: var(--jb-radius-lg); box-shadow: var(--jb-shadow-md);
  padding: 26px 30px; display: flex; justify-content: space-between;
  gap: 24px; flex-wrap: wrap; align-items: center;
}
.jb-hero-title { font-size: 20px; font-weight: 800; letter-spacing: -.3px; }
/* Приглушённый текст на тёмном — правило онбординга (раздел 19): не серый
   токен светлой темы, а полупрозрачный белый. */
.jb-hero-sub { font-size: 13.5px; color: rgba(255,255,255,.72); margin-top: 4px; max-width: 520px; }
/* Главная фраза сводки — белая, остальные приглушены: в сводке дня у дашборда
   первая фраза это самое срочное, и она обязана читаться первой. Своего цвета
   не заводим — тот же белый, что у чисел hero. */
.jb-hero-sub b { color: #fff; }
.jb-hero-stats { display: flex; gap: 26px; margin-top: 16px; flex-wrap: wrap; }
.jb-hero-stat { display: block; text-align: left; color: #fff; }
button.jb-hero-stat { background: none; border: none; padding: 0; cursor: pointer; font-family: var(--jb-font); }
.jb-hero-stat .jb-hero-v { font-size: 24px; font-weight: 800; font-variant-numeric: tabular-nums; }
button.jb-hero-stat .jb-hero-v { color: var(--jb-amber); }
.jb-hero-stat .jb-hero-l { font-size: 12.5px; color: rgba(255,255,255,.65); }
button.jb-hero-stat:hover .jb-hero-l { color: #fff; }
button.jb-hero-stat:focus-visible { outline: none; box-shadow: var(--jb-focus-ring); border-radius: 6px; }
.jb-hero-actions { display: flex; gap: 10px; flex-direction: column; align-items: stretch; flex: none; }
/* Чипы hero — целевые роли в шапке «Моей карьеры» (18.08.2026, выбор владельца,
   вариант «Маршрут карьеры»): человек видит, НА КОГО работает профиль, не
   открывая «Мой опыт». Полупрозрачный белый — тот же приглушённый слой, что у
   всего второстепенного на тёмном (правило онбординга, раздел 19); своих
   цветов у чипов нет, кликабельности тоже: это паспорт, а не фильтр (в отличие
   от чипов вердиктов, раздел 27). */
.jb-hero-chips { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 12px; }
.jb-hero-chip {
  font-size: 12px; font-weight: 600; padding: 4px 11px; border-radius: 999px;
  background: rgba(255,255,255,.1); border: 1px solid rgba(255,255,255,.25); color: #fff;
}
/* Полоса полноты в hero: «Профиль заполнен · [====  ] · 9 из 11 разделов».
   Заливка янтарная — тот же акцент, что у CTA и горячего номера очереди:
   «здесь ещё есть работа». Ширину заливки считает экран из
   JBCareer.careerReadyPercent — числа шагов в CSS нет. */
.jb-hero-meter { display: flex; align-items: center; gap: 10px; margin-top: 14px; font-size: 12.5px; color: rgba(255,255,255,.72); }
.jb-hero-meter-track { width: 160px; height: 6px; border-radius: 999px; background: rgba(255,255,255,.18); overflow: hidden; }
.jb-hero-meter-fill { display: block; height: 6px; border-radius: 999px; background: var(--jb-amber); }
/* Hero РАЗБОРА ВАКАНСИИ (18.08.2026, выбор владельца — комбинация
   «вердикт-hero + маршрут» из трёх предложенных). Отличается от hero раздела
   тем, ЧТО стоит крупно: у раздела это его имя, у разбора — ВЕРДИКТ, потому
   что страница существует ради одного решения «откликаться или нет». Балл
   рядом с вердиктом — янтарный и крупный: это второе, на что смотрят, и
   единственное число шапки (ряда `jb-hero-stats` у разбора нет).
   Название вакансии и должность живут ниже вердикта и спокойнее его —
   заголовком страницы служит «Оценка вакансии №N» над hero. */
.jb-hero-verdict { font-size: 32px; font-weight: 800; letter-spacing: -.6px; line-height: 1.1; }
.jb-hero-vacancy { font-size: 16px; font-weight: 700; margin-top: 18px; overflow-wrap: break-word; }
.jb-hero-vacancy-role { font-size: 14px; color: rgba(255,255,255,.86); margin-top: 2px; }
/* Балл и действия — одной группой справа: решение и его причина не должны
   разъезжаться по разным углам шапки. */
.jb-hero-decide { display: flex; gap: 18px; align-items: center; flex: none; }
.jb-hero-score { text-align: center; }
.jb-hero-score-v { display: block; font-size: 52px; font-weight: 800; line-height: 1; color: var(--jb-amber); letter-spacing: -1.5px; font-variant-numeric: tabular-nums; }
.jb-hero-score-of { font-size: 12.5px; color: rgba(255,255,255,.65); }
@media (max-width: 860px) { .jb-hero-decide { width: 100%; justify-content: space-between; } }
@media (max-width: 640px) {
  .jb-hero { padding: 20px 22px; }
  /* Строкой — но с переносом. `flex: 1` растягивает кнопки на равные доли, а
     ужаться меньше своей подписи они не могут: пара «Проанализировать резюме» +
     «Загрузить резюме» требует 352px там, где есть 291, и вторая кнопка уезжала
     за правый край карточки (замер живьём 25.08.2026 на 375px — и на «Моей
     карьере», и на «Моём опыте»). С переносом не поместившаяся кнопка встаёт
     второй строкой во всю ширину, а короткие пары по-прежнему стоят в строку. */
  .jb-hero-actions { flex-direction: row; flex-wrap: wrap; width: 100%; }
  .jb-hero-actions .jb-btn { flex: 1; }
  /* Действия РАЗБОРА живут внутри jb-hero-decide, и их три с длинными
     подписями: строкой они не помещаются даже растянутыми — на 375px
     «Открыть вакансию» и «Пропустить вакансию» уезжали за правый край
     карточки (найдено живым прогоном 18.08.2026, эталон ломался так же, как
     экран). Поэтому у разбора балл занимает первую строку, а кнопки встают
     под ним столбцом во всю ширину. Hero РАЗДЕЛА этим не задет: у него
     действия лежат прямо в hero, а не в группе решения. */
  .jb-hero-decide { flex-wrap: wrap; }
  .jb-hero-decide .jb-hero-actions { flex: 1 1 100%; flex-direction: column; }
  .jb-hero-decide .jb-hero-actions .jb-btn { flex: none; }
}
/* Кнопки на тёмном. --amber — главное действие hero (см. ревизию правила выше);
   --ondark — второстепенное действие на тёмном фоне: прозрачная с белой рамкой. */
.jb-btn--amber { background: var(--jb-amber); color: var(--jb-ink); border: none; font-weight: 700; }
.jb-btn--amber:hover { filter: brightness(1.05); }
/* Селектор с элементом — иначе ссылку-кнопку перекрашивает общее правило
   `.jb a` (синие ссылки); у кнопки на тёмном текст всегда белый. */
.jb-btn--ondark, a.jb-btn--ondark, a.jb-btn--ondark:hover, a.jb-btn--ondark:visited { background: transparent; color: #fff; border: 1px solid rgba(255,255,255,.35); }
.jb-btn--ondark:hover { background: rgba(255,255,255,.08); }
/* Третье действие на тёмном — отклоняющее и обратимое («Пропустить вакансию»).
   Рамки у него нет намеренно: в ряду из трёх кнопок две обведённые читаются
   как равные, а пропуск равным быть не должен. Красный тут не работает — на
   ink он не различим, поэтому «слабость» несёт прозрачность, а не цвет
   (18.08.2026, шапка разбора вакансии). */
.jb-btn--ondark-quiet {
  background: none; border: none; padding: 4px;
  color: rgba(255,255,255,.72); font: 600 13px var(--jb-font);
  cursor: pointer; text-decoration: underline;
}
.jb-btn--ondark-quiet:hover { color: #fff; }
.jb-btn--ondark-quiet:focus-visible { outline: none; box-shadow: var(--jb-focus-ring); border-radius: 6px; }

/* ---------- 26. Карточка находки (JobCard) ---------- */
/* Богатая карточка результата поиска: источник служебной строкой, название,
   чипы метаданных, ЗАРПЛАТА янтарным бейджем справа — на executive-поиске
   зарплата и есть главный сигнал строки, поэтому она заметнее названия
   компании. Подвал отделён линией: слева действия-переходы («Оценить»,
   «Открыть →»), справа — отклоняющие («Скрыть», «Нерелевантно»); разнесение
   намеренное, чтобы «Скрыть» не стоял в одном ряду с «Оценить» и не ловил
   промахи по соседству.

   «Оценить» — secondary, НЕ primary (primary экрана — CTA hero) и НЕ янтарная
   (янтарь кнопок живёт только в hero). Оценка платная, поэтому у кнопки
   обязателен title с предупреждением — текст в ките
   (JBSearchLabels.CARD_EVALUATE_TITLE). Чекбоксов выбора на карточке больше
   нет: замер ТЗ 12.08.2026 (494 находки на одну оценку, ноль оценок за три
   дня) показал, что трёхшаговая пачка «отметь → панель → оцени» не работает;
   оценка запускается с карточки в один клик. */
.jb-jobcard {
  background: var(--jb-surface); border-radius: var(--jb-radius-lg);
  box-shadow: var(--jb-shadow-sm); padding: 18px 22px; margin-bottom: 12px;
  transition: box-shadow .15s;
}
.jb-jobcard:hover { box-shadow: var(--jb-shadow-md); }
.jb-jobcard-top { display: flex; justify-content: space-between; gap: 14px; align-items: flex-start; }
.jb-jobcard h3 { font-size: 17px; font-weight: 800; letter-spacing: -.2px; margin: 2px 0 6px; }
/* Зарплатный бейдж. Не указана — приглушённый, НЕ янтарный: отсутствие данных
   не должно светиться как акцент. */
.jb-salary {
  background: var(--jb-amber); color: var(--jb-ink); font-weight: 800; font-size: 14px;
  border-radius: 10px; padding: 6px 12px; white-space: nowrap;
  font-variant-numeric: tabular-nums; flex: none;
}
.jb-salary--na { background: var(--jb-bg); color: var(--jb-text-muted); font-weight: 600; border: 1px solid var(--jb-border); }
.jb-chips { display: flex; gap: 6px; flex-wrap: wrap; margin: 8px 0 0; }
.jb-chip {
  font-size: 12px; font-weight: 600; padding: 4px 10px; border-radius: 999px;
  background: var(--jb-bg); border: 1px solid var(--jb-border); color: var(--jb-text-secondary);
}
/* Состояние «просмотрена» — зелёный чип: слово, а не только цвет. */
.jb-chip--viewed { color: var(--jb-success); border-color: var(--jb-success); }
.jb-jobcard-foot {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--jb-border);
}
.jb-jobcard-foot .jb-jobcard-spacer { margin-left: auto; }
@media (max-width: 640px) {
  .jb-jobcard-top { flex-direction: column; }
  .jb-salary { align-self: flex-start; }
}

/* ---------- 27. Чипы вердиктов (VerdictChips) ---------- */
/* Ряд чипов-фильтров по вердикту оценки: «4 Откликаться сразу · 5 Стоит
   откликнуться · 14 Подумать · 204 Не рекомендуется». Введён 15.08.2026
   (выбор владельца, комбинация «hero + триаж» для «Оценки совместимости»):
   пульс называет ЧИСЛО рекомендованных, чипы делают его СПИСКОМ — прямой
   мостик «оценил → откликнулся» по уже оплаченным данным.

   Чип — кнопка-фильтр, не бейдж: клик сужает список до вердикта, повторный —
   снимает. Активное состояние — синяя обводка (is-active), той же семантики,
   что jb-card--selected: выбранность кодируется синим, тон чипа — смыслом
   вердикта. Порядок и подписи — канон кита (JBEvaluate.VERDICT_FILTERS,
   VERDICT_PILL, verdictCounts); чип с нулём не рисуется — правило то же, что
   у плиток пульса и счётчика шапки. Цвет не единственный носитель смысла:
   вердикт назван словом в каждом чипе. */
.jb-vchip {
  font-family: var(--jb-font); font-size: 13px; font-weight: 600;
  padding: 6px 14px; border-radius: 999px; border: 1px solid transparent;
  cursor: pointer; display: inline-flex; gap: 7px; align-items: baseline;
}
.jb-vchip b { font-weight: 800; font-variant-numeric: tabular-nums; }
.jb-vchip--go    { background: var(--jb-success-bg); color: var(--jb-success); }
.jb-vchip--think { background: var(--jb-warning-bg); color: var(--jb-warning); }
.jb-vchip--no    { background: var(--jb-bg); color: var(--jb-text-secondary); border-color: var(--jb-border); }
.jb-vchip.is-active { outline: 2px solid var(--jb-blue); outline-offset: 1px; }
.jb-vchip:focus-visible { outline: none; box-shadow: var(--jb-focus-ring); }
.jb-vchips { display: flex; gap: 8px; flex-wrap: wrap; }

/* ---------- 28. Очередь дня (DayQueue) ---------- */
/* План дня на «Моём дашборде»: нумерованные строки-задачи, собранные из тех же
   очередей, что и баннеры действий (словарь JBDashboard.BANNERS), — по одной
   строке и ОДНОМУ действию на очередь. Введена 15.08.2026 (выбор владельца,
   комбинация «hero + очередь» из трёх предложенных): стопка баннеров говорила
   «есть три места, где что-то ждёт», очередь говорит «сделай по порядку».

   Первая строка — «горячая» (is-first): янтарный номер, той же семантики, что
   янтарная CTA hero, — это одно и то же самое ценное действие дня, показанное
   и кнопкой входа, и пунктом плана. Primary у строк НЕТ: единственная primary
   экрана — CTA hero, кнопки очереди — secondary.

   Выполненная строка (is-done) остаётся НА ЭКРАНЕ зачёркнутой, а не исчезает:
   «система уже поработала за вас» — вывод, а не мусор (например, поиск,
   отработавший по расписанию). Номер выполненной — галочка, не цифра. */
.jb-queue {
  background: var(--jb-surface); border-radius: var(--jb-radius-lg);
  box-shadow: var(--jb-shadow-sm); padding: 8px 24px;
}
.jb-qrow { display: flex; gap: 16px; align-items: center; padding: 15px 0; border-bottom: 1px solid var(--jb-border); }
.jb-qrow:last-child { border-bottom: none; }
.jb-qnum {
  flex: none; width: 30px; height: 30px; border-radius: 50%;
  background: var(--jb-blue-bg); color: var(--jb-blue);
  font-weight: 800; font-size: 14px; display: flex; align-items: center;
  justify-content: center; font-variant-numeric: tabular-nums;
}
.jb-qrow.is-first .jb-qnum { background: var(--jb-amber); color: var(--jb-ink); }
.jb-qmain { min-width: 0; flex: 1; }
.jb-qtitle { font-size: 15px; font-weight: 700; }
.jb-qsub { font-size: 13px; color: var(--jb-text-secondary); margin-top: 1px; }
.jb-qrow.is-done .jb-qtitle { text-decoration: line-through; color: var(--jb-text-muted); }
@media (max-width: 640px) {
  .jb-qrow { flex-wrap: wrap; }
  /* Текст задачи занимает всю строку РЯДОМ С НОМЕРОМ (46px — номер плюс
     отступ), а кнопка встаёт под них. Без этого короткая кнопка остаётся в
     строке (места ей хватает), и заголовок с подстрокой сжимаются в столбик по
     одному слову — замечено живым прогоном на 375px 15.08.2026. */
  .jb-qmain { flex-basis: calc(100% - 46px); }
  .jb-qrow .jb-btn { margin-left: 46px; }
}

/* ---------- Полосы осей балла (ScoreAxes) ---------- */
/* Номера у этого блока намеренно НЕТ: в файле две параллельные нумерации
   разделов — короткая «NN. NAME» и длинная «---------- NN. Название ----------»,
   и номера 24–29 заняты дважды; новый номер добавил бы третье значение к уже
   двусмысленным. Блок называется именем; разнести нумерацию — отдельная
   задача (18.08.2026).

   Образцы нумерации записаны здесь СЛОВАМИ, без символов комментария:
   вложенных комментариев в CSS не бывает, и процитированный маркер закрывает
   комментарий раньше времени — остаток строки парсер читает как правило.
   18.08.2026 такая цитата уронила `vite build` целиком (postcss: Unknown
   word), а тесты остались зелёными: CSS кита ни один из них не разбирает. */
/* «Из чего сложился балл» на разборе вакансии (18.08.2026). До этого пять осей
   стояли одинаковыми пилюлями `.eval-axis`: по ним не было видно ни того, что
   тянет балл вниз, ни того, что балл — ВЗВЕШЕННАЯ сумма (веса не показывались
   вовсе, хотя настраиваются в «Настройках»). Полоса длиной value/5 отвечает на
   оба вопроса сразу.

   КРАСНАЯ заливка (`is-low`) — не «ось ниже тройки», а ось ниже САМОГО БАЛЛА,
   то есть тянущая его вниз; признак считает кит (`JBEvaluate.scoreAxes`), а не
   экран на глаз: планка у каждого своя, и одна и та же 3.5 у одного тянет
   вниз, у другого держит верх.

   Числа — `tabular-nums` и справа: пять значений читаются столбцом, а не
   вразнобой. Вес — самым тихим цветом: это контекст, а не оценка. */
.jb-axis {
  display: grid; grid-template-columns: 150px 1fr 42px 76px; gap: 12px;
  align-items: center; padding: 7px 0;
}
.jb-axis-l { font-size: 13.5px; font-weight: 600; }
.jb-axis-track { height: 8px; border-radius: 999px; background: var(--jb-bg); border: 1px solid var(--jb-border); overflow: hidden; }
.jb-axis-fill { display: block; height: 100%; background: var(--jb-blue); border-radius: 999px; }
.jb-axis.is-low .jb-axis-fill { background: var(--jb-danger); }
.jb-axis-v { font-size: 14px; font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; }
.jb-axis-w { font-size: 12px; color: var(--jb-text-muted); text-align: right; }
@media (max-width: 640px) {
  /* На узком подпись и значение встают в строку, полоса под ними: сжатая до
     60px полоса перестаёт что-либо показывать. */
  .jb-axis { grid-template-columns: 1fr 42px; grid-template-areas: 'l v' 't t' 'w w'; }
  .jb-axis-l { grid-area: l; }
  .jb-axis-v { grid-area: v; }
  .jb-axis-track { grid-area: t; }
  .jb-axis-w { grid-area: w; text-align: left; }
}

/* ---------- 29. CODE (код, который человек переписывает) ---------- */
/* Резервный код доступа к зашифрованным данным: показывается ОДИН раз, и его
   переписывают руками на бумагу или в менеджер паролей. Отсюда требования:
   моноширинный шрифт (иначе не отличить «rn» от «m»), крупный кегль, широкие
   межбуквенные интервалы и возможность выделить целиком одним движением.
   Своих цветов нет — фон и рамка те же, что у блока подсказки. */
.jb-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 19px; font-weight: 700; letter-spacing: 1.5px;
  background: var(--jb-bg); border: 1px solid var(--jb-border);
  border-radius: var(--jb-radius-md); padding: 14px 16px;
  margin: 12px 0; text-align: center; user-select: all; word-break: break-all;
}

/* ---------- 30. Итог тренировки интервью ----------
   Балл за раунд, разбивка по критериям, шансы пройти дальше и тихий счётчик
   фоновых разборов. Появился 20.08.2026 вместе с переносом разбора в фон:
   раньше разбор падал в ленту посреди интервью, теперь копится и выходит
   здесь.

   Шансы — СЛОВОМ, без процента: у модели нет данных, чтобы отличить одну
   цифру от другой, а цифра читается как знание. */
.jb-practice-score {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 14px 16px;
  border: 1px solid var(--jb-border);
  border-radius: var(--jb-radius-md);
  background: var(--jb-bg);
}
.jb-practice-score-label {
  font-size: 13px;
  color: var(--jb-text-secondary);
}
.jb-practice-score-value {
  font-size: 30px;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.jb-practice-criteria {
  list-style: none;
  margin: 14px 0 0;
  padding: 0;
  display: grid;
  gap: 8px;
}
.jb-practice-criterion {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 13.5px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--jb-border);
}
.jb-practice-criterion b {
  font-variant-numeric: tabular-nums;
}
.jb-practice-odds {
  margin-top: 16px;
}
/* Тихий счётчик фоновых разборов. Намеренно неприметен: полоска задачи здесь
   мельтешила бы на каждом ходу и обесценила бы сам сигнал. */
.jb-practice-progress {
  margin-top: 10px;
  font-size: 12.5px;
  color: var(--jb-text-secondary);
}
/* Незаконченная тренировка: три дороги вместо молчаливого продолжения. */
.jb-practice-resume {
  padding: 16px;
  border: 1px solid var(--jb-border);
  border-radius: var(--jb-radius-md);
}
@media (max-width: 420px) {
  .jb-practice-criterion {
    font-size: 13px;
  }
  .jb-practice-score-value {
    font-size: 26px;
  }
}

/* ---------- Выбор из справочника (ChoiceGroup) ---------- */
/* Ответ ИЗ ЗАКРЫТОГО НАБОРА: «Тип занятости», «Формат работы», «Командировки»
   на странице «Профессиональная цель» (эталон jobburg-career.html,
   состояние 6). Значения и их порядок задаёт кит
   (`JBCareer.GOAL_DICTIONARIES`), а `multiple` решает, что за контрол:
   чекбоксы (можно несколько) или переключатели (ровно один).

   Почему не чипы: `.kc-*` (раздел 23) — редактор СВОБОДНОГО списка, где
   значение можно вписать своё. Здесь вписать нельзя ничего: набор закрыт, и
   поле ввода обещало бы обратное. Почему не `.jb-checkrow` (раздел 17): та
   строка — настройка во всю ширину с бейджем режима справа, а тут варианты
   стоят рядом и читаются одним взглядом как один вопрос.

   Сами контролы — `.jb-checkbox`/`.jb-radio` раздела 5, своих у блока нет:
   новым здесь остаётся только раскладка вариантов и рамка вокруг каждого.
   Рамка нужна, чтобы было видно ГРАНИЦУ варианта: без неё «На месте
   работодателя» и «Удаленно» в одной строке слипаются в одну подпись. */
.jb-choice { display: flex; flex-wrap: wrap; gap: 8px; }
/* Вариант целиком — область нажатия: подпись внутри <label>, поэтому промах
   мимо квадратика всё равно переключает ответ. */
.jb-choice-opt {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 8px 12px;
  border: 1px solid var(--jb-border); border-radius: var(--jb-radius-sm);
  background: var(--jb-surface);
  font-size: 14px; cursor: pointer;
}
.jb-choice-opt:hover { border-color: var(--jb-blue-border); background: var(--jb-blue-bg); }
/* Выбранный вариант отличается не только галочкой: цвет — не единственный
   носитель смысла, но и один лишь мелкий квадратик им быть не должен. */
.jb-choice-opt.is-on { border-color: var(--jb-blue); background: var(--jb-blue-bg); color: var(--jb-blue); font-weight: 600; }
.jb-choice-opt:focus-within { outline: none; box-shadow: var(--jb-focus-ring); }


/* SOURCEROW (строка источника в «Настройке поиска») ------------------
   Один источник = одна строка ОДИНАКОВОЙ высоты: имя · фраза расписания ·
   тумблер. Правка расписания открывается панелью внутри строки.

   26.08.2026, решение владельца. До этой даты расписание раскрывалось прямо в
   строке: селект режима, под ним кружки дней и поле времени, под ними окно
   запуска — всё прижатое к правому краю и без подписей. Строки становились
   разной высоты, имя источника центрировалось по трёхэтажной колонке, а
   селекты разной ширины («Вручную» против «По расписанию») не выравнивались
   между собой. Список переставал читаться как список.

   Теперь расписание в строке — ФРАЗА («Вт, Пт в 10:00»), под ней окно
   планового прогона, если сервер его прислал. Сами фразы считает кит
   (`JBSearchLabels.scheduleText` / `scheduleWindow`): разметка их не собирает.

   Своих контролов у блока почти нет. Режим в панели — `.jb-choice` раздела
   «Выбор из закрытого набора»: набор ровно тот, закрытый. Подписи полей —
   `.jb-label`, кнопки — `Button`, тумблер — `.jb-switch`. Новыми остаются
   раскладка строки, панель и кружки дней.

   Кружки дней раньше жили в CSS React-экрана (`.schedule-day-btn` в
   search.css) — то есть блок кита существовал только в приложении. Это тот же
   класс расхождения, что уже стрелял в списке Telegram-каналов (10.08.2026),
   и здесь он закрыт так же: объявление одно, в ките. */
.jb-srclist { border: 1px solid var(--jb-border); border-radius: var(--jb-radius-md); }
.jb-srcrow {
  display: grid; grid-template-columns: 1fr 260px 150px; gap: 16px;
  align-items: center; padding: 12px 16px; border-bottom: 1px solid var(--jb-border);
}
.jb-srcrow:last-child { border-bottom: none; }
/* Строка в правке приглушается фоном: панель принадлежит ей, а не списку. */
.jb-srcrow.is-editing { background: var(--jb-bg); }
.jb-srcname { min-width: 0; }
.jb-srcname b { font-size: 14.5px; }
.jb-srcnote { font-size: 13px; color: var(--jb-text-muted); font-weight: 500; }
/* Селектор с тегом обязателен: `.jb a` (0,1,1) перебивает одиночный класс. */
a.jb-srcedit, .jb a.jb-srcedit {
  font-weight: 600; font-size: 13px; color: var(--jb-blue);
  text-decoration: none; margin-left: 8px; cursor: pointer;
}
a.jb-srcedit:hover, .jb a.jb-srcedit:hover { text-decoration: underline; }
/* Фраза расписания — кнопка, а не ссылка: она открывает правку на месте, а не
   ведёт по адресу. Пунктир под ней говорит «здесь меняется», не притворяясь
   переходом. */
.jb-srcwhen { min-width: 0; }
button.jb-srcwhen-btn, .jb button.jb-srcwhen-btn {
  border: none; background: none; padding: 0;
  font-family: var(--jb-font); font-size: 14px; font-weight: 600;
  color: var(--jb-blue); border-bottom: 1px dashed var(--jb-blue-border); cursor: pointer;
}
button.jb-srcwhen-btn:focus-visible { outline: none; box-shadow: var(--jb-focus-ring); }
.jb-srcwindow { display: block; margin: 3px 0 0; font-size: 12.5px; color: var(--jb-text-muted); }
.jb-srcsw { justify-self: start; }
.jb-srcpanel {
  grid-column: 1 / -1; margin-top: 12px; padding: 14px 16px;
  background: var(--jb-surface); border: 1px solid var(--jb-blue-border);
  border-radius: var(--jb-radius-md);
}
.jb-srcpanel-title { font-weight: 700; font-size: 14px; margin: 0 0 10px; }
.jb-srcfield { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; margin-top: 14px; }
.jb-srcfield .jb-label { margin: 0; }
.jb-srcfield .jb-hint { margin: 0; }
.jb-srcdays { display: flex; gap: 6px; flex-wrap: wrap; }
.jb-srcday {
  font-family: var(--jb-font); font-size: 12px; font-weight: 600;
  width: 32px; height: 30px; border-radius: 999px;
  border: 1px solid var(--jb-border-strong); background: var(--jb-bg);
  color: var(--jb-text-muted); cursor: pointer;
}
.jb-srcday.is-on { background: var(--jb-blue); border-color: var(--jb-blue); color: #fff; }
.jb-srcday:focus-visible { outline: none; box-shadow: var(--jb-focus-ring); }
.jb-srctime { width: 108px; padding: 7px 12px; font-variant-numeric: tabular-nums; }
/* Действия панели отделены линией: до неё — что настроено, после — что будет
   с источником. Подпись главной кнопки называет это словами. */
.jb-srcpanel-acts {
  display: flex; gap: 12px; align-items: center; flex-wrap: wrap;
  margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--jb-border);
}
@media (max-width: 760px) {
  /* На узком имя встаёт сверху, фраза и тумблер — под ним: три колонки в
     360px превращаются в горизонтальный скролл. */
  .jb-srcrow { grid-template-columns: 1fr; gap: 10px; }
}
