Skip to content
Luna UI
Luna UI
loading progress bar webcore y2k
installing cuteness.exe

60% · about 2 minutes left

HTML
<div class="tv-webcore-progress" style="--tv-webcore-progress-value: 60%">
  <div class="tv-webcore-progress-bar">
    <span class="tv-webcore-progress-label">installing cuteness.exe</span>
    <span class="tv-webcore-progress-close" aria-hidden="true"></span>
  </div>
  <div class="tv-webcore-progress-track" role="progressbar" aria-label="Installing cuteness.exe" aria-valuemin="0" aria-valuemax="100" aria-valuenow="60">
    <span class="tv-webcore-progress-fill"></span>
  </div>
  <p class="tv-webcore-progress-note">60% · about 2 minutes left</p>
</div>
CSS
/* A pastel pop-up with a segmented block bar. Set the fill with --tv-webcore-progress-value. */
.tv-webcore-progress {
  --tv-webcore-progress-face: var(--tv-webcore-pink, #f7b5e4);
  --tv-webcore-progress-block: color-mix(in srgb, var(--tv-webcore-lilac, #a49bf3) 70%, var(--tv-webcore-navy, #2c2b9f));
  box-sizing: border-box;
  width: 100%;
  max-width: 24rem;
  margin: 0 auto;
  padding: 4px 14px 12px;
  border: 2px solid var(--tv-webcore-lilac, #a49bf3);
  background: var(--tv-webcore-progress-face, #f7b5e4);
  color: var(--tv-webcore-navy, #2c2b9f);
  font-family: "Lucida Console", "Courier New", ui-monospace, monospace;
  box-shadow: 4px 4px 0 color-mix(in srgb, var(--tv-webcore-navy, #2c2b9f) 25%, transparent);
}

.tv-webcore-progress-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: 28px;
}

.tv-webcore-progress-label {
  overflow: hidden;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-overflow: ellipsis;
  text-transform: uppercase;
  white-space: nowrap;
}

.tv-webcore-progress-close {
  position: relative;
  flex-shrink: 0;
  box-sizing: border-box;
  width: 18px;
  height: 16px;
  border: 1px solid var(--tv-webcore-navy, #2c2b9f);
  background: var(--tv-webcore-paper, #ffffff);
}

.tv-webcore-progress-close::before,
.tv-webcore-progress-close::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 10px;
  height: 2px;
  background: var(--tv-webcore-navy, #2c2b9f);
  transform: translate(-50%, -50%) rotate(45deg);
}

.tv-webcore-progress-close::after {
  transform: translate(-50%, -50%) rotate(-45deg);
}

.tv-webcore-progress-track {
  box-sizing: border-box;
  height: 24px;
  margin-top: 6px;
  padding: 3px;
  overflow: hidden;
  border: 1px solid var(--tv-webcore-navy, #2c2b9f);
  background: color-mix(in srgb, var(--tv-webcore-lilac, #a49bf3) 22%, var(--tv-webcore-paper, #ffffff));
}

/* Blocks with gaps: each 10px block is followed by a 3px gap. */
.tv-webcore-progress-fill {
  display: block;
  width: var(--tv-webcore-progress-value, 60%);
  height: 100%;
  background: repeating-linear-gradient(90deg, var(--tv-webcore-progress-block, #7b72d4) 0 10px, transparent 10px 13px);
}

.tv-webcore-progress-note {
  margin: 8px 0 0;
  font-size: 12px;
  letter-spacing: 0.05em;
  text-align: right;
}

.tv-webcore-progress--lilac {
  --tv-webcore-progress-face: var(--tv-webcore-lilac, #a49bf3);
  --tv-webcore-progress-block: var(--tv-webcore-navy, #2c2b9f);
}

/* Busy: no known end, so a short run of blocks marches across the track. */
.tv-webcore-progress--busy .tv-webcore-progress-fill {
  width: 35%;
  animation: tv-webcore-progress-march 1.8s steps(14) infinite;
}

@keyframes tv-webcore-progress-march {
  from { transform: translateX(-100%); }
  to { transform: translateX(290%); }
}

@media (prefers-reduced-motion: reduce) {
  .tv-webcore-progress--busy .tv-webcore-progress-fill {
    animation: none;
  }
}
Markdown MIT License
Usage & credits
Use when
Fake installers, loading screens, uploads and quest or level progress on Y2K pages.
Avoid when
Precise progress people rely on, or long tasks with no other feedback.
Requires
Set --tv-webcore-progress-value (0% to 100%) and aria-valuenow together. · For the Busy loop, remove aria-valuenow since there is no known end.