Work product · build spec (v2)

Demo Site Build Spec — Law Firm Document Automation

Deliverable: personalized interactive demo site, one URL per prospect
Stack: static build · Netlify · DNS CNAME per subdomain
Scope of v2: params reduced to firm + practice area + logo; current-tool detection replaced by an on-page toggle; pricing slider simplified; per-practice-area engagement letters; bot-protection spec for live send

1 · URL & personalization

ParamMeaningExampleDefault
fFirm display namef=Hale+%26+Mercer"Your Firm"
pPractice area (pi, estate, family, immigration, business)p=pibusiness
sFirm slug — keys the logo file and the send tokens=halemercernone
kSigned send-token (only on links where live send is enabled)k=eyJ...absent → simulation only

Logo system: per-prospect logo committed at /logos/{slug}.png. On load: if s is present and the logo exists, it renders in the demo header and document previews; otherwise a neutral mark + firm-name text. Adding a prospect = drop one PNG, commit, push. No code changes per prospect.

Sanitization: escape f, cap lengths, strip anything URL-like. All params are untrusted input.

Link generator (/make, noindex): firm name, slug, practice area, optional live-send enablement (prospect email domain + expiry) → outputs the personalized URL. 60 seconds per prospect.

2 · The tool toggle — one page, two buyers

A prominent pill button in the hero: "Already on Clio, MyCase, or PracticePanther? Tap here →". Tapping switches the entire page between two stakeholder framings:

Default mode (standalone e-sign or no system)PM mode (toggled)
Hero"{Firm}, stop paying per seat to send documents.""{Firm}, your intake and your documents should talk to each other."
Cost sliderSavings math vs. per-seat e-sign plansReframed as time math: hours/week of retyping × staff rate → annual cost of manual handling. Same component, different formula and labels.
Integration caption"Works alongside your intake tool — we read from it, we don't replace it."

The toggle doubles as qualification telemetry — an analytics event fires on tap, so we know what the prospect runs before the first call.

3 · Page structure

§A Hero

Firm name, logo if present, mode-aware copy, toggle button, CTA anchors ("Try the send flow" / "See the math").

§B Interactive send demo

Three-step simulation: template → recipient → live status dashboard with a Remind button and audit-trail modal. Template cards render the practice-area engagement letter with the firm's letterhead and merge fields highlighted.

Live-send button (rendered only with a valid k token — §6): "Send this to yourself for real →". The prospect signs the demo letter on their own phone. Every sent document carries the SAMPLE disclaimer.

§C Intake → auto-fill

Three-field mini intake form live-renders into the engagement-letter preview. This is the conversion section.

§D The gap calculator — no fee disclosure

Framing decision: the demo compares the prospect's current bill to the raw infrastructure cost of sending their documents. Our build fee and retainer are deliberately absent from the page — the slider's job is to make the size of the problem undeniable, not to quote. Pricing is scoped per client, on the call.
currentAnnual = seats × rate × 12
  // flag if vol×12 > seats×100: "over the per-seat envelope cap —
  // your real bill is higher than this."
sendingCost   = 300 + max(0, vol−100) × 0.25 × 12
gap           = currentAnnual − sendingCost
"Our build and support fees come out of that gap — scoped to your firm's needs on a 15-minute call. If the total doesn't beat your current bill, we'll tell you, and the call ends early."

Honesty rule: if the gap is small (<$1,000 at their settings), don't inflate — show "at your size this is a workflow play, not a cost play" and emphasize §C instead. Never fake a big number.

§E Compliance strip

ESIGN/UETA, audit trail, SOC 2, HIPAA-capable — and wet-ink exclusions (wills/codicils) stated plainly.

§F What you own + CTA

Repo handoff, the e-signature account in the firm's name, month-to-month support — no annual lock-in. No fee figures anywhere in this section. Closing line: "Bring your current invoice — if we can't beat it, the call ends early."

4 · Engagement letter templates

Five practice-area letters, selection driven by p. Each renders with firm letterhead, live-bound merge fields ({{client_name}}, {{matter_description}}, {{fee}}, {{date}}), and a visible footer in all rendered and sent versions:

"SAMPLE DOCUMENT — for demonstration purposes only. Not legal advice. Production systems use the firm's own approved language."

That disclaimer is non-negotiable: we are not supplying legal language to law firms, we're demonstrating plumbing.

5 · Build plan (1–2 days for v1, simulation-only)

  1. Param parser (f, p, s) + logo loader with fallback
  2. Mode toggle + two-key content config
  3. §D slider with both formulas + honesty state (unit-test the math)
  4. §B send simulation + letter templates wired to p
  5. §C live merge preview
  6. /make generator (link only; token minting ships with v1.5)
  7. Deploy, DNS, param/mode matrix test, Lighthouse, noindex

Live send is v1.5 — it ships, but never delays v1 outreach. Build cost ≈ half a day (one serverless function + token minting + rejection tests). Marginal cost per prospect after that: zero.

6 · Live send: bot-protection spec

Threat model, in priority order: (1) spam relay — bots using the endpoint to email arbitrary addresses, poisoning sender reputation; (2) resource abuse of the serverless function; (3) harassment via a leaked link.

#ControlImplementation
1No public endpoint behavior. Send exists only with a valid k token; everything else renders simulation only.HMAC-signed payload {slug, allowedDomain, exp}; secret in env vars, never client-side; signature + expiry verified on every call.
2Recipient domain lock. A leaked link cannot email anyone outside the prospect's own domain.Server-side check; client pre-locks the domain portion of the email field.
3Hard caps. 3 sends/token/day, 10 lifetime, per-IP rate limit.Counter in a KV store; in-function throttle.
4Invisible CAPTCHA on the send action.Client widget → server-side verification before sending.
5Honeypot + timing check.Hidden field must be empty; reject submissions <2s after render.
6Test-mode envelopes only. No billing exposure even if everything else fails.Separate API key from any production client work.
7Token expiry, 30 days. Stale links die — and refresh is a re-engagement excuse.exp in payload, set by /make.
8Logging + alert.Every attempt logged (slug, IP, outcome); alert on rejection spikes.

Residual risk after controls: low. Worst case with a leaked valid link is a handful of test-mode sample letters to the prospect's own domain — annoying, capped, recoverable. The catastrophic failure mode (open spam relay) is structurally impossible: no token → no send path.

7 · Definition of done