Crossfade Media Stage
A full-bleed image stage: three large images crossfade and slowly zoom while a centered serif headline, description and two buttons appear with each scene. A thin progress bar bottom left shows each scene’s length and can be clicked to jump; a button bottom right pauses or resumes.
Taken from the page template Zhiheng AI Research Company Home. Use it on its own, or combine it with the other components from the same template to rebuild the full page.
Plain HTML, CSS and a little vanilla JS, with no framework dependency. Copy the prompt into Claude Code, Cursor, Trae or Codex and the model adds Crossfade Media Stage to your project in your colors.
Where to use it
Image comparisons, video showcases, galleries, carousels and media cards.
Install
With Builder, install it with the 8pt CLI or call it directly from an editor connected to 8pt MCP.
Code
Source for Crossfade Media Stage. Motion uses only transform and opacity and respects the Reduce motion setting.
<div class="x-cms"><div class="x-cms__frame"><figure class="x-cms__slide is-on" data-i="0"><img src="https://8pt.dev/api/media/1ed1961067eaf3507d2951f0.webp" alt="" loading="eager"><figcaption class="x-cms__cap"><h2 class="x-cms__t">青岚与远岫</h2><p class="x-cms__p">我们迄今最强的两款模型,面向艰深的技术工作,在编程、金融与科学研究上树立新的标准。</p><span class="x-cms__btns"><a class="x-cms__b x-cms__b--lt" href="#news">了解更多</a><a class="x-cms__b x-cms__b--dk" href="#brief">试用知衡助手</a></span></figcaption></figure><figure class="x-cms__slide" data-i="1"><img src="https://8pt.dev/api/media/fee67b1bd7226a7d996a40af.webp" alt="" loading="lazy"><figcaption class="x-cms__cap"><h2 class="x-cms__t">知衡研究院</h2><p class="x-cms__p">面对强大 AI 可能给社会带来的重大挑战,我们在这里做长期而审慎的研究。</p><span class="x-cms__btns"><a class="x-cms__b x-cms__b--lt" href="#news">了解更多</a><a class="x-cms__b x-cms__b--dk" href="#brief">试用知衡助手</a></span></figcaption></figure><figure class="x-cms__slide" data-i="2"><img src="https://8pt.dev/api/media/5943bd27e23eb7567f0c28ea.webp" alt="" loading="lazy"><figcaption class="x-cms__cap"><h2 class="x-cms__t">模型准则</h2><p class="x-cms__p">一份详细的说明:我们希望模型拥有怎样的价值观,以及在真实世界里如何行事。</p><span class="x-cms__btns"><a class="x-cms__b x-cms__b--lt" href="#news">了解更多</a><a class="x-cms__b x-cms__b--dk" href="#brief">试用知衡助手</a></span></figcaption></figure><div class="x-cms__ui"><span class="x-cms__segs"><button type="button" class="x-cms__seg is-on" data-go="0" aria-label="第一幕"><i></i></button><button type="button" class="x-cms__seg" data-go="1" aria-label="第二幕"><i></i></button><button type="button" class="x-cms__seg" data-go="2" aria-label="第三幕"><i></i></button></span><button type="button" class="x-cms__pp" aria-label="暂停" aria-pressed="false"><svg class="i-pa" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M9 6.5v11"/><path d="M15 6.5v11"/></svg><svg class="i-pl" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M8.5 6v12l9.5-6-9.5-6z"/></svg></button></div></div></div>
.x-cms{box-sizing:border-box;width:100%;padding:0 clamp(20px,5.5vw,80px);background:#faf9f5;-webkit-font-smoothing:antialiased}.x-cms *,.x-cms *::before,.x-cms *::after{box-sizing:border-box}.x-cms svg{width:1em;height:1em;flex:none}.x-cms__frame{position:relative;width:100%;aspect-ratio:16/9;max-height:780px;overflow:hidden;border-radius:4px;background:#2a2620;isolation:isolate}.x-cms__slide{position:absolute;inset:0;margin:0;opacity:0;visibility:hidden;transition:opacity 1.1s ease,visibility 1.1s}.x-cms__slide.is-on{opacity:1;visibility:visible;z-index:1}.x-cms__slide img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transform:scale(1.06);transition:transform 8s linear}.x-cms__slide.is-on img{transform:scale(1)}.x-cms__slide::after{content:"";position:absolute;inset:0;background:radial-gradient(ellipse at 50% 55%,rgba(18,14,10,.55),rgba(18,14,10,.18) 75%)}.x-cms__cap{position:absolute;inset:0;z-index:2;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:24px;color:#fff;text-align:center}.x-cms__t{margin:0;font-family:"Noto Serif SC","Noto Serif CJK SC","Songti SC","STSong",serif;font-size:clamp(30px,4.4vw,64px);font-weight:400;line-height:1.12;letter-spacing:-.01em;opacity:0;transform:translateY(14px);transition:opacity .8s .35s,transform .8s .35s}.x-cms__p{max-width:400px;margin:22px 0 26px;font-size:15px;line-height:1.6;opacity:0;transform:translateY(14px);transition:opacity .8s .5s,transform .8s .5s;font-family:"PingFang SC","Noto Sans SC","Noto Sans CJK SC","Microsoft YaHei",system-ui,sans-serif}.x-cms__btns{display:flex;flex-wrap:wrap;justify-content:center;gap:10px;opacity:0;transition:opacity .8s .65s}.x-cms__slide.is-on .x-cms__t,.x-cms__slide.is-on .x-cms__p,.x-cms__slide.is-on .x-cms__btns{opacity:1;transform:none}.x-cms__b{display:inline-flex;align-items:center;height:36px;padding:0 16px;border-radius:8px;font-size:13.5px;font-weight:550;text-decoration:none;transition:transform .2s,background .2s;font-family:"PingFang SC","Noto Sans SC","Noto Sans CJK SC","Microsoft YaHei",system-ui,sans-serif}.x-cms__b:hover{transform:translateY(-1px)}.x-cms__b--lt{background:#faf9f5;color:#141413}.x-cms__b--dk{background:#141413;color:#faf9f5}.x-cms__ui{position:absolute;left:16px;right:16px;bottom:16px;z-index:3;display:flex;align-items:center;justify-content:space-between}.x-cms__segs{display:flex;gap:6px}.x-cms__seg{width:30px;height:16px;padding:7px 0;border:0;background:none;cursor:pointer}.x-cms__seg i{position:relative;display:block;height:2px;overflow:hidden;border-radius:2px;background:rgba(255,255,255,.35)}.x-cms__seg i::after{content:"";position:absolute;inset:0;background:#fff;transform:scaleX(0);transform-origin:left}.x-cms__seg.is-done i::after{transform:scaleX(1)}.x-cms__seg.is-on i::after{animation:x-cms-fill var(--dur,7s) linear forwards}.x-cms.is-paused .x-cms__seg.is-on i::after{animation-play-state:paused}@keyframes x-cms-fill{to{transform:scaleX(1)}}.x-cms__pp{display:grid;place-items:center;width:30px;height:30px;padding:0;border:0;border-radius:7px;background:rgba(20,20,19,.45);color:#fff;font-size:15px;cursor:pointer;backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px)}.x-cms__pp .i-pl{display:none}.x-cms.is-paused .x-cms__pp .i-pa{display:none}.x-cms.is-paused .x-cms__pp .i-pl{display:block}@media (max-width:700px){.x-cms{padding:0 20px}.x-cms__frame{aspect-ratio:3/4;max-height:none}.x-cms__p{font-size:14px}}@media (prefers-reduced-motion:reduce){.x-cms__slide,.x-cms__slide img,.x-cms__t,.x-cms__p,.x-cms__btns{transition:none}.x-cms__seg.is-on i::after{animation:none;transform:scaleX(1)}}(root) => {
const slides = [...root.querySelectorAll('.x-cms__slide')];
const segs = [...root.querySelectorAll('.x-cms__seg')];
const pp = root.querySelector('.x-cms__pp');
const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
let cur = 0;
const show = (n) => {
cur = (n + slides.length) % slides.length;
slides.forEach((s, i) => s.classList.toggle('is-on', i === cur));
segs.forEach((s, i) => { s.classList.remove('is-on'); s.classList.toggle('is-done', i < cur); });
const seg = segs[cur]; void seg.offsetWidth; seg.classList.add('is-on');
};
…