Files
2026-06-29 15:11:48 -07:00

80 lines
3.1 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Motion fixture — CSS keyframes</title>
<style>
:root { --bg: #0b0b10; --fg: #f5f5f7; --muted: #9aa0aa; --accent: #6d6aff; }
* { box-sizing: border-box; }
html, body { margin: 0; }
body {
background: var(--bg); color: var(--fg);
font-family: -apple-system, system-ui, Segoe UI, Roboto, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
}
.wrap { max-width: 920px; margin: 0 auto; padding: 64px 24px 96px; }
/* 1) Finite entrance: fade + slide up, ends at rest (fill forwards). */
@keyframes fadeUp {
from { opacity: 0; transform: translateY(28px); }
to { opacity: 1; transform: translateY(0); }
}
.hero h1 {
font-size: 56px; font-weight: 700; line-height: 1.05; letter-spacing: -0.02em; margin: 0 0 16px;
animation: fadeUp 700ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
.hero p {
font-size: 20px; line-height: 1.5; color: var(--muted); margin: 0; max-width: 560px;
animation: fadeUp 700ms cubic-bezier(0.22, 1, 0.36, 1) 120ms both;
}
/* 2) Infinite spinner. */
@keyframes spin { to { transform: rotate(360deg); } }
.spinner {
width: 48px; height: 48px; margin: 56px 0 0; border-radius: 9999px;
border: 4px solid rgba(255,255,255,0.15); border-top-color: var(--accent);
animation: spin 1s linear infinite;
}
/* 3) Infinite pulse (opacity + scale). */
@keyframes pulse {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.55; transform: scale(1.08); }
}
.badge {
display: inline-block; margin-top: 40px; padding: 8px 16px; border-radius: 9999px;
background: var(--accent); color: #fff; font-size: 14px; font-weight: 600;
animation: pulse 1.8s ease-in-out infinite;
}
.grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 64px; }
.card {
background: #15151d; border: 1px solid #23232e; border-radius: 14px; padding: 20px;
animation: fadeUp 600ms ease-out both;
}
.card h3 { margin: 0 0 8px; font-size: 18px; font-weight: 600; }
.card p { margin: 0; font-size: 15px; line-height: 1.5; color: var(--muted); }
.footer { margin-top: 80px; color: var(--muted); font-size: 14px; }
</style>
</head>
<body>
<main class="wrap">
<section class="hero">
<h1>Motion that replays</h1>
<p>A deterministic fixture: heading and subtext animate in, the loader spins forever, and the badge pulses.</p>
<div class="spinner" aria-label="Loading"></div>
<span class="badge">Live</span>
</section>
<section class="grid">
<div class="card"><h3>Entrance</h3><p>Cards fade and slide up on load via a CSS keyframes animation.</p></div>
<div class="card"><h3>Looping</h3><p>The spinner uses an infinite linear rotation that never settles.</p></div>
<div class="card"><h3>Pulsing</h3><p>The badge eases between two opacity and scale states forever.</p></div>
</section>
<p class="footer">Reconstructed deterministically — the clone should replay each of these.</p>
</main>
</body>
</html>