<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initia
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Desi Roman Typer · animated</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: radial-gradient(circle at 30% 10%, #1a1a2e, #0b0b16);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
padding: 18px;
margin: 0;
position: relative;
overflow-x: hidden;
}
/* ---- floating orbs (animated) ---- */
.orb {
position: fixed;
border-radius: 50%;
filter: blur(100px);
pointer-events: none;
z-index: 0;
opacity: 0.3;
animation: orbFloat 16s infinite alternate ease-in-out;
}
.orb1 {
width: 300px;
height: 300px;
background: #cba6f7;
top: -80px;
right: -60px;
animation-duration: 14s;
}
.orb2 {
width: 400px;
height: 400px;
background: #a6e3a1;
bottom: -120px;
left: -100px;
animation-duration: 20s;
opacity: 0.2;
}
.orb3 {
width: 220px;
height: 220px;
background: #f38ba8;
top: 40%;
left: 70%;
animation-duration: 12s;
opacity: 0.18;
}
@keyframes orbFloat {
0% { transform: translate(0, 0) scale(1); }
100% { transform: translate(30px, -40px) scale(1.25); }
}
/* ---- main glass card ---- */
.glass {
position: relative;
z-index: 2;
background: rgba(30, 30, 46, 0.7);
backdrop-filter: blur(14px);
-webkit-backdrop-filter: blur(14px);
border: 1px solid rgba(203, 166, 247, 0.2);
box-shadow: 0 30px 60px rgba(0, 0, 0, 0.7), 0 0 0 1px rgba(203, 166, 247, 0.08) inset;
border-radius: 56px;
padding: 34px 28px;
max-width: 620px;
width: 100%;
animation: cardFloat 2.8s infinite alternate ease-in-out;
transition: all 0.2s;
}
@keyframes cardFloat {
0% { transform: translateY(0px); }
100% { transform: translateY(-6px); }
}
/* ---- heading with sparkle animation ---- */
.head-wrap {
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
flex-wrap: wrap;
margin-bottom: 2px;
animation: fadeSlide 0.9s ease;
}
h2 {
color: #cba6f7;
font-size: 2.2rem;
font-weight: 700;
letter-spacing: -0.5px;
text-shadow: 0 0 20px rgba(203, 166, 247, 0.25);
animation: glowPulse 3.2s infinite alternate;
display: inline-flex;
align-items: center;
gap: 10px;
}
@keyframes glowPulse {
0% { text-shadow: 0 0 5px rgba(203, 166, 247, 0.15); }
100% { text-shadow: 0 0 30px rgba(203, 166, 247, 0.55); }
}
.emoji-bounce {
display: inline-block;
animation: bounceEmoji 2.4s infinite;
}
@keyframes bounceEmoji {
0%, 100% { transform: scale(1) rotate(0deg); }
50% { transform: scale(1.2) rotate(6deg); }
}
.subtitle {
color: #a6adc8;
font-size: 0.95rem;
font-weight: 400;
letter-spacing: 0.4px;
border-bottom: 1px dashed rgba(166, 173, 200, 0.15);
padding-bottom: 14px;
margin-bottom: 22px;
animation: fadeSlide 1.2s ease;
text-align: center;
}
@keyframes fadeSlide {
0% { opacity: 0; transform: translateX(-12px); }
100% { opacity: 1; transform: translateX(0); }
}
/* ---- textarea with shimmer border ---- */
.textarea-wrap {
position: relative;
border-radius: 32px;
background: rgba(24, 24, 37, 0.5);
border: 1.5px solid #45475a;
transition: all 0.3s ease;
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.5);
margin-bottom: 24px;
animation: borderShimmer 4s infinite linear;
background-clip: padding-box;
}
@keyframes borderShimmer {
0% { border-color: #45475a; box-shadow: 0 0 0 0 rgba(203, 166, 247, 0); }
25% { border-color: #cba6f7; box-shadow: 0 0 18px rgba(203, 166, 247, 0.15); }
50% { border-color: #a6e3a1; box-shadow: 0 0 18px rgba(166, 227, 161, 0.15); }
75% { border-color: #f38ba8; box-shadow: 0 0 18px rgba(243, 139, 168, 0.15); }
100% { border-color: #45475a; box-shadow: 0 0 0 0 rgba(203, 166, 247, 0); }
}
.textarea-wrap:focus-within {
border-color: #cba6f7;
box-shadow: 0 0 0 5px rgba(203, 166, 247, 0.2), 0 8px 28px rgba(0, 0, 0, 0.6);
transform: scale(1.01);
animation: none;
}
textarea {
width: 100%;
height: 180px;
background: transparent;
color: #a6e3a1;
border: none;
border-radius: 32px;
padding: 20px 24px;
font-size: 18px;
font-family: 'Courier New', 'Fira Code', monospace;
resize: none;
outline: none;
line-height: 1.6;
letter-spacing: 0.2px;
transition: background 0.2s;
position: relative;
z-index: 2;
}
textarea::placeholder {
color: #6c7086;
opacity: 0.45;
font-family: 'Segoe UI', sans-serif;
font-weight: 300;
}
/* ---- button group with pulse & hover animations ---- */
.btn-group {
display: flex;
gap: 16px;
flex-wrap: wrap;
justify-content: center;
animation: fadeSlide 1s ease;
}
.btn {
flex: 1 1 140px;
padding: 16px 10px;
border: none;
border-radius: 60px;
font-size: 1.1rem;
font-weight: 700;
letter-spacing: 0.6px;
background: #313244;
color: #cdd6f4;
cursor: pointer;
transition: all 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
box-shadow: 0 10px 18px -8px rgba(0, 0, 0, 0.6);
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
border: 1px solid rgba(255, 255, 255, 0.02);
position: relative;
overflow: hidden;
}
.btn::after {
content: '';
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(255,255,255,0.08) 0%, transparent 70%);
opacity: 0;
transition: opacity 0.3s;
pointer-events: none;
}
.btn:hover::after {
opacity: 1;
}
.btn:active {
transform: scale(0.94);
}
#startBtn {
background: linear-gradient(145deg, #a6e3a1, #7ecb7a);
color: #0e0e1a;
box-shadow: 0 0 24px rgba(166, 227, 161, 0.25);
border: 1px solid rgba(166, 227, 161, 0.4);
animation: btnPulseStart 2.8s infinite alternate;
}
@keyframes btnPulseStart {
0% { box-shadow: 0 0 10px rgba(166, 227, 161, 0.2); }
100% { box-shadow: 0 0 38px rgba(166, 227, 161, 0.55); }
}
#startBtn:hover {
background: linear-gradient(145deg, #b4befe, #a6a9f0);
box-shadow: 0 0 44px #b4befe99;
transform: scale(1.04) translateY(-3px);
border-color: #b4befe;
}
#stopBtn {
background: linear-gradient(145deg, #f38ba8, #e06b89);
color: #0e0e1a;
box-shadow: 0 0 24px rgba(243, 139, 168, 0.2);
border: 1px solid rgba(243, 139, 168, 0.3);
animation: btnPulseStop 3s infinite alternate;
}
@keyframes btnPulseStop {
0% { box-shadow: 0 0 10px rgba(243, 139, 168, 0.15); }
100% { box-shadow: 0 0 40px rgba(243, 139, 168, 0.5); }
}
#stopBtn:hover {
background: linear-gradient(145deg, #f9a8b9, #f38ba8);
box-shadow: 0 0 48px #f38ba8bb;
transform: scale(1.04) translateY(-3px);
border-color: #f9a8b9;
}
.btn .sparkle {
display: inline-block;
animation: sparkleTwinkle 2s infinite;
}
@keyframes sparkleTwinkle {
0%, 100% { transform: scale(1) rotate(0deg); opacity: 0.8; }
50% { transform: scale(1.4) rotate(12deg); opacity: 1; }
}
/* ---- status with fl