diff --git a/CHANGELOG.md b/CHANGELOG.md index 86237d6..9efb95d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ numbers below were the site's earlier, hand-kept numbering and are retired; the ### Added +- **Firefox.** The extension is on Firefox Add-ons (version 0.16.3). Every page now says it runs in Chrome, Chromium browsers and Firefox, the extension page offers "Add to Firefox" beside "Add to Chrome", and the privacy policy has an "In Firefox" section (claim links are pasted; Firefox's storage and Sync; school policy through policies.json; what the listing declares to Mozilla). The terms and the vulnerability disclosure scope cover Firefox too. - **The Chrome Web Store numbers on the home page.** The proof section says what the store listing shows, dated: rated 5.0 out of 5 (1 rating), 27 users, as of 29 October 2026, from `toddleExtension.storeStats` in @@ -68,6 +69,11 @@ numbers below were the site's earlier, hand-kept numbering and are retired; the ### Changed +- **@bundu/ui 0.9.0** (was 0.5.0), for the latest Nyuchi branding and + styling. `globals.css` now brings in Bundu's density rules, which the + site already imports. Nothing the site uses was removed. The one new + dependency is `uqr`, the QR-code library behind Bundu's new + address cards. - **Firefox is coming, and the pages say so.** The extension now builds for Firefox; until its addons.mozilla.org listing is live (`toddleExtension.firefoxStore` in `src/data/site.ts`, null for now) the diff --git a/package-lock.json b/package-lock.json index 43a46ed..4f96047 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "3.0.0", "license": "UNLICENSED", "dependencies": { - "@bundu/ui": "^0.5.0", + "@bundu/ui": "^0.9.0", "astro": "^7.3.5" }, "devDependencies": { @@ -649,15 +649,16 @@ } }, "node_modules/@bundu/ui": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@bundu/ui/-/ui-0.5.0.tgz", - "integrity": "sha512-391EJhoMD0K+nuwJPQGOPDvEpmUJsIjRrxWX9+W0fFqr5oPliQVov/ZpZjOMZO3lxAa7bu5zaIxVO8t9h8gaBA==", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@bundu/ui/-/ui-0.9.0.tgz", + "integrity": "sha512-NPhnyPmxLyktPiDa6j/NCp1MmtTi9HnaYJB/zPkgXza82WRaPTVjGIuVKoStuqn1WppJohssE2DFRaWAYq584A==", "license": "MIT", "dependencies": { "@bundu/server": "^0.1.0", - "class-variance-authority": "^0.7.1", - "clsx": "^2.1.1", - "tailwind-merge": "^3.0.2" + "class-variance-authority": ">=0.7.1 <0.8.0", + "clsx": ">=2.1.1 <3", + "tailwind-merge": ">=3.6.0 <4", + "uqr": ">=0.1.3 <0.2.0" } }, "node_modules/@capsizecss/unpack": { @@ -7563,6 +7564,12 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/uqr": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/uqr/-/uqr-0.1.3.tgz", + "integrity": "sha512-0rjE8iEJe4YmT9TOhwsZtqCMRLc5DXZUI2UEYUUg63ikBkqqE5EYWaI0etFe/5KUcmcYwLih2RND1kq+hrUJXA==", + "license": "MIT" + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -8830,7 +8837,7 @@ "version": "8.22.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.22.0.tgz", "integrity": "sha512-Ydggc987+RO0AnWtZ/7Wq9FtNvcrL1b/RO0ud9mWjUPgDrsAAwQSF51sm2hm1XofbU/4jkpGEsLFsZZxU+1DOg==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=10.0.0" diff --git a/package.json b/package.json index 2b9d426..6a0993b 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "ci:check": "astro check && vp fmt --check" }, "dependencies": { - "@bundu/ui": "^0.5.0", + "@bundu/ui": "^0.9.0", "astro": "^7.3.5" }, "devDependencies": { diff --git a/src/data/legal.ts b/src/data/legal.ts index 2c0327f..a099da8 100644 --- a/src/data/legal.ts +++ b/src/data/legal.ts @@ -10,7 +10,7 @@ export const legal = { /** Last substantive change, for every legal page. Update when a claim changes, not on typos. */ - updated: "2026-10-29", + updated: "2026-11-07", entity: "Nyuchi Africa (Private) Limited", shortEntity: "Nyuchi", country: "Zimbabwe", diff --git a/src/data/site.ts b/src/data/site.ts index 2f242e2..a96920d 100644 --- a/src/data/site.ts +++ b/src/data/site.ts @@ -168,10 +168,9 @@ export const MINERALS = [ * fall back to an enquiry, with no other edit.) * * `firefoxStore` is Firefox's: the addons.mozilla.org listing. The extension - * builds for Firefox from 0.17.0 (the extension's docs/firefox.md); until the - * listing is live it stays null and the pages say Firefox is coming. Set it - * and every page says Chrome and Firefox, and offers "Add to Firefox" beside - * "Add to Chrome", with no other edit. + * builds for Firefox (the extension's docs/firefox.md), listed since 0.16.3. + * Set, every page says Chrome and Firefox and offers "Add to Firefox" beside + * "Add to Chrome"; null, and the pages say Firefox is coming. */ /** A link that may not exist yet. Named so that every Prettier version formats the cast below the same way. */ @@ -184,8 +183,9 @@ export const toddleExtension = { /** The Chrome Web Store listing (live since version 0.7.1). */ webStore: "https://chromewebstore.google.com/detail/ofliokikjmkkdkinbdnadbjjdmkjdjfi" as Url, - /** The addons.mozilla.org listing: null until it is live. */ - firefoxStore: null as Url, + /** The addons.mozilla.org listing (live since version 0.16.3). */ + firefoxStore: + "https://addons.mozilla.org/firefox/addon/toddle-enhancement-extension/" as Url, /** What the Chrome Web Store listing showed, read by the owner on the date given. Update all three together; never round up. */ storeStats: { diff --git a/src/pages/legal/privacy.astro b/src/pages/legal/privacy.astro index f59d943..7e0921a 100644 --- a/src/pages/legal/privacy.astro +++ b/src/pages/legal/privacy.astro @@ -257,6 +257,45 @@ const description = sees or pastes it; an organisation key typed into the extension is refused.

+

+ In Firefox +

+

+ The extension is also on + Firefox Add-ons. It is the same extension, built from the same code, and everything on this page + applies to it in the same way, with these differences: +

+ +

Security

diff --git a/src/pages/legal/terms.astro b/src/pages/legal/terms.astro index d49840e..1f4b80d 100644 --- a/src/pages/legal/terms.astro +++ b/src/pages/legal/terms.astro @@ -126,7 +126,7 @@ const description =

How licence keys work

An individual licence's email carries a one-time link, not the key: open it in Chrome, click - Add it to Chrome, and the extension fetches the key once from our licence + Add it to Chrome (in Firefox, paste the link into the extension's licence page), and the extension fetches the key once from our licence server, in exchange for the link's code alone. The link works once, for 72 hours. A licence key is a signed statement that the extension checks on your own device, so checking it contacts nothing and works offline. A key carries the buyer's email diff --git a/src/pages/legal/vulnerability-disclosure.astro b/src/pages/legal/vulnerability-disclosure.astro index 3263f03..2b13a4e 100644 --- a/src/pages/legal/vulnerability-disclosure.astro +++ b/src/pages/legal/vulnerability-disclosure.astro @@ -43,7 +43,7 @@ const description = >

  • This website, learning.nyuchi.com.
  • - The {toddleExtension.name}, version {security.supportedFrom} and later from the Chrome Web Store + The {toddleExtension.name}, version {security.supportedFrom} and later from the Chrome Web Store, and from Firefox Add-ons (earlier versions are not supported; extension ID {toddleExtension.extensionId}).
  • diff --git a/vercel.json b/vercel.json index c9d08cc..730c980 100644 --- a/vercel.json +++ b/vercel.json @@ -27,7 +27,7 @@ }, { "key": "Content-Security-Policy", - "value": "default-src 'self'; script-src 'self' https://app.intercom.io https://widget.intercom.io https://js.intercomcdn.com https://www.googletagmanager.com 'sha256-Brc4B09cZ9aNF4dBE7dQSlIzUMTvBIzHAPqI3zLF8+I=' 'sha256-FFGFlD4m+iq+1VF7UwfmwBt3tn7qHB2INa+7rAycUC8=' 'sha256-H7lTFTHP+LM756VatSdCPdQqI5KgMvle+T0W7x3MQnM=' 'sha256-VIgVtD7fAVrU4eaS8Crl3kwF00ggST1rFqthmXLJELQ='; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com https://js.intercomcdn.com https://fonts.intercomcdn.com; img-src 'self' data: https://js.intercomcdn.com https://static.intercomassets.com https://downloads.intercomcdn.com https://uploads.intercomusercontent.com https://gifs.intercomcdn.com https://video-messages.intercomcdn.com https://messenger-apps.intercomcdn.com https://www.google-analytics.com https://*.google-analytics.com https://*.googletagmanager.com; connect-src 'self' https://formspree.io https://via.intercom.io https://api.intercom.io https://api-iam.intercom.io https://api-ping.intercom.io https://*.intercom-messenger.com wss://*.intercom-messenger.com https://nexus-websocket-a.intercom.io wss://nexus-websocket-a.intercom.io https://nexus-websocket-b.intercom.io wss://nexus-websocket-b.intercom.io https://uploads.intercomcdn.com https://uploads.intercomusercontent.com https://www.google-analytics.com https://*.google-analytics.com https://*.analytics.google.com https://*.googletagmanager.com; form-action 'self' https://formspree.io; frame-ancestors 'none'; base-uri 'self'; object-src 'none'; media-src 'self' https://js.intercomcdn.com; frame-src 'self' https://intercom-sheets.com https://www.intercom-reporting.com" + "value": "default-src 'self'; script-src 'self' https://app.intercom.io https://widget.intercom.io https://js.intercomcdn.com https://www.googletagmanager.com 'sha256-Brc4B09cZ9aNF4dBE7dQSlIzUMTvBIzHAPqI3zLF8+I=' 'sha256-FFGFlD4m+iq+1VF7UwfmwBt3tn7qHB2INa+7rAycUC8=' 'sha256-H7lTFTHP+LM756VatSdCPdQqI5KgMvle+T0W7x3MQnM=' 'sha256-k/SaY/US23qudvvmBdO1E+8Kcnq0gtOWaQxF58YESag='; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com https://js.intercomcdn.com https://fonts.intercomcdn.com; img-src 'self' data: https://js.intercomcdn.com https://static.intercomassets.com https://downloads.intercomcdn.com https://uploads.intercomusercontent.com https://gifs.intercomcdn.com https://video-messages.intercomcdn.com https://messenger-apps.intercomcdn.com https://www.google-analytics.com https://*.google-analytics.com https://*.googletagmanager.com; connect-src 'self' https://formspree.io https://via.intercom.io https://api.intercom.io https://api-iam.intercom.io https://api-ping.intercom.io https://*.intercom-messenger.com wss://*.intercom-messenger.com https://nexus-websocket-a.intercom.io wss://nexus-websocket-a.intercom.io https://nexus-websocket-b.intercom.io wss://nexus-websocket-b.intercom.io https://uploads.intercomcdn.com https://uploads.intercomusercontent.com https://www.google-analytics.com https://*.google-analytics.com https://*.analytics.google.com https://*.googletagmanager.com; form-action 'self' https://formspree.io; frame-ancestors 'none'; base-uri 'self'; object-src 'none'; media-src 'self' https://js.intercomcdn.com; frame-src 'self' https://intercom-sheets.com https://www.intercom-reporting.com" } ] }