/* =============================================================================
   Сценка подбора отелей на странице списка. Задача t_25939f89 (19.09.2026).

   ПОСТАНОВКА АРСЕНИЯ (19.09): крутящийся глобус; инспектор и уборщик едут по
   нему на машине; карточки отелей уменьшаются и прилипают к глобусу; персонажи
   объезжают их и ставят штампики — галочка или крестик, со свечением.
   РЕШЕНИЕ ДАНИЛА по бюджету времени: полная сценка с минимальным показом
   1.5–2 с — выдача придерживается до конца анимации, даже если ответ пришёл
   раньше. Это сознательное отступление от «не удлиняем ожидание» в исходной
   постановке, зафиксировано явным решением.

   ТРИ РЕЖИМА ПОДАЧИ (см. hotels-list-anim.js)
     full   — заставка с глобусом. Обычный телефон и десктоп.
     lite   — прежняя узкая полоса с двумя воркерами над списком. Слабое
              устройство (мало ядер/памяти) или экономия трафика: глобус с
              орбитой, свечением и летящими карточками — это реальная работа
              для GPU, и на слабом телефоне он дёргается, что хуже отсутствия
              анимации.
     reduce — prefers-reduced-motion: механика та же (подпись + прогресс), но
              без движения.

   Цвета, радиусы, кегли и отступы — только токены UI-кита (/js/vse-ui.css,
   диздок /js/vse-ui.README.md). Своих хексов здесь нет намеренно, кроме
   полупрозрачных подложек и оттенков планеты, которые по природе — rgba.
   ============================================================================= */

/* =============================================================================
   1. ЗАСТАВКА С ГЛОБУСОМ (режим full)
   ============================================================================= */

.hf-globe{
  position:fixed;inset:0;z-index:85;                 /* выше шторок (70–79), ниже карты (90) и шапки (1000) */
  display:none;flex-direction:column;align-items:center;justify-content:center;gap:var(--sp-5);
  padding:var(--sp-6) var(--sp-4) calc(var(--sp-6) + var(--safe-b));
  background:rgba(247,247,244,.94);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  font-family:var(--font);color:var(--ink);
  opacity:0;transition:opacity .22s ease;
}
.hf-globe.is-on{display:flex;opacity:1;}
.hf-globe.is-out{opacity:0;}

/* --- Сцена: глобус, орбита, пины ------------------------------------------- */
.hf-globe__stage{
  position:relative;flex:0 0 auto;
  --hf-stage:264px;                                   /* мобильный размер — базовый, канон mobile-first */
  --hf-ball:132px;                                    /* диаметр планеты */
  --hf-orbit:108px;                                   /* радиус, по которому едет машина и стоят отели */
  width:var(--hf-stage);height:var(--hf-stage);
}

/* Свечение вокруг планеты: мягкий синий ореол, дышит вместе со сценой. */
.hf-globe__glow{
  position:absolute;left:50%;top:50%;width:calc(var(--hf-ball) * 1.9);height:calc(var(--hf-ball) * 1.9);
  margin:calc(var(--hf-ball) * -0.95) 0 0 calc(var(--hf-ball) * -0.95);
  border-radius:50%;
  background:radial-gradient(circle,rgba(30,79,163,.20) 0%,rgba(30,79,163,.08) 45%,rgba(30,79,163,0) 70%);
  animation:hfGlowPulse 2.4s ease-in-out infinite alternate;
}
@keyframes hfGlowPulse{from{transform:scale(.92);opacity:.75;}to{transform:scale(1.04);opacity:1;}}

.hf-globe__ball{
  position:absolute;left:50%;top:50%;width:var(--hf-ball);height:var(--hf-ball);
  margin:calc(var(--hf-ball) / -2) 0 0 calc(var(--hf-ball) / -2);
  border-radius:50%;overflow:hidden;
  background:radial-gradient(circle at 34% 30%,#3E79D8 0%,var(--blue) 42%,var(--blue-deep) 100%);
  box-shadow:0 10px 30px rgba(18,33,59,.22), inset -8px -10px 22px rgba(15,47,102,.55);
}
/* Материки: один тайл шириной 132px, повторяется по X — при сдвиге фона ровно
   на тайл шов не виден, и планета выглядит крутящейся. Вращать сам элемент
   нельзя: круг просто закрутится плоско, как колесо. */
.hf-globe__map{
  position:absolute;inset:0;border-radius:50%;
  background-repeat:repeat-x;background-size:132px 100%;
  /* Пятна намеренно с резкой границей (сплошной цвет до 78% радиуса): на живой
     проверке 19.09 мягкие градиенты на синем шаре читались как блики, а не как
     материки — планета выглядела просто синим кругом. */
  background-image:
    radial-gradient(ellipse 26px 16px at 22px 40px,rgba(86,190,136,.95) 0%,rgba(86,190,136,.9) 78%,rgba(86,190,136,0) 100%),
    radial-gradient(ellipse 18px 22px at 52px 84px,rgba(86,190,136,.9) 0%,rgba(86,190,136,.85) 78%,rgba(86,190,136,0) 100%),
    radial-gradient(ellipse 30px 14px at 96px 52px,rgba(86,190,136,.92) 0%,rgba(86,190,136,.88) 78%,rgba(86,190,136,0) 100%),
    radial-gradient(ellipse 14px 12px at 118px 96px,rgba(86,190,136,.88) 0%,rgba(86,190,136,.82) 78%,rgba(86,190,136,0) 100%);
  animation:hfGlobeSpin 9s linear infinite;
}
@keyframes hfGlobeSpin{from{background-position-x:0;}to{background-position-x:-132px;}}
/* Блик — он же подсказка, что это шар, а не плоский круг. */
.hf-globe__shine{
  position:absolute;inset:0;border-radius:50%;
  background:radial-gradient(circle at 30% 24%,rgba(255,255,255,.42) 0%,rgba(255,255,255,0) 46%);
}

/* --- Машина с экипажем: едет по орбите ------------------------------------- */
.hf-globe__orbit{
  position:absolute;left:50%;top:50%;width:0;height:0;
  animation:hfOrbit 4s linear infinite;
}
.hf-globe__car{
  position:absolute;left:0;top:calc(var(--hf-orbit) * -1);
  display:flex;align-items:flex-end;gap:1px;
  transform:translate(-50%,-50%);
  font-size:var(--fs-15);line-height:1;white-space:nowrap;
  filter:drop-shadow(0 2px 4px rgba(18,33,59,.25));
  animation:hfOrbitBack 4s linear infinite;            /* контр-вращение: экипаж не кувыркается */
}
.hf-globe__auto{font-size:var(--fs-20);}
@keyframes hfOrbit{from{transform:rotate(0deg);}to{transform:rotate(360deg);}}
@keyframes hfOrbitBack{from{transform:translate(-50%,-50%) rotate(0deg);}to{transform:translate(-50%,-50%) rotate(-360deg);}}
/* Режим объезда: пока ответа нет, машина наматывает круги (анимация выше), а
   как только результат известен — берёт руль на себя и едет от отеля к отелю,
   угол задаёт JS. Иначе штампы появлялись бы там, где машины в этот момент нет,
   и «персонажи заезжают в каждый отель» превращалось бы в две независимые
   анимации рядом. Контр-вращение здесь снимается: машина едет по касательной. */
.hf-globe__orbit.is-drive{animation:none;transform:rotate(var(--drive,0deg));transition:transform .2s ease;}
.hf-globe__orbit.is-drive .hf-globe__car{animation:none;}

/* --- Отели, прилипшие к планете -------------------------------------------- */
.hf-globe__pin{
  position:absolute;left:50%;top:50%;width:0;height:0;
  transform:rotate(var(--a)) translateY(calc(var(--hf-orbit) * -1));
}
.hf-globe__pin-in{
  position:absolute;left:0;top:0;width:38px;height:38px;margin:-19px 0 0 -19px;
  border-radius:var(--r-s);overflow:visible;
  background:var(--card) center/cover no-repeat;
  border:1px solid var(--line);box-shadow:var(--sh-2);
  display:flex;align-items:center;justify-content:center;
  font-size:var(--fs-15);
  transform:rotate(calc(var(--a) * -1));               /* карточка остаётся «лицом» к человеку */
  transition:transform .55s cubic-bezier(.22,.9,.28,1),opacity .35s ease;
}
/* Стартовое положение: настоящая карточка списка. JS считает смещение и
   масштаб, дальше карточка сама уезжает на орбиту — это и есть «прилипают». */
.hf-globe__pin.is-flying .hf-globe__pin-in{
  transform:translate(var(--dx),var(--dy)) scale(var(--s)) rotate(calc(var(--a) * -1));
  opacity:.65;
}
/* Штампик: ставится, когда машина подъехала к отелю. */
.hf-globe__pin-in::after{
  content:'';position:absolute;right:-7px;bottom:-7px;
  width:19px;height:19px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  font-size:var(--fs-11);line-height:1;
  opacity:0;transform:scale(.4);
  transition:opacity .2s ease,transform .25s cubic-bezier(.2,1.5,.4,1);
}
.hf-globe__pin.is-ok .hf-globe__pin-in::after{content:'✅';opacity:1;transform:scale(1);}
.hf-globe__pin.is-no .hf-globe__pin-in::after{content:'❌';opacity:1;transform:scale(1);}
.hf-globe__pin.is-ok .hf-globe__pin-in{border-color:var(--green);}
.hf-globe__pin.is-no .hf-globe__pin-in{opacity:.55;}
/* Вспышка в момент штампа — короткая, без остаточного свечения. */
.hf-globe__pin.is-flash .hf-globe__pin-in{animation:hfStampFlash .42s ease-out;}
@keyframes hfStampFlash{
  0%{box-shadow:0 0 0 0 rgba(30,142,90,.55);}
  60%{box-shadow:0 0 0 10px rgba(30,142,90,0);}
  100%{box-shadow:0 0 0 0 rgba(30,142,90,0);}
}

/* --- Подпись и честный прогресс -------------------------------------------- */
.hf-globe__txt{width:min(420px,86vw);text-align:center;}
.hf-globe__cap{
  display:block;font-size:var(--fs-15);font-weight:600;color:var(--ink);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.hf-globe__sub{display:block;margin-top:2px;font-size:var(--fs-12);color:var(--muted);}
.hf-globe__bar{display:block;height:4px;margin-top:var(--sp-3);border-radius:var(--r-pill);background:var(--line-2);overflow:hidden;}
.hf-globe__fill{display:block;height:100%;width:8%;border-radius:var(--r-pill);background:var(--blue);transition:width .45s ease;}
.hf-globe.is-done .hf-globe__fill{background:var(--green);}
.hf-globe.is-done .hf-globe__cap{color:var(--green);}
.hf-globe.is-done .hf-globe__glow{background:radial-gradient(circle,rgba(30,142,90,.22) 0%,rgba(30,142,90,0) 70%);}

/* Десктоп: та же сцена крупнее. Мобильный размер — базовый, это донастройка. */
@media (min-width:768px){
  .hf-globe__stage{--hf-stage:320px;--hf-ball:164px;--hf-orbit:132px;}
  .hf-globe__pin-in{width:44px;height:44px;margin:-22px 0 0 -22px;}
}

/* =============================================================================
   2. ПОЛОСА НАД СПИСКОМ (режимы lite и reduce)
   Первая версия сценки от 19.09: два воркера, подпись, прогресс. Осталась как
   дешёвая подача для слабых устройств — не удалена намеренно.
   ============================================================================= */

.hf-scene{
  display:none;
  align-items:center;gap:var(--sp-3);
  margin:0 0 var(--sp-3);padding:var(--sp-3) var(--sp-4);
  background:var(--card);border:1px solid var(--line);border-radius:var(--r-m);
  box-shadow:var(--sh-1);
  font-family:var(--font);color:var(--ink);
}
.hf-scene.is-on{display:flex;}
.hf-scene.is-out{opacity:0;transition:opacity .28s ease;}

.hf-scene__crew{position:relative;flex:0 0 auto;width:96px;height:26px;}
.hf-scene__unit{position:absolute;top:0;display:inline-flex;align-items:flex-end;gap:1px;font-size:var(--fs-15);line-height:1;}
.hf-scene__unit--a{left:0;animation:hfWalkA 2s ease-in-out infinite alternate;}
.hf-scene__unit--b{right:0;animation:hfWalkB 2.3s ease-in-out infinite alternate;}
.hf-scene__tool{font-size:var(--fs-13);transform-origin:50% 90%;animation:hfToolSwing .55s ease-in-out infinite alternate;}
@keyframes hfWalkA{from{transform:translateX(0);}to{transform:translateX(34px);}}
@keyframes hfWalkB{from{transform:translateX(0);}to{transform:translateX(-30px);}}
@keyframes hfToolSwing{from{transform:rotate(-16deg);}to{transform:rotate(16deg);}}

.hf-scene__txt{flex:1;min-width:0;}
.hf-scene__cap{display:block;font-size:var(--fs-13);font-weight:600;color:var(--ink-2);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.hf-scene__bar{display:block;height:4px;margin-top:6px;border-radius:var(--r-pill);background:var(--line-2);overflow:hidden;}
.hf-scene__fill{display:block;height:100%;width:8%;border-radius:var(--r-pill);background:var(--blue);
  transition:width .45s ease;}
.hf-scene.is-done .hf-scene__fill{background:var(--green);}
.hf-scene.is-done .hf-scene__cap{color:var(--green);}

/* --- Карточки, которые не подошли, уезжают плавно ---------------------------
   Работает в lite/reduce, где заставки нет и список виден во время ожидания.
   В режиме full список закрыт глобусом, и отъезд по одной никто не увидит —
   там этот приём сознательно не применяется, чтобы не платить за невидимое. */
.hf-card-unit--collapsing{overflow:hidden;opacity:0;transform:scale(.97);
  transition:max-height .42s ease,opacity .28s ease,transform .28s ease,margin .42s ease,padding .42s ease;}

/* =============================================================================
   3. Доступность: механика остаётся, движение убирается.
   ============================================================================= */
@media (prefers-reduced-motion:reduce){
  .hf-scene__unit--a,.hf-scene__unit--b,.hf-scene__tool{animation:none;}
  .hf-scene__fill,.hf-card-unit--collapsing{transition:none;}
  .hf-scene.is-out{transition:none;}
  .hf-globe__map,.hf-globe__orbit,.hf-globe__car,.hf-globe__glow{animation:none;}
  .hf-globe__pin-in,.hf-globe__fill{transition:none;}
  .hf-globe,.hf-globe.is-out{transition:none;}
  .hf-globe__pin.is-flash .hf-globe__pin-in{animation:none;}
}
