|
105 | 105 | animation: doodle-float 6s ease-in-out infinite alternate; |
106 | 106 | } |
107 | 107 |
|
| 108 | +/* Scroll-driven parallax for doodles: browsers that support it get depth as |
| 109 | + they scroll, others simply show the doodles still. */ |
| 110 | +@keyframes doodle-parallax { |
| 111 | + from { transform: translateY(calc(var(--shift, 24) * 1px)); } |
| 112 | + to { transform: translateY(calc(var(--shift, 24) * -1px)); } |
| 113 | +} |
| 114 | +@supports (animation-timeline: view()) { |
| 115 | + @media (prefers-reduced-motion: no-preference) { |
| 116 | + .doodle-parallax { |
| 117 | + animation: doodle-parallax linear both; |
| 118 | + animation-timeline: view(); |
| 119 | + } |
| 120 | + } |
| 121 | +} |
| 122 | + |
| 123 | +/* Hero 3D stack idle float */ |
| 124 | +@keyframes hero-stack-float { |
| 125 | + from { transform: translateY(0); } |
| 126 | + to { transform: translateY(-10px); } |
| 127 | +} |
| 128 | +.hero-stack-float { |
| 129 | + animation: hero-stack-float 7s ease-in-out infinite alternate; |
| 130 | +} |
| 131 | + |
| 132 | +/* Interactive doodles */ |
| 133 | +@keyframes play-wiggle { |
| 134 | + 0%, 100% { transform: rotate(0) scale(1); } |
| 135 | + 25% { transform: rotate(-12deg) scale(1.18); } |
| 136 | + 60% { transform: rotate(9deg) scale(1.14); } |
| 137 | +} |
| 138 | +@keyframes play-burst { |
| 139 | + from { transform: translate(0, 0) scale(1); opacity: 0.95; } |
| 140 | + to { transform: translate(var(--bx), var(--by)) scale(0.3); opacity: 0; } |
| 141 | +} |
| 142 | +@keyframes play-caption { |
| 143 | + 0% { opacity: 0; transform: translateY(6px) rotate(-3deg); } |
| 144 | + 12%, 80% { opacity: 1; transform: translateY(0) rotate(-3deg); } |
| 145 | + 100% { opacity: 0; transform: translateY(-4px) rotate(-3deg); } |
| 146 | +} |
| 147 | + |
108 | 148 | /* ASCII intro failsafe: only applies if JavaScript never starts the intro, |
109 | 149 | so visitors without JS are never stuck behind it. */ |
110 | 150 | @keyframes ascii-intro-failsafe { |
|
0 commit comments