/* Иллюстрации модулей (из проекта Landings, генераторы app/illu-*-card.mjs) */
.illo{--bg:#F4F6F8;--surface:#FFFFFF;--surface-2:#EDF1F4;--ink:#333333;--muted:#5C6B78;
  --line:#DFE5EA;--accent:#F5852A;--accent-text:#0775A5;--accent-ink:#10151D;
  --ok:#3E8D44;--err:#E5342B;--info:#2E93C9;--idle:#8FA0AC;--pd:0s;
  display:block;border:1px solid var(--line);border-radius:2px;overflow:hidden;background:var(--surface)}
.illo svg{width:100%;height:auto;display:block}
@media (prefers-reduced-motion:reduce){.illo *{animation:none !important}}

/* --- putevoy --- */

  .put .scr-f { fill:var(--bg); stroke:var(--line); }
  .put-title { font:600 11px/1 "IBM Plex Mono",monospace; letter-spacing:0.1em; text-transform:uppercase; fill:var(--muted); }
  .put .src-b { fill:var(--surface); stroke:var(--line); stroke-width:2; }
  .put .src-scr { fill:var(--bg); stroke:var(--line); }
  .put .ecg { fill:none; stroke:var(--ok); stroke-width:2.2; stroke-linecap:round; stroke-linejoin:round; }
  .put .mbtn { transform-box:fill-box; transform-origin:center; }
  .put .mbtn-b { fill:color-mix(in srgb, var(--info) 14%, transparent); stroke:var(--info); stroke-width:1.5; }
  .put .mbtn-t { font:600 11px/1 "Golos Text",sans-serif; fill:var(--info); }
  .put .mbtn-tap { fill:none; stroke:var(--info); stroke-width:2; opacity:0; }
  .put .src-dot { fill:var(--idle); }
  .put .src-l { font:600 10.5px/1 "Golos Text",sans-serif; fill:var(--ink); }
  .put .src-st { font:600 9.5px/1 "IBM Plex Mono",monospace; fill:var(--muted); }
  .put .src-ok { font:700 14px/1 "IBM Plex Mono",monospace; fill:var(--ok); opacity:0; }
  .put .s2 .src-ok { fill:var(--info); }

  .put .chan { fill:none; stroke:var(--line); stroke-width:2; stroke-dasharray:4 5; }
  .put .pk { fill:var(--ok); opacity:0; offset-rotate:0deg;
    filter:drop-shadow(0 0 4px color-mix(in srgb, var(--ok) 75%, transparent)); }
  .put .pk2-c { fill:var(--info); filter:drop-shadow(0 0 4px color-mix(in srgb, var(--info) 75%, transparent)); }

  .put .car-b { fill:var(--surface); stroke:var(--line); stroke-width:2; }
  .put .rig { color:var(--idle); }
  .put .rig path, .put .rig circle { fill:currentColor; }
  .put .rig-sh { fill:var(--ink); opacity:.08; }
  .put .ring { fill:none; stroke:var(--ok); stroke-width:2.5; opacity:0; }
  .put .tag-b { fill:none; stroke-width:1.5; }
  .put .tag-t { font:600 9.5px/1 "Golos Text",sans-serif; }
  .put .tagc .tag-b { stroke:var(--err); fill:color-mix(in srgb, var(--err) 8%, transparent); }
  .put .tagc .tag-t { fill:var(--err); }
  .put .tag1, .put .tag2 { opacity:0; }
  .put .tag1 .tag-b { stroke:var(--ok); fill:color-mix(in srgb, var(--ok) 10%, transparent); }
  .put .tag1 .tag-t { fill:var(--ok); }
  .put .tag2 .tag-b { stroke:var(--info); fill:color-mix(in srgb, var(--info) 10%, transparent); }
  .put .tag2 .tag-t { fill:var(--info); }
  .put .node-t { font:600 12.5px/1 "Golos Text",sans-serif; fill:var(--ink); }
  .put .sep { stroke:var(--line); }
  .put .foot-h { font:600 12.5px/1 "Golos Text",sans-serif; fill:var(--ink); }

  /* Активный источник подсвечивается рамкой; неактивный приглушён */
  .put .src { transition:none; }

  @media (prefers-reduced-motion: no-preference) {
    /* 14 с. Эп.1 (0–48 %) — допуск от телемедицины. Эп.2 (50–98 %) — от медпункта.
       Оба источника независимы: погрузчик открывается тому, кто прошёл осмотр. */
    .put .scr-f { stroke-dasharray:1620; stroke-dashoffset:1620; animation:put-draw 1.1s ease-out forwards; }
    .put .s1 { animation:put-in .55s cubic-bezier(.16,1,.3,1) .25s both; }
    .put .s2 { animation:put-in .55s cubic-bezier(.16,1,.3,1) .4s both; }
    .put .car { animation:put-in .55s cubic-bezier(.16,1,.3,1) .55s both; }

    .put .s1 .src-b { animation:s1-active 14s steps(1) 1.2s infinite; }
    .put .s2 .src-b { animation:s2-active 14s steps(1) 1.2s infinite; }
    .put .ecg { stroke-dasharray:220; stroke-dashoffset:220; animation:draw-ecg 14s ease-in-out 1.2s infinite; }
    .put .mbtn { animation:mbtn-press 14s cubic-bezier(.34,1.56,.64,1) 1.2s infinite; }
    .put .mbtn-b { animation:mbtn-fill 14s ease-out 1.2s infinite; }
    .put .mbtn-tap { animation:mbtn-tap 14s ease-out 1.2s infinite; }
    .put .s1 .src-ok { animation:ok1 14s cubic-bezier(.16,1,.3,1) 1.2s infinite; }
    .put .s1 .src-dot { animation:dot1 14s steps(1) 1.2s infinite; }
    .put .s2 .src-ok { animation:ok2 14s cubic-bezier(.16,1,.3,1) 1.2s infinite; }
    .put .s2 .src-dot { animation:dot2 14s steps(1) 1.2s infinite; }

    .put .ch1 { animation:flow 1.1s linear infinite, chan1 14s steps(1) 1.2s infinite; }
    .put .ch2 { animation:flow 1.1s linear infinite, chan2 14s steps(1) 1.2s infinite; }
    .put .pk1 { animation:pk-run 14s cubic-bezier(.5,0,.5,1) infinite; animation-delay:var(--pd, 0s); }
    .put .pk2 { animation:pk-run 14s cubic-bezier(.5,0,.5,1) infinite; animation-delay:var(--pd, 0s); }

    .put .rig { animation:rig1 14s steps(1) 1.2s infinite; }
    .put .car-b { animation:carb 14s steps(1) 1.2s infinite; }
    .put .tagc { animation:tagc 14s steps(1) 1.2s infinite; }
    .put .tag1 { animation:tag1 14s cubic-bezier(.16,1,.3,1) 1.2s infinite; }
    .put .tag2 { animation:tag2 14s cubic-bezier(.16,1,.3,1) 1.2s infinite; }
    .put .ring { animation:ring-pop 14s ease-out 1.2s infinite; }
    .put .ring.r2 { animation-delay:1.55s; }
    .put .rig-wrap { animation:engine 14s ease-out 1.2s infinite; }
  }
  @keyframes put-draw { to { stroke-dashoffset:0; } }
  @keyframes put-in { from { opacity:0; transform:translateY(10px); } to { opacity:1; transform:none; } }
  @keyframes flow { to { stroke-dashoffset:-18; } }

  /* Осмотры */
  @keyframes draw-ecg { 0%,4% { stroke-dashoffset:220; } 18%,44% { stroke-dashoffset:0; } 47%,100% { stroke-dashoffset:220; } }
  /* Медик нажимает «Допустить»: кнопка проседает, всплеск, галочка */
  @keyframes mbtn-press { 0%,57% { transform:scale(1); } 60% { transform:scale(.9); } 63%,100% { transform:scale(1); } }
  @keyframes mbtn-tap { 0%,58% { r:10px; opacity:0; } 61% { opacity:.6; } 72%,100% { r:34px; opacity:0; } }
  /* Кнопка «загорается» в момент нажатия */
  @keyframes mbtn-fill { 0%,59% { fill:color-mix(in srgb, var(--info) 14%, transparent); } 61%,70% { fill:color-mix(in srgb, var(--info) 40%, transparent); } 74%,100% { fill:color-mix(in srgb, var(--info) 14%, transparent); } }
  @keyframes ok1 { 0%,17% { opacity:0; transform:scale(.9); } 20%,46% { opacity:1; transform:none; } 47%,100% { opacity:0; } }
  @keyframes dot1 { 0%,17% { fill:var(--idle); } 18%,46% { fill:var(--ok); } 47%,100% { fill:var(--idle); } }
  @keyframes ok2 { 0%,60% { opacity:0; transform:scale(.9); } 63%,95% { opacity:1; transform:none; } 96%,100% { opacity:0; } }
  @keyframes dot2 { 0%,60% { fill:var(--idle); } 61%,95% { fill:var(--info); } 96%,100% { fill:var(--idle); } }

  /* Активная рамка источника */
  @keyframes s1-active { 0%,46% { stroke:var(--ok); stroke-width:2.5; } 47%,100% { stroke:var(--line); stroke-width:2; } }
  @keyframes s2-active { 0%,49% { stroke:var(--line); stroke-width:2; } 50%,95% { stroke:var(--info); stroke-width:2.5; } 96%,100% { stroke:var(--line); stroke-width:2; } }

  /* Каналы: активный светится в свой эпизод */
  @keyframes chan1 { 0%,18% { stroke:var(--line); } 20%,44% { stroke:var(--ok); } 45%,100% { stroke:var(--line); } }
  @keyframes chan2 { 0%,61% { stroke:var(--line); } 63%,94% { stroke:var(--info); } 95%,100% { stroke:var(--line); } }

  /* Пакеты бегут по своему каналу только в свой эпизод */
  @keyframes pk-run {
    0% { offset-distance:0%; opacity:0; }
    2% { opacity:1; }
    12% { offset-distance:100%; opacity:1; }
    14%,100% { offset-distance:100%; opacity:0; }
  }

  /* Погрузчик: закрыт → открыт (эп.1 Абилов) → закрыт → открыт (эп.2 Крылов) → закрыт */
  @keyframes rig1 { 0%,25% { color:var(--idle); } 27%,44% { color:var(--ok); } 45%,69% { color:var(--idle); } 71%,94% { color:var(--info); } 95%,100% { color:var(--idle); } }
  @keyframes carb { 0%,25% { stroke:var(--line); } 27%,44% { stroke:var(--ok); } 45%,69% { stroke:var(--line); } 71%,94% { stroke:var(--info); } 95%,100% { stroke:var(--line); } }
  @keyframes tagc { 0%,25% { opacity:1; } 26%,44% { opacity:0; } 45%,69% { opacity:1; } 70%,94% { opacity:0; } 95%,100% { opacity:1; } }
  @keyframes tag1 { 0%,25% { opacity:0; transform:translateY(4px); } 28%,44% { opacity:1; transform:none; } 46%,100% { opacity:0; } }
  @keyframes tag2 { 0%,69% { opacity:0; transform:translateY(4px); } 72%,94% { opacity:1; transform:none; } 96%,100% { opacity:0; } }
  @keyframes ring-pop { 0%,25% { r:46px; opacity:0; stroke:var(--ok); } 28% { opacity:.55; } 40%,69% { r:92px; opacity:0; stroke:var(--ok); } 70% { stroke:var(--info); } 71% { r:46px; opacity:0; } 74% { opacity:.55; } 86%,100% { r:92px; opacity:0; } }
  @keyframes engine {
    0%,25%   { transform:none; }
    27%      { transform:translate(0,-2px); }
    29%      { transform:translate(1px,1px); }
    31%,69%  { transform:none; }
    71%      { transform:translate(0,-2px); }
    73%      { transform:translate(1px,1px); }
    75%,100% { transform:none; }
  }


/* --- vydacha --- */

  .vyd .scr { fill:var(--bg); stroke:var(--line); }
  .vyd .scr-title { font:600 11px/1 "IBM Plex Mono",monospace; letter-spacing:0.1em; text-transform:uppercase; fill:var(--muted); }

  .vyd .bar-t { font:600 9.5px/1 "IBM Plex Mono",monospace; letter-spacing:0.06em; text-transform:uppercase; fill:var(--muted); }
  .vyd .bar-n { font:600 11px/1 "IBM Plex Mono",monospace; fill:var(--ink); }
  .vyd .bar-l { stroke:var(--line); }
  .vyd .bar-d { fill:var(--idle); }
  .vyd .bar.free .bar-d { fill:var(--ok); }
  .vyd .bar.out .bar-d { fill:var(--info); }

  /* Плитки — контурные: цвет несёт обводка, а не заливка */
  .vyd .tile rect { fill:var(--surface); stroke:var(--ok); stroke-width:1.5; }
  .vyd .tile text { font:600 12px/1 "IBM Plex Mono",monospace; fill:var(--ink); }
  .vyd .out-t rect { stroke:var(--info); }
  .vyd .cons-t rect { stroke:var(--idle); }
  .vyd .cons-t text { fill:var(--muted); }
  .vyd .v-sep { stroke:var(--line); }

  /* Погрузчик с замком: закрыт — техника недоступна, открылся — выдана */
  .vyd .rig { color:var(--idle); }
  /* колесо «прорезает» линию корпуса — как в иконке-референсе */
  .vyd .rig path, .vyd .rig circle { fill:currentColor; }
  .vyd .lk { color:var(--idle); }
  .vyd .lk-body { fill:currentColor; }
  .vyd .lk-hole { fill:var(--bg); }
  .vyd .lk-closed, .vyd .lk-open { fill:none; stroke:currentColor; stroke-width:2.4; stroke-linecap:round; }
  .vyd .lk-open { opacity:0; }
  .vyd .n-b { opacity:0; }
  .vyd .landing { fill:none; stroke:var(--info); stroke-width:2; opacity:0; }
  .vyd .lk-ring { fill:none; stroke:currentColor; stroke-width:2; opacity:0; }
  /* Полосы групп — отсылка к цветным заголовкам реального терминала */
  .vyd .bar-band { fill:none; }
  .vyd .bar.free .bar-band { fill:var(--ok); fill-opacity:.08; }
  .vyd .bar.out .bar-band { fill:var(--info); fill-opacity:.08; }
  .vyd .bar.cons .bar-band { fill:var(--idle); fill-opacity:.08; }

  /* Тост «карта принята» — причина, по которой плитка едет в «выдана» */
  .vyd .toast { opacity:0; }
  .vyd .toast-p { fill:var(--surface); stroke:var(--line); }
  .vyd .toast-c { fill:var(--accent); }
  .vyd .toast-t { font:600 10px/1 "IBM Plex Mono",monospace; letter-spacing:0.03em; fill:var(--ink); }
  .vyd .toast-ring { fill:none; stroke:var(--accent); stroke-width:2; opacity:0; }

  /* Бейджи-замки на оставшихся доступных плитках */
  .vyd .lkb { opacity:0; transform-box:fill-box; transform-origin:center; }
  .vyd .lkb-c { fill:var(--surface); stroke:var(--idle); stroke-width:1.5; }
  .vyd .lkb-b { fill:var(--idle); }
  .vyd .lkb-s { fill:none; stroke:var(--idle); stroke-width:1.6; stroke-linecap:round; }

  /* Нулевой экран: считыватель и карта в линейной графике */
  .vyd .pre { opacity:0; }
  .vyd .pre-bg { fill:var(--bg); }
  .vyd .pre-t { font:600 13px/1 "IBM Plex Mono",monospace; letter-spacing:0.12em; text-transform:uppercase; fill:var(--muted); text-anchor:middle; }
  /* Считыватель — серая панель на стене, карта — белый пластик */
  .vyd .pre-rd rect { fill:var(--surface-2); stroke:var(--idle); stroke-width:2.5; }
  .vyd .pre-rd path { fill:none; stroke:var(--idle); stroke-width:2.5; stroke-linecap:round; }
  .vyd .pre-card rect { fill:#FFFFFF; stroke:var(--idle); stroke-width:2; }
  .vyd .pre-card path { fill:none; stroke:var(--idle); stroke-width:2.5; stroke-linecap:round; }
  .vyd .pre-dot { fill:var(--idle); }
  .vyd .pre-ring { fill:none; stroke:var(--ok); stroke-width:2; opacity:0; }

  .vyd .note-h { font:600 12px/1 "Golos Text",sans-serif; fill:var(--ink); }
  .vyd .note-s { font:400 10.5px/1 "Golos Text",sans-serif; fill:var(--muted); }

  @media (prefers-reduced-motion: no-preference) {
    /* Один цикл 12 с: поднесите карту → карта у считывателя → экран групп,
       тост с именем → единица 16 переехала в «выдана» → остальные закрылись. */
    .vyd .scr { stroke-dasharray:1620; stroke-dashoffset:1620; animation:scr-draw 1.1s ease-out forwards; }
    .vyd .bar { animation:bar-in .5s cubic-bezier(.16,1,.3,1) both; }
    .vyd .bar.free { animation-delay:.35s; }
    .vyd .bar.out { animation-delay:.45s; }
    .vyd .bar.cons { animation-delay:.55s; }
    .vyd .pool .tile, .vyd .out-t, .vyd .cons-t { animation:tile-in .45s cubic-bezier(.16,1,.3,1) both; }

    .vyd .pre { animation:vyd-pre 12s ease-in-out 0.7s infinite backwards; }
    .vyd .pre-card { animation:vyd-precard 12s cubic-bezier(.645,.045,.355,1) 0.7s infinite backwards; }
    .vyd .pre-dot { animation:vyd-predot 12s steps(1) 0.7s infinite; }
    .vyd .pre-ring { animation:vyd-prering 12s ease-out 0.7s infinite; }
    .vyd .pre-ring.pr2 { animation-delay:1.45s; }

    .vyd .toast { animation:vyd-toast 12s cubic-bezier(.16,1,.3,1) 0.7s infinite; }
    .vyd .toast-ring { animation:vyd-tring 12s ease-out 0.7s infinite; }
    .vyd .mover { animation:vyd-move 12s cubic-bezier(.5,0,.2,1) 0.7s infinite; }
    .vyd .mover rect { animation:vyd-color 12s cubic-bezier(.5,0,.2,1) 0.7s infinite; }
    .vyd .landing { animation:vyd-land 12s ease-out 0.7s infinite; }
    .vyd .rig { animation:rig-color 12s steps(1) 0.7s infinite; }
    .vyd .lk { animation:rig-color 12s steps(1) 0.7s infinite; }
    .vyd .lk-closed { animation:lk-hide 12s steps(1) 0.7s infinite; }
    .vyd .lk-open { animation:lk-show 12s steps(1) 0.7s infinite; }
    .vyd .lk-ring { animation:lk-ping 12s ease-out 0.7s infinite; }
    .vyd .lk-ring.r2 { animation-delay:1.6s; }
    .vyd .n-a { animation:cnt-a 12s steps(1) 0.7s infinite; }
    .vyd .n-b { animation:cnt-b 12s steps(1) 0.7s infinite; }
    .vyd .pool { animation:vyd-dim 12s ease-in-out 0.7s infinite; }
    .vyd .note text { animation:vyd-note 12s ease-in-out 0.7s infinite; }
    .vyd .lkb { animation:vyd-lock 12s cubic-bezier(.16,1,.3,1) 0.7s infinite; }
  }

  @keyframes scr-draw { to { stroke-dashoffset:0; } }
  @keyframes bar-in { from { opacity:0; transform:translateX(-12px); } to { opacity:1; transform:none; } }
  @keyframes tile-in { from { opacity:0; transform:translateY(10px) scale(.86); } to { opacity:1; transform:none; } }

  /* Фаза 0: заставка, подлёт карты, тап и отклик считывателя */
  @keyframes vyd-pre { 0%,16% { opacity:1; } 19%,94% { opacity:0; } 98%,100% { opacity:1; } }
  @keyframes vyd-precard {
    0%,3%   { transform:translate(102px,48px) rotate(14deg); }
    10%     { transform:none; }
    12%     { transform:translate(-5px,0); }
    14%,100% { transform:translate(-2px,0); }
  }
  @keyframes vyd-predot { 0%,10% { fill:var(--idle); } 11%,18% { fill:var(--ok); } 19%,100% { fill:var(--idle); } }
  @keyframes vyd-prering { 0%,11% { r:12px; opacity:0; } 13% { opacity:.7; } 19%,100% { r:36px; opacity:0; } }

  /* Тост с именем водителя */
  @keyframes vyd-toast {
    0%,18%  { opacity:0; transform:translateY(-8px); }
    22%,55% { opacity:1; transform:none; }
    60%     { opacity:0; transform:none; }
    61%,100% { opacity:0; transform:translateY(-8px); }
  }
  @keyframes vyd-tring { 0%,20% { r:10px; opacity:0; } 24% { opacity:.7; } 34%,100% { r:26px; opacity:0; } }

  /* Подхват, дуга полёта и приземление в свободный слот */
  @keyframes vyd-move {
    0%    { opacity:0; transform:translateY(-10px) scale(.85); }
    6%    { opacity:1; transform:none; }
    22%   { transform:none; }
    26%   { transform:scale(1.14); }
    31%   { transform:translate(38px,26px) rotate(-5deg) scale(1.08); }
    38%   { transform:translate(75px,68px) scale(1); }
    92%   { opacity:1; transform:translate(75px,68px); }
    95%   { opacity:0; transform:translate(75px,68px); }
    100%  { opacity:0; transform:none; }
  }
  @keyframes vyd-color {
    0%,26%   { stroke:var(--ok); }
    38%,100% { stroke:var(--info); }
  }
  @keyframes vyd-land { 0%,36% { opacity:0; stroke-width:2; } 40% { opacity:1; stroke-width:4; } 56%,100% { opacity:0; stroke-width:2; } }

  /* Погрузчик, замок, счётчики, затемнение пула, замочки на плитках */
  @keyframes rig-color { 0%,37% { color:var(--idle); } 38%,94% { color:var(--info); } 95%,100% { color:var(--idle); } }
  @keyframes lk-hide { 0%,37% { opacity:1; } 38%,94% { opacity:0; } 95%,100% { opacity:1; } }
  @keyframes lk-show { 0%,37% { opacity:0; } 38%,94% { opacity:1; } 95%,100% { opacity:0; } }
  @keyframes lk-ping { 0%,38% { r:12px; opacity:0; } 43% { opacity:.7; } 60%,100% { r:34px; opacity:0; } }
  @keyframes cnt-a { 0%,37% { opacity:1; } 38%,94% { opacity:0; } 95%,100% { opacity:1; } }
  @keyframes cnt-b { 0%,37% { opacity:0; } 38%,94% { opacity:1; } 95%,100% { opacity:0; } }
  @keyframes vyd-dim { 0%,46% { opacity:1; } 56%,90% { opacity:.32; } 95%,100% { opacity:1; } }
  @keyframes vyd-note { 0%,48% { opacity:0; } 58%,88% { opacity:1; } 93%,100% { opacity:0; } }
  @keyframes vyd-lock { 0%,54% { opacity:0; transform:scale(.5); } 60%,86% { opacity:1; transform:none; } 91%,100% { opacity:0; transform:none; } }


/* --- to --- */

  .tos .scr-f { fill:var(--bg); stroke:var(--line); }
  .tos .to-title { font:600 11px/1 "IBM Plex Mono",monospace; letter-spacing:0.1em; text-transform:uppercase; fill:var(--muted); }
  .tos .mh-l { font:600 10px/1 "IBM Plex Mono",monospace; letter-spacing:0.12em; fill:var(--muted); }
  .tos .mh { font:600 34px/1 "IBM Plex Mono",monospace; fill:var(--ink); }
  .tos .mh-d { font:400 10.5px/1 "Golos Text",sans-serif; fill:var(--muted); }
  .tos .stat { font:600 13px/1 "Golos Text",sans-serif; }
  .tos .stat.ok { fill:var(--ok); }
  .tos .stat.warn { fill:#B8860B; }
  .tos .stat.bad { fill:var(--err); }
  .tos .ph2, .tos .ph3, .tos .ph4, .tos .ph5 { opacity:0; }

  .tos .al-b { fill:none; stroke:#B8860B; stroke-width:1.5; }
  .tos .al-d { fill:#E0A020; }
  .tos .al-t { font:600 11px/1 "Golos Text",sans-serif; fill:#B8860B; }
  .tos .alert { opacity:0; }
  .tos .dn-b { fill:none; stroke:var(--ok); stroke-width:1.5; }
  .tos .dn-v { fill:none; stroke:var(--ok); stroke-width:2.2; stroke-linecap:round; stroke-linejoin:round; }
  .tos .dn-t { font:600 11px/1 "Golos Text",sans-serif; fill:var(--ok); }
  .tos .done { opacity:0; }

  .tos .z { opacity:.22; }
  .tos .zy, .tos .zr { opacity:.34; }
  .tos .zg { fill:var(--ok); }
  .tos .zy { fill:#E0A020; }
  .tos .zr { fill:var(--err); }
  .tos .zsep { stroke:var(--bg); stroke-width:2; opacity:.85; }
  .tos .fill { fill:var(--ok); }
  .tos .mk { fill:var(--ok); stroke:var(--bg); stroke-width:2.5; }
  .tos .mk-glow { fill:var(--ok); filter:blur(7px); opacity:.5; }
  .tos .mk-ring { fill:none; stroke:#E0A020; stroke-width:2.5; opacity:0; }
  .tos .tick { font:600 10px/1 "IBM Plex Mono",monospace; fill:var(--muted); }

  .tos .sep { stroke:var(--line); }
  .tos .th { font:600 9.5px/1 "IBM Plex Mono",monospace; letter-spacing:0.06em; text-transform:uppercase; fill:var(--muted); }
  .tos .td { font:500 12px/1 "Golos Text",sans-serif; fill:var(--ink); }
  .tos .td.n { font-family:"IBM Plex Mono",monospace; font-weight:600; }
  .tos .dot.ok { fill:var(--ok); }
  .tos .dot.warn { fill:#E0A020; }
  .tos .dot.bad { fill:var(--err); }
  .tos .foot-s { font:400 11px/1 "Golos Text",sans-serif; fill:var(--muted); }
  .tos .foot-s.b { font-weight:600; fill:var(--ink); }

  @media (prefers-reduced-motion: no-preference) {
    /* 10 с: на 32.57% маркер входит в жёлтую зону — там и уходит напоминание */
    .tos .scr-f { stroke-dasharray:1620; stroke-dashoffset:1620; animation:to-draw 1.1s ease-out forwards; }
    .tos .main { animation:to-in .55s cubic-bezier(.16,1,.3,1) .3s both; }
    .tos .trow { animation:to-in .5s cubic-bezier(.16,1,.3,1) both; }
    .tos .ph1 { animation:to-ph1 10s cubic-bezier(.16,1,.3,1) 1.2s infinite; }
    .tos .ph2 { animation:to-ph2 10s cubic-bezier(.16,1,.3,1) 1.2s infinite; }
    .tos .ph3 { animation:to-ph3 10s cubic-bezier(.16,1,.3,1) 1.2s infinite; }
    .tos .ph4 { animation:to-ph4 10s cubic-bezier(.16,1,.3,1) 1.2s infinite; }
    .tos .ph5 { animation:to-ph5 10s cubic-bezier(.16,1,.3,1) 1.2s infinite; }
    .tos .fill-clip { animation:to-fill 10s linear 1.2s infinite; }
    .tos .fill { animation:to-fill 10s linear 1.2s infinite, to-tone 10s steps(1) 1.2s infinite; }
    .tos .sh { animation:to-sh 2.6s linear 1.4s infinite; }
    .tos .mk-glow { animation:to-mark 10s linear 1.2s infinite, to-tone 10s steps(1) 1.2s infinite; }
    .tos .mk { animation:to-mark 10s linear 1.2s infinite, to-tone 10s steps(1) 1.2s infinite, to-hit 10s cubic-bezier(.16,1,.3,1) 1.2s infinite; }
    .tos .mk-ring { animation:to-ring 10s ease-out 1.2s infinite; }
    .tos .mk-ring.r2 { animation:to-ring2 10s ease-out 1.2s infinite; }
    .tos .alert { animation:to-alert 10s cubic-bezier(.16,1,.3,1) 1.2s infinite; }
    .tos .done { animation:to-done 10s cubic-bezier(.16,1,.3,1) 1.2s infinite; }
    .tos .al-d { animation:to-pulse 1.4s ease-in-out infinite; }
    .tos .dot.bad { animation:to-pulse 1.8s ease-in-out infinite; }
    .tos .zy { animation:to-zone 10s ease-out 1.2s infinite; }
    .tos .od { animation:to-od 10s cubic-bezier(.42,0,.18,1) 1.2s infinite; }
  }
  @keyframes to-draw { to { stroke-dashoffset:0; } }
  @keyframes to-in { from { opacity:0; transform:translateY(8px); } to { opacity:1; transform:none; } }
  @keyframes to-ph1 { 0%,8.31% { opacity:1; transform:none; } 11.31%,69% { opacity:0; transform:translateY(-13px); } 70% { opacity:0; transform:translateY(13px); } 73%,100% { opacity:1; transform:none; } }
  @keyframes to-ph2 { 0%,8.31% { opacity:0; transform:translateY(13px); } 11.31%,19.69% { opacity:1; transform:none; } 22.69%,100% { opacity:0; transform:translateY(-13px); } }
  @keyframes to-ph3 { 0%,19.69% { opacity:0; transform:translateY(13px); } 22.69%,31% { opacity:1; transform:none; } 34%,100% { opacity:0; transform:translateY(-13px); } }
  @keyframes to-ph4 { 0%,31.00% { opacity:0; transform:translateY(13px); } 34%,53% { opacity:1; transform:none; } 56%,100% { opacity:0; transform:translateY(-13px); } }
  @keyframes to-ph5 { 0%,53.00% { opacity:0; transform:translateY(13px); } 56%,70% { opacity:1; transform:none; } 73%,100% { opacity:0; transform:translateY(-13px); } }
  @keyframes to-fill { 0% { width:133.6px; } 34%,48% { width:342.8px; } 56%,72% { width:351.6px; } 82%,100% { width:133.6px; } }
  @keyframes to-mark { 0% { cx:177.6px; } 34%,48% { cx:386.8px; } 56%,72% { cx:395.6px; } 82%,100% { cx:177.6px; } }
  @keyframes to-tone { 0%,32.56% { fill:var(--ok); } 32.57%,71.9% { fill:#E0A020; } 72%,100% { fill:var(--ok); } }
  @keyframes to-od {
    0%,8.31% { transform:none; }
    11.31%,19.69% { transform:translateY(-32px); }
    22.69%,31.00% { transform:translateY(-64px); }
    34%,53.00% { transform:translateY(-96px); }
    56%,79% { transform:translateY(-128px); }
    82%,100% { transform:translateY(-160px); }
  }
  @keyframes to-sh { 0% { transform:translateX(0); } 100% { transform:translateX(520px); } }
  @keyframes to-hit { 0%,32.57% { r:5px; } 35.57% { r:9px; } 41.57%,100% { r:5px; } }
  @keyframes to-ring { 0%,32.57% { r:10px; opacity:0; } 36.07% { opacity:.7; } 51.57%,100% { r:32px; opacity:0; } }
  @keyframes to-ring2 { 0%,35.07% { r:10px; opacity:0; } 39.07% { opacity:.45; } 56.57%,100% { r:28px; opacity:0; } }
  @keyframes to-alert { 0%,32.57% { opacity:0; transform:translateX(10px); } 37.07%,52% { opacity:1; transform:none; } 55%,100% { opacity:0; transform:none; } }
  @keyframes to-done { 0%,54% { opacity:0; transform:translateX(10px); } 58%,88% { opacity:1; transform:none; } 92%,100% { opacity:0; transform:none; } }
  @keyframes to-zone { 0%,32.56% { opacity:.34; } 32.57% { opacity:1; } 44.57%,71.9% { opacity:.55; } 72%,100% { opacity:.34; } }
  @keyframes to-pulse { 0%,100% { opacity:1; } 50% { opacity:.3; } }


/* --- speed --- */

  .spd .scr-f { fill:var(--bg); stroke:var(--line); }
  .spd-title { font:600 11px/1 "IBM Plex Mono",monospace; letter-spacing:0.1em; text-transform:uppercase; fill:var(--muted); }
  .spd .sp-l { font:600 10px/1 "IBM Plex Mono",monospace; letter-spacing:0.12em; fill:var(--muted); }
  .spd .sp { font:600 26px/1 "IBM Plex Mono",monospace; fill:var(--ink); }
  .spd .sp-s { font:400 10.5px/1 "Golos Text",sans-serif; fill:var(--muted); }
  .spd .sp-s.b { font-weight:600; fill:var(--ink); }
  .spd .foot-s { font:400 11px/1 "Golos Text",sans-serif; fill:var(--muted); }
  .spd .n2, .spd .n3, .spd .n4 { opacity:0; }

  .spd .zn { fill:none; stroke-width:12; stroke-linecap:butt; }
  .spd .zn-lo { stroke:var(--ok); opacity:.3; }
  .spd .zn-hi { stroke:var(--idle); opacity:.26; }
  .spd .tk { stroke:var(--muted); stroke-width:2; opacity:.5; }
  .spd .tk-t { font:600 9px/1 "IBM Plex Mono",monospace; fill:var(--muted); }
  .spd .lim { stroke:var(--err); stroke-width:2.5; }
  .spd .lim-t { font:600 9.5px/1 "IBM Plex Mono",monospace; fill:var(--err); opacity:.85; }
  .spd .ndl { transform:rotate(-210deg); }
  .spd .ndl-l { stroke:var(--ink); stroke-width:4; stroke-linecap:round; }
  .spd .ndl-c { fill:var(--ink); }
  .spd .ping { fill:none; stroke:#E0A020; stroke-width:2.5; opacity:0; }

  .spd .wn-b { fill:none; stroke:#B8860B; stroke-width:1.5; }
  .spd .wn-d { fill:#E0A020; }
  .spd .wn-t { font:600 11px/1 "Golos Text",sans-serif; fill:#B8860B; }
  .spd .rc-b { fill:none; stroke:var(--err); stroke-width:1.5; }
  .spd .rc-d { fill:var(--err); }
  .spd .rc-t { font:600 11px/1 "Golos Text",sans-serif; fill:var(--err); }
  .spd .cm-b { fill:none; stroke:var(--ok); stroke-width:1.5; }
  .spd .cm-v { fill:none; stroke:var(--ok); stroke-width:2.2; stroke-linecap:round; stroke-linejoin:round; }
  .spd .cm-t { font:600 11px/1 "Golos Text",sans-serif; fill:var(--ok); }
  .spd .warn, .spd .rec, .spd .calm { opacity:0; }

  .spd .sep { stroke:var(--line); }
  .spd .lh { font:600 9.5px/1 "IBM Plex Mono",monospace; letter-spacing:0.06em; text-transform:uppercase; fill:var(--muted); }
  .spd .ld { font:500 12px/1 "Golos Text",sans-serif; fill:var(--ink); }
  .spd .ld.n { font-family:"IBM Plex Mono",monospace; font-weight:600; }
  .spd .c-b { opacity:0; }
  .spd .ldot.ok { fill:var(--ok); }
  .spd .ldot.warn { fill:#E0A020; }
  .spd .ldot.bad { fill:var(--err); }

  @media (prefers-reduced-motion: no-preference) {
    /* 12 с, старт со стрелки на 0.
       Эпизод 1: вышел за порог → сигнал → водитель сбросил → записи нет.
       Эпизод 2: вышел за порог → сигнал → проигнорировал → запись в журнал. */
    .spd .scr-f { stroke-dasharray:1620; stroke-dashoffset:1620; animation:spd-draw 1.1s ease-out forwards; }
    .spd .main { animation:spd-in .55s cubic-bezier(.16,1,.3,1) .3s both; }
    .spd .lrow { animation:spd-in .5s cubic-bezier(.16,1,.3,1) both; }
    .spd .ndl { animation:spd-ndl 12s cubic-bezier(.4,0,.3,1) 1.2s infinite; }
    .spd .zn-hi { animation:spd-zone 12s steps(1) 1.2s infinite; }
    .spd .n1 { animation:spd-n1 12s steps(1) 1.2s infinite; }
    .spd .n2 { animation:spd-n2 12s steps(1) 1.2s infinite, spd-num2 12s steps(1) 1.2s infinite; }
    .spd .n3 { animation:spd-n3 12s steps(1) 1.2s infinite, spd-num3 12s steps(1) 1.2s infinite; }
    .spd .n4 { animation:spd-n4 12s steps(1) 1.2s infinite; }
    .spd .warn { animation:spd-warn 12s cubic-bezier(.16,1,.3,1) 1.2s infinite; }
    .spd .rec { animation:spd-rec 12s cubic-bezier(.16,1,.3,1) 1.2s infinite; }
    .spd .calm { animation:spd-calm 12s cubic-bezier(.16,1,.3,1) 1.2s infinite; }
    .spd .wn-d, .spd .rc-d { animation:spd-pulse .9s ease-in-out infinite; }
    .spd .ping { animation:spd-ping 12s ease-out 1.2s infinite; }
    .spd .ping.p2 { animation:spd-ping2 12s ease-out 1.2s infinite; }
    .spd .c-a { animation:spd-cnt-a 12s steps(1) 1.2s infinite; }
    .spd .c-b { animation:spd-cnt-b 12s steps(1) 1.2s infinite; }
    .spd .ldot.bad { animation:spd-pulse 1.8s ease-in-out infinite; }
  }
  @keyframes spd-draw { to { stroke-dashoffset:0; } }
  @keyframes spd-in { from { opacity:0; transform:translateY(8px); } to { opacity:1; transform:none; } }
  /* Стрелка: 0 → 5.8 (сброс до 0) → 0 → 7.0 (держит, запись) → 0 */
  @keyframes spd-ndl {
    0%,6%    { transform:rotate(-210deg); }
    13%,26%  { transform:rotate(-36deg); }
    33%,52%  { transform:rotate(-75deg); }
    62%,84%  { transform:rotate(0deg); }
    92%,100% { transform:rotate(-210deg); }
  }
  /* Опасная зона: жёлтая на сигнале (эп.1), жёлтая→красная на записи (эп.2) */
  @keyframes spd-zone {
    0%,12%   { stroke:var(--idle); opacity:.26; }
    13%,26%  { stroke:#E0A020; opacity:.5; }
    27%,61%  { stroke:var(--idle); opacity:.26; }
    62%,69%  { stroke:#E0A020; opacity:.5; }
    70%,88%  { stroke:var(--err); opacity:.5; }
    89%,100% { stroke:var(--idle); opacity:.26; }
  }
  /* Видимость цифр: 0,0 в покое · 5,8 в эп.1 · 7,0 в эп.2 */
  @keyframes spd-n1 { 0%,12% { opacity:1; } 13%,91% { opacity:0; } 92%,100% { opacity:1; } }
  @keyframes spd-n2 { 0%,12% { opacity:0; } 13%,32% { opacity:1; } 33%,100% { opacity:0; } }
  @keyframes spd-n4 { 0%,32% { opacity:0; } 33%,55% { opacity:1; } 56%,100% { opacity:0; } }
  @keyframes spd-n3 { 0%,55% { opacity:0; } 56%,91% { opacity:1; } 92%,100% { opacity:0; } }
  /* Тон 5,8 — жёлтый пока сигнал */
  @keyframes spd-num2 { 0%,12% { fill:var(--ink); } 13%,26% { fill:#B8860B; } 27%,100% { fill:var(--ink); } }
  /* Тон 7,0 — жёлтый на сигнале, красный на записи */
  @keyframes spd-num3 { 0%,61% { fill:var(--ink); } 62%,69% { fill:#B8860B; } 70%,88% { fill:var(--err); } 89%,100% { fill:var(--ink); } }
  /* Предупреждение — в обоих эпизодах сначала сигнал */
  @keyframes spd-warn { 0%,12% { opacity:0; transform:translateX(8px); } 15%,25% { opacity:1; transform:none; } 27%,61% { opacity:0; transform:none; } 63%,69% { opacity:1; transform:none; } 71%,100% { opacity:0; transform:none; } }
  /* Сброс — только эп.1 */
  @keyframes spd-calm { 0%,28% { opacity:0; transform:translateX(8px); } 31%,48% { opacity:1; transform:none; } 50%,100% { opacity:0; transform:none; } }
  /* Запись — только эп.2, после проигнорированного сигнала */
  @keyframes spd-rec { 0%,69% { opacity:0; transform:translateX(8px); } 72%,88% { opacity:1; transform:none; } 90%,100% { opacity:0; transform:none; } }
  @keyframes spd-ping { 0%,12% { r:6px; opacity:0; } 14% { opacity:.65; } 24%,61% { r:24px; opacity:0; } 62% { r:6px; opacity:0; } 64% { opacity:.65; } 74%,100% { r:24px; opacity:0; } }
  @keyframes spd-ping2 { 0%,14.5% { r:6px; opacity:0; } 17% { opacity:.4; } 27%,63.5% { r:20px; opacity:0; } 64.5% { r:6px; opacity:0; } 66.5% { opacity:.4; } 76%,100% { r:20px; opacity:0; } }
  /* Счётчик Кузнецова растёт только когда случай записан (эп.2) */
  @keyframes spd-cnt-a { 0%,71.9% { opacity:1; } 72%,100% { opacity:0; } }
  @keyframes spd-cnt-b { 0%,71.9% { opacity:0; } 72%,100% { opacity:1; } }
  @keyframes spd-pulse { 0%,100% { opacity:1; } 50% { opacity:.3; } }


/* --- akb --- */

  .akb-title { font:600 12px/1 "IBM Plex Mono",monospace; letter-spacing:0.12em; text-transform:uppercase; fill:var(--muted); }
  .akb-hud rect { fill:var(--surface-2); stroke:var(--line); }
  .akb-hud-t { font:600 11px/1 "IBM Plex Mono",monospace; fill:var(--ink); }
  .akb-live { fill:var(--ok); }
  .akb .h2 { opacity:0; }

  .akb .bc-box { fill:var(--bg); stroke:var(--line); }
  .akb .bc-strip { fill:var(--idle); }
  .akb .bc-id { font:600 9px/1 "IBM Plex Mono",monospace; fill:#fff; }
  .akb .bc-status { font:600 12.5px/1 "Golos Text",sans-serif; fill:var(--ink); }
  .akb .bc-sub { font:400 10.5px/1 "Golos Text",sans-serif; fill:var(--muted); }
  .akb .bc-pct { font:600 15px/1 "IBM Plex Mono",monospace; fill:var(--ink); }
  .akb .ok .bc-strip { fill:var(--ok); }
  .akb .charge .bc-strip { fill:var(--info); }
  .akb .low .bc-strip { fill:var(--err); }
  .akb .low .bc-status, .akb .low .bc-pct { fill:var(--err); }
  .akb .pick .bc-box { stroke:var(--ok); stroke-width:2; fill:color-mix(in srgb, var(--ok) 8%, var(--bg)); }
  .akb .pick .bc-strip { fill:var(--ok); }
  .akb .pick .bc-status, .akb .pick .bc-pct { fill:var(--ok); }
  .akb .pick .bc-sub { fill:var(--ok); font-weight:600; }

  .akb .link { fill:none; stroke-width:1.6; stroke-dasharray:4 4; opacity:.8; }
  .akb .link-tip { fill:none; stroke-width:1.6; stroke-linecap:round; stroke-linejoin:round; }

  .akb .bat-tray { fill:none; stroke:var(--idle); stroke-width:3; }
  .akb .bat-body { fill:var(--surface-2); stroke:var(--line); }
  .akb .bat-caps circle { fill:var(--line); }
  .akb .bat-caps .bat-term { fill:var(--surface); stroke:var(--muted); stroke-width:2; }
  .akb .bat-sign { fill:none; stroke:var(--muted); stroke-width:2.4; stroke-linecap:round; }
  .akb .bat-jump path { fill:none; stroke:var(--muted); stroke-width:3; stroke-linecap:round; opacity:.45; }
  /* Двойная индикация как на реальном устройстве: корпус светится ярким белым,
     снизу зелёная полоса статуса. */
  .akb .bat-glow-c { filter:blur(13px); opacity:.4; }
  .akb .bat-glow-w { fill:#FFFFFF; filter:blur(8px); opacity:.95; }
  .akb .bat-dev { fill:#FFFFFF; stroke-width:2; }
  .akb .bat-led { filter:drop-shadow(0 0 8px currentColor); }
  .akb .halo-r { fill:none; stroke-width:2; opacity:0; }
  .akb .bat-cap1 { font:600 13px/1 "Golos Text",sans-serif; }
  .akb .bat-cap2 { font:400 11px/1 "Golos Text",sans-serif; fill:var(--muted); }

  .akb .pick .bat-glow-c { fill:var(--ok); }
  .akb .pick .bat-dev { stroke:var(--ok); }
  .akb .pick .bat-led { fill:var(--ok); color:var(--ok); }
  .akb .pick .halo-r { stroke:var(--ok); }
  .akb .pick .bat-cap1 { fill:var(--ok); }
  .akb .low .bat-glow-c { fill:var(--err); }
  .akb .low .bat-glow-w { opacity:0; }
  .akb .low .bat-dev { stroke:var(--err); }
  .akb .low .bat-led { fill:var(--err); color:var(--err); }
  .akb .low .halo-r { stroke:var(--err); }
  .akb .low .bat-cap1 { fill:var(--err); }
  .akb .ok-link { stroke:var(--ok); }
  .akb .low-link { stroke:var(--err); }


  @media (prefers-reduced-motion: no-preference) {
    .akb .bc { animation:akb-in .5s cubic-bezier(.16,1,.3,1) both; }
    .akb .bc:nth-of-type(2) { animation-delay:.05s; }
    .akb .bc:nth-of-type(3) { animation-delay:.1s; }
    .akb .bc:nth-of-type(4) { animation-delay:.15s; }
    .akb .bat { animation:akb-in .6s cubic-bezier(.16,1,.3,1) .35s both; }
    .akb .low .bat { animation-delay:.5s; }
    .akb .link, .akb .link-tip { animation:link-draw 3.4s ease-in-out infinite; }
    .akb .pick .bat-led, .akb .pick .bat-glow-w { animation:led-glow 2.8s ease-in-out infinite; }
    .akb .pick .bat-glow-c { animation:led-glow-c 2.8s ease-in-out infinite; }
    /* Мигает лампочка и подсветка вокруг — сам корпус устройства остаётся на месте */
    .akb .low .bat-led, .akb .low .bat-glow-c { animation:led-blink 1.4s steps(1) infinite; }
    .akb .pick .halo-r { animation:led-halo 2.8s ease-out infinite; }
    .akb .halo-r.r2 { animation-delay:.9s; }
    .akb .pick .bc-box { animation:pick-breathe 2.8s ease-in-out infinite; }
    .akb-live { animation:akb-blink 2.2s ease-in-out infinite; }
    .akb .h1 { animation:akb-cnt 6s steps(1) infinite; }
    .akb .h2 { animation:akb-cnt 6s steps(1) -3s infinite; }
  }
  @keyframes akb-in { from { opacity:0; transform:translateY(8px); } to { opacity:1; transform:none; } }
  @keyframes link-draw { 0%,100% { opacity:.25; } 45% { opacity:.9; } }
  @keyframes led-glow { 0%,100% { opacity:.72; } 50% { opacity:1; } }
  @keyframes led-glow-c { 0%,100% { opacity:.28; } 50% { opacity:.55; } }
  @keyframes led-blink { 0%,52% { opacity:1; } 53%,100% { opacity:.1; } }
  @keyframes led-halo { 0%,15% { r:26px; opacity:0; } 28% { opacity:.55; } 65%,100% { r:64px; opacity:0; } }
  @keyframes pick-breathe { 0%,100% { stroke-opacity:.55; } 50% { stroke-opacity:1; } }
  @keyframes akb-blink { 0%,100% { opacity:1; } 50% { opacity:.25; } }
  @keyframes akb-cnt { 0%,49% { opacity:1; } 50%,100% { opacity:0; } }


  .ops .wall { fill:none; stroke:var(--muted); stroke-width:1.6; }
  .ops .rack rect { fill:none; stroke:var(--line); stroke-width:1; }
  .ops .rack path { stroke:var(--line); stroke-width:0.8; fill:none; }
  .ops .dock rect { fill:var(--surface-2); stroke:var(--line); }
  .ops .lane { fill:color-mix(in srgb, var(--accent) 5%, transparent); }
  .ops .pin path, .ops .pin circle { fill:var(--ok); }
  .ops .pin text { font:600 10px/1 "IBM Plex Mono",monospace; fill:#fff; }
  .ops .pin.charge path, .ops .pin.charge circle { fill:var(--info); }
  .ops .pin.idle path, .ops .pin.idle circle { fill:var(--idle); }
  .ops .pin.live path, .ops .pin.live circle { fill:var(--ok); filter:drop-shadow(0 0 5px color-mix(in srgb, var(--ok) 70%, transparent)); }
  .ops .pin.find path, .ops .pin.find circle { fill:var(--accent); filter:drop-shadow(0 0 8px color-mix(in srgb, var(--accent) 75%, transparent)); }
  .ops .pin.find text { fill:var(--accent-ink); }
  .ops .ghost .pin path { display:none; }
  .ops .beacon rect { fill:var(--accent); }
  .ops .ripple { fill:none; stroke:var(--accent); stroke-width:1.5; opacity:0; }
  .ops .brk { fill:none; stroke:var(--accent); stroke-width:2; stroke-linecap:round; }
  .ops .lock-tag rect { fill:var(--ink); }
  .ops .lock-tag text { font:600 11px/1 "Golos Text",sans-serif; fill:var(--bg); }
  .ops .hud rect { fill:var(--surface-2); stroke:var(--line); }
  .ops .hud-t { font:600 11px/1 "IBM Plex Mono",monospace; fill:var(--ink); }
  .ops .live-dot { fill:var(--ok); }
  .ops .c2, .ops .c3 { opacity:0; }

  @media (prefers-reduced-motion: no-preference) {
    .ops .draw .wall { stroke-dasharray:1800; stroke-dashoffset:1800; animation:draw 1.5s ease-out forwards; }
    .ops .draw .rack, .ops .draw .dock { opacity:0; animation:map-fade .8s ease-out .5s forwards; }
    .ops .appear { animation:pin-in .5s cubic-bezier(.16,1,.3,1) both; }
    .ops .ripple { animation:ripple 4.4s ease-out infinite; }
    .ops .mover.m1 { animation:drive-1 26s linear infinite; }
    .ops .mover.m2 { animation:drive-2 32s linear infinite; }
    .ops .field { animation:field-dim 9s ease-out 1.6s infinite; }
    .ops .lock { opacity:0; animation:lock-in 9s ease-out 1.6s infinite; }
    .ops .target { animation:target-pulse 9s ease-out 1.6s infinite; }
    .ops .live-dot { animation:blink 2.2s ease-in-out infinite; }
    .ops .c1 { animation:cnt 9s steps(1) infinite; }
    .ops .c2 { animation:cnt 9s steps(1) -3s infinite; }
    .ops .c3 { animation:cnt 9s steps(1) -6s infinite; }
  }
  @keyframes draw { to { stroke-dashoffset:0; } }
  @keyframes map-fade { to { opacity:1; } }
  @keyframes pin-in { from { opacity:0; transform:translateY(-7px) scale(.8); } to { opacity:1; transform:none; } }
  @keyframes ripple { 0% { r:5px; opacity:.55; } 55%,100% { r:34px; opacity:0; } }
  @keyframes blink { 0%,100% { opacity:1; } 50% { opacity:.25; } }
  @keyframes cnt { 0%,33% { opacity:1; } 34%,100% { opacity:0; } }
  @keyframes lock-in {
    0%,42% { opacity:0; transform:translate(197px,206px) scale(1.5); }
    52%,84% { opacity:1; transform:translate(197px,206px) scale(1); }
    100% { opacity:0; transform:translate(197px,206px) scale(1); }
  }
  @keyframes field-dim { 0%,44% { opacity:1; } 56%,84% { opacity:.3; } 100% { opacity:1; } }
  @keyframes target-pulse { 0%,44% { opacity:.35; } 54%,86% { opacity:1; } 100% { opacity:.35; } }
  /* Маршруты только по пустому пространству: вертикали — проходы,
     поперёк — проезды у приёмки (y 54) и у отгрузки (y 316). */
  @keyframes drive-1 {
    0%   { transform:translate(111px,316px); }
    17%  { transform:translate(111px,54px); }
    22%  { transform:translate(197px,54px); }
    39%  { transform:translate(197px,316px); }
    45%  { transform:translate(283px,316px); }
    61%  { transform:translate(283px,54px); }
    67%  { transform:translate(369px,54px); }
    84%  { transform:translate(369px,316px); }
    100% { transform:translate(111px,316px); }
  }
  @keyframes drive-2 {
    0%   { transform:translate(283px,316px); }
    38%  { transform:translate(283px,54px); }
    50%  { transform:translate(369px,54px); }
    88%  { transform:translate(369px,316px); }
    100% { transform:translate(283px,316px); }
  }

/* --- собственные схемы: доступ / происшествия / статистика --- */

  .acc { --device:#26384C; }
  .acc .scr { fill:var(--bg); stroke:var(--line); }
  .acc .scr-title { font:600 11px/1 "IBM Plex Mono",monospace; letter-spacing:0.1em; text-transform:uppercase; fill:var(--muted); }
  .acc .card { transform-box:fill-box; transform-origin:center; }
  .acc .card-p { fill:var(--surface); stroke:var(--line); stroke-width:1.5; filter:drop-shadow(0 1px 2px rgba(16,21,29,.10)); }
  .acc .chip { fill:var(--accent); }
  .acc .chip-g { fill:var(--idle); }
  .acc .wave { fill:none; stroke:var(--idle); stroke-width:1.6; stroke-linecap:round; }
  .acc .card-t { font:600 12px/1 "IBM Plex Mono",monospace; fill:var(--ink); }
  .acc .card-s { font:500 9px/1 "IBM Plex Mono",monospace; letter-spacing:0.02em; fill:var(--muted); }
  .acc .log-p { fill:var(--surface); stroke:var(--line); }
  .acc .log-h { font:600 8.5px/1 "IBM Plex Mono",monospace; letter-spacing:0.08em; text-transform:uppercase; fill:var(--muted); }
  .acc .log-div { stroke:var(--line); }
  .acc .log-r { font:500 9px/1 "IBM Plex Mono",monospace; fill:var(--muted); }
  .acc .log-d.ok-d { fill:var(--ok); }
  .acc .log-d.err-d { fill:var(--err); }
  .acc .rd-plate { fill:var(--surface-2); stroke:var(--line); }
  .acc .rd-p { fill:var(--device); filter:drop-shadow(0 2px 3px rgba(16,21,29,.22)); }
  .acc .rd-slot { fill:rgba(255,255,255,.28); }
  .acc .rd-wave { fill:none; stroke:rgba(255,255,255,.35); stroke-width:1.5; stroke-linecap:round; }
  .acc .rd-led { fill:var(--idle); }
  .acc .rd-ring { fill:none; stroke:var(--ok); stroke-width:2; opacity:0; }
  .acc .floor { stroke:var(--line); stroke-width:1.5; }
  .acc .rig-sh { fill:var(--ink); opacity:.08; }
  .acc .rig { color:var(--idle); transform:translate(318px,96px) scale(.5); }
  .acc .rig path, .acc .rig circle { fill:currentColor; }
  .acc .verdict { opacity:0; }
  .acc .vd-p { fill:var(--surface); stroke:var(--ok); stroke-width:1.5; }
  .acc .vd-p.err-b { stroke:var(--err); }
  .acc .vd-d { fill:var(--ok); }
  .acc .vd-d.err-d { fill:var(--err); }
  .acc .vd-t { font:600 10px/1 "IBM Plex Mono",monospace; letter-spacing:0.03em; fill:var(--ink); }
  .acc .foot { font:500 9.5px/1 "IBM Plex Mono",monospace; letter-spacing:0.08em; text-transform:uppercase; fill:var(--muted); }
  .acc .c1 { animation:accC1 14s cubic-bezier(.5,0,.2,1) infinite; }
  .acc .c2 { animation:accC2 14s cubic-bezier(.5,0,.2,1) infinite; }
  .acc .c1 .card-p { animation:accCardA 14s linear infinite; }
  .acc .c2 .card-p { animation:accCardB 14s linear infinite; }
  .acc .rd-led { animation:accLed 14s linear infinite; }
  .acc .rd-ring { animation:accRing 14s linear infinite; }
  .acc .rig { animation:accRig 14s ease-in-out infinite; }
  .acc .rig-sh { animation:accSh 14s ease-in-out infinite; }
  .acc .v-ok { animation:accVok 14s linear infinite; }
  .acc .v-err { animation:accVerr 14s linear infinite; }
  .acc .log-d.r3 { animation:accRow3 14s linear infinite; }
  /* вся плашка летит к считывателю и «прикладывается»; вторая в это время притухает */
  @keyframes accC1 {
    0%,4%    { transform:none; opacity:1; }
    9%       { transform:translate(36px,9px) rotate(-2.5deg); opacity:1; }
    11%      { transform:translate(36px,9px); }
    12%      { transform:translate(40px,9px); }
    13.5%,38% { transform:translate(36px,9px); opacity:1; }
    44%      { transform:none; opacity:1; }
    52%      { transform:none; opacity:1; }
    56%,88%  { transform:none; opacity:.15; }
    94%,100% { transform:none; opacity:1; }
  }
  @keyframes accC2 {
    0%,4%    { transform:none; opacity:1; }
    8%,40%   { transform:none; opacity:.15; }
    46%      { transform:none; opacity:1; }
    52%      { transform:none; opacity:1; }
    57%      { transform:translate(36px,-51px) rotate(2.5deg); opacity:1; }
    59%      { transform:translate(36px,-51px); }
    60%      { transform:translate(40px,-51px); }
    61%,86%  { transform:translate(36px,-51px); opacity:1; }
    92%,100% { transform:none; opacity:1; }
  }
  @keyframes accCardA { 0%,10% { stroke:var(--line); } 12%,40% { stroke:var(--ok); } 48%,100% { stroke:var(--line); } }
  @keyframes accCardB { 0%,58% { stroke:var(--line); } 60%,88% { stroke:var(--err); } 96%,100% { stroke:var(--line); } }
  @keyframes accLed { 0%,12% { fill:var(--idle); } 14%,40% { fill:var(--ok); } 46%,60% { fill:var(--idle); } 62%,88% { fill:var(--err); } 92%,100% { fill:var(--idle); } }
  @keyframes accRing { 0%,12% { opacity:0; stroke:var(--ok); } 14% { opacity:.9; } 22%,60% { opacity:0; stroke:var(--ok); } 61% { stroke:var(--err); } 62% { opacity:.9; stroke:var(--err); } 70%,100% { opacity:0; } }
  @keyframes accRig { 0%,13% { color:var(--idle); transform:translate(318px,96px) scale(.5); } 17%,40% { color:var(--ok); transform:translate(330px,96px) scale(.5); } 47%,100% { color:var(--idle); transform:translate(318px,96px) scale(.5); } }
  @keyframes accSh { 0%,13% { transform:none; } 17%,40% { transform:translateX(12px); } 47%,100% { transform:none; } }
  @keyframes accVok { 0%,13% { opacity:0; } 15%,40% { opacity:1; } 44%,100% { opacity:0; } }
  @keyframes accVerr { 0%,61% { opacity:0; } 63%,88% { opacity:1; } 92%,100% { opacity:0; } }
  @keyframes accRow3 { 0%,61% { opacity:1; } 63%,66% { opacity:.2; } 68%,71% { opacity:1; } 73%,76% { opacity:.2; } 78%,100% { opacity:1; } }

  .inc .scr { fill:var(--bg); stroke:var(--line); }
  .inc .scr-title { font:600 11px/1 "IBM Plex Mono",monospace; letter-spacing:0.1em; text-transform:uppercase; fill:var(--muted); }
  .inc .pl-p { fill:var(--surface); stroke:var(--line); }
  .inc .axis { stroke:var(--line); stroke-width:1.5; }
  .inc .cur { stroke:var(--info); stroke-width:1.5; opacity:0; }
  .inc .sep { stroke:var(--line); stroke-width:1; }
  .inc .dot { fill:var(--idle); opacity:.5; transform-box:fill-box; transform-origin:center; }
  .inc .dot.st { opacity:.95; }
  .inc .dot.md { fill:var(--accent); }
  .inc .ev1, .inc .ev2, .inc .ev3 { fill:var(--err); }
  .inc .hit-ring { fill:none; stroke:var(--err); stroke-width:2; opacity:0; transform-box:fill-box; transform-origin:center; }
  .inc .pl-cap, .inc .rk-cap { font:500 9.5px/1 "IBM Plex Mono",monospace; letter-spacing:0.06em; fill:var(--muted); }
  .inc .rk-title { font:600 10px/1 "IBM Plex Mono",monospace; letter-spacing:0.08em; text-transform:uppercase; fill:var(--muted); }
  .inc .rk-name { font:600 11px/1 "IBM Plex Mono",monospace; fill:var(--ink); }
  .inc .rk-bar { fill:var(--idle); transform-box:fill-box; transform-origin:left center; }
  .inc .rk-bar.b1 { fill:var(--err); }
  .inc .rk-bar.b2 { fill:var(--accent); }
  .inc .foot { font:500 9.5px/1 "IBM Plex Mono",monospace; letter-spacing:0.08em; text-transform:uppercase; fill:var(--muted); }
  /* курсор времени идёт слева направо, журнал засевается, на 88-92% всё синхронно очищается */
  .inc .cur { animation:incCur 18s linear infinite; }
  .inc .hit-ring { animation:incRing 18s ease-out infinite; }
  .inc .rk-bar.b1 { animation:incB1 18s linear infinite; }
  .inc .rk-bar.b2 { animation:incB2 18s linear infinite; }
  .inc .rk-bar.b3 { animation:incB3 18s linear infinite; }
  @keyframes incCur { 0% { transform:none; opacity:0; } 1.5% { opacity:.55; } 78% { transform:translateX(174px); opacity:.55; } 80%,100% { transform:translateX(174px); opacity:0; } }
  @keyframes incRing { 0%,47.5% { transform:scale(.5); opacity:0; } 49% { opacity:.8; } 57%,100% { transform:scale(1.9); opacity:0; } }
  @keyframes incB1 { 0%,28% { transform:scaleX(.28); } 31%,47% { transform:scaleX(.55); } 50%,66% { transform:scaleX(.82); } 69%,88% { transform:scaleX(1); } 93%,100% { transform:scaleX(.28); } }
  @keyframes incB2 { 0%,30% { transform:scaleX(.55); } 33%,88% { transform:scaleX(1); } 93%,100% { transform:scaleX(.55); } }
  @keyframes incB3 { 0%,55% { transform:scaleX(.6); } 58%,88% { transform:scaleX(1); } 93%,100% { transform:scaleX(.6); } }
  .inc .d0{animation:incD0 18s linear infinite}@keyframes incD0{0%,1.4%{opacity:0;transform:scale(.2)}2.8%,88%{opacity:0.5;transform:scale(1)}92%,100%{opacity:0}}
  .inc .d1{animation:incD1 18s linear infinite}@keyframes incD1{0%,3.7%{opacity:0;transform:scale(.2)}5.1%,88%{opacity:0.5;transform:scale(1)}92%,100%{opacity:0}}
  .inc .d2{animation:incD2 18s linear infinite}@keyframes incD2{0%,5.1%{opacity:0;transform:scale(.2)}6.5%,88%{opacity:0.5;transform:scale(1)}92%,100%{opacity:0}}
  .inc .d3{animation:incD3 18s linear infinite}@keyframes incD3{0%,6.9%{opacity:0;transform:scale(.2)}8.3%,88%{opacity:0.5;transform:scale(1)}92%,100%{opacity:0}}
  .inc .d4{animation:incD4 18s linear infinite}@keyframes incD4{0%,12.9%{opacity:0;transform:scale(.2)}14.3%,88%{opacity:0.5;transform:scale(1)}92%,100%{opacity:0}}
  .inc .d5{animation:incD5 18s linear infinite}@keyframes incD5{0%,15.6%{opacity:0;transform:scale(.2)}17.0%,88%{opacity:0.5;transform:scale(1)}92%,100%{opacity:0}}
  .inc .d6{animation:incD6 18s linear infinite}@keyframes incD6{0%,16.1%{opacity:0;transform:scale(.2)}17.5%,88%{opacity:0.5;transform:scale(1)}92%,100%{opacity:0}}
  .inc .d7{animation:incD7 18s linear infinite}@keyframes incD7{0%,16.6%{opacity:0;transform:scale(.2)}18.0%,88%{opacity:0.5;transform:scale(1)}92%,100%{opacity:0}}
  .inc .d8{animation:incD8 18s linear infinite}@keyframes incD8{0%,17.0%{opacity:0;transform:scale(.2)}18.4%,88%{opacity:0.5;transform:scale(1)}92%,100%{opacity:0}}
  .inc .d9{animation:incD9 18s linear infinite}@keyframes incD9{0%,27.1%{opacity:0;transform:scale(.2)}28.5%,88%{opacity:0.5;transform:scale(1)}92%,100%{opacity:0}}
  .inc .d10{animation:incD10 18s linear infinite}@keyframes incD10{0%,46.0%{opacity:0;transform:scale(.2)}47.4%,88%{opacity:0.5;transform:scale(1)}92%,100%{opacity:0}}
  .inc .d11{animation:incD11 18s linear infinite}@keyframes incD11{0%,55.2%{opacity:0;transform:scale(.2)}56.6%,88%{opacity:0.5;transform:scale(1)}92%,100%{opacity:0}}
  .inc .d12{animation:incD12 18s linear infinite}@keyframes incD12{0%,63.0%{opacity:0;transform:scale(.2)}64.4%,88%{opacity:0.5;transform:scale(1)}92%,100%{opacity:0}}
  .inc .d13{animation:incD13 18s linear infinite}@keyframes incD13{0%,77.7%{opacity:0;transform:scale(.2)}79.1%,88%{opacity:0.5;transform:scale(1)}92%,100%{opacity:0}}
  .inc .d14{animation:incD14 18s linear infinite}@keyframes incD14{0%,6.9%{opacity:0;transform:scale(.2)}8.3%,88%{opacity:0.75;transform:scale(1)}92%,100%{opacity:0}}
  .inc .d15{animation:incD15 18s linear infinite}@keyframes incD15{0%,13.8%{opacity:0;transform:scale(.2)}15.2%,88%{opacity:0.75;transform:scale(1)}92%,100%{opacity:0}}
  .inc .d16{animation:incD16 18s linear infinite}@keyframes incD16{0%,19.3%{opacity:0;transform:scale(.2)}20.7%,88%{opacity:0.75;transform:scale(1)}92%,100%{opacity:0}}
  .inc .d17{animation:incD17 18s linear infinite}@keyframes incD17{0%,20.7%{opacity:0;transform:scale(.2)}22.1%,88%{opacity:0.75;transform:scale(1)}92%,100%{opacity:0}}
  .inc .d18{animation:incD18 18s linear infinite}@keyframes incD18{0%,27.6%{opacity:0;transform:scale(.2)}29.0%,88%{opacity:0.75;transform:scale(1)}92%,100%{opacity:0}}
  .inc .d19{animation:incD19 18s linear infinite}@keyframes incD19{0%,45.5%{opacity:0;transform:scale(.2)}46.9%,88%{opacity:0.75;transform:scale(1)}92%,100%{opacity:0}}
  .inc .d20{animation:incD20 18s linear infinite}@keyframes incD20{0%,47.8%{opacity:0;transform:scale(.2)}49.2%,88%{opacity:0.75;transform:scale(1)}92%,100%{opacity:0}}
  .inc .d21{animation:incD21 18s linear infinite}@keyframes incD21{0%,65.7%{opacity:0;transform:scale(.2)}67.1%,88%{opacity:0.75;transform:scale(1)}92%,100%{opacity:0}}
  .inc .d22{animation:incD22 18s linear infinite}@keyframes incD22{0%,27.6%{opacity:0;transform:scale(.2)}28.6%{opacity:0.95;transform:scale(1.35)}29.8%,88%{opacity:0.95;transform:scale(1)}92%,100%{opacity:0}}
  .inc .d23{animation:incD23 18s linear infinite}@keyframes incD23{0%,47.8%{opacity:0;transform:scale(.2)}48.8%{opacity:0.95;transform:scale(1.35)}50.0%,88%{opacity:0.95;transform:scale(1)}92%,100%{opacity:0}}
  .inc .d24{animation:incD24 18s linear infinite}@keyframes incD24{0%,67.1%{opacity:0;transform:scale(.2)}68.1%{opacity:0.95;transform:scale(1.35)}69.3%,88%{opacity:0.95;transform:scale(1)}92%,100%{opacity:0}}

  .sta .scr { fill:var(--bg); stroke:var(--line); }
  .sta .scr-title { font:600 11px/1 "IBM Plex Mono",monospace; letter-spacing:0.1em; text-transform:uppercase; fill:var(--muted); }
  .sta .axis { stroke:var(--line); stroke-width:1.5; }
  .sta .lvl { stroke-dasharray:5 6; stroke-width:1.5; }
  .sta .lvl-peak { stroke:var(--accent); }
  .sta .lvl-avg { stroke:var(--info); }
  .sta .lvl-t { font:600 9.5px/1 "IBM Plex Mono",monospace; letter-spacing:0.04em; }
  .sta .t-peak { fill:var(--accent-text); }
  .sta .t-avg { fill:var(--info); }
  .sta .st-bar { fill:var(--info); fill-opacity:.75; transform-box:fill-box; transform-origin:center bottom; animation:staBar 6s ease-in-out infinite; animation-delay:var(--sd,0s); }
  .sta .st-bar.s1 { fill-opacity:.55; }
  .sta .st-bar.s3 { fill-opacity:.62; }
  .sta .lg { font:500 10px/1 "IBM Plex Mono",monospace; letter-spacing:0.05em; fill:var(--muted); }
  .sta .lg-n { font-weight:600; font-size:13px; fill:var(--ink); }
  .sta .lg-ok { fill:var(--ok); }
  .sta .lg-acc { fill:var(--accent-text); }
  @keyframes staBar { 0%,100% { transform:scaleY(.92); } 50% { transform:scaleY(1); } }

/* --- who: сцена «Для кого» на /sklad (генератор scratchpad/gen-who.py, 02.09.2026). Цикл 12 с:
   эп.1 (0–45 %) статистика площадок сходится в окно центрального офиса — строки таблицы подсвечиваются
   по очереди, связь с площадкой пульсирует цветом (никаких летящих объектов); эп.2 (50–95 %) в центре
   двигают ползунок порога удара 30→35 % и жмут «Применить» — во всех трёх окнах филиалов значение
   меняется одновременно. Пауза/запуск — общая механика .illo (одна схема в момент времени). --- */
.illo.who{width:100%}
.who .who-bg{fill:var(--surface)}
.who .who-title{font:600 11px/1 "IBM Plex Mono",monospace;letter-spacing:.1em;text-transform:uppercase;fill:var(--muted)}
.who .who-win{fill:var(--surface);stroke:var(--line);stroke-width:1.5}
.who .who-bar{fill:var(--bg)}
.who .who-bar-sq{fill:var(--bg)}
.who .who-bar-line{stroke:var(--line);stroke-width:1.5}
.who .who-led{fill:var(--ok)}
.who .who-wt{font:600 12.5px/1 "Golos Text",sans-serif;fill:var(--ink)}
.who .who-hq .who-wt{font-size:13px}
.who .who-wm{font:500 9.5px/1 "IBM Plex Mono",monospace;fill:var(--muted)}
.who .who-ic{fill:var(--info)}
.who .who-ic-s{fill:none;stroke:var(--info);stroke-width:1.6;stroke-linecap:round}
.who .who-ic-s circle{fill:var(--surface)}
.who .who-rl{font:500 12px/1 "Golos Text",sans-serif;fill:var(--ink)}
.who .who-rv{font:600 11.5px/1 "IBM Plex Mono",monospace;fill:var(--ink)}
.who .who-sep{stroke:var(--line);stroke-width:1}
.who .who-sep-b{stroke:var(--line);stroke-width:1.5}
.who .who-flash{fill:var(--info);opacity:0}
.who .who-th{font:600 9.5px/1 "IBM Plex Mono",monospace;letter-spacing:.08em;fill:var(--muted)}
.who .who-row{fill:var(--info);opacity:0}
.who .who-td{font:500 12px/1 "IBM Plex Mono",monospace;fill:var(--ink)}
.who .who-td-name{font:600 12.5px/1 "Golos Text",sans-serif}
.who .who-sum{font:600 12.5px/1 "Golos Text",sans-serif;fill:var(--ink)}
.who .who-sum.who-tot{font-family:"IBM Plex Mono",monospace}
.who .who-pl{font-weight:600}
.who .who-track{stroke:var(--line);stroke-width:4;stroke-linecap:round}
.who .who-track-f{stroke:var(--info);stroke-width:4;stroke-linecap:round}
.who .who-knob{fill:var(--surface);stroke:var(--info);stroke-width:2.5}
.who .who-kv{font:600 12.5px/1 "IBM Plex Mono",monospace;fill:var(--ink)}
.who .who-btn{transform-box:fill-box;transform-origin:center}
.who .who-btn-b{fill:color-mix(in srgb,var(--info) 14%,transparent);stroke:var(--info);stroke-width:1.5}
.who .who-btn-t{font:600 11.5px/1 "Golos Text",sans-serif;fill:var(--accent-text)}
.who .who-tap{fill:none;stroke:var(--info);stroke-width:2;opacity:0}
.who .who-link{fill:none;stroke:var(--line);stroke-width:1.5;stroke-dasharray:4 5}
.who .who-v35{opacity:0}
.who .who-br,.who .who-hq{transform-box:fill-box;transform-origin:center}
@media (max-width:900px){.who{display:none}}

@media (prefers-reduced-motion:no-preference){
  .who .who-br{animation:who-in .6s cubic-bezier(.16,1,.3,1) both}
  .who .who-br.b2{animation-delay:.12s}
  .who .who-br.b3{animation-delay:.24s}
  .who .who-hq{animation:who-in .6s cubic-bezier(.16,1,.3,1) .3s both}
  .who .who-link{stroke-dasharray:4 5;animation:who-link-in .5s ease-out .5s both}
  .who .who-row1{animation:who-row1 12s ease-out .9s infinite}
  .who .who-row2{animation:who-row2 12s ease-out .9s infinite}
  .who .who-row3{animation:who-row3 12s ease-out .9s infinite}
  .who .who-n1{animation:who-n1 12s steps(1) .9s infinite}
  .who .who-n2{animation:who-n2 12s steps(1) .9s infinite}
  .who .who-n3{animation:who-n3 12s steps(1) .9s infinite}
  .who .who-tot{animation:who-tot 12s steps(1) .9s infinite}
  .who .l1{animation:who-link-in .5s ease-out .5s both, who-l1 12s steps(1) .9s infinite}
  .who .l2{animation:who-link-in .5s ease-out .5s both, who-l2 12s steps(1) .9s infinite}
  .who .l3{animation:who-link-in .5s ease-out .5s both, who-l3 12s steps(1) .9s infinite}
  .who .who-knob{animation:who-knob 12s cubic-bezier(.22,.61,.36,1) .9s infinite}
  .who .who-track-f{animation:who-trackf 12s cubic-bezier(.22,.61,.36,1) .9s infinite}
  .who .who-v30{animation:who-v30 12s steps(1) .9s infinite}
  .who .who-v35{animation:who-v35 12s steps(1) .9s infinite}
  .who .who-btn{animation:who-press 12s cubic-bezier(.34,1.56,.64,1) .9s infinite}
  .who .who-btn-b{animation:who-btnfill 12s ease-out .9s infinite}
  .who .who-tap{animation:who-tap 12s ease-out .9s infinite}
  .who .who-flash{animation:who-flash 12s ease-out .9s infinite}
  .who .who-led{animation:who-led 2.8s ease-in-out infinite}
  .who .who-br.b2 .who-led{animation-delay:.9s}
  .who .who-br.b3 .who-led{animation-delay:1.8s}
}
@keyframes who-led{0%,100%{opacity:1}50%{opacity:.45}}
@keyframes who-in{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@keyframes who-link-in{from{opacity:0}to{opacity:1}}
/* эп.1: строки 1→2→3 (5–15 %, 12–22 %, 19–29 %), итог с 30 % */
@keyframes who-row1{0%,4%{opacity:0}6%,13%{opacity:.14}16%,100%{opacity:0}}
@keyframes who-row2{0%,11%{opacity:0}13%,20%{opacity:.14}23%,100%{opacity:0}}
@keyframes who-row3{0%,18%{opacity:0}20%,27%{opacity:.14}30%,100%{opacity:0}}
@keyframes who-n1{0%,5%{opacity:0}6%,96%{opacity:1}97%,100%{opacity:0}}
@keyframes who-n2{0%,12%{opacity:0}13%,96%{opacity:1}97%,100%{opacity:0}}
@keyframes who-n3{0%,19%{opacity:0}20%,96%{opacity:1}97%,100%{opacity:0}}
@keyframes who-tot{0%,29%{opacity:0}30%,96%{opacity:1}97%,100%{opacity:0}}
/* связи: пульс цветом при приходе статистики (эп.1) и при рассылке порога всем сразу (эп.2, 66–74 %) */
@keyframes who-l1{0%,4%{stroke:var(--line)}5%,14%{stroke:var(--info)}15%,65%{stroke:var(--line)}66%,74%{stroke:var(--info)}75%,100%{stroke:var(--line)}}
@keyframes who-l2{0%,11%{stroke:var(--line)}12%,21%{stroke:var(--info)}22%,65%{stroke:var(--line)}66%,74%{stroke:var(--info)}75%,100%{stroke:var(--line)}}
@keyframes who-l3{0%,18%{stroke:var(--line)}19%,28%{stroke:var(--info)}29%,65%{stroke:var(--line)}66%,74%{stroke:var(--info)}75%,100%{stroke:var(--line)}}
/* эп.2: ползунок 52–58 %, кнопка 60–63 %, значение и подсветка в филиалах с 68 % */
@keyframes who-knob{0%,52%{transform:translateX(0)}58%,96%{transform:translateX(17.8px)}100%{transform:translateX(0)}}
@keyframes who-trackf{0%,52%{transform:scaleX(1)}58%,96%{transform:scaleX(1.1667)}100%{transform:scaleX(1)}}
@keyframes who-v30{0%,57%{opacity:1}58%,96%{opacity:0}97%,100%{opacity:1}}
@keyframes who-v35{0%,57%{opacity:0}58%,96%{opacity:1}97%,100%{opacity:0}}
@keyframes who-press{0%,60%{transform:scale(1)}62%{transform:scale(.93)}65%,100%{transform:scale(1)}}
@keyframes who-btnfill{0%,60%{fill:color-mix(in srgb,var(--info) 14%,transparent)}62%,68%{fill:color-mix(in srgb,var(--info) 40%,transparent)}72%,100%{fill:color-mix(in srgb,var(--info) 14%,transparent)}}
@keyframes who-tap{0%,60%{r:10px;opacity:0}62%{opacity:.6}70%,100%{r:34px;opacity:0}}
@keyframes who-flash{0%,67%{opacity:0}69%,74%{opacity:.14}80%,100%{opacity:0}}
.who .who-br .who-v30{animation-name:who-bv30}
.who .who-br .who-v35{animation-name:who-bv35}
@keyframes who-bv30{0%,67%{opacity:1}68%,96%{opacity:0}97%,100%{opacity:1}}
@keyframes who-bv35{0%,67%{opacity:0}68%,96%{opacity:1}97%,100%{opacity:0}}
.who .who-track-f{transform-box:fill-box;transform-origin:left center}

