Skip to content

Conversation

@antoncoding
Copy link
Owner

@antoncoding antoncoding commented Dec 29, 2025

  • Update landing page
  • Update layout + navbar to have more space, and more compact mode
  • Refine landing page buttons and navigations, copies
  • update loading page to new graphics
  • landing page graphic

Summary by CodeRabbit

  • New Features

    • New landing visuals and components: animated grid dividers, grid accents, feature cards, powered-by badge, scroll-reveal, and section tags
    • Asset selector gains a compact display option
  • Style

    • Added grid texture utilities and light/dark theme tokens
    • Harmonized header/navigation spacing and responsive typography
    • Reduced horizontal padding on multiple pages for fuller-width layouts
  • Refactor

    • Removed legacy slot animation component
    • Simplified vault UI and standardized transaction preview to "Last 5" items
  • Behavior

    • Markets table enhanced for pagination, styling and mobile responsiveness

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

@vercel
Copy link

vercel bot commented Dec 29, 2025

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

Project Deployment Review Updated (UTC)
monarch Ready Ready Preview, Comment Dec 30, 2025 8:43am

@coderabbitai
Copy link

coderabbitai bot commented Dec 29, 2025

📝 Walkthrough

Walkthrough

Adds global grid background utilities and tokens; introduces multiple landing UI components (grid accents, animated/divider grids, feature cards, badge, reveal); updates header/navbar spacing and separators; removes a RebalanceAnimation component; removes owner-only controls from vault cards; trims side padding across several pages; tightens transaction-history preview.

Changes

Cohort / File(s) Summary
Global styles
app/global.css
Add grid background utilities (.bg-dot-grid, .bg-line-grid), mask/fade helpers (.grid-corner-mask, .grid-top-fade, .grid-bottom-fade, .grid-radial-fade) and CSS tokens (--grid-line-color, --grid-dot-color, --grid-cell-active, --grid-cell-muted) with dark-mode overrides.
New landing components & exports
src/components/landing/*.tsx, src/components/landing/index.ts
Add client components: AnimatedGridDivider (+Responsive/Compact), FeatureCard, GridAccent, PoweredByBadge, ScrollGridReveal, SectionTag; update index.ts to re-export them.
Removed animation
src/components/animations/RebalanceAnimation.tsx
Delete RebalanceAnimation component and its types/constants/assets/interval-driven logic.
Landing / Home
src/features/home/home-view.tsx, src/features/home/typing-title.tsx
Replace hero/sections with new landing components and dot-grid background; adjust responsive typography and remove theme-mounted logic.
Header & navigation
src/components/layout/header/Header.tsx, .../Menu.tsx, .../Navbar.tsx, .../NavbarMobile.tsx
Reduce spacer/header heights, simplify header layout, add dashed separators between nav items, adjust logo/icon sizes, tweak More menu and mobile menu (Autovault removed from mobile).
Vault UI changes
src/features/autovault/components/vault-detail/*.tsx, src/features/autovault/vault-list-view.tsx, src/features/autovault/vault-view.tsx
Remove owner-only UI (gear/settings) and related hooks from allocator/collaterals cards; replace BenefitCard with FeatureCard in vault-list; add dot-grid background and adjust containers; remove TransactionHistoryPreview limit prop where used.
Markets / table API
src/features/markets/markets-view.tsx, src/features/markets/components/table/markets-table.tsx
Remove side padding from containers; MarketsView passes new props to MarketsTable (setCurrentPage, className, tableClassName, onRefresh, isMobile); MarketsTable signature extended accordingly.
Transaction history preview
src/features/history/components/transaction-history-preview.tsx
Remove limit prop from component API, fix query pageSize to 20, slice grouped results to first 5, and render static "Last 5 transactions".
Pages — padding/layout
app/settings/page.tsx, app/tools/page.tsx, src/features/positions/positions-view.tsx, src/features/rewards/rewards-view.tsx
Remove px-[4%] horizontal padding from multiple page containers to enable fuller-width layouts.
Date picker & asset selector
src/components/shared/date-picker.tsx, src/features/positions-report/components/asset-selector.tsx
DatePicker: change trigger layout, add ChevronDownIcon with rotation, adjust sizing and error styling. AssetSelector: add `variant?: 'default'
Positions report — table & view
src/features/positions-report/components/report-table.tsx, src/features/positions-report/positions-report-view.tsx
Major internal refactor: add MarketRow, expandable animated rows (AnimatePresence), new formatting helpers; combine market/position loading state; use compact AssetSelector and tighten controls layout.
Misc layout adjustments
src/features/market-detail/market-view.tsx, src/features/markets/markets-view.tsx, src/features/positions/positions-view.tsx, package.json
Simplify container classes, adjust spacing and wrapper usage; minor manifest/package mention updated.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly summarizes the main changes: a new landing page redesign and autovault feature launch. It directly reflects the substantial work across landing components, home view, and autovault pages.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/landing

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai bot added feature request Specific feature ready to be implemented ui User interface labels Dec 29, 2025
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: 3

🧹 Nitpick comments (5)
src/components/landing/GridAccent.tsx (2)

18-39: Position config defines unused gradient strings.

The gradient property in positionConfig (lines 21, 25, 29, 33, 37) isn't used anywhere. The inline styles (lines 56-77) duplicate this logic.

🔎 Suggested simplification

Extract the gradient string from config and parse it, or remove the unused gradient property from positionConfig:

 const positionConfig = {
   'top-left': {
     position: 'top-0 left-0',
-    gradient: 'mask-image: linear-gradient(to bottom right, black 0%, transparent 70%)',
   },
   // ... repeat for other positions
 };

Or, use the gradient strings from config:

const posConfig = positionConfig[position];
const gradientValue = posConfig.gradient.replace('mask-image: ', '');

style={{
  maskImage: gradientValue,
  WebkitMaskImage: gradientValue,
}}

56-77: Deeply nested ternary reduces readability.

The 4-level nested ternary is duplicated for both maskImage and WebkitMaskImage, making the code harder to maintain.

🔎 Proposed refactor

Extract the gradient value to a variable:

+const gradientMap = {
+  'top-left': 'linear-gradient(to bottom right, black 0%, transparent 70%)',
+  'top-right': 'linear-gradient(to bottom left, black 0%, transparent 70%)',
+  'bottom-left': 'linear-gradient(to top right, black 0%, transparent 70%)',
+  'bottom-right': 'linear-gradient(to top left, black 0%, transparent 70%)',
+  'top-strip': 'linear-gradient(to bottom, black 0%, transparent 100%)',
+};
+
+const maskGradient = gradientMap[position];
+
 return (
   <div
     className={...}
     style={{
-      maskImage:
-        position === 'top-left'
-          ? 'linear-gradient(to bottom right, black 0%, transparent 70%)'
-          : position === 'top-right'
-            ? 'linear-gradient(to bottom left, black 0%, transparent 70%)'
-            : position === 'bottom-left'
-              ? 'linear-gradient(to top right, black 0%, transparent 70%)'
-              : position === 'bottom-right'
-                ? 'linear-gradient(to top left, black 0%, transparent 70%)'
-                : 'linear-gradient(to bottom, black 0%, transparent 100%)',
-      WebkitMaskImage:
-        position === 'top-left'
-          ? 'linear-gradient(to bottom right, black 0%, transparent 70%)'
-          : position === 'top-right'
-            ? 'linear-gradient(to bottom left, black 0%, transparent 70%)'
-            : position === 'bottom-left'
-              ? 'linear-gradient(to top right, black 0%, transparent 70%)'
-              : position === 'bottom-right'
-                ? 'linear-gradient(to top left, black 0%, transparent 70%)'
-                : 'linear-gradient(to bottom, black 0%, transparent 100%)',
+      maskImage: maskGradient,
+      WebkitMaskImage: maskGradient,
     }}
src/components/landing/AnimatedGridDivider.tsx (2)

119-141: Wrapper types omit non-existent prop.

Omit<AnimatedGridDividerProps, 'columns'> references columns, but AnimatedGridDividerProps doesn't have a columns prop. Harmless, but slightly misleading.

Cleaner alternative
-export function ResponsiveGridDivider({ className, rows = 6, variant = 'default', ...props }: Omit<AnimatedGridDividerProps, 'columns'>) {
+export function ResponsiveGridDivider({ className, rows = 6, variant = 'default', ...props }: AnimatedGridDividerProps) {

68-75: Cell array recreation on state change.

Each animation tick recreates the entire cells array. For large viewports this could be hundreds of objects. Acceptable for a decorative component, but if jank appears, consider tracking only activeCells and checking membership inline during render.

src/features/autovault/vault-list-view.tsx (1)

86-95: Fetch logic duplicated between effect and retry handler.

Minor duplication. Could extract a fetchVaults function and call it from both places, but the current approach is readable enough.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eb3ea57 and 7f2fe6c.

📒 Files selected for processing (26)
  • app/global.css
  • app/settings/page.tsx
  • app/tools/page.tsx
  • src/components/animations/RebalanceAnimation.tsx
  • src/components/landing/AnimatedGridDivider.tsx
  • src/components/landing/FeatureCard.tsx
  • src/components/landing/GridAccent.tsx
  • src/components/landing/PoweredByBadge.tsx
  • src/components/landing/ScrollGridReveal.tsx
  • src/components/landing/SectionTag.tsx
  • src/components/landing/index.ts
  • src/components/layout/header/Header.tsx
  • src/components/layout/header/Menu.tsx
  • src/components/layout/header/Navbar.tsx
  • src/components/layout/header/NavbarMobile.tsx
  • src/features/autovault/components/vault-detail/vault-allocator-card.tsx
  • src/features/autovault/components/vault-detail/vault-collaterals-card.tsx
  • src/features/autovault/vault-list-view.tsx
  • src/features/autovault/vault-view.tsx
  • src/features/history/components/transaction-history-preview.tsx
  • src/features/home/home-view.tsx
  • src/features/home/typing-title.tsx
  • src/features/market-detail/market-view.tsx
  • src/features/markets/markets-view.tsx
  • src/features/positions/positions-view.tsx
  • src/features/rewards/rewards-view.tsx
💤 Files with no reviewable changes (1)
  • src/components/animations/RebalanceAnimation.tsx
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2024-10-12T09:23:16.495Z
Learnt from: antoncoding
Repo: antoncoding/monarch PR: 63
File: app/markets/components/MarketRowDetail.tsx:49-52
Timestamp: 2024-10-12T09:23:16.495Z
Learning: When rendering oracle feeds in `ExpandedMarketDetail` (`app/markets/components/MarketRowDetail.tsx`), prefer explicit rendering over iterating keys when dealing with a small number of feeds.

Applied to files:

  • src/features/market-detail/market-view.tsx
  • src/features/markets/markets-view.tsx
📚 Learning: 2025-12-09T10:06:43.810Z
Learnt from: antoncoding
Repo: antoncoding/monarch PR: 231
File: src/hooks/useDeployMorphoMarketV1Adapter.ts:3-3
Timestamp: 2025-12-09T10:06:43.810Z
Learning: In Wagmi v3, useConnection is the correct hook to obtain the connected wallet address, chainId, and connection status (isConnected). This replaces the useAccount hook from Wagmi v2. Usage: const { address, chainId, isConnected } = useConnection() from 'wagmi'.

Applied to files:

  • src/features/autovault/components/vault-detail/vault-collaterals-card.tsx
  • src/features/autovault/components/vault-detail/vault-allocator-card.tsx
📚 Learning: 2024-12-16T02:01:51.219Z
Learnt from: antoncoding
Repo: antoncoding/monarch PR: 97
File: app/positions/components/onboarding/OnboardingContext.tsx:36-43
Timestamp: 2024-12-16T02:01:51.219Z
Learning: In `app/positions/components/onboarding/OnboardingContext.tsx`, the `defaultStep` variable is no longer needed and can be removed.

Applied to files:

  • app/settings/page.tsx
  • src/features/positions/positions-view.tsx
🧬 Code graph analysis (10)
src/components/landing/SectionTag.tsx (1)
src/components/landing/index.ts (1)
  • SectionTag (1-1)
src/components/landing/GridAccent.tsx (1)
src/components/landing/index.ts (1)
  • GridAccent (3-3)
src/components/landing/FeatureCard.tsx (1)
src/components/landing/index.ts (1)
  • FeatureCard (4-4)
src/features/autovault/components/vault-detail/vault-collaterals-card.tsx (1)
src/components/ui/card.tsx (1)
  • CardHeader (58-58)
src/features/home/home-view.tsx (8)
src/components/landing/GridAccent.tsx (1)
  • GridAccent (41-81)
src/components/landing/index.ts (6)
  • GridAccent (3-3)
  • SectionTag (1-1)
  • ResponsiveGridDivider (5-5)
  • PoweredByBadge (2-2)
  • ScrollGridReveal (6-6)
  • FeatureCard (4-4)
src/components/landing/SectionTag.tsx (1)
  • SectionTag (10-23)
src/components/landing/AnimatedGridDivider.tsx (1)
  • ResponsiveGridDivider (119-128)
src/components/landing/PoweredByBadge.tsx (1)
  • PoweredByBadge (14-58)
src/components/landing/ScrollGridReveal.tsx (1)
  • ScrollGridReveal (15-78)
src/components/landing/FeatureCard.tsx (1)
  • FeatureCard (15-52)
src/utils/external.ts (1)
  • EXTERNAL_LINKS (62-66)
src/components/landing/PoweredByBadge.tsx (1)
src/components/landing/index.ts (1)
  • PoweredByBadge (2-2)
src/components/landing/ScrollGridReveal.tsx (1)
src/components/landing/index.ts (1)
  • ScrollGridReveal (6-6)
src/components/landing/AnimatedGridDivider.tsx (1)
src/components/landing/index.ts (3)
  • AnimatedGridDivider (5-5)
  • ResponsiveGridDivider (5-5)
  • CompactGridDivider (5-5)
src/features/autovault/components/vault-detail/vault-allocator-card.tsx (1)
src/components/ui/card.tsx (1)
  • CardHeader (58-58)
src/features/history/components/transaction-history-preview.tsx (1)
src/utils/transactionGrouping.ts (1)
  • groupTransactionsByHash (45-103)
🔇 Additional comments (40)
src/features/market-detail/market-view.tsx (1)

217-217: Verify responsive horizontal padding with Tailwind container utility.

The change removes explicit responsive padding (px-6 sm:px-8 md:px-12 lg:px-16) in favor of the container utility. While Tailwind v4's container provides automatic padding at breakpoints, the behavior may differ from the previous implementation. Ensure the layout looks correct on mobile and tablet viewports.

src/features/autovault/vault-view.tsx (2)

181-181: Minor visual adjustment looks good.

Centering the header items vertically is a reasonable UI refinement.


324-330: Prop removal aligns with component API change.

The removal of limit={10} is consistent with the TransactionHistoryPreview component now using a fixed internal limit.

src/features/history/components/transaction-history-preview.tsx (3)

58-66: Verify pageSize matches display needs.

Fetching 20 transactions when only 5 groups are displayed (line 70) may over-fetch. Consider whether pageSize can be reduced to match the display limit more closely, or clarify if the extra buffer is intentional for grouping logic.


68-71: Fixed display limit simplifies component API.

Hardcoding the slice to 5 items removes flexibility but ensures consistent UX. This is a reasonable trade-off for a preview component.


108-113: Static text matches hardcoded limit.

The description now accurately reflects the fixed 5-item display.

src/features/autovault/components/vault-detail/vault-allocator-card.tsx (1)

45-45: LGTM - Clean header simplification.

Removing justify-between makes sense now that the gear icon is gone. The component still correctly displays allocators, loading states, and initialization warnings.

src/features/autovault/components/vault-detail/vault-collaterals-card.tsx (1)

40-40: Consistent with allocator card refactor.

Header simplification matches vault-allocator-card.tsx. Modal and icon removals are clean with no orphaned references elsewhere in the codebase. Collateral display logic remains intact.

app/settings/page.tsx (1)

49-49: Horizontal padding removal looks good.

Aligns with the PR-wide layout simplification. No impact on functionality.

src/features/home/typing-title.tsx (1)

152-152: Text size adjustment looks good.

Smaller text at the md breakpoint fits the updated landing design.

src/features/rewards/rewards-view.tsx (1)

144-144: Padding removal matches other pages.

Consistent layout update across the PR.

app/tools/page.tsx (1)

107-107: Padding removal is consistent.

Part of the broader layout alignment.

src/features/positions/positions-view.tsx (1)

45-45: Padding removal completes the pattern.

Consistent with all other page updates.

src/components/layout/header/NavbarMobile.tsx (2)

53-53: Verify background removal doesn't affect visibility.

The bg-surface class was removed from the nav element. Ensure the header remains visible against page backgrounds in both light and dark themes.


62-62: Visual refinements look good.

Logo and icon size reductions, plus the dashed separator, fit the updated header design.

Also applies to: 66-67, 85-86

src/components/layout/header/Menu.tsx (1)

8-8: Verify header height changes don't break layouts.

Mobile header reduced by 8px (56→48), desktop by 16px (72→56). Ensure content under the header doesn't overlap and fixed positioning elsewhere still works.

Also applies to: 12-12

src/components/layout/header/Header.tsx (2)

1-1: 'use client' directive is correct.

Needed for useState and useEffect hooks.


37-47: Header restructure looks good.

Spacer heights match Menu.tsx, and the border container with dashed styling fits the new design system.

src/features/markets/markets-view.tsx (3)

168-168: Layout simplification looks good.

Removing the horizontal padding aligns with the broader layout refactor mentioned in the PR objectives.


171-171: Padding direction change is intentional.

Shifting from bottom to top padding adjusts the vertical rhythm for the search/filter section.


221-230: Extended MarketsTable API integration looks correct.

The new props (setCurrentPage, className, tableClassName, onRefresh, isMobile) provide better control over pagination, styling, and responsiveness as documented in the summary.

src/components/layout/header/Navbar.tsx (4)

39-52: Animated underline enhancement looks good.

The reduced font size and animated underline effect improve the header's visual hierarchy and interactivity.


99-196: Dashed dividers add visual clarity.

The consistent separator styling using border-dashed and theme-aware colors improves the navbar's visual structure.


100-105: Autovault navigation link added correctly.

The new link follows the existing pattern and aligns with the PR's autovault launch objective.


180-185: Theme toggle label improvement enhances UX.

Showing the target theme ("Light Theme" when in dark mode) makes the action clearer for users.

src/components/landing/SectionTag.tsx (1)

5-23: Simple tag component implemented correctly.

The string-only children prop and bracketed formatting are appropriate for a section tag badge.

src/components/landing/PoweredByBadge.tsx (1)

14-36: Theme-aware badge with proper hydration handling.

The mounted check prevents hydration mismatches, and the skeleton state provides a smooth loading experience.

src/components/landing/FeatureCard.tsx (1)

15-52: Feature card with conditional linking implemented correctly.

The component cleanly handles both clickable (with href) and static card variants, with coordinated hover transitions.

app/global.css (2)

135-163: Grid texture utilities added for landing page.

The new utilities (bg-dot-grid, bg-line-grid, and mask effects) provide consistent decorative elements across the landing pages with proper theme support.


196-247: Theme-aware grid color variables properly defined.

Both light and dark mode grid colors are configured with appropriate opacity values for visual consistency.

src/components/landing/index.ts (1)

1-6: Barrel export consolidates landing components.

Standard pattern for organizing related component exports in a single entry point.

src/components/landing/ScrollGridReveal.tsx (2)

15-39: Looks good overall.

The IntersectionObserver setup is clean with proper cleanup. One minor note: the component will re-animate from scratch if cellCount changes (new observer created), which seems intentional for this use case.


41-49: Direction logic is correct.

The reverse() and sort() mutations are safe since indices is freshly created within the memoization scope.

src/features/home/home-view.tsx (4)

4-24: Clean imports and component setup.

Good organization pulling icons and landing components together. The new modular structure makes the page composable.


50-56: GridAccent positioned correctly.

The top-right accent with dots variant adds visual depth without blocking content.


253-267: External link handling is correct.

Good use of target="_blank" with rel="noopener noreferrer" for the GitHub link.


379-411: Footer links are accessible.

Good use of aria-label attributes for icon-based links.

src/features/autovault/vault-list-view.tsx (3)

17-17: Landing components reused effectively.

Good consistency using SectionTag and FeatureCard from the shared landing module.


224-239: Dropdown implementation is solid.

Unique keys with networkId-address combo, and the Avatar gives visual identity to each vault.


288-304: FeatureCards integrated cleanly.

Consistent with the landing page pattern. The benefit descriptions are clear and concise.

Comment on lines +49 to +56
const generateActiveCells = useCallback(() => {
const activeCount = Math.floor(totalCells * effectiveRatio);
const indices = new Set<number>();
while (indices.size < activeCount) {
indices.add(Math.floor(Math.random() * totalCells));
}
return indices;
}, [totalCells, effectiveRatio]);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Potential infinite loop if effectiveRatio >= 1.

If effectiveRatio becomes >= 1 (e.g., activeRatio passed as 1 with variant='dense' making it 1.5), activeCount could exceed totalCells, and the while loop never terminates.

Proposed fix
 const generateActiveCells = useCallback(() => {
-  const activeCount = Math.floor(totalCells * effectiveRatio);
+  const activeCount = Math.min(Math.floor(totalCells * effectiveRatio), totalCells);
   const indices = new Set<number>();
   while (indices.size < activeCount) {
     indices.add(Math.floor(Math.random() * totalCells));
   }
   return indices;
 }, [totalCells, effectiveRatio]);
📝 Committable suggestion

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

Suggested change
const generateActiveCells = useCallback(() => {
const activeCount = Math.floor(totalCells * effectiveRatio);
const indices = new Set<number>();
while (indices.size < activeCount) {
indices.add(Math.floor(Math.random() * totalCells));
}
return indices;
}, [totalCells, effectiveRatio]);
const generateActiveCells = useCallback(() => {
const activeCount = Math.min(Math.floor(totalCells * effectiveRatio), totalCells);
const indices = new Set<number>();
while (indices.size < activeCount) {
indices.add(Math.floor(Math.random() * totalCells));
}
return indices;
}, [totalCells, effectiveRatio]);
🤖 Prompt for AI Agents
In src/components/landing/AnimatedGridDivider.tsx around lines 49 to 56, the
generateActiveCells callback can enter an infinite loop when effectiveRatio >= 1
because activeCount may exceed totalCells; clamp activeCount to at most
totalCells (e.g., compute activeCount = Math.min(Math.floor(totalCells *
effectiveRatio), totalCells) or otherwise guard for activeCount > totalCells)
before the while loop, and handle the zero case (return empty set if activeCount
<= 0) so the loop always terminates.

Comment on lines +22 to +43
if (!mounted) {
return (
<div
className={cn(
'inline-flex items-center gap-2 px-3 py-1.5',
'bg-surface/50 border border-border rounded-full',
'text-base text-secondary',
className,
)}
>
<div className="h-4 w-4 rounded-full bg-muted animate-pulse" />
<span className="font-zen">Powered by Morpho</span>
</div>
);
}

return (
<div
className={cn(
'inline-flex items-center gap-2 px-3 py-1.5',
'bg-surface/50 border border-border rounded-full',
'text-sm text-secondary',
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Text size mismatch between skeleton and mounted states.

The skeleton uses text-base (line 28) while the mounted version uses text-sm (line 43). This inconsistency may cause a layout shift during hydration.

🔎 Proposed fix
         'inline-flex items-center gap-2 px-3 py-1.5',
         'bg-surface/50 border border-border rounded-full',
-        'text-base text-secondary',
+        'text-sm text-secondary',
         className,
       )}
📝 Committable suggestion

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

Suggested change
if (!mounted) {
return (
<div
className={cn(
'inline-flex items-center gap-2 px-3 py-1.5',
'bg-surface/50 border border-border rounded-full',
'text-base text-secondary',
className,
)}
>
<div className="h-4 w-4 rounded-full bg-muted animate-pulse" />
<span className="font-zen">Powered by Morpho</span>
</div>
);
}
return (
<div
className={cn(
'inline-flex items-center gap-2 px-3 py-1.5',
'bg-surface/50 border border-border rounded-full',
'text-sm text-secondary',
if (!mounted) {
return (
<div
className={cn(
'inline-flex items-center gap-2 px-3 py-1.5',
'bg-surface/50 border border-border rounded-full',
'text-sm text-secondary',
className,
)}
>
<div className="h-4 w-4 rounded-full bg-muted animate-pulse" />
<span className="font-zen">Powered by Morpho</span>
</div>
);
}
return (
<div
className={cn(
'inline-flex items-center gap-2 px-3 py-1.5',
'bg-surface/50 border border-border rounded-full',
'text-sm text-secondary',
🤖 Prompt for AI Agents
In src/components/landing/PoweredByBadge.tsx around lines 22 to 43, the skeleton
(lines ~28) uses text-base while the mounted state (line ~43) uses text-sm
causing a layout shift on hydration; make the text size consistent by changing
the skeleton's class from text-base to text-sm so both states use text-sm (or
alternatively change both to text-base if you prefer larger text), and update
the className string accordingly to keep styling consistent between states.

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 (2)
src/features/market-detail/market-view.tsx (1)

217-217: gap-8 has no effect on non-flex/grid container.

The container isn't flex or grid, so gap-8 does nothing. Children already handle spacing via mb-6, mt-8, etc. Either add flex flex-col or remove gap-8.

🔎 Proposed fix
-      <div className="font-zen container h-full gap-8 pb-12">
+      <div className="font-zen container h-full pb-12">
src/components/landing/AnimatedGridDivider.tsx (1)

49-56: Clamp activeCount to prevent infinite loop.

If effectiveRatio >= 1, activeCount can exceed totalCells, causing the while loop to never terminate.

🔎 Proposed fix
 const generateActiveCells = useCallback(() => {
-  const activeCount = Math.floor(totalCells * effectiveRatio);
+  const activeCount = Math.min(Math.floor(totalCells * effectiveRatio), totalCells);
   const indices = new Set<number>();
   while (indices.size < activeCount) {
     indices.add(Math.floor(Math.random() * totalCells));
   }
   return indices;
 }, [totalCells, effectiveRatio]);
🧹 Nitpick comments (2)
src/features/home/typing-title.tsx (1)

151-161: Consider adding accessibility support.

The animated text lacks aria-live announcements for screen readers and doesn't respect prefers-reduced-motion. For a public landing page, these would improve the experience for users with assistive tech or motion sensitivity.

src/features/markets/markets-view.tsx (1)

221-232: Table layout refactoring looks good.

The conditional rendering based on effectiveTableViewMode correctly handles expanded vs compact layouts, and the new props passed to MarketsTable align with the updated component API.

Optional: simplify conditional className logic

Lines 226-227 could be more concise by avoiding explicit undefined:

         <MarketsTable
           currentPage={currentPage}
           setCurrentPage={setCurrentPage}
-          className={effectiveTableViewMode === 'compact' ? 'w-full' : undefined}
-          tableClassName={effectiveTableViewMode === 'compact' ? 'w-full min-w-full' : undefined}
+          {...(effectiveTableViewMode === 'compact' && {
+            className: 'w-full',
+            tableClassName: 'w-full min-w-full'
+          })}
           onRefresh={handleRefresh}
           isMobile={isMobile}
         />

Or extract to variables for clarity:

+        const isCompact = effectiveTableViewMode === 'compact';
         <MarketsTable
           currentPage={currentPage}
           setCurrentPage={setCurrentPage}
-          className={effectiveTableViewMode === 'compact' ? 'w-full' : undefined}
-          tableClassName={effectiveTableViewMode === 'compact' ? 'w-full min-w-full' : undefined}
+          className={isCompact ? 'w-full' : undefined}
+          tableClassName={isCompact ? 'w-full min-w-full' : undefined}
           onRefresh={handleRefresh}
           isMobile={isMobile}
         />
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7f2fe6c and 4e6e966.

📒 Files selected for processing (26)
  • app/global.css
  • app/settings/page.tsx
  • app/tools/page.tsx
  • src/components/animations/RebalanceAnimation.tsx
  • src/components/landing/AnimatedGridDivider.tsx
  • src/components/landing/FeatureCard.tsx
  • src/components/landing/GridAccent.tsx
  • src/components/landing/PoweredByBadge.tsx
  • src/components/landing/ScrollGridReveal.tsx
  • src/components/landing/SectionTag.tsx
  • src/components/landing/index.ts
  • src/components/layout/header/Header.tsx
  • src/components/layout/header/Menu.tsx
  • src/components/layout/header/Navbar.tsx
  • src/components/layout/header/NavbarMobile.tsx
  • src/features/autovault/components/vault-detail/vault-allocator-card.tsx
  • src/features/autovault/components/vault-detail/vault-collaterals-card.tsx
  • src/features/autovault/vault-list-view.tsx
  • src/features/autovault/vault-view.tsx
  • src/features/history/components/transaction-history-preview.tsx
  • src/features/home/home-view.tsx
  • src/features/home/typing-title.tsx
  • src/features/market-detail/market-view.tsx
  • src/features/markets/markets-view.tsx
  • src/features/positions/positions-view.tsx
  • src/features/rewards/rewards-view.tsx
💤 Files with no reviewable changes (1)
  • src/components/animations/RebalanceAnimation.tsx
🚧 Files skipped from review as they are similar to previous changes (10)
  • app/tools/page.tsx
  • src/features/history/components/transaction-history-preview.tsx
  • src/components/layout/header/Menu.tsx
  • src/components/landing/index.ts
  • src/components/landing/PoweredByBadge.tsx
  • src/components/layout/header/Navbar.tsx
  • app/settings/page.tsx
  • src/features/rewards/rewards-view.tsx
  • src/features/positions/positions-view.tsx
  • src/features/autovault/vault-view.tsx
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-12-09T10:06:43.810Z
Learnt from: antoncoding
Repo: antoncoding/monarch PR: 231
File: src/hooks/useDeployMorphoMarketV1Adapter.ts:3-3
Timestamp: 2025-12-09T10:06:43.810Z
Learning: In Wagmi v3, useConnection is the correct hook to obtain the connected wallet address, chainId, and connection status (isConnected). This replaces the useAccount hook from Wagmi v2. Usage: const { address, chainId, isConnected } = useConnection() from 'wagmi'.

Applied to files:

  • src/features/autovault/components/vault-detail/vault-allocator-card.tsx
  • src/features/autovault/components/vault-detail/vault-collaterals-card.tsx
📚 Learning: 2024-11-25T09:39:42.148Z
Learnt from: antoncoding
Repo: antoncoding/monarch PR: 87
File: app/home/HomePage.tsx:17-39
Timestamp: 2024-11-25T09:39:42.148Z
Learning: In `app/home/HomePage.tsx`, the `useEffect` hook depends on `[showCustomized]` because changing `showCustomized` triggers updates to the yield and risk terms.

Applied to files:

  • src/features/home/home-view.tsx
📚 Learning: 2024-10-12T09:23:16.495Z
Learnt from: antoncoding
Repo: antoncoding/monarch PR: 63
File: app/markets/components/MarketRowDetail.tsx:49-52
Timestamp: 2024-10-12T09:23:16.495Z
Learning: When rendering oracle feeds in `ExpandedMarketDetail` (`app/markets/components/MarketRowDetail.tsx`), prefer explicit rendering over iterating keys when dealing with a small number of feeds.

Applied to files:

  • src/features/markets/markets-view.tsx
  • src/features/market-detail/market-view.tsx
🧬 Code graph analysis (8)
src/features/autovault/components/vault-detail/vault-allocator-card.tsx (1)
src/components/ui/card.tsx (1)
  • CardHeader (58-58)
src/features/autovault/components/vault-detail/vault-collaterals-card.tsx (1)
src/components/ui/card.tsx (1)
  • CardHeader (58-58)
src/features/home/home-view.tsx (7)
src/components/landing/GridAccent.tsx (1)
  • GridAccent (41-81)
src/components/landing/SectionTag.tsx (1)
  • SectionTag (10-23)
src/features/home/typing-title.tsx (1)
  • CustomTypingAnimation (41-162)
src/components/landing/PoweredByBadge.tsx (1)
  • PoweredByBadge (14-58)
src/components/landing/ScrollGridReveal.tsx (1)
  • ScrollGridReveal (15-78)
src/components/landing/FeatureCard.tsx (1)
  • FeatureCard (15-52)
src/utils/external.ts (1)
  • EXTERNAL_LINKS (62-66)
src/components/landing/GridAccent.tsx (1)
src/components/landing/index.ts (1)
  • GridAccent (3-3)
src/components/landing/FeatureCard.tsx (1)
src/components/landing/index.ts (1)
  • FeatureCard (4-4)
src/components/landing/AnimatedGridDivider.tsx (1)
src/components/landing/index.ts (3)
  • AnimatedGridDivider (5-5)
  • ResponsiveGridDivider (5-5)
  • CompactGridDivider (5-5)
src/components/landing/ScrollGridReveal.tsx (1)
src/components/landing/index.ts (1)
  • ScrollGridReveal (6-6)
src/components/landing/SectionTag.tsx (1)
src/components/landing/index.ts (1)
  • SectionTag (1-1)
🔇 Additional comments (35)
src/features/home/typing-title.tsx (1)

152-152: Styling adjustment looks good.

Reducing the text size at the medium breakpoint aligns with the PR's goal to refine the landing page layout.

src/features/markets/markets-view.tsx (2)

168-168: Layout change aligns with PR objectives.

Removing horizontal padding increases usable space for the markets view, consistent with the stated goal of creating more space in the layout.


171-171: LGTM!

Adding top padding improves the vertical spacing of the search/filter block.

src/features/market-detail/market-view.tsx (1)

217-217: Verify h-full behavior in the new layout.

Setting h-full makes this container fill 100% of its parent's height. Ensure this doesn't cause unexpected scrolling or layout issues, especially when content exceeds viewport height.

src/components/layout/header/NavbarMobile.tsx (3)

53-53: LGTM - Background simplification.

Removing bg-surface aligns with the header layout changes across the PR.


62-67: LGTM - Consistent sizing and visual separator.

Logo size reduction and the new dashed separator align with the broader header refinements.


85-86: LGTM - Icon sizing adjustment.

Consistent with the header size refinements.

src/features/autovault/components/vault-detail/vault-allocator-card.tsx (1)

45-45: LGTM - Header layout simplified.

Removing justify-between is appropriate following the removal of the owner-based gear icon.

app/global.css (2)

135-164: LGTM - Grid texture utilities added.

The new grid pattern utilities (dot-grid, line-grid) and mask effects are well-structured and support the landing page design system. CSS variable usage enables proper theme support.


196-201: LGTM - Grid color tokens for theming.

The new CSS variables for grid colors are properly scoped for both light and dark themes.

Also applies to: 243-247

src/features/autovault/components/vault-detail/vault-collaterals-card.tsx (1)

40-40: LGTM - Header layout simplified.

Consistent with the removal of owner-based UI elements across autovault components.

src/components/layout/header/Header.tsx (3)

1-1: LGTM - Client directive added.

Required for the hooks used in this component (useState, useEffect).


37-38: LGTM - Spacer for fixed header.

Prevents content overlap with the fixed header. Responsive heights match the header dimensions.


40-47: LGTM - Simplified header structure.

The fixed positioning and bordered wrapper align well with the overall header layout refinements.

src/components/landing/AnimatedGridDivider.tsx (2)

30-42: LGTM - Resize handling.

Proper viewport-based column calculation with cleanup.


77-116: LGTM - Clean rendering implementation.

Grid rendering with proper transitions and theme-aware colors.

src/components/landing/SectionTag.tsx (1)

10-22: LGTM - Simple tag component.

Clean implementation for a styled section label.

src/components/landing/FeatureCard.tsx (1)

15-52: LGTM - Feature card with optional navigation.

Proper conditional rendering for Link wrapper. Clean styling with grid-inspired borders.

src/components/landing/ScrollGridReveal.tsx (4)

7-13: LGTM!

Props are well-typed with sensible defaults.


41-49: LGTM!

Direction handling is clean and correctly memoized.


51-77: LGTM!

Animation setup and rendering logic are solid. Proper use of aria-hidden for decorative content.


19-39: The CSS custom properties --grid-cell-active and --grid-cell-muted are already defined in app/global.css. No changes needed.

src/features/home/home-view.tsx (8)

4-24: LGTM!

Icon and component imports align with the new landing page design.


35-46: LGTM!

Background grid with proper browser compatibility and accessibility attributes.


116-195: LGTM!

Section structure, feature cards, and responsive layout are well-implemented.


197-280: LGTM!

Section layout and external link handling are correct.


282-284: LGTM!

Simple and effective section divider.


286-364: LGTM!

AutoVault section properly structured with correct navigation links.


366-414: LGTM!

Footer links properly configured with security attributes and good accessibility.


48-114: Header heights are correctly aligned. The Header component defines h-[48px] on mobile and md:h-[56px] on desktop, which match the pt-[48px] and md:pt-[56px] values and viewport calculations in home-view.tsx.

src/components/landing/GridAccent.tsx (1)

5-16: LGTM!

Type and size configuration are clean and well-structured.

src/features/autovault/vault-list-view.tsx (4)

17-17: LGTM!

Updated to use shared landing components.


143-152: LGTM!

Background grid implementation matches the pattern used in home-view.tsx.


180-182: LGTM!

SectionTag properly integrated into the hero section.


288-304: LGTM!

Clean migration from BenefitCard to shared FeatureCard component. Grid width adjustment improves visual hierarchy.

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

Caution

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

⚠️ Outside diff range comments (1)
src/features/autovault/vault-view.tsx (1)

127-127: Inconsistent container styling in loading state.

The loading skeleton uses the old layout pattern while line 178 uses the new container class. This mismatch could cause a layout shift when loading completes.

🔎 Align loading state with main content
-        <div className="mx-auto w-full max-w-6xl flex-1 px-6 pb-12 rounded">
+        <div className="mx-auto container flex-1 pb-12 rounded">
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4e6e966 and 4af915f.

📒 Files selected for processing (1)
  • src/features/autovault/vault-view.tsx
🔇 Additional comments (2)
src/features/autovault/vault-view.tsx (2)

178-178: Container class standardization looks good.

The switch from fixed max-width to the container class aligns with the PR's layout refactor objectives.


181-181: Header alignment and transaction history updates look correct.

The header now centers items vertically, and the removal of the limit prop aligns with the TransactionHistoryPreview component changes noted in the AI summary.

Also applies to: 325-330

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

Caution

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

⚠️ Outside diff range comments (2)
src/components/shared/date-picker.tsx (1)

14-23: Remove unused label prop from DatePickerProps.

The label prop is destructured in the function but never used in the component. Remove it from the interface:

 export type DatePickerProps = {
-  label?: string;
   value?: ZonedDateTime | DateValue;
   onChange?: (date: ZonedDateTime) => void;
   minValue?: DateValue;
   maxValue?: DateValue;
   isInvalid?: boolean;
   errorMessage?: string;
   granularity?: 'day' | 'hour';
 };

Also remove label from the function destructuring on line 26.

src/features/positions-report/components/asset-selector.tsx (1)

43-160: Significant code duplication between variants.

The dropdown rendering (lines 95-157 vs 213-275), search input, and asset list logic are nearly identical between compact and default modes. Consider extracting shared dropdown/list rendering into a separate component or function to reduce maintenance burden.

Suggested approach

Extract the common dropdown structure:

function AssetDropdown({ 
  isOpen, 
  query, 
  setQuery, 
  setIsOpen, 
  filteredAssets, 
  selectedAsset, 
  onSelect,
  compact = false 
}) {
  return (
    <div className={cn(/* shared dropdown classes */)}>
      {/* search input */}
      {/* asset list with variant-specific sizing */}
    </div>
  );
}

Then reference it from both variants to eliminate duplication.

Also applies to: 162-277

♻️ Duplicate comments (5)
src/features/market-detail/market-view.tsx (1)

217-217: gap-8 has no effect without flex or grid layout.

The parent <div> isn't a flex or grid container, so gap-8 does nothing. Add flex flex-col or remove gap-8.

src/components/landing/AnimatedGridDivider.tsx (1)

49-56: Infinite loop risk if effectiveRatio >= 1.

When effectiveRatio >= 1 (e.g., activeRatio=0.67 with variant='dense' gives 1.005), activeCount exceeds totalCells and the while loop never terminates.

🔎 Fix: clamp activeCount
 const generateActiveCells = useCallback(() => {
-  const activeCount = Math.floor(totalCells * effectiveRatio);
+  const activeCount = Math.min(Math.floor(totalCells * effectiveRatio), totalCells);
   const indices = new Set<number>();
   while (indices.size < activeCount) {
     indices.add(Math.floor(Math.random() * totalCells));
   }
   return indices;
 }, [totalCells, effectiveRatio]);
src/components/landing/PoweredByBadge.tsx (1)

22-43: Text size mismatch causes layout shift.

Skeleton uses text-base (line 28) while mounted state uses text-sm (line 43). This causes a visible shift during hydration.

🔎 Fix: match text size
         'inline-flex items-center gap-2 px-3 py-1.5',
         'bg-surface/50 border border-border rounded-full',
-        'text-base text-secondary',
+        'text-sm text-secondary',
         className,
       )}
src/components/landing/GridAccent.tsx (2)

18-39: Unused gradient config creates duplication.

The gradient field in positionConfig is defined but never used. Lines 56-77 re-implement the same gradients inline with nested ternaries.

🔎 Option 1: Use config gradients

Extract gradient strings from positionConfig and use them in the style prop, eliminating the inline ternaries at lines 56-77.

🔎 Option 2: Remove unused gradient field

Remove the gradient field from positionConfig if you prefer keeping the inline logic.


56-77: Nested ternaries duplicate gradient definitions.

This inline gradient logic duplicates what's already in positionConfig. Consider extracting to a gradient map for cleaner code.

🔎 Gradient map approach
+const gradientMap: Record<GridAccentProps['position'], string> = {
+  'top-left': 'linear-gradient(to bottom right, black 0%, transparent 70%)',
+  'top-right': 'linear-gradient(to bottom left, black 0%, transparent 70%)',
+  'bottom-left': 'linear-gradient(to top right, black 0%, transparent 70%)',
+  'bottom-right': 'linear-gradient(to top left, black 0%, transparent 70%)',
+  'top-strip': 'linear-gradient(to bottom, black 0%, transparent 100%)',
+};

       style={{
-        maskImage:
-          position === 'top-left'
-            ? 'linear-gradient(to bottom right, black 0%, transparent 70%)'
-            : position === 'top-right'
-              ? 'linear-gradient(to bottom left, black 0%, transparent 70%)'
-              : position === 'bottom-left'
-                ? 'linear-gradient(to top right, black 0%, transparent 70%)'
-                : position === 'bottom-right'
-                  ? 'linear-gradient(to top left, black 0%, transparent 70%)'
-                  : 'linear-gradient(to bottom, black 0%, transparent 100%)',
-        WebkitMaskImage:
-          position === 'top-left'
-            ? 'linear-gradient(to bottom right, black 0%, transparent 70%)'
-            : position === 'top-right'
-              ? 'linear-gradient(to bottom left, black 0%, transparent 70%)'
-              : position === 'bottom-left'
-                ? 'linear-gradient(to top right, black 0%, transparent 70%)'
-                : position === 'bottom-right'
-                  ? 'linear-gradient(to top left, black 0%, transparent 70%)'
-                  : 'linear-gradient(to bottom, black 0%, transparent 100%)',
+        maskImage: gradientMap[position],
+        WebkitMaskImage: gradientMap[position],
       }}
🧹 Nitpick comments (4)
src/components/layout/header/Header.tsx (1)

42-42: Consider using Tailwind's z-index class.

Replace inline style with z-40 class for consistency with Tailwind conventions.

🔎 Proposed refactor
       <header
         data-scroll-state={scrollState}
-        className="fixed left-0 right-0 top-0 w-full bg-surface"
-        style={{ zIndex: 40 }}
+        className="fixed left-0 right-0 top-0 z-40 w-full bg-surface"
       >
src/features/positions-report/components/report-table.tsx (2)

150-150: Redundant BigInt() calls.

marketReport.startBalance, endBalance, and avgCapital are already bigint per the PositionReport type. The BigInt() wrapper is unnecessary.

Same applies to lines 163, 180.

Suggested fix
-<span className="text-sm">{formatNumber(BigInt(marketReport.startBalance), asset.decimals)}</span>
+<span className="text-sm">{formatNumber(marketReport.startBalance, asset.decimals)}</span>

318-325: Add rel="noopener noreferrer" to external links.

When using target="_blank", it's good practice to include rel="noopener noreferrer" to prevent potential security issues. Same applies to line 329-335.

Suggested fix
 <Link
   href={getBlockExplorerUrl(report.startBlock, chainId)}
   target="_blank"
+  rel="noopener noreferrer"
   className="text-xs text-secondary hover:text-primary hover:underline"
 >
src/components/shared/date-picker.tsx (1)

188-188: Minor: Consider using cn() for consistency.

The error message now uses an explicit class string instead of cn(). While functionally equivalent, using cn() maintains consistency with the rest of the component's styling approach.

Optional: Maintain cn() pattern
-      {isInvalid && errorMessage && <p className="font-zen text-xs text-red-500">{errorMessage}</p>}
+      {isInvalid && errorMessage && <p className={cn('font-zen text-xs text-red-500')}>{errorMessage}</p>}

This keeps the styling pattern consistent, though the difference is purely cosmetic.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4af915f and 7296914.

📒 Files selected for processing (30)
  • app/global.css
  • app/settings/page.tsx
  • app/tools/page.tsx
  • src/components/animations/RebalanceAnimation.tsx
  • src/components/landing/AnimatedGridDivider.tsx
  • src/components/landing/FeatureCard.tsx
  • src/components/landing/GridAccent.tsx
  • src/components/landing/PoweredByBadge.tsx
  • src/components/landing/ScrollGridReveal.tsx
  • src/components/landing/SectionTag.tsx
  • src/components/landing/index.ts
  • src/components/layout/header/Header.tsx
  • src/components/layout/header/Menu.tsx
  • src/components/layout/header/Navbar.tsx
  • src/components/layout/header/NavbarMobile.tsx
  • src/components/shared/date-picker.tsx
  • src/features/autovault/components/vault-detail/vault-allocator-card.tsx
  • src/features/autovault/components/vault-detail/vault-collaterals-card.tsx
  • src/features/autovault/vault-list-view.tsx
  • src/features/autovault/vault-view.tsx
  • src/features/history/components/transaction-history-preview.tsx
  • src/features/home/home-view.tsx
  • src/features/home/typing-title.tsx
  • src/features/market-detail/market-view.tsx
  • src/features/markets/markets-view.tsx
  • src/features/positions-report/components/asset-selector.tsx
  • src/features/positions-report/components/report-table.tsx
  • src/features/positions-report/positions-report-view.tsx
  • src/features/positions/positions-view.tsx
  • src/features/rewards/rewards-view.tsx
💤 Files with no reviewable changes (1)
  • src/components/animations/RebalanceAnimation.tsx
🚧 Files skipped from review as they are similar to previous changes (15)
  • src/components/layout/header/Menu.tsx
  • src/features/history/components/transaction-history-preview.tsx
  • src/components/layout/header/NavbarMobile.tsx
  • src/components/landing/index.ts
  • src/features/rewards/rewards-view.tsx
  • src/components/landing/SectionTag.tsx
  • src/features/autovault/vault-list-view.tsx
  • src/features/autovault/components/vault-detail/vault-allocator-card.tsx
  • src/components/layout/header/Navbar.tsx
  • src/features/positions/positions-view.tsx
  • app/global.css
  • src/components/landing/FeatureCard.tsx
  • app/settings/page.tsx
  • src/features/markets/markets-view.tsx
  • src/features/autovault/vault-view.tsx
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2024-10-12T09:23:16.495Z
Learnt from: antoncoding
Repo: antoncoding/monarch PR: 63
File: app/markets/components/MarketRowDetail.tsx:49-52
Timestamp: 2024-10-12T09:23:16.495Z
Learning: When rendering oracle feeds in `ExpandedMarketDetail` (`app/markets/components/MarketRowDetail.tsx`), prefer explicit rendering over iterating keys when dealing with a small number of feeds.

Applied to files:

  • src/features/market-detail/market-view.tsx
  • src/features/positions-report/components/report-table.tsx
📚 Learning: 2025-12-09T10:06:43.810Z
Learnt from: antoncoding
Repo: antoncoding/monarch PR: 231
File: src/hooks/useDeployMorphoMarketV1Adapter.ts:3-3
Timestamp: 2025-12-09T10:06:43.810Z
Learning: In Wagmi v3, useConnection is the correct hook to obtain the connected wallet address, chainId, and connection status (isConnected). This replaces the useAccount hook from Wagmi v2. Usage: const { address, chainId, isConnected } = useConnection() from 'wagmi'.

Applied to files:

  • src/features/autovault/components/vault-detail/vault-collaterals-card.tsx
📚 Learning: 2024-12-16T02:01:51.219Z
Learnt from: antoncoding
Repo: antoncoding/monarch PR: 97
File: app/positions/components/onboarding/OnboardingContext.tsx:36-43
Timestamp: 2024-12-16T02:01:51.219Z
Learning: In `app/positions/components/onboarding/OnboardingContext.tsx`, the `defaultStep` variable is no longer needed and can be removed.

Applied to files:

  • src/components/landing/GridAccent.tsx
🧬 Code graph analysis (8)
src/components/landing/PoweredByBadge.tsx (1)
src/components/landing/index.ts (1)
  • PoweredByBadge (2-2)
src/features/positions-report/positions-report-view.tsx (4)
src/hooks/useProcessedMarkets.ts (1)
  • useProcessedMarkets (27-91)
src/components/status/loading-screen.tsx (1)
  • LoadingScreen (97-126)
src/features/positions-report/components/asset-selector.tsx (1)
  • AssetSelector (23-278)
src/components/ui/spinner.tsx (1)
  • Spinner (22-58)
src/features/positions-report/components/asset-selector.tsx (3)
src/components/shared/token-icon.tsx (1)
  • TokenIcon (23-95)
src/components/shared/network-icon.tsx (1)
  • NetworkIcon (4-15)
src/utils/networks.ts (1)
  • getNetworkName (220-223)
src/features/autovault/components/vault-detail/vault-collaterals-card.tsx (1)
src/components/ui/card.tsx (1)
  • CardHeader (58-58)
src/components/landing/ScrollGridReveal.tsx (1)
src/components/landing/index.ts (1)
  • ScrollGridReveal (6-6)
src/features/positions-report/components/report-table.tsx (6)
src/utils/networks.ts (2)
  • getExplorerUrl (225-227)
  • getNetworkName (220-223)
src/hooks/usePositionReport.ts (1)
  • PositionReport (11-22)
src/utils/rateMath.ts (1)
  • convertApyToApr (15-29)
src/features/markets/components/market-identity.tsx (1)
  • MarketIdentity (32-369)
src/components/shared/token-icon.tsx (1)
  • TokenIcon (23-95)
src/components/shared/transaction-identity.tsx (1)
  • TransactionIdentity (19-32)
src/components/landing/GridAccent.tsx (1)
src/components/landing/index.ts (1)
  • GridAccent (3-3)
src/components/landing/AnimatedGridDivider.tsx (1)
src/components/landing/index.ts (3)
  • AnimatedGridDivider (5-5)
  • ResponsiveGridDivider (5-5)
  • CompactGridDivider (5-5)
🔇 Additional comments (24)
src/components/layout/header/Header.tsx (3)

1-1: Correct use of 'use client' directive.

Required for Next.js 15 components using hooks.


37-38: More compact spacing aligns with PR objectives.

Conditional spacer rendering and reduced height work well for the new layout.


44-47: Border wrapper improves layout structure.

The bottom border container properly separates header regions and aligns with the new design.

src/features/autovault/components/vault-detail/vault-collaterals-card.tsx (1)

40-42: Clean removal of owner controls.

The CardHeader simplification is correct since the gear icon was removed. Vault settings remain accessible in the parent vault-view component via dedicated buttons for general, agents, and caps settings tabs.

src/features/positions-report/components/report-table.tsx (7)

24-26: LGTM!

Simple helper, does the job.


41-51: LGTM!

Clean formatting helpers.


225-269: LGTM!

Transaction row rendering is clean with proper key usage and defensive handling of optional tx.data?.assets.


296-307: LGTM!

Sorting logic is solid: filters invalid markets, sorts active positions first, then by interest earned. Using slice() before sort() avoids mutating the original array.


419-431: LGTM!

Clean table rendering with proper keys and toggle handling.


129-143: LGTM!

Animation setup with AnimatePresence and motion.div for height transitions is well done.


96-102: The TokenIcon component accepts a symbol prop. It's defined as an optional string in TokenIconProps (src/components/shared/token-icon.tsx:15), so the code here is correct.

app/tools/page.tsx (1)

107-107: Layout change aligns with PR objectives.

Removing horizontal padding achieves full-width content, consistent with similar changes in other pages (settings, market-detail).

src/components/landing/ScrollGridReveal.tsx (1)

15-78: Implementation looks solid.

IntersectionObserver logic correctly computes fillCount and applies staggered animations. Direction handling (ltr, rtl, center-out) is clean. Observer cleanup is proper.

src/features/home/typing-title.tsx (1)

152-152: Typography adjustment looks fine.

Reduced medium-breakpoint text size from 3xl to 2xl. Styling-only change.

src/features/home/home-view.tsx (1)

28-408: Major home page refresh looks well-structured.

The component-driven layout with new landing components (SectionTag, GridAccent, FeatureCard, etc.) creates a cohesive multi-section landing experience. Navigation flow and CTAs are clear.

src/components/shared/date-picker.tsx (3)

6-6: LGTM: Chevron indicator improves UX.

The rotating chevron provides clear visual feedback for the popover state, following standard dropdown patterns.

Also applies to: 143-148


124-124: LGTM: Button restructuring aligns with compact design goals.

The simplified button structure with reduced height (h-10) and hover transitions creates a cleaner, more compact UI. The placeholder text and icon layout are intuitive.

Also applies to: 133-142


168-168: LGTM: Consistent typography for hour controls.

The explicit font and size classes ensure visual consistency between the label and select element.

Also applies to: 172-172

src/features/positions-report/components/asset-selector.tsx (2)

4-4: LGTM: Backward-compatible API extension.

The new variant prop with a default value maintains backward compatibility while enabling the compact mode. Good use of the cn utility for conditional styling.

Also applies to: 20-20, 23-23


73-74: No issue. TokenIcon accepts symbol as an optional prop in its interface definition. The code correctly passes symbol={selectedAsset.symbol} and symbol={asset.symbol} at lines 73, 145, and 193.

Likely an incorrect or invalid review comment.

src/features/positions-report/positions-report-view.tsx (4)

14-14: LGTM: Clean loading state integration.

Combining markets and positions loading into a unified state improves UX. The approach is straightforward and maintains clarity.

Also applies to: 29-29, 36-36


186-189: Good conditional feedback for users.

The LoadingScreen message now distinguishes between loading markets and positions, providing clearer feedback during the loading sequence.


203-203: LGTM: Compact variant integration.

The compact AssetSelector variant, reduced button height, and smaller spinner size align well with the tighter UI layout. Consistent application of the compact theme across controls.

Also applies to: 238-238, 243-243


164-164: No action needed: useUserPositions guarantees a non-null array.

The hook returns data: enhancedPositions ?? [] (line 260 of useUserPositions.ts), which means positions is always an array—empty when no positions exist, populated when they do. Lines 164 and 190 are 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: 0

🧹 Nitpick comments (1)
src/features/home/home-view.tsx (1)

37-44: Consider scroll performance with fixed background.

The fixed bg-dot-grid layer may cause repaints during scroll. If performance becomes an issue, consider using transform: translateZ(0) or switching to absolute positioning scoped to individual sections.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7296914 and 6831ae1.

📒 Files selected for processing (2)
  • src/components/landing/GridAccent.tsx
  • src/features/home/home-view.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/landing/GridAccent.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
src/features/home/home-view.tsx (8)
src/components/landing/GridAccent.tsx (1)
  • GridAccent (41-63)
src/components/landing/SectionTag.tsx (1)
  • SectionTag (10-23)
src/features/home/typing-title.tsx (1)
  • CustomTypingAnimation (41-162)
src/components/landing/AnimatedGridDivider.tsx (1)
  • ResponsiveGridDivider (119-128)
src/components/landing/PoweredByBadge.tsx (1)
  • PoweredByBadge (14-58)
src/components/landing/ScrollGridReveal.tsx (1)
  • ScrollGridReveal (15-78)
src/components/landing/FeatureCard.tsx (1)
  • FeatureCard (15-52)
src/utils/external.ts (1)
  • EXTERNAL_LINKS (62-66)
🔇 Additional comments (7)
src/features/home/home-view.tsx (7)

4-24: Clean import organization.

All imports are used throughout the redesigned layout. The React Icons and landing components are properly organized.


29-32: Scroll helper looks good.

Optional chaining properly handles missing elements.


50-124: Hero section well structured.

Viewport height calculations account for header, fixed height for typing animation prevents layout shift, and CTAs use appropriate navigation patterns.


126-205: Section 1 structure is solid.

Feature cards, scroll reveals, and navigation work together cleanly. Responsive grid adapts well across breakpoints.


207-290: Section 2 layout works well.

Centered header with dual scroll reveals creates nice symmetry. Feature cards appropriately mix linked and non-linked content.


292-362: Section 3 and grid divider are clean.

AutoVault feature cards follow the established pattern. Single focused CTA works well here.


364-412: Footer community links properly secured.

External links correctly use target="_blank" with rel="noopener noreferrer" and include aria-label attributes for accessibility.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature request Specific feature ready to be implemented ui User interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants