"use client"; import type { RiftPageProfile } from "@/content/rift-page-profiles"; import { CONTOUR_MAJOR, CONTOUR_MINOR, RIFT_CHANNEL_INNER, RIFT_CHANNEL_OUTER_LEFT, RIFT_CHANNEL_OUTER_RIGHT, RIFT_VIEWBOX, contourOpacity, getChannelTransform, } from "@/lib/rift-topography-paths"; import { mixHex } from "@/lib/rift-colors"; import { cn } from "@/lib/utils"; const GREEN = "#1a5c38"; const GOLD = "#ffb300"; const BLUE = "#1f3d7e"; type Props = { variant: "hero" | "ambient" | "header"; profile: RiftPageProfile; className?: string; scrollProgress?: number; scrollY?: number; reduceMotion?: boolean; /** hero intro state */ introPhase?: "intro" | "settled" | "static"; }; function strokesFromProgress(p: number, accentMode: RiftPageProfile["accentMode"]) { const t = Math.max(0, Math.min(1, p)); let primary = GREEN; let accent = GOLD; if (accentMode === "gold") { primary = mixHex(GOLD, GREEN, 0.35); accent = GOLD; } else if (accentMode === "mixed") { if (t < 0.33) { primary = mixHex(GREEN, GOLD, t / 0.33); accent = mixHex(GOLD, BLUE, t / 0.33); } else if (t < 0.66) { primary = mixHex(GOLD, BLUE, (t - 0.33) / 0.33); accent = mixHex(BLUE, GREEN, (t - 0.33) / 0.33); } else { primary = mixHex(BLUE, GREEN, (t - 0.66) / 0.34); accent = mixHex(GREEN, GOLD, (t - 0.66) / 0.34); } } return { primary, accent }; } export function RiftTopographyLayer({ variant, profile, className, scrollProgress = 0, scrollY = 0, reduceMotion = false, introPhase = "static", }: Props) { const { primary, accent } = strokesFromProgress(scrollProgress, profile.accentMode); const drawOffset = reduceMotion ? 0 : Math.max(0, 1 - scrollProgress * 1.12 - 0.06); const majorOp = contourOpacity(profile.contourDensity, "major"); const minorOp = contourOpacity(profile.contourDensity, "minor"); const channelTransform = getChannelTransform(profile.channelBias); const parallaxY = reduceMotion ? 0 : scrollY * 0.04; const isHero = variant === "hero"; const sceneClass = cn( isHero && "rift-hero-scene", isHero && introPhase === "intro" && "rift-hero-intro", isHero && introPhase === "settled" && "rift-hero-settled", isHero && introPhase === "static" && "rift-hero-static", !isHero && profile.profileClass, profile.enablePulse && !reduceMotion && "rift-ambient-pulse" ); const strokeTransition = "stroke 0.85s ease, opacity 0.85s ease, stroke-dashoffset 0.25s ease-out"; const drawStyle = { strokeDasharray: 1, strokeDashoffset: drawOffset, transition: strokeTransition, } as const; const showMinor = profile.contourDensity !== "low" || profile.id === "partners"; return (