  :root{
    /* Без color-scheme Safari на iOS рисует системные контролы (галочку, выпадающий список,
       календарь в input[type=date], полосы прокрутки) всегда в светлом виде — в тёмной теме
       это выглядело как белые заплатки. */
    color-scheme:light;
    --bg:#EDEEEA; --paper:#F7F7F4; --ink:#1B2430; --ink-soft:#5B6570; --line:#D8D9D3;
    --amber:#F2A900; --amber-dark:#C98A00; --teal:#2D6E7E; --green:#3F8F5F; --red:#C24444;
    --surface:#fff; --green-tint:#EAF5EE; --green-dark:#1F7A4D; --green-wash:#E2F1E8;
    /* Янтарная заливка и подложка свёрнутой строки. Держим их рядом с остальной
       палитрой, а не хардкодим по месту: тема переключается целиком. */
    --amber-tint:#FBF0D8; --surface-2:#F0F1ED;
    --brand:#1B2430; --brand-text:#F7F7F4; --brand-text-soft:#A9B2BC; --brand-line:#3A4552;
    --content-max:520px;
    /* Первым идёт фирменный шрифт, дальше — системные запасные. Если /fonts/ пуст
       или ещё не докачался, интерфейс выглядит нормально и, главное, сразу. */
    --font-display:'Space Grotesk',ui-sans-serif,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
    --font-mono:'IBM Plex Mono',ui-monospace,SFMono-Regular,'SF Mono',Menlo,'Roboto Mono',monospace;
    --font-text:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',sans-serif;
    /* Три высоты на всё приложение. Было восемь разных — 32, 33, 34, 37, 39, 41,
       44, 45 — и именно от этого рябило в глазах: соседние элементы отличались
       на два-три пикселя, глаз это ловит, но как небрежность, а не как замысел.
       Рамка у элементов 1.5px с двух сторон, поэтому внутренняя высота на 3 меньше. */
    --h-field:40px;   /* поля, переключатели, счётчики, чекбоксы */
    --h-chip:30px;    /* чипсы и мелкие переключатели */
    --h-action:46px;  /* главная кнопка */
  }
  [data-theme="dark"]{
    color-scheme:dark;
    --bg:#10141A; --paper:#1B222B; --ink:#EDEEEA; --ink-soft:#93A0AC; --line:#2B333D;
    --teal:#5FB6C9; --green:#57C084; --red:#E2716D;
    --surface:#232B36; --green-tint:rgba(87,192,132,.16); --green-dark:#57C084; --green-wash:rgba(87,192,132,.14);
    /* На тёмном фоне приглушённый --amber-dark (#C98A00) читается плохо, поэтому
       в тёмной теме он совпадает с основным янтарным. */
    --amber-dark:#F2A900; --amber-tint:rgba(242,169,0,.13); --surface-2:#1D242E;
  }
  @media (min-width:700px){
    :root{ --content-max:680px; }
    body{ font-size:16px; }
  }
  @media (min-width:1000px){
    :root{ --content-max:760px; }
  }
  *{box-sizing:border-box;}
  button{color:inherit;font:inherit;-webkit-appearance:none;appearance:none;}
  /* Нативная подсветка тапа глушится ниже (-webkit-tap-highlight-color:transparent) —
     без этого правила кнопка не даёт вообще никакой обратной связи на тап.
     Общее правило на все 93 кнопки разом; конкретные классы (add-ticket,
     logout, pdf-share-btn и т.п.) переопределяют его своим :active, где
     нужен отдельный эффект. */
  button:active:not(:disabled){opacity:.65;}
  html{
    -webkit-text-size-adjust:100%;text-size-adjust:100%; /* iOS иначе раздувает текст в альбомной ориентации */
    background:var(--bg);
  }
  body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--font-text);padding-bottom:env(safe-area-inset-bottom);transition:background-color .2s,color .2s;
    -webkit-font-smoothing:antialiased;
    touch-action:manipulation;          /* убирает задержку 300мс и зум двойным тапом в Safari */
    overscroll-behavior-y:contain;      /* резиновый отскок не мешает нашему «потянуть для обновления» */
  }
  /* Пока открыта модалка, фон под ней на iOS прокручивался и «уезжал». Фиксируем страницу,
     позицию скролла запоминаем в JS и возвращаем при закрытии. */
  body.modal-open{position:fixed;left:0;right:0;width:100%;overflow:hidden;}
  .wrap{max-width:var(--content-max);margin:0 auto;
    padding-left:calc(16px + env(safe-area-inset-left));
    padding-right:calc(16px + env(safe-area-inset-right));}
  /* На короткой странице (мало месяцев в Истории и т.п.) строка версии внизу
     раньше повисала сразу под контентом с большим пустым куском экрана ниже —
     выглядело как будто она "оторвалась". #app растянут на весь экран, у
     .page-wrap (тот самый .wrap с контентом, не шапка) ровно одна из трёх
     вкладок реально видна и получает flex:1 - она и вытягивается, забирая
     пустое место на себя, а строка версии остаётся сразу под контентом с тем
     же отступом, что и раньше, просто теперь у самого низа экрана. */
  #app{display:flex;flex-direction:column;min-height:100vh;min-height:100dvh;}
  .page-wrap{display:flex;flex-direction:column;flex:1;}
  #tab-day,#tab-history,#tab-week{flex:1 0 auto;}
  header{padding:calc(20px + env(safe-area-inset-top)) calc(16px + env(safe-area-inset-right)) 18px calc(16px + env(safe-area-inset-left));background:var(--brand);color:var(--brand-text);position:relative;overflow:hidden;}
  .header-top{padding-left:0;padding-right:0;position:relative;z-index:2;display:flex;justify-content:space-between;align-items:flex-end;gap:8px;}
  .header-top>div:first-child{min-width:0;}
  /* h1 и .subtitle уже были защищены от переноса, а надстрочник — нет:
     на узком экране «Guru Maps · Учёт пройденного» ломался на две строки
     и толкал заголовок вниз. Текст укоротил и добавил ту же защиту. */
  .eyebrow{font-family:var(--font-mono);font-size:11px;letter-spacing:.11em;text-transform:uppercase;
    color:var(--amber);margin-bottom:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  h1{font-family:var(--font-display);font-size:24px;font-weight:700;margin:0 0 3px;letter-spacing:-0.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  /* Выделение текста отключено намеренно: быстрые тапы для пасхалки браузер
     принимал за попытку выделить текст (двойной/тройной клик), это перехватывало
     жест и сбивало счётчик. Само имя всё равно не тот текст, который копируют. */
  #headerName{-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;}
  /* Заголовки вкладок живут на светлом фоне контента, не в тёмной шапке — свой
     размер и отступ снизу, чтобы не путать со стилем h1 в шапке. */
  .tab-title{font-family:var(--font-display);font-size:19px;font-weight:700;
    color:var(--ink);margin:4px 0 14px;}
  @media (max-width:360px){ h1{font-size:22px;} }
  .subtitle{font-size:13px;color:var(--brand-text-soft);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .header-actions{display:flex;align-items:center;gap:8px;flex-shrink:0;}
  /* Раньше блок опирался на общий класс .wrap — тот же, что и верхний ряд шапки,
     но header уже даёт 16px отступа сам, а .wrap добавляет ещё 16px сверху, если
     их не погасить отдельным правилом. Вчера я сузил гашение до .header-top и
     случайно снял его с этого блока — полоса стала на 16px уже с каждой стороны,
     чем верхний ряд. Теперь центрирование задано прямо здесь, без зависимости
     от чужого класса и его побочных правил. */
  .goal-strip{position:relative;z-index:2;margin-top:14px;max-width:var(--content-max);margin-left:auto;margin-right:auto;}
  .goal-strip-top{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:6px;}
  .goal-strip-label{font-family:var(--font-mono);font-size:12px;color:var(--brand-text-soft);}
  .goal-strip-nums{font-family:var(--font-mono);font-size:12px;color:var(--amber);white-space:nowrap;}
  .goal-strip-nums .of{color:var(--brand-text-soft);}
  /* Медаль переехала в строку с цифрами, где текст и так 12px — она помещается там
     без запаса по высоте. Поэтому обёртки-строки вокруг полосы больше нет: полоса
     снова занимает всю ширину и остаётся ровно 4px, шапка не становится выше. */
  .goal-strip-bar{position:relative;height:4px;background:var(--brand-line);border-radius:2px;overflow:hidden;}
  /* Два слоя, а не один: зелёный лежит на всю пройденную длину, янтарный поверх него
     занимает ровно долю плана. Стык оттенков и показывает, где было 100%. */
  .goal-strip-over{position:absolute;left:0;top:0;height:100%;width:0;background:var(--green);border-radius:2px;transition:width .4s;}
  .goal-strip-fill{position:absolute;left:0;top:0;height:100%;background:var(--amber);border-radius:2px;transition:width .4s;}
  /* Медаль и цифры — одна визуальная строка, поэтому центрируются по общей оси.
     Родитель .goal-strip-top для этого переведён с baseline на center: у круглой
     медали нет базовой линии текста, и по baseline она села бы выше цифр. */
  .goal-strip-nums-wrap{display:flex;align-items:center;gap:6px;}
  /* Вариант 6б: строка экипажа 13px, имя янтарным, кнопка карты 22px за именем. */
  .crew-strip{display:block;width:100%;margin-top:6px;padding:0;background:none;border:0;cursor:pointer;text-align:left;
    font-family:var(--font-mono);font-size:13px;color:var(--brand-text-soft);}
  .crew-who{min-width:0;}
  .crew-name{color:var(--amber);font-weight:600;}
  .crew-geo{position:relative;width:22px;height:22px;flex:0 0 22px;margin-left:8px;padding:0;border-radius:7px;vertical-align:middle;
    border:1px solid var(--amber);background:none;color:var(--amber);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;}
  .crew-geo svg{width:13px;height:13px;}
  .crew-geo::after{content:"";position:absolute;inset:-11px;}  /* область касания 44px при видимых 22 */
  .name-row{display:flex;align-items:center;gap:10px;min-width:0;margin-bottom:3px;}
  .name-row h1{margin:0;min-width:0;}
  .geo-eye{position:relative;flex:0 0 auto;}
  .geo-eye-btn{position:relative;width:28px;height:28px;padding:0;border:0;border-radius:8px;background:var(--amber);
    color:#1B2430;display:flex;align-items:center;justify-content:center;cursor:pointer;}
  .geo-eye-btn::after{content:"";position:absolute;inset:-8px;}  /* область касания 44px */
  .geo-lid{transform-origin:12px 12px;transform-box:view-box;transition:transform 90ms ease-in-out;}
  .geo-lid.shut{transform:scaleY(.1);}
  .geo-eye-count{position:absolute;top:-6px;right:-6px;min-width:16px;height:16px;padding:0 3px;box-sizing:border-box;
    border-radius:8px;background:#EDEEEA;color:#1B2430;border:2px solid #1B2430;font-family:var(--font-mono);
    font-size:10px;font-weight:600;line-height:12px;text-align:center;}
  .geo-eye-pop{position:fixed;z-index:400;width:200px;padding:12px;border-radius:12px;
    background:#26313F;border:1px solid #3A4552;box-shadow:0 8px 24px rgba(0,0,0,.35);color:#EDEEEA;}
  .geo-eye-pop-t{font-size:12px;color:#9AA3AE;margin-bottom:6px;}
  .geo-eye-list{font-size:14px;line-height:1.7;max-height:180px;overflow-y:auto;overflow-wrap:anywhere;}
  .geo-eye-stop{display:block;width:100%;margin-top:10px;height:34px;border:0;border-radius:8px;background:var(--amber);
    color:#1B2430;font:inherit;font-size:13px;font-weight:600;cursor:pointer;}
  .geo-share-row{display:flex;gap:10px;align-items:flex-start;margin:12px 0 10px;font-size:12.5px;line-height:1.45;color:var(--ink-soft);cursor:pointer;}
  .geo-share-row b{color:var(--ink);font-weight:600;}
  .geo-share-row input{margin-top:2px;flex:0 0 auto;}
  .geo-modal{position:fixed;inset:0;z-index:300;flex-direction:column;background:var(--bg,#111821);
    padding-top:env(safe-area-inset-top,0px);padding-bottom:env(safe-area-inset-bottom,0px);}
  /* Шторка «кого показать» - короткий список + кнопка, полноэкранный geo-modal
     тут не нужен. */
  .geo-pick-backdrop{position:fixed;inset:0;z-index:299;background:rgba(0,0,0,.5);}
  .geo-pick-sheet{position:fixed;left:0;right:0;bottom:0;z-index:300;display:flex;flex-direction:column;
    background:var(--bg,#111821);border-radius:16px 16px 0 0;box-shadow:0 -8px 24px rgba(0,0,0,.35);
    max-height:80vh;}
  .geo-pick-sheet .geo-top{border-radius:16px 16px 0 0;}
  .geo-top{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:10px 14px;background:#1B2430;color:#EDEEEA;}
  .geo-top .btn{margin:0;height:36px;width:auto;padding:0 14px;}
  /* v2.77.2: шапка карты тёмная в обеих темах, а .btn-ghost берёт цвет текста из темы -
     в светлой «Закрыть»/«Отмена» становились тёмно-синими на тёмно-синем, одна рамка. */
  .geo-top .btn-ghost{color:#EDEEEA;border-color:rgba(237,238,234,.45);background:none;}
  .geo-title{font-family:var(--font-display);font-weight:700;font-size:16px;}
  .geo-canvas{position:relative;flex:1;overflow:hidden;background:#dfe3dc;touch-action:none;}
  .geo-ymap{position:absolute;inset:0;}
  /* Кнопка «Маршрут»: в списке под картой и в окошке метки напарника. */
  .geo-line{display:flex;align-items:center;gap:8px;justify-content:space-between;}
  .geo-navi{flex:0 0 auto;height:30px;padding:0 12px;border:0;border-radius:8px;background:#F2A900;color:#1B2430;
    font:inherit;font-size:12.5px;font-weight:600;cursor:pointer;}
  .geo-ymap .geo-navi{margin-top:6px;height:34px;width:100%;}
  .geo-ctrl{z-index:2;}
  .geo-fail{position:absolute;inset:0;z-index:3;display:flex;flex-direction:column;align-items:center;justify-content:center;
    gap:8px;padding:24px;text-align:center;background:var(--bg,#111821);color:var(--ink);font-size:15px;font-weight:600;}
  .geo-fail-sub{font-size:12.5px;font-weight:400;color:var(--ink-soft);max-width:260px;line-height:1.45;}
  .geo-fail .btn{width:auto;margin-top:6px;padding:0 16px;}
  .geo-mark{position:absolute;transform:translate(-50%,-50%);pointer-events:none;}
  .geo-dot{display:block;width:18px;height:18px;border-radius:50%;background:#F2A900;border:3px solid #fff;box-shadow:0 0 0 6px rgba(242,169,0,.25);}
  .geo-mark.me .geo-dot{background:#2F6FDE;box-shadow:0 0 0 6px rgba(47,111,222,.22);}
  .geo-lbl{position:absolute;left:50%;bottom:24px;transform:translateX(-50%);white-space:nowrap;background:#1B2430;color:#EDEEEA;font-size:11px;padding:2px 6px;border-radius:6px;}
  .geo-ctrl{position:absolute;right:10px;top:10px;display:flex;flex-direction:column;gap:6px;}
  .geo-ctrl button{width:40px;height:40px;border-radius:10px;border:0;background:#1B2430;color:#EDEEEA;font-size:20px;display:flex;align-items:center;justify-content:center;cursor:pointer;}
  .geo-ctrl svg{width:18px;height:18px;}
  /* v2.80.0: «Я» - слежение включено: янтарная, точка прицела закрашена. */
  .geo-ctrl .geo-me-btn.on{background:#F2A900;color:#1B2430;}
  .geo-me-btn.on .geo-me-dot{fill:currentColor;}
  .geo-seek{position:absolute;left:50%;top:56px;transform:translateX(-50%);z-index:2;pointer-events:none;white-space:nowrap;
    background:#1B2430;color:#F2A900;font:600 13px 'IBM Plex Mono',monospace;padding:7px 14px;border-radius:14px;}
  /* v2.83.0: переключатель «Лидар» на картах, как на iPhone. */
  .lidar-sw{position:absolute;left:10px;top:10px;z-index:2;display:flex;align-items:center;gap:8px;cursor:pointer;user-select:none;
    background:#1B2430;color:#EDEEEA;font:600 13px Inter,sans-serif;padding:6px 12px 6px 8px;border-radius:20px;}
  .lidar-sw input{position:absolute;opacity:0;width:0;height:0;}
  .lidar-sw-tr{position:relative;width:36px;height:22px;border-radius:11px;background:#4B5563;transition:background .2s;flex:none;}
  .lidar-sw-tr::after{content:'';position:absolute;left:3px;top:3px;width:16px;height:16px;border-radius:50%;background:#fff;transition:transform .2s;}
  .lidar-sw input:checked + .lidar-sw-tr{background:#EC4899;}
  .lidar-sw input:checked + .lidar-sw-tr::after{transform:translateX(14px);}
  .geo-attr{position:absolute;right:4px;bottom:2px;font-size:10px;color:#333;background:rgba(255,255,255,.7);padding:0 4px;border-radius:3px;}
  .geo-status{padding:12px 16px;background:#1B2430;color:#EDEEEA;font-family:var(--font-mono);font-size:12.5px;line-height:1.6;min-height:48px;}
  .geo-pick-row{display:flex;align-items:center;gap:10px;padding:10px 2px;border-bottom:1px solid var(--line);cursor:pointer;user-select:none;}
  .geo-pick-row:last-child{border-bottom:0;}
  .geo-pick-av{width:28px;height:28px;border-radius:50%;background:var(--surface-2);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;flex:0 0 28px;}
  .geo-pick-row span.nm{flex:1;font-size:14px;}
  .geo-pick-chk{width:22px;height:22px;border-radius:6px;border:1.5px solid var(--line);position:relative;flex:0 0 22px;}
  .geo-pick-chk.on{background:var(--amber);border-color:var(--amber);}
  .geo-pick-chk.on::after{content:"";position:absolute;left:7px;top:3px;width:5px;height:10px;border:solid #1B2430;border-width:0 2px 2px 0;transform:rotate(45deg);}
  .crew-row{display:flex;align-items:center;gap:8px;line-height:1.6;min-width:0;}
  .crew-row .crew-who{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .crew-row .crew-nums{white-space:nowrap;color:var(--brand-text);}
  .crew-row .crew-nums b{color:var(--amber);font-weight:inherit;}
  .crew-row .crew-geo{margin-left:0;}
  /* v2.85.3: строка экипажа всегда в одну строку (вторая съедала место в шапке);
     не влезло - многоточие у статуса (.crew-live, flex-shrink:100), имена целые. */
  /* С тремя строками слева кнопки справа держатся ряда имени, а не опускаются к экипажу. */
  .header-top .header-actions{align-self:flex-start;margin-top:2px;}
  .crew-pop{width:240px;}
  .crew-pop-row{display:flex;align-items:center;gap:8px;padding:8px 0;border-bottom:1px solid #3A4552;
    font-family:var(--font-mono);font-size:13px;}
  .crew-pop-row .nm{flex:1;min-width:0;font-family:var(--font-body,inherit);font-size:14px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .crew-pop-row b{color:var(--amber);font-weight:inherit;}
  .crew-pop-row .all{color:#6FBF73;}
  .crew-pop-row .none{color:#9AA3AE;}
  .crew-pop-set{display:block;width:100%;margin-top:8px;padding:6px 0 0;border:0;background:none;color:#A9B2BC;
    font:inherit;font-size:12.5px;text-align:left;cursor:pointer;}
  .goal-medal{flex:0 0 auto;display:none;align-items:center;justify-content:center;
    width:14px;height:14px;border-radius:50%;background:var(--green);}
  .goal-medal svg{display:block;}
  /* Пустое состояние — не просто текст, а кнопка: тап по ней сразу ведёт задавать
     цель, а не заставляет искать, где это делается. Стрелка справа — минимальный
     намёк на то, что строка кликабельна, без отдельной иконки. */
  .goal-strip-empty{display:flex;align-items:center;justify-content:space-between;gap:8px;
    width:100%;background:none;border:none;padding:0;margin-bottom:6px;cursor:pointer;}
  .goal-strip-empty .goal-strip-label{color:var(--amber);}
  .goal-strip-cta{font-family:var(--font-mono);font-size:12px;font-weight:700;color:var(--amber);white-space:nowrap;}
  .goal-strip-bar-ghost{height:4px;}
  /* Облачко висит чуть ниже полосы цели и указывает на неё стрелкой — не общий
     тост снизу экрана (те про прошедшее действие, не про «попробуй вот это»),
     а именно локальная подсказка рядом с тем местом, о котором идёт речь. */
  .goal-nudge{position:fixed;top:calc(20px + env(safe-area-inset-top) + 118px);
    left:16px;right:16px;max-width:400px;margin:0 auto;z-index:150;
    background:var(--amber);border-radius:10px;padding:12px 14px;
    box-shadow:0 8px 24px rgba(0,0,0,.25);animation:goal-nudge-in .3s ease-out;}
  .goal-nudge-arrow{position:absolute;top:-6px;left:24px;width:12px;height:12px;
    background:var(--amber);transform:rotate(45deg);}
  .goal-nudge-text{color:#1B2430;font-size:13px;line-height:1.45;font-weight:600;}
  .goal-nudge button{margin-top:10px;background:none;border:none;padding:0;
    color:#1B2430;font-size:12.5px;font-weight:700;text-decoration:underline;cursor:pointer;}
  @keyframes goal-nudge-in{from{opacity:0;transform:translateY(-6px);}to{opacity:1;transform:none;}}
  /* Облачко про чипсы живёт не в шапке, а рядом с самими чипсами — те скроллятся
     вместе со страницей, поэтому position:fixed (как у подсказки цели) тут не
     подходит: чипсы могут оказаться где угодно по высоте экрана. Тот же вид,
     но в потоке документа, сразу под тем, на что указывает. */
  .chips-nudge{position:relative;margin-top:10px;background:var(--amber);border-radius:10px;
    padding:12px 14px;animation:goal-nudge-in .3s ease-out;}
  .chips-nudge-arrow{position:absolute;top:-6px;left:24px;width:12px;height:12px;
    background:var(--amber);transform:rotate(45deg);}
  .chips-nudge-text{color:#1B2430;font-size:13px;line-height:1.45;font-weight:600;}
  .chips-nudge button{margin-top:10px;background:none;border:none;padding:0;
    color:#1B2430;font-size:12.5px;font-weight:700;text-decoration:underline;cursor:pointer;}
  /* v2.93: поздравление с медалью месяца — ночное небо с фейерверком, 3D-монета,
     своя музыка у каждой ступени. Цвет металла задаётся классом на оверлее. */
  #goalAchievedOverlay{--coin-y:calc(env(safe-area-inset-top) + 30vh);display:none;position:fixed;inset:0;z-index:400;overflow:hidden;background:#070b11;
    --m1:#FFF1B8;--m2:#F2A900;--m3:#A86F00;--edge:#7A5000;--mink:#3b2a00;--glow:242,169,0;}
  #goalAchievedOverlay.show{display:block;}
  #goalAchievedOverlay.silver{--m1:#FFFFFF;--m2:#C3CCD6;--m3:#6F7B87;--edge:#4f5a65;--mink:#26303a;--glow:205,218,232;}
  #goalAchievedOverlay.bronze{--m1:#FFD9B0;--m2:#C77838;--m3:#6E3A14;--edge:#4f260b;--mink:#331806;--glow:214,130,70;}
  #goalAchievedOverlay.platinum{--m1:#FFFFFF;--m2:#DDE8F2;--m3:#8FA6BC;--edge:#5e7489;--mink:#1d2a36;--glow:170,220,255;}
  #gaSky{position:absolute;inset:0;width:100%;height:100%;z-index:1;}
  .gw-shk{position:absolute;inset:0;z-index:2;}
  #goalAchievedOverlay.hit .gw-shk{animation:gw-shake .6s cubic-bezier(.36,.07,.19,.97);}
  @keyframes gw-shake{10%,90%{transform:translate(-3px,2px)}20%,80%{transform:translate(6px,-3px)}30%,50%,70%{transform:translate(-8px,4px)}40%,60%{transform:translate(8px,-4px)}}
  .gw-flash{position:absolute;inset:0;background:#FFF8E0;opacity:0;pointer-events:none;z-index:9;}
  #goalAchievedOverlay.hit .gw-flash{animation:gw-flash .5s ease-out;}
  @keyframes gw-flash{0%{opacity:.9}100%{opacity:0}}
  .gw-scene{position:absolute;left:50%;top:var(--coin-y);width:150px;height:150px;margin:-75px 0 0 -75px;perspective:700px;z-index:4;}
  .gw-tilt{width:100%;height:100%;transform-style:preserve-3d;transition:transform .25s ease-out;}
  .gw-coin{position:relative;width:100%;height:100%;transform-style:preserve-3d;opacity:0;}
  #goalAchievedOverlay.go .gw-coin{animation:gw-coin-in 1.5s cubic-bezier(.15,.8,.25,1) var(--coin-delay,.15s) forwards,gw-sway 5s ease-in-out calc(var(--coin-delay,.15s) + 1.65s) infinite;}
  @keyframes gw-coin-in{0%{opacity:0;transform:translateY(-240px) translateZ(-300px) rotateY(0) rotateX(30deg)}15%{opacity:1}75%{transform:translateY(8px) translateZ(40px) rotateY(1100deg) rotateX(-6deg)}90%{transform:translateY(-3px) translateZ(10px) rotateY(1075deg)}100%{opacity:1;transform:rotateY(1080deg)}}
  @keyframes gw-sway{0%,100%{opacity:1;transform:rotateY(1080deg) rotateX(0)}30%{opacity:1;transform:rotateY(1094deg) rotateX(5deg)}70%{opacity:1;transform:rotateY(1066deg) rotateX(-4deg)}}
  .gw-edge{position:absolute;inset:0;border-radius:50%;background:var(--edge);}
  .gw-face{position:absolute;inset:0;border-radius:50%;backface-visibility:hidden;-webkit-backface-visibility:hidden;overflow:hidden;background:radial-gradient(circle at 32% 26%,var(--m1) 0%,var(--m2) 42%,var(--m3) 100%);}
  .gw-face.front{transform:translateZ(7px);}
  .gw-face.back{transform:rotateY(180deg) translateZ(7px);}
  .gw-rim{position:absolute;inset:0;border-radius:50%;background:repeating-conic-gradient(from 0deg,rgba(0,0,0,.22) 0deg 2deg,rgba(255,255,255,.25) 2deg 4deg);-webkit-mask:radial-gradient(circle,transparent 78%,#000 79%);mask:radial-gradient(circle,transparent 78%,#000 79%);}
  .gw-inner{position:absolute;inset:13%;border-radius:50%;background:radial-gradient(circle at 60% 70%,var(--m1) 0%,var(--m2) 55%,var(--m3) 110%);box-shadow:inset 0 3px 6px rgba(255,255,255,.55),inset 0 -4px 8px rgba(0,0,0,.35);}
  .gw-val{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;color:var(--mink);white-space:nowrap;}
  .gw-val b{font-family:var(--font-display);font-size:40px;font-weight:700;line-height:.95;letter-spacing:-.02em;text-shadow:0 1px 0 rgba(255,255,255,.55),0 -1px 0 rgba(0,0,0,.25);}
  .gw-val b small{font-size:20px;}
  .gw-val span{font-family:var(--font-mono);font-size:9px;font-weight:700;letter-spacing:.2em;margin-top:6px;}
  .gw-spec{position:absolute;inset:0;border-radius:50%;background:linear-gradient(115deg,transparent 30%,rgba(255,255,255,.75) 46%,transparent 58%);background-size:260% 100%;background-position:120% 0;mix-blend-mode:screen;}
  #goalAchievedOverlay.go .gw-spec{animation:gw-spec 1.1s ease-in-out calc(var(--coin-delay,.15s) + 1.55s),gw-spec 1.1s ease-in-out calc(var(--coin-delay,.15s) + 4.8s);}
  @keyframes gw-spec{from{background-position:120% 0}to{background-position:-60% 0}}
  .gw-txt{position:absolute;left:0;right:0;bottom:0;max-width:var(--content-max);margin:0 auto;z-index:5;text-align:center;padding:60px 18px calc(18px + env(safe-area-inset-bottom));background:linear-gradient(180deg,transparent,rgba(7,11,17,.85) 35%,#070b11);margin:0 auto;}
  .gw-tier{display:inline-block;font-family:var(--font-mono);font-size:11px;font-weight:700;letter-spacing:.2em;color:var(--mink);padding:5px 12px;border-radius:4px;background:linear-gradient(180deg,var(--m1),var(--m2));white-space:nowrap;transform:scaleX(0);}
  #goalAchievedOverlay.go .gw-tier{animation:gw-rk .45s cubic-bezier(.2,1.5,.4,1) forwards;}
  @keyframes gw-rk{to{transform:scaleX(1)}}
  .gw-ttl{font-family:var(--font-display);font-size:30px;font-weight:700;color:#EDEEEA;margin-top:12px;white-space:nowrap;line-height:1.05;}
  .gw-ttl span{display:inline-block;opacity:0;}
  .gw-ttl .hl{color:rgb(var(--glow));text-shadow:0 0 24px rgba(var(--glow),.6);}
  #goalAchievedOverlay.go .gw-ttl span{animation:gw-slam .34s cubic-bezier(.5,0,.75,0) forwards;}
  @keyframes gw-slam{0%{opacity:0;transform:scale(2.6)}60%{opacity:1}100%{opacity:1;transform:scale(1)}}
  .gw-sub{font-family:var(--font-mono);font-size:12.5px;color:#9aa3ad;margin-top:8px;white-space:nowrap;opacity:0;}
  .gw-sub b{color:rgb(var(--glow));font-weight:500;}
  .gw-nums{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:12px;}
  .gw-nb{background:rgba(255,255,255,.05);border:1px solid rgba(var(--glow),.35);border-radius:8px;padding:8px 6px;opacity:0;transform:translateY(12px);}
  .gw-nb b{display:block;font-family:var(--font-mono);font-size:19px;font-weight:700;color:#EDEEEA;white-space:nowrap;transition:transform .15s;}
  .gw-nb b.hl{color:rgb(var(--glow));}
  .gw-nb span{display:block;font-size:10px;letter-spacing:.08em;color:#9aa3ad;white-space:nowrap;}
  .gw-ok{margin-top:14px;width:100%;height:48px;border:0;border-radius:8px;font-weight:700;font-size:16px;cursor:pointer;font-family:var(--font-text);color:var(--mink);background:linear-gradient(180deg,var(--m1),var(--m2));box-shadow:0 6px 26px rgba(var(--glow),.45);opacity:0;}
  #goalAchievedOverlay.go .gw-sub,#goalAchievedOverlay.go .gw-nb,#goalAchievedOverlay.go .gw-ok{animation:gw-up .4s ease-out forwards;}
  @keyframes gw-up{to{opacity:1;transform:none}}
  /* Для тех, кому мелькание не праздник: без полёта монеты и тряски, всё сразу на месте. */
  @media (prefers-reduced-motion:reduce){
    #goalAchievedOverlay.go .gw-coin{animation:none;opacity:1;transform:rotateY(0);}
    #goalAchievedOverlay.hit .gw-shk,#goalAchievedOverlay.hit .gw-flash,#goalAchievedOverlay.go .gw-spec{animation:none;}
    #goalAchievedOverlay.go .gw-tier{animation:none;transform:none;}
    #goalAchievedOverlay.go .gw-ttl span,#goalAchievedOverlay.go .gw-sub,#goalAchievedOverlay.go .gw-nb,#goalAchievedOverlay.go .gw-ok{animation:none;opacity:1;transform:none;}
  }

  /* ---- v2 монеты: чеканка, лавр, металл с переливом, аура ---- */
  .gw-scene{width:176px;height:176px;margin:-88px 0 0 -88px;}
  .gw-aura{position:absolute;left:50%;top:var(--coin-y);width:0;height:0;z-index:3;pointer-events:none;}
  .gw-rays{position:absolute;left:-240px;top:-240px;width:480px;height:480px;border-radius:50%;
    background:repeating-conic-gradient(from 0deg,rgba(var(--glow),.30) 0deg 5deg,transparent 5deg 15deg);
    -webkit-mask:radial-gradient(circle,#000 20%,transparent 60%);mask:radial-gradient(circle,#000 20%,transparent 60%);opacity:0;}
  .gw-rays.r2{background:repeating-conic-gradient(from 7deg,rgba(255,255,255,.14) 0deg 2deg,transparent 2deg 23deg);}
  .gw-halo{position:absolute;left:-125px;top:-125px;width:250px;height:250px;border-radius:50%;
    background:radial-gradient(circle,rgba(var(--glow),.65) 0%,rgba(var(--glow),.18) 40%,rgba(var(--glow),0) 68%);opacity:0;}
  .gw-wave{position:absolute;left:-90px;top:-90px;width:180px;height:180px;border-radius:50%;border:3px solid rgb(var(--glow));opacity:0;}
  .gw-orbit{position:absolute;left:-118px;top:-118px;width:236px;height:236px;transform:rotateX(72deg);opacity:0;}
  .gw-orbit div{position:absolute;inset:0;border-radius:50%;}
  .gw-orbit i{position:absolute;left:50%;top:-4px;width:8px;height:8px;margin-left:-4px;border-radius:50%;background:#fff;box-shadow:0 0 10px 3px rgb(var(--glow)),0 0 22px 6px rgba(var(--glow),.6);}
  #goalAchievedOverlay.go .gw-rays{animation:gw-fade .7s ease-out calc(var(--coin-delay) + 1.1s) forwards,gw-spin 16s linear infinite;}
  #goalAchievedOverlay.go .gw-rays.r2{animation:gw-fade .7s ease-out calc(var(--coin-delay) + 1.2s) forwards,gw-spin-r 24s linear infinite;}
  #goalAchievedOverlay.go .gw-halo{animation:gw-fade .5s ease-out calc(var(--coin-delay) + 1.1s) forwards,gw-halo 2.2s ease-in-out calc(var(--coin-delay) + 1.6s) infinite;}
  #goalAchievedOverlay.go .gw-wave{animation:gw-wave .9s cubic-bezier(.2,.7,.3,1) calc(var(--coin-delay) + 1.12s) forwards;}
  #goalAchievedOverlay.go .gw-orbit{animation:gw-fade .6s ease-out calc(var(--coin-delay) + 1.6s) forwards;}
  #goalAchievedOverlay.go .gw-orbit div{animation:gw-spin 3.2s linear infinite;}
  #goalAchievedOverlay.go .gw-orbit div:nth-child(2){animation-duration:4.6s;animation-direction:reverse;}
  @keyframes gw-fade{to{opacity:1}}
  @keyframes gw-spin{to{transform:rotate(360deg)}}
  @keyframes gw-spin-r{to{transform:rotate(-360deg)}}
  @keyframes gw-halo{0%,100%{transform:scale(1);opacity:1}50%{transform:scale(1.14);opacity:.75}}
  @keyframes gw-wave{0%{opacity:.95;transform:scale(.7)}100%{opacity:0;transform:scale(3.2)}}
  .gw-face svg{position:absolute;inset:0;width:100%;height:100%;}
  .gw-sheen{position:absolute;inset:0;border-radius:50%;mix-blend-mode:overlay;
    background:conic-gradient(rgba(255,255,255,0) 0deg,rgba(255,255,255,.55) 35deg,rgba(255,255,255,0) 75deg,rgba(255,255,255,0) 170deg,rgba(255,255,255,.4) 215deg,rgba(255,255,255,0) 255deg,rgba(255,255,255,0) 360deg);
    animation:gw-spin 7s linear infinite;}
  #goalAchievedOverlay.platinum .gw-sheen{mix-blend-mode:soft-light;background:conic-gradient(#ff9ecf,#9ecbff,#b6ffd9,#fff3a6,#d4b0ff,#ff9ecf);opacity:.55;}
  .gw-edge{background:linear-gradient(90deg,var(--m3),var(--m1) 50%,var(--m3));}

  /* серебро — чистое холодное; платина — тёмный лик, светлый гурт, звезда-орден и бриллиант */
  #goalAchievedOverlay.silver{--m1:#FFFFFF;--m2:#CDD3DA;--m3:#7B858F;--edge:#5a636c;--mink:#2a3138;--glow:228,232,240;}
  #goalAchievedOverlay.platinum{--m1:#FFFFFF;--m2:#C9D6E6;--m3:#6d7f96;--edge:#3b4a5e;--glow:150,130,255;
    --f1:#56708f;--f2:#26364c;--f3:#0f1724;--mink:#EAF4FF;--leaf:#c9d6e6;}
  .gw-gem{display:none;}
  #goalAchievedOverlay.platinum .gw-gem{display:inline;}
  #goalAchievedOverlay.platinum .gw-starico{display:none;}
  #goalAchievedOverlay.platinum .gw-tier{background:linear-gradient(90deg,#b9a4ff,#9fe6ff,#ffffff,#9fe6ff,#b9a4ff);color:#1d2140;}
  #goalAchievedOverlay.platinum .gw-ttl .hl{background:linear-gradient(90deg,#c7b5ff,#9fe6ff,#ffffff);-webkit-background-clip:text;background-clip:text;color:transparent;text-shadow:none;filter:drop-shadow(0 0 14px rgba(150,130,255,.6));}
  #goalAchievedOverlay.platinum .gw-orbit i{background:#fff;box-shadow:0 0 10px 3px #9fe6ff,0 0 24px 8px rgba(150,130,255,.7);}
  .gw-order{position:absolute;left:-122px;top:-122px;width:244px;height:244px;opacity:0;display:none;}
  #goalAchievedOverlay.platinum .gw-order{display:block;}
  #goalAchievedOverlay.go .gw-order{animation:gw-order-in .6s cubic-bezier(.2,1.6,.4,1) calc(var(--coin-delay) + 1.12s) forwards;}
  #goalAchievedOverlay.go .gw-order svg{animation:gw-spin 30s linear infinite;}
  @keyframes gw-order-in{0%{opacity:0;transform:scale(.4) rotate(-40deg)}100%{opacity:1;transform:scale(1) rotate(0)}}
  /* на тёмном лике платины тиснение — тенью, а не светлой кромкой */
  #goalAchievedOverlay.platinum .gw-face text[fill="#fff"]{fill:#000;opacity:.6;}
  /* Конверт итогов месяца: тёмный экран, пульсирующая медаль-силуэт, кнопка «Открыть» */
  .gw-intro{display:none;position:absolute;inset:0;z-index:10;flex-direction:column;align-items:center;justify-content:center;gap:10px;text-align:center;
    background:radial-gradient(ellipse at 50% 40%,rgba(var(--glow),.18),#070b11 65%);padding:0 24px;}
  #goalAchievedOverlay.intro .gw-intro{display:flex;}
  #goalAchievedOverlay.intro .gw-shk,#goalAchievedOverlay.intro #gaSky{visibility:hidden;}
  .gw-intro-medal{width:120px;height:120px;border-radius:50%;margin-bottom:10px;
    background:radial-gradient(circle at 35% 30%,rgba(255,255,255,.35),rgba(var(--glow),.25) 45%,rgba(0,0,0,.2) 100%);
    box-shadow:0 0 0 2px rgba(var(--glow),.5),0 0 50px 10px rgba(var(--glow),.35);animation:gw-halo 1.8s ease-in-out infinite;}
  .gw-intro-month{font-family:var(--font-mono);font-weight:700;font-size:13px;letter-spacing:.24em;color:rgb(var(--glow));white-space:nowrap;}
  .gw-intro-sub{font-family:var(--font-display);font-weight:700;font-size:24px;color:#EDEEEA;white-space:nowrap;}
  .gw-intro-btn{margin-top:18px;width:220px;height:50px;border:0;border-radius:8px;font-weight:700;font-size:16px;font-family:var(--font-text);cursor:pointer;
    color:var(--mink);background:linear-gradient(180deg,var(--m1),var(--m2));box-shadow:0 6px 26px rgba(var(--glow),.45);}
  /* Тумблер остаётся тумблером, но форма подтянута к остальному интерфейсу:
     скругление 8px, как у полей, чипсов и кнопок, вместо таблетки. Ползунок
     скруглён слабее корпуса (5px против 8), иначе внутри прямоугольника он
     выглядит вставленным из другого набора. */
  .theme-switch{position:relative;width:52px;height:28px;background:none;border:none;padding:0;cursor:pointer;flex-shrink:0;}
  .theme-switch-track{position:absolute;inset:0;background:var(--brand-line);border-radius:8px;display:flex;align-items:center;justify-content:space-between;padding:0 7px;}
  .theme-switch .ts-icon{color:var(--brand-text-soft);position:relative;z-index:1;}
  .theme-switch-knob{position:absolute;top:3px;left:3px;width:22px;height:22px;border-radius:5px;background:var(--brand-text);box-shadow:0 1px 3px rgba(0,0,0,.35);transition:transform .2s;}
  [data-theme="dark"] .theme-switch-knob{transform:translateX(24px);}
  [data-theme="dark"] .theme-switch-track{background:var(--amber-dark);}
  /* Плашка стоит в самом верху вкладки. Раньше она была под кнопкой «Сохранить день»,
     то есть за пределами экрана — человек её не видел и не знал, что данные
     восстановлены. Две явные кнопки вместо одной: «Продолжить» просто убирает плашку
     (данные уже в форме), «Очистить» стирает черновик и обнуляет поля. */
  /* Раньше текст и обе кнопки стояли в один ряд. Пока подсказка была короткой,
     это помещалось - но более длинный, понятный текст («Ты правил этот день,
     но не сохранил...») вместе с двумя широкими кнопками в одну строку на узком
     экране уже не влезал: тексту оставалось несколько пикселей ширины, и он
     разваливался по одному слову на строку. Текст и кнопки - разными ярусами. */
  #draftBanner{display:flex;flex-direction:column;gap:8px;background:var(--paper);
    border:1px solid var(--line);color:var(--ink);border-radius:8px;padding:10px 12px;
    margin-bottom:12px;animation:draft-in .22s ease-out;}
  @keyframes draft-in{from{opacity:0;transform:translateY(-5px);}to{opacity:1;transform:none;}}
  @media (prefers-reduced-motion:reduce){#draftBanner{animation:none;}}
  #draftBannerText{font-size:12.5px;line-height:1.42;}
  .draft-actions{display:flex;gap:8px;}
  .draft-actions button{flex:1;border-radius:8px;padding:8px 4px;font-size:12.5px;font-weight:600;
    cursor:pointer;font-family:var(--font-text);white-space:nowrap;}
  #draftKeepBtn{background:none;color:var(--amber);border:1px solid var(--amber);}
  #draftDiscardBtn{background:none;border:1px solid var(--ink-soft);color:var(--ink-soft);}
  /* Настройки верстаются плоско: карточка внутри шторки — это коробка в коробке,
     две рамки и двойные отступы, из-за чего экран выглядел рыхлым. */
  /* Была набрана как ярлык — моно с разрядкой, тем же приёмом, что «ИТОГО ЗА ДЕНЬ».
     Служебная строка не должна выглядеть акцентом. И висела вплотную под жёлтой
     кнопкой — теперь отделена линией. */
  /* Версия приложения - внизу экрана настроек, тихо. */
  .set-version{text-align:center;font-size:11px;line-height:14px;color:var(--ink-soft);
    font-family:var(--font-mono);padding:20px 0 4px;}
  .page-wrap{padding-bottom:24px;}
  /* Вкладки снизу (настройки -> Внешний вид -> Снизу). Значок над подписью, своё имя
     выбирается в настройках (см. renderTabIcons в app.js); сверху - вкладки без значков,
     как было всегда. */
  .tab-icon{display:none;width:20px;height:20px;margin:0 auto 3px;}
  .tab-icon svg{width:20px;height:20px;display:block;}
  html.nav-bottom .tabs{position:fixed;left:0;right:0;bottom:0;z-index:5;margin:0 auto;
    max-width:var(--content-max);height:calc(58px + env(safe-area-inset-bottom));
    padding:4px 6px env(safe-area-inset-bottom);gap:4px;align-items:flex-start;
    border-radius:0;background:var(--paper);border-top:1px solid var(--line);}
  html.nav-bottom .tab{height:50px;background:none;box-shadow:none;border-radius:12px;
    font-size:12.5px;color:var(--ink-soft);position:relative;
    display:flex;flex-direction:column;align-items:center;justify-content:center;gap:0;}
  html.nav-bottom .tab.active{background:rgba(242,169,0,.14);box-shadow:none;color:var(--amber-dark);}
  html.nav-bottom .tab-icon{display:block;}
  /* Сверху вкладок больше нет - контент начинается с отступа, а снизу нужен запас под панель. */
  html.nav-bottom .page-wrap{padding-top:16px;padding-bottom:calc(80px + env(safe-area-inset-bottom));}
  html.nav-bottom .toast{bottom:calc(72px + env(safe-area-inset-bottom));}
  .set-account{font-size:13px;color:var(--ink-soft);padding-bottom:16px;border-bottom:1px solid var(--line);}
  /* Настройки по разделам (v2.54.0): список кнопок вместо одной длинной ленты.
     #set-home и каждый #set-sec-* переключаются через openSetSection()/openSetHome() в app.js. */
  .set-item{width:100%;display:flex;align-items:center;gap:8px;height:52px;padding:0 14px;
    background:var(--surface);border:1px solid var(--line);border-radius:10px;
    color:var(--ink);font-size:14.5px;font-family:var(--font-text);margin-bottom:8px;cursor:pointer;}
  .set-item span:first-child{flex:0 0 auto;}
  .set-item-hint{margin-left:auto;font-size:12.5px;color:var(--ink-soft);text-align:right;}
  .set-item-arrow{width:16px;height:16px;flex:0 0 16px;color:var(--ink-soft);}
  .set-back{width:32px;height:32px;flex:0 0 32px;border:none;background:none;color:var(--ink);
    padding:0;margin:-4px 0 -4px -6px;display:flex;align-items:center;justify-content:center;cursor:pointer;}
  .set-back svg{width:22px;height:22px;display:block;}
  .set-sec .set-title:first-child{margin-top:0;}
  /* Предпросмотр нижней панели внутри настроек - отдельная мини-копия, не переиспользует
     .tabs/.tab (у тех position:fixed в режиме «снизу», внутри модалки это было бы некстати). */
  .tab-icon-preview{display:flex;gap:4px;background:var(--bg);border:1px solid var(--line);
    border-radius:12px;padding:6px;margin-bottom:14px;}
  .tab-icon-preview-btn{flex:1;height:50px;border:none;border-radius:10px;background:none;
    color:var(--ink-soft);font-size:12.5px;font-family:var(--font-text);
    display:flex;flex-direction:column;align-items:center;justify-content:center;padding:0;}
  .tab-icon-preview-btn.active{background:rgba(242,169,0,.14);color:var(--amber-dark);}
  .tab-icon-preview-ic{width:20px;height:20px;margin-bottom:3px;}
  .tab-icon-preview-ic svg{width:20px;height:20px;display:block;}
  .tab-icon-group{margin-bottom:14px;}
  .tab-icon-group-label{font-size:13px;color:var(--ink);margin-bottom:8px;}
  .tab-icon-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;}
  .tab-icon-opt{height:44px;border-radius:10px;border:1.5px solid var(--line);background:none;
    color:var(--ink-soft);display:flex;align-items:center;justify-content:center;padding:0;cursor:pointer;}
  .tab-icon-opt svg{width:20px;height:20px;display:block;}
  .tab-icon-opt.active{border-color:var(--amber);color:var(--amber-dark);background:rgba(242,169,0,.10);}
  /* Обучалка про переустроенные настройки/вкладки (v2.54.3): точка на шестерёнке + короткая
     выноска, и отдельно - выноска у нижней панели в момент включения режима «снизу».
     Выноска у шестерёнки - position:fixed, координаты ставит JS (getBoundingClientRect в
     positionOnboardTip()), а не вложенность в шапку: на телефонах с увеличенным системным
     шрифтом шапка перестраивается непредсказуемо, и вложенная выноска «уезжала» и растягивалась. */
  .onboard-dot{position:absolute;top:-2px;right:-2px;width:9px;height:9px;border-radius:50%;
    background:var(--amber);pointer-events:none;animation:onboard-pulse 1.8s ease-out infinite;}
  @keyframes onboard-pulse{0%{box-shadow:0 0 0 0 rgba(242,169,0,.55);}
    70%{box-shadow:0 0 0 9px rgba(242,169,0,0);}100%{box-shadow:0 0 0 0 rgba(242,169,0,0);}}
  .onboard-tip{position:fixed;z-index:60;background:var(--surface);
    border:1px solid var(--amber);border-radius:10px;padding:9px 30px 9px 12px;
    font-size:12.5px;line-height:1.4;width:190px;max-width:calc(100vw - 24px);
    box-shadow:0 6px 18px rgba(0,0,0,.30);}
  .onboard-tip::before{content:"";position:absolute;top:-7px;right:8px;width:12px;height:12px;
    background:var(--surface);border-left:1px solid var(--amber);border-top:1px solid var(--amber);
    transform:rotate(45deg);}
  .onboard-tip button{position:absolute;top:6px;right:8px;border:none;background:none;
    color:var(--ink-soft);font-size:11px;line-height:1;padding:2px;cursor:pointer;}
  /* Выноска у нижней панели: короткая, сама исчезает - см. showOnboardBottomTip() в app.js. */
  .onboard-bottom-tip{position:fixed;left:50%;transform:translateX(-50%);
    bottom:calc(66px + env(safe-area-inset-bottom));z-index:20;background:var(--surface);
    border:1px solid var(--amber);border-radius:10px;padding:8px 14px;font-size:12.5px;
    white-space:nowrap;box-shadow:0 6px 18px rgba(0,0,0,.30);}
  .onboard-bottom-tip::after{content:"";position:absolute;bottom:-6px;left:50%;margin-left:-6px;
    width:11px;height:11px;background:var(--surface);border-right:1px solid var(--amber);
    border-bottom:1px solid var(--amber);transform:rotate(45deg);}

  /* Команда (v2.55.0). */
  .team-person{display:flex;align-items:center;gap:8px;min-height:42px;padding:5px 10px;
    background:var(--surface);border:1px solid var(--line);border-radius:10px;margin-bottom:8px;}
  .team-av{width:26px;height:26px;flex:0 0 26px;border-radius:50%;background:var(--surface-2);
    color:var(--ink);font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center;}
  .team-name{flex:1;font-size:13.5px;}
  .team-mini-btn{height:28px;padding:0 10px;border-radius:8px;border:1px solid var(--line);
    background:none;color:var(--ink);font-size:12px;}
  .team-mini-btn.p{background:var(--amber);border-color:var(--amber);color:#1B2430;font-weight:600;}
  .team-mini-btn:disabled{opacity:.45;}
  .team-sub{font-size:11.5px;color:var(--ink-soft);}
  .team-leader-tag{margin-left:6px;font-size:11px;color:var(--ink-soft);font-weight:400;}
  .team-invite-timer{color:var(--ink-soft);font-weight:400;}
  .team-kick-btn{color:var(--red);border-color:var(--red);}
  #teamMembersList .team-person{flex-wrap:wrap;}
  /* Баннер входящего приглашения на «Сегодня» - тот же язык, что у draftBanner. */
  #teamInviteBanner{display:flex;flex-direction:column;gap:10px;background:var(--paper);
    border:1.5px solid var(--amber);border-radius:12px;padding:12px 14px;margin-bottom:16px;}
  .team-invite-row{display:flex;align-items:center;gap:10px;}
  .push-user-row{display:flex;justify-content:space-between;align-items:baseline;gap:10px;padding:6px 0;font-size:13px;border-bottom:1px solid var(--line);}
  .push-user-row:last-child{border-bottom:0;}
  .push-user-name{color:var(--ink);}
  .push-user-state{font-size:12px;text-align:right;}
  .push-user-state.on{color:#4CAF6D;}
  .push-user-state.off{color:var(--ink-soft);}
  .push-user-state.stale{color:var(--amber-dark);}
  .net-pill{position:fixed;left:50%;transform:translateX(-50%);top:calc(env(safe-area-inset-top,0px) + 8px);z-index:400;
    padding:6px 14px;border-radius:999px;background:var(--amber);color:#1B2430;font-size:12.5px;font-weight:600;
    box-shadow:0 4px 14px rgba(0,0,0,.25);white-space:nowrap;pointer-events:none;}
  .net-pill.ok{background:#4CAF6D;color:#0F1319;}
  #geoAskBanner{flex-direction:column;gap:10px;background:var(--paper);border:1.5px solid var(--amber);border-radius:12px;padding:12px 14px;margin-bottom:16px;}
  .geo-ask-ic{display:flex;align-items:center;justify-content:center;color:var(--amber);}
  .geo-ask-ic svg{width:18px;height:18px;}
  .team-invite-av{width:34px;height:34px;flex:0 0 34px;border-radius:50%;background:var(--surface-2);
    color:var(--ink);font-size:13px;font-weight:700;display:flex;align-items:center;justify-content:center;}
  .team-invite-txt{font-size:13px;line-height:1.4;color:var(--ink-soft);}
  .team-invite-txt b{display:block;font-size:14px;color:var(--ink);margin-bottom:1px;}
  .team-invite-btns{display:flex;gap:8px;}
  /* margin:0 - у .btn-ghost глобально margin-top:8px (для кнопки под полем), и в
     паре кнопок в строку «Отмена/Позже» из-за него всегда съезжала на 8px ниже. */
  .team-invite-btns{align-items:center;}
  .team-invite-btns .btn{flex:1;height:38px;font-size:13px;margin:0;}
  /* Метки напарников в списке тикетов при загрузке задания: живой выбор (контур) и
     уже сохранённый тикет (закрашено). Несколько человек на один номер - нормально. */
  .team-picks{display:flex;gap:3px;flex:0 0 auto;}
  .team-chip{width:16px;height:16px;border-radius:50%;font-size:8.5px;font-weight:700;
    display:flex;align-items:center;justify-content:center;color:var(--amber-dark);flex:0 0 16px;}
  .team-chip.live{border:1.5px solid var(--amber);background:none;}
  .team-chip.taken{background:var(--amber);color:#1B2430;border:none;}
  .team-chip.done{background:#4CAF6D;color:#0F1319;border:none;}
  /* Пояснение к кружкам-меткам под списком тикетов (только когда есть команда).
     Два отдельных ряда - «Напарник» (кружки) и «Твоё» (подписи текстом) - это
     разные визуальные языки для одного смысла (взял/выполнил), рядом вперемешку
     они читались как один непонятный список. */
  .team-legend{display:none;flex-direction:column;gap:6px;font-size:11.5px;color:var(--ink-soft);
    padding:10px 2px;margin-bottom:2px;border-top:1px solid var(--line);border-bottom:1px solid var(--line);}
  .team-legend-row{display:flex;flex-wrap:wrap;align-items:center;gap:6px 12px;}
  .team-legend-row span{display:flex;align-items:center;gap:5px;white-space:nowrap;}
  .team-legend-label{flex:0 0 auto;color:var(--ink);font-weight:600;font-size:11px;
    text-transform:uppercase;letter-spacing:.02em;min-width:58px;}
  .team-legend .team-chip{width:13px;height:13px;flex:0 0 13px;font-size:0;}  /* сам кружок без буквы - только форма; flex-basis переопределён следом за width - иначе он побеждает на главной оси и кружок сплющивается в овал */
  .team-legend-pct{font-family:var(--font-mono);color:var(--amber-dark);font-weight:600;}
  .team-legend-done{color:#4CAF6D;}
  .team-legend-done svg{width:13px;height:13px;}
    background:none;color:var(--ink-soft);font-size:16px;line-height:1;padding:0;cursor:pointer;}
  .set-account b{color:var(--ink);font-weight:600;}
  .set-section{padding-top:16px;}
  .set-tabs{margin-top:16px;}
  .set-title{font-family:var(--font-display);font-size:13px;font-weight:600;
    color:var(--ink-soft);text-transform:uppercase;letter-spacing:.06em;margin-bottom:16px;}
  /* Раньше кнопка настроек была заметно выше тумблера — паддинг 8px против рамки
     тумблера в 28px общей высоты. В паре элементов управления разная высота
     читается как нечаянная, а не как решение. Выравниваю обе под 28px. */
  .icon-action{background:none;border:1px solid var(--brand-line);color:var(--brand-text-soft);
    border-radius:8px;width:28px;height:28px;padding:0;cursor:pointer;display:flex;
    align-items:center;justify-content:center;flex-shrink:0;}
  .icon-action:active{background:var(--brand-line);}
  .logout{background:none;border:1.5px solid var(--line);color:var(--red);border-radius:8px;
    padding:0 16px;height:var(--h-field);font-size:14px;font-weight:600;
    font-family:var(--font-text);cursor:pointer;width:100%;}
  .logout:active{opacity:.7;}
  #pullRefreshIndicator{position:fixed;top:-60px;left:50%;transform:translateX(-50%);display:flex;align-items:center;gap:8px;background:var(--brand);color:var(--brand-text-soft);padding:12px 16px;border-radius:0 0 14px 14px;font-size:12px;font-weight:600;z-index:150;transition:top .2s,background-color .15s;pointer-events:none;white-space:nowrap;}
  #pullRefreshIndicator svg{transition:transform .15s;}
  #pullRefreshIndicator.ready svg{transform:rotate(180deg);color:var(--amber);}
  #pullRefreshIndicator.ready-hard{background:var(--red);}
  #pullRefreshIndicator.ready-hard svg{transform:rotate(180deg);color:var(--brand-text);}
  #pullRefreshIndicator.refreshing svg{animation:pull-spin .8s linear infinite;}
  .update-banner{position:fixed;top:0;left:0;right:0;background:var(--amber);color:#1B2430;text-align:center;
    padding:12px 16px;padding-top:calc(11px + env(safe-area-inset-top,0px));
    font-size:13px;font-weight:700;border:none;z-index:250;cursor:pointer;
    transform:translateY(-100%);transition:transform .25s,background-color .2s;}
  .update-banner.show{transform:translateY(0);}
  .update-banner .ub-icon{display:none;margin-right:8px;vertical-align:-2px;}
  .update-banner.applying{background:var(--brand);color:var(--brand-text);cursor:default;}
  .update-banner.applying .ub-icon{display:inline-block;animation:pull-spin .7s linear infinite;}
  body.has-update-banner{padding-top:40px;transition:padding-top .25s;}
  @keyframes pull-spin{to{transform:rotate(360deg);}}
  .tabs{display:flex;gap:2px;margin:16px 0 16px;background:var(--line);border-radius:8px;padding:4px;}
  .tab{flex:1;display:flex;align-items:center;justify-content:center;height:34px;padding:0;font-size:13px;font-weight:600;border-radius:8px;cursor:pointer;color:var(--ink-soft);-webkit-user-select:none;user-select:none;}
  .tab:active{opacity:.6;}
  .tab.active{background:var(--paper);color:var(--ink);box-shadow:0 1px 2px rgba(0,0,0,.08);}
  .card{background:var(--paper);border:1px solid var(--line);border-radius:12px;padding:16px;margin-bottom:16px;}
  /* У секции «Тикеты» своя рамка была лишней: внутри и так рамка у каждого
     тикета (.ticket-card) — получалась рамка в рамке, визуально тяжело.
     Отступы и высота секции остаются как у обычной .card, просто без
     собственных border/background. */
  .card.card-flat{background:none;border:none;}
  /* card-flat всё ещё держит свои 16px паддинга (чтобы заголовок и кнопка
     "+ Добавить тикет" были на одном уровне с текстом других карточек) - но
     у .ticket-card ЕСТЬ СВОЯ рамка, и без компенсации она оказывалась вложена
     ещё на 16px глубже рамок соседних карточек (казалась ощутимо уже).
     Отрицательный отступ у списка тикетов выравнивает рамку .ticket-card
     ровно по рамкам соседних карточек. */
  #ticketList, #em-ticketList{margin:0 -16px;}
  .card h2{font-family:var(--font-display);font-size:15px;margin:0 0 12px;}
  /* Свёрнутая по умолчанию карточка: заголовок сам — кнопка на всю ширину,
     тап в любом месте строки (не только по шеврону) открывает содержимое.
     АКБ и логистика используются не каждый день — держать их развёрнутыми
     всегда означало пролистывать мимо них в самой частой форме дня. */
  .section-toggle{display:flex;align-items:center;justify-content:space-between;
    width:100%;background:none;border:none;padding:0;margin:0;cursor:pointer;
    text-align:left;color:var(--ink);}
  .section-toggle h2{margin:0;}
  .section-chevron{flex-shrink:0;color:var(--ink-soft);transition:transform .15s ease;}
  .section-toggle[aria-expanded="true"] .section-chevron{transform:rotate(180deg);}
  .section-body{margin-top:12px;}
  /* 12 сверху и 6 снизу: подпись должна липнуть к своему полю и заметно
     отставать от предыдущего — иначе непонятно, к чему она относится. */
  label{display:block;font-size:12px;font-weight:600;color:var(--ink-soft);margin-bottom:6px;margin-top:12px;}
  label:first-of-type{margin-top:0;}
  input[type=text],input[type=number],input[type=date],input[type=password],textarea,select{
    width:100%;min-width:0;border:1.5px solid var(--line);background:var(--surface);border-radius:8px;padding:0 12px;
    /* Ровно 16px — при меньшем размере Safari на iPhone при тапе по полю сам увеличивает
       страницу и обратно уже не возвращает. Это была главная причина «скачущей» вёрстки. */
    font-size:16px;font-family:var(--font-text);color:var(--ink);
    -webkit-appearance:none;appearance:none;
    -webkit-text-fill-color:var(--ink); /* Safari игнорирует color в date/disabled-полях */
    height:var(--h-field);line-height:1.25;
  }
  /* Текстовой области фиксированная высота ни к чему — она растёт по содержимому */
  textarea{height:auto;padding:10px 12px;}
  /* Пробовал переводить числовые поля на моноширинный, чтобы номер в поле совпадал
     с номером в чипсе. В крупных полях получилась машинная распечатка — широкие
     символы, рваная разрядка. Поля остаются на Inter: они про ввод, а не про данные.
     Моноширинный оставлен там, где он к месту: чипсы, суммы, отчёты, статистика. */
  textarea{min-height:0;}
  /* -webkit-text-fill-color выше красит и плейсхолдер тоже: без этого правила подсказка
     «0.0» в поле километров выглядела бы как уже введённое значение. */
  input::placeholder,textarea::placeholder{
    color:var(--ink-soft);-webkit-text-fill-color:var(--ink-soft);opacity:.8;
  }
  select{
    padding-right:32px;background-repeat:no-repeat;background-position:right 12px center;background-size:11px;
    background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' fill='none' stroke='%235B6570' stroke-width='2' stroke-linecap='round'/></svg>");
  }
  [data-theme="dark"] select{
    background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' fill='none' stroke='%2393A0AC' stroke-width='2' stroke-linecap='round'/></svg>");
  }
  input:focus,select:focus,textarea:focus{outline:none;border-color:var(--amber);}
  *{-webkit-tap-highlight-color:transparent;}
  button:focus-visible,.tab:focus-visible,.rover-chip:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--teal);}
  .row{display:grid;grid-template-columns:1fr 1fr;gap:12px;} .row>*{min-width:0;overflow:hidden;}
  /* Safari не умеет ужимать input[type=date] внутри грид-колонки: без width:1px он распирает
     ячейку и наезжает на соседнее поле «Ровер». display:block нужен, чтобы iOS не центровал текст. */
  input[type=date]{width:1px;min-width:100%;display:block;text-align:left;}
  /* ::-webkit-date-and-time-value — отдельный псевдоэлемент со своей внутренней
     высотой строки, унаследованный line-height родителя на него не всегда
     распространяется (особенно на iPadOS) — отсюда текст даты сидел чуть выше
     центра поля. Задаю ему ту же высоту строки, что и высота самого поля: тогда
     центрирование по вертикали получается арифметически, а не по наследству. */
  input[type=date]::-webkit-date-and-time-value{text-align:left;margin:0;line-height:calc(var(--h-field) - 3px);}
  input[type=date]::-webkit-calendar-picker-indicator{opacity:.55;}
  /* Галочка и ползунок процентов: системный вид iOS мелкий и всегда синий */
  input[type=checkbox]{width:21px;height:21px;accent-color:var(--amber);-webkit-appearance:auto;appearance:auto;}
  /* Дорожка закрашивается янтарным до бегунка. В WebKit «пройденную» часть
     штатно не покрасить, поэтому заливка рисуется градиентом с резкой границей,
     а точка границы приезжает из JS в переменной --fill. */
  input[type=range]{accent-color:var(--amber);height:34px;background:transparent;-webkit-appearance:none;appearance:none;}
  input[type=range]::-webkit-slider-runnable-track{height:8px;border-radius:6px;
    background:linear-gradient(to right, var(--amber) 0 var(--fill,0%), var(--line) var(--fill,0%) 100%);}
  input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:28px;height:28px;
    border-radius:50%;background:var(--amber);border:3px solid var(--paper);margin-top:-10px;
    box-shadow:0 2px 6px rgba(0,0,0,.28);transition:transform .12s ease;}
  input[type=range]:active::-webkit-slider-thumb{transform:scale(1.12);}
  /* Firefox не понимает -webkit-псевдоэлементы: без пары правил ниже appearance:none
     оставлял бы ползунок вообще без дорожки и бегунка. */
  input[type=range]::-moz-range-track{height:8px;border-radius:6px;background:var(--line);border:none;}
  input[type=range]::-moz-range-progress{height:8px;border-radius:6px;background:var(--amber);border:none;}
  input[type=range]::-moz-range-thumb{width:28px;height:28px;border-radius:50%;background:var(--amber);
    border:3px solid var(--paper);box-shadow:0 2px 6px rgba(0,0,0,.28);}
  input[type=range]:focus{outline:none;box-shadow:none;}
  .segmented{display:flex;border:1.5px solid var(--line);border-radius:8px;overflow:hidden;}
  .status-row{display:flex;align-items:center;justify-content:space-between;gap:12px;}
  .status-row .segmented{width:auto;}
  .status-row .segmented button{flex:0 0 auto;}
  /* Пасхалка: ровер стоит вне потока над шапкой, невидим, пока не запущен явно. */
  /* header держит overflow:hidden — внутри неё уехавший вбок элемент обрежется
     сразу же. Значит ровер должен быть закреплён относительно всего экрана,
     а не внутри шапки, иначе виден только первый сантиметр проезда. */
  #easterRover{position:fixed;left:-48px;top:calc(20px + env(safe-area-inset-top) + 24px);z-index:500;opacity:0;pointer-events:none;}
  #easterRover.driving{opacity:1;animation:easter-drive 2.6s ease-in-out forwards;}
  @keyframes easter-drive{
    0%{transform:translateX(0);}
    8%{opacity:1;}
    88%{opacity:1;}
    100%{transform:translateX(calc(100vw + 48px));opacity:0;}
  }
  @media (prefers-reduced-motion:reduce){
    #easterRover.driving{animation:none;}
  }
  .segmented button{flex:1;border:none;background:var(--surface);padding:0;height:calc(var(--h-field) - 3px);font-size:13px;font-weight:600;color:var(--ink-soft);cursor:pointer;}
  .segmented button.active{background:var(--ink);color:var(--paper);}
  /* Два счётчика бок о бок: форма не растёт в высоту, а связь между ними
     («это две работы по одной ставке») читается сразу. min-width:0 обязателен,
     иначе на узком экране Safari даёт колонкам разъехаться. */
  /* По строке на каждую замену: с тремя АКБ за день нужно знать, какая была утром,
     а какая вечером — раньше это приходилось дописывать в поле руками. */
  /* Ширину и высоту урезал: это пометка к полю выше, а не главное действие
     в карточке. На всю ширину и в 42px они перевешивали сам ввод. */
  /* Поле и кнопки времени стоят в одной строке: поле тянется, кнопки держат
     свою ширину. Высоту берём от поля, иначе они не выровняются по нижнему краю. */
  .akb-row{display:flex;gap:8px;align-items:center;}
  .akb-row input{flex:1;min-width:0;}
  .akb-row .akb-when{margin-top:0;flex-shrink:0;}
  .akb-when{display:inline-flex;border:1px solid var(--line);border-radius:8px;overflow:hidden;margin-top:8px;}
  .akb-when button{background:var(--surface);border:none;/* Жирность постоянная: раньше она включалась только у выбранной кнопки,
     текст становился шире и обе кнопки заметно сдвигались. */
    font-weight:600;padding:0 14px;height:calc(var(--h-field) - 2px);font-size:12px;
    font-family:var(--font-text);color:var(--ink-soft);cursor:pointer;white-space:nowrap;}
  .akb-when button+button{border-left:1px solid var(--line);}
  /* Выбранное состояние окрашено по смыслу, а не одинаковой тёмной плашкой:
     утро — тёплый рассветный оттенок, вечер — сумеречный синий. Так пара
     читается с одного взгляда, не вчитываясь в подписи. */

  .akb-when button.on[data-w="утро"]{background:#FBE2AE;color:#6E4A0E;}
  .akb-when button.on[data-w="вечер"]{background:#39406B;color:#DDE0F2;}
  /* В тёмной теме те же два настроения, но не такие яркие, как на светлом фоне —
     полная светлая «утренняя» заливка била бы по глазам. Приглушение раньше было
     чрезмерным: контраст с невыбранной кнопкой падал до 1.1–1.5, и нажатое
     состояние на глаз не отличалось от обычного. Теперь контраст 2.4–3.0 —
     заметно, но не кричаще. */
  [data-theme="dark"] .akb-when button.on[data-w="утро"]{background:#9C6816;color:#F5CE86;}
  [data-theme="dark"] .akb-when button.on[data-w="вечер"]{background:#525DA3;color:#EDEFFB;}
  /* Счётчик и его подпись — одной строкой, поле с роверами идёт под ними.
     В две колонки логистика оказывалась оторванной от своего поля ввода. */
  /* Подпись и счётчик стояли одной строкой по краям карточки, и между ними
     провисала пустота в пол-экрана. Теперь счётчик идёт под своей подписью
     и прижат влево, а поле с роверами раскрывается прямо под ним: вся ветка
     «сколько замен → на каких роверах» читается сверху вниз одной колонкой.
     Ширина по содержимому — растягивать счётчик на всю карточку незачем,
     он не поле ввода. */
  .unit-block label{margin-top:0;}
  .unit-block .stepper{width:136px;}
  /* Ширина была по содержимому — счётчики получались узкими и не совпадали
     с полями под ними. Фон задаём всей полоске, а не отдельно кнопкам:
     раньше на стыке кнопки и числа проступала полоска другого оттенка. */
  .stepper{display:flex;align-items:center;border:1.5px solid var(--line);border-radius:8px;
    overflow:hidden;width:100%;background:var(--surface);}
  .stepper button{width:44px;flex-shrink:0;height:calc(var(--h-field) - 3px);border:none;
    background:transparent;font-size:18px;cursor:pointer;color:var(--ink);}
  .stepper span{flex:1;text-align:center;font-family:var(--font-mono);font-weight:600;font-size:15px;}
  .ticket-card{border:1.5px solid var(--line);border-radius:12px;padding:12px;margin-bottom:12px;background:var(--surface);}
  /* У .t-collapsed свой padding:10px (см. ниже) - вместе с паддингом .ticket-card
     выше получалось 22px с каждой стороны, а не 10-12: строка была выше и уже,
     чем должна. В свёрнутом виде паддинг даёт только .t-collapsed. */
  .ticket-card.collapsed{padding:0;}
  .ticket-card .head{display:flex;gap:8px;align-items:center;margin-bottom:12px;}
  .ticket-card .head input[type=text]{flex:1;font-weight:600;}
  /* Поле км — фиксированной узкой ширины, номер тикета остаётся растяжимым (flex:1).
     Обе строки одного роста и стиля, чтобы карточка не выглядела разнородной. */
  .ticket-card .head input.t-km{flex:0 0 56px;min-width:0;padding-left:4px;padding-right:4px;font-weight:600;text-align:center;}   /* v2.77.1: было 92px - номер тикета не влезал */
  /* Был голый символ без границ — на фоне обрамлённого поля рядом смотрелся
     недоделанным. Даём ту же рамку и высоту, что у поля номера. */
  .ticket-card .head .del{flex-shrink:0;width:var(--h-field);height:var(--h-field);padding:0;
    display:flex;align-items:center;justify-content:center;
    border:1.5px solid var(--line);border-radius:8px;background:var(--paper);
    color:var(--red);font-size:15px;line-height:1;cursor:pointer;}
  /* Свёрнутый тикет: одна строка вместо семи полей. Статус (.t-collapsed-pct,
     см. ticketStatusBadge) — голая цифра процента или «Готов» при 100%: три
     попытки текста подлиннее («выполнен», «выполнен на N%») всё равно не
     помещались вместе с км и фото на реальных данных. Раньше пытались защитить
     номер сжатием/обрезанием соседей — тоже не спасало на длинных км. Сейчас
     просто разрешаем строке перенестись на вторую, если не влезает: ничего не
     обрезается и не пропадает, только высота карточки не всегда одинаковая. */
  .t-collapsed{display:none;flex-wrap:wrap;align-items:center;gap:6px 9px;padding:10px;
    border-radius:8px;background:var(--surface-2);cursor:pointer;}
  .t-collapsed:active{opacity:.7;}
  .ticket-card.collapsed .t-collapsed{display:flex;}
  .ticket-card.collapsed .t-body{display:none;}
  .t-collapsed-num{font-family:var(--font-mono);font-size:14px;color:var(--ink);}
  .t-collapsed-meta{margin-left:auto;font-size:11px;color:var(--ink-soft);}
  .t-collapsed-pct{font-family:var(--font-mono);font-size:12px;color:var(--ink-soft);}
  .ticket-card:not(.is-zero) .t-collapsed-pct{color:var(--amber-dark);}
  .ticket-card.is-done .t-collapsed-pct{font-weight:700;}
  .t-collapsed-caret{padding-left:4px;font-size:11px;color:var(--ink-soft);}
  /* Второстепенное и частое действие — не должно спорить по весу с «Сохранить
     день». Раньше была амберная заливка, как у первичной кнопки; теперь просто
     нейтральная рамка, как у «Очистить» в баннере черновика. */
  .t-collapse-btn{width:100%;border:1.5px solid var(--ink-soft);background:none;
    color:var(--ink-soft);border-radius:8px;padding:10px;font-size:13px;font-weight:500;
    cursor:pointer;margin-top:16px;}
  .pct-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px;}
  .pct-label{font-size:12px;color:var(--ink-soft);}
  .percent-row{margin-bottom:10px;}
  /* Общий тикет (v2.64.1): кружки без наезда, свой первым и жёлтым, напарник -
     зелёным. Разошлись («Разделить») - тускнеют, синхронизация по номеру больше
     не идёт, но метка «был общий» остаётся видна. */
  .t-shared{display:inline-flex;gap:3px;margin-left:6px;vertical-align:middle;}
  .t-shared .av{width:15px;height:15px;border-radius:50%;font-size:7.5px;font-weight:700;
    display:flex;align-items:center;justify-content:center;flex:0 0 15px;}
  .t-shared .av.me{background:var(--amber);color:#1B2430;}
  .t-shared .av.mate{background:#4CAF6D;color:#0F1319;}
  .t-shared.split{opacity:.4;}
  .t-collapsed .t-shared{margin-left:-4px;}   /* v2.85.0: в свёрнутой строке уже есть gap */
  .ticket-card.mate-sync-flash{box-shadow:0 0 0 2px var(--amber) inset;border-radius:14px;}
  .t-mate-toast{display:flex;align-items:center;gap:8px;margin-top:8px;padding:7px 6px 7px 10px;
    border-radius:9px;background:var(--amber-tint);font-size:12.5px;color:var(--amber-dark);}
  .t-mate-toast-split{border:0;background:none;color:var(--amber-dark);font:inherit;font-weight:700;
    padding:4px 8px;cursor:pointer;flex:0 0 auto;}
  /* Блок фото отделён линией от полей ввода выше — по мокапу, чтобы не путался
     с «Совместно с ровером»: то поле редактируется руками, а тут просто список
     вложений. */
  .t-photos-block{margin-top:14px;padding-top:14px;border-top:1px solid var(--line);}
  .t-photos-label{margin-bottom:8px;display:block;}
  .t-photos-row{display:flex;flex-wrap:wrap;gap:8px;}
  /* Итоговые фото дня — квадрат растягивается на всю ширину своей колонки
     (aspect-ratio:1, не фиксированные px) - при следующем фото просто
     переносится на новую строку под предыдущим, оставаясь тем же размером.
     Раньше пробовали и мелкие миниатюры 76px (казались слишком маленькими),
     и крупные с тематической иконкой карты/дороги внутри пустого квадрата
     (иконку убрали по просьбе - просто «+», без картинки). */
  .cp-columns{display:grid;grid-template-columns:1fr 1fr;gap:12px;}
  .cp-row{display:flex;flex-wrap:wrap;gap:10px;}
  .cp-thumb-unit,.cp-add-tile{width:100%;aspect-ratio:1;border-radius:8px;flex-shrink:0;position:relative;overflow:hidden;}
  .cp-thumb-unit{border:1px solid var(--line);background:var(--paper);}
  .cp-thumb-unit img{width:100%;height:100%;object-fit:cover;display:block;cursor:pointer;}
  .cp-thumb-unit .cp-del{position:absolute;top:6px;right:6px;width:26px;height:26px;border-radius:50%;
    border:none;background:rgba(27,36,48,.72);color:#fff;font-size:14px;line-height:1;cursor:pointer;
    display:flex;align-items:center;justify-content:center;}
  .cp-thumb-unit.uploading img{opacity:.6;}
  .cp-thumb-unit .cp-spinner{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
    background:rgba(27,36,48,.35);}
  /* Пустая плитка — не призыв к действию, а нейтральное место для тапа; амбер
     ей не нужен, он занят кнопкой «Сохранить день». Раньше здесь был амбер у
     итоговых фото (cp-add-tile) и зелёный у фото тикета (t-photo-add) —
     разные цвета для одного и того же действия «добавить фото» без причины,
     свели к одному нейтральному виду. */
  .cp-add-tile{border:1.5px dashed var(--ink-soft);background:none;display:flex;flex-direction:column;
    align-items:center;justify-content:center;color:var(--ink-soft);
    cursor:pointer;padding:4px;gap:8px;}
  .cp-add-tile svg{flex-shrink:0;}
  .cp-add-plus{display:flex;flex-direction:column;align-items:center;gap:2px;}
  .cp-add-plus span:first-child{font-size:20px;line-height:1;}
  .cp-add-plus span:last-child{font-size:12px;line-height:1.1;}
  .cp-group{margin-bottom:14px;}
  .cp-group:last-child{margin-bottom:0;}
  .cp-group-label{font-size:13px;color:var(--ink-soft);margin-bottom:8px;display:block;}
  .t-photo-thumb,.t-photo-add{width:76px;height:76px;border-radius:8px;flex-shrink:0;position:relative;overflow:hidden;}
  /* Обёртка вокруг подтверждённого фото — сама миниатюра сверху, поле подписи
     под ней. У остальных состояний (грузится/не удалось) подписи нет: она имеет
     смысл только когда у фото уже есть настоящий id на сервере, куда её сохранять. */
  .t-photo-unit{width:76px;flex-shrink:0;display:flex;flex-direction:column;gap:3px;}
  .t-photo-unit .t-photo-thumb{width:76px;}
  /* pointer-events:none — иначе метка в углу перехватывала бы тап именно в этом
     месте на изображении, и просмотр на весь экран там бы не открывался. */
  .t-photo-geo-badge{position:absolute;bottom:3px;left:3px;width:16px;height:16px;border-radius:50%;
    background:var(--green);display:flex;align-items:center;justify-content:center;pointer-events:none;}
  .t-photo-caption{width:76px;font-size:9px;padding:3px 4px;border:1px solid var(--line);border-radius:5px;
    background:var(--surface);color:var(--ink);font-family:inherit;}
  .t-photo-thumb{border:1px solid var(--line);background:var(--paper);}
  .t-photo-thumb img{width:100%;height:100%;object-fit:cover;display:block;cursor:pointer;}
  .t-photo-thumb .t-photo-del{position:absolute;top:3px;right:3px;width:20px;height:20px;border-radius:50%;
    border:none;background:rgba(27,36,48,.72);color:#fff;font-size:11px;line-height:1;cursor:pointer;
    display:flex;align-items:center;justify-content:center;}
  .t-photo-thumb.uploading img{opacity:.85;}
  /* Оверлей лежит поверх реального превью фото, а не вместо него — раньше во
     время загрузки был просто тёмный квадрат без картинки, и было не понять,
     снялось ли фото вообще, пока не придёт ответ сервера. */
  .t-photo-overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
    background:rgba(27,36,48,.5);}
  .t-photo-spinner-ring{width:18px;height:18px;border:2.5px solid rgba(255,255,255,.35);
    border-top-color:#fff;border-radius:50%;animation:t-photo-spin .8s linear infinite;}
  @keyframes t-photo-spin{to{transform:rotate(360deg);}}
  @media (prefers-reduced-motion:reduce){.t-photo-spinner-ring{animation:none;border-top-color:rgba(255,255,255,.35);}}
  .t-photo-thumb.failed{border-color:var(--red);}
  .t-photo-overlay.failed{background:rgba(194,68,68,.68);flex-direction:column;gap:4px;padding:4px;text-align:center;}
  .t-photo-overlay.failed span{font-size:9px;color:#fff;line-height:1.2;}
  .t-photo-retry{background:#fff;color:var(--red);border:none;border-radius:5px;font-size:9.5px;
    font-weight:600;padding:2px 6px;cursor:pointer;}
  .t-photo-add{border:1.5px dashed var(--ink-soft);background:none;display:flex;align-items:center;justify-content:center;
    color:var(--ink-soft);font-size:11px;text-align:center;line-height:1.3;cursor:pointer;padding:4px;}
  /* Нижняя шторка выбора источника фото — крупные кнопки вместо тесной плитки. */
  .photo-source-sheet{display:flex;flex-direction:column;gap:10px;}
  .photo-source-btn{width:100%;height:52px;border-radius:10px;border:1.5px solid var(--line);
    background:var(--surface);color:var(--ink);font-size:15px;font-weight:600;cursor:pointer;}
  .photo-source-btn.cancel{border-color:transparent;background:none;color:var(--ink-soft);font-weight:500;}
  /* Шторка координаты — колонка фиксированной высоты, а не растущий по контенту
     блок. Раньше превью 220px + карта 220px + координата + три кнопки просто не
     помещались: шторка начинала скроллиться, и чтобы дотянуться до «Верно» или
     крестика, приходилось листать её вверх-вниз. Теперь превью маленькое,
     кнопки закреплены внизу, а всё лишнее место достаётся карте. */
  /* Раньше overflow:hidden + высота 92dvh: если контент (превью+карта+координата+
     подпись+кнопки) не помещался, всё, что не влезло, просто обрезалось снизу —
     кнопки «Обновить координаты»/«Без координаты» пропадали, и до них было не
     добраться никак, даже листанием. Теперь высота на весь экран, и вместо обрезки —
     прокрутка, но сами кнопки прилипают к низу шторки (position:sticky) и остаются
     на виду всегда, скроллится при нехватке места только то, что над ними. */
  .geo-confirm-sheet{display:flex;flex-direction:column;height:100%;max-height:100%;
    overflow-y:auto;-webkit-overflow-scrolling:touch;}
  /* Шапка с крестиком прилипает к верху: раньше она уезжала при прокрутке шторки
     (карта + подпись + кнопки на планшете не влезают), и закрыть окно было нечем. */
  .geo-confirm-sheet .sheet-head{flex-shrink:0;margin-bottom:10px;position:sticky;top:0;z-index:5;
    background:var(--bg);margin-top:-16px;padding-top:16px;padding-bottom:6px;}
  /* Превью решает одну задачу — понять, о каком снимке речь, поэтому оно
     маленькое: место в шторке нужнее карте. Но 104px оказалось мало, чтобы
     вообще разобрать кадр, а разглядывать иногда нужно — поэтому тап по превью
     открывает фото на весь экран в обычном просмотрщике. */
  .geo-confirm-preview{width:100%;height:150px;object-fit:cover;border-radius:10px;flex-shrink:0;
    background:var(--surface-2, rgba(127,140,158,.10));display:block;cursor:pointer;}
  /* min-height:0 обязателен: без него flex-элемент не даёт себя сжать ниже
     содержимого, и карта выдавливает кнопки за край экрана. */
  /* Карта и подсказка теперь в общей позиционируемой обёртке — сама подсказка
     лежит НАД картой как плашка, а не бледной строкой текста под ней, которая
     терялась и легко пропускалась. */
  .geo-map-area{position:relative;isolation:isolate;flex:1;min-height:200px;margin-top:10px;display:flex;flex-direction:column;}
  .geo-confirm-map{width:100%;flex:1;min-height:200px;border-radius:10px;
    overflow:hidden;touch-action:none;}
  .geo-map-hint{position:absolute;left:50%;top:10px;transform:translateX(-50%);z-index:2;
    display:flex;align-items:center;gap:6px;font-size:11.5px;font-weight:600;color:#fff;
    background:rgba(27,36,48,.82);border-radius:20px;padding:6px 12px;white-space:nowrap;
    box-shadow:0 2px 8px rgba(0,0,0,.25);pointer-events:none;}
  .geo-confirm-coord{margin-top:10px;font-family:var(--font-mono);font-size:17px;font-weight:700;
    color:var(--ink);text-align:center;flex-shrink:0;}
  .geo-confirm-hint{margin-top:14px;font-size:13px;color:var(--ink-soft);text-align:center;}
  .geo-confirm-warning{margin-top:8px;font-size:12.5px;color:var(--amber-dark);text-align:center;
    line-height:1.4;background:rgba(242,169,0,.14);border-radius:8px;padding:8px 10px;}
  .geo-confirm-actions{flex-shrink:0;}
  .geo-caption-wrap{flex-shrink:0;margin-top:10px;}
  .geo-caption-chips{display:flex;flex-wrap:wrap;gap:5px;}
  .geo-caption-chip{border:1.5px solid var(--line);background:none;border-radius:16px;
    padding:6px 12px;font-size:12px;color:var(--ink-soft);font-family:var(--font-text);cursor:pointer;}
  .geo-caption-chip.on{border-color:var(--amber);background:var(--amber-tint);color:var(--amber-dark);}
  .geo-caption-input{width:100%;margin-top:6px;border:1.5px solid var(--line);border-radius:8px;
    padding:9px 10px;font-size:13px;font-family:var(--font-text);background:var(--surface);color:var(--ink);}
  .geo-confirm-actions{display:flex;flex-direction:column;gap:10px;margin-top:18px;
    position:sticky;bottom:0;background:var(--bg);padding-top:10px;padding-bottom:2px;}
  .geo-confirm-actions-row{display:flex;gap:10px;}
  .geo-confirm-actions-row .btn-ghost{flex:1.4;height:var(--h-field);margin-top:0;}
  .geo-confirm-actions-row .btn-text-link{flex:1;width:auto;margin-top:0;}
  /* Ползунок по умолчанию не растягивается во flex-строке — у input[type=range]
     собственная браузерная ширина (около 100–150px), которую надо явно переопределить. */
  .percent-row input[type=range]{width:100%;min-width:0;display:block;}
  /* Цифра процента — кнопка: тап ставит сразу 100%. Тянуть ползунок до упора
     пальцем на ходу неудобно, а «выполнен полностью» — самый частый исход. */
  .percent-row .pct-val{font-family:var(--font-mono);font-weight:400;font-size:15px;
    color:var(--ink-soft);background:none;border:none;padding:2px 0 2px 10px;cursor:pointer;}
  .ticket-card:not(.is-zero) .percent-row .pct-val{color:var(--amber-dark);}
  .ticket-card.is-done .percent-row .pct-val{font-weight:700;}
  /* Была пунктирная и серая — терялась среди карточек тикетов. Потом стала янтарной
     с рамкой и перетянула на себя весь экран: добавление тикета — рутина, а выглядело
     главным действием дня. Зелёная рамка держит форму кнопки, подложка и текст —
     насыщенного травяного тона: видно сразу, но с янтарём итоговой суммы не спорит. */
  /* Рядовое действие формы, а не итог дня: зелёная заливка во всю ширину давала
     ему вес уровня «Сохранить» и перетягивала внимание на себя. */
  .add-ticket{background:none;border:1.5px solid var(--ink-soft);
    color:var(--ink-soft);border-radius:8px;padding:0;width:100%;height:var(--h-field);
    display:flex;align-items:center;justify-content:center;line-height:1;
    font-size:15px;font-weight:600;font-family:var(--font-text);cursor:pointer;}
  .add-ticket:active{opacity:.7;}
  /* Не соперничает ни с зелёным добавлением тикета, ни с янтарным итогом:
     это необязательный шаг, и выглядеть должен именно так. */
  .add-note{background:transparent;border:1.5px solid var(--ink-soft);color:var(--ink-soft);
    border-radius:8px;padding:0;width:100%;height:var(--h-field);margin-bottom:16px;
    font-size:15px;font-weight:600;font-family:var(--font-text);cursor:pointer;}
  .add-note:active{opacity:.7;}
  /* Раньше эти два ряда были обведёнными карточками (border+surface) - в
     приложении так оформлены отдельные КАРТОЧКИ (day-карта, панели), а не
     строки списка. Строки списка (сравни со свёрнутым тикетом, .t-collapsed
     выше) — плоские, на surface-2, без рамки. Раз куратор-блок теперь живёт
     прямо в «Основное» рядом с остальным интерфейсом, а не отдельным
     island'ом внизу, он должен выглядеть тем же языком, а не завезённым
     компонентом. */
  /* Строки теперь сидят прямо в «Основное» (панели выше лишились своего
     фона/рамки), а surface-2 почти сливался с paper-фоном самой карточки -
     контраста едва хватало. surface даёт ту же пару «карточка/paper → строка/
     surface», что и у обычных тикетов (.ticket-card на surface, лежит на
     card-paper) - предсказуемо и достаточно контрастно в обеих темах. */
  .curator-group-row{display:block;width:100%;text-align:left;padding:10px 12px;
    border:none;border-radius:8px;background:var(--surface);
    color:var(--ink);font-size:14px;font-family:var(--font-text);cursor:pointer;}
  .curator-group-row:active{opacity:.7;}
  .curator-check-row{display:flex;align-items:center;gap:12px;padding:0 14px;min-height:48px;
    border:none;border-radius:12px;background:var(--surface);font-size:15px;
    font-family:var(--font-mono);color:var(--ink);margin:0;}
  /* .curator-check-row - это <label>, а глобальное правило label{margin-top:12px;
     margin-bottom:6px} (для подписей полей вроде «Дата»/«Ровер») плюс gap:6px
     у самого списка вместе давали ~24px между строками - неоправданно много
     для плотного чек-листа. margin:0 выше гасит унаследованное, оставляя
     только gap контейнера. */
  /* Уже в дне: приглушаем только галочку и номер - кружки экипажа и значок
     приоритета должны читаться в полную силу (раньше гасилась вся строка). */
  .curator-check-row.curator-dup-row .curator-tick{opacity:.35;}
  .curator-check-row.curator-dup-row > span:not(.team-picks):not(.curator-pri):not(.curator-dup){opacity:.6;}
  .curator-dup-pct{font-family:var(--font-mono);color:var(--amber-dark);font-weight:600;}
  .team-chip.me{box-shadow:0 0 0 1.5px var(--surface),0 0 0 3px var(--ink-soft);}
  /* Глобальный input[type=checkbox] - 21x21px, рассчитан на одиночные поля
     форм («Помнить меня» и т.п.). Рядом с 13px номером тикета в плотном
     списке смотрелся непропорционально крупным - "аляписто". */
  .curator-tick{width:14px;height:14px;flex-shrink:0;}
  .curator-dup{margin-left:auto;font-size:11.5px;font-family:var(--font-text);color:var(--ink-soft);}
  .curator-dup-done{display:flex;align-items:center;gap:4px;color:#4CAF6D;}
  .curator-dup-done svg{width:13px;height:13px;flex:0 0 auto;}
  /* Выполненный дубль - и так приглушён общим .curator-dup-row, но зелёный текст
     должен читаться поверх этого приглушения. */
  .curator-check-row.curator-dup-row .curator-dup-done{opacity:1;}
  /* Расстояние (блокерный/критовый тикет - точка-в-точку, оно всегда есть) -
     простым текстом справа, тем же моно-шрифтом, что и номер тикета слева от
     него. Метка «Ковровая» (обход периметра улиц, единого расстояния нет) -
     отдельной таблеткой: это не число, и смешивать его с метражом визуально
     не стоит. */
  .curator-extra{margin-left:auto;font-size:13px;font-family:var(--font-mono);
    color:var(--ink-soft);white-space:nowrap;}
  .curator-extra-pill{margin-left:auto;font-size:12px;font-family:var(--font-text);
    color:var(--ink-soft);background:var(--surface-2);border-radius:999px;
    padding:4px 12px;white-space:nowrap;}
  #curatorAddBtn:disabled{opacity:.4;cursor:default;}
  .curator-pri{width:16px;height:16px;flex:0 0 16px;display:flex;align-items:center;justify-content:center;}
  .curator-pri svg{width:16px;height:16px;display:block;}
  .curator-pri-blocker{color:#D64545;}
  .curator-pri-crit{color:#E07B2E;}
  .curator-pri-normal{color:var(--ink-soft);}
  /* На карточке тикета значок показываем только у тех, у кого приоритет есть.
     Но если в списке хоть у одного он есть - у остальных (набранных руками)
     оставляем пустое место того же размера, чтобы номера стояли ровно. */
  .curator-pri.t-pri:not(.curator-pri-blocker):not(.curator-pri-crit):not(.curator-pri-normal){display:none;}
  :is(#ticketList,#em-ticketList):has(.t-pri.curator-pri-blocker, .t-pri.curator-pri-crit, .t-pri.curator-pri-normal)
    .curator-pri.t-pri:not(.curator-pri-blocker):not(.curator-pri-crit):not(.curator-pri-normal){display:flex;}
  /* Шапка экрана открытого экипажа: название слева, значок обновления справа,
     под ним время данных; дальше общая галочка в одной колонке с галочками тикетов. */
  .curator-hd{display:flex;align-items:center;justify-content:space-between;gap:8px;min-height:36px;}
  .curator-hd-title{font-size:15px;font-weight:600;color:var(--ink);}
  .curator-refresh-btn{width:36px;height:36px;flex:0 0 36px;border:1px solid var(--line);border-radius:10px;
    background:none;color:var(--ink);display:flex;align-items:center;justify-content:center;padding:0;margin:0;cursor:pointer;}
  .curator-hd-sub{font-size:12px;line-height:16px;color:var(--ink-soft);margin:2px 0 12px;}
  .curator-master{display:flex;align-items:center;gap:12px;height:40px;padding:0 14px;margin:0 0 4px;
    font-family:var(--font-text);font-size:14px;color:var(--ink);cursor:pointer;}
  .curator-master-cnt{margin-left:auto;font-family:var(--font-mono);font-size:13px;color:var(--ink-soft);}
  .curator-empty{padding:8px 0;font-size:13px;color:var(--ink-soft);text-align:center;}
  /* Загрузка: одна строка - подпись реального шага слева (мелко, без процентов), маленький
     радар справа. Метка падает и пульсирует, овал под ней заполняется по мере
     выученного сервером времени этапов (см. renderCuratorLoading и /api/curator/progress). */
  .curator-progress{display:flex;align-items:center;gap:10px;margin-top:4px;}
  .curator-progress-stage{flex:1;min-width:0;font-size:11px;line-height:14px;color:var(--ink-soft);
    font-family:var(--font-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .curator-radar{display:block;width:44px;height:26px;flex:0 0 44px;}
  .curator-ring{transition:stroke-dasharray .45s linear;}
  .curator-pulse{transform-origin:80px 60px;animation:curator-pulse 2.2s ease-out infinite;opacity:0;}
  .curator-pulse-2{animation-delay:1.1s;}
  @keyframes curator-pulse{0%{transform:scale(.12);opacity:.85;}100%{transform:scale(1);opacity:0;}}
  .curator-pin{animation:curator-drop 2.2s ease-in infinite;}
  @keyframes curator-drop{0%{transform:translateY(-20px);opacity:0;}30%{transform:translateY(0);opacity:1;}38%{transform:translateY(-5px);}46%,100%{transform:translateY(0);opacity:1;}}
  @media (prefers-reduced-motion:reduce){.curator-pulse,.curator-pin{animation:none;}.curator-pin{opacity:1;}.curator-ring{transition:none;}}
  .curator-warn{margin-top:6px;font-size:12px;color:var(--amber-dark);line-height:1.4;}
  /* Пустая подпись под названием (пока идёт загрузка) не должна оставлять зазор. */
  .curator-hd-sub:empty{display:none;}
  .checkbox-row{display:flex;align-items:center;gap:8px;margin-top:16px;}
  /* .km-compare-row и id-контейнер #kmBrokenRow заменили прежний .km-broken-row —
     см. комментарий у is-broken ниже про то, почему селекторы переехали на id. */
  /* Новая строка сверху: два источника пробега рядом для сравнения — сумма по
     тикетам (полезный пробег с ровера) и общий трек Guru Maps. Раньше у поля Guru
     не было подписи вообще (карточка называлась «Пройдено» и этого хватало), но
     теперь рядом появилось второе число, и без подписей стало неясно, где какое. */
  .km-compare-row{display:flex;gap:8px;margin-bottom:8px;}
  .km-compare-col{flex:1;min-width:0;}
  .km-compare-col label{display:block;font-size:11px;color:var(--ink-soft);margin-bottom:4px;}
  /* Единица измерения внутри поля, а не отдельной подписью сверху — при короткой
     строке подпись «Километров за день» только отъедала бы место у соседней галочки. */
  /* Раньше высота этой обёртки не задавалась явно — она получалась «как получится»
     от вложенного input и растягивалась родительским flex-рядом (align-items:stretch).
     У соседней плашки Guru высота задана жёстко, напрямую. Два разных способа
     получить одну и ту же цифру на практике считались чуть по-разному — верхний
     край съезжал на конкретных устройствах, хотя оба итоговых числа совпадали.
     Теперь оба элемента получают высоту одним и тем же прямым способом. */
  .km-field{position:relative;flex:1;min-width:0;display:flex;align-items:center;height:var(--h-field);}
  .km-field input{padding-right:38px;}
  /* Раньше «км» центровалось через top:50% от границ контейнера, а цифры в input —
     через line-height поля. Это два независимых центра, которые на деле не совпадали
     на пиксель-два — «км» читалось чуть выше цифр. Теперь оба в одном flex-ряду
     с одинаковым align-items, и оба следуют одной и той же центровке. */
  .km-field .km-unit{position:absolute;right:12px;
    font-size:12px;color:var(--ink-soft);pointer-events:none;line-height:1;}
  /* Два флага взаимоисключающие (Guru слетел / непогода) — раньше каждый был
     полноразмерным полем на всю ширину, вместе съедали почти столько же
     высоты, сколько сам блок «Пройдено» над ними. Теперь — компактные
     таблетки по размеру текста, ни один не нажат = обычный день, отдельного
     слова для этого состояния не нужно. Объясняющий текст под ними убран:
     оба названия говорят сами за себя без абзаца объяснений. */
  .broken-toggle-row{display:flex;gap:6px;margin-bottom:12px;}
  /* Разной высоты кнопки были из-за чужого правила: глобальный сброс
     label:first-of-type{margin-top:0} (для обычных стопок полей формы)
     случайно применялся только к ПЕРВОЙ из двух <label> в этом ряду - вторая
     получала обычные 12px сверху. В родительском flex со stretch margin
     вычитается из доступной высоты, и кнопки расходились ровно на эти 12px.
     Раньше здесь не было своего margin вообще - explicit margin:0
     гарантирует, что обе кнопки не зависят от контекста и чужих правил для
     label. */
  .broken-toggle{position:relative;display:flex;align-items:center;justify-content:center;flex:1;
    border:1.3px solid var(--line);border-radius:7px;padding:7px 4px;cursor:pointer;
    white-space:nowrap;background:var(--paper);margin:0;}
  /* inset:0 + auto width/height на чекбоксе (replaced-элемент) в части Android
     WebView не растягивает его на всю кнопку, а оставляет нативный размер
     ~21×21px - и почему-то в одном состоянии (не отмечен) эта неучтённая
     высота протекала в высоту самой кнопки, а в другом (отмечен) нет: два
     соседних флажка получались разной высоты без всякой видимой причины в
     разметке. Явные top/right/bottom/left и width/height:100% убирают саму
     возможность такой неоднозначности. */
  .broken-toggle input{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;
    opacity:0;margin:0;cursor:pointer;}
  .broken-toggle span{font-size:12px;color:var(--ink-soft);}
  .broken-toggle.on{border-color:var(--amber);background:var(--amber-tint);}
  .broken-toggle.on span{color:var(--amber-dark);font-weight:600;}
  /* Отмеченная галочка гасит поле км визуально — оно больше не то, что считается,
     и не должно выглядеть как обычное готовое к вводу поле. */
  /* Раньше .km-field и галочка лежали в одной строке с классом km-broken-row,
     и класс is-broken вешался прямо на неё. Теперь между ними появилась строка
     сравнения с полезным пробегом, и is-broken переехал на общий id-контейнер
     (#kmBrokenRow/#emKmBrokenRow), который держит обе строки — селекторы ниже
     это учитывают через id, а не через .km-broken-row. */
  #kmBrokenRow.is-broken .km-field input, #emKmBrokenRow.is-broken .km-field input{opacity:.4;}
  .checkbox-row input{width:auto;margin:0;flex-shrink:0;}
  .checkbox-row label{margin:0;font-size:13px;font-weight:500;color:var(--ink);line-height:1.3;}
  .total-card{background:var(--brand);color:var(--brand-text);border-radius:12px;padding:16px;margin-bottom:16px;}
  .total-card .label{font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--brand-text-soft);font-family:var(--font-mono);}
  .total-card .amount{font-family:var(--font-display);font-size:34px;font-weight:700;color:var(--amber);margin:4px 0 8px;}
  .total-card .formula{font-family:var(--font-mono);font-size:12px;color:var(--brand-text-soft);}
  .btn{width:100%;height:var(--h-action);padding:0;border-radius:8px;border:none;font-size:15px;font-weight:700;font-family:var(--font-text);cursor:pointer;}
  .btn-primary{background:var(--amber);color:#1B2430;}
  .btn-primary:disabled{opacity:.5;}
  .btn-ghost{background:transparent;border:1.5px solid var(--line);color:var(--ink);margin-top:8px;}
  .route-list{position:relative;padding-left:24px;}
  .route-list::before{content:'';position:absolute;left:6px;top:6px;bottom:6px;width:2px;background-image:repeating-linear-gradient(180deg,var(--teal) 0 6px,transparent 6px 12px);}
  .route-item{position:relative;padding-bottom:16px;}
  .route-item::before{content:'';position:absolute;left:-22px;top:4px;width:10px;height:10px;border-radius:50%;background:var(--amber);border:2px solid var(--paper);box-shadow:0 0 0 1px var(--teal);}
  .day-card{background:var(--paper);border:1px solid var(--line);border-radius:12px;padding:12px 16px;}
  .day-card.needs-km{background:rgba(242,169,0,.10);border-color:rgba(242,169,0,.4);}
  .needs-km-tag{color:var(--amber-dark);font-weight:700;}
  .day-card .top-row{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:8px;}
  .day-card .date{font-family:var(--font-mono);font-weight:600;font-size:13px;}
  .day-card .sum{font-family:var(--font-mono);font-weight:700;color:var(--amber-dark);font-size:15px;}
  .day-card .meta{font-size:12px;color:var(--ink-soft);line-height:1.5;}
  .day-card .tickets{font-size:13px;margin-top:4px;color:var(--ink);}
  .day-card .del{background:none;border:none;color:var(--red);cursor:pointer;font-size:12px;}
  .empty{text-align:center;padding:32px 12px;color:var(--ink-soft);font-size:13px;}
  .report-output{background:var(--surface);border:1.5px solid var(--line);border-radius:8px;padding:16px;font-family:var(--font-mono);font-size:12px;line-height:1.6;white-space:pre-wrap;overflow-wrap:anywhere;word-break:break-word;color:var(--ink);margin-top:12px;-webkit-user-select:text;user-select:text;-webkit-touch-callout:default;}
  .photo-check-header{display:flex;align-items:center;justify-content:space-between;margin-top:16px;
    font-size:13px;font-weight:600;color:var(--ink);}
  .photo-check-list{margin-top:8px;display:flex;flex-direction:column;gap:6px;}
  /* Каждая строка — сама себе действие: тап по «Отправить» сразу вызывает
     системное «Поделиться» для этого одного тикета. Пакетной отправки нет
     специально — несколько системных меню подряд без отдельного касания на
     каждое браузер не открывает надёжно (проверено на практике). */
  .photo-check-row{display:flex;align-items:center;justify-content:space-between;gap:10px;
    padding:8px 10px;border-radius:8px;border:1px solid var(--line);background:var(--surface);}
  .photo-check-num{display:block;font-size:13px;font-weight:600;color:var(--ink);}
  .photo-check-sub{display:block;font-size:11.5px;color:var(--ink-soft);margin-top:1px;}
  .photo-check-send{flex-shrink:0;border:1.5px solid var(--green);border-radius:7px;background:none;
    color:var(--green);font-size:12px;font-weight:600;padding:7px 12px;cursor:pointer;font-family:inherit;}
  .photo-check-send:disabled{opacity:.6;cursor:default;}
  /* Второстепенное действие — просто текст-ссылка под главной кнопкой, а не
     вторая кнопка того же веса: копирование текста нужно редко, отправка через
     «Поделиться» теперь основной путь. */
  /* Копирование текста — полноценное действие, а не сноска: им пользуются, когда
     системное «Поделиться» не нужно или недоступно. Серая строка без рамки
     читалась как подпись под кнопкой, поэтому даём ей границу и обычный рост,
     но оставляем без заливки — приоритет всё-таки у «Отправить отчёт». */
  .btn-text-link{display:block;width:100%;background:none;border:1.5px solid var(--line);
    border-radius:8px;height:var(--h-field);margin-top:8px;
    font-size:14px;font-weight:600;color:var(--ink-soft);text-align:center;cursor:pointer;font-family:inherit;}
  .btn-text-link:active{opacity:.7;}
  /* PDF-отчёт — отдельный путь отправки, не замена текстовому отчёту, поэтому
     тонкий разделитель отделяет его от пары «Отправить/Скопировать» выше, а
     сама кнопка обведена янтарным, а не залита им — это дополнительное
     действие, не главное действие дня (то остаётся за «Сохранить день»). */
  .pdf-divider{height:1px;background:var(--line);margin:14px 0 10px;}
  .pdf-share-btn{display:flex;flex-direction:column;align-items:center;gap:2px;
    width:100%;border:1.5px solid var(--amber);background:var(--amber-tint);
    border-radius:8px;padding:11px 12px;cursor:pointer;font-family:inherit;
    position:relative;overflow:hidden;isolation:isolate;}
  .pdf-share-btn span, .pdf-share-btn small{position:relative;z-index:1;}
  .pdf-share-btn span{font-size:14px;font-weight:600;color:var(--amber-dark);}
  .pdf-share-btn small{font-size:10.5px;color:var(--ink-soft);}
  .pdf-share-btn:disabled{opacity:.6;cursor:default;}
  .pdf-share-btn:active{opacity:.8;}
  /* Раньше заливка ползла к условному "почти готово" по формуле, которая ничего
     не знала о реальном ходе работы на сервере (см. историю в JS) - это и
     читалось как обманка: быстро долетала до ~90% и подолгу зависала там,
     будто что-то застряло, хотя сервер просто ещё работал. Честнее не
     притворяться, что известен процент, а прямо показать "идёт работа,
     сколько именно - не знаем": бегущая амберная полоса сканирует кнопку
     туда-сюда, пока не придёт ответ, и заменяется на сплошную заливку +
     пульс только в момент реального завершения (ниже, is-ready-fill). */
  .pdf-share-btn .pdf-fill{position:absolute;top:0;left:0;height:100%;width:0%;
    background:var(--amber);opacity:.32;transition:width .3s linear,opacity .2s linear;z-index:0;}
  .pdf-share-btn.is-loading .pdf-fill{width:100%;opacity:1;transition:none;
    background:linear-gradient(90deg, transparent, transparent 35%, var(--amber) 50%, transparent 65%, transparent);
    background-size:250% 100%;animation:pdf-loading-sweep 1.3s linear infinite;}
  @keyframes pdf-loading-sweep{0%{background-position:130% 0;}100%{background-position:-30% 0;}}
  @media (prefers-reduced-motion:reduce){
    .pdf-share-btn.is-loading .pdf-fill{animation:none;background:var(--amber);opacity:.45;}
  }
  .pdf-share-btn.is-ready-fill .pdf-fill{opacity:1;}
  .pdf-share-btn.is-ready-fill span, .pdf-share-btn.is-ready-fill small{color:#1B2430;}
  .pdf-share-btn.is-ready-fill{animation:btn-ready-pulse 1.1s ease-out 4;}
  /* Пульс на пару секунд, когда файл подготовлен и ждёт второго тапа — иначе
     смена подписи с «Готовлю…» на «Отправить →» легко проходит незамеченной. */
  @keyframes btn-ready-pulse{0%{box-shadow:0 0 0 0 rgba(242,169,0,.55);}70%{box-shadow:0 0 0 12px rgba(242,169,0,0);}100%{box-shadow:0 0 0 0 rgba(242,169,0,0);}}
  .is-ready-pulse{animation:btn-ready-pulse 1s ease-out 5;}
  /* Приглашение включить уведомления — снизу, как шторка, не по центру: это простое
     да/нет, а не действие, требующее тёмного фона и полного внимания. Скрыт по
     умолчанию через display:none в JS-логике показа (localStorage rl-push-seen),
     .show добавляется/убирается вместе с анимацией. */
  .push-prompt-overlay{position:fixed;left:0;right:0;bottom:0;z-index:60;display:none;
    justify-content:center;padding:0 12px calc(12px + env(safe-area-inset-bottom));pointer-events:none;}
  .push-prompt-overlay.show{display:flex;}
  .push-prompt-sheet{width:100%;max-width:420px;background:var(--paper);border:1px solid var(--line);
    border-radius:14px;padding:16px;box-shadow:0 8px 24px rgba(0,0,0,.25);pointer-events:auto;
    animation:push-prompt-in .3s cubic-bezier(.2,.8,.2,1);}
  .push-prompt-overlay.closing .push-prompt-sheet{animation:push-prompt-out .22s ease-in forwards;}
  @keyframes push-prompt-in{from{opacity:0;transform:translateY(24px);}to{opacity:1;transform:none;}}
  @keyframes push-prompt-out{from{opacity:1;transform:none;}to{opacity:0;transform:translateY(24px);}}
  @media (prefers-reduced-motion:reduce){.push-prompt-sheet{animation:none;}}
  .push-prompt-row{display:flex;align-items:flex-start;gap:10px;margin-bottom:14px;}
  .push-prompt-row svg{color:var(--amber-dark);flex-shrink:0;margin-top:1px;}
  .push-prompt-title{font-size:15px;font-weight:600;color:var(--ink);}
  .push-prompt-sub{font-size:13px;color:var(--ink-soft);margin-top:2px;line-height:1.4;}
  .push-prompt-actions{display:flex;gap:8px;}
  .push-prompt-actions .btn{margin-top:0;}
  /* Полоска-напоминание — тонкая, под шапкой, без анимации появления (в отличие от
     шторки, это не всплывающее событие, а просто ещё одна строка интерфейса). */
  .push-nudge-strip{display:none;align-items:center;gap:10px;padding:9px 14px;
    background:rgba(242,169,0,.10);border-bottom:1px solid rgba(242,169,0,.35);}
  .push-nudge-strip.show{display:flex;}
  .push-nudge-strip svg{color:var(--amber-dark);flex-shrink:0;}
  .push-nudge-text{font-size:13px;color:var(--ink);flex:1;}
  .push-nudge-strip button{border:none;background:none;padding:2px 4px;cursor:pointer;}
  #pushNudgeEnable{color:var(--amber-dark);font-size:13px;font-weight:700;}
  #pushNudgeClose{color:var(--ink-soft);font-size:15px;}
  /* Был по центру экрана с фоном --paper — контраст с фоном страницы всего
     1.09–1.15 (посчитано по формуле WCAG), то есть почти неотличим от того, что
     под ним, особенно если под тостом оказывался текст. Центр экрана вообще не
     то место для тоста — там как раз то, на что человек смотрит в моменте,
     и тост это перекрывал. Переехал к нижнему краю (обычное место для таких
     уведомлений), фон — фиксированный тёмный вне зависимости от темы: так
     гарантирован контраст с любым содержимым позади, а не только с одной из тем. */
  .toast{position:fixed;left:16px;right:16px;bottom:calc(20px + env(safe-area-inset-bottom));
    margin:0 auto;max-width:420px;background:rgba(90,104,132,.82);color:#F5F6F8;
    -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
    border-radius:10px;padding:0;font-size:13px;font-weight:600;
    opacity:0;pointer-events:none;transform:translateY(8px);
    transition:opacity .25s,transform .25s;z-index:340;
    box-shadow:0 12px 32px rgba(0,0,0,.32);overflow:hidden;}
  .toast.show{opacity:1;pointer-events:auto;transform:none;}
  .toast-row{display:flex;align-items:center;gap:10px;padding:13px 14px 13px 16px;}
  .toast-text{flex:1;min-width:0;line-height:1.4;}
  .toast-close{flex-shrink:0;background:none;border:none;color:#E1E4EC;
    font-size:16px;line-height:1;cursor:pointer;padding:4px;}
  /* Полоса времени — не декоративная деталь, а замена крестика для тех, кто не
     хочет закрывать руками: видно, сколько осталось, не читая текст на бегу. */
  .toast-bar{height:3px;background:rgba(255,255,255,.15);}
  .toast-bar-fill{height:100%;background:var(--amber);width:100%;
    transform-origin:left;animation:toast-shrink 5000ms linear forwards;}
  @keyframes toast-shrink{from{transform:scaleX(1);}to{transform:scaleX(0);}}
  .auth-wrap{max-width:380px;margin:60px auto;padding:0 20px;}
  .auth-toggle{display:flex;gap:8px;margin-bottom:16px;}
  .auth-toggle button{flex:1;padding:8px;border-radius:8px;border:1.5px solid var(--line);background:var(--surface);font-weight:600;cursor:pointer;}
  .auth-toggle button.active{background:var(--ink);color:var(--paper);border-color:var(--ink);}
  .error-msg{color:var(--red);font-size:13px;margin-top:8px;display:none;}
  /* Высота была calc(--h-chip - 3px) — единственное место в проекте, выпадавшее
     из шкалы высот, из-за чего чипсы в разных блоках вставали чуть по-разному.
     Скругление 8px вместо таблетки: то же, что у полей ввода рядом, — чипс читается
     как продолжение поля, которое он заполняет, а не как отдельная метка. */
  .rover-chip{
    display:inline-flex;align-items:center;
    border:1.5px solid var(--line);background:var(--surface);border-radius:8px;padding:0 10px;
    height:var(--h-chip);
    font-size:12px;font-weight:600;color:var(--ink-soft);cursor:pointer;font-family:var(--font-mono);
    position:relative;overflow:hidden;-webkit-user-select:none;user-select:none;
  }
  /* Один контейнер на все ряды чипсов: раньше отступы задавались инлайном
     и разъезжались от блока к блоку (то 2px сверху, то 4px). */
  .chips{display:flex;gap:6px;flex-wrap:wrap;margin-top:6px;}
  .rover-chip.active{background:var(--green-tint);color:var(--green);border-color:var(--green);font-weight:700;}
  .rover-chip.chip-removing::after{content:'';position:absolute;inset:0;background:var(--red);opacity:.3;transform-origin:left;transform:scaleX(0);animation:chip-hold-fill .5s linear forwards;}
  .rover-chip.chip-confirm{background:var(--red);color:#fff;border-color:var(--red);font-weight:700;}
  @keyframes chip-hold-fill{to{transform:scaleX(1);}}
  .stat-label{font-family:var(--font-mono);font-size:11px;color:var(--ink-soft);text-transform:uppercase;letter-spacing:.06em;}
  /* Вкладки года/месяца в «Статистике по всем данным» - тот же визуальный язык,
     что у .rover-chip, но акцент амбером (это навигация внутри статистики, а
     не выбор ровера), и явно горизонтально прокручиваемый ряд, а не перенос
     строк - иначе при большом количестве месяцев ряд разрастётся на пол-экрана. */
  .stat-tabs{display:flex;gap:6px;overflow-x:auto;margin:10px 0;padding-bottom:2px;
    -webkit-overflow-scrolling:touch;}
  .stat-tab{flex:0 0 auto;display:inline-flex;align-items:center;
    border:1.5px solid var(--line);background:var(--surface-2);border-radius:8px;
    padding:0 12px;height:30px;font-size:12px;font-weight:600;color:var(--ink-soft);
    cursor:pointer;font-family:var(--font-mono);white-space:nowrap;}
  .stat-tab.active{background:var(--amber);color:#1B2430;border-color:var(--amber);}
  /* Шапка выбранного месяца (название + км + тренд) стоит в отдельном блоке с
     границей снизу - раньше самый высокий столбик графика мог визуально
     цепляться за эту строку, разделение убирает саму возможность наложения. */
  .stat-month-header{border-bottom:1px solid var(--line);padding-bottom:10px;margin-bottom:14px;}
  .stat-month-header .line1{font-family:var(--font-mono);font-size:12px;color:var(--ink-soft);margin-bottom:4px;}
  .stat-month-trend{font-family:var(--font-mono);font-size:11.5px;}
  .stat-month-trend.up{color:var(--green);}
  .stat-month-trend.down{color:var(--red);}
  .stat-value{font-family:var(--font-display);font-size:22px;font-weight:700;}
  .stat-best{margin-top:16px;padding-top:16px;border-top:1px dashed var(--line);font-size:13px;color:var(--ink-soft);}
  .chart-bars{display:flex;align-items:flex-end;gap:4px;height:150px;width:100%;padding:0 2px;}
  /* В режиме календаря контейнер перестаёт быть полосой столбиков: сбрасываем
     фиксированную высоту и flex, иначе сетка внутри схлопнется. */
  .chart-bars.as-calendar{display:block;height:auto;padding:0;}
  .cal-head,.cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:4px;}
  .cal-head{margin-bottom:6px;}
  .cal-head div{font-family:var(--font-mono);font-size:9px;color:var(--ink-soft);text-align:center;}
  /* Ячейка 44×44 — почти квадрат.
     ВАЖНО (два скриншота подряд с Android, «Размер шрифта» увеличен в настройках
     экрана): сначала пробовали text-size-adjust:none — не помогло, потому что это
     свойство гасит только эвристику «раздуть текст после уменьшения масштаба
     страницы», а здесь работает другой, более сильный механизм — «Масштаб текста»
     в Accessibility самого Chrome, который умножает размер ЛЮБОГО текста на
     странице и специально сделан так, что сайт не может его отключить (это
     осознанная защита доступности, а не баг). Пробовали резиновую высоту ячейки —
     превращало квадраты в прямоугольники разной высоты, тоже не годится.
     Решение: цифры внутри ячейки — это не HTML-текст, а текст внутри SVG (см.
     calendarCellSvg() в JS). Масштаб текста Chrome применяется к обычному потоку
     страницы и не трогает то, что нарисовано как графика внутри SVG — поэтому
     размер остаётся ровно тем, что задан в px, при любом значении этой настройки,
     квадрат не режет и не растягивается, точка/запятая в километрах никуда не
     девается. Для пустых дней (без данных) риска нет — там только номер дня,
     одна строка, оставлен обычным HTML. */
  .cal-cell{position:relative;overflow:hidden;height:44px;border-radius:7px;
    background:var(--surface-2, rgba(127,140,158,.10));}
  .cal-cell svg{position:absolute;inset:0;width:100%;height:100%;display:block;}
  .cal-cell.cal-off{background:rgba(127,140,158,.05);}
  .cal-cell.cal-blank{background:none;}
  /* Скрытие сумм: у каждой суммы две части - настоящее значение (.mv) и точки (.mx). */
  .mx{display:none;}
  html.money-hidden .mv{display:none;}
  html.money-hidden .mx{display:inline;cursor:pointer;}
  /* Глазик: значок показывает действие. Скрыто - открытый глазик, видно - перечёркнутый. */
  .money-eye{width:24px;height:24px;flex:0 0 24px;border:1px solid var(--amber-dark);border-radius:7px;
    background:none;color:var(--amber-dark);display:flex;align-items:center;justify-content:center;
    padding:0;margin:0;cursor:pointer;}
  .money-eye svg{width:14px;height:14px;display:block;}
  .money-eye .ic-eye-off{display:none;}
  html:not(.money-hidden) .money-eye .ic-eye{display:none;}
  html:not(.money-hidden) .money-eye .ic-eye-off{display:block;}
  .total-head{display:flex;justify-content:space-between;align-items:center;height:28px;margin-top:-4px;}
  .stat-label-row{display:flex;align-items:center;justify-content:space-between;height:28px;}
  /* Карточка месяца в Истории: слева название, метаданные и сумма с глазиком,
     справа кнопка «Статистика» на всю высоту карточки. */
  .month-card{display:flex;align-items:center;gap:12px;background:var(--paper);border:1px solid var(--line);
    border-radius:12px;padding:10px 14px;}
  .month-card-left{flex:1;min-width:0;display:flex;flex-direction:column;}
  .month-toggle{display:flex;align-items:center;gap:8px;background:none;border:none;text-align:left;
    padding:4px 0;margin:-4px 0;cursor:pointer;color:inherit;font-family:inherit;line-height:20px;}
  .month-meta{font-family:var(--font-mono);font-size:12.5px;line-height:16px;color:var(--ink-soft);}
  .month-sum-row{display:flex;align-items:center;gap:8px;height:24px;margin-top:4px;}
  .month-sum{font-family:var(--font-mono);font-size:17px;font-weight:700;color:var(--amber-dark);}
  .month-stats-btn{width:68px;height:52px;flex-shrink:0;border:1px solid var(--teal);
    color:var(--teal);background:rgba(127,150,160,.10);border-radius:10px;font-size:11px;line-height:14px;
    font-weight:600;font-family:var(--font-text);display:flex;flex-direction:column;align-items:center;
    justify-content:center;gap:4px;padding:0;cursor:pointer;}
  /* День с записью, но без км (логистика/АКБ): контур вместо столбика. */
  .cal-cell.cal-nokm{box-sizing:border-box;border:1.5px solid var(--amber);}
  /* Дата у пустых дней — единственный оставшийся HTML-текст в календаре, риск
     обрезания у него минимален (одна короткая строка, ничего под ней). */
  .cal-day{position:absolute;top:4px;left:0;right:0;z-index:1;text-align:center;
    font-family:var(--font-mono);font-size:10px;font-weight:600;line-height:1;color:var(--ink-soft);}
  .cal-cell.cal-off .cal-day{opacity:.55;}
  .goal-bar{position:relative;height:8px;border-radius:4px;background:var(--line);overflow:hidden;margin:12px 0 8px;}
  .goal-bar-over{position:absolute;left:0;top:0;height:100%;width:0;background:var(--green);border-radius:4px;transition:width .3s;}
  .goal-percent-wrap{display:flex;align-items:center;gap:6px;}
  .goal-bar-medal{flex:0 0 auto;display:none;align-items:center;justify-content:center;
    width:16px;height:16px;border-radius:50%;background:var(--green);}
  .goal-bar-medal svg{display:block;}
  /* Заголовок карточки — кнопка-тогл. Всё, что было внутри, дублировало полосу
     в шапке, поэтому по умолчанию карточка свёрнута: в Истории она занимала
     пол-экрана каждый день, а нужна раз в месяц. */
  .goal-card-head{display:flex;align-items:center;justify-content:space-between;gap:12px;
    width:100%;background:none;border:none;padding:0;margin:0;text-align:left;
    font-family:inherit;color:inherit;cursor:pointer;}
  .goal-head-right{display:flex;align-items:center;gap:8px;}
  .goal-head-sum{font-family:var(--font-mono);font-size:12px;color:var(--amber);white-space:nowrap;}
  .goal-chev{flex-shrink:0;transition:transform .2s;}
  .goal-card-head.open .goal-chev{transform:rotate(180deg);}
  #goalBody{margin-top:12px;}
  /* Свёрнутая карточка — это одна строка текста, и обычные 16px по кругу давали
     ей высоту почти как у полноценной карточки. В раскрытом виде отступы прежние:
     там внутри полоса, цифры и кнопки, им тесно быть не должно. */
  .card.goal-collapsed{padding:10px 14px;margin-bottom:12px;}
  .goal-edit-btn{background:none;border:none;padding:0;font-size:12px;font-weight:600;
    color:var(--teal);font-family:var(--font-text);cursor:pointer;flex-shrink:0;}
  .goal-bar-fill{position:absolute;left:0;top:0;height:100%;background:var(--amber);border-radius:4px;transition:width .3s;}
  .goal-stats{display:flex;align-items:center;justify-content:space-between;font-size:12px;color:var(--ink-soft);font-family:var(--font-mono);}
  /* Нижние модалки (Статистика / Изменить запись). Раньше высота задавалась в vh —
     в Safari на iPhone это высота БЕЗ учёта адресной строки, поэтому низ окна (кнопки
     «Сохранить»/«Отмена») уезжал под край экрана. dvh считает реальную видимую область. */
  .sheet{background:var(--bg);width:100%;max-width:var(--content-max);border-radius:16px 16px 0 0;
    padding:16px calc(16px + env(safe-area-inset-right)) calc(18px + env(safe-area-inset-bottom)) calc(16px + env(safe-area-inset-left));
    max-height:88vh;max-height:88dvh;overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;}
  .sheet-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px;}
  .sheet-head h2{margin:0;font-family:var(--font-display);font-size:18px;}
  .sheet-close{background:none;border:none;font-size:22px;line-height:1;color:var(--ink-soft);cursor:pointer;padding:4px 8px;margin:-4px -8px;}
  /* Плоское затемнение не всегда читалось как «открылось окно» — на светлой теме
     особенно, где фон и так сероватый. Матовое стекло даёт мгновенный сигнал:
     страница позади размыта, значит сверху что-то модальное. -webkit-префикс
     обязателен — Safari до сих пор не понимает backdrop-filter без него. */
  .modal-overlay{display:none;position:fixed;inset:0;background:rgba(27,36,48,.45);
    -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
    z-index:200;align-items:flex-end;justify-content:center;}
  /* Базовый .modal-overlay выравнивает контент по низу — это подходит для шторки
     редактирования, но не для просмотра фото на весь экран, где картинка должна
     стоять по центру. */
  /* padding-top резервирует место под блок с подписью/координатой (см. разметку
     #photoViewerInfo) — он лежит поверх этой области position:absolute, а сама
     картинка центрируется уже в уменьшенной области ниже, без пересчёта margin. */
  #photoViewerOverlay{align-items:center;padding-top:76px;box-sizing:border-box;}
  .remember-row{display:flex;align-items:center;gap:8px;margin-top:16px;}
  .remember-row input{width:21px;height:21px;margin:0;flex-shrink:0;}
  .remember-row label{margin:0;font-size:13px;font-weight:500;color:var(--ink);}
  #authScreen,#app{display:none;}
  /* Мелкий поясняющий текст под кнопкой/полем */
  .hint{font-size:12px;line-height:1.4;color:var(--ink-soft);}

  /* Раньше и #authScreen, и #app были скрыты до ответа /api/me — то есть при
     медленном или залипшем запросе человек смотрел в чистый белый экран без
     единого признака жизни и решал, что «сайт завис». Теперь виден статус. */
  #bootScreen{position:fixed;inset:0;z-index:400;display:flex;flex-direction:column;
    align-items:center;justify-content:center;gap:14px;background:#1B2430;color:#9AA5B4;
    padding:24px;text-align:center;font-family:var(--font-text);}
  #bootScreen.hidden{display:none;}
  .boot-brand{font:700 26px var(--font-display,'Space Grotesk'),sans-serif;letter-spacing:5px;padding-left:5px;color:#EDEEEA;}
  .boot-road{position:relative;width:min(280px,80vw);height:46px;overflow:hidden;border-bottom:2px dashed #3A4658;}
  .boot-rv{position:absolute;top:0;left:-80px;animation:boot-go 2.6s ease-in-out infinite;}
  .boot-sc{animation:boot-pulse 1.1s ease-in-out infinite;transform-box:fill-box;transform-origin:center;}
  .boot-sc.b{animation-delay:.35s;}
  @keyframes boot-go{0%{left:-80px}100%{left:100%}}
  @keyframes boot-pulse{0%,100%{opacity:.35}50%{opacity:1}}
  @media (prefers-reduced-motion:reduce){.boot-rv{animation-duration:6s;}.boot-sc{animation:none;}}
  #bootMsg{font-size:15px;max-width:300px;line-height:1.45;min-height:20px;}
  #bootRetry{display:none;background:var(--amber);color:#1B2430;border:none;border-radius:8px;
    padding:12px 20px;font-size:15px;font-weight:600;font-family:var(--font-text);cursor:pointer;}

  /* ---------- Рация экипажа (v2.69.0) ---------- */
  /* Выше карты экипажа (300) - рация нужна и там, пока ждёшь напарника. */
  .vt-fab{position:fixed;z-index:320;width:58px;height:58px;border-radius:50%;display:flex;align-items:center;justify-content:center;
    background:rgba(27,36,48,.72);color:#fff;border:1.5px solid rgba(255,255,255,.6);box-sizing:border-box;
    box-shadow:0 2px 8px rgba(0,0,0,.25);touch-action:none;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;
    -webkit-tap-highlight-color:transparent;cursor:pointer;
    transition:left .28s cubic-bezier(.2,.8,.3,1),background .15s,transform .15s;}
  .vt-fab.out{background:rgba(27,36,48,.92);}
  .vt-fab.drag{transition:none;}
  .vt-fab.rec{background:var(--amber);color:#1B2430;transform:scale(1.2);}
  .vt-fab.cancel{background:var(--red);color:#fff;}
  .vt-fab.ring{animation:vtRing 1.2s infinite;}
  @keyframes vtRing{0%{box-shadow:0 0 0 0 rgba(242,169,0,.8)}70%{box-shadow:0 0 0 16px rgba(242,169,0,0)}100%{box-shadow:0 0 0 0 rgba(242,169,0,0)}}
  .vt-glyph{display:flex;transition:transform .28s;transform:translateX(-11px);pointer-events:none;}
  .vt-fab.side-l .vt-glyph{transform:translateX(11px);}
  .vt-fab.out .vt-glyph,.vt-fab.drag .vt-glyph{transform:none;}
  .vt-badge{position:absolute;top:-3px;right:-3px;min-width:18px;height:18px;padding:0 4px;border-radius:9px;display:none;
    align-items:center;justify-content:center;background:var(--amber);color:#1B2430;font:600 11px var(--font-mono);pointer-events:none;}
  .vt-fab:not(.out) .vt-badge{right:auto;left:4px;}
  .vt-fab.side-l:not(.out) .vt-badge{left:auto;right:4px;}
  .vt-pill{position:fixed;z-index:335;cursor:pointer;left:50%;top:calc(env(safe-area-inset-top,0px) + 12px);transform:translateX(-50%);
    display:none;align-items:center;gap:8px;padding:8px 14px;border-radius:20px;background:#1B2430;color:#fff;font-size:12.5px;white-space:nowrap;}
  .vt-pill.on{display:flex;}
  .vt-pill b{font-family:var(--font-mono);font-weight:500;color:var(--amber);}
  .vt-dot{width:8px;height:8px;border-radius:50%;background:var(--amber);animation:vtBlink 1s infinite;}
  @keyframes vtBlink{50%{opacity:.2}}
  .vt-back{position:fixed;inset:0;z-index:330;background:rgba(0,0,0,.25);display:none;}
  .vt-back.on{display:block;}
  .vt-sheet{position:fixed;z-index:331;left:0;right:0;bottom:0;max-width:560px;margin:0 auto;height:min(62vh,520px);
    display:flex;flex-direction:column;background:var(--surface);color:var(--ink);border-radius:18px 18px 0 0;border-top:1px solid var(--line);
    padding-bottom:env(safe-area-inset-bottom,0px);transform:translateY(105%);transition:transform .25s;visibility:hidden;}
  .vt-sheet.on{transform:translateY(0);visibility:visible;}
  .vt-head{display:flex;align-items:center;gap:4px;padding:14px 14px 8px;}
  .vt-title{flex:1;font-family:var(--font-display);font-weight:600;font-size:16px;}
  .vt-hbtn{border:0;background:none;color:var(--ink-soft);font-size:13px;padding:6px 8px;border-radius:8px;cursor:pointer;}
  .vt-hbtn.armed{background:var(--red);color:#fff;}
  .vt-list{flex:1;overflow-y:auto;-webkit-overflow-scrolling:touch;}
  .vt-item{display:flex;align-items:center;gap:10px;padding:10px 14px;border-top:1px solid var(--line);}
  .vt-play{width:36px;height:36px;flex:0 0 36px;border:0;border-radius:50%;padding:0;display:flex;align-items:center;justify-content:center;
    background:var(--ink);color:var(--bg);cursor:pointer;}
  .vt-play.off{opacity:.35;}
  .vt-mid{flex:1;min-width:0;}
  .vt-top{display:flex;align-items:baseline;gap:6px;font-size:13.5px;}
  .vt-who{font-weight:600;}
  .vt-new{font-size:11px;color:var(--amber-dark);}
  .vt-time{margin-left:auto;font-family:var(--font-mono);font-size:11.5px;color:var(--ink-soft);white-space:nowrap;}
  .vt-bar{height:4px;margin-top:6px;border-radius:2px;background:var(--surface-2);overflow:hidden;}
  .vt-bar i{display:block;height:100%;width:0;background:var(--amber);}
  .vt-st{margin-top:4px;font-size:11.5px;color:var(--ink-soft);}
  .vt-link{border:0;background:none;padding:0;color:var(--amber-dark);font-size:inherit;text-decoration:underline;cursor:pointer;}
  .vt-del{flex:0 0 auto;border:0;background:none;padding:6px;color:var(--ink-soft);display:flex;cursor:pointer;}
  .vt-del-ok{flex:0 0 auto;border:0;border-radius:8px;padding:7px 9px;background:var(--red);color:#fff;font-size:11.5px;white-space:nowrap;cursor:pointer;}
  .vt-empty{padding:18px 14px;font-size:13px;color:var(--ink-soft);}
  .vt-foot{padding:10px 14px 12px;border-top:1px solid var(--line);}
  .vt-foot-h{margin-top:8px;font-size:11.5px;color:var(--ink-soft);text-align:center;}
  .vt-ptt{display:flex;align-items:center;justify-content:center;gap:10px;width:100%;height:58px;border:1.5px solid var(--amber);border-radius:29px;
    background:none;color:var(--amber-dark);font:inherit;font-size:15px;font-weight:600;cursor:pointer;
    touch-action:none;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent;transition:background .15s,color .15s;}
  .vt-ptt.rec{background:var(--amber);color:#1B2430;}
  .vt-ptt.cancel{background:var(--red);border-color:var(--red);color:#fff;}
  .vt-ptt b{font-family:var(--font-mono);font-weight:500;}
  .vt-ptt svg{flex:0 0 auto;pointer-events:none;}
  .vt-ptt-tx{pointer-events:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  /* v2.75.2: в тёмной теме кнопка была светлой на 84% прозрачной - на светлой карте
     её не было видно совсем. Теперь одна и та же в обеих темах (см. .vt-fab). */
  [data-theme="dark"] .vt-fab.rec{background:var(--amber);}
  [data-theme="dark"] .vt-fab.cancel{background:var(--red);}
  @media (prefers-reduced-motion: reduce){.vt-fab.ring,.vt-dot{animation:none;}}

  /* ---------- Растормошить напарника (v2.70.0) ---------- */
  .crew-pop-row{flex-wrap:wrap;}
  .crew-nudge{width:28px;height:28px;flex:0 0 28px;padding:0;border:1px solid var(--amber);border-radius:8px;background:none;color:var(--amber);
    display:inline-flex;align-items:center;justify-content:center;cursor:pointer;font:500 12px var(--font-mono);}
  .crew-nudge.busy{background:var(--amber);color:#1B2430;}
  .crew-nudge.off{border-color:#3A4552;color:#9AA3AE;cursor:default;}
  .crew-pop-st{flex-basis:100%;font-family:var(--font-body,inherit);font-size:11.5px;color:#9AA3AE;margin-top:-2px;}
  .crew-pop-st .seen{color:var(--amber);}
  .crew-pop-st .ok{color:#6FBF73;}
  .vt-nudge{display:inline-flex;align-items:center;gap:5px;border:1px solid var(--amber);color:var(--amber-dark);font-weight:600;}
  .vt-nudge:disabled{border-color:var(--line);color:var(--ink-soft);cursor:default;}
  .vt-nudge-n{font-family:var(--font-mono);min-width:22px;text-align:center;}
  .vt-close{display:inline-flex;align-items:center;padding:6px;}
  .nd-ban{position:fixed;z-index:345;left:12px;right:12px;top:calc(env(safe-area-inset-top,0px) + 10px);max-width:520px;margin:0 auto;
    display:none;align-items:center;gap:12px;padding:12px 14px;border-radius:14px;background:#1B2430;color:#fff;}
  .nd-ban.on{display:flex;}
  .nd-ban.shake{animation:ndShake .5s 3;}
  @keyframes ndShake{0%,100%{transform:translateX(0)}25%{transform:translateX(-5px)}75%{transform:translateX(5px)}}
  .nd-ban-ic{width:36px;height:36px;flex:0 0 36px;border-radius:10px;background:var(--amber);color:#1B2430;display:flex;align-items:center;justify-content:center;}
  .nd-ban-tx{flex:1;min-width:0;font-size:14px;font-weight:600;}
  .nd-ban-go{border:0;border-radius:8px;background:var(--amber);color:#1B2430;padding:9px 14px;font-weight:600;font-size:13.5px;white-space:nowrap;cursor:pointer;}
  .nd-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;}
  .nd-opt{display:flex;align-items:center;gap:10px;padding:10px;border:1px solid var(--line);border-radius:12px;background:var(--surface);color:var(--ink);text-align:left;cursor:pointer;font:inherit;}
  .nd-opt.on{border:2px solid var(--amber);padding:9px;}
  .nd-opt-ic{width:36px;height:36px;flex:0 0 36px;border-radius:10px;background:#1B2430;color:var(--amber);display:flex;align-items:center;justify-content:center;}
  .nd-opt-tx{display:flex;flex-direction:column;min-width:0;}
  .nd-opt-nm{font-size:14px;font-weight:600;}
  .nd-opt-h{font-size:11px;color:var(--ink-soft);line-height:1.35;}
  @media (prefers-reduced-motion: reduce){.nd-ban.shake{animation:none;}}

  /* ---------- v2.71.0: «Где ты?» на карте, статус голосового ---------- */
  .geo-ask:disabled{opacity:.5;cursor:default;}
  .vt-pill.status .vt-dot{display:none;}
  .vt-ok{display:inline-flex;color:var(--amber);}
  .vt-ok svg + svg{margin-left:-7px;}

  /* v2.71.3: кнопка рации, оставленная посреди экрана, и скрытие при открытой ленте */
  .vt-fab.free .vt-glyph{transform:none;}
  .vt-fab.free .vt-badge,.vt-fab.free.side-l .vt-badge{left:auto;right:-3px;}
  .vt-fab.hidden{opacity:0;pointer-events:none;transition:opacity .15s;}

  /* v2.71.4: карточки напарников под картой - имя и время в строку, подробности ниже,
     кнопки отдельным рядом одинаковой ширины и высоты. */
  .geo-status{padding:14px 16px calc(14px + env(safe-area-inset-bottom,0px));}
  .geo-mate + .geo-mate{margin-top:12px;padding-top:12px;border-top:1px solid #2F3A47;}
  .geo-mate-top{display:flex;align-items:center;gap:8px;}
  .geo-mate-dot{width:9px;height:9px;flex:0 0 9px;border-radius:50%;background:#5B6570;}
  .geo-mate-dot.live{background:var(--amber);}
  .geo-mate-dot.off{background:none;border:1.5px solid #5B6570;box-sizing:border-box;}
  .geo-mate-nm{flex:1;min-width:0;font-family:var(--font-body,inherit);font-size:15px;font-weight:600;color:#fff;
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .geo-mate-ago{flex:0 0 auto;font-family:var(--font-mono);font-size:12.5px;color:#9AA3AE;}
  .geo-mate-sub{margin-top:3px;padding-left:17px;font-family:var(--font-body,inherit);font-size:13px;line-height:1.45;color:#9AA3AE;}
  .geo-mate-asked{color:var(--amber);}
  .geo-mate-btns{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:8px;margin-top:10px;}
  .geo-mate-btns .geo-navi,.geo-mate-btns .geo-ask{width:100%;height:42px;margin:0;box-sizing:border-box;border-radius:10px;
    font-family:var(--font-body,inherit);font-size:14px;font-weight:600;}
  .geo-ask{border:1.5px solid var(--amber);background:none;color:var(--amber);cursor:pointer;white-space:nowrap;padding:0 12px;}

  /* ---------- Тикет на карте (v2.72.0) ---------- */
  .t-map-btn{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;padding:0;cursor:pointer;
    border:1.5px solid var(--amber);border-radius:8px;background:none;color:var(--amber-dark);box-sizing:border-box;}
  .ticket-card .head .t-map-btn{width:var(--h-field);height:var(--h-field);}
  .t-collapsed .t-map-btn{width:30px;height:30px;}
  .t-collapsed .t-map-btn + .t-collapsed-caret{padding-left:0;}
  .tm-modal{z-index:305;}
  .tm-top{gap:6px;padding:8px 10px;}
  .tm-head{flex:1;min-width:0;text-align:center;}
  .tm-num{font-family:var(--font-mono);font-size:15px;font-weight:500;}
  .tm-sub{margin-top:2px;font-size:12px;color:#9AA3AE;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .tm-nav{width:40px;height:40px;flex:0 0 40px;border:1px solid #3A4552;border-radius:10px;background:none;color:#EDEEEA;
    display:flex;align-items:center;justify-content:center;padding:0;cursor:pointer;}
  .tm-close{margin-left:4px;}
  .tm-all.on{background:var(--amber);color:#1B2430;}
  .tm-btns:empty{display:none;}
  .tm-bottom .tm-ptt{margin-top:10px;height:52px;border-radius:26px;color:var(--amber);}
  .tm-btns:empty + .tm-ptt{margin-top:0;}
  /* Кнопка карты всегда у правого края строки: если справа уже есть расстояние/метка
     (они сами прижаты вправо через margin-left:auto) - встаёт сразу за ними. */
  .curator-check-row .cur-map-btn{width:30px;height:30px;margin-left:auto;}
  .curator-check-row .curator-dup + .cur-map-btn,
  .curator-check-row .curator-extra + .cur-map-btn,
  .curator-check-row .curator-extra-pill + .cur-map-btn{margin-left:0;}

  /* v2.73.1: таблички тикетов на карте - полупрозрачная карточка (карта слегка
     просвечивает), скругление 8 как у наших карточек, без «пилюль». Значок приоритета,
     номер моноширинным, «· ковёр» серым текстом в той же строке. */
  .tm-lbl{position:absolute;left:-4px;top:-15px;display:flex;align-items:center;gap:6px;height:30px;padding:0 10px 0 8px;
    box-sizing:border-box;border-radius:8px;background:rgba(255,255,255,.78);border:1.5px solid #C8CBC4;color:#1B2430;
    white-space:nowrap;cursor:pointer;}
  .tm-lbl .curator-pri,.tm-lbl .curator-pri svg{width:14px;height:14px;flex-basis:14px;}
  .tm-lbl .curator-pri-normal{color:#7A7F86;}
  .tm-lbl-num{font-family:var(--font-mono);font-size:13px;font-weight:600;line-height:1;}
  .tm-lbl-carpet{font-family:var(--font-body,inherit);font-size:12px;line-height:1;color:#7A7F86;}
  .tm-num{display:flex;align-items:center;justify-content:center;gap:6px;}
  .tm-num .curator-pri,.tm-num .curator-pri svg{width:15px;height:15px;flex-basis:15px;}
  .tm-num .curator-pri-normal{color:#9AA3AE;}
  /* Текущий тикет: та же табличка, рамка цвета пары (--crew), по центру своей точки. */
  .tm-lbl.main{left:auto;transform:translate(-50%,0);border:2px solid var(--crew,#9333EA);cursor:default;}

  /* ---------- Превью дня из календаря статистики (v2.74.0) ---------- */
  .cal-cell[data-date]{cursor:pointer;}
  .cal-cell[data-date]:active{opacity:.75;}
  .cal-cell.cal-sel{outline:2px solid var(--ink);outline-offset:1px;}
  .sd-back{position:fixed;inset:0;z-index:258;background:rgba(0,0,0,.3);display:none;}
  .sd-back.on{display:block;}
  .sd-sheet{position:fixed;z-index:259;left:0;right:0;bottom:0;max-width:560px;margin:0 auto;max-height:78vh;display:flex;flex-direction:column;
    background:#1B2430;color:#EDEEEA;border-radius:18px 18px 0 0;padding-bottom:env(safe-area-inset-bottom,0px);
    transform:translateY(105%);transition:transform .25s;visibility:hidden;}
  .sd-sheet.on{transform:none;visibility:visible;}
  .sd-head{display:flex;align-items:center;gap:6px;padding:12px 12px 10px;}
  .sd-title{flex:1;min-width:0;text-align:center;}
  .sd-date{font-family:var(--font-display);font-weight:600;font-size:16px;}
  .sd-sub{margin-top:2px;font-size:12.5px;color:#9AA3AE;}
  .sd-nav:disabled{opacity:.3;cursor:default;}
  .sd-body{flex:1;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:0 14px 6px;}
  .sd-tiles{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;}
  .sd-tile{background:#232C38;border-radius:10px;padding:9px 10px;min-width:0;}
  .sd-lb{font-family:var(--font-mono);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:#9AA3AE;}
  .sd-vl{margin-top:3px;font-family:var(--font-mono);font-size:15px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .sd-sec{margin:14px 0 2px;}
  .sd-tk{display:flex;align-items:center;gap:8px;padding:9px 0;border-top:1px solid #2A3340;font-size:13px;}
  .sd-num{font-family:var(--font-mono);font-size:13.5px;}
  .sd-meta{flex:1;min-width:0;text-align:right;font-size:12px;color:#9AA3AE;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .sd-st{flex:0 0 44px;text-align:right;font-family:var(--font-mono);font-size:12.5px;color:#9AA3AE;}
  .sd-st.done{color:var(--amber);font-weight:600;}
  .sd-note{margin-top:10px;font-size:12.5px;color:#9AA3AE;line-height:1.45;}
  .sd-note:empty{display:none;}
  .sd-memo{color:#C9CED4;font-style:italic;}
  .sd-empty{padding:22px 0;text-align:center;font-size:13.5px;color:#9AA3AE;}
  .sd-btns{display:grid;grid-template-columns:1fr 1fr;gap:8px;padding:10px 14px 14px;}
  .sd-btns button{height:44px;border-radius:10px;font:inherit;font-size:14px;font-weight:600;cursor:pointer;box-sizing:border-box;}
  .sd-map{background:none;border:1.5px solid var(--amber);color:var(--amber);}
  .sd-map:disabled{opacity:.4;cursor:default;}
  .sd-open{background:var(--amber);border:0;color:#1B2430;}

  /* ---------- «На связи» (v2.76.0) ---------- */
  .vt-ld{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:6px;vertical-align:middle;
    box-sizing:border-box;border:1.5px solid #7A8390;background:none;}
  .vt-ld.on{border:0;background:#34C759;box-shadow:0 0 0 3px rgba(52,199,89,.22);}
  .vt-live{display:none;position:absolute;right:1px;bottom:3px;width:14px;height:14px;border-radius:50%;box-sizing:border-box;
    border:2px solid #fff;background:#7A8390;pointer-events:none;}
  .vt-live.on{background:#34C759;}
  /* Кнопка спрятана наполовину - точку переносим на видимую половину. */
  .vt-fab:not(.out):not(.free):not(.side-l) .vt-live{right:auto;left:5px;}
  .vt-fab.side-l:not(.out):not(.free) .vt-live{right:5px;}
  .vt-live-line{display:none;margin-bottom:8px;text-align:center;font-size:12.5px;line-height:1.4;color:var(--ink-soft);}
  .vt-live-line .vt-lt{color:var(--ink);}
  .tm-bottom .vt-live-line{margin:10px 0 0;color:#9AA3AE;}
  .tm-bottom .vt-live-line .vt-lt{color:#EDEEEA;}
  .tm-bottom .vt-live-line + .tm-ptt{margin-top:8px;}
  .crew-live{margin-left:8px;font-size:12px;white-space:nowrap;color:#7A8390;
    /* v2.85.1: одна на строке и всё равно не влезла - многоточие у статуса, не у имени */
    min-width:0;overflow:hidden;text-overflow:ellipsis;flex-shrink:100;}
  .crew-live.on{color:#34C759;}
  .crew-live .vt-ld{width:7px;height:7px;margin-right:5px;}
  .crew-live:empty{display:none;}

  /* ---------- v2.76.5 ---------- */
  .crew-strip.crew-strip-full{padding-left:0;padding-right:0;position:relative;z-index:2;}
  .curator-actions{position:sticky;bottom:0;z-index:3;display:flex;gap:8px;margin:0 -16px -16px;padding:10px 16px calc(12px + env(safe-area-inset-bottom,0px));
    background:var(--paper);border-top:1px solid var(--line);border-radius:0 0 12px 12px;}
  html.nav-bottom .curator-actions{bottom:calc(58px + env(safe-area-inset-bottom,0px));padding-bottom:12px;}

  /* ---------- v2.77.0 ---------- */
  /* Вертикальная прокрутка проходит сквозь ползунок процента - листать карточку можно
     прямо по нему; сам ползунок двигается только за кружок (см. guardRangeThumb). */
  .t-pct{touch-action:pan-y;}
  /* v2.77.1: низ раскрытого тикета - «Свернуть» (просто закрыть) и «✓ Готово» (100% и
     свернуть). Прилипает к низу экрана, пока карточка на экране. У выполненного тикета
     «Готово» не показывается. */
  .t-bottom{display:flex;gap:8px;margin-top:16px;}
  .t-bottom .t-collapse-btn{flex:1;margin-top:0;height:44px;padding:0;}
  .t-done-btn{flex:1.2;height:44px;border:0;border-radius:8px;background:var(--amber);color:#1B2430;font:inherit;font-size:14px;font-weight:600;cursor:pointer;}
  .ticket-card.is-done .t-done-btn{display:none;}
  .ticket-card:not(.collapsed) .t-bottom{position:sticky;bottom:calc(12px + env(safe-area-inset-bottom,0px));z-index:2;
    background:var(--paper);box-shadow:0 -6px 12px var(--paper);}
  html.nav-bottom .ticket-card:not(.collapsed) .t-bottom{bottom:calc(70px + env(safe-area-inset-bottom,0px));}
  .percent-row .pct-val{cursor:default;pointer-events:none;}
  /* «Не на связи» - сплошная серая точка: пустой кружок рядом с текстом читался как буква «о». */
  .vt-ld{border:0;background:#7A8390;}

  /* v2.77.3: кнопки поверх фото (закрыть, сохранить) - видны на любом снимке. */
  .pv-btn{width:44px;height:44px;padding:0;border-radius:50%;box-sizing:border-box;display:flex;align-items:center;justify-content:center;
    background:rgba(27,36,48,.88);border:1.5px solid rgba(255,255,255,.75);color:#fff;box-shadow:0 2px 10px rgba(0,0,0,.45);cursor:pointer;}
  .pv-btn:active{transform:scale(.94);}

  /* v2.77.7: длина маршрута в табличке - в одну строку с номером, как «· ковёр». */
  .tm-lbl-dist{font-family:var(--font-mono);font-size:12px;font-weight:500;line-height:1;color:#1B2430;}
  .tm-lbl.main .tm-lbl-dist{color:var(--crew,#9333EA);}

  /* v2.77.8: «Обзор» в строке «Снять все / Выбрать все» загрузки задания. */
  .curator-master .cur-ov-btn{width:auto;height:32px;padding:0 10px;gap:6px;margin-left:10px;font:inherit;font-size:12.5px;font-weight:600;}

  /* ---------- Ровер с оператором на картах (v2.78.0) ---------- */
  .rv{position:absolute;left:-90px;top:-90px;width:180px;height:180px;pointer-events:none;}
  .rv-svg{position:absolute;left:0;top:0;overflow:visible;}
  .rv .rv-dot{display:none;}
  /* v2.104.6: при сильном отдалении остаётся тот же ровер (а не точка), без человека и лидара */
  .rv.small .rv-op,.rv.small .rv-beam,.rv.small .rv-cloud,.rv.small .rv-flag{display:none;}
  .rv.small .rv-svg{transform:scale(.8);transform-origin:90px 90px;}
  .rv-lbl{position:absolute;left:50%;top:50px;transform:translate(-50%,-100%);white-space:nowrap;font-family:var(--font-body,Inter),sans-serif;
    font-size:11.5px;font-weight:700;color:#1B2430;
    text-shadow:0 0 3px #fff,0 0 3px #fff,1px 1px 0 #fff,-1px -1px 0 #fff,1px -1px 0 #fff,-1px 1px 0 #fff;}
  .rv-lbl span{font-weight:600;color:var(--rv-col,#2F6FDE);}
  .rv.small .rv-lbl{top:72px;}
  /* v2.78.1: средний масштаб - уменьшенный ровер с человеком, без лидара. */
  .rv.mini .rv-svg{transform:scale(.62);transform-origin:90px 90px;}
  .rv.mini .rv-beam,.rv.mini .rv-cloud{display:none;}
  .rv.mini .rv-lbl{top:64px;}

  /* ---------- v2.79.0: подсказка собрать экипаж ---------- */
  .crew-solo-tx{color:var(--brand-text-soft,#9AA3AE);}
  .crew-solo-add{margin-left:8px;padding:1px 8px;border:1.5px solid var(--amber);border-radius:8px;color:var(--amber);font-weight:600;white-space:nowrap;}
  .ci-ov{position:fixed;inset:0;z-index:262;display:flex;align-items:flex-end;justify-content:center;background:rgba(27,36,48,0);transition:background .25s;}
  .ci-ov.on{background:rgba(27,36,48,.5);}
  .ci-sheet{width:100%;max-width:560px;box-sizing:border-box;padding:20px 18px calc(16px + env(safe-area-inset-bottom,0px));
    background:var(--paper);color:var(--ink);border-radius:18px 18px 0 0;transform:translateY(105%);transition:transform .25s;}
  .ci-ov.on .ci-sheet{transform:none;}
  .ci-title{font-family:var(--font-display);font-weight:600;font-size:19px;}
  .ci-sub{margin-top:4px;font-size:13.5px;color:var(--ink-soft);}
  .ci-row{display:flex;align-items:flex-start;gap:10px;margin-top:12px;font-size:13.5px;line-height:1.4;}
  .ci-ic{width:32px;height:32px;flex:0 0 32px;border-radius:8px;background:#1B2430;color:var(--amber);display:flex;align-items:center;justify-content:center;}
  .ci-go{width:100%;height:46px;margin-top:18px;border:0;border-radius:10px;background:var(--amber);color:#1B2430;font:inherit;font-size:15px;font-weight:600;cursor:pointer;}
  .ci-later{width:100%;height:42px;margin-top:6px;border:0;background:none;color:var(--ink-soft);font:inherit;font-size:14px;cursor:pointer;}

  /* ---------- v2.86.0: «Поставь на рабочий стол» (один раз, новеньким) ---------- */
  .a2hs-card{position:fixed;left:10px;right:10px;bottom:calc(16px + env(safe-area-inset-bottom,0px));z-index:60;
    max-width:460px;margin:0 auto;background:#1B2430;color:#EDEEEA;border:1px solid var(--amber);border-radius:14px;
    padding:12px 12px 10px;box-shadow:0 8px 24px rgba(0,0,0,.45);font-family:'Inter',sans-serif;}
  html.nav-bottom .a2hs-card{bottom:calc(68px + env(safe-area-inset-bottom,0px));}
  .a2hs-hd{display:flex;gap:10px;align-items:center;}
  .a2hs-ic{width:40px;height:40px;border-radius:10px;flex:none;}
  .a2hs-t{font-family:'Space Grotesk',sans-serif;font-weight:600;font-size:14.5px;}
  .a2hs-s{font-size:12px;color:#9AA3AE;margin-top:1px;}
  .a2hs-x{margin-left:auto;align-self:flex-start;background:none;border:0;color:#7A8390;font-size:16px;padding:2px 4px;cursor:pointer;}
  .a2hs-steps{margin:9px 0 0;font-size:13px;color:#C9CED6;line-height:1.6;}
  .a2hs-steps b{color:var(--amber);font-weight:600;}
  .a2hs-k{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:5px;
    border:1px solid #3A4454;vertical-align:-5px;margin:0 2px;color:#EDEEEA;}
  .a2hs-btns{display:flex;gap:8px;margin-top:10px;}
  .a2hs-go{flex:1;background:var(--amber);color:#1B2430;border:0;border-radius:10px;padding:10px;font-weight:700;font-size:14px;cursor:pointer;}
  .a2hs-btns .a2hs-no{background:none;color:#9AA3AE;border:1px solid #3A4454;border-radius:10px;padding:10px 14px;font-size:13.5px;cursor:pointer;}
  .a2hs-btns .a2hs-wide{flex:1;}

  /* ---------- v2.88.0: тест скорости (админ, Настройки → Аккаунт) ---------- */
  .speed-card{background:#1B2430;color:#EDEEEA;border-radius:14px;padding:14px;margin-bottom:20px;}
  .speed-h{font-family:'Space Grotesk',sans-serif;font-weight:600;font-size:15px;display:flex;align-items:center;gap:8px;}
  .speed-tag{font-size:10.5px;font-weight:600;color:#1B2430;background:var(--amber);border-radius:5px;padding:1px 6px;}
  .speed-sub{font-size:12px;color:#9AA3AE;margin-top:3px;}
  .speed-grp{font-size:11px;color:#7A8390;text-transform:uppercase;letter-spacing:.06em;margin:12px 0 4px;}
  .speed-u{font-size:11px;color:#7A8390;margin-left:3px;font-family:'Inter',sans-serif;font-weight:400;}
  .speed-verdict{margin-top:10px;background:#2A1E1E;border:1px solid #7F1D1D;color:#FCA5A5;border-radius:10px;padding:9px 10px;font-size:12.5px;line-height:1.5;}
  .speed-verdict.ok{background:#15291F;border-color:#166534;color:#86EFAC;}
  .speed-note{font-size:11px;color:#7A8390;margin-top:6px;}
  /* v2.89.0: «Дорога данных» */
  .speed-road{display:block;margin-top:6px;overflow:visible;}
  .speed-road text{font-family:'Inter',sans-serif;}
  .speed-road text.m{font-family:var(--font-mono);}
  .speed-verdict b{color:inherit;filter:brightness(1.15);}
  .speed-hr{display:grid;grid-template-columns:auto 1fr;gap:4px 10px;align-items:center;padding:7px 0;border-top:1px solid #2A3240;}
  .speed-grp + .speed-hr{border-top:0;}
  .speed-ht{font-size:11.5px;color:#C9CED6;line-height:1.3;white-space:nowrap;}
  .speed-ht small{display:block;font-size:10.5px;color:#6B7483;}
  .speed-bw{display:flex;align-items:center;gap:6px;font-size:11px;color:#9AA3AE;}
  .speed-bw + .speed-bw{margin-top:4px;}
  .speed-bw span{width:62px;flex:none;}
  .speed-bw b{font-family:var(--font-mono);font-weight:600;color:#EDEEEA;min-width:34px;text-align:right;font-size:12px;}
  .speed-tr{flex:1;height:7px;background:#12171F;border-radius:4px;overflow:hidden;}
  .speed-tr i{display:block;height:100%;border-radius:4px;}
  /* v2.89.3 */
  .speed-road tspan.u{font-family:'Inter',sans-serif;font-weight:400;}
  .speed-more{display:block;width:100%;margin-top:6px;padding:8px;background:none;border:1px solid #3A4454;border-radius:9px;color:#C9CED6;font-size:12.5px;cursor:pointer;}

  /* v2.91: цель раскрывается в шапке + отдельная шторка цели с графиком */
  #headerGoalHasGoal, #headerGoalBarWrap{cursor:pointer;}
  .goal-chev-h{display:inline-block;transition:transform .2s;margin-left:4px;}
  .goal-strip.open .goal-chev-h{transform:rotate(180deg);}
  .goal-more{margin-top:12px;}
  .goal-more-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px;}
  .goal-more-cell{background:rgba(255,255,255,.06);border-radius:10px;padding:8px 10px;}
  .goal-more-cell span{display:block;font-size:11px;color:var(--brand-text-soft);}
  .goal-more-cell b{font-family:var(--font-mono);font-size:16px;font-weight:500;color:var(--brand-text);}
  .goal-more-text{font-size:13px;line-height:1.55;color:var(--brand-text);margin-top:10px;}
  .goal-more-text b{color:var(--amber);font-weight:600;}
  .goal-more-text .ok{color:var(--green);}
  .goal-more-acts{display:flex;gap:8px;margin-top:10px;}
  .goal-more-acts button{flex:1;background:transparent;border:1px solid var(--brand-line);color:var(--brand-text);border-radius:10px;min-height:36px;font-size:13px;font-family:var(--font-text);cursor:pointer;}
  .goal-sheet-top{font-family:var(--font-mono);font-size:15px;}
  .goal-sheet-top b{font-size:22px;font-weight:500;}
  .goal-sheet-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:6px;}
  .goal-sheet-text{font-size:13.5px;line-height:1.55;margin:0 2px 12px;}
  .goal-sheet-text b{color:var(--amber-dark);font-weight:600;}
  .goal-sheet-text .ok{color:var(--green);}
  .goal-sheet-acts{display:flex;gap:8px;margin-bottom:12px;}
  .goal-sheet-acts .btn{flex:1;margin:0;}
  #goalChart svg{display:block;width:100%;height:auto;}
  .goal-chart-note{font-size:12px;color:var(--ink-soft);margin-top:6px;line-height:1.5;}
  /* v2.91.2: шторка цели — компактно, всё в одну строку, кнопки всегда видны */
  #goalModalOverlay .sheet-head{margin-bottom:10px;}
  .gs-card{padding:12px 14px;margin-bottom:10px;}
  .gs-top{font-family:var(--font-mono);font-size:13px;color:var(--ink-soft);white-space:nowrap;}
  .gs-top b{font-size:20px;font-weight:500;color:var(--ink);}
  .gs-bar{margin:8px 0 10px;height:6px;}
  .gs-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px 12px;}
  .gs-cell span{display:block;font-family:var(--font-mono);font-size:10.5px;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-soft);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .gs-cell b{display:block;font-family:var(--font-mono);font-size:17px;font-weight:500;white-space:nowrap;}
  .gs-cell b.acc{color:var(--amber-dark);}
  .gs-chart-head{display:flex;justify-content:space-between;align-items:center;gap:8px;margin-bottom:4px;}
  .gs-chart-title{font-family:var(--font-display);font-weight:700;font-size:14px;white-space:nowrap;}
  #goalChart svg{display:block;width:100%;height:auto;}
  .goal-rows{margin-top:10px;border-top:1px solid var(--line);}
  .goal-rows:empty{display:none;}
  .goal-row{display:flex;justify-content:space-between;align-items:center;gap:10px;padding:6px 0;border-bottom:1px solid var(--line);font-size:12.5px;}
  .goal-row:last-child{border-bottom:0;padding-bottom:0;}
  .goal-row span{color:var(--ink-soft);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;}
  .goal-row b{font-family:var(--font-mono);font-weight:500;white-space:nowrap;flex-shrink:0;}
  .goal-row b.bad{color:var(--red);}
  .goal-row b.good{color:var(--green);}
  .goal-row .dot{display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--red);margin-right:6px;vertical-align:1px;}
  .goal-legend{display:flex;gap:10px;font-size:11px;color:var(--ink-soft);white-space:nowrap;}
  .goal-legend span{display:inline-flex;align-items:center;gap:4px;}
  .goal-legend i{display:inline-block;width:12px;height:0;}
  .goal-legend .lg-fact{border-top:2.5px solid var(--amber);}
  .goal-legend .lg-plan{border-top:1.5px dashed var(--ink-soft);}
  .goal-legend .lg-fc{border-top:2px dotted var(--amber);}
  /* Кнопки прилипают к низу шторки — видны без прокрутки при любой высоте экрана */
  .goal-sheet-acts{display:flex;gap:8px;position:sticky;bottom:0;background:var(--bg);padding:10px 0 calc(4px + env(safe-area-inset-bottom));margin:0;z-index:2;}
  .goal-sheet-acts .btn{flex:1;margin:0;min-height:40px;font-size:13.5px;white-space:nowrap;}
  /* v2.91.3: раскрытая цель в шапке — ровно, без переносов */
  .goal-more{margin-top:10px;}
  .goal-more-grid{gap:8px;}
  .goal-more-cell{padding:7px 10px;}
  .goal-more-cell span{font-size:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .goal-more-cell b{font-size:15px;white-space:nowrap;}
  .goal-more-cell b.acc{color:var(--amber);}
  .goal-more-row{display:flex;justify-content:space-between;align-items:center;gap:10px;margin-top:8px;padding:0 2px;font-size:12.5px;color:var(--brand-text-soft);}
  .goal-more-row:empty{display:none;}
  .goal-more-row span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;}
  .goal-more-row b{font-family:var(--font-mono);font-weight:500;color:var(--brand-text);white-space:nowrap;flex-shrink:0;}
  .goal-more-row b i{font-style:normal;}
  .goal-more-row b .bad{color:var(--amber);}
  .goal-more-row b .good{color:var(--green);}
  .goal-more-acts{margin-top:10px;}
  .goal-more-acts button{min-height:34px;font-size:12.5px;white-space:nowrap;}
  /* v2.92: История — заголовок с кнопкой-фильтром и карточки дней без переносов */
  .hist-head{display:flex;justify-content:space-between;align-items:center;gap:10px;margin:2px 0 12px;position:relative;}
  .hist-filter{position:relative;}
  .hist-filter-btn{display:flex;align-items:center;gap:7px;height:36px;padding:0 10px;border:1.5px solid var(--line);border-radius:8px;background:var(--surface);color:var(--ink);font-family:var(--font-text);font-size:13.5px;cursor:pointer;white-space:nowrap;}
  .hist-filter-btn svg{color:var(--ink-soft);flex-shrink:0;}
  .hist-filter-btn .hf-x{display:none;}
  .hist-filter-btn.on{border-color:var(--amber);background:var(--amber-tint);}
  .hist-filter-btn.on svg{color:var(--amber-dark);}
  .hist-filter-btn.on .hf-chev{display:none;}
  .hist-filter-btn.on .hf-x{display:block;}
  .hist-filter-menu{position:absolute;right:0;top:42px;min-width:200px;max-height:60vh;overflow:auto;background:var(--paper);border:1.5px solid var(--line);border-radius:8px;z-index:20;}
  .hist-filter-menu button{display:flex;justify-content:space-between;align-items:center;gap:12px;width:100%;padding:10px 12px;border:0;border-bottom:1px solid var(--line);background:none;color:var(--ink);font-family:var(--font-text);font-size:13.5px;text-align:left;cursor:pointer;}
  .hist-filter-menu button:last-child{border-bottom:0;}
  .hist-filter-menu button.sel{background:var(--amber-tint);font-weight:600;}
  .hist-filter-menu .n{font-family:var(--font-mono);font-size:11.5px;color:var(--ink-soft);font-weight:400;}
  .day-card .top-row{align-items:center;margin-bottom:2px;}
  .day-card .date .wd{font-family:var(--font-text);font-weight:400;font-size:11.5px;color:var(--ink-soft);margin-left:6px;}
  .day-card .sum{white-space:nowrap;}
  .day-card .meta{font-family:var(--font-mono);font-size:11.5px;}
  .day-card .tk-list{margin-top:8px;padding-top:6px;border-top:1px dashed var(--line);}
  .day-card .tk-row{display:flex;justify-content:space-between;align-items:baseline;gap:10px;font-size:12.5px;padding:2px 0;}
  .day-card .tk-row .n{font-family:var(--font-mono);flex-shrink:0;}
  .day-card .tk-row .s{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;}
  .day-card .tk-row .s.ok{color:var(--green-dark);}
  .day-card .tk-row .s.pc{color:var(--amber-dark);}
  .day-card .tk-row .s.no{color:var(--red);}
  .day-card .tk-row .s .co{color:var(--teal);}
  .day-card .tk-empty{font-size:12px;color:var(--ink-soft);}
  /* v2.95: тест полос — в загрузке задания и строкой в «АКБ и логистика» */
  .curator-akb-head{display:flex;align-items:center;gap:6px;margin:14px 0 4px;font-family:var(--font-mono);font-size:10.5px;letter-spacing:.14em;color:var(--ink-soft);}
  .curator-akb-row{display:flex;align-items:center;gap:8px;padding:8px 10px;margin-top:6px;border:1px solid rgba(242,169,0,.45);border-radius:10px;background:var(--amber-tint);cursor:pointer;}
  .curator-akb-row input{width:18px;height:18px;accent-color:var(--amber);flex-shrink:0;}
  .curator-akb-row.is-dup{opacity:.55;}
  .akb-ico{width:24px;height:24px;border-radius:6px;background:var(--amber);color:#1B2430;display:flex;align-items:center;justify-content:center;flex-shrink:0;}
  .akb-ico svg{width:15px;height:15px;}
  .curator-akb-row .t{display:flex;flex-direction:column;min-width:0;line-height:1.2;}
  .curator-akb-row .t b{font-size:13.5px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .curator-akb-row .t span{font-size:11.5px;color:var(--ink-soft);white-space:nowrap;}
  .akb-task-row{margin-top:10px;padding:10px;border:1px solid var(--line);border-radius:10px;background:var(--surface-2);}
  .akb-task-row .l1,.akb-task-row .l2{display:flex;align-items:center;gap:8px;}
  .akb-task-row .l2{margin-top:8px;}
  .akb-task-row .tt{flex:1;min-width:0;font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .akb-task-row .tt span{color:var(--ink-soft);}
  .akb-task-row .akb-task-rover{flex:1;min-width:0;height:var(--h-field);font-family:var(--font-mono);font-size:16px;padding:0 10px;}
  .akb-task-row .w{height:32px;padding:0 10px;border-radius:8px;border:1.5px solid var(--line);background:var(--surface);color:var(--ink);font-size:12.5px;font-family:var(--font-text);white-space:nowrap;flex-shrink:0;cursor:pointer;}
  .akb-task-row .w.on{border-color:var(--green-dark);background:var(--green-dark);color:#fff;}
  /* v3.6.3: Утро/Вечер в строке из задания окрашены так же, как в ручной паре (.akb-when) */
  .akb-task-row .w.on[data-w="утро"]{border-color:#FBE2AE;background:#FBE2AE;color:#6E4A0E;}
  .akb-task-row .w.on[data-w="вечер"]{border-color:#39406B;background:#39406B;color:#DDE0F2;}
  [data-theme="dark"] .akb-task-row .w.on[data-w="утро"]{border-color:#9C6816;background:#9C6816;color:#F5CE86;}
  [data-theme="dark"] .akb-task-row .w.on[data-w="вечер"]{border-color:#525DA3;background:#525DA3;color:#EDEFFB;}
  /* v3.6.4: Утро/Вечер в строке теста полос - та же склеенная пара, что в ручной замене */
  .akb-task-row .akb-when{margin-top:0;flex-shrink:0;}
  .akb-task-row .akb-when .w{height:calc(var(--h-field) - 2px);padding:0 14px;border:none;border-radius:0;background:var(--surface);color:var(--ink-soft);font-size:12px;font-weight:600;}
  .akb-task-row .akb-when .w+.w{border-left:1px solid var(--line);}
  /* Кнопка «+ Другая замена АКБ»: тихая пунктирная полоска, пока замена не из задания не нужна */
  .akb-add-line{display:block;width:100%;height:36px;margin-top:10px;border:1px dashed #B9BBB3;border-radius:8px;background:none;color:var(--ink-soft);font-family:var(--font-text);font-size:13px;cursor:pointer;}
  [data-theme="dark"] .akb-add-line{border-color:#3A4552;}
  #akbTasks:not(:empty) + #akbCountBlock{margin-top:12px !important;}
  .akb-task-row .x{width:26px;height:26px;border:0;background:none;color:var(--ink-soft);font-size:16px;cursor:pointer;flex-shrink:0;padding:0;}
  .akb-map-btn{width:30px;height:30px;flex-shrink:0;margin-left:auto;display:inline-flex;align-items:center;justify-content:center;text-decoration:none;}
  /* Строка тикета: кружки экипажа не выталкивают кнопку карты за край —
     уступает таблетка «Ковровая»/расстояние (обрезается многоточием). */
  .curator-check-row{gap:8px;}
  .curator-check-row > span:first-of-type{flex-shrink:0;}
  .curator-check-row .cur-map-btn{flex-shrink:0;}
  .curator-check-row .curator-extra,.curator-check-row .curator-extra-pill{min-width:0;flex-shrink:1;overflow:hidden;text-overflow:ellipsis;}
  .akb-task-badge{font-family:var(--font-mono);font-size:11.5px;font-weight:400;padding:2px 8px;border-radius:4px;background:var(--amber-tint);color:var(--amber-dark);white-space:nowrap;margin-left:8px;margin-right:auto;}
  /* v2.96: «Обзор» в шапке списка задания; тесты полос всех экипажей */
  .curator-hd .curator-overview-btn{width:34px;height:34px;margin-left:auto;margin-right:6px;}
  .curator-akb-more{font-size:12.5px;color:var(--teal);margin:8px 2px 0;cursor:pointer;background:none;border:0;padding:0;font-family:var(--font-text);}
  .curator-akb-row.other{background:var(--surface);border-color:var(--line);}
  .tm-akb-pin{position:relative;transform:translate(-50%,-100%);cursor:pointer;}
  .tm-akb-pin .lb{position:absolute;left:50%;bottom:54px;transform:translateX(-50%);font:600 10.5px/1.3 var(--font-text);background:#1B2430;color:#EDEEEA;padding:1px 6px;border-radius:4px;white-space:nowrap;}
  .tm-akb-pin.mine .lb{background:#F2A900;color:#1B2430;}
  /* v2.97: карта тикетов — карточка над картой, «←» слева, без стрелок и зума */
  .tm-top .tm-close{margin-left:0;border:1.5px solid #EDEEEA;}
  .tm-spacer{width:40px;height:40px;flex:0 0 40px;}
  .tm-card{position:absolute;left:8px;right:8px;bottom:8px;z-index:20;display:none;align-items:center;gap:10px;padding:10px 10px 10px 12px;
    background:#1B2430;border:1px solid #3A4552;border-radius:12px;box-shadow:0 6px 20px rgba(0,0,0,.35);color:#EDEEEA;
    touch-action:pan-y;user-select:none;-webkit-user-select:none;}
  .tm-card-t{flex:1;min-width:0;}
  .tm-card-r1{display:flex;align-items:center;gap:6px;white-space:nowrap;min-width:0;}
  .tm-card-r1 .curator-pri,.tm-card-r1 .curator-pri svg{width:16px;height:16px;flex:0 0 16px;}
  .tm-card-num{font-family:var(--font-mono);font-size:13px;font-weight:600;flex-shrink:0;}
  .tm-card-meta{font-size:12px;color:#9AA3AE;overflow:hidden;text-overflow:ellipsis;min-width:0;}
  .tm-card-r2{margin-top:5px;display:flex;align-items:center;gap:5px;font-size:12.5px;white-space:nowrap;overflow:hidden;}
  .tm-card-r2 svg{flex:0 0 auto;color:#9AA3AE;}
  .tm-card-r2 span{overflow:hidden;text-overflow:ellipsis;min-width:0;}
  .tm-card-r3{margin-top:3px;font-size:11px;color:#9AA3AE;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .tm-card-btn{flex:0 0 104px;height:44px;border:1.5px solid var(--amber);border-radius:10px;background:none;color:var(--amber);
    font-family:var(--font-text);font-size:14px;font-weight:600;display:flex;align-items:center;justify-content:center;cursor:pointer;white-space:nowrap;padding:0;box-sizing:border-box;}
  .tm-card-btn.ok{border-color:#57C084;color:#57C084;cursor:default;}
  .tm-card-btn.pct{cursor:default;}
  .akb-ico-sm{display:inline-flex;align-items:center;color:var(--amber);}
  .akb-ico-sm svg{width:16px;height:16px;}
  .tm-lbl-mate{margin-left:2px;width:14px;height:14px;flex:0 0 14px;font-size:8px;}
  /* v2.97.1: свёрнутая карточка — тонкая полоска, чтобы не закрывать карту */
  .tm-card-caret{display:none;margin-left:auto;color:#9AA3AE;align-items:center;flex:0 0 auto;}
  .tm-card.collapsed{padding:7px 12px;gap:8px;cursor:pointer;}
  .tm-card.collapsed .tm-card-caret{display:flex;}
  .tm-card.collapsed .tm-card-r2,.tm-card.collapsed .tm-card-r3,.tm-card.collapsed .tm-card-btn,.tm-card.collapsed .tm-card-meta{display:none;}
  /* v2.98.1: «Назад / Добавить» в загрузке задания плавают у нижнего края, как «Свернуть / Готово» у тикета:
     список тикетов длинный, и раньше до кнопок приходилось долистывать. */
  .curator-actions{position:sticky;bottom:calc(12px + env(safe-area-inset-bottom,0px));z-index:5;display:flex;gap:8px;margin:0;
    padding:8px 0 0;background:var(--paper);box-shadow:0 -8px 12px var(--paper);border:0;border-radius:0;}
  html.nav-bottom .curator-actions{bottom:calc(70px + env(safe-area-inset-bottom,0px));padding-bottom:0;}

  /* ========== v2.99: карта тикетов — выноска на тикете, слои, люди ========== */
  /* Метка тикета: по центру своей точки; выбранная — янтарная, остальные при выборе приглушены. */
  .tm-lbl{left:0;top:0;transform:translate(-50%,-50%);transition:opacity .2s;}
  .tm-lbl.dim{opacity:.35;}
  .tm-lbl.sel{background:var(--amber);border:2px solid #1B2430;}
  .tm-lbl.sel .tm-lbl-dist,.tm-lbl.sel .tm-lbl-carpet,.tm-lbl.sel .tm-lbl-num{color:#1B2430;}
  .tm-lbl-here{width:16px;height:16px;flex:0 0 16px;border-radius:50%;border:1.5px solid #fff;box-sizing:content-box;color:#fff;font:700 9px/16px var(--font-text);text-align:center;}
  .tm-lbl-here.stale{background:#7D8894!important;}
  .tm-lbl-here.more{background:#1B2430!important;}
  .tm-akb-pin.dim{opacity:.4;}
  .tm-akb-pin.sel .lb{background:var(--amber);color:#1B2430;}
  /* Люди на карте: кружок цвета человека с инициалом; устаревшая точка — светлая, пустая; несколько рядом — тёмный с числом. */
  .tm-here-dot{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;flex:0 0 18px;border-radius:50%;color:#fff;font:700 10px/1 var(--font-text);}
  .tm-here-dot.stale{background:#7D8894!important;}
  /* Выноска у тикета */
  .tm-co{position:absolute;z-index:30;width:236px;box-sizing:border-box;padding:10px;background:#1B2430;border:1px solid #3A4552;border-radius:12px;
    box-shadow:0 8px 24px rgba(0,0,0,.4);color:#EDEEEA;touch-action:manipulation;}
  .tm-co-ptr{position:absolute;width:12px;height:12px;background:#1B2430;transform:rotate(45deg);}
  .tm-co-ptr.below{bottom:-7px;border-right:1px solid #3A4552;border-bottom:1px solid #3A4552;}
  .tm-co-ptr.above{top:-7px;border-left:1px solid #3A4552;border-top:1px solid #3A4552;}
  .tm-co-r1{display:flex;align-items:center;gap:6px;white-space:nowrap;min-width:0;}
  .tm-co-r1 .curator-pri,.tm-co-r1 .curator-pri svg{width:16px;height:16px;flex:0 0 16px;}
  .tm-co-num{font-family:var(--font-mono);font-size:13px;font-weight:600;flex-shrink:0;}
  .tm-co-meta{font-size:12px;color:#9AA3AE;overflow:hidden;text-overflow:ellipsis;min-width:0;}
  .tm-co-r1 .team-picks{margin-left:auto;}
  .tm-co-r2{margin-top:5px;display:flex;align-items:center;gap:5px;font-size:12.5px;white-space:nowrap;overflow:hidden;}
  .tm-co-r2 svg{flex:0 0 auto;color:#9AA3AE;}
  .tm-co-r2 span{overflow:hidden;text-overflow:ellipsis;min-width:0;}
  .tm-co-r3{margin-top:3px;font-size:11px;color:#9AA3AE;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .tm-co-here{margin-top:6px;display:flex;align-items:center;gap:5px;font-size:12px;flex-wrap:wrap;}
  .tm-co-bt{display:flex;gap:8px;margin-top:10px;}
  .tm-co-bt .geo-navi{flex:1;height:40px;margin:0;border-radius:8px;font-size:13.5px;font-weight:600;}
  .tm-co-bt.has-act .geo-navi{background:none;border:1.5px solid var(--amber);color:var(--amber);}
  .tm-co-btn{flex:1;height:40px;border:1.5px solid var(--amber);border-radius:8px;background:none;color:var(--amber);font-family:var(--font-text);
    font-size:13.5px;font-weight:600;display:flex;align-items:center;justify-content:center;cursor:pointer;white-space:nowrap;padding:0;box-sizing:border-box;}
  .tm-co-btn.p{background:var(--amber);color:#1B2430;border-color:var(--amber);}
  .tm-co-btn.ok{border-color:#57C084;color:#57C084;cursor:default;}
  .tm-co-btn.pct{cursor:default;}
  /* Ряд слоёв внизу карты */
  .tm-tgs{position:absolute;left:8px;right:8px;bottom:8px;z-index:25;display:flex;gap:6px;}
  .tm-tg{flex:1;height:40px;padding:0 4px;border:1.5px solid var(--amber);border-radius:8px;background:#1B2430;color:#EDEEEA;font-family:var(--font-text);font-size:13px;
    font-weight:500;display:flex;align-items:center;justify-content:center;gap:6px;white-space:nowrap;cursor:pointer;box-shadow:0 3px 10px rgba(0,0,0,.3);}
  .tm-tg i{font-family:var(--font-mono);font-size:11px;font-style:normal;color:#9AA3AE;}
  .tm-tg-ck{width:9px;color:var(--amber);font-weight:700;}
  .tm-tg.off{border-color:#3A4552;color:#7D8894;}
  .tm-tg.off b{text-decoration:line-through;font-weight:500;}
  .tm-tg.off .tm-tg-ck{color:#7D8894;}

  /* ========== v2.99.1: доводка карты тикетов ========== */
  /* Выноска шире и без обрезки текста: длинное переносится, а не прячется за «…». */
  .tm-co{width:300px;max-width:calc(100% - 16px);}
  .tm-co-r1{flex-wrap:nowrap;}
  .tm-co-meta{margin-top:3px;font-size:12.5px;color:#9AA3AE;white-space:normal;line-height:1.35;}
  .tm-co-r2{align-items:flex-start;white-space:normal;line-height:1.35;}
  .tm-co-r2 svg{margin-top:2px;}
  .tm-co-r2 span{white-space:normal;overflow:visible;text-overflow:clip;}
  .tm-co-r3{white-space:normal;overflow:visible;text-overflow:clip;line-height:1.35;}
  /* Ряд «Маршруты / Ковры» — компактнее и не на всю ширину. */
  .tm-tgs{right:auto;gap:6px;}
  .tm-tg{flex:none;height:30px;padding:0 10px;border-width:1.5px;font-size:12px;gap:5px;box-shadow:0 2px 6px rgba(0,0,0,.28);}
  .tm-tg i{font-size:10.5px;}
  /* Последняя известная точка человека — «запятая» с инициалом; острие на самой точке. */

  /* v2.99.4: выбранная табличка без тяжёлой тёмной рамки */
  .tm-lbl.sel{border:1.5px solid rgba(27,36,48,.5);}

  /* ========== v2.99.5: выноска компактная и полупрозрачная, всегда под тикетом ========== */
  .tm-co{width:272px;max-width:calc(100% - 16px);padding:8px 10px;background:rgba(27,36,48,.8);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
    border:1px solid rgba(255,255,255,.14);border-radius:12px;box-shadow:0 4px 14px rgba(0,0,0,.25);}
  .tm-co-ptr{background:rgba(27,36,48,.8);}
  .tm-co-ptr.above{border-left:1px solid rgba(255,255,255,.14);border-top:1px solid rgba(255,255,255,.14);}
  .tm-co-r1{flex-wrap:nowrap;}
  .tm-co-meta{margin-top:0;font-size:12px;color:#B6BCC6;white-space:normal;overflow:visible;text-overflow:clip;min-width:0;line-height:1.3;}
  .tm-co-r2{margin-top:4px;font-size:12px;color:#DFE3E8;}
  .tm-co-r3{color:#B6BCC6;}
  .tm-co-bt{margin-top:8px;}
  .tm-co-bt .geo-navi{height:34px;font-size:13px;}
  .tm-co-btn{height:34px;font-size:13px;}

  /* ========== v2.100.0: карта тикетов — карточка снизу, табличка маршрута у А, ковёр в ковре ========== */
  .tm-co{right:auto;bottom:auto;max-width:none;}
  .tm-co-ptr{display:none;}
  /* «Хвостик» от точки А маршрута к его табличке */
  .tm-lbl-lead{position:absolute;height:1.5px;margin-top:-.75px;background:#1B2430;transform-origin:0 50%;pointer-events:none;}
  .tm-lbl-dot{position:absolute;width:7px;height:7px;margin:-3.5px 0 0 -3.5px;border-radius:50%;background:#0E9F6E;border:1.5px solid #fff;box-sizing:content-box;pointer-events:none;}
  /* Вложенные ковры в карточке: образец пунктира своего цвета */
  .tm-co-rel{margin-top:4px;display:flex;align-items:center;gap:5px;font-size:12px;color:#DFE3E8;line-height:1.3;}
  .tm-co-sw{display:inline-block;flex:0 0 14px;width:14px;height:0;border-top:2px solid;}
  /* v2.100.1: остальные тикеты при выборе видны, а не «в тени» */
  .tm-lbl.dim{opacity:.72;}
  .tm-co-rt{display:inline-block;flex:0 0 14px;width:14px;height:0;border-top:2.5px solid #DFE3E8;border-radius:2px;}
  /* v2.100.3: табличка вложенного ковра тонирована его цветом */
  .tm-lbl.nest .tm-lbl-num{color:inherit;}
  .tm-lbl.nest .tm-lbl-carpet{color:var(--nc-sub);}

  /* ========== v2.102.0: ярлык ковра на контуре, флажок маршрута на точке А ========== */
  .tm-lbl.tm-tab,.tm-lbl.flag{height:22px;padding:0 8px 0 6px;gap:5px;border-radius:5px;border-width:1.2px;}
  .tm-lbl.tm-tab .tm-lbl-num,.tm-lbl.flag .tm-lbl-num{font-size:12px;}
  .tm-lbl.tm-tab .tm-lbl-carpet{font-size:11px;}
  .tm-lbl.tm-tab .curator-pri,.tm-lbl.tm-tab .curator-pri svg,.tm-lbl.flag .curator-pri,.tm-lbl.flag .curator-pri svg{width:12px;height:12px;flex-basis:12px;}
  .tm-lbl.flag{background:#1B2430;border:none;color:#fff;overflow:visible;}
  .tm-lbl.flag .tm-lbl-num{color:#fff;}
  .tm-lbl.flag .tm-lbl-dist{font-size:11px;color:#DCE0E5;}
  .tm-lbl.flag .curator-pri-normal{color:#DCE0E5;}
  .tm-lbl.flag.sel{background:var(--amber);border:none;}
  .tm-lbl.flag.sel .tm-lbl-num,.tm-lbl.flag.sel .tm-lbl-dist{color:#1B2430;}
  .tm-flag-mast{position:absolute;top:100%;width:1.6px;margin-left:-.8px;background:#1B2430;pointer-events:none;}
  .tm-lbl.flag .tm-lbl-dot{width:5px;height:5px;margin:-2.5px 0 0 -2.5px;border-width:1px;}

  /* v2.103.1: счётчик «на карте N из N» в ряду кнопок */
  .tm-tg.tm-cnt i{color:var(--amber);}
  .tm-tg.tm-cnt.part i{color:#E07B2E;}

  /* v2.104.1: точки А и Б выбранного маршрута — зелёный старт, красный финиш */
  .tm-ab{position:absolute;left:0;top:0;width:24px;height:24px;margin:-12px 0 0 -12px;border-radius:50%;box-sizing:border-box;
    border:2px solid #fff;color:#fff;font:700 13px/20px 'Space Grotesk','Inter',sans-serif;text-align:center;box-shadow:0 1px 4px rgba(0,0,0,.4);}
  .tm-ab.a{background:#0E9F6E;}
  .tm-ab.b{background:#D64545;}
  /* Старт и финиш в одной точке: двойной значок А | Б */
  .tm-ab.both{width:46px;margin-left:-23px;border-radius:12px;display:flex;overflow:hidden;background:none;}
  .tm-ab.both i{flex:1;font-style:normal;}
  .tm-ab.both .a{background:#0E9F6E;}
  .tm-ab.both .b{background:#D64545;}

  /* v2.104.3: капли А и Б (острие в точке) и цветные точки старта/финиша */
  .tm-dp{position:absolute;left:0;top:0;width:0;height:0;transform-origin:0 0;filter:drop-shadow(0 1px 2px rgba(0,0,0,.35));}
  .tm-dp svg{position:absolute;left:-15px;top:-38px;overflow:visible;}
  .tm-dp path{stroke:#fff;stroke-width:1.8px;stroke-linejoin:round;}
  .tm-dp-a{fill:#0E9F6E;} .tm-dp-b{fill:#D64545;}
  .tm-dp text{fill:#fff;font:700 13px 'Space Grotesk','Inter',sans-serif;}
  .tm-pt{position:absolute;left:0;top:0;width:6px;height:6px;margin:-3px 0 0 -3px;border-radius:50%;border:1.5px solid #fff;box-sizing:content-box;box-shadow:0 0 0 .5px rgba(0,0,0,.3);}
  .tm-pt.a{background:#0E9F6E;} .tm-pt.b{background:#D64545;}

  /* v2.104.7: кружки «выбрал / взял / выполнил» на тёмной плашке у края ярлыка — видны и на янтарном */
  .tm-lbl-chips{align-self:stretch;display:flex;align-items:center;gap:3px;background:#1B2430;margin:0 -8px 0 3px;padding:0 7px 0 6px;border-radius:0 5px 5px 0;}
  .tm-lbl-chips .team-chip.me{box-shadow:0 0 0 1.5px #fff;}
  .tm-lbl-chips .team-chip.live{border-color:var(--amber);}

/* слой тикетов экипажа на карте геопозиции: табличка в две строки (v3.0.5) */
.gt-lbl{position:absolute;left:0;top:0;display:flex;flex-direction:column;align-items:stretch;text-align:center;border-radius:6px;overflow:hidden;
  border:1.2px solid var(--c);background:#fff;white-space:nowrap;pointer-events:none}
.gt-lbl.gt-on{transform:translate(-50%,-50%)}
.gt-lbl.gt-up{transform:translate(-50%,calc(-100% - 4px - var(--d,0px)))}
.gt-lbl.gt-dn{transform:translate(-50%,calc(4px + var(--d,0px)))}
.gt-lbl.gt-lf{transform:translate(calc(-100% - 6px - var(--d,0px)),-50%)}
.gt-lbl.gt-rt{transform:translate(calc(6px + var(--d,0px)),-50%)}
.gt-lbl .gt-num{background:var(--c);color:#fff;font:500 12px/18px 'IBM Plex Mono',monospace;padding:0 8px}
.gt-lbl .gt-st{display:flex;justify-content:center;align-items:center;gap:3px;padding:0 8px;font:500 11px/17px 'Inter',sans-serif;color:#1B2430}
.gt-lbl.added{opacity:.8}.gt-lbl.added .gt-st{color:#5F5E5A}
.gt-lbl.done .gt-st{background:#DCFCE7;color:#166534}

/* заставка Rover List Full Edition (v3.0.1) */
#feSplash{position:fixed;inset:0;z-index:9000;background:#1B2430;color:#EDEEEA;overflow-y:auto;transition:opacity .35s;
  padding:max(14px,env(safe-area-inset-top)) 0 max(18px,env(safe-area-inset-bottom));box-sizing:border-box;}
.fe-main{display:flex;flex-direction:column;align-items:center;min-height:100%;}
.fe-artw{position:relative;width:100%;max-width:340px;aspect-ratio:340/230;margin-top:10px;}
.fe-artw svg,.fe-artw canvas{position:absolute;left:0;top:0;width:100%;height:100%;display:block;}
.fe-artw canvas{pointer-events:none;}
.fe-ln{fill:none;stroke-linecap:round;stroke-linejoin:round;}
.fe-dr{stroke-dasharray:100;stroke-dashoffset:100;animation:feDr 1.3s ease-out forwards;}
.fe-cf{fill-opacity:0;animation:feFf .8s ease-out forwards;}
.fe-st{opacity:0;animation:feFi .8s ease-out forwards;}
.fe-pp{opacity:0;transform-box:fill-box;transform-origin:center;animation:fePp .45s ease-out forwards;}
.fe-pp text{font:500 10px var(--font-body,Inter),sans-serif;fill:#fff;}
.fe-trail{stroke:#22D3EE;stroke-opacity:.2;stroke-width:15;stroke-dasharray:100;stroke-dashoffset:100;animation:feDr 2.2s linear .6s forwards;}
.fe-rt{stroke:#EDEEEA;stroke-opacity:.7;stroke-width:1.6;stroke-dasharray:3 3;}
.fe-rv{opacity:0;animation:feFi .2s linear .6s forwards;}
.fe-ring{fill:none;stroke:#F2A900;stroke-width:2;opacity:0;transform-box:fill-box;transform-origin:center;animation:feRg 1s ease-out 2.8s forwards;}
.fe-t1{display:flex;gap:3px;margin-top:14px;font:700 30px var(--font-display,'Space Grotesk'),sans-serif;letter-spacing:5px;padding-left:5px;}
.fe-t1 span{opacity:0;transform:translateY(10px);animation:feUp .5s ease-out forwards;}
.fe-bar{height:2px;background:#F2A900;width:0;margin-top:8px;animation:feBw .7s ease-out 2.9s forwards;}
.fe-t2{margin-top:9px;font:500 14px var(--font-mono,'IBM Plex Mono'),monospace;letter-spacing:6px;color:#F2A900;opacity:0;animation:feFi .6s ease-out 3.2s forwards;padding-left:6px;}
.fe-t3{margin-top:6px;font:500 13px var(--font-mono,'IBM Plex Mono'),monospace;color:#9AA5B4;opacity:0;animation:feFi .4s ease-out 3.4s forwards;}
.fe-t3.fe-pop{color:#F2A900;animation:feFi .1s forwards,feVp .5s ease-out;}
.fe-fl{margin-top:14px;width:min(292px,86vw);}
.fe-fl div{display:flex;gap:12px;align-items:baseline;padding:7px 0;border-bottom:1px solid #2A3646;font:400 13px var(--font-body,Inter),sans-serif;color:#D5DBE4;opacity:0;transform:translateX(-8px);animation:feUp .45s ease-out forwards;}
.fe-fl b{font:500 11px var(--font-mono,'IBM Plex Mono'),monospace;color:#F2A900;min-width:18px;}
.fe-act{margin-top:auto;padding-top:16px;display:flex;flex-direction:column;align-items:center;gap:14px;}
.fe-more{font:400 13px var(--font-body,Inter),sans-serif;color:#9AA5B4;background:none;border:0;border-bottom:1px solid #4A5667;border-radius:0;padding:0 0 2px;opacity:0;animation:feFi .5s ease-out 4.8s forwards;cursor:pointer;}
.fe-go{width:140px;height:42px;border:1.5px solid #F2A900;background:transparent;color:#F2A900;border-radius:10px;font:500 15px var(--font-body,Inter),sans-serif;opacity:0;animation:feFi .5s ease-out 4.9s forwards;cursor:pointer;}
.fe-dt{padding:22px 24px 26px;max-width:420px;margin:0 auto;box-sizing:border-box;}
.fe-dt h3{font:700 20px var(--font-display,'Space Grotesk'),sans-serif;letter-spacing:3px;text-align:center;margin:0 0 2px;color:#EDEEEA;}
.fe-sb{font:500 11px var(--font-mono,'IBM Plex Mono'),monospace;letter-spacing:4px;color:#F2A900;text-align:center;margin-bottom:14px;}
.fe-dt h4{font:500 11px var(--font-mono,'IBM Plex Mono'),monospace;letter-spacing:2px;color:#F2A900;margin:16px 0 4px;text-transform:uppercase;}
.fe-dt p{margin:0;padding:6px 0;border-bottom:1px solid #2A3646;font:400 13px/1.45 var(--font-body,Inter),sans-serif;color:#D5DBE4;}
.fe-bk{display:block;margin:20px auto 0;border:1.5px solid #F2A900;background:transparent;color:#F2A900;border-radius:10px;height:40px;width:140px;font:500 15px var(--font-body,Inter),sans-serif;cursor:pointer;}
@keyframes feDr{to{stroke-dashoffset:0}}
@keyframes feFi{to{opacity:1}}
@keyframes feFf{to{fill-opacity:.17}}
@keyframes feUp{to{opacity:1;transform:none}}
@keyframes fePp{0%{opacity:0;transform:scale(.3)}70%{transform:scale(1.25)}100%{opacity:1;transform:scale(1)}}
@keyframes feRg{0%{opacity:.9;transform:scale(.4)}100%{opacity:0;transform:scale(3)}}
@keyframes feBw{to{width:150px}}
@keyframes feVp{0%{transform:scale(1.5)}100%{transform:scale(1)}}
@media (prefers-reduced-motion:reduce){#feSplash *{animation-duration:.01s!important;animation-delay:0s!important}}

.fe-replay{margin-top:8px;border:1.5px solid #F2A900;background:transparent;color:#B07A00;border-radius:10px;height:38px;padding:0 16px;font:500 14px var(--font-text,Inter),sans-serif;cursor:pointer;}

/* окно «Поделиться» и заявки в экипаж: на общих цветах темы, кнопки как везде в приложении (v3.1.2) */
.geo-top-btns{display:flex;gap:8px;align-items:center;}
.geo-ib{width:40px;height:40px;border-radius:10px;border:0;background:#2A3646;color:#EDEEEA;display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0;}
.geo-ib svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round;}
.geo-ib.share{color:#F2A900;}
.geo-ib:active{background:#364559;}
.sh-back{position:fixed;inset:0;z-index:8500;background:rgba(15,20,28,.55);display:flex;align-items:flex-end;justify-content:center;}
.sh-sheet{background:var(--surface);color:var(--ink);width:100%;max-width:var(--content-max,520px);max-height:92vh;overflow-y:auto;border-radius:16px 16px 0 0;
  padding:14px 16px calc(18px + env(safe-area-inset-bottom,0px));box-sizing:border-box;font-family:var(--font-text);}
.sh-grab{width:36px;height:4px;border-radius:2px;background:var(--line);margin:0 auto 12px;}
.sh-sheet h3{font:700 18px var(--font-display);margin:0;color:var(--ink);}
.sh-sub{font-size:13.5px;color:var(--ink-soft);margin:6px 0 14px;line-height:1.45;}
.sh-link{background:var(--surface-2);border:1px solid var(--line);border-radius:8px;padding:11px 12px;font:500 13px var(--font-mono);color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.sh-row{display:flex;gap:8px;margin-top:10px;}
.sh-btn{flex:1;height:var(--h-action,44px);border-radius:8px;font:700 15px var(--font-text);border:1.5px solid var(--line);background:transparent;color:var(--ink);cursor:pointer;padding:0 8px;}
.sh-btn.pr{background:var(--amber);border-color:var(--amber);color:#1B2430;}
.sh-btn.dg{border-color:var(--red);color:var(--red);}
.sh-btn:active{opacity:.85;}
.sh-lb{font:600 11px var(--font-mono);letter-spacing:1.5px;color:var(--amber-dark);margin:16px 0 8px;text-transform:uppercase;}
.sh-chips{display:flex;gap:8px;flex-wrap:wrap;}
.sh-chip{flex:1 1 auto;min-height:40px;border:1.5px solid var(--line);background:transparent;color:var(--ink);border-radius:8px;padding:0 12px;font:600 14px var(--font-text);cursor:pointer;}
.sh-chip.on{background:var(--ink);color:var(--surface);border-color:var(--ink);}
.sh-until{font-size:13px;color:var(--ink-soft);margin-top:8px;line-height:1.4;}
.sh-sw{display:flex;align-items:center;justify-content:space-between;min-height:46px;border-bottom:1px solid var(--line);font-size:14.5px;}
.sh-tg{width:44px;height:26px;border-radius:13px;background:var(--line);position:relative;cursor:pointer;border:0;padding:0;flex:none;}
.sh-tg::after{content:"";position:absolute;left:3px;top:3px;width:20px;height:20px;border-radius:50%;background:#fff;transition:left .15s;}
.sh-tg.on{background:var(--amber);}.sh-tg.on::after{left:21px;}
.sh-ft{font-size:12.5px;color:var(--ink-soft);margin:12px 0 4px;line-height:1.5;}
.sh-err{background:rgba(194,68,68,.12);color:var(--red);border-radius:8px;padding:9px 11px;font-size:13.5px;margin-bottom:10px;}

.join-note{background:var(--amber-tint);border:1px solid var(--amber);color:var(--ink);border-radius:8px;padding:10px 12px;margin:10px 0 4px;font-size:13.5px;line-height:1.4;}

/* статус тикета в ярлыке карты заданий (v3.1.3) */
.tm-lbl-st{display:inline-flex;align-items:center;margin-left:5px;font:600 11px var(--font-mono);}
.tm-lbl.st-done .tm-lbl-st{color:#1F7A4D;}
.tm-lbl.sel .tm-lbl-st{color:inherit;}

/* галочка «выполнен» на тёмном флажке маршрута - светлая, иначе зелёное на сером не читается (v3.1.5) */
.tm-lbl.flag.st-done .tm-lbl-st{color:#9BE7B8;}
.tm-lbl.flag .tm-lbl-st{margin-left:4px;}
.tm-lbl-st svg{display:block;}

/* выполненный тикет на карте заданий (v3.1.9): светлая плашка с зелёной рамкой и зелёной галочкой, как остальные ярлыки, а не сплошная заливка */
.tm-lbl.st-done:not(.sel){background:#EEF1F5 !important;border-color:#334155 !important;color:#1E293B !important;}
.tm-lbl.flag.st-done:not(.sel){background:#1B2430 !important;border-color:#1B2430 !important;box-shadow:none;}
.tm-lbl.flag.st-done:not(.sel) .tm-lbl-num,.tm-lbl.flag.st-done:not(.sel) .tm-lbl-dist,.tm-lbl.flag.st-done:not(.sel) .tm-lbl-carpet{color:#fff !important;}
.tm-lbl.st-done:not(.sel) .tm-lbl-num,.tm-lbl.st-done:not(.sel) .tm-lbl-carpet,.tm-lbl.st-done:not(.sel) .tm-lbl-dist{color:#1E293B !important;}
.tm-lbl.st-done:not(.sel) .tm-lbl-st,.tm-lbl.flag.st-done:not(.sel) .tm-lbl-st{color:#16A34A !important;}
.gt-lbl.done .gt-st{background:#E8ECF1;color:#1E293B;}

/* добавлен (взяли, процента нет): пунктирная рамка; одинаково на обеих картах (v3.2.0) */
/* v3.3.3: пунктир только у свободных тикетов на карте задания (никто не добавил) */
.tm-lbl.st-free:not(.sel){border-style:dashed;border-color:#B7BEC7;background:rgba(255,255,255,.72);color:#6B7380;}
.tm-lbl.st-free:not(.sel) .tm-lbl-num{color:#6B7380;}
.tm-lbl.st-free:not(.sel) .curator-pri{opacity:.6;}
.tm-lbl.flag.st-free:not(.sel){background:#2A3340;border:none;outline:1.2px dashed #8E99A6;outline-offset:-2px;}
.tm-lbl.flag.st-free:not(.sel) .tm-lbl-num{color:#C9D0D8;}

/* «Задание экипажа» на экране смены (v3.3.0) */
.crew-task{margin-top:12px;border:1.5px solid var(--line);border-radius:10px;padding:10px 12px 12px;}
.ct-cap{font:600 11px var(--font-mono);letter-spacing:1.4px;text-transform:uppercase;color:var(--amber-dark);margin-bottom:4px;}
.ct-row{display:flex;align-items:baseline;justify-content:space-between;gap:10px;}
.ct-row b{font:700 16px var(--font-display);color:var(--ink);}
.ct-link{background:none;border:0;padding:4px 0;color:var(--amber-dark);font:600 13px var(--font-text);cursor:pointer;white-space:nowrap;}
.ct-meta{font-size:13px;color:var(--ink-soft);margin-top:2px;min-height:16px;}
.ct-open{margin-top:10px;}
.add-ticket.add-manual{background:transparent;border:1.5px dashed var(--line);color:var(--ink-soft);font-weight:600;font-size:14px;}

/* карточка «Тикеты»: задание экипажа + мои тикеты (v3.3.1) */
.ct-cap{display:flex;align-items:center;justify-content:space-between;font:600 11px var(--font-mono);letter-spacing:1.4px;text-transform:uppercase;color:var(--amber-dark);margin:2px 0 6px;}
.ct-chg{display:inline-flex;align-items:center;gap:4px;background:none;border:0;padding:4px 0;color:var(--ink-soft);font:500 12.5px var(--font-text);letter-spacing:0;text-transform:none;cursor:pointer;}
.ct-row{display:flex;align-items:center;gap:10px;}
.ct-nm{flex:1;min-width:0;}
.ct-nm b{display:block;font:700 16px var(--font-display);color:var(--ink);}
.ct-nm small{display:block;font-size:13px;color:var(--ink-soft);margin-top:2px;}
.ct-open{flex:none;display:inline-flex;align-items:center;gap:6px;height:40px;padding:0 14px;border-radius:10px;border:1.5px solid var(--amber);background:transparent;color:var(--amber-dark);font:700 14px var(--font-text);cursor:pointer;}
.ct-open[disabled]{opacity:.5;}
.ct-hr{height:1px;background:var(--line);margin:14px 0 12px;}
.ct-sub{font:600 11px var(--font-mono);letter-spacing:1.4px;text-transform:uppercase;color:var(--amber-dark);margin-bottom:8px;}
.ct-sub span{letter-spacing:0;}
.add-ticket.add-manual{display:flex;align-items:center;justify-content:center;gap:6px;}
#crewCard #curatorPreviewPanel{display:none !important;}
/* экран задания: вкладки и список */
.tm-seg{display:flex;gap:4px;margin:0;padding:6px 12px 10px;background:#1B2430;}
.tm-seg button{flex:1;height:36px;border-radius:9px;border:1px solid #2F3B4B;background:transparent;color:#9AA5B4;font:600 14px var(--font-text);cursor:pointer;}
.tm-seg button.on{background:#EDEEEA;color:#1B2430;border-color:#EDEEEA;}
.tm-listpane{position:absolute;inset:0;z-index:30;overflow-y:auto;background:var(--bg);padding:12px 12px 24px;box-sizing:border-box;}
.tm-listpane #curatorPreviewPanel{margin-top:0 !important;padding-top:0 !important;border-top:0 !important;}
.tm-listpane .curator-hd,.tm-listpane #curatorBackBtn{display:none !important;}
.tm-refresh.spin svg{animation:tmspin 1s linear infinite;}
@keyframes tmspin{to{transform:rotate(360deg);}}

/* v3.3.2: «Задание экипажа» - обычная карточка; «Мои тикеты» - как раньше, плоская (у тикетов своя рамка) */
.ct-head{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin-bottom:8px;}
.ct-head h2{margin:0;}
#myTicketsCnt{color:var(--ink-soft);font-weight:500;}

/* ручной ввод тикета - тонкой строкой внизу карточки «Задание экипажа» (v3.3.3) */
.ct-foot{margin-top:12px;padding-top:10px;border-top:1px solid var(--line);display:flex;justify-content:center;}
.ct-manual{display:inline-flex;align-items:center;gap:5px;background:none;border:0;padding:4px 6px;color:var(--ink-soft);font:500 13px var(--font-text);cursor:pointer;}

/* плашка обновления: маленькая, по центру сверху, как «нет связи» (v3.4.1). Четыре стадии: доступно, обновляю, сервер, обновлено */
.update-banner{position:fixed;left:50%;right:auto;top:calc(env(safe-area-inset-top,0px) + 8px);transform:translate(-50%,-220%);
  display:flex;align-items:center;gap:8px;height:28px;padding:0 13px;border-radius:999px;border:1px solid var(--amber);
  background:#2A3646;color:var(--amber);font:600 12.5px var(--font-text);white-space:nowrap;z-index:420;cursor:pointer;
  box-shadow:0 4px 14px rgba(0,0,0,.3);transition:transform .25s,background-color .2s,color .2s,border-color .2s;}
.update-banner.show{transform:translate(-50%,0);}
.update-banner .ub-sp,.update-banner .ub-ar,.update-banner .ub-ck{display:none;margin:0;}
.update-banner .ub-sp{width:12px;height:12px;border:2px solid currentColor;border-top-color:transparent;border-radius:50%;animation:pull-spin .8s linear infinite;flex:none;}
.update-banner.st-avail .ub-ar{display:block;}
.update-banner.applying,.update-banner.st-srvbusy{cursor:default;}
.update-banner.applying .ub-sp,.update-banner.st-srvbusy .ub-sp{display:block;}
.update-banner.st-srv{background:#2A3646;border-color:#5A6678;color:#E4E8EE;}
.update-banner.st-srv .ub-ar{display:block;}
.update-banner.st-srvbusy{background:#2A3646;border-color:#5A6678;color:#E4E8EE;}
.update-banner.st-done{background:#E6F6EC;border-color:#16A34A;color:#14532D;cursor:default;}
.update-banner.st-done .ub-ck{display:block;}
body.has-update-banner{padding-top:0 !important;}
.update-banner.applying{background:#2A3646;color:var(--amber);border-color:var(--amber);}

/* v3.5.1: вкладка «Список» - список прокручивается, а «Назад / Добавить» стоят у нижнего края всегда (раньше «Добавить АКБ» всплывало посреди списка) */
.tm-listpane{overflow:hidden !important;padding:0 !important;}
.tm-listpane #curatorPreviewPanel{display:flex !important;flex-direction:column;height:100%;}
.tm-listpane #curatorPreviewPanel[style*="display: none"]{display:none !important;}
.tm-listpane .curator-scroll{flex:1 1 auto;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:12px 12px 8px;}
.tm-listpane .curator-actions{position:static;flex:none;margin:0;border-radius:0;padding:10px 12px calc(12px + env(safe-area-inset-bottom,0px));}
/* v3.5.1: свободные тикеты на карте читаются: тёмнее рамка и текст, значок приоритета не бледнеет, у флажков значок на белой подложке */
.tm-lbl.st-free:not(.sel){border-color:#7C8695;color:#3B4452;}
.tm-lbl.st-free:not(.sel) .tm-lbl-num{color:#3B4452;}
.tm-lbl.st-free:not(.sel) .tm-lbl-carpet{color:#5A6372;}
.tm-lbl.st-free:not(.sel) .curator-pri{opacity:1;}
.tm-lbl.flag.st-free:not(.sel){background:#2A3340;}
.tm-lbl.flag .curator-pri{background:#fff;border-radius:50%;padding:2px;box-sizing:content-box;}

/* v3.5.3: переключатель темы - в тёмной теме корпус нейтральный (как поля ввода), а не янтарный: янтарь резал глаз */
[data-theme="dark"] .theme-switch-track{background:#2A3646;box-shadow:inset 0 0 0 1px #3A4658;}
[data-theme="dark"] .theme-switch .ts-icon{color:#7A8698;}

/* v3.5.5: свой «жест обновления» на карте и в списке задания отключён (там своя прокрутка), и тогда пальцем вниз срабатывало
   встроенное обновление браузера - грубая перезагрузка страницы. Запрещаем его совсем: обновление - значок ⟳ в шапке задания,
   а на «Сегодня», «Истории» и «Отчёте» работает наша мягкая тяга. */
html,body{overscroll-behavior-y:none;}
.tm-modal,.geo-modal,.tm-listpane,.curator-scroll,.sh-back,.sh-sheet,.sheet{overscroll-behavior:contain;}

/* v3.6.0: раздел «Подсказки и напоминания» - строки с галочками и сами правила скрытия */
.hint-row{display:flex;align-items:flex-start;gap:12px;padding:12px 2px;border-bottom:1px solid var(--line);cursor:pointer;}
.hint-row input{flex:none;width:22px;height:22px;margin-top:1px;accent-color:var(--amber);}
.hint-tx{display:flex;flex-direction:column;gap:2px;font-size:14.5px;line-height:1.35;}
.hint-tx small{font-size:12.5px;color:var(--ink-soft);font-weight:400;}
html.hide-h-vtLine .vt-live-line{display:none !important;}
html.hide-h-push #pushNudgeStrip{display:none !important;}
html.hide-h-geoAsk #geoAskBanner{display:none !important;}
html.hide-h-goal .goal-nudge{display:none !important;}
html.hide-h-chips .chips-nudge{display:none !important;}
html.hide-h-onboard .onboard-tip,html.hide-h-onboard .onboard-bottom-tip{display:none !important;}
html.hide-h-draft #draftBanner{display:none !important;}

.akb-split{font-size:12.5px;color:var(--ink-soft);margin-top:6px;min-height:16px;}

/* v3.6.4: галочка на тёмном флажке выполненного маршрута - светлая */
.tm-lbl.flag.st-done:not(.sel) .tm-lbl-st{color:#9BE7B8 !important;}

/* v3.6.10: полоска прогресса внутри строки обновления (под текстом и крутилкой) */
.update-banner{overflow:hidden;}
.update-banner .ub-fill{position:absolute;left:0;top:0;bottom:0;width:0;background:rgba(242,169,0,.28);pointer-events:none;}
.update-banner > :not(.ub-fill){position:relative;}

/* v3.6.11: значок приоритета - часть таблички, без белого кружка; цвет под фон таблички */
.tm-lbl .curator-pri{background:none!important;padding:0!important;border-radius:0!important;}
.tm-lbl.flag .curator-pri,.tm-lbl.flag .curator-pri svg{width:14px;height:14px;flex-basis:14px;}
.tm-lbl .curator-pri-blocker{color:#C62828;}
.tm-lbl .curator-pri-crit{color:#C2410C;}
.tm-lbl.flag:not(.sel) .curator-pri-blocker{color:#FF6B6B;}
.tm-lbl.flag:not(.sel) .curator-pri-crit{color:#FFA94D;}
.tm-lbl.flag:not(.sel) .curator-pri-normal{color:#C9CED6;}
.tm-lbl.sel .curator-pri-blocker{color:#B91C1C!important;}
.tm-lbl.sel .curator-pri-crit{color:#E8590C!important;}
.tm-lbl.sel .curator-pri-normal{color:#1B2430!important;}
.tm-lbl.sel .curator-pri svg{stroke-width:2.6;}

/* v3.6.12: общий тикет - значок «несколько экипажей» на табличке и строка экипажей в карточке */
.tm-lbl .tm-crews-ic{flex:0 0 16px;width:16px;height:16px;margin-left:1px;}
.tm-co-crews .tm-crews-ic{flex:0 0 14px;width:14px;height:14px;color:#9AA3AE;}
.tm-co-crews > span{display:flex;flex-wrap:wrap;column-gap:12px;row-gap:2px;}
.tm-co-crew{display:inline-flex;align-items:center;gap:5px;white-space:nowrap;}
.tm-co-crew i{width:8px;height:8px;border-radius:50%;flex:0 0 8px;}
/* v3.6.14: на тёмной табличке маршрута человечки светлые, как номер (брали тёмный цвет «свободной» таблички и терялись) */
.tm-lbl.flag:not(.sel) .tm-crews-ic{color:#DCE0E5;}
.tm-lbl.sel .tm-crews-ic{color:#1B2430;}

/* v3.6.16: строка экипажа в шапке - капсула со стрелкой (нажимается), точка «на связи», кнопка «Карта» со значком карты */
.crew-row .crew-cap{display:inline-flex;align-items:center;gap:6px;height:30px;padding:0 10px;min-width:0;flex:0 1 auto;
  border:1px solid rgba(255,255,255,.16);background:rgba(255,255,255,.06);border-radius:999px;}
.crew-row .crew-cap .crew-who{min-width:0;}
.crew-row .crew-cap .crew-nums{flex:0 0 auto;}
.crew-row .crew-chev{color:var(--amber);font-weight:600;flex:0 0 auto;}
.crew-row .crew-live{margin-left:0;flex:0 0 auto;line-height:0;}
.crew-row .crew-live .vt-ld{width:9px;height:9px;margin:0;}
.crew-row #crewGeoBtn{width:auto;height:30px;flex:0 0 auto;margin-left:auto;padding:0 12px;gap:6px;border-width:1.5px;border-radius:999px;
  font:600 12.5px var(--font-sans,inherit);}
.crew-row #crewGeoBtn svg{width:15px;height:15px;}
.crew-row #crewGeoBtn::after{inset:-7px -4px;}

/* v3.6.17: точка статуса внутри капсулы (после имён, перед счётом); зелёная пульсирует три раза при появлении, дальше ровно */
.crew-row .crew-cap .crew-live{flex:0 0 auto;margin:0;line-height:0;}
.crew-row .crew-live .vt-ld{position:relative;}
.crew-row .crew-live .vt-ld.on{box-shadow:none;}
.crew-live.ring .vt-ld::after{content:"";position:absolute;inset:0;border-radius:50%;background:#34C759;
  animation:crewRing 1.8s ease-out 3 both;animation-delay:var(--ring-skip,0s);pointer-events:none;}
@keyframes crewRing{0%{transform:scale(1);opacity:.55}100%{transform:scale(2.8);opacity:0}}
@media (prefers-reduced-motion:reduce){.crew-live.ring .vt-ld::after{animation:none;}}

/* v3.6.18: окно «Тикеты экипажа» - у каждого человека имя и счёт сверху, под ними две кнопки с подписями */
.crew-pop-row .crew-pop-top{flex:1 1 100%;display:flex;align-items:center;gap:8px;min-width:0;}
.crew-pop-row .crew-pop-btns{flex:1 1 100%;display:flex;gap:8px;}
.crew-pop-btns .crew-nudge,.crew-pop-btns .crew-geo{flex:1 1 0;width:auto;min-width:0;height:32px;margin:0;padding:0 6px;gap:6px;
  border-width:1.5px;border-radius:9px;display:inline-flex;align-items:center;justify-content:center;white-space:nowrap;
  font:600 12.5px var(--font-sans,inherit);}
.crew-pop-btns .crew-nudge svg,.crew-pop-btns .crew-geo svg{width:15px;height:15px;flex:0 0 15px;}
.crew-pop-btns .crew-geo::after{inset:-4px;}

/* v3.6.20: раскрытая цель в шапке - вердикт, три цифры, полоса смен, график на виду.
   Цвета: «успеваешь» бирюзовый, «можно успеть» жёлтый, красного/зелёного/оранжевого нет. Углы 8px, не пилюли. */
:root{--goal-ok:#0E8FA3;--goal-push:#B7791F;}
[data-theme="dark"]{--goal-ok:#2DD4EF;--goal-push:#FFD43B;}
.goal-row b.bad{color:var(--goal-push);}
.goal-row b.good{color:var(--goal-ok);}
.goal-row .dot{background:var(--goal-push);}
#headerGoalMore{margin-top:10px;--gm-ac:#C9CED6;}
.gm-vd{display:flex;align-items:center;justify-content:space-between;gap:8px;height:32px;padding:0 11px;border-radius:8px;box-sizing:border-box;}
.gm-vd .t{font-weight:600;font-size:13px;display:flex;align-items:center;gap:6px;white-space:nowrap;}
.gm-vd .r{font:500 12px var(--font-mono);white-space:nowrap;}
.gm-vd.ok{background:#2DD4EF;color:#0B2A33;}
.gm-vd.push{border:1.5px solid #FFD43B;color:#FFD43B;}
.gm-vd.calm{border:1px solid rgba(154,163,174,.35);background:rgba(154,163,174,.10);color:#C9CED6;}
.gm-c3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));margin-top:8px;background:rgba(255,255,255,.06);border-radius:8px;padding:9px 0;}
.gm-c3 > div{padding:0 9px;border-left:1px solid rgba(255,255,255,.10);min-width:0;}
.gm-c3 > div:first-child{border-left:0;}
.gm-lab{font-size:10px;letter-spacing:.3px;color:#9AA3AE;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.gm-v{font:600 18px var(--font-mono);color:var(--gm-ac);margin:3px 0 1px;white-space:nowrap;}
.gm-v.w{color:#EDEEEA;}
.gm-v i{font-style:normal;font-size:11px;font-weight:400;color:#9AA3AE;margin-left:3px;}
.gm-s{font-size:10px;color:#8A93A0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.gm-cells{display:grid;gap:2px;margin-top:10px;position:relative;padding-top:17px;}
.gm-cells.nf{padding-top:0;margin-top:12px;}
.gm-c{display:block;height:12px;border-radius:2px;box-sizing:border-box;}
.gm-c.dn{background:#6B7480;}
.gm-c.nd{border:1.5px solid var(--gm-ac);}
.gm-c.td{background:var(--gm-ac);border:1.5px solid var(--gm-ac);}
.gm-c.sp{border:1.5px dashed #5A6472;}
.gm-flag{position:absolute;top:0;transform:translateX(-50%);font:500 10px var(--font-mono);color:var(--gm-ac);display:flex;flex-direction:column;align-items:center;}
.gm-flag:after{content:"";width:1.5px;height:6px;background:var(--gm-ac);margin-top:1px;}
.gm-legend{display:flex;justify-content:space-between;font-size:10.5px;color:#8A93A0;margin-top:6px;}
.gm-chart{display:block;width:100%;margin-top:10px;padding:9px 10px 8px;text-align:left;background:rgba(255,255,255,.06);border:1px solid #3A4552;border-radius:8px;color:#EDEEEA;cursor:pointer;font:inherit;}
.gm-ch-h{display:flex;justify-content:space-between;align-items:center;font-size:13px;font-weight:500;margin-bottom:2px;}
.gm-more{color:#9AA3AE;font-weight:400;}
#gmSpark{min-height:100px;}
#gmSpark svg{display:block;width:100%;height:auto;}
.gm-key{display:flex;gap:14px;font-size:10.5px;color:#8A93A0;margin-top:4px;}
.gm-key i{display:inline-block;width:16px;height:0;vertical-align:middle;margin-right:5px;}
.gm-key .k1{border-top:2.2px solid #EDEEEA;}
.gm-key .k2{border-top:1.5px dashed #6B7480;}
.gm-key .k3{border-top:2px dotted var(--gm-ac);}
#headerGoalMore.gm-short .gm-c3,#headerGoalMore.gm-short .gm-cells,#headerGoalMore.gm-short .gm-legend{display:none;}

/* v3.6.22: карточка тикета над картой - без размытия фона. Размытие поверх живой карты пересчитывается на каждом кадре
   зума и сдвига и заметно роняет плавность; вместо него фон чуть плотнее, на вид почти то же. */
.tm-co{-webkit-backdrop-filter:none;backdrop-filter:none;background:rgba(27,36,48,.94);}

/* v3.7.0: метки и выноска на новой карте (v3). Круглая точка с подписью - «люди» на карте экипажа; выноска - по нажатию на человека. */
.y3-pm{pointer-events:none;}
.y3-dot{position:absolute;left:-7px;top:-7px;width:14px;height:14px;border-radius:50%;border:2px solid #fff;box-sizing:border-box;box-shadow:0 1px 4px rgba(0,0,0,.35);}
.y3-cap{position:absolute;left:12px;top:-9px;max-width:160px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:600 12px/18px var(--font-sans,inherit);color:#1B2430;text-shadow:0 0 3px #fff,0 0 3px #fff,0 0 3px #fff;}
.y3-balloon-wrap{position:relative;width:0;height:0;}
.y3-balloon{position:absolute;left:0;bottom:30px;transform:translateX(-50%);min-width:150px;max-width:240px;background:#fff;color:#1B2430;border-radius:10px;padding:10px 12px;box-shadow:0 4px 18px rgba(0,0,0,.28);font-size:13px;line-height:1.4;pointer-events:auto;}
.y3-balloon:after{content:"";position:absolute;left:50%;bottom:-6px;width:12px;height:12px;background:#fff;transform:translateX(-50%) rotate(45deg);}
.y3-bl-h{font-weight:600;margin-right:18px;}
.y3-bl-b{margin-top:4px;}
.y3-bl-x{position:absolute;right:6px;top:4px;border:0;background:none;font-size:18px;line-height:1;color:#6B7480;padding:2px 4px;cursor:pointer;}

/* v3.7.1: внутренности новой карты (логотип, авторские права) не должны вылезать поверх наших кнопок:
   карта живёт в своём слое, а кнопки, рация и переключатели лежат выше. */
.tm-ymap,#geoMapYandex{isolation:isolate;}

/* v3.7.3: поиск GPS - на кнопке «Найти себя», без плавающей плашки поверх карты. Заливка кнопки (.on) по-прежнему значит «слежу за мной». */
#geoSeekPill{display:none !important;}
.geo-ctrl .geo-me-btn{position:relative;}
.geo-ctrl .geo-me-btn.seek,.geo-ctrl .geo-me-btn.found{color:#F2A900;box-shadow:inset 0 0 0 1.5px #F2A900;}
.geo-ctrl .geo-me-btn.found .geo-me-dot{fill:currentColor;}
.geo-ctrl .geo-me-btn.seek::after{content:"";position:absolute;inset:-5px;border-radius:14px;border:2px solid #F2A900;animation:geoSeekPulse 1.4s ease-out infinite;pointer-events:none;}
@keyframes geoSeekPulse{0%{transform:scale(.88);opacity:.9}100%{transform:scale(1.22);opacity:0}}
.geo-ctrl .geo-me-btn.fail{opacity:.55;}
.geo-ctrl .geo-me-btn.on{box-shadow:none;}
@media (prefers-reduced-motion:reduce){.geo-ctrl .geo-me-btn.seek::after{animation:none;opacity:.55;}}

/* v3.7.4: обновление без выдуманных процентов - полоски нет; заставка на время обновления только тёмный фон, без ровера и подписей. */
.update-banner .ub-fill{display:none !important;}
#bootScreen.quiet > :not(#bootRetry){visibility:hidden;}

/* v3.7.5: дорога ровера на заставке короче (1,8 с вместо 2,6 с), чтобы он успевал доехать до конца. */
.boot-rv{animation-duration:1.8s;}
@media (prefers-reduced-motion:reduce){.boot-rv{animation-duration:6s;}}

/* v3.7.6: большая заставка - «Пропустить» видно сразу, закрывается тапом в любое место */
.fe-skip{position:fixed;right:14px;top:calc(env(safe-area-inset-top,0px) + 12px);z-index:3;background:none;border:0;color:#9AA5B4;
  font:400 13px var(--font-body,Inter),sans-serif;padding:8px 6px;opacity:0;animation:feFi .4s ease-out .3s forwards;cursor:pointer;}

/* v3.7.7: карточка «Задание»: заголовок со временем и выбором экипажа, сводка по приоритетам и типам, кнопка «Открыть карту» на всю ширину */
:root{--pri-bl:#C62828;--pri-cr:#C2410C;--pri-no:#5F6A78;--ty-ca:#7C3AED;--ty-ro:#5F6A78;}
[data-theme="dark"]{--pri-bl:#FF6B6B;--pri-cr:#FFA94D;--pri-no:#C9CED6;--ty-ca:#9C8AD9;--ty-ro:#C9CED6;}
#crewCard .ct-head2{display:flex;justify-content:space-between;align-items:center;min-height:26px;gap:8px;}
#crewCard .ct-head2 h2{margin:0;display:flex;align-items:baseline;gap:8px;}
#crewCard .ct-time{font:400 11.5px var(--font-mono);font-style:normal;color:var(--ink-soft);}
#crewCard .ct-sel{display:inline-flex;align-items:center;gap:6px;height:26px;padding:0 8px;border-radius:8px;border:1px solid var(--line);background:var(--surface-2,transparent);color:var(--ink);font:500 12px var(--font-text);cursor:pointer;flex:0 1 auto;min-width:0;}
#crewCard .ct-sel span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
#crewCard .ct-sel svg{flex:none;color:var(--ink-soft);}
#crewCard .ct-dot{width:8px;height:8px;border-radius:50%;flex:none;display:inline-block;}
#crewCard .ct-msg{margin-top:12px;font-size:13px;color:var(--ink-soft);min-height:18px;}
#crewCard .ct-p3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px;margin-top:8px;}
#crewCard .ct-pb{height:30px;border-radius:8px;border:1px solid var(--line);background:var(--surface-2,transparent);display:flex;align-items:center;justify-content:center;gap:7px;font:600 14.5px var(--font-mono);color:var(--ink);box-sizing:border-box;}
#crewCard .ct-pb.z{color:var(--ink-soft);}
#crewCard .ct-pb.z svg{opacity:.4;}
#crewCard .ct-t2{display:grid;grid-template-columns:1fr 1fr;margin-top:7px;}
#crewCard .ct-tc{height:20px;display:flex;align-items:center;justify-content:center;gap:7px;font:400 12.5px var(--font-text);color:var(--ink-soft);}
#crewCard .ct-tc + .ct-tc{border-left:1px solid var(--line);}
#crewCard .ct-tc b{font:600 14px var(--font-mono);color:var(--ink);}
#crewCard .ct-tc.z b{color:var(--ink-soft);}
#crewCard .ct-tc.z svg{opacity:.4;}
#crewCard .ct-open{display:flex;width:100%;justify-content:center;align-items:center;gap:8px;height:42px;margin-top:14px;border-radius:8px;font:700 14.5px var(--font-text);box-sizing:border-box;}

.curator-group-row.on{border-color:var(--amber) !important;box-shadow:inset 3px 0 0 var(--amber);}
.curator-group-row.on::after{content:"\2713";float:right;color:var(--amber);font-weight:700;}

/* v3.7.9: карточка «Задание» - кнопка обновить, «обновлено», выпадающий список экипажей, спокойная кнопка карты, подсказка под «Мои тикеты» */
#crewCard{position:relative;}
#crewCard .ct-right{display:flex;align-items:center;justify-content:flex-end;gap:6px;min-width:0;flex:1 1 auto;}
#crewCard .ct-ib{width:26px;height:26px;border-radius:8px;border:1px solid var(--line);background:var(--surface-2,transparent);color:var(--ink-soft);display:flex;align-items:center;justify-content:center;cursor:pointer;flex:none;padding:0;}
#crewCard .ct-ib.spin svg{animation:tmspin 1s linear infinite;}
#crewCard .ct-upd{font:400 12px var(--font-text);color:var(--ink-soft);margin-top:2px;min-height:16px;}
#crewCard .ct-upd:empty{display:none;}
#crewCard #curatorGroupPanel{position:absolute;right:16px;top:48px;width:236px;max-height:60vh;overflow-y:auto;z-index:20;margin:0 !important;padding:4px !important;border:1px solid var(--line) !important;border-radius:10px;background:var(--paper);box-shadow:0 10px 28px rgba(0,0,0,.4);}
#crewCard #curatorGroupPanel > div:first-child{display:none;}
#crewCard #curatorGroupList{margin-bottom:0 !important;gap:2px !important;}
#crewCard #curatorGroupCloseBtn{display:none;}
#crewCard .curator-group-row{display:flex;align-items:center;gap:10px;height:38px;padding:0 10px;border:0 !important;border-radius:7px;background:transparent;font:400 13.5px var(--font-text);color:var(--ink);box-shadow:none;}
#crewCard .curator-group-row.on{background:var(--surface-2);box-shadow:none;}
#crewCard .curator-group-row.on::after{margin-left:auto;float:none;}
#crewCard .cg-dot{width:9px;height:9px;border-radius:50%;flex:none;display:inline-block;}
#crewCard .ct-open{background:var(--surface-2,transparent);border:1px solid var(--line);color:var(--ink);font-weight:600;}
#crewCard .ct-open svg{color:var(--amber);}
.my-empty{font-size:13px;color:var(--ink-soft);padding:4px 0 2px;}

/* v3.7.12: «Задание» проще - строка-сводка и две кнопки одной высоты друг под другом */
#crewCard .ct-msg{margin-top:10px;font:500 13px var(--font-text);color:var(--ink-soft);min-height:18px;}
#crewCard .ct-open{margin-top:12px;}
#crewCard .ct-open.ct-manual{margin-top:8px;background:transparent;border:1px solid var(--line);color:var(--ink);font-weight:600;}
#crewCard .ct-open.ct-manual svg{color:var(--ink-soft);}

/* v3.7.14: на iPhone с «островом» скрытая плашка обновления не уезжала за край экрана и висела над островом - прячем полностью */
.update-banner{opacity:0;visibility:hidden;pointer-events:none;transition:transform .25s,opacity .2s,visibility 0s .25s,background-color .2s,color .2s,border-color .2s;}
.update-banner.show{opacity:1;visibility:visible;pointer-events:auto;transition:transform .25s,opacity .2s,visibility 0s,background-color .2s,color .2s,border-color .2s;}

/* v3.7.17: карточка «Задание» по макету (вариант B): крупнее заголовок и кнопки, сводка по центру,
   «Открыть задание» с янтарной рамкой и подкладкой, «Добавить тикет вручную» - подчёркнутая надпись с плюсом */
#crewCard .ct-head2 h2{font-size:22px;}
#crewCard .ct-head2{min-height:30px;}
#crewCard .ct-ib{width:30px;height:30px;}
#crewCard .ct-sel{height:30px;padding:0 10px;font-size:13.5px;}
#crewCard .ct-msg{margin-top:12px;text-align:center;font:500 13.5px var(--font-text);color:var(--ink-soft);min-height:0;}
#crewCard .ct-open{height:44px;margin-top:12px;border-radius:9px;font:600 15px var(--font-text);color:var(--ink);background:var(--amber-tint);border:1.5px solid var(--amber);}
[data-theme="dark"] #crewCard .ct-open{background:rgba(242,169,0,.2);}
#crewCard .ct-open svg{color:var(--amber-dark);}
#crewCard .ct-open.ct-manual{display:flex;width:auto;height:auto;margin:6px auto 0;padding:8px 6px 2px;background:none;border:0;border-radius:0;color:var(--ink-soft);font:500 14px var(--font-text);}
[data-theme="dark"] #crewCard .ct-open.ct-manual{background:none;}
#crewCard .ct-open.ct-manual svg{display:inline-block;color:var(--ink-soft);}
#crewCard .ct-open.ct-manual span{text-decoration:underline;text-underline-offset:3px;}

/* v3.7.21: выполненный тикет на карте - светлая табличка с зелёной рамкой и галочкой в конце (у ковра и у маршрута одинаково), контур зелёный */
.tm-lbl.st-done:not(.sel),.tm-lbl.flag.st-done:not(.sel){background:#FFFFFF !important;border:1.5px solid #3F8F5F !important;color:#1B2430 !important;box-shadow:none;}
.tm-lbl.st-done:not(.sel) .tm-lbl-num,.tm-lbl.st-done:not(.sel) .tm-lbl-dist,.tm-lbl.st-done:not(.sel) .tm-lbl-carpet,
.tm-lbl.flag.st-done:not(.sel) .tm-lbl-num,.tm-lbl.flag.st-done:not(.sel) .tm-lbl-dist,.tm-lbl.flag.st-done:not(.sel) .tm-lbl-carpet{color:#1B2430 !important;}
.tm-lbl.st-done:not(.sel) .tm-lbl-carpet{color:#5F6A78 !important;}
.tm-lbl.st-done:not(.sel) .tm-lbl-st,.tm-lbl.flag.st-done:not(.sel) .tm-lbl-st{color:#3F8F5F !important;}
.tm-lbl.flag.st-done:not(.sel) .curator-pri-blocker{color:#C62828;}
.tm-lbl.flag.st-done:not(.sel) .curator-pri-crit{color:#C2410C;}
.tm-lbl.flag.st-done:not(.sel) .curator-pri-normal{color:#5F6A78;}

/* v3.7.22: у выполненного тикета кружки Е и А лежат прямо на светлой табличке, без тёмной плашки */
.tm-lbl.st-done:not(.sel) .tm-lbl-chips{background:transparent !important;margin:0 0 0 3px !important;padding:0 !important;border-radius:0 !important;}

/* v3.7.23: тест полос — батарейка заряда, координаты, смены утро/вечер */
.tm-co-bat{display:inline-flex;flex:0 0 auto;line-height:0;}
.tm-co-win{margin-left:auto;margin-top:0;text-align:right;white-space:nowrap;}
.tm-co-mono{font-family:var(--font-mono);font-size:11.5px;color:#B6BCC6;}
.tm-co-sh{margin-top:4px;display:flex;align-items:flex-start;gap:6px;font-size:12px;color:#DFE3E8;line-height:1.35;}
.tm-co-r2 + .tm-co-sh{margin-top:6px;}
.tm-co-sh b{font-weight:500;color:#9AA3AE;flex:0 0 46px;}
.tm-co-shn{display:flex;flex-wrap:wrap;column-gap:10px;row-gap:1px;min-width:0;}
.tm-co-shn em{font-style:normal;color:#7D8894;}
.tm-co-okmark{margin-left:auto;color:#57C084;white-space:nowrap;}
.tm-akb-pin{line-height:0;}
.tm-akb-pin svg{display:block;}
.tm-akb-pin .lb{bottom:38px;font-size:10px;padding:0 5px;}
.tm-akb-pin.sel{transform:translate(-50%,-100%) scale(1.06);transform-origin:50% 100%;}
.geo-akb-co.tm-co{display:none;left:8px;right:8px;top:auto;bottom:72px;width:auto;max-width:none;z-index:40;}

/* v3.7.25: цель месяца - цвета из палитры приложения, подпись вердикта, «Вся статистика», полочки статистики */
:root{--goal-ok:#1F7A4D;--goal-push:#C98A00;}
[data-theme="dark"]{--goal-ok:#57C084;--goal-push:#F2A900;}
.gm-vd.ok{background:rgba(87,192,132,.14);border:1.5px solid #57C084;color:#57C084;}
.gm-vd.push{background:none;border:1.5px solid #F2A900;color:#F2A900;}
.gm-vs{margin-top:6px;font-size:12px;line-height:1.4;color:#C9CED6;}
.gm-all{display:flex;justify-content:space-between;align-items:center;width:100%;height:42px;margin-top:10px;padding:0 14px;box-sizing:border-box;
  border:1.5px solid var(--amber);border-radius:9px;background:rgba(242,169,0,.12);color:var(--amber);font:600 14px var(--font-text);cursor:pointer;}
.gm-all span:last-child{font-size:18px;line-height:1;}
.gs-sec{display:block;font:500 11px var(--font-mono);letter-spacing:.06em;color:var(--ink-soft);margin-bottom:8px;}
.gs-chart-head .gs-sec{margin-bottom:0;}
.gs-cell b.good{color:var(--goal-ok);}
.gs-cell b.acc{color:var(--goal-push);}
#goalShifts{margin-top:2px;}
#goalShifts .empty{font-size:12.5px;color:var(--ink-soft);padding:6px 0;}

/* v3.7.26: тяга для обновления - итог прямо на плашке */
#pullRefreshIndicator.done{color:#57C084;}
#pullRefreshIndicator.done svg{color:#57C084;transform:none;}
#pullRefreshIndicator.fail{color:#E2716D;}
