# AI Insight Cards

## Objective

Turn a report into a few grounded cards, each tied to a number the app calculated.

A small set of cards summarising notable movements in a report, each linked to the query and figure that produced it.

## 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. Detect candidate movements in the app first, using the report's own aggregations. The model ranks and phrases the candidates it is given; it does not go looking for them and it does not produce the arithmetic.
2. Bind each card to the query, metric, and period that support it, and make the card link through to the filtered view so a reader can check it in one click.
3. Set a materiality threshold before generation, in both relative and absolute terms, so a swing on a metric with three events does not outrank a real change on a metric with thousands.
4. Cap the set at a handful of cards and deduplicate before rendering. Two cards describing the same movement from different angles read as two separate problems.
5. This feature owns the individual, evidenced cards. The dashboard-level narrative paragraph belongs to AI Dashboard Insights; where both exist, that feature should summarise these cards rather than analysing the data a second time.

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

- A card with no traceable support is not shippable. Every card must carry the metric and query behind it, and any card whose supporting query cannot be re-run must be dropped rather than shown unsourced.
- The same movement will surface through several metrics at once. Deduplicate on the underlying movement, not on the wording, or a single drop will produce four near-identical cards.
- Percentage change on a small base is noise. Enforce a minimum absolute volume alongside the relative threshold so a move from two to four does not present as a hundred percent surge.
- Every number rendered on a card comes from the app's own calculation. Do not display a figure the model produced, even when it appears to match, because the one time it does not will be silent.
- Cards are tied to a filter set and a data snapshot. When filters change or the source data is reprocessed, expire the cards and regenerate rather than leaving figures that no longer reconcile with the report.
- Cards must respect the viewer's permissions individually. A card built on a metric this viewer cannot access must not render, even when the report itself is visible to them.
- Set a per-generation cost and token ceiling, and cache by filter set and snapshot so that reopening a report does not trigger a fresh run.
- A refusal, timeout, or unparseable response should show no cards and no error framing that suggests the report itself is broken.

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

- [ ] Every card cites the metric and query supporting it and links to the filtered view.
- [ ] All displayed figures come from the app's own calculations, never from model output.
- [ ] Cards describing the same underlying movement are collapsed into one.
- [ ] Materiality thresholds combine relative and absolute change, so small-base noise is excluded.
- [ ] Cards expire and regenerate when filters or source data change.
- [ ] Cards built on metrics the viewer cannot access are not rendered.
- [ ] A model failure yields no cards while the report remains fully usable.
- [ ] 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.
