Open comments for this post
worked around 8 hours on the projects section of akhilkonduru.com today.
i wanted the react side of it to feel less hardcoded, so i moved a lot of the project data into a cleaner structure and mapped it into reusable cards instead of manually editing each one. after that i spent a while fixing responsive issues because the layout looked fine on my screen but started falling apart on wider monitors and some smaller widths too.
the filtering and animation logic also took longer than i expected since a couple state changes were causing weird visual glitches when switching categories. it is a lot cleaner now though and adding future projects should be way easier.
Open comments for this post
refactoring github and cleaning up code
boring but I had to do it, it was long overdue
Open comments for this post
another 4 hours passed… time goes pretty quick icl
i have an ultrawide screen so i’ve spent this past time trying to cater to this screen. as you can see there is a lot of empty space and i’ve been trying to figure out how to utilize it.
Open comments for this post
another 4 hours passed… time goes pretty quick icl
i have an ultrawide screen so i’ve spent this past time trying to cater to this screen. as you can see there is a lot of empty space and i’ve been trying to figure out how to utilize it.
Open comments for this post
this past couple of hours was less of coding and more of setting up past things that i’ve been doing.
i havent finished everything yet but I am implementing things I have done in the past as well as descriptions for it.
im trying to ensure that my animation style stays consistent.
Open comments for this post
I worked on making this time zone counter that tracks the difference between your device’s local time and my time zone, which makes it easier for people to see where I am and what time it is and whether they Should’ve messaged me at that time. I’m not completely sure if it worked but I’m pretty sure it does
Open comments for this post
I’ve spent the first 46 minutes of this building the actual website or the actual service on iWAS. I’m trying to create the algorithm and refine it so that it stays accurate and takes in many factors into account such as:
- fatigue
- readiness
- time of day
- traffic
- number of turns
- driving length
and so on
Open comments for this post
I’ve spent the first 46 minutes of this building the actual website or the actual service on iWAS. I’m trying to create the algorithm and refine it so that it stays accurate and takes in many factors into account such as:
- fatigue
- readiness
- time of day
- traffic
- number of turns
- driving length
and so on
Open comments for this post
yo more cool animations. took a while to make this happen properly but now in the contact page I can hover over things and they move smoothly and imo pretty cool-ly
Open comments for this post
yo more cool animations. took a while to make this happen properly but now in the contact page I can hover over things and they move smoothly and imo pretty cool-ly
Open comments for this post
Devlog: Proximity Prefetching
Next.js prefetches links when they enter the viewport. I learned that is often too late. By the time a link is visible, I am usually already moving toward it.
So I built a proximity prefetcher. When the cursor gets within 150px of an internal link, that route starts loading in the background.
The idea
Hover prefetch works on desktop. I wanted something earlier. If I am drifting toward Projects, the page should already be warming up before I click.
What I learned
Performance — A raw mousemove handler on the whole window runs constantly. I learned to throttle checks to every 80ms and keep a Set of prefetched routes so the same page never gets requested twice.
Distance math — Measuring cursor to link center was wrong for wide nav items. I learned to find the closest point on the bounding box first, then check if the cursor is inside the radius.
What to prefetch — I learned to only prefetch internal paths starting with /. External and hash links stay out. Keeps the logic focused on actual page transitions.
Mobile — I learned this pattern is mouse only. Touch devices keep Next.js default prefetch. No cursor means no proximity signal.
Takeaway
I learned that small perf details matter on animation heavy sites. Navigation already has a bubble transition. Prefetching nearby routes made that transition feel instant instead of exposing a gap I had not designed for.
Open comments for this post
Devlog: The Spotify Widget
I wanted the About page to feel personal, so I added a music widget. Simple idea, messy execution.
The OAuth problem
Spotify’s real “top tracks” needs user login, refresh tokens, and a full OAuth flow. Too much work for a sidebar widget on a portfolio.
I switched to a curated song list and Spotify’s client credentials flow. A server API route searches each track, returns album art and links. No login needed. The label still says “Top Tracks” but it’s really my late night playlist.
What broke
Secrets — Almost used NEXT_PUBLIC_ env vars. That would expose the client secret in the browser. Everything stays server side now.
Rate limits — Ten searches per load adds up. Cached the API response for an hour on Vercel.
Layout shift — Tracks load after paint, page height changes, scroll animations fire at wrong positions. Same headache as lazy loaded images.
Local dev — Missing env vars shouldn’t crash the page. API returns a clear error, hook handles it gracefully.
Takeaway
Less API fidelity, faster ship. Curated search beats a half built OAuth flow every time.
Open comments for this post
intro animation
I wanted the site to feel personal from the first second — not a template fade-in. So I built a layered intro: a hand-drawn signature on load, a curved bubble curtain on navigation, and smooth scroll underneath.
The idea
Three cases, three behaviors:
Hard reload on home → signature draws, fades, done
First visit → signature on dark overlay, then bubble wipes up underneath
Other nav → quick bubble cover so you never flash the old page
Sounds clean. Getting the layers right was not.
What broke
Vivus + React — Vivus owns the DOM; React owns the DOM. Strict Mode double-mounting left ghost SVGs and half-drawn signatures. Fix: runId refs, replaceChildren() on mount, aggressive cleanup on unmount.
The blank frame — The bubble wiped before the new route painted. Fix: double requestAnimationFrame + a 600ms minimum cover so content exists before the curtain lifts.
Three scroll systems — Browser scroll, Lenis, and GSAP ScrollTrigger all had to stay in sync. Route changes kept you scrolled to the previous page; async content (images, fonts, widgets) broke trigger positions. Fix: resetScrollTop() on navigation, ResizeObserver on the body, and a debounced ScrollTrigger.refresh().
Callback restarts — An unstable onComplete re-ran Vivus mid-draw. Stable useCallback + refs fixed it.
Takeaway
The intro is the one thing every visitor sees. It took more debugging than any project page — but that’s why it doesn’t feel like a reskinned template.
Open comments for this post
commands are established
Command What it does
/dsb-ping-akhil
Replies with pong + latency
/dsb-help-akhil
Lists all available commands
/dsb-catfact-akhil
Fetches a random cat fact
/dsb-joke-akhil
Fetches a random joke
Open comments for this post
Building a contact form that doesn’t feel like a contact form
I wanted reaching out on the site to feel like texting a friend, not filling out a form. The iMessage widget on the About page is a small conversation: an incoming bubble asks what you want to talk about, then how to reach you, then anything else worth sharing. Each reply is a blue outgoing bubble; mine come back with a typing indicator and staggered delays so it reads like a real thread. Under the hood it’s a simple state machine (intro → contact → extra → done) with Framer Motion for bubble entrance and the three-dot typing animation. Messages auto-scroll to the bottom, and when you hover or focus the widget, page scroll locks so wheel events stay inside the chat instead of fighting the rest of the page.
The twist is what happens when the conversation ends. There’s no backend or email API — once the last answer lands, the widget assembles a mailto: link with the collected topic, contact method, and extra notes, and opens your email client with a pre-filled draft to me. That keeps the implementation lightweight (no server, no spam handling) while still turning a playful UI into something actionable. The glassy card, avatar, and bubble styling are mostly CSS and Tailwind; the behavior lives in one client component dynamically loaded on About so it doesn’t block the initial page load. It’s contact UX disguised as personality — form fields hidden inside something people already know how to use.
Open comments for this post
fixed demo link to attach to a channel where it is live
Open comments for this post
animations have been working smoothly.
there were some preloading typescript issues and I am narrowing down potential areas of issue and fixing them