/* ===== Reset / base ===== */
*,
*::before,
*::after {
  box-sizing: border-box;
}

/* Сброс нативного вида у всех кнопок проекта. Без этого браузер поверх
   background:none/border:none всё равно может подрисовывать свой control
   chrome (особенно заметно у кнопок с явными width/height, как .toggle__item) —
   именно это давало "призрачный" контур при переключении Chat/Work. */
button {
  appearance: none;
  -webkit-appearance: none;
  font: inherit;
  color: inherit;
}

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
}

body {
  min-height: 100dvh;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: #F99853; /* совпадает с базовым слоем фона, чтобы не было "мигания" до отрисовки .bg */
}

/* ===== Фон =====
   Слои снизу вверх:
   1. base color (#F99853)
   2. bg__blob--1 / bg__blob--2 — размытые объекты, "перекатывающиеся" по фону
   3. bg__riso — риso-текстура
   4. bg__noise — шум
   Фон зафиксирован (position: fixed) и всегда занимает весь видимый вьюпорт,
   независимо от скролла и высоты контента страницы. */

.bg {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  background-color: #F99853;
}

.bg__blob {
  position: absolute;
  will-change: transform;
  pointer-events: none;
  width: 100%;
  height: auto;
  max-width: none;
}

/* Экспортированный "Gradient top.webp" — крупное пятно, смещено выше и левее.
   Позиция/масштаб рассчитаны так, чтобы яркое пятно картинки совпадало
   с исходным референсом (Background.png), а мягкие края уходили за
   пределы вьюпорта — тогда анимация не обнажит "жёсткую" границу картинки. */
/* Размер уменьшен вдвое (было width 270.4% / left -106.2% / top 10.2%).
   Отступы пересчитаны, а не поделены пополам: пик яркости картинки лежит в
   точке (0.344, 0.091) от её размера, и смещения подобраны так, чтобы он
   остался на прежнем месте — иначе пятно уехало бы вместе с масштабом. */
.bg__blob--1 {
  top: 17.2%;
  left: -59.7%;
  width: 135.2%;
  animation: float-blob-1 14s ease-in-out infinite alternate;
}

/* Экспортированный "Gradient bottom.webp" — смещено ниже и правее */
/* Нижнее пятно выведено в правый нижний угол — в полосу фона за пределами
   окна приложения. Центр свечения картинки лежит в точке (0.412, 0.543) от её
   размера (считается по яркости × альфа: края у картинки прозрачные, и без
   учёта альфы пик определяется неверно). Отсюда смещения: чтобы центр попал
   примерно в (98% ширины, 98% высоты) вьюпорта, слева нужно 53.8%, сверху 56.5%. */
.bg__blob--2 {
  top: 56.5%;
  left: 53.8%;
  width: 107%;
  animation: float-blob-2 16s ease-in-out infinite alternate;
  animation-delay: -4s; /* сбиваем фазу, чтобы движение не выглядело синхронным */
}

@keyframes float-blob-1 {
  0% {
    transform: translate(0%, 0%) scale(1);
  }
  50% {
    transform: translate(4%, 3%) scale(1.06);
  }
  100% {
    transform: translate(-3%, 5%) scale(0.96);
  }
}

@keyframes float-blob-2 {
  0% {
    transform: translate(0%, 0%) scale(1);
  }
  50% {
    transform: translate(-4%, -3%) scale(1.07);
  }
  100% {
    transform: translate(3%, -4%) scale(0.95);
  }
}

.bg__riso {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  mix-blend-mode: overlay; /* уточним у тебя точный blend mode из Figma */
  opacity: 0.6;
}

.bg__noise {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  mix-blend-mode: overlay; /* в самом SVG уже запечены opacity:0.5 + overlay, здесь дублируем для корректного блендинга со страницей */
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .bg__blob {
    animation: none;
  }
}

/* ===== Фрейм приложения =====
   Ширина в проекте всегда фиксирована (1184px, снята с Figma-фрейма
   Main → App). Отступы сверху/снизу от края вьюпорта — 24px (по запросу
   уменьшены с исходных figma-48px) — так фрейм всегда "подогнан" под
   вьюпорт и сам не двигается, а высота (и, соответственно, скролл
   внутреннего контента) подстраивается под окно браузера. */

@font-face {
  font-family: "ABC Diatype";
  src: url("../assets/fonts/ABCDiatype-Regular.woff2") format("woff2"),
       url("../assets/fonts/ABCDiatype-Regular.woff") format("woff"),
       url("../assets/fonts/ABCDiatype-Regular.otf") format("opentype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* Bold нужен только тайтлам карточек концептов на странице проекта,
   на главной ABC Diatype везде Regular — начертание просто не подхватится. */
@font-face {
  font-family: "ABC Diatype";
  src: url("../assets/fonts/ABCDiatype-Bold.woff2") format("woff2"),
       url("../assets/fonts/ABCDiatype-Bold.woff") format("woff"),
       url("../assets/fonts/ABCDiatype-Bold.otf") format("opentype");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* Inter самохостится, а не тянется с Google Fonts: прототип должен открываться
   одинаково везде, в том числе там, где чужой CDN недоступен, и не ждать
   стороннего домена перед первой отрисовкой.
   Файл один на все начертания — Google отдаёт вариативный Inter (латиница,
   48 КБ), поэтому вместо трёх статических весов один диапазон 100–900.
   unicode-range — как в исходном css2: за пределами латиницы (кириллица и др.)
   подхватится системный шрифт, но UI-текста там нет. */
@font-face {
  font-family: "Inter";
  src: url("../assets/fonts/Inter-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  --font-ui: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-display: "ABC Diatype", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
}

.app-frame {
  position: fixed;
  top: 24px;
  left: 50%;
  transform: translateX(-50%);
  width: 1184px;
  bottom: 24px;
  background: #ffffff;
  border-radius: 24px;
  border: 1px solid rgba(22, 22, 22, 0.24);
  box-shadow: 0 30px 80px rgba(22, 22, 22, 0.18);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  font-family: var(--font-ui);
}

/* ===== Навбар ===== */
.app-nav {
  flex: 0 0 46px;
  display: flex;
  align-items: center;
  height: 46px;
  padding: 0 16px;
  background: rgba(255, 255, 255, 0.6);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-bottom: 1px solid rgba(22, 22, 22, 0.06);
}

.app-nav__traffic {
  display: flex;
  align-items: center;
  gap: 9px;
}

.app-nav__dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 0.5px solid rgba(0, 0, 0, 0.12);
}

.app-nav__dot--red { background: #FF4B59; }
.app-nav__dot--yellow { background: #FFC600; }
.app-nav__dot--green { background: #00CA48; }

.app-nav__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  padding: 0;
  border: none;
  background: none;
  border-radius: 4px;
  color: #DBDBDB;
  cursor: pointer;
  transition: background 0.15s ease, box-shadow 0.15s ease;
}

/* Ховер — серая плашка, как у крестика внутри вкладки (#161616 @8%).
   Плашка рисуется тенью с растяжкой 4px, а не увеличением самой кнопки:
   размеры иконок 20×20 участвуют в раскладке навбара (все отступы сняты
   из Figma от их краёв), и менять их нельзя. Тень повторяет border-radius,
   поэтому у плашки 28×28 углы получаются 8px. */
/* Цвет плашки — тот же #F2F2F0, что у ховера строк в списке чатов.
   Именно сплошной, а не полупрозрачный: навбар сам полупрозрачный с блюром,
   и альфа поверх него давала заметно более тёмный тон, чем в чатах. */
.app-nav__icon:hover:not([disabled]) {
  background: #F2F2F0;
  box-shadow: 0 0 0 4px #F2F2F0;
}

.app-nav__sidebar {
  margin-left: 32px; /* 108 - (16 паддинг + 60 трафик-лайты) */
  color: #161616;
}

/* Домик между сайдбаром и стрелками, по 20px до соседних иконок */
.app-nav__home {
  margin-left: 20px;
  color: #161616;
}

.app-nav__history {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: 20px; /* 20px от домика */
}

/* Стрелки истории приглушены, пока идти некуда. "Назад" загорается, когда
   в истории реально есть предыдущая страница (класс вешает js/nav.js). */
.app-nav__history .app-nav__icon {
  color: rgba(22, 22, 22, 0.32);
}

.app-nav__history .app-nav__icon.is-active {
  color: #161616;
}

.app-nav__history .app-nav__icon[disabled] {
  cursor: default;
}

.app-nav__plus {
  margin-left: 20px; /* 208 - (188 конец истории) */
  color: #161616;
}

/* ===== Вкладки в навбаре =====
   Полоса сжимается флексом; когда вкладки перестают помещаться, js/nav.js
   вешает .is-overflowing и хвост уходит в прозрачность — тем же приёмом,
   что и строка шагов в карточках. */
.app-tabs {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  flex: 0 1 auto;
  margin-left: 18px; /* 206 - 188 (конец блока истории) */

  /* Полоса прокручивается по горизонтали, когда вкладок больше, чем влезает.
     Системную полосу прокрутки прячем — в навбаре высотой 46px ей не место. */
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;

  /* Растушёвка с обеих сторон, ширины считает js/nav.js по позиции прокрутки:
     слева край проявляется, когда что-то уехало, справа гаснет, когда доехали
     до конца. Тот же приём, что у строки шагов в карточках. */
  --fade-left: 0px;
  --fade-right: 0px;
  -webkit-mask-image: linear-gradient(
    to right,
    transparent 0,
    #000 var(--fade-left),
    #000 calc(100% - var(--fade-right)),
    transparent 100%
  );
  mask-image: linear-gradient(
    to right,
    transparent 0,
    #000 var(--fade-left),
    #000 calc(100% - var(--fade-right)),
    transparent 100%
  );
}

.app-tabs::-webkit-scrollbar {
  display: none;
}

.app-tabs:empty {
  margin-left: 0;
}

/* Когда вкладки есть, «+» стоит ближе — 12 вместо 20 */
.app-tabs:not(:empty) + .app-nav__plus {
  margin-left: 12px;
}

/* Вкладка, страница которой сейчас не открыта, — серая. Обводка одинаковая
   в обоих состояниях, меняется только заливка. На главной активных вкладок
   нет вообще, поэтому там серые все. */
.app-tab {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 30px;
  padding: 0 8px;
  border-radius: 8px;
  background: #F9F9F8;
  border: 1px solid #E3E3E1;
}

.app-tab.is-active {
  background: #ffffff;
}

.app-tab__state {
  flex: 0 0 auto;
}

/* Вкладка проекта, который сейчас работает: вместо паузы крутится спиннер */
.app-tab__state--spin {
  animation: spin 1.1s linear infinite;
}

.app-tab__title {
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  font-family: var(--font-display);
  font-size: 13px;
  line-height: 16px;
  color: rgba(0, 0, 0, 0.7);
  white-space: nowrap;
}

.app-tab__close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  padding: 0;
  border: none;
  background: none;
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.15s ease;
}

.app-tab__close:hover {
  background: rgba(22, 22, 22, 0.08);
}

/* ===== Скроллящаяся часть фрейма ===== */
.app-scroll {
  flex: 1 1 auto;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* ===== Тоггл Chat / Work ===== */
.toggle {
  position: relative;
  flex-shrink: 0; /* внутри всё position:absolute, без этого флекс сжимает блок до нуля */
  margin-top: 20px; /* 66 - 46 (высота навбара) */
  width: 192px;
  height: 32px;
  background: #F6F6F6;
  border-radius: 100px;
}

.toggle__item {
  position: absolute;
  z-index: 1;
  border: none;
  background: none;
  padding: 0;
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: -0.04em;
  color: #000000;
  cursor: pointer;
}

/* Оба пункта — полноразмерные боксы под пилюлю, а не голый текст: так у них
   одинаковая модель, JS может брать геометрию пилюли прямо из offsetLeft/Width,
   и заодно у "Chat" появляется нормальная область клика.
   Центры текста сохранены как в Figma: 47.5 у Chat (2 + 91/2) и 143.5 у Work. */
.toggle__item--chat {
  left: 2px;
  top: 1px;
  width: 91px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.toggle__item--work {
  left: 96px;
  top: 1px;
  width: 95px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* "Таблетка" — общий элемент, JS двигает её под активный пункт */
.toggle__pill {
  position: absolute;
  z-index: 0;
  top: 1px;
  left: 96px;
  width: 95px;
  height: 30px;
  background: #ffffff;
  border-radius: 100px;
  border: 0.5px solid rgba(22, 22, 22, 0.12);
  transition: left 0.2s ease, width 0.2s ease;
  pointer-events: none;
}

/* ===== Заголовок / подзаголовок ===== */
.hero-title {
  margin: 64px 0 0; /* 162 - (66 + 32 высота тоггла) */
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 30px;
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: #000000;
  text-align: center;
}

.hero-subtitle {
  margin: 8px 0 0; /* 207 - (162 + 37) */
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 16px;
  /* прозрачность в цвете, а не в opacity: opacity занят анимацией появления */
  color: rgba(0, 0, 0, 0.32);
  text-align: center;
}

/* ===== Поисковая строка ===== */
.search {
  position: relative;
  flex-shrink: 0; /* внутри всё position:absolute, без этого флекс сжимает блок до нуля */
  margin: 42px 0 0; /* 269 - (207 + 20) */
  width: 568px;
  height: 45px;
  background: #ffffff;
  border-radius: 100px;
  border: 1px solid rgba(22, 22, 22, 0.12);
  box-shadow: 0 4px 12px rgba(22, 22, 22, 0.04);
  cursor: text; /* строка ведёт себя как поле ввода: по клику встаёт курсор */
  transition: border-color 0.15s ease;
}

/* Ховер: обводка на ступень темнее — та же шкала 12% → 20%, что у кнопок */
.search:hover {
  border-color: rgba(22, 22, 22, 0.2);
}

/* Мигающий курсор. Стоит ровно в начале текстовой строки (тот же left, что
   у плейсхолдера) и шириной в 1px — плейсхолдер из-за него не сдвигается.
   Показывается только по клику в строку (класс .is-focused вешает js/app.js). */
.search__caret {
  position: absolute;
  left: 24px;
  top: 50%;
  width: 1px;
  height: 18px;
  transform: translateY(-50%);
  background: #161616;
  opacity: 0;
  pointer-events: none;
}

.search.is-focused .search__caret {
  animation: caret-blink 1.06s infinite; /* 1.06s — период курсора в macOS */
}

@keyframes caret-blink {
  0%,
  49.9% {
    opacity: 1;
  }
  50%,
  100% {
    opacity: 0;
  }
}

.search__placeholder {
  position: absolute;
  left: 24px;
  top: 50%;
  transform: translateY(-50%);
  font-family: var(--font-ui);
  font-weight: 400;
  font-size: 15px;
  letter-spacing: -0.02em;
  color: rgba(22, 22, 22, 0.32);
}

.search__controls {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  gap: 10px;
}

.search__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  padding: 0;
  border: none;
  background: none;
  color: #DBDBDB;
  cursor: pointer;
}

.search__voice {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: none;
  border-radius: 40px;
  background: #161616;
  cursor: pointer;
}

/* ===== Контент страницы ===== */
.page {
  position: relative;
  min-height: 100dvh;
}

/* ===== Блоки с карточками (Needs your attention / In progress / ...) =====
   Контейнер CONTENT в Figma: 600px, gap 28 между блоками. Каждый блок —
   светло-серая панель (#F9F9F8, radius 28, padding 8/16/8/8), внутри
   заголовок секции и список карточек (gap 10). Карточка по умолчанию —
   просто текст без фона; при наведении получает белую подложку (см.
   компонент Card в Figma, состояния Default/Hover) — паддинг и радиус
   одинаковые в обоих состояниях, меняется только fill. */

/* ===== Вкладки Overview / All work =====
   Из Figma (Main → App → Tags): auto-layout по горизонтали, gap 24,
   X 308 / Y 361, hug 126×16. Оба текста Inter Medium 13 с трекингом −4%;
   активный чёрный, неактивный — тот же чёрный на 30% прозрачности.
   Ширина 600 и левый отступ 16 повторяют раскладку .content: 292 + 16 = 308,
   то есть вкладки встают ровно по левому краю иконки в заголовке блока. */
.tabs {
  flex-shrink: 0;
  width: 600px;
  padding-left: 16px;
  margin-top: 47px; /* 361 − 314 (низ поисковой строки) */
  display: flex;
  align-items: center;
  gap: 24px;
}

.tabs__item {
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: 13px;
  line-height: 16px;
  letter-spacing: -0.04em;
  color: #000000;
}

/* В Figma неактивная вкладка — слой с opacity 30%. Здесь это прозрачность
   в цвете, а не opacity: последний занят анимацией появления. */
.tabs__item[aria-selected="false"] {
  color: rgba(0, 0, 0, 0.3);
}

.content {
  width: 600px;
  margin: 18px 0 64px; /* 395 − 377 (низ вкладок) */
  display: flex;
  flex-direction: column;
  gap: 28px;
}

.block {
  background: #F9F9F8;
  border-radius: 28px;
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.block__title {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 0 0 8px;
  color: #000;
}

.block__icon {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
}

.block__heading {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 16px;
  letter-spacing: -0.02em;
  color: #000;
}

.block__count {
  font-family: var(--font-display);
  font-size: 16px;
  color: rgba(22, 22, 22, 0.32);
}

.cards {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px; /* в Figma зазор "auto" (space-between без минимума); 8px — просто страховка,
               чтобы текст не прилипал к кнопке на самых длинных строках */
  padding: 12px;
  border-radius: 20px;
  background: transparent;
  transition: background 0.15s ease;
  cursor: pointer;
  min-width: 0;
}

.card:hover {
  background: #ffffff;
}

/* Тот же вид, когда внутри карточки клавиатурный фокус.
   Именно :focus-visible, а не :focus-within: после клика мышью по кнопке
   фокус остаётся на ней, и карточка "залипала" бы в ховере, пока не кликнешь мимо.
   Правила вынесены отдельными блоками — если браузер не знает :has(),
   он выбросит только их, а обычный ховер выше продолжит работать. */
.card:has(:focus-visible) {
  background: #ffffff;
}

.card__body {
  min-width: 0;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.card__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 16px;
  color: #000;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.card__desc {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-display); /* сверено в Figma: тот же ABC Diatype и тот же 16px, что и у тайтла — отличается только заливка */
  font-weight: 400;
  font-size: 16px;
  color: rgba(22, 22, 22, 0.32);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.card__meta {
  margin: 0;
  font-family: var(--font-display);
  font-size: 13px;
  color: rgba(22, 22, 22, 0.32);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* В 4-строчных карточках ("In progress": тайтл → description → степы → meta)
   отступ тайтл↔description остаётся базовым (gap 4px), а два нижних —
   на 2px больше. Селектор с ~ .card__desc бьёт только по карточкам,
   где description есть, остальные блоки не задевает. */
.card__desc ~ .card__steps,
.card__desc ~ .card__meta {
  margin-top: 2px;
}

/* ===== Пауза / продолжение у карточек "In progress" =====
   Одно состояние — класс .is-paused на карточке — переключает сразу три вещи:
   иконку в кнопке, маркер текущего шага в трекере и спиннер у описания.
   Обе иконки лежат в разметке, JS только дёргает класс. */
.btn__ico--play,
.card--live .step__dot--pause {
  display: none;
}

.card--live.is-paused .btn__ico--pause,
.card--live.is-paused .step__dot--play,
.card--live.is-paused .spinner {
  display: none;
}

.card--live.is-paused .btn__ico--play,
.card--live.is-paused .step__dot--pause {
  display: inline-block;
}

/* Спиннер у описания "In progress"-карточек — тихо крутится, пока задача идёт */
.spinner {
  flex: 0 0 auto;
  animation: spin 1.1s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* ===== Шаги (степы) внутри карточки =====
   Одна строка, не переносится; если не помещается — обрезается мягким
   градиентом (mask), а не жёстким краем. */
.card__steps {
  display: flex;
  align-items: center;
  gap: 10px;
  overflow: hidden;

  /* Растушёвка с обеих сторон. В покое левой нет, правая на месте — то есть
     ровно как было. Когда строка едет бегущей строкой (js/app.js), обе ширины
     пересчитываются по позиции прокрутки: слева край проявляется, справа
     гаснет, когда доехали до конца. */
  --fade-left: 0px;
  --fade-right: 28px;
  -webkit-mask-image: linear-gradient(
    to right,
    transparent 0,
    #000 var(--fade-left),
    #000 calc(100% - var(--fade-right)),
    transparent 100%
  );
  mask-image: linear-gradient(
    to right,
    transparent 0,
    #000 var(--fade-left),
    #000 calc(100% - var(--fade-right)),
    transparent 100%
  );
}

/* Ряд шагов у Suggestions: план целиком не начат — все шаги одного цвета (32%),
   без зачёркивания, зазоры свои (12px между шагами, 4px внутри шага) */
.card__steps--plan {
  gap: 12px;
  /* строка плана помещается целиком, поэтому мягкое затухание хвоста тут не нужно —
     иначе оно съедало бы "Est. time 4h" */
  -webkit-mask-image: none;
  mask-image: none;
}

.card__steps--plan .step {
  gap: 4px;
  color: rgba(22, 22, 22, 0.32);
}

.step {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: var(--font-display);
  font-size: 13px;
  white-space: nowrap;
  flex: 0 0 auto;
}

.step__dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: currentColor;
  flex: 0 0 auto;
}

/* Маркер текущего шага у "Needs your attention" — иконка паузы 4×5 из Figma */
.step__dot--pause {
  width: 4px;
  height: 5px;
  background: none;
  border-radius: 0;
}

/* Пустой кружок — шаг ещё не начат (карточки Suggestions).
   В Figma это эллипс 5×5 без заливки, обводка #161616 1px inside; цвет обводки
   именно полный, а не 32% как у текста, поэтому не currentColor. */
.step__dot--ring {
  width: 5px;
  height: 5px;
  background: transparent;
  border: 1px solid #161616;
  position: relative;
  top: 1px; /* в макете кружок стоит на 1px ниже оптического центра строки */
}

.step__dot--play {
  width: 0;
  height: 0;
  background: transparent;
  border-style: solid;
  border-width: 3.5px 0 3.5px 5px;
  border-color: transparent transparent transparent currentColor;
  border-radius: 0;
}

.step.is-done {
  color: rgba(22, 22, 22, 0.32);
  text-decoration: line-through;
}

.step.is-current {
  color: #161616; /* по умолчанию как is-pending — так и есть в Figma для карточек "In progress", отличает их только иконка-маркер (▷ вместо точки) */
}

.step.is-pending {
  color: #161616;
}

/* Оранжевый текущий шаг — только у карточек "Needs your attention" (сверено в Figma).
   Маркер перед ним при этом остаётся тёмным (не наследует оранжевый), сам текст — оранжевый. */
.block--attention .step.is-current {
  color: #E8A126;
}

.block--attention .step.is-current .step__dot {
  background: #161616;
}

/* Иконка паузы рисует себя сама — заливку из правила выше с неё надо снять,
   иначе тёмный прямоугольник закрашивает фон позади SVG. Идёт ниже по файлу
   специально: специфичность у селекторов одинаковая, побеждает последний. */
.block--attention .step.is-current .step__dot--pause {
  background: none;
}

/* ===== Кнопки на карточках ===== */
.btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 32px;
  border-radius: 12px;
  background: #F9F9F8;
  border: 1px solid rgba(22, 22, 22, 0.12);
  cursor: pointer;
  color: #000;
  transition: background 0.15s ease, border-color 0.15s ease;
}

/* Два уровня ховера у кнопки — сняты из Figma (Component 5, свойство State):
   Default → fill #F9F9F8 + обводка 161616 @12%
   Hover   → наведён курсор на плашку: кнопка встаёт в тон белой карточки, обводка @20%
   Hover 2 → курсор на самой кнопке: та же заливка, края темнее — обводка @32% */
.card:hover .btn {
  background: #ffffff;
  border-color: rgba(22, 22, 22, 0.2);
}

/* Специфичность выше, чем у .card:hover .btn, — иначе ховер плашки перебивал бы ховер кнопки */
.card:hover .btn:hover,
.btn:hover {
  background: #ffffff;
  border-color: rgba(22, 22, 22, 0.32);
}

/* Те же состояния для клавиатурного фокуса — отдельными правилами, см. коммент у .card */
.card:has(:focus-visible) .btn {
  background: #ffffff;
  border-color: rgba(22, 22, 22, 0.2);
}

.card:has(:focus-visible) .btn:hover {
  background: #ffffff;
  border-color: rgba(22, 22, 22, 0.32);
}

.btn--text {
  padding: 0 20px;
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: -0.04em;
}

/* Кнопки в карточках Suggestions (тех, что с пилюлями) держат общую ширину,
   чтобы правый край у «Create task» и «Connect» был единым: карточки — отдельные
   флекс-контейнеры, связать их ширины иначе нельзя. 107px — измеренная ширина
   «Create task» (Inter Medium 13 + паддинги 20px и обводка), для неё правило
   ничего не меняет и работает только как пол для более короткого «Connect».
   Селектор цепляется за наличие пилюль, а не за класс-модификатор на кнопке:
   так правка живёт целиком в CSS и не зависит от версии разметки. */
.card:has(.pills) .btn--text {
  min-width: 107px;
}

.btn--icon {
  width: 32px;
  height: 30px;
  color: #161616;
}

/* "View all" — компонент из Figma с двумя состояниями: текст #000, слой 50% → 70% на ховере
   (типографика там же: Inter Medium 13 / -4%) */
.view-all {
  align-self: center;
  margin-top: -4px;
  margin-bottom: 4px; /* правка: воздуха под текстом до нижнего края на 4px больше — и в блоке In progress, и в списке All work */
  padding: 4px 8px;
  border: none;
  background: none;
  cursor: pointer;
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: -0.04em;
  color: #000;
  opacity: 0.5;
  transition: opacity 0.15s ease;
}

.view-all:hover {
  opacity: 0.7;
}

/* ===== Источники у Suggestions (Calendar / Drive / Gmail) ===== */
/* Размеры сняты в Figma (Card 4 → пилюля): сама пилюля 30px в высоту, радиус полный,
   иконка 20×20, зазор иконка↔текст 4px, внутренние отступы 12px слева / 16px справа
   (слева меньше, потому что иконка визуально уже своего 20px-бокса). Ряд пилюль — gap 2px. */
/* Ряд пилюль есть только в карточках Suggestions, поэтому его собственные
   вертикальные margin'ы — самый узкий способ развести три строки именно там.
   К базовому gap 4px у .card__body они добавляются с обеих сторон:
   было 2px (просветы 6px), стало 4px (просветы 8px) — по правке пользователя. */
.pills {
  display: flex;
  align-items: center;
  gap: 2px;
  margin: 4px 0;
}

.pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 30px;
  padding: 0 16px 0 12px;
  border-radius: 999px;
  background: #ffffff;
  border: 1px solid rgba(22, 22, 22, 0.12);
  font-family: var(--font-display); /* в Figma тут ABC Diatype 13, а не Inter */
  font-size: 13px;
  color: #000;
}

.pill__icon {
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
}

/* ===== "Customize home" — самая нижняя строка страницы ===== */
/* Тот же компонент, что и "View all" (в Figma — "Edit btn"): иконка + текст целиком
   на 50%, при ховере 70%. Поэтому прозрачность задаём кнопке, а не тексту с иконкой по отдельности. */
.customize {
  align-self: center;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: 8px; /* к gap 28px у .content — итого 36px от последнего блока */
  padding: 6px 10px;
  border: none;
  background: none;
  cursor: pointer;
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: -0.04em;
  /* 50/70% раскладываем на цвет текста и opacity иконки — собственный opacity кнопки
     занят анимацией появления */
  color: rgba(0, 0, 0, 0.5);
  transition: color 0.15s ease;
}

.customize:hover {
  color: rgba(0, 0, 0, 0.7);
}

.customize__icon {
  flex: 0 0 auto;
  opacity: 0.5;
  transition: opacity 0.15s ease;
}

.customize:hover .customize__icon {
  opacity: 0.7;
}

/* ===== Вкладка "All work" — плоский список всех проектов =====
   Из Figma (Main → App → Tasks, node 103:3529): панель 600×411, radius 28,
   fill #F9F9F8, padding 6; внутри вертикальный auto-layout ("Cards lines")
   с gap 4. Высота панели в макете фиксированная (411), здесь — min-height:
   список может вырасти, но пустая часть панели остаётся как в макете. */
.all-work {
  width: 600px;
  min-height: 411px;
  /* .app-scroll — флекс-колонка, и заданный min-height отменяет автоминимум
     по содержимому: без flex-shrink: 0 панель сжималась бы обратно до 411,
     а строки вылезали бы за её нижний край */
  flex-shrink: 0;
  margin: 18px 0 64px; /* та же раскладка, что у .content: верх панели на Y 395 */
  padding: 6px;
  border-radius: 28px;
  background: #F9F9F8;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* "View archived" под списком. Компонент общий с "View all" в блоке In progress,
   там зазор до карточек 16px (gap 20 − 4 у самой кнопки) — повторяем его:
   у списка gap 4, поэтому добираем 12. */
.all-work .view-all {
  margin-top: 12px;
}

/* Панели вкладок сами задают display, поэтому одного [hidden] мало */
[data-panel][hidden] {
  display: none;
}

/* Строка списка. 12px паддинг + 20px строка = 44px высоты (из макета),
   радиус 20 и белая заливка на ховере — ровно как у карточек на Overview. */
.row {
  display: flex;
  align-items: center;
  padding: 12px;
  border-radius: 20px;
  background: transparent;
  transition: background 0.15s ease;
  cursor: pointer;
}

.row:hover,
.row:has(:focus-visible) {
  background: #ffffff;
}

/* Иконка состояния проекта — та же, что во вкладке навбара (пауза / спиннер /
   галочка), только мельче: в макете 5×6 при 70% прозрачности. Ширину колонки
   держим по самой узкой иконке (пауза), остальные центруются относительно неё,
   чтобы текст всех строк начинался с одного X. */
.row__state {
  flex: 0 0 5px;
  min-width: 0; /* иначе флекс раздвинет колонку под спиннер (8px) и текст поедет вправо */
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0.7;
}

/* Спиннер и галочка шире колонки (11px против 5px у паузы) и вылезают из неё
   в обе стороны — так все три иконки стоят по одной оси. Без flex: 0 0 auto
   флекс сжал бы их по ширине колонки, и круг превратился бы в овал. */
.row__state svg {
  flex: 0 0 auto;
}

.row__state .is-spin {
  animation: spin 1.1s linear infinite;
}

/* Название проекта с описанием одной строкой. Ширина фиксированная (344px из
   макета): что не поместилось — уходит в прозрачность, а не обрезается краем.
   Маска статичная: на ховере строка намеренно НЕ едет (в отличие от степов
   в карточках) — это список, бегущий текст здесь только мешал бы. */
.row__title {
  flex: 0 0 320px;
  margin-left: 8px;
  font-family: var(--font-display);
  font-size: 16px;
  line-height: 20px;
  color: #000;
  white-space: nowrap;
  overflow: hidden;
}

/* Растушёвка только у строк, которые реально не поместились (класс вешает
   js/app.js). Будь она на всех — у короткой строки, чей хвост попал в последние
   28px, бледнели бы последние буквы без всякой причины. */
.row__title.is-clipped {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent 100%);
  mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent 100%);
}

/* Текущий шаг проекта. Маркера перед текстом здесь нет (в отличие от карточек):
   состояние уже показывает иконка в начале строки, второй раз — дубль.
   Раскладка трёх колонок в 588px строки (макетная, где колонок было две,
   пересчитана под третью): 12 + иконка 5 + 8 + название 320 + 24 + статус 110
   + 12 + время 53 + 12 + «…» 20 + 12. Ширины колонок — по самому длинному
   значению (статус «Build & implement» 105px, время «35m ago» 50.5px),
   остаток отдан названию: оно единственное, что реально длиннее места. */
.row__status {
  flex: 0 0 110px;
  margin-left: 24px;
  font-family: var(--font-display);
  font-size: 13px;
  line-height: 16px;
  color: #161616;
  white-space: nowrap;
  overflow: hidden;
}

/* Оранжевый — у проектов, которые ждут решения. Как на карточках Overview */
.row--paused .row__status {
  color: #E8A126;
}

/* Время последнего обновления — вторичное, поэтому та же серая заливка, что
   у .card__meta. По левому краю, как и две колонки перед ним. */
.row__time {
  flex: 0 0 53px;
  margin-left: 12px;
  font-family: var(--font-display);
  font-size: 13px;
  line-height: 16px;
  color: rgba(22, 22, 22, 0.32);
  white-space: nowrap;
}

/* Три точки — действия над проектом. Иконка 20×20 экспортирована из Figma
   вместе со своей прозрачностью (70%), поэтому кнопка отвечает только за
   появление: 0 → 1. Прижаты к правому краю строки (12px). */
.row__more {
  margin-left: auto;
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: none;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s ease;
}

/* Как и у иконки состояния: без flex: 0 0 auto флекс сжимал бы иконку
   по ширине содержимого (20×20 превращалось в 8×20) */
.row__more svg {
  flex: 0 0 auto;
}

.row:hover .row__more,
.row__more:focus-visible {
  opacity: 1;
}

/* ===== Появление контента =====
   Всё спрятано только при .js-anim на <html> — флаг ставится инлайн-скриптом в <head>
   и только если пользователь не просил "уменьшить движение". Так страница без JS
   (и с prefers-reduced-motion) остаётся сразу видимой, без пустого экрана.
   Тайминги и задержки раздаёт js/app.js. */
/* Заголовок "печатается": символы уже занимают своё место в строке и только
   проявляются по очереди. Именно opacity, а не появление символов по одному:
   строка отцентрована, и растущая ширина дёргала бы её по горизонтали. */
.js-anim .type {
  visibility: hidden; /* до того, как JS разложит текст по символам */
}

.js-anim .type.is-ready {
  visibility: visible;
}

.js-anim .type .type__ch {
  opacity: 0;
  white-space: pre-wrap; /* пробелы внутри span-ов иначе схлопываются */
  transition: opacity 0.06s linear;
}

.js-anim .type.is-typing .type__ch {
  opacity: 1;
}

.js-anim .reveal {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity 0.52s ease,
    transform 0.64s cubic-bezier(0.22, 0.61, 0.36, 1),
    color 0.15s ease; /* color — чтобы не сломать ховер "Customize home", он тоже .reveal */
  will-change: opacity, transform;
}

/* Блоки заезжают чуть длиннее и из слегка уменьшенного состояния */
.js-anim .reveal--block {
  transform: translateY(32px) scale(0.965);
  transition:
    opacity 0.6s ease,
    transform 0.78s cubic-bezier(0.22, 0.61, 0.36, 1),
    color 0.15s ease;
}

.js-anim .reveal.is-in {
  opacity: 1;
  transform: none;
}

/* После появления снимаем will-change, чтобы не держать слои под каждый блок */
.js-anim .reveal.is-done {
  will-change: auto;
}
