# Quote Calculator

## Objective

Let a visitor answer a few questions and get an honest price estimate on the spot.

A guided question flow that produces a priced estimate from server-held rules, with a saved copy for follow-up.

## Before You Begin

This feature is being added to an application that already exists and already
works. Do not scaffold a new project, and do not assume a blank slate.

Inspect the codebase first and establish:

- The existing application structure and where code of this kind already lives.
- The framework and version in use.
- The existing design system — colours, spacing, typography, and component conventions.
- Existing UI components you can reuse instead of writing new ones.
- The existing database structure, if this feature needs to persist anything.
- The existing authentication and authorization system, if this feature is user-scoped.
- Dependencies already installed, so you don't add a library that duplicates one.
- The existing test setup and conventions.

Only start writing code once you understand the above. If the application
already implements part of this feature, extend it rather than replacing it.

## Implementation Instructions

1. Build the question flow on the app's existing Multi-Step Form and Conditional Form Fields rather than a new one-off wizard. Showing and hiding questions based on earlier answers is exactly what conditional fields already do.
2. Keep every rate, multiplier, minimum, and discount on the server. The browser sends answers and receives a priced breakdown; it never holds the price list and never does the arithmetic that produces the total.
3. Show the estimate as itemised lines with a total, not a single number. A visitor who can see which answer added which cost will trust the figure and will adjust an answer instead of leaving.
4. State the estimate's status plainly next to it: what it includes, what it excludes, how long it holds, and that it is an estimate rather than a quote. Reuse the app's Number Formatting Component so currency matches the rest of the product.
5. Do not let the calculator become a pricing admin tool as well. Ship it reading rules that an operator edits in one defined place, and defer a visual rule builder until the pricing model has actually stopped changing.

## UI and UX Requirements

Match the application's existing design system exactly. Reuse its components,
spacing, and typography. This feature should look like it was always there.

## Responsive Requirements

Works on mobile, tablet, and desktop. Touch targets are large enough to hit on a
phone, and nothing overflows horizontally at 320px.

## Accessibility Requirements

- Fully keyboard navigable.
- Correct semantic elements and ARIA roles.
- Visible focus states.
- Meets WCAG AA contrast.
- Dynamic changes are announced to screen readers.
- Respects prefers-reduced-motion.

## Edge Cases

- Changing an earlier answer must recompute the whole estimate from scratch, not patch the previous total. Incremental adjustment accumulates error and leaves stale line items attached to answers the visitor has since changed.
- Rounding each line item and then summing gives a different total than summing and rounding once. Pick one rule, apply it in a single place, and make sure the displayed lines add up to the displayed total exactly.
- Some answer combinations genuinely cannot be priced to a single figure. Return a range with the reason rather than a falsely precise number, and make the range visibly a range so nobody quotes the lower bound back to you.
- Pricing rules held in the browser can be read and edited by anyone who opens the developer tools. Keep them server-side and treat any price arriving from the client as untrusted input to be recomputed, never as a value to store.
- Most visitors abandon partway. Save partial answers against the session so returning resumes where they stopped, and if an email has been captured, keep the partial estimate retrievable for follow-up.
- An estimate the visitor saw must remain reproducible after the rates change. Store the rule version alongside each saved estimate so a follow-up conversation is about the same numbers the visitor was shown.
- A calculator that emails or stores results is a spam target. Apply the app's existing Rate Limiting to submissions and validate the email before sending anything to it.
- Free-text and open numeric inputs invite absurd values. Clamp them server-side to a sane range and explain the limit rather than producing an estimate of several million.

## Testing

Exercise the feature end to end in the running application. Cover every edge case
above, then run the existing test suite and confirm nothing regressed.

## Acceptance Criteria

- [ ] A visitor completes the questions and receives an itemised estimate with a total.
- [ ] All pricing rules and arithmetic execute on the server; no rates are present in client code.
- [ ] Editing an earlier answer recomputes the full estimate and the visible lines sum exactly to the total.
- [ ] Under-specified inputs produce a labelled range rather than a single figure.
- [ ] Partial answers survive abandonment and resume on return.
- [ ] Every saved estimate records the pricing version used to produce it.
- [ ] Submissions are rate limited and out-of-range inputs are rejected with an explanation.
- [ ] The feature matches the existing design system.
- [ ] No existing functionality is broken.

## Adaptation Rules

- Match the existing design system. Do not introduce a new colour palette,
  spacing scale, or component library.
- Reuse existing components and utilities wherever they fit.
- Follow the naming, file layout, and code style already present.
- Do not upgrade, replace, or remove existing dependencies to make this
  feature fit. Adapt the feature to the app, not the app to the feature.
- Do not break existing functionality. If a change is genuinely required in
  existing code, make the smallest one that works and say so.
- If something in these instructions conflicts with how the application is
  built, follow the application and explain the deviation.

## Final Verification

Before you report the work as done:

1. Re-read the acceptance criteria above and check each one against what you
   actually built.
2. Run the application and exercise the feature end to end.
3. Run the existing test suite and confirm you have broken nothing.
4. Check the feature on mobile, tablet, and desktop widths.
5. Check keyboard navigation and focus handling.
6. Summarize what changed: files added, files modified, and anything you
   deliberately did differently because of how this application is built.

If any acceptance criterion is unmet, fix it before reporting completion.
