diff --git a/package-lock.json b/package-lock.json
index ac50faf..fda67d5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "siteforge",
- "version": "2.10.7",
+ "version": "2.10.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "siteforge",
- "version": "2.10.7",
+ "version": "2.10.8",
"dependencies": {
"@aws-sdk/client-s3": "^3.1135.0",
"@dnd-kit/core": "^6.3.1",
diff --git a/package.json b/package.json
index 08a1d82..9954c68 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "siteforge",
"private": true,
- "version": "2.10.7",
+ "version": "2.10.8",
"type": "module",
"scripts": {
"dev": "vite",
diff --git a/src/App.css b/src/App.css
index f94fe9d..b88ebaa 100644
--- a/src/App.css
+++ b/src/App.css
@@ -4156,6 +4156,204 @@
border-left: 3px solid rgba(111, 207, 151, 0.7);
}
+/* ── Study hub (guest landing) ── */
+.study-hub-count {
+ margin: 1.25rem 0 0;
+ font-size: 0.9rem;
+ color: var(--brand-muted);
+}
+
+.study-hub-steps {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: 1rem;
+}
+
+.study-hub-step {
+ padding: 1.4rem 1.4rem 1.5rem;
+ border: 1px solid rgba(201, 168, 76, 0.22);
+ border-radius: 14px;
+ background: rgba(17, 17, 15, 0.84);
+}
+
+.study-hub-step-number {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 2.3rem;
+ height: 2.3rem;
+ margin-bottom: 0.9rem;
+ border-radius: 50%;
+ border: 1px solid rgba(201, 168, 76, 0.6);
+ background: rgba(201, 168, 76, 0.14);
+ color: var(--brand-gold);
+ font-family: var(--brand-font-heading);
+ font-size: 1.2rem;
+ font-weight: 700;
+}
+
+.study-hub-step h3 {
+ margin: 0 0 0.45rem;
+ font-family: var(--brand-font-heading);
+ font-size: 1.3rem;
+ color: var(--brand-warm-white);
+}
+
+.study-hub-step p {
+ margin: 0;
+ color: #d6c7a6;
+ line-height: 1.6;
+}
+
+.study-track-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
+ gap: 1.1rem;
+ align-items: start;
+}
+
+.study-track-wrap { display: flex; flex-direction: column; gap: 0.5rem; }
+
+.study-track-card {
+ display: flex;
+ flex-direction: column;
+ gap: 0.6rem;
+ padding: 1.4rem;
+ border: 1px solid rgba(201, 168, 76, 0.24);
+ border-radius: 16px;
+ background: linear-gradient(180deg, rgba(26, 26, 22, 0.95), rgba(16, 16, 14, 0.95));
+ color: inherit;
+ text-decoration: none;
+ transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
+}
+
+a.study-track-card:hover {
+ transform: translateY(-3px);
+ border-color: rgba(201, 168, 76, 0.55);
+ box-shadow: 0 14px 36px rgba(0, 0, 0, 0.45);
+}
+
+.study-track-card--planned {
+ border-style: dashed;
+ opacity: 0.8;
+}
+
+.study-track-top {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 0.6rem;
+ flex-wrap: wrap;
+}
+
+.study-track-status {
+ font-size: 0.72rem;
+ letter-spacing: 0.12em;
+ text-transform: uppercase;
+ color: var(--brand-gold);
+}
+
+.study-track-status--complete { color: #6fcf97; }
+.study-track-status--planned { color: var(--brand-muted); }
+
+.study-difficulty {
+ padding: 0.18rem 0.65rem;
+ border-radius: 999px;
+ border: 1px solid;
+ font-size: 0.72rem;
+ font-weight: 600;
+ text-transform: capitalize;
+}
+
+.study-difficulty--beginner { color: #7fd484; border-color: rgba(76, 175, 80, 0.45); background: rgba(76, 175, 80, 0.12); }
+.study-difficulty--intermediate { color: #f0b45c; border-color: rgba(245, 124, 0, 0.45); background: rgba(245, 124, 0, 0.12); }
+.study-difficulty--advanced { color: #ef8a82; border-color: rgba(211, 47, 47, 0.5); background: rgba(211, 47, 47, 0.12); }
+
+.study-track-title {
+ margin: 0.2rem 0 0;
+ font-family: var(--brand-font-heading);
+ font-size: 1.5rem;
+ line-height: 1.2;
+ color: var(--brand-warm-white);
+}
+
+.study-track-desc {
+ margin: 0;
+ color: #d6c7a6;
+ line-height: 1.6;
+}
+
+.study-track-facts {
+ list-style: none;
+ margin: 0.4rem 0 0;
+ padding: 0.75rem 0 0;
+ border-top: 1px solid rgba(201, 168, 76, 0.16);
+ display: flex;
+ flex-direction: column;
+ gap: 0.3rem;
+ font-size: 0.9rem;
+ color: var(--brand-muted);
+}
+
+.study-track-cta {
+ margin-top: 0.5rem;
+ color: var(--brand-gold);
+ font-size: 0.85rem;
+ letter-spacing: 0.1em;
+ text-transform: uppercase;
+}
+
+.study-track-listen {
+ margin: 0;
+ padding: 0 0.4rem;
+ font-size: 0.9rem;
+ color: var(--brand-muted);
+}
+
+.study-hub-ask {
+ max-width: 640px;
+ margin: 1rem auto 2rem;
+ padding: clamp(1.75rem, 4vw, 2.5rem);
+ text-align: center;
+ border: 1px solid rgba(201, 168, 76, 0.24);
+ border-radius: 18px;
+ background:
+ radial-gradient(ellipse at top, rgba(201, 168, 76, 0.1), transparent 70%),
+ rgba(17, 17, 15, 0.9);
+}
+
+.study-hub-ask h2 {
+ margin: 0.4rem 0 0.75rem;
+ font-family: var(--brand-font-heading);
+ font-size: 1.8rem;
+ color: var(--brand-warm-white);
+}
+
+.study-hub-ask p:not(.eyebrow) {
+ margin: 0 auto 1.5rem;
+ max-width: 480px;
+ color: #b9aa86;
+ line-height: 1.6;
+}
+
+.study-hub-ask-actions {
+ display: flex;
+ gap: 0.75rem;
+ justify-content: center;
+ flex-wrap: wrap;
+}
+
+@media (max-width: 820px) {
+ .study-hub-steps { grid-template-columns: 1fr; }
+}
+
+@media (prefers-reduced-motion: reduce) {
+ a.study-track-card:hover { transform: none; }
+}
+
/* ── Sign in / Create account (split layout) ── */
.auth-page {
min-height: 70vh;
diff --git a/src/studyPages.tsx b/src/studyPages.tsx
index e8e89e2..32071a4 100644
--- a/src/studyPages.tsx
+++ b/src/studyPages.tsx
@@ -911,8 +911,8 @@ export function StudyLandingPage({ content }: Props) {
{study.completedLessons}/{study.totalLessons} lessons completed
{study.noteCount} notes
-
@@ -942,6 +942,54 @@ export function StudyLandingPage({ content }: Props) {
)
}
+ const availableCount = activeStudies.length + completeStudies.length
+
+ const renderTrackCard = (study: StudyProgram, variant: 'active' | 'complete' | 'planned') => {
+ const releasedCount = study.sections.filter(isSectionReleased).length
+ const nextLabel = getNextReleaseLabel(study)
+ const book = variant === 'complete' ? (content.finishedBooks ?? []).find(item => item.studySlug === study.slug) : undefined
+ const body = (
+ <>
+
+
+ {variant === 'active' ? 'In progress · start anytime' : variant === 'complete' ? 'Complete · self-paced' : 'Coming soon'}
+
+ {study.difficulty && {study.difficulty} }
+
+
{study.title}
+
{study.description}
+
+ {variant === 'planned' ? (
+
+ {study.startsAt && new Date(study.startsAt).getTime() > Date.now()
+ ? `Starts ${new Date(study.startsAt).toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric' })}`
+ : 'Preparing lesson structure and media'}
+
+ ) : (
+ <>
+ {variant === 'complete' ? `All ${study.sections.length} lessons available` : releasedCount > 0 ? `${releasedCount} of ${study.sections.length} lessons available` : 'Lessons will be published soon'}
+ {variant === 'active' && nextLabel && Next lesson: {nextLabel} }
+ {study.estimatedHours ? About {study.estimatedHours} hours : null}
+ >
+ )}
+
+ {variant !== 'planned' &&
View lessons → }
+ >
+ )
+ return (
+
+ {variant === 'planned'
+ ?
{body}
+ :
{body}}
+ {book && (
+
+ Just want to listen? Open the audio playlist — no account needed →
+
+ )}
+
+ )
+ }
+
return (
@@ -950,16 +998,22 @@ export function StudyLandingPage({ content }: Props) {
Study at Your Own Pace
Pick a study track, move lesson by lesson on your own schedule, and keep personal notes as you grow through each passage.
- {activeStudies.length + completeStudies.length} {activeStudies.length + completeStudies.length === 1 ? 'study' : 'studies'} available{completeStudies.length > 0 ? ` (${completeStudies.length} finished, start anytime)` : ''}{plannedStudies.length > 0 ? ` · ${plannedStudies.length} coming soon` : ''}
- Self-paced flow
+ Self-paced
Personal notes
Audio + commentary
+ Free account
- {firstActiveStudyFirstReleasedSection &&
Start Learning}
-
Create Account or Login
-
My Account
+ {firstActiveStudyFirstReleasedSection
+ ?
Start Learning
+ :
Browse Studies }
+
Create Free Account or Sign In
+
+ {availableCount} {availableCount === 1 ? 'study' : 'studies'} available
+ {completeStudies.length > 0 ? ` (${completeStudies.length} finished, start anytime)` : ''}
+ {plannedStudies.length > 0 ? ` · ${plannedStudies.length} coming soon` : ''}
+
@@ -969,63 +1023,33 @@ export function StudyLandingPage({ content }: Props) {
How It Works
A Simple Self-Paced Rhythm
-
-
- Step 1
- Choose Your Track
- Start with any active study and begin at lesson one, or jump back in where you left off.
-
-
- Step 2
- Work Each Lesson
- Read the text, listen to audio, review commentary, and process key Greek word notes.
-
-
- Step 3
- Save Notes and Continue
- Keep personal notes per lesson and build your own study archive over time.
-
-
+
+ {[
+ { title: 'Choose Your Track', body: 'Start with any active study and begin at lesson one, or jump back in where you left off.' },
+ { title: 'Work Each Lesson', body: 'Read the text, listen to audio, review commentary, and process key Greek word notes.' },
+ { title: 'Save Notes and Continue', body: 'Keep personal notes per lesson and build your own study archive over time.' },
+ ].map((step, index) => (
+
+ {index + 1}
+ {step.title}
+ {step.body}
+
+ ))}
+
-
-
-
-
Available Now
-
Current Study Tracks
+ {activeStudies.length > 0 && (
+
+
+
+
Available Now
+
Current Study Tracks
+
+
{activeStudies.map(study => renderTrackCard(study, 'active'))}
-
- {activeStudies.map(study => (
- (() => {
- const releasedCount = study.sections.filter(isSectionReleased).length
- return (
-
-
-
-
Start Anytime
- {study.difficulty &&
{study.difficulty} }
-
-
{study.title}
-
{study.description}
- {study.estimatedHours &&
⏱ {study.estimatedHours} hours
}
-
-
-
Track Snapshot
-
{releasedCount > 0 ? `${releasedCount} lessons available now` : 'Lessons will be published soon.'}
-
{(() => {
- const next = getNextReleaseLabel(study)
- if (next) return `Next lesson: ${next}`
- return study.sections.length > 0 ? 'New lessons release on a regular schedule.' : 'Pacing details coming with first lesson release.'
- })()}
-
-
- )
- })()
- ))}
-
-
-
+
+ )}
{completeStudies.length > 0 && (
@@ -1034,32 +1058,7 @@ export function StudyLandingPage({ content }: Props) {
Study On Your Own Time
Finished Studies
-
- {completeStudies.map(study => {
- const book = (content.finishedBooks ?? []).find(item => item.studySlug === study.slug)
- return (
-
-
-
-
Complete · Start Anytime
-
{study.title}
-
{study.description}
-
-
-
Self-Paced
-
All {study.sections.length} lessons available now
-
No schedule — go as fast or slow as you like.
-
-
- {book && (
-
- Just want to listen? Open the audio playlist — no account needed →
-
- )}
-
- )
- })}
-
+ {completeStudies.map(study => renderTrackCard(study, 'complete'))}
)}
@@ -1071,41 +1070,24 @@ export function StudyLandingPage({ content }: Props) {
Coming Soon
Next Study Tracks
-
- {plannedStudies.map(study => (
-
-
-
Planned
-
{study.title}
-
{study.description}
-
-
-
Status
-
{study.startsAt && new Date(study.startsAt).getTime() > Date.now()
- ? `Starts ${new Date(study.startsAt).toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric' })}`
- : 'Preparing lesson structure and media.'}
-
-
- ))}
-
+ {plannedStudies.map(study => renderTrackCard(study, 'planned'))}
)}
-
-
Have a question from the Word?
-
Ask Nate a Question
-
- Submit a Bible or theology question and it may be answered in a future episode or the Q&A archive.
-
-
-
Browse Q&A Archive →
-
Submit a Question
+
+
+
Have a question from the Word?
+
Ask Nate a Question
+
Submit a Bible or theology question and it may be answered in a future episode or the Q&A archive.
+
+ Browse Q&A Archive →
+ Submit a Question
+
-
)
}