Redesign an existing website to make it better. Built on top of impeccable.
71
89%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
A small data-* vocabulary that cinematic prototypes apply to
elements they want the motion runtime to animate. The vocabulary is
the declarative contract between the rendered HTML (which states
intent) and the runtime (which executes it).
Mirrors the structural data-section / data-intent vocabulary in
skills/stardust/reference/data-attributes.md but lives in
prototype/reference/ because motion attributes are scoped to
the cinematic feature, not to every prototype.
Three reasons:
<span data-countup="27">0</span> knows the value tweens 0 → 27
without reading any JS. The motion contract is auditable from the
markup.motion-registers.md. Registers differ in which
attributes their templates emit, not in runtime code.On the leaf element whose visual property animates. Not on the
section. The leaf is what getComputedStyle reads, what the
IntersectionObserver observes, and what the rAF loop transforms.
Exception: [data-tile-anim] goes on a tile-shaped container (a
card, an ops-tile) so the entrance affects the whole tile rather
than its individual children.
[data-anim]Type. Scroll-triggered entrance.
Effect. Element enters with opacity 0 → 1 and
translateY(40px → 0) over the scroll range
[trigger - 0.85vh, trigger - 0.5vh].
Stagger. Peers within the same band stagger by ~90ms per index.
Registers that emit. arrival, kinetic-display, editorial,
kinetic-grid. Not live-systems (tiles use [data-tile-anim]).
[data-tile-anim]Type. Scroll-triggered entrance for card / tile containers.
Effect. Element enters with opacity 0 → 1,
translateY(28px → 0), AND rotateX(8deg → 0) — the rotateX adds
depth on cascade-in.
Registers that emit. live-systems, kinetic-grid.
[data-countup="N"]Type. IO-triggered numeric tween (one-shot).
Effect. Element's textContent tweens from 0 to integer N
over a duration scaled by magnitude (target ≤ 5 → 600ms; target ≤
20 → 900ms; otherwise 1400ms). Uses easeOut3.
Element shape. Must contain only the integer; the runtime
replaces textContent on every frame. Use a wrapper for any units
(<span data-countup="27">0</span><span> min</span>).
Registers that emit. All five (every register has at least one
count-up surface — alerts, advisories, durations, percentages).
[data-flip="N"]Type. IO-triggered split-flap digit randomization (one-shot).
Effect. Element's textContent cycles through 8–12 random digits
(60ms per step) before settling on integer N. Evokes a flip-board
arrival.
Element shape. Same as [data-countup] — must contain only the
integer.
Registers that emit. kinetic-display only.
[data-fill="N"]Type. IO-triggered bar-fill (one-shot).
Effect. Element's CSS width tweens from 0% to N% over
1100ms with expo easing.
Element shape. Must be an inner element of a bar container
(e.g. <span class="park-bar"><i data-fill="78"></i></span>).
Registers that emit. live-systems only.
[data-split]Type. Scroll-triggered letter-by-letter reveal.
Effect. At measure-time the runtime splits the element's text
into individual <span> children, sets each to opacity 0,
translateY(60%), filter: blur(8px). On scroll, each letter
unblurs and rises with 50ms stagger.
Element shape. Must contain plain text only (no nested
markup at write-time).
Registers that emit. kinetic-display.
[data-parallax]Type. Scroll-progress-driven translate.
Effect. Element translates translateY(progress × -N vh) where
N is the register-default parallax.translate (typically 35 for
arrival, 10 for editorial).
Element shape. Must be inside an overflow: hidden parent —
the parallax can move the element past its own bounds.
Registers that emit. arrival, editorial.
These are class names rather than data-attributes because they participate in CSS selector matching (keyframe animations, hover states). Documented here for completeness.
.live-sweepA container that opts into the periodic refresh sweep. The runtime
adds .sweep every ~5.4s for 1.7s; the CSS rule paints a moving
linear-gradient via a ::after pseudo-element.
Registers. live-systems only.
.marquee__trackA flex-row of duplicated content. Animates with @keyframes marqueeScroll (translateX 0 → -50%) infinite.
Registers. kinetic-display, live-systems (top ticker).
.monogram-mask span (and equivalents)Display-monogram letters whose clip-path: inset(0 0 100% 0)
animates to inset(0 0 0 0) via @keyframes letterReveal.
Apply to letter spans inside a hero-monogram container when the
register is kinetic-display.
Registers. kinetic-display.
Every attribute and class above must respect
@media (prefers-reduced-motion: reduce):
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
[data-anim], [data-tile-anim], [data-split] span {
opacity: 1 !important;
transform: none !important;
filter: none !important;
clip-path: none !important;
}
.marquee__track, .brand-band__photo { animation: none !important; }
}The runtime additionally:
[data-countup] and [data-flip] to their target integer;[data-fill] width to the target percentage;The motion-validation gate's reduced-motion check
(motion-validation.md § Pass 3d) verifies that every attribute is
neutralized.
<!-- arrival hero -->
<h1 class="hero-marquee__title">BRAND</h1>
<p class="hero-marquee__body">Brand tagline goes here…</p>
<!-- live data chip with count-up -->
<span class="data-chip">
<span class="t">A1</span>
<span class="v" data-countup="27">0</span>
<span style="opacity:0.7">unit</span>
</span>
<!-- live-systems tile -->
<article class="tile warn" data-tile-anim>
<span class="tile__id">A1</span>
<div class="tile__metric">
<span class="v" data-countup="27">0</span>
<span class="u">unit</span>
</div>
</article>
<!-- bar fill -->
<span class="capacity-bar warn">
<i data-fill="78"></i>
</span>
<!-- kinetic-display split-flap -->
<span class="big-id" data-flip="5">0</span>
<!-- editorial scroll entrance -->
<p data-anim>Headline copy reveals on scroll.</p>
<!-- kinetic-display letter reveal -->
<h3 class="trio__title" data-split>WORD</h3>prototype --cinematic writes the attributes into the
rendered file based on the active register's template. The
attribute set is deterministic per register; the rendered HTML
is auditable.[data-countup] reaches its target; every [data-anim] ends
visible at appropriate scroll positions; every [data-fill]
has a finite target).migrate preserves them when re-deriving from the
prototype. Cinematic prototypes carry their motion contract
through to the deployed bundle.data-section /
data-intent vocabulary. They coexist. Structural attributes
describe what the section is for; motion attributes describe
what the element does under scroll.motion-runtime.md, (c) a
motion-validation gate update.v1 base set — ships with stardust v0.9.0 (the --cinematic
feature): [data-anim], [data-tile-anim], [data-countup],
[data-flip], [data-fill], [data-split], [data-parallax],
.live-sweep, .marquee__track.
New attributes are added in a backward-compatible way; renaming existing ones requires a minor version bump.
.tessl-plugin
skills
audit
reference
deploy
diff
direct
extract
migrate
prepare-migration
prototype
replica
reskin
rollout
stardust
uplift
reference