const displayVariables = (data: { status: string; title: string }[]): void => {
  const variablesElement = document.querySelector(".timeline3d__variables");
  if (!variablesElement) return;

  variablesElement.innerHTML = data
    .map(
      ({ status, title }) => `
          <div class="timeline3d__variable">
            <span class="">${title}</span>
            <span class="">${status}</span>
          </div>`,
    )
    .join("");
};

export const runScript = (): void => {
  const container = document.getElementById("3dTimeline") as HTMLElement | null;
  if (!container) return;

  container.innerHTML = `
    <div class="timeline3d">
      <div class="timeline3d__category"></div>
      <div class="timeline3d__slider"></div>
      <div class="scrollbar" id="timeline3d-scrollbar">
        <div class="scrollbar__thumb" id="timeline3d-scrollbar-thumb"></div>
      </div>
      <div class="timeline3d__variables">

      </div>
    </div>
  `;

  const track = container.querySelector<HTMLDivElement>(
    "#timeline3d-scrollbar",
  )!;
  const thumb = container.querySelector<HTMLDivElement>(
    "#timeline3d-scrollbar-thumb",
  )!;
  const root = container.querySelector<HTMLDivElement>(".timeline3d")!;

  const clamp = (val: number, min: number, max: number) =>
    Math.min(Math.max(val, min), max);

  let thumbX = 0;
  let startX = 0;
  let startOffset = 0;
  let activeId: number | null = null;
  let status = 0;

  const render = (): void => {
    root.style.setProperty("--thumb-x", `${thumbX}px`);

    const maxOffset = track.clientWidth - thumb.clientWidth;
    status = maxOffset ? Math.round((thumbX / maxOffset) * 100) : 0;

    displayVariables([{ status: `${status}%`, title: "status" }]);
  };

  const onPointerMove = (e: PointerEvent) => {
    const dx = e.clientX - startX;
    const maxOffset = track.clientWidth - thumb.clientWidth;
    thumbX = clamp(startOffset + dx, 0, maxOffset);
    render();
  };

  const onPointerUp = () => {
    document.removeEventListener("pointermove", onPointerMove);
    document.removeEventListener("pointerup", onPointerUp);
    if (activeId !== null) {
      thumb.releasePointerCapture(activeId);
      activeId = null;
    }
  };

  thumb.addEventListener("pointerdown", (e: PointerEvent) => {
    activeId = e.pointerId;
    thumb.setPointerCapture(activeId);

    startX = e.clientX;
    startOffset = thumbX;
    document.addEventListener("pointermove", onPointerMove);
    document.addEventListener("pointerup", onPointerUp);
  });

  render();
};
3D TIMELINE
Создали простой скроллбар, который двигается за мышкой, так же вывели статус от 0 до 100%