mirror of
https://github.com/kennethreitz/kjvstudy.org.git
synced 2026-06-05 23:00:16 +00:00
543903b3de
Increase font size, line height, and width constraints to improve tooltip appearance and content display.
707 lines
28 KiB
HTML
707 lines
28 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}{{ book }} {{ chapter }} - Authorized King James Version (KJV) Bible{% endblock %}
|
|
{% block description %}Read {{ book }} chapter {{ chapter }} from the Authorized King James Version (KJV) Bible with verse-by-verse display and study tools. Complete text of {{ book }} {{ chapter }} KJV.{% endblock %}
|
|
{% block keywords %}{{ book }} {{ chapter }}, {{ book }} {{ chapter }} KJV, {{ book }} chapter {{ chapter }} King James Version, Authorized King James Version, KJV Bible, {{ book }} {{ chapter }} verses{% endblock %}
|
|
|
|
{% block schema_type %}Article{% endblock %}
|
|
{% block structured_data %},
|
|
"headline": "{{ book }} {{ chapter }} - Authorized King James Version (KJV)",
|
|
"articleSection": "{{ book }}",
|
|
"text": "{{ verses[0].text[:150] }}...",
|
|
"wordCount": {{ verses|length }},
|
|
"isPartOf": {
|
|
"@type": "Book",
|
|
"name": "{{ book }} - Authorized King James Version",
|
|
"isPartOf": {
|
|
"@type": "Book",
|
|
"name": "Authorized King James Version Bible"
|
|
}
|
|
}{% endblock %}
|
|
|
|
{% block head %}
|
|
<style>
|
|
.verse-tools {
|
|
opacity: 0;
|
|
transition: opacity 0.2s ease;
|
|
display: inline-flex;
|
|
gap: 0.5rem;
|
|
margin-left: 0.5rem;
|
|
vertical-align: middle;
|
|
}
|
|
|
|
.verse:hover .verse-tools {
|
|
opacity: 1;
|
|
}
|
|
|
|
.verse-tool {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 24px;
|
|
height: 24px;
|
|
border-radius: var(--radius-sm);
|
|
background: var(--surface-color);
|
|
border: 1px solid var(--border-color);
|
|
color: var(--text-muted);
|
|
text-decoration: none;
|
|
font-size: 12px;
|
|
transition: all 0.2s ease;
|
|
}
|
|
|
|
.verse-tool:hover {
|
|
background: var(--primary-color);
|
|
color: white;
|
|
border-color: var(--primary-color);
|
|
}
|
|
|
|
.verse-number {
|
|
font-size: 0.75rem;
|
|
font-weight: 600;
|
|
color: var(--primary-color);
|
|
vertical-align: super;
|
|
margin-right: 0.25rem;
|
|
user-select: none;
|
|
cursor: pointer;
|
|
position: relative;
|
|
display: inline;
|
|
}
|
|
|
|
.verse-number:hover {
|
|
color: var(--primary-color);
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.highlight-verse {
|
|
animation: pulse-highlight 2s ease;
|
|
}
|
|
|
|
@keyframes pulse-highlight {
|
|
0% { background-color: transparent; }
|
|
30% { background-color: rgba(255, 235, 59, 0.5); }
|
|
100% { background-color: transparent; }
|
|
}
|
|
|
|
.chapter-navigation {
|
|
position: sticky;
|
|
top: 0;
|
|
background: var(--background-color);
|
|
border-bottom: 1px solid var(--border-color);
|
|
padding: 1rem 0;
|
|
margin-bottom: 2rem;
|
|
z-index: 10;
|
|
}
|
|
|
|
.chapter-nav-content {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
max-width: 800px;
|
|
margin: 0 auto;
|
|
padding: 0 2rem;
|
|
}
|
|
|
|
.chapter-info {
|
|
font-family: var(--font-display);
|
|
font-weight: 600;
|
|
color: var(--primary-color);
|
|
}
|
|
|
|
.chapter-controls {
|
|
display: flex;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.reading-options {
|
|
background: var(--surface-color);
|
|
border-radius: var(--radius-lg);
|
|
padding: 1.5rem;
|
|
margin-bottom: 2rem;
|
|
border: 1px solid var(--border-light);
|
|
}
|
|
|
|
.reading-options h3 {
|
|
margin: 0 0 1rem;
|
|
font-size: 1rem;
|
|
color: var(--primary-color);
|
|
font-family: var(--font-display);
|
|
}
|
|
|
|
.option-group {
|
|
display: flex;
|
|
gap: 1rem;
|
|
align-items: center;
|
|
margin-bottom: 0.75rem;
|
|
}
|
|
|
|
.option-group label {
|
|
font-size: 0.875rem;
|
|
color: var(--text-secondary);
|
|
min-width: 80px;
|
|
}
|
|
|
|
.range-input {
|
|
flex: 1;
|
|
max-width: 200px;
|
|
}
|
|
|
|
.verse-highlight {
|
|
background: linear-gradient(120deg, #fff59d 0%, #ffee58 100%);
|
|
background-size: 100% 40%;
|
|
background-repeat: no-repeat;
|
|
background-position: 0 60%;
|
|
}
|
|
|
|
.verse-text {
|
|
font-family: 'EB Garamond', Georgia, serif;
|
|
font-size: 1.5rem;
|
|
line-height: 1.8;
|
|
color: var(--text-primary);
|
|
font-feature-settings:
|
|
"liga" 1,
|
|
"dlig" 1,
|
|
"kern" 1,
|
|
"onum" 1;
|
|
text-rendering: optimizeLegibility;
|
|
-webkit-user-select: text;
|
|
-moz-user-select: text;
|
|
-ms-user-select: text;
|
|
user-select: text;
|
|
}
|
|
|
|
.verse-text::selection {
|
|
background: rgba(139, 92, 246, 0.4);
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.verse-text::-moz-selection {
|
|
background: rgba(139, 92, 246, 0.4);
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.verse-reference {
|
|
position: relative;
|
|
color: var(--primary-color);
|
|
text-decoration: none;
|
|
}
|
|
|
|
.verse-reference:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.verse-tooltip {
|
|
position: absolute;
|
|
bottom: 100%;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
background: rgba(0, 0, 0, 0.95);
|
|
color: white;
|
|
padding: 0.75rem 1rem;
|
|
border-radius: 6px;
|
|
font-size: 0.9rem;
|
|
line-height: 1.5;
|
|
max-width: 450px;
|
|
min-width: 350px;
|
|
white-space: normal;
|
|
z-index: 1000;
|
|
opacity: 0;
|
|
visibility: hidden;
|
|
transition: opacity 0.3s ease, visibility 0.3s ease;
|
|
pointer-events: none;
|
|
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
|
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
font-family: 'EB Garamond', Georgia, serif;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.verse-tooltip::after {
|
|
content: '';
|
|
position: absolute;
|
|
top: 100%;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
border: 6px solid transparent;
|
|
border-top-color: rgba(0, 0, 0, 0.95);
|
|
}
|
|
|
|
.verse-reference:hover .verse-tooltip {
|
|
opacity: 1;
|
|
visibility: visible;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.verse-text {
|
|
font-size: 1.25rem;
|
|
line-height: 1.7;
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block breadcrumb %}
|
|
<div class="container">
|
|
<nav class="breadcrumb" style="font-size: 1.2rem;">
|
|
<a href="/">📚 All Books</a>
|
|
<span class="breadcrumb-separator">/</span>
|
|
<a href="/book/{{ book }}">{{ book }}</a>
|
|
<span class="breadcrumb-separator">/</span>
|
|
<span>Chapter {{ chapter }}</span>
|
|
</nav>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block container_class %}narrow-container{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="chapter-navigation">
|
|
<div class="chapter-nav-content">
|
|
<div class="chapter-info">
|
|
{{ book }} {{ chapter }} (KJV)
|
|
</div>
|
|
<div class="chapter-controls">
|
|
<button onclick="toggleReadingOptions()" class="nav-button" style="padding: 0.5rem 1rem; font-size: 0.875rem;">
|
|
⚙️ Options
|
|
</button>
|
|
<button onclick="scrollToTop()" class="nav-button" style="padding: 0.5rem 1rem; font-size: 0.875rem;">
|
|
↑ Top
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="reading-options" id="readingOptions" style="display: none;">
|
|
<h3>📖 Reading Options</h3>
|
|
<div class="option-group">
|
|
<label for="fontSize">Text Size:</label>
|
|
<input type="range" id="fontSize" class="range-input" min="16" max="24" value="18" onchange="updateFontSize(this.value)">
|
|
<span id="fontSizeValue">18px</span>
|
|
</div>
|
|
<div class="option-group">
|
|
<label for="lineHeight">Line Spacing:</label>
|
|
<input type="range" id="lineHeight" class="range-input" min="1.4" max="2.2" step="0.1" value="1.75" onchange="updateLineHeight(this.value)">
|
|
<span id="lineHeightValue">1.75</span>
|
|
</div>
|
|
<div class="option-group">
|
|
<label>Verse Numbers:</label>
|
|
<label style="display: flex; align-items: center; gap: 0.5rem; min-width: auto; cursor: pointer;">
|
|
<input type="checkbox" id="showVerseNumbers" checked onchange="toggleVerseNumbers(this.checked)">
|
|
Show verse numbers
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="text-center mb-4">
|
|
<h1 class="chapter-title">{{ book }} {{ chapter }}</h1>
|
|
<p style="font-size: 1rem; color: var(--text-secondary); margin: 0.5rem 0 0 0; font-style: italic;">
|
|
Authorized King James Version (KJV)
|
|
</p>
|
|
</div>
|
|
|
|
<div class="verses-container" id="versesContainer">
|
|
{% for verse in verses %}
|
|
<div class="verse" id="verse-{{ verse.verse }}">
|
|
<span class="verse-number" title="Verse {{ verse.verse }}" onclick="navigateToVerse({{ verse.verse }})">{{ verse.verse }}</span><span class="verse-text">{{ verse.text }}</span>
|
|
<span class="verse-tools">
|
|
<a href="#verse-{{ verse.verse }}" class="verse-tool" title="Link to Verse {{ verse.verse }}" onclick="copyVerseLink({{ verse.verse }})">
|
|
🔗
|
|
</a>
|
|
<a href="#" class="verse-tool" title="Add note to Verse {{ verse.verse }}" onclick="addNote({{ verse.verse }})">
|
|
📝
|
|
</a>
|
|
<a href="#" class="verse-tool" title="Highlight Verse {{ verse.verse }}" onclick="highlightVerse({{ verse.verse }})">
|
|
✨
|
|
</a>
|
|
</span>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
|
|
<div class="commentary-preview" style="background: var(--surface-color); border-radius: var(--radius-lg); padding: 2rem; margin-top: 3rem; border: 1px solid var(--border-light); text-center;">
|
|
<h3 style="color: var(--primary-color); margin: 0 0 1rem; font-family: var(--font-display);">
|
|
🤖 AI Commentary
|
|
</h3>
|
|
{% if book == "Revelation" and chapter == 1 %}
|
|
<div style="background: linear-gradient(135deg, rgba(75, 46, 131, 0.1), rgba(65, 105, 225, 0.1)); border-radius: var(--radius-md); padding: 1.5rem; margin-bottom: 1.5rem; border-left: 4px solid var(--primary-color); box-shadow: var(--shadow-sm);">
|
|
<div style="display: flex; align-items: center; margin-bottom: 0.75rem;">
|
|
<span style="background: var(--primary-color); color: white; padding: 0.25rem 0.5rem; border-radius: var(--radius-sm); font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; margin-right: 0.5rem;">Premium</span>
|
|
<h4 style="margin: 0; font-weight: 600; color: var(--primary-color); font-size: 1.1rem;">✨ Revelation 1: The Apocalyptic Vision ✨</h4>
|
|
</div>
|
|
<p style="color: var(--text-primary); margin: 0 0 1rem; line-height: 1.6; font-style: italic;">
|
|
"I am Alpha and Omega, the beginning and the ending, saith the Lord, which is, and which was, and which is to come, the Almighty." — Revelation 1:8
|
|
</p>
|
|
<div style="display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 1rem;">
|
|
<span style="background: rgba(75, 46, 131, 0.1); color: var(--primary-color); padding: 0.25rem 0.5rem; border-radius: var(--radius-sm); font-size: 0.75rem;">Apocalyptic</span>
|
|
<span style="background: rgba(75, 46, 131, 0.1); color: var(--primary-color); padding: 0.25rem 0.5rem; border-radius: var(--radius-sm); font-size: 0.75rem;">Christology</span>
|
|
<span style="background: rgba(75, 46, 131, 0.1); color: var(--primary-color); padding: 0.25rem 0.5rem; border-radius: var(--radius-sm); font-size: 0.75rem;">Domitian Era</span>
|
|
<span style="background: rgba(75, 46, 131, 0.1); color: var(--primary-color); padding: 0.25rem 0.5rem; border-radius: var(--radius-sm); font-size: 0.75rem;">Seven Churches</span>
|
|
</div>
|
|
<p style="color: var(--text-secondary); margin: 0 0 1.5rem; line-height: 1.6;">
|
|
Explore our detailed verse-by-verse analysis of Revelation 1, featuring historical context from the late first century CE,
|
|
theological insights on apocalyptic literature, and cross-references to Old Testament prophetic visions.
|
|
</p>
|
|
<div style="background: rgba(255, 255, 255, 0.7); border-radius: var(--radius-sm); padding: 0.75rem; margin-bottom: 1rem; border: 1px solid rgba(75, 46, 131, 0.2);">
|
|
<h5 style="margin: 0 0 0.5rem; color: var(--primary-color); font-size: 0.9rem;">Featured Commentary Highlights:</h5>
|
|
<ul style="margin: 0; padding-left: 1.25rem; color: var(--text-secondary); font-size: 0.9rem;">
|
|
<li>Verse-by-verse exegesis with Greek word studies</li>
|
|
<li>Archaeological context of the seven churches</li>
|
|
<li>Counter-imperial themes and symbols</li>
|
|
<li>High Christology in apocalyptic literature</li>
|
|
<li>Connections to Daniel 7, Ezekiel 1, and Zechariah 4</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<p style="color: var(--text-secondary); margin: 0 0 1.5rem; line-height: 1.6;">
|
|
Explore verse-by-verse analysis with historical context, theological insights,
|
|
and cross-references for {{ book }} {{ chapter }} from the Authorized King James Version (KJV).
|
|
</p>
|
|
{% endif %}
|
|
<div class="button-group" style="display: flex; gap: 0.5rem; justify-content: center; flex-wrap: wrap;">
|
|
<a href="#embedded-commentary" class="nav-button" style="display: inline-block; margin-top: 1rem; padding: 0.75rem 1.5rem;">
|
|
View Commentary Below
|
|
</a>
|
|
<a href="/commentary/{{ book }}/{{ chapter }}" class="nav-button nav-button-primary" style="display: inline-block; margin-top: 1rem; padding: 0.75rem 1.5rem;">
|
|
Open Full Commentary
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Embedded Commentary Section -->
|
|
<div id="embedded-commentary" class="embedded-commentary" style="margin-top: 4rem; padding-top: 2rem; border-top: 1px solid var(--border-light);">
|
|
<h2 style="text-align: center; color: var(--primary-color); margin-bottom: 2rem; font-family: var(--font-display);">
|
|
AI Commentary on {{ book }} {{ chapter }}
|
|
</h2>
|
|
|
|
<!-- Chapter Overview -->
|
|
<div class="commentary-card" style="background: var(--surface-color); border-radius: var(--radius-lg); padding: 2rem; margin-bottom: 2rem; border: 1px solid var(--border-light); box-shadow: var(--shadow-sm);">
|
|
<h3 style="color: var(--primary-color); margin-top: 0; margin-bottom: 1rem; font-family: var(--font-display);">
|
|
Chapter Overview
|
|
</h3>
|
|
<div style="color: var(--text-secondary); line-height: 1.7;">
|
|
{{ chapter_overview|safe if chapter_overview else "Chapter overview is not available." }}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Verse-by-Verse Commentary -->
|
|
{% if commentaries %}
|
|
<h3 style="margin: 2rem 0 1rem; color: var(--primary-color); font-family: var(--font-display);">Verse-by-Verse Commentary</h3>
|
|
|
|
{% for verse in verses %}
|
|
{% if verse.verse in commentaries %}
|
|
<div id="commentary-verse-{{ verse.verse }}" class="commentary-card" style="background: var(--surface-color); border-radius: var(--radius-lg); padding: 1.5rem; margin-bottom: 1.5rem; border: 1px solid var(--border-light); box-shadow: var(--shadow-sm);">
|
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem; padding-bottom: 0.5rem; border-bottom: 1px solid var(--border-light);">
|
|
<h4 style="margin: 0; color: var(--primary-color); font-family: var(--font-display);">
|
|
<a href="#verse-{{ verse.verse }}" class="verse-link" style="text-decoration: none; color: inherit;">
|
|
Verse {{ verse.verse }}
|
|
</a>
|
|
</h4>
|
|
<a href="/commentary/{{ book }}/{{ chapter }}#verse-{{ verse.verse }}" style="font-size: 0.875rem; color: var(--primary-color); text-decoration: none;">
|
|
View in Full Commentary
|
|
</a>
|
|
</div>
|
|
|
|
<div class="verse-quote" style="background: rgba(255, 235, 59, 0.1); padding: 1rem; border-radius: var(--radius-md); margin-bottom: 1rem; border-left: 3px solid rgba(255, 235, 59, 0.5); font-family: var(--font-serif);">
|
|
{{ verse.text }}
|
|
</div>
|
|
|
|
<div style="display: flex; gap: 1rem; margin-bottom: 1rem; overflow-x: auto; padding-bottom: 0.5rem;">
|
|
<button class="tab active" onclick="switchCommentaryTab({{ verse.verse }}, 'analysis')" style="background: none; border: none; padding: 0.5rem 1rem; cursor: pointer; border-bottom: 2px solid var(--primary-color); color: var(--primary-color); font-weight: 500;">
|
|
Analysis
|
|
</button>
|
|
<button class="tab" onclick="switchCommentaryTab({{ verse.verse }}, 'historical')" style="background: none; border: none; padding: 0.5rem 1rem; cursor: pointer; border-bottom: 2px solid transparent; color: var(--text-secondary);">
|
|
Historical Context
|
|
</button>
|
|
<button class="tab" onclick="switchCommentaryTab({{ verse.verse }}, 'questions')" style="background: none; border: none; padding: 0.5rem 1rem; cursor: pointer; border-bottom: 2px solid transparent; color: var(--text-secondary);">
|
|
Study Questions
|
|
</button>
|
|
</div>
|
|
|
|
<div id="tab-{{ verse.verse }}-analysis" class="tab-content active" style="color: var(--text-secondary); line-height: 1.7;">
|
|
{{ commentaries[verse.verse].analysis|safe }}
|
|
|
|
{% if commentaries[verse.verse].cross_references %}
|
|
<div style="background: rgba(75, 46, 131, 0.05); padding: 1rem; border-radius: var(--radius-md); margin-top: 1rem;">
|
|
<h5 style="margin: 0 0 0.5rem; font-size: 0.875rem; color: var(--primary-color);">Cross References:</h5>
|
|
<ul style="margin: 0; padding-left: 1.25rem;">
|
|
{% for ref in commentaries[verse.verse].cross_references %}
|
|
<li>
|
|
<a href="{{ ref.url }}" class="verse-reference" style="color: var(--primary-color); text-decoration: none;">
|
|
{{ ref.text }}
|
|
<span class="verse-tooltip">{{ ref.verse_text|default(ref.context) }}</span>
|
|
</a> - {{ ref.context }}
|
|
</li>
|
|
{% endfor %}
|
|
</ul>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div id="tab-{{ verse.verse }}-historical" class="tab-content" style="display: none; color: var(--text-secondary); line-height: 1.7;">
|
|
{{ commentaries[verse.verse].historical|safe }}
|
|
</div>
|
|
|
|
<div id="tab-{{ verse.verse }}-questions" class="tab-content" style="display: none; color: var(--text-secondary); line-height: 1.7;">
|
|
<ol style="padding-left: 1.25rem; margin: 0;">
|
|
{% for question in commentaries[verse.verse].questions %}
|
|
<li style="margin-bottom: 0.75rem;">{{ question }}</li>
|
|
{% endfor %}
|
|
</ol>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
{% endfor %}
|
|
|
|
{% else %}
|
|
<div style="text-align: center; padding: 2rem; background: var(--surface-color); border-radius: var(--radius-lg); margin-bottom: 2rem; border: 1px solid var(--border-light);">
|
|
<p style="color: var(--text-secondary); margin: 0 0 1rem;">Commentary is still loading or not available for this chapter.</p>
|
|
<a href="/commentary/{{ book }}/{{ chapter }}" class="nav-button nav-button-primary">
|
|
Try Full Commentary
|
|
</a>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block navigation %}
|
|
<div class="container">
|
|
<div class="navigation">
|
|
<a href="/book/{{ book }}" class="nav-button" style="font-size: 1.2rem;">
|
|
← All Chapters
|
|
</a>
|
|
<div style="display: flex; gap: 0.5rem;">
|
|
{% if chapter > 1 %}
|
|
<a href="/book/{{ book }}/chapter/{{ chapter - 1 }}" class="nav-button" style="font-size: 1.2rem;">
|
|
← {{ book }} {{ chapter - 1 }}
|
|
</a>
|
|
{% endif %}
|
|
{% if chapter < chapters|length %}
|
|
<a href="/book/{{ book }}/chapter/{{ chapter + 1 }}" class="nav-button nav-button-primary" style="font-size: 1.2rem;">
|
|
{{ book }} {{ chapter + 1 }} →
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block scripts %}
|
|
<script>
|
|
function toggleReadingOptions() {
|
|
const options = document.getElementById('readingOptions');
|
|
options.style.display = options.style.display === 'none' ? 'block' : 'none';
|
|
}
|
|
|
|
function updateFontSize(value) {
|
|
const container = document.getElementById('versesContainer');
|
|
container.style.fontSize = value + 'px';
|
|
document.getElementById('fontSizeValue').textContent = value + 'px';
|
|
localStorage.setItem('kjv-font-size', value);
|
|
}
|
|
|
|
function updateLineHeight(value) {
|
|
const verses = document.querySelectorAll('.verse');
|
|
verses.forEach(verse => {
|
|
verse.style.lineHeight = value;
|
|
});
|
|
document.getElementById('lineHeightValue').textContent = value;
|
|
localStorage.setItem('kjv-line-height', value);
|
|
}
|
|
|
|
function toggleVerseNumbers(show) {
|
|
const numbers = document.querySelectorAll('.verse-number');
|
|
numbers.forEach(number => {
|
|
number.style.display = show ? 'inline' : 'none';
|
|
});
|
|
localStorage.setItem('kjv-show-verse-numbers', show);
|
|
}
|
|
|
|
function copyVerseLink(verseNumber) {
|
|
const url = window.location.origin + window.location.pathname + '#verse-' + verseNumber;
|
|
navigator.clipboard.writeText(url).then(() => {
|
|
showToast('Verse ' + verseNumber + ' link copied to clipboard!');
|
|
});
|
|
}
|
|
|
|
function addNote(verseNumber) {
|
|
showToast('Note feature coming soon!');
|
|
}
|
|
|
|
function highlightVerse(verseNumber) {
|
|
const verse = document.getElementById('verse-' + verseNumber);
|
|
const verseText = verse.querySelector('.verse-text');
|
|
verseText.classList.toggle('verse-highlight');
|
|
|
|
const highlighted = verseText.classList.contains('verse-highlight');
|
|
showToast(highlighted ? 'Verse ' + verseNumber + ' highlighted!' : 'Highlight removed from Verse ' + verseNumber);
|
|
}
|
|
|
|
function navigateToVerse(verseNumber) {
|
|
location.hash = 'verse-' + verseNumber;
|
|
showToast('Navigated to Verse ' + verseNumber);
|
|
}
|
|
|
|
function scrollToTop() {
|
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
}
|
|
|
|
function switchCommentaryTab(verseNumber, tabName) {
|
|
// Hide all tabs for this verse
|
|
const tabContents = document.querySelectorAll(`#commentary-verse-${verseNumber} .tab-content`);
|
|
tabContents.forEach(tab => tab.style.display = 'none');
|
|
|
|
// Deactivate all tab buttons
|
|
const tabButtons = document.querySelectorAll(`#commentary-verse-${verseNumber} .tab`);
|
|
tabButtons.forEach(button => {
|
|
button.classList.remove('active');
|
|
button.style.borderBottom = '2px solid transparent';
|
|
button.style.color = 'var(--text-secondary)';
|
|
});
|
|
|
|
// Activate the selected tab
|
|
document.getElementById(`tab-${verseNumber}-${tabName}`).style.display = 'block';
|
|
|
|
// Activate the tab button
|
|
const activeButton = document.querySelector(`#commentary-verse-${verseNumber} .tab:nth-child(${tabName === 'analysis' ? 1 : tabName === 'historical' ? 2 : 3})`);
|
|
activeButton.classList.add('active');
|
|
activeButton.style.borderBottom = '2px solid var(--primary-color)';
|
|
activeButton.style.color = 'var(--primary-color)';
|
|
activeButton.style.fontWeight = '500';
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
// Load saved preferences
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const savedFontSize = localStorage.getItem('kjv-font-size');
|
|
if (savedFontSize) {
|
|
document.getElementById('fontSize').value = savedFontSize;
|
|
updateFontSize(savedFontSize);
|
|
}
|
|
|
|
const savedLineHeight = localStorage.getItem('kjv-line-height');
|
|
if (savedLineHeight) {
|
|
document.getElementById('lineHeight').value = savedLineHeight;
|
|
updateLineHeight(savedLineHeight);
|
|
}
|
|
|
|
const savedShowNumbers = localStorage.getItem('kjv-show-verse-numbers');
|
|
if (savedShowNumbers === 'false') {
|
|
document.getElementById('showVerseNumbers').checked = false;
|
|
toggleVerseNumbers(false);
|
|
}
|
|
|
|
// Highlight verse from URL hash
|
|
if (window.location.hash) {
|
|
setTimeout(() => {
|
|
const target = document.querySelector(window.location.hash);
|
|
if (target) {
|
|
target.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
|
|
// Extract verse number from the hash
|
|
const verseMatch = window.location.hash.match(/verse-(\d+)/);
|
|
if (verseMatch && verseMatch[1]) {
|
|
showToast('Navigated to Verse ' + verseMatch[1]);
|
|
|
|
// If the verse has commentary, highlight the commentary card too
|
|
const commentaryCard = document.getElementById(`commentary-verse-${verseMatch[1]}`);
|
|
if (commentaryCard) {
|
|
commentaryCard.style.border = '2px solid var(--primary-color)';
|
|
commentaryCard.style.boxShadow = 'var(--shadow-md)';
|
|
setTimeout(() => {
|
|
commentaryCard.style.border = '1px solid var(--border-light)';
|
|
commentaryCard.style.boxShadow = 'var(--shadow-sm)';
|
|
}, 3000);
|
|
}
|
|
}
|
|
|
|
// Apply highlighting
|
|
target.classList.add('highlight-verse');
|
|
setTimeout(() => {
|
|
target.classList.remove('highlight-verse');
|
|
}, 2000);
|
|
}
|
|
}, 100);
|
|
}
|
|
|
|
// Add cross-links from verses to commentary
|
|
document.querySelectorAll('.verse').forEach(verse => {
|
|
const verseNum = verse.id.replace('verse-', '');
|
|
const commentaryEl = document.getElementById(`commentary-verse-${verseNum}`);
|
|
|
|
if (commentaryEl) {
|
|
// Mark verses with commentary
|
|
const verseTools = verse.querySelector('.verse-tools');
|
|
if (verseTools) {
|
|
const commentaryLink = document.createElement('a');
|
|
commentaryLink.href = `#commentary-verse-${verseNum}`;
|
|
commentaryLink.className = 'verse-tool';
|
|
commentaryLink.title = `View commentary for Verse ${verseNum}`;
|
|
commentaryLink.innerHTML = '💡';
|
|
commentaryLink.onclick = function(e) {
|
|
e.preventDefault();
|
|
commentaryEl.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
commentaryEl.style.border = '2px solid var(--primary-color)';
|
|
commentaryEl.style.boxShadow = 'var(--shadow-md)';
|
|
setTimeout(() => {
|
|
commentaryEl.style.border = '1px solid var(--border-light)';
|
|
commentaryEl.style.boxShadow = 'var(--shadow-sm)';
|
|
}, 3000);
|
|
return false;
|
|
};
|
|
verseTools.appendChild(commentaryLink);
|
|
}
|
|
|
|
// Add visual indicator to verses with commentary
|
|
const verseNumber = verse.querySelector('.verse-number');
|
|
if (verseNumber) {
|
|
const indicator = document.createElement('span');
|
|
indicator.style.cssText = `
|
|
display: inline-block;
|
|
width: 5px;
|
|
height: 5px;
|
|
border-radius: 50%;
|
|
background-color: var(--primary-color);
|
|
margin-left: 2px;
|
|
vertical-align: text-top;
|
|
`;
|
|
verseNumber.appendChild(indicator);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
// Add CSS animations
|
|
const style = document.createElement('style');
|
|
style.textContent = `
|
|
@keyframes slideIn {
|
|
from { transform: translateX(100%); opacity: 0; }
|
|
to { transform: translateX(0); opacity: 1; }
|
|
}
|
|
@keyframes slideOut {
|
|
from { transform: translateX(0); opacity: 1; }
|
|
to { transform: translateX(100%); opacity: 0; }
|
|
}
|
|
`;
|
|
document.head.appendChild(style);
|
|
</script>
|
|
{% endblock %} |