请制作一个可以在浏览器直接打开的单文件 HTML 动态示例，实现「逐字弹跳」（文字动画）。

视觉目标：字逐个弹入，落稳后保持可读。
适用场景：卡点、重点词、轻松内容
输入素材：文字为「去见山海」，支持更换短标题，提供系统字体回退；不得把描边、渐变模拟说成真实三维字体。
实现要求：原生 JavaScript + Canvas 2D，画布 960×540，requestAnimationFrame 按秒驱动，循环周期 4.8 秒。支持暂停、重播，文字效果支持编辑文字。画布缩放时保持 16:9，不依赖框架、在线字体或 AI 接口。

效果边界：可直接生成。整段持续弹跳会难读；强调少数词更清楚。

请按下列现有核心逻辑复现，并补齐共享变量与渲染初始化；需要精确复现时配合图鉴中的完整 HTML，不要只复制片段：
// type-8 · 逐字弹跳
// 摘自 textDemo(i, t)；依赖该函数的时间、画布及素材初始化。
// 完整可运行版本请切换「完整 HTML」。
if(i===8||i===9){const span=Math.min(740,chars.length*(size+8)),step=span/chars.length;chars.forEach((c,k)=>{const a=clamp((p*4.8-k*.14)/.65);if(i===8&&a<=0)return;let y=i===8?(-130*(1-a)+Math.sin(a*3*Math.PI)*23*(1-a)):Math.sin(t*2.5+k*.7)*28;ctx.save();ctx.translate((W-span)/2+step*(k+.5),H/2+y);const s=i===8?(.6+.4*a):1;ctx.scale(s,s);ctx.fillStyle=['#ffbc92','#f6ead1','#bce1d2'][k%3];ctx.fillText(c,0,0);ctx.restore()});
 }

// 每帧调用，t 的单位是秒：
clean();
textDemo(8, t);

交付完整可运行代码，解释可调参数；先确保上述效果，再调整速度、颜色或强度。检查循环首尾、暂停状态、图片载入失败和短标题可读性。