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)
This commit is contained in:
@@ -1,24 +1,20 @@
|
|||||||
/**
|
/**
|
||||||
* BrandSlot — Phase 17 seam component for the login page brand area.
|
* BrandSlot — Phase 17 seam component for the login page brand area.
|
||||||
*
|
*
|
||||||
* Phase 19 ships a minimal shippable placeholder: a 48px circle with "FS"
|
* Phase 19 shipped a minimal shippable placeholder: a 48px circle with "FS"
|
||||||
* initials, the app name "FamilySync", and the tagline "Family calendar & lists".
|
* initials, the app name "FamilySync", and the tagline "Family calendar & lists".
|
||||||
*
|
*
|
||||||
* Phase 17 replaces the internals of this component (swap the placeholder div for
|
* Phase 17 replaces the placeholder div with a decorative logo <img> — the approved
|
||||||
* an <img> with a real logo) without touching LoginPage's layout. This isolates
|
* FamilySync family-house SVG. LoginPage layout is untouched (seam contract honored;
|
||||||
* the branding seam — see 19-UI-SPEC.md §Brand Slot section.
|
* see 19-UI-SPEC.md §Brand Slot section).
|
||||||
*
|
*
|
||||||
* CSS custom properties used (all set in tokens.css with placeholder defaults;
|
* CSS custom properties used (all set in tokens.css):
|
||||||
* Phase 17 overrides these values):
|
* --brand-logo-size — image size (default: 48px)
|
||||||
* --brand-logo-bg — logo circle background (default: var(--color-member-0))
|
* --brand-logo-border-radius — image border-radius (0 — SVG draws its own shape)
|
||||||
* --brand-logo-text — initials color (default: #ffffff)
|
|
||||||
* --brand-logo-size — circle diameter (default: 48px)
|
|
||||||
* --brand-logo-border-radius — circle shape (default: 50%)
|
|
||||||
*
|
*
|
||||||
* Accessibility:
|
* Accessibility:
|
||||||
* <h1> contains the app name — screen readers read "FamilySync" as the page title.
|
* <h1> contains the app name — screen readers read "FamilySync" as the page title.
|
||||||
* The logo circle is aria-hidden (the text is the accessible label).
|
* The logo image is decorative (alt="", aria-hidden="true").
|
||||||
* No <img> today → no broken image ref → no layout shift when Phase 17 replaces it.
|
|
||||||
*
|
*
|
||||||
* Security: all copy is plain-text JSX children — no dangerouslySetInnerHTML (T-05-24).
|
* Security: all copy is plain-text JSX children — no dangerouslySetInnerHTML (T-05-24).
|
||||||
*/
|
*/
|
||||||
@@ -26,28 +22,22 @@
|
|||||||
export function BrandSlot() {
|
export function BrandSlot() {
|
||||||
return (
|
return (
|
||||||
<div style={{ textAlign: 'center' }}>
|
<div style={{ textAlign: 'center' }}>
|
||||||
{/* Phase 17 replaces this div with <img src="..." alt="" /> */}
|
{/* Decorative brand logo — Phase 17 approved brand mark (logo.svg) */}
|
||||||
<div
|
<img
|
||||||
|
src="/logo.svg"
|
||||||
|
alt=""
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
style={{
|
style={{
|
||||||
width: 'var(--brand-logo-size, 48px)',
|
width: 'var(--brand-logo-size, 48px)',
|
||||||
height: 'var(--brand-logo-size, 48px)',
|
height: 'var(--brand-logo-size, 48px)',
|
||||||
borderRadius: 'var(--brand-logo-border-radius, 50%)',
|
borderRadius: 'var(--brand-logo-border-radius)',
|
||||||
background: 'var(--brand-logo-bg, var(--color-member-0, #4a90d9))',
|
|
||||||
color: 'var(--brand-logo-text, #ffffff)',
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
margin: '0 auto var(--space-2, 8px)',
|
margin: '0 auto var(--space-2, 8px)',
|
||||||
fontSize: 'var(--text-display-size, 24px)',
|
display: 'block',
|
||||||
fontWeight: 600,
|
|
||||||
fontFamily: 'var(--font-family-base)',
|
|
||||||
flexShrink: 0,
|
|
||||||
aspectRatio: '1 / 1',
|
aspectRatio: '1 / 1',
|
||||||
|
objectFit: 'contain',
|
||||||
|
flexShrink: 0,
|
||||||
}}
|
}}
|
||||||
>
|
/>
|
||||||
FS
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* App name — <h1> so screen readers identify the page (UI-SPEC §Accessibility) */}
|
{/* App name — <h1> so screen readers identify the page (UI-SPEC §Accessibility) */}
|
||||||
<h1
|
<h1
|
||||||
|
|||||||
@@ -103,7 +103,7 @@
|
|||||||
--brand-logo-bg: var(--color-member-0); /* placeholder circle background */
|
--brand-logo-bg: var(--color-member-0); /* placeholder circle background */
|
||||||
--brand-logo-text: #ffffff; /* placeholder initials color */
|
--brand-logo-text: #ffffff; /* placeholder initials color */
|
||||||
--brand-logo-size: 48px; /* reserved slot height; keep 1:1 aspect */
|
--brand-logo-size: 48px; /* reserved slot height; keep 1:1 aspect */
|
||||||
--brand-logo-border-radius: 50%; /* circle for initials; Phase 17 may change */
|
--brand-logo-border-radius: 0; /* SVG draws its own rounded-square background (rx=104); no CSS clip needed */
|
||||||
--brand-app-name: 'FamilySync'; /* drives doc only — not used as CSS content */
|
--brand-app-name: 'FamilySync'; /* drives doc only — not used as CSS content */
|
||||||
|
|
||||||
/* ─────────────────────────────────────────────────────────────────────────
|
/* ─────────────────────────────────────────────────────────────────────────
|
||||||
|
|||||||
Reference in New Issue
Block a user