/* ============================================================
   assistant.css — ассистент в углу экрана: кружок, шторка на треть
   экрана, тонкая полоска над таббаром. Всё на токенах peach.css
   (--p-*), поэтому крем и мята подхватываются сами; отдельно
   расписана только тёмная «пх» — там поверхности заданы светлыми
   константами.

   Слои: таббар 50, оверлеи приложения 60, ассистент 90, вход 200.
   Выше шторок специально: открыв покупки, ассистент обязан
   остаться видимым поверх них.
   ============================================================ */

/* Стекло собрано в токены: тем четыре, и на чёрном полупрозрачное
   ведёт себя не так, как на персиковом. Меняется тема — меняются
   только эти цифры, правила ниже одни на всех.

     --as-surface   поверхность шторки триплетом RGB. Это тот же цвет,
                    что --p-card-solid, но нам нужна альфа, а из hex её
                    не достать.
     --as-glass     сколько поверхности остаётся под композером;
                    остальное отдано размытому фону приложения.
     --as-blur      радиус размытия под композером и полоской.
     --as-feather   полоса растворения: на ней плотный фон лога
                    переходит в стекло. Ей же равен нижний отступ лога,
                    поэтому в самом низу последняя строка стоит ровно
                    НАД стеклом и остаётся резкой.
     --as-comp-h    высота стекла: 9 сверху + 40 кнопки + 10 снизу
                    + полоса home-indicator.
     --as-ctl       заливка поля и микрофона поверх стекла. */
.as-root {
  position: fixed;
  inset: 0;
  z-index: 90;
  pointer-events: none;                    /* слой прозрачен для пальца */
  font-family: var(--p-sans);

  --as-surface: 255, 246, 238;             /* #fff6ee — персик */
  --as-glass: 0.52;
  --as-blur: 18px;
  --as-feather: 16px;
  --as-comp-h: calc(59px + var(--sa-bottom, 0px));
  --as-ctl: rgba(255, 255, 255, 0.5);
  --as-ctl-border: rgba(42, 31, 26, 0.13);
}
body[data-theme="cream"] .as-root { --as-surface: 255, 253, 248; }
body[data-theme="mint"]  .as-root { --as-surface: 255, 255, 255; }
.as-root > * { pointer-events: auto; }

/* ============================================================
   КРУЖОК. Позиция ровно как у .fab (right: 50% − 188px, на узких
   22px) — по правому краю карточек, а не стекла. Слот FAB'а не
   занимаем: появится .fab — кружок сам поднимется над ним.
   ============================================================ */
.as-fab {
  position: fixed;
  right: calc(50% - 188px);
  bottom: calc(92px + var(--sa-bottom));
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--p-shoot);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 12px 26px -8px rgba(42, 31, 26, 0.45),
              0 1px 0 rgba(255, 255, 255, 0.35) inset;
  transition: transform 0.2s cubic-bezier(.22,.61,.36,1), opacity 0.18s ease;
}
.as-fab:active { transform: scale(0.86); }
.as-fab__ring {
  position: absolute;
  inset: -7px;
  border-radius: 50%;
  border: 2px solid var(--p-shoot);
  opacity: 0;
}
/* пока ассистент думает — кружок дышит */
.as-root.is-busy .as-fab__ring { animation: as-pulse 1.5s ease-out infinite; }
@keyframes as-pulse {
  0%   { opacity: 0.55; transform: scale(0.9); }
  70%  { opacity: 0;    transform: scale(1.18); }
  100% { opacity: 0;    transform: scale(1.18); }
}

/* кружок прячется, когда открыта шторка ассистента, свёрнута
   полоска или поверх лежит любой оверлей приложения */
.as-root.is-open .as-fab,
.as-root.is-strip.is-collapsed .as-fab,
body:has(.app-overlay:not([hidden])) .as-fab {
  opacity: 0;
  transform: scale(0.6);
  pointer-events: none;
}
@media (max-width: 420px) {
  .as-fab { right: 22px; }
}
/* FAB приложения занимает 92…144 — уходим выше */
body:has(.fab) .as-fab   { bottom: calc(156px + var(--sa-bottom)); }
body:has(.fab) .as-strip { bottom: calc(150px + var(--sa-bottom)); }

/* Затемнение лёгкое: приложение за шторкой должно оставаться
   читаемым — это отличие от чата во весь экран. */
.as-scrim {
  position: fixed;
  inset: 0;
  background: rgba(42, 31, 26, 0.13);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.24s ease;
}
.as-root.is-open:not(.is-collapsed) .as-scrim { opacity: 1; pointer-events: auto; }

/* ============================================================
   ШТОРКА — треть экрана снизу
   bottom привязан к --kb-shift: main.js держит там высоту
   iOS-клавиатуры, и поле ввода не уезжает под неё.
   ============================================================ */
.as-panel {
  position: fixed;
  left: 0; right: 0;
  bottom: var(--kb-shift, 0px);
  margin: 0 auto;
  width: min(100%, 420px);
  height: clamp(238px, 36dvh, 380px);
  display: flex;
  flex-direction: column;
  padding: 0 16px calc(10px + var(--sa-bottom));
  /* Фон плотный там, где текст, и сходит на нет там, где стекло.
     Полосой --as-feather, а не встык: резкая граница читалась бы
     как линия обреза. Верхняя часть остаётся АБСОЛЮТНО непрозрачной —
     переписка не должна ничего терять в контрасте. */
  background:
    linear-gradient(to top,
      rgba(var(--as-surface), 0) 0,
      rgba(var(--as-surface), 0) var(--as-comp-h),
      rgba(var(--as-surface), 1) calc(var(--as-comp-h) + var(--as-feather)),
      rgba(var(--as-surface), 1) 100%);
  border: 1px solid var(--p-card-border);
  border-bottom: none;
  border-radius: var(--p-r-xl) var(--p-r-xl) 0 0;
  box-shadow: 0 -18px 44px -16px rgba(42, 31, 26, 0.3);
  transform: translateY(105%);
  transition: transform 0.34s cubic-bezier(.22,.61,.36,1);
  pointer-events: none;
}
.as-root.is-open .as-panel { transform: none; pointer-events: auto; }
.as-root.is-collapsed .as-panel { transform: translateY(105%); pointer-events: none; }

.as-panel__grip {
  width: 38px;
  height: 4px;
  margin: 8px auto 2px;
  border-radius: 999px;
  background: var(--p-divider);
  flex: none;
  touch-action: none;
  cursor: grab;
}
.as-panel__head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 4px 0 8px;
  flex: none;
}
.as-panel__title {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.as-panel__sub {
  flex: 1;
  min-width: 0;
  font-family: var(--p-serif);
  font-style: italic;
  font-size: 13px;
  color: var(--p-ink-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.as-icon-btn {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--p-bg-flat);
  color: var(--p-ink-2);
  font-size: 15px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  align-self: center;
  transition: transform 0.14s ease;
}
.as-icon-btn:active { transform: scale(0.86); }

/* ЛОГ — единственный прокручиваемый блок ассистента. contain
   обязателен: документ зафиксирован, и без него отскок списка
   утаскивал бы за собой всю страницу.

   Края растворяем маской, а не накладкой поверх: накладка с фоном
   закрыла бы текст, маска именно уводит его в ноль на подходе к краю.
   Маска считается от рамки блока, а не от содержимого, поэтому при
   прокрутке она стоит на месте — тает текст, а не она.

   Отступы равны длинам растворения (сверху 14, снизу 18) — на них
   при полной прокрутке и стоит крайняя строка, целиком за пределами
   градиента. То есть в покое НИ ОДНА строка не приглушена. */
.as-log {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px 2px 18px;
  -webkit-mask-image: linear-gradient(to bottom,
    rgba(0, 0, 0, 0) 0, #000 14px,
    #000 calc(100% - 18px), rgba(0, 0, 0, 0) 100%);
          mask-image: linear-gradient(to bottom,
    rgba(0, 0, 0, 0) 0, #000 14px,
    #000 calc(100% - 18px), rgba(0, 0, 0, 0) 100%);
}
.as-hint {
  margin: 4px 2px;
  font-family: var(--p-serif);
  font-style: italic;
  font-size: 14.5px;
  line-height: 1.4;
  color: var(--p-ink-2);
}
.as-msg {
  max-width: 92%;
  font-size: 14.5px;
  line-height: 1.45;
  white-space: pre-wrap;
  word-break: break-word;
  animation: as-in 0.22s cubic-bezier(.22,.61,.36,1);
}
.as-msg--me {
  align-self: flex-end;
  max-width: 84%;
  background: var(--p-ink);
  color: var(--p-ink-inv);
  padding: 8px 13px;
  border-radius: 16px 16px 5px 16px;
  font-size: 14px;
}
.as-msg--bot { align-self: flex-start; color: var(--p-ink); }

/* шаг: «переношу задачу» → «перенесла зал на четверг» */
.as-step {
  align-self: flex-start;
  max-width: 100%;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 12px 5px 10px;
  border-radius: 999px;
  background: var(--p-bg-flat);
  border: 1px solid var(--p-divider);
  font-size: 12.5px;
  color: var(--p-ink-2);
  animation: as-in 0.22s cubic-bezier(.22,.61,.36,1);
}
.as-step__label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.as-step__dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--p-ink-3);
  flex: none;
}
.as-step.is-run  .as-step__dot { background: var(--p-shoot); animation: as-blink 1s ease-in-out infinite; }
.as-step.is-ok   .as-step__dot { background: var(--p-rest); }
.as-step.is-fail .as-step__dot { background: var(--p-custom); }
.as-step.is-fail { color: var(--p-ink); }

@keyframes as-in    { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes as-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }

/* ============================================================
   СТРОКА ВВОДА — стекло. Под ней приложение видно размытым:
   разделительной линии нет, вместо неё плавный переход.
   Поля margin отрицательные, чтобы стекло дошло до самых краёв
   шторки и до низа под home-indicator, — иначе по бокам осталось
   бы 16px резкого фона, а под кнопками резкая полоса.
   ============================================================ */
.as-composer {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 -16px calc(-10px - var(--sa-bottom, 0px));
  padding: 9px 16px calc(10px + var(--sa-bottom, 0px));
  flex: none;
}
/* Само размытие — отдельным слоем, а не фоном композера: маску можно
   повесить только на слой, на композере она срезала бы и поле, и
   кнопки. Слой поднят на --as-feather вверх, в нижний отступ лога, и
   там же проявляется маской — ровно на полосе, где фон шторки сходит
   на нет.

   Про цену. Размывается ~420×110 — полоса, а не пол-экрана, и почти
   вся она стоит над неподвижным приложением. Прокрутка лога задевает
   только верхние --as-feather пикселей. На всю шторку размытие
   вешать нельзя: она большая, и под ней всё время что-то меняется. */
.as-composer::before {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  top: calc(-1 * var(--as-feather));
  background: rgba(var(--as-surface), var(--as-glass));
  -webkit-backdrop-filter: blur(var(--as-blur)) saturate(1.6);
          backdrop-filter: blur(var(--as-blur)) saturate(1.6);
  -webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0, #000 var(--as-feather));
          mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0, #000 var(--as-feather));
  pointer-events: none;
}
/* position нужен всем троим: ::before — позиционированный потомок и
   без него накрыл бы обычное поле ввода. */
.as-input {
  position: relative;
  flex: 1;
  min-width: 0;
  height: 40px;
  padding: 0 15px;
  border-radius: 999px;
  border: 1px solid var(--as-ctl-border);
  background: var(--as-ctl);
  color: var(--p-ink);
  outline: none;
  transition: border-color 0.15s ease, background 0.15s ease;
}
/* печатают — поле уплотняем: буквы важнее прозрачности */
.as-input:focus {
  border-color: var(--p-shoot);
  background: rgba(var(--as-surface), 0.88);
}
.as-mic, .as-send {
  width: 40px; height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  position: relative;
  transition: transform 0.14s ease, opacity 0.15s ease;
}
.as-mic {
  background: var(--as-ctl);
  border: 1px solid var(--as-ctl-border);
  color: var(--p-ink-2);
}
/* голос живой с фазы 4 — вид «идёт запись» в assistant-voice.css */
/* Отправка чуть прозрачнее, но остаётся главной кнопкой. Две строки
   фона намеренно: движки без color-mix берут первую, сплошную. */
.as-send {
  background: var(--p-shoot);
  background: color-mix(in srgb, var(--p-shoot) 88%, transparent);
  color: #fff;
  box-shadow: 0 6px 14px -6px rgba(42, 31, 26, 0.5);
}
.as-send:active, .as-mic:not([disabled]):active { transform: scale(0.86); }

/* ============================================================
   ПОЛОСКА — во что схлопывается шторка, когда что-то поменялось.
   Стоит над таббаром, приложение под ней целиком доступно.
   ============================================================ */
.as-strip {
  position: fixed;
  left: 0; right: 0;
  bottom: calc(86px + var(--sa-bottom));
  margin: 0 auto;
  width: min(calc(100% - 32px), 388px);
  height: 42px;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 0 12px 0 14px;
  border-radius: 999px;
  /* Полоска той же породы, что композер, но плотнее: она висит над
     произвольным содержимым экрана, и строка в ней обязана читаться
     всегда. 0.84 — стекло видно, контраст практически не тронут. */
  background: rgba(var(--as-surface), 0.84);
  -webkit-backdrop-filter: blur(16px) saturate(1.5);
          backdrop-filter: blur(16px) saturate(1.5);
  border: 1px solid var(--p-card-border);
  box-shadow: var(--p-sh-float);
  text-align: left;
  opacity: 0;
  transform: translateY(14px) scale(0.96);
  pointer-events: none;
  transition: opacity 0.26s ease, transform 0.26s cubic-bezier(.22,.61,.36,1);
}
.as-root.is-strip.is-collapsed .as-strip {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}
.as-strip:active { transform: scale(0.975); }
.as-strip__dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--p-shoot);
  flex: none;
}
.as-root.is-busy .as-strip__dot { animation: as-blink 1s ease-in-out infinite; }
.as-strip__text {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  color: var(--p-ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.as-strip__more {
  flex: none;
  font-size: 11px;
  font-weight: 600;
  color: var(--p-shoot);
  letter-spacing: 0.01em;
}

/* ============================================================
   ПОДСВЕТКА — «карточка мигнула, значит изменилась».
   Кольцо цветом акцента: читается на всех четырёх темах,
   ничего не сдвигает и не меняет размеры соседей.
   ============================================================ */
.as-flash { animation: as-flash 1.6s cubic-bezier(.22,.61,.36,1); }
@keyframes as-flash {
  0%   { box-shadow: 0 0 0 0 var(--p-shoot); }
  12%  { box-shadow: 0 0 0 3px var(--p-shoot); transform: scale(1.015); }
  55%  { box-shadow: 0 0 0 3px var(--p-shoot); transform: none; }
  100% { box-shadow: 0 0 0 0 rgba(0, 0, 0, 0); }
}

/* ============================================================
   ТЕМА «ПХ» — в peach.css поверхности светлые константами
   ============================================================ */
/* Стекло на чёрном — другая история: белого в подложке нет, поэтому
   поверхность плотнее (иначе под композером сквозит таббар), а
   заливка кнопок наоборот светлая и очень слабая — тёмное на тёмном
   не видно вовсе. */
body[data-theme="ph"] .as-root {
  --as-surface: 26, 26, 26;                /* #1a1a1a */
  --as-glass: 0.6;
  --as-ctl: rgba(255, 255, 255, 0.09);
  --as-ctl-border: rgba(255, 255, 255, 0.15);
}
body[data-theme="ph"] .as-panel,
body[data-theme="ph"] .as-strip {
  border-color: #2a2a2a;
  color: #fff;
}
body[data-theme="ph"] .as-fab,
body[data-theme="ph"] .as-send { background: #ff9000; color: #000; }
/* здесь свой color-mix: --p-shoot в «пх» перебит инлайновым акцентом
   из настроек, поэтому жёлтый задан константой, как и выше */
body[data-theme="ph"] .as-send { background: color-mix(in srgb, #ff9000 88%, transparent); }
body[data-theme="ph"] .as-fab__ring { border-color: #ff9000; }
body[data-theme="ph"] .as-icon-btn,
body[data-theme="ph"] .as-step { background: #232323; border-color: #2a2a2a; color: #fff; }
body[data-theme="ph"] .as-input,
body[data-theme="ph"] .as-mic { color: #fff; }
body[data-theme="ph"] .as-input::placeholder { color: #9a9a9a; }
body[data-theme="ph"] .as-msg--me { background: #2a2a2a; color: #fff; }
body[data-theme="ph"] .as-step.is-run .as-step__dot,
body[data-theme="ph"] .as-strip__dot { background: #ff9000; }
body[data-theme="ph"] .as-strip__more { color: #ff9000; }
body[data-theme="ph"] .as-scrim { background: rgba(0, 0, 0, 0.45); }
body[data-theme="ph"] .as-flash {
  animation-name: as-flash-ph;
}
@keyframes as-flash-ph {
  0%   { box-shadow: 0 0 0 0 #ff9000; }
  12%  { box-shadow: 0 0 0 3px #ff9000; transform: scale(1.015); }
  55%  { box-shadow: 0 0 0 3px #ff9000; transform: none; }
  100% { box-shadow: 0 0 0 0 rgba(0, 0, 0, 0); }
}

/* ============================================================
   БЕЗ РАЗМЫТИЯ. Движок, который backdrop-filter не умеет, показал бы
   резкое приложение прямо под кнопками. Тогда прозрачность убираем —
   читаемость дороже стекла. Блок стоит последним намеренно: он бьёт
   значения тем той же специфичностью, но порядком.
   ============================================================ */
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .as-root,
  body[data-theme] .as-root { --as-glass: 0.94; }
  .as-strip { background: rgba(var(--as-surface), 0.97); }
}

@media (prefers-reduced-motion: reduce) {
  .as-panel, .as-strip, .as-fab { transition-duration: 0.01ms; }
  .as-flash, .as-msg, .as-step, .as-fab__ring, .as-strip__dot { animation: none; }
}
