Что делает скрипт

Горизонтальная лента из карточек с перетаскиванием.

Как подключить

  1. Блоку задайте класс uc-techers; карточки лежат в группе flow-blog.
  2. Вставьте код в блок T123 «HTML-код» на страницу (или в «Настройки страницы» → «HTML-код для вставки внутрь head»).
  3. Опубликуйте страницу: код выполняется только на опубликованной странице.

Код

Код для вставки
<style>
/* Контейнер ленты: обрезаем всё, что уехало за край блока */
.uc-techers .flow-blog {
  overflow: hidden !important;
  width: calc(100% - 240px) !important; /* 120px отступ слева = столько же справа */
}

.uc-techers .flow-blog > .tn-molecule {
  --post-gap: 24px;
  --post-width: calc((100% - 72px) / 4); /* 4 карточки + 3 промежутка */

  display: flex !important;
  flex-wrap: nowrap !important;
  gap: var(--post-gap) !important;
  width: 100% !important;
  overflow-x: auto !important;
  overflow-y: hidden !important;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  cursor: grab;
}

.uc-techers .flow-blog > .tn-molecule::-webkit-scrollbar {
  display: none;
}

.uc-techers .flow-blog > .tn-molecule.is-dragging {
  cursor: grabbing;
  user-select: none;
  -webkit-user-select: none;
}

.uc-techers .flow-blog > .tn-molecule > .post {
  position: relative !important;
  top: auto !important;
  left: auto !important;
  width: var(--post-width) !important;
  min-width: var(--post-width) !important;
  max-width: none !important;
  flex: 0 0 var(--post-width) !important;
}

.uc-techers .flow-blog > .tn-molecule > .post > .tn-molecule {
  width: 100% !important;
}

.uc-techers .btn-left,
.uc-techers .btn-right {
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.uc-techers .btn-left.disabled,
.uc-techers .btn-right.disabled {
  pointer-events: none;
  opacity: 0.35;
}

.uc-techers .btn-left.hidden,
.uc-techers .btn-right.hidden {
  display: none !important;
}

@media screen and (max-width: 1199px) {
  .uc-techers .flow-blog > .tn-molecule {
    --post-gap: 20px;
    --post-width: calc((100% - 40px) / 3);
  }
}

@media screen and (max-width: 639px) {
  .uc-techers .flow-blog > .tn-molecule {
    --post-gap: 16px;
    --post-width: calc((100% - 16px) / 2);
  }
}

@media screen and (max-width: 419px) {
  .uc-techers .flow-blog > .tn-molecule {
    --post-gap: 12px;
    --post-width: 100%;
  }
}
</style>

<script>
$(function () {
  const sliderSelector = ".uc-techers";

  function initSlider(record) {
    const $record = $(record);
    const $scroller = $record.find(".flow-blog > .tn-molecule").first();

    if (!$scroller.length || $record.data("simpleFeedSliderReady")) return;

    const el = $scroller[0];
    const ns = ".simpleFeedSlider" + ($record.attr("id") || "");
    const $leftArrow = $record.find(".btn-left").first();
    const $rightArrow = $record.find(".btn-right").first();

    if (!$leftArrow.length || !$rightArrow.length) return;
    if (!$scroller.children(".post").length) return;

    $record.data("simpleFeedSliderReady", true);

    // Zero Block масштабирует группу через CSS zoom. scrollLeft и offsetLeft —
    // в «дизайнерских» px, pageX и getBoundingClientRect() — в экранных.
    // Всё, что смешивает две системы координат, делим на этот коэффициент.
    function getScale() {
      const rectWidth = el.getBoundingClientRect().width;
      return rectWidth && el.clientWidth ? rectWidth / el.clientWidth : 1;
    }

    // offsetLeft карточек — в той же системе координат, что и scrollLeft
    function getCardOffsets() {
      return $scroller
        .children(".post")
        .toArray()
        .map(function (card) {
          return card.offsetLeft;
        })
        .sort(function (a, b) {
          return a - b;
        });
    }

    function updateControls() {
      const maxScroll = Math.max(0, el.scrollWidth - el.clientWidth);
      const noScroll = maxScroll <= 5;

      $leftArrow.add($rightArrow).toggleClass("hidden", noScroll);
      $leftArrow.toggleClass("disabled", noScroll || el.scrollLeft <= 5);
      $rightArrow.toggleClass(
        "disabled",
        noScroll || el.scrollLeft >= maxScroll - 5
      );
    }

    function scrollToCard(direction) {
      const current = el.scrollLeft;
      let target = null;

      getCardOffsets().forEach(function (x) {
        if (direction > 0) {
          if (x <= current + 5) return;
          if (target === null || x < target) target = x;
        } else {
          if (x >= current - 5) return;
          if (target === null || x > target) target = x;
        }
      });

      el.scrollTo({
        left: target !== null ? target : direction > 0 ? el.scrollWidth : 0,
        behavior: "smooth"
      });

      setTimeout(updateControls, 400);
    }

    $leftArrow.off(ns).on("click" + ns, function (event) {
      event.preventDefault();
      scrollToCard(-1);
    });

    $rightArrow.off(ns).on("click" + ns, function (event) {
      event.preventDefault();
      scrollToCard(1);
    });

    let isDragging = false;
    let startX = 0;
    let startScrollLeft = 0;
    let dragScale = 1;
    let wasDragged = false;

    $scroller.off(ns);
    $(document).off(ns);
    $(window).off(ns);

    $scroller.on("mousedown" + ns, function (event) {
      if (event.button !== 0) return;

      isDragging = true;
      wasDragged = false;
      startX = event.pageX;
      startScrollLeft = el.scrollLeft;
      dragScale = getScale();
      $scroller.addClass("is-dragging");
    });

    $(document).on("mousemove" + ns, function (event) {
      if (!isDragging) return;

      const dx = event.pageX - startX;

      if (Math.abs(dx) > 4) {
        wasDragged = true;
        event.preventDefault();
      }

      el.scrollLeft = startScrollLeft - dx / dragScale;
    });

    $(document).on("mouseup" + ns, function () {
      if (!isDragging) return;

      isDragging = false;
      $scroller.removeClass("is-dragging");

      setTimeout(function () {
        wasDragged = false;
      }, 50);
    });

    // после перетаскивания не даём сработать ссылке «Подробнее»
    $scroller.on("click" + ns, "a", function (event) {
      if (!wasDragged) return;

      event.preventDefault();
      event.stopImmediatePropagation();
    });

    $scroller.on("scroll" + ns, updateControls);
    $(window).on("resize" + ns, updateControls);

    updateControls();
    setTimeout(updateControls, 500);
    setTimeout(updateControls, 1500);
  }

  function initAllSliders() {
    $(sliderSelector).each(function () {
      initSlider(this);
    });
  }

  // Zero Block дорисовывает карточки не сразу — ждём их появления, но не вечно
  let attempts = 0;
  const timer = setInterval(function () {
    attempts += 1;
    initAllSliders();

    if (
      $(sliderSelector + " .flow-blog > .tn-molecule > .post").length ||
      attempts >= 40
    ) {
      clearInterval(timer);
    }
  }, 150);

  initAllSliders();
});
</script>
тут нужно написать стили и js/css для того, чтобы отображались файлы скриптов