# Shipping Calculator

## Objective

Show real delivery options and costs for the shopper's address before they commit.

An address-aware shipping quote in the cart and at checkout, listing each available service with its cost and delivery estimate.

## 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. Quote as early as the shopper gives you a country and postal code, and requote at checkout once the full address is known. A cost that appears for the first time on the final screen is the most common reason a cart is abandoned.
2. Derive each rate from the actual cart: weights, dimensions, quantity, and any per-item shipping class the catalogue already carries. Do not quote from order value alone unless the business genuinely prices that way.
3. Present options the way a shopper compares them, by delivery date rather than by carrier product code, and preselect the cheapest rather than the fastest.
4. Store the quoted rate against the order with the inputs that produced it, so support can later answer why a customer was charged what they were charged.
5. Do not treat tax as part of shipping. The app already has Tax and VAT Collection; call into it and show duties, taxes, and shipping as separate lines rather than folding them into one number.

## 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

- Rate providers time out. When the lookup fails or takes too long, fall back to a configured flat estimate, label it as an estimate, and let the order proceed rather than blocking the sale.
- A cart can split across warehouses or shipping classes, which means more than one shipment and more than one rate. Decide whether the shopper sees one combined total or a shipment-by-shipment breakdown, and be consistent everywhere the total appears.
- An address outside the regions the business serves must be caught at the address step with a plain explanation, not accepted and then silently quoted at zero.
- A quoted rate has a shelf life. Hold it for a defined window, and requote whenever the cart contents, quantity, or address change, so the charge at capture matches what was shown.
- Cross-border orders carry duties and import taxes that are not shipping. Show them on their own line and say clearly whether they are prepaid or collected on delivery.
- Postal codes have wildly different formats by country. Validate against the selected country rather than a single pattern, and never reject a valid foreign code.
- A shopper changing address repeatedly must not fire a rate lookup on every keystroke. Debounce, and cancel the in-flight request when a newer one starts.
- Free shipping promotions and rate quotes have to agree. If a promotion zeroes the cost, the quoted service must still be recorded so the correct carrier is used at fulfilment.

## 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

- [ ] The shopper sees shipping options and costs before reaching the payment step.
- [ ] Rates reflect the cart's real weight, dimensions, and shipping classes.
- [ ] A provider failure degrades to a labelled flat estimate and the order still completes.
- [ ] Unserved regions are rejected at the address step with a clear message.
- [ ] Shipping, duties, and taxes appear as separate lines throughout the cart, checkout, and receipt.
- [ ] The rate charged at capture matches the rate quoted, or the shopper is requoted before payment.
- [ ] 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.
