Replay the loader logo animation on hover; narrow hero text

- Extract the logo into an inline-SVG LogoMark shared by the loader and
  the site logo; one CSS animation driven by `.is-animating`
- Hovering/focusing the logo redraws it from a faint ghost and runs one
  wave along the facets; a replay always finishes and can't restart
  midway; skipped for reduced motion
- Cap hero subtitles (inner pages + home intro) at 36rem with pretty
  wrapping so the About hero no longer runs across half the screen

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-11-05 07:33:42 +01:00
co-authored by Claude Opus 5.5
parent c3514d2607
commit eb08226343
6 changed files with 161 additions and 64 deletions
+41 -16
View File
@@ -152,13 +152,8 @@ html.motion.loader-leaving .page-loader {
transition-duration: 0.32s, 0s;
}
/* -- the logo -- */
.page-loader-logo {
--d0: 0.1s; /* start offset for the whole sequence */
width: 56px;
height: auto;
overflow: visible;
color: #fff;
--d0: 0.1s;
transition:
opacity 0.45s ease,
transform 0.7s cubic-bezier(0.65, 0, 0.35, 1);
@@ -174,27 +169,56 @@ html.loader-leaving .page-loader-logo {
opacity: 0;
}
.pl-shape {
/* ---- Logo mark (see src/components/general/LogoMark.tsx) ----
Solid by default; `.is-animating` plays the sequence. Tunables:
--d0 start offset, --pl-stroke outline width (viewBox units, so raise it
for small renders), --pl-fill-from starting fill (0 = draws from nothing),
--pl-waves how many times the wave runs. */
.logo-mark {
--d0: 0s;
--pl-stroke: 9;
--pl-fill-from: 0;
--pl-waves: infinite;
height: auto;
overflow: visible;
color: #fff;
}
.logo-mark .pl-shape {
fill: currentColor;
fill-opacity: 0;
}
/* Nav logo on hover: redraw from a faint ghost, one wave. */
.logo-mark--hover {
--pl-stroke: 26;
--pl-fill-from: 0.15;
--pl-waves: 1;
}
.logo-mark.is-animating .pl-shape {
fill-opacity: var(--pl-fill-from);
stroke: currentColor;
stroke-width: 9;
stroke-width: var(--pl-stroke);
stroke-linejoin: round;
stroke-dasharray: 1 1;
stroke-dashoffset: 1;
}
/* 1. the "B" draws itself in, then fills */
.pl-letter {
.logo-mark.is-animating .pl-letter {
animation:
pl-draw 1s cubic-bezier(0.65, 0, 0.35, 1) var(--d0) forwards,
pl-fill 0.55s ease calc(var(--d0) + 0.65s) forwards;
}
/* 2. the facets trace in and rise into place, left → right */
.pl-facet .pl-shape {
.logo-mark .pl-facet,
.logo-mark .pl-facet .pl-shape {
transform-box: fill-box;
transform-origin: center;
}
.logo-mark.is-animating .pl-facet .pl-shape {
animation:
pl-draw 0.6s ease-out calc(var(--d0) + 0.45s + var(--i) * 0.08s)
forwards,
@@ -204,12 +228,10 @@ html.loader-leaving .page-loader-logo {
calc(var(--d0) + 0.45s + var(--i) * 0.08s) both;
}
/* 3. while waiting: a signal runs along the facets */
.pl-facet {
transform-box: fill-box;
transform-origin: center;
/* 3. a signal runs along the facets */
.logo-mark.is-animating .pl-facet {
animation: pl-wave 1.8s ease-in-out
calc(var(--d0) + 1.35s + var(--i) * 0.11s) infinite;
calc(var(--d0) + 1.35s + var(--i) * 0.11s) var(--pl-waves);
}
@keyframes pl-draw {
@@ -219,6 +241,9 @@ html.loader-leaving .page-loader-logo {
}
@keyframes pl-fill {
from {
fill-opacity: var(--pl-fill-from);
}
to {
fill-opacity: 1;
}