Skip to content

feat(landing): port the v5 marketing landing onto production - #576

Merged
Darkest-Teddy merged 2 commits into
productionfrom
feat/landing-v5-to-production
Aug 23, 2026
Merged

feat(landing): port the v5 marketing landing onto production#576
Darkest-Teddy merged 2 commits into
productionfrom
feat/landing-v5-to-production

Conversation

@Darkest-Teddy

Copy link
Copy Markdown
Collaborator

Puts the v5 landing on saplinglearn.com without promoting the rest of main.

Why this shape

production still serves the v4 landing (the scroll-driven knowledge graph from #513). main has carried v5 since #524, but production is 68 commits behind it — a full make promote would also ship the gamification/achievements feature, the quiz overhaul, and apply 8 unrun migrations to the production database. This branch cuts from production and takes the landing alone: frontend only, no backend change, no migration.

What's in it

Every file is origin/main's version:

  • components/landing-v5/ (27 files), components/landing/useLanding.ts, lib/landing/ (engine, hero3d, content)
  • app/(public)/ — the v5 landing plus the pages its navbar links to: faq, gallery, news, team, wiki, and the updated about page
  • components/companion/CompanionShell.tsx, the three landing images
  • globals.css — the 238-line .landing-dc / .landing-v5 block

Three deliberate departures from "copy main's file":

  1. lib/api.ts gains only subscribeToNewsletter. The beta CTA calls it and production lacks it; taking main's whole api.ts would have brought the gamification client along. POST /api/newsletter/subscribe already exists on production's backend, so the CTA works as shipped.
  2. globals.css excludes the sap-burst keyframe that main added beside the landing block — it's the flourish behind an achievement badge in BadgeModal, a component this branch doesn't have.
  3. The superseded v4 marketing components are deletedFeatureBand, SurfaceBento, featureBands, graph/, surfaces/. Nothing outside components/marketing/ imported them; marketing/ now matches main exactly.

E2E follows the same rule: landing-graph.spec.ts drives the v4 graph section this removes, so it goes; landing-drag-field.spec.ts and the public-seo copy assertions come across. support/db.ts's additions stay behind — those belong to gamification.

Verification

Run on this branch, against the production profile:

  • tsc --noEmit — clean
  • DEPLOY_ENV=production next build — clean; /news, /team, /wiki, /gallery, /faq all in the route table
  • 44 landing unit tests pass (landing-v5 + lib/landing)
  • Served the build and loaded it in a browser: v5 root mounts, zero page errors, and /, /faq, /gallery, /news, /team, /wiki, /about all return 200

three@^0.184.0 was already a production dependency. layout.tsx, sitemap.ts, robots.ts, useScrollLock and errorMessage are identical between the branches and needed no change.

After merging

production will hold one more commit that main doesn't. It already carries 5 such commits, so make promote's production-diverged preflight guard already blocks (it has no override) — whenever you next promote, back-merge production into main first.

🤖 Generated with Claude Code

production still serves the v4 landing — the scroll-driven knowledge graph
from #513. main has carried v5 since #524, but production sits 68 commits
behind it, and promoting main wholesale would also ship the gamification
feature and apply 8 unrun migrations to the production database. This
takes the landing and nothing else.
Every file here is origin/main's version, with three deliberate departures:
- lib/api.ts gains only `subscribeToNewsletter`, which the beta CTA calls
and production lacks. Taking main's whole api.ts would have brought the
gamification client with it. POST /api/newsletter/subscribe already
exists on production's backend, so the CTA works as shipped.
- globals.css takes the 238-line .landing-dc/.landing-v5 block only. The
one other addition in main's copy — the sap-burst keyframe behind an
achievement badge in BadgeModal — belongs to a component this branch
does not have.
- The v4 marketing components it replaces are deleted (FeatureBand,
SurfaceBento, featureBands, graph/, surfaces/). Nothing outside
components/marketing/ imported them; marketing/ now matches main.
e2e follows the same rule: landing-graph.spec.ts drives the v4 graph
section this removes, so it goes; landing-drag-field.spec.ts and the
public-seo copy assertions come across. support/db.ts's additions stay
behind — those are gamification's.
Verified on this branch: tsc --noEmit clean, DEPLOY_ENV=production
next build clean, and the 44 landing unit tests pass. three@^0.184.0 is
already a production dependency; layout.tsx, sitemap.ts and robots.ts
needed no change.
No backend change, no migration.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Aug 23, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3eca33ad-469d-4588-b761-e1e3166cb07e


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@supabase

supabaseBot commented Aug 23, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project ybgqdonkoqftwrmweuyv because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@cloudflare-workers-and-pages

cloudflare-workers-and-pagesBot commented Aug 23, 2026

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitPreview URLUpdated (UTC)
✅ Deployment successful!
View logs
frontend-staging7d7f8e7Commit Preview URL

Branch Preview URL
Aug 23 2026, 03:49 AM

CI's `eslint . --max-warnings=-1` exits 2 on "There are suppressions left
that do not occur anymore" — 0 errors, but a stale entry is still a failure.
The three suppressed violations under src/app/(public)/page.tsx belonged to
the v4 landing (no-html-link-for-pages, two prefer-const, and a
set-state-in-effect); the v5 page this replaces has none of them.
Pruned with `eslint . --prune-suppressions`, the remedy the error names.
main's copy of this file does not list that page either, so this converges
on the same state rather than inventing one.
@Darkest-Teddy
Darkest-Teddy merged commit 56d1ac2 into productionAug 23, 2026
5 checks passed
AndresL230 added a commit that referenced this pull request Aug 23, 2026
…production" (#585)
This reverts commit 56d1ac2, reversing
changes made to 6ec3d0f.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Darkest-Teddy
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
feat(landing): port the v5 marketing landing onto production by Darkest-Teddy · Pull Request #576 · SaplingLearn/Sapling · GitHub
Skip to content

feat(landing): port the v5 marketing landing onto production - #576

Merged
Darkest-Teddy merged 2 commits into
productionfrom
feat/landing-v5-to-production
Aug 23, 2026
Merged

feat(landing): port the v5 marketing landing onto production#576
Darkest-Teddy merged 2 commits into
productionfrom
feat/landing-v5-to-production

Conversation

@Darkest-Teddy

Copy link
Copy Markdown
Collaborator

Puts the v5 landing on saplinglearn.com without promoting the rest of main.

Why this shape

production still serves the v4 landing (the scroll-driven knowledge graph from #513). main has carried v5 since #524, but production is 68 commits behind it — a full make promote would also ship the gamification/achievements feature, the quiz overhaul, and apply 8 unrun migrations to the production database. This branch cuts from production and takes the landing alone: frontend only, no backend change, no migration.

What's in it

Every file is origin/main's version:

  • components/landing-v5/ (27 files), components/landing/useLanding.ts, lib/landing/ (engine, hero3d, content)
  • app/(public)/ — the v5 landing plus the pages its navbar links to: faq, gallery, news, team, wiki, and the updated about page
  • components/companion/CompanionShell.tsx, the three landing images
  • globals.css — the 238-line .landing-dc / .landing-v5 block

Three deliberate departures from "copy main's file":

  1. lib/api.ts gains only subscribeToNewsletter. The beta CTA calls it and production lacks it; taking main's whole api.ts would have brought the gamification client along. POST /api/newsletter/subscribe already exists on production's backend, so the CTA works as shipped.
  2. globals.css excludes the sap-burst keyframe that main added beside the landing block — it's the flourish behind an achievement badge in BadgeModal, a component this branch doesn't have.
  3. The superseded v4 marketing components are deletedFeatureBand, SurfaceBento, featureBands, graph/, surfaces/. Nothing outside components/marketing/ imported them; marketing/ now matches main exactly.

E2E follows the same rule: landing-graph.spec.ts drives the v4 graph section this removes, so it goes; landing-drag-field.spec.ts and the public-seo copy assertions come across. support/db.ts's additions stay behind — those belong to gamification.

Verification

Run on this branch, against the production profile:

  • tsc --noEmit — clean
  • DEPLOY_ENV=production next build — clean; /news, /team, /wiki, /gallery, /faq all in the route table
  • 44 landing unit tests pass (landing-v5 + lib/landing)
  • Served the build and loaded it in a browser: v5 root mounts, zero page errors, and /, /faq, /gallery, /news, /team, /wiki, /about all return 200

three@^0.184.0 was already a production dependency. layout.tsx, sitemap.ts, robots.ts, useScrollLock and errorMessage are identical between the branches and needed no change.

After merging

production will hold one more commit that main doesn't. It already carries 5 such commits, so make promote's production-diverged preflight guard already blocks (it has no override) — whenever you next promote, back-merge production into main first.

🤖 Generated with Claude Code

production still serves the v4 landing — the scroll-driven knowledge graph
from #513. main has carried v5 since #524, but production sits 68 commits
behind it, and promoting main wholesale would also ship the gamification
feature and apply 8 unrun migrations to the production database. This
takes the landing and nothing else.
Every file here is origin/main's version, with three deliberate departures:
- lib/api.ts gains only `subscribeToNewsletter`, which the beta CTA calls
and production lacks. Taking main's whole api.ts would have brought the
gamification client with it. POST /api/newsletter/subscribe already
exists on production's backend, so the CTA works as shipped.
- globals.css takes the 238-line .landing-dc/.landing-v5 block only. The
one other addition in main's copy — the sap-burst keyframe behind an
achievement badge in BadgeModal — belongs to a component this branch
does not have.
- The v4 marketing components it replaces are deleted (FeatureBand,
SurfaceBento, featureBands, graph/, surfaces/). Nothing outside
components/marketing/ imported them; marketing/ now matches main.
e2e follows the same rule: landing-graph.spec.ts drives the v4 graph
section this removes, so it goes; landing-drag-field.spec.ts and the
public-seo copy assertions come across. support/db.ts's additions stay
behind — those are gamification's.
Verified on this branch: tsc --noEmit clean, DEPLOY_ENV=production
next build clean, and the 44 landing unit tests pass. three@^0.184.0 is
already a production dependency; layout.tsx, sitemap.ts and robots.ts
needed no change.
No backend change, no migration.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Aug 23, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3eca33ad-469d-4588-b761-e1e3166cb07e


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@supabase

supabaseBot commented Aug 23, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project ybgqdonkoqftwrmweuyv because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@cloudflare-workers-and-pages

cloudflare-workers-and-pagesBot commented Aug 23, 2026

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitPreview URLUpdated (UTC)
✅ Deployment successful!
View logs
frontend-staging7d7f8e7Commit Preview URL

Branch Preview URL
Aug 23 2026, 03:49 AM

CI's `eslint . --max-warnings=-1` exits 2 on "There are suppressions left
that do not occur anymore" — 0 errors, but a stale entry is still a failure.
The three suppressed violations under src/app/(public)/page.tsx belonged to
the v4 landing (no-html-link-for-pages, two prefer-const, and a
set-state-in-effect); the v5 page this replaces has none of them.
Pruned with `eslint . --prune-suppressions`, the remedy the error names.
main's copy of this file does not list that page either, so this converges
on the same state rather than inventing one.
@Darkest-Teddy
Darkest-Teddy merged commit 56d1ac2 into productionAug 23, 2026
5 checks passed
AndresL230 added a commit that referenced this pull request Aug 23, 2026
…production" (#585)
This reverts commit 56d1ac2, reversing
changes made to 6ec3d0f.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Darkest-Teddy
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat(landing): port the v5 marketing landing onto production by Darkest-Teddy · Pull Request #576 · SaplingLearn/Sapling · GitHub
Skip to content

feat(landing): port the v5 marketing landing onto production - #576

Merged
Darkest-Teddy merged 2 commits into
productionfrom
feat/landing-v5-to-production
Aug 23, 2026
Merged

feat(landing): port the v5 marketing landing onto production#576
Darkest-Teddy merged 2 commits into
productionfrom
feat/landing-v5-to-production

Conversation

@Darkest-Teddy

Copy link
Copy Markdown
Collaborator

Puts the v5 landing on saplinglearn.com without promoting the rest of main.

Why this shape

production still serves the v4 landing (the scroll-driven knowledge graph from #513). main has carried v5 since #524, but production is 68 commits behind it — a full make promote would also ship the gamification/achievements feature, the quiz overhaul, and apply 8 unrun migrations to the production database. This branch cuts from production and takes the landing alone: frontend only, no backend change, no migration.

What's in it

Every file is origin/main's version:

  • components/landing-v5/ (27 files), components/landing/useLanding.ts, lib/landing/ (engine, hero3d, content)
  • app/(public)/ — the v5 landing plus the pages its navbar links to: faq, gallery, news, team, wiki, and the updated about page
  • components/companion/CompanionShell.tsx, the three landing images
  • globals.css — the 238-line .landing-dc / .landing-v5 block

Three deliberate departures from "copy main's file":

  1. lib/api.ts gains only subscribeToNewsletter. The beta CTA calls it and production lacks it; taking main's whole api.ts would have brought the gamification client along. POST /api/newsletter/subscribe already exists on production's backend, so the CTA works as shipped.
  2. globals.css excludes the sap-burst keyframe that main added beside the landing block — it's the flourish behind an achievement badge in BadgeModal, a component this branch doesn't have.
  3. The superseded v4 marketing components are deletedFeatureBand, SurfaceBento, featureBands, graph/, surfaces/. Nothing outside components/marketing/ imported them; marketing/ now matches main exactly.

E2E follows the same rule: landing-graph.spec.ts drives the v4 graph section this removes, so it goes; landing-drag-field.spec.ts and the public-seo copy assertions come across. support/db.ts's additions stay behind — those belong to gamification.

Verification

Run on this branch, against the production profile:

  • tsc --noEmit — clean
  • DEPLOY_ENV=production next build — clean; /news, /team, /wiki, /gallery, /faq all in the route table
  • 44 landing unit tests pass (landing-v5 + lib/landing)
  • Served the build and loaded it in a browser: v5 root mounts, zero page errors, and /, /faq, /gallery, /news, /team, /wiki, /about all return 200

three@^0.184.0 was already a production dependency. layout.tsx, sitemap.ts, robots.ts, useScrollLock and errorMessage are identical between the branches and needed no change.

After merging

production will hold one more commit that main doesn't. It already carries 5 such commits, so make promote's production-diverged preflight guard already blocks (it has no override) — whenever you next promote, back-merge production into main first.

🤖 Generated with Claude Code

production still serves the v4 landing — the scroll-driven knowledge graph
from #513. main has carried v5 since #524, but production sits 68 commits
behind it, and promoting main wholesale would also ship the gamification
feature and apply 8 unrun migrations to the production database. This
takes the landing and nothing else.
Every file here is origin/main's version, with three deliberate departures:
- lib/api.ts gains only `subscribeToNewsletter`, which the beta CTA calls
and production lacks. Taking main's whole api.ts would have brought the
gamification client with it. POST /api/newsletter/subscribe already
exists on production's backend, so the CTA works as shipped.
- globals.css takes the 238-line .landing-dc/.landing-v5 block only. The
one other addition in main's copy — the sap-burst keyframe behind an
achievement badge in BadgeModal — belongs to a component this branch
does not have.
- The v4 marketing components it replaces are deleted (FeatureBand,
SurfaceBento, featureBands, graph/, surfaces/). Nothing outside
components/marketing/ imported them; marketing/ now matches main.
e2e follows the same rule: landing-graph.spec.ts drives the v4 graph
section this removes, so it goes; landing-drag-field.spec.ts and the
public-seo copy assertions come across. support/db.ts's additions stay
behind — those are gamification's.
Verified on this branch: tsc --noEmit clean, DEPLOY_ENV=production
next build clean, and the 44 landing unit tests pass. three@^0.184.0 is
already a production dependency; layout.tsx, sitemap.ts and robots.ts
needed no change.
No backend change, no migration.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Aug 23, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3eca33ad-469d-4588-b761-e1e3166cb07e


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@supabase

supabaseBot commented Aug 23, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project ybgqdonkoqftwrmweuyv because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@cloudflare-workers-and-pages

cloudflare-workers-and-pagesBot commented Aug 23, 2026

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitPreview URLUpdated (UTC)
✅ Deployment successful!
View logs
frontend-staging7d7f8e7Commit Preview URL

Branch Preview URL
Aug 23 2026, 03:49 AM

CI's `eslint . --max-warnings=-1` exits 2 on "There are suppressions left
that do not occur anymore" — 0 errors, but a stale entry is still a failure.
The three suppressed violations under src/app/(public)/page.tsx belonged to
the v4 landing (no-html-link-for-pages, two prefer-const, and a
set-state-in-effect); the v5 page this replaces has none of them.
Pruned with `eslint . --prune-suppressions`, the remedy the error names.
main's copy of this file does not list that page either, so this converges
on the same state rather than inventing one.
@Darkest-Teddy
Darkest-Teddy merged commit 56d1ac2 into productionAug 23, 2026
5 checks passed
AndresL230 added a commit that referenced this pull request Aug 23, 2026
…production" (#585)
This reverts commit 56d1ac2, reversing
changes made to 6ec3d0f.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Darkest-Teddy
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat(landing): port the v5 marketing landing onto production by Darkest-Teddy · Pull Request #576 · SaplingLearn/Sapling · GitHub
Skip to content

feat(landing): port the v5 marketing landing onto production - #576

Merged
Darkest-Teddy merged 2 commits into
productionfrom
feat/landing-v5-to-production
Aug 23, 2026
Merged

feat(landing): port the v5 marketing landing onto production#576
Darkest-Teddy merged 2 commits into
productionfrom
feat/landing-v5-to-production

Conversation

@Darkest-Teddy

Copy link
Copy Markdown
Collaborator

Puts the v5 landing on saplinglearn.com without promoting the rest of main.

Why this shape

production still serves the v4 landing (the scroll-driven knowledge graph from #513). main has carried v5 since #524, but production is 68 commits behind it — a full make promote would also ship the gamification/achievements feature, the quiz overhaul, and apply 8 unrun migrations to the production database. This branch cuts from production and takes the landing alone: frontend only, no backend change, no migration.

What's in it

Every file is origin/main's version:

  • components/landing-v5/ (27 files), components/landing/useLanding.ts, lib/landing/ (engine, hero3d, content)
  • app/(public)/ — the v5 landing plus the pages its navbar links to: faq, gallery, news, team, wiki, and the updated about page
  • components/companion/CompanionShell.tsx, the three landing images
  • globals.css — the 238-line .landing-dc / .landing-v5 block

Three deliberate departures from "copy main's file":

  1. lib/api.ts gains only subscribeToNewsletter. The beta CTA calls it and production lacks it; taking main's whole api.ts would have brought the gamification client along. POST /api/newsletter/subscribe already exists on production's backend, so the CTA works as shipped.
  2. globals.css excludes the sap-burst keyframe that main added beside the landing block — it's the flourish behind an achievement badge in BadgeModal, a component this branch doesn't have.
  3. The superseded v4 marketing components are deletedFeatureBand, SurfaceBento, featureBands, graph/, surfaces/. Nothing outside components/marketing/ imported them; marketing/ now matches main exactly.

E2E follows the same rule: landing-graph.spec.ts drives the v4 graph section this removes, so it goes; landing-drag-field.spec.ts and the public-seo copy assertions come across. support/db.ts's additions stay behind — those belong to gamification.

Verification

Run on this branch, against the production profile:

  • tsc --noEmit — clean
  • DEPLOY_ENV=production next build — clean; /news, /team, /wiki, /gallery, /faq all in the route table
  • 44 landing unit tests pass (landing-v5 + lib/landing)
  • Served the build and loaded it in a browser: v5 root mounts, zero page errors, and /, /faq, /gallery, /news, /team, /wiki, /about all return 200

three@^0.184.0 was already a production dependency. layout.tsx, sitemap.ts, robots.ts, useScrollLock and errorMessage are identical between the branches and needed no change.

After merging

production will hold one more commit that main doesn't. It already carries 5 such commits, so make promote's production-diverged preflight guard already blocks (it has no override) — whenever you next promote, back-merge production into main first.

🤖 Generated with Claude Code

production still serves the v4 landing — the scroll-driven knowledge graph
from #513. main has carried v5 since #524, but production sits 68 commits
behind it, and promoting main wholesale would also ship the gamification
feature and apply 8 unrun migrations to the production database. This
takes the landing and nothing else.
Every file here is origin/main's version, with three deliberate departures:
- lib/api.ts gains only `subscribeToNewsletter`, which the beta CTA calls
and production lacks. Taking main's whole api.ts would have brought the
gamification client with it. POST /api/newsletter/subscribe already
exists on production's backend, so the CTA works as shipped.
- globals.css takes the 238-line .landing-dc/.landing-v5 block only. The
one other addition in main's copy — the sap-burst keyframe behind an
achievement badge in BadgeModal — belongs to a component this branch
does not have.
- The v4 marketing components it replaces are deleted (FeatureBand,
SurfaceBento, featureBands, graph/, surfaces/). Nothing outside
components/marketing/ imported them; marketing/ now matches main.
e2e follows the same rule: landing-graph.spec.ts drives the v4 graph
section this removes, so it goes; landing-drag-field.spec.ts and the
public-seo copy assertions come across. support/db.ts's additions stay
behind — those are gamification's.
Verified on this branch: tsc --noEmit clean, DEPLOY_ENV=production
next build clean, and the 44 landing unit tests pass. three@^0.184.0 is
already a production dependency; layout.tsx, sitemap.ts and robots.ts
needed no change.
No backend change, no migration.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Aug 23, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3eca33ad-469d-4588-b761-e1e3166cb07e


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@supabase

supabaseBot commented Aug 23, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project ybgqdonkoqftwrmweuyv because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@cloudflare-workers-and-pages

cloudflare-workers-and-pagesBot commented Aug 23, 2026

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitPreview URLUpdated (UTC)
✅ Deployment successful!
View logs
frontend-staging7d7f8e7Commit Preview URL

Branch Preview URL
Aug 23 2026, 03:49 AM

CI's `eslint . --max-warnings=-1` exits 2 on "There are suppressions left
that do not occur anymore" — 0 errors, but a stale entry is still a failure.
The three suppressed violations under src/app/(public)/page.tsx belonged to
the v4 landing (no-html-link-for-pages, two prefer-const, and a
set-state-in-effect); the v5 page this replaces has none of them.
Pruned with `eslint . --prune-suppressions`, the remedy the error names.
main's copy of this file does not list that page either, so this converges
on the same state rather than inventing one.
@Darkest-Teddy
Darkest-Teddy merged commit 56d1ac2 into productionAug 23, 2026
5 checks passed
AndresL230 added a commit that referenced this pull request Aug 23, 2026
…production" (#585)
This reverts commit 56d1ac2, reversing
changes made to 6ec3d0f.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Darkest-Teddy
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' feat(landing): port the v5 marketing landing onto production by Darkest-Teddy · Pull Request #576 · SaplingLearn/Sapling · GitHub
Skip to content

feat(landing): port the v5 marketing landing onto production - #576

Merged
Darkest-Teddy merged 2 commits into
productionfrom
feat/landing-v5-to-production
Aug 23, 2026
Merged

feat(landing): port the v5 marketing landing onto production#576
Darkest-Teddy merged 2 commits into
productionfrom
feat/landing-v5-to-production

Conversation

@Darkest-Teddy

Copy link
Copy Markdown
Collaborator

Puts the v5 landing on saplinglearn.com without promoting the rest of main.

Why this shape

production still serves the v4 landing (the scroll-driven knowledge graph from #513). main has carried v5 since #524, but production is 68 commits behind it — a full make promote would also ship the gamification/achievements feature, the quiz overhaul, and apply 8 unrun migrations to the production database. This branch cuts from production and takes the landing alone: frontend only, no backend change, no migration.

What's in it

Every file is origin/main's version:

  • components/landing-v5/ (27 files), components/landing/useLanding.ts, lib/landing/ (engine, hero3d, content)
  • app/(public)/ — the v5 landing plus the pages its navbar links to: faq, gallery, news, team, wiki, and the updated about page
  • components/companion/CompanionShell.tsx, the three landing images
  • globals.css — the 238-line .landing-dc / .landing-v5 block

Three deliberate departures from "copy main's file":

  1. lib/api.ts gains only subscribeToNewsletter. The beta CTA calls it and production lacks it; taking main's whole api.ts would have brought the gamification client along. POST /api/newsletter/subscribe already exists on production's backend, so the CTA works as shipped.
  2. globals.css excludes the sap-burst keyframe that main added beside the landing block — it's the flourish behind an achievement badge in BadgeModal, a component this branch doesn't have.
  3. The superseded v4 marketing components are deletedFeatureBand, SurfaceBento, featureBands, graph/, surfaces/. Nothing outside components/marketing/ imported them; marketing/ now matches main exactly.

E2E follows the same rule: landing-graph.spec.ts drives the v4 graph section this removes, so it goes; landing-drag-field.spec.ts and the public-seo copy assertions come across. support/db.ts's additions stay behind — those belong to gamification.

Verification

Run on this branch, against the production profile:

  • tsc --noEmit — clean
  • DEPLOY_ENV=production next build — clean; /news, /team, /wiki, /gallery, /faq all in the route table
  • 44 landing unit tests pass (landing-v5 + lib/landing)
  • Served the build and loaded it in a browser: v5 root mounts, zero page errors, and /, /faq, /gallery, /news, /team, /wiki, /about all return 200

three@^0.184.0 was already a production dependency. layout.tsx, sitemap.ts, robots.ts, useScrollLock and errorMessage are identical between the branches and needed no change.

After merging

production will hold one more commit that main doesn't. It already carries 5 such commits, so make promote's production-diverged preflight guard already blocks (it has no override) — whenever you next promote, back-merge production into main first.

🤖 Generated with Claude Code

production still serves the v4 landing — the scroll-driven knowledge graph
from #513. main has carried v5 since #524, but production sits 68 commits
behind it, and promoting main wholesale would also ship the gamification
feature and apply 8 unrun migrations to the production database. This
takes the landing and nothing else.
Every file here is origin/main's version, with three deliberate departures:
- lib/api.ts gains only `subscribeToNewsletter`, which the beta CTA calls
and production lacks. Taking main's whole api.ts would have brought the
gamification client with it. POST /api/newsletter/subscribe already
exists on production's backend, so the CTA works as shipped.
- globals.css takes the 238-line .landing-dc/.landing-v5 block only. The
one other addition in main's copy — the sap-burst keyframe behind an
achievement badge in BadgeModal — belongs to a component this branch
does not have.
- The v4 marketing components it replaces are deleted (FeatureBand,
SurfaceBento, featureBands, graph/, surfaces/). Nothing outside
components/marketing/ imported them; marketing/ now matches main.
e2e follows the same rule: landing-graph.spec.ts drives the v4 graph
section this removes, so it goes; landing-drag-field.spec.ts and the
public-seo copy assertions come across. support/db.ts's additions stay
behind — those are gamification's.
Verified on this branch: tsc --noEmit clean, DEPLOY_ENV=production
next build clean, and the 44 landing unit tests pass. three@^0.184.0 is
already a production dependency; layout.tsx, sitemap.ts and robots.ts
needed no change.
No backend change, no migration.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Aug 23, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3eca33ad-469d-4588-b761-e1e3166cb07e


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@supabase

supabaseBot commented Aug 23, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project ybgqdonkoqftwrmweuyv because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@cloudflare-workers-and-pages

cloudflare-workers-and-pagesBot commented Aug 23, 2026

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitPreview URLUpdated (UTC)
✅ Deployment successful!
View logs
frontend-staging7d7f8e7Commit Preview URL

Branch Preview URL
Aug 23 2026, 03:49 AM

CI's `eslint . --max-warnings=-1` exits 2 on "There are suppressions left
that do not occur anymore" — 0 errors, but a stale entry is still a failure.
The three suppressed violations under src/app/(public)/page.tsx belonged to
the v4 landing (no-html-link-for-pages, two prefer-const, and a
set-state-in-effect); the v5 page this replaces has none of them.
Pruned with `eslint . --prune-suppressions`, the remedy the error names.
main's copy of this file does not list that page either, so this converges
on the same state rather than inventing one.
@Darkest-Teddy
Darkest-Teddy merged commit 56d1ac2 into productionAug 23, 2026
5 checks passed
AndresL230 added a commit that referenced this pull request Aug 23, 2026
…production" (#585)
This reverts commit 56d1ac2, reversing
changes made to 6ec3d0f.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Darkest-Teddy
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat(landing): port the v5 marketing landing onto production by Darkest-Teddy · Pull Request #576 · SaplingLearn/Sapling · GitHub
Skip to content

feat(landing): port the v5 marketing landing onto production - #576

Merged
Darkest-Teddy merged 2 commits into
productionfrom
feat/landing-v5-to-production
Aug 23, 2026
Merged

feat(landing): port the v5 marketing landing onto production#576
Darkest-Teddy merged 2 commits into
productionfrom
feat/landing-v5-to-production

Conversation

@Darkest-Teddy

Copy link
Copy Markdown
Collaborator

Puts the v5 landing on saplinglearn.com without promoting the rest of main.

Why this shape

production still serves the v4 landing (the scroll-driven knowledge graph from #513). main has carried v5 since #524, but production is 68 commits behind it — a full make promote would also ship the gamification/achievements feature, the quiz overhaul, and apply 8 unrun migrations to the production database. This branch cuts from production and takes the landing alone: frontend only, no backend change, no migration.

What's in it

Every file is origin/main's version:

  • components/landing-v5/ (27 files), components/landing/useLanding.ts, lib/landing/ (engine, hero3d, content)
  • app/(public)/ — the v5 landing plus the pages its navbar links to: faq, gallery, news, team, wiki, and the updated about page
  • components/companion/CompanionShell.tsx, the three landing images
  • globals.css — the 238-line .landing-dc / .landing-v5 block

Three deliberate departures from "copy main's file":

  1. lib/api.ts gains only subscribeToNewsletter. The beta CTA calls it and production lacks it; taking main's whole api.ts would have brought the gamification client along. POST /api/newsletter/subscribe already exists on production's backend, so the CTA works as shipped.
  2. globals.css excludes the sap-burst keyframe that main added beside the landing block — it's the flourish behind an achievement badge in BadgeModal, a component this branch doesn't have.
  3. The superseded v4 marketing components are deletedFeatureBand, SurfaceBento, featureBands, graph/, surfaces/. Nothing outside components/marketing/ imported them; marketing/ now matches main exactly.

E2E follows the same rule: landing-graph.spec.ts drives the v4 graph section this removes, so it goes; landing-drag-field.spec.ts and the public-seo copy assertions come across. support/db.ts's additions stay behind — those belong to gamification.

Verification

Run on this branch, against the production profile:

  • tsc --noEmit — clean
  • DEPLOY_ENV=production next build — clean; /news, /team, /wiki, /gallery, /faq all in the route table
  • 44 landing unit tests pass (landing-v5 + lib/landing)
  • Served the build and loaded it in a browser: v5 root mounts, zero page errors, and /, /faq, /gallery, /news, /team, /wiki, /about all return 200

three@^0.184.0 was already a production dependency. layout.tsx, sitemap.ts, robots.ts, useScrollLock and errorMessage are identical between the branches and needed no change.

After merging

production will hold one more commit that main doesn't. It already carries 5 such commits, so make promote's production-diverged preflight guard already blocks (it has no override) — whenever you next promote, back-merge production into main first.

🤖 Generated with Claude Code

production still serves the v4 landing — the scroll-driven knowledge graph
from #513. main has carried v5 since #524, but production sits 68 commits
behind it, and promoting main wholesale would also ship the gamification
feature and apply 8 unrun migrations to the production database. This
takes the landing and nothing else.
Every file here is origin/main's version, with three deliberate departures:
- lib/api.ts gains only `subscribeToNewsletter`, which the beta CTA calls
and production lacks. Taking main's whole api.ts would have brought the
gamification client with it. POST /api/newsletter/subscribe already
exists on production's backend, so the CTA works as shipped.
- globals.css takes the 238-line .landing-dc/.landing-v5 block only. The
one other addition in main's copy — the sap-burst keyframe behind an
achievement badge in BadgeModal — belongs to a component this branch
does not have.
- The v4 marketing components it replaces are deleted (FeatureBand,
SurfaceBento, featureBands, graph/, surfaces/). Nothing outside
components/marketing/ imported them; marketing/ now matches main.
e2e follows the same rule: landing-graph.spec.ts drives the v4 graph
section this removes, so it goes; landing-drag-field.spec.ts and the
public-seo copy assertions come across. support/db.ts's additions stay
behind — those are gamification's.
Verified on this branch: tsc --noEmit clean, DEPLOY_ENV=production
next build clean, and the 44 landing unit tests pass. three@^0.184.0 is
already a production dependency; layout.tsx, sitemap.ts and robots.ts
needed no change.
No backend change, no migration.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Aug 23, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3eca33ad-469d-4588-b761-e1e3166cb07e


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@supabase

supabaseBot commented Aug 23, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project ybgqdonkoqftwrmweuyv because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@cloudflare-workers-and-pages

cloudflare-workers-and-pagesBot commented Aug 23, 2026

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitPreview URLUpdated (UTC)
✅ Deployment successful!
View logs
frontend-staging7d7f8e7Commit Preview URL

Branch Preview URL
Aug 23 2026, 03:49 AM

CI's `eslint . --max-warnings=-1` exits 2 on "There are suppressions left
that do not occur anymore" — 0 errors, but a stale entry is still a failure.
The three suppressed violations under src/app/(public)/page.tsx belonged to
the v4 landing (no-html-link-for-pages, two prefer-const, and a
set-state-in-effect); the v5 page this replaces has none of them.
Pruned with `eslint . --prune-suppressions`, the remedy the error names.
main's copy of this file does not list that page either, so this converges
on the same state rather than inventing one.
@Darkest-Teddy
Darkest-Teddy merged commit 56d1ac2 into productionAug 23, 2026
5 checks passed
AndresL230 added a commit that referenced this pull request Aug 23, 2026
…production" (#585)
This reverts commit 56d1ac2, reversing
changes made to 6ec3d0f.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Darkest-Teddy
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat(landing): port the v5 marketing landing onto production by Darkest-Teddy · Pull Request #576 · SaplingLearn/Sapling · GitHub
Skip to content

feat(landing): port the v5 marketing landing onto production - #576

Merged
Darkest-Teddy merged 2 commits into
productionfrom
feat/landing-v5-to-production
Aug 23, 2026
Merged

feat(landing): port the v5 marketing landing onto production#576
Darkest-Teddy merged 2 commits into
productionfrom
feat/landing-v5-to-production

Conversation

@Darkest-Teddy

Copy link
Copy Markdown
Collaborator

Puts the v5 landing on saplinglearn.com without promoting the rest of main.

Why this shape

production still serves the v4 landing (the scroll-driven knowledge graph from #513). main has carried v5 since #524, but production is 68 commits behind it — a full make promote would also ship the gamification/achievements feature, the quiz overhaul, and apply 8 unrun migrations to the production database. This branch cuts from production and takes the landing alone: frontend only, no backend change, no migration.

What's in it

Every file is origin/main's version:

  • components/landing-v5/ (27 files), components/landing/useLanding.ts, lib/landing/ (engine, hero3d, content)
  • app/(public)/ — the v5 landing plus the pages its navbar links to: faq, gallery, news, team, wiki, and the updated about page
  • components/companion/CompanionShell.tsx, the three landing images
  • globals.css — the 238-line .landing-dc / .landing-v5 block

Three deliberate departures from "copy main's file":

  1. lib/api.ts gains only subscribeToNewsletter. The beta CTA calls it and production lacks it; taking main's whole api.ts would have brought the gamification client along. POST /api/newsletter/subscribe already exists on production's backend, so the CTA works as shipped.
  2. globals.css excludes the sap-burst keyframe that main added beside the landing block — it's the flourish behind an achievement badge in BadgeModal, a component this branch doesn't have.
  3. The superseded v4 marketing components are deletedFeatureBand, SurfaceBento, featureBands, graph/, surfaces/. Nothing outside components/marketing/ imported them; marketing/ now matches main exactly.

E2E follows the same rule: landing-graph.spec.ts drives the v4 graph section this removes, so it goes; landing-drag-field.spec.ts and the public-seo copy assertions come across. support/db.ts's additions stay behind — those belong to gamification.

Verification

Run on this branch, against the production profile:

  • tsc --noEmit — clean
  • DEPLOY_ENV=production next build — clean; /news, /team, /wiki, /gallery, /faq all in the route table
  • 44 landing unit tests pass (landing-v5 + lib/landing)
  • Served the build and loaded it in a browser: v5 root mounts, zero page errors, and /, /faq, /gallery, /news, /team, /wiki, /about all return 200

three@^0.184.0 was already a production dependency. layout.tsx, sitemap.ts, robots.ts, useScrollLock and errorMessage are identical between the branches and needed no change.

After merging

production will hold one more commit that main doesn't. It already carries 5 such commits, so make promote's production-diverged preflight guard already blocks (it has no override) — whenever you next promote, back-merge production into main first.

🤖 Generated with Claude Code

production still serves the v4 landing — the scroll-driven knowledge graph
from #513. main has carried v5 since #524, but production sits 68 commits
behind it, and promoting main wholesale would also ship the gamification
feature and apply 8 unrun migrations to the production database. This
takes the landing and nothing else.
Every file here is origin/main's version, with three deliberate departures:
- lib/api.ts gains only `subscribeToNewsletter`, which the beta CTA calls
and production lacks. Taking main's whole api.ts would have brought the
gamification client with it. POST /api/newsletter/subscribe already
exists on production's backend, so the CTA works as shipped.
- globals.css takes the 238-line .landing-dc/.landing-v5 block only. The
one other addition in main's copy — the sap-burst keyframe behind an
achievement badge in BadgeModal — belongs to a component this branch
does not have.
- The v4 marketing components it replaces are deleted (FeatureBand,
SurfaceBento, featureBands, graph/, surfaces/). Nothing outside
components/marketing/ imported them; marketing/ now matches main.
e2e follows the same rule: landing-graph.spec.ts drives the v4 graph
section this removes, so it goes; landing-drag-field.spec.ts and the
public-seo copy assertions come across. support/db.ts's additions stay
behind — those are gamification's.
Verified on this branch: tsc --noEmit clean, DEPLOY_ENV=production
next build clean, and the 44 landing unit tests pass. three@^0.184.0 is
already a production dependency; layout.tsx, sitemap.ts and robots.ts
needed no change.
No backend change, no migration.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Aug 23, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3eca33ad-469d-4588-b761-e1e3166cb07e


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@supabase

supabaseBot commented Aug 23, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project ybgqdonkoqftwrmweuyv because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@cloudflare-workers-and-pages

cloudflare-workers-and-pagesBot commented Aug 23, 2026

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitPreview URLUpdated (UTC)
✅ Deployment successful!
View logs
frontend-staging7d7f8e7Commit Preview URL

Branch Preview URL
Aug 23 2026, 03:49 AM

CI's `eslint . --max-warnings=-1` exits 2 on "There are suppressions left
that do not occur anymore" — 0 errors, but a stale entry is still a failure.
The three suppressed violations under src/app/(public)/page.tsx belonged to
the v4 landing (no-html-link-for-pages, two prefer-const, and a
set-state-in-effect); the v5 page this replaces has none of them.
Pruned with `eslint . --prune-suppressions`, the remedy the error names.
main's copy of this file does not list that page either, so this converges
on the same state rather than inventing one.
@Darkest-Teddy
Darkest-Teddy merged commit 56d1ac2 into productionAug 23, 2026
5 checks passed
AndresL230 added a commit that referenced this pull request Aug 23, 2026
…production" (#585)
This reverts commit 56d1ac2, reversing
changes made to 6ec3d0f.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Darkest-Teddy
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); feat(landing): port the v5 marketing landing onto production by Darkest-Teddy · Pull Request #576 · SaplingLearn/Sapling · GitHub
Skip to content

feat(landing): port the v5 marketing landing onto production - #576

Merged
Darkest-Teddy merged 2 commits into
productionfrom
feat/landing-v5-to-production
Aug 23, 2026
Merged

feat(landing): port the v5 marketing landing onto production#576
Darkest-Teddy merged 2 commits into
productionfrom
feat/landing-v5-to-production

Conversation

@Darkest-Teddy

Copy link
Copy Markdown
Collaborator

Puts the v5 landing on saplinglearn.com without promoting the rest of main.

Why this shape

production still serves the v4 landing (the scroll-driven knowledge graph from #513). main has carried v5 since #524, but production is 68 commits behind it — a full make promote would also ship the gamification/achievements feature, the quiz overhaul, and apply 8 unrun migrations to the production database. This branch cuts from production and takes the landing alone: frontend only, no backend change, no migration.

What's in it

Every file is origin/main's version:

  • components/landing-v5/ (27 files), components/landing/useLanding.ts, lib/landing/ (engine, hero3d, content)
  • app/(public)/ — the v5 landing plus the pages its navbar links to: faq, gallery, news, team, wiki, and the updated about page
  • components/companion/CompanionShell.tsx, the three landing images
  • globals.css — the 238-line .landing-dc / .landing-v5 block

Three deliberate departures from "copy main's file":

  1. lib/api.ts gains only subscribeToNewsletter. The beta CTA calls it and production lacks it; taking main's whole api.ts would have brought the gamification client along. POST /api/newsletter/subscribe already exists on production's backend, so the CTA works as shipped.
  2. globals.css excludes the sap-burst keyframe that main added beside the landing block — it's the flourish behind an achievement badge in BadgeModal, a component this branch doesn't have.
  3. The superseded v4 marketing components are deletedFeatureBand, SurfaceBento, featureBands, graph/, surfaces/. Nothing outside components/marketing/ imported them; marketing/ now matches main exactly.

E2E follows the same rule: landing-graph.spec.ts drives the v4 graph section this removes, so it goes; landing-drag-field.spec.ts and the public-seo copy assertions come across. support/db.ts's additions stay behind — those belong to gamification.

Verification

Run on this branch, against the production profile:

  • tsc --noEmit — clean
  • DEPLOY_ENV=production next build — clean; /news, /team, /wiki, /gallery, /faq all in the route table
  • 44 landing unit tests pass (landing-v5 + lib/landing)
  • Served the build and loaded it in a browser: v5 root mounts, zero page errors, and /, /faq, /gallery, /news, /team, /wiki, /about all return 200

three@^0.184.0 was already a production dependency. layout.tsx, sitemap.ts, robots.ts, useScrollLock and errorMessage are identical between the branches and needed no change.

After merging

production will hold one more commit that main doesn't. It already carries 5 such commits, so make promote's production-diverged preflight guard already blocks (it has no override) — whenever you next promote, back-merge production into main first.

🤖 Generated with Claude Code

production still serves the v4 landing — the scroll-driven knowledge graph
from #513. main has carried v5 since #524, but production sits 68 commits
behind it, and promoting main wholesale would also ship the gamification
feature and apply 8 unrun migrations to the production database. This
takes the landing and nothing else.
Every file here is origin/main's version, with three deliberate departures:
- lib/api.ts gains only `subscribeToNewsletter`, which the beta CTA calls
and production lacks. Taking main's whole api.ts would have brought the
gamification client with it. POST /api/newsletter/subscribe already
exists on production's backend, so the CTA works as shipped.
- globals.css takes the 238-line .landing-dc/.landing-v5 block only. The
one other addition in main's copy — the sap-burst keyframe behind an
achievement badge in BadgeModal — belongs to a component this branch
does not have.
- The v4 marketing components it replaces are deleted (FeatureBand,
SurfaceBento, featureBands, graph/, surfaces/). Nothing outside
components/marketing/ imported them; marketing/ now matches main.
e2e follows the same rule: landing-graph.spec.ts drives the v4 graph
section this removes, so it goes; landing-drag-field.spec.ts and the
public-seo copy assertions come across. support/db.ts's additions stay
behind — those are gamification's.
Verified on this branch: tsc --noEmit clean, DEPLOY_ENV=production
next build clean, and the 44 landing unit tests pass. three@^0.184.0 is
already a production dependency; layout.tsx, sitemap.ts and robots.ts
needed no change.
No backend change, no migration.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Aug 23, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3eca33ad-469d-4588-b761-e1e3166cb07e


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@supabase

supabaseBot commented Aug 23, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project ybgqdonkoqftwrmweuyv because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@cloudflare-workers-and-pages

cloudflare-workers-and-pagesBot commented Aug 23, 2026

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitPreview URLUpdated (UTC)
✅ Deployment successful!
View logs
frontend-staging7d7f8e7Commit Preview URL

Branch Preview URL
Aug 23 2026, 03:49 AM

CI's `eslint . --max-warnings=-1` exits 2 on "There are suppressions left
that do not occur anymore" — 0 errors, but a stale entry is still a failure.
The three suppressed violations under src/app/(public)/page.tsx belonged to
the v4 landing (no-html-link-for-pages, two prefer-const, and a
set-state-in-effect); the v5 page this replaces has none of them.
Pruned with `eslint . --prune-suppressions`, the remedy the error names.
main's copy of this file does not list that page either, so this converges
on the same state rather than inventing one.
@Darkest-Teddy
Darkest-Teddy merged commit 56d1ac2 into productionAug 23, 2026
5 checks passed
AndresL230 added a commit that referenced this pull request Aug 23, 2026
…production" (#585)
This reverts commit 56d1ac2, reversing
changes made to 6ec3d0f.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Darkest-Teddy