diff --git a/app/layout.tsx b/app/layout.tsx
index b4c68a4..05cd552 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -2,25 +2,36 @@ import type React from "react"
import type { Metadata } from "next"
import { Analytics } from "@vercel/analytics/next"
import "./globals.css"
+import LadderClimb from "@/components/ladderclimber"
+import Navbar from "@/components/navbar"
export const metadata: Metadata = {
title: "School For Schools",
description: "Combining expertise in education with cutting-edge technology",
- generator: "v0.app",
-
}
-export default function RootLayout({
- children,
-}: Readonly<{
- children: React.ReactNode
-}>) {
+export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
-
+
+
+
+
+ {/* LadderClimb is now global */}
+
+
+ {/* All page content */}
{children}
)
-}
+}
\ No newline at end of file
diff --git a/app/page.tsx b/app/page.tsx
index 2773717..7bd9aef 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -5,17 +5,19 @@ import Testimonials from "@/components/testimonials"
import OurOfferings from "@/components/our-offerings"
import TrustedBy from "@/components/trusted-by"
import Footer from "@/components/footer"
+import LadderClimb from "@/components/ladderclimber"
export default function Home() {
return (
-
-
-
- {/* This is the 'Why SFS' section */}
-
-
-
-
-
+ <>
+
+
+ {/* This is the 'Why SFS' section */}
+
+
+
+
+
+ >
)
}
diff --git a/components/ladderclimber.tsx b/components/ladderclimber.tsx
new file mode 100644
index 0000000..d46b69d
--- /dev/null
+++ b/components/ladderclimber.tsx
@@ -0,0 +1,143 @@
+"use client"
+
+import React, { useEffect, useRef, useState } from "react"
+
+export default function LadderClimb() {
+ const charRef = useRef(null)
+ const ladderRef = useRef(null)
+
+ const [animation, setAnimation] = useState<"idle" | "climbing">("idle")
+ const [visible, setVisible] = useState(true)
+
+ const ladderHeight = useRef(0)
+ const scrollTimeout = useRef(null)
+
+ const updateDimensions = () => {
+ if (ladderRef.current) {
+ ladderHeight.current = ladderRef.current.clientHeight
+ }
+ if (charRef.current) {
+ charRef.current.style.transform = `translateY(0px)`
+ }
+ }
+
+ useEffect(() => {
+ updateDimensions()
+ setAnimation("idle")
+
+ window.addEventListener("resize", updateDimensions)
+
+ const handleScroll = () => {
+ if (!charRef.current || !ladderRef.current) return
+
+ // show ladder & climbing animation
+ setVisible(true)
+ setAnimation("climbing")
+
+ const scrollTop = window.scrollY
+ const docHeight = document.body.scrollHeight
+ const viewportHeight = window.innerHeight
+
+ let progress = scrollTop / (docHeight - viewportHeight)
+ progress = Math.max(0, Math.min(1, progress))
+
+ const topOffset = 174
+ const bottomOffset = 30
+ const maxClimb = ladderHeight.current - topOffset - bottomOffset
+
+ const y = progress * maxClimb
+ charRef.current.style.transform = `translateY(-${y}px)`
+
+ // hide smoothly after scroll stops
+ if (scrollTimeout.current) clearTimeout(scrollTimeout.current)
+ scrollTimeout.current = setTimeout(() => {
+ setAnimation("idle")
+ setVisible(false)
+ }, 500)
+ }
+
+ window.addEventListener("scroll", handleScroll)
+
+ return () => {
+ window.removeEventListener("scroll", handleScroll)
+ window.removeEventListener("resize", updateDimensions)
+ if (scrollTimeout.current) clearTimeout(scrollTimeout.current)
+ }
+ }, [])
+
+ return (
+ <>
+ {/* Ladder container */}
+
+ {/* Ladder background */}
+
+
+ {/* Character */}
+
+ {/* CLIMBING */}
+ {animation === "climbing" && (
+

+ )}
+
+ {/* IDLE */}
+ {animation === "idle" && (
+

+ )}
+
+
+ >
+ )
+}
diff --git a/components/navbar.tsx b/components/navbar.tsx
index 3e133fa..b092667 100644
--- a/components/navbar.tsx
+++ b/components/navbar.tsx
@@ -75,7 +75,7 @@ export default function Navbar() {
}, [])
return (
-