Motion is part of my brand — not decoration
elangodev.com is a portfolio for an engineer who cares about interfaces. Static pages would contradict that story. I use Framer Motion across the public homepage, elangodev.com entry points, interactive lab demos, and the login screen leading to my dashboard. The goal is not animation for its own sake — it is communicating responsiveness, depth, and craft through physics-based movement users feel in their hands.
I learned early that linear CSS easing looks cheap on high-refresh phones. Real objects accelerate and settle. Framer Motion's spring model lets me define stiffness and damping once, then interrupt animations when scroll direction changes without visual pops.
Scroll progress bar with useSpring
HomeContent.jsx renders a fixed one-pixel bar at the top of elangodev.com that scales horizontally with reading progress. useScroll provides scrollYProgress as a motion value between zero and one. Raw binding would feel jittery on trackpads; useSpring smooths input into a natural deceleration curve.
const { scrollYProgress } = useScroll();
const scaleX = useSpring(scrollYProgress, {
stiffness: 100,
damping: 30,
restDelta: 0.001,
});
<motion.div
className="fixed top-0 h-1 origin-left z-50 bg-gradient-to-r ..."
style={{ scaleX }}
/>I animate scaleX via transform — GPU compositor territory — not width. Width animation would trigger layout every frame and destroy Interaction to Next Paint on long homepage sessions. That single choice is the difference between premium motion and janky progress indicators.
Hero entrances without blocking LCP
Hero copy and profile photo use motion.div with initial opacity and y offsets, easing via cubic-bezier arrays like [0.16, 1, 0.3, 1]. I delay secondary elements — quick link pills, floating stats badge — so the headline paints first for Lighthouse. Motion runs after meaningful content exists; I never hide text until JavaScript executes unless skeletons are shown, which I avoid on the main hero.
ScrollToTop and the Explore chevron use repeating y keyframes with easeInOut. Subtle loops guide attention without competing with CTA buttons. whileHover and whileTap on buttons give tactile scale feedback — 1.02 hover, 0.98 tap — mimicking physical button travel.
Card hover physics in elangodev.com
The card hover playground at /blog is where I stress-test spring presets before reusing them on the portfolio. Theme presets swap particle color arrays and gradient accents. Framer Motion handles card lifts, message typography entrances, and theme transitions while keeping animated properties on the compositor.
Physics here means more than springs — it is choosing velocities and easing that feel responsive without freezing low-end Android browsers. I cap simultaneous effects when previews run inside denser lab layouts. Themes swap CSS variables and Tailwind classes rather than re-mounting entire trees when possible.
<motion.div
initial={{ scale: 0 }}
animate={{ scale: 1 }}
transition={{ type: "spring", stiffness: 260, damping: 20, delay: 0.2 }}
>
<LogIn className="w-8 h-8 text-white" />
</motion.div>That snippet is from my login page — the same spring signature I reuse for icon badges so elangodev.com and auth flows feel cohesive. Consistent stiffness/damping pairs become an informal design token across elangodev.com.
Login page atmosphere
app/login/page.jsx wraps the form in animated blob backgrounds — large blurred circles with animate-blob keyframes in globals.css. The card uses glass morphism: backdrop-blur, semi-transparent borders. motion.div fades the panel upward on mount with easeOut over 0.8 seconds.
I keep form inputs unanimated — focus rings and border color transitions only. Typing while parent springs oscillate caused micro-stutters I eliminated by isolating motion to decorative layers behind the form.
PublicNav micro-interactions
PublicNav on blog and inner pages uses Framer Motion for mobile drawer AnimatePresence — enter exit opacity and x slides. Desktop links rely on CSS hover color shifts for zero JS cost on every mousemove. I match interaction budget to frequency: menus open rarely; hovers fire constantly.
Performance rules I enforce
Animate transform and opacity. Prefer springs for interruptible UI; use tween durations for one-shot page entrances. Lazy-mount heavy backgrounds with mounted state — HomeContent waits until useEffect sets mounted true before rendering MeshBackground blobs, saving first-paint work on slow devices.
Respect prefers-reduced-motion where feasible — I am incrementally adding media query overrides to disable infinite chevron loops for accessibility. Physics should delight, not nauseate.
Shared motion vocabulary across the site
The site lists gradient generators, CSS animation builders, and card hover demos in the homepage and blog. Each tool links out with consistent card hover scale and icon bounce on mount. I reuse the same transition duration tokens — 0.6s for page sections, 0.8s for auth modals — so moving between elangodev.com and /blog feels like one product family rather than unrelated demos.
Why this matters for hiring and editorial quality
Recruiters remember sites that feel alive. Core Web Vitals still pass because I choreograph motion around metrics — not against them. elangodev.com proves I can teach animation concepts because elangodev.com practices them on the homepage and interactive demos I actually host.
High-performance UI physics is a discipline: choose the right motion primitive, constrain animated properties, align spring constants across routes, and test on real phones. That is the implementation story behind the gradients and springs — code I ship on elangodev.com, not theory I bookmark.
Where motion belongs on a publication site
During AdSense recovery I reduced decorative motion on the homepage. Physics-inspired springs still power intentional transitions in demos and selected UI, but editorial reading mode stays calm. Motion should create hierarchy, not noise — especially when reviewers are scanning for substance.
I profile animations against INP. If a spring blocks input on mid-tier Android, it does not ship on / or /blog. Experiments stay on isolated routes.
Implementation notes from this codebase
Framer Motion appears where interaction needs it; CSS handles simple fades. I avoid animating large layout reflows on article pages. Prefer transform and opacity. Prefer reduced-motion media queries for accessibility — a publication that ignores prefers-reduced-motion fails real users even if Lighthouse is green.
Field notes unique to high performance ui physics
I keep this article in the elangodev.com corpus because it captures decisions I made while shipping features on this domain or in client systems I can discuss publicly. If a section ever drifts into generic textbook language, I rewrite it with a concrete file path, metric, or failure story. That editorial rule is how we avoid another round of low-value AdSense feedback.
Readers should leave with a default recommendation, a “do not do this” warning, and a verification step. For example: change one config, deploy to preview, measure one metric, then promote. Tutorials that never tell you how to know it worked are incomplete — I try to close every guide with a verification habit I actually use.
Finally, I cross-link related handbook chapters and sibling posts sparingly. Internal links should help humans navigate a topic cluster, not manufacture a crawl graph of thin pages. After the unpublish pass, only keepers that clear our depth bar remain published and sitemap-listed.
I will continue expanding this guide as production behavior on elangodev.com changes — new failure modes, new metrics, new code paths. Treat the article as a living engineering note, not a static SEO page. That maintenance posture is part of how a real publication compounds value for readers and for crawlers evaluating originality over time.
Verification step: after applying the ideas here, deploy to a preview URL, click through the affected elangodev.com route, and confirm logs or UI match the expectation stated above. If they do not, fix the implementation before you expand the essay further.





