A static, high-contrast Firefox theme built with the canonical Apollo palette.
Simulated dark and light previews — Firefox chrome can vary with browser and operating-system settings.
| Dark | Light | |
|---|---|---|
| Official display name | Apollo Theme | Apollo Light Theme |
| Source manifest | manifest.json |
variants/light/manifest.json |
| Version | 1.1.1 |
1.1.1 |
| Gecko GUID | humble-apollo@d0n9x1n |
apollo-light@d0n9x1n |
Apollo Dark uses the official display name Apollo Theme and immutable Gecko GUID humble-apollo@d0n9x1n. Apollo Light uses the official display name Apollo Light Theme and Gecko GUID apollo-light@d0n9x1n.
The npm package is apollo-theme; the repository remains firefox-apollo-theme. The dark Gecko GUID preserves upgrade continuity with public version 0.1.2. The light theme has a separate stable GUID because static Firefox themes cannot bundle two themes in one manifest.
Use Firefox Developer Edition for development. Either run:
npm ci
npm run dev:dark
npm run dev:lightEach preview targets an installed Firefox Developer Edition (web-ext alias deved) and uses a temporary profile. These commands open an interactive browser, so they are not run in CI.
To load either theme into an already-open Developer Edition instead:
- Open
about:debugging#/runtime/this-firefox. - Select Load Temporary Add-on….
- Choose
manifest.jsonfor dark orvariants/light/manifest.jsonfor light.
Temporary add-ons disappear when Firefox restarts.
Both manifests are generated; do not edit them directly. Edit the variant role mapping in scripts/common.py, then regenerate and verify:
python3 scripts/generate.py
npm run check
npm test
npm run lint
npm run build:dark
npm run build:lightRun one focused test with:
python3 -m unittest tests/test_theme.py -k test_gecko_identity_is_exact -vThe separate build commands write web-ext-artifacts/apollo-theme.zip and web-ext-artifacts/apollo-light-theme.zip; npm run build runs both. Each archive intentionally contains only its own manifest.json.
The committed palette/apollo.json and palette/apollo-light.json files are exact snapshots of the canonical dark and light palettes. Their SHA-256 values are pinned by the Python checks so palette and generated-manifest drift fail deterministically.
| Firefox role | Apollo value |
|---|---|
| Canvas, inactive frame, new tab, recessed fields | #141617 |
| Toolbar, selected tab, popup, sidebar | #1d2021 |
| Primary text and icons | #cfbc97 |
| Selected/highlighted text | #d5c4a1 |
| Inactive tab text | #928374 |
| Focus, loading, attention | #fabd2f |
| Selection and separators | #3c3836 |
#665c54 is never used for normal or small text. Firefox Manifest V2 has no general danger, success, or information color roles, so those canonical status colors remain unmapped rather than being assigned to unrelated browser chrome.
The GitHub build and release artifacts are unsigned ZIPs for source distribution and inspection. They are not Mozilla-signed XPIs and cannot be installed permanently in standard Firefox. Do not rename an unsigned ZIP to XPI and expect Firefox to accept it.
Firefox requires a separately Mozilla-signed XPI for each theme's permanent installation. The dark GUID belongs to its existing AMO listing; the light GUID is a separate identity and must not be uploaded as a version of the dark listing. Build the relevant ZIP, then submit or sign that theme with its matching AMO identity and API credentials. The following commands document the separate source roots; do not run them without an intentional signing or publishing action.
npx web-ext sign --source-dir . --channel listed \
--api-key "$AMO_JWT_ISSUER" \
--api-secret "$AMO_JWT_SECRET" \
--ignore-files package.json package-lock.json README.md CLAUDE.md LICENSE palette scripts tests variants .githubnpx web-ext sign --source-dir variants/light --channel listed \
--api-key "$AMO_JWT_ISSUER" \
--api-secret "$AMO_JWT_SECRET"--channel listed publishes to AMO; use --channel unlisted only for a signed, self-distributed XPI. The latest GitHub Release does not imply that either variant has been published to AMO. This repository makes no claim that version 1.1.1 of either theme is available from the marketplace.
To uninstall either variant, open about:addons, select Themes, switch to another theme, then remove Apollo Theme or Apollo Light Theme.
After temporary loading, inspect normal and private windows at regular and compact densities:
- active and inactive tabs, loading indicator, separators, and selected-tab focus;
- address bar unfocused, focused, typed selection, and autocomplete popup;
- toolbar icons, attention state, bookmarks, sidebar, and new-tab page;
- readable text in default, hover, selected, inactive, and high-contrast OS states.
Automated checks validate schema, palette membership, restricted text colors, and WCAG contrast. A human visual pass is still required before release.
A v* tag runs .github/workflows/release.yml. The workflow uses npm ci, checks generated output and tests, lints both source roots, verifies the tag matches package.json and both manifests, builds, and attaches both ZIPs to a GitHub Release.
Before tagging, bump package.json, regenerate both manifests, and commit them together. External pushing, tagging, GitHub release creation, signing, and AMO submission are deliberate maintainer actions.
The Gecko ID remains humble-apollo@d0n9x1n for upgrade continuity with public version 0.1.2. It must never change. The existing AMO URL slug may continue to be humble-apollo; this repository does not claim that AMO changed it.