header pass

This commit is contained in:
Greg Kilmer
2026-07-04 16:40:02 -04:00
parent db6ff9f213
commit 1e8f5f1f01
13 changed files with 250 additions and 141 deletions
+32 -12
View File
@@ -16,13 +16,12 @@
import { useEffect, useRef } from 'react';
interface Props {
className?: string;
/**
* Opt-in View Transition name. Unset by default. The page should set this on
* AT MOST ONE element per page (the hero field). Applied via the `.vt-sky`
* CSS class to avoid an SSR/hydration mismatch with React's inline style.
* Tailwind/className passthrough. The .astro call site includes `vt-sky` when
* this element should carry the view-transition morph. Not computed here to
* avoid a server/client hydration mismatch (see AnimatedBackground).
*/
transitionName?: 'sky';
className?: string;
}
interface Trace {
@@ -38,7 +37,6 @@ interface Node {
export default function CircuitField({
className = '',
transitionName,
}: Props) {
const canvasRef = useRef<HTMLCanvasElement>(null);
@@ -228,13 +226,35 @@ export default function CircuitField({
};
}, []);
const skyClass = transitionName === 'sky' ? 'vt-sky' : '';
return (
<canvas
ref={canvasRef}
className={`pointer-events-none absolute inset-0 h-full w-full ${skyClass} ${className}`}
// Root container mirrors AnimatedBackground's structure (gradient layers +
// canvas all INSIDE the named element) so the view-transition morph from a
// star hero into this circuit field is element-to-element equivalent and
// nothing flashes separately. The `vt-sky`/opacity classes are passed via
// className from the .astro call site.
<div
className={`pointer-events-none absolute inset-0 -z-10 overflow-hidden ${className}`}
aria-hidden="true"
/>
>
{/* Base dark purple/blue gradient — the professional hero's atmosphere. */}
<div
className="absolute inset-0"
style={{
background:
'linear-gradient(160deg, #0a0e2a 0%, #14123a 38%, #1a1648 64%, #0e0c28 100%)',
}}
/>
{/* Animated violet/teal nebula clouds for depth + motion. */}
<div
className="animate-gradient-shift absolute inset-0"
style={{
backgroundImage:
'radial-gradient(50% 60% at 18% 20%, rgba(139, 123, 216, 0.28), transparent 62%), radial-gradient(45% 55% at 85% 15%, rgba(111, 182, 173, 0.16), transparent 60%), radial-gradient(55% 70% at 70% 110%, rgba(139, 123, 216, 0.20), transparent 60%)',
backgroundSize: '200% 200%',
}}
/>
{/* Circuit traces + nodes + signal pulses. */}
<canvas ref={canvasRef} className="absolute inset-0 h-full w-full" />
</div>
);
}