From 641ab167b01615ceb3cf56d85a02fefcf86909e9 Mon Sep 17 00:00:00 2001 From: Zaldimmar Date: Fri, 25 Sep 2026 05:49:52 -0500 Subject: [PATCH] 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 --- src/components/DoveMark.tsx | 30 +++++++++++++++++++ src/pages/sections/home/HeroStage.tsx | 43 ++++++++++++++++++++------- src/pages/sections/home/home.css | 13 ++++++++ 3 files changed, 75 insertions(+), 11 deletions(-) create mode 100644 src/components/DoveMark.tsx diff --git a/src/components/DoveMark.tsx b/src/components/DoveMark.tsx new file mode 100644 index 0000000..675a5a7 --- /dev/null +++ b/src/components/DoveMark.tsx @@ -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 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) { + return ( + + ) +} diff --git a/src/pages/sections/home/HeroStage.tsx b/src/pages/sections/home/HeroStage.tsx index 420c8f7..38e4c0a 100644 --- a/src/pages/sections/home/HeroStage.tsx +++ b/src/pages/sections/home/HeroStage.tsx @@ -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,19 +159,38 @@ function BrandBackdrop() {
- - {[40, 70, 100, 130, 160, 190].map((r, i) => ( - - ))} - - + + + + + + + + {/* The rings are faint; the dove at their centre is not, so + the opacity sits on the rings rather than the whole SVG. */} + + + {[40, 70, 100, 130, 160, 190].map((r, i) => ( + + ))} + + + + + + + - - - + + {/* 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. */} + + + diff --git a/src/pages/sections/home/home.css b/src/pages/sections/home/home.css index 8534071..8fcfe46 100644 --- a/src/pages/sections/home/home.css +++ b/src/pages/sections/home/home.css @@ -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;