|
3 | 3 | import { base } from '$app/paths'; |
4 | 4 |
|
5 | 5 | interface SponsorAd { |
6 | | - id: number; |
| 6 | + id: string | number; |
7 | 7 | name: string; |
8 | 8 | tier: string; |
9 | 9 | logo: string; |
|
28 | 28 | let expanded = $state(false); |
29 | 29 | let progress = $state(0); |
30 | 30 | let dismissed = $state(false); |
31 | | - let isDarkMode = $state(false); |
32 | 31 |
|
33 | 32 | let progressInterval: ReturnType<typeof setInterval>; |
34 | 33 | let hideTimeout: ReturnType<typeof setTimeout>; |
|
104 | 103 | } |
105 | 104 |
|
106 | 105 | onMount(() => { |
107 | | - // Detect dark mode |
108 | | - const darkModeQuery = window.matchMedia('(prefers-color-scheme: dark)'); |
109 | | - isDarkMode = darkModeQuery.matches; |
110 | | -
|
111 | | - const handleColorSchemeChange = (e: MediaQueryListEvent) => { |
112 | | - isDarkMode = e.matches; |
113 | | - }; |
114 | | - darkModeQuery.addEventListener('change', handleColorSchemeChange); |
115 | | -
|
116 | 106 | // Show first ad after a short delay |
117 | 107 | const initialDelay = setTimeout(() => { |
118 | 108 | showAd(); |
|
123 | 113 | clearInterval(progressInterval); |
124 | 114 | clearTimeout(hideTimeout); |
125 | 115 | clearTimeout(nextAdTimeout); |
126 | | - darkModeQuery.removeEventListener('change', handleColorSchemeChange); |
127 | 116 | }; |
128 | 117 | }); |
129 | 118 |
|
|
137 | 126 | return path; |
138 | 127 | } |
139 | 128 |
|
140 | | - // Get the correct logo based on dark/light mode |
| 129 | + // Get the logo (always light mode) |
141 | 130 | function getLogo(ad: SponsorAd): string { |
142 | | - if (isDarkMode && ad.logoDark) { |
143 | | - return resolveAsset(ad.logoDark); |
144 | | - } |
145 | 131 | return resolveAsset(ad.logo); |
146 | 132 | } |
147 | 133 | </script> |
|
171 | 157 | <span class="sponsor-message">{currentAd.message}</span> |
172 | 158 | <span class="sponsor-name">{currentAd.name}</span> |
173 | 159 | <span class="sponsor-tier">{currentAd.tier} sponsor</span> |
| 160 | + <span class="tap-hint"> |
| 161 | + Tap for details |
| 162 | + <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"> |
| 163 | + <polyline points="9 18 15 12 9 6"/> |
| 164 | + </svg> |
| 165 | + </span> |
174 | 166 | </div> |
175 | 167 |
|
176 | 168 | <button |
|
307 | 299 | width: 100%; |
308 | 300 | text-align: left; |
309 | 301 | cursor: pointer; |
| 302 | + transition: transform var(--transition-fast), box-shadow var(--transition-fast); |
310 | 303 | } |
311 | 304 |
|
312 | | - @media (prefers-color-scheme: dark) { |
313 | | - .toast { |
314 | | - border-color: var(--color-yellow); |
315 | | - } |
| 305 | + .toast:hover { |
| 306 | + transform: translateY(-2px); |
| 307 | + box-shadow: 0 -6px 24px rgba(0, 0, 0, 0.2); |
316 | 308 | } |
317 | 309 |
|
| 310 | + .toast:active { |
| 311 | + transform: translateY(0); |
| 312 | + } |
| 313 | +
|
| 314 | +
|
318 | 315 | .progress-bar { |
319 | 316 | position: absolute; |
320 | 317 | top: 0; |
|
374 | 371 | text-overflow: ellipsis; |
375 | 372 | } |
376 | 373 |
|
| 374 | + .tap-hint { |
| 375 | + display: inline-flex; |
| 376 | + align-items: center; |
| 377 | + gap: 4px; |
| 378 | + font-size: var(--text-xs); |
| 379 | + font-weight: 600; |
| 380 | + color: var(--color-primary); |
| 381 | + margin-top: 2px; |
| 382 | + } |
| 383 | +
|
| 384 | + .tap-hint svg { |
| 385 | + animation: bounce-right 1s ease-in-out infinite; |
| 386 | + } |
| 387 | +
|
| 388 | + @keyframes bounce-right { |
| 389 | + 0%, 100% { |
| 390 | + transform: translateX(0); |
| 391 | + } |
| 392 | + 50% { |
| 393 | + transform: translateX(3px); |
| 394 | + } |
| 395 | + } |
| 396 | +
|
377 | 397 | .close-btn { |
378 | 398 | display: flex; |
379 | 399 | align-items: center; |
|
0 commit comments