diff --git a/kjvstudy_org/jinja_filters.py b/kjvstudy_org/jinja_filters.py
index f779963..7f871ec 100644
--- a/kjvstudy_org/jinja_filters.py
+++ b/kjvstudy_org/jinja_filters.py
@@ -160,7 +160,7 @@ def inject_word_markers(text, word_studies, verse_num):
# Link the original term to Strong's page if we have a Strong's number
strongs = study.get('strongs')
if strongs:
- term_html = f'{study["term"]}'
+ term_html = f'{study["term"]}'
else:
term_html = study["term"]
# Wrap details (translit + note) in a span that's hidden by default
diff --git a/kjvstudy_org/static/base.js b/kjvstudy_org/static/base.js
index 8640503..9a26cca 100644
--- a/kjvstudy_org/static/base.js
+++ b/kjvstudy_org/static/base.js
@@ -1619,6 +1619,113 @@ function showKeyboardHelp() {
});
})();
+// Strong's tooltip functionality
+(function() {
+ // Create tooltip element
+ var tooltip = document.createElement('div');
+ tooltip.className = 'strongs-tooltip';
+ document.body.appendChild(tooltip);
+
+ // Cache for fetched Strong's entries
+ var strongsCache = {};
+
+ // Fetch Strong's entry from API
+ async function fetchStrongsEntry(strongsNumber) {
+ if (strongsCache[strongsNumber]) {
+ return strongsCache[strongsNumber];
+ }
+
+ try {
+ var response = await fetch('/api/strongs/' + strongsNumber);
+ if (!response.ok) {
+ throw new Error('Not found');
+ }
+ var data = await response.json();
+ strongsCache[strongsNumber] = data;
+ return data;
+ } catch (e) {
+ return null;
+ }
+ }
+
+ // Show tooltip positioned relative to a link element
+ function showTooltip(data, linkElement) {
+ var isHebrew = data.strongs.startsWith('H');
+ var langClass = isHebrew ? 'hebrew' : 'greek';
+
+ tooltip.innerHTML =
+ '
' + data.word + '
' +
+ '' + data.transliteration + '
' +
+ '' + data.strongs + '
' +
+ '' + data.definition + '
';
+
+ // Position off-screen first to measure
+ tooltip.style.left = '-9999px';
+ tooltip.style.top = '-9999px';
+ tooltip.classList.add('show');
+
+ var tooltipWidth = tooltip.offsetWidth;
+ var tooltipHeight = tooltip.offsetHeight;
+
+ var linkRect = linkElement.getBoundingClientRect();
+ var padding = 10;
+
+ // Position below the link, centered
+ var x = linkRect.left + (linkRect.width / 2) - (tooltipWidth / 2);
+ var y = linkRect.bottom + 8 + window.scrollY;
+
+ // Keep within viewport
+ if (x + tooltipWidth > window.innerWidth - padding) {
+ x = window.innerWidth - tooltipWidth - padding;
+ }
+ if (x < padding) {
+ x = padding;
+ }
+ if (linkRect.bottom + 8 + tooltipHeight > window.innerHeight) {
+ y = linkRect.top - tooltipHeight - 8 + window.scrollY;
+ }
+ if (y < window.scrollY + padding) {
+ y = window.scrollY + padding;
+ }
+
+ tooltip.style.left = x + 'px';
+ tooltip.style.top = y + 'px';
+ }
+
+ function hideTooltip() {
+ tooltip.classList.remove('show');
+ }
+
+ // Event delegation for Strong's links
+ document.addEventListener('mouseover', function(e) {
+ var target = e.target;
+ if (!target.classList.contains('strongs-link')) return;
+
+ var strongsNumber = target.getAttribute('data-strongs');
+ if (!strongsNumber) return;
+
+ // Show loading state
+ tooltip.innerHTML = 'Loading...';
+ var linkRect = target.getBoundingClientRect();
+ tooltip.style.left = linkRect.left + 'px';
+ tooltip.style.top = (linkRect.bottom + 8 + window.scrollY) + 'px';
+ tooltip.classList.add('show');
+
+ // Fetch and display
+ fetchStrongsEntry(strongsNumber).then(function(data) {
+ if (data && target.matches(':hover')) {
+ showTooltip(data, target);
+ } else if (!data) {
+ hideTooltip();
+ }
+ });
+
+ target.addEventListener('mouseleave', function() {
+ hideTooltip();
+ }, { once: true });
+ });
+})();
+
// Site-wide verse linking
(function() {
function linkVerseReferences(element) {
diff --git a/kjvstudy_org/templates/base.html b/kjvstudy_org/templates/base.html
index 5136fdc..b7bd6de 100644
--- a/kjvstudy_org/templates/base.html
+++ b/kjvstudy_org/templates/base.html
@@ -301,6 +301,76 @@
}
}
+ /* Strong's tooltip styles */
+ .strongs-tooltip {
+ position: absolute;
+ background: var(--bg-color);
+ border: 1px solid var(--border-color-darker);
+ border-radius: 6px;
+ padding: 0.75rem 1rem;
+ min-width: 250px;
+ max-width: 350px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+ z-index: 9999;
+ font-size: 0.95rem;
+ line-height: 1.5;
+ color: var(--text-color);
+ pointer-events: none;
+ opacity: 0;
+ transition: opacity 0.2s ease-in-out;
+ }
+
+ .strongs-tooltip.show {
+ opacity: 1;
+ }
+
+ .strongs-tooltip-word {
+ font-size: 1.4rem;
+ font-weight: 600;
+ margin-bottom: 0.25rem;
+ }
+
+ .strongs-tooltip-word.hebrew {
+ font-family: 'SBL Hebrew', 'Ezra SIL', 'Times New Roman', serif;
+ direction: rtl;
+ }
+
+ .strongs-tooltip-word.greek {
+ font-family: 'SBL Greek', 'Gentium Plus', 'Times New Roman', serif;
+ }
+
+ .strongs-tooltip-translit {
+ font-style: italic;
+ color: var(--text-secondary);
+ margin-bottom: 0.5rem;
+ }
+
+ .strongs-tooltip-number {
+ font-family: monospace;
+ font-size: 0.8rem;
+ color: var(--text-tertiary);
+ margin-bottom: 0.5rem;
+ }
+
+ .strongs-tooltip-def {
+ font-size: 0.9rem;
+ color: var(--text-color);
+ }
+
+ [data-theme="dark"] .strongs-tooltip {
+ background: #2a2a2a;
+ border-color: #444;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
+ }
+
+ @media (prefers-color-scheme: dark) {
+ html:not([data-theme="light"]) .strongs-tooltip {
+ background: #2a2a2a;
+ border-color: #444;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
+ }
+ }
+
/* Enhanced typography and spacing */
body {
counter-reset: sidenote-counter;