Files
kjvstudy.org/kjvstudy_org/templates/commentary.html
T
kennethreitz 3336863a4d Improve keyboard navigation consistency across site
- Add KJVNav.initGridNav for standardized 2D grid navigation
- Migrate books.html, topics.html, resources.html to use initGridNav
- Add sidebarActive check to all templates with custom keyboard handlers
- Add [ and ] shortcuts for prev/next chapter on chapter pages
- Add [ and ] shortcuts for prev/next book on book pages
- Update accessibility page with comprehensive keyboard shortcut docs
- Add honest note about keyboard navigation complexity
- Fix sidebar nav conflicting with main content selection

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 01:26:09 -05:00

572 lines
18 KiB
HTML

{% extends "base.html" %}
{% block title %}AI Commentary: {{ book }} {{ chapter }} - Authorized King James Version (KJV) Bible{% endblock %}
{% block description %}AI-powered verse-by-verse commentary on {{ book }} {{ chapter }} from the Authorized King James Version (KJV) Bible. Explore historical context, cross-references, and study questions.{% endblock %}
{% block keywords %}{{ book }} {{ chapter }} commentary, {{ book }} {{ chapter }} analysis, KJV Bible commentary, {{ book }} {{ chapter }} study guide, AI Bible commentary, {{ book }} {{ chapter }} meaning, KJV study{% endblock %}
{% block schema_type %}Article{% endblock %}
{% block structured_data %},
"headline": "AI Commentary on {{ book }} {{ chapter }} - Authorized King James Version (KJV)",
"articleSection": "Biblical Commentary",
"text": "Verse-by-verse analysis and commentary on {{ book }} chapter {{ chapter }} from the Authorized King James Version (KJV) Bible.",
"isPartOf": {
"@type": "Book",
"name": "{{ book }} - Authorized King James Version",
"isPartOf": {
"@type": "Book",
"name": "Authorized King James Version Bible"
}
}{% endblock %}
{% block head %}
<style>
@keyframes pulse-highlight {
0% { background-color: transparent; }
30% { background-color: rgba(255, 235, 59, 0.5); }
100% { background-color: transparent; }
}
.highlight-verse {
animation: pulse-highlight 2s ease;
}
.commentary-container {
max-width: 800px;
margin: 0 auto;
padding: 0 1rem;
background-color: var(--background-color);
position: relative;
z-index: 1;
}
.verse-card {
margin-bottom: 2rem;
border-radius: var(--radius-lg);
overflow: hidden;
box-shadow: var(--shadow-sm);
border: 1px solid var(--border-light);
background: var(--surface-color);
position: relative;
z-index: 2;
}
.verse-header {
padding: 1rem 1rem 0.5rem;
background: rgba(75, 46, 131, 0.05);
}
.verse-number {
font-weight: 600;
font-family: var(--font-display);
color: var(--primary-color);
}
.verse-text {
padding: 1.25rem;
font-size: 1.125rem;
line-height: 1.7;
color: var(--text-primary);
background: var(--surface-color);
font-family: var(--font-serif);
border-bottom: 1px solid var(--border-light);
}
.commentary-section {
padding: 1.25rem;
background-color: var(--surface-color);
position: relative;
z-index: 2;
}
.commentary-title {
font-size: 1.1rem;
text-transform: uppercase;
letter-spacing: 0.05em;
margin: 0 0 0.75rem;
color: var(--text-secondary);
font-weight: 600;
}
.commentary-content {
font-size: 1.15rem;
line-height: 1.6;
color: var(--text-secondary);
margin-bottom: 1.5rem;
}
.cross-references {
background: rgba(75, 46, 131, 0.05);
padding: 1rem;
border-radius: var(--radius-md);
margin-bottom: 1.5rem;
}
.cross-references ul {
margin: 0.5rem 0 0;
padding-left: 1.5rem;
font-size: 1.1rem;
}
.cross-references li {
margin-bottom: 0.35rem;
}
.cross-references a {
color: var(--primary-color);
text-decoration: none;
}
.cross-references a:hover {
text-decoration: underline;
}
.study-questions {
background: rgba(112, 76, 182, 0.05);
padding: 1rem;
border-radius: var(--radius-md);
}
.study-questions ol {
margin: 0.5rem 0 0;
padding-left: 1.5rem;
font-size: 1.1rem;
}
.study-questions li {
margin-bottom: 0.6rem;
}
.commentary-header {
background: var(--surface-color);
color: var(--text-primary);
padding: 2rem 1rem;
text-align: center;
margin-bottom: 2rem;
position: relative;
z-index: 2;
border: 1px solid var(--border-color);
}
.commentary-header h1 {
margin: 0 0 0.5rem;
font-size: 2.4rem;
}
.commentary-header p {
margin: 0;
opacity: 0.9;
max-width: 600px;
margin: 0 auto;
font-size: 1.15rem;
}
.commentary-meta {
background: var(--surface-color);
border-radius: var(--radius-lg);
padding: 1.5rem;
margin-bottom: 2rem;
border: 1px solid var(--border-light);
text-align: center;
}
.commentary-meta p {
margin: 0;
color: var(--text-secondary);
font-size: 1.1rem;
}
.verse-actions {
display: flex;
gap: 0.5rem;
justify-content: flex-end;
padding: 0 1rem 0.75rem;
border-bottom: 1px solid var(--border-light);
background: rgba(75, 46, 131, 0.02);
}
.verse-action {
display: inline-flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
border-radius: var(--radius-sm);
background: var(--surface-color);
border: 1px solid var(--border-color);
color: var(--text-muted);
text-decoration: none;
font-size: 14px;
transition: all 0.2s ease;
}
.verse-action:hover {
background: var(--primary-color);
color: white;
border-color: var(--primary-color);
}
.tab-navigation {
display: flex;
border-bottom: 1px solid var(--border-light);
}
.tab-button {
padding: 0.75rem 1rem;
background: none;
border: none;
border-bottom: 2px solid transparent;
font-family: var(--font-sans);
font-size: 1.05rem;
color: var(--text-secondary);
cursor: pointer;
transition: all 0.2s ease;
}
.tab-button.active {
border-bottom-color: var(--primary-color);
color: var(--primary-color);
font-weight: 500;
}
.tab-content {
display: none;
background-color: var(--surface-color);
}
.tab-content.active {
display: block;
}
@media (max-width: 768px) {
.commentary-header h1 {
font-size: 1.8rem;
}
.verse-text {
font-size: 1.15rem;
}
.commentary-content {
font-size: 1.1rem;
}
}
/* Fix for background issues across browsers */
html, body {
min-height: 100vh;
background-color: var(--background-color) !important;
overflow-x: hidden;
}
/* Fix for black background in some browsers */
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: var(--background-color) !important;
z-index: -1;
}
.container, .commentary-container, .verse-card, .commentary-section {
position: relative;
z-index: 1;
background-color: var(--background-color) !important;
}
/* Ensure background color consistency */
.commentary-header, .commentary-meta, .chapter-overview, .verse-card {
background-color: var(--surface-color);
position: relative;
z-index: 2;
}
/* Additional black background fix */
.commentary-container::before {
content: '';
position: absolute;
top: 0;
left: -100vw;
width: 300vw;
height: 100%;
background-color: var(--background-color) !important;
z-index: -1;
}
</style>
{% endblock %}
{% block breadcrumb %}
<div class="container">
<nav class="breadcrumb" style="font-size: 1.1rem;">
<a href="/">📚 All Books</a>
<span class="breadcrumb-separator">/</span>
<a href="/book/{{ book }}">{{ book }}</a>
<span class="breadcrumb-separator">/</span>
<a href="/book/{{ book }}/chapter/{{ chapter }}">Chapter {{ chapter }}</a>
<span class="breadcrumb-separator">/</span>
<span>AI Commentary</span>
</nav>
</div>
{% endblock %}
{% block content %}
<header class="commentary-header">
<h1>AI Commentary: {{ book }} {{ chapter }}</h1>
<p>Verse-by-verse analysis and insights from the Authorized King James Version (KJV)</p>
</header>
<div style="background-color: var(--background-color) !important; min-height: 20px; position: relative; z-index: 1;"></div>
<div class="commentary-container" style="background-color: var(--background-color) !important; position: relative; z-index: 1;">
<div class="commentary-meta">
<p><strong>Note:</strong> This AI-powered commentary is generated based on historical, theological, and scholarly sources. It's designed to assist your study but should not replace personal reflection and traditional commentaries.</p>
</div>
<div class="chapter-overview verse-card">
<div class="verse-header">
<h2 style="margin: 0; font-size: 1.5rem;">Chapter Overview</h2>
</div>
<div class="commentary-section">
<div class="commentary-content">
{{ chapter_overview | safe }}
</div>
</div>
</div>
{% for verse in verses %}
<div class="verse-card" id="verse-{{ verse.verse }}">
<div class="verse-header">
<div class="verse-number">Verse {{ verse.verse }}</div>
</div>
<div class="verse-actions">
<a href="#verse-{{ verse.verse }}" class="verse-action" title="Copy link to: {{ verse.text|truncate(50) }}" onclick="copyVerseLink('{{ verse.verse }}')">
🔗
</a>
<a href="/book/{{ book }}/chapter/{{ chapter }}#verse-{{ verse.verse }}" class="verse-action" title="View in chapter: {{ verse.text|truncate(40) }}">
📖
</a>
</div>
<div class="verse-text">{{ verse.text }}</div>
<div class="tab-navigation">
<button class="tab-button active" onclick="switchTab({{ verse.verse }}, 'analysis')">Analysis</button>
<button class="tab-button" onclick="switchTab({{ verse.verse }}, 'historical')">Historical Context</button>
<button class="tab-button" onclick="switchTab({{ verse.verse }}, 'study')">Study Questions</button>
</div>
<div class="commentary-section">
<div id="tab-{{ verse.verse }}-analysis" class="tab-content active">
<h3 class="commentary-title">Analysis - Verse {{ verse.verse }}</h3>
<div class="commentary-content">
{{ commentaries[verse.verse].analysis | safe }}
</div>
<div class="cross-references">
<h3 class="commentary-title">Cross References</h3>
<ul>
{% for ref in commentaries[verse.verse].cross_references %}
<li><a href="{{ ref.url }}" title="{{ ref.verse_text|default(ref.context)|truncate(80) }}">{{ ref.text }}</a> - {{ ref.context }}</li>
{% endfor %}
</ul>
</div>
</div>
<div id="tab-{{ verse.verse }}-historical" class="tab-content">
<h3 class="commentary-title">Historical Context - Verse {{ verse.verse }}</h3>
<div class="commentary-content">
{{ commentaries[verse.verse].historical | safe }}
</div>
</div>
<div id="tab-{{ verse.verse }}-study" class="tab-content">
<h3 class="commentary-title">Study Questions - Verse {{ verse.verse }}</h3>
<div class="study-questions">
<ol>
{% for question in commentaries[verse.verse].questions %}
<li>{{ question }}</li>
{% endfor %}
</ol>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
{% endblock %}
{% block navigation %}
<div class="container">
<div class="navigation">
<a href="/book/{{ book }}/chapter/{{ chapter }}" class="nav-button">
← Back to {{ book }} {{ chapter }}
</a>
<div style="display: flex; gap: 0.5rem;">
{% if chapter > 1 %}
<a href="/commentary/{{ book }}/{{ chapter - 1 }}" class="nav-button">
← {{ book }} {{ chapter - 1 }} Commentary
</a>
{% endif %}
{% if chapter < chapters|length %}
<a href="/commentary/{{ book }}/{{ chapter + 1 }}" class="nav-button nav-button-primary">
{{ book }} {{ chapter + 1 }} Commentary →
</a>
{% endif %}
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
// Fix for black background in some browsers
document.addEventListener('DOMContentLoaded', function() {
const bgColor = getComputedStyle(document.documentElement).getPropertyValue('--background-color');
document.body.style.backgroundColor = bgColor;
document.documentElement.style.backgroundColor = bgColor;
document.querySelector('.commentary-container').style.backgroundColor = bgColor;
// Force background color on body
document.body.insertAdjacentHTML('afterbegin', `<div style="position:fixed; top:0; left:0; width:100%; height:100%; background-color:${bgColor}; z-index:-100;"></div>`);
// Force all main containers to have the background color
document.querySelectorAll('.container, .narrow-container, .commentary-container, .main-content').forEach(el => {
el.style.backgroundColor = bgColor;
});
});
function copyVerseLink(verseNumber) {
const url = window.location.origin + window.location.pathname + '#verse-' + verseNumber;
const verseText = document.querySelector(`#verse-${verseNumber} .verse-text`).textContent.trim();
const shortVerseText = verseText.length > 30 ? verseText.substring(0, 30) + '...' : verseText;
navigator.clipboard.writeText(url).then(() => {
showToast(`Verse ${verseNumber} copied: "${shortVerseText}"`);
});
}
function switchTab(verseNumber, tabName) {
// Hide all tabs
const tabContents = document.querySelectorAll(`.verse-card#verse-${verseNumber} .tab-content`);
tabContents.forEach(tab => tab.classList.remove('active'));
// Deactivate all tab buttons
const tabButtons = document.querySelectorAll(`.verse-card#verse-${verseNumber} .tab-button`);
tabButtons.forEach(button => button.classList.remove('active'));
// Activate the selected tab and button
document.getElementById(`tab-${verseNumber}-${tabName}`).classList.add('active');
event.currentTarget.classList.add('active');
// Update page title with current verse
const verseText = document.querySelector(`#verse-${verseNumber} .verse-text`).textContent.trim();
const shortVerseText = verseText.length > 20 ? verseText.substring(0, 20) + '...' : verseText;
document.title = `${tabName.charAt(0).toUpperCase() + tabName.slice(1)} - ${shortVerseText} | ${book} ${chapter}`;
}
function showToast(message) {
const toast = document.createElement('div');
toast.textContent = message;
toast.style.cssText = `
position: fixed;
top: 2rem;
right: 2rem;
background: var(--primary-color);
color: white;
padding: 0.75rem 1.5rem;
border-radius: var(--radius-md);
z-index: 1000;
font-size: 0.875rem;
animation: slideIn 0.3s ease;
`;
document.body.appendChild(toast);
setTimeout(() => {
toast.style.animation = 'slideOut 0.3s ease';
setTimeout(() => toast.remove(), 300);
}, 2000);
}
document.addEventListener('DOMContentLoaded', function() {
// Highlight verse from URL hash
if (window.location.hash) {
setTimeout(() => {
const target = document.querySelector(window.location.hash);
if (target) {
target.scrollIntoView({ behavior: 'auto', block: 'center' });
target.style.transition = 'background-color 1s';
target.style.backgroundColor = 'rgba(255, 235, 59, 0.5)';
// Get verse number to show in toast
const verseMatch = window.location.hash.match(/verse-(\d+)/);
if (verseMatch && verseMatch[1]) {
showToast('Navigated to Verse ' + verseMatch[1]);
}
setTimeout(() => {
target.style.backgroundColor = '';
}, 2000);
}
}, 100);
}
// Keyboard navigation for verse cards
const verseCards = Array.from(document.querySelectorAll('.verse-card[id^="verse-"]'));
if (verseCards.length === 0) return;
let selectedIndex = -1;
function selectCard(index) {
if (selectedIndex >= 0 && selectedIndex < verseCards.length) {
verseCards[selectedIndex].style.outline = '';
verseCards[selectedIndex].style.outlineOffset = '';
verseCards[selectedIndex].classList.remove('selected');
}
selectedIndex = Math.max(0, Math.min(index, verseCards.length - 1));
verseCards[selectedIndex].style.outline = '2px solid #4a7c59';
verseCards[selectedIndex].style.outlineOffset = '4px';
verseCards[selectedIndex].classList.add('selected');
verseCards[selectedIndex].scrollIntoView({ behavior: 'auto', block: 'center' });
}
document.addEventListener('keydown', function(e) {
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
if (KJVNav.sidebarActive) return;
if (e.key === 'ArrowDown' || e.key === 'j') {
e.preventDefault();
if (KJVNav.isSelectionOffScreen(verseCards, selectedIndex)) {
selectCard(KJVNav.findFirstVisibleIndex(verseCards));
} else {
selectCard(selectedIndex < 0 ? 0 : selectedIndex + 1);
}
} else if (e.key === 'ArrowUp' || e.key === 'k') {
e.preventDefault();
if (KJVNav.isSelectionOffScreen(verseCards, selectedIndex)) {
selectCard(KJVNav.findFirstVisibleIndex(verseCards));
} else if (selectedIndex <= 0) {
selectCard(0);
} else {
selectCard(selectedIndex - 1);
}
} else if (e.key === 'ArrowLeft' || e.key === 'h') {
e.preventDefault();
history.back();
} else if (e.key === 'Enter' && selectedIndex >= 0) {
e.preventDefault();
const verseLink = verseCards[selectedIndex].querySelector('.verse-action[href*="/book/"]');
if (verseLink) window.location.href = verseLink.href;
} else if (e.key === 'Escape') {
e.preventDefault();
if (selectedIndex >= 0 && selectedIndex < verseCards.length) {
verseCards[selectedIndex].style.outline = '';
verseCards[selectedIndex].style.outlineOffset = '';
verseCards[selectedIndex].classList.remove('selected');
}
selectedIndex = -1;
}
});
});
</script>
{% endblock %}