What They See: one control panel for all four customer stages

One registry of switches covering the estimate, the intake form, the agreement page and the dashboard, changeable at any time including days after the estimate went out.

What it is

A single registry defining every toggleable block on all four customer surfaces. Estimate keys are unprefixed for backwards compatibility; the other three stages are namespaced intake:, contract: and dash:. Rows can declare a capability they need, so a control never appears for content the estimate does not have, and drag-reordering writes a saved section order.

Also called: hide sections from the customer · customise the client portal · portal sections · what the client sees

See it, piece by piece
01

One panel decides what the customer sees on all four surfaces

Estimate, details form, agreement and dashboard, each a tab of switches over every block those pages can render. Everything defaults on, so a builder who never opens the panel gets the full page. Before this, only the estimate had controls, they lived inside a Send Estimate modal, and half of them were duplicated by a second set of toggles that wrote somewhere else entirely.

02

Change it days after the estimate went out

The live settings outrank the frozen snapshot, so switching a section on or off reaches an estimate already sitting in a customer's inbox — no resend, no new link, no explaining why they have two. Previously a section switched off at send time was off forever, and the controls silently did nothing for it.

03

Hide your labour line without changing what they owe

Every row in Your Investment has its own switch, and hiding one only stops itemising it — the customer total is untouched. If your labour is bundled into a square-foot rate, showing a labour line invites an argument you already priced around; if you sell on transparency, leave every row on. That decision is yours per estimate rather than the software's for everybody.

Your Investment

Your Investment

Materials$49,808.75
Labor$8,910.53
Services & Add-Ons$25,546.00
Concrete Pad$17,400.00
Site Prep & Grading$2,850.00
Seamless Gutters$1,596.00
Custom Garage Door — 9′ × 8′ (2)$3,700.00
Markup$9,083.22
Customer Total$93,348.50
As low as $1,915.24/month (60-month estimate at 8.5% APR)
Illustrative only — based on a 8.5% APR over 60 months. Actual financing terms vary by lender and credit profile. We are not a lender and do not provide financing.
Any of these rows can come off without moving the total. The real screen, drawn from the product’s own design system. Sample data — no customer information appears here.
04

Show a garage door and a price without showing the count and the rate

Each service has three levels: show the line, show its measurement (336 sq ft), show its unit price ($13/sq ft). The two attribute switches are labelled with the words your own catalog uses for that service's unit, so a square-foot service reads Square footage and $ per sq ft. Choosing the wording yourself is how Versetta Stone ends up billed as if it were a per-item line in front of a customer.

05

Controls never appear for content this estimate does not have

A row can declare what it needs, so the 3D viewer switch is absent on an estimate with no model, and the estimate tab generates one row per service line actually on that quote. You can also drag the estimate's sections into the order you sell in — warranty above the price, if that is how you close — and a newly added block drops into a sensible slot rather than the bottom of every layout you already saved.

How it works
  1. 1All toggles live in one sections_enabled JSON map, org defaults plus per-estimate overrides
  2. 2/api/client-portal/config merges them and every customer surface reads the merged map
  3. 3Rows with a needs flag are filtered out unless the estimate has that capability
  4. 4Everything defaults ON, so a builder who never opens the panel gets the full page
  5. 5The estimate stage additionally generates one row per actual service line
Why we built it

Only the first stage of the customer journey had visibility controls, they were buried in a modal labelled Send Estimate, and half of them were duplicated by a second set of switches that wrote somewhere else entirely — so a builder toggling a section off watched nothing happen. A section switched off at send time then stayed off forever, because the frozen copy outranked the live setting. One panel controls all four customer-facing stages, the live setting wins over the frozen snapshot, and the builder can add or remove any block days after the estimate went out.

The problem
  • Controls that only affected the estimate and only at send time
  • Duplicate toggle sets writing to different storage
  • Controls offered for content that does not exist on that estimate
Sound familiar?
What you get
One panel governs every customer-facing surface
Changes apply to already-sent estimates with no resend
Controls never appear for content the estimate cannot show
What's inside

See it on your own jobs

Twenty minutes, your numbers, no slide deck. We’ll build one of your real buildings in front of you and send you the estimate link at the end — yours to keep either way.

or keep browsing features →