Skip to content

Conversation

@antoinekm
Copy link
Member

@antoinekm antoinekm commented Dec 31, 2025

Summary by CodeRabbit

  • New Features

    • Link component now supports protocol-based URLs (mailto:, tel:, sms:, etc.) without adding locale prefixes
  • Style

    • Upgraded Tailwind usage and utilities (v4-style syntax), global stylesheet reorganized
    • UI refinements: reduced blur, softened shadows, updated focus outline behavior, updated gradients and animations, and many small presentational tweaks
  • Chores

    • Version bumps and changelogs added for several example and package releases
  • Other

    • Added new ignore rule for temp/

✏️ Tip: You can customize this high-level summary in your review settings.

Copilot AI review requested due to automatic review settings December 31, 2025 14:41
@vercel
Copy link

vercel bot commented Dec 31, 2025

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

Project Deployment Review Updated (UTC)
onruntime-website Ready Ready Preview, Comment Dec 31, 2025 2:55pm

@coderabbitai
Copy link

coderabbitai bot commented Dec 31, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

This PR migrates the app from Tailwind v3 → v4 (removes the Tailwind config, adopts CSS-driven theme), updates related dependencies, mass-updates utility classes/syntax, bumps several package/example versions, adds a gitignore entry, removes a sitemap changeset, and broadens Link external-url detection to include protocol schemes.

Changes

Cohort / File(s) Summary
Tailwind config & PostCSS
apps/web/tailwind.config.ts, apps/web/postcss.config.mjs
Deleted Tailwind config; switched PostCSS plugins from tailwindcss+autoprefixer@tailwindcss/postcss.
Global styles / Theme
apps/web/src/styles/globals.css
Rewrote globals to a CSS-variable-driven theme and inline theme mapping; replaced prior Tailwind base/components/utilities usage.
Dependency updates
apps/web/package.json
Upgraded tailwindcss to v4, bumped several @radix-ui packages, swapped/added tailwind-related deps (e.g., @tailwindcss/postcss, tw-animate-css).
Utility class migrations (masks, gradients, outlines, sizing)
apps/web/src/... (many presentation components)
Broad stylistic refactors: [mask-image:...]mask-[...], bg-gradient-to-*bg-linear-to-*, outline-noneoutline-hidden, bracket/parenthesis syntax changes for arbitrary values, and various size/shadow/blur token adjustments across many components.
Flex utility normalizations
apps/web/src/...
Replaced flex-growgrow, flex-shrink-0shrink-0, flex-[1]flex-1 in multiple components.
Complex UI component adjustments
apps/web/src/components/ui/dropdown-menu.tsx, .../toast.tsx, .../navigation-menu.tsx
Updated arbitrary value syntax, data attribute naming, origin/animation classes, size constraints, and several className tokens to align with v4 conventions.
Component-level visual tweaks
apps/web/src/components/..., apps/web/src/screens/...
Numerous small presentational updates (shadow levels, blur intensity, cursor, bg/position syntax, hover selector ordering) with no logic changes.
Tailwind removal impact
apps/web/tailwind.config.ts
File deleted (full config removed).
Next-sitemap package & examples
packages/next-sitemap/package.json, examples/next-sitemap/app/*
Bumped @onruntime/next-sitemap to 0.2.0; added example changelog and example version bump. .changeset/add-sitemap-options.md deleted.
Translations package & examples
packages/translations/src/next/components/link.tsx, packages/translations/package.json, examples/translations/*/package.json
Bumped translations packages; Link: expanded external detection to treat protocol-based URLs (mailto:, tel:, sms:, custom schemes) as external (no locale prefix).
CHANGELOGs / version bumps
packages/*/CHANGELOG.md, examples/*/CHANGELOG.md, */package.json
Added/updated changelogs and bumped several example/package versions (0.1.0 → 0.1.1 / 0.2.0).
Repo housekeeping
.gitignore, .changeset/add-sitemap-options.md
Added temp/ to .gitignore; removed the listed changeset file.

Sequence Diagram(s)

(Skipped — changes are stylistic, config/dependency, and small Link detection update; there is no new multi-component control flow requiring visualization.)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 Hopped through classes, I nudged each line,

Masks and gradients now follow the sign.
From shrink to grow and outlines gone hid,
New CSS tokens where Tailwind once did.
A carrot-shaped commit — styles tuned and spry! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: upgrading from Tailwind v3 to v4, which is reflected across package.json updates, tailwind.config deletion, PostCSS configuration changes, and systematic class refactoring throughout the codebase.
✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (6)
apps/web/src/components/marketing/landing/visitor/projects/card/index.tsx (1)

10-16: Add JSDoc documentation for exported types and components.

The exported ProjectCardProps type and ProjectCard component lack JSDoc comments. Per coding guidelines, all exported functions and classes should include JSDoc documentation.

🔎 Proposed documentation
+/**
+ * Props for the ProjectCard component.
+ */
 export type ProjectCardProps = {
   project: Project;
 };

+/**
+ * Displays a project card with image, title, description, and tags.
+ * @param props - The component props
+ * @returns The rendered project card
+ */
 const ProjectCard: React.FC<ProjectCardProps> = ({
apps/web/src/components/glossary/alphabet-nav.tsx (1)

10-10: Add JSDoc comment for the exported component.

Exported functions must include JSDoc comments describing their purpose, parameters, and return type per coding guidelines.

🔎 Proposed JSDoc comment
+/**
+ * Navigation component for glossary sections, allowing users to quickly jump to sections
+ * by letter (A-Z). Displays available letters and highlights the current section based on scroll position.
+ * 
+ * @param {GlossaryAlphabetNavProps} props - Component props
+ * @param {string[]} props.availableLetters - Array of letters that have glossary entries
+ * @returns {React.ReactElement} Sticky navigation bar with letter buttons
+ */
 export function GlossaryAlphabetNav({ availableLetters }: GlossaryAlphabetNavProps) {
apps/web/src/components/marketing/landing/visitor/team/grid/card/index.tsx (1)

17-23: Add JSDoc comment for exported component.

The exported TeamMemberCard component is missing JSDoc documentation. As per coding guidelines, all exported functions and classes must include JSDoc comments.

🔎 Suggested JSDoc documentation
+/**
+ * A card component displaying a team member's information with hover effects.
+ * Shows the member's name, roles, image, and a link to more details.
+ *
+ * @param props - The team member card properties
+ * @param props.name - Full name of the team member
+ * @param props.mainRole - Primary role/title of the team member
+ * @param props.secondaryRole - Optional secondary role/title
+ * @param props.image - Path to the team member's image
+ * @param props.link - URL to the team member's detailed profile or LinkedIn
+ * @returns A team member card component
+ */
 const TeamMemberCard: React.FC<TeamMemberCardProps> = ({
   name,
   mainRole,
   secondaryRole,
   image,
   link,
 }) => {

Based on coding guidelines requiring JSDoc comments for exported functions.

apps/web/src/components/marketing/agency/local-portfolio.tsx (2)

21-26: Add JSDoc comment for LocalPortfolioProject function.

Per coding guidelines, exported functions should include JSDoc comments describing their purpose, parameters, and return type.

🔎 Proposed JSDoc comment
+/**
+ * Renders a portfolio project card for a local agency.
+ * Fetches project and translation data server-side.
+ * @param {LocalPortfolioProjectProps} props - Component props
+ * @param {Project} props.project - The project to display
+ * @param {Agency} props.agency - The agency context
+ * @param {boolean} props.isPrimary - Whether this is the primary/featured project
+ * @returns {Promise<JSX.Element>} The rendered project card
+ */
 const LocalPortfolioProject = async ({
   project,
   agency,
   isPrimary,
}: LocalPortfolioProjectProps) => {

98-99: Add JSDoc comment for LocalPortfolio component.

Per coding guidelines, exported functions should include JSDoc comments describing their purpose and parameters.

🔎 Proposed JSDoc comment
+/**
+ * Displays a portfolio section for a local agency with featured and recent projects.
+ * Fetches project data and translations server-side.
+ * @param {LocalPortfolioProps} props - Component props
+ * @param {Agency} props.agency - The agency to display portfolio for
+ * @returns {Promise<JSX.Element>} The rendered portfolio section
+ */
 const LocalPortfolio = async ({ agency }: LocalPortfolioProps) => {
apps/web/src/components/ui/job-content.tsx (1)

8-30: Add JSDoc documentation for the exported component.

Per the coding guidelines, all exported functions and classes must have JSDoc comments. Please document this component's purpose, parameters, and the security requirement that content must be pre-sanitized HTML.

🔎 Suggested JSDoc
+/**
+ * Renders job content with styled HTML elements.
+ * 
+ * Applies consistent styling to headings, paragraphs, lists, and other HTML elements
+ * within job descriptions. Uses dangerouslySetInnerHTML to render pre-sanitized HTML.
+ * 
+ * @param {JobContentProps} props - Component props
+ * @param {string} props.content - Pre-sanitized HTML content to render
+ * @param {string} [props.className] - Optional additional CSS classes
+ * @returns {React.ReactElement} Styled job content container
+ * 
+ * @security Ensure `content` is sanitized before passing to this component to prevent XSS attacks
+ */
 const JobContent: React.FC<JobContentProps> = ({ content, className = "" }) => {
🧹 Nitpick comments (4)
apps/web/src/components/glossary/alphabet-nav.tsx (1)

15-44: Consider extracting scroll tracking to a custom hook for improved maintainability.

The scroll tracking logic in the useEffect is well-structured but represents a distinct concern that could be isolated into a reusable custom hook (e.g., useScrollTracking). This would make the component more focused and align better with keeping individual functions concise.

🔎 Example custom hook extraction
+/**
+ * Tracks which letter section is currently in view during scrolling.
+ * @param {string[]} availableLetters - Letters with entries
+ * @returns {number | null} Index of active letter, or null if none
+ */
+function useScrollTracking(availableLetters: string[]): number | null {
+  const alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
+  const [activeLetterIdx, setActiveLetterIdx] = useState<number | null>(null);
+  
+  useEffect(() => {
+    const handleScroll = () => {
+      const scrollPosition = window.scrollY + 150;
+      let currentSection: string | null = null;
+      
+      for (const letter of availableLetters) {
+        const element = document.getElementById(letter);
+        if (element) {
+          const offsetTop = element.offsetTop;
+          const offsetBottom = offsetTop + element.offsetHeight;
+          
+          if (scrollPosition >= offsetTop && scrollPosition < offsetBottom) {
+            currentSection = letter;
+            break;
+          }
+        }
+      }
+      
+      setActiveLetterIdx(currentSection ? alphabet.indexOf(currentSection) : null);
+    };
+    
+    window.addEventListener('scroll', handleScroll);
+    return () => window.removeEventListener('scroll', handleScroll);
+  }, [alphabet, availableLetters]);
+  
+  return activeLetterIdx;
+}
+
 export function GlossaryAlphabetNav({ availableLetters }: GlossaryAlphabetNavProps) {
-  const alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
-  const [activeLetterIdx, setActiveLetterIdx] = useState<number | null>(null);
+  const alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
+  const activeLetterIdx = useScrollTracking(availableLetters);
-  
-  useEffect(() => {
-    // ... scroll tracking logic ...
-  }, [alphabet, availableLetters]);

This would reduce the component body and make the scroll tracking logic reusable across other components if needed.

apps/web/src/components/marketing/agency/local-portfolio.tsx (1)

78-82: Use stable identifier as React key instead of array index.

Using tagIndex as the key can cause issues if the tags array order changes. Use a stable identifier like the tag enum value itself as the key.

🔎 Proposed fix
           {project.tags.map((tag, tagIndex) => (
-            <span key={tagIndex} className="px-2 py-1 bg-muted text-xs rounded-full">
+            <span key={tag} className="px-2 py-1 bg-muted text-xs rounded-full">
               {getTagLabel(tag)}
             </span>
           ))}
apps/web/src/components/marketing/services/sections/index.tsx (1)

8-8: Consider adding JSDoc comments to exported components.

Per coding guidelines, exported functions should have JSDoc comments describing their purpose and usage. This would improve code documentation for these marketing section components.

Example JSDoc format
+/**
+ * Displays value proposition section with three key features:
+ * flexible approach, optimized time-to-market, and dedicated team.
+ */
 export const ValuePropositionSection = () => (

Also applies to: 102-102, 136-136, 176-176

apps/web/package.json (1)

55-63: Tailwind v4 packages look correct; note browser compatibility requirements.

The addition of @tailwindcss/postcss and upgrade to tailwindcss v4.1.18 align with the official Tailwind CSS v4 migration path. However, be aware that Tailwind v4 requires modern browsers:

  • Chrome 111+ (released March 2023)
  • Safari 16.4+ (released March 2023)
  • Firefox 128+ (released July 2024)

Users on older browsers will no longer be supported. Ensure this aligns with your browser support policy and consider adding appropriate documentation or user notifications if needed.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 428ecec and fb579a0.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (63)
  • .changeset/add-sitemap-options.md
  • .gitignore
  • apps/web/package.json
  • apps/web/postcss.config.mjs
  • apps/web/src/app/[locale]/agency/[city]/page.tsx
  • apps/web/src/app/[locale]/agency/page.tsx
  • apps/web/src/app/[locale]/glossary/page.tsx
  • apps/web/src/app/[locale]/glossary/tags/page.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • apps/web/src/app/not-found.tsx
  • apps/web/src/components/glossary/alphabet-nav.tsx
  • apps/web/src/components/glossary/search.tsx
  • apps/web/src/components/marketing/agency/city-hero-section.tsx
  • apps/web/src/components/marketing/agency/contact-cta.tsx
  • apps/web/src/components/marketing/agency/local-portfolio.tsx
  • apps/web/src/components/marketing/landing/customer/featured/index.tsx
  • apps/web/src/components/marketing/landing/page-switcher/index.tsx
  • apps/web/src/components/marketing/landing/visitor/featured/index.tsx
  • apps/web/src/components/marketing/landing/visitor/projects/card/index.tsx
  • apps/web/src/components/marketing/landing/visitor/team/grid/card/index.tsx
  • apps/web/src/components/marketing/legal/page.tsx
  • apps/web/src/components/marketing/navbar/index.tsx
  • apps/web/src/components/marketing/navbar/navigation/agencies/index.tsx
  • apps/web/src/components/marketing/navbar/navigation/projects/index.tsx
  • apps/web/src/components/marketing/navbar/navigation/services/index.tsx
  • apps/web/src/components/marketing/npo/donations/index.tsx
  • apps/web/src/components/marketing/services/feature-section.tsx
  • apps/web/src/components/marketing/services/sections/index.tsx
  • apps/web/src/components/marketing/services/service-layout.tsx
  • apps/web/src/components/marketing/services/service-overview.tsx
  • apps/web/src/components/ui/animated-shiny-text.tsx
  • apps/web/src/components/ui/badge.tsx
  • apps/web/src/components/ui/button.tsx
  • apps/web/src/components/ui/dropdown-menu.tsx
  • apps/web/src/components/ui/job-content.tsx
  • apps/web/src/components/ui/navigation-menu.tsx
  • apps/web/src/components/ui/scroll-based-velocity.tsx
  • apps/web/src/components/ui/sheet.tsx
  • apps/web/src/components/ui/tabs.tsx
  • apps/web/src/components/ui/toast.tsx
  • apps/web/src/screens/marketing/careers/index.tsx
  • apps/web/src/screens/marketing/careers/job-details.tsx
  • apps/web/src/screens/marketing/careers/job-list.tsx
  • apps/web/src/screens/marketing/contact/index.tsx
  • apps/web/src/screens/marketing/npo/index.tsx
  • apps/web/src/screens/marketing/projects/details/index.tsx
  • apps/web/src/screens/marketing/projects/index.tsx
  • apps/web/src/screens/marketing/services/index.tsx
  • apps/web/src/styles/globals.css
  • apps/web/tailwind.config.ts
  • examples/next-sitemap/app/CHANGELOG.md
  • examples/next-sitemap/app/package.json
  • examples/translations/next-app/CHANGELOG.md
  • examples/translations/next-app/package.json
  • examples/translations/next-pages/CHANGELOG.md
  • examples/translations/next-pages/package.json
  • examples/translations/react/CHANGELOG.md
  • examples/translations/react/package.json
  • packages/next-sitemap/CHANGELOG.md
  • packages/next-sitemap/package.json
  • packages/translations/CHANGELOG.md
  • packages/translations/package.json
  • packages/translations/src/next/components/link.tsx
💤 Files with no reviewable changes (3)
  • apps/web/tailwind.config.ts
  • apps/web/src/app/[locale]/layout.tsx
  • .changeset/add-sitemap-options.md
🧰 Additional context used
📓 Path-based instructions (4)
apps/web/src/app/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

apps/web/src/app/**/*.{ts,tsx}: Use getTranslation function from @/lib/translations.server for translations in Server Components
Use Next.js 16 App Router with pages and API routes organized under [locale]/ for the web application

Files:

  • apps/web/src/app/[locale]/glossary/tags/page.tsx
  • apps/web/src/app/[locale]/glossary/page.tsx
  • apps/web/src/app/[locale]/agency/page.tsx
  • apps/web/src/app/not-found.tsx
  • apps/web/src/app/[locale]/agency/[city]/page.tsx
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Always use 'const' for variable declarations instead of 'var' or 'let' unless reassignment is required
Always add JSDoc comments for exported functions and classes
Use meaningful error messages that describe the context and expected recovery steps
Keep functions under 30 lines of code
All async functions must handle errors with try/catch blocks
Use absolute imports from the 'src' directory instead of relative imports

Files:

  • apps/web/src/app/[locale]/glossary/tags/page.tsx
  • apps/web/src/screens/marketing/services/index.tsx
  • apps/web/src/components/glossary/alphabet-nav.tsx
  • apps/web/src/components/marketing/landing/page-switcher/index.tsx
  • apps/web/src/components/ui/scroll-based-velocity.tsx
  • apps/web/src/components/marketing/landing/visitor/team/grid/card/index.tsx
  • apps/web/src/components/marketing/agency/contact-cta.tsx
  • apps/web/src/components/glossary/search.tsx
  • apps/web/src/components/ui/sheet.tsx
  • apps/web/src/components/marketing/navbar/navigation/agencies/index.tsx
  • apps/web/src/components/marketing/landing/visitor/projects/card/index.tsx
  • apps/web/src/screens/marketing/careers/job-details.tsx
  • apps/web/src/screens/marketing/projects/details/index.tsx
  • apps/web/src/screens/marketing/contact/index.tsx
  • apps/web/src/components/marketing/npo/donations/index.tsx
  • apps/web/src/components/marketing/landing/customer/featured/index.tsx
  • apps/web/src/components/marketing/services/feature-section.tsx
  • apps/web/src/screens/marketing/careers/job-list.tsx
  • apps/web/src/components/ui/badge.tsx
  • apps/web/src/components/ui/dropdown-menu.tsx
  • apps/web/src/app/[locale]/glossary/page.tsx
  • apps/web/src/components/ui/button.tsx
  • apps/web/src/components/marketing/navbar/index.tsx
  • apps/web/src/components/marketing/landing/visitor/featured/index.tsx
  • apps/web/src/components/ui/animated-shiny-text.tsx
  • apps/web/src/components/marketing/services/service-overview.tsx
  • apps/web/src/components/marketing/navbar/navigation/projects/index.tsx
  • apps/web/src/app/[locale]/agency/page.tsx
  • apps/web/src/components/ui/tabs.tsx
  • apps/web/src/components/marketing/agency/city-hero-section.tsx
  • apps/web/src/screens/marketing/npo/index.tsx
  • apps/web/src/screens/marketing/careers/index.tsx
  • apps/web/src/components/marketing/navbar/navigation/services/index.tsx
  • apps/web/src/app/not-found.tsx
  • apps/web/src/components/marketing/services/service-layout.tsx
  • apps/web/src/components/marketing/services/sections/index.tsx
  • apps/web/src/app/[locale]/agency/[city]/page.tsx
  • apps/web/src/components/ui/toast.tsx
  • apps/web/src/components/ui/navigation-menu.tsx
  • apps/web/src/components/marketing/legal/page.tsx
  • apps/web/src/components/ui/job-content.tsx
  • packages/translations/src/next/components/link.tsx
  • apps/web/src/screens/marketing/projects/index.tsx
  • apps/web/src/components/marketing/agency/local-portfolio.tsx
**/*.{jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Prefer functional components with hooks over class components in React

Files:

  • apps/web/src/app/[locale]/glossary/tags/page.tsx
  • apps/web/src/screens/marketing/services/index.tsx
  • apps/web/src/components/glossary/alphabet-nav.tsx
  • apps/web/src/components/marketing/landing/page-switcher/index.tsx
  • apps/web/src/components/ui/scroll-based-velocity.tsx
  • apps/web/src/components/marketing/landing/visitor/team/grid/card/index.tsx
  • apps/web/src/components/marketing/agency/contact-cta.tsx
  • apps/web/src/components/glossary/search.tsx
  • apps/web/src/components/ui/sheet.tsx
  • apps/web/src/components/marketing/navbar/navigation/agencies/index.tsx
  • apps/web/src/components/marketing/landing/visitor/projects/card/index.tsx
  • apps/web/src/screens/marketing/careers/job-details.tsx
  • apps/web/src/screens/marketing/projects/details/index.tsx
  • apps/web/src/screens/marketing/contact/index.tsx
  • apps/web/src/components/marketing/npo/donations/index.tsx
  • apps/web/src/components/marketing/landing/customer/featured/index.tsx
  • apps/web/src/components/marketing/services/feature-section.tsx
  • apps/web/src/screens/marketing/careers/job-list.tsx
  • apps/web/src/components/ui/badge.tsx
  • apps/web/src/components/ui/dropdown-menu.tsx
  • apps/web/src/app/[locale]/glossary/page.tsx
  • apps/web/src/components/ui/button.tsx
  • apps/web/src/components/marketing/navbar/index.tsx
  • apps/web/src/components/marketing/landing/visitor/featured/index.tsx
  • apps/web/src/components/ui/animated-shiny-text.tsx
  • apps/web/src/components/marketing/services/service-overview.tsx
  • apps/web/src/components/marketing/navbar/navigation/projects/index.tsx
  • apps/web/src/app/[locale]/agency/page.tsx
  • apps/web/src/components/ui/tabs.tsx
  • apps/web/src/components/marketing/agency/city-hero-section.tsx
  • apps/web/src/screens/marketing/npo/index.tsx
  • apps/web/src/screens/marketing/careers/index.tsx
  • apps/web/src/components/marketing/navbar/navigation/services/index.tsx
  • apps/web/src/app/not-found.tsx
  • apps/web/src/components/marketing/services/service-layout.tsx
  • apps/web/src/components/marketing/services/sections/index.tsx
  • apps/web/src/app/[locale]/agency/[city]/page.tsx
  • apps/web/src/components/ui/toast.tsx
  • apps/web/src/components/ui/navigation-menu.tsx
  • apps/web/src/components/marketing/legal/page.tsx
  • apps/web/src/components/ui/job-content.tsx
  • packages/translations/src/next/components/link.tsx
  • apps/web/src/screens/marketing/projects/index.tsx
  • apps/web/src/components/marketing/agency/local-portfolio.tsx
apps/web/src/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

apps/web/src/components/**/*.{ts,tsx}: Use useTranslation hook from @onruntime/translations/react for translations in Client Components
Store React components in the components/ directory, organized into subdirectories: ui/, layout/, and marketing/

Files:

  • apps/web/src/components/glossary/alphabet-nav.tsx
  • apps/web/src/components/marketing/landing/page-switcher/index.tsx
  • apps/web/src/components/ui/scroll-based-velocity.tsx
  • apps/web/src/components/marketing/landing/visitor/team/grid/card/index.tsx
  • apps/web/src/components/marketing/agency/contact-cta.tsx
  • apps/web/src/components/glossary/search.tsx
  • apps/web/src/components/ui/sheet.tsx
  • apps/web/src/components/marketing/navbar/navigation/agencies/index.tsx
  • apps/web/src/components/marketing/landing/visitor/projects/card/index.tsx
  • apps/web/src/components/marketing/npo/donations/index.tsx
  • apps/web/src/components/marketing/landing/customer/featured/index.tsx
  • apps/web/src/components/marketing/services/feature-section.tsx
  • apps/web/src/components/ui/badge.tsx
  • apps/web/src/components/ui/dropdown-menu.tsx
  • apps/web/src/components/ui/button.tsx
  • apps/web/src/components/marketing/navbar/index.tsx
  • apps/web/src/components/marketing/landing/visitor/featured/index.tsx
  • apps/web/src/components/ui/animated-shiny-text.tsx
  • apps/web/src/components/marketing/services/service-overview.tsx
  • apps/web/src/components/marketing/navbar/navigation/projects/index.tsx
  • apps/web/src/components/ui/tabs.tsx
  • apps/web/src/components/marketing/agency/city-hero-section.tsx
  • apps/web/src/components/marketing/navbar/navigation/services/index.tsx
  • apps/web/src/components/marketing/services/service-layout.tsx
  • apps/web/src/components/marketing/services/sections/index.tsx
  • apps/web/src/components/ui/toast.tsx
  • apps/web/src/components/ui/navigation-menu.tsx
  • apps/web/src/components/marketing/legal/page.tsx
  • apps/web/src/components/ui/job-content.tsx
  • apps/web/src/components/marketing/agency/local-portfolio.tsx
🧠 Learnings (5)
📚 Learning: 2025-12-30T20:07:40.279Z
Learnt from: antoinekm
Repo: onRuntime/onruntime PR: 367
File: apps/web/src/components/marketing/navbar/index.tsx:0-0
Timestamp: 2025-12-30T20:07:40.279Z
Learning: In apps/web/src/components/marketing/navbar/index.tsx, the Projects dropdown intentionally uses `project.name` (not localized). Project names are treated as canonical/proper nouns and should not be routed through i18n.

Applied to files:

  • apps/web/src/components/marketing/navbar/navigation/agencies/index.tsx
  • apps/web/src/components/marketing/landing/visitor/projects/card/index.tsx
  • apps/web/src/components/marketing/navbar/index.tsx
  • apps/web/src/components/marketing/navbar/navigation/projects/index.tsx
📚 Learning: 2025-12-31T00:13:11.117Z
Learnt from: CR
Repo: onRuntime/onruntime PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-31T00:13:11.117Z
Learning: Applies to apps/web/src/components/**/*.{ts,tsx} : Use `useTranslation` hook from `onruntime/translations/react` for translations in Client Components

Applied to files:

  • examples/translations/react/CHANGELOG.md
  • packages/translations/CHANGELOG.md
  • examples/translations/next-app/CHANGELOG.md
  • packages/translations/package.json
  • examples/translations/react/package.json
  • packages/translations/src/next/components/link.tsx
📚 Learning: 2025-12-31T00:13:11.118Z
Learnt from: CR
Repo: onRuntime/onruntime PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-31T00:13:11.118Z
Learning: Applies to apps/web/src/components/**/*.{ts,tsx} : Store React components in the `components/` directory, organized into subdirectories: `ui/`, `layout/`, and `marketing/`

Applied to files:

  • apps/web/src/screens/marketing/projects/details/index.tsx
  • apps/web/src/components/marketing/services/sections/index.tsx
  • apps/web/src/components/marketing/agency/local-portfolio.tsx
📚 Learning: 2025-12-30T19:53:08.661Z
Learnt from: antoinekm
Repo: onRuntime/onruntime PR: 367
File: apps/web/src/app/[locale]/services/[category]/[service]/page.tsx:83-90
Timestamp: 2025-12-30T19:53:08.661Z
Learning: In apps/web/src/app/[locale]/services/[category]/[service]/page.tsx, the benefits section title intentionally uses `serviceName` (original casing) while other sections may use `serviceNameLower`. This is by design and should not be changed to lowercase.

Applied to files:

  • apps/web/src/components/marketing/services/service-overview.tsx
  • apps/web/src/components/marketing/navbar/navigation/services/index.tsx
  • apps/web/src/components/marketing/services/service-layout.tsx
  • apps/web/src/components/marketing/services/sections/index.tsx
  • apps/web/src/app/[locale]/agency/[city]/page.tsx
📚 Learning: 2025-12-31T00:13:11.118Z
Learnt from: CR
Repo: onRuntime/onruntime PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-31T00:13:11.118Z
Learning: Applies to apps/web/src/app/**/*.{ts,tsx} : Use Next.js 16 App Router with pages and API routes organized under `[locale]/` for the web application

Applied to files:

  • packages/translations/src/next/components/link.tsx
🧬 Code graph analysis (2)
apps/web/src/components/marketing/landing/page-switcher/index.tsx (1)
apps/web/src/components/ui/tabs.tsx (1)
  • TabsList (55-55)
examples/translations/next-app/package.json (4)
packages/translations/src/next/contexts/app-context.tsx (1)
  • newLocale (40-69)
examples/translations/next-pages/pages/_app.tsx (1)
  • App (5-19)
examples/translations/next-app/app/[lang]/about/page.tsx (1)
  • About (6-41)
examples/translations/next-app/app/[lang]/layout.tsx (1)
  • lang (8-8)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Agent
🔇 Additional comments (87)
apps/web/src/components/marketing/landing/visitor/projects/card/index.tsx (1)

48-48: Tailwind v4 migration looks good.

The flex-growgrow change is correct per Tailwind v4 syntax updates. This aligns with the broader flex-grow-*grow-* migration across the codebase.

apps/web/src/screens/marketing/careers/job-list.tsx (1)

138-138: Correct Tailwind v4 migration.

The class name change from flex-shrink-0 to shrink-0 correctly aligns with Tailwind CSS v4's breaking changes.

apps/web/src/components/glossary/alphabet-nav.tsx (1)

60-60: Verify that shadow-2xs is a valid Tailwind v4 utility.

The Tailwind v4 documentation provided doesn't explicitly list shadow-2xs among the standard shadow utilities. Verify that this utility is either:

  • A standard Tailwind v4 utility not covered in the provided docs
  • A custom utility defined in your project's Tailwind v4 configuration (CSS or tailwind.config)
apps/web/src/components/marketing/landing/visitor/team/grid/card/index.tsx (1)

27-27: LGTM! Clean Tailwind v4 migration.

The change from flex-[1] (arbitrary value) to flex-1 (standard utility) is correct and follows Tailwind v4 best practices. Both are functionally equivalent, but using the standard utility improves code consistency.

apps/web/src/components/marketing/navbar/navigation/agencies/index.tsx (1)

43-43: Correct Tailwind v4 migration.

The change from outline-none to outline-hidden correctly follows the Tailwind v4 breaking change where outline-none now only removes the outline style, and outline-hidden is required to completely hide the outline.

apps/web/src/components/marketing/navbar/navigation/projects/index.tsx (1)

26-26: Correct Tailwind v4 migration applied consistently.

All three Link components correctly update outline-none to outline-hidden, following Tailwind v4's breaking change. The migration is applied consistently across FeaturedProjectCard, ProjectCard, and the main navigation link.

Also applies to: 56-56, 101-101

apps/web/src/components/marketing/navbar/navigation/services/index.tsx (1)

54-54: Correct Tailwind v4 migration applied consistently.

Both Link components correctly update outline-none to outline-hidden, aligning with Tailwind v4's breaking change. The migration maintains the intended outline behavior while using the new v4 syntax.

Also applies to: 97-97

apps/web/src/components/marketing/agency/local-portfolio.tsx (2)

1-10: Imports and file structure look good.

The component correctly uses absolute imports with the @/ alias, follows the required subdirectory organization (components/marketing/agency/), and properly imports from @onruntime/translations/next for internationalization in Server Components.

Based on learnings, this file follows the prescribed component organization structure for the components/marketing/ directory.


66-66: Tailwind v4 migration is complete across the codebase.

The grow utility on line 66 is correctly using Tailwind v4 syntax. A search of the entire codebase found no remaining flex-grow utilities, confirming the migration has been consistently applied throughout.

apps/web/src/components/marketing/landing/page-switcher/index.tsx (1)

20-20: Shadow token updated for visual consistency.

The shadow class change from shadow-xs to shadow-2xs aligns with the Tailwind v4 migration and maintains consistent visual hierarchy across marketing components.

apps/web/src/components/ui/sheet.tsx (1)

67-67: Correct Tailwind v4 migration for focus outline.

The change from focus:outline-none to focus:outline-hidden aligns with Tailwind v4 requirements, where outline-hidden completely removes the outline. Accessibility is preserved through the focus:ring-2 utility.

apps/web/src/components/marketing/navbar/index.tsx (1)

204-204: Shadow token updated for visual consistency.

The shadow reduction from shadow-xs to shadow-2xs maintains visual consistency with other navigation elements in the PR and aligns with the Tailwind v4 migration.

apps/web/src/components/marketing/npo/donations/index.tsx (1)

97-97: Correct Tailwind v4 migration for input focus styling.

The update from focus:outline-none to focus:outline-hidden properly migrates to Tailwind v4 syntax. The input maintains keyboard accessibility through the focus:ring-2 utility.

apps/web/src/components/ui/tabs.tsx (2)

32-32: Tailwind v4 migration applied correctly.

Both the focus outline change (outline-hidden) and shadow refinement (shadow-sm for active state) align with Tailwind v4 standards. Keyboard accessibility is maintained through focus-visible:ring-2.


47-47: Focus styling updated for Tailwind v4.

The migration from focus-visible:outline-none to focus-visible:outline-hidden is correct for Tailwind v4, with accessibility preserved through the ring utilities.

apps/web/src/components/ui/badge.tsx (1)

7-12: Tailwind v4 migration applied correctly.

Both changes align with Tailwind v4 requirements:

  • outline-hidden properly replaces outline-none for complete outline removal
  • Shadow reduction from shadow to shadow-sm adjusts visual weight consistently

Keyboard focus accessibility is preserved through the focus:ring-2 utility.

apps/web/src/components/ui/navigation-menu.tsx (4)

43-43: Comprehensive Tailwind v4 migration for navigation menu trigger.

All updates are correct for Tailwind v4:

  • outline-hidden replaces outline-none per v4 requirements
  • cursor-pointer improves UX clarity
  • data-active attribute syntax update aligns with v4 conventions

57-57: Icon alignment updated to Tailwind v4 syntax.

The change from top-[1px] to top-px uses the native Tailwind v4 utility, which is cleaner and more idiomatic.


88-88: CSS variable syntax correctly migrated to Tailwind v4.

Multiple v4 migrations applied correctly:

  • Bracket syntax [var(--...)] → parentheses syntax (--...) as required by v4
  • Shadow reduced to shadow-sm for consistency
  • All viewport sizing variables properly updated

106-106: Z-index utility updated to Tailwind v4 syntax.

The change from z-[1] to z-1 uses the native v4 utility support for numeric z-index values.

apps/web/src/components/ui/button.tsx (1)

7-16: Button component fully migrated to Tailwind v4.

All updates are correct and consistent:

  • outline-hidden properly replaces outline-none per v4 requirements
  • cursor-pointer added for improved UX clarity
  • Shadow tokens adjusted intentionally across variants for visual hierarchy:
    • Default: shadow-sm (reduced from shadow)
    • Outline: shadow-xs (reduced from shadow-sm)
    • Secondary: shadow-xs (reduced from shadow-sm)

Keyboard accessibility is maintained through focus-visible:ring-1.

apps/web/src/components/ui/dropdown-menu.tsx (6)

30-30: LGTM! Correct Tailwind v4 migration.

The outline-hidden class correctly replaces outline-none for complete outline removal in v4. The data attribute selector updates and utility classes are properly migrated.


50-50: LGTM! CSS variable and sizing syntax updated for v4.

  • min-w-32 correctly replaces min-w-[8rem] using Tailwind's standard scale
  • origin-(--radix-dropdown-menu-content-transform-origin) uses the new v4 parentheses syntax for CSS variables

68-69: LGTM! Proper v4 CSS variable syntax migration.

  • max-h-(--radix-dropdown-menu-content-available-height) correctly uses parentheses instead of brackets with var()
  • origin-(...) syntax is consistent with v4 conventions

87-87: LGTM! Boolean data attribute syntax simplified for v4.

The data-disabled: shorthand correctly replaces data-[disabled]: for boolean data attributes, which is the preferred v4 syntax.


103-103: LGTM!

Consistent v4 migration with outline-hidden and data-disabled: syntax.


127-127: LGTM!

Consistent with the other item components' v4 migration pattern.

apps/web/src/components/ui/toast.tsx (4)

19-19: LGTM! z-index updated for v4.

z-100 correctly replaces z-[100] using Tailwind v4's dynamic utility values, which no longer require arbitrary value brackets for numeric scales.


27-28: LGTM! Toast animations properly migrated to v4 syntax.

  • CSS variable translations updated to parentheses syntax: translate-x-(--radix-toast-swipe-end-x)
  • Variant order corrected to sm:data-[state=open]:slide-in-from-bottom-full (left-to-right evaluation in v4)

65-65: LGTM!

focus:outline-hidden correctly replaces focus:outline-none for complete outline removal in v4.


80-80: LGTM!

Consistent focus:outline-hidden usage matching other components in the v4 migration.

apps/web/src/styles/globals.css (5)

1-5: LGTM!

The import syntax and custom dark variant are correctly implemented for Tailwind v4. Using :where() for specificity control is a good practice for the class-based dark mode strategy.


7-39: LGTM!

The CSS variable structure follows shadcn/ui conventions correctly. The Tailwind internal variable fallbacks (lines 9-12) are a good defensive measure for browsers lacking @property support.


41-64: LGTM!

Dark mode variable overrides are well-structured and consistent with the light mode definitions.


131-155: LGTM!

The base layer styles correctly apply Tailwind v4 conventions:

  • font-normal! uses the correct v4 important modifier placement (moved from prefix to suffix)
  • Restoring cursor: pointer for interactive elements is necessary since Tailwind v4 removed the default pointer cursor for buttons

These are both documented breaking changes in v4 that have been properly addressed.


66-129: The font configuration is correctly set up. The --font-figtree CSS variable is properly defined by the Next.js font loader in apps/web/src/app/[locale]/layout.tsx (imported from next/font/google and configured with variable: "--font-figtree"), and it is applied to the HTML element where it becomes globally available. The globals.css code correctly references this variable.

Likely an incorrect or invalid review comment.

apps/web/src/components/ui/scroll-based-velocity.tsx (1)

113-113: The line-height conversion is correct.

In Tailwind v4, leading-20 equals 5rem (driven by the spacing scale where 20 × 0.25rem = 5rem). The change from md:leading-[5rem] to md:leading-20 is a valid migration to a built-in utility and maintains visual consistency.

apps/web/src/app/[locale]/glossary/tags/page.tsx (1)

50-50: LGTM! Correct Tailwind v4 migration.

The utility class update from flex-shrink-0 to shrink-0 correctly follows Tailwind v4's breaking changes.

apps/web/src/components/marketing/agency/contact-cta.tsx (1)

42-42: LGTM! Correct Tailwind v4 migration.

The utility class update from flex-shrink-0 to shrink-0 correctly follows Tailwind v4's breaking changes.

apps/web/src/app/[locale]/agency/[city]/page.tsx (1)

156-156: LGTM! Correct Tailwind v4 migration.

The utility class update from flex-shrink-0 to shrink-0 correctly follows Tailwind v4's breaking changes.

apps/web/src/components/glossary/search.tsx (1)

74-74: LGTM! Correct Tailwind v4 migration.

The update from focus:outline-none to focus:outline-hidden correctly follows Tailwind v4's breaking changes, where outline-none now only removes the outline style, and outline-hidden is required to remove it completely.

apps/web/src/components/ui/animated-shiny-text.tsx (1)

26-28: LGTM! Correct Tailwind v4 migrations.

The updates correctly follow Tailwind v4's breaking changes:

  • Line 26: Background utilities migrated to bracket syntax (bg-position-[0_0], bg-size-[var(--shiny-width)_100%])
  • Line 28: Gradient direction utility updated from bg-gradient-to-r to bg-linear-to-r
apps/web/src/components/marketing/legal/page.tsx (1)

40-40: LGTM! Correct Tailwind v4 migration.

The mask utility update from [mask-image:radial-gradient(...)] to mask-[radial-gradient(...)] correctly follows Tailwind v4's arbitrary value syntax changes.

apps/web/src/screens/marketing/services/index.tsx (1)

103-103: LGTM! Correct Tailwind v4 migration.

The mask utility update from [mask-image:radial-gradient(...)] to mask-[radial-gradient(...)] correctly follows Tailwind v4's arbitrary value syntax changes.

apps/web/src/components/marketing/landing/customer/featured/index.tsx (1)

15-48: LGTM! Correct Tailwind v4 migrations.

The updates correctly follow Tailwind v4's breaking changes:

  • Line 15: Gradient direction utility updated from bg-gradient-to-t to bg-linear-to-t
  • Line 48: Mask utility updated from [mask-image:radial-gradient(...)] to mask-[radial-gradient(...)]
apps/web/src/screens/marketing/careers/job-details.tsx (1)

144-144: LGTM! Tailwind v4 utility updates are correct.

The mask utility and flex shrink changes correctly follow Tailwind v4 syntax:

  • mask-[linear-gradient(...)] uses the proper arbitrary value format
  • shrink-0 is the correct replacement for flex-shrink-0

These changes preserve the visual appearance while adopting the new syntax.

Also applies to: 192-192, 205-205, 218-218, 232-232, 246-246

apps/web/src/app/[locale]/agency/page.tsx (1)

67-67: LGTM! Tailwind v4 gradient and mask utilities are correct.

The changes properly adopt Tailwind v4 syntax:

  • mask-[radial-gradient(...)] uses the correct arbitrary value format
  • bg-linear-to-l is the correct v4 replacement for bg-gradient-to-l

Visual appearance is preserved with the new syntax.

Also applies to: 239-239

apps/web/src/screens/marketing/contact/index.tsx (1)

84-84: LGTM! Mask utility correctly updated to Tailwind v4 syntax.

The change from [mask-image:radial-gradient(...)] to mask-[radial-gradient(...)] properly adopts the v4 arbitrary value format while preserving the visual effect.

apps/web/src/components/marketing/landing/visitor/featured/index.tsx (1)

17-17: LGTM! Tailwind v4 gradient and mask utilities are correctly applied.

All changes properly adopt the new syntax:

  • bg-linear-to-t correctly replaces bg-gradient-to-t
  • mask-[radial-gradient(...)] uses the proper arbitrary value format

The visual appearance remains unchanged.

Also applies to: 51-51, 67-67

apps/web/src/components/marketing/agency/city-hero-section.tsx (1)

57-57: LGTM! Tailwind v4 utilities correctly updated.

All changes properly follow the v4 migration:

  • backdrop-blur-xs and shadow-xs use the updated scale naming
  • mask-[radial-gradient(...)] uses the correct arbitrary value format

Visual consistency is maintained with the new utility values.

Also applies to: 66-66, 77-79, 94-94

apps/web/src/app/[locale]/glossary/page.tsx (1)

59-59: LGTM! Tailwind v4 flex and mask utilities are correct.

The changes properly adopt v4 syntax:

  • mask-[radial-gradient(...)] uses the correct arbitrary value format
  • grow is the correct v4 replacement for flex-grow

Functionality and appearance remain unchanged.

Also applies to: 96-96

apps/web/src/screens/marketing/npo/index.tsx (1)

78-78: LGTM! Tailwind v4 utilities correctly updated throughout.

All changes properly follow the v4 migration:

  • mask-[radial-gradient(...)] uses the correct arbitrary value format
  • shrink-0 correctly replaces flex-shrink-0 on all icon elements
  • bg-linear-to-l is the correct v4 replacement for bg-gradient-to-l

Visual appearance and layout behavior are preserved.

Also applies to: 281-281, 287-287, 293-293, 299-299, 305-305, 311-311, 435-435

apps/web/src/screens/marketing/projects/index.tsx (1)

50-50: LGTM! Tailwind v4 utilities correctly applied.

The changes properly adopt v4 syntax:

  • mask-[radial-gradient(...)] uses the correct arbitrary value format
  • shrink-0 correctly replaces flex-shrink-0 on all CheckCircle icons

Layout behavior and visual appearance are maintained.

Also applies to: 223-223, 234-234, 245-245

apps/web/src/screens/marketing/projects/details/index.tsx (3)

116-123: LGTM! Correct Tailwind v4 mask utility syntax.

The mask utility has been correctly updated from the v3 arbitrary property syntax [mask-image:radial-gradient(...)] to the v4 arbitrary value syntax mask-[radial-gradient(...)].


176-183: LGTM! Correct Tailwind v4 mask utility syntax.

Consistent with the earlier mask utility update, this has been correctly migrated to the v4 arbitrary value syntax.


270-270: LGTM! Correct Tailwind v4 gradient utility syntax.

The gradient utilities have been correctly updated from bg-gradient-to-l to bg-linear-to-l, following Tailwind v4's new linear gradient naming convention.

Also applies to: 518-518

apps/web/src/screens/marketing/careers/index.tsx (2)

91-98: LGTM! Correct Tailwind v4 mask utility syntax.

The mask utility has been correctly updated to the v4 arbitrary value syntax mask-[radial-gradient(...)].


212-212: LGTM! Correct Tailwind v4 gradient utility syntax.

The gradient utility has been correctly updated to bg-linear-to-l following Tailwind v4's naming convention.

apps/web/src/components/marketing/services/service-overview.tsx (4)

100-111: LGTM! Correct Tailwind v4 utility scale updates.

The backdrop blur and shadow utilities have been correctly updated to the new scale: backdrop-blur-xs and shadow-xs.


166-193: LGTM! Correct Tailwind v4 backdrop blur scale update.

The backdrop blur utility has been correctly updated to backdrop-blur-xs following Tailwind v4's new scale system.


201-208: LGTM! Correct Tailwind v4 mask utility syntax.

The mask utilities have been correctly updated to the v4 arbitrary value syntax mask-[radial-gradient(...)].

Also applies to: 265-272


330-358: LGTM! Correct Tailwind v4 gradient and mask utility updates.

Both the gradient utility (bg-linear-to-bl) and mask utility have been correctly migrated to Tailwind v4 syntax.

apps/web/src/components/marketing/services/service-layout.tsx (3)

58-96: LGTM! Correct Tailwind v4 utility scale updates.

The backdrop blur and shadow utilities have been consistently updated across all decorative elements and cards to the new scale: backdrop-blur-xs and shadow-xs. This maintains visual consistency while following Tailwind v4's naming conventions.


104-111: LGTM! Correct Tailwind v4 mask utility syntax.

The mask utility has been correctly updated to the v4 arbitrary value syntax mask-[radial-gradient(...)].


118-137: LGTM! Correct Tailwind v4 gradient utility syntax.

The gradient utility has been correctly updated to bg-linear-to-bl following Tailwind v4's new linear gradient naming convention.

apps/web/src/components/marketing/services/sections/index.tsx (2)

106-108: LGTM! Gradient utilities correctly migrated to Tailwind v4 syntax.

The transition from bg-gradient-to-r/l to bg-linear-to-r/l aligns with Tailwind v4's new gradient system. The color stops (from-muted to-transparent) remain compatible.


154-154: LGTM! Additional Tailwind v4 utility migrations are correct.

Both changes follow the v4 migration guide:

  • Line 154: Gradient utility correctly updated to bg-linear-to-l
  • Line 220: Flex utility correctly shortened from flex-shrink-0 to shrink-0

Also applies to: 220-220

apps/web/src/components/ui/job-content.tsx (1)

24-24: The hover behavior claim is incorrect—this file was newly created in the Tailwind v4 migration, not modified from a previous version.

The original review assumes a change from [&_a]:hover:underline to hover:[&_a]:underline, but the git history shows this component was created fresh during the v4 migration with hover:[&_a]:underline as the intended design. The behavior is not a breaking change but rather the intended hover interaction for this component.

However, the component is missing JSDoc documentation. As an exported component, it should include a JSDoc comment describing its purpose, props, and usage in accordance with the coding guidelines.

Likely an incorrect or invalid review comment.

examples/translations/next-pages/package.json (1)

3-3: LGTM! Version bump is consistent with the broader translations package update.

The patch version bump aligns with the coordinated update across the translations ecosystem.

.gitignore (1)

47-48: LGTM! Standard .gitignore entry for temporary files.

Adding the temp/ directory to .gitignore is appropriate and follows standard practices.

examples/translations/next-app/CHANGELOG.md (1)

1-8: LGTM! Changelog entry properly documents the dependency update.

The changelog follows standard formatting and accurately reflects the version bump and dependency update.

packages/next-sitemap/package.json (1)

3-3: LGTM! Minor version bump is appropriate for the new sitemap options.

The version bump from 0.1.0 to 0.2.0 correctly follows semantic versioning for the addition of new features (sitemap generation options).

apps/web/src/app/not-found.tsx (1)

3-3: LGTM! Proper use of Tailwind's semantic utility class.

Replacing the arbitrary value h-[100vh] with the semantic h-screen utility is a best practice and aligns well with the Tailwind v4 migration.

packages/translations/CHANGELOG.md (1)

1-7: LGTM! Changelog clearly documents the Link component fix.

The changelog entry properly describes the protocol-based URL handling improvement for the Link component.

examples/translations/next-pages/CHANGELOG.md (1)

1-8: LGTM! Changelog entry properly documents the dependency update.

The changelog follows standard formatting and accurately reflects the version bump and dependency update.

examples/translations/next-app/package.json (1)

3-3: LGTM! Version bump is consistent with the coordinated translations package update.

The patch version bump aligns with the broader translations ecosystem update.

examples/next-sitemap/app/package.json (1)

3-3: Version bump looks correct.

Aligns with the dependency update documented in the corresponding CHANGELOG.md.

packages/next-sitemap/CHANGELOG.md (1)

1-12: LGTM - Changelog entry is clear and well-structured.

Documents the new sitemap configuration options appropriately.

examples/next-sitemap/app/CHANGELOG.md (1)

1-8: Changelog entry is appropriate.

Correctly documents the dependency update to @onruntime/next-sitemap@0.2.0.

packages/translations/package.json (1)

3-3: Version bump is consistent.

Aligns with the corresponding CHANGELOG.md entry for 0.1.1.

examples/translations/react/CHANGELOG.md (1)

1-8: Changelog is appropriate.

examples/translations/react/package.json (1)

3-3: Version bump is consistent.

packages/translations/src/next/components/link.tsx (1)

21-28: Protocol detection logic is correctly implemented.

The regex pattern /^[a-zA-Z][a-zA-Z0-9+.-]*:/ properly matches URI schemes according to RFC 3986, correctly identifying protocol-based URLs like mailto:, tel:, and sms:. These URLs appropriately bypass locale prefixing, as they represent external or system-level links rather than internal routes.

The implementation maintains backward compatibility while extending functionality to handle additional URL protocols.

apps/web/postcss.config.mjs (1)

1-8: PostCSS configuration correctly updated for Tailwind v4.

The migration from separate tailwindcss and autoprefixer plugins to the unified @tailwindcss/postcss plugin is correct. Tailwind v4's Oxide engine includes built-in Lightning CSS integration that handles vendor prefixes, nesting, and minification automatically. CSS files have been properly updated to use the new @import "tailwindcss" syntax, and the @tailwindcss/postcss dependency is present in package.json.

apps/web/package.json (3)

48-48: tailwind-merge v3.4.0 is compatible with Tailwind CSS v4.

Version 3.4.0 officially supports Tailwind CSS v4.0–v4.1, including the breaking syntax changes. No further action needed.


49-49: No further action needed. The migration to tw-animate-css v1.4.0 is complete and properly implemented.

Verification results:

  • tw-animate-css v1.4.0 is confirmed compatible with Tailwind CSS v4.1.18
  • ✓ CSS import is correctly configured (@import "tw-animate-css" in globals.css)
  • ✓ All animation utilities in use (animate-accordion-up/down, animate-in/out, slide-in/out, fade-in/out, zoom-in/out) are standard tw-animate-css classes
  • ✓ No remaining references to tailwindcss-animate in the codebase
  • ✓ The package works as a direct replacement requiring only the CSS import (no plugin registration needed)

22-28: @radix-ui package updates are safe to use.

The @radix-ui packages (accordion 1.2.12, dialog 1.1.15, navigation-menu 1.2.14, slot 1.2.4, tabs 1.1.13, toast 1.2.15) have no documented breaking changes in these versions and are confirmed compatible with React 19.0.0. These are minor version updates that follow semantic versioning for backward compatibility.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR migrates the codebase from Tailwind CSS v3 to v4, including configuration changes, dependency updates, and utility class syntax adjustments across components.

  • Updates Tailwind CSS from v3.4.17 to v4.1.18
  • Replaces tailwindcss-animate with tw-animate-css plugin
  • Converts Tailwind config from TypeScript to CSS using @theme directive
  • Updates PostCSS configuration to use @tailwindcss/postcss plugin

Reviewed changes

Copilot reviewed 62 out of 64 changed files in this pull request and generated 42 comments.

Show a summary per file
File Description
pnpm-lock.yaml Updated dependencies for Tailwind v4, removed autoprefixer, added @tailwindcss/postcss
apps/web/package.json Updated Tailwind dependencies and removed autoprefixer
apps/web/postcss.config.mjs Replaced tailwindcss/autoprefixer with @tailwindcss/postcss
apps/web/tailwind.config.ts Removed - configuration moved to CSS
apps/web/src/styles/globals.css Major rewrite using Tailwind v4 @import and @theme syntax
apps/web/src/app/[locale]/layout.tsx Removed reset.css import
Component files Updated utility classes for Tailwind v4 syntax (mask, outline, flex, data attributes, etc.)
Package changelogs Added version updates for translations packages

Note: The PR contains numerous critical syntax errors that will prevent the styles from working correctly. The migration appears incomplete with systematic issues in gradient utilities, CSS variable references, data attribute selectors, and missing theme customizations.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

<NavigationMenuPrimitive.Viewport
className={cn(
"origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border bg-popover text-popover-foreground shadow data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]",
"origin-top-center relative mt-1.5 h-(--radix-navigation-menu-viewport-height) w-full overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-(--radix-navigation-menu-viewport-width)",
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

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

The CSS variable reference syntax is incorrect. Change h-(--radix-navigation-menu-viewport-height) to h-[var(--radix-navigation-menu-viewport-height)]. CSS variables must be wrapped in var() and enclosed in square brackets for arbitrary values.

Copilot uses AI. Check for mistakes.

return (
<header className="bg-gradient-to-t from-onruntime-blue/10 to-transparent">
<header className="bg-linear-to-t from-onruntime-blue/10 to-transparent">
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

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

The gradient utility class syntax is incorrect for Tailwind v4. The class should use bg-gradient-to-t instead of bg-linear-to-t. In Tailwind v4, gradient utilities remain as bg-gradient-{direction}, not bg-linear-{direction}.

Copilot uses AI. Check for mistakes.
</div>

<div className="absolute right-0 top-0 bottom-0 w-1/3 bg-gradient-to-l from-onruntime-blue/10 to-transparent" />
<div className="absolute right-0 top-0 bottom-0 w-1/3 bg-linear-to-l from-onruntime-blue/10 to-transparent" />
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

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

The gradient utility class syntax is incorrect for Tailwind v4. The class should use bg-gradient-to-l instead of bg-linear-to-l. In Tailwind v4, gradient utilities remain as bg-gradient-{direction}, not bg-linear-{direction}.

Copilot uses AI. Check for mistakes.
</div>

<div className="absolute right-0 top-0 bottom-0 w-1/3 bg-gradient-to-l from-onruntime-blue/10 to-transparent" />
<div className="absolute right-0 top-0 bottom-0 w-1/3 bg-linear-to-l from-onruntime-blue/10 to-transparent" />
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

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

The gradient utility class syntax is incorrect for Tailwind v4. The class should use bg-gradient-to-l instead of bg-linear-to-l. In Tailwind v4, gradient utilities remain as bg-gradient-{direction}, not bg-linear-{direction}.

Copilot uses AI. Check for mistakes.
ref={ref}
className={cn(
"top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in",
"top-full z-1 flex h-1.5 items-end justify-center overflow-hidden data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in",
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

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

The z-index value syntax is incorrect. In Tailwind v4, arbitrary z-index values should use square brackets: z-[1] instead of z-1. The utility z-1 is not a standard Tailwind class.

Copilot uses AI. Check for mistakes.
</div>

<div className="absolute right-0 top-0 bottom-0 w-1/3 bg-gradient-to-l from-onruntime-blue/10 to-transparent" />
<div className="absolute right-0 top-0 bottom-0 w-1/3 bg-linear-to-l from-onruntime-blue/10 to-transparent" />
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

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

The gradient utility class syntax is incorrect for Tailwind v4. The class should use bg-gradient-to-l instead of bg-linear-to-l. In Tailwind v4, gradient utilities remain as bg-gradient-{direction}, not bg-linear-{direction}.

Copilot uses AI. Check for mistakes.
ref={ref}
className={cn(
"fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 inset-x-0 sm:bottom-0 sm:right-0 sm:top-auto sm:left-auto sm:flex-col md:max-w-[420px]",
"fixed top-0 z-100 flex max-h-screen w-full flex-col-reverse p-4 inset-x-0 sm:bottom-0 sm:right-0 sm:top-auto sm:left-auto sm:flex-col md:max-w-[420px]",
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

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

The z-index value syntax is incorrect. In Tailwind v4, arbitrary z-index values should use square brackets: z-[100] instead of z-100. The utility z-100 is not a standard Tailwind class.

Copilot uses AI. Check for mistakes.
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-hidden transition-colors focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50",
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

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

The data attribute selector syntax is incorrect. Change data-disabled:pointer-events-none data-disabled:opacity-50 to data-[disabled]:pointer-events-none data-[disabled]:opacity-50. In Tailwind, data attribute selectors require square brackets around the attribute name.

Copilot uses AI. Check for mistakes.
<div className="relative hidden md:flex items-center justify-center p-8 overflow-hidden">
<div className="relative z-10 w-full max-w-xs aspect-square">
<div className={`absolute inset-0 rounded-full bg-${accentColor}/5 backdrop-blur-sm border border-${accentColor}/10 flex items-center justify-center`}>
<div className={`absolute inset-0 rounded-full bg-${accentColor}/5 backdrop-blur-xs border border-${accentColor}/10 flex items-center justify-center`}>
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

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

The backdrop-blur utility value is incorrect. The standard Tailwind backdrop-blur utilities are: backdrop-blur-none, backdrop-blur-sm, backdrop-blur, backdrop-blur-md, backdrop-blur-lg, backdrop-blur-xl, backdrop-blur-2xl, backdrop-blur-3xl. The utility backdrop-blur-xs doesn't exist in the default configuration.

Suggested change
<div className={`absolute inset-0 rounded-full bg-${accentColor}/5 backdrop-blur-xs border border-${accentColor}/10 flex items-center justify-center`}>
<div className={`absolute inset-0 rounded-full bg-${accentColor}/5 backdrop-blur-sm border border-${accentColor}/10 flex items-center justify-center`}>

Copilot uses AI. Check for mistakes.
</div>

<div className="absolute right-0 top-0 bottom-0 w-1/3 bg-gradient-to-l from-onruntime-blue/10 to-transparent" />
<div className="absolute right-0 top-0 bottom-0 w-1/3 bg-linear-to-l from-onruntime-blue/10 to-transparent" />
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

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

The gradient utility class syntax is incorrect for Tailwind v4. The class should use bg-gradient-to-l instead of bg-linear-to-l. In Tailwind v4, gradient utilities remain as bg-gradient-{direction}, not bg-linear-{direction}.

Suggested change
<div className="absolute right-0 top-0 bottom-0 w-1/3 bg-linear-to-l from-onruntime-blue/10 to-transparent" />
<div className="absolute right-0 top-0 bottom-0 w-1/3 bg-gradient-to-l from-onruntime-blue/10 to-transparent" />

Copilot uses AI. Check for mistakes.
Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link

Copilot AI commented Dec 31, 2025

@antoinekm I've opened a new pull request, #370, to work on those changes. Once the pull request is ready, I'll request review from you.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
apps/web/src/components/marketing/services/feature-section.tsx (1)

136-146: Add JSDoc comment for the exported component.

Per coding guidelines, exported functions should have JSDoc comments. Consider adding documentation to describe the component's purpose, prop meanings (especially type, variant, and reversed), and usage examples.

📝 Example JSDoc comment
+/**
+ * Renders a feature section with a title, description, and list of features.
+ * Displays features alongside a decorative visual panel with dynamic theming.
+ * 
+ * @param categoryId - The service category identifier
+ * @param serviceId - The specific service identifier  
+ * @param title - Section heading
+ * @param description - Section description text
+ * @param type - Type of features to display: 'features', 'benefits', or 'complementary'
+ * @param reversed - When true, swaps the content and visual panel positions
+ * @param accentColor - CSS custom property name for theme color (default: "onruntime-blue")
+ * @param variant - Display style: 'default' (list), 'cards' (grid), or 'minimal' (compact list)
+ */
 const FeatureSection: React.FC<FeatureSectionProps> = ({
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fb579a0 and bb2721b.

📒 Files selected for processing (1)
  • apps/web/src/components/marketing/services/feature-section.tsx
🧰 Additional context used
📓 Path-based instructions (3)
apps/web/src/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

apps/web/src/components/**/*.{ts,tsx}: Use useTranslation hook from @onruntime/translations/react for translations in Client Components
Store React components in the components/ directory, organized into subdirectories: ui/, layout/, and marketing/

Files:

  • apps/web/src/components/marketing/services/feature-section.tsx
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Always use 'const' for variable declarations instead of 'var' or 'let' unless reassignment is required
Always add JSDoc comments for exported functions and classes
Use meaningful error messages that describe the context and expected recovery steps
Keep functions under 30 lines of code
All async functions must handle errors with try/catch blocks
Use absolute imports from the 'src' directory instead of relative imports

Files:

  • apps/web/src/components/marketing/services/feature-section.tsx
**/*.{jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Prefer functional components with hooks over class components in React

Files:

  • apps/web/src/components/marketing/services/feature-section.tsx
🧬 Code graph analysis (1)
apps/web/src/components/marketing/services/feature-section.tsx (2)
apps/web/src/components/marketing/agency/city-hero-section.tsx (1)
  • CityHeroSectionProps (15-99)
apps/web/src/components/marketing/services/service-overview.tsx (1)
  • benefit (301-308)
🔇 Additional comments (2)
apps/web/src/components/marketing/services/feature-section.tsx (2)

225-243: Good migration to semantic Tailwind utilities.

The conversion from arbitrary values to semantic utilities improves maintainability:

  • min-h-[320px]min-h-80
  • w-[300px] h-[300px]size-75
  • w-[250px] h-[250px]size-62.5

The decorative background elements and feature icon correctly use inline styles with CSS custom properties for dynamic theming, maintaining consistency with the icon container pattern above.


30-36: Excellent fix for the dynamic class construction issue.

The migration from template-literal Tailwind classes (bg-${accentColor}/10, text-${accentColor}) to inline styles with CSS custom properties successfully resolves the critical purge/scanning issue flagged in the previous review. The pattern is applied consistently across all three components (FeatureItem, FeatureCard, FeatureMinimal).

The use of color-mix(in srgb, var(--${accentColor}) 10%, transparent) for semi-transparent backgrounds is a clean, modern CSS solution, and the change from flex-shrink-0 to shrink-0 aligns with Tailwind v4 conventions.

However, please verify:

#!/bin/bash
# Verify that the required CSS custom properties (e.g., --onruntime-blue) are defined
rg -n --type=css --type=scss -C3 'var\(--onruntime-blue\)|--onruntime-blue:'
What is the browser support for the CSS color-mix() function, and does it meet typical modern browser requirements for production web applications?

Also applies to: 69-75, 106-112

@antoinekm antoinekm merged commit fbbcf88 into master Dec 31, 2025
4 checks passed
@antoinekm antoinekm deleted the antoinekm/tw-v4 branch December 31, 2025 15:02
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.

2 participants