Compare commits
16 Commits
feat/initi
...
af7c61c203
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af7c61c203 | ||
|
|
0f02a62e6f | ||
|
|
47142051c4 | ||
|
|
135a6246d9 | ||
|
|
3bb71942dc | ||
|
|
62c77a8dc5 | ||
|
|
77bf0bfa74 | ||
|
|
518d7a8afc | ||
|
|
84ff83303a | ||
|
|
eff1ba6b8e | ||
|
|
03573b2ac1 | ||
|
|
6f0268ebea | ||
|
|
2526b1f0fc | ||
|
|
01cf23f2f6 | ||
|
|
3a1fe5f2c7 | ||
|
|
d6851cd5aa |
@@ -5,10 +5,15 @@
|
|||||||
# (Actions → deploy → Run workflow). Does NOT auto-deploy on push to main —
|
# (Actions → deploy → Run workflow). Does NOT auto-deploy on push to main —
|
||||||
# merges to main must be explicitly promoted to production.
|
# merges to main must be explicitly promoted to production.
|
||||||
#
|
#
|
||||||
# Build and deploy run in a single job so the built dist/ (including
|
# Build and deploy run in a single job; rsync uploads dist/ directly. No
|
||||||
# dotfiles like .htaccess) flows directly into rsync. An earlier split-job
|
# upload-artifact round-trip (v3 strips dotfiles, v4 isn't supported on Gitea).
|
||||||
# design was abandoned because actions/upload-artifact@v3 excludes dotfiles
|
#
|
||||||
# by default and the v4 client does not work on Gitea Actions / GHES.
|
# Security headers (HSTS, CSP, X-Frame-Options, etc.) are NOT set by this
|
||||||
|
# deploy. Hetzner Webhosting L runs Apache with AllowOverride None on the
|
||||||
|
# user docroot, so file-based .htaccess is silently ignored. All response
|
||||||
|
# headers are owned by Cloudflare Transform Rules — see OPERATOR-CHECKLIST.md
|
||||||
|
# §2 "Cloudflare". Apache config exposed via konsoleH UI is the only origin-
|
||||||
|
# side override path and is not managed from this repo.
|
||||||
#
|
#
|
||||||
# Runner: self-hosted arm64 Gitea runner. Adjust `runs-on` if your runner's
|
# Runner: self-hosted arm64 Gitea runner. Adjust `runs-on` if your runner's
|
||||||
# labels differ. Deploy target is Hetzner amd64 — arch mismatch is a non-issue
|
# labels differ. Deploy target is Hetzner amd64 — arch mismatch is a non-issue
|
||||||
@@ -54,15 +59,6 @@ jobs:
|
|||||||
- name: Build site
|
- name: Build site
|
||||||
run: npm run build
|
run: npm run build
|
||||||
|
|
||||||
# Astro/Vite does not copy dotfiles from public/ into dist/, so .htaccess
|
|
||||||
# never reaches the deployed origin and Apache never sees the security
|
|
||||||
# headers it sets. Copy it explicitly. Fail if the source is missing
|
|
||||||
# rather than silently shipping a header-less site.
|
|
||||||
- name: Copy .htaccess into dist
|
|
||||||
run: |
|
|
||||||
test -f public/.htaccess
|
|
||||||
cp public/.htaccess dist/.htaccess
|
|
||||||
|
|
||||||
- name: Guard — no TBD markers may ship in built HTML
|
- name: Guard — no TBD markers may ship in built HTML
|
||||||
run: |
|
run: |
|
||||||
if grep -rlE '(TBD):' dist 2>/dev/null | grep -E '\.(html|svg)$'; then
|
if grep -rlE '(TBD):' dist 2>/dev/null | grep -E '\.(html|svg)$'; then
|
||||||
|
|||||||
@@ -4,20 +4,25 @@ One-time setup that lives outside code. Do these before the first `main` merge t
|
|||||||
|
|
||||||
## 1. Hetzner Webhosting L
|
## 1. Hetzner Webhosting L
|
||||||
|
|
||||||
- [ ] Provision Webhosting L plan. Note the SSH hostname and SFTP path.
|
- [ ] Provision Webhosting L plan. Note the SSH hostname (e.g. `wwwNNN.your-server.de`) and the user login.
|
||||||
- [ ] In the Hetzner control panel, **enable SSH access** for the main user.
|
- [ ] In konsoleH, **enable SSH access** for the user.
|
||||||
|
- [ ] In konsoleH → Domainverwaltung, register the production domain (`www.cameleer.io`) on this hosting and confirm what document root Apache uses for it. On Webhosting L, the Apache vhost docroot for the addon domain is typically the bare `~/public_html/` (NOT a subdirectory). The `SFTP_PATH` secret must match this exactly — wrong path = 404 from origin.
|
||||||
- [ ] Generate an ed25519 SSH key pair locally (once):
|
- [ ] Generate an ed25519 SSH key pair locally (once):
|
||||||
```bash
|
```bash
|
||||||
ssh-keygen -t ed25519 -f ~/.ssh/cameleer-website-deploy -C "cameleer-website CI"
|
ssh-keygen -t ed25519 -f ~/.ssh/cameleer-website-deploy -C "cameleer-website CI"
|
||||||
```
|
```
|
||||||
- [ ] Add the **public** key to `~/.ssh/authorized_keys` on the Hetzner account.
|
- [ ] Add the **public** key to `~/.ssh/authorized_keys` on the Hetzner account (or via konsoleH SSH-Schlüssel UI).
|
||||||
- [ ] Test SSH: `ssh -i ~/.ssh/cameleer-website-deploy user@hetzner-host "ls -la"`.
|
- [ ] Test SSH on **port 222** (Hetzner Webhosting splits SFTP=22 / SSH-shell=222; rsync needs 222):
|
||||||
- [ ] Create a subdirectory for the site (typical path: `public_html/www.cameleer.io/`).
|
|
||||||
- [ ] Grab the SSH host key for pinning:
|
|
||||||
```bash
|
```bash
|
||||||
ssh-keyscan -t ed25519 hetzner-host > hetzner-known-hosts.txt
|
ssh -p 222 -i ~/.ssh/cameleer-website-deploy user@wwwNNN.your-server.de "ls -la"
|
||||||
```
|
```
|
||||||
- [ ] Install Let's Encrypt (or use Hetzner's built-in) for the origin hostname. Cloudflare Full (strict) requires a valid origin cert.
|
- [ ] Grab the SSH host key for pinning, also on **port 222**:
|
||||||
|
```bash
|
||||||
|
ssh-keyscan -p 222 -t rsa,ed25519,ecdsa wwwNNN.your-server.de > hetzner-known-hosts.txt
|
||||||
|
```
|
||||||
|
Verify the fingerprint against what your manual SSH session displayed before saving the secret — `ssh-keyscan` doesn't authenticate.
|
||||||
|
- [ ] **Origin TLS:** Cloudflare Full (strict) requires a valid origin cert. Hetzner Webhosting auto-issues Let's Encrypt — confirm the cert is active in konsoleH → SSL → SSL-Zertifikate.
|
||||||
|
- [ ] **`.htaccess` caveat (important):** Hetzner Webhosting L runs Apache with `AllowOverride None` on the user docroot, so any `.htaccess` file you `rsync` is **silently ignored** by Apache. The only way to set Apache directives on this tier is via konsoleH → Einstellungen → Serverkonfiguration (per-directory wrench panel). This repo therefore owns no `.htaccess`; all response headers live in Cloudflare (see §2). The konsoleH `.htaccess` panel is left empty by default; defense-in-depth header copies there are optional and survive rsync deploys (different storage location).
|
||||||
|
|
||||||
## 2. Cloudflare (zone: cameleer.io)
|
## 2. Cloudflare (zone: cameleer.io)
|
||||||
|
|
||||||
@@ -67,7 +72,7 @@ Add these under Repository settings → Actions → Secrets (or variables):
|
|||||||
|------|------|-------|
|
|------|------|-------|
|
||||||
| `SFTP_HOST` | secret | Hetzner SSH hostname |
|
| `SFTP_HOST` | secret | Hetzner SSH hostname |
|
||||||
| `SFTP_USER` | secret | Hetzner SSH user |
|
| `SFTP_USER` | secret | Hetzner SSH user |
|
||||||
| `SFTP_PATH` | secret | Absolute path to document root (e.g., `/usr/home/cameleer/public_html/www.cameleer.io`) |
|
| `SFTP_PATH` | secret | Absolute path to the Apache vhost docroot configured in konsoleH (typically `/usr/www/users/<login>/public_html`). Mismatch → 404 on origin. |
|
||||||
| `SFTP_KEY` | secret | Contents of `~/.ssh/cameleer-website-deploy` (private key, PEM) |
|
| `SFTP_KEY` | secret | Contents of `~/.ssh/cameleer-website-deploy` (private key, PEM) |
|
||||||
| `SFTP_KNOWN_HOSTS` | secret | Contents of `hetzner-known-hosts.txt` (captured via `ssh-keyscan`) |
|
| `SFTP_KNOWN_HOSTS` | secret | Contents of `hetzner-known-hosts.txt` (captured via `ssh-keyscan`) |
|
||||||
| `PUBLIC_AUTH_SIGNIN_URL` | secret | `https://auth.cameleer.io/sign-in` |
|
| `PUBLIC_AUTH_SIGNIN_URL` | secret | `https://auth.cameleer.io/sign-in` |
|
||||||
@@ -87,10 +92,13 @@ workflows read them via the `${{ secrets.* }}` context.
|
|||||||
|
|
||||||
## 5. First deploy
|
## 5. First deploy
|
||||||
|
|
||||||
|
The `deploy` workflow is **manual-only** — it does NOT auto-fire on push to `main`. After merging, trigger it explicitly.
|
||||||
|
|
||||||
1. Merge a PR to `main`.
|
1. Merge a PR to `main`.
|
||||||
2. Watch the Gitea Actions run: `build`, then `deploy`.
|
2. In Gitea: **Actions → deploy → Run workflow** on `main`.
|
||||||
3. The workflow includes a post-deploy smoke check — if HSTS / CSP / XFO are missing from the live response, the deploy fails and must be debugged at the Cloudflare Transform Rule layer.
|
3. Watch the single `deploy` job (build + tests + rsync + smoke test in one step).
|
||||||
4. Manually verify:
|
4. The workflow's post-deploy smoke check verifies HSTS / CSP / X-Frame-Options on the live response. If any fail, the deploy step exits non-zero — debug at the **Cloudflare Transform Rule** layer (§2 above), since headers no longer come from the origin.
|
||||||
- `curl -sI https://www.cameleer.io/` returns all six security headers.
|
5. Manually verify:
|
||||||
|
- `curl -sI https://www.cameleer.io/` returns all 5 security headers (HSTS, CSP, XFO, X-Content-Type-Options, Referrer-Policy, Permissions-Policy).
|
||||||
- `https://cameleer.io/` → `https://www.cameleer.io/` 301 redirect.
|
- `https://cameleer.io/` → `https://www.cameleer.io/` 301 redirect.
|
||||||
- Open the site in an incognito window on desktop + mobile.
|
- Open the site in an incognito window on desktop + mobile.
|
||||||
|
|||||||
@@ -34,7 +34,11 @@ See `.env.example`. All are `PUBLIC_*` (build-time, embedded in HTML).
|
|||||||
|
|
||||||
## Deployment
|
## Deployment
|
||||||
|
|
||||||
Push to `main` → Gitea Actions runs tests, builds, lints, then `rsync`s `dist/` to Hetzner over SSH (ed25519 key, host-key-pinned). Rollback is `git revert && git push`.
|
**Manual trigger only.** Merging to `main` does NOT auto-deploy. To ship: Gitea → **Actions → deploy → Run workflow** on `main`. The workflow runs tests, builds, then `rsync`s `dist/` to Hetzner over SSH (ed25519 key on port 222, host-key-pinned), and post-deploy curls the live site to verify security headers.
|
||||||
|
|
||||||
|
Rollback: trigger the deploy workflow on the previous `main` commit (Actions UI lets you pick a ref).
|
||||||
|
|
||||||
|
**Security headers** (HSTS, CSP, X-Frame-Options, etc.) are owned by **Cloudflare Transform Rules**, not by anything in this repo. Hetzner Webhosting L ignores file-based `.htaccess` (`AllowOverride None`), so origin-side header config is impossible from code. See `OPERATOR-CHECKLIST.md` §2.
|
||||||
|
|
||||||
See [`OPERATOR-CHECKLIST.md`](./OPERATOR-CHECKLIST.md) for the one-time Hetzner + Cloudflare setup.
|
See [`OPERATOR-CHECKLIST.md`](./OPERATOR-CHECKLIST.md) for the one-time Hetzner + Cloudflare setup.
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,11 @@ export default defineConfig({
|
|||||||
vite: {
|
vite: {
|
||||||
build: {
|
build: {
|
||||||
cssMinify: 'lightningcss',
|
cssMinify: 'lightningcss',
|
||||||
|
// Prevent Astro from inlining small scripts into the HTML.
|
||||||
|
// Without this, the hero rotator script (< 4 KB) gets inlined as a
|
||||||
|
// <script type="module"> tag, which violates CSP script-src 'self'
|
||||||
|
// (no 'unsafe-inline'). Setting 0 forces all scripts to external files.
|
||||||
|
assetsInlineLimit: 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
1088
docs/superpowers/plans/2026-04-24-cameleer-website-copy-refresh.md
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
# Cameleer website — copy + brand refresh spec
|
||||||
|
|
||||||
|
**Date**: 2026-04-24
|
||||||
|
**Status**: Approved for implementation planning
|
||||||
|
**Project**: `cameleer-website`
|
||||||
|
**Supersedes sections of**: `2026-04-24-cameleer-website-design.md` — copy, logo, and tone only. Architecture, auth flow, hosting, and tech stack from the original spec remain in force.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Overview
|
||||||
|
|
||||||
|
The current marketing site sells Cameleer as **"zero-code observability for Apache Camel"**. This underrepresents the product: Cameleer is a **hosted runtime platform for Apache Camel** — the place you actually run your integrations, with deep tracing, replay, and live control baked in. Comparable to Mulesoft CloudHub in category, for teams who chose Apache Camel specifically to stay open and avoid vendor lock-in.
|
||||||
|
|
||||||
|
This spec refreshes the homepage copy, tone, and brand mark to match that positioning. Three goals:
|
||||||
|
|
||||||
|
1. Reposition from "observability tool" to "hosted Camel runtime with observability baked in".
|
||||||
|
2. Lighten the tone — less technical jargon, more outcome-focused language, two strategic humor pops.
|
||||||
|
3. Replace the placeholder topographic-wave icon with the real Cameleer product logo (camel + cameleer figure + compass rose on desert waves, amber).
|
||||||
|
|
||||||
|
No architecture changes. No new pages. No new dependencies. Pure content + asset refresh.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Positioning
|
||||||
|
|
||||||
|
### 2.1 New thesis
|
||||||
|
|
||||||
|
**Run Apache Camel without running Apache Camel.**
|
||||||
|
|
||||||
|
Cameleer is 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.
|
||||||
|
|
||||||
|
### 2.2 Rotating Hero positioning lines
|
||||||
|
|
||||||
|
Three lines rotate slowly in the Hero subline area:
|
||||||
|
|
||||||
|
1. **Run Apache Camel without running Apache Camel.**
|
||||||
|
2. **Camel integrations, minus the baggage.**
|
||||||
|
3. **Your camels, our caravan. You just ride.**
|
||||||
|
|
||||||
|
**Rotation behavior:**
|
||||||
|
- Fade swap every ~10 seconds (8s static + 2s fade).
|
||||||
|
- Paused on hover and on focus within the Hero.
|
||||||
|
- If `prefers-reduced-motion: reduce` is set — render the first line only, no rotation, no JS.
|
||||||
|
- Initial render shows line 1 so the critical content is meaningful without JS.
|
||||||
|
- Implementation: small inline `<script type="module">` in the Hero component. No third-party animation library.
|
||||||
|
|
||||||
|
**Accessibility:**
|
||||||
|
- The rotating container is the H1 — it is the primary page heading and the accessibility name of the document. Use `aria-live="off"` on the rotation wrapper so assistive technology does not announce every swap (announcing a different H1 every 10 seconds is hostile). All three lines render in the DOM; only one is visible. Visually-hidden siblings should have `aria-hidden="true"` to avoid duplicate heading announcements.
|
||||||
|
- Tab-focus anywhere inside the Hero pauses rotation (same pause rule as hover).
|
||||||
|
|
||||||
|
### 2.3 Terms to avoid on landing page
|
||||||
|
|
||||||
|
Remove from all landing page copy:
|
||||||
|
|
||||||
|
- `-javaagent`, `java agent`, `Docker`, `ByteBuddy`, `Spring Boot`, `Quarkus`, `JAR`
|
||||||
|
- `Prometheus`, `OpenTelemetry`, `CDI`, `JMX`
|
||||||
|
- "nanosecond", "45+ EIP node types" (acceptable in headings-off detail, not in headlines/H2s)
|
||||||
|
- "zero-code instrumentation" → replace with "no code changes"
|
||||||
|
|
||||||
|
Keep (audience vocabulary):
|
||||||
|
|
||||||
|
- Apache Camel, routes, processors, exchanges
|
||||||
|
- Replay, trace, correlation ID
|
||||||
|
- EIP — allowed once as a credibility signal, not a feature
|
||||||
|
|
||||||
|
Out-of-scope for this spec: the `/install` or `/docs` routes where `-javaagent` snippets belong. The existing homepage's bash snippet moves off the homepage — see §4.3.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Brand mark refresh
|
||||||
|
|
||||||
|
### 3.1 Assets to import
|
||||||
|
|
||||||
|
From `C:/Users/Hendrik/Documents/projects/design-system/assets/` into `cameleer-website/public/`:
|
||||||
|
|
||||||
|
- `cameleer-16.png` → `public/icons/cameleer-16.png`
|
||||||
|
- `cameleer-32.png` → `public/icons/cameleer-32.png`
|
||||||
|
- `cameleer-48.png` → `public/icons/cameleer-48.png`
|
||||||
|
- `cameleer-180.png` → `public/icons/cameleer-180.png` (Apple touch)
|
||||||
|
- `cameleer-192.png` → `public/icons/cameleer-192.png` (PWA/Android)
|
||||||
|
- `cameleer-512.png` → `public/icons/cameleer-512.png` (PWA/Android)
|
||||||
|
- `cameleer-logo.svg` → `public/cameleer-logo.svg` (vector, used in header)
|
||||||
|
- `cameleer-logo.png` → `public/cameleer-logo.png` (raster fallback for OG)
|
||||||
|
|
||||||
|
The SVG is 1.5 MB (not SVGO'd). It's used only in the header at ~32px. If the unminified size becomes a concern, run it through SVGO at build time — not in this spec's scope. For now, ship as-is and measure.
|
||||||
|
|
||||||
|
### 3.2 Header icon swap
|
||||||
|
|
||||||
|
`src/components/SiteHeader.astro`:
|
||||||
|
|
||||||
|
- Remove the inline 3-wavy-lines SVG.
|
||||||
|
- Replace with `<img src="/cameleer-logo.svg" width="32" height="32" alt="" decoding="async">`.
|
||||||
|
- Keep the existing `<a href="/" aria-label="Cameleer home">` wrapper and the "Cameleer" wordmark beside it.
|
||||||
|
- Keep the `group-hover:text-accent` transition on the wordmark only.
|
||||||
|
|
||||||
|
### 3.3 Favicon chain
|
||||||
|
|
||||||
|
Update `src/layouts/BaseLayout.astro` `<head>`:
|
||||||
|
|
||||||
|
- Primary: `<link rel="icon" href="/cameleer-logo.svg" type="image/svg+xml">`
|
||||||
|
- Fallback: `<link rel="icon" href="/icons/cameleer-32.png" sizes="32x32" type="image/png">`
|
||||||
|
- Apple: `<link rel="apple-touch-icon" href="/icons/cameleer-180.png">`
|
||||||
|
- Remove the existing `public/favicon.svg` (placeholder topographic lines).
|
||||||
|
|
||||||
|
### 3.4 Hero brand mark
|
||||||
|
|
||||||
|
In the Hero section, add a distinct small mark (48–64px) next to or just above the rotating positioning line. Amber on transparent. Tasteful, not a watermark. The mark anchors the camel/desert/GPS humor visually — the humor lands harder when the camel is literally present.
|
||||||
|
|
||||||
|
### 3.5 OG image
|
||||||
|
|
||||||
|
Replace `public/og-image.svg` content with a new design built around the real logo + the new thesis "Run Apache Camel without running Apache Camel." Same dimensions (1200×630), same solid dark background. Exact layout is a creative execution task, not spec'd here.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Section-by-section copy changes
|
||||||
|
|
||||||
|
Each section below lists the current headline → new headline and notes on body copy changes. Specific body copy wording is implementation detail — the writer should follow the tone and term-use rules in §2.
|
||||||
|
|
||||||
|
### 4.1 Hero (`src/components/sections/Hero.astro`)
|
||||||
|
|
||||||
|
**Kicker** (small uppercase line above headline):
|
||||||
|
- Current: `Observability · Apache Camel`
|
||||||
|
- New: `Your camels called. They want a GPS.`
|
||||||
|
|
||||||
|
**Headline** (H1):
|
||||||
|
- Current: `See every route. / Reach into every flow.`
|
||||||
|
- New: `Run Apache Camel without running Apache Camel.` (the primary of three rotating lines)
|
||||||
|
- The H1 is the rotation target — it's the single most important piece of copy on the page and what gets indexed/shared.
|
||||||
|
|
||||||
|
**Subline**:
|
||||||
|
- Current: "Zero-code tracing, processor-level detail, and live control for Apache Camel — from a single `-javaagent` flag."
|
||||||
|
- New: "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."
|
||||||
|
- Static — does not rotate.
|
||||||
|
|
||||||
|
**`-javaagent` code inline**: removed from Hero.
|
||||||
|
|
||||||
|
**CTAButtons**: unchanged.
|
||||||
|
|
||||||
|
**RouteDiagram**: unchanged (visual, not copy).
|
||||||
|
|
||||||
|
### 4.2 DualValueProps (`src/components/sections/DualValueProps.astro`)
|
||||||
|
|
||||||
|
Current three tiles lead with outcomes but bodies are tech-heavy. Rewrite bodies to be outcome- and feeling-led. No humor in this section.
|
||||||
|
|
||||||
|
Tile 1 — **Ship integrations, then sleep.**
|
||||||
|
Body reframe: you can see every route, every processor, every exchange, without writing a single line of tracing code. When something breaks, you know where and why.
|
||||||
|
|
||||||
|
Tile 2 — **Debug in daylight, not at 3 AM.**
|
||||||
|
Body reframe: replay failed exchanges, follow a single request across services, capture exactly what went wrong — with the pieces ops actually needs at 3 AM already captured so you don't need to be up at 3 AM.
|
||||||
|
|
||||||
|
Tile 3 — **Own your stack. No lock-in.**
|
||||||
|
Body reframe: you chose Apache Camel on purpose — open, portable, standard. Cameleer runs and observes your Camel apps as they are. No SDK, no code changes, no rewrite.
|
||||||
|
|
||||||
|
All three tile bodies: strip `-javaagent`, `45+ EIP`, "nanosecond". Keep them plain, outcome-first, ~2-3 sentences each.
|
||||||
|
|
||||||
|
### 4.3 HowItWorks (`src/components/sections/HowItWorks.astro`)
|
||||||
|
|
||||||
|
Section kicker unchanged: `For engineers`. Section H2 unchanged: `How it works`.
|
||||||
|
|
||||||
|
Three steps:
|
||||||
|
|
||||||
|
01 — **Point us at your Camel app**
|
||||||
|
Body: drop your app in, or connect an existing one. No code changes, no SDK, nothing to rewrite.
|
||||||
|
**Remove** the `java -javaagent:...` bash snippet entirely. The install detail belongs in docs, not on the landing page.
|
||||||
|
|
||||||
|
02 — **We take it from there**
|
||||||
|
Body: every route, processor, exchange, and dependency is discovered and traced automatically. Sensitive fields are masked by default.
|
||||||
|
|
||||||
|
03 — **Watch it run**
|
||||||
|
Body: browse executions, tap live traffic, replay failed exchanges, follow flows across services. Nothing to instrument, nothing to maintain.
|
||||||
|
|
||||||
|
Subtitle under "How it works" — current: "Three steps. No code changes. Works across Camel 4.x." — softens to: "Three steps. No code changes. Nothing to maintain."
|
||||||
|
|
||||||
|
### 4.4 WhyUs (`src/components/sections/WhyUs.astro`)
|
||||||
|
|
||||||
|
Section unchanged structurally. Kicker `Why Cameleer` and H2 stay. Body softening only:
|
||||||
|
|
||||||
|
Tile 1 — headline stays: "Generic APMs do not understand Camel. Cameleer does."
|
||||||
|
Body: rewrite to drop "45+ Apache Camel EIP node types", "bidirectional protocol", "signed config changes". Translate to plain value: "Most monitoring tools see your app as a Java process and a pile of HTTP calls. Cameleer understands that you're running a Camel app — it speaks choices, splits, multicasts, error handlers, and every EIP pattern as first-class citizens. When you ask 'why did this exchange fail?', you get an answer, not a log tail."
|
||||||
|
|
||||||
|
Tile 2 — headline tweak: "Built by people who know what 3 AM looks like."
|
||||||
|
Body: keep the nJAMS-legacy story but warmer. "The Cameleer team 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'd build today, purpose-built for Apache Camel."
|
||||||
|
|
||||||
|
Retain the trademark review note (nJAMS legacy).
|
||||||
|
|
||||||
|
### 4.5 PricingTeaser (`src/components/sections/PricingTeaser.astro`)
|
||||||
|
|
||||||
|
Kicker `Pricing` unchanged. H2 `Start free. Grow when you need to.` unchanged.
|
||||||
|
|
||||||
|
Subline current: "No credit card for the trial. See full comparison →"
|
||||||
|
Subline new: "No credit card. No sales call. Just a working trial in ten minutes."
|
||||||
|
|
||||||
|
Tier cards and prices unchanged.
|
||||||
|
|
||||||
|
### 4.6 FinalCTA (`src/components/sections/FinalCTA.astro`)
|
||||||
|
|
||||||
|
**Headline:**
|
||||||
|
- Current: `Start seeing your routes.`
|
||||||
|
- New: `Your camels called. Time to ride.`
|
||||||
|
|
||||||
|
**Subline:**
|
||||||
|
- Current: "14-day free trial. Your first app, instrumented and live in under 10 minutes."
|
||||||
|
- New: "14-day free trial. Your first Camel app, hosted, traced, and running in under ten minutes. No code changes. No camels harmed."
|
||||||
|
|
||||||
|
**CTAButtons**: unchanged.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Files touched
|
||||||
|
|
||||||
|
- `src/components/SiteHeader.astro` — logo swap (§3.2)
|
||||||
|
- `src/layouts/BaseLayout.astro` — favicon chain + OG image reference (§3.3)
|
||||||
|
- `src/components/sections/Hero.astro` — kicker, rotating H1, subline, brand mark (§4.1, §3.4, §2.2)
|
||||||
|
- `src/components/sections/DualValueProps.astro` — three tile copy rewrites (§4.2)
|
||||||
|
- `src/components/sections/HowItWorks.astro` — step copy rewrites + bash snippet removal (§4.3)
|
||||||
|
- `src/components/sections/WhyUs.astro` — tile body softening (§4.4)
|
||||||
|
- `src/components/sections/PricingTeaser.astro` — subline tweak (§4.5)
|
||||||
|
- `src/components/sections/FinalCTA.astro` — headline + subline (§4.6)
|
||||||
|
- `public/cameleer-logo.svg`, `public/cameleer-logo.png` — new assets (§3.1)
|
||||||
|
- `public/icons/cameleer-{16,32,48,180,192,512}.png` — new assets (§3.1)
|
||||||
|
- `public/favicon.svg` — deleted (§3.3)
|
||||||
|
- `public/og-image.svg` — redesigned around new thesis (§3.5)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Out of scope
|
||||||
|
|
||||||
|
- Docs/install page creation — the `-javaagent` snippet moves off the homepage but this spec does not create its new home. Follow-up.
|
||||||
|
- Logo SVG optimization (1.5 MB ship-as-is; measure before optimizing).
|
||||||
|
- A/B testing the positioning lines. Rotation serves all three; we read analytics separately if/when added.
|
||||||
|
- Pricing page (`/pricing`), imprint, privacy copy changes — this spec is homepage-only.
|
||||||
|
- i18n — English only. No translation work.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Open questions / risks
|
||||||
|
|
||||||
|
**Trademark — nJAMS legacy wording**: §4.4 Tile 2 mentions "the kind of shops where a stuck exchange at 3 AM means someone's phone is ringing." This is legacy nJAMS muscle memory, not new IP. Hendrik's trademark review gate from the original spec's §10 still applies before go-live.
|
||||||
|
|
||||||
|
**Positioning tension with docs**: once the landing page stops saying "`-javaagent`", SEO signals around that specific technical term weaken. Acceptable trade-off for the target audience (SMB+ Camel-chooser decision-makers), but if engineer-skewed traffic matters for discovery, consider a technical sub-page (`/how-it-runs`) or docs page carrying those keywords.
|
||||||
|
|
||||||
|
**Logo SVG weight**: 1.5 MB is large for a ~32px header render. If Lighthouse performance regresses, swap the header to reference `cameleer-logo.png` or an SVGO-minified copy.
|
||||||
|
|
||||||
|
**SEO title/description**: the BaseLayout `<title>` + meta description currently read "Zero-code observability for Apache Camel." These should update to match the new thesis ("Run Apache Camel without running Apache Camel."). Include this in the Hero section implementation task.
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
# ---------------------------------------------------------------
|
|
||||||
# www.cameleer.io — Apache config at the Hetzner origin.
|
|
||||||
# Defense in depth: Cloudflare handles most of this at the edge;
|
|
||||||
# these rules make sure the origin is hardened even without the CDN.
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
|
|
||||||
# Enable rewriting
|
|
||||||
RewriteEngine On
|
|
||||||
|
|
||||||
# Force HTTPS — redundant with Cloudflare but belts-and-braces.
|
|
||||||
RewriteCond %{HTTPS} !=on
|
|
||||||
RewriteCond %{HTTP:X-Forwarded-Proto} !=https
|
|
||||||
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
|
|
||||||
|
|
||||||
# Redirect apex -> www.
|
|
||||||
RewriteCond %{HTTP_HOST} ^cameleer\.io$ [NC]
|
|
||||||
RewriteRule ^(.*)$ https://www.cameleer.io/$1 [L,R=301]
|
|
||||||
|
|
||||||
# Disable directory listings.
|
|
||||||
Options -Indexes
|
|
||||||
|
|
||||||
# Block access to dotfiles and sensitive extensions that should never be here.
|
|
||||||
<FilesMatch "^\.|\.(env|ini|log|sh|bak|sql|git)$">
|
|
||||||
Require all denied
|
|
||||||
</FilesMatch>
|
|
||||||
|
|
||||||
# Prevent MIME sniffing, clickjacking, etc. (primary copy also comes from Astro middleware
|
|
||||||
# and Cloudflare Transform Rules — these apply if either layer is bypassed).
|
|
||||||
<IfModule mod_headers.c>
|
|
||||||
Header always set X-Content-Type-Options "nosniff"
|
|
||||||
Header always set X-Frame-Options "DENY"
|
|
||||||
Header always set Referrer-Policy "strict-origin-when-cross-origin"
|
|
||||||
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=(), usb=()"
|
|
||||||
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
|
||||||
|
|
||||||
# Cache hashed build assets aggressively; HTML must be revalidated.
|
|
||||||
<FilesMatch "\.(css|js|woff2|svg|png|jpg|jpeg|webp|ico)$">
|
|
||||||
Header set Cache-Control "public, max-age=31536000, immutable"
|
|
||||||
</FilesMatch>
|
|
||||||
<FilesMatch "\.html$">
|
|
||||||
Header set Cache-Control "public, max-age=3600, must-revalidate"
|
|
||||||
</FilesMatch>
|
|
||||||
|
|
||||||
# Remove Server header leak where possible.
|
|
||||||
Header unset X-Powered-By
|
|
||||||
</IfModule>
|
|
||||||
|
|
||||||
# Compression (Hetzner supports mod_deflate).
|
|
||||||
<IfModule mod_deflate.c>
|
|
||||||
AddOutputFilterByType DEFLATE text/html text/css application/javascript application/json image/svg+xml text/plain
|
|
||||||
</IfModule>
|
|
||||||
|
|
||||||
# Custom error pages (optional — fall back to default if not present).
|
|
||||||
ErrorDocument 404 /404.html
|
|
||||||
ErrorDocument 403 /404.html
|
|
||||||
BIN
public/cameleer-logo.png
Normal file
|
After Width: | Height: | Size: 342 KiB |
112
public/cameleer-logo.svg
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
@@ -1,8 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
|
||||||
<rect width="32" height="32" rx="6" fill="#060a13"/>
|
|
||||||
<g fill="none" stroke="#f0b429" stroke-width="1.4" 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>
|
|
||||||
|
Before Width: | Height: | Size: 332 B |
BIN
public/icons/cameleer-16.png
Normal file
|
After Width: | Height: | Size: 941 B |
BIN
public/icons/cameleer-180.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
public/icons/cameleer-192.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
public/icons/cameleer-32.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
public/icons/cameleer-48.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
public/icons/cameleer-512.png
Normal file
|
After Width: | Height: | Size: 151 KiB |
@@ -1,13 +1,20 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 630">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 630" width="1200" height="630">
|
||||||
<rect width="1200" height="630" fill="#060a13"/>
|
<rect width="1200" height="630" fill="#060a13"/>
|
||||||
<g fill="none" stroke="#f0b429" stroke-width="1" opacity="0.2">
|
<!-- Subtle topographic lines -->
|
||||||
<path d="M0,120 Q300,60 600,150 T1200,120"/>
|
<g fill="none" stroke="#f0b429" stroke-width="1.2" stroke-linecap="round" opacity="0.10">
|
||||||
<path d="M0,240 Q300,180 600,270 T1200,240"/>
|
<path d="M0 140 Q200 80 400 160 T800 140 T1200 160"/>
|
||||||
<path d="M0,360 Q300,300 600,390 T1200,360"/>
|
<path d="M0 250 Q200 190 400 270 T800 250 T1200 270"/>
|
||||||
<path d="M0,480 Q300,420 600,510 T1200,480"/>
|
<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>
|
</g>
|
||||||
<text x="80" y="260" fill="#f0b429" font-family="'DM Sans', sans-serif" font-size="22" letter-spacing="6">OBSERVABILITY · APACHE CAMEL</text>
|
<!-- Product mark (fallback: amber circle w/ wordmark — real PNG logo embedded would exceed OG size budget) -->
|
||||||
<text x="80" y="360" fill="#e8eaed" font-family="'DM Sans', sans-serif" font-size="72" font-weight="700">See every route.</text>
|
<g transform="translate(90, 110)">
|
||||||
<text x="80" y="440" fill="#e8eaed" font-family="'DM Sans', sans-serif" font-size="72" font-weight="700">Reach into every flow.</text>
|
<circle cx="60" cy="60" r="58" fill="none" stroke="#f0b429" stroke-width="2"/>
|
||||||
<text x="80" y="540" fill="#9aa3b2" font-family="'JetBrains Mono', monospace" font-size="26">cameleer.io</text>
|
<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>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 921 B After Width: | Height: | Size: 1.7 KiB |
@@ -4,14 +4,14 @@ import CTAButtons from './CTAButtons.astro';
|
|||||||
<header class="sticky top-0 z-40 backdrop-blur-md bg-bg/80 border-b border-border">
|
<header class="sticky top-0 z-40 backdrop-blur-md bg-bg/80 border-b border-border">
|
||||||
<div class="max-w-content mx-auto px-6 h-16 flex items-center justify-between gap-6">
|
<div class="max-w-content mx-auto px-6 h-16 flex items-center justify-between gap-6">
|
||||||
<a href="/" class="flex items-center gap-2 group" aria-label="Cameleer home">
|
<a href="/" class="flex items-center gap-2 group" aria-label="Cameleer home">
|
||||||
<svg width="28" height="28" viewBox="0 0 32 32" aria-hidden="true">
|
<img
|
||||||
<rect width="32" height="32" rx="6" fill="#0c111a"/>
|
src="/cameleer-logo.svg"
|
||||||
<g fill="none" stroke="#f0b429" stroke-width="1.6" stroke-linecap="round">
|
width="32"
|
||||||
<path d="M4 10 Q10 6 16 12 T28 10"/>
|
height="32"
|
||||||
<path d="M4 16 Q10 12 16 18 T28 16"/>
|
alt=""
|
||||||
<path d="M4 22 Q10 18 16 24 T28 22"/>
|
decoding="async"
|
||||||
</g>
|
class="shrink-0"
|
||||||
</svg>
|
/>
|
||||||
<span class="font-sans font-bold text-lg tracking-tight text-text group-hover:text-accent transition-colors">Cameleer</span>
|
<span class="font-sans font-bold text-lg tracking-tight text-text group-hover:text-accent transition-colors">Cameleer</span>
|
||||||
</a>
|
</a>
|
||||||
<nav class="flex items-center gap-8 text-sm" aria-label="Primary">
|
<nav class="flex items-center gap-8 text-sm" aria-label="Primary">
|
||||||
|
|||||||
@@ -8,19 +8,19 @@ interface Tile {
|
|||||||
// user-supplied or CMS content into set:html further down (XSS risk).
|
// user-supplied or CMS content into set:html further down (XSS risk).
|
||||||
const tiles: Tile[] = [
|
const tiles: Tile[] = [
|
||||||
{
|
{
|
||||||
outcome: 'Cut debugging time in half.',
|
outcome: 'Ship integrations, then sleep.',
|
||||||
capability:
|
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.',
|
'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: 'Ship integrations with confidence.',
|
outcome: 'Debug in daylight.',
|
||||||
capability:
|
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.',
|
'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 have built.',
|
outcome: 'Keep what you built. Keep what you chose.',
|
||||||
capability:
|
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.',
|
'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.',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ import TopographicBg from '../TopographicBg.astro';
|
|||||||
<TopographicBg opacity={0.18} lines={6} />
|
<TopographicBg opacity={0.18} lines={6} />
|
||||||
<div class="relative max-w-content mx-auto px-6 py-24 md:py-32 text-center">
|
<div class="relative max-w-content mx-auto px-6 py-24 md:py-32 text-center">
|
||||||
<h2 class="text-display font-bold text-text mb-6">
|
<h2 class="text-display font-bold text-text mb-6">
|
||||||
Start seeing your routes.
|
Your camels called. Time to ride.
|
||||||
</h2>
|
</h2>
|
||||||
<p class="text-lg md:text-xl text-text-muted max-w-prose mx-auto mb-10">
|
<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.
|
14-day free trial. Your first Camel app, hosted, traced, and running in under ten minutes. No code changes. No camels harmed.
|
||||||
</p>
|
</p>
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
<CTAButtons size="lg" />
|
<CTAButtons size="lg" />
|
||||||
|
|||||||
@@ -7,16 +7,30 @@ import TopographicBg from '../TopographicBg.astro';
|
|||||||
<TopographicBg opacity={0.14} lines={10} />
|
<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="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="max-w-3xl">
|
||||||
<p class="text-accent font-mono text-xs tracking-[0.25em] uppercase mb-6">
|
<div class="flex items-center gap-3 mb-6">
|
||||||
Observability · Apache Camel
|
<img
|
||||||
</p>
|
src="/cameleer-logo.svg"
|
||||||
<h1 class="text-display font-bold text-text mb-6">
|
width="48"
|
||||||
See every route.<br />
|
height="48"
|
||||||
Reach into every flow.
|
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 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>
|
</h1>
|
||||||
<p class="text-lg md:text-xl text-text-muted max-w-prose leading-relaxed mb-10">
|
<p class="text-lg md:text-xl text-text-muted max-w-prose leading-relaxed mb-10">
|
||||||
Zero-code tracing, processor-level detail, and live control for Apache Camel —
|
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.
|
||||||
from a single <code class="font-mono text-accent bg-bg-elevated border border-border rounded px-1.5 py-0.5 text-base">-javaagent</code> flag.
|
|
||||||
</p>
|
</p>
|
||||||
<CTAButtons size="lg" />
|
<CTAButtons size="lg" />
|
||||||
</div>
|
</div>
|
||||||
@@ -25,3 +39,57 @@ import TopographicBg from '../TopographicBg.astro';
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<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>
|
||||||
|
|||||||
@@ -9,19 +9,18 @@ interface Step {
|
|||||||
const steps: Step[] = [
|
const steps: Step[] = [
|
||||||
{
|
{
|
||||||
n: '01',
|
n: '01',
|
||||||
title: 'Add the agent',
|
title: 'Point us at your Camel app',
|
||||||
body: 'Drop the Cameleer agent JAR alongside your Camel app and start it with a single flag. That is the entire installation.',
|
body: 'Drop it in, or connect one you already run. No code changes. No SDK. Nothing to rewrite.',
|
||||||
code: 'java \\\n -javaagent:cameleer-agent.jar \\\n -jar your-camel-app.jar',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
n: '02',
|
n: '02',
|
||||||
title: 'Launch your app',
|
title: 'We take it from there',
|
||||||
body: 'Every route, processor, exchange, and route graph is discovered and reported automatically. Configurable redaction keeps sensitive fields out of the trace.',
|
body: 'Every route, every processor, every exchange — discovered and traced automatically. Sensitive fields are masked by default.',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
n: '03',
|
n: '03',
|
||||||
title: 'See it in Mission Control',
|
title: 'Watch it run',
|
||||||
body: 'Browse executions, tap live traffic, replay failed exchanges, and follow flows across services. Nothing to instrument, nothing to maintain.',
|
body: 'Browse executions, tap live traffic, replay failed exchanges, follow flows across services. Nothing to instrument. Nothing to maintain.',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
---
|
---
|
||||||
@@ -30,7 +29,7 @@ const steps: Step[] = [
|
|||||||
<div class="max-w-2xl mb-16">
|
<div class="max-w-2xl mb-16">
|
||||||
<p class="text-cyan font-mono text-xs tracking-[0.25em] uppercase mb-4">For engineers</p>
|
<p class="text-cyan font-mono text-xs tracking-[0.25em] uppercase mb-4">For engineers</p>
|
||||||
<h2 class="text-hero font-bold text-text mb-4">How it works</h2>
|
<h2 class="text-hero font-bold text-text mb-4">How it works</h2>
|
||||||
<p class="text-text-muted text-lg">Three steps. No code changes. Works across Camel 4.x.</p>
|
<p class="text-text-muted text-lg">Three steps. No code changes. Nothing to maintain.</p>
|
||||||
</div>
|
</div>
|
||||||
<ol class="grid md:grid-cols-3 gap-6 md:gap-8">
|
<ol class="grid md:grid-cols-3 gap-6 md:gap-8">
|
||||||
{steps.map((step) => (
|
{steps.map((step) => (
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ const tiers: Tier[] = [
|
|||||||
<p class="text-accent font-mono text-xs tracking-[0.25em] uppercase mb-4">Pricing</p>
|
<p class="text-accent font-mono text-xs tracking-[0.25em] uppercase mb-4">Pricing</p>
|
||||||
<h2 class="text-hero font-bold text-text mb-4">Start free. Grow when you need to.</h2>
|
<h2 class="text-hero font-bold text-text mb-4">Start free. Grow when you need to.</h2>
|
||||||
<p class="text-text-muted text-lg">
|
<p class="text-text-muted text-lg">
|
||||||
No credit card for the trial.
|
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>
|
<a href="/pricing" class="text-accent hover:underline">See full comparison →</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -14,19 +14,19 @@
|
|||||||
<div class="rounded-lg border border-border bg-bg-elevated p-8">
|
<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>
|
<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">
|
<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.
|
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>
|
||||||
<p class="text-text-muted leading-relaxed">
|
<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.
|
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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="rounded-lg border border-border bg-bg-elevated p-8">
|
<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>
|
<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">
|
<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.
|
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>
|
||||||
<p class="text-text-muted leading-relaxed">
|
<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.
|
Cameleer is what we would build today, purpose-built for Apache Camel. No legacy, no retrofit, no assumptions about a generic middleware platform.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -31,7 +31,9 @@ const ogUrl = new URL(ogImage, Astro.site ?? 'https://www.cameleer.io').toString
|
|||||||
<meta name="description" content={description} />
|
<meta name="description" content={description} />
|
||||||
<link rel="canonical" href={canonical} />
|
<link rel="canonical" href={canonical} />
|
||||||
|
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
<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" />
|
||||||
|
|
||||||
<meta property="og:type" content="website" />
|
<meta property="og:type" content="website" />
|
||||||
<meta property="og:site_name" content="Cameleer" />
|
<meta property="og:site_name" content="Cameleer" />
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import PricingTeaser from '../components/sections/PricingTeaser.astro';
|
|||||||
import FinalCTA from '../components/sections/FinalCTA.astro';
|
import FinalCTA from '../components/sections/FinalCTA.astro';
|
||||||
---
|
---
|
||||||
<BaseLayout
|
<BaseLayout
|
||||||
title="Cameleer — Zero-code observability for Apache Camel"
|
title="Cameleer — Run Apache Camel without running 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."
|
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."
|
||||||
>
|
>
|
||||||
<SiteHeader />
|
<SiteHeader />
|
||||||
<main>
|
<main>
|
||||||
|
|||||||