|
46 | 46 | overflow-x: hidden; |
47 | 47 | cursor: none; |
48 | 48 | } |
49 | | -/* Enhanced grid overlay – matches main site */ |
50 | 49 | body::before { |
51 | 50 | content: ''; |
52 | 51 | position: fixed; |
|
58 | 57 | pointer-events: none; |
59 | 58 | z-index: 10; |
60 | 59 | } |
61 | | -/* Scanline overlay – restored from main site */ |
62 | 60 | body::after { |
63 | 61 | content: ''; |
64 | 62 | position: fixed; |
|
74 | 72 | } |
75 | 73 | @keyframes scan { 0% { transform: translateY(0); } 100% { transform: translateY(4px); } } |
76 | 74 |
|
77 | | -/* CURSOR – identical to main site */ |
| 75 | +/* PURE-GPU CURSOR – no trail, no DOM updates, zero layout shift */ |
78 | 76 | .custom-cursor { |
79 | 77 | width: 20px; |
80 | 78 | height: 20px; |
|
87 | 85 | transition: transform 0.1s ease, background 0.2s ease, box-shadow 0.2s ease; |
88 | 86 | transform: translate(-50%, -50%); |
89 | 87 | box-shadow: 0 0 15px var(--gold), 0 0 30px rgba(212,175,55,0.3); |
| 88 | + will-change: transform; |
90 | 89 | } |
91 | 90 | .custom-cursor.hover { |
92 | 91 | transform: translate(-50%, -50%) scale(1.8); |
93 | 92 | background: rgba(212,175,55,0.1); |
94 | 93 | border-color: var(--rose); |
95 | 94 | box-shadow: 0 0 25px var(--rose), 0 0 50px rgba(232,160,176,0.5); |
96 | 95 | } |
97 | | -.cursor-trail { |
98 | | - position: fixed; |
99 | | - width: 6px; |
100 | | - height: 6px; |
101 | | - border-radius: 50%; |
102 | | - background: var(--gold); |
103 | | - pointer-events: none; |
104 | | - z-index: 9998; |
105 | | - opacity: 0.6; |
106 | | - box-shadow: 0 0 10px var(--gold); |
107 | | - transition: opacity 0.3s ease; |
108 | | -} |
109 | 96 |
|
110 | 97 | #hero-canvas { |
111 | 98 | position: fixed; |
|
114 | 101 | width: 100%; |
115 | 102 | height: 100%; |
116 | 103 | z-index: 0; |
117 | | - opacity: 0.65; /* matched to main site */ |
| 104 | + opacity: 0.65; |
118 | 105 | pointer-events: none; |
119 | 106 | } |
120 | 107 |
|
|
167 | 154 | margin: 32px auto; |
168 | 155 | } |
169 | 156 |
|
170 | | -/* SCROLL INDICATOR – pure CSS heart path, no canvas, no RAF */ |
171 | 157 | .scroll-indicator { |
172 | 158 | position: relative; |
173 | 159 | z-index: 2; |
|
234 | 220 | grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); |
235 | 221 | gap: 32px; |
236 | 222 | max-width: 900px; |
237 | | - margin: 0 auto 80px; |
| 223 | + margin: 0 auto 40px; |
238 | 224 | padding: 0 30px; |
239 | 225 | } |
240 | 226 | .card { |
|
263 | 249 | .card-signature span { display: block; font-family: var(--mono); font-size: 9px; letter-spacing: 2px; text-transform: uppercase; color: var(--muted); margin-top: 6px; font-style: normal; } |
264 | 250 |
|
265 | 251 | footer { position: relative; z-index: 2; text-align: center; padding: 40px 20px; font-family: var(--mono); font-size: 10px; color: var(--dim); letter-spacing: 1px; } |
| 252 | +.cosmic-thanks { font-family:var(--garamond); font-size:18px; font-style:italic; color:var(--rose); margin-bottom:8px; text-shadow:0 0 6px var(--rose); } |
266 | 253 |
|
267 | 254 | @media (max-width: 600px) { |
268 | 255 | .cards { grid-template-columns: 1fr; } |
|
275 | 262 | <canvas id="hero-canvas"></canvas> |
276 | 263 |
|
277 | 264 | <div class="custom-cursor" id="custom-cursor"></div> |
278 | | -<div id="cursor-trail-container"></div> |
279 | 265 |
|
280 | 266 | <div class="hero"> |
281 | 267 | <div class="hero-eyebrow">✦ Mother's Day 2026 ✦</div> |
@@ -327,9 +313,7 @@ <h1 class="hero-title"><em>Happy</em> Mother's<br>Day</h1> |
327 | 313 | </div> |
328 | 314 |
|
329 | 315 | <footer> |
330 | | - <p style="font-family:var(--garamond); font-size:18px; font-style:italic; color:var(--rose); margin-bottom:8px; text-shadow:0 0 6px var(--rose);"> |
331 | | - And to the one who birthed the stars and set the first spark of life — thank you. We come from you. |
332 | | - </p> |
| 316 | + <p class="cosmic-thanks">And to the one who birthed the stars and set the first spark of life — thank you. We come from you.</p> |
333 | 317 | Made with love · Evans Mills, New York · May 10, 2026 |
334 | 318 | </footer> |
335 | 319 |
|
@@ -522,29 +506,12 @@ <h1 class="hero-title"><em>Happy</em> Mother's<br>Day</h1> |
522 | 506 | resizeCanvas(); |
523 | 507 | requestAnimationFrame(drawSymbols); |
524 | 508 |
|
525 | | - // ========== CUSTOM CURSOR & TRAIL ========== |
| 509 | + // ========== CUSTOM CURSOR (GPU-only, no trail, no layout shift) ========== |
526 | 510 | const cursor = document.getElementById('custom-cursor'); |
527 | | - const trailContainer = document.getElementById('cursor-trail-container'); |
528 | | - let trailPositions = []; |
529 | | - const MAX_TRAIL = 8; |
530 | 511 |
|
531 | 512 | function updateCursor(e) { |
532 | 513 | const x = e.clientX, y = e.clientY; |
533 | | - cursor.style.left = x + 'px'; cursor.style.top = y + 'px'; |
534 | | - trailPositions.push({ x, y, time: Date.now() }); |
535 | | - if (trailPositions.length > MAX_TRAIL) trailPositions.shift(); |
536 | | - trailContainer.innerHTML = ''; |
537 | | - trailPositions.forEach((pos, i) => { |
538 | | - const dot = document.createElement('div'); |
539 | | - dot.className = 'cursor-trail'; |
540 | | - const age = (Date.now() - pos.time) / 1000; |
541 | | - const opacity = Math.max(0, 0.6 - age * 0.8); |
542 | | - const scale = 1 - i * 0.1; |
543 | | - dot.style.left = pos.x + 'px'; dot.style.top = pos.y + 'px'; |
544 | | - dot.style.opacity = opacity; |
545 | | - dot.style.transform = `translate(-50%, -50%) scale(${scale})`; |
546 | | - trailContainer.appendChild(dot); |
547 | | - }); |
| 514 | + cursor.style.transform = `translate3d(${x - 10}px, ${y - 10}px, 0)`; |
548 | 515 | } |
549 | 516 |
|
550 | 517 | document.addEventListener('mousemove', updateCursor, { passive: true }); |
|
0 commit comments