diff --git a/CHANGELOG.md b/CHANGELOG.md index 64011a6..73d1f44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,33 +1,100 @@ # Changelog -All notable changes to GFPriceChecker will be documented in this file. +Release history for the **GF PriceChecker website** ([gfpricechecker.com](https://gfpricechecker.com)). + +Changes to the iOS app are tracked separately in the [app repository](https://github.com/CuWilliams/GFPriceChecker). The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Versioning + +The site is a continuously deployed static site: every merge to `main` is live within a minute or two. Tags mark meaningful states rather than deployments. + +- **Minor** (`1.1.0` → `1.2.0`) — a content release: new pages, a substantive rewrite, or a new site feature. +- **Patch** (`1.2.0` → `1.2.1`) — corrections, copy fixes, dependency-free housekeeping. +- **Major** — a redesign or a change in what the site is for. + +Routine blog posts and announcements are content edits, not releases, and don't get tags. + +To cut a release: move the `[Unreleased]` entries below into a new version heading, then tag `main`. + +``` +git tag -a v1.2.0 -m "Short description of the release" +git push origin v1.2.0 +``` + +--- + ## [Unreleased] +### Changed +- Rewrote site copy to describe the app as it works today: unit price differential adjusted for + package size as the headline metric, the three-step capture review (name, price, size), optional + size entry, and the receipt verification flow. +- Removed claims that the app's reports are CRA-compliant or accepted by the Canada Revenue Agency. + The Medical Expense Tax Credit is now presented as context for why the app exists, with the + ~3%-of-net-income threshold stated plainly. This matches the app, which removed agency branding + from its own interface in April 2026. +- Updated the advocacy section on the home page: petition e-6853 was declined by the government in + March 2026. +- Replaced the "Coming Soon" / waitlist calls to action with links to the TestFlight beta, live + since January 2026. +- Corrected the privacy claim on the features page — backup files are not encrypted. +- Rewrote `README.md` to document this website repository rather than the iOS app. +- Repurposed this changelog for the website; it previously tracked app development. +- Archived the original build plans to `Documents/archive/`. + ### Added -- Manual product entry with price comparison -- Camera scanning with OCR for shelf price tags -- Receipt verification and fuzzy product matching -- PDF and CSV export for CRA tax filing -- Data backup/restore functionality -- Onboarding tutorial -- VoiceOver accessibility support -- MIT License and project documentation +- Announcement covering build 8 and the move to unit pricing. +- FAQ entries on unit pricing, optional size capture, receipt verification, and data storage. +- Notes above the screenshot carousel and walkthrough videos flagging that they show an earlier + build. ### Fixed -- OCR price detection with spatial analysis (Session 25) -- Multi-line receipt format support (Session 16) -- Data import security-scoped resource access (Session 26) -- PDF page layout overlapping (Session 26) -- Image viewer first-tap loading (Session 26) +- The pre-JavaScript status banner fallback still read "Coming Soon! GF PriceChecker is currently in + development" on five of six pages, contradicting the beta call to action alongside it whenever + JavaScript was slow, blocked, or disabled. +- Announcements rendered as a single unbroken block with Markdown links shown as literal text. + Paragraph handling now uses the same `preserveLineBreaks` helper as the blog, promoted from + `blog-loader.js` into the shared `utils.js`. +- The home page printed the entire text of the latest announcement instead of a preview. +- Every blog post and announcement date displayed one day early for readers west of UTC — including + everyone in Canada. `YYYY-MM-DD` strings were parsed as UTC midnight and then rendered in local + time; they're now built as local dates. +- Stale `lastmod` dates in `sitemap.xml`; `blog.html` claimed January while carrying posts through + August. + +--- + +## [1.1.0] - 2026-08-12 + +Pre-overhaul snapshot: the site as it stood before the content rewrite above. -### Known Issues -- OCR accuracy varies with lighting conditions -- Fuzzy matching may need tuning for non-Sobeys receipts +### Added +- Beta page with TestFlight instructions, testing focus areas, and the public join link. +- Developer blog rendered from `data/blog.json`, with a GitHub Actions workflow that emails a + reminder to write one whenever a pull request merges. +- Three walkthrough videos with poster images, and a fourteen-slide screenshot carousel. +- "Why GF PriceChecker Exists" section on the home page covering the Medical Expense Tax Credit and + Celiac Canada's advocacy. +- Cloudflare Web Analytics across all pages. +- Custom domain via `CNAME`. + +### Changed +- Extracted the navigation and footer into runtime-injected components under `components/`. +- Extracted shared helpers into `assets/js/utils.js` (`fetchJSON`, `escapeHtml`, `formatDate`, + `renderEmptyState`, `renderCard`). +- Site-wide status moved from "coming soon" to public beta. -## Release Notes +## [1.0.0] - 2026-01-03 -No releases yet. App currently in field testing phase. +Initial public site. + +### Added +- Home, features, announcements, FAQ, privacy, and terms pages. +- JSON-driven content system for announcements, FAQ entries, and the status banner. +- Design system with shared tokens (`DESIGN-SYSTEM.md`), base and component stylesheets. +- SEO metadata, Open Graph tags, JSON-LD structured data, `sitemap.xml`, and `robots.txt`. +- Accessibility pass: skip links, ARIA labelling, keyboard-navigable carousel. +- MIT license. diff --git a/Claude.md b/Claude.md index 6eabec5..c7907c9 100644 --- a/Claude.md +++ b/Claude.md @@ -42,6 +42,7 @@ This project follows **DESIGN-SYSTEM.md** guidelines: / ├── index.html # Home page ├── features.html # Features page with carousel +├── beta.html # TestFlight beta instructions ├── blog.html # Developer blog posts ├── announcements.html # News and updates page ├── faq.html # Frequently asked questions @@ -50,17 +51,20 @@ This project follows **DESIGN-SYSTEM.md** guidelines: ├── sitemap.xml # XML sitemap for SEO ├── robots.txt # Search engine crawl rules ├── CNAME # GitHub Pages custom domain -├── README.md # GitHub repository description +├── README.md # How the site is built, run, and added to +├── CHANGELOG.md # Site release history and versioning approach ├── Claude.md # This file - project documentation ├── DESIGN-SYSTEM.md # Design guidelines and tokens ├── Documents/ -│ ├── EXECUTION_PLAN.md # Phased implementation plan -│ └── TECHNICAL_REQUIREMENTS.md # Technical specifications +│ └── archive/ # Original build plans (historical) +│ ├── EXECUTION_PLAN.md +│ └── TECHNICAL_REQUIREMENTS.md ├── assets/ │ ├── css/ │ │ ├── base.css # Design tokens, reset, utilities │ │ └── components.css # Component library styles │ ├── js/ +│ │ ├── utils.js # Shared helpers (window.GFUtils) - load first │ │ ├── main.js # Mobile nav, component initialization │ │ ├── components.js # Component loader for navbar/footer │ │ ├── content-loader.js # Dynamic content from JSON @@ -309,27 +313,81 @@ Dynamic content will be managed via JSON files in `/data/`: --- -## Placeholders and Future Work +## Content Conventions -### Current Placeholders -- ❌ Logo files (need SVG and PNG) -- ❌ App screenshots (12+ images for carousel) -- ❌ Instructional videos (MP4, <50MB, 720p) -- ❌ Cloudflare Analytics token (in index.html) -- ❌ Open Graph image -- ❌ Favicon +### Don't claim tax compliance -### Future Pages (Phase 3) -- features.html -- announcements.html -- faq.html -- privacy.html -- terms.html +The app deliberately carries no Canada Revenue Agency branding in its interface. Agency references +and specific tax line numbers were stripped out in April 2026 — tracking price differences is what +the app does, and what a user does with those records at tax time is between them and their +accountant. **The site follows the same rule.** -### Future Features (Phase 4) -- Horizontal screenshot carousel with stacked effect -- HTML5 video player for instructional content -- Lazy loading for images +- Explain the Medical Expense Tax Credit as context for why the app exists. That's fair and useful. +- Never describe the app's exports as CRA-compliant, approved, accepted, or endorsed. +- Never promise anyone a deduction. Where it's relevant, mention that the credit only applies to + medical expenses above roughly 3% of net income — a modest year may not reach it. + +Before merging copy changes, sweep for regressions: + +``` +grep -rn "CRA\|Tax Compliant\|tax compliance\|Line 33099" --include=*.html --include=*.json . +``` + +Every surviving hit should be explanatory context, never a claim about the app's output. + +### Describe the app as it currently works + +The headline metric is the **unit price differential** — cost per unit, scaled back to the size +actually purchased — not the package-to-package difference, which is kept beside it for reference. +Copy that leads with package price is out of date. Likewise, capturing a product is a single review +screen with three steps (name, price, size), and **size is optional**. Don't describe it as +mandatory or as a separate screen. + +When the app changes, the blog gets updated first (there's a GitHub Actions reminder on every merged +PR). The static pages have no such prompt and are the ones that quietly rot — check them against +`data/blog.json` and the app's release notes whenever a feature lands. + +### Don't overclaim on privacy either + +Local-only storage, on-device text recognition, no accounts, no sync: all true, all worth saying. +But backup files are **not** encrypted. Don't say they are. + +--- + +## Outstanding Work + +The original launch placeholders — logo, favicon, Open Graph image, Cloudflare Analytics token, +screenshots, and videos — were all resolved during January 2026, and every page planned in the +original build now exists (plus `beta.html` and `blog.html`, which came later). What follows is +what's actually outstanding. + +### Media is out of date +The three walkthrough videos were recorded January 17–24 2026 and the majority of the carousel +screenshots on January 3. Both predate the move to unit pricing as the headline figure (April 2026) +and the rebuilt three-step capture review (July 2026), so they show screens that no longer exist. +Both sections carry a `.media-note` saying so. Replacing them needs a device or simulator session: + +- Re-record the three walkthroughs against the current build. +- Re-capture screenshots 08–14 (capture flow, receipt views, product detail, list, export, + dashboard). +- Keep video files under 50MB — `receipt-management.mp4` is already at 49MB. + +### Videos have no captions +No VTT track exists for any video. This was deferred at launch and is still open; it's the site's +most significant remaining accessibility gap. + +### Canonical domain is inconsistent +`CNAME` holds `www.gfpricechecker.com`, but every canonical link, Open Graph URL, JSON-LD entry, +sitemap URL, and `robots.txt` reference uses the bare `gfpricechecker.com`. One of the two is wrong. +Pick the canonical host, then sweep all of them to match. + +### Legal review +`privacy.html` and `terms.html` were revised on January 25 2026 and no longer carry placeholder +banners, but they have never had professional legal review. + +### Not built +A community product database was once advertised on the features page as "Planned". It was never +built and the card has been removed rather than left promising something that isn't coming. --- @@ -586,80 +644,12 @@ This project strictly follows DESIGN-SYSTEM.md: ### Placeholder Content Status -**Assets Requiring Replacement Before Launch**: - -1. **Logo Files** (Priority: HIGH): - - Location: `/assets/images/logos/` - - Required formats: SVG (primary), PNG (fallback) - - Currently: Placeholder references in HTML - - Used on: All 6 pages in navbar - -2. **App Screenshots** (Priority: MEDIUM): - - Location: `/assets/images/screenshots/` - - Required: 12+ screenshots (9:16 aspect ratio, iPhone format) - - Current state: Placeholder via.placeholder.com images - - Used on: features.html carousel - - Replacement instructions: Update `data-src` attributes in features.html:103-161 - -3. **Instructional Videos** (Priority: LOW): - - Location: `/assets/video/` - - Required files: - - `getting-started.mp4` - - `price-tracking.mp4` - - `receipt-management.mp4` - - `tax-reports.mp4` - - Requirements: MP4 format, H.264 codec, 720p max, <50MB each - - Current state: Placeholder poster images, video files referenced but not present - - Used on: features.html video grid - -4. **Open Graph Image** (Priority: MEDIUM): - - Location: `/assets/images/og-image.png` - - Recommended size: 1200x630px - - Current state: Referenced in meta tags but file doesn't exist - - Used on: All pages for social media sharing - -5. **Favicon** (Priority: LOW): - - Location: `/assets/images/favicon.png` - - Current state: Referenced but file doesn't exist - - Used on: All pages - -6. **Cloudflare Analytics Token** (Priority: HIGH): - - Location: HTML `` section of all pages - - Current state: Commented out with "TODO" note - - Action required: Replace "YOUR_TOKEN_HERE" with actual Cloudflare site tag - - Affects: All 6 pages - -### JSON Data Files Status - -**✅ status.json**: -- Current state: "coming-soon" -- Message: "Coming Soon! GF PriceChecker is currently in development." -- Status: Ready for launch -- No changes needed - -**✅ announcements.json**: -- Contains launch announcement dated 2026-01-02 -- Status: Ready for launch -- Future updates: Add new announcements to array as needed - -**✅ faq.json**: -- Contains 3 comprehensive FAQ items -- Covers: What is GF PriceChecker, tax deductions, availability -- Status: Ready for launch - -### Legal Content Status - -**⚠️ privacy.html**: -- Status: **PLACEHOLDER - REQUIRES LEGAL REVIEW** -- Prominent note displayed: "This is placeholder content. Final privacy policy will be prepared with legal review before app launch." -- Last updated: January 2, 2026 -- Action required: Professional legal review and finalization before app launch - -**⚠️ terms.html**: -- Status: **PLACEHOLDER - REQUIRES LEGAL REVIEW** -- Prominent note displayed: "This is placeholder content. Final terms of use will be prepared with legal review before app launch." -- Last updated: January 2, 2026 -- Action required: Professional legal review and finalization before app launch +> **Historical.** This section recorded the state of the site at the end of the January 2026 build, +> when the logo, screenshots, videos, Open Graph image, favicon, and Cloudflare Analytics token were +> all still outstanding, and `privacy.html` and `terms.html` carried placeholder banners. All of +> those were resolved during January 2026 — the analytics token is live on every page and the legal +> placeholder banners are gone. For what is genuinely still open, see +> [Outstanding Work](#outstanding-work) above. ### Final Validation Checks @@ -715,15 +705,8 @@ This project strictly follows DESIGN-SYSTEM.md: - [x] All links tested and functional - [x] Legal content flagged for review -**Pending Tasks (Before Production Launch)**: -- [ ] Replace logo placeholder with actual logo files -- [ ] Add Cloudflare Web Analytics token to all pages -- [ ] Add Open Graph image for social sharing -- [ ] Add favicon -- [ ] Privacy policy: Professional legal review and finalization -- [ ] Terms of use: Professional legal review and finalization -- [ ] Optional: Add app screenshots (can use placeholders initially) -- [ ] Optional: Add instructional videos (can use placeholders initially) +**Pending Tasks**: every item on this list except legal review was completed during January 2026. +See [Outstanding Work](#outstanding-work) above for what remains. **Deployment Notes**: - GitHub Pages will serve from `main` branch root directory @@ -763,11 +746,17 @@ This project strictly follows DESIGN-SYSTEM.md: ## Contact & Support **Repository**: https://github.com/CuWilliams/GFPriceChecker.github.io -**Documentation**: See `Documents/` folder for detailed requirements and execution plan +**Getting started**: See `README.md` for how the site is built, run locally, and added to **Design Guidelines**: See `DESIGN-SYSTEM.md` for design tokens and patterns +**Release history**: See `CHANGELOG.md` for the versioning approach and past releases +**Original build plans**: See `Documents/archive/` — historical, kept for reference only --- -*Last Updated: January 2, 2026 - All Phases Complete (1-6)* +*Last Updated: August 12, 2026* -**Project Status**: Ready for deployment with noted placeholders. Legal content requires professional review before app launch. +**Project Status**: Live at [gfpricechecker.com](https://gfpricechecker.com), serving an app in +public TestFlight beta. The Phase 1–6 sections below the design and conventions material are a +historical record of the January 2026 build, not a description of the site today. Outstanding items +are listed under [Outstanding Work](#outstanding-work): media showing an older build, missing video +captions, the `www` vs. bare-domain inconsistency, and legal review. diff --git a/Documents/EXECUTION_PLAN.md b/Documents/archive/EXECUTION_PLAN.md similarity index 96% rename from Documents/EXECUTION_PLAN.md rename to Documents/archive/EXECUTION_PLAN.md index 2b2e185..791d461 100644 --- a/Documents/EXECUTION_PLAN.md +++ b/Documents/archive/EXECUTION_PLAN.md @@ -1,3 +1,9 @@ +> **Archived — historical record.** This is the phase-by-phase plan used to build the site in +> January 2026. All six phases were completed and the site has changed considerably since. It is +> kept as a record of how the site was originally constructed; it does not describe the site as it +> stands today. For current documentation see [README.md](../../README.md) and +> [Claude.md](../../Claude.md). + # GF PriceChecker Website - Execution Plan **Version:** 1.0 diff --git a/Documents/TECHNICAL_REQUIREMENTS.md b/Documents/archive/TECHNICAL_REQUIREMENTS.md similarity index 93% rename from Documents/TECHNICAL_REQUIREMENTS.md rename to Documents/archive/TECHNICAL_REQUIREMENTS.md index bc625f5..341f312 100644 --- a/Documents/TECHNICAL_REQUIREMENTS.md +++ b/Documents/archive/TECHNICAL_REQUIREMENTS.md @@ -1,3 +1,8 @@ +> **Archived — historical record.** These are the requirements the site was originally built +> against in January 2026. They were met, and the site has changed considerably since. Kept as a +> record of the original brief; it does not describe the site as it stands today. For current +> documentation see [README.md](../../README.md) and [Claude.md](../../Claude.md). + # GF PriceChecker Website - Technical Requirements Document **Version:** 1.0 diff --git a/README.md b/README.md index 2b66d7d..ad6a0ce 100644 --- a/README.md +++ b/README.md @@ -1,96 +1,102 @@ -# GFPriceChecker +# GFPriceChecker.github.io -iOS app for tracking gluten-free vs regular product price differentials for Canadian tax deductions. +The marketing and documentation website for **GF PriceChecker**, an iOS app that helps Canadians measure and document the price premium on gluten-free groceries. -## Overview +Live at [gfpricechecker.com](https://gfpricechecker.com). The app itself lives in a separate repository: [CuWilliams/GFPriceChecker](https://github.com/CuWilliams/GFPriceChecker). -GFPriceChecker helps individuals with celiac disease document the price difference between gluten-free and regular products for Canadian Revenue Agency (CRA) medical expense claims. The app provides camera-based OCR scanning, receipt verification, and professional PDF/CSV export reports. +## How the site is built -## Status +A static site served directly by GitHub Pages from the root of `main`. There is **no build step, no bundler, and no dependencies** — hand-authored HTML, CSS, and vanilla JavaScript. Push to `main` and it deploys. -**Active Development** - Currently in field testing and refinement. +Two ideas do most of the work: -This is a personal project built primarily for family use, made available to the broader celiac community at no cost. +**Shared components are fetched at runtime.** Every page contains `` and ``. On load, `assets/js/components.js` fetches `components/navbar.html` and `components/footer.html` and injects them, then re-runs the nav initializers from `main.js` against the newly inserted DOM. Edit the nav or footer once, in `components/`, and every page picks it up. -## Features +**Content that changes often lives in JSON.** Blog posts, announcements, FAQ entries, and the status banner are data files under `data/`, rendered client-side by `content-loader.js` and `blog-loader.js`. Adding a post means editing JSON, not HTML. -- Manual product entry with price comparison -- Camera scanning with OCR for shelf price tags and receipts -- Receipt verification and product matching -- PDF and CSV export for CRA tax filing -- Data backup/restore -- No ads, no tracking, completely free +## Layout -## Requirements +``` +├── index.html # Home +├── features.html # What the app does, screenshots, walkthrough videos +├── beta.html # TestFlight instructions and testing focus areas +├── blog.html # Developer blog (rendered from data/blog.json) +├── announcements.html # Release announcements +├── faq.html # Frequently asked questions +├── privacy.html, terms.html # Legal +│ +├── components/ # navbar.html, footer.html — injected at runtime +├── data/ # blog.json, announcements.json, faq.json, status.json +├── assets/ +│ ├── css/ # base.css (tokens, reset, utilities), components.css +│ ├── js/ # utils.js, components.js, content-loader.js, +│ │ # blog-loader.js, main.js +│ ├── images/ # logos, favicon, OG image, screenshots/, video posters +│ └── video/ # walkthrough videos (keep under 50MB each) +│ +├── Documents/archive/ # Historical build plans from the site's construction +├── CHANGELOG.md # Site release history +├── DESIGN-SYSTEM.md # Design tokens and component reference +└── Claude.md # Working notes and conventions for this repo +``` -- **iOS:** 18.0 or later -- **Xcode:** 16.1.1 or later -- **Swift:** 6.0 -- **Device:** iPhone with camera (recommended for OCR features) +Script load order matters: `utils.js` defines `window.GFUtils` and must come before `content-loader.js` and `blog-loader.js`, which consume it. -## Installation +## Running locally -1. Clone the repository ``` -git clone https://github.com/CuWilliams/GFPriceChecker.git +python3 -m http.server 8000 ``` -2. Open project in Xcode -``` -cd GFPriceChecker -open GFPriceChecker.xcodeproj +Then open `http://localhost:8000`. A server is required rather than opening the files directly — the component includes and JSON loading both use `fetch()`, which browsers block on `file://` URLs. + +## Adding content + +**A blog post** — prepend an object to `data/blog.json`: + +```json +{ + "id": "2026-08-12-post-slug", + "date": "2026-08-12", + "title": "Post Title", + "content": "First paragraph.\n\nSecond paragraph." +} ``` -3. Build and run -- Select target device or simulator -- Press `Cmd+R` to build and run +Separate paragraphs with `\n\n`. Content is escaped before rendering, so write plain prose — Markdown is not parsed, and any HTML you include will be shown as literal text. Posts are sorted by date, newest first, so file order doesn't matter. The `id` becomes the anchor (`/blog.html#post-`), so keep it stable once published. -## Documentation +**An announcement** — the same shape, in `data/announcements.json`. The home page shows a preview of the most recent one. -Comprehensive development history and technical decisions documented in `claude.md`. +**An FAQ entry** — `data/faq.json`, with `id`, `question`, and `answer`. These render as an accordion in file order. -For website development plan, see `TECHNICAL_REQUIREMENTS.md` and `EXECUTION_PLAN.md`. +**The status banner** — `data/status.json` drives the banner on every page. Each page also hardcodes a matching fallback so the banner still reads correctly before JavaScript runs; if you change the state here, update those fallbacks too. + +After editing any data file, confirm it still parses: -## Project Structure ``` -GFPriceChecker/ -├── Models/ # SwiftData persistence models -├── Views/ # SwiftUI views -│ ├── Library/ # Product list and detail views -│ ├── CaptureFlow/ # Camera and manual entry -│ ├── Reports/ # Export and dashboard -│ ├── Settings/ # App settings and preferences -│ └── Onboarding/ # First-run experience -├── ViewModels/ # Business logic and state management -├── Services/ # OCR, PDF, CSV, image storage -├── Utilities/ # Helpers and reusable components -└── Resources/ # Assets and app branding +for f in data/*.json; do python3 -m json.tool "$f" > /dev/null && echo "OK $f"; done ``` -## Contributing +A malformed file fails silently in the browser and renders an empty state. + +## Writing conventions + +The app deliberately carries no Canada Revenue Agency branding in its interface — tracking price differences is the app's job, and what a user does with those records at tax time is between them and their accountant. **The site follows the same rule.** Explain the Medical Expense Tax Credit as context for why the app exists, but don't describe the app's output as CRA-compliant, approved, or endorsed, and don't promise anyone a deduction. -This is a personal project with limited maintenance bandwidth. +Beyond that, see [DESIGN-SYSTEM.md](DESIGN-SYSTEM.md) for design tokens and component patterns, and [Claude.md](Claude.md) for the fuller set of working notes. -- **Forks:** Encouraged -- **Pull Requests:** Welcome but may not be reviewed promptly -- **Issues:** GitHub Issues disabled - contact via methods below instead +## Releases -If you want to build an Android version or contribute significant features, please contact me. +Site releases are annotated git tags on `main`, with history in [CHANGELOG.md](CHANGELOG.md). See the top of that file for the versioning approach. ## Contact -- **GitHub Issues:** [@CuWilliams](https://github.com/CuWilliams) - **X (Twitter):** [@CurtisWill3z](https://x.com/CurtisWill3z) - **LinkedIn:** [Curtis Williams](https://www.linkedin.com/in/curtis-williams-154382b3) +- **Email:** gfpricechecker@gmail.com ## License -MIT License - see [LICENSE](LICENSE) file for details. +MIT License — see [LICENSE](LICENSE). Copyright (c) 2025 Curtis Williams - -## Acknowledgments - -Developed with assistance from Anthropic's Claude AI using Claude Code for iOS development and documentation. - -Built for the celiac community with focus on Canadian tax compliance requirements. diff --git a/announcements.html b/announcements.html index 3bfd7d7..a0c7989 100644 --- a/announcements.html +++ b/announcements.html @@ -49,8 +49,8 @@
-
- Coming Soon! GF PriceChecker is currently in development. +
+ Beta Testing! Join our TestFlight beta program.
diff --git a/assets/css/components.css b/assets/css/components.css index ec0ec6d..f600c52 100644 --- a/assets/css/components.css +++ b/assets/css/components.css @@ -766,6 +766,16 @@ margin: 0; } +/* Note above media that shows an older build */ +.media-note { + max-width: 700px; + margin: 0 auto var(--space-xl); + font-size: var(--text-sm); + color: var(--medium-gray); + line-height: var(--line-height-relaxed); + text-align: center; +} + /* ======================================== BETA PAGE LISTS ======================================== */ diff --git a/assets/js/blog-loader.js b/assets/js/blog-loader.js index 1098937..10919d7 100644 --- a/assets/js/blog-loader.js +++ b/assets/js/blog-loader.js @@ -8,28 +8,7 @@ 'use strict'; // Shorthand references to utility functions - const { fetchJSON, escapeHtml, renderEmptyState, renderCard } = window.GFUtils; - - /** - * Preserve line breaks in content - * @param {string} content - Content with line breaks - * @returns {string} HTML with preserved line breaks - */ - function preserveLineBreaks(content) { - if (!content) return ''; - const paragraphs = content.split('\n\n'); - return paragraphs - .map(para => { - const trimmed = para.trim(); - if (trimmed) { - const withBreaks = trimmed.replace(/\n/g, '
'); - return `

${escapeHtml(withBreaks).replace(/<br>/g, '
')}

`; - } - return ''; - }) - .filter(p => p) - .join(''); - } + const { fetchJSON, preserveLineBreaks, renderEmptyState, renderCard } = window.GFUtils; /** * Load and render full blog posts list diff --git a/assets/js/content-loader.js b/assets/js/content-loader.js index be63d70..25f42ad 100644 --- a/assets/js/content-loader.js +++ b/assets/js/content-loader.js @@ -8,7 +8,7 @@ 'use strict'; // Shorthand references to utility functions - const { fetchJSON, escapeHtml, formatDate, renderEmptyState, renderCard } = window.GFUtils; + const { fetchJSON, escapeHtml, formatDate, preserveLineBreaks, renderEmptyState, renderCard } = window.GFUtils; /** * Load and render status banner @@ -97,10 +97,13 @@ const sortedAnnouncements = [...data].sort((a, b) => new Date(b.date) - new Date(a.date)); const latest = sortedAnnouncements[0]; + const preview = latest.content.substring(0, 150); + const needsEllipsis = latest.content.length > 150; + container.innerHTML = renderCard({ title: latest.title, date: latest.date, - content: latest.content, + content: preview + (needsEllipsis ? '...' : ''), footer: { text: 'View All Announcements', url: '/announcements.html' } }); } @@ -128,7 +131,7 @@ container.innerHTML = sortedAnnouncements.map(announcement => renderCard({ title: announcement.title, date: announcement.date, - content: announcement.content, + contentHtml: preserveLineBreaks(announcement.content), className: 'mb-lg', titleTag: 'div' })).join(''); diff --git a/assets/js/utils.js b/assets/js/utils.js index 2b7bc6d..ba24fc3 100644 --- a/assets/js/utils.js +++ b/assets/js/utils.js @@ -37,13 +37,39 @@ return div.innerHTML; } + /** + * Split content into paragraphs, preserving single line breaks + * @param {string} content - Content with line breaks + * @returns {string} HTML with preserved line breaks + */ + function preserveLineBreaks(content) { + if (!content) return ''; + const paragraphs = content.split('\n\n'); + return paragraphs + .map(para => { + const trimmed = para.trim(); + if (trimmed) { + const withBreaks = trimmed.replace(/\n/g, '
'); + return `

${escapeHtml(withBreaks).replace(/<br>/g, '
')}

`; + } + return ''; + }) + .filter(p => p) + .join(''); + } + /** * Format date as "Month Day, Year" * @param {string} dateString - ISO date string (YYYY-MM-DD) * @returns {string} Formatted date */ function formatDate(dateString) { - const date = new Date(dateString); + // "YYYY-MM-DD" is parsed as UTC midnight by the Date constructor, which renders + // as the previous day for anyone west of UTC. Build it as a local date instead. + const parts = /^(\d{4})-(\d{2})-(\d{2})$/.exec(String(dateString)); + const date = parts + ? new Date(Number(parts[1]), Number(parts[2]) - 1, Number(parts[3])) + : new Date(dateString); return date.toLocaleDateString('en-US', { year: 'numeric', month: 'long', @@ -144,6 +170,7 @@ window.GFUtils = { fetchJSON: fetchJSON, escapeHtml: escapeHtml, + preserveLineBreaks: preserveLineBreaks, formatDate: formatDate, renderEmptyState: renderEmptyState, renderCard: renderCard, diff --git a/beta.html b/beta.html index 3620b23..14ab6cd 100644 --- a/beta.html +++ b/beta.html @@ -112,9 +112,11 @@

What to Focus On

When testing, pay attention to these areas:

diff --git a/blog.html b/blog.html index f747f6a..1d42360 100644 --- a/blog.html +++ b/blog.html @@ -49,8 +49,8 @@
-
- Coming Soon! GF PriceChecker is currently in development. +
+ Beta Testing! Join our TestFlight beta program.
diff --git a/data/announcements.json b/data/announcements.json index 7743fc9..4bb959f 100644 --- a/data/announcements.json +++ b/data/announcements.json @@ -8,7 +8,13 @@ { "id": "2", "date": "2026-01-27", - "title": "Public Beta Now Available", - "content": "GFPriceChecker has reached an important milestone: the public beta is now live on TestFlight.\n\nThe app provides tools for product comparison, receipt verification, and CRA-compliant report generation—all while maintaining complete data privacy through local-only storage.\n\nBeta testing is a critical phase where real-world usage reveals opportunities for improvement that isolated development cannot uncover. Your participation helps ensure the app meets the practical needs of the celiac community.\n\nTo join the beta program, visit our [Beta Testing page](/beta.html) for complete instructions and access to the TestFlight link.\n\nWe welcome your feedback. TestFlight includes built-in feedback tools that allow you to report issues, suggest improvements, or share observations directly with the development team. Your input during this phase will directly shape the final release.\n\nThank you for your interest in GFPriceChecker and your willingness to contribute to a tool designed for our community." -} + "title": "Public Beta Now Available", + "content": "GF PriceChecker has reached an important milestone: the public beta is now live on TestFlight.\n\nThe app provides tools for product comparison, receipt verification, and exportable expense records—all while maintaining complete data privacy through local-only storage.\n\nBeta testing is a critical phase where real-world usage reveals opportunities for improvement that isolated development cannot uncover. Your participation helps ensure the app meets the practical needs of the celiac community.\n\nTo join the beta program, visit the Beta Testing page for complete instructions and access to the TestFlight link.\n\nWe welcome your feedback. TestFlight includes built-in feedback tools that allow you to report issues, suggest improvements, or share observations directly with the development team. Your input during this phase will directly shape the final release.\n\nThank you for your interest in GF PriceChecker and your willingness to contribute to a tool designed for our community." + }, + { + "id": "3", + "date": "2026-08-12", + "title": "Unit Pricing Is Now the Number That Counts", + "content": "Several months of beta feedback have reshaped how the app measures the gluten-free premium, and build 8 is now on TestFlight.\n\nThe headline change: unit price is the figure the app leads with everywhere. Not what the package cost—what it cost per hundred grams. Gluten-free products don't only cost more, they frequently contain less, and comparing sticker prices hides that. A $7.99 gluten-free loaf at 400g beside a $3.99 regular loaf at 675g looks like a $4.00 difference. Measured per gram and scaled back to the size you actually bought, the real premium is $5.63. That size-adjusted number now leads the product list, the summary dashboard, the PDF report, and the CSV export. The plain package difference is still there, labelled and kept for reference.\n\nCapturing a product is simpler too. After scanning a shelf tag, the review screen used to hand you off to a second form partway through. It's now one continuous screen with three plain steps—name, then price, then size—and your scan results stay in front of you the whole time. Size is optional: skip it when you're in a hurry, and the app tells you which items sat out of the unit price totals rather than quietly folding them in.\n\nAlso in this build: deleting a product pair now removes its photographs instead of leaving them on the device, and a bug that dropped size data when restoring a backup has been fixed. Backup files from build 7 and earlier still import cleanly—those records simply have no size data to restore.\n\nOne piece of news from outside the app. Celiac Canada's petition for a flat refundable credit, signed by 33,000 Canadians, was declined by the government in March. The Medical Expense Tax Credit stays as it is, and itemized receipts remain your responsibility to keep. Celiac Canada is continuing to press the case. Until something changes, this app still has a job to do." + } ] diff --git a/data/faq.json b/data/faq.json index 8eceb4d..143dcc5 100644 --- a/data/faq.json +++ b/data/faq.json @@ -2,16 +2,36 @@ { "id": "1", "question": "What is GF PriceChecker?", - "answer": "GF PriceChecker is an iOS app designed to help Canadians track the price differential between gluten-free and regular products. This information is essential for claiming medical expense deductions on your Canadian tax return, as the CRA allows you to deduct the incremental cost of gluten-free products if you have celiac disease or gluten intolerance." + "answer": "GF PriceChecker is an iOS app that helps Canadians measure and document what eating gluten free actually costs. You capture a gluten-free product and its regular equivalent, and the app works out the difference in price — adjusted for the fact that the two packages are rarely the same size. It keeps the photographs and receipts that support each figure, and exports the whole year as a PDF or spreadsheet." }, { "id": "2", - "question": "How does tracking price differentials help with tax deductions?", - "answer": "The Canada Revenue Agency (CRA) allows individuals with celiac disease or gluten intolerance to claim the incremental cost of gluten-free products as a medical expense. GF PriceChecker helps you accurately track and document these price differences, making it easier to calculate your eligible deductions and maintain records for your tax filing." + "question": "How does this relate to the Medical Expense Tax Credit?", + "answer": "For someone with celiac disease, the extra cost of gluten-free food is a medical expense, and Canada's Medical Expense Tax Credit recognizes the difference in price between a gluten-free product and its regular equivalent. Claiming it means keeping itemized records and producing them if asked. That record-keeping is what this app is for. It does not file anything, does not tell you what you are eligible to claim, and makes no claim of being approved or endorsed by any tax authority — what you do with your records is between you and your accountant. Worth knowing before you start: the credit only applies to medical expenses above a threshold of roughly three percent of your net income, so a modest year of gluten-free purchases may not reach it on its own." }, { "id": "3", + "question": "Why compare unit prices instead of package prices?", + "answer": "Because gluten-free products don't only cost more — they often contain less, and comparing the sticker prices hides that. A $7.99 gluten-free loaf at 400g sitting beside a $3.99 regular loaf at 675g looks like a $4.00 difference. Compare them by cost per gram and scale the result back to the size you actually bought, and the real premium is $5.63. The app leads with that size-adjusted number everywhere and keeps the plain package difference beside it for reference." + }, + { + "id": "4", + "question": "Do I have to enter the package size?", + "answer": "No. Size is optional. When you scan a shelf tag, the review screen walks you through three steps — name, price, then size — and there's a Skip Size button on the last one. Items without a size are still tracked and still show a package price difference; they're simply left out of the unit price totals, and the app tells you how many were excluded rather than quietly folding them in. You can enter size a few ways: type the package size directly, or enter the unit price posted on the shelf tag in cents or dollars and let the app work backwards from it." + }, + { + "id": "5", + "question": "What does receipt verification do?", + "answer": "It ties what you recorded in the aisle to proof that you bought it. You pick the products from a shopping trip, scan the receipt, then go through them one at a time and tap the line on the receipt that matches each one. The app suggests a likely line to save you hunting. Confirmed products are marked verified and stay linked to that receipt image, which travels with them into your PDF and CSV exports. Products you haven't verified yet are listed separately in exports rather than mixed in with the rest." + }, + { + "id": "6", + "question": "Where is my data stored?", + "answer": "On your device, and nowhere else. There are no accounts, no sign-in, and no cloud sync. Text recognition on shelf tags and receipts runs on the device itself, so your photographs are never uploaded anywhere. Backups are files you export and store wherever you choose — note that a backup file is not encrypted, so keep it somewhere you'd be comfortable keeping your receipts." + }, + { + "id": "7", "question": "When will the app be available?", - "answer": "GF PriceChecker is currently in public beta on TestFlight. You can download and use the app now by visiting our Beta page for instructions and the TestFlight link. We're gathering feedback to refine the experience before the official App Store release. If you'd rather wait for the polished version, check back for announcements on the launch date." + "answer": "GF PriceChecker is in public beta on TestFlight now, and you can use it today — visit the Beta page for instructions and the link. It's free, with no ads, and it will stay that way on the App Store. Feedback from beta testers is actively shaping the app, so if something is confusing or wrong, please say so through TestFlight." } ] diff --git a/data/status.json b/data/status.json index 993f8fa..f931ea4 100644 --- a/data/status.json +++ b/data/status.json @@ -1,6 +1,6 @@ { "state": "testflight", - "message": "Beta now available!", - "linkText": "Join the TestFlight beta.", + "message": "Build 8 is on TestFlight!", + "linkText": "Join the beta.", "link": "/beta.html" } diff --git a/faq.html b/faq.html index f9da4d5..ac3d98c 100644 --- a/faq.html +++ b/faq.html @@ -49,8 +49,8 @@
-
- Coming Soon! GF PriceChecker is currently in development. +
+ Beta Testing! Join our TestFlight beta program.
diff --git a/features.html b/features.html index 0a73122..4e0bb9d 100644 --- a/features.html +++ b/features.html @@ -7,7 +7,7 @@ Features - GF PriceChecker - + @@ -16,14 +16,14 @@ - + - + @@ -44,7 +44,7 @@ "name": "GF PriceChecker", "applicationCategory": "FinanceApplication", "operatingSystem": "iOS", - "description": "Track gluten-free product price differentials for Canadian tax deductions. Compare prices, manage receipts, and generate CRA-compliant tax reports.", + "description": "Track gluten-free product price differentials by unit price, adjusted for package size. Scan shelf tags, verify purchases against receipts, and export your records as PDF or CSV.", "offers": { "@type": "Offer", "price": "0", @@ -61,10 +61,11 @@ }, "countriesSupported": "CA", "featureList": [ - "Price comparison tracking for gluten-free products", - "Receipt scanning and management", - "Tax report generation for CRA medical expense claims", - "Product database with price history", + "Unit price comparison adjusted for package size", + "Shelf tag scanning with on-device text recognition", + "Guided three-step capture of product name, price, and size", + "Receipt verification with line-by-line product matching", + "PDF and CSV export with receipt images", "Privacy-focused local-first storage" ] } @@ -83,17 +84,17 @@
-
- Coming Soon! GF PriceChecker is currently in development. +
+ Beta Testing! Join our TestFlight beta program.
-

Powerful Features for Tax Compliance

+

What the App Does

- GF PriceChecker simplifies tracking gluten-free product price differentials, helping Canadians with celiac disease or gluten intolerance maximize their medical expense deductions. + GF PriceChecker measures the real cost premium on gluten-free groceries — comparing cost per unit rather than package to package — and keeps the receipts and photographs that back every figure up.

@@ -101,7 +102,12 @@

Powerful Features for Tax Compliance

-

See It in Action

+

See It in Action

+

+ Some of these screenshots were captured in January 2026 and show an earlier build. + The current release leads with the unit price differential and uses a three-step + review when capturing a product. New screenshots are on the way. +

@@ -237,9 +245,13 @@

Key Features

-

Price Comparison Tracking

+

Unit Price Comparison

- Easily compare prices between gluten-free and regular equivalent products. Our app calculates the differential automatically, ensuring accurate records for your tax claims. + Gluten-free products don't only cost more — they frequently contain less. A $7.99 400g + gluten-free loaf next to a $3.99 675g regular one looks like a $4.00 gap. Compared by + cost per gram and scaled back to the size you actually bought, the premium is $5.63. + The app leads with that size-adjusted figure everywhere and keeps the plain package + difference alongside it for reference.

-

Receipt Management

+

Package Size Capture

- Scan and organize your receipts in one place. Keep digital copies of your purchases with timestamps and categorization for easy retrieval during tax season. + Enter size the way the shelf tag gives it to you: type the package size directly, or + enter the posted unit price and let the app work backwards from it — in cents or + dollars, whichever the tag uses. Size is optional. Skip it when you're in a hurry and + the app simply tells you which items sat out of the unit price totals.

-

Tax Reports

+

Guided Shelf Tag Scanning

- Generate comprehensive reports that summarize your gluten-free product expenses and calculated differentials. Export-ready formats make filing your taxes straightforward. + Photograph the shelf tag and the app reads it on device. A single review screen walks + you through three steps — tap the product name, tap the price, tap the size — with the + scan results staying in front of you the whole time. Nothing is committed until you + confirm it, and anything the scan misses can be typed in by hand.

-

Product Database

+

Receipt Verification

- Access a growing database of gluten-free products with price history and equivalents. Save time by leveraging community data while maintaining your personal tracking. + Choose the products from a shopping trip, scan the receipt, then work through them one + at a time, tapping the line on the receipt that matches. The app flags a suggested line + to save you hunting for it. Confirmed products are marked verified and stay linked to + the receipt image, which travels with them into your exports.

-

CRA Compliance

+

Records You Can Stand On

- Built with CRA medical expense guidelines in mind. Our reports include the documentation format accepted by the Canada Revenue Agency. + Export a year as a PDF report or a CSV spreadsheet: every product itemized with both + prices, both sizes, both differentials, the purchase date, and the receipt image that + backs it up. Products still lacking a receipt are listed separately rather than + quietly folded into the totals.

Privacy-Focused

- Your financial and health data stays on your device. We prioritize your privacy with local-first storage and optional encrypted backups. + Your financial and health data stays on your device. Text recognition runs on device, + there are no accounts and no cloud sync, and backups are files you control and store + wherever you choose.

@@ -134,11 +140,14 @@

A Complex Claim Process

Celiac Canada Advocacy

- Celiac Canada is actively lobbying the federal government to replace the METC with a + Celiac Canada is lobbying the federal government to replace the METC with a simple, flat refundable tax credit of $1,000 per adult and $600 per child — eliminating the administrative burden entirely. Petition e-6853, supported by 33,000 Canadians, was presented in Parliament in February 2026. + In March 2026 the government declined it: the Medical Expense Tax Credit stays as it is, + and itemized receipts remain your responsibility to keep and produce on request. + Celiac Canada is continuing to press the case ahead of the fall budget.

GF PriceChecker fully supports this effort. We genuinely hope this @@ -183,21 +192,28 @@

Latest from the Dev Blog

Key Features

-

Price Comparison

+

Unit Price Comparison

- Compare prices between gluten-free and regular products to track price differentials for tax purposes. + Gluten-free products don't just cost more — they often contain less. Capture both + package sizes and the app compares cost per unit, not just package to package. + A $7.99 400g gluten-free loaf beside a $3.99 675g regular one looks like a $4.00 + difference. Adjusted for size, the real premium is $5.63.

-

Receipt Tracking

+

Receipt Verification

- Scan and organize your receipts to maintain accurate records for CRA medical expense claims. + Pick the products from a shopping trip, scan the receipt, and tap the matching line + for each one. The app suggests likely matches from the scanned text. Verified products + stay linked to the receipt image that backs them up.

-

Tax Reports

+

Reports & Export

- Generate comprehensive reports that simplify your medical expense deductions come tax season. + Export a year of records as a PDF report or a CSV spreadsheet, with receipt images + included and every product itemized — both the package price difference and the + size-adjusted unit price difference.

diff --git a/sitemap.xml b/sitemap.xml index db73112..87dcc94 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -2,49 +2,49 @@ https://gfpricechecker.com/ - 2026-01-02 + 2026-08-12 weekly 1.0 https://gfpricechecker.com/features.html - 2026-01-02 + 2026-08-12 monthly 0.9 https://gfpricechecker.com/beta.html - 2026-01-25 + 2026-08-12 weekly 0.9 https://gfpricechecker.com/announcements.html - 2026-01-02 + 2026-08-12 weekly 0.8 https://gfpricechecker.com/blog.html - 2026-01-10 + 2026-08-12 weekly 0.8 https://gfpricechecker.com/faq.html - 2026-01-02 + 2026-08-12 monthly 0.7 https://gfpricechecker.com/privacy.html - 2026-01-02 + 2026-01-25 yearly 0.5 https://gfpricechecker.com/terms.html - 2026-01-02 + 2026-01-25 yearly 0.5