From a3e36043d6c48296c795a876e620e1b47b3fbef5 Mon Sep 17 00:00:00 2001 From: Codex CLI Date: Sun, 1 Feb 2026 20:28:33 -0700 Subject: [PATCH 1/3] chore: update footer trademark notice for Deal Scale --- src/components/layout/Footer.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/layout/Footer.tsx b/src/components/layout/Footer.tsx index 4f0c77e0..6c7033ca 100644 --- a/src/components/layout/Footer.tsx +++ b/src/components/layout/Footer.tsx @@ -196,9 +196,9 @@ export const Footer: React.FC = ({
-

- DealScaleREI © 2025 Deal Scale. All rights reserved. -

+

+ © 2025 Deal Scale™ — All Rights Reserved. Deal Scale is a registered trademark. +

Date: Sun, 1 Feb 2026 20:33:14 -0700 Subject: [PATCH 2/3] fix: resolve hydration mismatch errors in FeatureShowcase and AnimatedBeam --- .../demos/real-time-analytics/FeatureShowcase.tsx | 13 ++++--------- src/components/ui/animated-beam-network.tsx | 1 + src/components/ui/animated-beam.tsx | 7 ++++++- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/components/demos/real-time-analytics/FeatureShowcase.tsx b/src/components/demos/real-time-analytics/FeatureShowcase.tsx index 2fdd1714..467f0d10 100644 --- a/src/components/demos/real-time-analytics/FeatureShowcase.tsx +++ b/src/components/demos/real-time-analytics/FeatureShowcase.tsx @@ -2,14 +2,7 @@ import { AnimatePresence, motion } from "motion/react"; import Link from "next/link"; -import { - useCallback, - useEffect, - useId, - useMemo, - useRef, - useState, -} from "react"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { MacbookScroll } from "@/components/ui/macbook-scroll"; import { ShinyButton } from "@/components/ui/shiny-button"; @@ -37,6 +30,9 @@ const ROI_CALCULATOR_URL = export function FeatureShowcase({ features, }: FeatureShowcaseProps): JSX.Element | null { + // Move useId() before any conditional returns to comply with React hooks rules + // Use a stable prefix for SSR/client hydration consistency + const generatedId = "feature-showcase"; const stableFeatures = useMemo(() => features.filter(Boolean), [features]); const featureIds = useMemo( () => stableFeatures.map((feature) => feature.id), @@ -48,7 +44,6 @@ export function FeatureShowcase({ } const fallbackId = stableFeatures[0]?.id ?? ""; - const generatedId = useId(); const [activeId, setActiveId] = useState(fallbackId); const interactionRef = useRef(false); const lastManualSelectionRef = useRef(Date.now()); diff --git a/src/components/ui/animated-beam-network.tsx b/src/components/ui/animated-beam-network.tsx index d7fa3940..d3017bda 100644 --- a/src/components/ui/animated-beam-network.tsx +++ b/src/components/ui/animated-beam-network.tsx @@ -228,6 +228,7 @@ export function AnimatedBeamNetwork({ = ({ @@ -41,8 +43,11 @@ export const AnimatedBeam: React.FC = ({ startYOffset = 0, endXOffset = 0, endYOffset = 0, + beamId, }) => { - const id = useId(); + const reactId = useId(); + // Use provided beamId for SSR consistency, fall back to React's useId() + const id = beamId ?? reactId; const [pathD, setPathD] = useState(""); const [svgDimensions, setSvgDimensions] = useState({ width: 0, height: 0 }); From f5b57fd0343c82a5b4904de96243b7c1b1587911 Mon Sep 17 00:00:00 2001 From: Codex CLI Date: Sun, 1 Feb 2026 20:37:18 -0700 Subject: [PATCH 3/3] fix: hydration mismatches and full-width scroll indicator --- next-env.d.ts | 2 +- .../demos/real-time-analytics/FeatureShowcase.tsx | 8 ++++---- src/components/home/testimonials/TestimonialTabs.tsx | 7 ++++--- src/components/ui/scroll-distance-indicator.tsx | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/next-env.d.ts b/next-env.d.ts index 2d5420eb..0c7fad71 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -1,7 +1,7 @@ /// /// /// -import "./.next/types/routes.d.ts"; +import "./.next/dev/types/routes.d.ts"; // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/src/components/demos/real-time-analytics/FeatureShowcase.tsx b/src/components/demos/real-time-analytics/FeatureShowcase.tsx index 467f0d10..1df82941 100644 --- a/src/components/demos/real-time-analytics/FeatureShowcase.tsx +++ b/src/components/demos/real-time-analytics/FeatureShowcase.tsx @@ -2,7 +2,7 @@ import { AnimatePresence, motion } from "motion/react"; import Link from "next/link"; -import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { useCallback, useEffect, useId, useMemo, useRef, useState } from "react"; import { MacbookScroll } from "@/components/ui/macbook-scroll"; import { ShinyButton } from "@/components/ui/shiny-button"; @@ -30,9 +30,9 @@ const ROI_CALCULATOR_URL = export function FeatureShowcase({ features, }: FeatureShowcaseProps): JSX.Element | null { - // Move useId() before any conditional returns to comply with React hooks rules - // Use a stable prefix for SSR/client hydration consistency - const generatedId = "feature-showcase"; + // Use React's useId hook for SSR-safe ID generation + // This ensures server and client render the same IDs and prevents hydration mismatches + const generatedId = useId(); const stableFeatures = useMemo(() => features.filter(Boolean), [features]); const featureIds = useMemo( () => stableFeatures.map((feature) => feature.id), diff --git a/src/components/home/testimonials/TestimonialTabs.tsx b/src/components/home/testimonials/TestimonialTabs.tsx index aa0b94c0..4c3ca9cf 100644 --- a/src/components/home/testimonials/TestimonialTabs.tsx +++ b/src/components/home/testimonials/TestimonialTabs.tsx @@ -1,6 +1,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import type { Testimonial } from "@/types/testimonial"; import { AnimatePresence, type Variants, motion } from "framer-motion"; +import { useId } from "react"; import { TAB_KEYS, type TabKey } from "./tabConfig"; interface TestimonialTabsProps { @@ -22,9 +23,9 @@ export function TestimonialTabs({ fadeInUp, testimonial, }: TestimonialTabsProps) { - // Use a stable ID to prevent hydration mismatches with Radix UI's random ID generation - // This ensures server and client render the same IDs - const tabsId = "testimonial-tabs"; + // Use React's useId hook for SSR-safe ID generation + // This ensures server and client render the same IDs and prevents hydration mismatches + const tabsId = useId(); return (