From 6eab6551a4f37daffd961246cdb1a6ed8b6c8774 Mon Sep 17 00:00:00 2001 From: Mike Stankavich Date: Fri, 17 Apr 2026 10:00:26 -0500 Subject: [PATCH 01/18] spec(tra-336): design for wholesale platform rewrite of trakrf.id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Captures the repositioning from a consumer conversion funnel to a technology/platform site aimed at channel partners and technical evaluators. Deletes ShipFast-derived sections (Pricing, FAQ, Problem, FeaturesAccordion, CTA) and replaces them with six new sections: HowItWorks, FreeBleScanning, Hardware (two-tier), ChannelPartners, BecomePartner (Google Calendar booking + mailto), TechnicalDetails. Hero/Header/Footer rewritten in place. Imagery sourced from rfidready.net product photos and app screenshots — no stock or AI-generated assets. Co-Authored-By: Claude Opus 4.7 (1M context) --- ...6-04-17-trakrf-wholesale-rewrite-design.md | 238 ++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 docs/superpowers/specs/2026-04-17-trakrf-wholesale-rewrite-design.md diff --git a/docs/superpowers/specs/2026-04-17-trakrf-wholesale-rewrite-design.md b/docs/superpowers/specs/2026-04-17-trakrf-wholesale-rewrite-design.md new file mode 100644 index 0000000..f946261 --- /dev/null +++ b/docs/superpowers/specs/2026-04-17-trakrf-wholesale-rewrite-design.md @@ -0,0 +1,238 @@ +# TRA-336: Rewrite trakrf.id as Wholesale Platform/Technology Site + +**Linear issue:** [TRA-336](https://linear.app/trakrf/issue/TRA-336/rewrite-trakrfid-as-wholesale-platformtechnology-site) +**Branch:** `miks2u/tra-336-rewrite-trakrfid-as-wholesale-platformtechnology-site` +**Date:** 2026-04-17 + +## Context + +TrakRF is wholesale-only. All customer-facing sales flow through channel partners (rfidReady today; Wesco and Camcode as they formalize). trakrf.id is NOT a customer conversion funnel — it is a technology/platform site whose job is to recruit channel partners and support technical due diligence for prospects a partner has already pitched. + +The current trakrf.id is a ShipFast-derived template with consumer-pitch components (pricing tiers, "80% of RFID projects fail" problem narrative, "no credit card required" CTAs, refund-policy FAQ). None of that positioning survives the wholesale strategy shift. + +## Target audiences + +1. **Potential channel partners** — Wesco channel managers, industrial distributors evaluating whether to resell TrakRF +2. **Technical evaluators** — customers doing due diligence after a partner pitch +3. **Developers / integrators** — API and integration evaluation (e.g., TeamCentral-style integrations) + +## Success criteria + +- Site reflects wholesale/platform positioning — no direct-sale framing anywhere +- rfidReady listed as channel partner with working link to rfidready.net +- Partner intake path exists (primary: Google Calendar booking link; secondary: mailto:partners@trakrf.id) +- Free BLE scanning link to app.trakrf.id works and is positioned as proof point, not trial funnel +- Product screenshots and hardware photos used as visuals — no stock photos, no AI-generated imagery +- No ShipFast template artifacts or placeholder copy remaining +- No pricing page, checkout links, or direct-sale CTAs +- `pnpm lint`, `pnpm typecheck`, `pnpm build` all pass + +## Out of scope + +Explicitly NOT in this ticket: +- Pricing anywhere on the site (channel partners set their own customer-facing prices) +- Stripe, checkout, or signup flows +- Trial signup optimization +- Customer testimonials or case studies (those live on partner sites) +- Feature comparison matrices +- FAQ section (the existing FAQ is consumer-framed; a partner-oriented FAQ can be a later issue if demand warrants) +- Blog content (the blog stub page remains on disk but is unlinked from the footer — deletion is out of scope) +- New dev dependencies (Alpine.js is already in BaseLayout and is retained) +- Automated tests (the repo has no test framework today; adding one is a separate decision) + +## Architecture + +Single-page Astro site. `src/pages/index.astro` is rewritten to compose eight new section components. Four ShipFast-derived components are deleted. Hero, Header, and Footer are rewritten in place. + +### Component inventory + +**Deleted (5):** +- `src/components/Problem.astro` — consumer-failure framing +- `src/components/FeaturesAccordion.astro` — generic feature pitch +- `src/components/Pricing.astro` — no direct-sale model +- `src/components/CTA.astro` — "no credit card required" framing +- `src/components/FAQ.astro` — consumer-framed ("Can I get a refund?"), no replacement in this ticket + +**New (6):** +- `src/components/HowItWorks.astro` — architecture overview: handheld Web BLE path + fixed-reader MQTT path, Web Worker for UI responsiveness +- `src/components/FreeBleScanning.astro` — app.trakrf.id free tier as proof point, primary "Try it now" external link +- `src/components/Hardware.astro` — two-tier hardware grid: Supported today + On roadmap +- `src/components/ChannelPartners.astro` — rfidReady card + link to rfidready.net + placeholder for additional partners +- `src/components/BecomePartner.astro` — primary Google Calendar booking link + secondary mailto +- `src/components/TechnicalDetails.astro` — BSL license, self-hosting, API-first, integration-ready + +**Rewritten in place (3):** +- `src/components/Hero.astro` — wholesale/platform positioning with "Scanner + TrakRF" composite as hero image +- `src/components/Header.astro` — new nav + external CTA, mobile menu preserved +- `src/components/Footer.astro` — dead links removed, ShipFast artifacts removed, copyright updated + +**Unchanged:** +- `src/components/PreviewBanner.astro` — preview-branch indicator (independent concern) +- `src/layouts/BaseLayout.astro` — layout shell, Alpine.js script, meta tags +- `src/pages/privacy-policy.astro`, `src/pages/tos.astro` — legal pages remain linked from footer +- `src/pages/blog/index.astro` — stub page remains on disk but unlinked from footer + +### Page composition + +`src/pages/index.astro` imports and renders, in order: + +1. Hero +2. HowItWorks — `
` +3. FreeBleScanning +4. Hardware — `
` +5. ChannelPartners — `
` +6. BecomePartner — `
` +7. TechnicalDetails + +Header and Footer continue to wrap via `BaseLayout.astro`. The existing smooth-scroll script in `index.astro` currently excludes `#signin` and `#checkout` — those exclusions are removed (both anchors are gone); the script keeps only the guard against empty hashes. + +## Section designs + +### 1. Hero + +**Image:** `scanner-trakrf-hero.jpg` (Scanner + TrakRF composite scraped from rfidready.net), right-side on desktop, stacked on mobile. Replaces the existing `public/images/hero.jpg` stock photo. + +**Copy:** +- H1: "The RFID implementation layer for channel partners and integrators" +- Sub: "Browser-based asset tracking. Zero install, no middleware, no driver support calls. Handheld BLE and fixed-reader MQTT paths in one platform." +- Primary CTA: "Try the free BLE app" → `https://app.trakrf.id` (external) +- Secondary CTA: "Talk to us about partnering" → anchor `#become-partner` + +### 2. How it works + +Two-lane architecture overview, no photo. Inline SVG or pure-Tailwind diagram (simple boxes + arrows) showing the two data paths. Total ~120 words across the two lanes. + +**Handheld lane:** +- Browser on Bluetooth-capable device → CSL CS108 (or similar BLE reader) via Web BLE +- Reads go directly to the TrakRF web app; Web Worker decodes the tag stream so the UI stays responsive +- No installs, no driver support calls + +**Fixed lane:** +- LLRP readers (Impinj Speedway, CSL CS463) → MQTT (direct or via Pi 5 edge relay) → TrakRF web app +- Same UI and data model as the handheld path; same Web Worker architecture + +### 3. Free BLE scanning + +Screenshot (`app-scan-screen.png`) alongside ~80 words of copy. Frames app.trakrf.id as a **proof point**, not a trial funnel: anyone with a BLE-capable browser and a CS108 can scan right now without an account. Technical evaluators can touch the product in under a minute. + +CTA: "Open app.trakrf.id" (external). + +### 4. Supported hardware + +Two-tier card grid. Each card: name, short spec line, integration path note, optional product photo (scraped or omitted per availability), optional vendor "Spec sheet" link. + +**Supported today** (green check badge): +- CSL CS108 — handheld UHF, direct BLE +- CSL CS463 — fixed UHF, direct MQTT +- Impinj Speedway R420 — fixed UHF, via Pi 5 edge relay (already in production on OMH) +- GL-S10 gateway — MQTT bridge for LLRP readers +- Pi 5 edge server — LLRP → MQTT bridge; enables any LLRP reader today + +**On roadmap** (clock badge, captioned "Prioritized by partner demand"): +- Impinj R700 — native MQTT, no edge relay needed +- Impinj xArray / later Speedway revisions +- Chainway C72 / C66 — Android handheld, BLE +- TSL 1153 / 2166 — BLE sled +- Zebra RFD8500 / FX9600 — handheld + fixed + +The narrative for evaluators: "any LLRP reader works today via Pi 5; the roadmap focuses on readers with direct MQTT so deployments can skip the edge device." + +### 5. Channel partners + +Intro line: "TrakRF is wholesale-only. Our channel partners handle pricing, implementation services, and support." + +rfidReady card (logo if scrapeable, otherwise text-only card) with link to rfidready.net. + +Placeholder line: "Additional partners added as agreements finalize." + +### 6. Become a partner + +Anchor ID `#become-partner`. ~40-word pitch framed for distributors, integrators, and MSPs with industrial/logistics customers. + +- Primary button: "Book a 30-min intro call" → `https://calendar.app.google/Hv1Bsm8Mc4wjPaJV8` +- Secondary text line: "Or email [partners@trakrf.id](mailto:partners@trakrf.id)" + +Delivery for partners@trakrf.id currently routes via partners@devopstoai.com (trakrf.id is a user alias domain behind devopstoai.com); the site-visible address is partners@trakrf.id. + +### 7. Technical details + +Four-item grid or two-column list: +- **License:** Business Source License (BSL) with self-hosting rights +- **Self-hosting:** Run the full stack on partner or customer infrastructure +- **API-first:** Every app action is an API call (enables TeamCentral-style integrations) +- **Integration-ready:** MQTT, REST, webhooks + +### 8. Footer + +Logo + one-line tagline ("The RFID implementation layer"). + +Three link columns: +- **Platform** — app.trakrf.id (external) +- **Partners** — rfidready.net (external), Become a partner (anchor `#become-partner`) +- **Legal** — Terms of services, Privacy policy + +Copyright: `© {currentYear} DevOps To AI LLC dba TrakRF` + +Removed from current footer: `/#pricing` link, `/blog` link, "Support" mailto (folded into Become a partner), ShipFast artifacts. + +## Navigation (Header) + +Desktop: +- Logo (links to `/`) +- How it works (anchor) +- Hardware (anchor) +- Partners (anchor) +- [button] "Try the free app" → `https://app.trakrf.id` + +Mobile menu (Alpine.js, preserved from existing Header) mirrors the desktop links with the primary CTA at the bottom. + +Removed from current header: Pricing link, FAQ link, Sign In button, `handheld.trakrf.id` "Read Tags" link (superseded by `app.trakrf.id`). + +## Image assets + +All images live under `public/images/product/`. Sourced by scraping rfidready.net during implementation (`curl` + direct image URLs from the live site). No AI-generated or stock fallbacks. + +Target filenames: +- `scanner-trakrf-hero.jpg` — Scanner + TrakRF composite (Hero) +- `cs108-handheld.jpg` — CS108 with mount (Hardware) +- `tag-sample-pack.jpg` — tag sample pack (Hardware) +- `app-home-screen.png` — TrakRF app home screen +- `app-scan-screen.png` — TrakRF app scan screen (FreeBleScanning) +- `app-locate-screen.png` — TrakRF app locate/search screen +- `rfidready-logo.svg` or `.png` — rfidReady logo (ChannelPartners) + +**Fallback policy:** if a target image is not findable on rfidready.net during implementation, the affected section uses a text-only card or drops the image. Implementation flags any missing asset so it can be addressed separately. No stock or AI fallbacks. + +The existing `public/images/hero.jpg` (stock photo) is removed along with any references. + +## Validation + +Aligned with `spec/stack.md`: +- `pnpm lint` — Prettier + ESLint, must pass cleanly +- `pnpm typecheck` — Astro TypeScript checker, zero errors +- `pnpm build` — static site builds successfully +- Manual smoke checks: + - All in-page anchor links scroll to their targets + - Google Calendar booking link opens in a new tab + - app.trakrf.id link opens in a new tab + - mailto:partners@trakrf.id opens the default mail client + - No broken image references (`` or Astro ``) + - Mobile menu opens and closes + - Preview banner appears when built with `PUBLIC_BRANCH=preview` + - Footer shows current year and legal links still work + +No automated tests added in this ticket. + +## Open questions / deferred + +- **Partner-oriented FAQ:** not in this ticket. If partner prospects start asking the same questions, add as a follow-on. +- **Additional channel partners (Wesco, Camcode):** not listed until they have signed agreements and live app instances. Adding them is a one-line change inside `ChannelPartners.astro` when the time comes. +- **Image licensing:** all visuals are either TrakRF product screenshots or rfidready.net product photos (our own channel partner's assets). If any image on rfidready.net turns out to be vendor-supplied with restrictive licensing, flag during implementation and fall back to text-only. +- **Impinj R700 hardware dev:** user has an R700 on hand. Direct-MQTT integration is the easiest roadmap item to accelerate; promotion from "on roadmap" to "supported today" is a one-line change in `Hardware.astro`. + +## Follow-on work (not in this ticket) + +- Delete or properly populate `src/pages/blog/index.astro` — handled in a separate ticket +- Evaluate dropping Alpine.js entirely if mobile menu is the only remaining consumer +- Add automated visual regression or accessibility tests +- Retire the `spec/csw/` workflow infrastructure if the team decides to standardize on superpowers (separate cleanup ticket) From 89d450f0d9fedae980ce9e457e127e4c7b8463bc Mon Sep 17 00:00:00 2001 From: Mike Stankavich Date: Fri, 17 Apr 2026 10:07:09 -0500 Subject: [PATCH 02/18] plan(tra-336): implementation plan for wholesale platform rewrite Fourteen-task plan covering imagery sourcing from rfidready.net, deletion of five ShipFast components, in-place rewrites of Hero / Header / Footer, six new section components, progressive composition into src/pages/index.astro, and end-to-end validation. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../2026-04-17-trakrf-wholesale-rewrite.md | 1381 +++++++++++++++++ 1 file changed, 1381 insertions(+) create mode 100644 docs/superpowers/plans/2026-04-17-trakrf-wholesale-rewrite.md diff --git a/docs/superpowers/plans/2026-04-17-trakrf-wholesale-rewrite.md b/docs/superpowers/plans/2026-04-17-trakrf-wholesale-rewrite.md new file mode 100644 index 0000000..3a5c8d3 --- /dev/null +++ b/docs/superpowers/plans/2026-04-17-trakrf-wholesale-rewrite.md @@ -0,0 +1,1381 @@ +# TRA-336 Wholesale Rewrite Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Rewrite the trakrf.id marketing site from a ShipFast-derived consumer funnel into a single-page Astro wholesale/platform site targeting channel partners and technical evaluators, per spec `docs/superpowers/specs/2026-04-17-trakrf-wholesale-rewrite-design.md`. + +**Architecture:** Delete five obsolete ShipFast components, rewrite Hero/Header/Footer in place, add six new section components (HowItWorks, FreeBleScanning, Hardware, ChannelPartners, BecomePartner, TechnicalDetails), and recompose `src/pages/index.astro`. Real product imagery is scraped from rfidready.net (our own channel partner's site) into `public/images/product/`. No stock photos, no AI imagery, no pricing, no checkout. + +**Tech Stack:** Astro 4.x, Tailwind CSS + DaisyUI, TypeScript (strict), Alpine.js (CDN, already in BaseLayout), pnpm. + +**Validation per-task:** No automated tests exist in this repo. Per-task validation is `pnpm typecheck`, visual smoke in `pnpm dev`, and `pnpm lint`. Full `pnpm build` runs at the end. + +**Branch:** `miks2u/tra-336-rewrite-trakrfid-as-wholesale-platformtechnology-site` (already created; the design spec lives in its initial commit). + +--- + +## Phase 1: Prep — product imagery + +### Task 1: Scrape product images from rfidready.net + +**Files:** +- Create: `public/images/product/` (directory) +- Create: `public/images/product/scanner-trakrf-hero.jpg` +- Create: `public/images/product/cs108-handheld.jpg` +- Create: `public/images/product/tag-sample-pack.jpg` +- Create: `public/images/product/app-scan-screen.png` +- Create: `public/images/product/rfidready-logo.{svg|png}` +- Optional: `public/images/product/app-home-screen.png`, `public/images/product/app-locate-screen.png` + +- [ ] **Step 1: Create target directory** + +Run: `mkdir -p public/images/product` + +- [ ] **Step 2: Enumerate candidate image URLs on rfidready.net** + +Use WebFetch against `https://rfidready.net/` and any linked product/solution pages to harvest image URLs. Look specifically for: +- Composite image showing a handheld scanner next to the TrakRF app (hero candidate) +- CS108 handheld with mount (product photo) +- Tag sample pack (loose tags fanned out) +- TrakRF app screenshots (home / scan / locate / search views) +- rfidReady wordmark or logo + +Record the full URL and content-type for each candidate before downloading. + +- [ ] **Step 3: Download each candidate to `public/images/product/` with the target filename** + +For every mapped asset, run the equivalent of: + +```bash +curl -L --fail -o public/images/product/scanner-trakrf-hero.jpg \ + 'https://rfidready.net//.jpg' +``` + +Keep the Content-Type honest — use `.png` for PNGs, `.jpg` for JPEGs, `.svg` for SVGs. Do not re-encode. + +- [ ] **Step 4: Sanity-check sizes and dimensions** + +```bash +ls -lah public/images/product/ +file public/images/product/* +``` + +Expected: each file under ~2 MB; correct MIME. If any file is an HTML error page (happens when a URL 404s under `curl -L` without `--fail`), delete it and re-resolve its source URL. + +- [ ] **Step 5: Flag missing assets** + +If any of the five required assets (scanner-trakrf-hero, cs108-handheld, tag-sample-pack, app-scan-screen, rfidready-logo) cannot be sourced from rfidready.net, note which ones in the commit message. Do NOT substitute stock photos or AI-generated imagery. Downstream tasks will render text-only cards in the affected sections. + +- [ ] **Step 6: Commit** + +```bash +git add public/images/product/ +git commit -m "chore(tra-336): scrape product imagery from rfidready.net" +``` + +--- + +## Phase 2: Shell rewrites — Header, Footer, Hero + +### Task 2: Rewrite Header.astro + +New nav: How it works / Hardware / Partners, plus a primary "Try the free app" button linking to app.trakrf.id. Remove Pricing, FAQ, Sign In, and the `handheld.trakrf.id` link. Mobile menu is preserved (Alpine.js). + +**Files:** +- Modify: `src/components/Header.astro` (full rewrite) + +- [ ] **Step 1: Replace the entire contents of `src/components/Header.astro` with the following** + +```astro +--- +import { Image } from 'astro:assets'; +import logo from '../../public/images/icon.png'; + +const links = [ + { href: '#how-it-works', label: 'How it works' }, + { href: '#hardware', label: 'Hardware' }, + { href: '#partners', label: 'Partners' } +]; +--- + +
+ + + +
+
+
+ + TrakRF + + +
+
+
+ { + links.map((link) => ( + + {link.label} + + )) + } +
+ + Try the free app + +
+
+
+
+
+``` + +- [ ] **Step 2: Typecheck** + +Run: `pnpm typecheck` +Expected: passes. Astro may still warn about unused imports elsewhere; only fail on errors in `Header.astro`. + +- [ ] **Step 3: Visually smoke-test in dev server** + +Run: `pnpm dev` (leave running through subsequent tasks) +Open: `http://localhost:4321/` +Check: +- Header shows logo + three nav links + "Try the free app" button on desktop +- Mobile menu button visible below `lg` breakpoint; clicking it opens the drawer with the same links + button +- "Try the free app" opens `https://app.trakrf.id` in a new tab + +The nav anchors may 404-scroll for now since the target sections don't exist yet — that's expected; we'll add them later. + +- [ ] **Step 4: Commit** + +```bash +git add src/components/Header.astro +git commit -m "feat(tra-336): rewrite Header for wholesale positioning" +``` + +--- + +### Task 3: Rewrite Footer.astro + +Three-column footer: Platform (app.trakrf.id external), Partners (rfidready.net external, Become a partner anchor), Legal (ToS, Privacy). Copyright becomes "© YYYY DevOps To AI LLC dba TrakRF". Remove `/#pricing` link, `/blog` link, and the generic Support mailto (superseded by the Become a partner section). + +**Files:** +- Modify: `src/components/Footer.astro` (full rewrite) + +- [ ] **Step 1: Replace the entire contents of `src/components/Footer.astro` with the following** + +```astro +--- +import { Image } from 'astro:assets'; +import logo from '../../public/images/icon.png'; + +const currentYear = new Date().getFullYear(); +--- + + +``` + +- [ ] **Step 2: Typecheck** + +Run: `pnpm typecheck` +Expected: passes. + +- [ ] **Step 3: Smoke-test** + +Reload `http://localhost:4321/`. Check: +- Three columns visible on desktop (Platform / Partners / Legal) +- rfidReady link opens rfidready.net in new tab +- Become a partner link targets `#become-partner` (will no-op until that section exists; fine for now) +- Copyright line shows "© {currentYear} DevOps To AI LLC dba TrakRF" + +- [ ] **Step 4: Commit** + +```bash +git add src/components/Footer.astro +git commit -m "feat(tra-336): rewrite Footer with wholesale navigation" +``` + +--- + +### Task 4: Rewrite Hero.astro + +New hero with wholesale positioning. Primary CTA → app.trakrf.id (external); secondary CTA → `#become-partner`. Image is `scanner-trakrf-hero.jpg` from Task 1 (or text-only variant if missing). + +**Files:** +- Modify: `src/components/Hero.astro` (full rewrite) + +- [ ] **Step 1: Replace the entire contents of `src/components/Hero.astro` with the following** + +```astro +--- +import { Image } from 'astro:assets'; +import heroImage from '../../public/images/product/scanner-trakrf-hero.jpg'; +--- + +
+ +
+

+ The RFID implementation layer for channel partners and integrators +

+

+ Browser-based asset tracking. Zero install, no middleware, no driver support calls. Handheld + BLE and fixed-reader MQTT paths in one platform. +

+ +
+ + +
+ A handheld RFID scanner paired with the TrakRF web app +
+
+``` + +- [ ] **Step 2: Handle missing image gracefully** + +If Task 1 could not source `scanner-trakrf-hero.jpg`, replace the `---` frontmatter and the `` block with a text-only variant: + +```astro +--- +--- + +
+ +
+

+ The RFID implementation layer for channel partners and integrators +

+

+ Browser-based asset tracking. Zero install, no middleware, no driver support calls. Handheld + BLE and fixed-reader MQTT paths in one platform. +

+ +
+
+``` + +- [ ] **Step 3: Typecheck** + +Run: `pnpm typecheck` +Expected: passes. If Astro complains about the image import when the file is missing, you are in the fallback case — use the text-only variant from Step 2. + +- [ ] **Step 4: Smoke-test** + +Reload `http://localhost:4321/`. Check: +- New H1 copy renders +- Both buttons present +- Image loads if present; no broken-image icon + +- [ ] **Step 5: Commit** + +```bash +git add src/components/Hero.astro +git commit -m "feat(tra-336): rewrite Hero with wholesale positioning" +``` + +--- + +## Phase 3: Transition — simplify index.astro and delete obsolete components + +### Task 5: Simplify index.astro to Hero-only and fix smooth-scroll guard + +Before deleting obsolete components we must stop importing them. This task leaves the page at "just the new Hero" so the delete in Task 6 is clean. + +**Files:** +- Modify: `src/pages/index.astro` (full rewrite) + +- [ ] **Step 1: Replace the entire contents of `src/pages/index.astro` with the following** + +```astro +--- +import BaseLayout from '../layouts/BaseLayout.astro'; +import Hero from '../components/Hero.astro'; + +const title = 'TrakRF — The RFID implementation layer'; +const description = + 'Browser-based RFID and BLE asset tracking for channel partners and integrators. Zero install, no middleware, no driver support calls.'; +--- + + +
+ +
+ + +
+``` + +Note the guard list changed from `'#' || '#signin' || '#checkout'` to just the empty-hash guard — those two anchors are gone. + +- [ ] **Step 2: Typecheck** + +Run: `pnpm typecheck` +Expected: passes. Even though `Problem.astro`, `FeaturesAccordion.astro`, `Pricing.astro`, `FAQ.astro`, and `CTA.astro` still exist on disk, nothing imports them any more. + +- [ ] **Step 3: Smoke-test** + +Reload `http://localhost:4321/`. Page should render Hero only (between Header and Footer). Title in the tab should be "TrakRF — The RFID implementation layer". + +- [ ] **Step 4: Commit** + +```bash +git add src/pages/index.astro +git commit -m "chore(tra-336): reduce index.astro to Hero-only as transition point" +``` + +--- + +### Task 6: Delete obsolete ShipFast components + +**Files:** +- Delete: `src/components/Problem.astro` +- Delete: `src/components/FeaturesAccordion.astro` +- Delete: `src/components/Pricing.astro` +- Delete: `src/components/FAQ.astro` +- Delete: `src/components/CTA.astro` + +- [ ] **Step 1: Verify no lingering imports** + +```bash +grep -RIn "Problem\.astro\|FeaturesAccordion\.astro\|Pricing\.astro\|FAQ\.astro\|CTA\.astro" src/ || true +grep -RIn "from '\.\./components/\(Problem\|FeaturesAccordion\|Pricing\|FAQ\|CTA\)'" src/ || true +``` + +Expected: zero matches. If any remain, resolve them before deleting. + +- [ ] **Step 2: Delete the files** + +```bash +git rm src/components/Problem.astro \ + src/components/FeaturesAccordion.astro \ + src/components/Pricing.astro \ + src/components/FAQ.astro \ + src/components/CTA.astro +``` + +- [ ] **Step 3: Typecheck and build** + +```bash +pnpm typecheck +pnpm build +``` + +Expected: both pass. Build must succeed — this is the last chance to catch a lingering reference before we start adding new sections. + +- [ ] **Step 4: Smoke-test** + +Reload `http://localhost:4321/`. Still Hero-only, no runtime errors in the browser console. + +- [ ] **Step 5: Commit** + +```bash +git commit -m "chore(tra-336): remove ShipFast-derived section components" +``` + +--- + +## Phase 4: New section components + +Each task creates one component and inserts it into `src/pages/index.astro` in the correct position. Section anchor IDs match the Header nav and footer "Become a partner" link. + +### Task 7: HowItWorks.astro + +Two-lane architecture overview — handheld (Web BLE) + fixed (MQTT). No photos. + +**Files:** +- Create: `src/components/HowItWorks.astro` +- Modify: `src/pages/index.astro` + +- [ ] **Step 1: Create `src/components/HowItWorks.astro`** + +```astro +--- +const lanes = [ + { + title: 'Handheld · Web BLE', + flow: 'Browser → Web BLE → CS108 (or any supported BLE reader)', + body: + 'A Bluetooth-capable browser talks directly to the handheld. Tags stream into the TrakRF web app; a Web Worker decodes the read stream so the UI stays responsive. No installs, no drivers, no support tickets for USB cables.' + }, + { + title: 'Fixed · MQTT', + flow: 'LLRP reader → MQTT (direct or via Pi 5 edge relay) → Browser', + body: + 'Fixed readers publish to MQTT — directly if the reader supports native MQTT, or through the TrakRF Pi 5 edge relay for LLRP-only hardware. The browser subscribes and renders reads through the same UI and data model as the handheld path.' + } +]; +--- + +
+
+
+

How it works

+

+ Two paths, one browser-based platform +

+
+ +
+ { + lanes.map((lane) => ( +
+

{lane.title}

+

{lane.flow}

+

{lane.body}

+
+ )) + } +
+
+
+``` + +- [ ] **Step 2: Add to `src/pages/index.astro`** + +Replace the current imports and `
` block with: + +```astro +--- +import BaseLayout from '../layouts/BaseLayout.astro'; +import Hero from '../components/Hero.astro'; +import HowItWorks from '../components/HowItWorks.astro'; + +const title = 'TrakRF — The RFID implementation layer'; +const description = + 'Browser-based RFID and BLE asset tracking for channel partners and integrators. Zero install, no middleware, no driver support calls.'; +--- + + +
+ + +
+ + +
+``` + +- [ ] **Step 3: Typecheck + smoke** + +Run: `pnpm typecheck` +Expected: passes. Reload browser; click the Header "How it works" link — page should now smooth-scroll to the new section. + +- [ ] **Step 4: Commit** + +```bash +git add src/components/HowItWorks.astro src/pages/index.astro +git commit -m "feat(tra-336): add HowItWorks section" +``` + +--- + +### Task 8: FreeBleScanning.astro + +Proof-point section — app.trakrf.id is not a trial funnel, it's a technology demonstrator. + +**Files:** +- Create: `src/components/FreeBleScanning.astro` +- Modify: `src/pages/index.astro` + +- [ ] **Step 1: Create `src/components/FreeBleScanning.astro`** + +```astro +--- +import { Image } from 'astro:assets'; +let screenshot: ImageMetadata | null = null; +try { + screenshot = (await import('../../public/images/product/app-scan-screen.png')).default; +} catch { + screenshot = null; +} +--- + +
+
+
+
+

Free BLE scanning

+

+ Touch the product in under a minute +

+

+ app.trakrf.id is a + proof point, not a trial funnel. Open it in a Bluetooth-capable browser, pair a CSL + CS108, and scan — no account, no download, no middleware. Technical evaluators can + verify the platform end-to-end without a sales conversation. +

+ +
+ +
+ { + screenshot ? ( + TrakRF web app scan screen + ) : ( +
+ Screenshot coming soon +
+ ) + } +
+
+
+
+``` + +- [ ] **Step 2: Add to `src/pages/index.astro`** + +Update the imports and `
`: + +```astro +import FreeBleScanning from '../components/FreeBleScanning.astro'; +``` + +```astro + + + +``` + +- [ ] **Step 3: Typecheck + smoke** + +`pnpm typecheck` → passes. Reload; new section renders between HowItWorks and Footer. "Open app.trakrf.id" opens in a new tab. + +- [ ] **Step 4: Commit** + +```bash +git add src/components/FreeBleScanning.astro src/pages/index.astro +git commit -m "feat(tra-336): add FreeBleScanning proof-point section" +``` + +--- + +### Task 9: Hardware.astro + +Two-tier grid: Supported today + On roadmap. Uses scraped images for CS108 and tag sample pack where available; text-only cards otherwise. + +**Files:** +- Create: `src/components/Hardware.astro` +- Modify: `src/pages/index.astro` + +- [ ] **Step 1: Create `src/components/Hardware.astro`** + +```astro +--- +import { Image } from 'astro:assets'; + +let cs108Img: ImageMetadata | null = null; +let tagsImg: ImageMetadata | null = null; +try { + cs108Img = (await import('../../public/images/product/cs108-handheld.jpg')).default; +} catch {} +try { + tagsImg = (await import('../../public/images/product/tag-sample-pack.jpg')).default; +} catch {} + +const supported = [ + { + name: 'CSL CS108', + spec: 'Handheld UHF · BLE · iOS/Android/Browser', + integration: 'Direct BLE to browser', + image: cs108Img, + alt: 'CSL CS108 handheld RFID reader' + }, + { + name: 'CSL CS463', + spec: 'Fixed UHF · 4 antennas · PoE', + integration: 'Direct MQTT', + image: null, + alt: null + }, + { + name: 'Impinj Speedway R420', + spec: 'Fixed UHF · 4 antennas · LLRP', + integration: 'Via Pi 5 edge relay (in production on OMH)', + image: null, + alt: null + }, + { + name: 'GL-S10 gateway', + spec: 'MQTT bridge for LLRP readers', + integration: 'LLRP → MQTT on a compact gateway', + image: null, + alt: null + }, + { + name: 'Pi 5 edge server', + spec: 'TrakRF edge software on Raspberry Pi 5', + integration: 'Enables any LLRP reader today', + image: null, + alt: null + }, + { + name: 'Tag sample pack', + spec: 'UHF inlays for pilots and testing', + integration: 'Included in partner evaluation kits', + image: tagsImg, + alt: 'Assorted UHF RFID tag inlays' + } +]; + +const roadmap = [ + { name: 'Impinj R700', note: 'Native MQTT — skip the edge relay' }, + { name: 'Impinj xArray / later Speedway', note: 'Fixed UHF family' }, + { name: 'Chainway C72 / C66', note: 'Android handheld, BLE' }, + { name: 'TSL 1153 / 2166', note: 'BLE sled' }, + { name: 'Zebra RFD8500 / FX9600', note: 'Handheld + fixed' } +]; +--- + +
+
+
+

Supported hardware

+

+ Any LLRP reader today. More on the roadmap. +

+

+ The Pi 5 edge relay covers every LLRP reader in the field right now. The roadmap + focuses on readers with native MQTT so deployments can skip the edge device. +

+
+ +

+ Supported today +

+
+ { + supported.map((dev) => ( +
+ {dev.image && ( + {dev.alt + )} +
+

{dev.name}

+

{dev.spec}

+

{dev.integration}

+
+
+ )) + } +
+ +

+ On roadmap + + Prioritized by partner demand + +

+
+ { + roadmap.map((dev) => ( +
+

{dev.name}

+

{dev.note}

+
+ )) + } +
+
+
+``` + +- [ ] **Step 2: Add to `src/pages/index.astro`** + +```astro +import Hardware from '../components/Hardware.astro'; +``` + +```astro + + + + +``` + +- [ ] **Step 3: Typecheck + smoke** + +`pnpm typecheck` → passes. Reload; Hardware renders with the two tiers. If CS108 or tag sample pack images were missing in Task 1, those cards render without an image but the rest of the card content still appears. + +- [ ] **Step 4: Commit** + +```bash +git add src/components/Hardware.astro src/pages/index.astro +git commit -m "feat(tra-336): add Hardware section with supported/roadmap tiers" +``` + +--- + +### Task 10: ChannelPartners.astro + +rfidReady card (logo if scraped; wordmark fallback) + "more coming" placeholder. + +**Files:** +- Create: `src/components/ChannelPartners.astro` +- Modify: `src/pages/index.astro` + +- [ ] **Step 1: Create `src/components/ChannelPartners.astro`** + +Use whichever extension Task 1 landed for the logo. If neither is present, the card renders with a text wordmark. + +```astro +--- +import { Image } from 'astro:assets'; +let rfidReadyLogo: ImageMetadata | null = null; +try { + rfidReadyLogo = (await import('../../public/images/product/rfidready-logo.png')).default; +} catch { + try { + rfidReadyLogo = (await import('../../public/images/product/rfidready-logo.svg')).default; + } catch {} +} +--- + +
+
+
+

Channel partners

+

+ TrakRF is wholesale-only +

+

+ Our channel partners handle pricing, implementation services, and customer support. + If you're an end customer, start with one of our partners. +

+
+ + +
+
+``` + +- [ ] **Step 2: Add to `src/pages/index.astro`** + +```astro +import ChannelPartners from '../components/ChannelPartners.astro'; +``` + +```astro + + + + + +``` + +- [ ] **Step 3: Typecheck + smoke** + +`pnpm typecheck` → passes. Reload; the Header "Partners" link should now smooth-scroll to this section. Inline `#become-partner` link falls through (target still missing). + +- [ ] **Step 4: Commit** + +```bash +git add src/components/ChannelPartners.astro src/pages/index.astro +git commit -m "feat(tra-336): add ChannelPartners section with rfidReady" +``` + +--- + +### Task 11: BecomePartner.astro + +Primary Google Calendar booking button + secondary mailto. + +**Files:** +- Create: `src/components/BecomePartner.astro` +- Modify: `src/pages/index.astro` + +- [ ] **Step 1: Create `src/components/BecomePartner.astro`** + +```astro +--- +const bookingUrl = 'https://calendar.app.google/Hv1Bsm8Mc4wjPaJV8'; +const partnerEmail = 'partners@trakrf.id'; +--- + +
+
+

Become a partner

+

+ Let's talk about reselling TrakRF +

+

+ We're looking for distributors, systems integrators, and MSPs with industrial and + logistics customers. 30 minutes is enough to see the platform, hear your use case, and + decide if it's a fit. +

+ +
+
+``` + +- [ ] **Step 2: Add to `src/pages/index.astro`** + +```astro +import BecomePartner from '../components/BecomePartner.astro'; +``` + +```astro + + + + + + +``` + +- [ ] **Step 3: Typecheck + smoke** + +`pnpm typecheck` → passes. Reload; scroll-to `#become-partner` now resolves. Click the booking button — opens Google Calendar in a new tab. Click the mailto — opens the default mail client. + +- [ ] **Step 4: Commit** + +```bash +git add src/components/BecomePartner.astro src/pages/index.astro +git commit -m "feat(tra-336): add BecomePartner section with booking + mailto" +``` + +--- + +### Task 12: TechnicalDetails.astro + +Four-item grid: License (BSL), Self-hosting, API-first, Integration-ready. + +**Files:** +- Create: `src/components/TechnicalDetails.astro` +- Modify: `src/pages/index.astro` + +- [ ] **Step 1: Create `src/components/TechnicalDetails.astro`** + +```astro +--- +const details = [ + { + title: 'License', + body: + 'Business Source License (BSL). Self-hosting is included. Commercial resale is governed by the partner agreement.' + }, + { + title: 'Self-hosting', + body: + 'Run the full stack on partner or customer infrastructure. No mandatory TrakRF-hosted dependency for operational data.' + }, + { + title: 'API-first', + body: + 'Every action in the web app is an API call. The same endpoints power TeamCentral-style integrations and third-party automation.' + }, + { + title: 'Integration-ready', + body: + 'MQTT, REST, and webhooks out of the box. Pair with Pi 5 edge relay to bridge LLRP readers and existing event buses.' + } +]; +--- + +
+
+
+

Technical details

+

+ Built for partners who need to ship +

+
+ +
+ { + details.map((item) => ( +
+

{item.title}

+

{item.body}

+
+ )) + } +
+
+
+``` + +- [ ] **Step 2: Add to `src/pages/index.astro` (final composition)** + +```astro +--- +import BaseLayout from '../layouts/BaseLayout.astro'; +import Hero from '../components/Hero.astro'; +import HowItWorks from '../components/HowItWorks.astro'; +import FreeBleScanning from '../components/FreeBleScanning.astro'; +import Hardware from '../components/Hardware.astro'; +import ChannelPartners from '../components/ChannelPartners.astro'; +import BecomePartner from '../components/BecomePartner.astro'; +import TechnicalDetails from '../components/TechnicalDetails.astro'; + +const title = 'TrakRF — The RFID implementation layer'; +const description = + 'Browser-based RFID and BLE asset tracking for channel partners and integrators. Zero install, no middleware, no driver support calls.'; +--- + + +
+ + + + + + + +
+ + +
+``` + +- [ ] **Step 3: Typecheck + smoke** + +`pnpm typecheck` → passes. Reload; all seven sections render in order. + +- [ ] **Step 4: Commit** + +```bash +git add src/components/TechnicalDetails.astro src/pages/index.astro +git commit -m "feat(tra-336): add TechnicalDetails section and finalize index composition" +``` + +--- + +## Phase 5: Cleanup and final validation + +### Task 13: Remove obsolete `public/images/hero.jpg` + +The old stock-photo hero is no longer referenced. Delete it. + +**Files:** +- Delete: `public/images/hero.jpg` + +- [ ] **Step 1: Confirm nothing references it** + +```bash +grep -RIn "images/hero\.jpg\|hero\.jpg" src/ public/ || true +``` + +Expected: zero matches. + +- [ ] **Step 2: Delete** + +```bash +git rm public/images/hero.jpg +``` + +- [ ] **Step 3: Typecheck and build** + +```bash +pnpm typecheck +pnpm build +``` + +Both must pass. + +- [ ] **Step 4: Commit** + +```bash +git commit -m "chore(tra-336): remove unused ShipFast hero stock photo" +``` + +--- + +### Task 14: Final validation and push + +- [ ] **Step 1: Lint** + +Run: `pnpm lint` +Expected: passes cleanly. Fix any formatting or ESLint findings before proceeding. + +- [ ] **Step 2: Typecheck** + +Run: `pnpm typecheck` +Expected: zero errors. + +- [ ] **Step 3: Build** + +Run: `pnpm build` +Expected: builds successfully. Note any unused-image or preload warnings and decide whether to address them inline. + +- [ ] **Step 4: Manual smoke checklist** + +Run: `pnpm dev` and walk through the following in a desktop browser: + +- Header: logo + three nav links + primary button visible +- Clicking each nav link smooth-scrolls to the corresponding section (`#how-it-works`, `#hardware`, `#partners`) +- Hero: H1 copy matches the spec; both CTAs work +- HowItWorks: two lanes render side-by-side on desktop, stacked on mobile +- FreeBleScanning: app.trakrf.id button opens in new tab; screenshot present if sourced +- Hardware: Supported-today grid shows 6 cards; On-roadmap grid shows 5 cards; badges render +- ChannelPartners: rfidReady card links to rfidready.net +- BecomePartner: booking button opens Google Calendar; mailto opens mail client +- TechnicalDetails: four-card grid renders +- Footer: three columns (Platform / Partners / Legal), current-year copyright, no broken links +- Mobile (narrow viewport): hamburger menu opens, nav links work, primary button present at the bottom +- Browser console: no errors on load or navigation + +Then test the preview banner path: + +```bash +PUBLIC_BRANCH=preview pnpm build && pnpm preview +``` + +Expected: the Pythonesque preview banner appears at the top of the page. + +- [ ] **Step 5: Push the branch** + +```bash +git push -u origin miks2u/tra-336-rewrite-trakrfid-as-wholesale-platformtechnology-site +``` + +- [ ] **Step 6 (optional): open the pull request** + +If the user has confirmed they want a PR opened, use: + +```bash +gh pr create --title "TRA-336: rewrite trakrf.id as wholesale platform site" --body "$(cat <<'EOF' +## Summary +- Deletes five ShipFast-derived consumer-funnel components +- Adds six new section components (HowItWorks, FreeBleScanning, Hardware, ChannelPartners, BecomePartner, TechnicalDetails) +- Rewrites Hero, Header, and Footer for wholesale/partner positioning +- Sources real product imagery from rfidready.net + +Closes TRA-336. + +## Test plan +- [ ] pnpm lint clean +- [ ] pnpm typecheck clean +- [ ] pnpm build succeeds +- [ ] Manual smoke on desktop + mobile +- [ ] Preview banner still fires with PUBLIC_BRANCH=preview + +🤖 Generated with [Claude Code](https://claude.com/claude-code) +EOF +)" +``` + +Otherwise stop here and wait for user confirmation. + +--- + +## Notes for the implementer + +- **Alpine.js** is loaded via ` + From 368c44849ccfe335fcad1e222a497075c6112ae5 Mon Sep 17 00:00:00 2001 From: Mike Stankavich Date: Fri, 17 Apr 2026 10:28:31 -0500 Subject: [PATCH 18/18] chore(tra-336): address code review feedback - Hero: switch to ImageMetadata | null + conditional render so the section degrades to a text-only hero if the scraped image is ever missing, matching the pattern already in FreeBleScanning, Hardware, and ChannelPartners. - FreeBleScanning: add mb-2 to the eyebrow paragraph so spacing matches the other six section components. - Remove unreferenced app-home-screen.webp and app-locate-screen.webp (scraped in Task 1 as nice-to-haves, never wired in). Co-Authored-By: Claude Opus 4.7 (1M context) --- public/images/product/app-home-screen.webp | Bin 10060 -> 0 bytes public/images/product/app-locate-screen.webp | Bin 11938 -> 0 bytes src/components/FreeBleScanning.astro | 2 +- src/components/Hero.astro | 27 ++++++++++++------- 4 files changed, 18 insertions(+), 11 deletions(-) delete mode 100644 public/images/product/app-home-screen.webp delete mode 100644 public/images/product/app-locate-screen.webp diff --git a/public/images/product/app-home-screen.webp b/public/images/product/app-home-screen.webp deleted file mode 100644 index 80a05a147e9eb8a40b6d79a7fd5155b2d4e5d831..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10060 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 IDf>_UAB_o0X8-^I diff --git a/public/images/product/app-locate-screen.webp b/public/images/product/app-locate-screen.webp deleted file mode 100644 index 17357ec20682715d28eeb56be01e4415515aa328..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11938 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 K{r{HzH~t?)T_8*V diff --git a/src/components/FreeBleScanning.astro b/src/components/FreeBleScanning.astro index b2e36c9..f34be69 100644 --- a/src/components/FreeBleScanning.astro +++ b/src/components/FreeBleScanning.astro @@ -12,7 +12,7 @@ try {
-

Free BLE scanning

+

Free BLE scanning

Touch the product in under a minute

diff --git a/src/components/Hero.astro b/src/components/Hero.astro index b291994..540fed3 100644 --- a/src/components/Hero.astro +++ b/src/components/Hero.astro @@ -1,6 +1,9 @@ --- import { Image } from 'astro:assets'; -import heroImage from '../../public/images/product/scanner-trakrf-hero.webp'; +let heroImage: ImageMetadata | null = null; +try { + heroImage = (await import('../../public/images/product/scanner-trakrf-hero.webp')).default; +} catch {} ---
-
- A handheld RFID scanner paired with the TrakRF web app -
+ { + heroImage && ( +
+ A handheld RFID scanner paired with the TrakRF web app +
+ ) + }