mirror of
https://github.com/kennethreitz/kjvstudy.org.git
synced 2026-06-05 23:00:16 +00:00
Add dark mode, print styles, and keyboard shortcuts
- Implement comprehensive dark mode: * CSS variables for light/dark color schemes * Toggle button in top-right with sun/moon icons * Smooth transitions between themes * Persists preference in localStorage * Updates all UI elements dynamically - Add professional print styles: * Optimized typography for printed pages * Hide navigation elements * Expand sidenotes inline with context * Proper page breaks and orphan/widow control * Show URLs for external links * Beautiful formatting for PDF exports - Implement keyboard shortcuts for power users: * Cmd/Ctrl + D: Toggle dark mode * Cmd/Ctrl + B: Toggle sidebar * Cmd/Ctrl + K or /: Go to search * ?: Show keyboard shortcuts help * Esc: Clear input focus 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -13,9 +13,41 @@
|
||||
{% block head %}{% endblock %}
|
||||
|
||||
<style>
|
||||
/* Color scheme variables */
|
||||
:root {
|
||||
--bg-color: #fffff8;
|
||||
--text-color: #111;
|
||||
--text-secondary: #666;
|
||||
--text-tertiary: #888;
|
||||
--text-quaternary: #999;
|
||||
--border-color: #eee;
|
||||
--border-color-dark: #ddd;
|
||||
--border-color-darker: #ccc;
|
||||
--link-color: #333;
|
||||
--link-hover: #000;
|
||||
--code-bg: #f5f5f5;
|
||||
}
|
||||
|
||||
[data-theme="dark"] {
|
||||
--bg-color: #1a1a1a;
|
||||
--text-color: #e0e0e0;
|
||||
--text-secondary: #b0b0b0;
|
||||
--text-tertiary: #909090;
|
||||
--text-quaternary: #707070;
|
||||
--border-color: #333;
|
||||
--border-color-dark: #444;
|
||||
--border-color-darker: #555;
|
||||
--link-color: #d0d0d0;
|
||||
--link-hover: #fff;
|
||||
--code-bg: #2a2a2a;
|
||||
}
|
||||
|
||||
/* Enhanced typography and spacing */
|
||||
body {
|
||||
counter-reset: sidenote-counter;
|
||||
background-color: var(--bg-color);
|
||||
color: var(--text-color);
|
||||
transition: background-color 0.3s ease, color 0.3s ease;
|
||||
}
|
||||
|
||||
article {
|
||||
@@ -59,38 +91,38 @@
|
||||
.breadcrumb {
|
||||
margin: 2rem 0 3rem 0;
|
||||
font-size: 0.95rem;
|
||||
color: #666;
|
||||
color: var(--text-secondary);
|
||||
font-style: italic;
|
||||
border-bottom: 1px solid #eee;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.breadcrumb a {
|
||||
color: #333;
|
||||
color: var(--link-color);
|
||||
text-decoration: none;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
.breadcrumb a:hover {
|
||||
color: #000;
|
||||
color: var(--link-hover);
|
||||
}
|
||||
|
||||
.breadcrumb-separator {
|
||||
margin: 0 0.75rem;
|
||||
color: #999;
|
||||
color: var(--text-quaternary);
|
||||
}
|
||||
|
||||
/* Enhanced link styling */
|
||||
a {
|
||||
color: #333;
|
||||
color: var(--link-color);
|
||||
text-decoration: none;
|
||||
border-bottom: 1px solid #ddd;
|
||||
border-bottom: 1px solid var(--border-color-dark);
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #000;
|
||||
border-bottom-color: #000;
|
||||
color: var(--link-hover);
|
||||
border-bottom-color: var(--link-hover);
|
||||
}
|
||||
|
||||
/* Section dividers */
|
||||
@@ -100,14 +132,14 @@
|
||||
}
|
||||
|
||||
section:not(:first-of-type) {
|
||||
border-top: 1px solid #eee;
|
||||
border-top: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
/* Ornamental breaks */
|
||||
.ornament {
|
||||
text-align: center;
|
||||
margin: 3rem 0;
|
||||
color: #999;
|
||||
color: var(--text-quaternary);
|
||||
font-size: 1.5rem;
|
||||
letter-spacing: 1rem;
|
||||
}
|
||||
@@ -146,8 +178,8 @@
|
||||
font-style: italic;
|
||||
margin: 0 0 0.5rem 0;
|
||||
padding-bottom: 0.4rem;
|
||||
border-bottom: 1px solid #eee;
|
||||
color: #555;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.nav-sidebar ul {
|
||||
@@ -161,7 +193,7 @@
|
||||
}
|
||||
|
||||
.nav-sidebar a {
|
||||
color: #666;
|
||||
color: var(--text-secondary);
|
||||
text-decoration: none;
|
||||
border-bottom: none;
|
||||
display: block;
|
||||
@@ -170,11 +202,11 @@
|
||||
}
|
||||
|
||||
.nav-sidebar a:hover {
|
||||
color: #000;
|
||||
color: var(--link-hover);
|
||||
}
|
||||
|
||||
.nav-sidebar a.current {
|
||||
color: #000;
|
||||
color: var(--link-hover);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@@ -186,7 +218,7 @@
|
||||
font-size: 0.75rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
color: #888;
|
||||
color: var(--text-tertiary);
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
@@ -200,7 +232,7 @@
|
||||
font-size: 0.75rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
color: #888;
|
||||
color: var(--text-tertiary);
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 600;
|
||||
list-style: none;
|
||||
@@ -244,19 +276,57 @@
|
||||
height: 24px;
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
border: 1px solid #ccc;
|
||||
border: 1px solid var(--border-color-darker);
|
||||
border-radius: 3px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 0.85rem;
|
||||
color: #666;
|
||||
color: var(--text-secondary);
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.sidebar-toggle-btn:hover {
|
||||
border-color: #888;
|
||||
color: #000;
|
||||
border-color: var(--text-tertiary);
|
||||
color: var(--link-hover);
|
||||
}
|
||||
|
||||
/* Dark mode toggle */
|
||||
.dark-mode-toggle {
|
||||
position: fixed;
|
||||
top: 2rem;
|
||||
right: 2rem;
|
||||
z-index: 101;
|
||||
margin: -25px 0 0 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.dark-mode-btn {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
border: 1px solid var(--border-color-darker);
|
||||
border-radius: 3px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-secondary);
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.dark-mode-btn:hover {
|
||||
border-color: var(--text-tertiary);
|
||||
color: var(--link-hover);
|
||||
}
|
||||
|
||||
.dark-mode-btn::before {
|
||||
content: '☀';
|
||||
}
|
||||
|
||||
[data-theme="dark"] .dark-mode-btn::before {
|
||||
content: '☾';
|
||||
}
|
||||
|
||||
.nav-sidebar {
|
||||
@@ -287,7 +357,7 @@
|
||||
content: '-';
|
||||
}
|
||||
|
||||
/* Hide sidebar on smaller screens */
|
||||
/* Hide sidebar and controls on smaller screens */
|
||||
@media (max-width: 1200px) {
|
||||
.nav-sidebar {
|
||||
display: none;
|
||||
@@ -296,6 +366,150 @@
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.dark-mode-toggle {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Print styles for beautiful printed pages */
|
||||
@media print {
|
||||
/* Use light colors for print */
|
||||
:root {
|
||||
--bg-color: white;
|
||||
--text-color: black;
|
||||
--text-secondary: #333;
|
||||
--border-color: #ccc;
|
||||
}
|
||||
|
||||
body {
|
||||
background: white;
|
||||
color: black;
|
||||
font-size: 12pt;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* Hide navigation elements */
|
||||
.nav-sidebar,
|
||||
.sidebar-toggle-container,
|
||||
.dark-mode-toggle,
|
||||
.breadcrumb {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Expand article to full width */
|
||||
article {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Optimize typography for print */
|
||||
h1 {
|
||||
font-size: 24pt;
|
||||
margin-top: 0;
|
||||
page-break-after: avoid;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 18pt;
|
||||
page-break-after: avoid;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 14pt;
|
||||
page-break-after: avoid;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 12pt;
|
||||
orphans: 3;
|
||||
widows: 3;
|
||||
}
|
||||
|
||||
/* Avoid breaking inside elements */
|
||||
section,
|
||||
.verse-item,
|
||||
.angel-entry,
|
||||
.prophet-entry,
|
||||
.name-entry,
|
||||
.parable-entry,
|
||||
.covenant-entry,
|
||||
.apostle-entry,
|
||||
.woman-entry,
|
||||
.festival-entry {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
/* Make sidenotes visible in print */
|
||||
.sidenote,
|
||||
.marginnote {
|
||||
display: block !important;
|
||||
float: none !important;
|
||||
width: 100% !important;
|
||||
margin: 0.5rem 0 0.5rem 2rem !important;
|
||||
padding: 0.5rem;
|
||||
border-left: 2px solid #ccc;
|
||||
font-size: 10pt;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* Hide sidenote toggles */
|
||||
.margin-toggle {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Show URLs for links */
|
||||
a[href^="http"]:after {
|
||||
content: " (" attr(href) ")";
|
||||
font-size: 10pt;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* Don't show URLs for internal links */
|
||||
a[href^="/"]:after {
|
||||
content: "";
|
||||
}
|
||||
|
||||
/* Clean borders */
|
||||
section:not(:first-of-type) {
|
||||
border-top: 1px solid #ccc;
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
/* Optimize verse display */
|
||||
.verse-item {
|
||||
margin: 0.5rem 0;
|
||||
padding-left: 1rem;
|
||||
}
|
||||
|
||||
.verse-ref {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.verse-text {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* Remove link underlines for cleaner print */
|
||||
a {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* Page breaks */
|
||||
h1, h2 {
|
||||
page-break-before: auto;
|
||||
}
|
||||
|
||||
/* Add chapter/verse numbers in margin for reference */
|
||||
@page {
|
||||
margin: 2cm;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -303,6 +517,9 @@
|
||||
<p class="sidebar-toggle-container">
|
||||
<label for="sidebar-toggle" class="sidebar-toggle-btn" title="Toggle sidebar"></label>
|
||||
</p>
|
||||
<p class="dark-mode-toggle">
|
||||
<button class="dark-mode-btn" title="Toggle dark mode" onclick="toggleDarkMode()"></button>
|
||||
</p>
|
||||
<article>
|
||||
{% if breadcrumbs %}
|
||||
<nav class="breadcrumb">
|
||||
@@ -371,6 +588,20 @@
|
||||
</nav>
|
||||
|
||||
<script type="text/javascript">
|
||||
// Dark mode functionality
|
||||
(function() {
|
||||
// Check for saved theme preference or default to light mode
|
||||
const currentTheme = localStorage.getItem('theme') || 'light';
|
||||
document.documentElement.setAttribute('data-theme', currentTheme);
|
||||
})();
|
||||
|
||||
function toggleDarkMode() {
|
||||
const currentTheme = document.documentElement.getAttribute('data-theme');
|
||||
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
|
||||
document.documentElement.setAttribute('data-theme', newTheme);
|
||||
localStorage.setItem('theme', newTheme);
|
||||
}
|
||||
|
||||
// Sidebar collapse state persistence
|
||||
(function() {
|
||||
var toggle = document.getElementById('sidebar-toggle');
|
||||
@@ -383,6 +614,57 @@
|
||||
});
|
||||
})();
|
||||
|
||||
// Keyboard shortcuts
|
||||
document.addEventListener('keydown', function(e) {
|
||||
// Don't trigger if user is typing in an input field
|
||||
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') {
|
||||
// Allow Escape to clear focus
|
||||
if (e.key === 'Escape') {
|
||||
e.target.blur();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Cmd/Ctrl + D: Toggle dark mode
|
||||
if ((e.metaKey || e.ctrlKey) && e.key === 'd') {
|
||||
e.preventDefault();
|
||||
toggleDarkMode();
|
||||
}
|
||||
|
||||
// Cmd/Ctrl + B: Toggle sidebar
|
||||
if ((e.metaKey || e.ctrlKey) && e.key === 'b') {
|
||||
e.preventDefault();
|
||||
var toggle = document.getElementById('sidebar-toggle');
|
||||
if (toggle) {
|
||||
toggle.checked = !toggle.checked;
|
||||
toggle.dispatchEvent(new Event('change'));
|
||||
}
|
||||
}
|
||||
|
||||
// Cmd/Ctrl + K or /: Focus search
|
||||
if (((e.metaKey || e.ctrlKey) && e.key === 'k') || e.key === '/') {
|
||||
e.preventDefault();
|
||||
window.location.href = '/search';
|
||||
}
|
||||
|
||||
// ?: Show keyboard shortcuts help
|
||||
if (e.key === '?' && !e.shiftKey) {
|
||||
showKeyboardHelp();
|
||||
}
|
||||
});
|
||||
|
||||
// Keyboard shortcuts help modal
|
||||
function showKeyboardHelp() {
|
||||
var helpText = 'Keyboard Shortcuts:\\n\\n' +
|
||||
'Cmd/Ctrl + D - Toggle dark mode\\n' +
|
||||
'Cmd/Ctrl + B - Toggle sidebar\\n' +
|
||||
'Cmd/Ctrl + K - Go to search\\n' +
|
||||
'/ - Go to search\\n' +
|
||||
'? - Show this help\\n' +
|
||||
'Esc - Clear focus';
|
||||
alert(helpText);
|
||||
}
|
||||
|
||||
// Gauges analytics
|
||||
var _gauges = _gauges || [];
|
||||
(function() {
|
||||
|
||||
Reference in New Issue
Block a user