Motion · Component reference
Text moments
Let a small text accent reinforce meaning without delaying access to the words.
Try the live exampleResearch and our take
The starting prompt was the visible caption of Omar Farooq’s scratch file demonstration. Full playback was blocked during the original review. Starlit developed the reveal and gold highlight from that idea and our own design direction. We are not claiming to have recreated unseen frames.
Design reasoning
Let a small text accent reinforce meaning without delaying access to the words.
- Start with the person’s task and the barrier they may encounter.
- Use one short flourish on an existing heading. The production version needs only the stylesheet and authored spans.
- Keep the ordinary content and action usable before adding enhancement.
- Use the still preview, enlarge text, print, and disable JavaScript. The original words should remain readable once.
Usage pattern
Use one short flourish on an existing heading. The production version needs only the stylesheet and authored spans.
Impact and tradeoffs
A brief accent adds emphasis. Repeating it across every heading adds distraction and weakens the hierarchy.
Accessibility solutions
Keep text visible from the start, preserve heading semantics and stop the effect for device or site reduced motion.
Build accessible source content first. Personal preferences supplement semantic HTML, useful names, keyboard access and visible focus.
HTML
A concrete usage example. Host these assets on your own origin if you adapt the pattern. Read the source and credits before reuse.
<html lang="en-CA" data-moment-motion="system">
<!-- In your document head: -->
<link rel="stylesheet" href="/open-ui/examples/text-moments/text-moments.css">
<!-- In your document body: -->
<h1>Projects with <span class="sdou-text-moment"
data-moment="highlight">purpose.</span></h1>
</html>CSS
Production effect stylesheet. Keep this separate from the scratch page controls.
Read the css implementation (109 lines)
/* Starlit text moments. Text remains present and readable without animation. */
.sdou-text-moment {
--moment-accent: var(--studio-gold, var(--sdou-gold, #e8c58e));
display: inline-block;
position: relative;
max-inline-size: 100%;
color: var(--moment-accent);
isolation: isolate;
}
.sdou-text-moment[data-moment="highlight"]::after {
content: "";
position: absolute;
z-index: -1;
inset: auto 0 0.04em;
height: 0.13em;
border-radius: 0.08em;
background: currentColor;
opacity: 0.22;
transform-origin: left center;
}
/* Wait for the host to resolve saved motion preferences before starting. */
:is(html[data-sdou-a11y-motion="system"], html[data-moment-motion="system"])
.sdou-text-moment {
animation: sdou-word-arrive 900ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
:is(html[data-sdou-a11y-motion="system"], html[data-moment-motion="system"])
.sdou-text-moment[data-moment="highlight"]::after {
animation: sdou-gold-draw 1100ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
:is(html[data-sdou-a11y-motion="system"], html[data-moment-motion="system"])
.sdou-text-moment[data-moment="glow"] {
animation: sdou-word-glow 1200ms ease-out both;
}
@keyframes sdou-word-arrive {
from {
transform: translateY(0.1em);
}
to {
transform: none;
}
}
@keyframes sdou-gold-draw {
from {
transform: scaleX(0);
}
to {
transform: scaleX(1);
}
}
@keyframes sdou-word-glow {
0% {
text-shadow: 0 0 0 transparent;
}
45% {
text-shadow: 0 0 0.16em currentColor;
}
100% {
text-shadow: 0 0 0 transparent;
}
}
@media (prefers-reduced-motion: reduce) {
.sdou-text-moment,
.sdou-text-moment::after {
animation: none !important;
transform: none !important;
opacity: 1;
}
.sdou-text-moment[data-moment="highlight"]::after {
opacity: 0.22;
}
}
html[data-sdou-a11y-motion="reduce"] .sdou-text-moment,
html[data-sdou-a11y-motion="reduce"] .sdou-text-moment::after,
[data-sdou-a11y-motion="reduce"] .sdou-text-moment,
[data-sdou-a11y-motion="reduce"] .sdou-text-moment::after,
[data-moment-motion="reduce"] .sdou-text-moment,
[data-moment-motion="reduce"] .sdou-text-moment::after {
animation: none !important;
transform: none !important;
opacity: 1;
}
html[data-sdou-a11y-motion="reduce"]
.sdou-text-moment[data-moment="highlight"]::after,
[data-sdou-a11y-motion="reduce"] .sdou-text-moment[data-moment="highlight"]::after,
[data-moment-motion="reduce"]
.sdou-text-moment[data-moment="highlight"]::after {
opacity: 0.22;
}
@media (forced-colors: active) {
.sdou-text-moment {
color: CanvasText;
}
.sdou-text-moment[data-moment="highlight"]::after {
background: Highlight;
opacity: 1;
}
}
@media print {
.sdou-text-moment,
.sdou-text-moment::after {
animation: none !important;
transform: none !important;
opacity: 1;
}
.sdou-text-moment[data-moment="highlight"]::after {
opacity: 0.22;
}
}
JavaScript
The production effect is CSS. The preview page adds optional replay controls.
// No JavaScript is needed in production.
// The live scratch page uses scratch.js only to preview and replay variants.PHP integration
In your own application, PHP can render this HTML on the server. Here, the example is escaped text only. The library has no PHP runner or execution endpoint. The browser owns the interaction.
<?php
// Server rendering example, not a payment or mailing endpoint.
declare(strict_types=1);
$heading = 'Text moments';
$e = static fn (string $value): string =>
htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
?>
<section aria-labelledby="example-heading">
<h2 id="example-heading"><?= $e($heading) ?></h2>
<?php
// Include the trusted component HTML shown above from your own file.
// Never build this path from a request parameter.
require __DIR__ . '/partials/text-moments.html';
?>
</section>
API and dependencies
The HTML section lists the actual selectors, IDs, classes and data attributes used by the example. Preserve IDs referenced by labels and JavaScript, and make them unique when composing a page. The shared controller is a demonstration bundle, not a backend service.
For PHP, save the body markup above in the fixed partial path shown, and load its linked CSS and scripts once in your page head. Escape dynamic text at output. Never insert untrusted HTML, URLs or script fragments into the partial.
Form, plan and dashboard outcomes are local simulations. A production submission needs its own validated endpoint, abuse controls and honest delivery result. Decorative studies need integration specific review before production use.
Testing and limitations
Use the still preview, enlarge text, print, and disable JavaScript. The original words should remain readable once.
These visual studies are learning examples. Their presence here is not a claim that each is deployed across Starlit products or fully audited. Check motion changes, keyboard focus, status announcements and content equivalents in the final host.
Production review still needs assistive technology, touch, zoom, custom styles and representative content. See our testing scope and known gaps. Report a barrier to Starlit.