Skip to content

feat(gtm): Spec 2 — positioning & risks (hero + /contact + risk-cleanup sweeps)#381

Merged
blove merged 16 commits into
mainfrom
gtm-spec-2-positioning-and-risks
May 16, 2026
Merged

feat(gtm): Spec 2 — positioning & risks (hero + /contact + risk-cleanup sweeps)#381
blove merged 16 commits into
mainfrom
gtm-spec-2-positioning-and-risks

Conversation

@blove
Copy link
Copy Markdown
Contributor

@blove blove commented May 16, 2026

Summary

Spec 2 ships Phase-1 developer clarity: locked Direction-A hero, new `/contact` enterprise CTA destination, four risk-cleanup copy sweeps, and CTA tracking that makes the two-track funnel measurable.

Hero — H1 "Ship production agent UIs in Angular." with subhead from `docs/gtm/messaging.md`. Primary CTA `Install @ngaf/chat` copies the install command (clipboard) + fires `marketing:cta_click {cta_id: hero_install, track: developer}`. Secondary CTA `Talk to our engineers` routes to `/contact?source=home_hero&track=enterprise` + fires `{cta_id: hero_talk_to_engineers, track: enterprise}`. Six proof pills + italic subline.

`/contact` — Direction A.v2: "Talk to an engineer." H1, SLA card, GitHub stars pill (live build-time ISR fetch — verified live as "★ 2 on GitHub"), alt-channel row (docs · GitHub issues · Discord), form with email (required) + name, company, message (all optional), hidden attribution fields (`source_page`, `track`, `cta_id`, `paper`, `referrer_host`) auto-populated. Submits to the existing `/api/leads` pipeline — Spec 1E's qualification gate stamps `marketing:lead_qualified` when company + non-personal email.

`/pricing` — replaced "All Angular versions" with a real `CompatibilityMatrix` (Supported: 20, 21 / Experimental: — / Planned: 22 / Unsupported: ≤19).

Three full-repo sweeps (per-file review, never `replace_all`):

  • "Angular Agent Framework" → "Agent UI for Angular" (40 files)
  • "A2UI v1" → "A2UI v0.9-compatible" / "A2UI v0.9" in code comments (11 files)
  • "No telemetry" — already canonical from prior Spec 1 work (no changes needed)

Typed `CtaId` union in `apps/website/src/lib/analytics/events.ts` so misspellings get caught at build time.

`/api/leads` validation loosened to email-only; Resend subject + email template handle missing name.

`docs/gtm/messaging.md` Contact page §Fields updated to reflect the expanded field set (deviation from the original locked spec — call-out in the design doc explains why).

Spec & Plan

  • Spec: `docs/superpowers/specs/gtm/2026-05-16-positioning-and-risks-design.md`
  • Plan: `docs/superpowers/plans/gtm/2026-05-16-positioning-and-risks.md`

Chrome MCP smoke (post-implementation)

End-to-end verified locally against `http://localhost:3000\`:

  • ✅ Hero renders locked copy + eyebrow + 6 proof pills + italic subline + right-column collage preserved
  • ✅ Primary CTA click: clipboard receives `npm install @ngaf/chat`
  • ✅ Secondary CTA: `href="/contact?source=home_hero&track=enterprise"`
  • ✅ `/contact` H1 + SLA card + 4 form fields + GitHub pill (live count) + alt-channel row
  • ✅ Form submit POSTed to `/api/leads` with full body including hidden attribution fields; success message displayed
  • ✅ `/pricing` shows the 4-row CompatibilityMatrix; "All Angular versions" copy is gone; "See compatibility matrix below" is in CompareTable
  • ✅ Page titles swept to "Agent UI for Angular"

Test plan

  • `nx run-many -t test -p telemetry,cockpit,posthog-tools` — green
  • `apps/website` vitest unit tests — 18/18 pass (Hero, ContactForm, GitHubStarsPill, getGitHubStars, CompatibilityMatrix, server.spec.ts)
  • `nx run website:build` — green
  • Chrome MCP smoke (this PR description's verification list)
  • Post-merge: confirm hero CTAs fire `marketing:cta_click` in PostHog Live Events with `cta_id=hero_install` (track=developer) and `cta_id=hero_talk_to_engineers` (track=enterprise)

🤖 Generated with Claude Code

blove and others added 16 commits May 16, 2026 14:03
Replaces the homepage hero with the locked Direction-A copy, stands up
the /contact enterprise CTA destination, applies four risk-cleanup copy
changes (telemetry phrasing, compatibility matrix, A2UI v0.9, category
sweep), and wires the two CTA tracks so the developer/enterprise funnel
split becomes measurable in PostHog.

One deviation from messaging.md's locked Contact-page field set:
expands fields from "email + body only" to "email (required) + name,
company, message (optional)" so Spec 1E's captureLeadQualified gate
(which requires company) still works for contact-form submissions.
messaging.md gets updated in the implementation PR.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…r Angular"

Per-file review across page titles, OG metadata, hero eyebrow, email
templates, README files, gtm.md, and llms.txt routes. CHANGELOG.md,
release-notes, and superpowers spec/plan history excluded.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Per-file review. User-facing copy uses "v0.9-compatible"; code
comments and test descriptions referencing the on-the-wire envelope
use plain "A2UI v0.9". Tightens claims until v1 is verified.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Locks the cta_id property to a known union so misspellings or
inconsistent slicing in PostHog get caught at build time. Initial
members include hero_install (developer track), hero_talk_to_engineers
(enterprise track) plus all pre-existing literals found in callsites
(home_whitepaper_*, toast_*, copy_code, copy_prompt, nav_*, mobile_nav_*,
footer_*). Template-literal members cover nav/footer/copy callsites that
derive cta_id from a label at runtime; Nav.tsx narrows ctaId to one of
the surface-prefixed template forms so the typecheck passes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- H1: "Ship production agent UIs in Angular."
- Subhead per docs/gtm/messaging.md
- Primary CTA: copies "npm install @ngaf/chat", fires cta_id=hero_install
  (track=developer)
- Secondary CTA: links to /contact?source=home_hero&track=enterprise,
  fires cta_id=hero_talk_to_engineers (track=enterprise)
- Eyebrow updated to "Agent UI for Angular · MIT"
- Proof pills + subline match the locked copy

Three tests cover both CTAs (event payload + clipboard write + link href).
UI primitives are mocked in the spec because the website's vitest setup
doesn't auto-inject the JSX runtime into transitive imports.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Server-only helper that fetches repo stargazer count via Next.js fetch
with 24h revalidate. Returns null on any failure (non-2xx, network
error, missing field) so callers can render a graceful fallback.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…count

Renders "★ <n> on GitHub" when the fetch succeeds; falls back to a
plain "GitHub" pill on null. Links to the repo regardless. ISR via
the getGitHubStars helper means at most one fetch per 24h.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ional

POSTs to /api/leads with hidden attribution fields (source_page, track,
cta_id, paper, referrer_host) populated from URL params + document
.referrer. Fires marketing:lead_form_submit / _success / _fail with
surface=contact. Inline success state; no redirect.

Adds 'contact' to the AnalyticsSurface union so the new tracking calls
type-check.

Three unit tests cover email-only submit, full-fields submit, failure path.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Renders the "replies personally from a real inbox" promise and the
docs / GitHub issues / Discord row below the contact form, per the
locked Direction A.v2 spec.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Server-rendered page composing ContactForm, SlaCard, GitHubStarsPill,
and AltChannelRow. Headline + subhead from docs/gtm/messaging.md.
ContactForm wrapped in Suspense for useSearchParams compatibility.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replaces the "All Angular versions" risk claim with a real
supported/experimental/planned/unsupported matrix. Initial content
matches the peer-deps reality: Angular 20, 21 supported; 22 planned;
≤19 unsupported.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replaces the "All Angular versions" claim with a real matrix. New
"Compatibility" section sits between CompareTable and LeadForm.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Spec 2's /contact form collects email (required) + name, company,
message (all optional). Pricing's LeadForm continues to send name.
Resend notification subject falls back to email when name is missing.
The lead-notification email template no longer requires name.

Spec 1E's qualified-lead gate is unchanged — still requires non-personal
email + non-empty company. Contact-form leads without a company fire
marketing:lead_form_success but not marketing:lead_qualified, by design.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Direction A.v2 originally locked "email + free-text body." During Spec 2
implementation we expanded to email (required) + name, company, message
(all optional) so Spec 1E's captureLeadQualified gate (which requires
company) still works for contact-form submissions.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Surfaced when dev server boot triggered the @nx/js:typescript-sync
generator. Mostly project-reference additions for cockpit Angular
examples that consume @ngaf/cockpit-telemetry (Spec 1C) and stable
formatting/paths normalization. No behavioral changes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 16, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cacheplane Ready Ready Preview, Comment May 16, 2026 11:27pm

Request Review

@blove blove merged commit 8c636e2 into main May 16, 2026
13 of 14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant