Manifest scan, single beat
Variant: Single beat
A background integrity check on a list of records: a scan line sweeps the rows, and one unlisted row that was sitting quietly at the same opacity as its neighbours gets flagged as it passes. Reach for it as an ambient status indicator on an audit or validation panel — it explains what the system is doing rather than just spinning. The scan itself is linear because it is constant machine motion, while the flag uses ease-out so the detection reads as instant on arrival. This sibling runs the whole detect-and-clear cycle as one quick beat, for a dense panel where the check should feel routine.
The source
A complete HTML document. Paste it into an empty .html file and it plays — no stylesheet, script, font, or image to fetch.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Manifest scan — single beat</title>
<style>
:root {
/* Neutrals — fixed, never remixed. */
--ivory: #faf9f5;
--paper: #ffffff;
--oat: #e3dacc;
--slate: #141413;
/* Knobs — the remix API. A knob exists iff declared here and used below. */
--hue: 38.8;
--lift: 0;
--chroma: 1;
--round: 1;
--speed: 1;
/* Accents — derived from the knobs with the family's offsets baked in,
so one hue roll moves them together. Defaults reproduce the original hex
(#d97757 / #b85c3e / #788c5d / #b04a3f). */
--clay: oklch(calc(0.6724 + var(--lift)) calc(0.1308 * var(--chroma)) var(--hue));
--clay-d: oklch(calc(0.5797 + var(--lift)) calc(0.127 * var(--chroma)) var(--hue));
--olive: oklch(calc(0.6118 + var(--lift)) calc(0.0713 * var(--chroma)) calc(var(--hue) + 88.3));
--rust: oklch(calc(0.5408 + var(--lift)) calc(0.1357 * var(--chroma)) calc(var(--hue) - 10.3));
/* Clock — every duration in the document runs off --t. */
--cycle: 2.6s;
--t: calc(var(--cycle) / var(--speed));
--ease-out: cubic-bezier(0.23, 1, 0.32, 1);
}
* { box-sizing: border-box; }
body {
margin: 0;
min-height: 100vh;
display: grid;
place-items: center;
background: var(--ivory);
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
color: var(--slate);
}
.panel {
position: relative;
width: min(360px, 90vw);
padding: clamp(12px, 3.4vw, 18px);
background: var(--paper);
border: 1px solid var(--oat);
border-radius: calc(12px * var(--round));
overflow: hidden;
}
.head {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
font-size: clamp(11px, 2.9vw, 12.5px);
letter-spacing: 0.06em;
text-transform: uppercase;
color: color-mix(in oklab, var(--slate) 55%, var(--paper));
margin-bottom: clamp(10px, 2.6vw, 14px);
}
.pip {
width: 7px;
height: 7px;
border-radius: 50%;
background: var(--olive);
animation: pip var(--t) linear infinite;
}
.rows {
position: relative;
display: grid;
gap: clamp(7px, 1.9vw, 9px);
}
.row {
position: relative;
display: flex;
align-items: center;
gap: 9px;
height: clamp(20px, 5.4vw, 24px);
padding: 0 8px;
border-radius: calc(6px * var(--round));
background: color-mix(in oklab, var(--oat) 26%, var(--paper));
}
.bar {
height: 5px;
border-radius: 999px;
background: color-mix(in oklab, var(--slate) 22%, var(--paper));
}
.tick {
width: 10px;
height: 10px;
flex: 0 0 auto;
border-radius: 50%;
border: 1.5px solid color-mix(in oklab, var(--slate) 24%, var(--paper));
}
/* The unlisted row: identical to its neighbours until the scan reaches it. */
.row.stow {
background: color-mix(in oklab, var(--oat) 26%, var(--paper));
animation: flag var(--t) var(--ease-out) infinite;
}
.row.stow .tick {
animation: flagtick var(--t) var(--ease-out) infinite;
}
.row.stow .bar {
animation: flagbar var(--t) var(--ease-out) infinite;
}
.scan {
position: absolute;
left: -6%;
right: -6%;
top: 0;
height: 34%;
pointer-events: none;
background: linear-gradient(
to bottom,
transparent 0%,
color-mix(in oklab, var(--clay) 12%, transparent) 62%,
var(--clay) 100%
);
animation: sweep var(--t) linear infinite;
}
.foot {
margin-top: clamp(10px, 2.6vw, 13px);
font-size: clamp(11px, 2.8vw, 12px);
color: color-mix(in oklab, var(--slate) 50%, var(--paper));
animation: foot var(--t) var(--ease-out) infinite;
}
/* Sweep crosses the stowaway row (4th of 5) at ~62% of the pass. */
@keyframes sweep {
0% { transform: translateY(-40%); opacity: 0; }
8% { opacity: 1; }
62% { opacity: 1; }
72% { transform: translateY(285%); opacity: 0; }
100% { transform: translateY(285%); opacity: 0; }
}
@keyframes flag {
0%, 58% { background: color-mix(in oklab, var(--oat) 26%, var(--paper)); transform: translateX(0); }
66% { background: color-mix(in oklab, var(--rust) 16%, var(--paper)); transform: translateX(2.2%); }
86% { background: color-mix(in oklab, var(--rust) 14%, var(--paper)); transform: translateX(2.2%); }
100% { background: color-mix(in oklab, var(--oat) 26%, var(--paper)); transform: translateX(0); }
}
@keyframes flagtick {
0%, 58% { border-color: color-mix(in oklab, var(--slate) 24%, var(--paper)); transform: scale(0.97); }
66% { border-color: var(--rust); transform: scale(1); }
86% { border-color: var(--rust); transform: scale(1); }
100% { border-color: color-mix(in oklab, var(--slate) 24%, var(--paper)); transform: scale(0.97); }
}
@keyframes flagbar {
0%, 58% { background: color-mix(in oklab, var(--slate) 22%, var(--paper)); }
66%, 86% { background: var(--rust); }
100% { background: color-mix(in oklab, var(--slate) 22%, var(--paper)); }
}
@keyframes foot {
0%, 58% { opacity: 0.45; color: color-mix(in oklab, var(--slate) 50%, var(--paper)); }
68%, 88% { opacity: 1; color: var(--rust); }
100% { opacity: 0.45; color: color-mix(in oklab, var(--slate) 50%, var(--paper)); }
}
@keyframes pip {
0%, 55% { background: var(--olive); }
68%, 86% { background: var(--rust); }
100% { background: var(--olive); }
}
@media (max-width: 380px) {
.panel { padding: 11px; }
.row { padding: 0 6px; gap: 7px; }
}
@media (prefers-reduced-motion: reduce) {
/* Keep the detection legible as a colour cycle; drop the travelling line. */
.scan { animation: none; opacity: 0; }
.row.stow,
.row.stow .tick,
.row.stow .bar,
.foot,
.pip {
animation-duration: calc(var(--cycle) * 2.4 / var(--speed));
}
@keyframes flag {
0%, 50% { background: color-mix(in oklab, var(--oat) 26%, var(--paper)); transform: none; }
70%, 88% { background: color-mix(in oklab, var(--rust) 14%, var(--paper)); transform: none; }
100% { background: color-mix(in oklab, var(--oat) 26%, var(--paper)); transform: none; }
}
@keyframes flagtick {
0%, 50% { border-color: color-mix(in oklab, var(--slate) 24%, var(--paper)); transform: none; }
70%, 88% { border-color: var(--rust); transform: none; }
100% { border-color: color-mix(in oklab, var(--slate) 24%, var(--paper)); transform: none; }
}
}
</style>
</head>
<body>
<div class="panel">
<div class="head">
<span>Manifest check</span>
<span class="pip" aria-hidden="true"></span>
</div>
<div class="rows">
<div class="row"><span class="tick"></span><span class="bar" style="width: 54%"></span></div>
<div class="row"><span class="tick"></span><span class="bar" style="width: 70%"></span></div>
<div class="row"><span class="tick"></span><span class="bar" style="width: 44%"></span></div>
<div class="row stow"><span class="tick"></span><span class="bar" style="width: 62%"></span></div>
<div class="row"><span class="tick"></span><span class="bar" style="width: 50%"></span></div>
<div class="scan" aria-hidden="true"></div>
</div>
<div class="foot">1 record not on the manifest</div>
</div>
</body>
</html>
The variant family
Same idea, one axis moved. Compare them side by side before you commit.