/* ---------------------------------------------------------------------
   Оформление мини-аппа.

   Вся палитра — в блоке :root ниже. Перекрасить приложение целиком
   значит поправить эти двадцать строк, по остальному файлу цвета
   не раскиданы.

   Тему берём свою, а не из Telegram. Переменные Telegram
   (--tg-theme-bg-color и прочие) в разных клиентах заполнены
   по-разному, и приложение на них выглядит каждый раз иначе.
   --------------------------------------------------------------------- */
:root {
  /* Зима. Фон не нейтрально-чёрный, а с синевой: на нём белый снег
     читается как снег, а не как пыль на экране. */
  --bg:          #060B12;
  --bg-deep:     #04070D;
  --surface:     #0F1621;
  --surface-2:   #16202D;
  --surface-3:   #1E2A3A;
  --line:        rgba(255, 255, 255, .065);
  --line-2:      rgba(255, 255, 255, .13);

  /* текст */
  --ink:         #EEF4FA;
  --ink-dim:     #8FA3B8;
  --ink-faint:   #5A6B7E;

  /* акцент: лёд и морозная дымка */
  --brand:       #58AEFF;
  --brand-2:     #7FE3F5;
  --brand-soft:  rgba(88, 174, 255, .14);
  --brand-line:  rgba(88, 174, 255, .34);

  /* состояния */
  --ok:          #3ED9A8;
  --ok-soft:     rgba(62, 217, 168, .13);
  --warn:        #FFC06A;
  --warn-soft:   rgba(255, 192, 106, .13);
  --bad:         #FF6B7E;
  --bad-soft:    rgba(255, 107, 126, .13);

  /* Завеса над фоновой картинкой. Картинка яркая и с крупным логотипом
     посередине — без затемнения карточки на ней не читаются. Вверху
     тоньше, чтобы фон был виден, внизу плотнее: там панель и длинные
     списки. Крутить яркость фона — этими двумя числами, четвёртый
     разряд ближе к единице делает темнее. */
  --veil-top:    rgba(6, 11, 18, .84);
  --veil-bottom: rgba(4, 7, 13, .94);

  /* Насколько проступает узор на фоне профиля. Узор — это эмодзи,
     размноженное плиткой: заметное, оно лезет в глаза и спорит с именем
     поверх, поэтому держим его на уровне фактуры. Больше число — узор
     виднее, 0 — его нет совсем. */
  --look-pattern-fade: .07;

  /* геометрия */
  --r-sm:        12px;
  /* Верхний отступ экрана. Названо, потому что на него же вылезает
     баннер отрицательным margin — два места должны меняться вместе. */
  --screen-top:  16px;
  --r:           18px;
  --r-lg:        24px;
  --pad:         16px;

  /* движение */
  --ease:        cubic-bezier(.22, .78, .24, 1);
  --fast:        .18s;
  --slow:        .36s;

  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI Variable Text",
          "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  /* Отступы под вырез и домашнюю полоску. Telegram с версии 8.0 отдаёт
     свои значения; где их нет — берём системные env(). */
  --safe-top:    max(env(safe-area-inset-top), var(--tg-safe-area-inset-top, 0px));
  --safe-bottom: max(env(safe-area-inset-bottom), var(--tg-safe-area-inset-bottom, 0px));
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body {
  /* Скроллим не страницу, а .scroll внутри: иначе вебвью Telegram
     закрывает мини-апп на оттяжке вниз. */
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
}

/* Фон висит на html, а не на body, и это важно. Снег и подсветка лежат
   на отрицательных слоях (z-index -1 и -2), а фон body по порядку
   отрисовки идёт ПОЗЖЕ них — непрозрачный body просто закрыл бы собой
   и то и другое. */
html { background: var(--bg); }

body {
  margin: 0;
  background: transparent;
  color: var(--ink);
  font: 400 15px/1.45 var(--font);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  touch-action: manipulation;
}

/* Фон складывается из трёх вещей, сверху вниз: два холодных пятна по
   углам, завеса и сама картинка. Фиксированный, при скролле не едет.
   z-index -2, чтобы снег (-1) шёл поверх фона, но под содержимым.

   Размытия нет намеренно: слой во весь экран с filter: blur пересчитывался
   бы на каждом кадре снега, а это ровно тот случай, когда на телефоне
   начинает дёргаться прокрутка. Картинку глушит завеса, не размытие.

   --fon приезжает из index.html: там в адрес подставляется отпечаток
   статики. Задай мы его здесь, адрес остался бы без версии, а /static/
   отдаётся с immutable на год — подменённый файл не доехал бы до
   телефонов до следующего года. */
body::before {
  content: "";
  position: fixed; inset: 0; z-index: -2; pointer-events: none;
  background:
    radial-gradient(90% 55% at 12% -8%,  rgba(88, 174, 255, .20), transparent 60%),
    radial-gradient(80% 50% at 95% 4%,   rgba(127, 227, 245, .11), transparent 62%),
    linear-gradient(180deg, var(--veil-top) 0%, var(--veil-bottom) 55%),
    /* Без background-attachment: fixed — слой и так на fixed-элементе,
       а на iOS это свойство и тормозит, и местами просто игнорируется. */
    var(--fon, none) center / cover no-repeat,
    var(--bg);
}

/* Снег идёт за всем содержимым и не скроллится. Карточки его закрывают,
   видно в промежутках — как за сообщениями в Telegram. */
.snow {
  position: fixed; inset: 0; z-index: -1;
  width: 100%; height: 100%;
  pointer-events: none;
}
.snow[hidden] { display: none; }

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

svg:not(.sprite) {
  width: 20px; height: 20px;
  fill: none; stroke: currentColor; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
  flex: none;
}

h1, h2, h3, p, ol, ul { margin: 0; }
b, strong { font-weight: 650; }
button { font: inherit; color: inherit; border: 0; background: none; cursor: pointer; }

.num { font-variant-numeric: tabular-nums; }


/* ——— заставка ———————————————————————————————————————————— */
.splash {
  position: fixed; inset: 0; z-index: 50;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 22px;
  background: var(--bg);
  transition: opacity var(--slow) var(--ease);
}
.splash.is-off { opacity: 0; pointer-events: none; }
.splash__note { color: var(--ink-faint); font-size: 13.5px; }

/* ——— знак с логотипом ————————————————————————————————————— */
/* Один вид на заставке и на заслонке: это те два экрана, где человек
   видит сервис до того, как увидит его содержимое. Фон логотипа чёрный
   и совпадает с нашим — шва на скруглении не видно. */
.mark {
  position: relative;
  width: 92px; height: 92px; border-radius: 30px;
  background: var(--surface-2);
  box-shadow: 0 20px 50px -18px rgba(88, 174, 255, .6);
  animation: rise var(--slow) var(--ease) both;
}
.mark--big { width: 108px; height: 108px; border-radius: 34px; }

.mark__img {
  display: block; width: 100%; height: 100%;
  border-radius: inherit; object-fit: cover;
}

/* кольцо вокруг знака медленно дышит */
.mark::after {
  content: ""; position: absolute; inset: -14px;
  border-radius: 42px; border: 1px solid var(--brand-line);
  animation: breathe 3.4s var(--ease) infinite;
}
@keyframes breathe {
  0%, 100% { transform: scale(1);    opacity: .7;  }
  50%      { transform: scale(1.07); opacity: .25; }
}


/* ——— заслонка: открыли не из Telegram ————————————————————— */
/* Показывается вместо всего остального. Фронт при этом не грузится:
   boot.js останавливается до api.js и app.js. */
.gate {
  position: fixed; inset: 0; z-index: 55;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 13px; padding: 36px 28px;
  padding-top: calc(36px + var(--safe-top));
  padding-bottom: calc(36px + var(--safe-bottom));
  background: var(--bg); text-align: center;
}
.gate[hidden] { display: none; }

.gate .mark { margin-bottom: 6px; }
.gate__title {
  font-size: 21px; font-weight: 680; letter-spacing: -.02em;
  animation: rise var(--slow) var(--ease) both; animation-delay: 60ms;
}
.gate__text {
  color: var(--ink-dim); font-size: 14.5px; line-height: 1.5; max-width: 32ch;
  animation: rise var(--slow) var(--ease) both; animation-delay: 105ms;
}
.gate .btn {
  text-decoration: none;
  animation: rise var(--slow) var(--ease) both; animation-delay: 150ms;
}
.gate .btn[hidden] { display: none; }
.gate__note {
  margin-top: 2px; color: var(--ink-faint); font-size: 12.5px; max-width: 30ch;
  animation: rise var(--slow) var(--ease) both; animation-delay: 195ms;
}

/* ——— экран ошибки ————————————————————————————————————————— */
.fatal {
  position: fixed; inset: 0; z-index: 60;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px; padding: 32px 26px;
  padding-bottom: calc(32px + var(--safe-bottom));
  background: var(--bg); text-align: center;
}
.fatal[hidden] { display: none; }
.fatal__ico { width: 44px; height: 44px; color: var(--bad); stroke-width: 1.5; }
.fatal__title { font-size: 19px; font-weight: 650; }
.fatal__text { color: var(--ink-dim); font-size: 14.5px; max-width: 30ch; }
.fatal__raw {
  max-width: 100%; max-height: 32vh; overflow: auto; margin: 4px 0 0;
  padding: 10px 12px; border: 1px solid var(--line);
  border-radius: var(--r-sm); background: var(--surface);
  color: var(--ink-faint); font: 400 11.5px/1.5 var(--mono);
  text-align: left; white-space: pre-wrap; word-break: break-word;
}


/* ——— каркас ——————————————————————————————————————————————— */
/* position: relative — чтобы плавающая нижняя панель считала свои
   края от окна приложения, а не от страницы целиком. */
.app { position: relative; display: flex; flex-direction: column; height: 100%; }
.app[hidden] { display: none; }

.top {
  display: flex; align-items: center; gap: 12px;
  padding: calc(var(--safe-top) + 12px) var(--pad) 12px;
  background: linear-gradient(180deg, rgba(8, 10, 15, .92), rgba(8, 10, 15, .55));
  -webkit-backdrop-filter: blur(18px) saturate(150%);
          backdrop-filter: blur(18px) saturate(150%);
  border-bottom: 1px solid var(--line);
  flex: none;
}
/* Кнопка, а не блок: левая половина шапки ведёт в профиль. Сбрасываем
   всё, что браузер рисует у кнопок по умолчанию, и оставляем отклик
   на нажатие — иначе непонятно, что сюда можно тыкать. */
.top__who {
  display: flex; align-items: center; gap: 11px; min-width: 0; flex: 1;
  margin: -6px -8px; padding: 6px 8px;
  border: 0; border-radius: 14px; background: none;
  color: inherit; font: inherit; text-align: left; cursor: pointer;
  /* Сжатие при нажатии даёт класс .tap — здесь только подсветка */
  transition: background var(--fast) var(--ease);
}
.top__who:active { background: rgba(255, 255, 255, .05); }
.top__who:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.top__text { display: flex; flex-direction: column; min-width: 0; }
.top__hi {
  font-size: 15px; font-weight: 650; letter-spacing: -.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.top__sub { color: var(--ink-faint); font-size: 12.5px; }

.avatar {
  width: 38px; height: 38px; border-radius: 13px; flex: none;
  display: grid; place-items: center;
  background: linear-gradient(145deg, var(--brand), var(--brand-2));
  box-shadow: 0 4px 14px rgba(88, 174, 255, .3);
  color: #fff; font-size: 15px; font-weight: 650;
  background-size: cover; background-position: center;
  overflow: hidden;
}
.avatar.has-photo span { display: none; }

/* Значок сервиса справа в шапке. Логотип квадратный — скругляем здесь.
   Тонкая обводка нужна: логотип почти чёрный и без неё растворяется
   в шапке. */
.brandmark {
  width: 34px; height: 34px; flex: none;
  border-radius: 11px; object-fit: cover;
  border: 1px solid var(--line-2);
  box-shadow: 0 2px 10px rgba(0, 0, 0, .5);
}

.scroll {
  flex: 1; min-height: 0;
  overflow-y: auto; overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain;
}

.screen {
  display: flex; flex-direction: column; gap: 10px;
  padding: var(--screen-top) var(--pad) 0;
  /* место под плавающую панель: её высота плюс отступ снизу */
  padding-bottom: calc(100px + var(--safe-bottom));
}
.screen[hidden] { display: none; }

.head {
  margin: 12px 2px 2px;
  font-size: 12.5px; font-weight: 650;
  letter-spacing: .07em; text-transform: uppercase;
  color: var(--ink-faint);
}
.foot {
  margin: 14px 2px 0;
  color: var(--ink-faint); font-size: 12px; text-align: center;
}


/* ——— карточки ————————————————————————————————————————————— */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
}

/* Пропорции задаёт сам файл (1280×427), а не наоборот: баннер — готовая
   композиция, фонари по краям и снеговик по центру. Обрезка под более
   высокий прямоугольник отрезала бы края.

   Во всю ширину — значит вылезти из отступов .screen: вверх на padding-top,
   по бокам на --pad. Поэтому скруглений и боковой обводки нет, они висели
   бы за краем экрана; от прежней рамки осталась нижняя волосяная линия —
   она отделяет картинку от содержимого. */
.banner {
  position: relative; overflow: hidden;
  margin: calc(var(--screen-top) * -1) calc(var(--pad) * -1) 2px;
  aspect-ratio: 1280 / 427;
  border-bottom: 1px solid var(--brand-line);
  /* цвет взят из самого баннера: пока картинка едет, на её месте
     не дыра, а тёмно-синее поле ровно того же тона */
  background: linear-gradient(170deg, #0C1B33, #061020);
  box-shadow: 0 18px 44px -26px rgba(88, 174, 255, .55);
}
.banner__img {
  display: block; width: 100%; height: 100%;
  /* страховка: при дробной ширине экрана коробка округлится, картинка нет */
  object-fit: cover;
}

/* ——— счётчики под баннером ——————————————————————————————————— */
.tally {
  border-radius: var(--r);
  border: 1px solid var(--line);
  background: var(--surface);
  overflow: hidden;
}
.tally__row { display: flex; gap: 10px; padding: 13px 14px; }
.tally__cell { display: flex; flex-direction: column; gap: 3px; flex: 1; min-width: 0; }
.tally__cell i { color: var(--ink-faint); font-size: 11.5px; font-style: normal; }
.tally__cell b {
  font-size: 19px; font-weight: 650; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}
/* Статус — отдельной строкой, а не третьей колонкой: подписи вроде
   «ждём второй файл» в треть ширины не помещаются. */
.tally__now {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 14px;
  border-top: 1px solid var(--line);
  background: rgba(255, 255, 255, .02);
}
.tally__now span { color: var(--ink-faint); font-size: 12px; }
.tally__now b {
  min-width: 0; font-size: 13px; font-weight: 600; color: var(--ink-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}


/* ——— сетка услуг ——————————————————————————————————————————— */
.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

.svc {
  display: flex; flex-direction: column; gap: 7px;
  padding: 14px; text-align: left;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r);
  transition: border-color var(--fast) var(--ease),
              background var(--fast) var(--ease),
              transform var(--fast) var(--ease);
}
.svc:active { transform: scale(.975); border-color: var(--brand-line); }
.svc__ico {
  width: 36px; height: 36px; border-radius: 11px;
  display: grid; place-items: center;
  background: var(--brand-soft); color: var(--brand);
}
.svc__ico svg { width: 19px; height: 19px; }
.svc__text { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.svc__title { font-size: 14px; font-weight: 600; letter-spacing: -.01em; }
.svc__hint { color: var(--ink-faint); font-size: 11.5px; line-height: 1.35; }
.svc__price {
  margin-top: auto; padding-top: 4px;
  font-size: 13px; font-weight: 650; color: var(--brand);
  font-variant-numeric: tabular-nums;
}
.svc--admin .svc__ico { background: var(--warn-soft); color: var(--warn); }

/* Клиентский товар один, и он занимает обе колонки: значок слева,
   цена справа, остальное посередине. Админские инструменты под ним
   так и ложатся парами. */
.svc--wide {
  grid-column: 1 / -1;
  flex-direction: row; align-items: center; gap: 14px;
  padding: 15px 16px;
}
.svc--wide .svc__ico { width: 46px; height: 46px; border-radius: 15px; }
.svc--wide .svc__ico svg { width: 24px; height: 24px; }
.svc--wide .svc__text { flex: 1; }
.svc--wide .svc__price {
  margin: 0; padding: 0; flex: none;
  font-size: 15px; white-space: nowrap;
}


/* ——— шаги ————————————————————————————————————————————————— */
.steps {
  counter-reset: step; list-style: none; padding: 4px 0; margin: 0;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
}
.steps li {
  position: relative;
  display: flex; flex-direction: column; gap: 1px;
  padding: 11px 14px 11px 50px;
}
.steps li + li { border-top: 1px solid var(--line); }
.steps li::before {
  counter-increment: step; content: counter(step);
  position: absolute; left: 14px; top: 11px;
  width: 24px; height: 24px; border-radius: 8px;
  display: grid; place-items: center;
  background: var(--brand-soft); color: var(--brand);
  font-size: 12px; font-weight: 650;
}
.steps li b { font-size: 14px; }
.steps li span { color: var(--ink-faint); font-size: 12.5px; }


/* ——— строки «ключ — значение» ————————————————————————————— */
.rows { padding: 2px 0; }
.rows__row { display: flex; align-items: center; gap: 10px; padding: 11px 14px; }
.rows__row + .rows__row { border-top: 1px solid var(--line); }
.rows__row i { flex: 1; font-style: normal; color: var(--ink-dim); font-size: 13.5px; }
.rows__row b {
  font-size: 13.5px; font-weight: 600; text-align: right;
  font-variant-numeric: tabular-nums;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 58%;
}


/* ——— профиль ——————————————————————————————————————————————— */
/* Шапка вылезает за поля экрана: подложка должна доходить до его краёв,
   иначе получится картинка в рамке, а не фон. */
.me {
  position: relative; isolation: isolate; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  margin: -16px calc(var(--pad) * -1) 0;
  padding: 28px var(--pad) 24px;
}

/* Цвет и узор из профиля Telegram. Пока /api/look не ответил — прозрачны,
   поэтому профиль рисуется сразу и не ждёт похода в Bot API. */
.me__bg, .me__pattern {
  position: absolute; inset: 0; z-index: -1;
  opacity: 0; transition: opacity .55s var(--ease);
  /* книзу растворяется, как это сделано в самом Telegram */
  -webkit-mask-image: linear-gradient(180deg, #000 46%, transparent);
          mask-image: linear-gradient(180deg, #000 46%, transparent);
}
.me__bg {
  background: linear-gradient(165deg, var(--look-a, transparent),
                                      var(--look-b, transparent));
}
.me__pattern {
  background-image: var(--look-pattern, none);
  background-repeat: repeat;
  background-size: 42px 42px;
}
.me.has-look .me__bg { opacity: 1; }
.me.has-pattern .me__pattern { opacity: var(--look-pattern-fade); }
.me__avatar {
  width: 78px; height: 78px; border-radius: 26px; margin-bottom: 10px;
  display: grid; place-items: center;
  background: linear-gradient(145deg, var(--brand), var(--brand-2));
  background-size: cover; background-position: center;
  box-shadow: 0 14px 34px -14px rgba(88, 174, 255, .7);
  color: #fff; font-size: 28px; font-weight: 650;
  overflow: hidden;
}
.me__avatar.has-photo span { display: none; }
.me__name { font-size: 20px; font-weight: 680; letter-spacing: -.02em; }
.me__sub { color: var(--ink-faint); font-size: 13px; }


/* ——— плитки сводки ————————————————————————————————————————— */
/* ——— кнопки-строки в админке ———————————————————————————————— */
/* Группы разделены воздухом, а не заголовками: «Управление» над тремя
   кнопками ничего не добавляет к тому, что на них написано. */
.acts { display: flex; flex-direction: column; gap: 10px; }
/* 18 сверху плюс 10 от .screen — между группами выходит 28 точек против
   10 внутри группы. Меньше — и разрыв читается как случайный отступ. */
.acts--sep { margin-top: 18px; }

.act {
  display: flex; align-items: center; gap: 13px;
  padding: 13px 15px; text-align: left;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r);
  color: inherit; font: inherit; cursor: pointer;
  transition: border-color var(--fast) var(--ease);
}
.act:active { border-color: var(--brand-line); }
.act__ico {
  width: 38px; height: 38px; border-radius: 12px; flex: none;
  display: grid; place-items: center;
  background: var(--warn-soft); color: var(--warn);
}
.act__ico svg { width: 20px; height: 20px; }
.act__title {
  flex: 1; min-width: 0;
  font-size: 14.5px; font-weight: 600; letter-spacing: -.01em;
}
.act__go { color: var(--ink-faint); width: 18px; height: 18px; }
/* Чаты стоят отдельной группой — и цветом тоже, чтобы воздух между
   группами читался как граница, а не как случайный отступ. */
.act--talk .act__ico { background: var(--brand-soft); color: var(--brand); }

/* ——— назад с подэкрана ——————————————————————————————————————— */
.back {
  display: inline-flex; align-items: center; gap: 4px;
  align-self: flex-start;
  margin: 0 0 2px -6px; padding: 6px;
  border: 0; border-radius: 10px; background: none;
  color: var(--ink-dim); font: inherit; font-size: 13.5px; cursor: pointer;
  transition: color var(--fast) var(--ease);
}
.back:active { color: var(--ink); }
.back svg { width: 17px; height: 17px; transform: rotate(180deg); }

.tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.tile {
  padding: 14px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
}
.tile i {
  display: block; font-style: normal; margin-bottom: 4px;
  color: var(--ink-faint); font-size: 11.5px;
}
.tile b {
  display: block;
  font-size: 23px; font-weight: 700; letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
}
.tile small { color: var(--ink-faint); font-size: 11.5px; }
.tile--accent { border-color: var(--brand-line); background: var(--brand-soft); }
.tile--accent b { color: #B9C6FF; }


/* ——— список заявок ————————————————————————————————————————— */
.job {
  display: flex; align-items: center; gap: 12px;
  padding: 13px 14px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
}
.job + .job { margin-top: 8px; }
.job__ico { position: relative; width: 46px; height: 46px; flex: none; }

/* Углы режем обрезкой, а не подложкой: значок банка может прийти и
   квадратным, и уже скруглённым. Прозрачные углы так и остаются
   прозрачными, прямые — обрезаются. */
.job__bank {
  display: block; width: 100%; height: 100%;
  border-radius: 15px; object-fit: cover;
}
/* Банк незнакомый — домик в такой же плитке. Отступ и толщину линии
   задаём явно: иконка нарисована под 20 точек, а здесь ей двадцать
   четыре, и тонкая линия на сером фоне просто пропадала. */
.job__ico > svg {
  width: 100%; height: 100%; padding: 11px; border-radius: 15px;
  background: var(--surface-3); color: var(--ink-dim);
  stroke-width: 1.5;
}

/* Состояние заявки — кружком поверх правого нижнего угла, как метка
   у аватара. Обводка цветом карточки вырезает его из значка. */
.job__state {
  position: absolute; right: -3px; bottom: -3px;
  width: 21px; height: 21px; border-radius: 50%;
  display: grid; place-items: center;
  border: 2px solid var(--surface);
  background: var(--surface-3); color: var(--ink-dim);
}
.job__state svg { width: 12px; height: 12px; }
.job--done .job__state { background: var(--ok);   color: #05241B; }
.job--wait .job__state { background: var(--warn); color: #3B2604; }
.job--dead .job__state { background: var(--bad);  color: #320811; }

.job__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.job__title {
  font-size: 15px; font-weight: 600; letter-spacing: -.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.job__meta {
  color: var(--ink-faint); font-size: 12px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.job__price {
  font-size: 14px; font-weight: 650; flex: none;
  font-variant-numeric: tabular-nums;
}


/* ——— пустые состояния и скелетоны ————————————————————————— */
.empty {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 44px 24px; text-align: center;
  border: 1px dashed var(--line-2); border-radius: var(--r);
  color: var(--ink-faint);
}
.empty svg { width: 30px; height: 30px; color: var(--ink-faint); stroke-width: 1.4; }
.empty b { color: var(--ink-dim); font-size: 14.5px; }
.empty span { font-size: 12.5px; max-width: 28ch; }

.skel {
  border-radius: var(--r); height: 66px;
  background: linear-gradient(100deg, var(--surface) 20%, var(--surface-2) 38%,
                                      var(--surface) 56%);
  background-size: 220% 100%;
  animation: shimmer 1.3s linear infinite;
}
.skel + .skel { margin-top: 8px; }
@keyframes shimmer {
  from { background-position: 130% 0; }
  to   { background-position: -30% 0; }
}


/* ——— кнопки ———————————————————————————————————————————————— */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 13px 20px; border-radius: 14px;
  background: linear-gradient(145deg, var(--brand), #4ED4EE);
  color: #fff; font-size: 15px; font-weight: 620;
  box-shadow: 0 10px 26px -12px rgba(88, 174, 255, .9);
}
.btn--wide { width: 100%; max-width: 300px; margin-top: 12px; }
.btn__ico { width: 18px; height: 18px; stroke-width: 2; }
.tap { transition: transform var(--fast) var(--ease), opacity var(--fast) var(--ease); }
.tap:active { transform: scale(.96); opacity: .9; }


/* ——— нижняя панель ————————————————————————————————————————— */
/* Плавающая таблетка поверх содержимого, без подписей: названия держат
   иконки, а разделов немного. Место под неё отведено снизу в .screen.

   При прокрутке вниз панель поджимается — так она меньше закрывает
   список. Возвращается, когда человек почти наверху: один порог на
   сжатие и другой на возврат, иначе на границе она дрожала бы.      */
.tabs {
  position: absolute; z-index: 10;
  left: 12px; right: 12px;
  bottom: calc(10px + var(--safe-bottom));
  display: flex; gap: 2px; padding: 6px;
  border-radius: 28px;
  background: rgba(21, 26, 35, .84);
  -webkit-backdrop-filter: blur(22px) saturate(160%);
          backdrop-filter: blur(22px) saturate(160%);
  border: 1px solid var(--line-2);
  box-shadow: 0 18px 44px -20px rgba(0, 0, 0, .95);
  transform-origin: bottom center;
  transition: transform .34s var(--ease);
}
.tabs.is-small { transform: scale(.86); }

/* Подложка активной вкладки едет одним элементом — так переход читается
   как движение, а не как перекраска двух кнопок. */
.tabs__pill {
  position: absolute; top: 6px; left: 0;
  height: 56px; border-radius: 20px;
  background: rgba(255, 255, 255, .085);
  transition: transform var(--slow) var(--ease), width var(--slow) var(--ease),
              opacity var(--fast) var(--ease);
  pointer-events: none;
}
.tab {
  position: relative; z-index: 1;
  flex: 1; min-width: 0;
  display: grid; place-items: center;
  height: 56px; border-radius: 20px;
  color: var(--ink-faint);
  transition: color var(--fast) var(--ease), transform var(--fast) var(--ease);
}
.tab[hidden] { display: none; }
.tab:active { transform: scale(.89); }
.tab:focus-visible { outline: 2px solid var(--brand); outline-offset: -3px; }
.tab__ico { width: 25px; height: 25px; }
.tab.is-on { color: var(--ink); }
.tab.is-on .tab__ico { stroke-width: 2; }


/* ——— появление ————————————————————————————————————————————— */
.rise { animation: rise var(--slow) var(--ease) both; animation-delay: calc(var(--i, 0) * 45ms); }
@keyframes rise {
  from { opacity: 0; transform: translate3d(0, 14px, 0); }
  to   { opacity: 1; transform: none; }
}

/* Кому движение мешает — отдаём статику. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* Планшет и широкий десктоп Telegram: колонка по центру, а не растянутая
   на всю ширину — две плитки в ряд на 1200px выглядели бы абсурдно. */
@media (min-width: 560px) {
  .scroll > .screen { max-width: 520px; margin: 0 auto; width: 100%; }
  .top { max-width: 520px; margin: 0 auto; width: 100%; }
  /* Панель лежит абсолютно, поэтому центрируется нулевыми краями
     и автополями, а не transform: его занимает сжатие при прокрутке. */
  .tabs { left: 0; right: 0; width: 496px; margin-inline: auto; }
  .grid, .tiles { grid-template-columns: repeat(3, 1fr); }
}
