Skip to content

Conversation

@fsdiasv
Copy link
Owner

@fsdiasv fsdiasv commented Jun 28, 2025

Summary

  • Added new auth UI components with accessibility features
  • Removed unused mobile demo pages and components
  • Clean up temporary files that were not integrated

Changes

New Components

  • FormInput: Accessible form input with label and error states
  • PasswordInput: Password field with show/hide toggle functionality
  • PrimaryButton: Primary action button with loading state support
  • SocialLoginButton: Social authentication buttons for Google, Twitter, and GitHub

Removed Files

  • Deleted unused mobile demo pages (mobile-demo, test-safe-area)
  • Removed temporary placeholder pages (notifications, profile)
  • Cleaned up unused mobile-specific components that were not integrated into the main app

All new components follow the project's mobile-first approach with 44px minimum touch targets and proper accessibility attributes.

Test Plan

  • New auth components render correctly
  • Form inputs handle validation and error states
  • Password input toggle works properly
  • Social login buttons are accessible
  • No broken imports from deleted files
  • Build passes successfully

Summary by CodeRabbit

  • New Features

    • Added localized navigation terms, app naming, and detailed authentication UI text in English, Spanish, and Portuguese.
    • Introduced Signup, Login, and Forgot Password pages with localized content and responsive layouts.
    • Added AuthLayout and Testimonial components for authentication pages.
    • Introduced form components: FormInput, PasswordInput, PrimaryButton, and SocialLoginButton.
    • Added navigation persistence hook with scroll restoration and history management.
    • Added layout components: Stack, Spacer, Section with flexible layout and spacing options.
    • Introduced responsive image components supporting adaptive loading and art direction.
    • Added adaptive loading components and resource hinting utilities.
    • Introduced PWA layout with install prompts, safe area handling, and viewport meta management.
    • Added visual layout debugger and Core Web Vitals monitoring tools.
    • Added hooks for responsive design, device capabilities, and PWA feature detection.
  • Enhancements

    • Improved CSS with safe area fallbacks, viewport-aware spacing, container queries, touch target sizing, and enhanced print styles.
    • Enabled fluid, viewport-adaptive typography sizing.
    • Updated Tailwind CSS config to support container queries.
    • Enhanced localization dictionaries with new navigation and authentication keys.
    • Replaced gesture handling from react-use-gesture to @use-gesture/react with updated drag implementations.
    • Refined layout shift prevention and font load optimization for visual stability.
    • Suppressed hydration warnings on input components for better SSR compatibility.
    • Simplified authentication layout container styles by removing background, padding, and width constraints.
  • Documentation

    • Added comprehensive README for layout system, utilities, best practices, and browser support.
  • Chores

    • Added new dev dependencies for container queries and gesture support.
    • Extended TypeScript types for PWA navigator properties and install events.
    • Removed deprecated navigation and gesture-related exports.
    • Cleaned up formatting in documentation and CI workflows.
  • Removals

    • Deleted safe area test page component.

fsdiasv added 3 commits June 28, 2025 15:29
- Fixed translation key paths in mobile-layout.tsx to use correct 'common.navigation.*' namespace
- Fixed infinite loop in usePWAFeatures hook by properly handling CSS environment variables
- Added safe fallbacks for CSS safe area insets in globals.css
- Added TypeScript declarations for Navigator PWA APIs
- Fixed ESLint errors in mobile components

The translation errors were caused by incorrect key paths - they needed the 'common' prefix.
The infinite loop was due to parsing 'env(safe-area-inset-*)' strings as integers, which returned NaN.
- Add new auth UI components:
  - FormInput: Accessible form input with label and error states
  - PasswordInput: Password field with show/hide toggle
  - PrimaryButton: Primary action button component
  - SocialLoginButton: Social authentication button
- Remove unused mobile demo and test pages
- Remove unused mobile-specific components that were not integrated
- Clean up temporary notification and profile placeholders
@coderabbitai
Copy link

coderabbitai bot commented Jun 28, 2025

Walkthrough

This update extends localization files with new navigation and authentication UI text keys in English, Spanish, and Portuguese. It removes a test-safe-area demo page and adds new React components for authentication layouts, input controls, responsive layout utilities, adaptive loading, PWA features, web vitals monitoring, and layout debugging. The gesture handling library is replaced and refactored. CSS and Tailwind config are enhanced for safe area, container queries, and print styles. Navigation persistence and PWA detection hooks are introduced.

Changes

Files / Groups Change Summary
messages/en.json, messages/es.json, messages/pt.json Added new navigation keys and an "app" name key for localization; expanded authentication UI text for signup, login, forgot password, and testimonial sections.
package.json, tailwind.config.ts Removed react-use-gesture dependency; added @tailwindcss/container-queries and @use-gesture/react; enabled container queries plugin in Tailwind config.
src/app/globals.css Enhanced safe area handling with CSS variables, added fluid spacing utilities, container queries support, viewport unit utilities, responsive touch target sizing, and comprehensive print stylesheet improvements.
src/app/[locale]/(app)/test-safe-area/page.tsx Removed the test-safe-area demo page component.
src/components/auth/auth-layout.tsx, src/components/auth/testimonial.tsx Added AuthLayout and Testimonial components for authentication page layouts with optional testimonial display and localized content.
src/components/dashboard/page-transition-wrapper.tsx, src/components/navigation/components/... Added TypeScript const assertions for animation transition types; no runtime or behavioral changes.
src/components/layout/AdaptiveLoader.tsx Added AdaptiveLoader, DynamicComponent, ProgressiveEnhancement, and ResourceHint components for adaptive and progressive loading strategies and resource hinting.
src/components/layout/LayoutDebugger.tsx Added LayoutDebugger component providing visual overlays for grid, container queries, touch targets, viewport info, breakpoints, and performance metrics with toggle controls.
src/components/layout/PWALayout.tsx Added PWALayout component supporting PWA features: safe area insets, fullscreen mode, install prompt UI, dynamic theme color, and pull-to-refresh prevention; includes hooks useViewportMeta and SafeAreaInset component.
src/hooks/use-pwa-features.tsx Added usePWAFeatures hook to detect and manage PWA capabilities including standalone mode, install prompt, safe area insets, vibration, badging, and online status with utility methods.
src/components/layout/README.md Added detailed documentation for responsive layout components, hooks, utilities, adaptive loading, web vitals, PWA features, debugging tools, CSS utilities, and best practices.
src/components/layout/ResponsiveImage.tsx Added ResponsiveImage and Picture components for adaptive, responsive image rendering with lazy loading, quality adjustment, placeholders, error handling, and art-directed source sets.
src/components/layout/ResponsiveUtils.tsx Added hooks: useViewport, useDeviceCapabilities, useResponsiveValue, and useContainerQuery for responsive design and device feature detection.
src/components/layout/Section.tsx Added Section component with flexible semantic element rendering, configurable padding, margin, safe area insets, and container query support.
src/components/layout/Stack.tsx Added Stack and Spacer components for flexible layout stacking with direction, gap, alignment, wrapping, and spacing controls.
src/components/layout/Typography.tsx Updated Typography component to apply fluid, viewport-relative font sizes using CSS clamp for responsive text sizing while preserving font weight and tracking styles.
src/components/layout/WebVitals.tsx Added WebVitals monitoring component with UI, useLayoutShiftPrevention hook, LayoutStable wrapper, and useFontLoadOptimization hook for Core Web Vitals tracking and layout shift prevention.
src/components/layout/index.ts Reorganized exports: added new layout components (Stack, Spacer, Section), responsive utilities, adaptive loading components, web vitals tools, PWA features, and debugging tools; removed navigation and gesture-related exports.
src/components/navigation/components/DrawerNavigation/index.tsx, src/hooks/useGestureNavigation.ts Replaced react-use-gesture with @use-gesture/react; refactored gesture handlers for drag/swipe with updated API and consistent destructuring; no signature changes.
src/components/ui/form-input.tsx, src/components/ui/password-input.tsx, Added new accessible UI components: FormInput with label and error support, PasswordInput with visibility toggle, PrimaryButton with loading state, and SocialLoginButton for Google, Twitter, and GitHub providers.
src/hooks/use-navigation-persistence.tsx Added hook for navigation state and history persistence with scroll position saving/restoration and back/forward navigation integration in Next.js apps.
src/lib/theme-provider.tsx Removed a TypeScript expect-error comment related to legacy iOS standalone detection; no logic changes.
src/types/navigator.d.ts Added TypeScript declarations for PWA-related navigator properties (standalone, setAppBadge, clearAppBadge) and beforeinstallprompt event interface.
.github/workflows/CI.yml Added newline at end of file; no functional changes.
docs/prd.md Removed extraneous blank lines for formatting consistency; no content changes.
src/app/[locale]/(auth)/forgot-password/page.tsx, src/app/[locale]/(auth)/login/page.tsx, Added localized React client components for authentication pages: ForgotPasswordPage, LoginPage, and SignUpPage with forms, loading states, links, and social login options, wrapped in AuthLayout.
src/app/[locale]/(auth)/signup/page.tsx Added localized React client component for signup page with form validation, loading state, social login buttons, and legal notices.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant App
  participant AdaptiveLoader
  participant DynamicComponent
  participant DeviceCapabilities
  participant ResourceHint

  User->>App: Visits a page
  App->>AdaptiveLoader: Renders component with loadOn prop
  AdaptiveLoader->>DeviceCapabilities: Checks device/network
  AdaptiveLoader-->>App: Loads children based on strategy (immediate/interaction/idle/visible)
  App->>DynamicComponent: Renders heavy component with AdaptiveLoader
  DynamicComponent->>AdaptiveLoader: Defers loading until trigger
  App->>ResourceHint: Injects resource hints for preloading/prefetching
Loading
sequenceDiagram
  participant User
  participant PWALayout
  participant usePWAFeatures
  participant Browser

  User->>PWALayout: Loads PWA-enabled page
  PWALayout->>usePWAFeatures: Detects PWA/standalone mode, insets, install prompt
  Browser-->>PWALayout: Fires beforeinstallprompt event
  PWALayout->>User: Shows install prompt UI if available
  User->>PWALayout: Accepts or dismisses install
  PWALayout->>Browser: Triggers install prompt or hides UI
Loading

Possibly related PRs

Poem

🐇
New layouts leap and PWA dreams soar,
Responsive images hop across the floor.
Safe areas cushioned, fluid spaces grow,
Debugger panels pop up, letting metrics show.
Adaptive loaders nibble, waiting for their cue—
With every hop, this code feels brand new!
🌱✨

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

- Create reusable form components with accessibility and mobile-first design
- Add FormInput, PasswordInput, PrimaryButton, and SocialLoginButton components
- Implement Sign Up page with two-column layout and testimonial
- Create Login page with consistent styling and layout
- Add Forgot Password page with single-column centered layout
- Ensure all pages are fully internationalized with next-intl
- Add translations for all auth pages in English, Portuguese, and Spanish
- Components include proper ARIA attributes and 44px minimum touch targets
- All forms are keyboard accessible and screen reader friendly

🚀 Mobile-first PWA authentication flow ready!
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: 33

🔭 Outside diff range comments (1)
src/app/globals.css (1)

313-318: Remove duplicate .safe-area-container class definition.

The class is defined twice with slightly different implementations.

Keep the utility layer version and remove the component layer definition:

-  /* Safe area containers */
-  .safe-area-container {
-    padding-top: var(--safe-area-inset-top);
-    padding-right: var(--safe-area-inset-right);
-    padding-bottom: var(--safe-area-inset-bottom);
-    padding-left: var(--safe-area-inset-left);
-  }

Also applies to: 441-446

♻️ Duplicate comments (2)
messages/es.json (1)

26-33: Duplicate of earlier comment – same key duplication appears here.

messages/pt.json (1)

26-33: Duplicate of earlier comment – same key duplication appears here.

🧹 Nitpick comments (19)
src/components/ui/social-login-button.tsx (3)

50-58: Consider re-using the shadcn Button primitive for consistency

All UI primitives under src/components/ui should extend the existing shadcn Button component so that variants, dark-mode styles, and accessibility helpers stay centralised. Wrapping that component keeps styling DRY and ensures future theme tweaks propagate automatically.

-import { ButtonHTMLAttributes, forwardRef } from 'react'
+import { forwardRef } from 'react'
+import { Button, ButtonProps } from '@/components/ui/button'
 
-export interface SocialLoginButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
+export interface SocialLoginButtonProps extends ButtonProps {
   provider: 'google' | 'twitter' | 'github'
 }

Nice-to-have, but it will simplify maintenance.


52-56: Tailwind class ordering flagged by Prettier

Static analysis reports ordering issues (rounded-md border … p-2.5, focus ring order, etc.). Running prettier --write (with the Tailwind plugin already configured) should auto-fix these and keep the file lint-clean.

No functional impact, just to silence CI.


68-70: Minor: export directly for terser import paths

-export { SocialLoginButton }
+export default SocialLoginButton

Using a default export matches most shadcn primitives and lets consumers import SocialLoginButton from '@/components/ui/social-login-button' without the extra braces.

messages/en.json (1)

26-33: Terminology duplication: “logout” vs. existing “signout”

You now have both "auth.signout" and "common.navigation.logout". Maintaining two keys for the same action increases translator workload and risks UI inconsistency. Consolidate to a single canonical key (signout is already used).

src/types/navigator.d.ts (1)

12-14: Prettier newline warning

Static analysis flagged a missing newline at EOF – add one to keep CI green.

tailwind.config.ts (1)

1-2: Fix import order to comply with ESLint rules.

The container queries import should come after the type import according to the project's import ordering rules.

Apply this diff to fix the import order:

import type { Config } from 'tailwindcss'
-import containerQueries from '@tailwindcss/container-queries'
+import containerQueries from '@tailwindcss/container-queries'
src/components/auth/auth-layout.tsx (2)

1-2: Fix import grouping and formatting issues.

Multiple formatting issues need to be addressed to comply with the project's linting rules.

Apply this diff to fix the formatting:

-import { ReactNode } from 'react'
+import type { ReactNode } from 'react'
+
 import { Testimonial } from './testimonial'

11-22: Fix className formatting and structure.

The component logic is excellent for mobile-first auth layouts, but formatting needs adjustment.

Apply this diff to fix the formatting:

-    <div className="min-h-screen flex">
-      <div className={`flex-1 flex items-center justify-center p-8 ${showTestimonial ? 'lg:w-[60%]' : ''}`}>
-        <div className="w-full max-w-md">
-          {children}
-        </div>
+    <div className="flex min-h-screen">
+      <div
+        className={`flex flex-1 items-center justify-center p-8 ${showTestimonial ? 'lg:w-[60%]' : ''}`}
+      >
+        <div className="w-full max-w-md">{children}</div>
       </div>
       {showTestimonial && (
-        <div className="hidden lg:block lg:w-[40%] bg-slate-50">
+        <div className="hidden bg-slate-50 lg:block lg:w-[40%]">
           <Testimonial />
         </div>
       )}
     </div>
src/components/auth/testimonial.tsx (1)

11-13: Consider making the avatar dynamic.

The hardcoded "P" in the avatar should be made configurable to support different testimonials or users. Consider adding an avatar or authorInitial prop.

-            <div className="w-12 h-12 rounded-full bg-orange-500 flex items-center justify-center">
-              <span className="text-white font-bold text-lg">P</span>
-            </div>
+            <div className="w-12 h-12 rounded-full bg-orange-500 flex items-center justify-center">
+              <span className="text-white font-bold text-lg">{t('author.initial')}</span>
+            </div>
src/components/ui/form-input.tsx (1)

6-9: Consider enhancing for react-hook-form integration.

Based on project requirements, all forms should use react-hook-form with Zod validation. Consider adding props or utilities to better integrate with Controller components.

export interface FormInputProps extends InputHTMLAttributes<HTMLInputElement> {
  label?: string
  error?: string
  // Add react-hook-form integration helpers
  fieldError?: FieldError
  register?: UseFormRegisterReturn
}
src/hooks/use-pwa-features.tsx (1)

102-123: Improve type safety for badge APIs

The badge-related navigator methods lack proper TypeScript types. Consider using the navigator type definitions from src/types/navigator.d.ts mentioned in the AI summary.

Ensure the navigator types include these methods or cast appropriately:

-            if (navigator.clearAppBadge) {
-              await navigator.clearAppBadge()
-            }
+            await (navigator as any).clearAppBadge?.()
           } else {
-            await navigator.setAppBadge?.(count)
+            await (navigator as any).setAppBadge?.(count)
src/components/layout/WebVitals.tsx (1)

152-164: Simplify the preventShift implementation

The manual DOMRect construction is verbose and might not match the actual interface.

Consider storing just the dimensions:

   const preventShift = (elementId: string, dimensions: { width: number; height: number }) => {
-    elementsRef.current.set(elementId, {
-      width: dimensions.width,
-      height: dimensions.height,
-      top: 0,
-      left: 0,
-      right: dimensions.width,
-      bottom: dimensions.height,
-      x: 0,
-      y: 0,
-      toJSON: () => ({}),
-    })
+    // Store just the dimensions needed for preventing shifts
+    elementsRef.current.set(elementId, new DOMRect(0, 0, dimensions.width, dimensions.height))
   }
src/components/layout/PWALayout.tsx (2)

44-44: Use proper type augmentation for navigator.standalone.

Instead of casting to any, rely on the type declarations from src/types/navigator.d.ts.

-        setIsPWAInstalled(standalone || (window.navigator as any).standalone === true)
+        setIsPWAInstalled(standalone || window.navigator.standalone === true)
       const isStandalone =
         window.matchMedia('(display-mode: standalone)').matches ||
-        (window.navigator as any).standalone === true
+        window.navigator.standalone === true

Also applies to: 207-207


237-246: Use function declaration for consistency.

-export const SafeAreaInset: React.FC<SafeAreaInsetProps> = ({ position, className }) => {
+export function SafeAreaInset({ position, className }: SafeAreaInsetProps) {
   const insetClasses = {
     top: 'h-safe-top',
     bottom: 'h-safe-bottom',
     left: 'w-safe-left',
     right: 'w-safe-right',
   }

   return <div className={cn(insetClasses[position], className)} aria-hidden='true' />
 }
src/components/layout/Section.tsx (1)

86-86: Improve ref type handling.

Use a type assertion that's more specific:

       <Component
-        ref={ref as any}
+        ref={ref as React.Ref<HTMLElement>}
src/components/layout/AdaptiveLoader.tsx (2)

109-111: Consider adjusting the device memory threshold.

The 4GB threshold might be too aggressive and exclude many capable mid-range devices.

   // Show fallback for low-end devices or slow networks
-  if (networkSpeed === 'slow' || deviceMemory < 4) {
+  if (networkSpeed === 'slow' || deviceMemory < 2) {
     return fallback ? <>{fallback}</> : null
   }

171-216: Use function declarations for consistency.

-export const ProgressiveEnhancement: React.FC<ProgressiveEnhancementProps> = ({
+export function ProgressiveEnhancement({
   basic,
   enhanced,
   enhanceOn = 'idle',
   className,
-}) => {
+}: ProgressiveEnhancementProps) {
   // ... implementation
 }

-export const ResourceHint: React.FC<ResourceHintProps> = ({
+export function ResourceHint({
   href,
   as,
   type,
   crossOrigin,
   rel = 'preload',
-}) => {
+}: ResourceHintProps) {
   // ... implementation
 }

Also applies to: 229-253

src/app/globals.css (1)

433-438: Remove redundant container query rule.

The @container rule with .container-queries inside it is redundant.

-  /* Container queries utility */
-  @container {
-    .container-queries {
-      container-type: inline-size;
-    }
-  }
src/components/layout/index.ts (1)

10-12: Consider dynamic imports for heavy responsive image components

ResponsiveImage spans ~284 lines and includes complex hooks and runtime logic—and Picture likely has similar complexity. To reduce the initial client bundle, you can code-split these client-side components using Next’s dynamic():

  • File: src/components/layout/index.ts
    Replace the direct exports of ResponsiveImage/Picture with dynamic imports:

    - export { OptimizedImage, AvatarImage } from './OptimizedImage'
    - export { ResponsiveImage, Picture } from './ResponsiveImage'
    + import dynamic from 'next/dynamic'
    +
    + export { OptimizedImage, AvatarImage } from './OptimizedImage'
    +
    + const ResponsiveImage = dynamic(
    +   () => import('./ResponsiveImage'),
    +   { ssr: true, loading: () => <SkeletonImage /> }
    + )
    + const Picture = dynamic(
    +   () => import('./Picture'),
    +   { ssr: true, loading: () => <SkeletonImage /> }
    + )
    +
    + export { ResponsiveImage, Picture }
  • Tune the ssr option (true or false) and customize the loading placeholder as needed.

  • Measure bundle size and page-load metrics before/after to verify the benefit.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 39ec63d and ec3cb33.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (30)
  • messages/en.json (2 hunks)
  • messages/es.json (2 hunks)
  • messages/pt.json (2 hunks)
  • package.json (1 hunks)
  • src/app/[locale]/(app)/test-safe-area/page.tsx (0 hunks)
  • src/app/globals.css (2 hunks)
  • src/components/auth/auth-layout.tsx (1 hunks)
  • src/components/auth/testimonial.tsx (1 hunks)
  • src/components/dashboard/page-transition-wrapper.tsx (1 hunks)
  • src/components/layout/AdaptiveLoader.tsx (1 hunks)
  • src/components/layout/LayoutDebugger.tsx (1 hunks)
  • src/components/layout/PWALayout.tsx (1 hunks)
  • src/components/layout/README.md (1 hunks)
  • src/components/layout/ResponsiveImage.tsx (1 hunks)
  • src/components/layout/ResponsiveUtils.tsx (1 hunks)
  • src/components/layout/Section.tsx (1 hunks)
  • src/components/layout/Stack.tsx (1 hunks)
  • src/components/layout/Typography.tsx (2 hunks)
  • src/components/layout/WebVitals.tsx (1 hunks)
  • src/components/layout/index.ts (1 hunks)
  • src/components/navigation/components/DrawerNavigation/index.tsx (1 hunks)
  • src/components/ui/form-input.tsx (1 hunks)
  • src/components/ui/password-input.tsx (1 hunks)
  • src/components/ui/primary-button.tsx (1 hunks)
  • src/components/ui/social-login-button.tsx (1 hunks)
  • src/hooks/use-navigation-persistence.tsx (1 hunks)
  • src/hooks/use-pwa-features.tsx (1 hunks)
  • src/lib/theme-provider.tsx (0 hunks)
  • src/types/navigator.d.ts (1 hunks)
  • tailwind.config.ts (2 hunks)
💤 Files with no reviewable changes (2)
  • src/lib/theme-provider.tsx
  • src/app/[locale]/(app)/test-safe-area/page.tsx
🧰 Additional context used
📓 Path-based instructions (2)
`src/components/ui/**/*`: Use shadcn/ui components for UI elements in this directory.

src/components/ui/**/*: Use shadcn/ui components for UI elements in this directory.

📄 Source: CodeRabbit Inference Engine (CLAUDE.md)

List of files the instruction was applied to:

  • src/components/ui/password-input.tsx
  • src/components/ui/social-login-button.tsx
  • src/components/ui/primary-button.tsx
  • src/components/ui/form-input.tsx
`src/app/globals.css`: Use @import 'tailwindcss'; and define custom colors inside a @theme block.

src/app/globals.css: Use @import 'tailwindcss'; and define custom colors inside a @theme block.

📄 Source: CodeRabbit Inference Engine (CLAUDE.md)

List of files the instruction was applied to:

  • src/app/globals.css
🧠 Learnings (22)
📓 Common learnings
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: A task is only considered complete when it meets all criteria: mobile-first, internationalized, touch-friendly, offline-capable, fully type-safe, Zod validation, >80% test coverage, performance validated (Lighthouse >95), accessibility (WCAG 2.1 AA), security review, code review, and no TypeScript or ESLint errors.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: The prettier-plugin-tailwindcss is installed and will automatically sort Tailwind CSS classes on save; do not manually reorder classes.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
src/components/dashboard/page-transition-wrapper.tsx (2)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: TypeScript strict mode is enforced; do not use any types and adhere strictly to tsconfig.json rules.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Implement animations using framer-motion for consistent and performant UI transitions.
tailwind.config.ts (1)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: The prettier-plugin-tailwindcss is installed and will automatically sort Tailwind CSS classes on save; do not manually reorder classes.
package.json (2)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: The prettier-plugin-tailwindcss is installed and will automatically sort Tailwind CSS classes on save; do not manually reorder classes.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use the class-variance-authority (CVA) library to create type-safe style variants for components, combining it with clsx and tailwind-merge.
src/components/auth/testimonial.tsx (1)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: All user-facing strings must be internationalized using next-intl; hardcoded strings are not allowed anywhere in the codebase.
src/components/ui/password-input.tsx (1)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use the lucide-react library for all icons throughout the application.
src/components/ui/social-login-button.tsx (1)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use the lucide-react library for all icons throughout the application.
src/components/ui/primary-button.tsx (1)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use Server Components by default in Next.js; only use 'use client' when interactivity is essential.
src/components/ui/form-input.tsx (1)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: All forms must be built with react-hook-form and validated with Zod, integrated via @hookform/resolvers.
src/components/layout/README.md (2)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use Server Components by default in Next.js; only use 'use client' when interactivity is essential.
src/hooks/use-pwa-features.tsx (1)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Critical features must support offline usage via the Service Worker, following the offline-first PWA principle.
src/components/layout/Stack.tsx (2)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use Server Components by default in Next.js; only use 'use client' when interactivity is essential.
src/components/layout/ResponsiveImage.tsx (3)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use dynamic imports (next/dynamic) for heavy or non-critical components (such as charts or editors) to optimize bundle size and performance.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use Server Components by default in Next.js; only use 'use client' when interactivity is essential.
src/components/layout/LayoutDebugger.tsx (1)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
src/components/layout/WebVitals.tsx (4)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use dynamic imports (next/dynamic) for heavy or non-critical components (such as charts or editors) to optimize bundle size and performance.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use Server Components by default in Next.js; only use 'use client' when interactivity is essential.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: SVGs can be imported directly as React components due to @svgr/webpack configuration.
src/components/layout/Typography.tsx (1)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use the class-variance-authority (CVA) library to create type-safe style variants for components, combining it with clsx and tailwind-merge.
src/components/layout/PWALayout.tsx (3)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Critical features must support offline usage via the Service Worker, following the offline-first PWA principle.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use Server Components by default in Next.js; only use 'use client' when interactivity is essential.
src/components/layout/AdaptiveLoader.tsx (5)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use dynamic imports (next/dynamic) for heavy or non-critical components (such as charts or editors) to optimize bundle size and performance.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use Server Components by default in Next.js; only use 'use client' when interactivity is essential.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use @t3-oss/env-nextjs for type-safe environment variable validation and access; define variables in src/env.js and import the env object for usage. Do not use process.env directly in client-side components.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: SVGs can be imported directly as React components due to @svgr/webpack configuration.
src/components/layout/Section.tsx (1)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use Server Components by default in Next.js; only use 'use client' when interactivity is essential.
src/components/layout/ResponsiveUtils.tsx (3)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use Server Components by default in Next.js; only use 'use client' when interactivity is essential.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use @t3-oss/env-nextjs for type-safe environment variable validation and access; define variables in src/env.js and import the env object for usage. Do not use process.env directly in client-side components.
src/app/globals.css (2)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: All interactive elements must have a minimum touch target area of 44x44px to ensure accessibility and usability on mobile devices.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
src/components/layout/index.ts (3)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use dynamic imports (next/dynamic) for heavy or non-critical components (such as charts or editors) to optimize bundle size and performance.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use Server Components by default in Next.js; only use 'use client' when interactivity is essential.
🧬 Code Graph Analysis (15)
src/components/auth/auth-layout.tsx (1)
src/components/auth/testimonial.tsx (1)
  • Testimonial (3-34)
src/components/ui/password-input.tsx (2)
src/components/ui/form-input.tsx (2)
  • FormInputProps (6-9)
  • FormInput (50-50)
src/lib/utils.ts (1)
  • cn (19-21)
src/components/ui/social-login-button.tsx (1)
src/lib/utils.ts (1)
  • cn (19-21)
src/components/ui/primary-button.tsx (1)
src/lib/utils.ts (1)
  • cn (19-21)
src/components/ui/form-input.tsx (1)
src/lib/utils.ts (1)
  • cn (19-21)
src/hooks/use-pwa-features.tsx (4)
src/lib/pwa.ts (2)
  • BeforeInstallPromptEvent (5-12)
  • isStandalone (49-57)
src/components/layout/PWALayout.tsx (1)
  • usePWAFeatures (190-227)
src/components/layout/index.ts (1)
  • usePWAFeatures (39-39)
src/lib/utils.ts (1)
  • getSafeAreaInsets (128-152)
src/types/navigator.d.ts (1)
src/lib/pwa.ts (1)
  • BeforeInstallPromptEvent (5-12)
src/components/layout/Stack.tsx (2)
src/components/layout/index.ts (2)
  • Stack (4-4)
  • Spacer (4-4)
src/lib/utils.ts (1)
  • cn (19-21)
src/components/layout/ResponsiveImage.tsx (3)
src/components/layout/index.ts (4)
  • ResponsiveImage (12-12)
  • useViewport (16-16)
  • useDeviceCapabilities (17-17)
  • Picture (12-12)
src/components/layout/ResponsiveUtils.tsx (2)
  • useViewport (8-38)
  • useDeviceCapabilities (43-92)
src/lib/utils.ts (1)
  • cn (19-21)
src/components/layout/WebVitals.tsx (3)
scripts/measure-performance.js (1)
  • metrics (92-99)
src/components/layout/index.ts (4)
  • WebVitals (32-32)
  • useLayoutShiftPrevention (33-33)
  • LayoutStable (34-34)
  • useFontLoadOptimization (35-35)
src/lib/utils.ts (1)
  • cn (19-21)
src/components/layout/PWALayout.tsx (5)
src/components/layout/index.ts (4)
  • PWALayout (39-39)
  • usePWAFeatures (39-39)
  • SafeAreaInset (39-39)
  • useViewportMeta (39-39)
src/lib/pwa.ts (1)
  • showInstallPrompt (109-126)
src/lib/utils.ts (1)
  • cn (19-21)
src/hooks/use-pwa-features.tsx (1)
  • usePWAFeatures (19-211)
src/app/[locale]/layout.tsx (1)
  • viewport (36-46)
src/components/layout/AdaptiveLoader.tsx (2)
src/components/layout/index.ts (5)
  • AdaptiveLoader (24-24)
  • useDeviceCapabilities (17-17)
  • DynamicComponent (25-25)
  • ProgressiveEnhancement (26-26)
  • ResourceHint (27-27)
src/components/layout/ResponsiveUtils.tsx (1)
  • useDeviceCapabilities (43-92)
src/components/layout/Section.tsx (2)
src/components/layout/index.ts (1)
  • Section (5-5)
src/lib/utils.ts (1)
  • cn (19-21)
src/hooks/use-navigation-persistence.tsx (1)
src/components/navigation/types/navigation.ts (1)
  • NavigationState (61-67)
src/components/layout/ResponsiveUtils.tsx (3)
src/components/layout/index.ts (4)
  • useViewport (16-16)
  • useDeviceCapabilities (17-17)
  • useResponsiveValue (18-18)
  • useContainerQuery (19-19)
src/app/[locale]/layout.tsx (1)
  • viewport (36-46)
src/lib/pwa.ts (1)
  • isStandalone (49-57)
🪛 ESLint
tailwind.config.ts

[error] 2-2: @tailwindcss/container-queries import should occur before type import of tailwindcss

(import/order)

src/components/auth/auth-layout.tsx

[error] 1-1: There should be at least one empty line between import groups

(import/order)


[error] 11-11: Replace "min-h-screen·flex" with 'flex·min-h-screen'

(prettier/prettier)


[error] 12-12: Replace ·className={flex-1·flex·items-center·justify-center·p-8·${showTestimonial·?·'lg:w-[60%]'·:·''}} with ⏎········className={flex·flex-1·items-center·justify-center·p-8·${showTestimonial·?·'lg:w-[60%]'·:·''}}⏎······

(prettier/prettier)


[error] 13-15: Replace "w-full·max-w-md">⏎··········{children}⏎········ with 'w-full·max-w-md'>{children}

(prettier/prettier)


[error] 18-18: Replace "hidden·lg:block·lg:w-[40%]·bg-slate-50" with 'hidden·bg-slate-50·lg:block·lg:w-[40%]'

(prettier/prettier)


[error] 24-24: Insert

(prettier/prettier)

src/components/auth/testimonial.tsx

[error] 7-7: Replace "h-full·flex·items-center·justify-center·p-8" with 'flex·h-full·items-center·justify-center·p-8'

(prettier/prettier)


[error] 8-8: Replace "max-w-md" with 'max-w-md'

(prettier/prettier)


[error] 9-9: Replace "flex·items-start·space-x-4" with 'flex·items-start·space-x-4'

(prettier/prettier)


[error] 10-10: Replace "flex-shrink-0" with 'flex-shrink-0'

(prettier/prettier)


[error] 11-11: Replace "w-12·h-12·rounded-full·bg-orange-500·flex·items-center·justify-center" with 'flex·h-12·w-12·items-center·justify-center·rounded-full·bg-orange-500'

(prettier/prettier)


[error] 12-12: Replace "text-white·font-bold·text-lg" with 'text-lg·font-bold·text-white'

(prettier/prettier)


[error] 16-16: Replace "mb-4" with 'mb-4'

(prettier/prettier)


[error] 17-17: Replace "font-bold·text-slate-800" with 'font-bold·text-slate-800'

(prettier/prettier)


[error] 18-18: Replace "text-sm·text-slate-500" with 'text-sm·text-slate-500'

(prettier/prettier)


[error] 20-20: Replace "text-slate-800·leading-relaxed" with 'leading-relaxed·text-slate-800'

(prettier/prettier)


[error] 22-22: Replace (chunks) with chunks

(prettier/prettier)


[error] 23-25: Replace "bg-orange-100·px-1·py-0.5·rounded">⏎····················{chunks}⏎·················· with 'rounded·bg-orange-100·px-1·py-0.5'>{chunks}

(prettier/prettier)


[error] 26-26: Insert ,

(prettier/prettier)


[error] 34-34: Insert

(prettier/prettier)

src/components/ui/password-input.tsx

[error] 4-4: There should be at least one empty line between import groups

(import/order)


[error] 4-4: lucide-react import should occur before import of react

(import/order)


[error] 5-5: There should be at least one empty line between import groups

(import/order)


[error] 6-6: @/lib/utils import should occur before import of ./form-input

(import/order)


[error] 13-13: Replace "relative" with 'relative'

(prettier/prettier)


[error] 21-21: Replace "button" with 'button'

(prettier/prettier)


[error] 23-23: Replace "absolute·right-3·top-[50%]·-translate-y-[50%]·text-slate-500·hover:text-slate-700·focus:outline-none·focus:text-slate-700" with 'absolute·top-[50%]·right-3·-translate-y-[50%]·text-slate-500·hover:text-slate-700·focus:text-slate-700·focus:outline-none'

(prettier/prettier)


[error] 27-27: Replace "h-4·w-4"·aria-hidden="true" with 'h-4·w-4'·aria-hidden='true'

(prettier/prettier)


[error] 29-29: Replace "h-4·w-4"·aria-hidden="true" with 'h-4·w-4'·aria-hidden='true'

(prettier/prettier)


[error] 39-39: Insert

(prettier/prettier)

src/components/ui/social-login-button.tsx

[error] 3-3: There should be at least one empty line between import groups

(import/order)


[error] 12-12: Replace "h-5·w-5"·viewBox="0·0·24·24"·aria-hidden="true" with 'h-5·w-5'·viewBox='0·0·24·24'·aria-hidden='true'

(prettier/prettier)


[error] 14-14: Replace "currentColor" with 'currentColor'

(prettier/prettier)


[error] 15-15: Replace "M22.56·12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26·1.37-1.04·2.53-2.21·3.31v2.77h3.57c2.08-1.92·3.28-4.74·3.28-8.09z" with 'M22.56·12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26·1.37-1.04·2.53-2.21·3.31v2.77h3.57c2.08-1.92·3.28-4.74·3.28-8.09z'

(prettier/prettier)


[error] 18-18: Replace "currentColor" with 'currentColor'

(prettier/prettier)


[error] 19-19: Replace "M12·23c2.97·0·5.46-.98·7.28-2.66l-3.57-2.77c-.98.66-2.23·1.06-3.71·1.06-2.86·0-5.29-1.93-6.16-4.53H2.18v2.84C3.99·20.53·7.7·23·12·23z" with 'M12·23c2.97·0·5.46-.98·7.28-2.66l-3.57-2.77c-.98.66-2.23·1.06-3.71·1.06-2.86·0-5.29-1.93-6.16-4.53H2.18v2.84C3.99·20.53·7.7·23·12·23z'

(prettier/prettier)


[error] 22-22: Replace "currentColor" with 'currentColor'

(prettier/prettier)


[error] 23-23: Replace "M5.84·14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43·8.55·1·10.22·1·12s.43·3.45·1.18·4.93l2.85-2.22.81-.62z" with 'M5.84·14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43·8.55·1·10.22·1·12s.43·3.45·1.18·4.93l2.85-2.22.81-.62z'

(prettier/prettier)


[error] 26-26: Replace "currentColor" with 'currentColor'

(prettier/prettier)


[error] 27-27: Replace "M12·5.38c1.62·0·3.06.56·4.21·1.64l3.15-3.15C17.45·2.09·14.97·1·12·1·7.7·1·3.99·3.47·2.18·7.07l3.66·2.84c.87-2.6·3.3-4.53·6.16-4.53z" with 'M12·5.38c1.62·0·3.06.56·4.21·1.64l3.15-3.15C17.45·2.09·14.97·1·12·1·7.7·1·3.99·3.47·2.18·7.07l3.66·2.84c.87-2.6·3.3-4.53·6.16-4.53z'

(prettier/prettier)


[error] 32-32: Replace "h-5·w-5"·fill="currentColor"·viewBox="0·0·24·24"·aria-hidden="true" with 'h-5·w-5'·fill='currentColor'·viewBox='0·0·24·24'·aria-hidden='true'

(prettier/prettier)


[error] 33-33: Replace "M18.244·2.25h3.308l-7.227·8.26·8.502·11.24H16.17l-5.214-6.817L4.99·21.75H1.68l7.73-8.835L1.254·2.25H8.08l4.713·6.231zm-1.161·17.52h1.833L7.084·4.126H5.117z" with 'M18.244·2.25h3.308l-7.227·8.26·8.502·11.24H16.17l-5.214-6.817L4.99·21.75H1.68l7.73-8.835L1.254·2.25H8.08l4.713·6.231zm-1.161·17.52h1.833L7.084·4.126H5.117z'

(prettier/prettier)


[error] 37-37: Replace "h-5·w-5"·fill="currentColor"·viewBox="0·0·24·24"·aria-hidden="true" with 'h-5·w-5'·fill='currentColor'·viewBox='0·0·24·24'·aria-hidden='true'

(prettier/prettier)


[error] 39-39: Replace "evenodd" with 'evenodd'

(prettier/prettier)


[error] 40-40: Replace "M12·2C6.477·2·2·6.484·2·12.017c0·4.425·2.865·8.18·6.839·9.504.5.092.682-.217.682-.483·0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608·1.003.07·1.531·1.032·1.531·1.032.892·1.53·2.341·1.088·2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951·0-1.093.39-1.988·1.029-2.688-.103-.253-.446-1.272.098-2.65·0·0·.84-.27·2.75·1.026A9.564·9.564·0·0112·6.844c.85.004·1.705.115·2.504.337·1.909-1.296·2.747-1.027·2.747-1.027.546·1.379.202·2.398.1·2.651.64.7·1.028·1.595·1.028·2.688·0·3.848-2.339·4.695-4.566·4.943.359.309.678.92.678·1.855·0·1.338-.012·2.419-.012·2.747·0·.268.18.58.688.482A10.019·10.019·0·0022·12.017C22·6.484·17.522·2·12·2z" with 'M12·2C6.477·2·2·6.484·2·12.017c0·4.425·2.865·8.18·6.839·9.504.5.092.682-.217.682-.483·0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608·1.003.07·1.531·1.032·1.531·1.032.892·1.53·2.341·1.088·2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951·0-1.093.39-1.988·1.029-2.688-.103-.253-.446-1.272.098-2.65·0·0·.84-.27·2.75·1.026A9.564·9.564·0·0112·6.844c.85.004·1.705.115·2.504.337·1.909-1.296·2.747-1.027·2.747-1.027.546·1.379.202·2.398.1·2.651.64.7·1.028·1.595·1.028·2.688·0·3.848-2.339·4.695-4.566·4.943.359.309.678.92.678·1.855·0·1.338-.012·2.419-.012·2.747·0·.268.18.58.688.482A10.019·10.019·0·0022·12.017C22·6.484·17.522·2·12·2z'

(prettier/prettier)


[error] 41-41: Replace "evenodd" with 'evenodd'

(prettier/prettier)


[error] 44-44: Insert ,

(prettier/prettier)


[error] 53-53: Replace p-2.5·border·border-slate-300·rounded-md·bg-white with rounded-md·border·border-slate-300·bg-white·p-2.5

(prettier/prettier)


[error] 54-54: Replace ·focus:outline-none·focus:ring-2·focus:ring-blue-600·focus:ring-offset-2 with ·focus:ring-2·focus:ring-blue-600·focus:ring-offset-2·focus:outline-none

(prettier/prettier)


[error] 70-70: Insert

(prettier/prettier)

src/components/ui/primary-button.tsx

[error] 3-3: There should be at least one empty line between import groups

(import/order)


[error] 16-16: Replace px-3·py-2·text-sm·font-semibold·text-white·bg-blue-600·rounded-md with rounded-md·bg-blue-600·px-3·py-2·text-sm·font-semibold·text-white

(prettier/prettier)


[error] 17-17: Replace outline-none·focus:ring-2·focus:ring-blue-600·focus:ring-offset-2 with ring-2·focus:ring-blue-600·focus:ring-offset-2·focus:outline-none

(prettier/prettier)


[error] 18-18: Replace opacity-50·disabled:cursor-not-allowed with cursor-not-allowed·disabled:opacity-50

(prettier/prettier)


[error] 27-27: Replace "flex·items-center·justify-center" with 'flex·items-center·justify-center'

(prettier/prettier)


[error] 29-29: Replace "animate-spin·-ml-1·mr-3·h-5·w-5·text-white" with 'mr-3·-ml-1·h-5·w-5·animate-spin·text-white'

(prettier/prettier)


[error] 30-30: Replace "http://www.w3.org/2000/svg" with 'http://www.w3.org/2000/svg'

(prettier/prettier)


[error] 31-31: Replace "none" with 'none'

(prettier/prettier)


[error] 32-32: Replace "0·0·24·24" with '0·0·24·24'

(prettier/prettier)


[error] 33-33: Replace "true" with 'true'

(prettier/prettier)


[error] 36-36: Replace "opacity-25" with 'opacity-25'

(prettier/prettier)


[error] 37-37: Replace "12" with '12'

(prettier/prettier)


[error] 38-38: Replace "12" with '12'

(prettier/prettier)


[error] 39-39: Replace "10" with '10'

(prettier/prettier)


[error] 40-40: Replace "currentColor" with 'currentColor'

(prettier/prettier)


[error] 41-41: Replace "4" with '4'

(prettier/prettier)


[error] 44-44: Replace "opacity-75" with 'opacity-75'

(prettier/prettier)


[error] 45-45: Replace "currentColor" with 'currentColor'

(prettier/prettier)


[error] 46-46: Replace "M4·12a8·8·0·018-8V0C5.373·0·0·5.373·0·12h4zm2·5.291A7.962·7.962·0·014·12H0c0·3.042·1.135·5.824·3·7.938l3-2.647z" with 'M4·12a8·8·0·018-8V0C5.373·0·0·5.373·0·12h4zm2·5.291A7.962·7.962·0·014·12H0c0·3.042·1.135·5.824·3·7.938l3-2.647z'

(prettier/prettier)


[error] 61-61: Insert

(prettier/prettier)

src/components/ui/form-input.tsx

[error] 3-3: There should be at least one empty line between import groups

(import/order)


[error] 14-14: Replace "w-full" with 'w-full'

(prettier/prettier)


[error] 16-19: Replace ⏎············htmlFor={id}⏎············className="block·text-sm·font-medium·text-slate-800·mb-1"⏎·········· with ·htmlFor={id}·className='mb-1·block·text-sm·font-medium·text-slate-800'

(prettier/prettier)


[error] 27-27: Replace px-3·py-2·text-sm·rounded-md·border·border-slate-300 with rounded-md·border·border-slate-300·px-3·py-2·text-sm

(prettier/prettier)


[error] 29-29: Replace outline-none·focus:ring-2·focus:ring-blue-600·focus:border-blue-600 with border-blue-600·focus:ring-2·focus:ring-blue-600·focus:outline-none

(prettier/prettier)


[error] 31-31: Replace ring-red-500·focus:border with border-red-500·focus:ring

(prettier/prettier)


[error] 39-39: Replace "mt-1·text-sm·text-red-600" with 'mt-1·text-sm·text-red-600'

(prettier/prettier)


[error] 50-50: Insert

(prettier/prettier)

src/hooks/use-pwa-features.tsx

[error] 18-19: Delete

(prettier/prettier)


[error] 34-34: Replace (window.navigator.standalone·===·true) with window.navigator.standalone·===·true

(prettier/prettier)

src/types/navigator.d.ts

[error] 14-14: Insert

(prettier/prettier)

src/components/layout/ResponsiveImage.tsx

[error] 77-77: 'isTouch' is assigned a value but never used.

(@typescript-eslint/no-unused-vars)

src/components/layout/LayoutDebugger.tsx

[error] 19-340: Function component is not a function declaration

(react/function-component-definition)


[error] 77-77: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)

src/components/layout/WebVitals.tsx

[error] 25-118: Function component is not a function declaration

(react/function-component-definition)


[error] 180-198: Function component is not a function declaration

(react/function-component-definition)

src/components/layout/PWALayout.tsx

[error] 37-37: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 44-44: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 207-207: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 237-246: Function component is not a function declaration

(react/function-component-definition)

src/components/layout/AdaptiveLoader.tsx

[error] 30-30: 'errorComponent' is defined but never used.

(@typescript-eslint/no-unused-vars)


[error] 134-134: The {} ("empty object") type allows any non-nullish value, including literals like 0 and "".

  • If that's what you want, disable this lint rule with an inline comment or configure the 'allowObjectTypes' rule option.
  • If you want a type meaning "any object", you probably want object instead.
  • If you want a type meaning "any value", you probably want unknown instead.

(@typescript-eslint/no-empty-object-type)


[error] 142-142: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 142-142: The {} ("empty object") type allows any non-nullish value, including literals like 0 and "".

  • If that's what you want, disable this lint rule with an inline comment or configure the 'allowObjectTypes' rule option.
  • If you want a type meaning "any object", you probably want object instead.
  • If you want a type meaning "any value", you probably want unknown instead.

(@typescript-eslint/no-empty-object-type)


[error] 171-216: Function component is not a function declaration

(react/function-component-definition)


[error] 229-253: Function component is not a function declaration

(react/function-component-definition)

src/components/layout/Section.tsx

[error] 86-86: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)

src/components/layout/ResponsiveUtils.tsx

[error] 64-64: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 68-68: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 82-82: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)

🪛 Biome (1.9.4)
src/components/layout/LayoutDebugger.tsx

[error] 146-146: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)


[error] 171-171: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

src/components/layout/AdaptiveLoader.tsx

[error] 67-70: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 72-72: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 73-77: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 88-96: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 64-64: This code is unreachable

... because either this statement will return from the function, ...

... this statement will break the flow of the code, ...

... this statement will return from the function, ...

... or this statement will return from the function beforehand

(lint/correctness/noUnreachable)


[error] 202-202: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 203-203: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 199-199: This code is unreachable

... because either this statement will return from the function, ...

... this statement will break the flow of the code, ...

... this statement will return from the function, ...

... or this statement will return from the function beforehand

(lint/correctness/noUnreachable)


[error] 134-134: Don't use '{}' as a type.

Prefer explicitly define the object shape. '{}' means "any non-nullable value".

(lint/complexity/noBannedTypes)


[error] 142-142: Don't use '{}' as a type.

Prefer explicitly define the object shape. '{}' means "any non-nullable value".

(lint/complexity/noBannedTypes)

🔇 Additional comments (37)
src/components/ui/primary-button.tsx (4)

1-1: Consider if 'use client' is necessary.

While this button has interactive features, evaluate if Server Component rendering could be maintained with proper event handling patterns. The loading state and disabled logic could potentially be managed server-side depending on the use case.

Based on the retrieved learning: "Use Server Components by default in Next.js; only use 'use client' when interactivity is essential."


6-8: Interface design looks good.

The interface properly extends ButtonHTMLAttributes<HTMLButtonElement> for type safety and adds the optional isLoading prop appropriately.


20-20: Excellent accessibility consideration.

The min-h-[44px] ensures proper touch target size, adhering to mobile-first principles and accessibility guidelines.


59-61: Component setup and export are correct.

The displayName setting and export pattern follow React best practices.

Note: Add a final newline at the end of the file as required by Prettier.

 export { PrimaryButton }
+
src/components/layout/ResponsiveUtils.tsx (2)

97-113: LGTM! Excellent mobile-first responsive value implementation.

The hook correctly implements mobile-first breakpoints that align with the Tailwind configuration, with proper cascading from largest to smallest breakpoints.


118-141: LGTM! Well-implemented container query hook.

The ResizeObserver implementation is clean with proper cleanup and provides useful size categorization flags.

src/components/dashboard/page-transition-wrapper.tsx (1)

23-24: LGTM! Excellent type safety improvement.

Adding as const assertions ensures these animation properties are treated as literal types, improving TypeScript inference and consistency with other animation configurations.

tailwind.config.ts (1)

192-192: LGTM! Container queries plugin properly integrated.

The addition of the container queries plugin enhances the responsive design capabilities and aligns with the new container query utilities being used in the layout components.

src/components/navigation/components/DrawerNavigation/index.tsx (1)

152-152: LGTM! Consistent type safety improvement.

Adding as const to the animation type properties improves TypeScript inference and maintains consistency with similar changes across other animation configurations.

Also applies to: 160-160

src/components/auth/testimonial.tsx (2)

1-4: LGTM: Proper internationalization implementation.

The component correctly uses next-intl for all user-facing strings and follows the established namespace pattern for auth components.


21-27: Excellent use of rich text formatting.

The implementation of highlighted text using t.rich() with a custom highlight component is well-executed and accessible.

src/components/ui/password-input.tsx (1)

24-24: Excellent accessibility implementation.

The aria-label that dynamically updates based on password visibility state is well-implemented and follows accessibility best practices.

src/components/layout/Typography.tsx (3)

32-42: Excellent fluid typography implementation.

The CSS clamp expressions provide excellent responsive typography that scales smoothly across viewport sizes. This is a modern, accessibility-friendly approach to responsive text.


104-108: Well-structured responsive sizing logic.

The conditional logic correctly applies fluid sizes when responsive mode is enabled while preserving static sizing as fallback. This provides excellent flexibility for different use cases.


116-116: Container Query Variants Verified

The @tailwindcss/container-queries plugin is already added in tailwind.config.ts, and your defined screens (md, lg, etc.) will automatically generate the @md: and @lg: container-query variants. No changes needed here.

src/components/ui/form-input.tsx (2)

15-22: Excellent accessibility implementation.

The conditional label rendering with proper htmlFor association follows accessibility best practices.


34-36: Proper ARIA attributes for form validation.

The use of aria-invalid and aria-describedby correctly links error messages to the input for screen readers.

src/components/layout/LayoutDebugger.tsx (2)

144-166: Excellent touch target validation feature.

The 44px minimum touch target indicators are perfect for validating mobile accessibility compliance during development.


48-106: Comprehensive performance monitoring implementation.

The FPS, memory usage, and layout shift monitoring provides valuable insights for performance optimization. The cleanup logic is properly implemented.

src/components/layout/README.md (1)

283-293: Update documentation to match implementation

The example shows properties that don't exist in the actual usePWAFeatures implementation. The hook returns different properties like isStandalone, isPWA, safeAreaInsets, etc.

Update the example to reflect the actual API:

 const { isInstalled, canInstall, hasShareSupport } = usePWAFeatures()
+const { isStandalone, isPWA, canInstall, vibrate, setBadge } = usePWAFeatures()
 
-if (hasShareSupport) {
-  navigator.share({ title, text, url })
+if (canInstall) {
+  // Show install button
 }

Likely an incorrect or invalid review comment.

src/components/layout/Stack.tsx (1)

20-24: Container Queries Are Production-Ready

CSS container queries (@sm:flex-row) now enjoy broad support in all major modern browsers (Chrome 106+, Edge 106+, Firefox 110+, Safari 16+, Opera 94+, Samsung Internet 20+). For environments without support (e.g., Internet Explorer or very old mobile browsers), the default flex-col behavior will remain in effect, or you can scope your container-query rules behind a feature check:

@supports (container-type: inline-size) {
  /* container query rules here */
}

• File: src/components/layout/Stack.tsx (lines 20–24): directionClasses.responsive implementation ✅

Approved and ready to merge.

src/components/layout/WebVitals.tsx (1)

25-118: Well-implemented Core Web Vitals monitoring

Excellent implementation with proper thresholds based on Google's Core Web Vitals guidelines. The development-only indicator by default is a good choice.

src/components/layout/PWALayout.tsx (2)

248-280: Well-implemented viewport meta management.

The hook properly manages the viewport meta tag with all necessary options and correct effect dependencies.


86-86: Improve ref type handling for dynamic components.

The ref casting can be avoided by using a more specific approach.

-      <Component
-        ref={ref as any}
+      <Component
+        ref={ref as React.Ref<HTMLElement>}
⛔ Skipped due to learnings
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use dynamic imports (next/dynamic) for heavy or non-critical components (such as charts or editors) to optimize bundle size and performance.
src/components/layout/Section.tsx (1)

62-114: Well-structured layout component with comprehensive styling options.

The component provides excellent flexibility with safe area support, container queries, and responsive padding/margin options that align well with the mobile-first approach.

src/hooks/use-navigation-persistence.tsx (2)

85-113: Robust navigation history management.

The implementation correctly handles forward/backward navigation cases and maintains a proper history stack with size limits.


24-47: Excellent scroll position persistence implementation.

The scroll position saving and restoration logic is well-implemented with proper event handling for both beforeunload and visibility changes.

Also applies to: 165-180

src/app/globals.css (3)

103-113: Excellent safe area variable implementation with fallbacks.

The safe area CSS variables are properly defined with 0px fallbacks and convenient shorthand variables.


400-431: Excellent viewport-aware fluid spacing utilities.

The fluid spacing utilities using clamp() provide responsive spacing that scales smoothly with viewport size, perfectly aligned with mobile-first design principles.


478-613: Comprehensive and well-structured print styles.

The print media query provides thorough styling for printed output, including proper page breaks, link URL display, and table formatting. The use of print-color-adjust: exact ensures consistent output.

src/components/layout/index.ts (7)

1-1: Good organization with clear categorization.

The comment update provides clear context for the file's purpose.


1-42: Flag inconsistency between PR objectives and implementation.

The PR objectives mention "Add auth UI components" but this file focuses on layout components and responsive utilities. There's a significant discrepancy between the stated objectives and the actual implementation.

#!/bin/bash
# Search for any auth-related components in the layout directory
rg -i "auth|login|password|form" src/components/layout/
# Also check if auth components exist elsewhere
fd -t f -i "auth|login|password" src/components/

Likely an incorrect or invalid review comment.


22-28: AdaptiveLoader already employs dynamic imports; no changes needed.

Verified that src/components/layout/AdaptiveLoader imports dynamic from next/dynamic and uses it to load components dynamically. The recommendation to introduce lazy or dynamic imports is already satisfied.

Likely an incorrect or invalid review comment.


41-42: Verify that LayoutDebugger is excluded from production builds

A search in src/components/layout/LayoutDebugger.* and in src/components/layout/index.ts for common development‐only guards (process.env.NODE_ENV, __DEV__, etc.) returned no matches. As written, the export

// Development tools
export { LayoutDebugger } from './LayoutDebugger'

will be included in production bundles unless your build pipeline explicitly removes it.

Please ensure one of the following:

  • Wrap or gate the export/import behind a development‐only check, for example:
    export const LayoutDebugger =
      process.env.NODE_ENV === 'development'
        ? require('./LayoutDebugger').LayoutDebugger
        : () => null;
  • Import LayoutDebugger only in files that themselves are loaded only in development.
  • Confirm your bundler (e.g. using DefinePlugin + tree-shaking or a plugin like IgnorePlugin) drops src/components/layout/LayoutDebugger from production builds.

4-5: Layout primitive exports confirmed

All three layout primitives are present and properly exported:

  • src/components/layout/Stack.tsx defines and exports both Stack and Spacer.
  • src/components/layout/Section.tsx defines and exports Section.
  • src/components/layout/index.ts re-exports Stack, Spacer, and Section.

No further changes needed.


14-20: Responsive utilities verified with mobile-first breakpoints

I’ve reviewed all hooks in src/components/layout/ResponsiveUtils.tsuseViewport, useDeviceCapabilities, useResponsiveValue, and useContainerQuery—and they consistently use min-width thresholds with a default “base” for the smallest (mobile) viewport. This aligns with our mobile-first principle:

  • useViewport: isMobile (<768px), isTablet (≥768px & <1024px), isDesktop (≥1024px)
  • useResponsiveValue: base for mobile, sm (≥640px), md (≥768px), lg (≥1024px), xl (≥1280px), 2xl (≥1536px)
  • useContainerQuery: isSmall (<640px), isMedium (≥640px & <1024px), isLarge (≥1024px)

No changes needed here—these utilities follow the project’s mobile-first approach.


30-36: Web Vitals exports verified

All four exports (WebVitals, useLayoutShiftPrevention, LayoutStable, useFontLoadOptimization) are defined in src/components/layout/WebVitals.tsx and re-exported in src/components/layout/index.ts. No missing identifiers found.

No further changes required.

- Increase maximum width for forms on larger screens (sm:max-w-md lg:max-w-lg)
- Scale typography for better readability on desktop (headings and text)
- Increase input and button padding on larger screens
- Scale social login button icons and testimonial avatar
- Improve overall proportions and spacing for desktop experience
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: 5

🧹 Nitpick comments (2)
src/app/globals.css (2)

312-318: Duplicate .safe-area-container rules – keep one source of truth

The same selector is declared twice with slightly different bodies.
Apart from increasing bundle size, this complicates maintenance and makes it easy to introduce divergent behaviour later.

Consider keeping the definition once (component layer is a good fit) and, if needed, extend it there with the additional env() fallbacks.

Also applies to: 441-446


320-324: Minor: container-name + container-type can live in the utilities layer

The .container-queries helper is currently defined in the components layer. It behaves more like a low-level utility than a full component, so placing it in @layer utilities keeps concerns better separated and avoids accidental overrides.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ec3cb33 and 1f1131e.

📒 Files selected for processing (18)
  • .github/workflows/CI.yml (1 hunks)
  • docs/prd.md (0 hunks)
  • messages/en.json (3 hunks)
  • messages/es.json (3 hunks)
  • messages/pt.json (3 hunks)
  • src/app/[locale]/(auth)/forgot-password/page.tsx (1 hunks)
  • src/app/[locale]/(auth)/login/page.tsx (1 hunks)
  • src/app/[locale]/(auth)/signup/page.tsx (1 hunks)
  • src/app/globals.css (2 hunks)
  • src/components/auth/auth-layout.tsx (1 hunks)
  • src/components/auth/testimonial.tsx (1 hunks)
  • src/components/layout/README.md (1 hunks)
  • src/components/ui/form-input.tsx (1 hunks)
  • src/components/ui/password-input.tsx (1 hunks)
  • src/components/ui/primary-button.tsx (1 hunks)
  • src/components/ui/social-login-button.tsx (1 hunks)
  • src/hooks/use-pwa-features.tsx (1 hunks)
  • src/types/navigator.d.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • docs/prd.md
✅ Files skipped from review due to trivial changes (2)
  • .github/workflows/CI.yml
  • src/components/layout/README.md
🚧 Files skipped from review as they are similar to previous changes (10)
  • src/components/ui/password-input.tsx
  • src/components/ui/social-login-button.tsx
  • src/components/auth/testimonial.tsx
  • src/components/ui/form-input.tsx
  • src/components/ui/primary-button.tsx
  • src/types/navigator.d.ts
  • messages/en.json
  • src/components/auth/auth-layout.tsx
  • src/hooks/use-pwa-features.tsx
  • messages/es.json
🧰 Additional context used
📓 Path-based instructions (1)
`src/app/globals.css`: Use @import 'tailwindcss'; and define custom colors inside a @theme block.

src/app/globals.css: Use @import 'tailwindcss'; and define custom colors inside a @theme block.

📄 Source: CodeRabbit Inference Engine (CLAUDE.md)

List of files the instruction was applied to:

  • src/app/globals.css
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: A task is only considered complete when it meets all criteria: mobile-first, internationalized, touch-friendly, offline-capable, fully type-safe, Zod validation, >80% test coverage, performance validated (Lighthouse >95), accessibility (WCAG 2.1 AA), security review, code review, and no TypeScript or ESLint errors.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: The prettier-plugin-tailwindcss is installed and will automatically sort Tailwind CSS classes on save; do not manually reorder classes.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
src/app/[locale]/(auth)/forgot-password/page.tsx (1)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use Server Components by default in Next.js; only use 'use client' when interactivity is essential.
src/app/[locale]/(auth)/signup/page.tsx (4)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: All user-facing strings must be internationalized using next-intl; hardcoded strings are not allowed anywhere in the codebase.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use Server Components by default in Next.js; only use 'use client' when interactivity is essential.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use @t3-oss/env-nextjs for type-safe environment variable validation and access; define variables in src/env.js and import the env object for usage. Do not use process.env directly in client-side components.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: All forms must be built with react-hook-form and validated with Zod, integrated via @hookform/resolvers.
src/app/globals.css (2)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: All interactive elements must have a minimum touch target area of 44x44px to ensure accessibility and usability on mobile devices.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
src/app/[locale]/(auth)/login/page.tsx (4)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: All user-facing strings must be internationalized using next-intl; hardcoded strings are not allowed anywhere in the codebase.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use Server Components by default in Next.js; only use 'use client' when interactivity is essential.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use @t3-oss/env-nextjs for type-safe environment variable validation and access; define variables in src/env.js and import the env object for usage. Do not use process.env directly in client-side components.
🔇 Additional comments (5)
src/app/globals.css (2)

3-3: Confirm Tailwind v4 supports @custom-variant dark

@custom-variant is still considered experimental in Tailwind v4 nightly builds.
Ensure your build pipeline includes the tailwindcss/custom-variants plugin (or equivalent) so the rule doesn’t get stripped at compile time.


400-432: Great addition – fluid spacing utilities align with mobile-first guidelines

The new *-fluid helpers use clamp() with viewport units, giving designers predictable yet responsive rhythm. No issues spotted.

messages/pt.json (1)

26-33: Comprehensive Portuguese localization additions look good!

The new translations provide excellent coverage for the authentication flow and navigation elements. The structure is consistent with the auth page components and follows proper i18n patterns.

Also applies to: 59-61, 75-120

src/app/[locale]/(auth)/signup/page.tsx (1)

96-108: Verify terms and privacy page routes exist

I wasn’t able to find terms or privacy directories (and their page.tsx files) under src/app. Please confirm that you have:

  • src/app/[locale]/terms/page.tsx
  • src/app/[locale]/privacy/page.tsx

If these pages live elsewhere or use different routes, either update the links in src/app/[locale]/(auth)/signup/page.tsx or add the missing route files.

src/app/[locale]/(auth)/login/page.tsx (1)

87-91: Accessibility and functionality of SocialLoginButton verified
The SocialLoginButton uses a native <button> element (inherently keyboard‐navigable), includes an aria-label (“Sign in with {provider}”), enforces a 44×44px touch target, displays focus rings, and forwards all props (e.g. onClick) for authentication handlers. No changes needed.

- Add comprehensive PWA features hook with haptic feedback and touch detection
- Improve layout debugger with interactive controls and performance metrics
- Enhance auth pages with better mobile-first design and desktop layout
- Update gesture navigation to use @use-gesture/react (replacing deprecated library)
- Add safe area inset support with proper CSS variable naming
- Optimize responsive utilities with mobile-friendly patterns
- Remove unused dependencies and update package.json
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: 2

♻️ Duplicate comments (5)
src/components/layout/ResponsiveImage.tsx (1)

76-77: Clean up unused variable as indicated by past review.

The isTouch variable is destructured but never used in the component.

Remove the unused variable:

     const { isMobile, isTablet } = useViewport()
-    const { networkSpeed, isTouch } = useDeviceCapabilities()
+    const { networkSpeed } = useDeviceCapabilities()
src/components/layout/AdaptiveLoader.tsx (3)

16-16: Remove unused errorComponent prop.

The errorComponent prop is defined but never used in the component.

 interface AdaptiveLoaderProps {
   children?: React.ReactNode
   fallback?: React.ReactNode
   loadingComponent?: React.ReactNode
-  errorComponent?: React.ReactNode
   loadOn?: 'immediate' | 'interaction' | 'idle' | 'visible'
   // ...
 }

Also applies to: 30-30


65-83: Add block scoping to switch cases to prevent variable hoisting.

Variables declared in switch cases can be accessed by other cases without block scoping.

       case 'interaction': {
         const handleInteraction = () => {
           setShouldLoad(true)
           cleanup()
         }

         const events = ['click', 'touchstart', 'mouseenter', 'focus']
         const cleanup = () => {
           events.forEach(event => {
             document.removeEventListener(event, handleInteraction)
           })
         }

         events.forEach(event => {
           document.addEventListener(event, handleInteraction, { once: true })
         })

         return cleanup
+      }

       case 'visible': {
         if (!elementRef.current) return

         const observer = new IntersectionObserver(
           ([entry]) => {
             if (entry?.isIntersecting) {
               setShouldLoad(true)
               observer.disconnect()
             }
           },
           { threshold, rootMargin }
         )

         observer.observe(elementRef.current)
         return () => observer.disconnect()
+      }

Also applies to: 85-100


143-143: Replace any type with proper constraints.

Use a more specific type instead of any for better type safety.

-export function DynamicComponent<P extends Record<string, any> = Record<string, unknown>>({
+export function DynamicComponent<P extends Record<string, unknown> = Record<string, unknown>>({
src/components/layout/index.ts (1)

38-40: Address previous mobile-first PWA concerns.

Based on the past review comment, ensure PWALayout implements mobile-first responsive design with proper breakpoints and the useViewportMeta hook provides mobile-optimized viewport settings.

#!/bin/bash
# Description: Follow up on PWALayout mobile-first implementation as noted in past review

echo "=== Checking PWALayout for mobile-first responsive patterns ==="
if [ -f "src/components/layout/PWALayout.tsx" ]; then
  echo "→ Responsive breakpoints (should find sm:, md:, lg: patterns):"
  grep -n -E "sm:|md:|lg:|xl:" src/components/layout/PWALayout.tsx || echo "No responsive breakpoints found"
  
  echo -e "\n→ Mobile-first utility classes:"
  grep -n -E "flex|grid|p-|m-|w-|h-" src/components/layout/PWALayout.tsx | head -5
  
  echo -e "\n→ Safe area handling:"
  grep -n -A2 -B1 "safe-area\|env(" src/components/layout/PWALayout.tsx
else
  echo "PWALayout.tsx not found"
fi

echo -e "\n=== Checking useViewportMeta hook for mobile viewport settings ==="
rg -A5 -B2 "useViewportMeta" src/components/layout/PWALayout.tsx src/hooks/ || echo "useViewportMeta implementation not found in expected locations"
🧹 Nitpick comments (13)
public/sw.js (2)

1-1: Generated bundle triggers linter error for redundant "use strict"

Biome flags the "use strict" inside the Workbox define() wrapper as redundant because ESM modules are already strict-mode.
Since this file is machine-generated during the build, the warning is harmless, but you can eliminate the noise by:

-define(["./workbox-977fb9bf"],(function(e){"use strict";
+define(["./workbox-977fb9bf"],(function(e){

If you control the Workbox build step, add --format=esm (or equivalent) or a small post-processing strip to keep CI green.
Otherwise, consider silencing the rule for public/sw.js in your linter config.


1-1: Consider moving the minified SW bundle out of source control

This 500-line single-line bundle is regenerated on every build (all hashes change). Keeping it in VCS causes noisy diffs and bloats repo size.

Typical alternatives:

  1. Exclude public/sw.js via .gitignore and let your deployment pipeline upload the artifact.
  2. Commit the unminified Workbox config (e.g., workbox.config.ts) and rely on CI to emit the final service-worker at build time.

Adopting one of these keeps history meaningful and avoids merge conflicts.

src/app/[locale]/(auth)/forgot-password/page.tsx (1)

1-19: Previous critical issues have been properly addressed.

The form now correctly implements react-hook-form with Zod validation as required by project standards. However, there's a minor import order issue to fix.

Fix the import order:

-import Link from 'next/link'
-import { useTranslations, useLocale } from 'next-intl'
-import { useState } from 'react'
-import { useForm } from 'react-hook-form'
-import { zodResolver } from '@hookform/resolvers/zod'
-import { z } from 'zod'
+import Link from 'next/link'
+import { useTranslations, useLocale } from 'next-intl'
+import { useState } from 'react'
+import { zodResolver } from '@hookform/resolvers/zod'
+import { useForm } from 'react-hook-form'
+import { z } from 'zod'
src/components/navigation/components/DrawerNavigation/index.tsx (1)

8-8: Fix import order and formatting issues.

Multiple formatting and import order issues need to be addressed.

-import { useDrag } from '@use-gesture/react'
+import { useDrag } from '@use-gesture/react'

Also, move this import to the correct position according to ESLint rules (before framer-motion).

src/app/[locale]/(auth)/signup/page.tsx (1)

1-15: Previous critical issues properly resolved.

The signup form now correctly implements react-hook-form with Zod validation, addressing the previous reviewer's concerns. Minor import order issue to fix.

-import { useForm } from 'react-hook-form'
-import { zodResolver } from '@hookform/resolvers/zod'
+import { zodResolver } from '@hookform/resolvers/zod'
+import { useForm } from 'react-hook-form'
src/app/[locale]/(auth)/login/page.tsx (1)

1-15: Previous critical concerns successfully addressed.

The login form now properly implements react-hook-form with Zod validation, resolving the previous reviewer's critical feedback. Minor import order fix needed.

-import { useForm } from 'react-hook-form'
-import { zodResolver } from '@hookform/resolvers/zod'
+import { zodResolver } from '@hookform/resolvers/zod'
+import { useForm } from 'react-hook-form'
src/components/layout/LayoutDebugger.tsx (2)

19-27: Fix function component definition and apply proper formatting.

The ESLint rule prefers function declarations over const assignments for React components, and there are formatting issues throughout the file.

Apply these formatting fixes:

-export const LayoutDebugger: React.FC<LayoutDebuggerProps> = ({
+export function LayoutDebugger({
   showGrid = true,
   showBreakpoints = true,
   showContainerQueries = true,
   showTouchTargets = true,
   showViewportInfo = true,
   showPerformance = true,
   className,
-}) => {
+}: LayoutDebuggerProps) {

78-86: Improve type safety for memory API usage.

The current implementation uses any type for the performance.memory API which could be improved with proper type checking.

Apply this fix for better type safety:

-    const memoryInterval = setInterval(() => {
-      if ('memory' in performance) {
-        const memory = (performance as any).memory
-        setPerformanceMetrics(prev => ({
-          ...prev,
-          memory: Math.round(memory.usedJSHeapSize / 1048576), // Convert to MB
-        }))
-      }
-    }, 1000)
+    const memoryInterval = setInterval(() => {
+      if ('memory' in performance) {
+        const memory = (performance as any).memory
+        if (memory && typeof memory.usedJSHeapSize === 'number') {
+          setPerformanceMetrics(prev => ({
+            ...prev,
+            memory: Math.round(memory.usedJSHeapSize / 1048576), // Convert to MB
+          }))
+        }
+      }
+    }, 1000)
src/components/layout/Stack.tsx (1)

1-7: Fix import order per ESLint guidelines.

The static analysis indicates import order issues that should be resolved.

Apply this fix:

 'use client'

+import { Slot } from '@radix-ui/react-slot'
 import type React from 'react'
 import { forwardRef, type HTMLAttributes } from 'react'
-import { Slot } from '@radix-ui/react-slot'

 import { cn } from '@/lib/utils'
src/hooks/use-pwa-features.tsx (2)

1-2: Add proper import grouping.

The static analysis indicates missing empty line between import groups.

Apply this fix:

 import { useState, useEffect, useCallback } from 'react'
+
 import type { BeforeInstallPromptEvent } from '@/lib/pwa'

30-39: Fix formatting and improve standalone detection.

The formatting needs improvement and the code structure could be cleaner.

Apply this formatting fix:

   const detectStandaloneMode = useCallback(() => {
     const isStandalone =
       window.matchMedia('(display-mode: standalone)').matches ||
-      window.navigator.standalone === true ||
+      (window.navigator as any).standalone === true ||
       document.referrer.includes('android-app://') ||
       window.location.href.includes('mode=standalone')

     return isStandalone
   }, [])
src/hooks/use-navigation-persistence.tsx (1)

155-155: Remove unused parameter from popstate handler.

The e parameter is not used in the handler function.

-    const handlePopState = (e: PopStateEvent) => {
+    const handlePopState = () => {
src/hooks/useGestureNavigation.ts (1)

5-5: Fix import order to follow ESLint configuration.

The @use-gesture/react import should come after the React imports.

 import { useRouter } from 'next/navigation'
 import { useCallback, useEffect, useState } from 'react'
-import { useDrag } from '@use-gesture/react'
+import { useDrag } from '@use-gesture/react'

Move the useDrag import after the React imports to comply with the import order rules.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1f1131e and 778cc3e.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (19)
  • package.json (1 hunks)
  • public/sw.js (1 hunks)
  • src/app/[locale]/(auth)/forgot-password/page.tsx (1 hunks)
  • src/app/[locale]/(auth)/login/page.tsx (1 hunks)
  • src/app/[locale]/(auth)/signup/page.tsx (1 hunks)
  • src/app/globals.css (2 hunks)
  • src/components/layout/AdaptiveLoader.tsx (1 hunks)
  • src/components/layout/LayoutDebugger.tsx (1 hunks)
  • src/components/layout/PWALayout.tsx (1 hunks)
  • src/components/layout/ResponsiveImage.tsx (1 hunks)
  • src/components/layout/ResponsiveUtils.tsx (1 hunks)
  • src/components/layout/Section.tsx (1 hunks)
  • src/components/layout/Stack.tsx (1 hunks)
  • src/components/layout/index.ts (1 hunks)
  • src/components/navigation/components/DrawerNavigation/index.tsx (3 hunks)
  • src/hooks/use-navigation-persistence.tsx (1 hunks)
  • src/hooks/use-pwa-features.tsx (1 hunks)
  • src/hooks/useGestureNavigation.ts (4 hunks)
  • src/types/navigator.d.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/components/layout/ResponsiveUtils.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • package.json
🧰 Additional context used
📓 Path-based instructions (1)
`src/app/globals.css`: Use @import 'tailwindcss'; and define custom colors inside a @theme block.

src/app/globals.css: Use @import 'tailwindcss'; and define custom colors inside a @theme block.

📄 Source: CodeRabbit Inference Engine (CLAUDE.md)

List of files the instruction was applied to:

  • src/app/globals.css
🧠 Learnings (14)
📓 Common learnings
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: A task is only considered complete when it meets all criteria: mobile-first, internationalized, touch-friendly, offline-capable, fully type-safe, Zod validation, >80% test coverage, performance validated (Lighthouse >95), accessibility (WCAG 2.1 AA), security review, code review, and no TypeScript or ESLint errors.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: The prettier-plugin-tailwindcss is installed and will automatically sort Tailwind CSS classes on save; do not manually reorder classes.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
src/components/navigation/components/DrawerNavigation/index.tsx (3)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Implement animations using framer-motion for consistent and performant UI transitions.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use the lucide-react library for all icons throughout the application.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use Server Components by default in Next.js; only use 'use client' when interactivity is essential.
src/components/layout/LayoutDebugger.tsx (1)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
src/hooks/use-pwa-features.tsx (3)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Critical features must support offline usage via the Service Worker, following the offline-first PWA principle.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: A task is only considered complete when it meets all criteria: mobile-first, internationalized, touch-friendly, offline-capable, fully type-safe, Zod validation, >80% test coverage, performance validated (Lighthouse >95), accessibility (WCAG 2.1 AA), security review, code review, and no TypeScript or ESLint errors.
src/components/layout/ResponsiveImage.tsx (3)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use dynamic imports (next/dynamic) for heavy or non-critical components (such as charts or editors) to optimize bundle size and performance.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use Server Components by default in Next.js; only use 'use client' when interactivity is essential.
src/app/globals.css (2)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use @t3-oss/env-nextjs for type-safe environment variable validation and access; define variables in src/env.js and import the env object for usage. Do not use process.env directly in client-side components.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
src/components/layout/index.ts (5)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: A task is only considered complete when it meets all criteria: mobile-first, internationalized, touch-friendly, offline-capable, fully type-safe, Zod validation, >80% test coverage, performance validated (Lighthouse >95), accessibility (WCAG 2.1 AA), security review, code review, and no TypeScript or ESLint errors.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Critical features must support offline usage via the Service Worker, following the offline-first PWA principle.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use dynamic imports (next/dynamic) for heavy or non-critical components (such as charts or editors) to optimize bundle size and performance.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use Server Components by default in Next.js; only use 'use client' when interactivity is essential.
public/sw.js (2)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use dynamic imports (next/dynamic) for heavy or non-critical components (such as charts or editors) to optimize bundle size and performance.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use Server Components by default in Next.js; only use 'use client' when interactivity is essential.
src/app/[locale]/(auth)/forgot-password/page.tsx (3)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: All forms must be built with react-hook-form and validated with Zod, integrated via @hookform/resolvers.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: A task is only considered complete when it meets all criteria: mobile-first, internationalized, touch-friendly, offline-capable, fully type-safe, Zod validation, >80% test coverage, performance validated (Lighthouse >95), accessibility (WCAG 2.1 AA), security review, code review, and no TypeScript or ESLint errors.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
src/app/[locale]/(auth)/login/page.tsx (6)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: All forms must be built with react-hook-form and validated with Zod, integrated via @hookform/resolvers.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: All user-facing strings must be internationalized using next-intl; hardcoded strings are not allowed anywhere in the codebase.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use Server Components by default in Next.js; only use 'use client' when interactivity is essential.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: All inputs, both client and server, must be validated using Zod schemas to ensure security and type safety.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: A task is only considered complete when it meets all criteria: mobile-first, internationalized, touch-friendly, offline-capable, fully type-safe, Zod validation, >80% test coverage, performance validated (Lighthouse >95), accessibility (WCAG 2.1 AA), security review, code review, and no TypeScript or ESLint errors.
src/app/[locale]/(auth)/signup/page.tsx (4)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: All forms must be built with react-hook-form and validated with Zod, integrated via @hookform/resolvers.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: All user-facing strings must be internationalized using next-intl; hardcoded strings are not allowed anywhere in the codebase.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: All inputs, both client and server, must be validated using Zod schemas to ensure security and type safety.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: A task is only considered complete when it meets all criteria: mobile-first, internationalized, touch-friendly, offline-capable, fully type-safe, Zod validation, >80% test coverage, performance validated (Lighthouse >95), accessibility (WCAG 2.1 AA), security review, code review, and no TypeScript or ESLint errors.
src/components/layout/AdaptiveLoader.tsx (5)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use dynamic imports (next/dynamic) for heavy or non-critical components (such as charts or editors) to optimize bundle size and performance.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use Server Components by default in Next.js; only use 'use client' when interactivity is essential.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: SVGs can be imported directly as React components due to @svgr/webpack configuration.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use @t3-oss/env-nextjs for type-safe environment variable validation and access; define variables in src/env.js and import the env object for usage. Do not use process.env directly in client-side components.
src/components/layout/PWALayout.tsx (5)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Critical features must support offline usage via the Service Worker, following the offline-first PWA principle.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: All interactive elements must have a minimum touch target area of 44x44px to ensure accessibility and usability on mobile devices.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: A task is only considered complete when it meets all criteria: mobile-first, internationalized, touch-friendly, offline-capable, fully type-safe, Zod validation, >80% test coverage, performance validated (Lighthouse >95), accessibility (WCAG 2.1 AA), security review, code review, and no TypeScript or ESLint errors.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use Server Components by default in Next.js; only use 'use client' when interactivity is essential.
src/components/layout/Section.tsx (1)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use Server Components by default in Next.js; only use 'use client' when interactivity is essential.
🧬 Code Graph Analysis (6)
src/components/layout/ResponsiveImage.tsx (3)
src/components/layout/index.ts (4)
  • ResponsiveImage (12-12)
  • useViewport (16-16)
  • useDeviceCapabilities (17-17)
  • Picture (12-12)
src/components/layout/ResponsiveUtils.tsx (2)
  • useViewport (20-49)
  • useDeviceCapabilities (54-105)
src/lib/utils.ts (1)
  • cn (19-21)
src/app/[locale]/(auth)/forgot-password/page.tsx (3)
src/components/auth/auth-layout.tsx (1)
  • AuthLayout (10-25)
src/components/ui/form-input.tsx (1)
  • FormInput (50-50)
src/components/ui/primary-button.tsx (1)
  • PrimaryButton (62-62)
src/app/[locale]/(auth)/login/page.tsx (5)
src/components/auth/auth-layout.tsx (1)
  • AuthLayout (10-25)
src/components/ui/form-input.tsx (1)
  • FormInput (50-50)
src/components/ui/password-input.tsx (1)
  • PasswordInput (41-41)
src/components/ui/primary-button.tsx (1)
  • PrimaryButton (62-62)
src/components/ui/social-login-button.tsx (1)
  • SocialLoginButton (81-81)
src/components/layout/Section.tsx (2)
src/components/layout/index.ts (1)
  • Section (5-5)
src/lib/utils.ts (1)
  • cn (19-21)
src/components/layout/Stack.tsx (2)
src/components/layout/index.ts (2)
  • Stack (4-4)
  • Spacer (4-4)
src/lib/utils.ts (1)
  • cn (19-21)
src/types/navigator.d.ts (1)
src/lib/pwa.ts (1)
  • BeforeInstallPromptEvent (5-12)
🪛 ESLint
src/components/navigation/components/DrawerNavigation/index.tsx

[error] 1-1: Do not use "@ts-nocheck" because it alters compilation errors.

(@typescript-eslint/ban-ts-comment)


[error] 8-8: @use-gesture/react import should occur before import of framer-motion

(import/order)


[error] 127-127: Delete ······

(prettier/prettier)


[error] 130-130: Delete ······

(prettier/prettier)

src/components/layout/LayoutDebugger.tsx

[error] 19-366: Function component is not a function declaration

(react/function-component-definition)


[error] 80-80: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 115-115: Delete ····

(prettier/prettier)

src/hooks/use-pwa-features.tsx

[error] 1-1: There should be at least one empty line between import groups

(import/order)


[error] 98-98: Delete ·

(prettier/prettier)


[error] 101-101: Delete ······

(prettier/prettier)


[error] 227-227: Delete ··

(prettier/prettier)


[error] 232-232: Insert ··

(prettier/prettier)


[error] 233-233: Insert ··

(prettier/prettier)


[error] 236-236: Delete ····

(prettier/prettier)


[error] 239-239: Delete ····

(prettier/prettier)


[error] 245-245: Delete ··

(prettier/prettier)


[error] 251-251: Delete ····

(prettier/prettier)


[error] 255-255: Delete ····

(prettier/prettier)

src/hooks/useGestureNavigation.ts

[error] 5-5: @use-gesture/react import should occur before import of next/navigation

(import/order)

src/app/[locale]/(auth)/forgot-password/page.tsx

[error] 7-7: @hookform/resolvers/zod import should occur before import of next/link

(import/order)

src/app/[locale]/(auth)/login/page.tsx

[error] 7-7: @hookform/resolvers/zod import should occur before import of next/link

(import/order)

src/app/[locale]/(auth)/signup/page.tsx

[error] 7-7: @hookform/resolvers/zod import should occur before import of next/link

(import/order)

src/components/layout/AdaptiveLoader.tsx

[error] 143-143: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 172-218: Function component is not a function declaration

(react/function-component-definition)


[error] 231-255: Function component is not a function declaration

(react/function-component-definition)

src/components/layout/PWALayout.tsx

[error] 7-7: @/lib/pwa type import should occur before import of @/lib/utils

(import/order)


[error] 45-45: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 173-173: Replace w-full·rounded-md·px-4·py-3·text-sm·font-medium·transition-colors·active:scale-95·sm:flex-1·sm:py-2·min-h-[44px]·touch-manipulation with min-h-[44px]·w-full·touch-manipulation·rounded-md·px-4·py-3·text-sm·font-medium·transition-colors·active:scale-95·sm:flex-1·sm:py-2

(prettier/prettier)


[error] 174-174: Replace "Install·the·app" with 'Install·the·app'

(prettier/prettier)


[error] 180-180: Replace w-full·rounded-md·border·px-4·py-3·text-sm·font-medium·transition-colors·active:scale-95·sm:w-auto·sm:py-2·min-h-[44px]·touch-manipulation with min-h-[44px]·w-full·touch-manipulation·rounded-md·border·px-4·py-3·text-sm·font-medium·transition-colors·active:scale-95·sm:w-auto·sm:py-2

(prettier/prettier)


[error] 181-181: Replace "Dismiss·install·prompt" with 'Dismiss·install·prompt'

(prettier/prettier)


[error] 204-213: Function component is not a function declaration

(react/function-component-definition)


[error] 218-218: Insert ⏎··

(prettier/prettier)


[error] 219-219: Insert ··

(prettier/prettier)


[error] 220-220: Replace ·· with ····

(prettier/prettier)


[error] 221-221: Insert ··

(prettier/prettier)


[error] 222-222: Insert ··

(prettier/prettier)


[error] 223-223: Replace ·· with ····

(prettier/prettier)


[error] 224-224: Replace ·· with ····

(prettier/prettier)


[error] 225-225: Insert ··

(prettier/prettier)


[error] 226-226: Replace }·=·{} with ··}·=·{}⏎

(prettier/prettier)


[error] 229-229: Delete ····

(prettier/prettier)


[error] 241-241: Replace ·?·initial-scale=${options.initialScale}`` with ⏎········?·initial-scale=${options.initialScale}`⏎·······`

(prettier/prettier)


[error] 242-242: Replace ·?·minimum-scale=${options.minimumScale}`` with ⏎········?·minimum-scale=${options.minimumScale}`⏎·······`

(prettier/prettier)


[error] 243-243: Replace ·?·maximum-scale=${options.maximumScale}`` with ⏎········?·maximum-scale=${options.maximumScale}`⏎·······`

(prettier/prettier)


[error] 255-255: Delete ····

(prettier/prettier)


[error] 259-259: Replace viewport·&&·viewport.parentNode·&&·!document.querySelector('meta[name="viewport"][data-original]') with ⏎········viewport·&&⏎········viewport.parentNode·&&⏎········!document.querySelector('meta[name="viewport"][data-original]')⏎······

(prettier/prettier)


[error] 263-263: Replace options.width,·options.height,·options.initialScale,·options.minimumScale,·options.maximumScale,·options.userScalable,·options.viewportFit with ⏎····options.width,⏎····options.height,⏎····options.initialScale,⏎····options.minimumScale,⏎····options.maximumScale,⏎····options.userScalable,⏎····options.viewportFit,⏎··

(prettier/prettier)

src/components/layout/Section.tsx

[error] 84-84: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)

src/components/layout/Stack.tsx

[error] 5-5: @radix-ui/react-slot import should occur before type import of react

(import/order)

src/hooks/use-navigation-persistence.tsx

[error] 155-155: 'e' is defined but never used.

(@typescript-eslint/no-unused-vars)

🪛 Biome (1.9.4)
public/sw.js

[error] 1-1: Redundant use strict directive.

The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.

(lint/suspicious/noRedundantUseStrict)

src/components/layout/AdaptiveLoader.tsx

[error] 63-63: This code is unreachable

... because either this statement will return from the function, ...

... this statement will break the flow of the code, ...

... this statement will return from the function, ...

... or this statement will return from the function beforehand

(lint/correctness/noUnreachable)

src/components/layout/PWALayout.tsx

[error] 259-259: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

src/types/navigator.d.ts

[error] 2-3: This empty export is useless because there's another export or import.

This import makes useless the empty export.

Safe fix: Remove this useless empty export.

(lint/complexity/noUselessEmptyExport)

🔇 Additional comments (38)
public/sw.js (1)

1-1: Ensure self.fallback is defined before usage in the Service Worker

In public/sw.js, every handlerDidError plugin calls self.fallback(e), but there’s no local definition of self.fallback. If the imported fallback-*.js script fails to load (e.g. due to a network error), any subsequent route handler errors will break the SW.

Please verify one of the following:

  • The fallback-9clwDph9wR3HcsIQd9nqb.js script unconditionally registers self.fallback = … before any cached requests could invoke it.
  • Add a defensive stub around the import to prevent SW activation from failing if the fallback script is missing or errors out:
- importScripts("fallback-9clwDph9wR3HcsIQd9nqb.js");
+ try {
+   importScripts("fallback-9clwDph9wR3HcsIQd9nqb.js");
+ } catch (_) {
+   // Fallback stub to avoid SW activation failures
+   self.fallback = () => Response.error();
+ }
src/types/navigator.d.ts (1)

1-15: LGTM! Previous concerns have been properly addressed.

The file correctly implements global interface augmentation with proper module context. The export {} statement is necessary to make this a module and prevent global scope pollution, despite what the static analysis tool suggests.

The implementation properly:

  • Imports the BeforeInstallPromptEvent type to avoid duplication
  • Uses declare global to safely augment global interfaces
  • Maintains module context with export {}
src/app/[locale]/(auth)/forgot-password/page.tsx (3)

14-16: Well-implemented Zod schema with proper validation.

The schema correctly validates email format and ensures required fields, following project standards for input validation.


25-31: Proper react-hook-form integration with Zod resolver.

The form setup correctly uses the zodResolver to integrate Zod validation with react-hook-form, addressing the previous critical concern.


49-63: Excellent form implementation with proper error handling.

The form correctly uses react-hook-form's handleSubmit and register methods, with proper error display integration.

src/components/navigation/components/DrawerNavigation/index.tsx (2)

124-147: Proper migration to @use-gesture/react.

The gesture handling has been correctly updated to use the new library with proper event destructuring and handler consolidation.


152-165: Good type safety improvement with const assertions.

The const assertions on the spring transition types prevent TypeScript from widening the string literal types.

src/app/[locale]/(auth)/signup/page.tsx (4)

16-25: Excellent comprehensive validation schema.

The password validation is particularly robust, enforcing security best practices with:

  • Minimum length requirement
  • Mixed case requirements
  • Number requirement
  • Proper string length limits

This exceeds basic validation requirements and follows security best practices.


34-40: Proper form setup with type safety.

The react-hook-form configuration correctly integrates with the Zod schema, providing full type safety and validation.


66-98: Well-structured form with proper error handling.

The form implementation correctly uses react-hook-form's register method and displays validation errors inline, providing excellent user experience.


110-114: Good social login integration.

The social login buttons provide multiple authentication options while maintaining consistent styling and accessibility.

src/app/[locale]/(auth)/login/page.tsx (4)

16-19: Appropriate validation schema for login.

The schema correctly validates required fields without overly complex requirements for the login use case, unlike signup which needs stronger password validation.


28-34: Consistent form configuration pattern.

The react-hook-form setup follows the same pattern as other auth pages, maintaining consistency across the authentication flow.


60-93: Well-integrated form with proper UX.

The form correctly implements:

  • react-hook-form registration and error handling
  • Proper password input with forgot password link
  • Consistent styling and accessibility features

105-109: Consistent social authentication options.

The social login buttons maintain consistency with the signup page, providing multiple authentication pathways.

src/components/layout/LayoutDebugger.tsx (1)

331-360: Excellent mobile-first implementation of debugging controls.

The checkbox controls are well-structured with proper labels and accessibility attributes. The mobile-first approach with touch-friendly sizing is commendable.

src/components/layout/Stack.tsx (3)

21-35: Excellent responsive layout utilities with container query support.

The component provides comprehensive responsive options including container query support (@sm:flex-row, @sm:gap-6) which aligns perfectly with the mobile-first principle. The responsive gap classes are well-structured.


54-95: Well-implemented asChild pattern with proper TypeScript.

The component now correctly implements the asChild pattern using Radix Slot, resolving the previous incomplete implementation. The conditional component rendering and prop forwarding are properly handled.


122-137: Mobile-friendly Spacer component with accessibility.

The Spacer component is well-designed with proper aria-hidden attribute and flexible sizing options. The implementation supports both fixed and auto-growing spacers appropriately.

src/components/layout/ResponsiveImage.tsx (4)

89-102: Excellent adaptive loading strategy with mobile-first approach.

The loading strategy intelligently adapts to network conditions and device type, prioritizing performance on mobile devices and slow networks. This aligns perfectly with the mobile-first principle from the learnings.


147-168: Proper effect dependencies for preloading.

The effect dependencies are now correctly updated to include all variables that getResponsiveSrc() relies on, ensuring preload links update when device state changes.


207-226: Well-implemented image component with loading states.

The component properly handles loading states with smooth opacity transitions and includes proper error handling with fallback UI. The approach is mobile-friendly and accessible.


269-282: Excellent Picture component for art direction.

The Picture component provides proper art-directed responsive images using the HTML picture element with fallback to ResponsiveImage. This enables different images for different viewport sizes while maintaining mobile-first principles.

src/hooks/use-pwa-features.tsx (3)

81-92: Good approach to avoid CSS custom property conflicts.

The implementation correctly uses distinct CSS variable names (--js-safe-area-inset-*) to avoid conflicts with the global CSS variables. This addresses the previous concern about overwriting global safe-area variables.


94-106: Excellent mobile-friendly vibration patterns.

The vibration patterns are properly capped at 100ms for touch feedback, ensuring good mobile UX. The touch-friendly approach aligns with mobile-first principles.


214-223: Well-designed haptic feedback patterns for mobile.

The predefined haptic feedback patterns provide excellent mobile UX with appropriate vibration durations for different interaction types.

src/components/layout/PWALayout.tsx (5)

171-184: Good implementation of touch-friendly install buttons.

The install prompt buttons now properly implement the 44px minimum touch target requirement with min-h-[44px] and include proper touch-manipulation and accessibility attributes. This aligns with the accessibility requirements from the learnings.


139-158: Excellent mobile-first PWA layout implementation.

The component properly implements mobile-first responsive design with safe area handling, overflow control for touch scrolling, and PWA-specific styling. The approach aligns perfectly with the mobile-first principle.


204-212: Well-implemented SafeAreaInset component.

The component provides clean safe area inset handling with proper accessibility attributes (aria-hidden='true') and follows the pattern established in the global CSS.


227-264: Comprehensive viewport meta management with mobile-first defaults.

The useViewportMeta hook provides excellent mobile-first viewport management with sensible defaults for PWA usage. The inclusion of accessibility considerations (allowing zoom by default) is particularly noteworthy.


45-45: Fix type safety issue with navigator.standalone.

The code uses any type which should be avoided for better type safety.

Apply this fix:

-        setIsPWAInstalled(standalone || (window.navigator as any).standalone === true)
+        setIsPWAInstalled(standalone || Boolean((window.navigator as any).standalone))
⛔ Skipped due to learnings
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: A task is only considered complete when it meets all criteria: mobile-first, internationalized, touch-friendly, offline-capable, fully type-safe, Zod validation, >80% test coverage, performance validated (Lighthouse >95), accessibility (WCAG 2.1 AA), security review, code review, and no TypeScript or ESLint errors.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Critical features must support offline usage via the Service Worker, following the offline-first PWA principle.
src/app/globals.css (3)

108-112: Excellent addition of shorthand safe area variables.

The shorthand variables (--sat, --sar, --sab, --sal) provide convenient access to safe area insets and will improve developer experience when working with PWA layouts.


400-432: Well-implemented fluid spacing utilities.

The fluid spacing utilities using clamp() with viewport-relative units provide excellent responsive behavior. The progressive scaling from mobile to desktop breakpoints follows mobile-first principles perfectly.


477-633: Comprehensive print styles enhance accessibility.

The extensive print media queries provide excellent print support with proper typography scaling, color adjustments, and layout optimizations. The page break controls and content visibility management are particularly well-implemented.

src/components/layout/index.ts (4)

14-20: Excellent addition of responsive utilities.

The new responsive utilities section provides essential hooks for adaptive design. This aligns well with the mobile-first approach and device capability detection needs.


42-43: Verified: LayoutDebugger implements required overlays and toggles

I’ve confirmed that LayoutDebugger includes:

  • Grid overlay (gridEnabled) with fixed inset styling
  • Container queries outline (containerQueriesEnabled)
  • Touch-target highlighting (touchTargetsEnabled)
  • Toggle via Ctrl + Shift + D and checkbox controls in the UI

No changes are needed here—exporting LayoutDebugger as-is provides the full suite of debugging utilities.


22-28: AdaptiveLoader dynamic imports usage confirmed

Verified that DynamicComponent in src/components/layout/AdaptiveLoader.tsx correctly uses next/dynamic with a loader and fallback, and that ProgressiveEnhancement and ResourceHint are implemented as expected. No further changes needed.


1-5: Layout exports verified – Stack and Section components exist and implement mobile-first responsive patterns.

No further changes needed.

fsdiasv added 2 commits June 29, 2025 07:32
- Add suppressHydrationWarning to input components
- Prevents mismatch errors from password manager attributes (wfd-id)
- Applied fix to both FormInput and base Input components
…Navigation

- Removed @ts-nocheck directive
- Fixed drag handler type issues with @use-gesture/react
- Explicitly passed individual pointer event handlers to avoid conflicts with motion.div props
- Component is now fully type-safe
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

🔭 Outside diff range comments (1)
src/components/navigation/components/DrawerNavigation/index.tsx (1)

222-222: Internationalize hardcoded strings.

All user-facing strings must be internationalized using next-intl. The hardcoded "Menu" and "Close menu" strings violate this requirement.

Based on the project's internationalization requirements, these strings need to be replaced with internationalized versions:

-              <h2 className='text-lg font-semibold'>Menu</h2>
+              <h2 className='text-lg font-semibold'>{t('navigation.menu')}</h2>
-                <span className='sr-only'>Close menu</span>
+                <span className='sr-only'>{t('navigation.closeMenu')}</span>

You'll need to add the corresponding keys to your localization files and import the translation function.

Also applies to: 230-230

🧹 Nitpick comments (1)
src/components/navigation/components/DrawerNavigation/index.tsx (1)

151-151: Remove unnecessary type assertions.

The as const type assertions for the transition type are unnecessary since TypeScript can infer the literal type correctly.

-        type: 'spring' as const,
+        type: 'spring',
-        type: 'spring' as const,
+        type: 'spring',

Also applies to: 159-159

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 99774a2 and 46116dd.

📒 Files selected for processing (1)
  • src/components/navigation/components/DrawerNavigation/index.tsx (3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: A task is only considered complete when it meets all criteria: mobile-first, internationalized, touch-friendly, offline-capable, fully type-safe, Zod validation, >80% test coverage, performance validated (Lighthouse >95), accessibility (WCAG 2.1 AA), security review, code review, and no TypeScript or ESLint errors.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: All user-facing strings must be internationalized using next-intl; hardcoded strings are not allowed anywhere in the codebase.
src/components/navigation/components/DrawerNavigation/index.tsx (2)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: TypeScript strict mode is enforced; do not use any types and adhere strictly to tsconfig.json rules.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use the lucide-react library for all icons throughout the application.
🪛 ESLint
src/components/navigation/components/DrawerNavigation/index.tsx

[error] 7-7: @use-gesture/react import should occur before import of framer-motion

(import/order)


[error] 126-126: Delete ······

(prettier/prettier)


[error] 129-129: Delete ······

(prettier/prettier)

🔇 Additional comments (2)
src/components/navigation/components/DrawerNavigation/index.tsx (2)

123-143: Good refactoring of gesture handling logic.

The migration from react-use-gesture to @use-gesture/react with the consolidated callback pattern is well-implemented. The single callback handling movement, dragging state, and drag end detection (last flag) is cleaner than separate handlers.

However, fix the formatting issues flagged by Prettier:

 const bind = useDrag(
   ({ movement, dragging, velocity, last }) => {
     if (!enableSwipeToClose) return
-      
+     
     setIsDragging(dragging ?? false)
     handleDrag(movement)
-      
+     
     if (last) {
       handleDragEnd(movement, velocity)
     }
   },

201-205: Conditional event handler assignment is well-implemented.

The conditional assignment of drag handlers based on enableSwipeToClose provides good control over when gesture handling is active, preventing unnecessary event listeners when swipe functionality is disabled.

fsdiasv added 2 commits June 29, 2025 07:42
Replace 'ref as any' with type-safe switch statement for element rendering
- Replace CopyUI with Works-Boilerplate in all translation files
- Improve auth layout with better responsive design:
  - Adjust width distributions for better desktop/tablet experience
  - Change social login buttons to responsive 3-column grid layout
  - Remove hardcoded background colors for cleaner design
- Fix TypeScript errors in auth forms (unused parameters)
- Reorder imports in DrawerNavigation component
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

🔭 Outside diff range comments (1)
src/components/navigation/components/DrawerNavigation/index.tsx (1)

222-222: Replace hardcoded strings with internationalized versions.

The hardcoded strings "Menu" and "Close menu" violate the project's internationalization requirements. All user-facing strings must use next-intl.

Apply this diff to fix the internationalization issues:

+import { useTranslations } from 'next-intl'

// Inside the component function:
+const t = useTranslations('navigation')

// Replace the hardcoded strings:
-<h2 className='text-lg font-semibold'>Menu</h2>
+<h2 className='text-lg font-semibold'>{t('menu')}</h2>

-<span className='sr-only'>Close menu</span>
+<span className='sr-only'>{t('closeMenu')}</span>

Ensure the corresponding keys are added to your translation files.

Also applies to: 230-230

♻️ Duplicate comments (3)
src/app/[locale]/(auth)/login/page.tsx (3)

3-8: Fix import order violation.

Same import ordering issue as in the signup page.

-import Link from 'next/link'
-import { useTranslations, useLocale } from 'next-intl'
-import { useState } from 'react'
-import { useForm } from 'react-hook-form'
-import { zodResolver } from '@hookform/resolvers/zod'
-import { z } from 'zod'
+import { zodResolver } from '@hookform/resolvers/zod'
+import Link from 'next/link'
+import { useTranslations, useLocale } from 'next-intl'
+import { useState } from 'react'
+import { useForm } from 'react-hook-form'
+import { z } from 'zod'

36-41: Fix unused parameter warning.

Same issue as other auth pages - _data parameter unused for simulation.


59-59: Fix formatting issue.

Same formatting issue as other auth pages.

-        <form onSubmit={(e) => void handleSubmit(onSubmit)(e)} className='space-y-6'>
+        <form onSubmit={e => void handleSubmit(onSubmit)(e)} className='space-y-6'>
🧹 Nitpick comments (6)
src/components/navigation/components/DrawerNavigation/index.tsx (1)

123-143: Fix formatting issues in the gesture refactor.

The gesture library migration logic is correct and maintains the same functionality with the new useDrag API. However, there are formatting issues that need to be addressed.

Apply this diff to fix the formatting:

 const bind = useDrag(
   ({ movement, dragging, velocity, last }) => {
     if (!enableSwipeToClose) return
-      
+     
     setIsDragging(dragging ?? false)
     handleDrag(movement)
-      
+     
     if (last) {
       handleDragEnd(movement, velocity)
     }
src/app/[locale]/(auth)/forgot-password/page.tsx (2)

33-38: Fix unused parameter warning.

The _data parameter is intentionally unused for simulation purposes, but you can remove the underscore prefix once the actual API integration is implemented.


48-48: Fix formatting issue.

ESLint/Prettier expects simplified arrow function syntax.

-        <form onSubmit={(e) => void handleSubmit(onSubmit)(e)} className='space-y-6'>
+        <form onSubmit={e => void handleSubmit(onSubmit)(e)} className='space-y-6'>
src/app/[locale]/(auth)/signup/page.tsx (3)

3-8: Fix import order violation.

The @hookform/resolvers/zod import should come before next/link according to the project's import ordering rules.

-import Link from 'next/link'
-import { useTranslations, useLocale } from 'next-intl'
-import { useState } from 'react'
-import { useForm } from 'react-hook-form'
-import { zodResolver } from '@hookform/resolvers/zod'
-import { z } from 'zod'
+import { zodResolver } from '@hookform/resolvers/zod'
+import Link from 'next/link'
+import { useTranslations, useLocale } from 'next-intl'
+import { useState } from 'react'
+import { useForm } from 'react-hook-form'
+import { z } from 'zod'

42-47: Fix unused parameter warning.

Similar to the forgot password page, the _data parameter is intentionally unused for simulation.


65-65: Fix formatting issue.

ESLint/Prettier expects simplified arrow function syntax.

-        <form onSubmit={(e) => void handleSubmit(onSubmit)(e)} className='space-y-6'>
+        <form onSubmit={e => void handleSubmit(onSubmit)(e)} className='space-y-6'>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b3919bd and ef32413.

⛔ Files ignored due to path filters (2)
  • current.png is excluded by !**/*.png
  • image.png is excluded by !**/*.png
📒 Files selected for processing (9)
  • messages/en.json (3 hunks)
  • messages/es.json (3 hunks)
  • messages/pt.json (3 hunks)
  • src/app/[locale]/(auth)/forgot-password/page.tsx (1 hunks)
  • src/app/[locale]/(auth)/layout.tsx (1 hunks)
  • src/app/[locale]/(auth)/login/page.tsx (1 hunks)
  • src/app/[locale]/(auth)/signup/page.tsx (1 hunks)
  • src/components/auth/auth-layout.tsx (1 hunks)
  • src/components/navigation/components/DrawerNavigation/index.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/components/auth/auth-layout.tsx
  • messages/en.json
  • messages/es.json
  • messages/pt.json
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: A task is only considered complete when it meets all criteria: mobile-first, internationalized, touch-friendly, offline-capable, fully type-safe, Zod validation, >80% test coverage, performance validated (Lighthouse >95), accessibility (WCAG 2.1 AA), security review, code review, and no TypeScript or ESLint errors.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: All user-facing strings must be internationalized using next-intl; hardcoded strings are not allowed anywhere in the codebase.
src/app/[locale]/(auth)/forgot-password/page.tsx (3)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: All forms must be built with react-hook-form and validated with Zod, integrated via @hookform/resolvers.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: A task is only considered complete when it meets all criteria: mobile-first, internationalized, touch-friendly, offline-capable, fully type-safe, Zod validation, >80% test coverage, performance validated (Lighthouse >95), accessibility (WCAG 2.1 AA), security review, code review, and no TypeScript or ESLint errors.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
src/app/[locale]/(auth)/login/page.tsx (6)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: All forms must be built with react-hook-form and validated with Zod, integrated via @hookform/resolvers.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: All user-facing strings must be internationalized using next-intl; hardcoded strings are not allowed anywhere in the codebase.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use Server Components by default in Next.js; only use 'use client' when interactivity is essential.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Always develop and validate in a mobile viewport first (mobile-first principle) for all Next.js, React, and TypeScript code.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: All inputs, both client and server, must be validated using Zod schemas to ensure security and type safety.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: A task is only considered complete when it meets all criteria: mobile-first, internationalized, touch-friendly, offline-capable, fully type-safe, Zod validation, >80% test coverage, performance validated (Lighthouse >95), accessibility (WCAG 2.1 AA), security review, code review, and no TypeScript or ESLint errors.
src/app/[locale]/(auth)/signup/page.tsx (4)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: All forms must be built with react-hook-form and validated with Zod, integrated via @hookform/resolvers.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: All user-facing strings must be internationalized using next-intl; hardcoded strings are not allowed anywhere in the codebase.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: All inputs, both client and server, must be validated using Zod schemas to ensure security and type safety.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: A task is only considered complete when it meets all criteria: mobile-first, internationalized, touch-friendly, offline-capable, fully type-safe, Zod validation, >80% test coverage, performance validated (Lighthouse >95), accessibility (WCAG 2.1 AA), security review, code review, and no TypeScript or ESLint errors.
src/components/navigation/components/DrawerNavigation/index.tsx (4)
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: TypeScript strict mode is enforced; do not use any types and adhere strictly to tsconfig.json rules.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Implement animations using framer-motion for consistent and performant UI transitions.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use Server Components by default in Next.js; only use 'use client' when interactivity is essential.
Learnt from: CR
PR: fsdiasv/works-boilerplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-28T17:54:45.422Z
Learning: Use the lucide-react library for all icons throughout the application.
🪛 ESLint
src/app/[locale]/(auth)/forgot-password/page.tsx

[error] 33-33: '_data' is defined but never used.

(@typescript-eslint/no-unused-vars)


[error] 48-48: Replace (e) with e

(prettier/prettier)

src/app/[locale]/(auth)/login/page.tsx

[error] 7-7: @hookform/resolvers/zod import should occur before import of next/link

(import/order)


[error] 36-36: '_data' is defined but never used.

(@typescript-eslint/no-unused-vars)


[error] 59-59: Replace (e) with e

(prettier/prettier)

src/app/[locale]/(auth)/signup/page.tsx

[error] 7-7: @hookform/resolvers/zod import should occur before import of next/link

(import/order)


[error] 42-42: '_data' is defined but never used.

(@typescript-eslint/no-unused-vars)


[error] 65-65: Replace (e) with e

(prettier/prettier)

src/components/navigation/components/DrawerNavigation/index.tsx

[error] 126-126: Delete ······

(prettier/prettier)


[error] 129-129: Delete ······

(prettier/prettier)

🔇 Additional comments (12)
src/components/navigation/components/DrawerNavigation/index.tsx (4)

3-3: LGTM: Gesture library migration import.

The import change from the deprecated react-use-gesture to @use-gesture/react is correct and the import order now complies with ESLint rules.


145-145: LGTM: Clean conditional handler extraction.

The conditional extraction of drag handlers using bind() is a clean approach that only applies gesture handlers when swipe-to-close is enabled.


151-151: LGTM: Improved type safety with const assertions.

The as const type assertions for the spring transition types improve TypeScript type safety and align with strict typing requirements.

Also applies to: 159-159


201-205: LGTM: Correct pointer event handler implementation.

The explicit application of individual pointer event handlers correctly implements the new gesture library API and covers all necessary pointer events for drag gestures.

src/app/[locale]/(auth)/layout.tsx (1)

9-10: LGTM! Layout simplification aligns with new AuthLayout component.

The removal of background, padding, and width constraints makes sense given the introduction of the dedicated AuthLayout component that handles the responsive design and styling responsibilities.

src/app/[locale]/(auth)/forgot-password/page.tsx (3)

14-16: Excellent Zod schema implementation.

The email validation schema correctly combines email format validation with required field validation, following project standards.


25-31: Proper react-hook-form integration.

The form setup correctly uses zodResolver for validation integration and follows TypeScript best practices with proper typing.


40-75: Excellent internationalization and accessibility implementation.

The component properly uses next-intl for all user-facing text and includes proper accessibility attributes like autoComplete. The responsive design follows mobile-first principles.

src/app/[locale]/(auth)/signup/page.tsx (2)

16-25: Excellent password security validation.

The password schema implements strong security requirements with uppercase, lowercase, number, and minimum length validation. This follows security best practices.


49-135: Outstanding UI implementation with comprehensive features.

The signup page excellently combines:

  • Proper form validation and error handling
  • Complete internationalization
  • Social login integration
  • Legal compliance with terms/privacy links
  • Mobile-first responsive design
  • Accessibility features

This implementation meets all project standards.

src/app/[locale]/(auth)/login/page.tsx (2)

16-19: Appropriate validation for login flow.

The login schema correctly implements simpler validation compared to signup - email format validation and required password without complexity requirements, which is appropriate for the login use case.


43-112: Excellent login page implementation.

The login page provides a complete user experience with:

  • Proper form validation and error handling
  • Integrated forgot password functionality
  • Social login options
  • Full internationalization
  • Mobile-first responsive design
  • Proper accessibility attributes

This implementation successfully meets all project requirements.

@fsdiasv fsdiasv merged commit 5249826 into main Jun 29, 2025
1 check passed
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