body {
    background: #0b0b0b;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
  }

.container {
  --animation-duration: 5s;
  --circle-bg-clr: #111;
  
  --ellipse-perimeter: 314; /* approximate perimeter of your ellipse */
  --line-length: 5;         /* visible segment */
  
    /* calculate line dash based on radius and line length */
  --line-dash: calc(var(--ellipse-perimeter) - var(--line-length));
  

    width: 600px;
    height: 400px;
    position: relative;
  }

  svg {
    width: 100%;
    height: 100%;
    display: block;
  }

  .oval {
    fill: none;
    stroke: #0ff2;
    stroke-width: .5;
  }

.path-line {
  fill: none;
  stroke: #0ff;
  stroke-width: 1;
  stroke-linecap: round;
  stroke-dasharray: var(--line-length) var(--line-dash);
  stroke-dashoffset: 0;

  animation: moveLine var(--animation-duration) linear infinite;
}
/* clearly this would be simpler done in JS but I like a challenge */
@keyframes moveLine {
  0%,8%     { stroke-dashoffset: -12; }  /* pause at 1st circle */
  15%,23%   { stroke-dashoffset: -52; }   /* 2nd circle */
  33%,41% { stroke-dashoffset: -110; }    /* 3rd circle */
  51%,59%   { stroke-dashoffset: -170; }  /* 4th circle */ 
  67%,75%   { stroke-dashoffset: -210; }  /* 5th circle */
  85%,93% { stroke-dashoffset: -270; } /* 6th circle */
  100%        { stroke-dashoffset: -324; } /* end */
}





  /* HTML circles (content placeholders) */
 .circle {
  position: absolute;
  top: var(--circle-y);
  left: var(--circle-x);
  translate: -50% -50%;
  width: 100px;
  aspect-ratio: 1;
   background-color: var(--circle-bg-clr);
  /*opacity: .5;*/
  border: 2px solid #333;
  color: white;
  border-radius: 50%;
 
  /* Use calculated delay per circle */
  animation: pulse var(--animation-duration) linear infinite;
}

.circle:nth-of-type(1) { --circle-x: 30%; --circle-y: 15%; --stop-index: 0; }
.circle:nth-of-type(2) { --circle-x: 70%; --circle-y: 15%; --stop-index: 1; }
.circle:nth-of-type(3) { --circle-x: 99%; --circle-y: 50%; --stop-index: 2; }
.circle:nth-of-type(4) { --circle-x: 70%; --circle-y: 85%; --stop-index: 3; }
.circle:nth-of-type(5) { --circle-x: 30%; --circle-y: 85%; --stop-index: 4; }
.circle:nth-of-type(6) { --circle-x: 1%; --circle-y: 50%; --stop-index: 5; }


/* Calculate animation-delay */
.circle {
  animation-delay: calc((var(--animation-duration) * var(--stop-index)  / 6) - 250ms);
  & svg{
    /* opacity: var(--icon-opacity,.5);*/
    scale: var(--icon-scale, .5);
    transition-property: opacity,scale;
    transition-duration:150ms;
    transition-timing-function: ease-in-out;
  }
  &.heart > svg{
    color:red;
  }
  &.battery > svg{
    color: green;
  }
  &.notes > svg{
    color: dodgerblue;
  }
  &.parcel > svg{
    color: yellow;
  }
  &.scooter > svg{
    color: orange
  }
  &.security > svg{
    color: purple;
  }
}


 @keyframes pulse {
  5%,13% { 
    scale: 1.2; 
    border-color:#0ff;
    background-color: rgb(5, 51, 69);
    --icon-opacity: 1;
    --icon-scale: .8;
  } 
   
  15% { 
    scale: 1; 
    border-color:#222;
    background-color: var(--circle-bg-clr);
    --icon-opacity: .5;
    --icon-scale: .5;
  }
}