Skip to content

perf: improve homepage and projects page#164

Open
unhexate wants to merge 3 commits intomainfrom
fix/optimizing
Open

perf: improve homepage and projects page#164
unhexate wants to merge 3 commits intomainfrom
fix/optimizing

Conversation

@unhexate
Copy link
Contributor

Optimize animations on homepage, remove glow from the grid animation and use transforms instead of background-position
When selecting a project card in /projects, it would remove it from the grid then expand it, which would mess up the scroll. Now the project remains in the background grid even when selected.
Added arrow keys and swipe navigation for projects page
Fix #145

Copilot AI review requested due to automatic review settings February 27, 2026 02:30
@github-actions
Copy link

Deploy preview for web ready!

✅ Preview
https://web-7zzimpt5h-mlabwebdev.vercel.app

Built with commit 17c4773.
This pull request is being automatically deployed with vercel-action

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR focuses on improving animation performance on the homepage and fixing interaction/scroll behavior on the /projects page (including keyboard + swipe navigation), aligning with issue #145’s mobile/scroll concerns.

Changes:

  • Optimizes the homepage grid animation (removes glow, switches to transform-based movement) and moves glitch keyframes into home.css.
  • Refactors the homepage About section to use an in-component scrambling implementation instead of ScrambleText.
  • Updates /projects selection UX so the selected project expands in an overlay while the card remains in the background grid; adds arrow-key + swipe navigation and prevents scroll jumps.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
css/home.css Optimizes grid animation and centralizes glitch animation CSS.
components/root/aboutUs.js Replaces ScrambleText + inline global styles with a hook-driven scramble implementation and relies on home.css for glitch styles.
components/ProjectCard.tsx Adds a disabled mode to suppress hover effects while a project overlay is open.
app/(main)/projects/page.tsx Keeps cards in the grid while showing an overlay for the selected project; adds keyboard and touch swipe navigation and prevents router scroll jumps.
app/(main)/layout.tsx Changes the main layout scroll/height behavior to address mobile layout issues.

Comment on lines +81 to +84
const id = setInterval(tick, SPEED)
return () => clearInterval(id)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useScrambleAll keeps a 25ms setInterval running even when all strings are finished (until RESTART_DELAY elapses). That means the component wakes up ~40x/sec doing work with no state changes, which is a measurable idle CPU cost on the homepage. Consider switching to a self-scheduling setTimeout that only runs while a scramble is active (or clearing the interval when changed is false and scheduling the next restart with a timeout).

Copilot uses AI. Check for mistakes.
Comment on lines +147 to +150
<span className="glitch layers">What We Do</span>
</a>
<a href="/projects" className={btnClass}>
<span className="glitch layers">Past Projects</span>
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .layers::before/::after styles in home.css render their text via content: attr(data-text), but these spans don't set data-text. As a result, the animated glitch layers will be empty and only the base text will render. Add matching data-text attributes (or change the CSS to duplicate the element text another way) so the effect actually displays.

Suggested change
<span className="glitch layers">What We Do</span>
</a>
<a href="/projects" className={btnClass}>
<span className="glitch layers">Past Projects</span>
<span className="glitch layers" data-text="What We Do">What We Do</span>
</a>
<a href="/projects" className={btnClass}>
<span className="glitch layers" data-text="Past Projects">Past Projects</span>

Copilot uses AI. Check for mistakes.
return (
<div className="group relative cursor-pointer items-center justify-center overflow-hidden rounded-xl bg-black shadow-2xl transition-all duration-500 hover:shadow-xl hover:shadow-black/10">
<div
className={`${disabled ? '' : 'group'} relative cursor-pointer items-center justify-center overflow-hidden rounded-xl bg-black shadow-2xl transition-all duration-500 ${disabled ? '' : '[@media(hover:hover)]:hover:shadow-xl [@media(hover:hover)]:hover:shadow-black/10'}`}
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When disabled is true the hover effects are removed, but the root card still has cursor-pointer, which communicates it’s clickable even though /projects ignores clicks while a modal is open. Consider toggling the cursor style (e.g., cursor-default) and/or adding aria-disabled/pointer-events-none when disabled to match behavior.

Suggested change
className={`${disabled ? '' : 'group'} relative cursor-pointer items-center justify-center overflow-hidden rounded-xl bg-black shadow-2xl transition-all duration-500 ${disabled ? '' : '[@media(hover:hover)]:hover:shadow-xl [@media(hover:hover)]:hover:shadow-black/10'}`}
aria-disabled={disabled}
className={`${disabled ? 'cursor-default pointer-events-none' : 'group cursor-pointer'} relative items-center justify-center overflow-hidden rounded-xl bg-black shadow-2xl transition-all duration-500 ${disabled ? '' : '[@media(hover:hover)]:hover:shadow-xl [@media(hover:hover)]:hover:shadow-black/10'}`}

Copilot uses AI. Check for mistakes.
Comment on lines +146 to +151
const expandedCard =
selectedId !== -1
? (() => {
const card = currentProjects[selectedId]
const i = selectedId
return (
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expandedCard assumes currentProjects[selectedId] always exists. If currentYear changes while a card is open (possible via keyboard focus reaching the year buttons behind the overlay), currentProjects can change without resetting selectedId, making card undefined and causing a runtime crash when reading card.poster_url/title. Fix by resetting selectedId when currentYear/currentProjects changes (or preventing year changes while open) and guarding against out-of-range selectedId before dereferencing.

Copilot uses AI. Check for mistakes.
Comment on lines +189 to +193
<button
className="relative h-6 w-6 shrink-0 lg:h-8 lg:w-8"
onClick={(e) => {
e.stopPropagation()
setSelectedId(
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These icon-only buttons (prev/next/close) don’t have accessible names. Add aria-labels (and optionally type="button") so screen readers can announce their purpose and keyboard users can identify them.

Copilot uses AI. Check for mistakes.
return (
<html lang="en">
<body className="font-martian-mono h-screen flex flex-col overflow-hidden">
<body className="font-martian-mono flex flex-col">
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing h-screen from the <body> means the flex container no longer has a definite minimum height, so flex-grow on <main> won’t push the footer to the bottom on short pages (it will just follow content). If the intent is a sticky footer while still allowing natural page scroll, consider using min-h-[100svh]/min-h-screen instead of dropping the height entirely.

Suggested change
<body className="font-martian-mono flex flex-col">
<body className="font-martian-mono flex flex-col min-h-screen">

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix mobile view

2 participants