/* =========================================================
   Карточка публикации — общий слой ленты и страницы поста.

   Здесь живёт всё, что делает публикацию публикацией: молочная подложка
   карточки, шапка с автором, заголовок под фотографией, отметка конкурса
   и единая строка действий. Файл подключают и лента (home.html,
   feed/feed_page.html, groups/group_detail.html, contests/contest_entries.html),
   и страница поста (posts/post_detail.html), поэтому один и тот же объект
   выглядит одинаково в обоих местах: страница поста читается как раскрытая
   карточка ленты, а не как отдельный интерфейс.

   Главное в карточке — фотография. Всё остальное занимает минимум места:
   отдельной полосы голосования со своим фоном, серой плашки места и
   второй панели реакций у карточки нет, а горизонтальных линий — не
   больше одной.

   Геометрия страницы — ширина колонки, отступы, сетка — остаётся за самими
   страницами (home-reference.css и post-detail.css).
   ========================================================= */

/* The canonical palette lives in variables.css. A former light-only palette
   in this component reset every semantic token after the browser selected
   dark mode. */

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: var(--shadow-sm);
}

/* ===== Внешний контейнер =====
   Лёгкая рамка вместо рамки и тени сразу: у карточки остаётся один
   способ отделиться от фона страницы. Ритм отступов задают две
   переменные — шаг между блоками и горизонтальное поле; отдельных
   почти-одинаковых значений на каждый блок в карточке нет. */
.post-card {
  --card-pad-x: var(--space-2);   /* 16px — поле от края карточки */
  --card-gap: var(--space-2);     /* 16px — шаг между блоками */
  --card-gap-tight: 12px;         /* сжатый шаг: шапка → фото, конкурс */
  width: 100%;
  padding: 0;
  gap: 0;
  border-radius: 14px;
  box-shadow: none;
}

/* ===== Шапка ===== */
.post-card__header {
  grid-template-columns: 42px minmax(0, 1fr) 34px;
  gap: 12px;
  padding: 14px var(--card-pad-x) var(--card-gap-tight);
}
.post-card__avatar { width: 42px; height: 42px; }
.post-card__author { display: flex; align-items: center; gap: 6px; min-width: 0; }
.post-card__author-name { font-size: 17px; line-height: 21px; font-weight: 600; color: var(--text); }
.post-card__author .verified-badge { flex-shrink: 0; }

/* Строка вторичных метаданных: «2 дня назад · 📍 Место». Дата не
   сжимается и не переносится, место забирает остаток ширины и обрезается
   многоточием. */
.post-card__byline { display: flex; flex-wrap: nowrap; align-items: center; gap: 5px; min-width: 0; overflow: hidden; font-size: 13px; line-height: 18px; color: var(--text-secondary); }
.post-card__byline time { flex: 0 0 auto; white-space: nowrap; }
.post-card__byline-sep { flex: 0 0 auto; }
.post-card__byline .post-location { flex: 1 1 auto; min-width: 0; overflow: hidden; }
.post-card__byline .post-location__icon { flex-shrink: 0; }
.post-card__byline .post-location__name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.post-card__more { flex-shrink: 0; width: 34px; height: 34px; font-size: 18px; }

/* География — обычные вторичные метаданные, а не поле ввода: серой
   плашки под ней в карточке нет. Кликабельность населённого пункта
   остаётся, у ссылки только подчёркивание при наведении. */
.post-card__byline .post-location {
  padding: 0;
  border-radius: 0;
  background: transparent;
  font-size: inherit;
  line-height: inherit;
  font-weight: inherit;
  color: inherit;
}
.post-card__byline a.post-location:hover { background: transparent; color: var(--text); }

/* «Объект, населённый пункт» — цельная подпись, а не строка, растянутая
   до края шапки. Сама подпись — текстовая строка (см. posts.css), здесь
   она только перестаёт занимать всю оставшуюся ширину. */
.post-card__byline .post-location--place { flex: 0 1 auto; }
.post-card__byline .post-location__sep { opacity: 1; }

/* ===== Фотография =====
   Никакой рамки, тени, подложки и внутренней карточки — только само
   изображение с небольшим скруглением. Пропорции кадра сохраняются:
   высота считается от ширины, обрезки нет. */
.post-card__image { position: relative; display: block; width: auto; margin-inline: var(--card-pad-x); border: 0; border-radius: 8px; overflow: hidden; background: transparent; box-shadow: none; }
.post-card__image img { display: block; width: 100%; height: auto; max-height: none; object-fit: initial; background: transparent; }
.post-card__gallery { padding-inline: var(--card-pad-x); gap: 6px; }

/* ===== Заголовок =====
   Название лежит на самой фотографии, в её левом нижнем углу, и строки под
   кадром не занимает: подпись принадлежит снимку, а не карточке. Прежней
   охристой чёрточки перед текстом нет.

   Вариант ниже — для публикации без фотографии: тогда заголовку негде лежать
   поверх кадра и он остаётся обычной строкой карточки. */
.post-card__title {
  margin: var(--card-gap) var(--card-pad-x) 0;
  font-family: var(--ff-heading);
  font-size: 20px;
  line-height: 26px;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.post-card__title::before { content: none; }
.post-card__title a { color: var(--text); }
.post-card__title a:hover { color: var(--green); }

/* Заголовок поверх фотографии. Плашки под текстом нет — контраст держит
   градиент .post-card__shade, — поэтому текст остаётся белым и на светлом
   снимке, а лёгкая тень страхует его на выбеленном небе.

   Набор здесь мельче и легче, чем у заголовка карточки: это подпись к
   снимку, а не заголовок статьи. Отсюда основная гарнитура вместо
   акцидентной и вес 600 — на тёмном градиенте 700/800 читались бы как
   врезка поверх фотографии и спорили бы с самим кадром.

   Больше двух строк заголовок не занимает: остаток обрезается многоточием,
   и самое длинное название не закрывает кадр и не выходит за его границы. */
.post-card__image .post-card__title {
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 12px;
  z-index: 2;
  margin: 0;
  font-family: inherit;
  font-size: 16px;
  line-height: 1.25;
  font-weight: 600;
  letter-spacing: normal;
  color: #fff;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .45);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  overflow-wrap: anywhere;
}

/* Затемнение — отдельный слой под заголовком, а не фильтр на кадре: оно
   занимает нижнюю четверть снимка и гаснет уже там, поэтому кадр остаётся
   светлым, а тёмная полоса не читается как отдельная плашка под подписью.
   В разметке слоя нет у публикации без заголовка — затемнять там нечего. */
.post-card__shade {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1;
  height: 28%;
  pointer-events: none;
  background: linear-gradient(
    to top,
    rgba(0, 0, 0, .58) 0%,
    rgba(0, 0, 0, .20) 55%,
    rgba(0, 0, 0, 0) 100%
  );
}

/* ===== Отметка конкурса =====
   Компактная кликабельная строка, а не полноширинная цветная CTA-панель:
   от остального содержимого её отличают только приглушённая охра и
   стрелка справа. У неконкурсной публикации строки нет вместе с её
   отступом — шаблон не выводит ничего. */
.post-card__contest {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: var(--card-gap-tight) var(--card-pad-x) 0;
  min-height: 40px;
  padding: 6px 10px;
  border-radius: 10px;
  background: color-mix(in srgb, var(--ochre) 10%, transparent);
  color: var(--ochre);
  font-size: 13px;
  line-height: 18px;
  font-weight: 500;
}
.post-card__contest:hover { background: color-mix(in srgb, var(--ochre) 16%, transparent); color: var(--ochre); }
.post-card__contest-icon { flex: none; font-size: 15px; line-height: 1; }
.post-card__contest-text { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.post-card__contest-chevron { flex: none; opacity: .75; }

.post-card__text { margin-top: var(--card-gap-tight); padding: 0 var(--card-pad-x); font-size: 15px; }

/* ===== Единая строка действий =====
   Лёгкий action-bar, а не ряд кнопок: у элементов строки нет ни капсул, ни
   рамок, ни постоянного фона — только знак и число. Слева стоят реакции и
   «+», за тонкой вертикальной чертой — рейтинг и комментарии, справа
   («сохранить» и «поделиться») строку закрывает пара иконок.

   Две переменные держат строку единой: --action-icon — размер любого знака
   (эмодзи и SVG одинаковы, иначе эмодзи выглядит крупнее иконки),
   --action-hit — минимальная область нажатия. Видимый знак маленький,
   область нажатия — нет: она набирается padding'ом вокруг знака.

   Единственная горизонтальная линия карточки — верхняя граница подвала:
   она отделяет содержимое публикации от того, что с ней можно сделать. */
.post-card__footer {
  --action-icon: 18px;      /* эмодзи и SVG одного визуального размера */
  --action-hit: 40px;       /* минимальная область нажатия */
  --action-gap: 14px;       /* шаг между группами строки */
  --action-radius: 8px;     /* скругление лёгкой подсветки при наведении */
  display: block;
  min-height: 0;
  margin-top: var(--card-gap-tight);
  padding: 2px var(--card-pad-x) 4px;
  border-top: 1px solid var(--c-divider);
}

/* Правая пара отодвигается от левой группы остатком ширины, а не
   space-between: между самими действиями слева промежутки остаются
   одинаковыми и не растягиваются вслед за шириной карточки. Собственный
   промежуток строки (10 px) не сжимается вместе с --action-gap: даже на
   320 px счётчик комментариев не должен встать вплотную к закладке. */
.post-card__actions { display: flex; align-items: center; gap: 10px; min-width: 0; }
.post-card__actions-main { display: flex; align-items: center; gap: var(--action-gap); min-width: 0; }
.post-card__actions-aside { display: flex; align-items: center; gap: 2px; flex-shrink: 0; margin-left: auto; }

/* Все числа строки — один кегль, вес и интерлиньяж: счётчик реакции,
   рейтинг и число комментариев читаются как один ряд чисел, а не как три
   разных подписи. font: inherit нужен явно — иначе браузер подставит
   кнопке и ссылке собственный системный шрифт. */
.post-card__actions,
.post-card__actions button,
.post-card__actions a,
.post-card__actions span {
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  line-height: 1;
}
.post-card__actions button,
.post-card__actions a { font: inherit; }

.post-card__actions .reaction-count,
.post-card__actions .post-rating__value,
.post-card__actions .post-card__stats-count {
  font-size: 14px;
  font-weight: 600;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Ни один элемент строки не сжимается: число рядом со знаком должно
   остаться числом, а не двумя цифрами в столбик. Когда ширины не хватает,
   ряд укорачивают реакции (см. data-narrow-visible-limit), а не вёрстка. */
.post-card__actions-main > *,
.post-card__actions-aside > *,
.post-card .post-reactions > * { flex: none; }

/* Страховка на случай, когда в строке всё-таки оказалось больше, чем
   ширины: уступают ряды эмодзи, а рейтинг, комментарии и правая пара
   остаются на своих местах и не наезжают друг на друга. */
.post-card__actions-main > .post-reactions,
.post-card__actions-main > .post-reactions-legacy {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
}

/* Знаки строки — эмодзи и SVG — одного размера. Правило намеренно висит
   на .post-card__actions, а не на всём подвале: у страницы публикации в
   подвале своя раскладка со своими иконками (см. post-detail.css). */
.post-card__actions svg { width: var(--action-icon); height: var(--action-icon); flex: none; }

/* Реакции читаются как обычное действие строки, а не как ряд пилюль.
   Промежуток внутри ряда маленький: кнопки уже разведены собственными
   полями, из которых набрана область нажатия. */
.post-card .post-reactions { flex-wrap: nowrap; justify-content: flex-start; gap: 0; padding: 0; }
.post-card .post-reactions-legacy { gap: 0; }
.post-card .post-reactions .reaction-btn,
.post-card .reaction-btn,
.post-card .reaction-btn--top,
.post-card .reaction-btn--legacy {
  min-width: var(--action-hit);
  min-height: var(--action-hit);
  padding: 2px 6px;
  gap: 5px;
  border: 0;
  border-radius: var(--action-radius);
  background: transparent;
  box-shadow: none;
}

.post-card .post-reactions .reaction-btn--active {
  background: transparent;
  border: 0;
  box-shadow: none;
  color: var(--text);
}

.post-card .post-reactions .reaction-btn--active .reaction-count {
  color: var(--text);
}

/* «+» — обычный знак строки, а не кнопка в капсуле: у неё тот же кегль,
   что у эмодзи рядом, и та же область нажатия. */
.post-card .post-reactions .reaction-btn--picker {
  width: auto;
  height: auto;
  min-width: var(--action-hit);
  min-height: var(--action-hit);
  padding: 2px 6px;
  justify-content: center;
  background: transparent;
  border: 0;
  border-radius: var(--action-radius);
  box-shadow: none;
  color: var(--text-secondary);
  font-size: var(--action-icon);
  font-weight: 500;
  line-height: 1;
}

.post-card .post-reactions .reaction-emoji,
.post-card .reaction-emoji {
  font-size: var(--action-icon);
  line-height: 1;
  filter: none;
}
.post-card .post-reactions .reaction-count,
.post-card .reaction-count { min-width: 0; color: var(--text); }

/* Тонкая вертикальная черта между реакциями и счётчиками. Она заметно
   короче строки и светлее любой границы карточки: это пауза в ряду
   действий, а не край секции. */
.post-card__actions-divider {
  flex: none;
  width: 1px;
  height: 20px;
  background: var(--c-divider);
}

/* ===== Голосование в строке действий =====
   Вместо надписи «Голосовать» — стрелка и текущий рейтинг. Ни фона, ни
   капсулы: элемент весит столько же, сколько соседние действия. */
.post-rating--inline { gap: 0; flex-shrink: 0; }
.post-rating--inline .post-rating__arrow--up {
  width: var(--action-hit);
  height: var(--action-hit);
  border-radius: var(--action-radius);
  background: transparent;
  color: var(--text-secondary);
}
.post-rating--inline .post-rating__value {
  min-width: 0;
  padding: 0 2px;
  background: transparent;
}

/* Цвет рейтинга зависит от самого рейтинга, а не от того, голосовал ли
   текущий пользователь: положительный рейтинг зелёный и у того, кто ещё
   не голосовал. Классы состояния проставляет шаблон, а после голосования
   — reactions.js. */
.post-rating--inline .post-rating__value.score-pill--positive { color: var(--green); }
.post-rating--inline .post-rating__value.score-pill--neutral,
.post-rating--inline .post-rating__value.score-pill--negative { color: var(--text-secondary); }
.post-rating--inline:has(.post-rating__value.score-pill--positive) .post-rating__arrow--up { color: var(--green); }
/* Свой голос показывает цвет стрелки, а не зелёный квадрат вокруг неё:
   постоянных подложек в строке нет ни у одного состояния. */
.post-rating--inline .post-rating__arrow--up.is-active { color: var(--green); background: transparent; }

.post-card__stats-comments {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  min-width: var(--action-hit);
  min-height: var(--action-hit);
  padding: 0 6px;
  border-radius: var(--action-radius);
  background: transparent;
  color: var(--text-secondary);
}
.post-card__stats-comments .post-card__stats-count { color: var(--text); }

.post-card__stats { margin-left: auto; gap: var(--action-gap); color: var(--text); }
.post-card__stats-divider { display: none; }
.post-card__action-btn {
  width: var(--action-hit);
  height: var(--action-hit);
  border-radius: var(--action-radius);
  background: transparent;
  color: var(--text-secondary);
}

/* Подсветка при наведении — только там, где есть настоящий курсор: на
   тапе она залипает под пальцем и остаётся плашкой до следующего касания,
   поэтому сначала гасим :hover, унаследованный от общих правил кнопок, и
   возвращаем его ниже — уже под запрос о настоящем курсоре. */
.post-card__footer .reaction-btn:hover:not(:disabled),
.post-card__footer .reaction-btn--active:hover:not(:disabled),
.post-card__footer .reaction-btn--picker:hover:not(:disabled),
.post-card__footer .post-rating__arrow:hover,
.post-card__footer .post-card__stats-comments:hover,
.post-card__footer .post-card__action-btn:hover {
  background: transparent;
}

@media (hover: hover) and (pointer: fine) {
  .post-card__footer .reaction-btn:hover:not(:disabled),
  .post-card__footer .reaction-btn--active:hover:not(:disabled),
  .post-card__footer .reaction-btn--picker:hover:not(:disabled),
  .post-card__footer .post-rating__arrow--up:hover:not(:disabled),
  .post-card__footer .post-card__stats-comments:hover,
  .post-card__footer .post-card__action-btn:hover:not(:disabled) {
    background: var(--surface-soft);
    border-radius: var(--action-radius);
  }
  .post-card__footer .post-card__stats-comments:hover,
  .post-card__footer .post-card__action-btn:hover:not(:disabled) { color: var(--text); }
  /* Счётчик прежнего набора кликать нечего — и подсвечивать тоже. */
  .post-card__footer .reaction-btn--legacy:hover { background: transparent; }
}

/* Фокус виден, но не тяжелее самой строки: тонкий контур вместо широкого
   кольца, которое в ряду из шести элементов выглядит как выделенная плашка. */
.post-card__footer .reaction-btn:focus-visible,
.post-card__footer .post-rating__arrow:focus-visible,
.post-card__footer .post-card__stats-comments:focus-visible,
.post-card__footer .post-card__action-btn:focus-visible {
  outline: 2px solid var(--green);
  outline-offset: -2px;
  box-shadow: none;
  border-radius: var(--action-radius);
}

@media (max-width: 640px) {
  .post-card { --card-pad-x: 14px; }
  .post-card__header { grid-template-columns: 40px minmax(0, 1fr) 30px; gap: 10px; padding: 12px var(--card-pad-x) var(--card-gap-tight); }
  .post-card__avatar { width: 40px; height: 40px; }
  .post-card__author-name { font-size: 16px; line-height: 20px; font-weight: 600; }
  .post-card__identity { overflow: hidden; }
  .post-card__byline { gap: 5px; font-size: 13px; color: var(--text-secondary); }
  .post-card__byline > :last-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  /* Фото во всю ширину экрана: поля карточки на нём не экономят место, а
     отнимают его у главного элемента. */
  .post-card__image { width: 100%; max-width: none; margin-inline: 0; border-radius: 0; }
  .post-card__image img { width: 100%; max-width: none; max-height: none; height: auto; display: block; object-fit: initial; }

  .post-card__title { font-size: 18px; line-height: 24px; }
  /* На узком экране подпись ещё компактнее: кадр занимает всю ширину, и
     заголовку тем более незачем отбирать у него площадь. */
  .post-card__image .post-card__title {
    left: 12px;
    right: 12px;
    bottom: 10px;
    font-size: 15px;
    line-height: 1.2;
    font-weight: 600;
  }

  /* Интерактивные элементы не мельчают ради того, чтобы поместиться: знак
     остаётся 18 px, область нажатия — 40 px, а сжимаются промежутки между
     ними. Строка при этом остаётся одной строкой: перенос на вторую и
     горизонтальная прокрутка тут одинаково недопустимы. */
  .post-card__footer { --action-gap: 8px; padding-inline: var(--card-pad-x); }
  .post-card__actions { flex-wrap: nowrap; }
  .post-card__actions-main { flex-wrap: nowrap; }

  /* Счётчики прежнего набора в ленте на узком экране не показываются.
     Голосовать за них нельзя, а места они занимают столько же, сколько
     живые реакции, — и тогда строка перестаёт помещаться. Из БД они не
     делись никуда: их по-прежнему видно в ленте на десктопе и на самой
     странице публикации, где у футера другая раскладка. */
  .post-card__actions .post-reactions-legacy { display: none; }

  .post-card { border: 0; border-radius: 14px; box-shadow: none; }
  /* Прямой потомок — ссылка на населённый пункт, когда объекта съёмки нет.
     Только он: ссылка внутри подписи «объект, населённый пункт» остаётся
     частью текстовой строки, блоком она бы разорвала её на две. */
  .post-card__byline > a { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* 320-360 px: сначала уходят промежутки и поля карточки, следом —
   вертикальная черта. Размер знаков и область нажатия не трогаем: строка
   должна остаться нажимаемой, а не поместиться любой ценой. */
@media (max-width: 400px) {
  .post-card__footer { --action-gap: 4px; }
  .post-card .post-reactions .reaction-btn,
  .post-card .post-reactions .reaction-btn--picker { padding-inline: 3px; }
  .post-card__stats-comments { padding-inline: 3px; }
}

@media (max-width: 380px) {
  .post-card { --card-pad-x: 10px; }
  .post-card__footer { --action-gap: 2px; }
  .post-card__actions-divider { display: none; }
  .post-card .post-reactions .reaction-btn,
  .post-card .post-reactions .reaction-btn--picker { padding-inline: 2px; }
  .post-card__stats-comments { padding-inline: 2px; }
}

@media (prefers-color-scheme: dark) {
  .post-card .post-reactions .reaction-btn,
  .post-card .reaction-btn,
  .post-card .reaction-btn--top,
  .post-card .reaction-btn--legacy {
    background: transparent;
    border: 0;
    box-shadow: none;
    color: var(--text);
  }

  .post-card .post-reactions .reaction-btn--active {
    background: transparent;
  }

  .post-card .post-reactions .reaction-btn--picker {
    background: transparent;
    color: var(--text-secondary);
  }

  .post-card__contest {
    background: color-mix(in srgb, var(--ochre) 16%, transparent);
  }
}
