/*
 * Компоненты: карточки, навигация, боковые блоки, модальное окно.
 */

/* ---------- Хлебные крошки ---------- */

.breadcrumbs {
  margin-bottom: 20px;
}

.breadcrumbs__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--size-tiny);
  color: var(--color-text-light);
}

.breadcrumbs__item + .breadcrumbs__item::before {
  content: "→";
  margin-right: 6px;
  color: var(--color-border-strong);
}

.breadcrumbs__item a {
  color: var(--color-text-muted);
}

.breadcrumbs__item a:hover {
  color: var(--color-accent-ink);
}

.breadcrumbs__item--current {
  color: var(--color-text-light);
}

/* ---------- Заголовок раздела ---------- */

.section-head {
  margin-bottom: 28px;
}

.section-head__title {
  margin-bottom: 10px;
}

.section-head__desc {
  color: var(--color-text-muted);
  max-width: 760px;
}

/* ---------- Карточки материалов ---------- */

.cards {
  display: grid;
  gap: 20px;
}

.card {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  gap: 20px;
  padding: 16px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-bg);
  transition: border-color .15s ease, box-shadow .15s ease;
}

.card:hover {
  border-color: var(--color-border-strong);
  box-shadow: var(--shadow);
}

/*
 * Изображение всегда одного размера.
 *
 * Раньше картинка растягивалась на высоту карточки, а высота карточки зависела
 * от длины заголовка: у соседних материалов изображения выходили 141 и 240
 * пикселей. Фиксированное соотношение сторон убирает эту зависимость,
 * обрезка идёт от центра — значимая часть кадра обычно там.
 */
.card__image {
  display: block;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  border-radius: var(--radius-small);
  background: var(--color-bg-soft);
}

.card__image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  transition: transform .3s ease;
}

.card:hover .card__image img {
  transform: scale(1.03);
}

.card__body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/*
 * Под заголовок всегда отведены две строки, даже если он занял одну.
 * Иначе карточки в одном ряду разъезжаются по высоте.
 */
.card__title {
  font-size: 19px;
  line-height: 1.35;
  margin: 0 0 8px;
  min-height: calc(19px * 1.35 * 2);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.card__title a {
  color: var(--color-text);
}

.card__title a:hover {
  color: var(--color-accent-ink);
}

/*
 * На выдаче поиска заголовок карточки не обрезается.
 *
 * Замер на запросе «кредит», первая страница из двенадцати карточек:
 * обрезано пять заголовков при ширине 360, четыре при 375, два при 390
 * и один при 414. В списке, из которого выбирают по заголовку, обрезка
 * заголовка и есть потеря; анонс под ним остаётся на трёх строках —
 * он предварительный и на выбор не влияет.
 */
.search .card__title {
  display: block;
  min-height: 0;
  -webkit-line-clamp: none;
}

/*
 * Строка запроса под заголовком выдачи.
 *
 * Поле тянется на всю ширину формы: по умолчанию у поля поиска своя
 * ширина по числу знаков, и на 360 оно занимало 189 пикселей из 320 —
 * четверть строки пустовала. Ограничение по ширине нужно для десктопа,
 * где область содержимого 740 и поле во всю ширину выглядит анкетой.
 *
 * Правило именно у формы на выдаче: форма в шапке остаётся прежней,
 * её ширину этот этап не трогает.
 */
.section-head .search-form {
  margin-top: 16px;
  max-width: 520px;
}

.section-head .search-form input[type="search"] {
  flex: 1;
  min-width: 0;
}

/*
 * Анонс ровно на три строки. Обрезает вёрстка, а не подсчёт слов:
 * многоточие встаёт там, где текст действительно упёрся в край строки.
 */
.card__excerpt {
  color: var(--color-text-muted);
  font-size: var(--size-small);
  line-height: 1.5;
  margin-bottom: 12px;
  height: calc(var(--size-small) * 1.5 * 3);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.card__meta {
  display: flex;
  gap: 16px;
  margin-top: auto;
  font-size: var(--size-tiny);
  color: var(--color-text-light);
}

/* ---------- Постраничная навигация ---------- */

.pagination {
  margin: 32px 0 8px;
}

.pagination__list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.pagination a,
.pagination span {
  display: block;
  min-width: 42px;
  padding: 9px 13px;
  text-align: center;
  border-radius: var(--radius-small);
  background: var(--color-bg-soft);
  color: var(--color-text);
  font-weight: 600;
}

.pagination a:hover {
  background: var(--color-accent);
  color: var(--color-on-accent);
}

.pagination .current {
  background: var(--color-accent);
  color: var(--color-on-accent);
}

.pagination .dots {
  background: none;
}

/* ---------- Боковая колонка ---------- */

.side-block {
  padding: 18px 20px;
  background: var(--color-bg-soft);
  border-radius: var(--radius);
}

.side-block__title {
  font-weight: 700;
  margin-bottom: 12px;
}

.side-menu,
.side-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.side-menu a,
.side-list__item a {
  display: block;
  padding: 8px 0;
  color: var(--color-text);
  font-size: var(--size-small);
  border-bottom: 1px solid var(--color-border);
}

.side-menu li:last-child a,
.side-list__item:last-child a {
  border-bottom: none;
}

.side-menu a:hover,
.side-list__item a:hover {
  color: var(--color-accent-ink);
}

/* Оглавление в боковой колонке — прилипает при прокрутке */
.side-block--toc {
  position: sticky;
  top: 88px;
  max-height: calc(100vh - 110px);
  overflow-y: auto;
  padding: 0;
  background: none;
}

/* ---------- Облако тегов ---------- */

.tag-cloud {
  margin: 36px 0 0;
  padding: 22px 24px;
  background: var(--color-bg-soft);
  border-radius: var(--radius);
}

.tag-cloud__title {
  font-family: var(--font-head);
  font-size: 19px;
  font-weight: 700;
  margin-bottom: 14px;
}

.tag-cloud__list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 14px;
}

.tag-cloud__item {
  color: var(--color-text-muted);
  line-height: 1.3;
}

.tag-cloud__item:hover {
  color: var(--color-accent-ink);
}

/* ---------- Пустой результат ---------- */

.empty {
  padding: 40px 24px;
  text-align: center;
  background: var(--color-bg-soft);
  border-radius: var(--radius);
  color: var(--color-text-muted);
}

/* ---------- Рубрики раздела на хабе ---------- */

.hub {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
  margin: 32px 0;
}

.hub__item {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 20px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  transition: border-color .15s ease;
}

.hub__item:hover {
  border-color: var(--color-accent-ink);
}

/*
 * Вся карточка рубрики — цель, а не одна строка заголовка.
 *
 * До этапа 48 нажималась строка 239×22 внутри блока 320×164: цель вдвое
 * ниже нормы посреди большого пустого места, и промахнуться проще, чем
 * попасть. Ссылка растягивается на карточку псевдоэлементом — разметка
 * при этом не меняется и ссылка остаётся одна: читалка объявляет один
 * пункт, а не два, и обводка при переходе клавиатурой рисуется там же,
 * где и раньше, — по заголовку.
 */
.hub__title a::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--radius);
}

.hub__title {
  margin: 0;
  font-size: 20px;
}

/*
 * Мозаика рубрик на главной — этап 56.
 *
 * Та же карточка, что в разделах, но плотнее: на главной она не рассказывает
 * о рубрике, а служит входом. Полная карточка занимает 165 пикселей, пять
 * таких в столбик — 825, весь первый экран телефона. В мозаике 80 пикселей
 * и две колонки: пять рубрик укладываются в 276 вместе с промежутками.
 *
 * Две колонки держатся и на узком экране: общее правило `.hub` ниже 640
 * переводит сетку в одну колонку, и мозаике это правило не подходит.
 */
.hub--compact {
  /*
   * На широком экране плитки идут в четыре колонки, на телефоне — в две.
   * Число колонок задано явно, а не автоподбором: при `auto-fit` на 360
   * колонка не дотягивала до минимальной ширины, и мозаика схлопывалась
   * в один столбец — то есть ровно в то, от чего уходим.
   *
   * `grid-auto-rows: 1fr` равняет ряды между собой: без него ряд
   * с двухстрочным названием выше соседнего на 21 пиксель, и сетка
   * выглядит рваной.
   */
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-auto-rows: 1fr;
  gap: 12px;
  margin: 16px 0 28px;
}

.hub--compact .hub__item {
  gap: 4px;
  min-height: 80px;
  padding: 14px 16px;
}

.hub--compact .hub__title {
  font-size: 17px;
  line-height: 1.25;
}

.hub--compact .hub__count {
  font-size: var(--size-tiny);
}

.hub__desc {
  margin: 0;
  color: var(--color-text-muted);
}

/* Счётчик прижат вниз, чтобы у карточек с разной длиной описания он был на одной линии. */
.hub__count {
  margin-top: auto;
  padding-top: 4px;
  color: var(--color-text-light);
  font-size: var(--size-small);
}

/* ---------- Выбор города на посадочной «Работы» ---------- */

.citypick {
  margin: 28px 0 0;
}

.citypick__title {
  margin: 0 0 16px;
  font-family: var(--font-head);
  font-size: 28px;
}

/*
 * Города плитками, а не выпадающим списком: их шесть, и выбор — главное
 * действие первого экрана. Список пришлось бы сначала раскрыть.
 * Автоподбор ширины колонки: названия городов разной длины, и жёсткая
 * сетка оставляла бы пустоту справа от «Уфы».
 */
.citypick__list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 12px;
}

.citypick__item {
  display: block;
  padding: 14px 18px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  color: var(--color-text);
  text-decoration: none;
  font-weight: 600;
}

.citypick__item:hover {
  border-color: var(--color-accent-ink);
  color: var(--color-accent-ink);
}

/* «Вся Россия» — не город, поэтому отделена фоном, а не порядком в списке */
.citypick__item--any {
  background: var(--color-bg-soft);
}

.citypick__note {
  margin: 16px 0 0;
  color: var(--color-text-muted);
  font-size: var(--size-small);
}

.citypick__go {
  margin: 20px 0 0;
}


/* ---------- Статьи раздела «Работа» ---------- */

.rabota-articles {
  margin: 36px 0 0;
}

.rabota-articles__title {
  margin: 0 0 16px;
  font-family: var(--font-head);
  font-size: 28px;
}

/* ---------- Частые вопросы ---------- */

.faq {
  margin: 40px 0 0;
  padding: 28px 0 0;
  border-top: 1px solid var(--color-border);
}

/*
 * Заголовок блока — 28 на широком экране и 22 на телефоне, один кегль
 * на весь сайт. Сверка 06.09 показала разнобой: главная 28, каталог 23,
 * работа 26, вопросы 22 — одна и та же роль выглядела по-разному
 * в четырёх местах.
 */
.faq__title {
  margin: 0 0 16px;
  font-family: var(--font-head);
  font-size: 28px;
}

@media (max-width: 1023px) {
  .citypick__title,
  .rabota-articles__title,
  .faq__title { font-size: 22px; }
}

.faq__item {
  border-bottom: 1px solid var(--color-border);
}

/*
 * Вопрос — строка, по которой кликают, поэтому курсор и отступ под палец.
 * Стрелку браузера убираем и рисуем свою: штатный треугольник в Safari
 * и Chrome выглядит по-разному и съезжает от текста.
 */
.faq__q {
  position: relative;
  display: block;
  padding: 16px 40px 16px 0;
  cursor: pointer;
  font-weight: 600;
  list-style: none;
}

.faq__q::-webkit-details-marker {
  display: none;
}

.faq__q::after {
  content: "";
  position: absolute;
  right: 8px;
  top: 22px;
  width: 9px;
  height: 9px;
  border-right: 2px solid var(--color-text-light);
  border-bottom: 2px solid var(--color-text-light);
  transform: rotate(45deg);
  transition: transform 0.15s ease;
}

.faq__item[open] .faq__q::after {
  transform: rotate(-135deg);
  top: 26px;
}

.faq__q:hover {
  color: var(--color-accent-ink);
}

.faq__a {
  padding: 0 0 18px;
  max-width: 760px;
  color: var(--color-text-muted);
}

.faq__a p {
  margin: 0 0 10px;
}

.faq__a p:last-child {
  margin-bottom: 0;
}

/* ---------- Формы ---------- */

.btn,
input[type="submit"] {
  display: inline-block;
  padding: 12px 26px;
  border: none;
  border-radius: var(--radius-small);
  background: var(--color-accent);
  color: var(--color-on-accent);
  font-weight: 700;
  text-align: center;
}

.btn:hover,
input[type="submit"]:hover {
  background: var(--color-accent-hover);
  color: var(--color-on-accent);
}

/* ---------- Адаптив ---------- */

@media (max-width: 640px) {

  /*
   * Крошки на телефоне: кегль 15 вместо 13, звено — цель в 44 пикселя.
   *
   * До этапа 49 звено было 47×17 при кегле 13, а это основной способ
   * вернуться на шаг назад: промахнуться по нему проще, чем попасть.
   * Полный путь сохраняется — решение владельца от 04.09; замену одной
   * кнопкой возврата не делаем.
   *
   * Промежуток между строками 4, а не прежние 6: при высоте звена 44
   * каждая лишняя пара пикселей уходит с первого экрана, а по вертикали
   * соседние звенья и так разведены самой высотой.
   *
   * **Кегль поднят только у ссылок, последнее звено остаётся 13.**
   * Оно не нажимается и дословно повторяет заголовок страницы, который
   * стоит строкой ниже. На длинных названиях крупный кегль стоил дорого:
   * блок крошек на статье вырастал с 70 до 145 пикселей, и весь этот рост
   * приходился на строку, по которой некуда нажимать.
   *
   * **Кегль 14, а не 15 из набора размеров.** Замер: на 360 пикселях
   * при 15 цепочка «Главная → Финансовая грамотность → Налоги» перестаёт
   * помещаться в строку (54+173+49 против 320) и переносится, а перенос
   * добавляет к блоку ещё 48 пикселей — на статье выходило 139 вместо 70.
   * При 14 та же цепочка занимает 51+162+46 и остаётся в одной строке
   * на всех четырёх проверяемых ширинах.
   *
   * Граница взята существующая, 640: своей заводить не нужно, ниже неё
   * лежат все телефонные ширины.
   */
  .breadcrumbs__list {
    row-gap: 4px;
    column-gap: 8px;
  }

  .breadcrumbs__item {
    display: flex;
    align-items: center;
  }

  .breadcrumbs__item a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    font-size: 14px;
  }

  /*
   * Списки боковой колонки: строка не ниже 44.
   *
   * До этапа 50 строка была 41,8 — не хватало двух пикселей до нормы.
   * Растягиваем отступами, а не высотой строки: у списка есть разделители,
   * и текст должен оставаться прижатым к своей линии.
   *
   * Промежуток между строками остаётся прежним, 2 пикселя. Разводить
   * соседние цели на 8, как в подвале, здесь нельзя: список разделён
   * линиями, и с промежутками линии повисли бы в воздухе. Границу между
   * целями показывает сама линия.
   */
  .side-menu a,
  .side-list__item a {
    padding: 10px 0;
  }

  /*
   * Поля чужих форм — обратной связи и подписки — этап 55.
   *
   * Было: поле имени 336×32,4 при поле сообщения 304 — разной ширины
   * и вдвое ниже нормы; флажок согласия 13×13, а без него форма подписки
   * не отправляется вовсе.
   *
   * Правим стилями, а не разметкой: её выдают плагины, и правка в них
   * исчезнет при первом же обновлении.
   */
  .wpcf7-form-control:not([type="submit"]):not([type="checkbox"]):not([type="radio"]),
  .tnp-email {
    box-sizing: border-box;
    width: 100%;
    min-height: 44px;
  }

  .wpcf7-form-control[type="submit"],
  .tnp-submit {
    min-height: 44px;
  }

  .tnp-privacy {
    width: 24px;
    height: 24px;
  }

  .hub {
    grid-template-columns: 1fr;
  }

  /* Мозаика главной остаётся в две колонки — в этом её смысл. */
  .hub--compact {
    grid-template-columns: 1fr 1fr;
  }

  .card {
    grid-template-columns: 1fr;
    gap: 14px;
  }

  .card__image img {
    max-height: 200px;
  }

  .side-block--toc {
    position: static;
    max-height: none;
  }
}
