Text motionCC0-style snippets
Count-up number
A short numeric transition that gives a metric a sense of arrival without hiding the final value.
<span data-sc-effect="count-up" data-value="240">240</span>
const count = document.querySelector('[data-sc-effect="count-up"]');
const end = Number(count.dataset.value || 240);
const start = performance.now();
function tick(now) {
const progress = Math.min((now - start) / 900, 1);
count.textContent = Math.round(end * (1 - Math.pow(1 - progress, 3))).toLocaleString();
if (progress < 1) requestAnimationFrame(tick);
}
requestAnimationFrame(tick);
Text motionCC0-style snippets
Typewriter text
A short, decorative typewriter cue for a headline or status line, with the full copy preserved for assistive technology.
<span data-sc-effect="typewriter" data-text="Build with clarity">Build with clarity</span>
const node = document.querySelector('[data-sc-effect="typewriter"]');
const text = node.dataset.text || node.textContent;
node.setAttribute('aria-label', text);
node.textContent = '';
let index = 0;
const type = () => { node.textContent = text.slice(0, ++index); if (index < text.length) setTimeout(type, 55); };
type();
Text motionCC0-style snippets
Pauseable marquee
A low-priority looping strip with a pause control, suitable for decorative keywords or partner labels.
[data-sc-effect="marquee"] { overflow: hidden; }
[data-sc-effect="marquee"] .sc-marquee-track { display: flex; width: max-content; animation: sc-marquee 18s linear infinite; }
[data-sc-effect="marquee"]:has(button:focus-visible) .sc-marquee-track,
[data-sc-effect="marquee"].is-paused .sc-marquee-track { animation-play-state: paused; }
@keyframes sc-marquee { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { [data-sc-effect="marquee"] .sc-marquee-track { animation: none; } }
<div data-sc-effect="marquee"><div class="sc-marquee-track"><span>Clarity · Motion · Speed · </span><span aria-hidden="true">Clarity · Motion · Speed · </span></div><button type="button" data-sc-marquee-toggle>Pause</button></div>
<script>
const marquee = document.querySelector('[data-sc-effect="marquee"]');
marquee.querySelector('[data-sc-marquee-toggle]').addEventListener('click', (event) => {
marquee.classList.toggle('is-paused');
event.currentTarget.textContent = marquee.classList.contains('is-paused') ? 'Play' : 'Pause';
});
</script>
Text motionCC0-style snippets
Underline sweep
A bright underline that draws attention to a link while leaving the text and focus state intact.
[data-sc-effect="underline-sweep"] { background: linear-gradient(currentColor, currentColor) 0 100% / 0 2px no-repeat; transition: background-size 220ms ease; }
[data-sc-effect="underline-sweep"]:hover,
[data-sc-effect="underline-sweep"]:focus-visible { background-size: 100% 2px; }
@media (prefers-reduced-motion: reduce) { [data-sc-effect="underline-sweep"] { transition: none; } }
Text motionCC0-style snippets
Text mask wipe
Reveal a short heading with a clean mask wipe that preserves the text in the document tree.
[data-sc-effect="text-mask-wipe"] {
clip-path: inset(0 100% 0 0); transform: translateX(-.2em);
animation: sc-mask-wipe 800ms cubic-bezier(.2,.8,.2,1) forwards;
}
@keyframes sc-mask-wipe { to { clip-path: inset(0); transform: none; } }
@media (prefers-reduced-motion: reduce) {
[data-sc-effect="text-mask-wipe"] { clip-path: inset(0); transform: none; animation: none; }
}
Text motionCC0-style snippets
Gradient text flow
Move a restrained brand gradient across a short text treatment while keeping a solid-color fallback.
[data-sc-effect="gradient-text-flow"] {
color: #155eef; background: linear-gradient(100deg, #155eef, #8b5cf6, #0ea5a1, #155eef);
background-size: 220% auto; background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; animation: sc-gradient-text 7s linear infinite;
}
@keyframes sc-gradient-text { to { background-position: 220% center; } }
@media (prefers-reduced-motion: reduce) {
[data-sc-effect="gradient-text-flow"] { animation: none; background-position: 0 center; }
}
Text motionCC0-style snippets
Text scramble
Resolve a short label through a burst of characters before landing on the real message.
[data-sc-effect="text-scramble"] { font-variant-numeric: tabular-nums; }
const scramble = document.querySelector('[data-sc-effect="text-scramble"]');
const finalText = scramble.textContent;
const chars = 'アカサタナ0123456789';
let frame = 0;
const scrambleTimer = setInterval(() => {
scramble.textContent = finalText.split('').map((letter, index) => index < frame / 3 ? letter : chars[Math.floor(Math.random() * chars.length)]).join('');
frame += 1;
if (frame > finalText.length * 3) { clearInterval(scrambleTimer); scramble.textContent = finalText; }
}, 42);
Text motionCC0-style snippets
Number ticker
Animate a metric to a final value with a readable numeric fallback and no dependency.
[data-sc-effect="number-ticker"] { font-variant-numeric: tabular-nums; }
const ticker = document.querySelector('[data-sc-effect="number-ticker"]');
const targetValue = Number(ticker.dataset.value || 240);
const reduceTicker = matchMedia('(prefers-reduced-motion: reduce)').matches;
if (reduceTicker) ticker.textContent = targetValue.toLocaleString();
else {
const start = performance.now();
const tick = (now) => {
const progress = Math.min(1, (now - start) / 900);
ticker.textContent = Math.round(targetValue * (1 - Math.pow(1 - progress, 3))).toLocaleString();
if (progress < 1) requestAnimationFrame(tick);
};
requestAnimationFrame(tick);
}