HEX
Server: nginx/1.18.0
System: Linux test-ipsremont 5.4.0-214-generic #234-Ubuntu SMP Fri Mar 14 23:50:27 UTC 2025 x86_64
User: ips (1000)
PHP: 8.0.30
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /var/www/quadcode.com/src/components/blocks/main/Kickstart.svelte
<script lang="ts">
  import Button from '../../button/Button.svelte';
  import { popupForm } from '../../../store';
  import { t } from '$lib/translations';
  import { onMount, onDestroy, tick } from 'svelte';
  import Swiper from 'swiper';
  import 'swiper/css';
  import { Pagination } from 'swiper/modules';

  let swiperInstance: Swiper | null = null;
  let activeIndex = 0;
  let progress = 0;
  let progressInterval: number | null = null;
  let slideInterval: number | null = null;
  import desktopImage from '../../../assets/images/main/hero/desktop.webp';
  import mobileImage from '../../../assets/images/main/hero/sample-mobile.webp';

  $: steps = [
    {
      number: '01',
      title: $t('Leave request'),
      description: '',
    },
    {
      number: '02',
      title: $t('Check out the demo'),
      description: $t('Check out our demo to learn everything you need to know about the platform'),
    },
    {
      number: '03',
      title: $t('Customise the platform'),
      description: '',
    },
    {
      number: '04',
      title: $t('Sign the contract'),
      description: '',
    },
    {
      number: '05',
      title: $t('Get brokerage solution'),
      description: '',
    },
  ];

  function startProgress() {
    if (progressInterval !== null) {
      cancelAnimationFrame(progressInterval);
    }

    progress = 0;
    const startTime = Date.now();
    const duration = 3000;

    function updateProgress() {
      const elapsed = Date.now() - startTime;
      const newProgress = Math.min((elapsed / duration) * 100, 100);
      progress = newProgress;

      if (newProgress < 100) {
        progressInterval = requestAnimationFrame(updateProgress);
      } else {
        progressInterval = null;
        progress = 100;
        nextSlide();
      }
    }

    progressInterval = requestAnimationFrame(updateProgress);
  }

  function nextSlide() {
    activeIndex = (activeIndex + 1) % steps.length;
    progress = 0;
    startProgress();
  }

  onMount(async () => {
    await tick();

    const container: HTMLElement | null = document.querySelector('.block-kickstart__swiper');
    if (!container) return;

    swiperInstance = new Swiper(container, {
      modules: [Pagination],
      slidesPerView: 'auto',
      spaceBetween: 20,
      loop: false,
      allowTouchMove: false,
      pagination: {
        enabled: false,
      },
    });

    activeIndex = 0;
    startProgress();
  });

  onDestroy(() => {
    if (progressInterval !== null) {
      cancelAnimationFrame(progressInterval);
    }
    if (slideInterval !== null) {
      clearInterval(slideInterval);
    }
  });
</script>

<div class="block-kickstart">
  <div class="container">
    <div class="block-kickstart__content">
      <h1 class="block-kickstart__title">{@html $t('Kickstart your broker within 14 days')}</h1>
      <div class="block-kickstart__right">
        <p class="block-kickstart__description">
          {@html $t(
            'Fill out the form and chat with our managers to discuss your project and see how quickly you can set up your brokerage business'
          )}
        </p>
        <div class="block-kickstart__button-wrapper">
          <Button text={$t('Leave request')} onClick={() => popupForm.set(true)} />
        </div>
      </div>
    </div>

    <div class="block-kickstart__images">
      <img
        src={desktopImage}
        alt="Desktop trading platform"
        class="block-kickstart__image block-kickstart__image--desktop"
      />
      <img
        src={mobileImage}
        alt="Mobile trading platform"
        class="block-kickstart__image block-kickstart__image--mobile"
      />
    </div>

    <div class="block-kickstart__slider">
      <div class="swiper block-kickstart__swiper">
        <div class="swiper-wrapper">
          {#each steps as step, index (step.number)}
            <div class="swiper-slide">
              <div class="block-kickstart__step" class:active={activeIndex === index}>
                <div class="block-kickstart__step-line-wrapper">
                  <div class="block-kickstart__step-line">
                    {#if activeIndex === index}
                      <div class="block-kickstart__step-progress" style="width: {progress}%" />
                    {:else}
                      <div class="block-kickstart__step-progress" style="width: 0%" />
                    {/if}
                  </div>
                </div>
                <div class="block-kickstart__step-number">{step.number}.</div>
                <div class="block-kickstart__step-title">{step.title}</div>
                {#if step.description}
                  <div class="block-kickstart__step-description">{step.description}</div>
                {/if}
              </div>
            </div>
          {/each}
        </div>
      </div>
    </div>
  </div>
</div>

<style lang="scss">
  @import 'src/scss/variables';
  @import 'src/scss/media';
  @import 'src/scss/mixins';

  .block-kickstart {
    padding: 120px 56px 100px 56px;
    background: #161618;
    overflow-x: hidden;

    @media (max-width: 1366px) {
      padding: 120px 40px 100px 40px;
    }

    @media (max-width: 1365px) {
      padding: 120px 32px;
    }

    @media (max-width: 1023px) {
      padding: 120px 32px 40px 32px;
    }

    @media (max-width: 719px) {
      padding: 120px 24px 40px 24px;
    }

    @media (max-width: 393px) {
      padding: 90px 20px 40px 20px;
    }

    & .container {
      @media (max-width: 1366px) {
        padding: 0;
      }
    }

    &__content {
      display: flex;
      align-items: flex-start;
      gap: 96px;

      @media (max-width: 720px) {
        flex-direction: column;
        gap: 24px;
      }
    }

    &__title {
      flex: 1;
      font-weight: 400;
      font-size: 64px;
      line-height: 72px;
      max-width: 804px;
      background: linear-gradient(180deg, #f9fbfc 0%, #adb1b7 100%);
      -webkit-background-clip: text;
      background-clip: text;
      -webkit-text-fill-color: transparent;
      color: transparent;

      @media (max-width: 1024px) {
        font-size: 56px;
        line-height: 68px;
        max-width: 440px;
      }

      @media (max-width: 720px) {
        font-size: 52px;
        line-height: 64px;
        max-width: 648px;
      }

      @media (max-width: 393px) {
        font-size: 36px;
        line-height: 44px;
      }
    }

    &__right {
      display: flex;
      flex-direction: column;
      gap: 31px;
      flex: 1;
      padding-left: 4px;
      max-width: 424px;

      @media (max-width: 1366px) {
        padding-left: 0;
      }

      @media (max-width: 720px) {
        max-width: 540px;
      }
    }

    &__description {
      color: rgba(255, 255, 255, 0.8);
      font-size: 16px;
      line-height: 24px;
    }

    &__button-wrapper {
      align-self: flex-start;

      :global(.button) {
        padding: 8px 16px;
        font-size: 14px;
        line-height: 20px;
        width: fit-content;
        font-weight: 450;
      }
    }

    &__images {
      background: #28282c;
      padding: 56px 56px 0 56px;
      margin-top: 58px;
      border-radius: 32px;
      display: flex;
      justify-content: center;
      gap: 32px;
      overflow: hidden;
      position: relative;
      height: 388px;

      @media (max-width: 720px) {
        gap: 16px;
        padding: 32px 0px 0 24px;
        height: 364px;
        justify-content: flex-start;
      }

      @media (max-width: 480px) {
        height: 308px;
      }

      @media (max-width: 393px) {
        gap: 8px;
        padding: 32px 0px 0 24px;
        height: 208px;
        justify-content: flex-start;
        border-radius: 16px;
      }
    }

    &__image {
      max-width: 100%;
      object-fit: contain;
      object-position: bottom;
      height: auto;
      margin-top: auto;
      align-self: flex-end;

      &--desktop {
        flex: 1;
        max-width: 80%;

        @media (max-width: 1366px) {
          width: 872px;
          max-width: 872px;
          flex: 0 0 872px;
        }

        @media (max-width: 1365px) {
          width: 594px;
          max-width: 594px;
          flex: 0 0 594px;
        }

        @media (max-width: 1024px) {
          width: 594px;
          max-width: 594px;
          flex: 0 0 594px;
        }

        @media (max-width: 720px) {
          order: 2;
          width: 800px;
          max-width: none;
          flex: none;
          object-fit: cover;
          object-position: left center;
        }

        @media (max-width: 480px) {
          width: 480px;
          max-width: 480px;
        }

        @media (max-width: 480px) {
          width: 440px;
          max-width: 440px;
        }
      }

      &--mobile {
        max-width: 270px;

        @media (max-width: 720px) {
          order: 1;
          width: 176px;
          max-width: 176px;
          object-fit: cover;
        }

        @media (max-width: 480px) {
          width: 160px;
          max-width: 160px;
        }

        @media (max-width: 393px) {
          width: 106px;
          height: 223px;
          max-width: 106px;
        }
      }
    }

    &__slider {
      margin-top: 58px;
      overflow: visible;
    }

    &__swiper {
      padding-bottom: 60px;

      @media (max-width: 720px) {
        padding-bottom: 80px;
        height: 200px;
      }

      :global(.swiper-wrapper) {
        display: flex;
        width: 100%;

        @media (max-width: 1365px) {
          justify-content: center;
        }

        @media (max-width: 1024px) {
          justify-content: flex-start;
        }
      }
    }

    &__step {
      position: relative;
      padding-top: 24px;
      padding-bottom: 16px;
      display: flex;
      flex-direction: column;
      gap: 16px;
      flex: 1 1 0;
      min-width: 0;
      align-items: flex-start;
      overflow: visible;
      transition: width 0.3s ease, flex 0.3s ease;

      @media (max-width: 720px) {
        gap: 12px;
        padding-top: 16px;
        padding-bottom: 12px;
      }

      &.active {
        flex: 0 0 427px;
        width: 427px;

        @media (max-width: 720px) {
          flex: 0 0 234px;
          width: 234px;
        }

        @media (max-width: 480px) {
          flex: 0 0 168px;
          width: 168px;
        }

        @media (max-width: 393px) {
          flex: 0 0 168px;
          width: 168px;
        }
      }
    }

    &__step-line-wrapper {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      height: 2px;
    }

    &__step-line {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      height: 2px;
      background: rgba(255, 255, 255, 0.1);
      opacity: 1;
    }

    &__step-line {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      height: 2px;
      background: rgba(255, 255, 255, 0.1);
      opacity: 1;
    }

    &__step-progress {
      position: absolute;
      top: 0;
      left: 0;
      height: 100%;
      background: $redPrimary;
      transition: width 0.1s linear;
    }

    &__step-number {
      font-size: 16px;
      line-height: 20px;
      color: rgba(255, 255, 255, 0.6);
      transition: color 0.3s ease;
    }

    &__step.active &__step-number {
      color: rgba(255, 255, 255, 0.6);
    }

    &__step-title {
      font-size: 16px;
      line-height: 24px;
      font-weight: 400;
      color: #f9fbfc;
      transition: color 0.3s ease;

      @media (max-width: 720px) {
        font-size: 14px;
        line-height: 20px;
      }

      @media (max-width: 880px) {
        display: none;
      }
    }

    &__step.active &__step-title {
      color: $techWhite;

      @media (max-width: 880px) {
        display: block;
      }
    }

    &__step-description {
      position: absolute;
      top: 100%;
      left: 0;
      font-size: 16px;
      line-height: 20px;
      font-weight: 400;
      color: #7d8387;
      opacity: 0;
      pointer-events: none;
      transition: opacity 0.3s ease;
      max-width: 427px;

      @media (max-width: 393px) {
        font-size: 14px;
        line-height: 20px;
      }
    }

    &__step.active &__step-description {
      opacity: 1;
    }

    &__swiper :global(.swiper-slide) {
      height: auto;
      flex: 1 1 0;
      min-width: 0;
      transition: flex 0.3s ease, width 0.3s ease;

      &:has(.block-kickstart__step.active) {
        flex: 0 0 427px;
        width: 427px;

        @media (max-width: 720px) {
          flex: 0 0 234px;
          width: 234px;
        }

        @media (max-width: 480px) {
          flex: 0 0 168px;
          width: 168px;
        }

        @media (max-width: 393px) {
          flex: 0 0 168px;
          width: 168px;
        }
      }

      @media (max-width: 1024px) {
        margin-right: 24px !important;
      }

      @media (max-width: 480px) {
        margin-right: 16px !important;
      }
    }
  }
</style>