Skip to content

Commit 9266020

Browse files
author
Luke
committed
Add Nicene Creed and Messianc Prophecies
1 parent 37daa00 commit 9266020

2 files changed

Lines changed: 1401 additions & 14 deletions

File tree

index.html

Lines changed: 299 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@
173173
transform: scale(0.95);
174174
}
175175
</style>
176+
<style id="presentation-styles">
177+
!PRESENTATION_STYLES!
178+
</style>
176179
</head>
177180
<body class="bg-gray-900 text-gray-100 h-screen flex flex-col">
178181
<!-- Overlay for mobile drawers -->
@@ -217,8 +220,14 @@ <h1 class="text-base sm:text-lg font-bold text-blue-400 truncate">Bible Cross-Re
217220
class="w-20 sm:w-24 h-2 bg-gray-700 rounded-lg cursor-pointer">
218221
<span id="arc-value" class="text-xs w-8">500</span>
219222
</div>
220-
<input type="text" id="search-input" placeholder="Search (e.g., John 3:16, Gen 1:1-3)... "
221-
class="bg-gray-700 text-gray-100 text-xs rounded px-2 py-1 w-24 sm:w-48 focus:outline-none focus:ring-2 focus:ring-blue-500">
223+
<button onclick="openPresentation('creed')" class="text-xs bg-gray-700 hover:bg-blue-600 px-2 sm:px-3 py-1.5 rounded border border-gray-600 hover:border-blue-500 text-blue-400 hover:text-white transition-colors whitespace-nowrap">
224+
Nicene Creed
225+
</button>
226+
<button onclick="openPresentation('prophecy')" class="text-xs bg-gray-700 hover:bg-blue-600 px-2 sm:px-3 py-1.5 rounded border border-gray-600 hover:border-blue-500 text-blue-400 hover:text-white transition-colors whitespace-nowrap">
227+
Prophecies
228+
</button>
229+
<input type="text" id="search-input" placeholder="Search... "
230+
class="bg-gray-700 text-gray-100 text-xs rounded px-2 py-1 w-24 sm:w-32 focus:outline-none focus:ring-2 focus:ring-blue-500">
222231
<button onclick="toggleHelp()" class="text-gray-400 hover:text-blue-300 transition-colors" title="Help">
223232
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
224233
<circle cx="12" cy="12" r="10"></circle>
@@ -246,7 +255,6 @@ <h2 class="text-sm font-semibold text-blue-400">How to Use</h2>
246255
<h3 class="font-semibold text-gray-100 mb-1">What You're Viewing</h3>
247256
<p class="leading-relaxed">Thousands of Bible cross-references mapped to Rainbow-colored themes. Each arc shows a connection between two verses, colored by the dominant theme of the source verse.</p>
248257
</div>
249-
250258
<div>
251259
<h3 class="font-semibold text-gray-100 mb-1">Navigate Visualization</h3>
252260
<ul class="space-y-1 ml-4 list-disc">
@@ -256,7 +264,6 @@ <h3 class="font-semibold text-gray-100 mb-1">Navigate Visualization</h3>
256264
<li><strong>Use keyboard arrows</strong> ← → for quick navigation</li>
257265
</ul>
258266
</div>
259-
260267
<div>
261268
<h3 class="font-semibold text-gray-100 mb-1">View Details</h3>
262269
<ul class="space-y-1 ml-4 list-disc">
@@ -265,30 +272,41 @@ <h3 class="font-semibold text-gray-100 mb-1">View Details</h3>
265272
<li><strong>Bible Difficulties</strong> appear below arcs when scrolled</li>
266273
</ul>
267274
</div>
268-
269275
<div>
270-
<h3 class="font-semibold text-gray-100 mb-1">Rainbow Themes</h3>
271-
<p class="leading-relaxed">Each color represents a theological theme (e.g., God=blue, Creation=green, Redemption=purple). Filter by theme using the sidebar.</p>
276+
<h3 class="font-semibold text-gray-100 mb-1">Presentations</h3>
277+
<ul class="space-y-1 ml-4 list-disc">
278+
<li><strong>Nicene Creed</strong> - 16-slide presentation with correlating KJV scriptures</li>
279+
<li><strong>Prophecies</strong> - 18 messianic prophecies with fulfillment verses</li>
280+
</ul>
272281
</div>
273-
274282
<div>
275283
<h3 class="font-semibold text-gray-100 mb-1">Controls</h3>
276284
<ul class="space-y-1 ml-4 list-disc">
277285
<li><strong>Votes slider</strong> — filter cross-references by community votes</li>
278286
<li><strong>Arcs slider</strong> — limit number of visible arcs</li>
279-
<li><strong>Search</strong> — find books (e.g., "Genesis") or verses (e.g., "John 3:16", "Gen 1:1-3")</li>
280-
<li><strong>Verse search</strong> — finds verse + all connected cross-references (shows relevant arcs only)</li>
281-
<li><strong>Source filters</strong> — toggle Bible difficulties by source</li>
287+
<li><strong>Search</strong> — find books or verses</li>
282288
</ul>
283289
</div>
284-
285290
<div class="pt-2 border-t border-gray-700">
286291
<p class="text-gray-500 italic">Use the <kbd class="bg-gray-700 px-1.5 py-0.5 rounded text-[10px]">?</kbd> button to show/hide this help</p>
287292
</div>
288293
</div>
289294
</div>
290295
</div>
291296

297+
<!-- Presentation Overlay -->
298+
<div id="presentation-overlay" class="fixed inset-0 bg-black/80 backdrop-blur-sm z-[100] hidden">
299+
<button onclick="closePresentation()" class="absolute top-4 right-4 z-50 w-10 h-10 bg-gray-800/90 hover:bg-gray-700 border border-gray-600 rounded-full flex items-center justify-center text-white transition-all hover:scale-110" title="Close presentation">
300+
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
301+
<line x1="18" y1="6" x2="6" y2="18"></line>
302+
<line x1="6" y1="6" x2="18" y2="18"></line>
303+
</svg>
304+
</button>
305+
<div id="presentation-content" class="w-full h-full overflow-auto">
306+
<!-- Presentation content will be injected here -->
307+
</div>
308+
</div>
309+
292310
<!-- Mobile Controls Bar -->
293311
<div class="mobile-only bg-gray-800 border-b border-gray-700 px-3 py-2 flex items-center gap-3 flex-shrink-0">
294312
<div class="flex items-center gap-1">
@@ -2848,6 +2866,273 @@ <h4 class="text-xs font-semibold text-gray-400 uppercase mb-1">Cross-References
28482866
requestAnimationFrame(animate);
28492867
}
28502868
animate();
2851-
</script>
2852-
</body>
2869+
</script>
2870+
2871+
<script src="presentation_data.js"></script>
2872+
2873+
<script>
2874+
(function() {
2875+
'use strict';
2876+
2877+
// Presentation overlay management
2878+
let presentationContent = '';
2879+
let cleanupFunction = null;
2880+
2881+
function openPresentation(type) {
2882+
const overlay = document.getElementById('presentation-overlay');
2883+
const contentDiv = document.getElementById('presentation-content');
2884+
const stylesElement = document.getElementById('presentation-styles');
2885+
2886+
// Show overlay
2887+
overlay.classList.remove('hidden');
2888+
document.body.style.overflow = 'hidden';
2889+
2890+
// Load presentation styles and content
2891+
if (type === 'creed') {
2892+
stylesElement.textContent = PRESENTATION_STYLES;
2893+
presentationContent = `
2894+
<div class="bg-animation"></div>
2895+
<div class="particles" id="creed-particles"></div>
2896+
<div class="main-container">
2897+
<div class="title">Nicene Creed</div>
2898+
<div class="creed-container">
2899+
<div class="slide-container" id="creed-slideContainer">${creedSlidesHTML}</div>
2900+
<div class="progress-container" id="creed-progressContainer"></div>
2901+
<div class="nav-buttons">
2902+
<button class="nav-btn" id="creed-prevBtn">← Previous</button>
2903+
<button class="nav-btn pause-btn" id="creed-pauseBtn">Pause</button>
2904+
<button class="nav-btn" id="creed-nextBtn">Next →</button>
2905+
</div>
2906+
<div class="footer">"Jesus answered them, and said, My doctrine is not mine, but his that sent me." - John 7:16</div>
2907+
</div>
2908+
</div>
2909+
`;
2910+
contentDiv.innerHTML = presentationContent;
2911+
initCreedPresentation();
2912+
} else if (type === 'prophecy') {
2913+
stylesElement.textContent = PRESENTATION_STYLES;
2914+
presentationContent = `
2915+
<div class="bg-animation"></div>
2916+
<div class="particles" id="prophecy-particles"></div>
2917+
<div class="main-container">
2918+
<div class="title">Messianic Prophecies</div>
2919+
<div class="creed-container">
2920+
<div class="slide-container" id="prophecy-slideContainer">${prophecySlidesHTML}</div>
2921+
<div class="progress-container" id="prophecy-progressContainer"></div>
2922+
<div class="nav-buttons">
2923+
<button class="nav-btn" id="prophecy-prevBtn">← Previous</button>
2924+
<button class="nav-btn pause-btn" id="prophecy-pauseBtn">Pause</button>
2925+
<button class="nav-btn" id="prophecy-nextBtn">Next →</button>
2926+
</div>
2927+
<div class="footer">"Search the scriptures; for in them ye think ye have eternal life: and they are they which testify of me." - John 5:39</div>
2928+
</div>
2929+
</div>
2930+
`;
2931+
contentDiv.innerHTML = presentationContent;
2932+
initProphecyPresentation();
2933+
}
2934+
}
2935+
2936+
function closePresentation() {
2937+
const overlay = document.getElementById('presentation-overlay');
2938+
const contentDiv = document.getElementById('presentation-content');
2939+
const stylesElement = document.getElementById('presentation-styles');
2940+
2941+
// Clean up presentation interval if exists
2942+
if (cleanupFunction) {
2943+
cleanupFunction();
2944+
cleanupFunction = null;
2945+
}
2946+
2947+
// Clear content and styles
2948+
contentDiv.innerHTML = '';
2949+
stylesElement.textContent = '';
2950+
2951+
// Hide overlay
2952+
overlay.classList.add('hidden');
2953+
document.body.style.overflow = '';
2954+
}
2955+
2956+
// Initialize Nicene Creed presentation
2957+
function initCreedPresentation() {
2958+
initPresentation('creed');
2959+
}
2960+
2961+
// Initialize Prophecy presentation
2962+
function initProphecyPresentation() {
2963+
initPresentation('prophecy');
2964+
}
2965+
2966+
// Generic presentation initialization
2967+
function initPresentation(prefix) {
2968+
const SLIDE_DURATION = 12000;
2969+
let currentSlide = 0;
2970+
let slideInterval = null;
2971+
let isPaused = false;
2972+
2973+
const prefixLower = prefix.toLowerCase();
2974+
const slides = document.getElementById(prefixLower + '-slideContainer').querySelectorAll('.slide');
2975+
const progressContainer = document.getElementById(prefixLower + '-progressContainer');
2976+
const prevBtn = document.getElementById(prefixLower + '-prevBtn');
2977+
const nextBtn = document.getElementById(prefixLower + '-nextBtn');
2978+
const pauseBtn = document.getElementById(prefixLower + '-pauseBtn');
2979+
const particlesContainer = document.getElementById(prefixLower + '-particles');
2980+
2981+
if (!slides.length) {
2982+
console.error('No slides found for', prefix);
2983+
return;
2984+
}
2985+
2986+
// Create particles
2987+
for (let i = 0; i < 30; i++) {
2988+
const particle = document.createElement('div');
2989+
particle.className = 'particle';
2990+
particle.style.left = Math.random() * 100 + '%';
2991+
particle.style.animationDelay = Math.random() * 8 + 's';
2992+
particle.style.animationDuration = (6 + Math.random() * 4) + 's';
2993+
particlesContainer.appendChild(particle);
2994+
}
2995+
2996+
// Create progress dots
2997+
slides.forEach((_, index) => {
2998+
const dot = document.createElement('div');
2999+
dot.className = 'progress-dot' + (index === 0 ? ' active' : '');
3000+
dot.addEventListener('click', () => goToSlide(index));
3001+
progressContainer.appendChild(dot);
3002+
});
3003+
3004+
function updateProgressDots() {
3005+
const dots = progressContainer.querySelectorAll('.progress-dot');
3006+
dots.forEach((dot, index) => {
3007+
dot.classList.toggle('active', index === currentSlide);
3008+
});
3009+
}
3010+
3011+
function showSlide(index) {
3012+
slides.forEach((slide, i) => {
3013+
slide.classList.toggle('active', i === index);
3014+
});
3015+
}
3016+
3017+
function goToSlide(index) {
3018+
if (index < 0) index = slides.length - 1;
3019+
if (index >= slides.length) index = 0;
3020+
3021+
currentSlide = index;
3022+
showSlide(currentSlide);
3023+
updateProgressDots();
3024+
3025+
if (!isPaused) {
3026+
resetInterval();
3027+
}
3028+
}
3029+
3030+
function nextSlide() {
3031+
goToSlide(currentSlide + 1);
3032+
}
3033+
3034+
function prevSlide() {
3035+
goToSlide(currentSlide - 1);
3036+
}
3037+
3038+
function resetInterval() {
3039+
if (slideInterval) {
3040+
clearInterval(slideInterval);
3041+
}
3042+
slideInterval = setInterval(nextSlide, SLIDE_DURATION);
3043+
}
3044+
3045+
function togglePause() {
3046+
isPaused = !isPaused;
3047+
pauseBtn.textContent = isPaused ? 'Play' : 'Pause';
3048+
pauseBtn.classList.toggle('paused', isPaused);
3049+
3050+
if (isPaused) {
3051+
clearInterval(slideInterval);
3052+
} else {
3053+
resetInterval();
3054+
}
3055+
}
3056+
3057+
// Event listeners
3058+
const cleanupEvents = [];
3059+
3060+
const prevHandler = () => { prevSlide(); };
3061+
const nextHandler = () => { nextSlide(); };
3062+
const pauseHandler = () => { togglePause(); };
3063+
3064+
prevBtn.addEventListener('click', prevHandler);
3065+
nextBtn.addEventListener('click', nextHandler);
3066+
pauseBtn.addEventListener('click', pauseHandler);
3067+
cleanupEvents.push(() => { prevBtn.removeEventListener('click', prevHandler); });
3068+
cleanupEvents.push(() => { nextBtn.removeEventListener('click', nextHandler); });
3069+
cleanupEvents.push(() => { pauseBtn.removeEventListener('click', pauseHandler); });
3070+
3071+
// Keyboard navigation
3072+
const keyboardHandler = (e) => {
3073+
if (e.key === 'ArrowRight' || e.key === ' ') {
3074+
e.preventDefault();
3075+
nextSlide();
3076+
} else if (e.key === 'ArrowLeft') {
3077+
e.preventDefault();
3078+
prevSlide();
3079+
} else if (e.key === 'p' || e.key === 'P') {
3080+
togglePause();
3081+
} else if (e.key === 'Escape') {
3082+
closePresentation();
3083+
}
3084+
};
3085+
document.addEventListener('keydown', keyboardHandler);
3086+
cleanupEvents.push(() => { document.removeEventListener('keydown', keyboardHandler); });
3087+
3088+
// Touch/swipe support
3089+
let touchStartX = 0;
3090+
let touchEndX = 0;
3091+
3092+
const touchStartHandler = (e) => {
3093+
touchStartX = e.changedTouches[0].screenX;
3094+
};
3095+
const touchEndHandler = (e) => {
3096+
touchEndX = e.changedTouches[0].screenX;
3097+
handleSwipe();
3098+
};
3099+
3100+
document.addEventListener('touchstart', touchStartHandler, { passive: true });
3101+
document.addEventListener('touchend', touchEndHandler, { passive: true });
3102+
cleanupEvents.push(() => { document.removeEventListener('touchstart', touchStartHandler); });
3103+
cleanupEvents.push(() => { document.removeEventListener('touchend', touchEndHandler); });
3104+
3105+
function handleSwipe() {
3106+
const swipeThreshold = 50;
3107+
const diff = touchStartX - touchEndX;
3108+
3109+
if (Math.abs(diff) > swipeThreshold) {
3110+
if (diff > 0) {
3111+
nextSlide();
3112+
} else {
3113+
prevSlide();
3114+
}
3115+
}
3116+
}
3117+
3118+
// Initialize
3119+
showSlide(0);
3120+
resetInterval();
3121+
3122+
// Cleanup function
3123+
cleanupFunction = () => {
3124+
if (slideInterval) {
3125+
clearInterval(slideInterval);
3126+
}
3127+
cleanupEvents.forEach(fn => fn());
3128+
};
3129+
}
3130+
3131+
// Make functions globally accessible
3132+
window.openPresentation = openPresentation;
3133+
window.closePresentation = closePresentation;
3134+
})();
3135+
3136+
</script>
3137+
</body>
28533138
</html>

0 commit comments

Comments
 (0)