@mixin circle($r: 2em) {
  width: $r;
  height: $r;
  border-radius: 50%;
}

@mixin center {
  display: flex;
  justify-content: center;
  align-items: center;
}

body {
  @include center;
  height: 100vh;
  background: #1a1e23;
}

.progress {
  --value: 0;
  --dark-color: rgba(0, 0, 0, 0.25);
  --light-color: cyan;
  --duration: 3s;
  position: relative;
  width: 25em;
  height: 1em;
  animation: loading var(--duration) ease-out forwards;

  .progress-bar {
    height: inherit;
    background: var(--dark-color);

    .progress-value {
      width: calc(var(--value) * 1%);
      height: inherit;
      background: var(--light-color);
    }

    .progress-indicator {
      @include circle;
      position: absolute;
      top: -13px;
      left: calc(-12px + var(--value) * 4.3px);
      z-index: 2;
      background: #222;
      border: 4px solid var(--light-color);
      counter-reset: progress var(--value);

      &::after {
        @include center;
        position: absolute;
        // var() doesn't work cuz content only accepts string, so use counter()
        content: counter(progress) "%";
        width: 100%;
        height: 100%;
        color: var(--light-color);
        font-size: 9px;
      }
    }
  }

  .progress-start {
    @include circle;
    position: absolute;
    top: -13px;
    left: -12px;
    background: #222;
    border: 4px solid var(--light-color);

    svg {
      @include center;
      width: 100%;
      height: 100%;
      transform: scale(0.6);
    }
  }

  .progress-end {
    @include circle;
    position: absolute;
    top: -13px;
    right: -12px;
    background: #222;
    border: 4px solid var(--dark-color);

    svg {
      @include center;
      width: 100%;
      height: 100%;
      transform: scale(0.6);
      opacity: 0.25;
    }
  }
}

@keyframes loading {
  @for $i from 0 through 100 {
    #{$i}% {
      --value: #{$i};
    }
  }
}
