# Webcore progress window

Pastel pop\-up with a segmented block progress bar; set the fill with one CSS variable, or loop it\.

- Kind: element
- Category: misc
- Default background: light
- 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\.
- Kit: [Webcore](https://thuvien.org/ui/kits/webcore.md)
- Credit: [Luna UI](https://thuvien.org/ui)
- License: MIT

## Variants

Add one variant class next to the root element's class.

- [Pink](https://thuvien.org/ui/elements/webcore-progress?variant=pink): default, no extra class
- [Lilac](https://thuvien.org/ui/elements/webcore-progress?variant=lilac): `tv-webcore-progress--lilac`
- [Busy](https://thuvien.org/ui/elements/webcore-progress?variant=busy): `tv-webcore-progress--busy`

## HTML

```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

```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;
  }
}
```
