diff --git a/docs/superpowers/plans/2026-04-25-cameleer-website-relaunch.md b/docs/superpowers/plans/2026-04-25-cameleer-website-relaunch.md new file mode 100644 index 0000000..eab9359 --- /dev/null +++ b/docs/superpowers/plans/2026-04-25-cameleer-website-relaunch.md @@ -0,0 +1,1131 @@ +# Cameleer Website Relaunch — 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:** Rebuild the Cameleer homepage composition + copy on the existing static Astro 5 stack to fix conversion gaps identified in the post-launch design review (single H1, social proof strip, before/after walkthrough, simplified pricing teaser, fewer puns). + +**Architecture:** Pure content + structural change. No new dependencies, no backend, no analytics, no forms. Two new section components replace two retired ones; five existing sections rebuilt-in-place; tier names refreshed across `index.astro` and `/pricing.astro`. One CSS line added (`scroll-behavior: smooth`) for the new in-page anchor CTA. + +**Tech Stack:** Astro 5, Tailwind CSS, vitest (existing), html-validate, linkinator, Lighthouse CI. No new libraries. + +**Spec:** `docs/superpowers/specs/2026-04-25-cameleer-website-relaunch-design.md` + +--- + +## File structure + +**New files:** +- `src/components/sections/SocialProofStrip.astro` — founder quote + design-partner CTA (new section, sits between Hero and walkthrough) +- `src/components/sections/ThreeAmWalkthrough.astro` — before/after split with 3 callouts (replaces DualValueProps + ProductShowcase) + +**Deleted files:** +- `src/components/sections/DualValueProps.astro` +- `src/components/sections/ProductShowcase.astro` + +**Modified files:** +- `src/components/sections/Hero.astro` — kill rotator, single H1, microline, secondary CTA, annotation pin overlay +- `src/components/sections/HowItWorks.astro` — slim copy on steps 1, 3 +- `src/components/sections/WhyUs.astro` — drop `03:00` watermark, reword card 2 +- `src/components/sections/PricingTeaser.astro` — rename tiers, 2 cards on homepage, "See all plans" link +- `src/components/sections/FinalCTA.astro` — H2 + sub + single CTA reword +- `src/pages/index.astro` — section imports/order updated +- `src/pages/pricing.astro` — tier names refreshed +- `src/styles/global.css` — add `html { scroll-behavior: smooth }` plus reduced-motion override + +**Unchanged (do not touch):** +- `src/components/SiteHeader.astro`, `SiteFooter.astro`, `CTAButtons.astro`, `Lightbox.astro`, `TopographicBg.astro`, `RouteDiagram.astro` +- `src/middleware.ts`, `src/middleware.test.ts` +- `src/config/auth.ts` (existing tests cover this — must stay green) +- `astro.config.mjs`, `tailwind.config.mjs`, `package.json` + +--- + +## Working assumptions + +- Branch `relaunch-2026-04-25` is checked out (already created). +- Spec doc is committed at `e338347` (already done). +- `npm ci` has been run; `node_modules/` is present. +- Tailwind tokens used in this plan all exist in `tailwind.config.mjs` — verified: `bg`, `bg-elevated`, `border`, `border-strong`, `accent`, `accent-muted`, `cyan`, `text`, `text-muted`, `text-faint`, `font-sans`, `font-mono`, `text-hero`, `max-w-content`, `max-w-prose`. +- The CTAButtons component API is unchanged — it already accepts `secondaryLabel`, `secondaryHref`, `showSecondary` props. + +--- + +## Task 1: Add `scroll-behavior: smooth` to global.css + +**Files:** +- Modify: `src/styles/global.css` + +**Why first:** Foundational and tiny; the new hero anchor CTA needs it. Keep separate so the diff is reviewable on its own. + +- [ ] **Step 1.1: Read the file** + +Use the Read tool on `src/styles/global.css` (required by edit hooks). + +- [ ] **Step 1.2: Insert the smooth-scroll rule into the `html` block** + +The existing `html` block at line 16-21: + +```css +html { + @apply bg-bg text-text font-sans; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-rendering: optimizeLegibility; + } +``` + +Replace with (adds the one new property): + +```css +html { + @apply bg-bg text-text font-sans; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-rendering: optimizeLegibility; + scroll-behavior: smooth; + } + + @media (prefers-reduced-motion: reduce) { + html { + scroll-behavior: auto; + } + } +``` + +- [ ] **Step 1.3: Verify the build still works** + +Run: `npm run build` +Expected: `✔ Completed in …ms` with no errors and `dist/` populated. + +- [ ] **Step 1.4: Commit** + +```bash +git add src/styles/global.css +git commit -m "feat(styles): enable smooth in-page anchor scrolling + +Adds html { scroll-behavior: smooth } with a prefers-reduced-motion +override. Required for the relaunch hero's 'See it in action' anchor +CTA to feel natural. + +Co-Authored-By: Claude Opus 4.7 (1M context) " +``` + +--- + +## Task 2: Create `SocialProofStrip.astro` + +**Files:** +- Create: `src/components/sections/SocialProofStrip.astro` + +**Spec reference:** §6.2 of the design spec. + +**Why now:** Add the new component before any consumer references it. Astro is happy with unimported components, so the build stays green throughout. + +- [ ] **Step 2.1: Create the file with the full component body** + +Write the full content below to `src/components/sections/SocialProofStrip.astro`: + +```astro +--- +import { getAuthConfig } from '../../config/auth'; + +const auth = getAuthConfig(); + +// PENDING — must be filled in before publish: +// 1. [Founder Name] placeholder below. +// 2. The "ex-nJAMS" mention is gated on Hendrik's trademark review +// (same pattern as WhyUs.astro §10 caveat). If the review is not +// cleared by publish time, drop the " · ex-nJAMS" suffix from the +// attribution line. +const founderName = '[Founder Name]'; +const designPartnerSubject = 'Design partner enquiry — Cameleer'; +const designPartnerHref = `mailto:${auth.salesEmail}?subject=${encodeURIComponent(designPartnerSubject)}`; +--- +
+
+
+

+ // Built by people who've done this before +

+
+

+ “We spent 15 years building integration monitoring for banks that couldn’t afford downtime. Cameleer is what we’d build today — purpose-built for Apache Camel, no retrofit.” +

+
+ — {founderName}, co-founder · ex-nJAMS +
+
+ + Apply to the design-partner program + +
+
+
+``` + +- [ ] **Step 2.2: Verify the build** + +Run: `npm run build` +Expected: build succeeds. The component isn't imported yet, so it produces no output but must still type-check. + +- [ ] **Step 2.3: Commit** + +```bash +git add src/components/sections/SocialProofStrip.astro +git commit -m "feat(sections): add SocialProofStrip component + +Founder pedigree quote plus design-partner mailto CTA. +Uses auth.salesEmail (not auth.salesMailto) so we can pass a subject. + +Two PENDING gates documented in the component: + - [Founder Name] placeholder + - 'ex-nJAMS' wording subject to trademark clearance + +Component is created but not yet wired into index.astro. + +Co-Authored-By: Claude Opus 4.7 (1M context) " +``` + +--- + +## Task 3: Create `ThreeAmWalkthrough.astro` + +**Files:** +- Create: `src/components/sections/ThreeAmWalkthrough.astro` + +**Spec reference:** §6.3 of the design spec. + +- [ ] **Step 3.1: Create the file with the full component body** + +Write the full content below to `src/components/sections/ThreeAmWalkthrough.astro`: + +```astro +--- +import Lightbox from '../Lightbox.astro'; + +interface Callout { + title: string; + body: string; +} + +const callouts: Callout[] = [ + { + title: 'Cross-service correlation.', + body: 'Every exchange carries its correlation ID forward. One click jumps to what the downstream route did with the same message.', + }, + { + title: 'Runtime detail, not guesswork.', + body: 'Circuit breaker tripped. Fallback path ran. Request tried backend:80. The pieces a 3 AM page actually needs — already captured.', + }, + { + title: 'The whole story of a failure.', + body: 'Exception class, message, stack trace, headers, payload — all pinned to the exchange. No log-grepping tour.', + }, +]; +--- +
+
+
+

// When something breaks

+

+ The 3 AM page. With and without Cameleer. +

+

+ Same Camel app. Same failed exchange. Different night. +

+
+ +
+ +
+
+ Without Cameleer · 03:12 AM +
+
$ kubectl logs camel-router-7d4f8c
+ERROR org.apache.camel.CamelExecutionException
+  at org.apache.camel.processor.SendProcessor.process
+  at org.apache.camel.processor.Pipeline.process
+  ...
+
+$ grep "order-842" *.log
+router-3.log: WARN  exchange order-842 stuck in saga-fulfillment
+router-3.log: ERROR processor backend:80 → connect timeout
+
+$ ssh prod-integration-3
+prod-integration-3 $ kubectl logs ...
+
+> slack #integration-team
+  "anyone know why order-842 is stuck??"
+  [3 of 4 reactions, no answer]
+
+~47 min later: someone wakes up an SRE.
+
+ + +
+
+ With Cameleer · 30 sec +
+ +
+ Open exchange order-842 → see the failure pinned → click Replay after fix. +
+
+
+
+ +
    + {callouts.map((c, i) => ( +
  • + +

    {c.title}

    +

    {c.body}

    +
  • + ))} +
+
+
+ + +``` + +- [ ] **Step 3.2: Verify the build** + +Run: `npm run build` +Expected: build succeeds. Linkinator hasn't run yet — anchor target `#walkthrough` will validate when this section is wired into index.astro (Task 10). + +- [ ] **Step 3.3: Commit** + +```bash +git add src/components/sections/ThreeAmWalkthrough.astro +git commit -m "feat(sections): add ThreeAmWalkthrough component + +Replaces DualValueProps + ProductShowcase with a single before/after +split: a styled
 block (the 'without' state) next to the
+existing /product/error-detail.png screenshot (the 'with' state).
+Three short callouts below.
+
+Section anchor #walkthrough is the target for the Hero's
+'See it in action ↓' secondary CTA (added in Task 4).
+
+The 'without' panel is implemented as a styled 
 per the spec —
+no asset production required.  A future phase may swap to a recorded
+terminal screencap; that swap is a one-component change.
+
+Co-Authored-By: Claude Opus 4.7 (1M context) "
+```
+
+---
+
+## Task 4: Rebuild `Hero.astro`
+
+**Files:**
+- Modify: `src/components/sections/Hero.astro`
+
+**Spec reference:** §6.1 of the design spec.
+
+**Changes:**
+1. Remove the rotator (3 spans inside H1, the wrapper styles `.hero-rotator` / `.hero-line`, the `
diff --git a/src/components/sections/HowItWorks.astro b/src/components/sections/HowItWorks.astro
index 6e8c198..7fd8049 100644
--- a/src/components/sections/HowItWorks.astro
+++ b/src/components/sections/HowItWorks.astro
@@ -10,7 +10,7 @@ const steps: Step[] = [
   {
     n: '01',
     title: 'Point us at your Camel app',
-    body: 'Drop it in, or connect one you already run. No code changes. No SDK. Nothing to rewrite.',
+    body: 'Drop it in, or connect one you already run. No code changes.',
   },
   {
     n: '02',
@@ -20,7 +20,7 @@ const steps: Step[] = [
   {
     n: '03',
     title: 'Watch it run',
-    body: 'Browse executions, tap live traffic, replay failed exchanges, follow flows across services. Nothing to instrument. Nothing to maintain.',
+    body: 'Browse executions, tap live traffic, replay failed exchanges, follow flows across services.',
   },
 ];
 ---
@@ -29,7 +29,7 @@ const steps: Step[] = [
     

For engineers

How it works

-

Three steps. No code changes. Nothing to maintain.

+

Three steps. Nothing to maintain.

    {steps.map((step) => ( diff --git a/src/components/sections/PricingTeaser.astro b/src/components/sections/PricingTeaser.astro index d23a65a..2db9f40 100644 --- a/src/components/sections/PricingTeaser.astro +++ b/src/components/sections/PricingTeaser.astro @@ -21,27 +21,13 @@ const tiers: Tier[] = [ cta: 'Start free trial', }, { - name: 'MID', + name: 'Starter', price: '20 € /mo', sub: '2 environments · 10 apps · 7-day retention', href: auth.signUpUrl, - cta: 'Start on MID', + cta: 'Start on Starter', highlight: true, }, - { - name: 'HIGH', - price: 'Contact', - sub: 'Unlimited envs · 50 apps · 90-day retention · Debugger, Replay', - href: auth.salesMailto, - cta: 'Talk to sales', - }, - { - name: 'BUSINESS', - price: 'Contact', - sub: 'Unlimited everything · 365-day retention · all features', - href: auth.salesMailto, - cta: 'Talk to sales', - }, ]; ---
    @@ -51,15 +37,14 @@ const tiers: Tier[] = [

    Start free. Grow when you need to.

    No credit card. No sales call. Just a working trial in ten minutes. - See full comparison →

    -
    +
    {tiers.map((tier) => (
    {tier.highlight && ( @@ -85,5 +70,10 @@ const tiers: Tier[] = [
    ))}
    +

    + + See all plans (Scale, Enterprise) → + +

    diff --git a/src/components/sections/ProductShowcase.astro b/src/components/sections/ProductShowcase.astro deleted file mode 100644 index 863ae1a..0000000 --- a/src/components/sections/ProductShowcase.astro +++ /dev/null @@ -1,91 +0,0 @@ ---- -import TopographicBg from '../TopographicBg.astro'; -import Lightbox from '../Lightbox.astro'; - -interface Callout { - title: string; - body: string; -} - -const callouts: Callout[] = [ - { - title: 'Cross-service correlation.', - body: 'Every exchange carries its correlation ID forward. One click jumps to what the downstream route did with the same message — 610 ms later.', - }, - { - title: 'Runtime detail, not guesswork.', - body: 'Circuit breaker tripped. Fallback path ran. The request tried to reach backend:80. The kind of pieces a 3 AM page actually needs — already captured.', - }, - { - title: 'The whole story of a failure.', - body: 'Exception class, message, stack trace, headers, payload — all pinned to the exchange. No log-grepping tour. No SSH into the pod.', - }, -]; ---- -
    - -
    -
    -

    When it breaks

    -

    - When something breaks, the answer is already waiting. -

    -

    - Follow a single exchange from ingestion to failure. See the route it took, the fallback that ran, the stack trace, the correlated downstream work — in one place. Without writing a line of tracing code. -

    -
    - -
    -
    -
    - -
    -
    - -
    Screenshot of a failed exchange in Cameleer, showing the full execution graph, fallback path, and exception context.
    -
    - -
      - {callouts.map((c, i) => ( -
    • - -

      {c.title}

      -

      {c.body}

      -
    • - ))} -
    -
    -
    -
    - - diff --git a/src/components/sections/SocialProofStrip.astro b/src/components/sections/SocialProofStrip.astro new file mode 100644 index 0000000..4105290 --- /dev/null +++ b/src/components/sections/SocialProofStrip.astro @@ -0,0 +1,38 @@ +--- +import { getAuthConfig } from '../../config/auth'; + +const auth = getAuthConfig(); + +// PENDING — must be filled in before publish: +// 1. [Founder Name] placeholder below. +// 2. The "ex-nJAMS" mention is gated on Hendrik's trademark review +// (same pattern as WhyUs.astro §10 caveat). If the review is not +// cleared by publish time, drop the " · ex-nJAMS" suffix from the +// attribution line. +const founderName = '[Founder Name]'; +const designPartnerSubject = 'Design partner enquiry — Cameleer'; +const designPartnerHref = `mailto:${auth.salesEmail}?subject=${encodeURIComponent(designPartnerSubject)}`; +--- +
    +
    +
    +

    + // Built by people who've done this before +

    +
    +

    + “We spent 15 years building integration monitoring for banks that couldn’t afford downtime. Cameleer is what we’d build today — purpose-built for Apache Camel, no retrofit.” +

    +
    + — {founderName}, co-founder · ex-nJAMS +
    +
    + + Apply to the design-partner program + +
    +
    +
    diff --git a/src/components/sections/ThreeAmWalkthrough.astro b/src/components/sections/ThreeAmWalkthrough.astro new file mode 100644 index 0000000..c05ff23 --- /dev/null +++ b/src/components/sections/ThreeAmWalkthrough.astro @@ -0,0 +1,104 @@ +--- +import Lightbox from '../Lightbox.astro'; + +interface Callout { + title: string; + body: string; +} + +const callouts: Callout[] = [ + { + title: 'Cross-service correlation.', + body: 'Every exchange carries its correlation ID forward. One click jumps to what the downstream route did with the same message.', + }, + { + title: 'Runtime detail, not guesswork.', + body: 'Circuit breaker tripped. Fallback path ran. Request tried backend:80. The pieces a 3 AM page actually needs — already captured.', + }, + { + title: 'The whole story of a failure.', + body: 'Exception class, message, stack trace, headers, payload — all pinned to the exchange. No log-grepping tour.', + }, +]; +--- +
    +
    +
    +

    // When something breaks

    +

    + The 3 AM page. With and without Cameleer. +

    +

    + Same Camel app. Same failed exchange. Different night. +

    +
    + +
    +
    +
    + Without Cameleer · 03:12 AM +
    +
    $ kubectl logs camel-router-7d4f8c
    +ERROR org.apache.camel.CamelExecutionException
    +  at org.apache.camel.processor.SendProcessor.process
    +  at org.apache.camel.processor.Pipeline.process
    +  ...
    +
    +$ grep "order-842" *.log
    +router-3.log: WARN  exchange order-842 stuck in saga-fulfillment
    +router-3.log: ERROR processor backend:80 → connect timeout
    +
    +$ ssh prod-integration-3
    +prod-integration-3 $ kubectl logs ...
    +
    +> slack #integration-team
    +  "anyone know why order-842 is stuck??"
    +  [3 of 4 reactions, no answer]
    +
    +~47 min later: someone wakes up an SRE.
    +
    + +
    +
    + With Cameleer · 30 sec +
    + +
    + Open exchange order-842 → see the failure pinned → click Replay after fix. +
    +
    +
    +
    + +
      + {callouts.map((c, i) => ( +
    • + +

      {c.title}

      +

      {c.body}

      +
    • + ))} +
    +
    +
    + + diff --git a/src/components/sections/WhyUs.astro b/src/components/sections/WhyUs.astro index d4ffc88..a5fc5ff 100644 --- a/src/components/sections/WhyUs.astro +++ b/src/components/sections/WhyUs.astro @@ -20,31 +20,14 @@ So when you ask "why did this exchange fail?", you get an answer, not a log tail. And you can reach back into a running app to replay a message, deep-trace a correlation ID, or toggle recording — observability that does things, not just shows them.

    -
    - -
    -
    - - 03:00:47.218 - · - ops desk -
    -

    Built by people who know what 3 AM looks like.

    -

    - We spent years building integration monitoring for banks, insurers, and logistics operators — the kind of shops where a stuck exchange at 3 AM means someone's phone is ringing. We know what integration teams actually need then, and what they never use. -

    -

    - Cameleer is what we would build today, purpose-built for Apache Camel. No legacy, no retrofit, no assumptions about a generic middleware platform. -

    -
    +
    +

    Built by people who've operated integration in production for 15 years.

    +

    + We spent over a decade building integration monitoring for banks, insurers, and logistics operators — the kind of shops where a stuck exchange is a regulatory event, not just an inconvenience. +

    +

    + Cameleer is what we'd build today, purpose-built for Apache Camel. No legacy, no retrofit, no assumptions about a generic middleware platform. +

    diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro index 3a0de31..998a47a 100644 --- a/src/layouts/BaseLayout.astro +++ b/src/layouts/BaseLayout.astro @@ -31,7 +31,6 @@ const ogUrl = new URL(ogImage, Astro.site ?? 'https://www.cameleer.io').toString - diff --git a/src/pages/index.astro b/src/pages/index.astro index e74a383..dfecb9a 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -3,22 +3,22 @@ import BaseLayout from '../layouts/BaseLayout.astro'; import SiteHeader from '../components/SiteHeader.astro'; import SiteFooter from '../components/SiteFooter.astro'; import Hero from '../components/sections/Hero.astro'; -import DualValueProps from '../components/sections/DualValueProps.astro'; -import ProductShowcase from '../components/sections/ProductShowcase.astro'; +import SocialProofStrip from '../components/sections/SocialProofStrip.astro'; +import ThreeAmWalkthrough from '../components/sections/ThreeAmWalkthrough.astro'; import HowItWorks from '../components/sections/HowItWorks.astro'; import WhyUs from '../components/sections/WhyUs.astro'; import PricingTeaser from '../components/sections/PricingTeaser.astro'; import FinalCTA from '../components/sections/FinalCTA.astro'; ---
    - - + + diff --git a/src/pages/pricing.astro b/src/pages/pricing.astro index 3491dba..fb6cea8 100644 --- a/src/pages/pricing.astro +++ b/src/pages/pricing.astro @@ -33,7 +33,7 @@ const tiers: FullTier[] = [ cta: 'Start free trial', }, { - name: 'MID', + name: 'Starter', price: '20 €', priceNote: 'per month', envs: '2 environments', @@ -41,28 +41,28 @@ const tiers: FullTier[] = [ retention: '7-day retention', features: ['Everything in Trial', 'Data flow lineage', 'Cross-service correlation'], href: auth.signUpUrl, - cta: 'Start on MID', + cta: 'Start on Starter', highlight: true, }, { - name: 'HIGH', + name: 'Scale', price: 'Contact', priceNote: 'sales', envs: 'Unlimited environments', apps: '50 apps', retention: '90-day retention', - features: ['Everything in MID', 'Live debugger', 'Exchange replay', 'Live tap'], + features: ['Everything in Starter', 'Live debugger', 'Exchange replay', 'Live tap'], href: auth.salesMailto, cta: 'Talk to sales', }, { - name: 'BUSINESS', + name: 'Enterprise', price: 'Contact', priceNote: 'sales', envs: 'Unlimited environments', apps: 'Unlimited apps', retention: '365-day retention', - features: ['Everything in HIGH', 'Priority support', 'SLA', 'Dedicated success contact'], + features: ['Everything in Scale', 'Priority support', 'SLA', 'Dedicated success contact'], href: auth.salesMailto, cta: 'Talk to sales', }, @@ -117,7 +117,7 @@ const tiers: FullTier[] = [ ))}

    - Prices in EUR, excluding VAT. Billed monthly. Annual billing available for HIGH and BUSINESS — talk to sales. + Prices in EUR, excluding VAT. Billed monthly. Annual billing available for Scale and Enterprise — talk to sales.

    diff --git a/src/styles/global.css b/src/styles/global.css index 940b3c6..16fe614 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -18,6 +18,13 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; + scroll-behavior: smooth; + } + + @media (prefers-reduced-motion: reduce) { + html { + scroll-behavior: auto; + } } body { @apply min-h-screen;