feat: update image assets and enhance animations#2973
Conversation
- Replaced the cover image for the StoreAlert customer story with a new WebP format for better performance. - Added a new avatar image for Phil McCluskey in WebP format to improve loading times. - Updated CSS animations by removing unnecessary blur effects and refining keyframes for smoother transitions. - Adjusted HTML structure in various components for better accessibility and semantic correctness. - Increased the number of icons displayed per page in the homepage strip for improved user experience. These changes aim to enhance the overall performance and visual quality of the application.
Appwrite WebsiteProject ID: Website (appwrite/website)Project ID: Tip SSR frameworks are fully supported with configurable build runtimes |
Greptile SummaryThis PR replaces image assets with WebP equivalents, strips blur effects from CSS animations, adds font preload hints for CLS reduction, fixes label/input associations in bento animations, and refactors the homepage AI tool strip and platforms section into unified components with direct doc links.
Confidence Score: 3/5The PR is generally safe but the homepage AI tools strip has an HTML validity issue that should be resolved before merging. The ecosystem strip in src/routes/(marketing)/(components)/ai.svelte needs attention for the nested interactive element structure; src/lib/components/MainNav.svelte should be verified to confirm the submenu component manages ARIA attributes independently. Important Files Changed
Reviews (1): Last reviewed commit: "format" | Re-trigger Greptile |
| <Tooltip.Trigger | ||
| class="border-smooth group relative flex h-16 w-full items-center justify-center border-r border-dashed {i === | ||
| 0 | ||
| ? 'border-l' | ||
| : ''}" | ||
| > | ||
| <span class="relative z-10">{tool.name}</span> | ||
| <div | ||
| class="absolute inset-0 rounded-md bg-gradient-to-tl from-(--primary-color)/4 to-(--secondary-color)/10" | ||
| ></div> | ||
| </div> | ||
| {/if} | ||
| </button> | ||
| class="pointer-events-none absolute inset-0 z-0 bg-gradient-to-tl from-(--primary-color)/4 to-(--secondary-color)/10 opacity-0 transition-opacity group-hover:opacity-100" | ||
| > | ||
| <Noise opacity={0.1} /> | ||
| </div> | ||
| <a | ||
| href={tool.href} | ||
| class="relative z-10 flex size-full min-h-0 min-w-0 items-center justify-center" | ||
| aria-label={`${tool.name} — Appwrite docs`} | ||
| > | ||
| <img | ||
| src={$themeInUse === 'light' ? tool.light : tool.dark} | ||
| alt="" | ||
| class="h-9 w-9 shrink-0 object-contain opacity-90 transition-opacity duration-300 group-hover:opacity-100" | ||
| /> | ||
| </a> | ||
| </Tooltip.Trigger> |
There was a problem hiding this comment.
<a> nested inside <Tooltip.Trigger> produces invalid HTML
Tooltip.Trigger from bits-ui renders as a <button> element by default. Placing an <a> inside it creates a <button><a></a></button> structure, which is explicitly invalid per the HTML spec (interactive content cannot contain other interactive content). Browsers parse this inconsistently — some promote the <a> outside the <button>, breaking the hover trigger region — and screen readers may announce both elements independently, confusing the accessible name. The fix is to pass asChild to Tooltip.Trigger and use a semantically neutral wrapper so the <a> itself is the only interactive element.
| {#each links as link} | ||
| <li class="web-main-header-nav-item text-primary hover:text-accent"> | ||
| {#if link.submenu} | ||
| <div | ||
| class="web-main-header-nav-item-button" | ||
| aria-haspopup="true" | ||
| aria-expanded="false" | ||
| aria-controls="submenu" | ||
| data-submenu-button | ||
| > | ||
| <div class="web-main-header-nav-item-button"> | ||
| <svelte:component this={link.submenu} label={link.label} /> | ||
| </div> | ||
| {:else} |
There was a problem hiding this comment.
ARIA attributes removed from nav item button
aria-haspopup="true", aria-expanded="false", and aria-controls="submenu" were removed from the wrapper div. These attributes signal to screen readers that the element opens a popup and whether it is currently open. Without them, assistive technologies will not announce the presence of the submenu to keyboard and screen-reader users, reducing discoverability. If the submenu component itself now manages these attributes on its internal trigger, this is fine — but if it does not, the accessibility regression should be addressed before merging.
| <Pullquote | ||
| name="Phil McCluskey" | ||
| title="App Manager, Majik Kids" | ||
| avatar="/images/testimonials/phil.jpg" | ||
| avatar="/images/testimonials/phil-avatar.webp" |
There was a problem hiding this comment.
Old
phil.jpg avatar not removed from static assets
The reference was updated to phil-avatar.webp, but the original static/images/testimonials/phil.jpg file is not deleted in this PR. The stale file will continue to ship in the production bundle and be processed by the image optimiser on the next run, wasting build cache and CDN storage. It should be deleted alongside this change.


These changes aim to enhance the overall performance and visual quality of the application.
What does this PR do?
(Provide a description of what this PR does.)
Test Plan
(Write your test plan here. If you changed any code, please provide us with clear instructions on how you verified your changes work.)
Related PRs and Issues
(If this PR is related to any other PR or resolves any issue or related to any issue link all related PR and issues here.)
Have you read the Contributing Guidelines on issues?
(Write your answer here.)