North Creek starts with the portfolio, but the interesting interaction is what happens after a visitor chooses a package. The enquiry opens with the shoot type already selected, then asks for a date, a location and contact details.
I built this as a fictional wedding, family and brand photographer in Ann Arbor. The site uses React 19, TypeScript, Vite and Tailwind CSS v4, with motion for the enquiry transitions and static deployment on a Cloudflare Worker.
01 / FIELD NOTESThe questions a quote needs are not a quote
Preparing a quote and calculating one are different jobs. North Creek handles the first: four steps collect the details, with the package choice carried into the form. The documented implementation does not include a pricing formula or generated quote.
The confirmation has a separate limit. It is a front-end screen, not a connected delivery path. Completing the flow does not send the details to the photographer.
02 / FIELD NOTESFour steps, one validation function
The source validates the current step before allowing the flow to advance:
const isStepValid = () => {
switch (step) {
case 1:
return formData.shootType !== '';
case 2:
return isFlexibleDate || formData.date !== '';
case 3:
return formData.location.trim().length > 2;
case 4:
return (
formData.name.trim().length > 1 &&
/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.email) &&
formData.phone.trim().length > 6
);
default:
return false;
}
};The first step requires a nonempty shoot type. The date step allows either a date or the flexible-date option. The location step checks trimmed length. The contact step combines a name-length check, an email pattern and a phone-length check.
INSPECT THE BOUNDARY
What does this check actually prove?
Evaluate fixed examples against the original function, including cases it does not validate further.
shootType: ""SOURCE CONDITIONshootType !== ''The type is empty, so the first step cannot advance.
Read the explanation without interacting
Type must be nonempty. Date must be nonempty or marked flexible. Location must have more than two trimmed characters. Contact combines name length greater than one, the shown email pattern, and phone-string length greater than six. Seven letters in the phone field can therefore pass; that is not phone validation.
This inspector evaluates the published conditions against fixed examples. A phone string containing seven letters passes the length condition; that does not make it a usable phone number. Similarly, the date branch shown checks whether a value is nonempty, not whether the photographer is available.
This is the validation function shown in the article. Any additional browser constraints would need to be checked against the input components themselves.
03 / FIELD NOTESDon't ask for the same choice twice
The original page has three packages with visible sample price labels. Clicking one opens the enquiry with the shoot type preselected, so the visitor can move straight to the date.
That gives the pricing section and the form a shared piece of context. It also preserves a way back: the new local explanation on the project page lets a reader revise the type without losing the rest of the sample answers.
“I'm flexible” handles a different kind of uncertainty. A visitor may know the kind of session they need before they know its date. The source treats that as an explicit answer rather than requiring a made-up date to continue.
04 / FIELD NOTESThe portfolio still matters
The original design uses a warm paper background, Cormorant Garamond headings and a filterable masonry grid of twelve images with a lightbox. The guided enquiry complements that image-led presentation; it is not intended to replace it with a form-first homepage.
No original photos or full-resolution capture were supplied with this reference. The case-study illustrations therefore explain the sequence instead of pretending to display the photographer's real work.
05 / FIELD NOTESWhere this version stops
The original improvement list is short and concrete. The confirmation is front-end-only; a Worker endpoint and email notification are the missing delivery path. The twelve portfolio images load eagerly; the source identifies lazy-loading as the next step before expanding to a much larger collection.
There is no conversion experiment in the account and no delivered-enquiry evidence to add here. The useful result is the interaction itself: package context carried forward, a flexible date, step-by-step checks, and a clearer set of details for the eventual conversation.
Source, dates, and what this page verifies
This rewrite describes the supplied fictional-business project and its article published July 17, 2026. The original publication date and canonical source address are preserved. The original application and current deployment have not been audited.
New miniatures are explicitly illustrative, not screenshots or full reproductions. All teaching inputs stay in memory. No booking tool, enquiry service, message provider or outside page is loaded by an interaction. Original code excerpts remain unchanged and are displayed rather than executed as application code.
The named source limits and exact explanation of each new model are recorded in docs/batch-4/SOURCE-REVIEW.md. No business, medical, conversion or performance outcome was measured for these demos.