clean: remove .pi/ config from calvana repo — lives in pi-vs-claude-code now

- Removed all .pi/ (agents, themes, extensions, skills, observatory)
- Removed CLAUDE.md (belongs in parent pi repo)
- Added .pi/ and CLAUDE.md to .gitignore
- Added .pi/ to pledge-now-pay-later/.gitignore
This commit is contained in:
2026-03-04 17:32:20 +08:00
parent ef37ca0c18
commit 59485579ec
46 changed files with 31 additions and 5291 deletions

View File

@@ -115,104 +115,52 @@ const GALLERY_IMAGES = [
{ src: "/images/brand/youth-01-workshop.jpg", alt: "Youth workshop in full swing" },
]
/* Slide directions: [incoming start offset, outgoing end offset] as CSS translate values */
const SLIDES: [string, string][] = [
["translateX(100%)", "translateX(-100%)"], // from right
["translateX(-100%)", "translateX(100%)"], // from left
["translateY(100%)", "translateY(-100%)"], // from bottom
["translateY(-100%)", "translateY(100%)"], // from top
]
const DURATION = 420 // ms — snappy
const INTERVAL = 3500
const SLIDE_DIR: [string, string] = ["translateX(100%)", "translateX(-100%)"] // slide from right
const SLIDE_SPEED = 150 // ms — fast snap-slide
const SLIDE_INTERVAL = 3500
function GallerySlideshow() {
const [idx, setIdx] = useState(0)
const [prevIdx, setPrevIdx] = useState(-1)
const [phase, setPhase] = useState<"idle" | "prep" | "go">("idle")
const dirRef = useRef(SLIDES[0])
const dirRef = useRef(SLIDE_DIR)
const inRef = useRef<HTMLDivElement>(null)
const outRef = useRef<HTMLDivElement>(null)
// Pick random direction and kick off transition
const advance = useCallback(() => {
dirRef.current = SLIDES[Math.floor(Math.random() * SLIDES.length)]
setIdx((i) => {
setPrevIdx(i)
return (i + 1) % GALLERY_IMAGES.length
})
setPhase("prep") // frame 1: position incoming off-screen
setIdx((i) => { setPrevIdx(i); return (i + 1) % GALLERY_IMAGES.length })
setPhase("prep")
}, [])
// Two-frame trick: prep → go
useEffect(() => {
if (phase === "prep") {
// Position incoming element at its start offset (no transition)
const el = inRef.current
if (el) {
el.style.transition = "none"
el.style.transform = dirRef.current[0]
}
const oel = outRef.current
if (oel) {
oel.style.transition = "none"
oel.style.transform = "translate(0,0)"
}
// Next frame: enable transition and snap to final position
requestAnimationFrame(() => {
requestAnimationFrame(() => setPhase("go"))
})
if (inRef.current) { inRef.current.style.transition = "none"; inRef.current.style.transform = dirRef.current[0] }
if (outRef.current) { outRef.current.style.transition = "none"; outRef.current.style.transform = "translate(0,0)" }
requestAnimationFrame(() => requestAnimationFrame(() => setPhase("go")))
}
if (phase === "go") {
const ease = `transform ${DURATION}ms cubic-bezier(0.25, 1, 0.5, 1)`
const el = inRef.current
if (el) {
el.style.transition = ease
el.style.transform = "translate(0,0)"
}
const oel = outRef.current
if (oel) {
oel.style.transition = ease
oel.style.transform = dirRef.current[1]
}
const t = setTimeout(() => {
setPrevIdx(-1)
setPhase("idle")
}, DURATION + 20)
return () => clearTimeout(t)
const t = `transform ${SLIDE_SPEED}ms cubic-bezier(0.16, 1, 0.3, 1)`
if (inRef.current) { inRef.current.style.transition = t; inRef.current.style.transform = "translate(0,0)" }
if (outRef.current) { outRef.current.style.transition = t; outRef.current.style.transform = dirRef.current[1] }
const timer = setTimeout(() => { setPrevIdx(-1); setPhase("idle") }, SLIDE_SPEED + 10)
return () => clearTimeout(timer)
}
}, [phase])
// Auto-advance timer
useEffect(() => {
const t = setInterval(advance, INTERVAL)
const t = setInterval(advance, SLIDE_INTERVAL)
return () => clearInterval(t)
}, [advance])
return (
<div className="relative min-h-[280px] md:min-h-[360px] overflow-hidden bg-gray-100">
{/* Outgoing image */}
{prevIdx !== -1 && (
<div ref={outRef} className="absolute inset-0 z-[1] will-change-transform">
<Image
src={GALLERY_IMAGES[prevIdx].src}
alt={GALLERY_IMAGES[prevIdx].alt}
fill
className="object-cover"
sizes="(max-width: 768px) 100vw, 50vw"
/>
<Image src={GALLERY_IMAGES[prevIdx].src} alt={GALLERY_IMAGES[prevIdx].alt} fill className="object-cover" sizes="(max-width: 768px) 100vw, 50vw" />
</div>
)}
{/* Incoming / current image */}
<div ref={inRef} className="absolute inset-0 z-[2] will-change-transform">
<Image
src={GALLERY_IMAGES[idx].src}
alt={GALLERY_IMAGES[idx].alt}
fill
className="object-cover"
sizes="(max-width: 768px) 100vw, 50vw"
priority={idx === 0}
/>
<Image src={GALLERY_IMAGES[idx].src} alt={GALLERY_IMAGES[idx].alt} fill className="object-cover" sizes="(max-width: 768px) 100vw, 50vw" priority={idx === 0} />
</div>
</div>
)