©Ridge NelsonWebsites & systems

QuoteWell

← All work

More workProduct
Front end
QA

A website and the lead system behind it, sold as one product to contractors who lose work in the gap between a call coming in and somebody answering it.

Role
Owned product. Positioning, identity, copy, interface, build and tests.
Status
Live at quotewell.net, 2026.
Stack
Next.js, TypeScript, Tailwind, Cal.com, Playwright
The QuoteWell homepage as shipped, top to bottom: “Your website, plus the lead system.” over a darkened job-site photograph with a Get a Free Lead-Loss Audit button, then the response-time figures, the argument that the business is already established while the website has to catch up, and the Selected work section.
Live · quotewell.net

The homepage as shipped. Point at it or press Scroll the site.

Positioning

Most agencies fix the shopfront and leave the leak.

A website alone does nothing about the gap between a call coming in and somebody answering it. QuoteWell sells both halves as one thing: the site, and the response system wired to it.

The writing is plain on purpose. Contractors are sold to badly and constantly, so every page answers one question and ends in the same two actions: book the audit, or see the work.

The QuoteWell process page: “The process is the guarantee.” set very large in white on near-black, above a line describing five stages: audit, scope, build, test, stabilize.
Five named stages.
A QuoteWell section listing where contractors lose work (calls missed, leads scattered across texts and forms) beside a photograph of a roofer laying tile on a steep red roof.
The problem it is sold against.

Proof

No invented metrics, no borrowed testimonials.

No booked-job outcomes are claimed anywhere. The work section ships two complete reference builds instead, a roofing company and a grounds-care company, each labelled as a demonstration, not a client.

QA

The tests break the lead form on purpose.

A lost lead is the failure that costs money, so that is what gets attacked. One test found a real bug, and the test itself had only ever passed by luck.

  1. Fail

    The form endpoint is forced to return a 500. The test looks for the error message by role, and stops.

    strict mode violation: getByRole("alert") resolved to 2 elements
  2. Trace

    Two live regions, not one: the form’s own error, and the route announcer Next.js injects into every page.

    1 form error role="alert" 2 route announcer role="alert"
  3. Fix

    Scope the locator to the form, so the assertion can only see the element the form controls.

    form.getByRole("alert")
  4. Verify

    Both failure-path tests pass, and fail again when the error state is broken on purpose.

    ✓ 500 keeps the input, offers retry ✓ network drop never loses the lead 28 cases · axe in the same run

Reconstructed from commit 0dee430 and tests/smoke.spec.ts. The guarantee under test: if the form endpoint fails, the visitor keeps what they typed and is offered a retry.

tests/smoke.spec.ts · real excerpt43 cases · @axe-core/playwright
test("contact form: a server failure keeps the user's input and offers a retry", async ({ page }) => {
  await page.route("**/formspree.io/**", (route) =>
    route.fulfill({ status: 500, body: "boom" }),
  );
  await page.goto("/contact/");
  await page.fill("#c-name", "Test Person");
  await page.fill("#c-email", "test@example.com");
  await page.fill("#c-message", "This submission is going to fail.");
  await page.getByRole("button", { name: /send message/i }).click();

A second defect was in the copy: the site claimed “0.00 layout shift”. Measured on a throttled mobile profile it was 0.022, so the claim came down and a number that held on every run replaced it.

Current state

Live at quotewell.net. A static export with no client database, booking through Cal.com, essential cookies only. 43 Playwright cases run with axe.

Back to the flagships · 01 OVREL