Put the NGU dove at the centre of the brand hero's rings
DoveMark carries the dove path from the original home page as its own component. The hero draws it at the rings' centre, upright while they turn, with a soft glow and a gentle bob that stops under reduced motion. The rings' opacity moves from the SVG to their own group so the dove isn't dimmed with them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
6a69084de2
commit
641ab167b0
3 changed files with 75 additions and 11 deletions
30
src/components/DoveMark.tsx
Normal file
30
src/components/DoveMark.tsx
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/* ═══════════════════════════════════════════════════════════════
|
||||
DOVE MARK
|
||||
|
||||
NGU's dove, lifted from the original home page. The path and its
|
||||
two transforms are the drawing as exported, untouched; only the
|
||||
wrapper changed — sized by the caller, coloured by currentColor,
|
||||
and hidden from screen readers since it's decoration wherever
|
||||
it appears.
|
||||
|
||||
Renders as an <svg> element, so it nests inside another SVG as
|
||||
well as in HTML: pass x, y, width and height to place it in a
|
||||
parent viewBox.
|
||||
═══════════════════════════════════════════════════════════════ */
|
||||
|
||||
import type { SVGProps } from 'react'
|
||||
|
||||
const PATH =
|
||||
'm 355.91146,-123.11955 c 3.13369,-1.59928 7.04147,-4.49077 10.29591,-6.33595 3.25443,-1.84519 6.30899,-3.58417 9.61426,-4.20523 2.65302,-0.4889 6.37319,-0.18817 9.07211,0.58357 2.69896,0.77175 5.57299,2.70484 7.16593,3.40762 1.59295,0.70275 2.24655,0.19006 2.82855,-0.77494 0.582,-0.96504 2.81839,-6.05064 3.84362,-8.9293 1.02519,-2.87864 2.26409,-5.72337 4.14553,-7.76121 1.88144,-2.03782 2.31893,-2.07776 4.06202,-3.15865 1.74307,-1.08086 10.24244,-3.71628 14.53403,-5.61581 4.29158,-1.89953 8.11957,-3.58996 12.24067,-5.48028 4.12109,-1.89033 6.08861,-2.79441 7.30709,-3.29554 0.273,0.73801 -0.2034,3.06663 -1.16031,5.22317 -0.95691,2.15654 -2.9569,5.04357 -4.86279,7.26365 -1.90589,2.22009 -4.28775,4.10342 -6.82223,5.66812 -2.53448,1.56467 -4.53981,2.45823 -7.60439,3.71266 -3.06457,1.25446 -11.88915,4.7102 -14.64698,7.12005 -2.75786,2.40984 -4.18313,6.63212 -3.64772,7.60115 0.5354,0.96902 2.51391,-1.48598 3.81084,-2.34867 1.29694,-0.8627 1.95172,-1.05814 3.14897,-1.09198 1.17765,-0.0172 2.77532,0.40067 3.29849,0.63293 1.48441,0.659 3.97438,2.00122 3.54176,3.36038 -0.16368,0.51434 -0.19462,0.56904 -3.05611,1.25841 -2.86151,0.68935 -3.48508,1.29579 -3.81533,3.74861 -0.22097,1.47094 -1.44719,3.88743 -3.13317,5.28015 -1.68596,1.39274 -4.55099,2.93627 -8.41717,3.35482 -3.86617,0.41855 -6.17544,3.97192 -6.93256,5.37259 -0.75713,1.40064 -2.66104,5.90506 -2.99685,6.15238 -0.3358,0.24732 -2.76998,-0.36582 -3.79458,-0.82517 -1.02463,-0.45935 -2.612,-1.39111 -3.63624,-2.16132 -1.02425,-0.7702 -3.457,-2.975 -3.0018,-3.64018 0.45519,-0.66516 1.56543,-1.35445 2.73515,-2.12254 1.16972,-0.76811 3.86984,-2.33631 5.3456,-3.59002 1.47576,-1.25372 2.7334,-2.47754 3.4042,-3.48323 0.67079,-1.00567 0.9358,-2.14286 -0.28206,-2.7388 -1.21786,-0.59597 -1.84092,-0.39835 -4.4486,0.0225 -2.60769,0.42097 -4.8218,1.10142 -8.46858,1.9005 -3.64678,0.79905 -7.82786,2.49393 -10.97221,3.07304 -3.14439,0.5791 -4.3363,0.83756 -8.5197,0.95691 -4.1834,0.11935 -7.15938,-0.35864 -8.95468,-0.91763 -1.7953,-0.55899 -2.64147,-1.55556 -2.60415,-2.17667 3.90737,-1.58574 7.9469,-3.2841 11.38348,-5.04009 z'
|
||||
|
||||
export default function DoveMark(props: SVGProps<SVGSVGElement>) {
|
||||
return (
|
||||
<svg viewBox="0 0 72.867699 48.568241" aria-hidden="true" focusable="false" {...props}>
|
||||
<g transform="translate(-70.490069,-117.83965)">
|
||||
<g transform="matrix(0.71532587,0,0,0.71532587,-173.91758,237.73112)">
|
||||
<path d={PATH} fill="currentColor" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
|
@ -4,7 +4,8 @@
|
|||
The top of the front page, in whichever mode the admin set:
|
||||
|
||||
brand drifting colour and slow concentric rings — many
|
||||
circles, one centre — behind the words
|
||||
circles, one centre — behind the words, with the
|
||||
dove at that centre
|
||||
photos the hero photos, crossfading with a slow zoom, a
|
||||
progress bar per photo and a pause button (anything
|
||||
that moves on its own for more than five seconds
|
||||
|
|
@ -24,6 +25,7 @@
|
|||
import { useEffect, useState, type CSSProperties } from 'react'
|
||||
|
||||
import HomeLink from './HomeLink.tsx'
|
||||
import DoveMark from '../../../components/DoveMark.tsx'
|
||||
import { livestreamEmbedUrl } from '../../../lib/embeds.ts'
|
||||
import { heroPhoto } from '../../../lib/media.ts'
|
||||
import type { Hero, HeroSlide } from '../../../lib/useFrontPage.ts'
|
||||
|
|
@ -157,9 +159,19 @@ function BrandBackdrop() {
|
|||
<div className="hp-aurora hp-aurora--c" style={blob('#d8b64a', '30vw', '70%', '-5%')} />
|
||||
|
||||
<svg
|
||||
className="absolute -right-[20vw] top-1/2 h-[120vw] w-[120vw] -translate-y-1/2 opacity-[0.16] md:-right-[10vw] md:h-[80vw] md:w-[80vw]"
|
||||
className="absolute -right-[20vw] top-1/2 h-[120vw] w-[120vw] -translate-y-1/2 md:-right-[10vw] md:h-[80vw] md:w-[80vw]"
|
||||
viewBox="0 0 400 400"
|
||||
>
|
||||
<defs>
|
||||
<radialGradient id="hp-dove-glow">
|
||||
<stop offset="0%" stopColor="#9fe7d0" stopOpacity="0.35" />
|
||||
<stop offset="100%" stopColor="#9fe7d0" stopOpacity="0" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
|
||||
{/* The rings are faint; the dove at their centre is not, so
|
||||
the opacity sits on the rings rather than the whole SVG. */}
|
||||
<g opacity="0.16">
|
||||
<g className="hp-rings" fill="none" stroke="#ffffff">
|
||||
{[40, 70, 100, 130, 160, 190].map((r, i) => (
|
||||
<circle key={r} cx="200" cy="200" r={r} strokeWidth={i % 2 ? 0.6 : 1.2} strokeDasharray={i % 2 ? '2 6' : undefined} />
|
||||
|
|
@ -171,6 +183,15 @@ function BrandBackdrop() {
|
|||
<circle cx="200" cy="200" r="115" strokeWidth="0.8" strokeDasharray="1 10" />
|
||||
<circle cx="85" cy="200" r="3.5" fill="#ffffff" stroke="none" />
|
||||
</g>
|
||||
</g>
|
||||
|
||||
{/* Outside the rotating groups, so it stays upright while the
|
||||
rings turn around it. 64 × 42.7 at the centre fits inside
|
||||
the innermost ring (r 40) with room to float. */}
|
||||
<circle cx="200" cy="200" r="46" fill="url(#hp-dove-glow)" />
|
||||
<g className="hp-dove" style={{ color: '#ffffff' }} opacity="0.9">
|
||||
<DoveMark x="168" y="178.65" width="64" height="42.7" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -44,6 +44,18 @@
|
|||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
/* The dove at the rings' centre bobs gently rather than turning. */
|
||||
.hp-dove {
|
||||
animation: hp-bob 6s ease-in-out infinite;
|
||||
transform-box: fill-box;
|
||||
transform-origin: center;
|
||||
}
|
||||
|
||||
@keyframes hp-bob {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-4px); }
|
||||
}
|
||||
|
||||
/* ── Hero: headline words rise in ────────────────────────────── */
|
||||
|
||||
.hp-rise {
|
||||
|
|
@ -137,6 +149,7 @@
|
|||
@media (prefers-reduced-motion: reduce) {
|
||||
.hp-aurora,
|
||||
.hp-rings,
|
||||
.hp-dove,
|
||||
.hp-slide--on img,
|
||||
.hp-live-dot {
|
||||
animation: none;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue