Commit Graph

64 Commits

Author SHA1 Message Date
hsiegeln
eff1ba6b8e feat(brand): swap header icon for real Cameleer logo
Placeholder 3-wavy-lines SVG replaced with the product logo
(camel + cameleer figure + compass rose).
2026-04-24 23:39:13 +02:00
hsiegeln
03573b2ac1 feat(brand): wire favicon chain to real product logo
SVG primary + 32px PNG fallback + Apple touch icon. Removes the
placeholder 3-wavy-lines favicon.
2026-04-24 23:38:12 +02:00
hsiegeln
6f0268ebea 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).
2026-04-24 23:37:04 +02:00
hsiegeln
2526b1f0fc docs: implementation plan for copy + brand refresh
13 tasks, each self-contained with exact file paths, final copy,
verification steps, and a commit at the end. Covers: logo + favicon
import (tasks 1-3), SEO meta (task 4), Hero static + rotating H1
(tasks 5-6), all five section copy rewrites (tasks 7-11), OG image
redesign (task 12), end-to-end verification (task 13). CSP-safe
rotation via Astro <script> bundling (script-src 'self' respected).
2026-04-24 23:34:38 +02:00
hsiegeln
01cf23f2f6 docs: copy + brand refresh spec — reposition as hosted Camel runtime
Reframe the homepage from "observability tool" to "hosted runtime platform
for Apache Camel with observability baked in" — matching what the product
actually is across cameleer, cameleer-server, and cameleer-saas.

- Thesis: "Run Apache Camel without running Apache Camel."
- Three rotating Hero positioning lines (slow fade, reduced-motion aware).
- Two strategic humor pops (Hero kicker + FinalCTA), rest stays serious.
- Drop implementation jargon (-javaagent, Docker, ByteBuddy, etc.) from
  the landing page; keep Camel-audience vocabulary (routes, processors,
  exchanges, replay).
- Replace placeholder topographic-wave icon with the real Cameleer product
  logo (camel + cameleer figure + compass rose) from design-system/assets.
- Section-by-section copy changes for Hero, DualValueProps, HowItWorks,
  WhyUs, PricingTeaser, FinalCTA.

No architecture changes; content + asset refresh only.
2026-04-24 23:28:10 +02:00
hsiegeln
3a1fe5f2c7 docs+ci: own security headers at Cloudflare, drop dead .htaccess path
All checks were successful
ci / build-test (push) Successful in 3m33s
Hetzner Webhosting L runs Apache with AllowOverride None on the
user docroot, so file-based .htaccess is silently ignored — directives
in public/.htaccess never applied. Confirmed via direct-origin tests:
neither Header, Rewrite, nor FilesMatch fired regardless of the file
being present and readable.

The only origin-side override path on this tier is konsoleH's per-
directory Serverkonfiguration UI, which writes to a separate Apache
config file outside the user's filesystem (and thus outside any
deploy pipeline).

Make the architecture honest:
- Delete public/.htaccess (dead code Apache never reads).
- Remove the "Copy .htaccess into dist" CI step (now a no-op).
- Update deploy.yml header comment to point at Cloudflare for headers.
- Update OPERATOR-CHECKLIST.md §1 with the three Webhosting-L gotchas:
  port 222 for SSH, SFTP_PATH must match the actual vhost docroot
  (default is bare public_html/), and AllowOverride None.
- Update §5 to reflect manual workflow_dispatch (no auto-deploy on
  push) and 5-header expectation.
- Update README.md deploy section likewise.

Headers (HSTS, CSP, XFO, X-Content-Type-Options, Referrer-Policy,
Permissions-Policy) are now owned by Cloudflare Transform Rules,
documented in OPERATOR-CHECKLIST.md §2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 23:04:09 +02:00
hsiegeln
d6851cd5aa Merge branch 'feat/initial-build' into main
All checks were successful
ci / build-test (push) Successful in 4m2s
Merge build+deploy jobs, switch to manual trigger only.
2026-04-24 21:24:44 +02:00
hsiegeln
ca2a725953 ci(deploy): merge build+deploy into one job, manual trigger only
All checks were successful
ci / build-test (push) Successful in 4m0s
Two changes:

1. Merge build and deploy jobs into a single 'deploy' job. This
   eliminates the actions/upload-artifact@v3 round-trip, which was
   silently stripping dotfiles (.htaccess) from the artifact and
   leaving the deployed origin without security headers. The built
   dist/ (including .htaccess) now flows directly into rsync in the
   same workspace.

2. Remove the 'push: branches: [main]' trigger so deploy runs only
   on workflow_dispatch (manual click in Gitea Actions UI).
   Merges to main no longer auto-deploy — production promotion is
   an explicit user action.

The concurrency group at workflow level still prevents overlapping
deploys. All secrets remain unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 21:24:42 +02:00
hsiegeln
fdb0411c35 Sync main into feat/initial-build before merge-jobs refactor 2026-04-24 21:23:58 +02:00
hsiegeln
461b5e0cd6 Merge branch 'feat/initial-build' into main
Some checks failed
deploy / build (push) Successful in 36s
deploy / deploy (push) Failing after 14s
ci / build-test (push) Successful in 3m54s
Copy public/.htaccess into dist after Astro build (Astro/Vite drops
dotfiles from public/ otherwise, leaving the origin without HSTS).

# Conflicts:
#	.gitea/workflows/deploy.yml
2026-04-24 21:09:35 +02:00
hsiegeln
0d743402ac ci(deploy): copy public/.htaccess into dist after build
All checks were successful
ci / build-test (push) Successful in 3m47s
Astro/Vite drops dotfiles from public/ during build, so .htaccess
never makes it into dist/. The deployed Apache origin then has no
header rules to apply, leaving the site without HSTS, X-Frame-Options,
Referrer-Policy, etc. — caught today by the post-deploy smoke test
("HSTS missing").

Copy the file explicitly after build. test -f makes the step fail
loudly if public/.htaccess goes missing, rather than silently
shipping a header-less site.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 21:08:51 +02:00
hsiegeln
28fcaf16c5 Merge branch 'feat/initial-build' into main
Some checks failed
ci / build-test (push) Successful in 4m2s
deploy / build (push) Successful in 30s
deploy / deploy (push) Failing after 13s
Revert to rsync, route through Hetzner's SSH port 222 (the shell port,
as opposed to port 22 which is SFTP-only).
2026-04-24 20:24:33 +02:00
hsiegeln
e3fbbbada7 ci(deploy): revert to rsync via SSH port 222 (Hetzner shell port)
All checks were successful
ci / build-test (push) Successful in 3m57s
Hetzner Webhosting exposes SSH on TWO ports:
  port 22  — SFTP only, refuses remote command exec
  port 222 — full SSH with shell, supports rsync

Previous deploys hit "exec request failed on channel 0" because we
were using port 22. Switch back from lftp to plain rsync, but route
it through port 222 with --rsync-path=/usr/bin/rsync (Hetzner's
locked-down PATH doesn't include rsync by default) and BatchMode=yes
to disable interactive prompts.

Mirrors the working local command:
  rsync -avz --rsync-path=/usr/bin/rsync \
    -e "ssh -p 222 -i ~/.ssh/id_ed25519_gitea -o BatchMode=yes" \
    ./ apibny@www691.your-server.de:/usr/www/users/apibny/www.cameleer.io

Keeps host-key pinning (StrictHostKeyChecking + UserKnownHostsFile)
which the local command omits because the user's personal known_hosts
already trusts the host.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 20:24:27 +02:00
hsiegeln
cb21be71f0 Merge branch 'feat/initial-build' into main
Some checks failed
ci / build-test (push) Successful in 3m55s
deploy / build (push) Successful in 28s
deploy / deploy (push) Failing after 12s
Fix lftp auth (explicit -u USER, + unindented heredoc body).
2026-04-24 20:08:29 +02:00
hsiegeln
5417565e34 ci(deploy): fix lftp auth — explicit empty password + unindented script
All checks were successful
ci / build-test (push) Successful in 4m0s
Two issues from the previous lftp run:
- "GetPass() failed -- assume anonymous login" / "Password required":
  without `-u USER,` (trailing comma = empty password), lftp tries
  to prompt for a password instead of relying on the ssh key passed
  via sftp:connect-program.
- Heredoc body was indented with leading whitespace; lftp can mis-
  parse leading-whitespace lines as command continuations.

Also bump verbosity (`debug 3`) so the ssh command lftp launches
is logged — makes the next failure easier to read — and bound
retries to 1 so we fail fast in CI.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 20:08:22 +02:00
hsiegeln
60813e44d9 Merge branch 'feat/initial-build' into main
Some checks failed
ci / build-test (push) Successful in 4m1s
deploy / build (push) Successful in 31s
deploy / deploy (push) Failing after 27s
Switch deploy from rsync-over-SSH to lftp mirror over SFTP —
Hetzner Webhosting is SFTP-only and refuses remote exec.
2026-04-24 19:49:54 +02:00
hsiegeln
64aa8f426b ci(deploy): switch from rsync to lftp mirror (SFTP-only hosting)
All checks were successful
ci / build-test (push) Successful in 3m55s
Hetzner Webhosting accepts SSH for file transfer but refuses remote
command exec, failing rsync with:

  exec request failed on channel 0
  rsync error: error in rsync protocol data stream (code 12)

rsync over SSH requires spawning a remote rsync binary, which isn't
possible on SFTP-only tiers. Switch the mirror to lftp, which speaks
SFTP end-to-end. Same semantics (upload + delete removed files), same
key + known_hosts pinning via sftp:connect-program.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 19:49:42 +02:00
hsiegeln
c438d67469 Merge branch 'feat/initial-build' into main
Some checks failed
deploy / build (push) Successful in 33s
ci / build-test (push) Successful in 4m18s
deploy / deploy (push) Failing after 13s
Brings in the CI infrastructure fixes:
- ci.yml: probe Chromium binary; fall back to Playwright (95977c8)
- tailwind: lift text-faint to meet WCAG AA contrast (2fde385)
- deploy.yml: pin artifact actions to v3 for Gitea (bbd68ec)
2026-04-24 19:12:55 +02:00
hsiegeln
bbd68eca1f ci(deploy): pin upload/download-artifact to v3 for Gitea Actions
All checks were successful
ci / build-test (push) Successful in 3m59s
actions/upload-artifact@v4 and download-artifact@v4 use the
@actions/artifact v2+ client, which targets a github.com-only
backend and fails on Gitea / Forgejo / GHES with:

  GHESNotSupportedError: @actions/artifact v2.0.0+, upload-artifact@v4+
  and download-artifact@v4+ are not currently supported on GHES.

Pin both to v3, which uses the older artifact protocol that Gitea
Actions implements.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 19:12:34 +02:00
bb6b8e63d7 .gitea/workflows/deploy.yml aktualisiert
Some checks failed
deploy / build (push) Failing after 32s
deploy / deploy (push) Has been skipped
ci / build-test (push) Failing after 57s
2026-04-24 19:04:16 +02:00
hsiegeln
2fde385ecf theme: lift text-faint to meet WCAG AA contrast
All checks were successful
ci / build-test (push) Successful in 3m39s
text-faint #6b7280 on bg #060a13 measures ~4.06:1 contrast — under the
4.5:1 normal-text threshold — which fails Lighthouse's color-contrast
audit and drops the accessibility score to 0.90 on /pricing and
/privacy (the only pages currently using this token).

#828b9b yields ~5.66:1, clears AA with margin, and stays visually
distinct from text-muted (#9aa3b2, ~7.8:1) so the design hierarchy
between text / text-muted / text-faint is preserved.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 18:57:40 +02:00
hsiegeln
95977c8d6c ci: probe Chromium binary, fall back to Playwright-bundled
Some checks failed
ci / build-test (push) Failing after 3m35s
The Ubuntu runner image ships /usr/bin/chromium-browser as a snap
forwarder stub that exits with "install via snap" when invoked but
is found on PATH. The previous detection used `command -v` only, so
it accepted the stub, set CHROME_PATH to it, and Lighthouse later
failed to launch Chrome (ECONNREFUSED on the debug port).

Probe each candidate with `--version` to confirm it actually runs.
When no working system binary exists, install Playwright's bundled
Chromium (supports linux/arm64) with --with-deps for system libs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 18:50:28 +02:00
b9b17df0ea .gitea/workflows/ci.yml aktualisiert
Some checks failed
ci / build-test (push) Failing after 2m12s
2026-04-24 18:25:52 +02:00
d772048fb4 .gitea/workflows/ci.yml aktualisiert
Some checks failed
ci / build-test (push) Has been cancelled
2026-04-24 18:10:49 +02:00
259871d34a Merge pull request 'feat/initial-build' (#3) from feat/initial-build into main
Some checks failed
ci / build-test (push) Failing after 1m3s
deploy / build (push) Failing after 51s
deploy / deploy (push) Has been skipped
Reviewed-on: #3
2026-04-24 18:09:37 +02:00
hsiegeln
295e2bcfff replaced TBD with TODO
Some checks failed
ci / build-test (push) Failing after 49s
ci / build-test (pull_request) Failing after 1m6s
2026-04-24 18:06:32 +02:00
hsiegeln
93131461b8 Fix CI build: read PUBLIC_* values from secrets context, broaden TODO guard
Some checks failed
ci / build-test (push) Failing after 46s
- Switch ci.yml + deploy.yml env bindings from ${{ vars.* }} to
  ${{ secrets.* }}. Gitea lets you put non-sensitive Actions values in
  either tab, and the secrets tab was used in practice — workflow was
  reading the wrong context and getting empty strings.
- Broaden the "no TODO markers ship" guard to accept both TODO: and
  legacy TBD: prefixes, matching the imprint/privacy page markers that
  were recently renamed.
- Document the secret-vs-variable choice in OPERATOR-CHECKLIST so the
  next operator doesn't get tripped up by the same thing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 18:04:16 +02:00
ba6069f14e Merge pull request 'replaced TBD with TODO' (#2) from feat/initial-build into main
Some checks failed
deploy / build (push) Has been cancelled
deploy / deploy (push) Has been cancelled
ci / build-test (push) Failing after 1m6s
Reviewed-on: #2
2026-04-24 18:00:52 +02:00
hsiegeln
9a4644bada replaced TBD with TODO
Some checks failed
ci / build-test (push) Failing after 51s
ci / build-test (pull_request) Failing after 1m4s
2026-04-24 17:58:49 +02:00
65667d9b50 Merge pull request 'feat/initial-build' (#1) from feat/initial-build into main
Some checks failed
ci / build-test (push) Failing after 1m4s
deploy / build (push) Failing after 33s
deploy / deploy (push) Has been skipped
Reviewed-on: #1
2026-04-24 17:56:09 +02:00
hsiegeln
7ecd1ff871 Split CI and deploy into separate workflows
Some checks failed
ci / build-test (push) Failing after 1m19s
ci / build-test (pull_request) Failing after 1m4s
- .gitea/workflows/ci.yml: builds, tests, lints, and runs Lighthouse on
  every push and PR to main. Runs on arm64 self-hosted Gitea runner.
- .gitea/workflows/deploy.yml: deploys to Hetzner on push to main or
  manual workflow_dispatch from Gitea UI. No Lighthouse (that's CI's
  job). Keeps the TBD-marker guard as a last-line safety check.

Both workflows live on the same concurrency group so no two deploys
race. On main push, CI and deploy run in parallel; CI is independent
and non-blocking for the deploy step.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 17:46:04 +02:00
hsiegeln
ea6267d6f7 Make CI arm64-runner-aware for Gitea self-hosted act_runner
Runner: self-hosted arm64. Deploy target: amd64 (Hetzner). Cross-arch is
safe because Astro output is plain static HTML/CSS/JS — nothing in the
bundle is arch-specific.

Changes:
- runs-on: ubuntu-latest (most portable act_runner label — override per your
  runner's registered labels if needed).
- Install Chromium from apt at workflow time (Google Chrome has no Linux/arm64
  stable build; Chromium does). Handles both chromium and chromium-browser
  package names, sudo-less runners, and idempotently skips if already present.
- Export CHROME_PATH so LHCI picks the right binary.
- Add chromeFlags to lighthouserc.cjs: --no-sandbox --headless=new
  --disable-gpu --disable-dev-shm-usage (required in containerized/root
  Chromium on CI runners).
- timeout-minutes on both jobs.
- Defense-in-depth install of rsync + openssh in deploy job if the runner
  image doesn't ship them.
- Null-guard SFTP_KEY and SFTP_KNOWN_HOSTS secrets.
- Switch echo to printf for deterministic newline handling when writing key
  material to ~/.ssh files.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 17:39:34 +02:00
hsiegeln
d98d73b14a Apply final-review cleanup: robots sitemap, CI guards, header parity
- Remove Sitemap line from robots.txt (no @astrojs/sitemap installed; was
  pointing to a 404 that would trip Google Search Console).
- Align Permissions-Policy across all three enforcement layers (middleware,
  .htaccess, Cloudflare Transform Rule in OPERATOR-CHECKLIST) by dropping the
  stray fullscreen=(self) from the middleware.
- Bump Lighthouse CI numberOfRuns from 1 to 3 to dampen CI-runner noise.
- Add CI guard that fails the build if any <TBD:...> marker survives into
  dist/ — prevents a legally incomplete imprint from shipping by accident.
- Add SFTP_* secret null-guard before the rsync --delete step so a missing
  secret fails loudly instead of targeting the SSH user's home root.
- Document the set:html compile-time-constant invariant in DualValueProps.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 17:34:27 +02:00
hsiegeln
7e0d341c89 Add README and operator checklist for Hetzner + Cloudflare + Gitea setup 2026-04-24 17:25:53 +02:00
hsiegeln
92bef08357 Add Gitea Actions workflow: build, test, lint, Lighthouse, rsync deploy with header smoke check 2026-04-24 17:25:02 +02:00
hsiegeln
cc7802e461 Add Lighthouse CI config with >=95 thresholds across 4 categories 2026-04-24 17:24:37 +02:00
hsiegeln
04a1bd0aaf Add CI lint configs (html-validate, linkinator), fix nav a11y and URL routing
- .htmlvalidate.json with relaxed rules for design-system inline styles
- linkinator.config.json skipping mail, external auth/platform origins
- Fix lint:html npm script quoting for Windows-shell compatibility
- Switch astro build.format to 'directory' so /pricing resolves without MultiViews
- trailingSlash: 'ignore' lets both /pricing and /pricing/ work naturally
- Add aria-label to both <nav> landmarks (Primary, Footer) to satisfy html-validate

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 17:24:21 +02:00
hsiegeln
dfb8419b08 Add .htaccess for origin hardening, HTTPS redirect, and cache headers 2026-04-24 17:22:25 +02:00
hsiegeln
ecbf1f90d7 Add privacy policy page (GDPR-aligned, no-cookies posture documented) 2026-04-24 17:21:56 +02:00
hsiegeln
07de57dda5 Add imprint page (TMG §5 / DDG §5 structure, operator fields marked <TBD>) 2026-04-24 17:21:17 +02:00
hsiegeln
d4449bb404 Add pricing page with 4-tier comparison cards 2026-04-24 17:20:21 +02:00
hsiegeln
6f70e1a642 Assemble homepage — Hero, DualValueProps, HowItWorks, WhyUs, PricingTeaser, FinalCTA 2026-04-24 17:19:47 +02:00
hsiegeln
94b9b844ac Add PricingTeaser section — 4 tier mini-cards linking to /pricing 2026-04-24 17:18:58 +02:00
hsiegeln
9795c633c9 Add WhyUs section — moat (zero-code, bidirectional) + team pedigree 2026-04-24 17:18:33 +02:00
hsiegeln
5af7e0079f Add HowItWorks section — 3-step engineer-facing walkthrough 2026-04-24 17:18:08 +02:00
hsiegeln
6f9e98aeb6 Add DualValueProps section — 3 tiles pairing outcomes with capabilities 2026-04-24 17:17:46 +02:00
hsiegeln
754333226b Add homepage Hero section — headline, subhead, CTAs, diagram 2026-04-24 17:17:24 +02:00
hsiegeln
6b27d8f013 Add RouteDiagram hero SVG: 2 Camel routes with cross-route correlation 2026-04-24 17:16:29 +02:00
hsiegeln
8b4b1ae699 Add shared building-block components: header, footer, CTAs, topographic background
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 17:14:58 +02:00
hsiegeln
e084177acf Add BaseLayout with meta tags, favicon, robots.txt, and OG card
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 17:13:07 +02:00