Skip to content

chore: add veo angency template - #1

Open
dbugshe2 wants to merge 19 commits into
mainfrom
dev
Open

chore: add veo angency template#1
dbugshe2 wants to merge 19 commits into
mainfrom
dev

Conversation

@dbugshe2

@dbugshe2 dbugshe2 commented Apr 1, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • Style

    • Overhauled design tokens: colors, typography (new default fonts), spacing, tracking, shadows, and border radius for a more consistent look
  • New Features

    • Added a broad set of reusable UI components (cards, inputs, forms, dialogs, menus, charts, tables, etc.) and a new in-app Toaster; default theme now set to light
  • Chores

    • Removed legacy toast implementation and updated shared utility import paths
  • Content

    • Rebranded site content and copy to Medbase Africa; simplified navigation, team listings, and footer/social links

@dbugshe2 dbugshe2 self-assigned this Apr 1, 2026
@vercel

vercel Bot commented Apr 1, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
medbase Ready Ready Preview, 💬 3 unresolved
✅ 25 resolved
Jun 22, 2026 4:44pm

@coderabbitai

coderabbitai Bot commented Apr 1, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Switch fonts and default theme to light, add many client UI primitives, replace many cn import paths, update branding/copy and social links, add dependencies and pnpm build entries, and remove a legacy in-memory toast hook.

Changes

Main cohort

Layer / File(s) Summary
Layout & fonts
app/layout.tsx
Swapped Google font imports to new fonts, changed metadata.openGraph.images[0].url, set ThemeProvider defaultTheme="light", and inserted a <Toaster /> mount inside the provider.
UI primitives & components
components/ui/*, components/*, components/systaliko-ui/*
Added many client UI primitives and helpers (cards, chart toolkit, combobox, dialog, drawer, dropdown, empty/field/input group/select/slider-like primitives, sheet, skeleton, spinner, switch, table, tabs, textarea, tooltip, etc.), plus multiple imports rewired to @/utils/shared-utils for cn.
Branding, copy, and nav
components/logo.tsx, components/icons/insta-icon.tsx, sections/*, components/desktop-nav.tsx, components/mobile-nav.tsx, sections/footer.tsx, sections/header.tsx
Replaced logo SVG, added Instagram icon, updated hero/about/process/values/team/testimonials copy and CTA labels, simplified nav/links/socials to the Medbase Africa branding and adjusted social anchors.
Config & dependencies
package.json, tsconfig.json, components.json
Added several new UI/data deps (@base-ui/react, radix-ui, recharts, sonner, vaul, react-resizable-panels), added pnpm.onlyBuiltDependencies, changed TS JSX to react-jsx, extended include globs, and updated the @/utils alias.
Removed legacy toast hook
hooks/use-toast.ts
Removed the previous in-memory toast hook and its useToast / toast exports.

Sequence Diagram(s)

sequenceDiagram
  participant Layout as app/layout.tsx
  participant Theme as ThemeProvider
  participant ToasterWrap as Toaster (client)
  participant Sonner as sonner.Toaster
  Layout->>Theme: render children
  Theme->>ToasterWrap: mount Toaster inside provider
  ToasterWrap->>Sonner: render Sonner Toaster with resolved theme & icons
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hopped through tokens, OKLCH in tow,
I swapped the fonts and let the lightness show,
A toaster now pops with icons bright and merry,
Old hook tucked away, new paths tidy and airy,
Cheers — a rabbit's nibble of code confetti! 🎉

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

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 and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 12

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

🟡 Minor comments (11)
hooks/use-toast.ts-6-6 (1)

6-6: ⚠️ Potential issue | 🟡 Minor

Verify the toast removal delay value.

TOAST_REMOVE_DELAY = 1000000 is ~16.6 minutes. This is unusually long for a toast notification—typical values are 3,000–10,000ms. If the intent is for toasts to persist until manually dismissed, consider using Infinity or a more descriptive constant name. Otherwise, this may be a typo.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@hooks/use-toast.ts` at line 6, The TOAST_REMOVE_DELAY constant is set to
1000000 (~16.6 minutes), which is likely unintended; confirm the desired
behavior and update TOAST_REMOVE_DELAY in hooks/use-toast.ts accordingly: if
toasts should auto-dismiss set a typical value between 3000 and 10000 (e.g.,
5000), if they should persist until user action use Infinity (or null) and
update any runtime checks, or rename the constant to
TOAST_PERSISTENT/TOAST_AUTO_REMOVE_DELAY to make intent explicit; ensure any
code that reads TOAST_REMOVE_DELAY (e.g., showToast, removeToast timers) handles
the new value correctly.
components/icons/linkedin-icon.tsx-7-7 (1)

7-7: ⚠️ Potential issue | 🟡 Minor

Incorrect accessible label for LinkedIn icon.

Line 7 uses aria-label="website", which does not match the icon meaning.

Suggested fix
-      aria-label="website"
+      aria-label="LinkedIn"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/icons/linkedin-icon.tsx` at line 7, The LinkedIn icon component
uses an incorrect aria-label ("website"); update the accessible label on the
LinkedInIcon component (or the element rendering the SVG/button in
linkedin-icon.tsx) to a descriptive value like "LinkedIn" or "LinkedIn profile"
so screen readers convey the correct purpose; replace aria-label="website" with
the new label and ensure it matches the intent wherever the LinkedInIcon is
rendered.
components/mobile-nav.tsx-29-35 (1)

29-35: ⚠️ Potential issue | 🟡 Minor

Keep the list children as <li> elements.

This inserts a <div> directly under the <ul>, which is invalid list markup and can confuse assistive tech. Wrap the controls in an <li> or move them outside the list.

Suggested fix
-                        <div className="flex flex-col gap-4">
+                        <li className="flex flex-col gap-4">
                             <Button variant={'outline'}>
                                 Book a meeting 
                             </Button>

                             <ModeToggle />
-                        </div>
+                        </li>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/mobile-nav.tsx` around lines 29 - 35, The JSX places a <div>
directly inside a <ul>, which is invalid; replace the <div className="flex
flex-col gap-4"> that wraps Button and ModeToggle with an <li> (you can keep an
inner div for layout if needed) or move that control block entirely outside the
<ul>; update the element wrapping Button and ModeToggle so the list children are
proper <li> elements (target the JSX near Button and ModeToggle in the mobile
navigation component).
components/systaliko-ui/cards/cards-stack.tsx-17-23 (1)

17-23: ⚠️ Potential issue | 🟡 Minor

Spread props before the merged style.

If a caller passes style, Line 23 re-applies that original prop after the merge, so the container loses its default perspective. That makes the style merge here incorrect for any customized usage.

Suggested fix
 export const CardsStackContainer = React.forwardRef<
   HTMLDivElement,
   React.HTMLProps<HTMLDivElement>
->(({ children, className, ...props }, ref) => {
+>(({ children, className, style, ...props }, ref) => {
   return (
     <div
       ref={ref}
+      {...props}
       className={cn('relative w-full', className)}
-      style={{ perspective: '1000px', ...props.style }}
-      {...props}
+      style={{ perspective: '1000px', ...style }}
     >
       {children}
     </div>
   );
 });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/systaliko-ui/cards/cards-stack.tsx` around lines 17 - 23, The
component spreads {...props} after setting style which allows a caller-provided
style to overwrite the default perspective; update the component (the arrow
function receiving ({ children, className, ...props }, ref) in cards-stack.tsx
or the CardsStack wrapper) to either destructure style from props (e.g., const {
style, ...rest } = props) and then render {...rest} before applying style={{
perspective: '1000px', ...style }}, or move {...props} before the style prop so
the merged style retains the default perspective while honoring caller
overrides.
sections/values.tsx-19-26 (1)

19-26: ⚠️ Potential issue | 🟡 Minor

Typo in value ID: value-startegyvalue-strategy.

✏️ Proposed fix
   {
-    id: 'value-startegy',
+    id: 'value-strategy',
     title: 'Strategy first',
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sections/values.tsx` around lines 19 - 26, The value object has a typo in its
id: change the id value 'value-startegy' to 'value-strategy' in the values
array/object (look for the entry with title 'Strategy first' and icon
ListStartIcon) so downstream lookups and keys use the correct spelling; update
only the id string to 'value-strategy' to fix references and keep consistency.
sections/work.tsx-58-66 (1)

58-66: ⚠️ Potential issue | 🟡 Minor

Image alt text should be descriptive.

Using alt="project" for all images is not accessible. Screen reader users won't know what the image depicts. Use descriptive alt text that includes the project name.

♿ Proposed fix
                   <Image
                     className="w-full max-h-full"
                     width={906}
                     height={604}
                     src={project.imageUrl}
-                    alt="project"
+                    alt={`${project.title} project showcase`}
                   />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sections/work.tsx` around lines 58 - 66, The Image usage sets alt="project",
which is not descriptive; update the Image component's alt prop to include the
specific project's name (e.g., use project.name or project.title) and a short
descriptor like "screenshot" or "preview" so screen readers get meaningful
context—locate the Image element that reads src={project.imageUrl} and replace
the hardcoded alt with a descriptive string derived from project (e.g.,
project.name).
sections/services.tsx-6-43 (1)

6-43: ⚠️ Potential issue | 🟡 Minor

Typos in service IDs.

Two IDs contain spelling errors:

  • service-starategy-identity-serviceservice-strategy-identity-service
  • growth-anilytics-servicegrowth-analytics-service
✏️ Proposed fix
   {
-    id: 'service-starategy-identity-service',
+    id: 'service-strategy-identity-service',
     title: 'Brand Strategy & Identity',
   {
-    id: 'growth-anilytics-service',
+    id: 'growth-analytics-service',
     title: 'Growth & Analytics',
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sections/services.tsx` around lines 6 - 43, Update the misspelled id strings
in the SERVICES_CARDS array: change "service-starategy-identity-service" to
"service-strategy-identity-service" and change "growth-anilytics-service" to
"growth-analytics-service" so the unique identifiers in the SERVICE_CARDS
constant match expected naming (locate these values in the SERVICES_CARDS array
to edit the id fields).
sections/values.tsx-67-71 (1)

67-71: ⚠️ Potential issue | 🟡 Minor

Remove the leading hyphen from the gradient class.

The class bg-linear-45 is a valid Tailwind CSS v4 gradient utility for a 45-degree linear gradient. However, the leading hyphen prefix (-bg-linear-45) is incorrect—gradient utilities do not support negation. Change to bg-linear-45.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sections/values.tsx` around lines 67 - 71, The element rendering the icon
uses an incorrect class string with a leading hyphen in the gradient utility;
update the className template in the icon container (the div that currently
contains `className={`size-14 flex items-center justify-center -bg-linear-45
rounded ${value.iconBg}`}`) to remove the hyphen so it uses `bg-linear-45`
instead of `-bg-linear-45` (ensure any dynamic `${value.iconBg}` remains
intact).
sections/work.tsx-43-45 (1)

43-45: ⚠️ Potential issue | 🟡 Minor

Button has no action.

The "Explore all cases" button does nothing when clicked. If the route doesn't exist yet, consider using a disabled state or removing the button until the feature is ready.

Proposed fix to link to a future route
-                    <Button variant={'secondary'}>
+                    <Button variant={'secondary'} asChild>
+                      <Link href="/work">
                         Explore all cases
+                      </Link>
                     </Button>

This assumes the Button component supports asChild prop (common in Radix UI-based components) and requires importing Link from next/link.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sections/work.tsx` around lines 43 - 45, The "Explore all cases" Button in
sections/work.tsx currently has no click action; wrap or render it as a Link to
the target route (e.g., href="/cases") so it navigates, or if the route isn't
ready set the Button to disabled or remove it. Update the Button usage
(component named Button) to support navigation by using its asChild prop and a
next/link Link or by wrapping Button in Link from next/link, and add the href to
point to the intended route (or set disabled={true} and adjust aria-disabled if
removing functionality). Ensure you import Link from next/link and update the
Button element labeled "Explore all cases" accordingly.
sections/testimonials.tsx-77-79 (1)

77-79: ⚠️ Potential issue | 🟡 Minor

Fix broken ARIA references: add id attributes to match aria-labelledby and aria-describedby.

The aria-labelledby and aria-describedby attributes reference IDs like card-${testimonial.id}-title and card-${testimonial.id}-content, but card-testimonial.tsx does not render elements with these IDs. Add id props to the relevant child components or apply the IDs directly to the TestimonialQuote and TestimonialAuthor elements.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sections/testimonials.tsx` around lines 77 - 79, The ARIA attributes on the
card use aria-labelledby={`card-${testimonial.id}-title`} and
aria-describedby={`card-${testimonial.id}-content`} but no matching id
attributes are rendered; update the TestimonialQuote and TestimonialAuthor (or
the child components that render the title/content) to accept and render id
props and pass id={`card-${testimonial.id}-content`} to TestimonialQuote and
id={`card-${testimonial.id}-title`} to TestimonialAuthor (or apply those ids
directly on the elements that output the title and content) so the ARIA
references resolve correctly for each testimonial.
components/systaliko-ui/blocks/scroll-animation.tsx-51-58 (1)

51-58: ⚠️ Potential issue | 🟡 Minor

Document that spacerClass="h-0" disables scroll-driven animations.

The scroll progress is driven by scrolling through the container including the spacer element (default h-96). When spacerClass="h-0" is used (as in sections/process.tsx), the scrollYProgress will not vary meaningfully since there's no scrollable height to track, effectively disabling animations.

If this is intentional for static layouts, consider adding a comment. Otherwise, consumers like sections/process.tsx that use spacerClass="h-0" with ScrollScale expecting animation (inputRange={[0, 0.2]}) will see no animation effect.

🧹 Nitpick comments (15)
hooks/use-toast.ts (1)

155-159: Consider refining the update parameter type.

The update function accepts ToasterToast which requires id, but the implementation overrides id anyway. Use Partial<ToasterToast> to match the UPDATE_TOAST action type and avoid requiring callers to provide an id that gets ignored.

♻️ Suggested improvement
-  const update = (props: ToasterToast) =>
+  const update = (props: Partial<ToasterToast>) =>
     dispatch({
       type: "UPDATE_TOAST",
       toast: { ...props, id },
     });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@hooks/use-toast.ts` around lines 155 - 159, The update function currently
types its parameter as ToasterToast which requires an id that the function then
overrides; change the parameter type to Partial<ToasterToast> (or
Omit<ToasterToast, 'id'>) so callers aren't forced to pass an id that is
ignored, and keep the implementation of update (which spreads props and sets id)
and the dispatch to the "UPDATE_TOAST" action unchanged; update the signature
for the update function in hooks/use-toast.ts to use the new type and ensure
TypeScript no longer errors when callers omit id.
data/data.ts (1)

3-3: Make the site URL deployment-specific.

app/layout.tsx feeds this into metadata/Open Graph, so any non-demo deployment will publish the demo host as its canonical URL. Pull it from env/config instead of hardcoding it here.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@data/data.ts` at line 3, The hardcoded url field in data.ts (the "url"
property) must be replaced with a deployment-specific value read from
environment/config; update data.ts to import or read your runtime config (e.g.,
process.env.NEXT_PUBLIC_SITE_URL or your existing config helper) and set url to
that env value with a sensible fallback (like the demo URL) so app/layout.tsx
continues to get a string but uses the deployment's canonical URL. Ensure the
symbol "url" in the exported data object is updated and that any helper you use
is available at build/runtime.
components/ui/button.tsx (1)

38-55: Default native buttons to type="button".

Without an explicit type, <button> submits the nearest form. This is a shared primitive, so it's safer to opt out unless a caller explicitly requests submit.

💡 Suggested tweak
 function Button({
   className,
   variant,
   size,
   asChild = false,
+  type,
   ...props
 }: React.ComponentProps<"button"> &
   VariantProps<typeof buttonVariants> & {
     asChild?: boolean
   }) {
   const Comp = asChild ? Slot : "button"
 
   return (
     <Comp
       data-slot="button"
       className={cn(buttonVariants({ variant, size, className }))}
+      type={asChild ? undefined : type ?? "button"}
       {...props}
     />
   )
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/ui/button.tsx` around lines 38 - 55, The Button component
currently leaves the native button type unspecified; update Button to default to
type="button" unless a caller passes an explicit type and avoid forcing a type
onto a custom child: destructure type from props with a default (e.g. const {
type = "button", ...rest } = props), and when rendering use <Comp ... { ...(Comp
=== "button" ? { type } : {}) } {...rest} /> (referencing the Button function,
Comp variable, asChild flag and props) so native buttons default to
non-submitting while custom children aren’t given an invalid type prop.
components/logo.tsx (1)

1-6: Consider importing SVGProps explicitly for clarity.

While React.SVGProps<SVGSVGElement> works without an explicit import in this Next.js + TypeScript setup due to ambient type declarations from @types/react, it's clearer to import the type explicitly:

+import type { SVGProps } from "react";
 import { cn } from "@/lib/utils";
 
 export const Logo = ({
   className,
   ...props
-}: React.SVGProps<SVGSVGElement>) => {
+}: SVGProps<SVGSVGElement>) => {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/logo.tsx` around lines 1 - 6, Import the SVGProps type explicitly
from React and update the Logo component signature to use it; specifically, add
an import like "import React, { SVGProps } from 'react'" (or "import type {
SVGProps } from 'react'") and change the prop type on the Logo function from
"React.SVGProps<SVGSVGElement>" to "SVGProps<SVGSVGElement>" so the component
(Logo) uses the explicit SVGProps type for clarity.
sections/values.tsx (2)

7-7: Unused import: stagger from motion.

The stagger function is imported but not used in this file. ContainerStagger likely handles staggering internally.

🧹 Proposed fix
-import { stagger } from 'motion';
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sections/values.tsx` at line 7, The import of stagger from 'motion' is unused
in sections/values.tsx; remove the unused import statement (the symbol stagger)
and rely on ContainerStagger for staggering behavior to eliminate the
unused-import lint warning and dead code.

50-50: "Request demo" button should be a link.

A Button with variant="link" that performs navigation should use an anchor element for proper accessibility and SEO. Consider wrapping with Link or using the asChild pattern.

♿ Proposed fix
-          <Button variant={'link'}>Request demo</Button>
+          <Button variant={'link'} asChild>
+            <Link href="/contact">Request demo</Link>
+          </Button>

Requires importing Link from next/link.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sections/values.tsx` at line 50, The "Request demo" Button currently uses
variant="link" but must be rendered as an actual anchor for accessibility/SEO;
import Link from next/link and replace the Button usage so it renders an <a>
with an href (either wrap <Button variant="link"> with <Link
href="/your-path">...</Link> or use the UI library's asChild pattern like
<Button asChild> and place <Link href="/your-path">Request demo</Link> inside);
update the Button call in sections/values.tsx (the Button component) to ensure
the href is provided and the element rendered is an anchor.
app/(home)/page.tsx (1)

1-21: Work section is defined but not rendered.

The sections/work.tsx component exists in this PR but is not imported or rendered in the home page. If this is intentional (e.g., work-in-progress), consider adding a comment or removing the file until it's ready to avoid dead code.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/`(home)/page.tsx around lines 1 - 21, The Home page currently doesn't
render the Work section defined in sections/work.tsx; either import the Work
component and add <Work /> into the Home component JSX (e.g., alongside
Hero/About/Values/etc.) to display it, or if the work component is intentionally
not ready, remove sections/work.tsx or add a clear TODO comment near the Work
component export to avoid dead code; reference the Work component in
sections/work.tsx and the Home function in app/(home)/page.tsx to locate where
to change.
sections/services.tsx (2)

45-72: Services section lacks a visible heading.

Unlike other sections (About, Work, Values), this section has no <h2> or section title. Adding a heading improves accessibility (screen reader navigation) and provides context for users.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sections/services.tsx` around lines 45 - 72, The Services component is
missing a visible section heading which harms accessibility; add a semantic
heading (e.g., an <h2> with appropriate text like "Services") inside the
Services() return, placed before the CardsStackContainer so screen readers and
users can identify the section; ensure the heading uses the same styling pattern
as other sections (matching size/utility classes used elsewhere) and keep it
outside each CardSticky so it appears once for the whole SERVICES_CARDS list.

53-54: Remove commented-out code.

The commented className is dead code. Either use it or remove it to keep the codebase clean.

🧹 Proposed fix
           <CardSticky
             key={service.id}
             index={index}
-            // className="min-h-[50vh] py-8 px-12 flex flex-wrap md:flex-nowrap md:gap-8 justify-between items-start even:border bg-card odd:bg-muted"
             className="min-h-[50vh] py-8 px-12 flex gap-6 justify-between flex-wrap even:border bg-card odd:bg-muted"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sections/services.tsx` around lines 53 - 54, Remove the dead commented-out
className in sections/services.tsx: delete the line starting with "//
className="min-h-[50vh] py-8 px-12 flex flex-wrap md:flex-nowrap md:gap-8
justify-between items-start even:border bg-card odd:bg-muted"" so only the
active className remains (className="min-h-[50vh] py-8 px-12 flex gap-6
justify-between flex-wrap even:border bg-card odd:bg-muted"); no behavioral
changes required, just remove the commented code to keep the file clean.
sections/footer.tsx (1)

25-42: Consider consolidating navigation links with data/constants.ts.

The footer defines its own LINKS array while data/constants.ts has NAV_LINKS with the same labels but placeholder href: '/' values. Consider using a single source of truth for navigation links to prevent inconsistencies.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sections/footer.tsx` around lines 25 - 42, The footer has a duplicated LINKS
constant that conflicts with the canonical NAV_LINKS; remove the local LINKS in
the footer and import NAV_LINKS from data/constants instead, or update NAV_LINKS
to include the correct href values and then reference NAV_LINKS inside the
Footer component (replace occurrences of LINKS with NAV_LINKS) so there is a
single source of truth for navigation links.
sections/header.tsx (1)

14-19: Add accessible name to the logo link.

The logo link contains only visual elements (icon and text) but lacks an accessible name for screen readers. Consider adding an aria-label to clarify the link's purpose.

♿ Proposed fix
-          <Link className="flex-grow-[1] inline-flex items-center gap-1" href="/">
+          <Link className="grow inline-flex items-center gap-1" href="/" aria-label="Veo - Go to homepage">
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sections/header.tsx` around lines 14 - 19, The logo Link currently lacks an
accessible name for screen readers; update the Link element (the wrapping Link
that contains the Logo component and the "Veo" span) to include an appropriate
aria-label (e.g., aria-label="Veo homepage" or "Go to Veo homepage") so
assistive technologies can announce its purpose; ensure the aria-label is on the
Link component (not the inner Logo) and keep the visible text unchanged.
components/systaliko-ui/cards/cards-stack-rotated.tsx (1)

69-69: Remove unused containerRef.

The ref is created but never used for any purpose.

🧹 Remove dead code
 export const CardsContainer: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({
   children,
   className,
   ...props
 }) => {
-  const containerRef = React.useRef<HTMLDivElement>(null);
-
   return (
     <div
-      ref={containerRef}
       className={cn('sticky top-0 left-0', className)}
       style={{ perspective: '1000px', ...props.style }}
       {...props}
     >
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/systaliko-ui/cards/cards-stack-rotated.tsx` at line 69, Remove the
unused ref by deleting the declaration of containerRef (const containerRef =
React.useRef<HTMLDivElement>(null)); in the CardsStackRotated component so there
is no dead code left; search for "containerRef" to ensure it's not referenced
elsewhere and remove any related unused imports if they become unnecessary.
components/systaliko-ui/blocks/scroll-animation.tsx (2)

106-111: Use more specific types instead of unknown[].

The range props use unknown[] which bypasses type safety. Since these are used with useTransform, they should be typed more specifically.

💡 Suggested typing improvement
 }: HTMLMotionProps<'div'> & {
   inputRange?: MapInputRange;
-  insetRangeY?: unknown[];
-  insetXRange?: unknown[];
-  roundednessRange?: unknown[];
+  insetRangeY?: number[];
+  insetXRange?: number[];
+  roundednessRange?: number[];
 }) {

Apply similar changes to other components using unknown[] (lines 137, 155, 173, 191-192).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/systaliko-ui/blocks/scroll-animation.tsx` around lines 106 - 111,
The props insetRangeY, insetXRange, and roundednessRange are typed as unknown[]
which removes type safety; change their types to more specific arrays (e.g.,
number[] or (number | string)[] as appropriate for values passed into
useTransform) and update the component signature (the function in
scroll-animation.tsx with props inputRange, insetRangeY, insetXRange,
roundednessRange) to use those concrete types; then adjust any usages/calls to
useTransform inside this component to match the new types and apply the same
replacement for other occurrences noted (the other components/lines referenced
in the review).

196-203: layout without "position" may cause unexpected layout animations.

Using layout (which equals layout={true}) animates both position and size changes. If only position animations are intended (as in other components like CardTransformed), use layout="position" to prevent unwanted size animations.

Also, willChange: 'border-radius' is non-standard. The correct value would be 'border-radius' in some browsers, but for better compatibility use 'auto' or remove it since borderRadius changes aren't typically performance-critical.

💡 Suggested fix
   return (
     <motion.div
-      layout
+      layout="position"
       className={className}
-      style={{ borderRadius, willChange: 'border-radius', ...style }}
+      style={{ borderRadius, ...style }}
       {...props}
     />
   );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/systaliko-ui/blocks/scroll-animation.tsx` around lines 196 - 203,
The motion.div in ScrollAnimation currently uses layout (i.e., layout={true})
and a nonstandard willChange value; change layout to layout="position" on the
motion.div to restrict animations to position-only (avoid unintended size/scale
animations), and remove or replace the willChange: 'border-radius' in the style
(either remove the willChange entry or use a more compatible value like 'auto'
if needed) while preserving borderRadius, className and spreading ...props as
before.
app/layout.tsx (1)

32-39: Consider deriving OG image URL from data.url for consistency.

The metadata uses data.url for the OpenGraph URL but hardcodes the image URL to 'https://veo.vercel.app/og-image.png'. If the deployment URL changes, this could lead to inconsistency.

💡 Suggested improvement
     images: [
       {
-        url: 'https://veo.vercel.app/og-image.png',
+        url: `${data.url}/og-image.png`,
         width: 1200,
         height: 630,
         alt: data.name,
       },
     ],
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/layout.tsx` around lines 32 - 39, The OG image URL is hardcoded instead
of being derived from data.url, causing potential deployment inconsistencies;
update the metadata construction that builds the images array (images[0].url) to
derive the image URL from data.url (e.g., use URL resolution or string join like
new URL('/og-image.png', data.url).toString() or `${data.url.replace(/\/$/,
'')}/og-image.png`) so the image host matches the site URL; locate the images
array in the metadata block where data.name and data.url are used and replace
the literal 'https://veo.vercel.app/og-image.png' with the derived URL
expression.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@components/desktop-nav.tsx`:
- Around line 22-25: The "Book a meeting" Button currently renders without an
action; update the Button element in components/desktop-nav.tsx (and mirror the
same change in components/mobile-nav.tsx) to provide a real action: either add
an href prop to navigate to your scheduling page (e.g., "/book" or your external
scheduler URL) or attach an onClick handler that opens the scheduling URL in a
new tab or triggers the booking modal (call the existing openBookingModal or
navigate function if available). Ensure you use the same Button component API
(e.g., onClick or href) so the CTA is keyboard-accessible and works the same in
both DesktopNav and MobileNav.
- Around line 12-16: NAV_LINKS currently contains identical hrefs ('/'), causing
all nav items to route to the homepage and breaking both desktop and mobile
navigation; update the NAV_LINKS entries (the array referenced by NAV_LINKS used
in components/desktop-nav.tsx and mobile nav) so each object has a distinct href
that matches the intended destination (e.g., '/about', '/services', '/pricing'
or '#about', '#services', '#pricing' for anchors), then ensure the Link usage in
the desktop NavLink mapping continues to use link.href and link.label as before
so each <Link> points to the new unique hrefs.

In `@components/systaliko-ui/cards/card-testimonial.tsx`:
- Line 55: The Card in card-testimonial.tsx is passing a precomputed className
via cn(cardVariants({ variant, className })) which duplicates the styling
because Card itself calls cardVariants; instead, remove the call to cardVariants
and pass the variant and className props directly to Card (i.e., use <Card
variant={variant} className={className} ...>) so Card can apply cardVariants
internally; update the Card invocation in
components/systaliko-ui/cards/card-testimonial.tsx accordingly and remove
cn(cardVariants(...)) usage.

In `@components/systaliko-ui/cards/cards-stack-rotated.tsx`:
- Line 74: The CSS class string passed into cn in the CardsStackRotated
component contains a typo: change the 'stiky' token in the className expression
(className={cn('stiky top-0 left-0', className)}) to 'sticky' so the sticky
positioning works; update the string used in that className call accordingly.
- Around line 88-98: The destructured prop default incrementRotation = -index +
90 references index during parameter defaulting which is confusing and fragile;
move the derived rotation calculation into the component body instead of using a
parameter default that depends on another parameter (or if you intended a static
default, set incrementRotation to a constant like 0). Locate the component that
destructures { arrayLength, index, incrementY, incrementZ, incrementRotation,
... } (the props block in cards-stack-rotated.tsx), remove the computed default
from the parameter list, and compute a local value (e.g., const computedRotation
= incrementRotation ?? (-index + 90)) inside the function before using it.

In `@components/systaliko-ui/rating-stars.tsx`:
- Around line 14-17: Clamp the incoming rating value to the valid range [0,
maxRating] before computing filledStars, fractionalPart, and emptyStars to avoid
negative counts and Array(...) crashes; e.g., compute a local clampedRating =
Math.max(0, Math.min(rating, maxRating)) and use clampedRating in the existing
calculations (filledStars, fractionalPart, emptyStars) and any other places that
derive star counts (also update the other occurrence around the code mentioned
at lines 59-60).
- Around line 41-56: The gradient id "half" is global and will collide across
instances; update the RatingStars component to generate a unique gradient id per
instance (e.g., using React's useId() or a useRef-based unique string) and
replace id="half" with that unique id and the fill="url(`#half`)" with the
matching fill using the same unique id (e.g., fill={`url(#${uniqueId})`}) so
each rendered star uses its own gradient.

In `@data/constants.ts`:
- Around line 6-16: The navigation entries for labels 'About', 'Services', and
'Pricing' currently all use href: '/'—update each object's href so they point to
the correct destinations (e.g., '/about' or '#about', '/services' or
'#services', '/pricing' or '#pricing' depending on your routing/anchor scheme)
by locating the array of link objects (the ones with label: 'About', label:
'Services', label: 'Pricing') in data/constants.ts and replacing their href
values with the intended paths.

In `@hooks/use-toast.ts`:
- Around line 189-197: The useEffect subscribing the toast listener currently
lists [state] as a dependency which causes repeated unsubscribe/resubscribe on
every state change; update the effect in the hook where React.useEffect adds
listeners.push(setState) and removes it on cleanup to use an empty dependency
array ([]) so the listener is added once on mount and removed on unmount (keep
references to listeners and setState as-is).

In `@sections/footer.tsx`:
- Around line 53-64: The JSX currently nests an <a> inside the Button created
for each SOCIAL_LINKS entry (map over SOCIAL_LINKS using link.id, link.href,
link.icon), producing invalid HTML; change the Button to render as an anchor
using its asChild prop (so Button wraps the anchor element or is rendered as an
<a>) and move href to the rendered anchor (use link.href), add target="_blank"
and rel="noopener noreferrer" for external links, and ensure each icon-only link
has an accessible name by adding an aria-label (e.g., from link.label or
similar) when rendering the icon inside Button/asChild.

In `@sections/hero.tsx`:
- Around line 18-21: The external anchor that opens in a new tab (the <a>
element pointing to "https://systaliko-ui.vercel.app/docs/templates/veo") is
missing rel attributes; update that anchor to include rel="noopener noreferrer"
to prevent tabnabbing and protect the opener, ensuring the element that
currently uses target="_blank" also includes rel="noopener noreferrer".

In `@sections/testimonials.tsx`:
- Around line 63-66: The card is being passed a shifted index (index={index +
2}) which breaks the stacking/transform math and can produce negative z-index or
invalid scroll ranges; change the prop to use the actual zero-based index
(index={index}) wherever the Card (or the component receiving index) relies on
TESTIMONIALS.length for stacking calculations (look for usages of index in the
card transform/z-index/scroll math) and update any dependent arithmetic if you
intentionally need an offset so all z-index/transform calculations remain
consistent with TESTIMONIALS.length and zero-based indexing.

---

Minor comments:
In `@components/icons/linkedin-icon.tsx`:
- Line 7: The LinkedIn icon component uses an incorrect aria-label ("website");
update the accessible label on the LinkedInIcon component (or the element
rendering the SVG/button in linkedin-icon.tsx) to a descriptive value like
"LinkedIn" or "LinkedIn profile" so screen readers convey the correct purpose;
replace aria-label="website" with the new label and ensure it matches the intent
wherever the LinkedInIcon is rendered.

In `@components/mobile-nav.tsx`:
- Around line 29-35: The JSX places a <div> directly inside a <ul>, which is
invalid; replace the <div className="flex flex-col gap-4"> that wraps Button and
ModeToggle with an <li> (you can keep an inner div for layout if needed) or move
that control block entirely outside the <ul>; update the element wrapping Button
and ModeToggle so the list children are proper <li> elements (target the JSX
near Button and ModeToggle in the mobile navigation component).

In `@components/systaliko-ui/cards/cards-stack.tsx`:
- Around line 17-23: The component spreads {...props} after setting style which
allows a caller-provided style to overwrite the default perspective; update the
component (the arrow function receiving ({ children, className, ...props }, ref)
in cards-stack.tsx or the CardsStack wrapper) to either destructure style from
props (e.g., const { style, ...rest } = props) and then render {...rest} before
applying style={{ perspective: '1000px', ...style }}, or move {...props} before
the style prop so the merged style retains the default perspective while
honoring caller overrides.

In `@hooks/use-toast.ts`:
- Line 6: The TOAST_REMOVE_DELAY constant is set to 1000000 (~16.6 minutes),
which is likely unintended; confirm the desired behavior and update
TOAST_REMOVE_DELAY in hooks/use-toast.ts accordingly: if toasts should
auto-dismiss set a typical value between 3000 and 10000 (e.g., 5000), if they
should persist until user action use Infinity (or null) and update any runtime
checks, or rename the constant to TOAST_PERSISTENT/TOAST_AUTO_REMOVE_DELAY to
make intent explicit; ensure any code that reads TOAST_REMOVE_DELAY (e.g.,
showToast, removeToast timers) handles the new value correctly.

In `@sections/services.tsx`:
- Around line 6-43: Update the misspelled id strings in the SERVICES_CARDS
array: change "service-starategy-identity-service" to
"service-strategy-identity-service" and change "growth-anilytics-service" to
"growth-analytics-service" so the unique identifiers in the SERVICE_CARDS
constant match expected naming (locate these values in the SERVICES_CARDS array
to edit the id fields).

In `@sections/testimonials.tsx`:
- Around line 77-79: The ARIA attributes on the card use
aria-labelledby={`card-${testimonial.id}-title`} and
aria-describedby={`card-${testimonial.id}-content`} but no matching id
attributes are rendered; update the TestimonialQuote and TestimonialAuthor (or
the child components that render the title/content) to accept and render id
props and pass id={`card-${testimonial.id}-content`} to TestimonialQuote and
id={`card-${testimonial.id}-title`} to TestimonialAuthor (or apply those ids
directly on the elements that output the title and content) so the ARIA
references resolve correctly for each testimonial.

In `@sections/values.tsx`:
- Around line 19-26: The value object has a typo in its id: change the id value
'value-startegy' to 'value-strategy' in the values array/object (look for the
entry with title 'Strategy first' and icon ListStartIcon) so downstream lookups
and keys use the correct spelling; update only the id string to 'value-strategy'
to fix references and keep consistency.
- Around line 67-71: The element rendering the icon uses an incorrect class
string with a leading hyphen in the gradient utility; update the className
template in the icon container (the div that currently contains
`className={`size-14 flex items-center justify-center -bg-linear-45 rounded
${value.iconBg}`}`) to remove the hyphen so it uses `bg-linear-45` instead of
`-bg-linear-45` (ensure any dynamic `${value.iconBg}` remains intact).

In `@sections/work.tsx`:
- Around line 58-66: The Image usage sets alt="project", which is not
descriptive; update the Image component's alt prop to include the specific
project's name (e.g., use project.name or project.title) and a short descriptor
like "screenshot" or "preview" so screen readers get meaningful context—locate
the Image element that reads src={project.imageUrl} and replace the hardcoded
alt with a descriptive string derived from project (e.g., project.name).
- Around line 43-45: The "Explore all cases" Button in sections/work.tsx
currently has no click action; wrap or render it as a Link to the target route
(e.g., href="/cases") so it navigates, or if the route isn't ready set the
Button to disabled or remove it. Update the Button usage (component named
Button) to support navigation by using its asChild prop and a next/link Link or
by wrapping Button in Link from next/link, and add the href to point to the
intended route (or set disabled={true} and adjust aria-disabled if removing
functionality). Ensure you import Link from next/link and update the Button
element labeled "Explore all cases" accordingly.

---

Nitpick comments:
In `@app/`(home)/page.tsx:
- Around line 1-21: The Home page currently doesn't render the Work section
defined in sections/work.tsx; either import the Work component and add <Work />
into the Home component JSX (e.g., alongside Hero/About/Values/etc.) to display
it, or if the work component is intentionally not ready, remove
sections/work.tsx or add a clear TODO comment near the Work component export to
avoid dead code; reference the Work component in sections/work.tsx and the Home
function in app/(home)/page.tsx to locate where to change.

In `@app/layout.tsx`:
- Around line 32-39: The OG image URL is hardcoded instead of being derived from
data.url, causing potential deployment inconsistencies; update the metadata
construction that builds the images array (images[0].url) to derive the image
URL from data.url (e.g., use URL resolution or string join like new
URL('/og-image.png', data.url).toString() or `${data.url.replace(/\/$/,
'')}/og-image.png`) so the image host matches the site URL; locate the images
array in the metadata block where data.name and data.url are used and replace
the literal 'https://veo.vercel.app/og-image.png' with the derived URL
expression.

In `@components/logo.tsx`:
- Around line 1-6: Import the SVGProps type explicitly from React and update the
Logo component signature to use it; specifically, add an import like "import
React, { SVGProps } from 'react'" (or "import type { SVGProps } from 'react'")
and change the prop type on the Logo function from
"React.SVGProps<SVGSVGElement>" to "SVGProps<SVGSVGElement>" so the component
(Logo) uses the explicit SVGProps type for clarity.

In `@components/systaliko-ui/blocks/scroll-animation.tsx`:
- Around line 106-111: The props insetRangeY, insetXRange, and roundednessRange
are typed as unknown[] which removes type safety; change their types to more
specific arrays (e.g., number[] or (number | string)[] as appropriate for values
passed into useTransform) and update the component signature (the function in
scroll-animation.tsx with props inputRange, insetRangeY, insetXRange,
roundednessRange) to use those concrete types; then adjust any usages/calls to
useTransform inside this component to match the new types and apply the same
replacement for other occurrences noted (the other components/lines referenced
in the review).
- Around line 196-203: The motion.div in ScrollAnimation currently uses layout
(i.e., layout={true}) and a nonstandard willChange value; change layout to
layout="position" on the motion.div to restrict animations to position-only
(avoid unintended size/scale animations), and remove or replace the willChange:
'border-radius' in the style (either remove the willChange entry or use a more
compatible value like 'auto' if needed) while preserving borderRadius, className
and spreading ...props as before.

In `@components/systaliko-ui/cards/cards-stack-rotated.tsx`:
- Line 69: Remove the unused ref by deleting the declaration of containerRef
(const containerRef = React.useRef<HTMLDivElement>(null)); in the
CardsStackRotated component so there is no dead code left; search for
"containerRef" to ensure it's not referenced elsewhere and remove any related
unused imports if they become unnecessary.

In `@components/ui/button.tsx`:
- Around line 38-55: The Button component currently leaves the native button
type unspecified; update Button to default to type="button" unless a caller
passes an explicit type and avoid forcing a type onto a custom child:
destructure type from props with a default (e.g. const { type = "button",
...rest } = props), and when rendering use <Comp ... { ...(Comp === "button" ? {
type } : {}) } {...rest} /> (referencing the Button function, Comp variable,
asChild flag and props) so native buttons default to non-submitting while custom
children aren’t given an invalid type prop.

In `@data/data.ts`:
- Line 3: The hardcoded url field in data.ts (the "url" property) must be
replaced with a deployment-specific value read from environment/config; update
data.ts to import or read your runtime config (e.g.,
process.env.NEXT_PUBLIC_SITE_URL or your existing config helper) and set url to
that env value with a sensible fallback (like the demo URL) so app/layout.tsx
continues to get a string but uses the deployment's canonical URL. Ensure the
symbol "url" in the exported data object is updated and that any helper you use
is available at build/runtime.

In `@hooks/use-toast.ts`:
- Around line 155-159: The update function currently types its parameter as
ToasterToast which requires an id that the function then overrides; change the
parameter type to Partial<ToasterToast> (or Omit<ToasterToast, 'id'>) so callers
aren't forced to pass an id that is ignored, and keep the implementation of
update (which spreads props and sets id) and the dispatch to the "UPDATE_TOAST"
action unchanged; update the signature for the update function in
hooks/use-toast.ts to use the new type and ensure TypeScript no longer errors
when callers omit id.

In `@sections/footer.tsx`:
- Around line 25-42: The footer has a duplicated LINKS constant that conflicts
with the canonical NAV_LINKS; remove the local LINKS in the footer and import
NAV_LINKS from data/constants instead, or update NAV_LINKS to include the
correct href values and then reference NAV_LINKS inside the Footer component
(replace occurrences of LINKS with NAV_LINKS) so there is a single source of
truth for navigation links.

In `@sections/header.tsx`:
- Around line 14-19: The logo Link currently lacks an accessible name for screen
readers; update the Link element (the wrapping Link that contains the Logo
component and the "Veo" span) to include an appropriate aria-label (e.g.,
aria-label="Veo homepage" or "Go to Veo homepage") so assistive technologies can
announce its purpose; ensure the aria-label is on the Link component (not the
inner Logo) and keep the visible text unchanged.

In `@sections/services.tsx`:
- Around line 45-72: The Services component is missing a visible section heading
which harms accessibility; add a semantic heading (e.g., an <h2> with
appropriate text like "Services") inside the Services() return, placed before
the CardsStackContainer so screen readers and users can identify the section;
ensure the heading uses the same styling pattern as other sections (matching
size/utility classes used elsewhere) and keep it outside each CardSticky so it
appears once for the whole SERVICES_CARDS list.
- Around line 53-54: Remove the dead commented-out className in
sections/services.tsx: delete the line starting with "// className="min-h-[50vh]
py-8 px-12 flex flex-wrap md:flex-nowrap md:gap-8 justify-between items-start
even:border bg-card odd:bg-muted"" so only the active className remains
(className="min-h-[50vh] py-8 px-12 flex gap-6 justify-between flex-wrap
even:border bg-card odd:bg-muted"); no behavioral changes required, just remove
the commented code to keep the file clean.

In `@sections/values.tsx`:
- Line 7: The import of stagger from 'motion' is unused in sections/values.tsx;
remove the unused import statement (the symbol stagger) and rely on
ContainerStagger for staggering behavior to eliminate the unused-import lint
warning and dead code.
- Line 50: The "Request demo" Button currently uses variant="link" but must be
rendered as an actual anchor for accessibility/SEO; import Link from next/link
and replace the Button usage so it renders an <a> with an href (either wrap
<Button variant="link"> with <Link href="/your-path">...</Link> or use the UI
library's asChild pattern like <Button asChild> and place <Link
href="/your-path">Request demo</Link> inside); update the Button call in
sections/values.tsx (the Button component) to ensure the href is provided and
the element rendered is an anchor.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a68ed6dd-a3f5-4bc8-bf19-048c46560faf

📥 Commits

Reviewing files that changed from the base of the PR and between 6d6f1f8 and b5acba9.

⛔ Files ignored due to path filters (7)
  • app/favicon.ico is excluded by !**/*.ico
  • package-lock.json is excluded by !**/package-lock.json
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • public/images/bg_01.png is excluded by !**/*.png
  • public/images/medbase-coming-soon.jpg is excluded by !**/*.jpg
  • public/images/shapes.svg is excluded by !**/*.svg
  • public/images/xera.svg is excluded by !**/*.svg
📒 Files selected for processing (52)
  • .gitignore
  • app/(home)/page.tsx
  • app/globals.css
  • app/layout.tsx
  • app/not-found.tsx
  • app/page.tsx
  • components.json
  • components/LightRays.css
  • components/LightRays.jsx
  • components/SplashCursor.jsx
  • components/desktop-nav.tsx
  • components/icons/github-icon.tsx
  • components/icons/linkedin-icon.tsx
  • components/icons/x-icon.tsx
  • components/logo.tsx
  • components/mobile-nav.tsx
  • components/mode-toggle.tsx
  • components/systaliko-ui/blocks/container-stagger.tsx
  • components/systaliko-ui/blocks/scroll-animation.tsx
  • components/systaliko-ui/cards/card-testimonial.tsx
  • components/systaliko-ui/cards/card.tsx
  • components/systaliko-ui/cards/cards-stack-rotated.tsx
  • components/systaliko-ui/cards/cards-stack.tsx
  • components/systaliko-ui/rating-stars.tsx
  • components/systaliko-ui/text/text-stagger-inview.tsx
  • components/systaliko-ui/utils/animation-variants.tsx
  • components/systaliko-ui/utils/transitions.tsx
  • components/ui/avatar.tsx
  • components/ui/badge.tsx
  • components/ui/button.tsx
  • components/ui/popover.tsx
  • data/constants.ts
  • data/data.ts
  • eslint.config.mjs
  • hooks/use-toast.ts
  • next.config.ts
  • package.json
  • postcss.config.mjs
  • prettier.config.js
  • providers/route-provider.tsx
  • providers/theme-provider.tsx
  • sections/about.tsx
  • sections/footer.tsx
  • sections/header.tsx
  • sections/hero.tsx
  • sections/process.tsx
  • sections/services.tsx
  • sections/team.tsx
  • sections/testimonials.tsx
  • sections/values.tsx
  • sections/work.tsx
  • tsconfig.json
💤 Files with no reviewable changes (6)
  • components/LightRays.css
  • providers/route-provider.tsx
  • app/not-found.tsx
  • app/page.tsx
  • components/LightRays.jsx
  • components/SplashCursor.jsx

Comment thread components/desktop-nav.tsx
Comment on lines +22 to +25
<div className="flex gap-4 items-center">
<Button variant={'outline'}>
Book a meeting
</Button>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Wire the “Book a meeting” CTA to a real action.

This renders as a primary interactive control but has no href or onClick, so users get a dead CTA. The same placeholder appears in components/mobile-nav.tsx, so both entry points should be hooked up before release.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/desktop-nav.tsx` around lines 22 - 25, The "Book a meeting" Button
currently renders without an action; update the Button element in
components/desktop-nav.tsx (and mirror the same change in
components/mobile-nav.tsx) to provide a real action: either add an href prop to
navigate to your scheduling page (e.g., "/book" or your external scheduler URL)
or attach an onClick handler that opens the scheduling URL in a new tab or
triggers the booking modal (call the existing openBookingModal or navigate
function if available). Ensure you use the same Button component API (e.g.,
onClick or href) so the CTA is keyboard-accessible and works the same in both
DesktopNav and MobileNav.

<CardTestimonialContext.Provider
value={{ testimonialQuote, testimonialAuthor, testimonialRating }}
>
<Card className={cn(cardVariants({ variant, className }))} {...props}>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Bug: Double application of cardVariants.

Looking at the Card component in components/systaliko-ui/cards/card.tsx (lines 20-31), it already applies cardVariants({ variant, className }) internally. Here, you're pre-applying cardVariants to the className before passing it to Card, which will then apply cardVariants again, resulting in duplicated styles.

🐛 Fix by passing variant and className directly to Card
-      <Card className={cn(cardVariants({ variant, className }))} {...props}>
+      <Card variant={variant} className={className} {...props}>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Card className={cn(cardVariants({ variant, className }))} {...props}>
<Card variant={variant} className={className} {...props}>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/systaliko-ui/cards/card-testimonial.tsx` at line 55, The Card in
card-testimonial.tsx is passing a precomputed className via cn(cardVariants({
variant, className })) which duplicates the styling because Card itself calls
cardVariants; instead, remove the call to cardVariants and pass the variant and
className props directly to Card (i.e., use <Card variant={variant}
className={className} ...>) so Card can apply cardVariants internally; update
the Card invocation in components/systaliko-ui/cards/card-testimonial.tsx
accordingly and remove cn(cardVariants(...)) usage.

return (
<div
ref={containerRef}
className={cn('stiky top-0 left-0', className)}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Typo: stiky should be sticky.

This CSS class typo will prevent the sticky positioning from working.

🐛 Fix typo
-      className={cn('stiky top-0 left-0', className)}
+      className={cn('sticky top-0 left-0', className)}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
className={cn('stiky top-0 left-0', className)}
className={cn('sticky top-0 left-0', className)}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/systaliko-ui/cards/cards-stack-rotated.tsx` at line 74, The CSS
class string passed into cn in the CardsStackRotated component contains a typo:
change the 'stiky' token in the className expression (className={cn('stiky top-0
left-0', className)}) to 'sticky' so the sticky positioning works; update the
string used in that className call accordingly.

Comment on lines +88 to +98
(
{
arrayLength,
index,
incrementY = 10,
incrementZ = 10,
incrementRotation = -index + 90,
className,
style,
...props
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Critical: Default parameter references itself causing incorrect behavior.

The default value for incrementRotation is -index + 90, but index is being used in its own destructuring default assignment. In JavaScript, default parameter values are evaluated left-to-right, so index is available here, but this creates a confusing pattern where the default depends on the parameter itself. This means every card will have a different default rotation based on its index, which may be intentional but is unusual for a "default" value.

If intended, consider computing this inside the function body for clarity. If not intended, this should be a static default.

🔧 Suggested fix if rotation should be computed from index
   (
     {
       arrayLength,
       index,
       incrementY = 10,
       incrementZ = 10,
-      incrementRotation = -index + 90,
+      incrementRotation,
       className,
       style,
       ...props
     },
     ref,
   ) => {
+    const rotation = incrementRotation ?? (-index + 90);
     const { scrollYProgress } = useContainerScrollContext();

     const start = index / (arrayLength + 1);
     const end = (index + 1) / (arrayLength + 1);
     const range = React.useMemo(() => [start, end], [start, end]);
     const rotateRange = [range[0] - 1.5, range[1] / 1.5];

     const y = useTransform(scrollYProgress, range, ['0%', '-180%']);
-    const rotate = useTransform(scrollYProgress, rotateRange, [
-      incrementRotation,
-      0,
-    ]);
+    const rotate = useTransform(scrollYProgress, rotateRange, [rotation, 0]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/systaliko-ui/cards/cards-stack-rotated.tsx` around lines 88 - 98,
The destructured prop default incrementRotation = -index + 90 references index
during parameter defaulting which is confusing and fragile; move the derived
rotation calculation into the component body instead of using a parameter
default that depends on another parameter (or if you intended a static default,
set incrementRotation to a constant like 0). Locate the component that
destructures { arrayLength, index, incrementY, incrementZ, incrementRotation,
... } (the props block in cards-stack-rotated.tsx), remove the computed default
from the parameter list, and compute a local value (e.g., const computedRotation
= incrementRotation ?? (-index + 90)) inside the function before using it.

Comment thread data/constants.ts Outdated
Comment on lines +6 to +16
{
label: 'About',
href: '/',
},
{
label: 'Services',
href: '/',
},
{
label: 'Pricing',
href: '/',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Navigation links all resolve to the same destination.

Line 8, Line 12, and Line 16 currently point to '/', so “About”, “Services”, and “Pricing” don’t navigate to their intended sections.

Suggested fix
 export const NAV_LINKS = [
     {
         label: 'Home',
         href: '/',
     },
     {
         label: 'About',
-        href: '/',
+        href: '/#about',
     },
     {
         label: 'Services',
-        href: '/',
+        href: '/#services',
     },
     {
         label: 'Pricing',
-        href: '/',
+        href: '/#pricing',
     }
 ]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{
label: 'About',
href: '/',
},
{
label: 'Services',
href: '/',
},
{
label: 'Pricing',
href: '/',
export const NAV_LINKS = [
{
label: 'Home',
href: '/',
},
{
label: 'About',
href: '/#about',
},
{
label: 'Services',
href: '/#services',
},
{
label: 'Pricing',
href: '/#pricing',
}
]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@data/constants.ts` around lines 6 - 16, The navigation entries for labels
'About', 'Services', and 'Pricing' currently all use href: '/'—update each
object's href so they point to the correct destinations (e.g., '/about' or
'#about', '/services' or '#services', '/pricing' or '#pricing' depending on your
routing/anchor scheme) by locating the array of link objects (the ones with
label: 'About', label: 'Services', label: 'Pricing') in data/constants.ts and
replacing their href values with the intended paths.

Comment thread hooks/use-toast.ts Outdated
Comment thread sections/footer.tsx
Comment thread sections/hero.tsx Outdated
Comment thread sections/testimonials.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/globals.css`:
- Around line 38-40: Stylelint is failing on the custom property font values and
an extra blank line before the body declaration: update the font token values so
generic family keywords are lowercase (e.g., keep "Inter" / "Georgia" /
"JetBrains Mono" as-is for the named fonts but change the generic keywords to
"sans-serif", "serif", "monospace" in the --font-sans, --font-serif, and
--font-mono declarations) and remove the stray empty line before the body
selector (or adjust to match your project's declaration-empty-line-before rule)
so the body declaration spacing passes linting.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 97971b22-468a-4a34-b5b5-0479734366c4

📥 Commits

Reviewing files that changed from the base of the PR and between b5acba9 and 023f88c.

📒 Files selected for processing (5)
  • app/(home)/page.tsx
  • app/globals.css
  • app/layout.tsx
  • package.json
  • tsconfig.json
✅ Files skipped from review due to trivial changes (3)
  • app/(home)/page.tsx
  • package.json
  • tsconfig.json

Comment thread app/globals.css
Comment on lines +38 to +40
--font-sans: Inter, system-ui, sans-serif;
--font-serif: Georgia, serif;
--font-mono: JetBrains Mono, monospace;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix current Stylelint errors in font-token declarations and body declaration spacing.

Stylelint is currently flagging these lines (value-keyword-case and declaration-empty-line-before), which can block lint-gated merges.

Proposed fix
-  --font-sans: Inter, system-ui, sans-serif;
-  --font-serif: Georgia, serif;
-  --font-mono: JetBrains Mono, monospace;
+  --font-sans: "Inter", system-ui, sans-serif;
+  --font-serif: "Georgia", serif;
+  --font-mono: "JetBrains Mono", monospace;
...
-  --font-sans: Inter, system-ui, sans-serif;
-  --font-serif: Georgia, serif;
-  --font-mono: JetBrains Mono, monospace;
+  --font-sans: "Inter", system-ui, sans-serif;
+  --font-serif: "Georgia", serif;
+  --font-mono: "JetBrains Mono", monospace;
...
   body {
     `@apply` bg-background text-foreground;
+
     letter-spacing: var(--tracking-normal);
   }

Also applies to: 93-95, 179-179

🧰 Tools
🪛 Stylelint (17.5.0)

[error] 38-38: Expected "Inter" to be "inter" (value-keyword-case)

(value-keyword-case)


[error] 39-39: Expected "Georgia" to be "georgia" (value-keyword-case)

(value-keyword-case)


[error] 40-40: Expected "JetBrains" to be "jetbrains" (value-keyword-case)

(value-keyword-case)


[error] 40-40: Expected "Mono" to be "mono" (value-keyword-case)

(value-keyword-case)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/globals.css` around lines 38 - 40, Stylelint is failing on the custom
property font values and an extra blank line before the body declaration: update
the font token values so generic family keywords are lowercase (e.g., keep
"Inter" / "Georgia" / "JetBrains Mono" as-is for the named fonts but change the
generic keywords to "sans-serif", "serif", "monospace" in the --font-sans,
--font-serif, and --font-mono declarations) and remove the stray empty line
before the body selector (or adjust to match your project's
declaration-empty-line-before rule) so the body declaration spacing passes
linting.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
components/logo.tsx (1)

9-16: Inconsistent indentation in SVG attributes.

The viewBox and fill attributes (lines 10-11) lack indentation while subsequent attributes are properly indented. Consider aligning all attributes for consistency.

✨ Suggested formatting fix
 <svg
-viewBox="0 0 127 133"
-fill="currentColor"
+    viewBox="0 0 127 133"
+    fill="currentColor"
     xmlns="http://www.w3.org/2000/svg"
     aria-label='Veo Logo'
     className={cn('w-32', className)}
     {...props}
 >
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/logo.tsx` around lines 9 - 16, The SVG element's attributes are
misaligned—move the `viewBox` and `fill` attributes to match the indentation
style used for the other attributes on the `<svg>` element (the same indentation
as `xmlns`, `aria-label`, `className={cn('w-32', className)}`, and `{...props}`)
so all attributes are consistently indented; locate the `<svg` tag in the Logo
component and adjust `viewBox="0 0 127 133"` and `fill="currentColor"` to the
same indent level as the remaining attributes.
sections/team.tsx (1)

28-52: Consider removing commented-out code.

Leaving large blocks of commented-out data in the codebase creates noise and can become stale over time. If these team members might be re-added, consider tracking this in a separate issue or using version control history to recover them when needed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sections/team.tsx` around lines 28 - 52, Remove the large commented-out team
member objects in sections/team.tsx (the block of avatar/name/role JSON-like
objects) to avoid clutter; if you want to preserve them, move the data into a
separate seed/test file or create a GitHub issue referencing these entries
instead of leaving them commented in the Team component/file.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@components/logo.tsx`:
- Around line 9-16: The SVG element's attributes are misaligned—move the
`viewBox` and `fill` attributes to match the indentation style used for the
other attributes on the `<svg>` element (the same indentation as `xmlns`,
`aria-label`, `className={cn('w-32', className)}`, and `{...props}`) so all
attributes are consistently indented; locate the `<svg` tag in the Logo
component and adjust `viewBox="0 0 127 133"` and `fill="currentColor"` to the
same indent level as the remaining attributes.

In `@sections/team.tsx`:
- Around line 28-52: Remove the large commented-out team member objects in
sections/team.tsx (the block of avatar/name/role JSON-like objects) to avoid
clutter; if you want to preserve them, move the data into a separate seed/test
file or create a GitHub issue referencing these entries instead of leaving them
commented in the Team component/file.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 10a73c10-5a2e-4c96-b94f-8ae92a91d7e3

📥 Commits

Reviewing files that changed from the base of the PR and between 6aa7dad and 89bf241.

📒 Files selected for processing (13)
  • components/logo.tsx
  • components/systaliko-ui/blocks/scroll-animation.tsx
  • components/systaliko-ui/cards/card-testimonial.tsx
  • components/systaliko-ui/cards/card.tsx
  • components/systaliko-ui/cards/cards-stack-rotated.tsx
  • components/systaliko-ui/cards/cards-stack.tsx
  • components/systaliko-ui/rating-stars.tsx
  • components/ui/avatar.tsx
  • components/ui/badge.tsx
  • components/ui/button.tsx
  • components/ui/popover.tsx
  • hooks/use-toast.ts
  • sections/team.tsx
💤 Files with no reviewable changes (1)
  • hooks/use-toast.ts
✅ Files skipped from review due to trivial changes (9)
  • components/systaliko-ui/rating-stars.tsx
  • components/systaliko-ui/cards/cards-stack-rotated.tsx
  • components/systaliko-ui/blocks/scroll-animation.tsx
  • components/systaliko-ui/cards/card-testimonial.tsx
  • components/ui/avatar.tsx
  • components/ui/badge.tsx
  • components/systaliko-ui/cards/cards-stack.tsx
  • components/systaliko-ui/cards/card.tsx
  • components/ui/popover.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
package.json (1)

52-56: ⚠️ Potential issue | 🟡 Minor

pnpm.onlyBuiltDependencies: unrs-resolver looks valid, but keep the source-build rationale checked
unrs-resolver is a published npm package (v1.12.2, “UnRS Resolver Node API”), so it’s not an obvious typo/internal-only name. Ensure it’s included in pnpm.onlyBuiltDependencies only if it actually requires building from source (e.g., native/binary code).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@package.json` around lines 52 - 56, Verify whether "unrs-resolver" truly
requires source-building before listing it in pnpm.onlyBuiltDependencies: check
the package.json's pnpm.onlyBuiltDependencies array and inspect the
"unrs-resolver" package (version 1.12.2) for native/binary build steps or native
bindings; if it does not require source build, remove "unrs-resolver" from
pnpm.onlyBuiltDependencies, otherwise add a short comment near the
pnpm.onlyBuiltDependencies entry documenting the build rationale (e.g., native
dependency or install scripts) so the reason for including "unrs-resolver" is
explicit.
🧹 Nitpick comments (2)
components/ui/chart.tsx (1)

42-82: ⚖️ Poor tradeoff

Consider using CSS-in-JS or a safer style injection method.

The current approach with dangerouslySetInnerHTML requires careful sanitization and is prone to security issues. Consider using a CSS-in-JS library or React's inline styles for dynamic theming.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/ui/chart.tsx` around lines 42 - 82, The ChartContainer currently
relies on injected raw CSS via the ChartStyle usage which can use
dangerouslySetInnerHTML—replace the style injection with a safer approach: move
dynamic CSS generation out of raw HTML and into a CSS-in-JS or inline-style
solution (e.g., convert ChartStyle to a styled-component or a component that
returns React inline style objects) and ensure theming values come from
ChartContext.config; locate ChartContainer, ChartStyle, and the
RechartsPrimitive.ResponsiveContainer children to apply the new styled component
or inline styles so dynamic rules (the long cn() class list and per-chart id
styles) are rendered without using dangerouslySetInnerHTML.
components/ui/field.tsx (1)

194-219: ⚖️ Poor tradeoff

Consider memoizing the Map construction separately.

The error deduplication logic creates a new Map on every render when errors changes. For large error arrays, extracting the Map construction to a separate useMemo could improve performance, though this is likely negligible for typical form validation scenarios.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/ui/field.tsx` around lines 194 - 219, The current useMemo that
computes content does inline Map-based deduplication of errors, rebuilding the
Map on every change; extract the Map construction into its own memoized value
(e.g., const uniqueErrors = useMemo(() => { return [...new Map(errors.map(e =>
[e?.message, e])).values()]; }, [errors]) ) and then reference that memoized
uniqueErrors inside the existing content useMemo, keeping the same conditional
checks (children, uniqueErrors length, and rendering of the <ul>) so behavior of
the content constant and useMemo remains identical but avoids reconstructing the
Map repeatedly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/layout.tsx`:
- Line 36: In app/layout.tsx the metadata `url:
'https://medbase.vercel.app/og-image.png'` points to a non-existent OG image
(404); fix by either adding the missing image to the deployed public assets and
referencing it (e.g., place og-image.png in the site's public folder and use the
deployed absolute or root-relative path) or update the metadata `url` to point
to an existing working image URL; locate the `metadata` object in app/layout.tsx
and change the `url` value or deploy the asset so the current `og-image.png`
path resolves.

In `@components/ui/chart.tsx`:
- Around line 84-115: The ChartStyle component is injecting unsanitized config
keys into CSS (via colorConfig / [key, itemConfig] and building --color-${key}),
enabling CSS/HTML injection; fix by validating or escaping keys before
use—restrict keys to a safe whitelist/regex (e.g. alphanumeric, dash,
underscore) or map them to generated safe IDs, then use the sanitized identifier
when building selectors and CSS variable names (and update any consumers to
provide or accept sanitized keys); ensure all references to key in ChartStyle
(and any THEMES-based selector generation) use the sanitized value.
- Around line 59-60: The chart ID construction (uniqueId, chartId) uses id with
only colon stripping, allowing malicious characters to break out of CSS in
dangerouslySetInnerHTML; fix by fully sanitizing the id prop to a whitelist
(allow only A-Z, a-z, 0-9, hyphen and underscore) and fall back to React.useId()
when the sanitized result is empty; use this sanitized value for chartId and any
CSS selectors/inline styles instead of the raw id to prevent CSS/HTML/JS
injection.

In `@components/ui/combobox.tsx`:
- Line 119: The utility class string in components/ui/combobox.tsx contains an
invalid calc() usage: replace the bad token
min-w-[calc(var(--anchor-width)+--spacing(7))] in the Combobox content class
with a valid expression—either use a proper CSS variable (e.g. var(--spacing-7))
inside calc, a fixed value (e.g. 1.75rem) inside calc, or remove calc and apply
a Tailwind spacing class; update the string where the class contains
"group/combobox-content ... min-w-[calc(var(--anchor-width)+--spacing(7))] ..."
so the final min-w uses only valid CSS (var(...) or fixed value).
- Line 134: In the Combobox component's class string where the max-h utility is
defined (the token starting with "max-h-[min(calc(...)]"), fix the malformed CSS
by replacing the non-standard and unwrapped custom-property usage with proper
var() references and add spaces around the subtraction operator; specifically
change occurrences like --spacing(96), ---spacing(9) and
calc(var(--available-height)---spacing(9)) to use var(--spacing-96) and
var(--spacing-9) and ensure the calc expressions read like
calc(var(--spacing-96) - var(--spacing-9)) and calc(var(--available-height) -
var(--spacing-9)) so the overall max-h becomes min(calc(...), calc(...)) with
correct spacing and var() usage.

In `@components/ui/empty.tsx`:
- Around line 71-82: EmptyDescription is typed as React.ComponentProps<"p"> but
returns a div, causing a props/semantic mismatch; fix by making the types and
markup consistent: either change the component to render a <p> (preserve
React.ComponentProps<"p">) or update the prop type to
React.ComponentProps<"div"> (or React.HTMLAttributes<HTMLDivElement>) if you
want a div; update the signature of EmptyDescription and any callers accordingly
and keep the data-slot, className, and {...props} usage intact.

In `@components/ui/field.tsx`:
- Line 207: Replace the loose equality comparison in the conditional that checks
uniqueErrors length (the expression using uniqueErrors?.length == 1) with strict
equality (===) to prevent type coercion; update the conditional in the component
in components/ui/field.tsx (the block referencing uniqueErrors?.length) to use
=== instead of == and run typechecking/linting to ensure no other occurrences
remain.

In `@components/ui/navigation-menu.tsx`:
- Around line 1-6: Add the "use client" directive as the very first line of the
file (before all imports) so this module becomes a Next.js Client Component;
this is required because this file uses Radix primitives like
NavigationMenuPrimitive and interactive icons like ChevronDownIcon (and
utilities such as cn) that rely on client-side hooks/event handlers. Ensure the
string literal "use client" is placed above the existing imports to avoid
runtime build failures.

In `@components/ui/progress.tsx`:
- Line 25: The progress indicator uses style={{ transform: `translateX(-${100 -
(value || 0)}%)` }} and fails to clamp out-of-range value inputs; update the
Progress component to normalize value by clamping it to the [0,100] range (e.g.,
const clamped = Math.max(0, Math.min(100, value ?? 0))) and then compute the
transform with clamped instead of value so negative or >100 inputs produce valid
positioning.

In `@sections/hero.tsx`:
- Line 27: In the JSX in sections/hero.tsx update the badge text inside the
<strong> element that currently reads "Strategic Parnership" to the correct
spelling "Strategic Partnership" so the displayed copy is fixed; locate the
<strong> element in the hero component and replace the misspelled word.

---

Outside diff comments:
In `@package.json`:
- Around line 52-56: Verify whether "unrs-resolver" truly requires
source-building before listing it in pnpm.onlyBuiltDependencies: check the
package.json's pnpm.onlyBuiltDependencies array and inspect the "unrs-resolver"
package (version 1.12.2) for native/binary build steps or native bindings; if it
does not require source build, remove "unrs-resolver" from
pnpm.onlyBuiltDependencies, otherwise add a short comment near the
pnpm.onlyBuiltDependencies entry documenting the build rationale (e.g., native
dependency or install scripts) so the reason for including "unrs-resolver" is
explicit.

---

Nitpick comments:
In `@components/ui/chart.tsx`:
- Around line 42-82: The ChartContainer currently relies on injected raw CSS via
the ChartStyle usage which can use dangerouslySetInnerHTML—replace the style
injection with a safer approach: move dynamic CSS generation out of raw HTML and
into a CSS-in-JS or inline-style solution (e.g., convert ChartStyle to a
styled-component or a component that returns React inline style objects) and
ensure theming values come from ChartContext.config; locate ChartContainer,
ChartStyle, and the RechartsPrimitive.ResponsiveContainer children to apply the
new styled component or inline styles so dynamic rules (the long cn() class list
and per-chart id styles) are rendered without using dangerouslySetInnerHTML.

In `@components/ui/field.tsx`:
- Around line 194-219: The current useMemo that computes content does inline
Map-based deduplication of errors, rebuilding the Map on every change; extract
the Map construction into its own memoized value (e.g., const uniqueErrors =
useMemo(() => { return [...new Map(errors.map(e => [e?.message, e])).values()];
}, [errors]) ) and then reference that memoized uniqueErrors inside the existing
content useMemo, keeping the same conditional checks (children, uniqueErrors
length, and rendering of the <ul>) so behavior of the content constant and
useMemo remains identical but avoids reconstructing the Map repeatedly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6cf50657-b317-476a-b9bf-e61c06ede5c0

📥 Commits

Reviewing files that changed from the base of the PR and between 89bf241 and d1e6b23.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (47)
  • app/layout.tsx
  • components/desktop-nav.tsx
  • components/icons/insta-icon.tsx
  • components/logo.tsx
  • components/mobile-nav.tsx
  • components/ui/aspect-ratio.tsx
  • components/ui/card.tsx
  • components/ui/chart.tsx
  • components/ui/checkbox.tsx
  • components/ui/combobox.tsx
  • components/ui/dialog.tsx
  • components/ui/drawer.tsx
  • components/ui/dropdown-menu.tsx
  • components/ui/empty.tsx
  • components/ui/field.tsx
  • components/ui/hover-card.tsx
  • components/ui/input-group.tsx
  • components/ui/input.tsx
  • components/ui/label.tsx
  • components/ui/menubar.tsx
  • components/ui/navigation-menu.tsx
  • components/ui/pagination.tsx
  • components/ui/progress.tsx
  • components/ui/resizable.tsx
  • components/ui/scroll-area.tsx
  • components/ui/select.tsx
  • components/ui/separator.tsx
  • components/ui/sheet.tsx
  • components/ui/skeleton.tsx
  • components/ui/spinner.tsx
  • components/ui/switch.tsx
  • components/ui/table.tsx
  • components/ui/tabs.tsx
  • components/ui/textarea.tsx
  • components/ui/toggle.tsx
  • components/ui/tooltip.tsx
  • data/constants.ts
  • data/data.ts
  • package.json
  • sections/about.tsx
  • sections/footer.tsx
  • sections/header.tsx
  • sections/hero.tsx
  • sections/process.tsx
  • sections/team.tsx
  • sections/testimonials.tsx
  • sections/values.tsx
✅ Files skipped from review due to trivial changes (8)
  • sections/header.tsx
  • components/ui/aspect-ratio.tsx
  • components/ui/separator.tsx
  • components/desktop-nav.tsx
  • sections/about.tsx
  • sections/testimonials.tsx
  • components/mobile-nav.tsx
  • components/ui/drawer.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • sections/team.tsx

Comment thread app/layout.tsx
Comment thread components/ui/chart.tsx
Comment on lines +59 to +60
const uniqueId = React.useId()
const chartId = `chart-${id ?? uniqueId.replace(/:/g, "")}`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

XSS vulnerability: insufficient sanitization of chart ID.

The id prop is only sanitized for colons (:) before being used in CSS selectors injected via dangerouslySetInnerHTML. A malicious id could inject arbitrary CSS or break out of the <style> tag to inject scripts.

For example: id="x] { } </style><script>alert('XSS')</script><style>"

This would close the style tag and inject JavaScript.

🛡️ Proposed fix
 function ChartContainer({
   id,
   className,
   children,
   config,
   initialDimension = INITIAL_DIMENSION,
   ...props
 }: React.ComponentProps<"div"> & {
   config: ChartConfig
   children: React.ComponentProps<
     typeof RechartsPrimitive.ResponsiveContainer
   >["children"]
   initialDimension?: {
     width: number
     height: number
   }
 }) {
   const uniqueId = React.useId()
-  const chartId = `chart-${id ?? uniqueId.replace(/:/g, "")}`
+  const chartId = `chart-${(id ?? uniqueId).replace(/[^a-zA-Z0-9-_]/g, "")}`

This sanitizes the ID to only allow alphanumeric characters, hyphens, and underscores, preventing CSS injection and XSS.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const uniqueId = React.useId()
const chartId = `chart-${id ?? uniqueId.replace(/:/g, "")}`
const uniqueId = React.useId()
const chartId = `chart-${(id ?? uniqueId).replace(/[^a-zA-Z0-9-_]/g, "")}`
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/ui/chart.tsx` around lines 59 - 60, The chart ID construction
(uniqueId, chartId) uses id with only colon stripping, allowing malicious
characters to break out of CSS in dangerouslySetInnerHTML; fix by fully
sanitizing the id prop to a whitelist (allow only A-Z, a-z, 0-9, hyphen and
underscore) and fall back to React.useId() when the sanitized result is empty;
use this sanitized value for chartId and any CSS selectors/inline styles instead
of the raw id to prevent CSS/HTML/JS injection.

Comment thread components/ui/chart.tsx
Comment thread components/ui/combobox.tsx Outdated
data-slot="combobox-content"
data-chips={!!anchor}
className={cn(
"group/combobox-content relative max-h-96 w-(--anchor-width) max-w-(--available-width) min-w-[calc(var(--anchor-width)+--spacing(7))] origin-(--transform-origin) overflow-hidden rounded-md bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[chips=true]:min-w-(--anchor-width) data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 *:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-8 *:data-[slot=input-group]:border-input/30 *:data-[slot=input-group]:bg-input/30 *:data-[slot=input-group]:shadow-none data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Invalid CSS calc() syntax mixing CSS variables and Tailwind tokens.

Line 119 contains min-w-[calc(var(--anchor-width)+--spacing(7))] which combines a proper CSS variable reference (var(--anchor-width)) with an invalid token reference (--spacing(7)). CSS calc() requires all custom properties to use var() syntax. The --spacing(7) notation is not valid CSS—if you need a spacing value, use either:

  1. A Tailwind spacing class directly (not in calc)
  2. A proper CSS variable like var(--spacing-7) if such a variable exists
  3. A fixed value like 1.75rem

This will fail silently or produce unexpected results at runtime.

🔧 Possible fix (assuming --spacing-7 is a defined CSS variable)
-            "group/combobox-content relative max-h-96 w-(--anchor-width) max-w-(--available-width) min-w-[calc(var(--anchor-width)+--spacing(7))] origin-(--transform-origin) overflow-hidden rounded-md bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[chips=true]:min-w-(--anchor-width) data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 *:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-8 *:data-[slot=input-group]:border-input/30 *:data-[slot=input-group]:bg-input/30 *:data-[slot=input-group]:shadow-none data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
+            "group/combobox-content relative max-h-96 w-(--anchor-width) max-w-(--available-width) min-w-[calc(var(--anchor-width)+var(--spacing-7))] origin-(--transform-origin) overflow-hidden rounded-md bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[chips=true]:min-w-(--anchor-width) data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 *:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-8 *:data-[slot=input-group]:border-input/30 *:data-[slot=input-group]:bg-input/30 *:data-[slot=input-group]:shadow-none data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",

Or use a fixed rem value if appropriate.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"group/combobox-content relative max-h-96 w-(--anchor-width) max-w-(--available-width) min-w-[calc(var(--anchor-width)+--spacing(7))] origin-(--transform-origin) overflow-hidden rounded-md bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[chips=true]:min-w-(--anchor-width) data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 *:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-8 *:data-[slot=input-group]:border-input/30 *:data-[slot=input-group]:bg-input/30 *:data-[slot=input-group]:shadow-none data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
"group/combobox-content relative max-h-96 w-(--anchor-width) max-w-(--available-width) min-w-[calc(var(--anchor-width)+var(--spacing-7))] origin-(--transform-origin) overflow-hidden rounded-md bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[chips=true]:min-w-(--anchor-width) data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 *:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-8 *:data-[slot=input-group]:border-input/30 *:data-[slot=input-group]:bg-input/30 *:data-[slot=input-group]:shadow-none data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/ui/combobox.tsx` at line 119, The utility class string in
components/ui/combobox.tsx contains an invalid calc() usage: replace the bad
token min-w-[calc(var(--anchor-width)+--spacing(7))] in the Combobox content
class with a valid expression—either use a proper CSS variable (e.g.
var(--spacing-7)) inside calc, a fixed value (e.g. 1.75rem) inside calc, or
remove calc and apply a Tailwind spacing class; update the string where the
class contains "group/combobox-content ...
min-w-[calc(var(--anchor-width)+--spacing(7))] ..." so the final min-w uses only
valid CSS (var(...) or fixed value).

Comment thread components/ui/combobox.tsx Outdated
<ComboboxPrimitive.List
data-slot="combobox-list"
className={cn(
"max-h-[min(calc(--spacing(96)---spacing(9)),calc(var(--available-height)---spacing(9)))] scroll-py-1 overflow-y-auto p-1 data-empty:p-0",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Invalid CSS syntax with triple dashes and malformed calc() expressions.

Line 134 contains max-h-[min(calc(--spacing(96)---spacing(9)),calc(var(--available-height)---spacing(9)))] with multiple syntax errors:

  1. Triple dash ---spacing(9): This is invalid CSS. It appears to be an attempt at subtraction but CSS requires spaces around operators: - var(--spacing-9).
  2. --spacing(96) without var(): Inside calc(), all custom properties must use the var() function.
  3. Non-standard --spacing() notation: CSS doesn't support function-call syntax for custom properties.

This will not compute correctly at runtime.

🔧 Possible fix (assuming proper CSS variables exist)
       className={cn(
-        "max-h-[min(calc(--spacing(96)---spacing(9)),calc(var(--available-height)---spacing(9)))] scroll-py-1 overflow-y-auto p-1 data-empty:p-0",
+        "max-h-[min(calc(var(--spacing-96)-var(--spacing-9)),calc(var(--available-height)-var(--spacing-9)))] scroll-py-1 overflow-y-auto p-1 data-empty:p-0",
         className
       )}

Ensure you add spaces around the - operator and wrap all custom properties with var().

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"max-h-[min(calc(--spacing(96)---spacing(9)),calc(var(--available-height)---spacing(9)))] scroll-py-1 overflow-y-auto p-1 data-empty:p-0",
"max-h-[min(calc(var(--spacing-96)-var(--spacing-9)),calc(var(--available-height)-var(--spacing-9)))] scroll-py-1 overflow-y-auto p-1 data-empty:p-0",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/ui/combobox.tsx` at line 134, In the Combobox component's class
string where the max-h utility is defined (the token starting with
"max-h-[min(calc(...)]"), fix the malformed CSS by replacing the non-standard
and unwrapped custom-property usage with proper var() references and add spaces
around the subtraction operator; specifically change occurrences like
--spacing(96), ---spacing(9) and calc(var(--available-height)---spacing(9)) to
use var(--spacing-96) and var(--spacing-9) and ensure the calc expressions read
like calc(var(--spacing-96) - var(--spacing-9)) and calc(var(--available-height)
- var(--spacing-9)) so the overall max-h becomes min(calc(...), calc(...)) with
correct spacing and var() usage.

Comment thread components/ui/empty.tsx
Comment on lines +71 to +82
function EmptyDescription({ className, ...props }: React.ComponentProps<"p">) {
return (
<div
data-slot="empty-description"
className={cn(
"text-sm/relaxed text-muted-foreground [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary",
className
)}
{...props}
/>
)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Type mismatch: props typed as "p" but renders a div.

The EmptyDescription component is typed as React.ComponentProps<"p"> but renders a <div> element. This creates a type-safety gap where paragraph-specific props could be passed but won't work correctly.

🔧 Proposed fix
-function EmptyDescription({ className, ...props }: React.ComponentProps<"p">) {
+function EmptyDescription({ className, ...props }: React.ComponentProps<"div">) {
   return (
     <div

Alternatively, if paragraph semantics are desired:

 function EmptyDescription({ className, ...props }: React.ComponentProps<"p">) {
   return (
-    <div
+    <p
       data-slot="empty-description"
       className={cn(
         "text-sm/relaxed text-muted-foreground [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary",
         className
       )}
       {...props}
     />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function EmptyDescription({ className, ...props }: React.ComponentProps<"p">) {
return (
<div
data-slot="empty-description"
className={cn(
"text-sm/relaxed text-muted-foreground [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary",
className
)}
{...props}
/>
)
}
function EmptyDescription({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="empty-description"
className={cn(
"text-sm/relaxed text-muted-foreground [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary",
className
)}
{...props}
/>
)
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/ui/empty.tsx` around lines 71 - 82, EmptyDescription is typed as
React.ComponentProps<"p"> but returns a div, causing a props/semantic mismatch;
fix by making the types and markup consistent: either change the component to
render a <p> (preserve React.ComponentProps<"p">) or update the prop type to
React.ComponentProps<"div"> (or React.HTMLAttributes<HTMLDivElement>) if you
want a div; update the signature of EmptyDescription and any callers accordingly
and keep the data-slot, className, and {...props} usage intact.

Comment thread components/ui/field.tsx
...new Map(errors.map((error) => [error?.message, error])).values(),
]

if (uniqueErrors?.length == 1) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use strict equality.

Replace loose equality == with strict equality === to avoid type coercion issues.

🔧 Proposed fix
-    if (uniqueErrors?.length == 1) {
+    if (uniqueErrors?.length === 1) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (uniqueErrors?.length == 1) {
if (uniqueErrors?.length === 1) {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/ui/field.tsx` at line 207, Replace the loose equality comparison
in the conditional that checks uniqueErrors length (the expression using
uniqueErrors?.length == 1) with strict equality (===) to prevent type coercion;
update the conditional in the component in components/ui/field.tsx (the block
referencing uniqueErrors?.length) to use === instead of == and run
typechecking/linting to ensure no other occurrences remain.

Comment thread components/ui/navigation-menu.tsx Outdated
Comment on lines +1 to +6
import * as React from "react"
import { cva } from "class-variance-authority"
import { ChevronDownIcon } from "lucide-react"
import { NavigationMenu as NavigationMenuPrimitive } from "radix-ui"

import { cn } from "@/utils"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Missing "use client" directive will break in Next.js App Router.

Radix UI components require client-side hooks and event handlers, but this module lacks the "use client" directive. In Next.js App Router (the default in v15+), components are Server Components unless explicitly marked as Client Components. At runtime, Radix will attempt to use hooks (useState, useEffect, etc.) which are forbidden in Server Components, causing the build or runtime to fail.

🔧 Proposed fix
+import "use client"
+
 import * as React from "react"
 import { cva } from "class-variance-authority"

Note: Place the directive at the very top, before all imports.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import * as React from "react"
import { cva } from "class-variance-authority"
import { ChevronDownIcon } from "lucide-react"
import { NavigationMenu as NavigationMenuPrimitive } from "radix-ui"
import { cn } from "@/utils"
"use client"
import * as React from "react"
import { cva } from "class-variance-authority"
import { ChevronDownIcon } from "lucide-react"
import { NavigationMenu as NavigationMenuPrimitive } from "radix-ui"
import { cn } from "`@/utils`"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/ui/navigation-menu.tsx` around lines 1 - 6, Add the "use client"
directive as the very first line of the file (before all imports) so this module
becomes a Next.js Client Component; this is required because this file uses
Radix primitives like NavigationMenuPrimitive and interactive icons like
ChevronDownIcon (and utilities such as cn) that rely on client-side hooks/event
handlers. Ensure the string literal "use client" is placed above the existing
imports to avoid runtime build failures.

<ProgressPrimitive.Indicator
data-slot="progress-indicator"
className="h-full w-full flex-1 bg-primary transition-all"
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Clamp progress value before computing transform.

On Line 25, out-of-range value inputs (e.g. -10, 140) produce invalid indicator positioning. Clamp to [0, 100] before applying translateX.

Proposed fix
 function Progress({
   className,
   value,
   ...props
 }: React.ComponentProps<typeof ProgressPrimitive.Root>) {
+  const safeValue = Math.min(100, Math.max(0, value ?? 0))
   return (
     <ProgressPrimitive.Root
@@
       <ProgressPrimitive.Indicator
         data-slot="progress-indicator"
         className="h-full w-full flex-1 bg-primary transition-all"
-        style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
+        style={{ transform: `translateX(-${100 - safeValue}%)` }}
       />
     </ProgressPrimitive.Root>
   )
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/ui/progress.tsx` at line 25, The progress indicator uses style={{
transform: `translateX(-${100 - (value || 0)}%)` }} and fails to clamp
out-of-range value inputs; update the Progress component to normalize value by
clamping it to the [0,100] range (e.g., const clamped = Math.max(0,
Math.min(100, value ?? 0))) and then compute the transform with clamped instead
of value so negative or >100 inputs produce valid positioning.

Comment thread sections/hero.tsx Outdated
Sign up for free to 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