<graph>
  <text split>CSS is Awesome</text>
  <belt split="21"></belt>
  <tree split="13"></tree>
  <tree split="13" outer></tree>
  <star split="21"></star>
  <circle></circle>
  <arrow></arrow>
</graph>


<warning>
  Your browser doesn't support 
  <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Motion_Path">CSS Motion Path</a>
</warning>


<script>
  /* You may want to use splitting.js */ 
 Array.from(document.querySelectorAll('[split]') || []).forEach(el => {
   let text = el.innerHTML.trim();
   let total = text.length || Number(el.getAttribute('split')) || 0;
   el.style.setProperty('--total', total);
   el.innerHTML = Array(total).fill(0)
     .map((n, i) => `<span style="--n:${i}">${text[i]||''}</span>`)
     .join('');
 });
</script>
html, body {
  height: 100%;
  margin: 0;
}
body { 
  display: grid; 
  place-content: center;  
}

graph {
  width: 400px; height: 400px;
  border: 10px double #000; 
  border-radius: 50%;
  position: relative;
  overflow: hidden;
  background: linear-gradient(#000, #000) 50% / 100% 2px no-repeat;
  font-family: 'PT Mono', monospace;
  text-transform: uppercase;
  line-height: 1;
  
  &:before {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    width: 58%; height: 58%;
    transform: translate(-50%, -50%) rotate(-135deg);
    border: 6px double;
    border-radius: 50%;
    border-color: #000 transparent transparent #000;
  }
  
  &:after {
    content: '♥';
    position: absolute;
    left: 50%; top: 50%;
    transform: translate(-50%, -50%);
    font-family: 'Nanum Gothic', sans-serif;
    font-size: 80px;
    color: transparent;
    text-shadow: 0 0 #000;
  }
  
  --circle-up-path: path('M 0 200 A 200 200 0 0 1 400 200');
  --circle-down-path: path('M 0 200 A 200 200 0 0 0 400 200');
}

[split] > * {
  position: absolute;
}

text > * {
  font-size: 50px;
  transform: translateY(75%);
  offset-path: var(--circle-up-path); 
  offset-distance: calc(8% + var(--n) * 89.5% / var(--total));
}

belt > * {
  transform: translateY(-40px);
  offset-path: var(--circle-down-path); 
  offset-distance: calc(7% + var(--n) * 91% / var(--total));
  width: 18px; height: 16px;
  background: #000;
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
  &:nth-child(even) {
    clip-path: circle(30%);
  }
}

tree > * {
  width: 2px; height: 30px;
  transform: translateY(-98px);
  background: #000;
  offset-path: var(--circle-down-path); 
  offset-distance: calc(5% + var(--n) * 98% / var(--total));
  
  &:after {
    content: '';
    position: absolute;
    top: -10px;
    left: calc(50% - 4px);
    width: 8px; height: 8px;
    border-radius: 50%;
    background: #000;
  }
  
  &:nth-child(even) {
    height: 15px;
    transform: translateY(-90px);
  }
}

tree[outer] > * {
  offset-path: var(--circle-up-path); 
  transform: translateY(128px);
  height: 60px;
  &:nth-child(odd) {
    height: 30px;
  }
}

star > * {
  offset-path: var(--circle-down-path); 
  offset-distance: calc(6% + var(--n) * 93% / var(--total));
  transform: translateY(-15px);
  &:after {
    content: '***';
    font-family: verdana;
    color: #000;
    font-size: 13px;
  }
}

circle {
  position: absolute;
  width: 30%; height: 30%;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%) rotate(45deg);
  border: 6px solid #000;
  border-style: double solid solid double;
  border-radius: 50%;
  background: #fff;
}

arrow:after, arrow:before {
  content: '';
  position: absolute;
  top: calc(50% - 11px);
  width: 20px; height: 20px;
  transform: rotateX(45deg) rotate(45deg);
  border: 2px solid #000;
  background: #fff;   
}
arrow:before {
  left: -13px;
}
arrow:after {
  right: -13px;
}


@media screen and (max-width: 440px) {
  graph {
    transform: scale(.5);
  }
}

warning {
  background: yellow;
  position: fixed;
  top: 0;
  width: 100%;
  text-align: center;
  padding: .5em 0;
}

@supports (offset-path: path('M 0 0 z')) {
  warning { display: none }
}
View Compiled

External CSS

  1. https://fonts.googleapis.com/css?family=PT+Mono&amp;display=swap
  2. https://fonts.googleapis.com/css?family=Nanum+Gothic&amp;display=swap

External JavaScript

This Pen doesn't use any external JavaScript resources.