/* Tiveli UI Kit — v0.1
 * Слой компонентов поверх tiveli-tokens.css.
 * Подключать строго после токенов: здесь нет ни одного HEX-значения.
 *
 * Разметка каждого компонента зафиксирована в docs/design/ui-kit-v0.1.md —
 * templ-компоненты должны отдавать ровно её.
 */

/* ---------------------------------------------------------------- база --- */

/* Минимальный сброс. Без него width: 100% у полей ввода складывается
   с их padding и поле переполняет контейнер — браузер по умолчанию
   считает размеры по content-box. Сброс намеренно ограничен .t-root,
   чтобы слой не влиял на чужую разметку. */
.t-root *,
.t-root *::before,
.t-root *::after {
  box-sizing: border-box;
}

.t-root :where(h1, h2, h3, h4, p, figure, blockquote, ul, ol, dl, dd) {
  margin: 0;
}

.t-root :where(ul, ol) {
  padding: 0;
  list-style: none;
}

.t-root :where(img, svg, video) {
  max-width: 100%;
  display: block;
}

.t-root {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: var(--text-body);
  line-height: var(--leading-normal);
  -webkit-font-smoothing: antialiased;
}

/* Один видимый фокус на весь продукт. Мышью не показывается. */
.t-root :focus-visible {
  outline: var(--border-emphasis) solid var(--color-focus);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

.t-label {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--color-text-tertiary);
}

/* ------------------------------------------------- временная группа ------ */
/* «Скоро», «Позже», «Когда-нибудь», «История» — заголовки разделов ленты. */

.t-group {
  display: grid;
  gap: var(--space-3);
}

.t-group__head {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  padding-bottom: var(--space-2);
  border-bottom: var(--border-hairline) solid var(--color-line);
}

.t-group__title {
  font-size: var(--text-h2);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
}

.t-group__count {
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  font-variant-numeric: tabular-nums;
  color: var(--color-text-tertiary);
}

/* «История» — единственная группа с тёплой температурой. */
.t-group--past .t-group__title { color: var(--color-past-text); }

.t-group__items {
  display: grid;
  gap: var(--space-3);
}

/* -------------------------------------------- карточка намерения --------- */
/* Стадия кодируется плотностью: фон, контур, вес заголовка, объём данных.
   Цветом стадии не кодируются — см. design-tokens-v0.1.md §6. */

.t-card {
  display: grid;
  gap: var(--space-2);
  padding: var(--space-4);
  border: var(--border-hairline) solid var(--color-line);
  border-radius: var(--radius-md);
  background: transparent;
  transition: border-color var(--duration-default) var(--ease-standard),
              background-color var(--duration-default) var(--ease-standard);
}

.t-card__stage {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--color-text-tertiary);
}

.t-card__title {
  font-size: var(--text-h3);
  font-weight: var(--weight-medium);
  line-height: var(--leading-snug);
  text-wrap: balance;
}

/* Длинное название не обрезается: намерение важнее ровной сетки. */
.t-card__title a {
  color: inherit;
  text-decoration: none;
}

.t-card__title a:hover { text-decoration: underline; text-underline-offset: 3px; }

.t-card__meta {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  font-size: var(--text-caption);
  color: var(--color-text-secondary);
}

.t-card__when {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

.t-card__people { margin-left: auto; }

.t-card__cover {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: var(--radius-lg);
  background: var(--color-surface-sunken);
}

.t-card--linked:hover { border-color: var(--color-line-strong); }

/* --- стадии --- */

.t-card--idea .t-card__title { color: var(--color-text-secondary); }

.t-card--planned { background: var(--color-surface); }

.t-card--soon {
  background: var(--color-surface);
  border-width: var(--border-emphasis);
  border-color: var(--color-line-strong);
}
.t-card--soon .t-card__title { font-weight: var(--weight-semibold); }

.t-card--past {
  background: var(--color-surface-past);
  border-color: transparent;
}
.t-card--past .t-card__stage { color: var(--color-past-text); }

.t-card--paused { background: var(--color-surface); }
.t-card--paused .t-card__title { color: var(--color-text-secondary); }

.t-card--cancelled .t-card__title {
  color: var(--color-text-tertiary);
  font-weight: var(--weight-regular);
}

/* --- действия на карточке --- */

.t-card__actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-top: var(--space-1);
}

.t-card__ask {
  font-size: var(--text-caption);
  color: var(--color-text-secondary);
}

/* --- смена стадии: продолжение, а не переключение флага --- */
/* Тёплая линия проходит по карточке слева направо и уводит намерение
   в «Историю». Ни галочки, ни вспышки, ни звука завершения — Visual
   Identity §10 требует продолжения вместо завершения. */

.t-card { position: relative; }

.t-card--continuing {
  overflow: hidden;
}

.t-card--continuing::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--border-emphasis);
  background: var(--color-past);
  transform-origin: left center;
  animation: t-continue var(--duration-continuation) var(--ease-standard) both;
}

@keyframes t-continue {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* Метка стадии успевает смениться, пока идёт линия. */
.t-card--continuing .t-card__stage {
  color: var(--color-past-text);
  transition: color var(--duration-continuation) var(--ease-standard);
}

/* «Отложено» и «Отменено» — не продолжение, поэтому линии нет. Карточка
   теряет плотность за то же время: намерение отступает, а не завершается.
   Обычная смена стадии идёт за --duration-default; здесь длительность
   растянута, потому что это переход, а не наведение курсора. */
.t-card--settling,
.t-card--settling .t-card__title,
.t-card--settling .t-card__stage {
  transition-property: background-color, border-color, color;
  transition-duration: var(--duration-continuation);
  transition-timing-function: var(--ease-standard);
}

@media (prefers-reduced-motion: reduce) {
  .t-card--continuing::after { animation: none; }
}

/* ------------------------------------------------------- участники ------- */

.t-people {
  display: flex;
  align-items: center;
}

.t-avatar {
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  display: grid;
  place-items: center;
  flex: none;
  font-size: var(--text-micro);
  font-weight: var(--weight-medium);
  background: var(--color-accent-quiet);
  color: var(--color-accent-text);
  border: var(--border-hairline) solid var(--color-bg);
}

/* Перекрытие начинается со второго — первый стоит на своём месте. */
.t-people .t-avatar + .t-avatar { margin-left: -0.4rem; }

/* Больше четырёх участников сворачиваются в счётчик, иначе стопка
   начинает конкурировать с названием намерения. */
.t-avatar--more {
  background: transparent;
  color: var(--color-text-tertiary);
  border-color: var(--color-line-strong);
  font-family: var(--font-mono);
}

.t-card--past .t-avatar {
  background: color-mix(in srgb, var(--color-past) 22%, transparent);
  color: var(--color-past-text);
}

/* ------------------------------------------------------- вложения -------- */

.t-attachments {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.t-attach {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  max-width: 100%;
  padding: var(--space-1) var(--space-3);
  border: var(--border-hairline) solid var(--color-line);
  border-radius: var(--radius-sm);
  background: var(--color-bg);
  font-size: var(--text-caption);
  color: var(--color-text-secondary);
  text-decoration: none;
}

a.t-attach:hover { border-color: var(--color-line-strong); color: var(--color-text); }

.t-attach__kind {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  flex: none;
}

.t-attach__name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ------------------------------------------------------ обсуждение ------- */
/* Не мессенджер: реплики не заключены в пузыри. Visual Identity §13 прямо
   требует, чтобы карточки не выглядели пузырями, и обсуждение — не
   исключение. Реплики разделяются пространством и именем автора. */

.t-thread {
  display: grid;
  gap: var(--space-5);
}

.t-message {
  display: grid;
  gap: var(--space-2);
}

.t-message__head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.t-message__author {
  font-size: var(--text-body-sm);
  font-weight: var(--weight-medium);
}

.t-message__when {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  color: var(--color-text-tertiary);
  font-variant-numeric: tabular-nums;
}

.t-message__body {
  font-size: var(--text-body);
  color: var(--color-text-secondary);
  max-width: var(--measure);
}

/* Поле ответа. Кнопка выравнивается по нижней границе поля. */
.t-composer {
  display: flex;
  align-items: flex-end;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.t-composer .t-field { flex: 1 1 20rem; max-width: none; }

/* --------------------------------------------------------- галерея ------- */

.t-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: var(--space-3);
}

.t-photo {
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-lg);
  background: var(--color-surface-sunken);
  border: var(--border-hairline) solid var(--color-line);
}

/* Загруженная фотография заполняет своё место целиком: воспоминание важнее
   аккуратной рамки вокруг него. */
.t-photo--filled {
  margin: 0;
  overflow: hidden;
  position: relative;
}

.t-photo__image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Действие удаления не висит над снимком, а появляется под ним по наведению
   или фокусу: галерея должна читаться как фотографии, а не как список
   управляемых объектов. */
.t-photo--filled .t-attach__remove,
.t-attachrow .t-attach__remove {
  opacity: 0;
  transition: opacity var(--duration-default) var(--ease-standard);
}

.t-photo--filled:hover .t-attach__remove,
.t-photo--filled:focus-within .t-attach__remove,
.t-attachrow:hover .t-attach__remove,
.t-attachrow:focus-within .t-attach__remove {
  opacity: 1;
}

.t-photo--filled .t-attach__remove {
  position: absolute;
  right: var(--space-2);
  bottom: var(--space-2);
  background: var(--color-surface);
  border-radius: var(--radius-sm);
}

.t-attachrow {
  display: grid;
  gap: var(--space-2);
}

@media (prefers-reduced-motion: reduce) {
  .t-photo--filled .t-attach__remove,
  .t-attachrow .t-attach__remove { transition: none; }
}

/* Ссылка с превью и заметка — вложения, которым мало строки-чипа. */
.t-linkcard,
.t-note {
  display: grid;
  gap: var(--space-2);
  padding: var(--space-4);
  border: var(--border-hairline) solid var(--color-line);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  text-decoration: none;
  color: inherit;
}

a.t-linkcard:hover { border-color: var(--color-line-strong); }

.t-linkcard__kind,
.t-note__kind {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--color-text-tertiary);
}

.t-linkcard__title,
.t-note__title {
  font-size: var(--text-body);
  font-weight: var(--weight-medium);
  line-height: var(--leading-snug);
}

.t-linkcard__host {
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  color: var(--color-text-tertiary);
}

.t-note__body {
  font-size: var(--text-body-sm);
  color: var(--color-text-secondary);
  max-width: var(--measure);
}

/* ------------------------------------------------ подсказка Tiveli ------- */
/* Линия из знака вместо иконки. Ни свечения, ни бейджа «AI»,
   ни собственной поверхности — подсказка читается как реплика. */

.t-hint {
  display: grid;
  gap: var(--space-2);
  padding-left: var(--space-4);
  border-left: var(--border-emphasis) solid var(--color-accent);
}

.t-hint__kind { /* вопрос · идея · следующий шаг · напоминание · итог */
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--color-text-tertiary);
}

.t-hint__body {
  font-size: var(--text-body-sm);
  color: var(--color-text-secondary);
  max-width: var(--measure);
}

.t-hint__actions {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
}

/* --------------------------------------------------------- кнопки -------- */

.t-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border: var(--border-hairline) solid transparent;
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: var(--text-body-sm);
  font-weight: var(--weight-medium);
  line-height: var(--leading-tight);
  cursor: pointer;
  text-decoration: none;
  transition: background-color var(--duration-instant) var(--ease-standard),
              border-color var(--duration-instant) var(--ease-standard);
}

.t-btn--primary {
  background: var(--color-accent);
  color: var(--color-text-on-accent);
}
.t-btn--primary:hover { background: var(--color-accent-text); }

.t-btn--secondary {
  background: transparent;
  color: var(--color-text);
  border-color: var(--color-line-strong);
}
.t-btn--secondary:hover { background: var(--color-surface); }

/* Третичная кнопка — для действий внутри подсказки: голосом бренда
   это предложение, а не команда, поэтому она не выглядит призывом. */
.t-btn--quiet {
  background: transparent;
  color: var(--color-accent-text);
  padding-inline: 0;
}
.t-btn--quiet:hover { text-decoration: underline; text-underline-offset: 3px; }

.t-btn--danger {
  background: transparent;
  color: var(--color-danger);
  border-color: var(--color-danger);
}
.t-btn--danger:hover { background: var(--color-danger-quiet); }

.t-btn[disabled],
.t-btn[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: 0.45;
}
/* Выключенная кнопка не реагирует на наведение — каждая роль держит
   свой собственный фон, а не общий. */
.t-btn--primary[disabled]:hover { background: var(--color-accent); }
.t-btn--secondary[disabled]:hover { background: transparent; }
.t-btn--danger[disabled]:hover { background: transparent; }
.t-btn--quiet[disabled]:hover { text-decoration: none; }

/* ---------------------------------------------------------- поля --------- */

.t-field {
  display: grid;
  gap: var(--space-2);
  max-width: 32rem;
}

.t-field__label {
  font-size: var(--text-body-sm);
  font-weight: var(--weight-medium);
}

.t-field__control {
  width: 100%;
  padding: var(--space-3);
  font: inherit;
  font-size: var(--text-body);
  color: var(--color-text);
  background: var(--color-surface);
  border: var(--border-hairline) solid var(--color-line-strong);
  border-radius: var(--radius-sm);
  transition: border-color var(--duration-instant) var(--ease-standard);
}

.t-field__control::placeholder { color: var(--color-text-tertiary); }
.t-field__control:hover { border-color: var(--color-text-tertiary); }
textarea.t-field__control { min-height: 6rem; resize: vertical; line-height: var(--leading-normal); }

.t-field__note {
  font-size: var(--text-caption);
  color: var(--color-text-tertiary);
}

.t-field__control[disabled] {
  background: var(--color-surface-sunken);
  color: var(--color-text-tertiary);
  cursor: not-allowed;
}

/* Ошибка передаётся не только цветом: остаётся текст под полем. */
.t-field--invalid .t-field__control { border-color: var(--color-danger); }
.t-field--invalid .t-field__note { color: var(--color-danger); }

/* ------------------------------------------------- всплывающие слои ------ */
/* Единственное место, где разрешена тень. */

.t-menu {
  min-width: 12rem;
  padding: var(--space-2);
  background: var(--color-surface);
  border: var(--border-hairline) solid var(--color-line);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lifted);
  display: grid;
  gap: 2px;
}

.t-menu__item {
  display: block;
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  font: inherit;
  font-size: var(--text-body-sm);
  color: var(--color-text);
  text-align: left;
  cursor: pointer;
}
.t-menu__item:hover { background: var(--color-accent-quiet); color: var(--color-accent-text); }
.t-menu__item--danger { color: var(--color-danger); }
.t-menu__item--danger:hover { background: var(--color-danger-quiet); color: var(--color-danger); }

.t-menu__sep {
  height: var(--border-hairline);
  margin: var(--space-1) 0;
  background: var(--color-line);
}

.t-dialog {
  max-width: 26rem;
  padding: var(--space-5);
  background: var(--color-surface);
  border: var(--border-hairline) solid var(--color-line);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lifted);
  display: grid;
  gap: var(--space-3);
}

.t-dialog__title {
  font-size: var(--text-h3);
  font-weight: var(--weight-semibold);
}

.t-dialog__body {
  font-size: var(--text-body-sm);
  color: var(--color-text-secondary);
}

.t-dialog__actions {
  display: flex;
  gap: var(--space-2);
  justify-content: flex-end;
  flex-wrap: wrap;
  margin-top: var(--space-2);
}

/* ------------------------------------------------- пустые состояния ------ */

.t-empty {
  display: grid;
  gap: var(--space-3);
  justify-items: start;
  padding: var(--space-6) 0;
  max-width: var(--measure);
}

.t-empty__title {
  font-size: var(--text-h2);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-tight);
  text-wrap: balance;
}

.t-empty__body {
  font-size: var(--text-body);
  color: var(--color-text-secondary);
}

/* ------------------------------------------------------ горизонты -------- */
/* Четыре временных горизонта, названные словами. Показываются один раз —
   на полностью пустом пространстве, вместо четырёх пустых заголовков. */

.t-horizons {
  display: grid;
  gap: var(--space-2);
}

.t-horizon {
  display: flex;
  gap: var(--space-3);
  align-items: baseline;
  font-size: var(--text-body-sm);
}

.t-horizon__name {
  font-weight: var(--weight-medium);
  min-width: 9rem;
}

.t-horizon__note { color: var(--color-text-secondary); }

@media (max-width: 420px) {
  .t-horizon { display: grid; gap: 0; }
  .t-horizon__name { min-width: 0; }
}

/* ------------------------------------------------------ утилиты ---------- */

.t-stack { display: grid; gap: var(--space-5); }
.t-row { display: flex; gap: var(--space-3); flex-wrap: wrap; align-items: center; }
.t-muted { color: var(--color-text-secondary); }
.t-measure { max-width: var(--measure); }

/* ------------------------------------------------------- реакции --------- */

/* Отклик на реплику. Поставленные реакции видны всегда; предложенные
   проявляются по наведению или фокусу — обсуждение должно читаться как
   разговор, а не как панель кнопок. */
.t-reactions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
  margin-top: var(--space-2);
}

.t-reactions__form { display: contents; }

.t-reaction {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 2px var(--space-2);
  border: var(--border-hairline) solid var(--color-line);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
  line-height: 1.6;
  cursor: pointer;
}

.t-reaction--mine {
  border-color: var(--color-accent);
  background: var(--color-accent-quiet);
}

.t-reaction--offer {
  opacity: 0;
  transition: opacity var(--duration-default) var(--ease-standard);
}

.t-message:hover .t-reaction--offer,
.t-message:focus-within .t-reaction--offer { opacity: 1; }

.t-reaction__count {
  font-size: 0.85em;
  color: var(--color-text-secondary);
}

.t-reaction--mine .t-reaction__count { color: var(--color-accent-text); }

@media (hover: none) {
  .t-reaction--offer { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .t-reaction--offer { transition: none; }
}

/* Приглашение на главной: не подсказка, а действие. */
.page__invitation {
  display: grid;
  gap: var(--space-2);
  justify-items: start;
  padding: var(--space-4);
  border: var(--border-emphasis) solid var(--color-accent-quiet);
  border-radius: var(--radius-md);
}

/* --------------------------------------------------- лента событий ------- */

/* Ссылка на ленту и число непрочитанного. Число — спокойная метка, а не
   тревожный значок: продукт не подгоняет человека. */
.t-events__link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-accent-text);
  text-decoration: none;
  white-space: nowrap;
}

.t-events__link:hover { text-decoration: underline; text-underline-offset: 3px; }

.t-events__count {
  min-width: 1.5rem;
  padding: 0 var(--space-1);
  border-radius: var(--radius-sm);
  background: var(--color-accent-quiet);
  color: var(--color-accent-text);
  font-size: 0.85em;
  text-align: center;
}

.t-events { display: grid; gap: var(--space-3); }

/* Событие — строка, а не карточка: лента читается сверху вниз одним взглядом
   и не соревнуется с намерениями за внимание. */
.t-event { margin: 0; }

.t-event__open {
  display: grid;
  gap: var(--space-1);
  width: 100%;
  padding: var(--space-4);
  border: var(--border-hairline) solid var(--color-line);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.t-event--unread .t-event__open {
  border-color: var(--color-accent-quiet);
  background: var(--color-surface-sunken);
}

.t-event__kind {
  font-size: 0.85em;
  color: var(--color-text-tertiary);
  text-transform: lowercase;
}

.t-event__title { font-weight: var(--weight-medium); }
.t-event--unread .t-event__title { color: var(--color-accent-text); }

.t-event__body {
  color: var(--color-text-secondary);
  line-height: var(--leading-normal);
}

.t-event__when { font-size: 0.85em; color: var(--color-text-tertiary); }

/* Убранная реплика: место остаётся, слова — нет. */
.t-message--gone .t-message__author,
.t-message__body--gone { color: var(--color-text-tertiary); font-style: italic; }

.t-message__note { font-size: 0.85em; color: var(--color-text-tertiary); }

.t-message__own { margin-top: var(--space-2); }

.t-message__own-summary {
  font-size: 0.9em;
  color: var(--color-text-secondary);
  cursor: pointer;
}

.t-message__own[open] .t-message__own-summary { margin-bottom: var(--space-2); }

.t-message__edit { display: grid; gap: var(--space-2); margin-bottom: var(--space-2); }
.t-message__edit .t-field { max-width: none; }

/* Тихие часы: метка вместо счётчика. Не тревога, а сообщение о том, что
   продукт сейчас молчит. */
.t-events__quiet {
  font-size: 0.85em;
  color: var(--color-text-tertiary);
}
