# Cameleer website copy + brand refresh — 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:** Reposition the homepage from "observability tool" to "hosted Camel runtime with observability baked in." Refresh copy (3 rotating Hero headlines, two humor pops, plain-language tone), and replace the placeholder topographic-wave icon with the real camel product logo.

**Architecture:** Pure content + static asset refresh on an Astro 5 site. No new components, no new pages, no new deps. One small piece of client-side JS lives in the Hero (three-line rotation with reduced-motion guard and pause-on-interaction) — delivered via Astro's `<script>` block so it gets bundled and served same-origin (CSP is strict: `script-src 'self'` with no `'unsafe-inline'`; inline `<script>` tags would be blocked).

**Tech Stack:** Astro 5, Tailwind CSS (design tokens already defined), TypeScript, Vitest for logic tests, html-validate + linkinator for build-output checks, Playwright MCP available for browser verification.

**Reference spec:** `docs/superpowers/specs/2026-04-24-cameleer-website-copy-refresh-design.md`

---

## Ground rules

- **Dev server:** `npm run dev` → http://localhost:4321. Leave it running across tasks where possible.
- **Build check:** `npm run build` after any component edit. Treat warnings as errors in component files.
- **No placeholders:** every copy string in this plan is the final copy. Do not paraphrase.
- **Verify visually:** most tasks end with a Playwright navigate-and-screenshot check. The `playwright` MCP tools are available (`mcp__playwright__browser_navigate`, `mcp__playwright__browser_take_screenshot`).
- **Commit scope:** each task ends in a single focused commit. Do not batch.
- **CSP:** use Astro `<script>` blocks (default bundled mode). Never use `is:inline` on a `<script>`. Never use inline `onclick`/`onhover` handlers.

---

## Task 1: Import the real Cameleer product logo + icon set

**Files:**
- Create: `public/cameleer-logo.svg`
- Create: `public/cameleer-logo.png`
- Create: `public/icons/cameleer-16.png`
- Create: `public/icons/cameleer-32.png`
- Create: `public/icons/cameleer-48.png`
- Create: `public/icons/cameleer-180.png`
- Create: `public/icons/cameleer-192.png`
- Create: `public/icons/cameleer-512.png`

Assets come from the sibling `design-system` repo: `C:/Users/Hendrik/Documents/projects/design-system/assets/`.

- [ ] **Step 1: Create the `public/icons/` directory**

```bash
mkdir -p C:/Users/Hendrik/Documents/projects/cameleer-website/public/icons
```

- [ ] **Step 2: Copy the SVG and PNG logo variants**

```bash
cd C:/Users/Hendrik/Documents/projects/cameleer-website
cp ../design-system/assets/cameleer-logo.svg public/cameleer-logo.svg
cp ../design-system/assets/cameleer-logo.png public/cameleer-logo.png
cp ../design-system/assets/cameleer-16.png public/icons/cameleer-16.png
cp ../design-system/assets/cameleer-32.png public/icons/cameleer-32.png
cp ../design-system/assets/cameleer-48.png public/icons/cameleer-48.png
cp ../design-system/assets/cameleer-180.png public/icons/cameleer-180.png
cp ../design-system/assets/cameleer-192.png public/icons/cameleer-192.png
cp ../design-system/assets/cameleer-512.png public/icons/cameleer-512.png
```

- [ ] **Step 3: Verify files landed**

```bash
cd C:/Users/Hendrik/Documents/projects/cameleer-website
ls -la public/cameleer-logo.svg public/cameleer-logo.png public/icons/
```

Expected: 8 files listed, non-zero sizes. `cameleer-logo.svg` is ~1.5 MB (ship as-is per spec §3.1).

- [ ] **Step 4: Commit**

```bash
cd C:/Users/Hendrik/Documents/projects/cameleer-website
git add public/cameleer-logo.svg public/cameleer-logo.png public/icons/
git commit -m "feat(brand): import real cameleer product logo + favicon set

Camel + cameleer figure on compass rose, amber on transparent. Imported
from design-system/assets. Replaces the placeholder topographic-wave icon
across favicon chain, header, and OG assets (subsequent tasks)."
```

---

## Task 2: Update BaseLayout favicon chain + delete placeholder

**Files:**
- Modify: `src/layouts/BaseLayout.astro` — swap the single-favicon line for a proper chain
- Delete: `public/favicon.svg` (placeholder 3-wavy-lines SVG)

- [ ] **Step 1: Replace the favicon `<link>` in BaseLayout**

In `src/layouts/BaseLayout.astro`, find this line:

```html
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
```

Replace with:

```html
    <link rel="icon" type="image/svg+xml" href="/cameleer-logo.svg" />
    <link rel="icon" type="image/png" sizes="32x32" href="/icons/cameleer-32.png" />
    <link rel="apple-touch-icon" href="/icons/cameleer-180.png" />
```

- [ ] **Step 2: Delete the placeholder favicon**

```bash
cd C:/Users/Hendrik/Documents/projects/cameleer-website
rm public/favicon.svg
```

- [ ] **Step 3: Build to confirm nothing references the deleted file**

```bash
npm run build
```

Expected: build succeeds, no 404s on `/favicon.svg` in the output.

- [ ] **Step 4: Verify the favicon loads in the dev server**

Start the dev server in the background if it isn't running:

```bash
npm run dev
```

Use Playwright MCP to verify:

```
mcp__playwright__browser_navigate → http://localhost:4321
mcp__playwright__browser_evaluate → document.querySelector('link[rel="icon"][type="image/svg+xml"]').href
```

Expected: ends in `/cameleer-logo.svg` — and a GET for that URL returns 200 (check the Network tab with `mcp__playwright__browser_network_requests`).

- [ ] **Step 5: Commit**

```bash
git add src/layouts/BaseLayout.astro public/favicon.svg
git commit -m "feat(brand): wire favicon chain to real product logo

SVG primary + 32px PNG fallback + Apple touch icon. Removes the
placeholder 3-wavy-lines favicon."
```

---

## Task 3: Replace the inline SVG in SiteHeader with the real logo

**Files:**
- Modify: `src/components/SiteHeader.astro`

- [ ] **Step 1: Replace the inline `<svg>` block with an `<img>` referencing the real logo**

In `src/components/SiteHeader.astro`, find this block (lines ~7–14):

```astro
      <svg width="28" height="28" viewBox="0 0 32 32" aria-hidden="true">
        <rect width="32" height="32" rx="6" fill="#0c111a"/>
        <g fill="none" stroke="#f0b429" stroke-width="1.6" stroke-linecap="round">
          <path d="M4 10 Q10 6 16 12 T28 10"/>
          <path d="M4 16 Q10 12 16 18 T28 16"/>
          <path d="M4 22 Q10 18 16 24 T28 22"/>
        </g>
      </svg>
```

Replace with:

```astro
      <img
        src="/cameleer-logo.svg"
        width="32"
        height="32"
        alt=""
        decoding="async"
        class="shrink-0"
      />
```

Rationale: `alt=""` is correct — the adjacent `<span>Cameleer</span>` wordmark provides the accessible label, and the `<a aria-label="Cameleer home">` wraps both. An `alt` on the image would cause a duplicate announcement.

- [ ] **Step 2: Verify in the dev server**

With `npm run dev` running:

```
mcp__playwright__browser_navigate → http://localhost:4321
mcp__playwright__browser_take_screenshot → filename: hero-header.png
```

Expected: the header shows the amber camel-on-compass logo (32px) next to the "Cameleer" wordmark. No broken image icon.

- [ ] **Step 3: Commit**

```bash
git add src/components/SiteHeader.astro
git commit -m "feat(brand): swap header icon for real Cameleer logo

Placeholder 3-wavy-lines SVG replaced with the product logo
(camel + cameleer figure + compass rose)."
```

---

## Task 4: Update homepage title + meta description

**Files:**
- Modify: `src/pages/index.astro` — the `<title>` and `description` props drive every `<meta>` in the head

- [ ] **Step 1: Replace the title and description props**

In `src/pages/index.astro`, find:

```astro
<BaseLayout
  title="Cameleer — Zero-code observability for Apache Camel"
  description="See every route. Reach into every flow. Zero-code tracing, processor-level detail, and live control for Apache Camel — from a single -javaagent flag."
>
```

Replace with:

```astro
<BaseLayout
  title="Cameleer — Run Apache Camel without running Apache Camel"
  description="The hosted home for your Camel integrations — with deep tracing, replay, and live control built in. Because you chose Camel to stay free, not to stay up all night."
>
```

- [ ] **Step 2: Build and verify the rendered HTML**

```bash
npm run build
```

```bash
grep -o '<title>[^<]*</title>\|<meta name="description"[^>]*>' dist/index.html
```

Expected:
```
<title>Cameleer — Run Apache Camel without running Apache Camel</title>
<meta name="description" content="The hosted home for your Camel integrations — with deep tracing, replay, and live control built in. Because you chose Camel to stay free, not to stay up all night.">
```

- [ ] **Step 3: Commit**

```bash
git add src/pages/index.astro
git commit -m "feat(copy): update homepage title + meta description

Thesis: 'Run Apache Camel without running Apache Camel.' Reframes the
page from observability tool to hosted runtime platform for Camel."
```

---

## Task 5: Hero — static content rewrite (no rotation yet)

**Files:**
- Modify: `src/components/sections/Hero.astro`

This task rewrites the Hero markup to the new static content. Rotation is added in Task 6. Keeping the two changes separate makes each commit reviewable and keeps a bisection target if rotation regresses something.

- [ ] **Step 1: Rewrite the Hero component**

Replace the entire contents of `src/components/sections/Hero.astro` with:

```astro
---
import CTAButtons from '../CTAButtons.astro';
import RouteDiagram from '../RouteDiagram.astro';
import TopographicBg from '../TopographicBg.astro';
---
<section class="relative overflow-hidden border-b border-border">
  <TopographicBg opacity={0.14} lines={10} />
  <div class="relative max-w-content mx-auto px-6 pt-20 pb-24 md:pt-28 md:pb-32">
    <div class="max-w-3xl">
      <div class="flex items-center gap-3 mb-6">
        <img
          src="/cameleer-logo.svg"
          width="48"
          height="48"
          alt=""
          decoding="async"
          class="shrink-0"
        />
        <p class="text-accent font-mono text-xs tracking-[0.25em] uppercase">
          Your camels called. They want a GPS.
        </p>
      </div>
      <h1 class="text-display font-bold text-text mb-6">
        Run Apache Camel without running Apache Camel.
      </h1>
      <p class="text-lg md:text-xl text-text-muted max-w-prose leading-relaxed mb-10">
        The hosted home for your Camel integrations — with deep tracing, replay, and live control built in. Because you chose Camel to stay free, not to stay up all night.
      </p>
      <CTAButtons size="lg" />
    </div>
    <div class="mt-16 md:mt-20">
      <RouteDiagram />
    </div>
  </div>
</section>
```

Changes vs current:
- Added 48px brand mark next to the kicker (per spec §3.4).
- Kicker text: `Observability · Apache Camel` → `Your camels called. They want a GPS.`
- H1: `See every route. / Reach into every flow.` → `Run Apache Camel without running Apache Camel.`
- Subline rewritten — no more `-javaagent` reference.

- [ ] **Step 2: Build to confirm it compiles**

```bash
npm run build
```

Expected: success, no warnings about missing props or broken imports.

- [ ] **Step 3: Visual check in dev server**

With `npm run dev` running:

```
mcp__playwright__browser_navigate → http://localhost:4321
mcp__playwright__browser_take_screenshot → filename: hero-task5.png
```

Expected: amber camel mark (48px) next to the uppercase "YOUR CAMELS CALLED. THEY WANT A GPS." kicker. Headline reads "Run Apache Camel without running Apache Camel." Subline is the new plain-language version.

- [ ] **Step 4: Commit**

```bash
git add src/components/sections/Hero.astro
git commit -m "feat(copy): Hero static rewrite — new kicker, thesis H1, subline

Drops -javaagent from the hero. Adds the 48px product mark next to the
kicker. Rotation is added in the next commit."
```

---

## Task 6: Hero — three rotating H1 lines with fade, pause, and reduced-motion guard

**Files:**
- Modify: `src/components/sections/Hero.astro` — add two extra `<span>`s inside the H1, add `<style>` and `<script>` blocks

This task adds the rotation. All three lines render in the DOM. The visible one is controlled via a `data-active` attribute; CSS drives the fade. The script cycles `data-active` every 10 seconds, pauses on hover/focus, and does nothing if `prefers-reduced-motion: reduce`.

`aria-live="off"` on the rotation wrapper prevents assistive tech from announcing every swap. `aria-hidden="true"` on the two inactive lines avoids duplicate heading announcements.

- [ ] **Step 1: Replace the H1 + add style + script blocks**

In `src/components/sections/Hero.astro`, replace the current H1:

```astro
      <h1 class="text-display font-bold text-text mb-6">
        Run Apache Camel without running Apache Camel.
      </h1>
```

With:

```astro
      <h1
        class="text-display font-bold text-text mb-6 hero-rotator"
        aria-live="off"
        data-hero-rotator
      >
        <span class="hero-line" data-active aria-hidden="false">Run Apache Camel without running Apache Camel.</span>
        <span class="hero-line" aria-hidden="true">Camel integrations, minus the baggage.</span>
        <span class="hero-line" aria-hidden="true">Your camels, our caravan. You just ride.</span>
      </h1>
```

Then at the bottom of the file (after the closing `</section>`), add:

```astro
<style>
  .hero-rotator {
    position: relative;
    display: block;
    /* Reserve height for the tallest line so no layout shift on swap.
       Two lines at current H1 size handles all three on most viewports. */
    min-height: 2.2em;
  }
  .hero-line {
    display: block;
    opacity: 0;
    transition: opacity 700ms ease-in-out;
    /* Stack all lines on top of each other — only [data-active] is visible. */
    position: absolute;
    inset: 0;
  }
  .hero-line[data-active] {
    opacity: 1;
    position: relative;
  }
  @media (prefers-reduced-motion: reduce) {
    .hero-line {
      transition: none;
    }
  }
</style>

<script>
  // Hero rotating headline. Bundled by Astro (CSP: script-src 'self').
  const rotator = document.querySelector<HTMLElement>('[data-hero-rotator]');
  if (rotator) {
    const lines = Array.from(rotator.querySelectorAll<HTMLElement>('.hero-line'));
    const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    if (!reduced && lines.length > 1) {
      let index = 0;
      let paused = false;
      const pause = () => { paused = true; };
      const resume = () => { paused = false; };
      rotator.addEventListener('mouseenter', pause);
      rotator.addEventListener('mouseleave', resume);
      rotator.addEventListener('focusin', pause);
      rotator.addEventListener('focusout', resume);
      setInterval(() => {
        if (paused) return;
        lines[index].removeAttribute('data-active');
        lines[index].setAttribute('aria-hidden', 'true');
        index = (index + 1) % lines.length;
        lines[index].setAttribute('data-active', '');
        lines[index].setAttribute('aria-hidden', 'false');
      }, 10000);
    }
  }
</script>
```

- [ ] **Step 2: Build to confirm the script is bundled (not inlined)**

```bash
npm run build
```

Then:

```bash
grep -c 'hero-rotator' dist/index.html
ls dist/_astro/*.js 2>&1 | head
```

Expected: the HTML contains the `data-hero-rotator` attribute. A hoisted JS file appears under `dist/_astro/`. The HTML should NOT contain an inline `<script>` block with the rotator code (Astro hoists `<script>` tags by default).

- [ ] **Step 3: Verify CSP compliance in the browser**

With `npm run dev` running:

```
mcp__playwright__browser_navigate → http://localhost:4321
mcp__playwright__browser_console_messages
```

Expected: no `Content-Security-Policy` violation messages. (Note: CSP headers only apply to `preview`/prod; dev server doesn't enforce them — but the inline-vs-bundled distinction is a build-time property, so if Step 2 confirmed the script was hoisted, CSP will pass in prod.)

- [ ] **Step 4: Verify the rotation behavior visually**

```
mcp__playwright__browser_navigate → http://localhost:4321
mcp__playwright__browser_evaluate →
  Array.from(document.querySelectorAll('.hero-line')).map(l => ({
    text: l.textContent?.trim(),
    active: l.hasAttribute('data-active'),
    ariaHidden: l.getAttribute('aria-hidden'),
  }))
```

Expected at page load:
```js
[
  { text: 'Run Apache Camel without running Apache Camel.', active: true, ariaHidden: 'false' },
  { text: 'Camel integrations, minus the baggage.', active: false, ariaHidden: 'true' },
  { text: 'Your camels, our caravan. You just ride.', active: false, ariaHidden: 'true' },
]
```

Wait 11 seconds and re-run the evaluate. Expected: second entry now has `active: true, ariaHidden: 'false'`; first and third are inactive.

- [ ] **Step 5: Verify reduced-motion guard at the code level**

The Playwright MCP in this environment does not expose a media-query emulation tool, so the runtime check is split into two parts:

(a) **Code inspection** — re-read the `<script>` block and confirm:
- `const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;`
- The `setInterval` is inside `if (!reduced && lines.length > 1) { ... }` — so when `reduced` is true, the interval is never registered.
- The CSS `@media (prefers-reduced-motion: reduce) .hero-line { transition: none; }` — so even if a swap fired, it would be instant. Belt and suspenders.

(b) **Optional manual verification** — if you want a live check, toggle reduced-motion at the OS level:
  - Windows: Settings → Accessibility → Visual effects → Animation effects: Off
  - Then reload the page and wait ~15 seconds. First line should remain active.

If (a) matches the code you just wrote, (b) is optional — the guard is structurally correct and the CSS fallback makes it defensive.

- [ ] **Step 6: Commit**

```bash
git add src/components/sections/Hero.astro
git commit -m "feat(hero): rotate three positioning lines on a 10s cycle

All three lines render in the DOM; CSS drives the fade via data-active.
Reduced-motion users see the first line only (no interval, no fade).
Rotation pauses on hover and keyboard focus. aria-live=off on the
rotator so AT does not announce every swap; aria-hidden flips per-swap
to avoid duplicate heading announcements."
```

---

## Task 7: DualValueProps — three outcome-led tiles

**Files:**
- Modify: `src/components/sections/DualValueProps.astro`

Rewrite the three tile headlines and bodies. Outcome-led, no `-javaagent`, no "nanosecond", no "45+ EIP". Keep the existing card styling.

- [ ] **Step 1: Rewrite the `tiles` array**

In `src/components/sections/DualValueProps.astro`, replace the current `tiles` definition:

```ts
const tiles: Tile[] = [
  {
    outcome: 'Cut debugging time in half.',
    capability:
      'Every processor on every route, timed to the nanosecond. Choice branches, splits, multicasts, and error handlers preserved as a proper execution tree — not a pile of log lines.',
  },
  {
    outcome: 'Ship integrations with confidence.',
    capability:
      'Capture real payloads and replay them on demand. Deep-trace a specific correlation ID across services. Push trace settings to a running agent without a redeploy.',
  },
  {
    outcome: 'Keep what you have built.',
    capability:
      'One `-javaagent` flag. No code changes, no SDK, no framework lock-in. Native understanding of 45+ EIP node types across Apache Camel 4.x.',
  },
];
```

With:

```ts
const tiles: Tile[] = [
  {
    outcome: 'Ship integrations, then sleep.',
    capability:
      'Every route, every processor, every exchange — traced automatically. When something breaks at 3 AM, the answer is already waiting for you. So you do not have to be.',
  },
  {
    outcome: 'Debug in daylight.',
    capability:
      'Replay the exact exchange that failed. Follow a single request across services. See payloads before and after each processor. The pieces your ops team needs at 3 AM, captured already — so 3 AM stays quiet.',
  },
  {
    outcome: 'Keep what you built. Keep what you chose.',
    capability:
      'You picked Apache Camel on purpose — open, portable, yours. Cameleer runs and understands your Camel apps as they are. No code changes, no SDK, no rewrite, no lock-in.',
  },
];
```

Note: the template still renders `tile.capability` through a backtick-to-`<code>` replace. None of the new bodies use backticks, so the replace is a no-op. Keep the template untouched.

- [ ] **Step 2: Build**

```bash
npm run build
```

Expected: success.

- [ ] **Step 3: Visual check**

```
mcp__playwright__browser_navigate → http://localhost:4321
mcp__playwright__browser_take_screenshot → filename: dualvalue.png
```

Expected: three tiles with the new outcome-led headlines and softened bodies. No backtick-code fragments visible. No mentions of "nanosecond", "-javaagent", "45+", or "EIP".

- [ ] **Step 4: Grep-confirm the removals**

```bash
grep -E 'nanosecond|javaagent|45\+|EIP node' dist/index.html || echo "CLEAN"
```

Expected: `CLEAN`.

- [ ] **Step 5: Commit**

```bash
git add src/components/sections/DualValueProps.astro
git commit -m "feat(copy): DualValueProps — outcome-led, plain language

Three tiles: ship-then-sleep, debug-in-daylight, keep-what-you-chose.
Drops -javaagent, nanosecond, and 45+ EIP node types from the landing
copy — those belong in docs."
```

---

## Task 8: HowItWorks — three softer steps, drop the bash snippet

**Files:**
- Modify: `src/components/sections/HowItWorks.astro`

- [ ] **Step 1: Rewrite the `steps` array and the section subtitle**

In `src/components/sections/HowItWorks.astro`, replace the `steps` constant and the subtitle paragraph.

The `steps` constant:

```ts
const steps: Step[] = [
  {
    n: '01',
    title: 'Add the agent',
    body: 'Drop the Cameleer agent JAR alongside your Camel app and start it with a single flag. That is the entire installation.',
    code: 'java \\\n  -javaagent:cameleer-agent.jar \\\n  -jar your-camel-app.jar',
  },
  {
    n: '02',
    title: 'Launch your app',
    body: 'Every route, processor, exchange, and route graph is discovered and reported automatically. Configurable redaction keeps sensitive fields out of the trace.',
  },
  {
    n: '03',
    title: 'See it in Mission Control',
    body: 'Browse executions, tap live traffic, replay failed exchanges, and follow flows across services. Nothing to instrument, nothing to maintain.',
  },
];
```

Becomes:

```ts
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.',
  },
  {
    n: '02',
    title: 'We take it from there',
    body: 'Every route, every processor, every exchange — discovered and traced automatically. Sensitive fields are masked by default.',
  },
  {
    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.',
  },
];
```

The subtitle:

```astro
      <p class="text-text-muted text-lg">Three steps. No code changes. Works across Camel 4.x.</p>
```

Becomes:

```astro
      <p class="text-text-muted text-lg">Three steps. No code changes. Nothing to maintain.</p>
```

The `code?` field on Step 1 is gone; the `{step.code && (...)}` conditional in the template renders nothing for steps without code. No template change needed.

- [ ] **Step 2: Build**

```bash
npm run build
```

- [ ] **Step 3: Confirm the bash snippet is gone**

```bash
grep -E 'javaagent|cameleer-agent\.jar' dist/index.html || echo "CLEAN"
```

Expected: `CLEAN`.

- [ ] **Step 4: Visual check**

```
mcp__playwright__browser_navigate → http://localhost:4321
mcp__playwright__browser_take_screenshot → filename: howitworks.png
```

Expected: three numbered cards with the new titles and bodies. No `<pre>` block in any card.

- [ ] **Step 5: Commit**

```bash
git add src/components/sections/HowItWorks.astro
git commit -m "feat(copy): HowItWorks — plain-language steps, bash snippet gone

Step 1 no longer shows java -javaagent:... on the marketing page; that
detail belongs in docs/install. Subtitle tightened to 'Nothing to
maintain.'"
```

---

## Task 9: WhyUs — softer, warmer bodies with 3-AM framing

**Files:**
- Modify: `src/components/sections/WhyUs.astro`

- [ ] **Step 1: Replace both tile bodies and the second tile's headline**

Find the first tile (lines ~14–22):

```astro
      <div class="rounded-lg border border-border bg-bg-elevated p-8">
        <h3 class="text-xl font-bold text-text mb-4">Generic APMs do not understand Camel. Cameleer does.</h3>
        <p class="text-text-muted leading-relaxed mb-4">
          Our Java agent speaks 45+ Apache Camel EIP node types natively — choices, splits, multicasts, doTry, error handlers, dynamic endpoints, thread boundaries in async routes. It extracts your route topology as a first-class graph, not a pile of metrics.
        </p>
        <p class="text-text-muted leading-relaxed">
          A bidirectional protocol lets the server push deep-trace requests, per-route recording toggles, and signed config changes back to running agents — turning passive observability into active control. Not something you build in a weekend.
        </p>
      </div>
```

Replace with:

```astro
      <div class="rounded-lg border border-border bg-bg-elevated p-8">
        <h3 class="text-xl font-bold text-text mb-4">Generic APMs do not understand Camel. Cameleer does.</h3>
        <p class="text-text-muted leading-relaxed mb-4">
          Most monitoring tools see your app as a Java process and a pile of HTTP calls. Cameleer understands that you are running a Camel app — choices, splits, multicasts, error handlers, and every other EIP pattern as first-class citizens.
        </p>
        <p class="text-text-muted leading-relaxed">
          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.
        </p>
      </div>
```

Find the second tile (lines ~23–31):

```astro
      <div class="rounded-lg border border-border bg-bg-elevated p-8">
        <h3 class="text-xl font-bold text-text mb-4">Built by people who have shipped this class of product before.</h3>
        <p class="text-text-muted leading-relaxed mb-4">
          The Cameleer team spent years building and supporting integration monitoring for banks, insurers, and logistics operators. We know what integration teams actually need at 3 AM — and what they never use.
        </p>
        <p class="text-text-muted leading-relaxed">
          Cameleer is what we would build today, purpose-built for Apache Camel — no legacy, no retrofit, no assumptions about a generic middleware platform.
        </p>
      </div>
```

Replace with:

```astro
      <div class="rounded-lg border border-border bg-bg-elevated p-8">
        <h3 class="text-xl font-bold text-text mb-4">Built by people who know what 3 AM looks like.</h3>
        <p class="text-text-muted leading-relaxed mb-4">
          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.
        </p>
        <p class="text-text-muted leading-relaxed">
          Cameleer is what we would build today, purpose-built for Apache Camel. No legacy, no retrofit, no assumptions about a generic middleware platform.
        </p>
      </div>
```

Keep the existing comment block at the top of the file (trademark review note).

- [ ] **Step 2: Build**

```bash
npm run build
```

- [ ] **Step 3: Confirm the removals**

```bash
grep -E '45\+|bidirectional protocol|signed config changes|deep-trace requests' dist/index.html || echo "CLEAN"
```

Expected: `CLEAN`.

- [ ] **Step 4: Commit**

```bash
git add src/components/sections/WhyUs.astro
git commit -m "feat(copy): WhyUs — warmer language, 3-AM framing

Tile 2 headline now 'Built by people who know what 3 AM looks like.'
Bodies soften 'bidirectional protocol / signed config' into plain-value
language. nJAMS-legacy trademark review note preserved."
```

---

## Task 10: PricingTeaser — subline tweak

**Files:**
- Modify: `src/components/sections/PricingTeaser.astro`

- [ ] **Step 1: Replace the subline paragraph**

Find (lines ~52–55):

```astro
      <p class="text-text-muted text-lg">
        No credit card for the trial.
        <a href="/pricing" class="text-accent hover:underline">See full comparison →</a>
      </p>
```

Replace with:

```astro
      <p class="text-text-muted text-lg">
        No credit card. No sales call. Just a working trial in ten minutes.
        <a href="/pricing" class="text-accent hover:underline">See full comparison →</a>
      </p>
```

Tier cards and prices unchanged.

- [ ] **Step 2: Build**

```bash
npm run build
```

- [ ] **Step 3: Commit**

```bash
git add src/components/sections/PricingTeaser.astro
git commit -m "feat(copy): PricingTeaser — 'no credit card, no sales call'

Subline slightly warmer and more concrete ('a working trial in ten
minutes'). Tier cards untouched."
```

---

## Task 11: FinalCTA — second humor pop

**Files:**
- Modify: `src/components/sections/FinalCTA.astro`

- [ ] **Step 1: Replace the headline and subline**

Find:

```astro
    <h2 class="text-display font-bold text-text mb-6">
      Start seeing your routes.
    </h2>
    <p class="text-lg md:text-xl text-text-muted max-w-prose mx-auto mb-10">
      14-day free trial. Your first app, instrumented and live in under 10 minutes.
    </p>
```

Replace with:

```astro
    <h2 class="text-display font-bold text-text mb-6">
      Your camels called. Time to ride.
    </h2>
    <p class="text-lg md:text-xl text-text-muted max-w-prose mx-auto mb-10">
      14-day free trial. Your first Camel app, hosted, traced, and running in under ten minutes. No code changes. No camels harmed.
    </p>
```

CTAButtons block unchanged.

- [ ] **Step 2: Build**

```bash
npm run build
```

- [ ] **Step 3: Visual check**

```
mcp__playwright__browser_navigate → http://localhost:4321
mcp__playwright__browser_take_screenshot → filename: finalcta.png
```

Expected: large centered "Your camels called. Time to ride." over the topographic background, subline ends with "No camels harmed.", CTA buttons still work.

- [ ] **Step 4: Commit**

```bash
git add src/components/sections/FinalCTA.astro
git commit -m "feat(copy): FinalCTA — 'Your camels called. Time to ride.'

Second humor pop (pairing with the Hero kicker). Subline adds the
tasteful-absurd 'No camels harmed.' closer."
```

---

## Task 12: Redesign OG image around the new thesis

**Files:**
- Modify: `public/og-image.svg` — full rewrite

Target: 1200×630, solid dark background (`#060a13`), amber accents (`#f0b429`), centered layout with the real logo + the thesis headline + a short subhead.

- [ ] **Step 1: Read the current OG image to understand conventions**

```bash
cat C:/Users/Hendrik/Documents/projects/cameleer-website/public/og-image.svg
```

Note the existing dimensions, font references, and colors, so the replacement keeps the same structural shape.

- [ ] **Step 2: Replace the file with the new design**

Write the following to `public/og-image.svg`:

```xml
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 630" width="1200" height="630">
  <rect width="1200" height="630" fill="#060a13"/>
  <!-- Subtle topographic lines -->
  <g fill="none" stroke="#f0b429" stroke-width="1.2" stroke-linecap="round" opacity="0.10">
    <path d="M0 140 Q200 80 400 160 T800 140 T1200 160"/>
    <path d="M0 250 Q200 190 400 270 T800 250 T1200 270"/>
    <path d="M0 360 Q200 300 400 380 T800 360 T1200 380"/>
    <path d="M0 470 Q200 410 400 490 T800 470 T1200 490"/>
  </g>
  <!-- Product mark (fallback: amber circle w/ wordmark — real PNG logo embedded would exceed OG size budget) -->
  <g transform="translate(90, 110)">
    <circle cx="60" cy="60" r="58" fill="none" stroke="#f0b429" stroke-width="2"/>
    <text x="60" y="74" text-anchor="middle" font-family="DM Sans, system-ui, sans-serif" font-size="40" font-weight="700" fill="#f0b429">C</text>
  </g>
  <text x="220" y="190" font-family="DM Sans, system-ui, sans-serif" font-size="28" font-weight="600" fill="#f0b429" letter-spacing="3">CAMELEER</text>
  <text x="90" y="340" font-family="DM Sans, system-ui, sans-serif" font-size="64" font-weight="700" fill="#f4f5f7">Run Apache Camel</text>
  <text x="90" y="420" font-family="DM Sans, system-ui, sans-serif" font-size="64" font-weight="700" fill="#f4f5f7">without running Apache Camel.</text>
  <text x="90" y="500" font-family="DM Sans, system-ui, sans-serif" font-size="28" font-weight="400" fill="#a0a8b8">The hosted home for your Camel integrations.</text>
  <text x="90" y="540" font-family="DM Sans, system-ui, sans-serif" font-size="28" font-weight="400" fill="#a0a8b8">Deep tracing, replay, and live control — built in.</text>
</svg>
```

Rationale for the "C" fallback mark: the real product PNG logo at OG resolution would bloat the SVG past reasonable social-card budgets, and embedding a raster inside SVG is awkward. The amber circle-C on topographic lines reads correctly at the common 600×315 OG thumbnail render.

- [ ] **Step 3: Verify the SVG renders**

Open the file in a browser or image viewer to confirm it renders at 1200×630 and the headline doesn't overflow.

```
mcp__playwright__browser_navigate → http://localhost:4321/og-image.svg
mcp__playwright__browser_take_screenshot → filename: og-image.png
```

Expected: centered dark card, amber topographic lines, amber circle "C" mark top-left, "Run Apache Camel / without running Apache Camel." as the main text, softened subhead below.

- [ ] **Step 4: Commit**

```bash
git add public/og-image.svg
git commit -m "feat(brand): redesign OG image around new thesis

1200x630, solid #060a13 ground, amber topographic lines, circle-C mark,
headline 'Run Apache Camel without running Apache Camel.' plus short
subhead. The full camel-compass product logo is not embedded — raster
inside SVG at OG size would bloat the asset. Circle-C wordmark reads
cleanly at the 600x315 thumbnail render."
```

---

## Task 13: End-to-end verification

**Files:** none modified; verification-only.

- [ ] **Step 1: Clean build + run all static checks**

```bash
cd C:/Users/Hendrik/Documents/projects/cameleer-website
rm -rf dist
npm run build
npm run test
npm run lint:html
npm run lint:links
```

Expected: all green. `lint:html` checks the built HTML against `.htmlvalidate.json`. `lint:links` walks internal links in the built output.

- [ ] **Step 2: Full-page visual capture in the dev server**

```bash
npm run dev
```

```
mcp__playwright__browser_navigate → http://localhost:4321
mcp__playwright__browser_resize → width: 1440, height: 900
mcp__playwright__browser_take_screenshot → filename: homepage-desktop.png, fullPage: true
mcp__playwright__browser_resize → width: 375, height: 812
mcp__playwright__browser_take_screenshot → filename: homepage-mobile.png, fullPage: true
```

Visual review checklist — walk through each screenshot and confirm:

- [ ] Header: amber camel-on-compass logo + "Cameleer" wordmark, nav link "Pricing", CTA buttons on the right.
- [ ] Hero: 48px brand mark next to the "YOUR CAMELS CALLED. THEY WANT A GPS." kicker. Headline reads the current rotation line (one of the three). Subline starts with "The hosted home for your Camel integrations".
- [ ] DualValueProps: three tiles with the new headlines ("Ship integrations, then sleep.", "Debug in daylight.", "Keep what you built. Keep what you chose.").
- [ ] HowItWorks: three cards with "Point us at your Camel app", "We take it from there", "Watch it run". No `<pre>` bash snippet anywhere.
- [ ] WhyUs: tile 2 headline reads "Built by people who know what 3 AM looks like."
- [ ] PricingTeaser: subline reads "No credit card. No sales call. Just a working trial in ten minutes."
- [ ] FinalCTA: "Your camels called. Time to ride." + subline ending in "No camels harmed."

- [ ] **Step 3: Observe rotation live**

With the browser still open, wait ~25 seconds on the homepage and watch the H1 cycle. Expected order:

1. Run Apache Camel without running Apache Camel.
2. Camel integrations, minus the baggage.
3. Your camels, our caravan. You just ride.
4. (wraps back to #1)

- [ ] **Step 4: Confirm no forbidden terms appear in the built HTML**

```bash
cd C:/Users/Hendrik/Documents/projects/cameleer-website
grep -i -E 'javaagent|bytebuddy|nanosecond|45\+ EIP|\-jar your-camel-app' dist/index.html || echo "CLEAN"
```

Expected: `CLEAN`. If anything shows up, the corresponding earlier task regressed — re-open that task's step that removed the term.

- [ ] **Step 5: Confirm the real logo assets are actually reachable**

```bash
cd C:/Users/Hendrik/Documents/projects/cameleer-website
for path in /cameleer-logo.svg /icons/cameleer-32.png /icons/cameleer-180.png; do
  curl -sI "http://localhost:4321$path" | head -1
done
```

Expected: each line begins with `HTTP/1.1 200`.

- [ ] **Step 6: Confirm no console errors or CSP violations in `preview` mode**

```bash
npm run preview
```

Then:

```
mcp__playwright__browser_navigate → http://localhost:4321
mcp__playwright__browser_console_messages
```

Expected: no messages with level `error`. `preview` mode emits the real CSP headers, so this is the definitive CSP check.

- [ ] **Step 7: No commit**

This is verification only. If any step fails, it points to a regression in an earlier task — fix it there with an amended commit or a follow-up fix commit in the relevant task's scope, not as a general cleanup.

---

## Spec coverage verification (self-review)

| Spec section | Covered by task |
|---|---|
| §2.1 new thesis in copy | Task 4 (title), Task 5 (Hero H1 default), Task 6 (rotation) |
| §2.2 three rotating lines + behavior + accessibility | Task 6 |
| §2.3 forbidden terms | Tasks 4, 5, 7, 8, 9 — each task removes specific terms; Task 13 Step 4 greps the final HTML |
| §3.1 import asset list | Task 1 |
| §3.2 header icon swap | Task 3 |
| §3.3 favicon chain + delete placeholder | Task 2 |
| §3.4 Hero brand mark (48px next to kicker) | Task 5 |
| §3.5 OG image redesign | Task 12 |
| §4.1 Hero copy (kicker, H1, subline, remove `-javaagent`) | Tasks 5 + 6 |
| §4.2 DualValueProps rewrite | Task 7 |
| §4.3 HowItWorks rewrite + drop bash snippet | Task 8 |
| §4.4 WhyUs softening + tile 2 headline | Task 9 |
| §4.5 PricingTeaser subline tweak | Task 10 |
| §4.6 FinalCTA humor pop | Task 11 |

All spec sections are covered by at least one task.
