Files
familysync/apps/pwa/src/components/BrandSlot.tsx
T
Lucas Berger ce95aa3e6b feat(17-04): wire logo img into BrandSlot, set --brand-logo-border-radius 0
- Replace placeholder FS div with decorative <img src="/logo.svg" alt="" aria-hidden>
- Apply Surface B-1 style (width/height brand-logo-size, borderRadius token, contain/block)
- Update --brand-logo-border-radius from 50% to 0 (SVG draws its own rx=104 shape)
- h1 FamilySync and tagline p unchanged; LoginPage.tsx untouched (seam contract honored)
- No dangerouslySetInnerHTML (T-05-24 invariant maintained)
2026-06-18 12:48:55 -04:00

75 lines
2.5 KiB
TypeScript

/**
* BrandSlot — Phase 17 seam component for the login page brand area.
*
* Phase 19 shipped a minimal shippable placeholder: a 48px circle with "FS"
* initials, the app name "FamilySync", and the tagline "Family calendar & lists".
*
* Phase 17 replaces the placeholder div with a decorative logo <img> — the approved
* FamilySync family-house SVG. LoginPage layout is untouched (seam contract honored;
* see 19-UI-SPEC.md §Brand Slot section).
*
* CSS custom properties used (all set in tokens.css):
* --brand-logo-size — image size (default: 48px)
* --brand-logo-border-radius — image border-radius (0 — SVG draws its own shape)
*
* Accessibility:
* <h1> contains the app name — screen readers read "FamilySync" as the page title.
* The logo image is decorative (alt="", aria-hidden="true").
*
* Security: all copy is plain-text JSX children — no dangerouslySetInnerHTML (T-05-24).
*/
export function BrandSlot() {
return (
<div style={{ textAlign: 'center' }}>
{/* Decorative brand logo — Phase 17 approved brand mark (logo.svg) */}
<img
src="/logo.svg"
alt=""
aria-hidden="true"
style={{
width: 'var(--brand-logo-size, 48px)',
height: 'var(--brand-logo-size, 48px)',
borderRadius: 'var(--brand-logo-border-radius)',
margin: '0 auto var(--space-2, 8px)',
display: 'block',
aspectRatio: '1 / 1',
objectFit: 'contain',
flexShrink: 0,
}}
/>
{/* App name — <h1> so screen readers identify the page (UI-SPEC §Accessibility) */}
<h1
style={{
margin: 0,
marginTop: 'var(--space-2, 8px)',
marginBottom: 'var(--space-1, 4px)',
fontSize: 'var(--text-display-size, 24px)',
fontWeight: 600,
lineHeight: 'var(--text-display-line-height, 1.2)',
color: 'var(--color-text-primary, #111318)',
fontFamily: 'var(--font-family-base)',
}}
>
FamilySync
</h1>
{/* Tagline */}
<p
style={{
margin: 0,
marginBottom: 'var(--space-8, 32px)',
fontSize: 'var(--text-body-size, 15px)',
fontWeight: 400,
lineHeight: 'var(--text-body-line-height, 1.5)',
color: 'var(--color-text-secondary, #6b7280)',
fontFamily: 'var(--font-family-base)',
}}
>
Family calendar &amp; lists
</p>
</div>
);
}