Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Typewriter Effect — Cinematic Module</title> | |
| <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"> | |
| <style> | |
| :root{--bg:#0a0a0b;--text:#eae7e2;--muted:#5a5a5e;--accent:#c8a97e;--border:#1e1e22} | |
| *{margin:0;padding:0;box-sizing:border-box}body{background:var(--bg);color:var(--text);font-family:'Outfit',sans-serif;-webkit-font-smoothing:antialiased;overflow-x:hidden} | |
| .hero{min-height:100dvh;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:40px 24px} | |
| .hero-label{font-size:12px;letter-spacing:.15em;text-transform:uppercase;color:var(--muted);margin-bottom:20px} | |
| .hero h1{font-size:clamp(32px,6vw,64px);font-weight:600;line-height:1.15;max-width:700px;letter-spacing:-.025em} | |
| .hero h1 span{color:var(--accent)} | |
| .type-section{padding:80px 24px;max-width:700px;margin:0 auto;text-align:center} | |
| .type-section-label{font-size:12px;letter-spacing:.15em;text-transform:uppercase;color:var(--muted);margin-bottom:32px} | |
| .type-display{font-size:clamp(24px,4vw,48px);font-weight:600;letter-spacing:-.02em;min-height:1.3em;line-height:1.3} | |
| .type-cursor{display:inline-block;width:3px;height:1em;background:var(--accent);margin-left:2px;vertical-align:text-bottom;animation:blink .6s step-end infinite} | |
| @keyframes blink{50%{opacity:0}} | |
| .type-mono{font-family:'JetBrains Mono',monospace;font-size:clamp(16px,2.5vw,24px);font-weight:400;color:var(--accent);background:#111114;border:1px solid var(--border);border-radius:12px;padding:32px;text-align:left;min-height:120px;margin-top:60px;line-height:1.7} | |
| .type-chat{margin-top:60px;max-width:500px;margin-left:auto;margin-right:auto;display:flex;flex-direction:column;gap:12px} | |
| .chat-msg{padding:14px 20px;border-radius:16px;font-size:15px;line-height:1.5;max-width:80%;opacity:0;transform:translateY(10px);transition:all .3s cubic-bezier(.16,1,.3,1)} | |
| .chat-msg.visible{opacity:1;transform:translateY(0)} | |
| .chat-msg.user{background:#1e1e22;align-self:flex-end;border-bottom-right-radius:4px} | |
| .chat-msg.bot{background:rgba(200,169,126,.1);border:1px solid rgba(200,169,126,.15);align-self:flex-start;border-bottom-left-radius:4px} | |
| .divider{width:60px;height:1px;background:var(--border);margin:80px auto} | |
| .explain{padding:120px 24px;text-align:center;max-width:680px;margin:0 auto;border-top:1px solid #1a1a1d} | |
| .explain .tag{display:inline-block;font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--accent);border:1px solid rgba(200,169,126,.2);padding:4px 12px;border-radius:100px;margin-bottom:20px} | |
| .explain h2{font-size:clamp(24px,4vw,40px);font-weight:600;letter-spacing:-.02em;margin-bottom:16px} | |
| .explain p{font-size:17px;color:var(--muted);line-height:1.6} | |
| footer{border-top:1px solid #1a1a1d;padding:24px;text-align:center;font-size:12px;color:var(--muted)} | |
| </style> | |
| </head> | |
| <body> | |
| <section class="hero"> | |
| <div class="hero-label">Module 29 — Typewriter Effect</div> | |
| <h1>Text types itself <span>letter by letter</span></h1> | |
| <p>Multi-line typewriter with delete-and-retype cycling, code block typing, and chat bubble sequencing. Three variants below.</p> | |
| </section> | |
| <section class="type-section"> | |
| <div class="type-section-label">Cycling headline — types, pauses, deletes, repeats</div> | |
| <div class="type-display" id="cycler"><span class="type-cursor"></span></div> | |
| </section> | |
| <div class="divider"></div> | |
| <section class="type-section"> | |
| <div class="type-section-label">Code block typewriter</div> | |
| <div class="type-mono" id="codeType"></div> | |
| </section> | |
| <div class="divider"></div> | |
| <section class="type-section"> | |
| <div class="type-section-label">Chat sequence</div> | |
| <div class="type-chat" id="chatArea"> | |
| <div class="chat-msg user" data-delay="0">How fast can you build a landing page?</div> | |
| <div class="chat-msg bot" data-delay="1200">Under 30 seconds. Want me to start?</div> | |
| <div class="chat-msg user" data-delay="2600">Show me.</div> | |
| <div class="chat-msg bot" data-delay="3800">Done. Check the preview above.</div> | |
| </div> | |
| </section> | |
| <section class="explain"> | |
| <div class="tag">Why it works</div> | |
| <h2>Pacing creates focus</h2> | |
| <p>The typewriter forces the visitor to read at your pace. Unlike a static headline, each word earns attention as it appears. AI chatbots, developer tools, and SaaS onboarding all use this to demonstrate capability in real-time. The cycling variant keeps the hero fresh without a carousel.</p> | |
| </section> | |
| <footer>Cinematic Module — Typewriter Effect</footer> | |
| <script> | |
| (function(){ | |
| // Cycling headline | |
| var phrases=['We build websites.','We build brands.','We build products.','We build trust.']; | |
| var el=document.getElementById('cycler'); | |
| var pi=0,ci=0,deleting=false,pause=0; | |
| function tick(){ | |
| var phrase=phrases[pi]; | |
| if(!deleting){ | |
| ci++; | |
| if(ci>phrase.length){pause++;if(pause>40){deleting=true;pause=0}requestAnimationFrame(tick);return} | |
| }else{ | |
| ci--; | |
| if(ci<0){ci=0;deleting=false;pi=(pi+1)%phrases.length;pause=0;setTimeout(tick,400);return} | |
| } | |
| el.innerHTML=phrase.substring(0,ci)+'<span class="type-cursor"></span>'; | |
| setTimeout(tick,deleting?30:60); | |
| } | |
| tick(); | |
| // Code block | |
| var code='const site = await claude.build({\n url: "example.com",\n theme: "dark",\n animation: "scroll-frame"\n});\n\nconsole.log(site.url);\n// => https://example.vercel.app'; | |
| var codeEl=document.getElementById('codeType'); | |
| var cIdx=0; | |
| function typeCode(){ | |
| if(cIdx<=code.length){ | |
| codeEl.textContent=code.substring(0,cIdx)+'_'; | |
| cIdx++; | |
| setTimeout(typeCode,Math.random()*40+20); | |
| }else{codeEl.textContent=code} | |
| } | |
| // Start when in view | |
| var observer=new IntersectionObserver(function(entries){ | |
| if(entries[0].isIntersecting){typeCode();observer.disconnect()} | |
| },{threshold:.5}); | |
| observer.observe(codeEl); | |
| // Chat sequence | |
| document.querySelectorAll('.chat-msg').forEach(function(msg){ | |
| var delay=parseInt(msg.dataset.delay); | |
| setTimeout(function(){msg.classList.add('visible')},delay+500); | |
| }); | |
| })(); | |
| </script> | |
| <div style="position:fixed;bottom:0;left:0;right:0;padding:8px 16px;font-size:11px;color:#5a5a5e;text-align:center;z-index:99;background:rgba(9,9,11,.85);backdrop-filter:blur(8px);border-top:1px solid #1e1e22;font-family:Outfit,sans-serif">© Created by Jay from <a href="https://robonuggets.com" style="color:#e8793a;text-decoration:none">RoboLabs</a>. Learn more at <a href="https://robonuggets.com" style="color:#e8793a;text-decoration:none">RoboNuggets</a></div> | |
| </body> | |
| </html> | |