feat(ui): electric Bat-Computer redesign — cyan→magenta theme
build-and-deploy / build (push) Failing after 11m29s

Cinematic full-page backdrop: per-theme Bat-Computer board image,
scroll-panned (S→E→SE→NE) via CSS scroll-driven animation behind a
legibility scrim — replaces the grid/aura motif.

- Accent retuned royal-blue → the board's cyan→magenta; headline runs a
  cyan→magenta electric sweep; gradient primary CTA + scroll-progress line.
- Display face: self-hosted Chakra Petch (OFL) on hero + section titles.
- Skill chips reworked as circuit-node chips (glowing via + gradient hover
  outline); frosted-glass cards with a cyan→magenta hover hairline; section
  eyebrows get a gradient tick.
- Remove unused BackgroundGrid component + grid assets.

All CSS-only / zero external requests / no inline JS — strict CSP and A+
security headers preserved.
This commit is contained in:
2026-06-27 20:31:48 +10:00
parent d64f528ff7
commit 03b0cf7c7f
12 changed files with 400 additions and 91 deletions
-67
View File
@@ -1,67 +0,0 @@
---
// Cheap, CSS-only topology motif: a faint grid + slow-drifting accent glows.
// No canvas, no WebGL, no JS. Fully disabled under prefers-reduced-motion.
---
<div class="bg" aria-hidden="true">
<div class="bg__grid"></div>
<div class="bg__glow bg__glow--a"></div>
<div class="bg__glow bg__glow--b"></div>
</div>
<style>
.bg {
position: absolute;
inset: 0;
overflow: hidden;
z-index: 0;
pointer-events: none;
}
.bg__grid {
position: absolute;
inset: -2px;
background-image:
linear-gradient(to right, var(--grid-line) 1px, transparent 1px),
linear-gradient(to bottom, var(--grid-line) 1px, transparent 1px);
background-size: 46px 46px;
/* Fade the grid out toward the edges so it reads as a motif, not a table. */
mask-image: radial-gradient(120% 90% at 50% 0%, #000 35%, transparent 78%);
-webkit-mask-image: radial-gradient(120% 90% at 50% 0%, #000 35%, transparent 78%);
}
.bg__glow {
position: absolute;
width: 46rem;
height: 46rem;
border-radius: 50%;
filter: blur(60px);
opacity: 0.5;
}
.bg__glow--a {
top: -22rem;
left: -10rem;
background: radial-gradient(circle, var(--accent-glow), transparent 62%);
animation: drift-a 26s var(--ease) infinite alternate;
}
.bg__glow--b {
top: -16rem;
right: -14rem;
background: radial-gradient(circle, var(--accent-glow), transparent 65%);
opacity: 0.35;
animation: drift-b 32s var(--ease) infinite alternate;
}
@keyframes drift-a {
to {
transform: translate(6rem, 4rem) scale(1.12);
}
}
@keyframes drift-b {
to {
transform: translate(-5rem, 3rem) scale(1.08);
}
}
@media (prefers-reduced-motion: reduce) {
.bg__glow {
animation: none;
}
}
</style>
+31 -5
View File
@@ -1,11 +1,9 @@
---
import BackgroundGrid from "./BackgroundGrid.astro";
import { site } from "../data/site";
import { cvAvailable } from "../lib/assets";
---
<section class="hero">
<BackgroundGrid />
<div class="container hero__inner">
<p class="eyebrow hero__eyebrow">{site.role}</p>
@@ -53,16 +51,32 @@ import { cvAvailable } from "../lib/assets";
margin-bottom: var(--space-4);
}
.hero__title {
font-family: var(--font-display);
font-size: var(--step-5);
line-height: 1.12;
letter-spacing: -0.03em;
/* Chakra Petch is geometric/wide — looser tracking than Inter's -0.03em. */
letter-spacing: -0.005em;
/* Extend the paint box below the baseline so background-clip:text doesn't
crop glyph descenders (the "g" in Wright). */
padding-bottom: 0.14em;
background: linear-gradient(180deg, var(--text), color-mix(in srgb, var(--text) 62%, var(--accent)));
/* Electric kinetic fill: light text with a cyan→magenta band — the same
sweep as the Bat-Computer board — gliding across once on load (heroSheen)
over an electric halo, tying the headline into the backdrop. */
background: linear-gradient(
100deg,
var(--text) 0%,
var(--text) 34%,
var(--accent) 46%,
var(--accent-2) 56%,
var(--text) 66%,
var(--text) 100%
);
background-size: 230% 100%;
background-position: 130% 0;
-webkit-background-clip: text;
background-clip: text;
color: transparent;
filter: drop-shadow(0 0 26px var(--accent-glow));
}
.hero__positioning {
margin-top: var(--space-5);
@@ -103,8 +117,11 @@ import { cvAvailable } from "../lib/assets";
.hero__cta {
animation: heroIn 0.7s var(--ease) both;
}
/* Entrance + a one-shot electric sheen sweeping across the name. */
.hero__title {
animation-delay: 0.06s;
animation:
heroIn 0.7s var(--ease) 0.06s both,
heroSheen 1.6s var(--ease) 0.7s both;
}
.hero__positioning {
animation-delay: 0.14s;
@@ -126,4 +143,13 @@ import { cvAvailable } from "../lib/assets";
transform: none;
}
}
/* A bright royal band sweeps left→right across the glyphs, then rests. */
@keyframes heroSheen {
from {
background-position: 130% 0;
}
to {
background-position: 0% 0;
}
}
</style>
+16
View File
@@ -25,11 +25,27 @@ const { id, eyebrow, title, index } = Astro.props;
.section__head {
margin-bottom: var(--space-6);
}
/* A short cyan→magenta tick leads each section eyebrow — board palette. */
.section__head .eyebrow {
display: inline-flex;
align-items: center;
gap: 0.6rem;
}
.section__head .eyebrow::before {
content: "";
width: 1.7rem;
height: 2px;
border-radius: 2px;
background: linear-gradient(90deg, var(--accent), var(--accent-2));
box-shadow: 0 0 8px var(--accent-glow);
}
.section__index {
color: var(--text-faint);
margin-right: 0.6rem;
}
.section__title {
font-family: var(--font-display);
letter-spacing: -0.01em;
margin-top: var(--space-3);
font-size: var(--step-3);
max-width: 22ch;
+50 -1
View File
@@ -10,7 +10,9 @@ const { group } = Astro.props;
<h3 class="skill__title">{group.title}</h3>
<p class="skill__blurb">{group.blurb}</p>
<ul class="skill__items">
{group.items.map((item) => <li class="tag">{item}</li>)}
{group.items.map((item) => (
<li class="chip"><span class="chip__node" aria-hidden="true"></span>{item}</li>
))}
</ul>
</article>
@@ -40,6 +42,53 @@ const { group } = Astro.props;
margin: var(--space-2) 0 0;
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
/* Circuit-node chips — a glowing cyan→magenta node + mono label, wired to the
board palette. Gradient border via padding-box/border-box layering so the
radius survives. Lights to a full gradient outline + glow on hover. */
.chip {
--chip-grad: linear-gradient(100deg, var(--accent), var(--accent-2));
display: inline-flex;
align-items: center;
gap: 0.45rem;
font-family: var(--font-mono);
font-size: 0.72rem;
letter-spacing: 0.01em;
color: var(--text-dim);
padding: 0.3rem 0.62rem 0.3rem 0.55rem;
border-radius: 7px;
border: 1px solid var(--accent-line);
background: color-mix(in srgb, var(--surface-2) 88%, var(--accent) 12%);
transition: color 0.2s var(--ease), transform 0.2s var(--ease),
border-color 0.2s var(--ease), box-shadow 0.2s var(--ease),
background 0.2s var(--ease);
}
/* The node: a small cyan→magenta square that glows, like a lit via/pad. */
.chip__node {
flex: none;
width: 6px;
height: 6px;
border-radius: 2px;
background: var(--chip-grad);
box-shadow: 0 0 7px var(--accent-glow);
}
.chip:hover {
color: var(--text);
transform: translateY(-1px);
border-color: transparent;
/* dark fill (padding-box) inside a live gradient border (border-box) */
background: linear-gradient(var(--surface-2), var(--surface-2)) padding-box,
var(--chip-grad) border-box;
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.32), 0 0 16px var(--accent-glow);
}
@media (prefers-reduced-motion: reduce) {
.chip {
transition: none;
}
.chip:hover {
transform: none;
}
}
</style>