/* Палитра и шрифты как на demo.scifinews.ru: кремовый фон, почти чёрный
   текст, заголовки Unbounded, текст Golos Text. Акцент — терракот, но
   притемнённый: светлый #E08A5B на кремовом фоне не даёт контраста. */
@font-face { font-family: "Unbounded"; font-style: normal; font-display: swap;
  font-weight: 200 900;
  src: url(/static/fonts/unbounded-cyrillic-wght-normal-C627f1f8.woff2) format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; }
@font-face { font-family: "Unbounded"; font-style: normal; font-display: swap;
  font-weight: 200 900;
  src: url(/static/fonts/unbounded-latin-wght-normal-D5afBTBx.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+2122; }
@font-face { font-family: "Golos Text"; font-style: normal; font-display: swap;
  font-weight: 400 700;
  src: url(/static/fonts/golos-text-cyrillic-wght-normal-mKek_fSS.woff2) format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; }
@font-face { font-family: "Golos Text"; font-style: normal; font-display: swap;
  font-weight: 400 700;
  src: url(/static/fonts/golos-text-latin-wght-normal-BS5oQT7X.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+2122; }

:root {
  --bg: #EDE7DC;          /* кремовый фон демо-сайта */
  --surface: #F7F3EB;     /* карточки и панели — чуть светлее фона */
  --ink: #14181A;         /* основной текст */
  --muted: #6B6357;       /* подписи */
  --accent: #B4551F;      /* терракот, притемнённый для контраста на светлом */
  --accent-soft: #E08A5B; /* прежний светлый — для заливок и кнопок */
  --line: #DDD4C4;        /* границы */
}

* { box-sizing: border-box; margin: 0; }
body { font-family: "Golos Text", -apple-system, "Segoe UI", sans-serif;
       background: var(--bg); color: var(--ink); line-height: 1.6; }
h1, h2, h3, .card-cta { font-family: "Unbounded", "Segoe UI", sans-serif;
                        font-weight: 600; line-height: 1.2; }
a { color: inherit; text-decoration: none; }

.hero { text-align: center; padding: 40px 16px 24px; max-width: 640px; margin: 0 auto; }
.hero h1 { font-size: clamp(1.6rem, 4vw, 2.4rem); margin-bottom: 14px; }
.hero p { color: var(--muted); }

/* Карточки крупные: мимика в ролике должна читаться, а не угадываться.
   Пропорция кадра равна пропорции исходников — портреты 800x800 и ролики
   512x512 квадратные. При 3/4 срезалось по 12% сверху и снизу, и у половины
   персонажей кадр обрезал лоб. Появятся вертикальные ролики — меняется
   здесь и в .persona-media одновременно. */
.cards { display: grid; gap: 20px; padding: 16px; max-width: 1200px; margin: 0 auto;
         grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); }
.card-media { position: relative; aspect-ratio: 1 / 1; overflow: hidden; }
.card-media video.ava, .card-media img.ava { width: 100%; height: 100%;
         object-fit: cover; display: block; transition: transform .4s ease; }
.card:hover .card-media video.ava, .card:hover .card-media img.ava {
         transform: scale(1.04); }
.card-body { padding: 12px 16px 16px; }
.card-cta { display: inline-block; margin-top: 10px; padding: 8px 16px;
         border-radius: 10px; background: var(--accent); color: #FFF6EE;
         font-size: .82rem; font-weight: 600; transition: background .2s; }
.card:hover .card-cta { background: #94430f; }
.card { background: var(--surface); border: 1px solid var(--line); border-radius: 14px; overflow: hidden;
        transition: transform .25s cubic-bezier(.2, .9, .3, 1.4), box-shadow .25s; }
.card:hover { transform: translateY(-6px) scale(1.02);
              box-shadow: 0 14px 30px rgba(20, 24, 26, .14); }
.card h2, .card h3 { font-size: 1.1rem; padding: 12px 14px 4px; }
.card p { color: var(--muted); font-size: .9rem; }

.chat-page { display: flex; flex-direction: column; height: 100dvh; }
.chat-header { display: flex; align-items: center; gap: 12px; padding: 10px 14px;
               background: var(--surface); border-bottom: 1px solid var(--line); }
.chat-header .back { font-size: 1.4rem; padding: 4px 8px; }
.chat-header small { color: var(--muted); }

/* Панель персоны: крупное лицо слева, разговор справа. Ради этого кадра
   и снимались ролики thinking/answering — в кружке 40x40 их не видно. */
.chat-body { flex: 1; display: flex; min-height: 0; }
.chat-main { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.persona { display: flex; flex-direction: column; background: var(--surface);
           border-right: 1px solid var(--line); flex: 0 0 360px; }
/* Пропорция кадра равна пропорции исходника. Портреты в static/img
   квадратные 800x800, и растягивание их на всю высоту колонки (0.43)
   срезало 43% по краям — в кадре оставались глаза и рот. */
.persona-media { flex: 0 0 auto; aspect-ratio: 1 / 1; overflow: hidden; }
.persona-media img, .persona-media video { width: 100%; height: 100%;
           object-fit: cover; display: block; }
.persona-meta { padding: 12px 16px 16px; }
.persona-meta h2 { font-size: 1.25rem; }
.persona-status { color: var(--muted); font-size: .9rem; min-height: 1.4em; }
/* Заметка «из жизни» персонажа — записка на полях панели. Даёт повод
   заговорить (docs/психология-первого-касания.md), заполняет пустую
   зону, на которую указал владелец 12.08. */
.persona-note { margin: 4px 14px 16px; padding: 12px 14px;
                background: #FFFDF7; border: 1px solid var(--line);
                border-radius: 3px 14px 14px 14px;
                box-shadow: 0 2px 10px -6px rgba(20, 24, 26, .25);
                animation: meet-pop .3s ease .4s backwards; }
.persona-note-label { font-size: .68rem; letter-spacing: .06em;
                text-transform: uppercase; color: var(--accent);
                font-weight: 700; margin-bottom: 4px; }
.persona-note-text { font-size: .9rem; line-height: 1.5; }

/* На телефоне панель ложится полосой сверху, а при наборе ужимается:
   клавиатура съедает пол-экрана, и лента там важнее лица. */
/* На телефоне размер панели задаётся ШИРИНОЙ, а не высотой. Пока
   пропорция была 3:4, высота 38vh давала узкий кадр и всё помещалось;
   с квадратом та же высота дала ширину в 38vh, панель вылезла за экран
   и появилась горизонтальная прокрутка. */
@media (max-width: 899px) {
  .chat-body { flex-direction: column; }
  .persona { flex: 0 0 auto; flex-direction: row; align-items: center;
             gap: 14px; height: auto; border-right: 0;
             border-bottom: 1px solid var(--line); }
  .persona-media { flex: 0 0 38%; width: 38%; height: auto; min-height: 0;
                   aspect-ratio: 1 / 1; transition: flex-basis .25s ease,
                   width .25s ease; }
  .persona { flex-wrap: wrap; }
  .persona-meta { padding: 0 16px 0 0; min-width: 0; }
  .persona-meta h2 { font-size: 1.1rem; }
  /* Заметка на телефоне ложится строкой под лицом и именем. Пока человек
     печатает, панель ужата — заметку прячем, лента важнее. */
  .persona-note { flex: 1 1 100%; margin: 0 12px 12px; }
  .chat-page.typing .persona-note { display: none; }
  /* Клавиатура съедает пол-экрана: пока человек печатает, лицо
     ужимается до аватарки и лента получает место. */
  .chat-page.typing .persona-media { flex-basis: 84px; width: 84px; }
}
.log { flex: 1; overflow-y: auto; padding: 16px; display: flex;
       flex-direction: column; gap: 10px; }
.bubble { max-width: 78%; padding: 10px 14px; border-radius: 16px;
          white-space: pre-wrap; line-height: 1.4; }
.bubble.user { align-self: flex-end; background: var(--accent); color: #FFF6EE; }
.bubble.assistant { align-self: flex-start; background: var(--surface);
                    border: 1px solid var(--line); }
.composer { display: flex; gap: 8px; padding: 10px 14px 16px; background: var(--surface);
            border-top: 1px solid var(--line);
            position: relative; z-index: 2; }
.composer textarea { flex: 1; resize: none; border: 0; border-radius: 12px;
                     padding: 10px 14px; font: inherit; background: var(--bg);
                     color: var(--ink); border: 1px solid var(--line); }
.composer textarea:focus { outline: 2px solid var(--accent); }
.composer button { border: 0; border-radius: 12px; padding: 0 18px;
                   background: var(--accent); color: #FFF6EE; font-size: 1.1rem;
                   cursor: pointer; }
.composer button:hover { background: #94430f; }

/* «живые» карточки: каскадное появление и случайное шевеление */
.card.enter { animation: card-enter .6s cubic-bezier(.2, .9, .3, 1.2) backwards; }
@keyframes card-enter {
  from { opacity: 0; transform: translateY(22px) scale(.96); }
  to   { opacity: 1; transform: none; }
}
.card.wave { animation: card-wave 1s ease; }
.card.wave img { animation: img-wiggle 1s ease; }
@keyframes card-wave {
  0%   { transform: none; }
  30%  { transform: translateY(-9px) rotate(-1.2deg) scale(1.03); }
  60%  { transform: translateY(2px) rotate(.6deg); }
  100% { transform: none; }
}
@keyframes img-wiggle {
  0%, 100% { transform: none; }
  35% { transform: scale(1.08) rotate(-2deg); }
  70% { transform: scale(1.03) rotate(1.2deg); }
}

@media (prefers-reduced-motion: reduce) {
  .card, .card img { transition: none; animation: none; }
}

/* текстовые блоки главной (SEO-контент) */
.about { max-width: 760px; margin: 8px auto 0; padding: 8px 20px 24px;
         line-height: 1.6; }
.about h2 { font-size: 1.2rem; margin: 28px 0 10px; color: var(--accent); }
.about p { color: #3d3a34; margin-bottom: 10px; }
.about strong { color: var(--ink); font-weight: 600; }
.foot { text-align: center; padding: 20px 16px 32px; color: var(--muted);
        font-size: .85rem; }

/* посадочные страницы */
.about a { color: #E08A5B; text-decoration: underline;
           text-underline-offset: 3px; }
.about a:hover { color: #eb9a6f; }
.about ul { color: #3d3a34; margin: 0 0 10px 22px; padding: 0; }
.about li { margin-bottom: 8px; }
.crumbs { max-width: 760px; margin: 0 auto; padding: 14px 20px 0;
          font-size: .85rem; color: var(--muted); }
.crumbs a { color: var(--muted); text-decoration: underline;
            text-underline-offset: 3px; }
.note { background: var(--surface); border-left: 3px solid #C97B9C;
        border-radius: 0 12px 12px 0; padding: 14px 16px; margin: 20px 0; }
.note p { color: #3d3a34; margin: 0; }

/* плашка «напомнить о разговоре» — над полем ввода, ненавязчиво */
/* Атрибут hidden скрывает элемент через display: none в стилях браузера,
   и любое авторское display это перебивает. У .tg-connect стоял
   inline-block, у .remind-form — flex, поэтому оба канала напоминания
   показывались одновременно, а вкладки Telegram/Email ничего не
   переключали. Нашлось сквозной проверкой: бот не настроен, сервер
   отдаёт 503, а кнопка «Подключить Telegram» всё равно висела. */
[hidden] { display: none !important; }

.remind { position: relative; margin: 0 14px 8px; padding: 12px 40px 12px 14px;
          background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
          animation: remind-in .35s ease backwards; }
@keyframes remind-in { from { opacity: 0; transform: translateY(8px); } }
.remind-title { font-size: .95rem; margin-bottom: 10px; }
.remind-close { position: absolute; top: 6px; right: 8px; border: 0;
                background: none; color: var(--muted); font-size: 1.3rem;
                line-height: 1; cursor: pointer; padding: 4px 6px; }
.remind-close:hover { color: var(--ink); }
.remind-tabs { display: flex; gap: 8px; margin-bottom: 8px; }
.remind-tab { border: 1px solid #4a3b2e; border-radius: 10px; padding: 6px 12px;
              background: transparent; color: var(--muted); font: inherit;
              font-size: .85rem; cursor: pointer; }
.remind-tab:hover { color: var(--ink); }
.remind-tab.is-on { background: #E08A5B; border-color: #E08A5B; color: #241209; }
.remind-form { display: flex; gap: 8px; }
.remind-form input { flex: 1; min-width: 0; border: 0; border-radius: 10px;
                     padding: 9px 12px; font: inherit; font-size: .9rem;
                     background: var(--bg); color: var(--ink); }
.remind-form input:focus { outline: 2px solid #E08A5B; }
.remind-form button { border: 0; border-radius: 10px; padding: 0 16px;
                      background: #E08A5B; color: #241209; font: inherit;
                      cursor: pointer; }
.remind-form button:hover { background: #eb9a6f; }
.remind-note { color: var(--muted); font-size: .82rem; margin-top: 8px; }
.remind-note:empty { display: none; }
/* «Подключить Telegram» — кнопка-ссылка на t.me/<бот>?start=<токен>:
   chat_id бот узнаёт сам, руками вводить нечего */
.tg-connect { display: inline-block; border-radius: 10px; padding: 9px 16px;
              background: #E08A5B; color: #241209; font-size: .9rem;
              text-decoration: none; }
.tg-connect:hover { background: #eb9a6f; }
.composer textarea:disabled { color: var(--muted); background: #1f1a15;
                              cursor: not-allowed; }
.composer button:disabled { opacity: .45; cursor: not-allowed;
                            background: var(--accent-soft); }
.unsub-back { color: #E08A5B; text-decoration: underline;
              text-underline-offset: 3px; }
@media (prefers-reduced-motion: reduce) { .remind { animation: none; } }

/* Видео вместо картинки: карточки на витрине и аватар в чате */
.persona-media .ava-video { width: 100%; height: 100%; object-fit: cover;
                            display: block; }

/* «печатает»: меняющиеся реплики и три точки */
.bubble.thinking { color: var(--muted); font-style: italic; opacity: .9; }
.dots { display: inline-flex; gap: 3px; margin-left: 6px; vertical-align: middle; }
.dots i { width: 4px; height: 4px; border-radius: 50%; background: var(--accent);
          animation: dot 1.2s ease-in-out infinite; }
.dots i:nth-child(2) { animation-delay: .18s; }
.dots i:nth-child(3) { animation-delay: .36s; }
@keyframes dot { 0%, 60%, 100% { opacity: .25; transform: translateY(0); }
                 30% { opacity: 1; transform: translateY(-3px); } }

/* ссылки на посадочные страницы с главной */
.links { list-style: none; padding: 0; }
.links li { margin-bottom: 8px; color: var(--muted); }
.links a { color: var(--accent); font-weight: 600; }
.links a:hover { text-decoration: underline; }

/* Блок знакомства: двое заговаривают первыми. Кадр вертикальный и почти
   ростовой — он должен читаться иначе, чем ряд одинаковых плиток ниже. */
.meet { display: grid; gap: 20px; padding: 16px; max-width: 1100px;
        margin: 0 auto; grid-template-columns: 1fr; }
@media (min-width: 800px) { .meet { grid-template-columns: 1fr 1fr; } }
.meet-hero { display: flex; gap: 16px; background: var(--surface);
             border: 1px solid var(--line); border-radius: 18px;
             overflow: hidden;
             box-shadow: 0 1px 2px rgba(20, 24, 26, .04),
                         0 10px 28px -18px rgba(20, 24, 26, .28);
             transition: transform .25s ease, box-shadow .25s ease; }
.meet-hero:hover { transform: translateY(-2px);
                   box-shadow: 0 2px 4px rgba(20, 24, 26, .05),
                               0 18px 36px -18px rgba(20, 24, 26, .34); }
/* Пропорция по исходнику, как в карточках и в панели чата: портреты
   и ролики квадратные, а 9:16 срезало по краям почти половину кадра.
   Ростовой план отменён 11 августа, так что 1:1 — это окончательно
   (разбор в docs/sd-поясные-исходники.md). */
/* overflow: hidden обязателен: без него видео внутри диктует высоту
   контейнеру, и aspect-ratio не действует вовсе. Ровно так кадр здесь
   всё это время задавался роликом, а не правилом. */
.meet-media { flex: 0 0 40%; aspect-ratio: 1 / 1; overflow: hidden;
              background: var(--bg); }
.meet-video { width: 100%; height: 100%; object-fit: cover; display: block; }
.meet-talk { flex: 1; min-width: 0; display: flex; flex-direction: column;
             padding: 16px 16px 16px 0; }
.meet-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.meet-name { font-family: "Unbounded", "Segoe UI", sans-serif; font-weight: 600; }
/* «на связи» — честный статус сервиса (отвечает мгновенно, 24/7),
   а не имитация живого человека: кто перед тобой, написано в шапке
   и в подписи персонажа. */
.meet-online { font-size: .74rem; color: #2E7D4F; font-weight: 600;
               display: inline-flex; align-items: center; gap: 5px; }
.meet-online::before { content: ""; width: 7px; height: 7px; border-radius: 50%;
               background: #3FA46A; animation: meet-pulse 2.2s ease infinite; }
@keyframes meet-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(63, 164, 106, .45); }
  55% { box-shadow: 0 0 0 5px rgba(63, 164, 106, 0); } }
.meet-status { color: var(--muted); font-size: .85rem; min-height: 1.3em; }
/* Индикатор набора: три прыгающие точки, как в мессенджере. Текст
   «печатает» остаётся в разметке — его читает скринридер. */
.meet-status.is-typing::after { content: ""; display: inline-block;
               width: 1.2em; text-align: left;
               animation: meet-dots 1.2s steps(4, end) infinite; }
@keyframes meet-dots {
  0% { content: ""; } 25% { content: "."; }
  50% { content: ".."; } 75% { content: "..."; } }
/* Реплика — чат-пузырь. Пустого пузыря не бывает: до первой буквы блок
   скрыт, поэтому карточка не выглядит недостроенной. */
.meet-line { align-self: flex-start; margin: 8px 12px 12px 0; max-width: 100%;
             background: #FFFDF7; border: 1px solid var(--line);
             border-radius: 4px 16px 16px 16px; padding: 10px 14px;
             box-shadow: 0 2px 8px -4px rgba(20, 24, 26, .18);
             animation: meet-pop .25s ease; }
.meet-line:empty { display: none; }
.meet-spacer { flex: 1; }
@keyframes meet-pop {
  from { opacity: 0; transform: translateY(4px) scale(.98); }
  to { opacity: 1; transform: none; } }
.meet-form { display: flex; gap: 8px; align-items: center; }
.meet-form input { flex: 1; min-width: 0; border-radius: 999px; padding: 10px 16px;
                   font: inherit; background: #FFFDF7; color: var(--ink);
                   border: 1px solid var(--line);
                   transition: border-color .2s, box-shadow .2s; }
.meet-form input:focus { outline: none; border-color: var(--accent);
                   box-shadow: 0 0 0 3px rgba(180, 85, 31, .18); }
.meet-form button { border: 0; border-radius: 50%; width: 42px; height: 42px;
                    flex: 0 0 42px; display: grid; place-items: center;
                    background: var(--accent); color: #FFF6EE; cursor: pointer;
                    font-size: 1rem; transition: background .2s, transform .15s; }
.meet-form button:active { transform: scale(.94); }
/* Трение, которого нет, должно быть видно (Talkie-урок из
   docs/психология-первого-касания.md). */
.meet-foot { color: var(--muted); font-size: .74rem; margin: 6px 2px 0;
             padding-bottom: 10px; }

/* На узком экране лицо ложится над разговором, а не рядом: в ряд
   колонка текста схлопывается, имя переносится, а поле ответа налезает
   на реплику. Кадр здесь 16:9 — квадратный исходник он подрезает сверху
   и снизу, но лицо остаётся целым, а двое героев не съедают весь экран. */
@media (max-width: 560px) {
  .meet-hero { flex-direction: column; gap: 0; }
  .meet-media { flex: 0 0 auto; width: 100%; aspect-ratio: 4 / 3; }
  .meet-talk { padding: 12px 16px 14px; }
  .meet-line { min-height: 2.4em; margin-top: 4px; }
  .meet-name { font-size: 1rem; }
}
.meet-form button:hover { background: #94430f; }

/* Страницы персонажей: /katya, /sofia и остальные */
.profile-face { width: 320px; max-width: 100%; height: auto; aspect-ratio: 1 / 1;
                object-fit: cover; border-radius: 14px; display: block; }
.about .card-cta { color: #FFF6EE; }
.about .card-cta:hover { background: #94430f; }

/* Начатый разговор на витрине: карточка, где человек уже был, не должна
   выглядеть как восемь нетронутых. */
.card.started { border-color: var(--accent); }
.card-last { color: var(--muted); font-size: .82rem; font-style: italic;
             margin-top: 8px; overflow: hidden; display: -webkit-box;
             -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.resume { display: block; max-width: 1100px; margin: 8px auto 0;
          padding: 12px 20px; background: var(--accent); color: #FFF6EE;
          border-radius: 999px; font-weight: 600; text-align: center;
          box-shadow: 0 8px 20px -12px rgba(180, 85, 31, .55);
          transition: background .2s, transform .2s; }
.resume::after { content: " →"; }
.resume:hover { background: #94430f; transform: translateY(-1px); }
