feat(design): atmosphere + WhyUs editorial 3-AM treatment
TopographicBg now actually reads: - Per-line stroke width varies (triangle wave — contour-interval feel) - Per-line opacity varies by vertical depth (darker mid-section, lighter edges) - One line in four rendered in cyan (echo of cross-route correlation) - Radial-mask soft edge fade so lines dissolve into the section boundary - Default opacity bumped from 0.12 to 0.35; section callers still scale it down via the opacity prop, but the new internal variation makes the atmosphere visible where before it was invisible WhyUs second tile: 3-AM storytelling moment now lands typographically: - Decorative 03:00 glyph (amber/4% alpha) in the top-right corner - Eyebrow log-entry treatment: pulsing amber dot + mono 03:00:47.218 timestamp + OPS DESK label — reads like a product UI log row - The rest of the tile unchanged ProductShowcase figure: figcaption moved to last child (HTML spec requires figcaption to be first or last in a figure; a div after it was a validation error).
This commit is contained in:
@@ -3,24 +3,66 @@ interface Props {
|
|||||||
opacity?: number;
|
opacity?: number;
|
||||||
lines?: number;
|
lines?: number;
|
||||||
}
|
}
|
||||||
const { opacity = 0.12, lines = 8 } = Astro.props;
|
const { opacity = 0.35, lines = 9 } = Astro.props;
|
||||||
|
|
||||||
const paths: string[] = [];
|
interface Line {
|
||||||
|
d: string;
|
||||||
|
width: number; // stroke width in CSS px (non-scaling)
|
||||||
|
lineOpacity: number; // per-line opacity (0..1) — varies depth
|
||||||
|
tone: 'amber' | 'cyan';
|
||||||
|
}
|
||||||
|
|
||||||
|
const out: Line[] = [];
|
||||||
const stepY = 100 / (lines + 1);
|
const stepY = 100 / (lines + 1);
|
||||||
for (let i = 1; i <= lines; i++) {
|
for (let i = 1; i <= lines; i++) {
|
||||||
const y = i * stepY;
|
const y = i * stepY;
|
||||||
const amp = 4 + (i % 3) * 2;
|
// Mix two frequencies so adjacent lines don't read parallel.
|
||||||
paths.push(`M0,${y} Q25,${y - amp} 50,${y + amp * 0.6} T100,${y}`);
|
const amp = 3 + (i % 3) * 2 + Math.sin(i * 1.7) * 1.2;
|
||||||
|
const phase = (i * 13) % 25; // shift crests horizontally
|
||||||
|
const d = `M0,${y} Q${25 + phase / 3},${y - amp} ${50 + phase / 5},${y + amp * 0.6} T100,${y + (i % 2 ? 1 : -1)}`;
|
||||||
|
// Vary stroke weight with a triangle wave — gives the feel of cartographic contour intervals.
|
||||||
|
const triangle = Math.abs(((i + 2) % 4) - 2) / 2;
|
||||||
|
const width = 0.6 + triangle * 0.9;
|
||||||
|
// Depth: middle lines darker, edges lighter.
|
||||||
|
const depth = 1 - Math.abs((i - (lines + 1) / 2)) / ((lines + 1) / 2);
|
||||||
|
const lineOpacity = 0.35 + depth * 0.65;
|
||||||
|
// One cyan line roughly every 4th — echo of the cross-route correlation color.
|
||||||
|
const tone: 'amber' | 'cyan' = i % 4 === 2 ? 'cyan' : 'amber';
|
||||||
|
out.push({ d, width, lineOpacity, tone });
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
<svg
|
<div
|
||||||
class="absolute inset-0 w-full h-full pointer-events-none"
|
class="topo-wrap absolute inset-0 pointer-events-none"
|
||||||
|
aria-hidden="true"
|
||||||
|
style={`--topo-opacity:${opacity}`}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="topo-svg absolute inset-0 w-full h-full"
|
||||||
viewBox="0 0 100 100"
|
viewBox="0 0 100 100"
|
||||||
preserveAspectRatio="none"
|
preserveAspectRatio="none"
|
||||||
aria-hidden="true"
|
>
|
||||||
style={`opacity:${opacity}`}
|
<g fill="none" vector-effect="non-scaling-stroke" stroke-linecap="round">
|
||||||
>
|
{out.map((l) => (
|
||||||
<g fill="none" stroke="#f0b429" stroke-width="0.15" vector-effect="non-scaling-stroke">
|
<path
|
||||||
{paths.map((d) => <path d={d} />)}
|
d={l.d}
|
||||||
|
stroke={l.tone === 'cyan' ? '#5cc8ff' : '#f0b429'}
|
||||||
|
stroke-width={l.width}
|
||||||
|
stroke-opacity={l.lineOpacity}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.topo-wrap {
|
||||||
|
opacity: var(--topo-opacity, 0.35);
|
||||||
|
/* Soft edge fade — lines should feel like they dissolve at the section
|
||||||
|
boundaries rather than hit them hard. */
|
||||||
|
-webkit-mask-image: radial-gradient(ellipse at 50% 45%, black 55%, transparent 95%);
|
||||||
|
mask-image: radial-gradient(ellipse at 50% 45%, black 55%, transparent 95%);
|
||||||
|
}
|
||||||
|
.topo-svg {
|
||||||
|
filter: blur(0.15px);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -48,8 +48,8 @@ const callouts: Callout[] = [
|
|||||||
/>
|
/>
|
||||||
<div class="absolute inset-0 ring-1 ring-inset ring-accent/10 pointer-events-none rounded-lg"></div>
|
<div class="absolute inset-0 ring-1 ring-inset ring-accent/10 pointer-events-none rounded-lg"></div>
|
||||||
</div>
|
</div>
|
||||||
<figcaption class="sr-only">Screenshot of a failed exchange in Cameleer, showing the full execution graph, fallback path, and exception context.</figcaption>
|
|
||||||
<div aria-hidden="true" class="showcase-shot-glow"></div>
|
<div aria-hidden="true" class="showcase-shot-glow"></div>
|
||||||
|
<figcaption class="sr-only">Screenshot of a failed exchange in Cameleer, showing the full execution graph, fallback path, and exception context.</figcaption>
|
||||||
</figure>
|
</figure>
|
||||||
|
|
||||||
<ul class="lg:col-span-4 space-y-7 lg:pt-4">
|
<ul class="lg:col-span-4 space-y-7 lg:pt-4">
|
||||||
|
|||||||
@@ -20,7 +20,23 @@
|
|||||||
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.
|
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 transition-all duration-200 ease-out hover:-translate-y-0.5 hover:border-accent/40 hover:shadow-[0_12px_32px_-12px_rgba(240,180,41,0.18)]">
|
<div class="relative overflow-hidden rounded-lg border border-border bg-bg-elevated p-8 transition-all duration-200 ease-out hover:-translate-y-0.5 hover:border-accent/40 hover:shadow-[0_12px_32px_-12px_rgba(240,180,41,0.18)]">
|
||||||
|
<div
|
||||||
|
aria-hidden="true"
|
||||||
|
class="pointer-events-none select-none absolute -top-6 -right-4 font-mono font-bold leading-none tracking-tight text-accent/[0.04] text-[7rem] md:text-[9rem]"
|
||||||
|
>
|
||||||
|
03:00
|
||||||
|
</div>
|
||||||
|
<div class="relative">
|
||||||
|
<div class="flex items-center gap-2.5 mb-5 font-mono text-xs">
|
||||||
|
<span aria-hidden="true" class="relative inline-flex w-1.5 h-1.5">
|
||||||
|
<span class="absolute inset-0 rounded-full bg-accent"></span>
|
||||||
|
<span class="absolute inset-0 rounded-full bg-accent/60 animate-ping [animation-duration:2.4s]"></span>
|
||||||
|
</span>
|
||||||
|
<span class="text-accent tabular-nums tracking-wide">03:00:47.218</span>
|
||||||
|
<span class="text-text-faint">·</span>
|
||||||
|
<span class="text-text-faint uppercase tracking-[0.2em]">ops desk</span>
|
||||||
|
</div>
|
||||||
<h3 class="text-xl font-bold text-text mb-4">Built by people who know what 3 AM looks like.</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">
|
||||||
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.
|
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.
|
||||||
@@ -31,4 +47,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
Reference in New Issue
Block a user