/* ============================================================
   Мур-Молл: уличная сценка с котами (outdoor-scene)
   Подключается парой к outdoor-scene.js на любой странице,
   КРОМЕ самого мола. Все селекторы под префиксом ods-,
   чтобы не пересекаться со стилями мола.

   Два независимых слоя:
   1. #ods-sky   — статичный градиент неба + чисто CSS-облака
                   (нулевая цена в рантайме, никакого JS);
   2. #ods-strip — фиксированная полоса улицы внизу вьюпорта,
                   по которой ходят коты (DOM-спрайты, JS-цикл).

   Вся сценка pointer-events:none — никогда не перехватывает
   клики по формам, кнопкам и ссылкам страницы.
   ============================================================ */

/* ---------- небо ---------- */
#ods-root {
  position: fixed; inset: 0; z-index: 0;
  overflow: hidden; pointer-events: none;
}
/* The outdoor scene is one self-contained background stacking context.
   Page content must always stay above skyline, props, traffic and cats. */
body.ods-active > #home {
  position: relative; z-index: 1;
}
#ods-sky {
  position: fixed; inset: 0; z-index: -1;
  pointer-events: none;
  background: linear-gradient(180deg,
    #b8d9ea 0%, #cfe3ec 32%, #ecebd8 62%, #f2e8cf 82%, #efe3c6 100%);
}
html[data-theme="dark"] #ods-sky {
  background:
    radial-gradient(ellipse at 74% 11%, rgba(204,219,239,.16) 0 2%, transparent 7%),
    linear-gradient(180deg, #07111f 0%, #0d1b2d 34%, #16283c 63%, #24344a 100%);
}
.ods-cloud {
  position: absolute; display: block;
  width: 170px; height: 46px; border-radius: 40px;
  background: rgba(255,255,255,.85); filter: blur(1px);
  animation: ods-drift 130s linear infinite;
}
html[data-theme="dark"] .ods-cloud {
  background: rgba(132,151,177,.18);
  filter: blur(2px);
}
.ods-cloud::before, .ods-cloud::after {
  content: ''; position: absolute; background: inherit; border-radius: 50%;
}
.ods-cloud::before { width: 74px; height: 62px; left: 28px; top: -26px; }
.ods-cloud::after  { width: 52px; height: 44px; right: 30px; top: -16px; }
.ods-cloud.c1 { top: 9%; }
.ods-cloud.c2 { top: 22%; transform: scale(.62); opacity: .7; animation-duration: 180s; animation-delay: -80s; }
@keyframes ods-drift {
  from { translate: -30vw 0; }
  to   { translate: 130vw 0; }
}

/* ---------- полоса улицы ---------- */
#ods-strip {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  height: min(150px, 20vh);
  pointer-events: none;         /* декорация, не UI */
  overflow: visible;            /* кроны деревьев и пузыри выше полосы */
  /* газон, сходящий в небо сверху, бордюр и тротуар снизу */
  background:
    linear-gradient(180deg,
      rgba(122,164,86,0) 0%, rgba(122,164,86,.55) 16%, #7ba653 28%,
      #6f9a4c 68%, #5d7a3f 71.5%,
      #cfc4ad 72%, #c3b69c 84%, #b1a286 100%);
}
html[data-theme="dark"] #ods-strip {
  background:
    linear-gradient(180deg,
      rgba(33,71,57,0) 0%, rgba(33,71,57,.54) 16%, #244d3c 28%,
      #1f4435 68%, #173429 71.5%,
      #4a4c50 72%, #3e4248 84%, #303740 100%);
}
/* редкие цветочки на газоне */
#ods-strip::before {
  content: ''; position: absolute; inset: 0 0 28% 0;
  background:
    radial-gradient(3px 3px at 12% 74%, #e8b3c9 60%, transparent 61%),
    radial-gradient(3px 3px at 27% 58%, #f2d16b 60%, transparent 61%),
    radial-gradient(2.5px 2.5px at 48% 70%, #e8b3c9 60%, transparent 61%),
    radial-gradient(3px 3px at 63% 55%, #fff 60%, transparent 61%),
    radial-gradient(2.5px 2.5px at 79% 66%, #f2d16b 60%, transparent 61%),
    radial-gradient(3px 3px at 92% 58%, #fff 60%, transparent 61%);
  opacity: .8;
}
html[data-theme="dark"] #ods-strip::before {
  opacity:.45;
  filter:brightness(.75) saturate(.72);
}

/* ---------- декор: прозрачные WebP-спрайты ----------
   Три статичных слоя создают глубину без участия JS: дальний слой выше,
   меньше и мягче; средний задаёт силуэт парка; ближний содержит мелкие
   предметы. Все три остаются за котами, чтобы декор не скрывал прогулку. */
.ods-scenery { position: absolute; inset: 0; z-index: 1; }
.ods-scenery-layer { position: absolute; inset: 0; }
.ods-scenery-skyline { z-index: 0; }
.ods-traffic { z-index: 1; overflow: visible; }
.ods-scenery-far { z-index: 2; }
.ods-scenery-mid { z-index: 3; }
.ods-scenery-near { z-index: 4; }
.ods-scenery-sprite {
  position: absolute; display: block; width: auto; max-width: none;
  object-fit: contain; object-position: 50% 100%; transform-origin: 50% 100%;
  user-select: none; -webkit-user-drag: none;
  filter: drop-shadow(0 7px 7px rgba(48,43,24,.2));
}

/* Панорама лежит глубже всего. Светлая дымка под ней отделяет здания от
   зелёного газона: город остаётся мягким, но трава не просвечивает сквозь
   фасады так, как при низкой opacity всего изображения. */
.ods-scenery-skyline::before {
  content: ''; position: absolute; left: 0; right: 0; bottom: 68%;
  z-index: 0; height: min(38vh, 285px);
  background: linear-gradient(180deg,
    rgba(231,233,222,0) 0%, rgba(229,232,218,.24) 34%,
    rgba(220,226,208,.5) 76%, rgba(207,217,191,.62) 100%);
}
html[data-theme="dark"] .ods-scenery-skyline::before {
  background: linear-gradient(180deg,
    rgba(10,22,35,0) 0%, rgba(16,31,44,.2) 34%,
    rgba(21,40,49,.45) 76%, rgba(25,48,48,.62) 100%);
}
.ods-skyline {
  left: 50%; bottom: 68%; z-index: 1;
  width: 100%; height: clamp(340px, 31.25vw, 520px);
  object-fit: cover; object-position: 50% 100%;
  transform: translateX(-50%); opacity: .62;
  filter: saturate(.58) contrast(.86) brightness(1.02);
}
html[data-theme="dark"] .ods-skyline {
  opacity:.93;
  filter:saturate(.76) contrast(.94) brightness(.9);
}

/* Дальний транспорт: два ряда на дороге панорамы. Машины остаются за
   деревьями и оградой; отдельные длительности не дают потоку синхронизироваться. */
.ods-vehicle {
  position: absolute; left: 0; bottom: calc(68% - 8px);
  display: none; width: auto; height: 76px; max-width: none;
  transform-origin: 50% 50%; user-select: none; -webkit-user-drag: none;
  pointer-events: none; opacity: .86;
}
.ods-vehicle.ods-driving {
  display: block;
  animation-duration: var(--drive-time);
  animation-timing-function: linear;
  animation-iteration-count: 1;
  animation-fill-mode: both;
  will-change: transform;
}
html[data-theme="dark"] .ods-vehicle {
  opacity:.86;
}
.ods-lane-far {
  bottom: calc(68% + 24px); height: 64px; opacity: .76;
}
html[data-theme="dark"] .ods-lane-far {
  opacity:.68;
}
.ods-drive-east { animation-name: ods-drive-east; }
.ods-drive-west { animation-name: ods-drive-west; }
@keyframes ods-drive-east {
  from { transform: translate3d(-180px,0,0) scaleX(1); }
  to { transform: translate3d(calc(100vw + 180px),0,0) scaleX(1); }
}
@keyframes ods-drive-west {
  from { transform: translate3d(calc(100vw + 180px),0,0) scaleX(-1); }
  to { transform: translate3d(-180px,0,0) scaleX(-1); }
}

/* Дальний план: приглушённый контраст, небольшой blur и высокая линия
   основания дают атмосферную перспективу, не затрагивая чёткость UI. */
.ods-scenery-far .ods-scenery-sprite {
  opacity: .9;
  filter: saturate(.58) contrast(.82) brightness(1.13) blur(1.25px)
          drop-shadow(0 4px 5px rgba(48,43,24,.10));
}
html[data-theme="dark"] .ods-scenery-far .ods-scenery-sprite {
  opacity:.93;
  filter:saturate(.72) contrast(.9) brightness(.88) blur(1px)
         drop-shadow(0 5px 7px rgba(0,0,0,.24));
}
/* Sub-pixel radii stay visible on high-density displays without making the
   skyline and far scenery softer than their standard-density counterparts. */
@media (min-resolution: 2dppx) {
  .ods-skyline {
    filter: saturate(.58) contrast(.86) brightness(1.02);
  }
  html[data-theme="dark"] .ods-skyline {
    filter:saturate(.76) contrast(.94) brightness(.9);
  }
  .ods-scenery-far .ods-scenery-sprite {
    filter: saturate(.58) contrast(.82) brightness(1.13) blur(.55px)
            drop-shadow(0 4px 5px rgba(48,43,24,.10));
  }
  html[data-theme="dark"] .ods-scenery-far .ods-scenery-sprite {
    filter:saturate(.72) contrast(.9) brightness(.88) blur(.45px)
           drop-shadow(0 5px 7px rgba(0,0,0,.24));
  }
}
.ods-fence { bottom: 45%; height: clamp(66px, 6.5vw, 88px); }
.ods-fence.f1 { left: 3%; }
.ods-fence.f2 { right: 4%; transform: scaleX(-1); }
.ods-tree-cluster { left: 12%; bottom: 47%; height: clamp(138px, 13vw, 176px); }
.ods-tree-cluster-secondary { left: 58%; bottom: 47%; height: clamp(138px, 13vw, 176px); transform: scaleX(-1); }
.ods-shrub-cluster { right: 20%; bottom: 46%; height: clamp(62px, 6vw, 80px); }

/* Средний план: крупные ориентиры и основные точки реплик котов. */
.ods-tree { bottom: 34%; }
.ods-tree-broadleaf { left: -2%; height: clamp(176px, 17vw, 226px); }
.ods-tree-blossom { left: 20%; height: clamp(166px, 15.8vw, 210px); filter: saturate(.82) brightness(1.02) drop-shadow(0 7px 7px rgba(48,43,24,.19)); }
.ods-tree-linden { right: 12%; height: clamp(172px, 16.5vw, 218px); filter: saturate(.87) brightness(.96) drop-shadow(0 7px 7px rgba(48,43,24,.2)); }
.ods-tree-willow { right: -4%; height: clamp(184px, 18vw, 236px); filter: saturate(.8) brightness(.92) drop-shadow(0 7px 7px rgba(48,43,24,.22)); }
html[data-theme="dark"] .ods-tree-blossom,
html[data-theme="dark"] .ods-tree-linden,
html[data-theme="dark"] .ods-tree-willow {
  filter:saturate(.82) brightness(.86) drop-shadow(0 8px 9px rgba(0,0,0,.3));
}
/* Three posts share one baseline and use evenly spaced centre points. */
.ods-lamp { bottom: 31%; height: clamp(142px, 13vw, 178px); transform: translateX(-50%); }
.ods-lamp.l1 { left: 16.666%; }
.ods-lamp.l2 { left: 50%; }
.ods-lamp.l3 { left: 83.333%; }
.ods-sign { left: 67%; bottom: 30%; height: clamp(116px, 11vw, 150px); }
.ods-shrub { bottom: 31%; }
.ods-shrub-clipped { left: 37%; height: clamp(58px, 5.2vw, 72px); }
.ods-shrub-flowering { left: 56%; height: clamp(68px, 6.1vw, 82px); }
.ods-shrub-spreading { right: 5%; height: clamp(62px, 5.6vw, 76px); }

/* Ближний план: более сильная тень и тёплый цвет помогают предметам
   читаться отдельно от приглушённого горизонта. */
.ods-scenery-near .ods-scenery-sprite {
  filter: saturate(.96) drop-shadow(0 7px 7px rgba(48,43,24,.24));
}
html[data-theme="dark"] .ods-scenery-near .ods-scenery-sprite {
  filter:saturate(.86) brightness(.9) drop-shadow(0 8px 9px rgba(0,0,0,.34));
}
.ods-bin { left: 28%; bottom: 31%; height: clamp(40px, 3.8vw, 52px); }
.ods-parcel { left: 82%; bottom: 6%; height: clamp(30px, 2.8vw, 39px); }
.ods-watering-can { right: 1.5%; bottom: 7%; height: clamp(48px, 4.4vw, 60px); }

/* ---------- коты ---------- */
.ods-cats { position: absolute; inset: 0; z-index: 5; }
.ods-cat { position: absolute; left: 0; top: 0; width: 0; height: 0; }
.ods-body {
  position: absolute; bottom: 0; left: 0;
  transform-origin: 50% 100%;
}
/* Walk-cycle strip: width follows the frame ratio, the frame is a background position. */
.ods-spr { position: relative; height: 110px; display: block; background-repeat: no-repeat; }
.ods-shadow {
  position: absolute; bottom: -6px; left: 0; width: 110px; height: 20px; margin-left: -55px;
  background: radial-gradient(50% 50% at 50% 50%, rgba(40,50,20,.35), transparent 70%);
  filter: blur(2px);
  transform-origin: 50% 50%;
}
html[data-theme="dark"] .ods-shadow {
  background:radial-gradient(50% 50% at 50% 50%, rgba(0,0,0,.5), transparent 70%);
}
.ods-bubble {
  position: absolute; left: 0; bottom: 90px;
  transform: translateX(-50%) scale(.7);
  background: rgba(255,253,247,.96); color: #3c3226;
  font: 12.5px/1.35 var(--ui-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif);
  padding: 7px 11px; border-radius: 13px;
  max-width: 190px; width: max-content; text-align: center;
  box-shadow: 0 4px 14px rgba(60,40,15,.22);
  opacity: 0;
  transition: opacity .22s ease, transform .22s cubic-bezier(.34,1.56,.64,1);
}
html[data-theme="dark"] .ods-bubble {
  background:rgba(24,33,45,.97); color:#f0e8dc;
  box-shadow:0 4px 16px rgba(0,0,0,.38);
}
.ods-bubble::after {
  content: ''; position: absolute; top: 100%; left: 50%; margin-left: -6px;
  border: 6px solid transparent; border-top-color: rgba(255,253,247,.96);
}
html[data-theme="dark"] .ods-bubble::after {
  border-top-color:rgba(24,33,45,.97);
}
.ods-bubble.show { opacity: 1; transform: translateX(-50%) scale(1); }

/* ---------- адаптивность ---------- */
@media (max-width: 640px) {
  #ods-strip { height: min(112px, 16vh); }
  .ods-scenery-skyline::before { bottom: 67%; height: 300px; }
  .ods-skyline {
    width: 1200px; height: 375px; bottom: 67%; opacity: .82;
    transform: translateX(var(--ods-skyline-mobile-shift, -50%));
  }
  .ods-vehicle { bottom: calc(67% - 6px); height: 54px; }
  .ods-lane-far { bottom: calc(67% + 18px); height: 45px; }
  /* На телефоне остаётся узнаваемый, но менее плотный срез сцены. */
  .ods-fence.f2, .ods-tree-cluster, .ods-tree-cluster-secondary,
  .ods-tree-blossom, .ods-tree-linden, .ods-shrub-clipped, .ods-shrub-spreading,
  .ods-detail-prop { display: none; }
  .ods-fence.f1 { left: 13%; bottom: 45%; height: 56px; }
  .ods-shrub-cluster { right: 18%; bottom: 45%; height: 52px; }
  .ods-tree-broadleaf { left: -13%; height: 158px; }
  .ods-tree-willow { right: -15%; height: 166px; }
  .ods-lamp { height: 108px; }
  .ods-sign { display: none; }
  .ods-shrub-flowering { left: 56%; height: 58px; }
}
/* короткие вьюпорты (ландшафт на телефоне, открытая клавиатура):
   полоса ужимается и не наползает на контент */
@media (max-height: 520px) {
  #ods-strip { height: 80px; }
  .ods-skyline, .ods-traffic { display: none; }
  .ods-tree, .ods-tree-cluster, .ods-tree-cluster-secondary, .ods-lamp, .ods-sign,
  .ods-detail-prop { display: none; }
}
@media (max-height: 380px) {
  #ods-strip, #ods-sky .ods-cloud { display: none; }
}

/* ---------- чувствительность к движению ---------- */
/* JS в этом режиме не запускает цикл и показывает статичный кадр;
   CSS со своей стороны останавливает облака */
@media (prefers-reduced-motion: reduce) {
  .ods-cloud { animation: none; }
  .ods-traffic { display: none; }
  .ods-bubble { transition: none; }
}

/* Explicitly stop compositor work while the tab or window is unfocused. */
#ods-root.ods-paused .ods-cloud,
#ods-root.ods-paused .ods-vehicle {
  animation-play-state: paused;
}
