# Lildra contributor instructions

## Purpose and product boundaries

Lildra is a deliberately small Chrome/Edge Manifest V3 extension for distraction-free reading on Canvas/QLearn course lesson and wiki pages. It hides Canvas navigation, keeps the native lesson content at a centred reading width, and adds only a title bar and version label.

Never move, clone, wrap, or reconstruct lesson DOM. Never restyle lesson typography, headings, images, links, tables, embeds, or user content. Keep selectors limited to known Canvas shell elements and guarded by strict page detection. Do not broaden activation to dashboards, assignments, discussions, quizzes, modules, account pages, or arbitrary websites.

Do not add frameworks, build tools, dependencies, analytics, telemetry, remote scripts, content delivery networks, settings pages, options pages, popup interfaces, accounts, storage, or unrelated features. Do not add persistent host permissions when `activeTab` is sufficient.

## Architecture

- `manifest.json` defines the MV3 service worker, toolbar action, Alt+L command, permissions, and icons.
- `background.js` handles the toolbar and command, then injects `lildra.js` into the active tab.
- `lildra.js` validates the URL and Canvas DOM, injects scoped layout CSS and two inert UI elements, watches for dynamic title changes, and owns complete toggle cleanup.
- `icons/` contains the packaged toolbar/store icons.
- `tools/build-release.ps1` creates and validates the runtime-only Web Store ZIP.
- `tools/build-store-assets.ps1` deterministically composites local source captures into store artwork.
- `store-assets/ready-to-upload/` contains final listing artwork; local `screenshots/` inputs are ignored because they may contain private Canvas identifiers.

There is intentionally no content script registered for persistent execution. Re-injecting `lildra.js` toggles the current page off through its page-scoped state object.

## Coding standards

- Use dependency-free, modern JavaScript supported by current Chrome and Edge.
- Keep strict mode enabled and avoid leaking globals except the single toggle state key.
- Scope every CSS rule under `html.lildra-active` and target Canvas shell IDs/classes narrowly.
- Treat injected visual labels as decorative when equivalent page information already exists, so screen readers do not receive duplicate landmarks or titles.
- Read package metadata from `chrome.runtime.getManifest()`; do not duplicate the version in JavaScript or CSS.
- Preserve cleanup symmetry: every observer, class, style, and element added on enable must be removed on disable.
- Prefer clear names and comments that explain constraints, not obvious syntax.

## Test procedure

Before release:

1. Parse `manifest.json` and confirm every referenced JavaScript and icon file exists.
2. Load the unpacked extension in current Chrome and Edge with no extension errors.
3. On a QLearn lesson page, toggle on and off with both the toolbar button and Alt+L.
4. Confirm the global and course navigation hide, lesson content remains centred at its normal bounded width, and no lesson content styling or DOM position changes.
5. Test long and dynamically rendered titles; confirm centring, one-line ellipsis, and title updates.
6. Test desktop and narrow/mobile-width viewports, including pages with tables, images, links, and embeds.
7. Confirm `Lildra vX.Y.Z` matches `manifest.json` and remains unobtrusive.
8. Try dashboards, module lists, assignments, discussions, quizzes, non-content page routes, HTTP pages, and unrelated sites; Lildra must not activate.
9. Navigate between Canvas pages without a full reload and confirm no stale title or injected UI remains.
10. Check keyboard-only use and a screen reader for duplicate announcements or lost access to lesson content.

## Versioning and releases

Use Semantic Versioning. Change the version only in `manifest.json`: patch for fixes, minor for backward-compatible behaviour, and major for incompatible product changes. Move completed notes from `Unreleased` into a dated version section in `CHANGELOG.md`. Never commit packaged ZIP files. Do not commit or push unless the user explicitly requests it.
