Skip to contact form
← BlogProcessNovember 22, 2026 · 4 min read

How our web and app development process actually works

Discovery, design, build, launch — four phases, and the section of the homepage that explains them is doing more engineering than it looks like. Scroll the demo below.

eople asking "what does a web design agency process actually look like" usually get one of two unsatisfying answers: a vague five-word list with no timeline, or a diagram so detailed it reads like it was written to look thorough rather than to be read. Our homepage answers it with four phases — discovery, design, build, launch — each with a real week range, laid out as cards you scroll through with a progress bar tracking how far along the whole thing you are.

Theinterestingpartisn'tthefourphases.It'sthatthecardsreplayeverytimeyouscrollbackintothem,andtheprogressbardoesn't.

Scroll through it

01 · week 0–1

Discovery

02 · weeks 1–3

Design

03 · weeks 3–9

Build

Each card uses whileInView with viewport: { once: false } — deliberately the opposite of most of the reveal animations on this site, which play once and stay played. Scroll a phase card out of view and back in and it fades and slides in again, every single time. For a section that's explaining a sequence, that repeatability matters: if you scroll back up to re-read Design, you should see it arrive again, not sit there inert because it already "used up" its one entrance.

Two motion systems, one section, doing different jobs

typescript

// Per-card: viewport-triggered, replayable <motion.div initial={{ opacity: 0, x: -20 }} whileInView={{ opacity: 1, x: 0 }} viewport={{ once: false, margin: '-20% 0px' }} /> // Whole-section progress: continuous scroll position, not viewport events const { scrollYProgress } = useScroll({ target: containerRef, offset: ['start 0.2', 'end 0.8'], }); const progressWidth = useTransform(scrollYProgress, [0, 1], ['0%', '100%']);

The cards and the progress bar are driven by two genuinely different mechanisms sitting a few lines apart. whileInView is event-based — it fires when an element crosses a viewport threshold, discrete and re-triggerable. The progress bar is value-based — useScroll continuously reports a 0-to-1 number for how far the pointer target has moved through its scroll range, and the bar's width is just that number, always current, never "triggered." Discrete events for things that should feel like arrivals; continuous values for things that should feel like a fact about where you are.

Why a real week range on every phase

It would be easy to leave the phases untimed — safer, in the sense that nothing can be checked against reality later. We put ranges on them anyway, because a process description without a timeline isn't actually answering the question "how long does this take," which is the question underneath most of the others. Week 0–1 for discovery, weeks 1–3 for design, and so on aren't marketing copy; they're what we tell a client on the first call, published in the same words.