The login screen was just a bare card on a dark background. Adds a
feature-highlight panel alongside it (tagline, what the app does, a
scripture quote) on wider screens, using only colors already in the
app's palette (slate-900/300/400, white, sky-500) — no new theme.
Collapses to the original single-card layout on mobile.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds a full admin view (users + projects, with view/delete) gated
server-side by ADMIN_EMAIL in server/auth.js (defaults to the site
owner's account, overridable via env var for other deployments). The
gate is enforced on every /api/admin/* route, not just hidden in the
UI — verified a non-admin session gets 403 even when it hits the
endpoints directly. Deleting a user leaves their projects in place
(not cascade-deleted) so admin cleanup can't accidentally destroy
someone's study data.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Study templates: richer multi-line guiding questions in the OIA placeholders
- PDF/print export: reuses buildExportHtml in a new tab + window.print()
- Markdown export: new buildMarkdownExport() with matching tests
- Breadcrumb: current chunk's passage reference shown in the Study page header
- Reader bookmarks: SVG icons instead of ambiguous emoji, always visible
(not hover-only, so it works on touch devices), plus a Bookmarks panel
that lists all saved verses across every book and jumps + scrolls to them
- Whole-Bible search: no server-side search endpoint exists, so this fetches
the full translation once (~7MB) and searches an in-memory flat verse
index client-side, with results linking back into the reader
- Read-only share links: per-project share token, a public unauthenticated
/api/share/:token endpoint, and a ?share=TOKEN view that bypasses the auth
gate entirely and renders the export HTML in a script-sandboxed iframe
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Other people using this app just want to do personal Bible study, not
produce a podcast episode, so the always-visible chrome (chunk
metadata, DOCX import, exports) now says "Session" instead of
"Episode" and marks podcast-only fields as optional. The "Prepare for
Podcast" prompt no longer hardcodes "Verse by Verse with Nate" for
every user — it now pulls from a new "Podcast / show name" field in
Account Settings, so it still works exactly as before once you set
yours, but produces a sensible generic prompt for anyone who hasn't.
Also added an explanatory blurb to the session-list import page and
loosened its docx parser to accept "Session N — Title" in addition to
"Ep. N — Title".
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Projects that exist on the server but not in this browser's local
cache (e.g. a fresh device) are now pulled down automatically, instead
of requiring a manual "Restore" click per project. Shows a brief
"synced N projects" toast instead. Conflict handling for projects that
exist locally but are stale is unchanged (still a manual "Pull latest"
action), since silently overwriting local edits there would risk data
loss.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Projects were previously global to anyone who could reach the server.
Adds email/password accounts with httpOnly cookie sessions, scopes
every project (both SQLite and localStorage) to the signed-in user,
and auto-claims pre-existing unowned projects for whoever registers
first. Also adds optional TOTP two-factor auth with backup codes,
managed from a new Account Settings page, since there's no
password-reset flow to fall back on otherwise.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Upload a Word doc with an Ep./Title/Passage table (or "Ep. N — Title"
intro paragraphs) and it parses episodes, fetches the needed chapters,
and creates chunks with episode metadata and verse ranges pre-filled,
including cross-chapter spillover and zero-length markers for
passage-less rows.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add ‹ Prev / Chunk N of M / Next › buttons at top of chunk editor
header so you can navigate without scrolling to the bottom
- Fix speak audio click: only cancel() when speech is active, append a
period for a natural trailing pause, slow rate to 0.85, and chain a
zero-volume tail utterance so the audio session fades out cleanly
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Append trailing spaces so the audio session stays open briefly before
closing, preventing the hardware click/pop on webkit/macOS.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add shortHebrewGloss() helper that strips [idiom]/[phrase] prefixes and
takes the first word before any comma/semicolon/paren, matching the clean
one-word display Greek already had. Full kjv_def is preserved in
shortDefinition; englishGloss and the modal bold label now show one word.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The NT Strong's gloss file only contains G#### keys, so Hebrew lookups
always returned an empty englishGloss. Now falls back to short_definition
(kjv_def from the BDBT API) so Hebrew words match Greek behaviour.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add 🔊 Speak buttons on Greek/Hebrew word cards in both the reader interlinear panel and study-side word entries (Web Speech API, he-IL / el-GR)
- Click verse number to expand inline interlinear panel with original script, transliteration, gloss, parsing, and Strong's number
- Verse bookmarking with 5 highlight colors, persisted to localStorage
- 🔗 Cross-Refs toggle fetches open-cross-ref dataset and shows amber reference chips per verse
- 🔍 In-chapter search filters verses live with yellow keyword highlights
- S/M/L/XL font size controls
- 📋 Copy verse button outputs formatted citation (Book Ch:V BSB — text)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a "Read Bible" button on the home screen that opens a simple
chapter browser using the existing helloao BSB API, with book/chapter
pickers and prev/next navigation, separate from study projects.
https://claude.ai/code/session_013GXQxSaTF6zeBsSYTeF3fN
- Bridge jsdom localStorage/sessionStorage over Node 22+'s experimental
globals that vitest's jsdom environment doesn't override
- Update Greek lookup tests to mock the OpenScriptures Strong's
dictionary instead of the retired bolls.life path
- Update migrateChunk no-op test for backfilled fields
- Match en-dash verse range labels in chunk creation test
- Untrack .api.log/.api.pid and gitignore them
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds a collapsible Interlinear section beneath the Scripture text
(stacked and split layouts) showing each original-language word with
its BSB gloss, transliteration, parsing, and Strong's number on hover.
Data is generated offline from the Berean Standard Bible translation
tables via scripts/build-interlinear.mjs into per-book JSON files.
Use antique gold accent, rich black text, Cormorant Garamond
headings, and Lora body text. Remove fill backgrounds, keeping
only the gold left-border scripture callout and section divider.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add background notes, tags, and final script to the export
- Use shaded section labels, accent color, and a callout-style scripture box
- Switch accent color from indigo to teal
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Shows quick-add chips and a datalist of tags already used elsewhere
in this project or across all projects.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Tag chunks with topics; aggregate into project index and add a Home page tag filter
- Persist studyLayout/activeStudyTab in localStorage
- Make the Split View tab bar sticky while scrolling
- Show a hoverable Strong's number badge with gloss on each word study card
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Scripture stays pinned in a sticky left column while Notes,
Cross-Refs, Word Study, Commentary, and Script become tabs in
the right column. Toggle via "Split View" / "Stacked View".
Adds a Commentary section (HelloAO commentaries) and a "Suggest from
passage" cross-reference feature using the open-cross-ref dataset, with
hover popups that show the referenced verse text.
Three bugs fixed:
1. lastEdited mismatch: saveProjectToStorage stamped Date.now() in
localStorage but saveRemoteProject sent the React state's stale
lastEdited — server and localStorage had different timestamps, so
the "Pull latest" stale detection on a second device never fired.
Fix: stamp lastEdited once before both calls so they're identical.
2. saveProjectToStorage now returns the stamped object so callers don't
have to re-compute the timestamp.
3. Sync errors were auto-clearing after 2.5s making failures invisible.
Now the "⚠ Sync failed" badge stays visible until the next successful
sync, and a Retry button lets you force a re-push without making an edit.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New englishGloss field on every word object (editable input, placeholder "e.g. grace")
- Populated automatically from the macula-greek gloss map on lookup and suggest
- Shows alongside Short definition in the card's second row
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds public/nt-strongs-gloss.json (100 KB) — the most-common per-word
English gloss for each Strong's number, computed from the macula-greek
SBLGNT dataset. This replaces the fragile kjv_def comma-parsing approach:
grace now shows "grace" not "acceptable", God shows "God" not "X exceeding",
will shows "will" not "desire", etc.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Strip Strong's X/+ notation prefixes and take the first meaningful
English word from the comma-separated kjv_def — so G2316 shows
"God" instead of "exceeding", G40 shows "holy" instead of "(most) holy
(one", etc. Falls back to the raw def if all segments are filtered.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>