Add transparent nav SVG assets with raster fallbacks, header contrast and focus fixes, automated a11y audit scripts, and evidence reports for institutional review. Co-authored-by: Cursor <[email protected]>
106 lines
3.0 KiB
TypeScript
106 lines
3.0 KiB
TypeScript
export type LogoMarkVariant = 'nav' | 'footer' | 'square'
|
|
|
|
export interface LogoMarkProps {
|
|
/** nav: symbol on mobile, horizontal on md+; footer: symbol on xs, horizontal on sm+ */
|
|
variant?: LogoMarkVariant
|
|
className?: string
|
|
}
|
|
|
|
const BRAND = {
|
|
symbolNavSvg: '/brand/logo-symbol-nav.svg',
|
|
symbolNav: '/brand/logo-symbol-nav.png',
|
|
horizontalNavSvg: '/brand/logo-horizontal-nav.svg',
|
|
horizontalNav: '/brand/logo-horizontal-nav.png',
|
|
horizontalNavWebp: '/brand/logo-horizontal-nav.webp',
|
|
horizontal: '/brand/logo-horizontal.png',
|
|
square: '/brand/logo-square.png',
|
|
} as const
|
|
|
|
function ResponsiveLockup({
|
|
symbolClassName,
|
|
horizontalClassName,
|
|
}: {
|
|
symbolClassName: string
|
|
horizontalClassName: string
|
|
}) {
|
|
return (
|
|
<>
|
|
<picture className={symbolClassName}>
|
|
<source srcSet={BRAND.symbolNavSvg} type="image/svg+xml" />
|
|
<img
|
|
src={BRAND.symbolNav}
|
|
alt=""
|
|
className="logo-mark__img logo-mark__img--symbol"
|
|
width={256}
|
|
height={256}
|
|
decoding="async"
|
|
fetchPriority="high"
|
|
/>
|
|
</picture>
|
|
<picture className={horizontalClassName}>
|
|
<source srcSet={BRAND.horizontalNavSvg} type="image/svg+xml" />
|
|
<source srcSet={BRAND.horizontalNavWebp} type="image/webp" />
|
|
<img
|
|
src={BRAND.horizontalNav}
|
|
alt=""
|
|
className="logo-mark__img logo-mark__img--horizontal"
|
|
width={1024}
|
|
height={354}
|
|
decoding="async"
|
|
fetchPriority="high"
|
|
/>
|
|
</picture>
|
|
</>
|
|
)
|
|
}
|
|
|
|
export function LogoMark({ variant = 'nav', className = '' }: LogoMarkProps) {
|
|
const isDecorative = variant === 'nav' || variant === 'footer'
|
|
|
|
if (variant === 'nav') {
|
|
return (
|
|
<span
|
|
className={['logo-mark', 'logo-mark--nav', className].filter(Boolean).join(' ')}
|
|
aria-hidden={true}
|
|
>
|
|
<ResponsiveLockup
|
|
symbolClassName="logo-mark__img-wrap logo-mark__img-wrap--symbol block md:hidden"
|
|
horizontalClassName="logo-mark__img-wrap logo-mark__img-wrap--horizontal hidden md:block"
|
|
/>
|
|
</span>
|
|
)
|
|
}
|
|
|
|
if (variant === 'footer') {
|
|
return (
|
|
<span
|
|
className={['logo-mark', 'logo-mark--footer', className].filter(Boolean).join(' ')}
|
|
aria-hidden={true}
|
|
>
|
|
<ResponsiveLockup
|
|
symbolClassName="logo-mark__img-wrap logo-mark__img-wrap--symbol block sm:hidden"
|
|
horizontalClassName="logo-mark__img-wrap logo-mark__img-wrap--horizontal hidden sm:block"
|
|
/>
|
|
</span>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<span
|
|
className={['logo-mark', 'logo-mark--square', className].filter(Boolean).join(' ')}
|
|
aria-hidden={isDecorative || undefined}
|
|
>
|
|
<img
|
|
src={BRAND.square}
|
|
alt={isDecorative ? '' : 'Miracles in Motion Foundation'}
|
|
className="logo-mark__img"
|
|
width={1024}
|
|
height={1024}
|
|
decoding="async"
|
|
/>
|
|
</span>
|
|
)
|
|
}
|
|
|
|
export default LogoMark
|