Files
kennethreitzandClaude Fable 5 5e05bf1dc3 Refresh reading plans and the kids story pages
reading_plans.html: elevated plan cards with accent hover lift, bronze
small-caps durations, token-coloured progress bars and "Your Reading
Plans" progress rows (accent wash instead of the old green rgba),
gold-tipped small-caps section headings, keyboard nav on the accent
token.

story_kids.html: the page was pure Tailwind indigo/violet/amber. Kept
the playfulness — rounded plates, pill chips, stars, dashed borders —
but recoloured everything into the site's family: warm gold-to-green
gradient header with a bronze category pill and green title, gilt
star-prefixed character badges, gold asterism dividers, tokenised meta
cards, callout, action chips, and prev/next labels. Removed all 70
lines of per-page dark-mode overrides; tokens handle dark mode.

All 976 tests pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 00:01:22 -04:00

446 lines
14 KiB
HTML

{% extends "base.html" %}
{% block title %}Bible Reading Plans - KJV Study{% endblock %}
{% block description %}Structured Bible reading schedules for systematic Scripture study{% endblock %}
{% block head %}
<style>
.plan-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1.5rem;
max-width: 90%;
margin: 2rem 0;
}
.plan-card {
display: block;
padding: 1.4rem 1.5rem;
background: var(--bg-elevated);
border: 1px solid var(--border-color-dark);
border-radius: 8px;
transition: all 0.2s ease;
text-decoration: none;
color: inherit;
cursor: pointer;
}
.plan-card:hover {
border-color: var(--accent);
box-shadow: var(--shadow-soft);
transform: translateY(-2px);
}
.plan-name {
font-size: 1.35rem;
font-weight: 600;
margin-bottom: 0.5rem;
color: var(--text-strong);
transition: color 0.15s ease;
}
.plan-card:hover .plan-name {
color: var(--accent-strong);
}
.plan-description {
font-size: 1rem;
color: var(--text-secondary);
line-height: 1.6;
margin: 0.5rem 0;
}
.plan-duration {
font-size: 0.7rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.14em;
color: var(--bronze);
margin-top: 0.85rem;
}
.plan-progress {
margin-top: 0.75rem;
display: none;
}
.plan-progress.has-progress {
display: block;
}
.plan-progress-bar {
height: 6px;
background: var(--border-color);
border-radius: 3px;
overflow: hidden;
}
.plan-progress-fill {
height: 100%;
background: var(--accent);
transition: width 0.3s;
}
.plan-progress-text {
font-size: 0.8rem;
color: var(--accent-strong);
margin-top: 0.3rem;
font-weight: 500;
}
.your-plans {
display: none;
}
.your-plans.has-plans {
display: block;
}
.your-plans-list {
list-style: none;
padding: 0;
margin: 1rem 0;
max-width: 60%;
}
.your-plans-list li {
padding: 0.85rem 1.1rem;
border: 1px solid var(--border-color-dark);
border-radius: 8px;
margin-bottom: 0.6rem;
display: flex;
align-items: center;
gap: 1rem;
background: linear-gradient(to right, var(--accent-soft) var(--progress, 0%), var(--bg-elevated) var(--progress, 0%));
position: relative;
transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.your-plans-list li:hover {
border-color: var(--accent);
box-shadow: var(--shadow-soft);
}
.your-plan-link {
font-weight: 600;
color: var(--text-strong);
text-decoration: none;
border-bottom: none;
}
.your-plan-link:hover {
color: var(--accent-strong);
}
.your-plan-next {
color: var(--text-secondary);
font-size: 0.9rem;
margin-left: auto;
}
.your-plan-progress {
font-size: 0.8rem;
font-weight: 600;
color: var(--accent-strong);
}
.your-plan-completed {
font-size: 0.72rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.12em;
color: var(--bronze);
}
/* Section headings — small caps over a gold-tipped rule */
#your-reading-plans h2,
#available-reading-plans h2,
#using-reading-plans h2 {
position: relative;
font-size: 0.95rem !important;
font-weight: 600;
font-style: normal !important;
text-transform: uppercase;
letter-spacing: 0.18em;
color: var(--text-secondary) !important;
margin: 0 0 1.25rem;
padding-bottom: 0.6rem;
border-bottom: 1px solid var(--border-color);
max-width: 90%;
}
#your-reading-plans h2::after,
#available-reading-plans h2::after,
#using-reading-plans h2::after {
content: '';
position: absolute;
left: 0;
bottom: -1px;
width: 2.75rem;
height: 1px;
background: var(--gold);
}
/* Mobile optimizations */
@media (max-width: 768px) {
.plan-grid {
max-width: 100%;
grid-template-columns: 1fr;
gap: 1rem;
}
.plan-card {
padding: 1.25rem;
}
.plan-name {
font-size: 1.2rem;
}
.plan-description {
font-size: 0.95rem;
}
.intro-text {
max-width: 100%;
font-size: 1.05rem;
}
.your-plans-section {
padding: 1rem;
}
.your-plan-item {
flex-direction: column;
align-items: flex-start;
gap: 0.5rem;
}
.your-plan-next {
margin-left: 0;
}
}
</style>
{% endblock %}
{% block content %}
<h1>Bible Reading Plans</h1>
<p class="subtitle">Structured Schedules for Systematic Scripture Study</p>
<section>
<p class="intro-text"><span class="newthought">Systematic Bible reading</span> provides structure for comprehensive Scripture engagement. These curated plans offer various approaches—chronological progression, thematic focus, or testament-specific study—each designed to facilitate sustained interaction with God's Word.</p>
<p class="intro-text">Whether pursuing canonical familiarity through complete Bible reading or concentrating on specific portions, these schedules provide daily guidance for disciplined Scripture intake. Select a plan suited to your current season and study objectives.</p>
</section>
<div id="your-reading-plans" class="your-plans">
<h2 id="your-plans-heading">Your Reading Plans</h2>
<ul class="your-plans-list" id="your-plans-list"></ul>
</div>
<section id="available-reading-plans">
<h2>Available Reading Plans</h2>
<div class="plan-grid">
{% for plan in plans %}
<a href="/reading-plans/{{ plan.id }}" class="plan-card" data-plan-id="{{ plan.id }}" data-total-days="{{ plan.days }}">
<div class="plan-name">{{ plan.name }}</div>
<div class="plan-description">{{ plan.description }}</div>
<div class="plan-duration">{{ plan.days }} days</div>
<div class="plan-progress">
<div class="plan-progress-bar">
<div class="plan-progress-fill" style="width: 0%"></div>
</div>
<div class="plan-progress-text"></div>
</div>
</a>
{% endfor %}
</div>
</section>
<section id="using-reading-plans">
<h2>Using Reading Plans</h2>
<p class="intro-text">Select a plan above to view its complete schedule. Each plan provides daily readings with thematic notes. Consider marking your progress and maintaining consistency—even brief daily reading surpasses sporadic lengthy sessions in forming lasting Scripture engagement habits.</p>
</section>
<script>
(function() {
// Load and display progress for each plan
const cards = Array.from(document.querySelectorAll('.plan-card'));
var yourPlansSection = document.getElementById('your-reading-plans');
var yourPlansList = document.getElementById('your-plans-list');
var plansWithProgress = [];
cards.forEach(function(card) {
var planId = card.dataset.planId;
var totalDays = parseInt(card.dataset.totalDays);
var storageKey = 'reading-plan-' + planId;
var saved = localStorage.getItem(storageKey);
if (saved) {
try {
var data = JSON.parse(saved);
var completed = data.completed ? data.completed.length : 0;
if (completed > 0) {
var percent = Math.round((completed / totalDays) * 100);
var progressEl = card.querySelector('.plan-progress');
var fillEl = card.querySelector('.plan-progress-fill');
var textEl = card.querySelector('.plan-progress-text');
progressEl.classList.add('has-progress');
fillEl.style.width = percent + '%';
if (completed === totalDays) {
textEl.textContent = 'Completed!';
} else {
textEl.textContent = completed + '/' + totalDays + ' days (' + percent + '%)';
}
// Add to your plans list
var planName = card.querySelector('.plan-name').textContent;
var nextDay = completed + 1;
var isComplete = completed >= totalDays;
plansWithProgress.push({
id: planId,
name: planName,
completed: completed,
totalDays: totalDays,
nextDay: nextDay,
isComplete: isComplete,
percent: percent
});
}
} catch(e) {}
}
});
// Populate "Your Reading Plans" section
if (plansWithProgress.length > 0) {
yourPlansSection.classList.add('has-plans');
var heading = document.getElementById('your-plans-heading');
if (plansWithProgress.length === 1) {
heading.textContent = 'Your Reading Plan';
}
plansWithProgress.forEach(function(plan) {
var li = document.createElement('li');
var statusText;
if (plan.isComplete) {
statusText = '<span class="your-plan-completed">Completed!</span>';
} else {
statusText = '<span class="your-plan-next">Up next: Day ' + plan.nextDay + '</span>';
}
li.style.setProperty('--progress', plan.percent + '%');
li.innerHTML = '<a href="/reading-plans/' + plan.id + '" class="your-plan-link">' + plan.name + '</a>' +
'<span class="your-plan-progress">' + plan.percent + '%</span>' +
statusText;
yourPlansList.appendChild(li);
});
}
// Keyboard navigation - combine your plans list items + grid cards
var yourPlanItems = Array.from(document.querySelectorAll('.your-plans-list li'));
var allNavItems = yourPlanItems.concat(Array.from(cards));
if (allNavItems.length === 0) return;
var selectedIndex = -1;
var yourPlansCount = yourPlanItems.length;
function getGridColumns() {
if (window.innerWidth <= 768) return 1;
const grid = document.querySelector('.plan-grid');
if (!grid) return 1;
const style = getComputedStyle(grid);
const cols = style.gridTemplateColumns.split(' ').length;
return cols || 1;
}
function clearSelection() {
if (selectedIndex >= 0 && selectedIndex < allNavItems.length) {
allNavItems[selectedIndex].style.outline = '';
allNavItems[selectedIndex].style.outlineOffset = '';
allNavItems[selectedIndex].classList.remove('selected');
}
}
function selectItem(index) {
clearSelection();
selectedIndex = Math.max(0, Math.min(index, allNavItems.length - 1));
allNavItems[selectedIndex].style.outline = '2px solid var(--accent)';
allNavItems[selectedIndex].style.outlineOffset = '2px';
allNavItems[selectedIndex].classList.add('selected');
allNavItems[selectedIndex].scrollIntoView({ behavior: 'auto', block: 'center' });
}
function getItemLink(item) {
// For li items, find the link inside; for cards, the item IS the link
if (item.tagName === 'LI') {
var link = item.querySelector('a');
return link ? link.href : null;
}
return item.href;
}
document.addEventListener('keydown', function(e) {
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
if (KJVNav.sidebarActive) return;
var cols = getGridColumns();
var inYourPlans = selectedIndex >= 0 && selectedIndex < yourPlansCount;
var inGrid = selectedIndex >= yourPlansCount;
if (e.key === 'ArrowDown' || e.key === 'j') {
e.preventDefault();
if (selectedIndex < 0) {
selectItem(0);
} else if (inYourPlans) {
// Move down in your plans list, or to grid
if (selectedIndex + 1 < yourPlansCount) {
selectItem(selectedIndex + 1);
} else {
selectItem(yourPlansCount); // First grid item
}
} else {
// In grid, move down by columns
selectItem(selectedIndex + cols);
}
} else if (e.key === 'ArrowUp' || e.key === 'k') {
e.preventDefault();
if (selectedIndex < 0) {
selectItem(0);
} else if (inYourPlans) {
if (selectedIndex > 0) selectItem(selectedIndex - 1);
} else {
// In grid
var newIndex = selectedIndex - cols;
if (newIndex >= yourPlansCount) {
selectItem(newIndex);
} else if (yourPlansCount > 0) {
// Jump to last your-plan item
selectItem(yourPlansCount - 1);
}
}
} else if (e.key === 'ArrowRight' || e.key === 'l') {
e.preventDefault();
if (selectedIndex < 0) selectItem(0);
else if (inGrid) selectItem(selectedIndex + 1);
} else if (e.key === 'ArrowLeft' || e.key === 'h') {
e.preventDefault();
if (selectedIndex <= 0) history.back();
else if (inGrid && selectedIndex > yourPlansCount) selectItem(selectedIndex - 1);
else if (inYourPlans) history.back();
} else if (e.key === 'Enter' && selectedIndex >= 0) {
e.preventDefault();
var href = getItemLink(allNavItems[selectedIndex]);
if (href) window.location.href = href;
} else if (e.key === 'Escape') {
e.preventDefault();
clearSelection();
selectedIndex = -1;
}
});
})();
</script>
{% endblock %}