/* ============================================================================
   common.css — общие стили проекта.
   Пока охватывает только страницу «Вход». После готовности «Черепохи»
   добавим сюда её правила и объединим всё в один общий файл.
   ============================================================================ */

/* ---- базовые сбросы ---- */
* { box-sizing: border-box; }
/* Тема экрана входа. Ставится атрибутом data-theme на <html> ещё до отрисовки (см. index.html),
   значения — здесь; сцена (сфера и пыль) читает их же через getComputedStyle. */
:root {
  --m-bg: #e4e4e6;          /* фон экрана и «дальний» цвет сферы */
  --m-ink: #1d1d1f;         /* текст */
  --m-floor: #545458;       /* серый у дна сферы */
  --m-shadow: #232327;      /* тень у самого дна */
  --m-dust: #ffffff;        /* цвет пыли */
  --m-chip: rgba(0,0,0,0.06);
  --m-chip-hover: rgba(0,0,0,0.11);
}
/* ТЁМНАЯ ТЕМА — ИНВЕРСИЯ СВЕТЛОЙ ЦЕЛИКОМ, А НЕ ВТОРАЯ ПАЛИТРА.
   Своих цветов у неё нет: экран выворачивается одним фильтром на <html>.
   Отсюда три следствия, ради которых это и сделано:

   1. Соотношения сохраняются сами. Пыль в светлой на 9.5 L* СВЕТЛЕЕ фона —
      в тёмной ровно на столько же ТЕМНЕЕ. Дно сферы: 26.1 темнее → 26.1
      светлее. Раньше это приходилось выставлять руками и по каждому объекту
      отдельно; подбор давал #1b1b1e для фона, а инверсия #e4e4e6 даёт
      #1b1b19 — то же самое, только без ручного счёта.
   2. Под правило попадает ВСЁ, а не только пыль и сфера: плашка ввода,
      стрелка, подсказка, чипы. Раньше они оставались светлыми в тёмной теме,
      потому что переменных на них заведено не было.
   3. Переход плавный без единой строки JS: filter анимируется CSS-переходом,
      и фон, пыль, сфера и плашка едут одним движением, не расходясь.

   ЧЕГО ЗДЕСЬ НЕЛЬЗЯ ДЕЛАТЬ. Инверсия крутит и оттенок: любой цветной элемент
   вывернется в дополнительный (оранжевый → синий). Сейчас видимый экран
   полностью серый, поэтому приём корректен. Появится цветной акцент —
   его придётся исключать (`filter: invert(1)` на самом элементе) ЛИБО
   возвращаться к раздельным палитрам. Единственный цветной сейчас — точка
   загрузки в скрытой отладочной панели пыли, её не видно. */
:root { --m-theme-ms: 520ms; }
:root[data-theme="dark"] { filter: invert(1); }
html {
  transition: filter var(--m-theme-ms) cubic-bezier(.4, 0, .2, 1);
  background: var(--m-bg);          /* красим и html: <body> при инверсии не закрывает края */
}
body { margin: 0; background: var(--m-bg); overflow: hidden; }
img, svg { -webkit-user-drag: none; user-drag: none; }

/* ============================================================================
   СТРАНИЦА «ВХОД»
   ============================================================================ */

/* ---- анимации ---- */
@keyframes pin-shake {
  10%,90% { transform: translateX(-1px); }
  20%,80% { transform: translateX(2px); }
  30%,50%,70% { transform: translateX(-5px); }
  40%,60% { transform: translateX(5px); }
}
@keyframes pf-type { from { max-width: 0; } to { max-width: 32ch; } }

/* ---- плашка ввода ПИН ---- */
.pf.shake { animation: pin-shake .42s cubic-bezier(0.36,0.07,0.19,0.97); }
/* ЕДИНСТВЕННОЕ ИСКЛЮЧЕНИЕ ИЗ ИНВЕРСИИ — плотность стекла плашки.
   Инверсия сохраняет числовой контраст, но не воспринимаемый: одна и та же
   разница в sRGB у чёрного заметна примерно втрое сильнее, чем у белого (на
   этом и построена гамма). Замер по двум соседним кадрам под плашкой:
   светлая 0.66 L*, тёмная 1.75 L* — пыль под ней одна и та же, а мерцает она
   только в тёмной. Размытие тут ни при чём и работает исправно: сквозь
   плашку проходит 15% движения пыли в светлой и 25% в тёмной.
   Поэтому в тёмной делаем стекло плотнее и глубже — меньше проходит внутрь.
   Через переменную, а не правилом на `.pf`: иначе override перебил бы
   `.pf.loading` и `.pf.exit-line`, у которых свой фон. */
:root { --pf-veil: rgba(232,232,232,0.16); --pf-veil-hover: rgba(236,236,236,0.22); --pf-blur: 38px; }
/* Тёмное значение подобрано замером, а не на глаз. Плашка обязана остаться
   ТЁМНОЙ, поэтому светлоту не трогаем вовсе — гасим только плотностью.
   Сквозь стекло проходит доля (1 − alpha): 0.16 пропускало 84% движения пыли,
   0.78 пропускает 22%, и дрожание падает вчетверо при той же темноте.
   Цвет стекла светлее (230 ДО инверсии = тёмное ПОСЛЕ), чтобы уплотнение не
   утащило плашку в чёрное: одна лишь плотность делает её темнее фона и
   съедает половину выигрыша — проверено, 0.42 давало лишь 1.20 L*. */
:root[data-theme="dark"] { --pf-veil: rgba(230,230,230,0.78); --pf-veil-hover: rgba(234,234,234,0.80); --pf-blur: 60px; }

.pf {
  padding: 8px 8px 8px 22px;
  height: 60px;
  cursor: default;
  background: var(--pf-veil);
  -webkit-backdrop-filter: blur(var(--pf-blur)) saturate(180%);
  backdrop-filter: blur(var(--pf-blur)) saturate(180%);
  transition: height .7s cubic-bezier(.5,.1,.2,1),
              padding .7s cubic-bezier(.5,.1,.2,1),
              background .4s ease,
              -webkit-backdrop-filter .5s ease,
              backdrop-filter .5s ease;
}
.pf:hover { background: var(--pf-veil-hover); }
.pf.loading {
  height: 4px; padding: 0; background: transparent;
  -webkit-backdrop-filter: none; backdrop-filter: none;
  cursor: default;
}

/* поле ввода + печатающаяся подсказка */
.pf-in { -webkit-user-select: text; user-select: text; cursor: default; }
.pf-in[data-empty="true"]::before {
  content: attr(data-placeholder);
  color: rgba(255,255,255,0.8);
  pointer-events: none;
  font-weight: 400;
  display: inline-block;
  white-space: nowrap;
  overflow: hidden;
  max-width: 0;
  vertical-align: bottom;
}
.pf.chrome .pf-in[data-empty="true"]::before { animation: pf-type 0.5s steps(32,end) forwards; }
.pf.infocus .pf-in[data-empty="true"]::before { display: none; }

/* кнопки (глаз / вход): фон прозрачный, реагирует сама иконка (SVG) — при наведении −30% альфы */
.pf-eye svg, .pf-btn svg { transition: none; opacity: 1; }
.pf.chrome .pf-btn:hover svg,
.pf.chrome.has-pin .pf-eye:hover svg { opacity: 0.7; }
/* иконки не перехватывают события: единственная hit-зона — сама кнопка */
.pf-eye *, .pf-btn * { pointer-events: none; }

/* появление содержимого плашки */
.pf-eye { color: #ffffff; background: transparent; opacity: 0; pointer-events: none; }
.pf.chrome.has-pin .pf-eye { opacity: 1; pointer-events: auto; }
.pf-in, .pf-btn { opacity: 0; pointer-events: none; }
.pf.chrome .pf-in, .pf.chrome .pf-btn { opacity: 1; pointer-events: auto; }

/* линия-прелоадер (заливка плашки) */
.pf-fill {
  position: absolute; left: 0; top: 0; bottom: 0; width: 100%;
  transform: scaleX(0); transform-origin: 0% 50%;
  border-radius: 9999px;
  background: rgba(228,228,230,0.6);
  -webkit-backdrop-filter: blur(22px) saturate(180%);
  backdrop-filter: blur(22px) saturate(180%);
  transition: transform 1.6s cubic-bezier(.5,.12,.2,1), opacity .6s ease;
  pointer-events: none; z-index: 0;
}

/* ---- анимация выхода (успешный вход): контент гаснет → плашка сжимается в линию → линия уходит слева направо ---- */
.pf.exit .pf-in, .pf.exit .pf-eye, .pf.exit .pf-btn {
  opacity: 0 !important; pointer-events: none !important;
  transition: opacity .5s ease !important;
}
.pf.exit-line {
  height: 4px !important; padding: 0 !important;
  background: rgba(228,228,230,0.85) !important;
  -webkit-backdrop-filter: blur(22px) saturate(180%) !important;
  backdrop-filter: blur(22px) saturate(180%) !important;
  transition: height .55s cubic-bezier(.5,.1,.2,1),
              padding .55s cubic-bezier(.5,.1,.2,1),
              background .3s ease !important;
}
.pf.exit-line.exit-empty {
  transform: scaleX(0); transform-origin: 100% 50%;
  transition: transform 1.3s cubic-bezier(.5,.12,.2,1) !important;
}

/* Переключатель темы на экране входа: незаметная пилюля в углу, не спорит со сценой. */
.m-theme {
  position: fixed; top: 18px; right: 18px; z-index: 9;
  width: 34px; height: 34px; display: grid; place-items: center;
  border: none; border-radius: 9999px; cursor: pointer; padding: 0;
  color: var(--m-ink); background: var(--m-chip);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  transition: background-color .2s ease, color .2s ease, opacity .2s ease;
  opacity: .72;
}
.m-theme:hover { background: var(--m-chip-hover); opacity: 1; }
.m-theme svg { grid-area: 1 / 1; display: block; }
.m-theme .m-theme__sun { display: none; }
:root[data-theme="dark"] .m-theme .m-theme__sun { display: block; }
:root[data-theme="dark"] .m-theme .m-theme__moon { display: none; }
