/* =====================================================================
   brand.css — токены и базовые компоненты Казули.
   Описание направления: DESIGN.md в корне проекта.
   Подключать ДО <style> страницы:
     <link rel="stylesheet" href="brand.css">          (из operator/* — ../brand.css)
   Шрифты подключаются отдельно, ссылкой из раздела «Шрифты» в DESIGN.md.
   ===================================================================== */
:root {
  /* Цвета */
  --sky:        #2B67F0;
  --sky-press:  #1D52CF;
  --sky-mist:   #EAF0FE;
  --sky-soft:   #8FB0FF;   /* синий на тёмном фоне */
  --ink:       #15203A;
  --ink-2:      #4A5468;
  --ink-3:      #6B7385;
  --line:       #E3E6EC;
  --milk:       #F5F6F3;
  --paper:      #FFFFFF;
  --meadow:     #2E8B47;
  --meadow-mist:#E6F4EA;
  --brick:      #D2453B;
  --brick-mist: #FCEBE9;

  /* Шрифты */
  --font-display: 'Wix Madefor Display', 'Wix Madefor Text', sans-serif;
  --font-text:    'Wix Madefor Text', 'Wix Madefor Display', sans-serif;

  /* Шкала текста */
  --fs-13: 13px; --fs-15: 15px; --fs-17: 17px; --fs-20: 20px;
  --fs-24: 24px; --fs-30: 30px; --fs-36: 36px;

  /* Радиусы по роли */
  --r-chip: 8px; --r-control: 12px; --r-card: 18px; --r-sheet: 28px;

  /* Тень — только для парящих элементов */
  --shadow-float: 0 1px 2px rgba(21, 32, 58, .06), 0 10px 28px -8px rgba(21, 32, 58, .18);

  /* Движение */
  --ease: cubic-bezier(.2, .7, .2, 1);
  --t-fast: 120ms; --t-base: 200ms;
}

/* ---------- База ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--font-text);
  font-weight: 400;
  font-size: var(--fs-17);
  line-height: 1.45;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-tap-highlight-color: transparent;
}
h1, h2, h3 { font-family: var(--font-display); font-weight: 700; color: var(--ink); margin: 0; }
p { margin: 0; }
[hidden] { display: none !important; }   /* иначе display:flex у компонентов перебивает hidden */
:focus-visible { outline: 2px solid var(--sky); outline-offset: 2px; }

/* ---------- Типографика ---------- */
.t-title {
  font-family: var(--font-display); font-weight: 800;
  font-size: var(--fs-36); line-height: 1.05; letter-spacing: -0.03em;
}
.t-h2 {
  font-family: var(--font-display); font-weight: 700;
  font-size: var(--fs-24); line-height: 1.15; letter-spacing: -0.02em;
}
.t-lead  { font-size: var(--fs-17); line-height: 1.45; color: var(--ink-2); }
.t-small { font-size: var(--fs-13); line-height: 1.4;  color: var(--ink-3); }
.t-code  {
  font-family: var(--font-display); font-weight: 700;
  font-variant-numeric: tabular-nums; letter-spacing: 0.06em;
}

/* ---------- Кнопки ---------- */
.b-btn {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; min-height: 54px; padding: 0 20px;
  border: 0; border-radius: var(--r-control);
  font-family: var(--font-text); font-weight: 600; font-size: var(--fs-17);
  text-decoration: none; cursor: pointer;
  background: var(--sky); color: #fff;
  transition: background-color var(--t-base) var(--ease), transform var(--t-fast) var(--ease);
}
.b-btn:hover  { background: var(--sky-press); }
.b-btn:active { transform: scale(.985); }
.b-btn[disabled], .b-btn[aria-disabled="true"] {
  background: var(--line); color: var(--ink-3); cursor: default; transform: none;
}
.b-btn--secondary {
  background: var(--paper); color: var(--ink);
  box-shadow: inset 0 0 0 1.5px var(--line);
}
.b-btn--secondary:hover { background: var(--milk); }
.b-btn svg { width: 20px; height: 20px; flex: none; }

/* Цена «Сено» внутри кнопки */
.b-price {
  display: inline-flex; align-items: center; gap: 6px;
  margin-left: auto; padding: 4px 10px 4px 8px;
  border-radius: var(--r-chip);
  background: rgba(255, 255, 255, .16);
  font-family: var(--font-display); font-weight: 700; font-variant-numeric: tabular-nums;
}
.b-btn[disabled] .b-price { background: rgba(21, 32, 58, .06); }

/* Чип баланса «Сено» */
.b-seno {
  display: inline-flex; align-items: center; gap: 6px;
  height: 36px; padding: 0 12px 0 10px;
  border-radius: 999px; background: var(--sky-mist); color: var(--ink);
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-15);
  font-variant-numeric: tabular-nums; text-decoration: none;
}
.b-seno svg { width: 18px; height: 18px; color: var(--sky); }

/* Номер станции — настоящая последовательность маршрута */
.b-step {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: 10px;
  background: var(--sky); color: #fff;
  font-family: var(--font-display); font-weight: 800; font-size: var(--fs-17);
}

/* =====================================================================
   Загрузка и движение — общие детали для всех страниц.
   Правило: анимация отвечает на «нажалось? / идёт процесс? / появилось новое?».
   ===================================================================== */

/* Экран загрузки страницы: Казуля + тонкая полоска.
   <div class="b-loader" id="page-loader" role="status">
     <img class="b-loader__mascot" src="images/kazulya-avatar.webp" alt="">
     <p class="b-loader__text">Готовим карту</p>
     <div class="b-loader__bar"><i></i></div>   (без --determinate — бегущая полоска)
   </div>
   Скрыть: добавить .is-hidden (плавно гаснет за 200 мс, потом можно удалить узел).
   Показывать лоадер только если загрузка дольше ~300 мс (см. DESIGN.md). */
.b-loader {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px;
  background: var(--paper);
  transition: opacity var(--t-base) var(--ease), visibility 0s linear var(--t-base);
}
.b-loader.is-hidden { opacity: 0; visibility: hidden; pointer-events: none; }
.b-loader__mascot {
  width: 96px; height: 96px; border-radius: 50%; object-fit: cover; background: var(--milk);
  animation: b-nod 2.6s var(--ease) infinite;
}
.b-loader__text { font-weight: 600; font-size: var(--fs-15); color: var(--ink-2); }
.b-loader__bar {
  position: relative; width: 160px; height: 4px; border-radius: 2px;
  background: var(--line); overflow: hidden;
}
.b-loader__bar > i {
  position: absolute; top: 0; bottom: 0; left: 0; width: 40%;
  border-radius: inherit; background: var(--sky);
  animation: b-slide 1.2s var(--ease) infinite;
}
.b-loader__bar--determinate > i { width: 0; animation: none; transition: width .4s linear; }
@keyframes b-nod {
  0%, 100% { transform: translateY(0) rotate(0); }
  50%      { transform: translateY(-6px) rotate(-4deg); }
}
@keyframes b-slide {
  from { transform: translateX(-100%); }
  to   { transform: translateX(250%); }
}

/* Спиннер для кнопки и мелких мест: <span class="b-spin" aria-hidden="true"></span>
   Кнопка в процессе: .b-btn.is-busy — текст остаётся, клики выключены. */
.b-spin {
  display: inline-block; flex: none; width: 18px; height: 18px;
  border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%;
  animation: b-rotate .7s linear infinite;
}
@keyframes b-rotate { to { transform: rotate(360deg); } }
.b-btn.is-busy { pointer-events: none; opacity: .85; }
.b-btn.is-busy > svg { display: none; }   /* спиннер встаёт вместо иконки */
.b-btn.is-busy[disabled] { background: var(--sky); color: #fff; }   /* в процессе — не «серая недоступная» */
.b-btn--secondary.is-busy[disabled] { background: var(--paper); color: var(--ink); }

/* Скелетон — место под контент, который вот-вот придёт (фото в альбоме, списки) */
.b-skel {
  position: relative; overflow: hidden;
  background: var(--milk); border-radius: var(--r-chip);
}
.b-skel::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .7), transparent);
  transform: translateX(-100%);
  animation: b-shimmer 1.4s var(--ease) infinite;
}
@keyframes b-shimmer { to { transform: translateX(100%); } }

/* Картинка проявляется, когда загрузилась: <img class="b-fade" onload="this.classList.add('is-loaded')"> */
.b-fade { opacity: 0; transition: opacity var(--t-base) var(--ease); }
.b-fade.is-loaded { opacity: 1; }

/* Попап и нижний лист: затемнение + карточка.
   <div class="b-overlay" id="x"><div class="b-sheet">…</div></div>
   Открыть/закрыть — класс .is-open (не display:none, чтобы работал выход). */
.b-overlay {
  position: fixed; inset: 0; z-index: 300;
  display: flex; align-items: flex-end; justify-content: center;
  padding: 16px; padding-bottom: calc(16px + env(safe-area-inset-bottom));
  background: rgba(21, 32, 58, .5);
  opacity: 0; visibility: hidden;
  transition: opacity var(--t-base) var(--ease), visibility 0s linear var(--t-base);
}
.b-overlay.is-open { opacity: 1; visibility: visible; transition: opacity var(--t-base) var(--ease); }
.b-overlay--center { align-items: center; }
.b-sheet {
  width: 100%; max-width: 440px; max-height: 88vh; overflow: auto;
  padding: 24px 20px 20px;
  background: var(--paper); border-radius: var(--r-sheet); box-shadow: var(--shadow-float);
  transform: translateY(16px);
  transition: transform var(--t-base) var(--ease);
}
.b-overlay.is-open .b-sheet { transform: none; }
.b-sheet__x {
  width: 36px; height: 36px; flex: none;
  display: flex; align-items: center; justify-content: center;
  border: 0; border-radius: 50%; background: var(--milk); color: var(--ink-2); cursor: pointer;
}
.b-sheet__head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-bottom: 16px;
}
.b-sheet__title { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-20); letter-spacing: -0.01em; }
body.b-locked { overflow: hidden; }

/* Тост — короткое сообщение внизу: «Скопировано», «Нет связи».
   Один на страницу: <div class="b-toast" id="toast" role="status"></div>, варианты --ok / --error. */
.b-toast {
  position: fixed; left: 50%; bottom: calc(24px + env(safe-area-inset-bottom)); z-index: 1100;
  max-width: calc(100% - 32px); padding: 12px 16px;
  border-radius: var(--r-control); background: var(--ink); color: #fff;
  font-weight: 600; font-size: var(--fs-15); box-shadow: var(--shadow-float);
  opacity: 0; visibility: hidden; transform: translate(-50%, 8px);
  transition: opacity var(--t-base) var(--ease), transform var(--t-base) var(--ease), visibility 0s linear var(--t-base);
}
.b-toast.is-shown { opacity: 1; visibility: visible; transform: translate(-50%, 0); transition: opacity var(--t-base) var(--ease), transform var(--t-base) var(--ease); }
.b-toast--ok    { background: var(--meadow); }
.b-toast--error { background: var(--brick); }

/* Пустое состояние / ошибка загрузки — по центру, с персонажем */
.b-empty {
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  padding: 40px 24px; text-align: center;
}
.b-empty img { width: 120px; height: auto; }
.b-empty p { color: var(--ink-2); font-size: var(--fs-15); max-width: 300px; }
.b-empty__title { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-20); letter-spacing: -0.01em; color: var(--ink); }

/* =====================================================================
   Появление экрана и живой персонаж.
   Хореография — один раз при входе на экран, вся укладывается в ~700 мс.
   Задержка — через --d:  <h1 class="b-rise" style="--d:80ms">
   ===================================================================== */
:root { --ease-out-back: cubic-bezier(.34, 1.56, .64, 1); }

/* Подъём снизу с проявлением — заголовки, текст, кнопки */
.b-rise { animation: b-rise 480ms var(--ease) both; animation-delay: var(--d, 0ms); }
@keyframes b-rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

/* «Прилипает» с лёгким отскоком — наклейки, бейджи, печать */
.b-pop { animation: b-pop 420ms var(--ease-out-back) both; animation-delay: var(--d, 0ms); }
@keyframes b-pop {
  from { opacity: 0; transform: scale(.6) rotate(var(--rot, 0deg)); }
  to   { opacity: 1; transform: scale(1)  rotate(var(--rot, 0deg)); }
}

/* Печать: падает сверху крупной и «шлёпается» */
.b-stamp { animation: b-stamp 520ms cubic-bezier(.5, 0, .3, 1.4) both; animation-delay: var(--d, 0ms); }
@keyframes b-stamp {
  0%   { opacity: 0; transform: scale(1.8) rotate(var(--rot, -12deg)); }
  60%  { opacity: 1; transform: scale(.94) rotate(var(--rot, -12deg)); }
  100% { opacity: 1; transform: scale(1)   rotate(var(--rot, -12deg)); }
}

/* Персонаж в покое: дышит/покачивается. Только на одном персонаже на экране. */
.b-idle  { animation: b-idle 3.2s ease-in-out infinite; animation-delay: var(--d, 0ms); transform-origin: 50% 100%; }
@keyframes b-idle {
  0%, 100% { transform: translateY(0) rotate(0); }
  50%      { transform: translateY(-4px) rotate(-1.5deg); }
}
/* Маятник — для Казули, которая висит сверху */
.b-swing { animation: b-swing 3.6s ease-in-out infinite; transform-origin: 50% 0; }
@keyframes b-swing {
  0%, 100% { transform: rotate(-3deg); }
  50%      { transform: rotate(3deg); }
}

/* =====================================================================
   Операторская панель (operator/*) — рабочие экраны, плотнее гостевых.
   Фон страницы — молоко, контент в белых панелях. Шрифт 15 по умолчанию.
   ===================================================================== */
.o-page { min-height: 100vh; background: var(--milk); font-size: var(--fs-15); }

/* Шапка: логотип/название слева, навигация по разделам, справа статус */
.o-header {
  position: sticky; top: 0; z-index: 50;
  display: flex; align-items: center; gap: 20px;
  min-height: 64px; padding: 0 24px;
  background: var(--paper); border-bottom: 1px solid var(--line);
}
.o-header__brand {
  display: flex; align-items: center; gap: 10px; flex: none;
  font-family: var(--font-display); font-weight: 800; font-size: var(--fs-17);
  letter-spacing: -0.01em; color: var(--ink); text-decoration: none;
}
.o-header__brand img { width: 32px; height: 32px; border-radius: 50%; background: var(--milk); object-fit: cover; }
.o-header__brand small { font-family: var(--font-text); font-weight: 600; font-size: var(--fs-13); color: var(--ink-3); letter-spacing: 0; }
.o-nav { display: flex; gap: 4px; overflow-x: auto; scrollbar-width: none; }
.o-nav a {
  display: inline-flex; align-items: center; height: 36px; padding: 0 12px;
  border-radius: var(--r-chip); color: var(--ink-2); font-weight: 600; font-size: var(--fs-15);
  text-decoration: none; white-space: nowrap;
  transition: background-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.o-nav a:hover { background: var(--milk); color: var(--ink); }
.o-nav a[aria-current="page"] { background: var(--sky-mist); color: var(--sky); }
.o-header__end { margin-left: auto; display: flex; align-items: center; gap: 12px; }

/* Статус подключения/сервиса: точка + подпись */
.o-status {
  display: inline-flex; align-items: center; gap: 8px; height: 32px; padding: 0 12px;
  border-radius: 999px; background: var(--milk); color: var(--ink-2);
  font-weight: 600; font-size: var(--fs-13); white-space: nowrap;
}
.o-status::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--ink-3); }
.o-status--ok    { background: var(--meadow-mist); color: var(--meadow); }
.o-status--ok::before { background: var(--meadow); }
.o-status--error { background: var(--brick-mist); color: var(--brick); }
.o-status--error::before { background: var(--brick); }
.o-status--wait::before { background: var(--sky); animation: b-blink 1.2s ease-in-out infinite; }
@keyframes b-blink { 50% { opacity: .25; } }

/* Рабочая область и панели */
.o-main { max-width: 1280px; margin: 0 auto; padding: 24px; display: flex; flex-direction: column; gap: 20px; }
.o-title { font-family: var(--font-display); font-weight: 800; font-size: var(--fs-30); line-height: 1.1; letter-spacing: -0.03em; }
.o-panel { background: var(--paper); border-radius: var(--r-card); padding: 20px; }
.o-panel__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 16px; }
.o-panel__title { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-20); letter-spacing: -0.01em; }

/* Счётчики: крупная цифра + подпись */
.o-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; }
.o-stat { background: var(--paper); border-radius: var(--r-card); padding: 16px 18px; }
.o-stat__num { font-family: var(--font-display); font-weight: 800; font-size: var(--fs-30); line-height: 1; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.o-stat__label { margin-top: 6px; color: var(--ink-3); font-size: var(--fs-13); }

/* Таблица */
.o-table { width: 100%; border-collapse: collapse; font-size: var(--fs-15); }
.o-table th {
  padding: 10px 12px; text-align: left; white-space: nowrap;
  font-weight: 600; font-size: var(--fs-13); color: var(--ink-3);
  border-bottom: 1px solid var(--line);
}
.o-table td { padding: 12px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.o-table tr:last-child td { border-bottom: 0; }
.o-table tbody tr { transition: background-color var(--t-fast) var(--ease); }
.o-table tbody tr:hover { background: var(--milk); }
.o-table .num { text-align: right; font-variant-numeric: tabular-nums; }

/* Бейдж статуса в строке */
.o-badge {
  display: inline-flex; align-items: center; height: 24px; padding: 0 8px;
  border-radius: 6px; background: var(--milk); color: var(--ink-2);
  font-weight: 600; font-size: 12px; white-space: nowrap;
}
.o-badge--ok    { background: var(--meadow-mist); color: var(--meadow); }
.o-badge--error { background: var(--brick-mist); color: var(--brick); }
.o-badge--info  { background: var(--sky-mist); color: var(--sky); }

/* Поля ввода */
.o-field { display: flex; flex-direction: column; gap: 6px; }
.o-field__label { font-weight: 600; font-size: var(--fs-13); color: var(--ink-2); }
.o-input, .o-select, .o-textarea {
  width: 100%; min-height: 44px; padding: 10px 12px;
  border: 0; border-radius: var(--r-control);
  background: var(--paper); box-shadow: inset 0 0 0 1.5px var(--line);
  color: var(--ink); font: inherit; font-size: var(--fs-15); outline: none;
  transition: box-shadow var(--t-fast) var(--ease);
}
.o-textarea { min-height: 96px; resize: vertical; line-height: 1.45; }
.o-input:focus, .o-select:focus, .o-textarea:focus { box-shadow: inset 0 0 0 2px var(--sky); }
.o-input.is-wrong { box-shadow: inset 0 0 0 2px var(--brick); animation: b-shake 360ms var(--ease); }
@keyframes b-shake { 20%, 60% { transform: translateX(-6px); } 40%, 80% { transform: translateX(6px); } }

/* Компактные кнопки для админки: .b-btn.o-btn */
.b-btn.o-btn { width: auto; min-height: 40px; padding: 0 16px; font-size: var(--fs-15); }
.b-btn.o-btn--danger { background: var(--brick); }
.b-btn.o-btn--danger:hover { background: #B83A31; }

@media (max-width: 720px) {
  .o-header { padding: 0 16px; gap: 12px; flex-wrap: wrap; }
  .o-main { padding: 16px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 1ms !important; animation-iteration-count: 1 !important; transition-duration: 1ms !important; }
}
