fix(brand): unify calligraphy logo across header, footer and brand page

- logo.svg: remove dark-mode white fill so header/hero calligraphy stays
  visible on white backgrounds and matches footer logo-white.svg
- about/brand: replace sans-serif brand title with BrandCalligraphyName,
  reusing the same AoyagiReisho SVG paths as the footer logo without
  loading the 4.4MB font file
- add unit tests for BrandCalligraphyName and document decision in CONTEXT.md
This commit is contained in:
2026-08-18 12:51:33 +08:00
parent 628a0f1a2b
commit 8d3bd723c3
5 changed files with 84 additions and 12 deletions
@@ -2,6 +2,7 @@
import { motion } from 'framer-motion';
import { ScrollReveal } from '@/components/ui/scroll-reveal';
import { BrandCalligraphyName } from '@/components/ui/brand-calligraphy-name';
import {
ArrowRight,
Target,
@@ -91,11 +92,15 @@ export default function BrandContent() {
initial={{ opacity: 0, y: 40 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8, delay: 0.2, ease: EASE_OUT }}
className="text-4xl sm:text-5xl md:text-6xl lg:text-7xl xl:text-8xl font-black text-ink leading-[0.92] tracking-tightest mb-8 sm:mb-10"
className="text-4xl sm:text-5xl md:text-6xl lg:text-7xl xl:text-8xl text-ink leading-[1.05] tracking-tight mb-8 sm:mb-10"
>
<span className="sr-only"></span>
<BrandCalligraphyName
className="block h-[0.95em] w-auto text-ink"
ariaHidden
/>
<br />
<span className="text-brand"></span>
<span className="text-brand font-black"></span>
</motion.h1>
{/* 数据条 */}
@@ -0,0 +1,31 @@
import { describe, it, expect } from '@jest/globals';
import { render } from '@testing-library/react';
import '@testing-library/jest-dom';
import { BrandCalligraphyName } from './brand-calligraphy-name';
describe('BrandCalligraphyName', () => {
it('renders the four calligraphy glyph paths from the logo asset', () => {
const { container } = render(<BrandCalligraphyName />);
const svg = container.querySelector('svg');
expect(svg).toBeInTheDocument();
expect(svg).toHaveAttribute('viewBox', '0 -40 200 48');
expect(svg!.querySelectorAll('path')).toHaveLength(4);
expect(svg!.querySelectorAll('path')[0]!.getAttribute('d')).toContain('M 378.00 62.00');
expect(svg!.querySelectorAll('path')[3]!.getAttribute('d')).toContain('M 799.00 85.00');
});
it('is exposed as an image with a brand label by default', () => {
const { container } = render(<BrandCalligraphyName />);
const svg = container.querySelector('svg');
expect(svg).toHaveAttribute('role', 'img');
expect(svg).toHaveAttribute('aria-label', '睿新致遠');
});
it('can be hidden from assistive technology when paired with sr-only text', () => {
const { container } = render(<BrandCalligraphyName ariaHidden />);
const svg = container.querySelector('svg');
expect(svg).toHaveAttribute('aria-hidden', 'true');
expect(svg).not.toHaveAttribute('role');
expect(svg).not.toHaveAttribute('aria-label');
});
});
File diff suppressed because one or more lines are too long