Glossary(term) tooltip syntax — focus pages
Section titled “Glossary(term) tooltip syntax — focus pages”Continuation of 2026-06-23_Tooltip-Component. Replaces the initial hardcoded per-term injection approach with a generic build-time resolver.
What changed
Section titled “What changed”Architecture decision
Section titled “Architecture decision”Previous approach (Tooltip-Component session): injectFASTTooltip() matched F.A.S.T. text via regex and wrapped it. Each new term required a new function + regex. This was recognised as brittle hardcoding.
New approach: authors write Glossary(TermName) anywhere in KB focus markdown. The build pipeline resolves it from Core/Misc/Glossary.md — no code changes needed for new terms.
Design constraint: Glossary() is opt-in, not auto-magic. The pipeline does NOT auto-tooltip every substring matching a Glossary key. Auto-matching would silently tooltip common terms (AI, HTML, SSOT) wherever they appear. Explicit Glossary() call gives authors control over which occurrences get a tooltip and where.
Code changes — sites/mbr/src/utils/load-focus-content.ts
Section titled “Code changes — sites/mbr/src/utils/load-focus-content.ts”loadGlossaryTerms()— readsCore/Misc/Glossary.mdonce at build time, splits on### Termheadings, returnsMap<string, string>with bold (**text**) converted to<b>text</b>injectGlossaryTooltips(html, terms)— replacesGlossary(TermName)tokens with.fttooltip spans; degrades to plain text if term not foundprocessHtml()simplified:injectBrands → injectGlossaryTooltips(F.A.S.T. auto-inject removed)injectFASTTooltip(),injectCancer50Tooltip(),loadCancer50TooltipHtml(),C50_FALLBACKall removeddefaultContent()derives F.A.S.T. and Cancer50Pledge tooltips from the loaded glossary map
Code changes — sites/sdc/src/utils/load-focus-content.ts
Section titled “Code changes — sites/sdc/src/utils/load-focus-content.ts”- Same
loadGlossaryTerms()+injectGlossaryTooltips()infrastructure added - SDC content currently has no
Glossary()terms; infrastructure ready for future use
KB changes
Section titled “KB changes”MBR/_WorkingOn/Focus.md—**Cancer50Pledge**→Glossary(Cancer50Pledge);F.A.S.T.→Glossary(F.A.S.T.)in body +plan_intro; info callout documentsGlossary()syntaxSDC/_WorkingOn/Focus.md— info callout updated with Glossary syntax note
Documentation
Section titled “Documentation”README.md(monorepo) —Glossary(TermName)syntax added to Focus Pages section with examplesLESSONS.md(monorepo) — two entries added:visibility:hiddenmeasurability;set:html/ Astro component injection pattern
Viewport fix (follow-up, same date)
Section titled “Viewport fix (follow-up, same date)”The initial .ft tooltip positioning JS only handled vertical flipping (top → bottom). No horizontal clamping. Cancer50Pledge appears near the left edge of the focus page — its 18rem tooltip bubble overflowed the left viewport edge.
Fix in sites/mbr/src/pages/focus.astro:
positionTooltip()now clamps horizontally after vertical check: shiftstip.style.leftbycalc(50% + Npx)when bubble overflows left or right viewport edge- Caret (
::after) tracks the shift via--caret-leftCSS variable so it continues pointing at the trigger word - Measurement uses
getBoundingClientRect()on thevisibility:hiddenbubble (no show/hide dance needed)
Files changed
Section titled “Files changed”| File | Change |
|---|---|
sites/mbr/src/utils/load-focus-content.ts | Generic Glossary loader + injector; per-term functions removed |
sites/sdc/src/utils/load-focus-content.ts | Glossary infrastructure added |
sites/mbr/src/pages/focus.astro | Horizontal viewport clamping in positionTooltip(); --caret-left CSS var |
MBR/_WorkingOn/Focus.md | Glossary() syntax in body + plan_intro; info callout |
SDC/_WorkingOn/Focus.md | Info callout updated |
README.md | Glossary syntax documented in Focus Pages section |
LESSONS.md | Two new entries |
Gotchas
Section titled “Gotchas”Glossary()is case-sensitive — term must match the### Headingin Glossary.md exactly- Glossary.md is parsed at build time; changes require a rebuild to take effect
visibility:hiddenbubble is measurable withgetBoundingClientRect()— correct rect returned even when hidden- Caret offset must be adjusted when bubble is horizontally clamped — use
--caret-leftCSS variable; pseudo-elements can’t be styled directly from JS