nav hover: glow instead of the underline bar, and give keyboard focus the same glow
build-and-deploy / build (push) Failing after 11m32s
build-and-deploy / build (push) Failing after 11m32s
This commit is contained in:
@@ -27,7 +27,7 @@ const links = [
|
||||
target={l.external ? "_blank" : undefined}
|
||||
rel={l.external ? "noopener noreferrer" : undefined}
|
||||
>
|
||||
{l.label}<span class="nav__ul" aria-hidden="true"></span>
|
||||
{l.label}
|
||||
</a>
|
||||
))}
|
||||
</nav>
|
||||
@@ -98,21 +98,12 @@ const links = [
|
||||
color: var(--text);
|
||||
text-decoration: none;
|
||||
}
|
||||
/* Hover underline - scaleX sprung by the Motion layer, growing from the
|
||||
start of the label. No scroll-spy: it tracked the active section as you
|
||||
scrolled, which read as clunky on a page this short. */
|
||||
.nav__ul {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: -0.45rem;
|
||||
height: 2px;
|
||||
border-radius: 2px;
|
||||
background: linear-gradient(90deg, var(--accent), var(--accent-2));
|
||||
box-shadow: 0 0 8px var(--accent-glow);
|
||||
transform: scaleX(0);
|
||||
transform-origin: 0 50%;
|
||||
pointer-events: none;
|
||||
/* Hover = glow, not an underline (owner call 2026-08-18: the bar read as clunky).
|
||||
Keyboard focus gets the same treatment so the affordance is not mouse-only. */
|
||||
.nav__links a:hover,
|
||||
.nav__links a:focus-visible {
|
||||
color: var(--accent);
|
||||
text-shadow: 0 0 10px var(--accent-glow), 0 0 22px var(--accent-glow);
|
||||
}
|
||||
.nav__actions {
|
||||
display: flex;
|
||||
|
||||
+1
-22
@@ -84,32 +84,11 @@ function run(): void {
|
||||
}
|
||||
|
||||
/* 5. Nav - animated active-section underline + tactile hover. */
|
||||
initNav();
|
||||
|
||||
/* 6. Buttons - spring lift on hover, press on tap. */
|
||||
/* Buttons - spring lift on hover, press on tap. (Nav hover is pure CSS glow now.) */
|
||||
initButtons();
|
||||
}
|
||||
|
||||
function initNav(): void {
|
||||
const links = Array.from(
|
||||
document.querySelectorAll<HTMLAnchorElement>(".nav__links a"),
|
||||
);
|
||||
if (!links.length) return;
|
||||
|
||||
const spring = { type: "spring", stiffness: 380, damping: 30 } as const;
|
||||
|
||||
const under = (a: HTMLAnchorElement, on: boolean): void => {
|
||||
const ul = a.querySelector<HTMLElement>(".nav__ul");
|
||||
if (!ul) return;
|
||||
animate(ul, { scaleX: on ? 1 : 0 }, spring);
|
||||
};
|
||||
|
||||
for (const a of links) {
|
||||
a.addEventListener("pointerenter", () => under(a, true));
|
||||
a.addEventListener("pointerleave", () => under(a, false));
|
||||
}
|
||||
}
|
||||
|
||||
function initButtons(): void {
|
||||
const lift = { type: "spring", stiffness: 400, damping: 26 } as const;
|
||||
const tap = { type: "spring", stiffness: 600, damping: 22 } as const;
|
||||
|
||||
Reference in New Issue
Block a user