/* ============================================================================
   chat.css - виджет чата с Верой. Редакция 6 канона.

   МАТЕРИАЛ. Виджет собран ступенью 2 (литое стекло): вся оптика нарисована
   заливкой, СВОЕГО backdrop-filter у него нет ни на одном элементе. Число
   размывающих слоёв на странице обязано остаться 13 - это приёмочный порог
   канона, и виджет его не двигает. Под панелью на молочном фоне размывать
   нечего, поэтому честный фильтр и грамотная заливка тут неразличимы, а
   фильтр на постоянно висящем поверх страницы объекте стоит дорого.

   РАДИУСЫ. Только три канонических: 14 / 24 / 30. Круглой кнопки-пузыря нет -
   пилюля по образцу телефона в шапке (999px там уже узаконен для одного
   объекта, и виджет присоединяется к нему, а не заводит четвёртый радиус).

   КАСКАД. Мобильный блок стоит В КОНЦЕ файла осознанно: при равной
   специфичности побеждает последнее правило, медиазапрос специфичность не
   повышает (грабля 53ф - схлопнутый в ноль контейнер именно из-за этого).
   ============================================================================ */

/* ---------- кнопка вызова ---------- */
.td-bubble{
  position:fixed;right:var(--pad-x);z-index:44;
  bottom:calc(20px + env(safe-area-inset-bottom,0px));
  display:inline-flex;align-items:center;gap:9px;
  min-height:48px;padding:0 18px 0 15px;border:0;border-radius:999px;
  font:400 var(--fs-cap)/1.2 "IBM Plex Sans",system-ui,sans-serif;
  color:var(--ink-1);cursor:pointer;
  background:
    linear-gradient(168deg,rgba(255,255,255,.72),rgba(255,255,255,.10) 52%,rgba(246,244,239,.42)),
    var(--cast-base);
  box-shadow:
    inset 0 2px 0 rgba(255,255,255,1),
    inset 0 0 0 1px rgba(28,34,64,.085),
    inset 0 -2px 0 rgba(28,34,64,.13),
    var(--cast-shadow);
  transition:box-shadow var(--t-state) var(--ease),
             opacity var(--t-state) var(--ease),
             transform var(--t-state) var(--ease),
             bottom var(--t-state) var(--ease);
}
/* Липкая строка действия появляется динамически и знает свою настоящую высоту
   только показанной (её скрипт пишет --bar-h). Кнопка считается от переменной,
   а не от зашитого числа - иначе на устройстве с другим кеглем они наедут. */
body.has-bar .td-bubble{
  bottom:calc(var(--bar-h) + env(safe-area-inset-bottom,0px) + 14px);
}
.td-bubble:active{box-shadow:
  inset 0 1px 0 rgba(255,255,255,.92),
  inset 0 0 0 1px rgba(28,34,64,.07),
  inset 0 -1px 0 rgba(28,34,64,.12),
  0 8px 20px -18px rgba(30,36,72,.22)}
@media (hover:hover) and (pointer:fine){
  .td-bubble:hover{box-shadow:
    inset 0 2px 0 rgba(255,255,255,1),
    inset 0 0 0 1px rgba(43,60,196,.20),
    inset 0 -2px 0 rgba(28,34,64,.12),
    var(--cast-shadow-lift)}
}
.td-bubble--hidden{opacity:0;pointer-events:none;transform:scale(.94)}

/* Точка присутствия. Дышит медленно и одна на весь виджет: канон запрещает
   мигание и любой ритм, подгоняющий человека. */
.td-dot{
  width:8px;height:8px;border-radius:50%;background:var(--accent);flex:0 0 auto;
  box-shadow:0 0 0 3px rgba(43,60,196,.12);
  animation:tdBreath 3.4s var(--ease) infinite;
}
@keyframes tdBreath{
  0%,100%{opacity:.55;box-shadow:0 0 0 3px rgba(43,60,196,.10)}
  50%{opacity:1;box-shadow:0 0 0 5px rgba(43,60,196,.14)}
}

/* ---------- панель ---------- */
/* ⚠️ Это правило несущее, а не косметика. Атрибут hidden прячет элемент правилом
   display:none из стилей браузера, а оно проигрывает ЛЮБОМУ авторскому display.
   Без явной строки ниже закрытая панель остаётся в раскладке (просто прозрачной)
   и на мобильной ширине, где она во весь экран, ПЕРЕХВАТЫВАЕТ все касания:
   кнопку чата физически невозможно нажать. Поймано замером при приёмке. */
.td-panel[hidden]{display:none}

.td-panel{
  position:fixed;right:var(--pad-x);bottom:20px;z-index:50;
  width:392px;max-width:calc(100vw - var(--pad-x) * 2);
  height:min(640px,74vh);
  display:flex;flex-direction:column;overflow:hidden;
  border-radius:var(--r-media);
  background:
    linear-gradient(168deg,rgba(255,255,255,.72),rgba(255,255,255,.10) 52%,rgba(246,244,239,.42)),
    var(--cast-base);
  box-shadow:
    inset 0 2px 0 rgba(255,255,255,1),
    inset 1px 0 0 rgba(255,251,244,.9),
    inset -1px 0 0 rgba(232,236,250,.9),
    inset 0 0 0 1px rgba(28,34,64,.085),
    var(--cast-shadow-lift);
  opacity:0;transform:translateY(10px);
  transition:opacity 240ms var(--ease-glass),transform 240ms var(--ease-glass);
}
.td-panel--in{opacity:1;transform:translateY(0)}

/* шапка */
.td-head{
  flex:0 0 auto;display:flex;align-items:center;gap:10px;
  padding:14px 12px 12px 18px;
  box-shadow:inset 0 -1px 0 var(--line);
}
.td-head__name{
  font:600 17px/1.2 "Spectral",Georgia,serif;color:var(--ink-1);
}
.td-head__role{
  font:400 13px/1.3 "IBM Plex Mono",monospace;color:var(--ink-3);
  letter-spacing:.02em;margin-top:2px;display:block;
}
.td-head__txt{flex:1 1 auto;min-width:0}
.td-x{
  flex:0 0 auto;width:44px;height:44px;margin:-6px -6px -6px 0;
  display:inline-flex;align-items:center;justify-content:center;
  border:0;background:transparent;color:var(--ink-2);cursor:pointer;border-radius:var(--r-ui);
  transition:background-color var(--t-state) var(--ease),color var(--t-state) var(--ease);
}
.td-x:active{background:rgba(28,34,64,.06);color:var(--ink-1)}
@media (hover:hover) and (pointer:fine){
  .td-x:hover{background:rgba(28,34,64,.05);color:var(--ink-1)}
}

/* лента */
.td-log{
  flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  padding:16px 18px 8px;display:flex;flex-direction:column;gap:12px;
  -webkit-overflow-scrolling:touch;
}
.td-msg{max-width:88%;padding:11px 14px;border-radius:var(--r-ui);font-size:var(--fs-note);line-height:1.55}
.td-msg p{margin:0 0 8px}
.td-msg p:last-child{margin:0}
.td-msg ul{margin:6px 0 2px;padding-left:19px}
.td-msg li{margin:3px 0}
.td-msg b{font-weight:500;color:var(--ink-1)}
/* ответ помощника - вкладыш: живёт внутри панели и своего объёма не имеет */
.td-msg--bot{
  align-self:flex-start;color:var(--ink-1);
  background:rgba(255,255,255,.62);
  box-shadow:inset 0 0 0 1px rgba(28,34,64,.05), inset 0 1px 0 rgba(255,255,255,.72);
}
/* реплика посетителя - тот же вкладыш, но в цвете пасты */
.td-msg--me{
  align-self:flex-end;color:var(--ink-1);
  background:rgba(43,60,196,.09);
  box-shadow:inset 0 0 0 1px rgba(43,60,196,.16);
}
.td-msg a{color:var(--accent);text-underline-offset:3px}

/* Подсказки-темы: показываются один раз, до первого вопроса.
   ⚠️ Материал у них НЕ вкладыш, хотя по вложенности он бы напрашивался. Первая
   версия была вкладышем - тем же светлым прямоугольником, что и реплика помощника,
   и заказчик на кадре с iPhone прочитал три кнопки как продолжение сообщения.
   Кнопка обязана отличаться от реплики РОДОМ, а не оттенком, поэтому здесь взят
   язык вторичной кнопки сайта: акцентный контур, акцентный текст, стрелка. */
.td-hints{display:flex;flex-direction:column;align-items:stretch;gap:8px;margin-top:4px}
.td-hints__cap{
  margin:0 0 2px 2px;
  font:400 13px/1.3 "IBM Plex Mono",monospace;color:var(--ink-3);letter-spacing:.04em;
}
.td-hint{
  width:100%;display:flex;align-items:center;justify-content:space-between;gap:10px;
  text-align:left;cursor:pointer;min-height:44px;
  padding:10px 12px 10px 14px;border:0;border-radius:var(--r-ui);
  font:400 var(--fs-cap)/1.35 "IBM Plex Sans",system-ui,sans-serif;
  color:var(--accent);background:#fff;
  box-shadow:inset 0 0 0 1px var(--accent-line), 0 1px 2px rgba(30,36,72,.05);
  transition:box-shadow var(--t-state) var(--ease),background-color var(--t-state) var(--ease);
}
.td-hint svg{flex:0 0 auto;opacity:.7}
.td-hint:active{background:var(--accent-wash);box-shadow:inset 0 0 0 1px var(--accent)}
@media (hover:hover) and (pointer:fine){
  .td-hint:hover{background:var(--accent-wash);box-shadow:inset 0 0 0 1px var(--accent), 0 4px 10px -6px rgba(43,60,196,.35)}
}

/* индикатор набора */
.td-typing{display:flex;gap:5px;align-items:center;min-height:22px}
.td-typing i{
  width:6px;height:6px;border-radius:50%;background:var(--pencil);display:inline-block;
  animation:tdWait 1.3s var(--ease) infinite;
}
.td-typing i:nth-child(2){animation-delay:.18s}
.td-typing i:nth-child(3){animation-delay:.36s}
@keyframes tdWait{0%,70%,100%{opacity:.28}35%{opacity:.85}}

/* каретка на дописываемом ответе */
.td-stream p:last-child::after{
  content:"";display:inline-block;width:2px;height:1em;margin-left:2px;
  background:var(--accent);vertical-align:-2px;
  animation:tdCaret 1s steps(1) infinite;
}
@keyframes tdCaret{0%,50%{opacity:1}51%,100%{opacity:0}}

/* поле ввода */
.td-form{
  flex:0 0 auto;display:flex;align-items:flex-end;gap:8px;
  padding:10px 12px 10px 14px;
  box-shadow:inset 0 1px 0 var(--line);
}
.td-form textarea{
  flex:1 1 auto;min-width:0;resize:none;max-height:120px;
  padding:11px 13px;border:0;border-radius:var(--r-ui);
  background:rgba(255,255,255,.62);color:var(--ink-1);
  box-shadow:inset 0 0 0 1px rgba(28,34,64,.07);
  font-family:"IBM Plex Sans",system-ui,sans-serif;line-height:1.45;
  /* ⚠️ 16px ОБЯЗАТЕЛЬНЫ и не уменьшаются на мобильных: iOS Safari сам зумит
     страницу при фокусе на поле с меньшим кеглем, и весь макет уезжает вбок -
     кнопка отправки уходит за край экрана (грабля 53х). Уменьшать только
     медиазапросом от 701px, то есть на десктопе. */
  font-size:16px;
  transition:box-shadow var(--t-state) var(--ease),background-color var(--t-state) var(--ease);
}
.td-form textarea:focus{
  outline:none;background:rgba(255,255,255,.82);
  box-shadow:inset 0 0 0 1px rgba(43,60,196,.34);
}
.td-form textarea::placeholder{color:var(--ink-3)}
.td-send{
  flex:0 0 auto;width:44px;height:44px;border:0;border-radius:var(--r-ui);cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--accent-grad);color:#fff;
  box-shadow:0 8px 18px -12px rgba(43,60,196,.55), inset 0 1px 0 rgba(255,255,255,.28);
  transition:box-shadow var(--t-state) var(--ease),opacity var(--t-state) var(--ease);
}
.td-send:active{box-shadow:0 5px 12px -10px rgba(43,60,196,.5)}
.td-busy .td-send{opacity:.45;pointer-events:none}
.td-busy .td-form textarea{opacity:.7}

/* подпись */
.td-foot{
  flex:0 0 auto;margin:0;padding:0 18px 12px;
  font:400 13px/1.4 "IBM Plex Sans",system-ui,sans-serif;color:var(--ink-3);
}
.td-foot a{color:var(--ink-2)}

/* ---------- деградации ---------- */
@media (prefers-reduced-motion:reduce){
  .td-panel,.td-bubble{transition:none}
  .td-dot,.td-typing i,.td-stream p:last-child::after{animation:none}
  .td-panel{opacity:1;transform:none}
}
@media (prefers-reduced-transparency:reduce){
  .td-panel,.td-bubble{background:var(--surface)}
  .td-msg--bot,.td-form textarea{background:#fff}
}
@media print{
  .td-bubble,.td-panel{display:none}
}

/* ---------- десктоп ---------- */
@media (min-width:701px){
  /* На десктопе автозума нет, и 16px в поле выглядит крупновато рядом с лентой */
  .td-form textarea{font-size:15px}
}
@media (min-width:1024px){
  /* Липкая строка действия здесь выключена, значит и подъём кнопки не нужен */
  body.has-bar .td-bubble{bottom:calc(20px + env(safe-area-inset-bottom,0px))}
}

/* ---------- мобильный слой (строго последним, см. шапку файла) ----------
   Панель разворачивается на весь экран и садится на ФАКТИЧЕСКУЮ видимую
   область. Переменные --td-vh и --td-vtop пишет скрипт по visualViewport:
   при открытой клавиатуре видимая область сжимается, а 100dvh остаётся
   полным, и без синхронизации низ панели с полем ввода уезжает под
   клавиатуру (грабля 53ц). 100dvh оставлен только запасным значением. */
@media (max-width:700px){
  .td-panel{
    left:0;right:0;bottom:auto;
    top:var(--td-vtop,0px);
    width:auto;max-width:none;
    height:var(--td-vh,100dvh);
    border-radius:0;
    transform:translateY(14px);
  }
  .td-panel--in{transform:translateY(0)}
  .td-head{padding-top:calc(14px + env(safe-area-inset-top,0px))}
  .td-form{padding-bottom:calc(10px + env(safe-area-inset-bottom,0px))}
  .td-foot{padding-bottom:calc(12px + env(safe-area-inset-bottom,0px))}
  /* При открытой клавиатуре место отдаём ленте: подпись уже прочитана */
  .td-panel.td-kbd .td-foot{display:none}
  .td-panel.td-kbd .td-form{padding-bottom:10px}
  .td-msg{max-width:92%}
}
