Verdict: exactly 1 of ~376 routable PDPs conforms to the Figma design — item 1969.
Every other product renders its live kent-automotive.com page re-skinned, so it doesn't match the Figma
layout and each one looks different from the next. That's the inconsistency you're seeing — it's architectural, not a per-page bug.
Why they look different — two render paths
The PDP route (app/shop/pdp.tsx) branches on the item number:
- Item 1969 →
buildSamplePdpHtml() — a hand-built HTML page that reproduces Figma 1321:670 exactly, filled with 1969's real data. Figma-exact
- Every other product (~375) → the real live product page loaded in a WebView and re-skinned via injected CSS (
webview-transcode.ts). Colors/fonts/CTA pills are corrected, but the layout & scale stay the live site's, and each product's live page differs. live re-skin
See it — same 375px width, real data
1 · FIGMA TARGETnode 1321:670
2 · Item 1969 (in app)CONFORMS — Figma page
3 · Item 1969 live re-skinthe "everyone else" path
4 · Item 54455 (Tool)as the app shows it
5 · Item P60170 (Chemical)as the app shows it
Col 2 is the polished Figma look. Cols 3–5 are the live re-skin every other product gets — note the oversized title, grey Item# pill, "Read More" truncation, and how 54455/P60170 differ from each other by their own live content.
Conformance gaps — Figma vs the live re-skin
| Element | Figma 1321:670 / item 1969 | Live re-skin (all other PDPs) | Match |
| Product title | Montserrat Medium 16px | Live H1 ~36px, bold, multi-line | no |
| Item # label | Plain text "Item#: 1969" | Grey rounded pill | no |
| Description | Full copy shown inline | Truncated with "Read More" | no |
| Head rating | Sample drops it (honest, 0 reviews) | Empty orange stars shown | differs |
| Colors / fonts / CTA pills | Navy #445980, Montserrat+Roboto Cond. | Same tokens applied | yes |
| Product cards / carousels | Figma card (244:4261) | Re-skinned to match | yes |
| Section order & spacing | Figma rhythm (gallery→head→desc→buy→share→…) | Live theme's own order/scale | no |
| Buy box / spec table / reviews | Figma-exact styled blocks | Live blocks, present only if the live page has them | varies |
Two ways to make them all conform — a decision for you
MY RECOMMENDATION
Option A — roll the 1969 Figma page out to every product
Generalize buildSamplePdpHtml() to take any product's real data (we already resolve it via resolvePdp() + the bundled scrape + live Shopify feed) and route all products through it. Every PDP then renders the identical Figma 1321:670 layout.
- True pixel-consistency across all PDPs — matches what you've been approving on 1969.
- ⚠️ Supersedes your 2026-07-10 rule "the webview always shows the real live page." This is a rebuilt page, not the live page.
- Sections appear only where we have the data (see edge cases).
Option B — push the live re-skin the rest of the way to Figma
Keep the live-page WebView, extend webview-transcode.ts to also fix title size, Item# pill, "Read More", head stars, and re-order sections to the Figma rhythm.
- Honors the "always the live page" rule; always current with the live site.
- Can only ever be as consistent as each product's live DOM allows — products on different templates will still diverge, and selector gaps leave unskinned patches.
Edge cases — I need your call before building
- Reviews. The Figma page hard-codes the empty state ("Review (0) · Be the first"). Some real products have real reviews (Kent uses SiteVibes). Under Option A that would hide real reviews. → Fetch real review counts per product, or show the empty state everywhere?
- Spec table coverage. We have scraped spec tables for ~250 SKUs, not all ~376 catalog products. Missing ones show no spec section (honest empty state). → Ship with honest gaps and I backfill the missing scrapes, or hold rollout until specs cover 100%?
- Accessories / Frequently-bought / Suggested rails. Present only where scraped; the Figma shows them populated. Some PDPs will lack them. → OK to omit per-product where absent?
- Description fallback. For arbitrary products the description comes from the live Shopify feed; where it's missing we'd fall back to
short_desc — which for some products is a title-dupe (the exact bug you flagged on 1969). → I'll auto-hide any description that equals the title. Confirm?
- Off-catalog SKUs. A few rail/deep-link taps point to items not in the bundled catalog. We have no captured data for those, so they'd keep the live-webview fallback. → Acceptable to leave those on the live path?
Nothing has been built or changed yet — this is the review you asked for. Tell me Option A or B and your calls on the 5 edge cases, and I'll scope + build with a preview link before any Firebase build.