The Inkscape-exported cameleer-logo.svg in public/ is 1.5 MB —
loaded eagerly in the SiteHeader (32×32) and Hero (64×64), it was
the dominant hit on the homepage's largest-contentful-paint. The
relaunch's added above-the-fold DOM nudged Lighthouse perf from
0.95 to 0.92 and tipped CI's >=0.95 threshold red.
Switch all four SVG references to the pre-optimised PNG icons that
already ship in public/icons/:
- SiteHeader (32-displayed): /icons/cameleer-48.png (4.4 KB)
- Hero (64-displayed): /icons/cameleer-192.png (36 KB)
- SiteFooter (24-displayed): /icons/cameleer-32.png (2.4 KB)
- BaseLayout favicon link: drop the SVG, keep the existing
32 PNG fallback (already declared on the next line).
Local Lighthouse (http-server, no gzip) before: perf 0.72,
LCP 10.0s. After: perf 0.94, LCP 1.6s. CI on Linux + LH static
server should comfortably clear the 0.95 gate.
The SVG file itself is left in place — unreferenced, but kept in
case any external link still points at it.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
128 lines
4.4 KiB
Plaintext
128 lines
4.4 KiB
Plaintext
---
|
|
import CTAButtons from '../CTAButtons.astro';
|
|
import TopographicBg from '../TopographicBg.astro';
|
|
import Lightbox from '../Lightbox.astro';
|
|
|
|
interface Pin {
|
|
label: string;
|
|
body: string;
|
|
top: string;
|
|
left: string;
|
|
}
|
|
|
|
const pins: Pin[] = [
|
|
{ label: '01', body: 'Correlation ID — click to follow one exchange across services.', top: '14%', left: '12%' },
|
|
{ label: '02', body: 'Failure in context — circuit breaker tripped, fallback ran, tried backend:80.', top: '46%', left: '52%' },
|
|
{ label: '03', body: 'Full error pinned — exception, stack trace, headers, payload.', top: '78%', left: '78%' },
|
|
];
|
|
---
|
|
<section class="relative overflow-hidden border-b border-border">
|
|
<TopographicBg opacity={0.22} lines={11} />
|
|
<div class="relative max-w-content mx-auto px-6 pt-16 pb-20 md:pt-24 md:pb-24 lg:pt-28">
|
|
<div class="grid lg:grid-cols-12 gap-10 lg:gap-14 items-center">
|
|
<div class="lg:col-span-5">
|
|
<img
|
|
src="/icons/cameleer-192.png"
|
|
width="64"
|
|
height="64"
|
|
alt=""
|
|
decoding="async"
|
|
class="shrink-0 mb-5 hero-mark"
|
|
/>
|
|
<p
|
|
class="inline-flex items-center gap-2 mb-7 rounded-full border border-accent/30 bg-accent/[0.08] text-accent px-3.5 py-1 text-sm italic font-medium"
|
|
>
|
|
<span aria-hidden="true" class="text-base">✦</span>
|
|
Your camels called. They want a GPS.
|
|
</p>
|
|
<h1 class="font-bold text-text mb-6 hero-h1">
|
|
Ship Camel integrations. Sleep through the night.
|
|
</h1>
|
|
<p class="text-lg md:text-xl text-text-muted max-w-prose leading-relaxed mb-8">
|
|
Cameleer is the hosted runtime and observability platform for Apache Camel — auto-traced, replay-ready, cross-service correlated. The 3 AM page becomes a 30-second answer.
|
|
</p>
|
|
<CTAButtons
|
|
size="lg"
|
|
secondaryLabel="See it in action ↓"
|
|
secondaryHref="#walkthrough"
|
|
/>
|
|
<p class="mt-4 font-mono text-xs text-text-faint">
|
|
14-day trial · from €20/mo · no credit card
|
|
</p>
|
|
</div>
|
|
<div class="lg:col-span-7 relative">
|
|
<div class="hero-shot relative rounded-lg border border-border-strong bg-bg-elevated overflow-hidden">
|
|
<Lightbox
|
|
src="/product/exchange-detail.png"
|
|
alt="Cameleer Mission Control — route execution detail with processor-level trace"
|
|
width={1920}
|
|
height={945}
|
|
loading="eager"
|
|
/>
|
|
<div class="absolute inset-0 ring-1 ring-inset ring-accent/10 pointer-events-none rounded-lg"></div>
|
|
{pins.map((pin) => (
|
|
<span
|
|
aria-hidden="true"
|
|
class="hero-pin absolute inline-flex items-center justify-center w-7 h-7 rounded-full bg-accent text-bg font-mono text-xs font-bold pointer-events-none"
|
|
style={`top:${pin.top};left:${pin.left}`}
|
|
>
|
|
{pin.label}
|
|
</span>
|
|
))}
|
|
</div>
|
|
<ul class="hero-pin-legend mt-5 grid sm:grid-cols-3 gap-3 text-text-muted">
|
|
{pins.map((pin) => (
|
|
<li class="flex items-start gap-2 text-sm leading-snug">
|
|
<span class="font-mono text-accent text-xs mt-0.5">{pin.label}</span>
|
|
<span>{pin.body}</span>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
<div aria-hidden="true" class="hero-shot-glow"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<style>
|
|
.hero-h1 {
|
|
font-size: clamp(2.25rem, 4.5vw, 4rem);
|
|
line-height: 1.05;
|
|
letter-spacing: -0.02em;
|
|
}
|
|
.hero-shot {
|
|
box-shadow:
|
|
0 1px 0 rgba(240, 180, 41, 0.08) inset,
|
|
0 30px 60px -20px rgba(0, 0, 0, 0.6),
|
|
0 10px 25px -10px rgba(0, 0, 0, 0.5);
|
|
}
|
|
.hero-pin {
|
|
box-shadow: 0 0 0 4px rgba(240, 180, 41, 0.22), 0 4px 10px -2px rgba(0, 0, 0, 0.5);
|
|
transform: translate(-50%, -50%);
|
|
}
|
|
.hero-shot-glow {
|
|
position: absolute;
|
|
inset: 10% -5% 10% -5%;
|
|
background: radial-gradient(
|
|
60% 60% at 50% 50%,
|
|
rgba(240, 180, 41, 0.18),
|
|
transparent 70%
|
|
);
|
|
filter: blur(40px);
|
|
z-index: -1;
|
|
}
|
|
|
|
@keyframes hero-mark-sway {
|
|
0%, 100% { transform: translateY(0) rotate(0deg); }
|
|
50% { transform: translateY(-2px) rotate(-1.5deg); }
|
|
}
|
|
.hero-mark {
|
|
animation: hero-mark-sway 7s ease-in-out infinite;
|
|
transform-origin: 50% 90%;
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.hero-mark { animation: none; }
|
|
}
|
|
</style>
|