/* Плавающая кнопка «написать нам» — постоянный вход в форму обращения с
   каждой страницы (`app/templates/base.html`, блок `contact_button`).

   Отдельным файлом, а не строкой в `components.css`: правило CSP не даёт ни
   `style=`, ни инлайнового `<style>` (`app/web/security_headers.py`), а
   класть стили окна в общий лист посреди недели, когда четыре окна сводят в
   одну ветку, значило бы устроить конфликт на ровном месте.

   Цвета — только токенами и `color-mix`: страж палитры допускает ровно
   одиннадцать значений и запрещает `rgba`, `hsl`, имена цветов и градиенты
   (`tests/test_public_pages.py`). */

.contact-button {
  position: fixed;
  inset-inline-end: var(--space-4);
  inset-block-end: var(--space-4);

  /* Ниже баннера согласия (`z-index: 60`) нарочно. Полоса согласия — решение,
     которое человек принимает раньше всего остального, и закрывать её собой
     кнопка права не имеет. Расходятся они отступом, а не слоями: правило
     ниже поднимает кнопку над полосой, пока полоса на экране. */
  z-index: 50;

  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  padding-inline: var(--space-3);

  /* Потолок ширины обязателен: подпись приходит из настройки, то есть её
     пишет человек и правит без выкатки. Замер на 390 px — подпись из четырёх
     слов растянула кнопку до 374 px, то есть 96 % экрана: плавающая кнопка
     превращалась в сплошную полосу внизу каждой страницы, а починить это
     можно было бы только выкладкой. Теперь длинный текст переносится внутри
     кнопки, и она растёт вверх, а не поперёк экрана.

     Потолок двойной, и вторая половина обязательна: `rem` растёт вместе с
     корневым шрифтом, который человек ставит себе сам, и одной ею защита
     таяла — замер на той же подписи дал 66 % экрана при 16 px, 82 % при
     20 px и 94 % при 24 px, то есть при полуторном шрифте кнопка снова
     становилась полосой.

     Вторая половина записана процентами, а не долей ширины окна. У элемента
     с `position: fixed` содержащий блок — само окно, поэтому проценты здесь
     считают ровно от него, и никакая единица ширины окна для этого не нужна;
     а она бы ещё и мерила вместе с полосой прокрутки. Вычитаются два поля,
     чтобы кнопка не упиралась в края. */
  max-width: min(16rem, calc(100% - 2 * var(--space-4)));
  border: var(--hairline) solid var(--btn-edge);
  border-radius: var(--radius-button);
  background: var(--btn-bg);
  color: var(--btn-ink);
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;

  /* Потолок высоты — та же забота, что и потолок ширины, только с другой
     стороны. Упершись в потолок ширины, длинная подпись из настройки начала бы
     расти вверх и заняла бы нижнюю треть экрана. Подпись в одну строку, лишнее
     срезается многоточием: кнопка остаётся кнопкой, а полный текст человек
     всё равно прочитает на самой странице обращения. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;

  /* Тень отделяет кнопку от текста, который проезжает под ней. Через
     `color-mix`, потому что `rgba` запрещена стражем палитры — тем же
     приёмом, что и тень самого баннера согласия. */
  box-shadow: 0 0.25rem 0.75rem color-mix(in srgb, var(--navy) 30%, transparent);
}

/* Отклик на наведение — тот же, что у кнопок портала (`components.css`,
   `.btn:hover`). Свой класс ничего не наследует, и без этих двух строк
   главный новый орган управления портала был единственным, который на
   указатель не отвечает вовсе. Проверено замером фона до и после наведения. */
.contact-button:hover {
  background: color-mix(in srgb, var(--btn-bg) 84%, var(--anthracite));
  border-color: color-mix(in srgb, var(--btn-edge) 84%, var(--anthracite));
  color: var(--btn-ink);
}

/* Пока полоса согласия внизу, кнопка стоит НАД ней, а не поверх неё.
   Высота полосы замерена в WebKit на живых страницах 05.09, и она зависит
   не только от языка, но и от ширины экрана — чем уже, тем больше переносов:

       390 px:  ru 261.9   en 261.9   de 282.7
       320 px:  ru 341.0   en 282.7   de 320.3

   Отсюда два числа, а не одно (решение оркестратора после разбора). Основное
   снято по 390 px — 283 px, наибольшая высота там. Одним им обойтись нельзя:
   на 320 px полоса вырастает до 341 px, и кнопка с отступом по 390 px
   пересекала бы её на ru и de. Второе правило ниже закрывает узкие экраны.

   **Оба числа записаны в rem, а не в px, и это не вкус.** Полоса состоит из
   текста, то есть её высота растёт вместе с корневым шрифтом, который человек
   ставит себе сам. Подъём, записанный пикселями, за ней не поспевает: при
   17 px он уже рассыпается, а при 20 px кнопка пересекает полосу почти везде.
   Первые слагаемые — те самые 283 и 341, делённые на 16.

   Вторые слагаемые — запас, и он большой не от щедрости. Полоса растёт
   БЫСТРЕЕ шрифта: с крупным шрифтом текст переносится на большее число строк,
   и высота прибавляет скачком, а не пропорционально. Замер высоты полосы,
   переведённый в rem (полоса, делённая на шрифт):

       16 px:  320 ru 21.32   320 de 20.02   390 ru 16.37   390 de 17.67
       17 px:  320 ru 22.35   320 de 23.65   390 ru 16.35   390 de 17.65
       20 px:  320 ru 26.21   320 de 28.81   390 ru 21.26   390 de 19.99

   Отсюда потолок: широкому правилу нужно 21.26rem, узкому — 28.81rem. Взято
   21.5rem и 29rem. Цена честная и её видно: при обычном шрифте кнопка стоит
   выше, чем строго необходимо, — на 390 px её низ в 484 px от верха окна
   вместо 545 px. Это плата за то, что при 125 % шрифта она не залезет на
   полосу согласия.

   Класс, а не `body:has(.consent-banner)`: селектор `:has()` знают не все
   браузеры, и там, где его нет, правило не применялось совсем — кнопка
   оставалась у нижнего края и уходила ПОД полосу (z-index 50 против 60),
   то есть до выбора была недоступна. Замерено. Признак «полоса на экране» у
   сервера уже есть — им и печатается модификатор (`base.html`, флаг
   `consent_banner`), и тогда селектору не нужно угадывать полосу по DOM.

   Число здесь ничего не доказывает; непересечение прямоугольников держит
   браузерная проверка `tests/test_contact_button.py` — на обеих ширинах.

   Граница у отступа есть, и она названа честно: высота полосы растёт ещё и
   от размера шрифта, который человек ставит себе сам, и при корневых 150 %
   подъёма не хватит никакому числу — отступ, покрывающий такую полосу, вынес
   бы кнопку на середину экрана при обычном шрифте. Худший исход безопасен:
   перекрыта оказывается КНОПКА, а не полоса; согласие принимается как обычно,
   а дорога к форме остаётся строкой в подвале. */
.contact-button--above-banner {
  inset-block-end: calc(17.75rem + 3.75rem + var(--space-4));
}

/* Узкий экран: полоса выше, потому что текст переносится чаще. */
@media (max-width: 360px) {
  .contact-button--above-banner {
    inset-block-end: calc(21.375rem + 7.625rem + var(--space-4));
  }
}

/* На бумаге плавающих кнопок не бывает: печатают страницу, а не портал. */
@media print {
  .contact-button {
    display: none;
  }
}
