- 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)
75 lines
2.5 KiB
TypeScript
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 & lists
|
|
</p>
|
|
</div>
|
|
);
|
|
}
|