2026 04 18 Mbr Text Component
mBR Text Entity Component — Session Log
Section titled “mBR Text Entity Component — Session Log”Date: 2026-04-17 – 2026-04-18 Status: Complete
What was built
Section titled “What was built”MyBetterRatesEntity.astro — CSS-only animated brand text component for “myBetterRates”.
Location: ~/projects/monorepo/sites/Template/src/components/brand/MyBetterRatesEntity.astro
Usage:
<MyBetterRatesEntity /> <!-- myBetterRates --><MyBetterRatesEntity variant="Advisor" /> <!-- myBetterRates Advisor -->Final design (what was decided and why)
Section titled “Final design (what was decided and why)”Resting character: small $ (not s)
Section titled “Resting character: small $ (not s)”The terminal character is always displayed as a small $ (x-height, font-size: 0.73em; font-weight: 700). A full-size $ briefly pulses every 4 seconds.
Why: An s resting state hides the financial identity 87.5% of the time. The small $ continuously signals “rates / dollar / financial” at all text sizes — even at 12px email body text where a bar-only animation would be imperceptible. The pulse becomes emphasis, not reveal.
Animation: Logo Sync timing (87.5% / 93.75%)
Section titled “Animation: Logo Sync timing (87.5% / 93.75%)”Small $ rests for 3.5s (87.5% of 4s cycle). Big $ briefly pulses at the 93.75% mark — identical keyframe percentages to the logo bar-blink and dot-pulse. Wordmark and logo pulse simultaneously every 4 seconds.
Why: Discrete pulse (brief → gone) respects the reader more than sustained oscillation. Works at all text sizes without being disruptive. Logo sync creates a coordinated brand moment at repeated exposure.
Cross-device positioning: position: absolute; bottom: 0; left: 0
Section titled “Cross-device positioning: position: absolute; bottom: 0; left: 0”Big $ uses position: absolute; top: auto; right: auto; bottom: 0; left: 0 — bottom-anchored (not inset: 0). Small $ in normal flow defines layout width.
Why: When the resting char is 0.73em and overlay is 1em, inset: 0 misaligns the baseline by ~0.2em. Bottom-anchored places the big $ at the same baseline as the small $. The SmartDebtEntity inset: 0 pattern assumes equal font sizes — not applicable here.
What failed before this:
inline-grid— broken on iPad/Safaritop: Xemmagic numbers — font-metric-dependent, rejectedtop: 50%; translateY(-50%)— approximately wrong, rejectedwidth: 0; overflow: visible— advance-width mismatch
SEO: aria-label="myBetterRates" on outer span
Section titled “SEO: aria-label="myBetterRates" on outer span”Screen readers and web crawlers always read “myBetterRates”. Keyword variations (“my better rates”) belong in page copy and meta descriptions — not inside the component. No hidden text, no duplicate content.
What else was done
Section titled “What else was done”MyBetterRatesEntityShowcase.astro— added as first section on/componentspage (props table, usage code, live examples at 1rem / 2rem / 3.5rem, card context)BrandLogo.astroextended —brand="mbr"support added (viewBox27 8 76 84, bar-blink + dot-pulse animation, aria-label)Header.astro— default header switched from SmartDebt Coach to mBR logo +MyBetterRatesEntity- mBR favicons — regenerated via
pnpm favicon:mbr; removed erroneouschar-bardisplay:none (was showing S state, now shows static$state, no animation) docs.astro— Sites list expanded (Template, mbr, sdc, ts); Brand Assets includes mbr; Brand Entity Components section added;pnpm favicon:mbrcommand documentedBrand.md— Wordmark animation section updated: small$resting state decision, rationale, component path. Implementation specifics (CSS values) canonical in component source.- Playwright tests —
branding.spec.tsupdated; all 25 tests pass
Commits
Section titled “Commits”386559f—feat(brand): mBR text entity component — small $ resting, big $ logo-sync pulse407b86c—docs(brand): wordmark animation — small $ permanent resting state(KB repo)8f7745c—feat(brand): mBR favicon shows $ state + header switched to mBR
Gotchas
Section titled “Gotchas”generate-favicon.mjswas hidingchar-barfor mBR — old code showed S state in favicon. Fixed by removing the mBR block (lines 103-115). Source SVG haschar-barvisible by default.BrandLogo.astroviewBox is hardcoded0 0 100 100— mBR logo uses27 8 76 84. Fix: added aviewBoxMapkeyed by brand; SVG template uses dynamicviewBox={viewBox}.- Commit timing — Talbot asked for review before commit. Future sessions: hold commits until explicit confirmation.