Behind the Scenes of makashif.com — Fluid, Calligraphy, Sound and Performance
TechPortfolio

Behind the Scenes of makashif.com — Fluid, Calligraphy, Sound and Performance

Muhammad Makashif
Muhammad Makashif
2025-10-25 7 min read

makashif.com is my portfolio, but it is also my test bench. Every immersive idea I might propose to a client, from paintable fluids to live sound, I first had to make work here, on real phones, without hiding the content. This is how the site is built, what each layer does, and the lessons I now bring to client projects.

The brief I gave myself

I wanted one page to show the full range of what I do: creative direction, motion and engineering. The constraints were strict:

  • It had to feel alive, not like a template with a video background.
  • The words had to stay readable and indexable, because a portfolio search engines cannot read is just a poster.
  • It had to stay usable on mid-range phones, not just my development machine.
  • Every effect had to belong to the brand, not just show off.

Because I direct the visuals and write the code myself, I could design each effect with its performance cost in mind from the first sketch, with no agency-to-developer hand-off.

The foundation

The site runs on Next.js 16 with the App Router, React 19, TypeScript and Tailwind. Content, metadata and structured data are rendered on the server, so the text arrives as real HTML. The heavy visuals are client-side layers that sit behind that content, built with WebGL, using Three.js for the background, and the Web Audio API.

If every effect failed, the site would still be a fast, readable portfolio; the atmosphere is an enhancement, not a dependency.

Layer 1: a deep-space background that costs less than it looks

The background is a starfield with a multicoloured nebula. No image files are involved: the nebula is generated procedurally in a shader from layered, domain-warped noise, which produces the swirls and filaments of real gas clouds.

The trick that keeps it light is resolution. The nebula is rendered at a third of the screen's resolution in each direction and upscaled with bilinear filtering. Gas is soft by nature, so the lower resolution is effectively invisible, while the GPU shades only about a ninth of the pixels. A tiny dither on the upscale prevents colour banding in the dark gradients.

Lesson: match render resolution to the content. Soft things do not need full resolution.

Layer 2: a fluid you can paint with

The centrepiece is a GPU fluid simulation. Move your pointer or finger and you inject ink and velocity into it.

The part I am proudest of is what happens when you stop. After a couple of seconds of inactivity, the fluid begins to write my name, مکاشف, over the logo, stroke by stroke and right to left, the way it is actually handwritten in Urdu.

Getting that right took more care than the simulation itself. The logo is a filled outline, so its path traces around both edges of every letter, which is useless as a pen path. I extracted the centreline of each letter and ordered the strokes the way a calligrapher would write them: the body of م and ک continuing up through the alef, then the slanted stroke of ک, then the teeth of ش flowing into the loop of ف and its long tail, and finally the dots. The pen lifts between strokes and pauses briefly, so it reads as handwriting rather than a plotter.

When the logo is not on screen, the idle fluid draws shapes instead, taking turns between a heart, an atom, a star, a spiral and a flower.

Lesson: an idle state is an invitation. Showing the interaction is more persuasive than a "drag here" label.

In the hero, a smoke effect gathers into the Urdu logo. It sets the tone before any text is read, and ties the effects back to the identity: the smoke, the fluid writer and the logo all share one calligraphy.

Layer 4: a new palette on every visit

Each visit generates a new colour theme, and everything follows it: the fluid's ink, the smoke's tint and the nebula's colours.

It is not pure randomness. Hues are chosen with a colour-harmony rule, and each role in the palette keeps a fixed range of saturation and lightness. The base is always deep, highlights are always vivid and accents are always bright. Only the hue relationships change, so contrast and mood stay consistent while the site never looks quite the same twice.

Lesson: randomise one variable and constrain the rest.

Layer 5: sound you can play

The site has an ambient soundscape inspired by the Interstellar score: organ-like drones, slow string pads and a faint dusty texture, moving through an Am, F, Em, Am, F, G progression. It is synthesised live with the Web Audio API, so there are no music files to download.

The fluid has a voice too. As you paint, your stroke speed picks a note from whichever chord the music is playing, low for slow strokes and high for fast ones, and your horizontal position pans it left or right. Soft chimes from the same chord add sparkle. Everything stays in key, and even the idle calligraphy writer sings as it writes.

Two rules keep it from becoming annoying:

  • It is opt-in. Browsers block audio until the visitor interacts with the page, and the site has clear controls to turn music and effects on or off.
  • It knows its place. When you play a video with sound, whether a native video or a YouTube embed, the site's audio fades out. It stays quiet while that video is paused but still on screen, and returns only once it has left the viewport. Muted videos are ignored.

Layer 6: a quality governor that trusts the device

Many adaptive-quality systems drop quality at the first dropped frame. I took the opposite position: the site should look its best unless the experience is genuinely breaking.

The governor ignores the first ten seconds, when shader compilation and asset loading cause unavoidable hitches. After that, it steps down one quality level only when the frame rate stays very low for several seconds, or when several long main-thread freezes happen close together, because an average frame rate can hide a freeze. An effect is switched off entirely only if it is still unusable at the lowest level. When things stay smooth for a long stretch, quality steps back up. The background, smoke and fluid each have their own level, so one heavy effect does not drag the others down.

Lesson: measure stalls, not averages, and react only to what people would actually notice.

The interface on top

The content sits on glass panels: translucent, blurred surfaces that keep the moving atmosphere visible behind them. Because the palette and fluid keep changing, each panel carries enough tint to keep its text readable over whatever is beneath.

Booking is handled by a cal.com scheduler embedded directly on the site, so a visitor can pick a time for a call without leaving the page.

What I would tell a client who wants something similar

  • Pick one signature interaction. The fluid works because it is the centrepiece, not one of ten competing effects.
  • Render content first. Server-rendered text and metadata keep a site fast and searchable even if WebGL fails.
  • Budget the GPU like money. Lower render resolutions, fewer noise layers and separate quality levels per effect.
  • Make sound opt-in and polite. Audio that respects content earns the right to stay on.
  • Test on mid-range Android phones, not just flagship devices.

If you want an immersive site that still loads fast and ranks, that is exactly the overlap of creative direction and full-stack web development I work in.

Key takeaways

  • Keep content server-rendered and treat visual effects as layers that can fail gracefully.
  • Render soft visuals like gas and smoke at low resolution and upscale them.
  • Use idle states to demonstrate the interaction, and make them meaningful to the brand.
  • Randomise colour within strict rules so variety never breaks contrast.
  • Make sound opt-in, keep it in key, and fade it out for real content.
  • Adapt quality based on real stalls, not momentary dips.

Planning a project? Book a free discovery call — I'll tell you honestly what it needs.

#Next.js#WebGL#Web Audio#Creative Development#Case Study#Performance

Keep Reading

EXPLORE ALL JOURNAL ENTRIES