/*
 * app.css — оформление Mini App: токены темы, компоненты формы, две шкуры.
 *
 * Порядок правил значим: скиновые переопределения идут ПОСЛЕ базовых, а
 * блок наведения — последним, иначе более специфичные правила перебивают
 * подсветку (уже ловили это на подсказках и крестиках).
 */
  :root {
    --bg: var(--tg-theme-bg-color, #ffffff);
    --bg2: var(--tg-theme-secondary-bg-color, #f2f2f7);
    --text: var(--tg-theme-text-color, #1c1c1e);
    --hint: var(--tg-theme-hint-color, #8e8e93);
    --accent: var(--tg-theme-button-color, #2481cc);
    --accent-text: var(--tg-theme-button-text-color, #ffffff);
    --danger: #e53935;
    --ok: #34c759;
    --radius: 14px;
    --shadow: 0 1px 3px rgba(0, 0, 0, .06);
  }


  /* ── Бета: предложение заполнить форму по счёту ─────────────────────── */
  .autofill {
    margin-top: 12px;
    /* Без нижнего отступа блок вставал вплотную к кнопкам ниже и читался
       как наложение. */
    margin-bottom: 14px;
    padding: 13px 14px;
    border-radius: 12px;
    border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
    background: color-mix(in srgb, var(--accent) 9%, var(--bg));
    animation: rise .3s ease;
  }
  .autofill-head {
    display: flex; align-items: center; gap: 8px;
    font-size: 14px; font-weight: 650; margin-bottom: 10px;
  }
  .beta {
    font-size: 10px; font-weight: 700; letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--accent-text);
    background: var(--accent);
    padding: 2px 7px; border-radius: 999px;
  }
  /* Та же причина: предупреждение автопроверки липло к кнопкам. */
  #file-warn:not(.hidden) { margin-bottom: 14px; }

  .autofill-list { display: grid; gap: 10px; }
  .autofill-field { display: grid; gap: 4px; }
  .autofill-field label {
    font-size: 12px; color: var(--hint);
  }
  .autofill-field input, .autofill-field textarea {
    font-size: 15px;
    padding: 9px 11px;
  }
  .autofill-field textarea { resize: vertical; min-height: 74px; }
  .autofill-note {
    font-size: 12.5px; color: var(--hint);
    display: flex; gap: 8px;
  }
  .autofill-note b { color: var(--text); font-weight: 600; }

  /* ── Экран «Оформление» ─────────────────────────────────────────────── */
  .skin-options { display: grid; gap: 10px; }
  @media (min-width: 460px) { .skin-options { grid-template-columns: 1fr 1fr; } }
  .skin-opt {
    display: grid;
    gap: 6px;
    text-align: left;
    padding: 14px;
    border-radius: 12px;
    border: 1.5px solid color-mix(in srgb, var(--hint) 30%, transparent);
    background: var(--bg2);
    color: var(--text);
    font: inherit;
    cursor: pointer;
    transition: border-color .2s ease, transform .12s ease, background .2s ease;
  }
  .skin-opt:active { transform: scale(.98); }
  .skin-opt.active {
    border-color: var(--accent);
    background: color-mix(in srgb, var(--accent) 12%, var(--bg2));
  }
  .skin-opt:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
  .skin-name { font-weight: 650; font-size: 15px; }
  .skin-desc { font-size: 12.5px; color: var(--hint); line-height: 1.4; }
  /* Образец темы: три полосы — фон, поверхность, акцент. */
  .skin-swatch { display: flex; gap: 4px; height: 34px; margin-bottom: 4px; }
  .skin-swatch i { flex: 1; border-radius: 7px; }
  .sw-tg i:nth-child(1) { background: #f2f2f7; }
  .sw-tg i:nth-child(2) { background: #ffffff; border: 1px solid #e3e3e8; }
  .sw-tg i:nth-child(3) { background: #2481cc; }
  .sw-neon i:nth-child(1) { background: #05080A; }
  .sw-neon i:nth-child(2) { background: #131A1D; }
  .sw-neon i:nth-child(3) { background: #10B981; box-shadow: 0 0 12px rgba(16,185,129,.65); }
  /* ── Скин «Неон»: второй вариант оформления ───────────────────────────
     Переопределяем ТОЛЬКО токены — вся остальная вёрстка написана через
     них, поэтому новая тема не требует ни одного дубля правил.
     Выбор запоминается в localStorage (invoice_skin_v1).              */
  :root[data-skin="neon"] {
    --bg: #0B1114;
    --bg2: #05080A;
    --text: #E9F1EE;
    --hint: #8FA09B;
    --accent: #10B981;          /* изумруд, а не мята */
    --accent-text: #04140D;
    --danger: #F08672;
    --ok: #10B981;
    --shadow: 0 10px 30px -18px rgba(0, 0, 0, .9);
  }
  /* Цветные пятна — часть «телеграмного» скина; в неоне их место занимает
     живое полотно, иначе два фона спорят друг с другом. */
  :root[data-skin="neon"] .bg { display: none; }
  /* Мятная дымка по фону: плоская чернота выглядит пусто, а мята рядом с
     изумрудным акцентом даёт глубину, не перетягивая внимание.
     Слои закреплены (fixed) — при прокрутке подсветка остаётся на месте. */
  :root[data-skin="neon"] body {
    background:
      radial-gradient(115% 70% at 50% -8%,  rgba(110, 231, 183, .20), transparent 62%),
      radial-gradient(85% 55% at 105% 22%,  rgba(47, 211, 162, .14), transparent 66%),
      radial-gradient(90% 60% at -10% 78%,  rgba(16, 185, 129, .13), transparent 68%),
      linear-gradient(180deg, #071013 0%, #05080A 55%, #061012 100%);
    background-attachment: fixed;
  }
  :root[data-skin="neon"] .card {
    border-color: rgba(255, 255, 255, .08);
    background: rgba(255, 255, 255, .04);
  }
  :root[data-skin="neon"] .seg button:not(.active):not(:hover) {
    background: rgba(255, 255, 255, .06);
  }
  :root[data-skin="neon"] .chip,
  :root[data-skin="neon"] .chip-x { background: rgba(255, 255, 255, .06); }
  :root[data-skin="neon"] .chip { color: var(--text); }
  :root[data-skin="neon"] .drop { border-color: rgba(255, 255, 255, .18); }
  /* В неоне подложку несёт панель целиком: у каждой кнопки своя давала
     «кнопки внутри кнопки». */
  :root[data-skin="neon"] .gears { background: rgba(255, 255, 255, .06); }
  :root[data-skin="neon"] .gear { background: none; }
  /* Поля ввода: на почти чёрном фоне им нужна своя поверхность и граница,
     иначе они сливаются со страницей и перестают читаться как поля. */
  :root[data-skin="neon"] input[type=text],
  :root[data-skin="neon"] input[type=date],
  :root[data-skin="neon"] input[type=time],
  :root[data-skin="neon"] textarea {
    background: rgba(255, 255, 255, .05);
    border-color: rgba(255, 255, 255, .09);
    color-scheme: dark;
  }

  #skin-field {
    position: fixed;
    inset: 0;
    z-index: -1;              /* над цветными пятнами .bg, под контентом */
    width: 100%;
    height: 100%;
    display: block;
    pointer-events: none;
    opacity: .5;              /* телеграмная тема: сеть лишь угадывается */
    transition: opacity .3s ease;
  }
  :root[data-skin="neon"] #skin-field { opacity: .75; }
  * { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }
  html, body { height: 100%; }
  body {
    background: var(--bg2);
    color: var(--text);
    font: 16px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
    -webkit-font-smoothing: antialiased;
    padding: 16px 16px 104px;
    overflow-x: hidden;
  }

  /* ---------- Анимированный фон (aurora) ---------- */
  .bg {
    position: fixed;
    inset: 0;
    z-index: -1;
    overflow: hidden;
    pointer-events: none;
  }
  .blob {
    position: absolute;
    width: 68vw;
    height: 68vw;
    min-width: 380px;
    min-height: 380px;
    border-radius: 50%;
    filter: blur(58px);
    opacity: .38;
    will-change: transform;
  }
  /* В тёмной теме пятна «светятся» поверх фона, иначе они тонут в темноте. */
  body[data-theme="dark"] .blob {
    opacity: .55;
    mix-blend-mode: screen;
  }
  .b1 {
    top: -18vw; left: -14vw;
    background: radial-gradient(circle at 35% 35%,
      var(--accent) 0%,
      color-mix(in srgb, var(--accent) 70%, transparent) 40%,
      transparent 72%);
    animation: drift1 34s ease-in-out infinite alternate;
  }
  .b2 {
    top: 26%; right: -22vw;
    background: radial-gradient(circle at 60% 40%,
      color-mix(in srgb, var(--accent) 25%, #8a5cff) 0%,
      color-mix(in srgb, #8a5cff 55%, transparent) 42%,
      transparent 72%);
    animation: drift2 44s ease-in-out infinite alternate;
  }
  .b3 {
    bottom: -20vw; left: 8vw;
    background: radial-gradient(circle at 45% 55%,
      color-mix(in srgb, var(--accent) 20%, #2fd6a7) 0%,
      color-mix(in srgb, #2fd6a7 55%, transparent) 42%,
      transparent 72%);
    animation: drift3 39s ease-in-out infinite alternate;
  }
  @keyframes drift1 {
    from { transform: translate3d(0, 0, 0) scale(1); }
    to   { transform: translate3d(16vw, 12vh, 0) scale(1.25); }
  }
  @keyframes drift2 {
    from { transform: translate3d(0, 0, 0) scale(1.15) rotate(0deg); }
    to   { transform: translate3d(-14vw, -10vh, 0) scale(.9) rotate(40deg); }
  }
  @keyframes drift3 {
    from { transform: translate3d(0, 0, 0) scale(.95); }
    to   { transform: translate3d(10vw, -14vh, 0) scale(1.2); }
  }

  /* ---------- Появление ---------- */
  @keyframes rise {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: none; }
  }
  header { animation: rise .4s cubic-bezier(.22,1,.36,1) backwards; }
  .card:nth-of-type(1) { animation-delay: .05s; }
  .card:nth-of-type(2) { animation-delay: .11s; }
  .card:nth-of-type(3) { animation-delay: .17s; }
  .card:nth-of-type(4) { animation-delay: .23s; }

  /* padding-right уточняет layoutHeaderIcons() по числу ВИДИМЫХ иконок:
     базовое значение — на две всегда видимые (инструкция и «Мои заявки»). */
  /* Отступ под панель кнопок — не на всей шапке, а только на строке с героем
     (.brand ниже): панель стоит на её уровне и подписи не мешает, а общий
     отступ ужимал подпись вдвое и ломал её на две строки. Здесь запасное
     значение на время до первого замера в layoutHeaderIcons. */
  header { margin: 4px 2px 16px; position: relative; }
  h1 { font-size: 21px; letter-spacing: -.02em; }
  /* Имя бота — крупнее прочих заголовков: это единственная «вывеска» в
     приложении. Всё в em, поэтому марка ужимается вместе с надписью. */
  /* Подложки под персонажем нет — фон шапки общий со страницей. Поля
     сверху оставлены по делу: без них на подъёме герой упирался ушами
     в край экрана. */
  .brand {
    display: flex;
    align-items: flex-end;
    justify-content: center;
    margin: 0;
    min-height: 96px;
    padding: 4px 92px 0 8px;
  }

  /* Кнопки собраны в панель, поэтому кегль заголовка больше ни на что не
     влияет: при пяти иконках ужимается сама марка, а не надпись. */
  header.icons-5 .mark { height: 82px; }
  @media (max-width: 400px) {
    .mark { height: 82px; }
    header.icons-5 .mark { height: 74px; }
    .brand { min-height: 86px; }
  }
  /* text-wrap: balance — чтобы подзаголовок не оставлял одно слово на
     последней строке. Строки распределяются ровно; браузеры без поддержки
     свойство игнорируют и переносят как раньше. */
  header p {
    color: var(--hint);
    font-size: 14px;
    margin-top: 2px;
    text-wrap: balance;
  }

  /* Носитель градиентов марки: в потоке не участвует, но отрисовывается —
     иначе браузер не отдаёт из него заливки. */
  .svg-defs { position: absolute; width: 0; height: 0; overflow: hidden; }

  /* Имя больше не показывается: его место занял персонаж. В разметке
     оставлено — без него у экрана нет заголовка для скринридера. */
  .brand-name {
    position: absolute; width: 1px; height: 1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
  }

  /* Полноростовая марка: высота в пикселях, потому что персонаж стоит на
     месте и его размер больше не зависит от кегля заголовка. */
  .mark {
    height: 92px;
    width: auto;
    flex: none;
    overflow: visible;
  }

  /* ---------- Оживление марки ----------
     Полный круг: шесть замахов, лайк, пауза. Длительность одна на все
     дорожки — иначе фазы разъезжаются и лист уходит мимо взмаха. */
  /* --fly — множитель разлёта листов. Дуги заданы в единицах рисунка и
     растут вместе с героем, поэтому в пикселях они зависят и от размера
     марки, и от свободной ширины. Точное значение выставляет
     layoutHeaderIcons(): брейкпоинтами это не угадать — ширина зависит ещё
     и от числа видимых кнопок. */
  header { --mark-cycle: 5.4s; --fly: 1; }

  /* ---------- Рига ---------- */
  #mk-thumb, #mk-wink { opacity: 0; }
  #mk-body, #mk-leg-l, #mk-leg-r, #mk-ear-l, #mk-ear-r, .pup,
  #mk-eye-r, #mk-thumb, #mk-paw-free, #mk-shadow { transform-box: fill-box; }
  #mk-body { transform-origin: 50% 92%; }
  #mk-leg-l, #mk-leg-r { transform-origin: 50% 2%; }
  #mk-ear-l, #mk-ear-r { transform-origin: 50% 90%; }
  #mk-eye-r { transform-origin: 50% 50%; }
  #mk-thumb { transform-origin: 50% 90%; }
  /* Рука на лайке повёрнута — кулак доворачиваем обратно, чтобы палец
     смотрел строго вверх. */
  #mk-thumb > * { transform-box: view-box; transform-origin: 68px 396px; }
  #mk-paw-free { transform-origin: 62% 34%; }
  #mk-shadow { transform-origin: 50% 50%; }
  .paper { transform-box: fill-box; transform-origin: 50% 50%; opacity: 0; }
  /* Оси — в плечах. transform-box: view-box отсчитывает от начала viewBox
     (64,74), поэтому из координат рисунка вычтено это смещение:
     плечо (176,436) → 112px 362px, плечо (330,438) → 266px 364px. */
  #mk-arm-free { transform-box: view-box; transform-origin: 176px 436px; }
  #mk-paw-doc  { transform-box: view-box; transform-origin: 330px 438px; }

  @keyframes paper-1 {
    0%, 8.0%   { opacity: 0; transform: translate(0,0) rotate(0deg) scale(.45); }
    10.5%   { opacity: 1; transform: translate(calc(var(--fly) * -139px), calc(var(--fly) * -15px)) rotate(-9deg) scale(1); }
    23.6% { opacity: .95; transform: translate(calc(var(--fly) * -526px), calc(var(--fly) * -46px)) rotate(-28deg) scale(.98); }
    34.0%   { opacity: 0; transform: translate(calc(var(--fly) * -773px), calc(var(--fly) * -27px)) rotate(-40deg) scale(.9); }
    100%        { opacity: 0; transform: translate(0,0) rotate(0deg) scale(.45); }
  }
  @keyframes paper-2 {
    0%, 9.5%   { opacity: 0; transform: translate(0,0) rotate(0deg) scale(.45); }
    12.0%   { opacity: 1; transform: translate(calc(var(--fly) * -118px), calc(var(--fly) * -61px)) rotate(-19deg) scale(1); }
    25.1% { opacity: .95; transform: translate(calc(var(--fly) * -447px), calc(var(--fly) * -190px)) rotate(-59deg) scale(.98); }
    35.5%   { opacity: 0; transform: translate(calc(var(--fly) * -658px), calc(var(--fly) * -114px)) rotate(-85deg) scale(.9); }
    100%        { opacity: 0; transform: translate(0,0) rotate(0deg) scale(.45); }
  }
  @keyframes paper-3 {
    0%, 20.0%   { opacity: 0; transform: translate(0,0) rotate(0deg) scale(.45); }
    22.5%   { opacity: 1; transform: translate(calc(var(--fly) * -75px), calc(var(--fly) * -95px)) rotate(-29deg) scale(1); }
    35.6% { opacity: .95; transform: translate(calc(var(--fly) * -283px), calc(var(--fly) * -300px)) rotate(-91deg) scale(.98); }
    46.0%   { opacity: 0; transform: translate(calc(var(--fly) * -417px), calc(var(--fly) * -180px)) rotate(-130deg) scale(.9); }
    100%        { opacity: 0; transform: translate(0,0) rotate(0deg) scale(.45); }
  }
  @keyframes paper-4 {
    0%, 21.5%   { opacity: 0; transform: translate(0,0) rotate(0deg) scale(.45); }
    24.0%   { opacity: 1; transform: translate(calc(var(--fly) * -130px), calc(var(--fly) * -37px)) rotate(-13deg) scale(1); }
    37.1% { opacity: .95; transform: translate(calc(var(--fly) * -494px), calc(var(--fly) * -115px)) rotate(-42deg) scale(.98); }
    47.5%   { opacity: 0; transform: translate(calc(var(--fly) * -726px), calc(var(--fly) * -70px)) rotate(-60deg) scale(.9); }
    100%        { opacity: 0; transform: translate(0,0) rotate(0deg) scale(.45); }
  }
  @keyframes paper-5 {
    0%, 32.0%   { opacity: 0; transform: translate(0,0) rotate(0deg) scale(.45); }
    34.5%   { opacity: 1; transform: translate(calc(var(--fly) * -97px), calc(var(--fly) * -80px)) rotate(-23deg) scale(1); }
    47.6% { opacity: .95; transform: translate(calc(var(--fly) * -366px), calc(var(--fly) * -248px)) rotate(-74deg) scale(.98); }
    58.0%   { opacity: 0; transform: translate(calc(var(--fly) * -538px), calc(var(--fly) * -149px)) rotate(-105deg) scale(.9); }
    100%        { opacity: 0; transform: translate(0,0) rotate(0deg) scale(.45); }
  }
  @keyframes paper-6 {
    0%, 33.5%   { opacity: 0; transform: translate(0,0) rotate(0deg) scale(.45); }
    36.0%   { opacity: 1; transform: translate(calc(var(--fly) * -46px), calc(var(--fly) * -104px)) rotate(-33deg) scale(1); }
    49.1% { opacity: .95; transform: translate(calc(var(--fly) * -174px), calc(var(--fly) * -323px)) rotate(-105deg) scale(.98); }
    59.5%   { opacity: 0; transform: translate(calc(var(--fly) * -255px), calc(var(--fly) * -194px)) rotate(-150deg) scale(.9); }
    100%        { opacity: 0; transform: translate(0,0) rotate(0deg) scale(.45); }
  }
  @keyframes paper-7 {
    0%, 14.0%   { opacity: 0; transform: translate(0,0) rotate(0deg) scale(.45); }
    16.5%   { opacity: 1; transform: translate(calc(var(--fly) * 142px), calc(var(--fly) * -20px)) rotate(10deg) scale(1); }
    29.6% { opacity: .95; transform: translate(calc(var(--fly) * 535px), calc(var(--fly) * -64px)) rotate(31deg) scale(.98); }
    40.0%   { opacity: 0; transform: translate(calc(var(--fly) * 786px), calc(var(--fly) * -38px)) rotate(45deg) scale(.9); }
    100%        { opacity: 0; transform: translate(0,0) rotate(0deg) scale(.45); }
  }
  @keyframes paper-8 {
    0%, 15.5%   { opacity: 0; transform: translate(0,0) rotate(0deg) scale(.45); }
    18.0%   { opacity: 1; transform: translate(calc(var(--fly) * 121px), calc(var(--fly) * -64px)) rotate(20deg) scale(1); }
    31.1% { opacity: .95; transform: translate(calc(var(--fly) * 457px), calc(var(--fly) * -202px)) rotate(63deg) scale(.98); }
    41.5%   { opacity: 0; transform: translate(calc(var(--fly) * 672px), calc(var(--fly) * -121px)) rotate(90deg) scale(.9); }
    100%        { opacity: 0; transform: translate(0,0) rotate(0deg) scale(.45); }
  }
  @keyframes paper-9 {
    0%, 26.0%   { opacity: 0; transform: translate(0,0) rotate(0deg) scale(.45); }
    28.5%   { opacity: 1; transform: translate(calc(var(--fly) * 78px), calc(var(--fly) * -100px)) rotate(30deg) scale(1); }
    41.6% { opacity: .95; transform: translate(calc(var(--fly) * 292px), calc(var(--fly) * -312px)) rotate(94deg) scale(.98); }
    52.0%   { opacity: 0; transform: translate(calc(var(--fly) * 430px), calc(var(--fly) * -187px)) rotate(135deg) scale(.9); }
    100%        { opacity: 0; transform: translate(0,0) rotate(0deg) scale(.45); }
  }
  @keyframes paper-10 {
    0%, 27.5%   { opacity: 0; transform: translate(0,0) rotate(0deg) scale(.45); }
    30.0%   { opacity: 1; transform: translate(calc(var(--fly) * 133px), calc(var(--fly) * -43px)) rotate(14deg) scale(1); }
    43.1% { opacity: .95; transform: translate(calc(var(--fly) * 502px), calc(var(--fly) * -132px)) rotate(46deg) scale(.98); }
    53.5%   { opacity: 0; transform: translate(calc(var(--fly) * 739px), calc(var(--fly) * -80px)) rotate(65deg) scale(.9); }
    100%        { opacity: 0; transform: translate(0,0) rotate(0deg) scale(.45); }
  }
  @keyframes paper-11 {
    0%, 38.0%   { opacity: 0; transform: translate(0,0) rotate(0deg) scale(.45); }
    40.5%   { opacity: 1; transform: translate(calc(var(--fly) * 99px), calc(var(--fly) * -83px)) rotate(24deg) scale(1); }
    53.6% { opacity: .95; transform: translate(calc(var(--fly) * 375px), calc(var(--fly) * -260px)) rotate(77deg) scale(.98); }
    64.0%   { opacity: 0; transform: translate(calc(var(--fly) * 551px), calc(var(--fly) * -156px)) rotate(110deg) scale(.9); }
    100%        { opacity: 0; transform: translate(0,0) rotate(0deg) scale(.45); }
  }
  @keyframes paper-12 {
    0%, 39.5%   { opacity: 0; transform: translate(0,0) rotate(0deg) scale(.45); }
    42.0%   { opacity: 1; transform: translate(calc(var(--fly) * 48px), calc(var(--fly) * -107px)) rotate(34deg) scale(1); }
    55.1% { opacity: .95; transform: translate(calc(var(--fly) * 182px), calc(var(--fly) * -334px)) rotate(108deg) scale(.98); }
    65.5%   { opacity: 0; transform: translate(calc(var(--fly) * 269px), calc(var(--fly) * -201px)) rotate(155deg) scale(.9); }
    100%        { opacity: 0; transform: translate(0,0) rotate(0deg) scale(.45); }
  }
  @keyframes mk-arm-throw {
    0%, 4%  { transform: rotate(0deg); }
    5%   { transform: rotate(-30deg); }
    8%     { transform: rotate(96deg); }
    11%   { transform: rotate(44deg); }
    17%   { transform: rotate(-30deg); }
    20%     { transform: rotate(96deg); }
    23%   { transform: rotate(44deg); }
    29%   { transform: rotate(-30deg); }
    32%     { transform: rotate(96deg); }
    35%   { transform: rotate(44deg); }
    44%, 62% { transform: rotate(0deg); }
    68%     { transform: rotate(26deg) translate(0,-16px); }
    88%     { transform: rotate(26deg) translate(0,-16px); }
    93%     { transform: rotate(0deg) translate(0,0); }
    100%    { transform: rotate(0deg); }
  }
  @keyframes mk-arm-doc {
    0%, 4%  { transform: rotate(0deg); }
    11%   { transform: rotate(28deg); }
    14%     { transform: rotate(-94deg); }
    17%   { transform: rotate(-42deg); }
    23%   { transform: rotate(28deg); }
    26%     { transform: rotate(-94deg); }
    29%   { transform: rotate(-42deg); }
    35%   { transform: rotate(28deg); }
    38%     { transform: rotate(-94deg); }
    41%   { transform: rotate(-42deg); }
    44%, 100% { transform: rotate(0deg); }
  }
  @keyframes mk-recoil {
    0%, 4%  { transform: translateY(0) scale(1,1) rotate(0deg); }
    6%   { transform: translateY(1.4%) scale(1.025,.975) rotate(-0.7deg); }
    9%   { transform: translateY(-1.3%) scale(.985,1.015) rotate(1.5deg); }
    12%   { transform: translateY(1.4%) scale(1.025,.975) rotate(0.7deg); }
    15%   { transform: translateY(-1.3%) scale(.985,1.015) rotate(-1.5deg); }
    18%   { transform: translateY(1.4%) scale(1.025,.975) rotate(-0.7deg); }
    21%   { transform: translateY(-1.3%) scale(.985,1.015) rotate(1.5deg); }
    24%   { transform: translateY(1.4%) scale(1.025,.975) rotate(0.7deg); }
    27%   { transform: translateY(-1.3%) scale(.985,1.015) rotate(-1.5deg); }
    30%   { transform: translateY(1.4%) scale(1.025,.975) rotate(-0.7deg); }
    33%   { transform: translateY(-1.3%) scale(.985,1.015) rotate(1.5deg); }
    36%   { transform: translateY(1.4%) scale(1.025,.975) rotate(0.7deg); }
    39%   { transform: translateY(-1.3%) scale(.985,1.015) rotate(-1.5deg); }
    44%     { transform: translateY(0) scale(1,1) rotate(0deg); }
    66%     { transform: translateY(-2.5%) scale(.98,1.02); }
    88%     { transform: translateY(-2.5%) scale(.98,1.02); }
    94%,100%{ transform: translateY(0) scale(1,1); }
  }
  /* Лист уходит из лапы ровно на выхлёсте и через паузу берётся новый. */
  @keyframes held-l {
    0%, 7.9%   { opacity: 1; }
    8%, 16.9%  { opacity: 0; }
    17%, 19.9% { opacity: 1; }
    20%, 28.9% { opacity: 0; }
    29%, 31.9% { opacity: 1; }
    32%, 93.9% { opacity: 0; }
    94%, 100%  { opacity: 1; }
  }
  @keyframes held-r {
    0%, 13.9%  { opacity: 1; }
    14%, 22.9% { opacity: 0; }
    23%, 25.9% { opacity: 1; }
    26%, 34.9% { opacity: 0; }
    35%, 37.9% { opacity: 1; }
    38%, 45.9% { opacity: 0; }
    46%, 100%  { opacity: 1; }
  }
  @keyframes mk-thumb-upright { 0%,100% { transform: rotate(-26deg); } }
  @keyframes mk-thumb {
    0%, 64%  { opacity: 0; transform: scale(.35) translateY(20%); }
    69%      { opacity: 1; transform: scale(1.18) translateY(-4%); }
    72%      { opacity: 1; transform: scale(.97) translateY(0); }
    75%, 88% { opacity: 1; transform: scale(1) translateY(0); }
    92%      { opacity: 0; transform: scale(.5) translateY(16%); }
    100%     { opacity: 0; transform: scale(.35) translateY(20%); }
  }
  @keyframes mk-wink {
    0%, 68%  { opacity: 0; }
    70%, 87% { opacity: 1; }
    90%,100% { opacity: 0; }
  }
  @keyframes mk-eye-shut {
    0%, 68%  { transform: scaleY(1); }
    70%, 87% { transform: scaleY(.08); }
    90%,100% { transform: scaleY(1); }
  }
  @keyframes mk-look {
    0%, 66%  { transform: translate(0,0); }
    72%, 88% { transform: translate(-9%,-6%); }
    94%,100% { transform: translate(0,0); }
  }
  @keyframes mk-ear-shake {
    0%, 4%  { transform: rotate(0deg); }
    9%      { transform: rotate(-7deg); }
    15%     { transform: rotate(6deg); }
    21%     { transform: rotate(-6deg); }
    27%     { transform: rotate(5deg); }
    33%     { transform: rotate(-6deg); }
    39%     { transform: rotate(5deg); }
    45%,100%{ transform: rotate(0deg); }
  }

  header.play #mk-body   { animation: mk-recoil var(--mark-cycle) ease-in-out infinite; }
  header.play #mk-arm-free { animation: mk-arm-throw var(--mark-cycle) ease-in-out infinite; }
  header.play #mk-paw-doc  { animation: mk-arm-doc var(--mark-cycle) ease-in-out infinite; }
  header.play #mk-ear-l  { animation: mk-ear-shake var(--mark-cycle) ease-in-out infinite; }
  header.play #mk-ear-r  { animation: mk-ear-shake var(--mark-cycle) ease-in-out infinite; animation-delay: .06s; }
  header.play #mk-held-l { animation: held-l var(--mark-cycle) steps(1,end) infinite; }
  header.play #mk-held-r { animation: held-r var(--mark-cycle) steps(1,end) infinite; }
  header.play #mk-thumb > * { animation: mk-thumb-upright var(--mark-cycle) linear infinite; }
  header.play #mk-thumb  { animation: mk-thumb var(--mark-cycle) cubic-bezier(.34,1.56,.64,1) infinite; }
  header.play #mk-wink   { animation: mk-wink var(--mark-cycle) steps(1,end) infinite; }
  header.play #mk-eye-r  { animation: mk-eye-shut var(--mark-cycle) ease-in-out infinite; }
  header.play .pup       { animation: mk-look var(--mark-cycle) ease-in-out infinite; }
  header.play #paper-1 { animation: paper-1 var(--mark-cycle) cubic-bezier(.2,.6,.5,1) infinite; }
  header.play #paper-2 { animation: paper-2 var(--mark-cycle) cubic-bezier(.2,.6,.5,1) infinite; }
  header.play #paper-3 { animation: paper-3 var(--mark-cycle) cubic-bezier(.2,.6,.5,1) infinite; }
  header.play #paper-4 { animation: paper-4 var(--mark-cycle) cubic-bezier(.2,.6,.5,1) infinite; }
  header.play #paper-5 { animation: paper-5 var(--mark-cycle) cubic-bezier(.2,.6,.5,1) infinite; }
  header.play #paper-6 { animation: paper-6 var(--mark-cycle) cubic-bezier(.2,.6,.5,1) infinite; }
  header.play #paper-7 { animation: paper-7 var(--mark-cycle) cubic-bezier(.2,.6,.5,1) infinite; }
  header.play #paper-8 { animation: paper-8 var(--mark-cycle) cubic-bezier(.2,.6,.5,1) infinite; }
  header.play #paper-9 { animation: paper-9 var(--mark-cycle) cubic-bezier(.2,.6,.5,1) infinite; }
  header.play #paper-10 { animation: paper-10 var(--mark-cycle) cubic-bezier(.2,.6,.5,1) infinite; }
  header.play #paper-11 { animation: paper-11 var(--mark-cycle) cubic-bezier(.2,.6,.5,1) infinite; }
  header.play #paper-12 { animation: paper-12 var(--mark-cycle) cubic-bezier(.2,.6,.5,1) infinite; }

  /* ---------- Пустой список: расстроенный Оплатыч ----------
     Класс ставится клоном марки в JS, поэтому высота задаётся ЗДЕСЬ: при
     клонировании теряется .mark, и без своей высоты SVG растягивался по
     ширине карточки во весь экран. */
  .empty-art {
    display: block;
    height: 128px;
    width: auto;
    margin: 2px auto 12px;
    overflow: visible;
    /* Приглушён: заявок нет, и герой не бодрится. */
    opacity: .85;
    filter: saturate(.75);
    transform-origin: 50% 92%;
    animation: mk-sad 4.2s ease-in-out infinite;
  }

  /* Понурился и вздохнул: лёгкое покачивание, без резких движений — это фон,
     а не аттракцион. */
  @keyframes mk-sad {
    0%, 100% { transform: rotate(-2.5deg) translateY(0) scaleY(1); }
    22%      { transform: rotate(-2.5deg) translateY(3px) scaleY(.982); }
    46%      { transform: rotate(-1deg) translateY(1px) scaleY(1); }
    72%      { transform: rotate(2.5deg) translateY(3px) scaleY(.986); }
  }

  @media (prefers-reduced-motion: reduce) {
    .empty-art { animation: none; transform: rotate(-2deg); }
  }

  @media (prefers-reduced-motion: reduce) {
    header.play #mk-body, header.play #mk-arm-free, header.play #mk-paw-doc,
    header.play #mk-ear-l, header.play #mk-ear-r, header.play #mk-thumb,
    header.play #mk-wink, header.play #mk-eye-r, header.play .pup,
    header.play .paper, header.play #mk-held-l, header.play #mk-held-r {
      animation: none !important;
    }
  }

  /* ---------- Кнопки шапки ----------
     Одна панель на все кнопки со скруглением карточек формы: раньше это были
     отдельные кружки с тенью, которые layoutHeaderIcons() расставлял по
     right — от скрытых оставались дыры. Теперь порядок держит flex. */
  .gears {
    position: absolute;
    top: 0; right: 0;
    display: flex;
    gap: 2px;
    padding: 3px;
    border-radius: 15px;
    background: color-mix(in srgb, var(--bg) 70%, transparent);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text) 9%, transparent);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
  }
  .gear {
    position: relative;
    width: 38px; height: 38px;
    flex: none;
    padding: 0;
    border: none;
    border-radius: 11px;
    background: none;
    color: var(--accent);
    display: grid;
    place-items: center;
    cursor: pointer;
    transition: background .16s ease, color .16s ease, transform .12s ease;
  }
  .gear svg {
    width: 20px; height: 20px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
  }
  .gear.hidden { display: none; }
  /* Только масштаб, без поворота: подсказка — псевдоэлемент кнопки и
     крутилась вместе с ней, превращаясь в вертикальную полоску текста. */
  .gear:active { transform: scale(.93); }
  @media (max-width: 400px) {
    .gear { width: 34px; height: 34px; border-radius: 10px; }
    .gear svg { width: 18px; height: 18px; }
  }

  .help-text { font-size: 14.5px; line-height: 1.55; }
  .help-text b { font-weight: 600; }
  .help-text + .help-text { margin-top: 8px; }

  .draft-note {
    display: inline-block;
    font-size: 12.5px;
    color: var(--hint);
    background: var(--bg);
    border-radius: 999px;
    padding: 5px 11px;
    margin: -6px 0 12px;
    box-shadow: var(--shadow);
    animation: rise .4s ease backwards;
  }

  /* ---------- Чипсы контрагентов ---------- */
  .chips {
    display: flex;
    gap: 6px;
    overflow-x: auto;
    margin-top: 8px;
    padding-bottom: 2px;
  }

  /* Статьи расходов — тот же список подсказок, только кнопками: одна строка
     под полем ввода, листается так же. Вертикальные отступы держат свечение
     выбранной кнопки, которое иначе срезал бы overflow.
     Селекторы с двумя классами намеренно: правила .seg идут ниже по файлу и
     при равной специфичности перебивали бы и перенос, и растяжение кнопок. */
  .seg.seg-scroll {
    flex-wrap: nowrap;
    overflow-x: auto;
    margin-top: 8px;
    padding: 4px 0 6px;
  }
  /* Ряд статей — такие же подсказки, как у контрагента, поэтому и размер
     тот же: пилюля, тот же кегль и те же поля. Остальные сегменты (валюта,
     срочность) остаются крупными кнопками выбора — это не подсказки. */
  .seg.seg-scroll button {
    flex: 0 0 auto;
    min-width: 0;
    padding: 7px 12px;
    border-width: 1px;
    border-radius: 999px;
    font-size: 13px;
  }
  .seg.seg-scroll .seg-x { font-size: 12px; padding: 1px 5px; }

  /* На телефоне список листается пальцем, а на десктопе листать было нечем:
     тач-жеста нет, полоса спрятана, вертикальное колесо горизонталь не
     крутит. Там, где указатель точный, возвращаем тонкую полосу; колесо
     разворачивает вбок скрипт (wireHScroll). */
  .hscroll { scrollbar-width: none; }
  .hscroll::-webkit-scrollbar { display: none; }
  @media (pointer: fine) {
    .hscroll { scrollbar-width: thin; scrollbar-color: var(--accent) transparent; }
    .hscroll::-webkit-scrollbar { display: block; height: 6px; }
    .hscroll::-webkit-scrollbar-track { background: transparent; }
    .hscroll::-webkit-scrollbar-thumb {
      border-radius: 3px;
      background: color-mix(in srgb, var(--accent) 55%, transparent);
    }
  }
  /* Растушёвка края — единственный намёк, что список продолжается за
     обрезом. Классы ставит updateFades() по фактической позиции прокрутки. */
  .fade-r {
    mask-image: linear-gradient(to right, #000 calc(100% - 26px), transparent);
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 26px), transparent);
  }
  .fade-l {
    mask-image: linear-gradient(to left, #000 calc(100% - 26px), transparent);
    -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 26px), transparent);
  }
  .fade-l.fade-r {
    mask-image: linear-gradient(to right, transparent, #000 26px,
                #000 calc(100% - 26px), transparent);
    -webkit-mask-image: linear-gradient(to right, transparent, #000 26px,
                #000 calc(100% - 26px), transparent);
  }

  /* ---------- Вкладки настроек ---------- */
  /* Ровно одна строка: все разделы должны быть видны сразу, без переноса и
     без прокрутки. Поэтому подписи без эмодзи, а на узких экранах кегль и
     поля ужимаются — шесть вкладок влезают и в 320 px. */
  .tabs {
    display: flex;
    flex-wrap: nowrap;
    gap: 5px;
    margin: 0 0 14px;
  }
  .tab {
    /* Не сжимаются: сжатая кнопка молча режет подпись вместо переполнения.
       Поля подобраны под ШЕСТЬ вкладок (столько видит админ) с запасом на
       чужой шрифт: измеряется в tests/e2e/settings.test.cjs. */
    flex: 0 0 auto;
    white-space: nowrap;
    border: 1px solid color-mix(in srgb, var(--hint) 35%, transparent);
    border-radius: 999px;
    padding: 8px 10px;
    background: var(--bg);
    color: var(--hint);
    font-size: 13.5px;
    font-weight: 600;
    cursor: pointer;
    transition: background .18s ease, color .18s ease, border-color .18s ease;
  }
  /* Самая длинная подпись разворачивается только там, где на неё есть
     место, — на широком экране десктопного Telegram. */
  .t-long { display: none; }
  @media (min-width: 561px) {
    .t-long { display: inline; }
    .t-short { display: none; }
  }
  @media (max-width: 460px) {
    .tab { padding: 8px 5px; font-size: 12.5px; }
  }
  /* Шесть вкладок (у админа) на 360 px не помещались ровно на 2 px: поля
     ужимаем, кегль не трогаем — читаемость дороже симметрии. */
  @media (max-width: 400px) {
    .tabs { gap: 4px; }
    .tab { padding: 7px 4px; font-size: 10.5px; }
  }
  @media (max-width: 340px) {
    .tabs { gap: 3px; }
    .tab { padding: 6px 3px; font-size: 9.5px; }
  }
  .tab[aria-selected="true"] {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--accent-text);
  }
  .tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
  .chip {
    flex: 0 0 auto;
    max-width: 60vw;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    background: var(--bg2);
    border: 1px solid transparent;
    border-radius: 999px;
    padding: 7px 12px;
    font-size: 13px;
    color: var(--text);
    cursor: pointer;
    transition: background .16s ease, border-color .16s ease, color .16s ease,
                transform .12s ease;
  }
  .chip:active { transform: scale(.94); }
  /* Подсказку можно убрать: чипс = кнопка подстановки + крестик рядом.
     Вложенная кнопка в кнопку недопустима, поэтому обёртка. */
  .chip-wrap { display: inline-flex; flex: 0 0 auto; max-width: 70vw; }
  .chip-wrap .chip { border-radius: 999px 0 0 999px; padding-right: 8px; border-right: none; }
  .chip-x {
    flex: 0 0 auto;
    border: 1px solid transparent;
    border-left: none;
    border-radius: 0 999px 999px 0;
    background: var(--bg2);
    color: var(--hint);
    font-size: 12px;
    padding: 0 9px;
    cursor: pointer;
    transition: background .16s ease, border-color .16s ease, color .16s ease;
  }
  /* Крестик внутри кнопки-статьи: span, а не button (вложенность запрещена). */
  .seg-x {
    display: inline-block;
    margin-left: 7px;
    padding: 2px 5px;
    border-radius: 999px;
    color: var(--hint);
    font-size: 11px;
    line-height: 1;
    cursor: pointer;
    opacity: .8;
    transition: background .16s ease, color .16s ease, opacity .16s ease;
  }

  /* ---------- Предупреждения по реквизитам ---------- */
  .req-warn {
    margin-top: 8px;
    background: color-mix(in srgb, #f59e0b 13%, var(--bg));
    color: #b45309;
    border-radius: 10px;
    padding: 10px 12px;
    font-size: 13px;
    line-height: 1.5;
    white-space: pre-line;
  }
  body[data-theme="dark"] .req-warn { color: #fbbf24; }
  .checking-note {
    margin-top: 8px;
    font-size: 13px;
    color: var(--hint);
  }

  /* Плашка контура (стенд): висит постоянно, поэтому заметная, но не крикливая. */
  .env-banner {
    margin: 0 2px 10px; padding: 7px 12px; border-radius: 10px;
    background: color-mix(in srgb, var(--danger) 16%, var(--bg));
    border: 1px solid color-mix(in srgb, var(--danger) 40%, transparent);
    color: var(--danger); font-size: 13px; font-weight: 700;
    letter-spacing: .04em; text-align: center; text-transform: uppercase;
  }

  /* ---------- Админ-панель ---------- */
  .row-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 4px;
    border-bottom: .5px solid var(--bg2);
    animation: rise .25s ease backwards;
  }
  .row-item:last-child { border-bottom: none; }
  .row-item .who { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  .row-item .sub { color: var(--hint); font-size: 12px; }
  .tag {
    flex: 0 0 auto;
    font-size: 11px;
    color: var(--hint);
    background: var(--bg2);
    border-radius: 6px;
    padding: 2px 7px;
  }
  /* Строка живого состояния связи. Точка — цветом, текст — словами: цвет
     один не читается ни дальтоником, ни в ярком солнце. */
  .state-line {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 2px 0 4px;
    padding: 9px 11px;
    border-radius: 11px;
    background: var(--bg2);
    color: var(--hint);
    font-size: 13px;
    cursor: pointer;
  }
  .state-line .dot {
    flex: 0 0 auto;
    width: 8px; height: 8px;
    border-radius: 50%;
    background: var(--accent);
  }
  .state-line.bad {
    background: color-mix(in srgb, var(--danger) 12%, var(--bg));
    color: var(--danger);
    font-weight: 600;
  }
  .state-line.bad .dot { background: var(--danger); animation: pulse-dot 1.6s ease-in-out infinite; }
  @keyframes pulse-dot { 50% { opacity: .25; } }
  /* Переключатель категории: узкий, чтобы длинная подпись сбоя не переносилась. */
  .kind-toggle {
    flex: 0 0 auto;
    min-width: 58px;
    border: 1.5px solid var(--bg2);
    border-radius: 9px;
    padding: 6px 10px;
    background: var(--bg2);
    color: var(--hint);
    font-size: 13px;
    cursor: pointer;
    transition: background .18s ease, color .18s ease, border-color .18s ease,
                transform .12s ease;
  }
  .kind-toggle:active { transform: scale(.94); }
  .kind-toggle.on {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--accent-text);
    font-weight: 600;
  }
  .row-del {
    flex: 0 0 auto;
    width: 28px; height: 28px;
    border: none;
    border-radius: 50%;
    background: color-mix(in srgb, var(--danger) 12%, var(--bg));
    color: var(--danger);
    font-size: 14px;
    cursor: pointer;
    transition: transform .12s ease;
  }
  .row-del:active { transform: scale(.86); }
  /* Ряд кнопок и полей. flex-wrap обязателен: без него длинная надпись
     («⏰ Проверить на себе») не даёт кнопке сжаться, и ряд вылезает за
     карточку на любом экране уже 393 px — а это все iPhone с включённым
     увеличением дисплея. min-width: 0 здесь НЕ ставим: он разрешает кнопке
     сжаться до нуля, и вместо переноса обрезается надпись. Пусть лучше
     кнопка уедет на вторую строку целиком. */
  .add-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
  .add-row input { flex: 1; }
  .add-btn {
    flex: 0 0 auto;
    border: none;
    border-radius: 11px;
    background: var(--accent);
    color: var(--accent-text);
    font-size: 15px;
    font-weight: 600;
    /* Собственная высота: в рядах без input кнопки не должны сплющиваться. */
    padding: 13px 18px;
    cursor: pointer;
    transition: transform .12s ease, opacity .15s ease;
  }
  .add-btn:active { transform: scale(.95); }
  /* Фильтры статусов не влезают в один ряд — разрешаем перенос. */
  .seg-wrap { flex-wrap: wrap; }
  .fin-count { color: var(--hint); font-size: 12.5px; margin-top: 8px; }
  .tap-hint {
    margin-left: auto;
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
    font-size: 11.5px;
    opacity: .8;
    user-select: none;
  }
  /* Вся карточка заявки кликабельна — открывает подробности. */
  .my-item.tappable {
    cursor: pointer;
    /* Клик не должен выделять текст карточки. */
    user-select: none;
    border-radius: 12px;
    padding-left: 10px;
    padding-right: 10px;
    margin: 0 -10px;
    transition: background .15s ease;
  }
  .modal-rows { display: grid; grid-template-columns: auto 1fr; gap: 6px 12px; }
  .modal-rows dt { color: var(--hint); font-size: 13px; white-space: nowrap; }
  .modal-rows dd { font-size: 14px; overflow-wrap: anywhere; }
  .modal-req {
    margin-top: 12px;
    font-size: 13.5px;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    background: var(--bg2);
    border-radius: 10px;
    padding: 10px;
  }

  #admin-msg, #my-msg, #fin-msg {
    display: none;
    border-radius: 10px;
    padding: 10px 12px;
    margin-bottom: 12px;
    font-size: 13.5px;
    background: color-mix(in srgb, var(--accent) 12%, var(--bg));
    animation: rise .25s ease;
  }
  .empty-note { color: var(--hint); font-size: 13.5px; padding: 6px 4px; }

  /* Подсказки к полю «@username или id»: список тех, кого бот уже знает. */
  .suggest {
    margin-top: 6px;
    border: 1px solid color-mix(in srgb, var(--hint) 30%, transparent);
    border-radius: 10px;
    overflow: hidden;
  }
  .suggest-row {
    display: block;
    width: 100%;
    padding: 9px 11px;
    border: none;
    background: var(--bg);
    color: var(--text);
    font-size: 14px;
    text-align: left;
    cursor: pointer;
  }
  .suggest-row + .suggest-row { border-top: 1px solid color-mix(in srgb, var(--hint) 18%, transparent); }
  .suggest-row .sub { display: block; font-size: 11.5px; color: var(--hint); margin-top: 2px; }

  /* Пока доступа нет, из формы остаются только шапка и сама плашка: поля,
     которые всё равно не отправить, только сбивают с толку. */
  #form-view.no-access .card,
  #form-view.no-access #draft-note,
  #form-view.no-access #form-reset,
  #form-view.no-access #submit-fallback,
  #form-view.no-access #fallback-note { display: none; }

  /* Экран «доступа нет»: не тупик, а кнопка попросить. */
  .access-gate {
    margin-bottom: 14px;
    padding: 14px;
    border-radius: var(--radius);
    border: 1px solid color-mix(in srgb, var(--danger) 45%, transparent);
    background: color-mix(in srgb, var(--danger) 10%, var(--bg));
  }
  .access-gate b { display: block; font-size: 15px; }
  .access-gate p { margin: 6px 0 10px; color: var(--hint); font-size: 13.5px; }
  .access-gate .add-btn { width: 100%; padding: 12px; }

  /* Заголовок группы в списке пользователей: роли вперемешку не читались. */
  .group-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    margin: 12px 0 2px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--accent);
  }
  .group-head:first-child { margin-top: 2px; }
  .group-head span {
    font-weight: 400;
    letter-spacing: 0;
    text-transform: none;
    color: var(--hint);
  }

  /* ---------- «Мои заявки» ---------- */
  .my-item {
    padding: 12px 0;
    border-bottom: .5px solid var(--bg2);
    animation: rise .25s ease backwards;
  }
  .my-item:last-child { border-bottom: none; }
  .my-top { display: flex; align-items: center; gap: 8px; }
  .my-status {
    flex: 0 0 auto;
    font-size: 12px;
    font-weight: 600;
    border-radius: 7px;
    padding: 3px 9px;
    background: var(--bg2);
  }
  .my-status.st-paid { background: color-mix(in srgb, var(--ok) 18%, var(--bg)); color: var(--ok); }
  .my-status.st-rejected { background: color-mix(in srgb, var(--danger) 14%, var(--bg)); color: var(--danger); }
  .my-status.st-new { background: color-mix(in srgb, var(--accent) 15%, var(--bg)); color: var(--accent); }
  .my-sum { flex: 1; text-align: right; font-weight: 600; white-space: nowrap; }
  .my-cp {
    margin-top: 7px;
    font-size: 14.5px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .my-meta { margin-top: 3px; color: var(--hint); font-size: 12.5px; }
  .my-reason {
    margin-top: 6px;
    font-size: 13px;
    border-radius: 9px;
    padding: 7px 9px;
    background: color-mix(in srgb, var(--danger) 9%, var(--bg));
  }
  .my-comment {
    white-space: normal;
    overflow-wrap: anywhere;
  }
  .my-id {
    margin-top: 5px;
    font-size: 11.5px;
    color: var(--hint);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    overflow-wrap: anywhere;
  }
  /* Кнопок бывает три (изменить/повторить/отозвать) — переносим строкой. */
  .my-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
  .my-actions .add-btn { flex: 1 1 120px; padding: 9px 12px; font-size: 13.5px; }
  .btn-ghost {
    background: var(--bg2);
    color: var(--text);
  }
  .btn-danger {
    background: color-mix(in srgb, var(--danger) 13%, var(--bg));
    color: var(--danger);
  }

  .optional-mark {
    font-size: 10px;
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
    color: var(--hint);
    background: var(--bg2);
    border-radius: 6px;
    padding: 2px 7px;
  }

  /* Глазик: скрытие реквизитов от посторонних глаз (как спойлер в Telegram).
     Акцентный фон и рамка — иначе на тёмной теме кнопка сливалась с полем. */
  .eye-btn {
    position: absolute;
    top: 8px; right: 8px;
    z-index: 2;
    width: 32px; height: 32px;
    border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
    border-radius: 50%;
    background: color-mix(in srgb, var(--accent) 20%, var(--bg));
    box-shadow: var(--shadow);
    font-size: 15px;
    line-height: 1;
    cursor: pointer;
    transition: transform .12s ease;
  }
  .eye-btn:active { transform: scale(.88); }
  textarea.veiled { filter: blur(6px); }

  /* Знак вопроса с пояснением настройки. */
  .help-q {
    margin-left: auto;
    width: 20px; height: 20px;
    flex: 0 0 auto;
    border: none;
    border-radius: 50%;
    background: var(--bg2);
    color: var(--hint);
    font-size: 12px;
    font-weight: 700;
    line-height: 20px;
    cursor: pointer;
    transition: transform .12s ease;
  }
  .help-q:active { transform: scale(.85); }

  .card {
    background: var(--bg); /* fallback, если color-mix не поддерживается */
    background: color-mix(in srgb, var(--bg) 78%, transparent);
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
    border: 1px solid color-mix(in srgb, var(--bg) 40%, transparent);
    border-radius: var(--radius);
    padding: 16px;
    margin-bottom: 12px;
    box-shadow: var(--shadow);
    animation: rise .4s cubic-bezier(.22,1,.36,1) backwards;
  }
  .card-title {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--hint);
    margin-bottom: 10px;
  }

  label.field-label {
    display: block;
    font-size: 13px;
    color: var(--hint);
    margin: 12px 0 6px;
  }
  label.field-label:first-of-type { margin-top: 0; }

  input[type=text], input[type=date], input[type=time], textarea {
    width: 100%;
    /* На iPhone поле времени вылезало за карточку ровно на свои горизонтальные
       поля: WKWebView меряет нативный контрол по содержимому и добавляет
       padding снаружи. Ни Chromium, ни WebKit под Linux этого не повторяют,
       поэтому предел жёсткий — что бы движок ни думал о width. */
    box-sizing: border-box;
    max-width: 100%;
    min-width: 0;
    border: 1.5px solid transparent;
    background: var(--bg2);
    color: var(--text);
    border-radius: 11px;
    padding: 12px 13px;
    font-size: 16px;
    outline: none;
    color-scheme: light dark;
    transition: border-color .18s ease, box-shadow .18s ease;
  }
  input[type=text]:focus, input[type=date]:focus, input[type=time]:focus, textarea:focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
  }
  /* Нативный вид date/time на iOS не слушается box-sizing; appearance: none
     возвращает обычную блочную модель, пикер по тапу остаётся. */
  input[type=date], input[type=time] {
    -webkit-appearance: none;
    appearance: none;
  }
  textarea { resize: vertical; min-height: 74px; }

  #amount { font-size: 22px; font-weight: 600; letter-spacing: .01em; }

  .invalid {
    border-color: var(--danger) !important;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger) 15%, transparent) !important;
  }

  /* ---------- Сегменты ---------- */
  .seg { display: flex; gap: 6px; flex-wrap: wrap; }
  /* Ряд с РАВНЫМИ долями. Обычный .seg растит кнопки от надписи, и в столбце
     рядов граница гуляет (157|164, 196|125, 141|180) — читается как съехавший
     блок. Здесь доли равны, поэтому класс ставится только там, где надписи
     заведомо короткие: на «🗓 Настраиваемая» в форме равные трети обрезают
     текст, и это было бы хуже зигзага. */
  /* .seg.seg-even, а не .seg-even: правило .seg button идёт ниже, и при равной
     специфичности перекрывало бы модификатор. */
  .seg.seg-even button { flex: 1 1 0; min-width: 0; }

  .seg button {
    flex: 1 0 auto;
    min-width: 56px;
    padding: 11px 8px;
    border: 1.5px solid transparent;
    background: var(--bg2);
    color: var(--text);
    border-radius: 11px;
    font-size: 15px;
    cursor: pointer;
    transition: background .18s ease, color .18s ease, border-color .18s ease,
                transform .12s ease, box-shadow .18s ease;
  }
  .seg button:active { transform: scale(.95); }
  .seg button.active {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--accent-text);
    font-weight: 600;
    box-shadow: 0 3px 10px color-mix(in srgb, var(--accent) 35%, transparent);
  }
  @keyframes pop {
    0% { transform: scale(1); }
    45% { transform: scale(1.06); }
    100% { transform: scale(1); }
  }
  .seg button.just-picked { animation: pop .22s ease; }

  .counter {
    font-size: 12px;
    color: var(--hint);
    text-align: right;
    margin-top: 4px;
    transition: color .2s ease;
  }
  .pay-date-note {
    display: inline-block;
    margin-top: 10px;
    font-size: 13.5px;
    color: var(--text);
    background: var(--bg2);
    border-radius: 999px;
    padding: 7px 12px;
    transition: opacity .2s ease;
  }
  .card:nth-of-type(5) { animation-delay: .29s; }
  .card:nth-of-type(6) { animation-delay: .35s; }
  .counter.warn { color: var(--danger); font-weight: 600; }

  /* ---------- Файл ---------- */
  .drop {
    position: relative;
    border: 1.5px dashed color-mix(in srgb, var(--hint) 55%, transparent);
    border-radius: 11px;
    padding: 20px 14px;
    text-align: center;
    color: var(--hint);
    cursor: pointer;
    transition: border-color .2s ease, background .2s ease, transform .12s ease;
  }
  .drop:active { transform: scale(.985); }
  .drop .drop-icon { font-size: 26px; display: block; margin-bottom: 6px; }
  .drop small { display: block; margin-top: 4px; font-size: 12px; }
  .drop.has-file {
    border-style: solid;
    border-color: var(--ok);
    background: color-mix(in srgb, var(--ok) 8%, var(--bg));
    color: var(--text);
  }
  @keyframes attach-bounce {
    0% { transform: scale(.9); }
    55% { transform: scale(1.04); }
    100% { transform: scale(1); }
  }
  .drop.has-file .drop-inner { animation: attach-bounce .28s ease; }
  .drop .file-name { font-weight: 600; word-break: break-all; }
  .file-remove {
    position: absolute;
    top: 8px; right: 8px;
    width: 26px; height: 26px;
    border: none;
    border-radius: 50%;
    background: color-mix(in srgb, var(--hint) 22%, transparent);
    color: var(--text);
    font-size: 14px;
    line-height: 26px;
    cursor: pointer;
    display: none;
    transition: transform .12s ease, background .15s ease;
  }
  .file-remove:active { transform: scale(.88); }
  .drop.has-file .file-remove { display: block; }

  /* ---------- Ошибка ---------- */
  /* Сброс черновика: две точки входа, обе почти невесомые — ссылка в
     плашке восстановления (там, где это нужнее всего) и приглушённая
     строка в конце формы (когда плашка уже исчезла). */
  #draft-clear {
    margin-left: 8px;
    border: none;
    background: none;
    color: var(--accent);
    font: inherit;
    font-size: 12.5px;
    font-weight: 600;
    padding: 0;
    cursor: pointer;
    text-decoration: underline;
  }
  #form-reset {
    display: block;
    width: 100%;
    margin: 4px 0 12px;
    border: none;
    background: none;
    color: var(--hint);
    font: inherit;
    font-size: 13px;
    padding: 6px;
    cursor: pointer;
  }
  @media (hover: hover) { #form-reset:hover { color: var(--danger); } }
  #form-reset:focus-visible, #draft-clear:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: 8px;
  }

  #error-banner {
    display: none;
    background: color-mix(in srgb, var(--danger) 12%, var(--bg));
    color: var(--danger);
    border-radius: 11px;
    padding: 12px 14px;
    margin-bottom: 12px;
    font-size: 14px;
    box-shadow: var(--shadow);
  }
  @keyframes shake {
    10%, 90% { transform: translateX(-1px); }
    20%, 80% { transform: translateX(2px); }
    30%, 50%, 70% { transform: translateX(-4px); }
    40%, 60% { transform: translateX(4px); }
  }
  #error-banner.shaking { display: block; animation: shake .45s ease; }

  /* ---------- Своё модальное окно ----------
     Не tg.showPopup: нативный попап Telegram рисуется в ГЛАВНОМ окне
     мессенджера, а Mini App на десктопе живёт в отдельном — подтверждение
     уезжало «на другой экран». Своё окно всегда по центру приложения. */
  #modal {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 100;
    background: rgba(0, 0, 0, .45);
    backdrop-filter: blur(2px);
    padding: 20px;
    overflow-y: auto;
  }
  #modal.shown { display: flex; align-items: center; justify-content: center; }
  .modal-box {
    width: 100%;
    max-width: 380px;
    background: var(--bg);
    border-radius: var(--radius);
    box-shadow: 0 12px 40px rgba(0, 0, 0, .3);
    padding: 20px;
    animation: rise .22s cubic-bezier(.22, 1, .36, 1);
  }
  .modal-title { font-size: 17px; font-weight: 600; margin-bottom: 8px; }
  .modal-text { font-size: 14.5px; line-height: 1.5; white-space: pre-line; }
  .modal-actions { display: flex; gap: 8px; margin-top: 18px; }
  .modal-actions .add-btn { flex: 1; }

  /* ---------- Подсказки у иконок ----------
     Появляются при наведении и с клавиатуры (:focus-visible). На тач-экранах
     hover не срабатывает — там смысл кнопок объясняет экран «Инструкция». */
  .tip { position: relative; }
  /* Глазок и «убрать файл» стоят на своей абсолютной раскладке. Кнопки
     шапки — наоборот: они лежат в панели на flex, и absolute сложил бы их
     в стопку (правило .tip идёт по файлу позже и перебивало бы .gear).
     static, а не relative: тогда подсказка отсчитывается от панели, а не от
     самой кнопки. У крайней левой кнопки подсказка иначе уезжала за левый
     край экрана — на 320 px «Настройки» начинались с −4 px. Одновременно
     видна всё равно только одна, так что общий якорь ничего не ломает. */
  .eye-btn.tip, .file-remove.tip { position: absolute; }
  .gear.tip { position: static; }
  .tip::after {
    content: attr(data-tip);
    position: absolute;
    top: calc(100% + 7px);
    right: 0;
    max-width: calc(100vw - 24px);
    z-index: 60;
    white-space: nowrap;
    font-size: 12px;
    font-weight: 500;
    color: var(--bg);
    background: color-mix(in srgb, var(--text) 88%, transparent);
    border-radius: 7px;
    padding: 5px 9px;
    opacity: 0;
    transform: translateY(-3px);
    pointer-events: none;
    transition: opacity .15s ease, transform .15s ease;
  }
  @media (hover: hover) {
    .tip:hover::after { opacity: 1; transform: translateY(0); }
  }
  .tip:focus-visible::after { opacity: 1; transform: translateY(0); }

  /* ---------- Наведение ----------
     Только для устройств с курсором: на тач-экранах :hover «залипает»
     после нажатия. */
  @media (hover: hover) {
    .add-btn:hover { filter: brightness(1.08); }
    .btn-ghost:hover, .row-del:hover, .btn-danger:hover {
      filter: none;
      background: color-mix(in srgb, var(--accent) 18%, var(--bg));
    }
    .btn-danger:hover, .row-del:hover {
      background: color-mix(in srgb, var(--danger) 22%, var(--bg));
    }
    .gear:hover { background: var(--bg2); box-shadow: 0 2px 8px rgba(0, 0, 0, .12); }
    /* Подсказки подсвечиваются одинаково: контур акцентом по всей пилюле
       (крестик — её часть) плюс лёгкая заливка. Раньше чипс контрагента
       обводился, а кнопка статьи только меняла фон. */
    .chip-wrap:hover .chip, .chip-wrap:hover .chip-x,
    .seg button:hover:not(.active) {
      border-color: var(--accent);
      background: color-mix(in srgb, var(--accent) 12%, transparent);
      color: var(--accent);
    }
    .help-q:hover { background: var(--accent); color: var(--accent-text); }
    .drop:hover { border-color: var(--accent); }
    .eye-btn:hover, .file-remove:hover { filter: brightness(1.15); }
    /* Заметная подсветка: слабая заливка сливалась с фоном карточки. */
    .my-item.tappable:hover { background: color-mix(in srgb, var(--accent) 16%, var(--bg)); }
    .suggest-row:hover { background: color-mix(in srgb, var(--accent) 14%, var(--bg)); }
    /* Крестик под курсором краснеет — он удаляет, а не подставляет.
       Селекторы длиннее правила пилюли выше: иначе оно перебивало красный
       и наведение прямо на крестик оставалось акцентным. */
    .chip-wrap .chip-x:hover, .seg button .seg-x:hover {
      color: var(--danger);
      opacity: 1;
    }
  }
  /* Клавиатурная навигация: видимый фокус на всех интерактивных элементах. */
  button:focus-visible, input:focus-visible, textarea:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
  }

  /* ---------- Вне Telegram ---------- */
  #fallback-note {
    display: none;
    text-align: center;
    color: var(--hint);
    font-size: 14px;
    margin-top: 12px;
  }
  #submit-fallback {
    display: none;
    width: 100%;
    padding: 15px;
    margin-top: 8px;
    border: none;
    border-radius: var(--radius);
    background: var(--accent);
    color: var(--accent-text);
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    transition: transform .12s ease, opacity .15s ease;
  }
  #submit-fallback:active { transform: scale(.98); }
  /* Незаполненная форма: кнопка серая, но НАЖИМАЕМАЯ — по нажатию открывается
     список того, чего не хватает. Погашенную кнопку нажать нельзя, и человек
     оставался с серым прямоугольником без объяснений. */
  #submit-fallback.incomplete {
    background: color-mix(in srgb, var(--hint) 45%, var(--bg2));
    color: var(--hint);
  }

  /* Что осталось заполнить — видно без нажатия. */
  #gaps-hint {
    margin-top: 10px;
    padding: 11px 13px;
    border-radius: var(--radius);
    border: 1px solid color-mix(in srgb, var(--hint) 32%, transparent);
    background: color-mix(in srgb, var(--hint) 10%, var(--bg));
    color: var(--text);
    font-size: 13.5px;
    line-height: 1.5;
  }
  #gaps-hint b { font-weight: 600; }
  #gaps-hint .gap-item { color: var(--hint); }

  /* Список незаполненного в модальном окне. */
  .modal-gaps {
    margin: 8px 0 0;
    padding-left: 20px;
    line-height: 1.6;
  }
  .modal-gaps li { margin-bottom: 2px; }

  /* ---------- Успех ---------- */
  #success {
    display: none;
    text-align: center;
    padding: 56px 16px;
  }
  #success.shown { display: block; animation: rise .45s cubic-bezier(.22,1,.36,1); }
  .check-wrap { width: 96px; height: 96px; margin: 0 auto 4px; }
  .check-wrap svg { width: 100%; height: 100%; }
  .check-circle {
    fill: none;
    stroke: var(--ok);
    stroke-width: 5;
    stroke-linecap: round;
    stroke-dasharray: 302;
    stroke-dashoffset: 302;
    animation: draw-circle .55s ease-out forwards;
  }
  .check-mark {
    fill: none;
    stroke: var(--ok);
    stroke-width: 6;
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-dasharray: 60;
    stroke-dashoffset: 60;
    animation: draw-mark .3s .45s ease-out forwards;
  }
  @keyframes draw-circle { to { stroke-dashoffset: 0; } }
  @keyframes draw-mark { to { stroke-dashoffset: 0; } }
  #success h2 { margin: 14px 0 6px; font-size: 22px; }
  #success .req-id {
    display: inline-block;
    color: var(--text);
    background: var(--bg);
    border-radius: 9px;
    padding: 6px 12px;
    font-weight: 600;
    box-shadow: var(--shadow);
  }
  #success p { margin-top: 12px; color: var(--hint); font-size: 14px; }

  .hidden { display: none !important; }

  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
      animation-duration: .01ms !important;
      animation-delay: 0ms !important;
      transition-duration: .01ms !important;
    }
  }
