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/fintechfuel/src/routes/[...lang=locale]/(app)/Devices.svelte
<script lang="ts">
  import playCircle from '../../../assets/images/play-circle.svg';
  import { browser } from '$app/environment';
  import close from '../../../assets/images/close.svg';
  import play from '../../../assets/images/play.svg';
  import pause from '../../../assets/images/pause.svg';
  import { loadEvent } from '../../../store';
  import loadObserver from '../../../utils/loadObserver';
  import { t } from '$lib/translations';

  let showPopup = false;
  let timeM = 0;
  let timeB = 0;
  let timeD = 0;
  let durationM = 0;
  let durationB = 0;
  let durationD = 0;
  let paused = false;

  function format(seconds) {
    if (isNaN(seconds)) return '...';

    const minutes = Math.floor(seconds / 60);
    seconds = Math.floor(seconds % 60);
    if (seconds < 10) seconds = '0' + seconds;

    return `${minutes}:${seconds}`;
  }

  const onMouse = () => {
    const list = document.querySelector('.devicesList');
    let cursor = document.querySelector('.devicesCursor');

    if (list) {
      list.addEventListener('mousemove', (e) => {
        cursor = document.querySelector('.devicesCursor');
        if (!cursor) return false;

        cursor.style.opacity = 1;
        cursor.style.position = 'fixed';
        cursor.style.left = e.clientX + -75 + 'px';
        cursor.style.top = e.clientY + -22 + 'px';
      });

      list.addEventListener('mouseleave', () => {
        cursor = document.querySelector('.devicesCursor');
        if (!cursor) return false;

        cursor.style.opacity = 0;
      });
    }

    const items = document.querySelectorAll('.devicesItem');

    if (items.length) {
      items.forEach((item) => {
        if (!item) return false;

        item.addEventListener('mousemove', () => {
          items.forEach((item) => {
            item.classList.add('opacity');
          });
          item.classList.add('hover');
        });

        item.addEventListener('mouseleave', () => {
          items.forEach((item) => {
            item.classList.remove('opacity');
          });
          item.classList.remove('hover');
        });
      });
    }
  };

  if (browser) {
    const matches = window.matchMedia('(min-width: 1024px)').matches;

    window.addEventListener('resize', function () {
      if (matches) {
        onMouse();
      }
    });

    if (matches) {
      onMouse();

      const items = document.querySelectorAll('.devicesItem');

      if (items?.length) {
        items.forEach((item) => {
          const close = item.querySelector('.devicesPopupClose');
          const controls = item.querySelector('.devicesPopupVideoControls');
          const video = item.querySelector('.devicesPopupVideo video');

          item.addEventListener('click', () => {
            if (video && !showPopup) {
              if (!video.src) {
                video.src = item.dataset.src;
              }

              video.play();
              paused = false;
            }

            item.classList.add('show');
            item.style.zIndex = 2;
            showPopup = true;
          });

          if (controls) {
            controls.addEventListener('click', () => {
              setTimeout(() => {
                if (paused) {
                  video?.play();
                  paused = false;
                } else {
                  video?.pause();
                  paused = true;
                }
              }, 1);
            });
          }

          if (close) {
            close.addEventListener('click', () => {
              setTimeout(() => {
                item.classList.remove('show');
                showPopup = false;

                if (video) {
                  video.pause();
                  paused = true;
                }
              }, 1);

              setTimeout(() => {
                item.style.zIndex = 'unset';
              }, 300);
            });
          }
        });
      }
    } else {
      const items = document.querySelectorAll('.devicesItem');

      if (items?.length) {
        items.forEach((item) => {
          setTimeout(() => {
            const video = item.querySelector('.devicesPopupVideo video');

            video.src = item.dataset.src;
          }, 100);
        });
      }
    }
  }

  const onload = loadObserver(() => {
    loadEvent.set(true);
  });
</script>

<div class="devices">
  <div class="devicesContent">
    <h2 class="devicesTitle">{$t('Available on all devices')}</h2>
    <p class="devicesText">{$t('Enable your clients to trade on the go and never miss an opportunity.')}</p>
  </div>
  <div class="devicesList">
    {#if !showPopup}
      <div class="devicesCursor">
        <p>{$t('How it works')}</p>
        <img src={playCircle} alt="" />
      </div>
    {/if}
    <div
      class="devicesItem mobile"
      data-src="../devices/mobile.MP4"
      data-poster="../devices/iphone-poster.png"
      data-name={$t('Mobile Apps')}
      data-system="iOS · Android"
      data-img="../devices/iphone.png"
      data-mask="../devices/iphone-mask.svg"
      data-type="mobile"
    >
      <div class="devicesPopup mobile">
        <div class="devicesPopupClose">
          <img src={close} alt="" />
        </div>
        <div class="devicesPopupVideoControls">
          {#if paused}
            <img src={play} alt="" />
          {:else}
            <img src={pause} alt="" />
          {/if}
        </div>
        <div class="devicesPopupVideoTime">{format(durationM - timeM)}</div>
        <div class="devicesPopupContainer">
          <div class="devicesPopupVideo">
            <video
              style="-webkit-mask-image: url(../devices/iphone-mask.svg)"
              poster="../devices/static/mobile.png"
              loop
              muted
              autoplay
              playsinline
              bind:duration={durationM}
              bind:currentTime={timeM}
            />
          </div>
          <div class="devicesPopupImg">
            <img use:onload src="../devices/static/mobile.png" alt="" />
          </div>
        </div>
      </div>
      <div class="devicesItemContent">
        <p class="devicesContentName">{$t('Mobile Apps')}</p>
        <p class="devicesContentSystem">iOS · Android</p>
      </div>
    </div>
    <div
      class="devicesItem browser"
      data-src="../devices/browser.mp4"
      data-poster="../devices/browser-poster.png"
      data-name={$t('All browsers')}
      data-system="Safari · Chrome · Opera and etc."
      data-chevron={$t('PWA version by request')}
      data-img="../devices/browser.png"
      data-mask="../devices/browser-mask.svg"
      data-type="browser"
    >
      <div class="devicesPopup browser">
        <div class="devicesPopupClose">
          <img src={close} alt="" />
        </div>
        <div class="devicesPopupVideoControls">
          {#if paused}
            <img src={play} alt="" />
          {:else}
            <img src={pause} alt="" />
          {/if}
        </div>
        <div class="devicesPopupVideoTime">{format(durationB - timeB)}</div>
        <div class="devicesPopupContainer">
          <div class="devicesPopupVideo">
            <video
              style="-webkit-mask-image: url(../devices/browser-mask.svg)"
              poster="../devices/browser-poster.png"
              loop
              muted
              autoplay
              playsinline
              bind:duration={durationB}
              bind:currentTime={timeB}
            />
          </div>
          <div class="devicesPopupImg">
            <img use:onload src="../devices/static/browser.png" alt="" />
          </div>
        </div>
      </div>
      <div class="devicesItemContent">
        <p class="devicesContentName">{$t('All browsers')}</p>
        <p class="devicesContentSystem">Safari · Chrome · Opera and etc.</p>
        <p class="devicesContentChevron">{$t('PWA version by request')}</p>
      </div>
    </div>
    <div
      class="devicesItem desktop"
      data-src="../devices/desktop-x2.mp4"
      data-poster="../devices/desktop-poster.png"
      data-name={$t('Standalone OS Apps')}
      data-system="Windows · MacOS"
      data-img="../devices/desktop.png"
      data-mask="../devices/desktop-mask.svg"
      data-type="desktop"
    >
      <div class="devicesPopup desktop">
        <div class="devicesPopupClose">
          <img src={close} alt="" />
        </div>
        <div class="devicesPopupVideoControls">
          {#if paused}
            <img src={play} alt="" />
          {:else}
            <img src={pause} alt="" />
          {/if}
        </div>
        <div class="devicesPopupVideoTime">{format(durationD - timeD)}</div>
        <div class="devicesPopupContainer">
          <div class="devicesPopupVideo">
            <video
              style="-webkit-mask-image: url(../devices/desktop-mask.svg)"
              poster="../devices/static/desktop.png"
              loop
              muted
              autoplay
              playsinline
              bind:duration={durationD}
              bind:currentTime={timeD}
            />
          </div>
          <div class="devicesPopupImg">
            <img use:onload src="../devices/static/desktop.png" alt="" />
          </div>
        </div>
      </div>
      <div class="devicesItemContent">
        <p class="devicesContentName">{$t('Standalone OS Apps')}</p>
        <p class="devicesContentSystem">Windows · MacOS</p>
      </div>
    </div>
  </div>
</div>

<style lang="scss">
  @import '../../../scss/media';

  .devices {
    .devicesContent {
      max-width: 790px;
      margin-inline: auto;
      margin-bottom: 72px;

      @include breakpoint-down('tabM') {
        max-width: 544px;
      }

      @include breakpoint-down('tabS') {
        margin-bottom: 64px;
      }

      @include breakpoint-down('mobM') {
        margin-bottom: 56px;
      }
    }

    .devicesCursor {
      position: absolute;
      display: flex;
      align-items: center;
      gap: 8px;
      z-index: 1;
      background: #fe4d0d;
      padding: 10px 20px;
      border-radius: 16px;
      white-space: nowrap;
      opacity: 0;
      pointer-events: none;

      @include breakpoint-down('tabM') {
        display: none;
      }

      > p {
        font-size: 16px;
        font-weight: 500;
        line-height: 24px;
        letter-spacing: 0.005em;
        color: #ffffff;
      }

      > img {
        width: 20px;
        height: 20px;
      }
    }

    .devicesTitle {
      text-align: center;
      margin-bottom: 24px;
      font-size: 72px;
      font-weight: 600;
      line-height: 94px;

      @include breakpoint-down('tabM') {
        font-size: 48px;
        line-height: 58px;
      }

      @include breakpoint-down('mobM') {
        font-size: 32px;
        line-height: 42px;
      }
    }

    .devicesText {
      text-align: center;
      font-size: 24px;
      font-weight: 400;
      line-height: 36px;

      @include breakpoint-down('tabM') {
        font-size: 22px;
        line-height: 33px;
      }

      @include breakpoint-down('tabS') {
        font-size: 20px;
        line-height: 30px;
      }

      @include breakpoint-down('mobM') {
        font-size: 18px;
        line-height: 27px;
      }
    }

    .devicesList {
      display: flex;
      position: relative;
      min-height: 869px;
      cursor: none !important;

      @include breakpoint-down('deskS') {
        min-height: 692px;
      }

      @include breakpoint-down('tabM') {
        flex-direction: column;
        width: 100%;
        max-width: 544px;
        margin-inline: auto;
        cursor: auto !important;
      }
    }

    .devicesItem {
      position: absolute;
      background: #faf9f8;
      width: calc(100% / 3);
      transition: 0.3s ease-in-out;

      @include breakpoint-down('tabM') {
        position: unset !important;
        transform: none !important;
        width: 100%;
        display: flex;
        flex-direction: column-reverse;
        margin-bottom: 72px;

        &:last-of-type {
          margin-bottom: 0;
        }
      }

      @include breakpoint-down('mobM') {
        position: relative;
        left: -16px;
        right: -16px;
        width: calc(100% + 16px + 16px);
        margin-left: -16px;
        margin-bottom: 56px;
      }

      &.mobile {
        left: 0;
        top: 0;
        bottom: 0;
      }

      &.browser {
        left: 50%;
        transform: translateX(-50%);
        top: 0;
        bottom: 0;
      }

      &.desktop {
        right: 0;
        top: 0;
        bottom: 0;
      }

      &.opacity {
        .devicesPopup {
          opacity: 0.6;
        }
      }

      &.hover {
        .devicesPopup {
          opacity: 1;
        }
      }
    }

    .devicesPopup {
      margin-bottom: 40px;
      padding: 78px 73px 78px 73px;
      overflow: hidden;
      position: relative;
      transition: 0.3s ease-in-out;

      @include breakpoint-down('deskS') {
        height: 550px;
        padding: 60px 55px 60px 55px;
      }

      @include breakpoint-down('tabM') {
        height: 730px;
        margin-top: 40px;
        margin-bottom: 0;
        padding-top: 80px;
        padding-bottom: 80px;
      }

      @include breakpoint-down('tabS') {
        margin-top: 28px;
      }

      @include breakpoint-down('mobM') {
        height: auto;
        padding-top: 44px;
        padding-bottom: 44px;
      }

      &.mobile {
        border-radius: 24px 0 0 24px;
        background: #caccc4;

        @include breakpoint-down('tabM') {
          border-radius: 20px;
          padding-left: 133px;
          padding-right: 133px;
        }

        @include breakpoint-down('tabS') {
          padding-left: 75px;
          padding-right: 75px;
        }

        @include breakpoint-down('mobM') {
          border-radius: 0;
          padding-left: 41px;
          padding-right: 41px;
        }

        .devicesPopupContainer {
          width: 278px;
          height: 572px;
          margin-inline: auto;
          overflow: hidden;
          position: relative;

          @include breakpoint-down('deskS') {
            height: 432px;
            width: 210px;
          }

          @include breakpoint-down('tabM') {
            height: 100%;
            width: max-content;
          }

          @include breakpoint-down('mobM') {
            width: 100%;
          }

          .devicesPopupVideo {
            width: 278px;
            height: 572px;
            padding: 12px;

            @include breakpoint-down('deskS') {
              height: 432px;
              width: 210px;
              padding: 10px;
            }

            @include breakpoint-down('tabM') {
              height: 100%;
              width: max-content;
            }
          }

          img,
          video {
            width: 100%;
            height: 100%;
            object-fit: contain;
          }
        }
      }

      &.browser {
        background: #d2d4cc;

        @include breakpoint-down('tabM') {
          border-radius: 20px;
          padding-left: 78px;
        }

        @include breakpoint-down('mobM') {
          border-radius: 0;
          padding-left: 56px;
        }

        .devicesPopupContainer {
          width: 982px;
          height: 572px;
          margin-inline: auto;
          overflow: hidden;
          position: relative;

          @include breakpoint-down('deskS') {
            height: 432px;
            width: 741px;
          }

          @include breakpoint-down('tabM') {
            height: 100%;
            width: max-content;
          }

          .devicesPopupVideo {
            width: 982px;
            height: 572px;
            padding-top: 52px;

            @include breakpoint-down('deskS') {
              height: 432px;
              width: 741px;
              padding-top: 39px;
            }

            @include breakpoint-down('tabM') {
              height: 100%;
              width: max-content;
              padding-top: 52px;
            }
          }

          img,
          video {
            width: 100%;
            height: 100%;
            display: block;
            object-fit: contain;
          }
        }
      }

      &.desktop {
        background: #dee0da;
        border-radius: 0 24px 24px 0;

        @include breakpoint-down('tabM') {
          border-radius: 20px;
          padding-left: 66px;
        }

        @include breakpoint-down('mobM') {
          border-radius: 0;
          padding-left: 44px;
        }

        .devicesPopupContainer {
          width: 935px;
          height: 572px;
          margin-inline: auto;
          overflow: hidden;
          position: relative;

          @include breakpoint-down('deskS') {
            height: 432px;
            width: 706px;
          }

          @include breakpoint-down('tabM') {
            height: 100%;
            width: max-content;
          }

          .devicesPopupVideo {
            width: 935px;
            height: 572px;
            padding: 22px 74px 25px 74px;

            @include breakpoint-down('deskS') {
              height: 432px;
              width: 706px;
              padding: 18px 46px 18px 56px;
            }

            @include breakpoint-down('tabM') {
              height: 100%;
              width: max-content;
              padding: 22px 74px 25px 74px;
            }
          }

          img,
          video {
            width: 100%;
            height: 100%;
            display: block;
            object-fit: contain;
          }
        }
      }
    }

    .devicesPopupClose {
      border-radius: 24px;
      border: 1px solid #d9d7cc;
      background: #faf9f8;
      height: 44px;
      width: 44px;
      display: flex;
      align-items: center;
      justify-content: center;
      position: absolute;
      top: 32px;
      right: 32px;
      cursor: pointer;
      z-index: 2;
      opacity: 0;
      pointer-events: none;
      transition: 0s ease-in-out;

      &:hover {
        background: #f0ede8;
        border: 1px solid #f0ede8;
      }

      &:active {
        background: #d9d7cc;
        border: 1px solid #d9d7cc;
      }
    }

    .devicesPopupVideoControls {
      cursor: pointer;
      position: absolute;
      right: 32px;
      bottom: 32px;
      opacity: 0;
      pointer-events: none;
      transition: 0s ease-in-out;

      &:hover {
        right: 30px;
        bottom: 30px;
        img {
          width: 48px;
          height: 48px;
        }
      }
    }

    .devicesPopupVideoTime {
      position: absolute;
      left: 32px;
      bottom: 44px;
      opacity: 0;
      pointer-events: none;
      transition: 0s ease-in-out;
    }

    .devicesPopupVideo {
      position: absolute;
      left: 0;
      top: 0;
      opacity: 0;
      pointer-events: none;
      transition: 0s ease-in-out;

      @include breakpoint-down('tabM') {
        opacity: 1;
      }

      video {
        -webkit-mask-repeat: no-repeat;
        mask-repeat: no-repeat;

        -webkit-mask-position: center;
        mask-position: center;

        -webkit-mask-size: 100%;
        mask-size: 100%;
      }
    }

    .devicesItemContent {
      display: flex;
      flex-direction: column;
      align-items: center;
    }

    .devicesContentName {
      margin-bottom: 4px;
      font-size: 18px;
      font-weight: 600;
      line-height: 27px;
      letter-spacing: 0.005em;
      text-align: center;
    }

    .devicesContentSystem {
      color: #73726c;
    }

    .devicesContentChevron {
      background: #dee0da;
      border-radius: 8px;
      padding: 6px 10px;
      margin-top: 16px;
      font-size: 14px;
      font-weight: 400;
      line-height: 18px;
    }
  }

  :global(.devicesItem.show) {
    width: 100% !important;
    z-index: 3 !important;
    cursor: auto !important;

    .devicesPopup {
      border-radius: 24px;
    }

    .devicesPopupClose,
    .devicesPopupVideoControls,
    .devicesPopupVideoTime,
    .devicesPopupVideo {
      opacity: 1;
      pointer-events: all;
    }
  }
</style>