# Brand Logo Uploader

## Objective

Let a customer upload their logo once and have it appear correctly everywhere.

A per-workspace logo upload with light and dark variants, normalised sizes, and consistent rendering across app, email, and exports.

## 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. Treat the logo as a workspace setting with a preview, not a one-off file field. Show the customer exactly how it will look in the app header, on an email, and on an exported document before they save.
2. Accept both vector and raster sources and derive a fixed set of normalised renditions from whichever arrives — a small mark for navigation, a larger one for documents, and a raster fallback for email clients that will not render vector.
3. Support a light and a dark variant, and fall back sensibly when only one is supplied rather than showing a black logo on a black header. Make it obvious in the UI which variant is missing.
4. Reuse the app's existing file upload, storage, and image processing — the same path used by Avatar Upload or File Upload — including its type checks, size ceiling, and malware scanning. Do not add a second uploader with its own rules.
5. Do not render the customer's original file directly wherever a logo is needed. An unbounded original blows out email layouts and export margins; always serve a generated rendition at a known size.

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

- Vector and raster sources behave completely differently and both arrive. Normalise each into the same set of renditions so downstream surfaces never have to care which was uploaded.
- A logo designed for a white page disappears on a dark header. Store separate light and dark variants and pick per surface, rather than inverting the image and hoping.
- Exported files often carry generous transparent or white margins. Trim the surrounding empty space on ingest, or the logo will sit visibly off-centre next to every other element.
- A tiny upload scaled up looks broken on a document header. Enforce a minimum pixel dimension at upload time and explain the requirement in the error, instead of accepting it and rendering mush.
- A replaced logo must appear immediately everywhere. Serve renditions under a URL that changes with the file, or customers will keep seeing the old mark from cache and report it as a bug.
- Vector files can contain scripts and external references. Sanitise them on the server before they are ever served back to a browser.
- The logo appears in contexts that are read aloud or blocked. Give it alt text derived from the workspace name, and reserve its box so headers do not jump while it loads.
- Email clients frequently block remote images. The layout must still read correctly with the logo absent, not collapse around a missing block.

## 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 workspace can upload a logo once and it renders in the app, in outgoing email, and in exports.
- [ ] Vector and raster uploads both produce the same set of normalised renditions.
- [ ] Light and dark variants are supported, with a defined fallback when only one exists.
- [ ] Uploads below the minimum dimensions are rejected with an explanatory message.
- [ ] Surrounding whitespace is trimmed so the logo aligns with adjacent elements.
- [ ] Replacing a logo updates every surface immediately with no stale cached copy.
- [ ] The logo has alt text and a reserved box that prevents layout shift.
- [ ] 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.
