Skip to content

Conversation

@ComputelessComputer
Copy link
Collaborator

@ComputelessComputer ComputelessComputer commented Dec 5, 2025

Summary

Adds two interactive hover-reveal links to the Resources column in the website footer:

  • "Versus [blurred]" - Shows competitor name blurred, reveals on hover (e.g., "Versus Otter.ai"), clicking navigates to the corresponding VS comparison page
  • "For [blurred]" - Shows use case blurred, reveals on hover (e.g., "For Sales"), clicking navigates to the corresponding solution page

Each hover picks a different random item from the list, so hovering repeatedly cycles through options. The getNextRandomIndex helper ensures the same item isn't shown twice in a row.

The blur effect uses Tailwind's blur-sm class with group-hover:blur-none and a smooth 150ms transition.

Competitors included: Otter.ai, Granola, Fireflies, Fathom, Notion, Obsidian

Use cases included: Sales, Recruiting, Consulting, Coaching, Research, Journalism

Updates since last revision

  • Changed from stable-per-page-load (useMemo) to shuffle-on-each-hover behavior per user feedback
  • Added getNextRandomIndex helper to avoid showing the same item twice in a row
  • Renamed "Hyprnote for ???" to "For ???" for brevity
  • Replaced "???" placeholder with blurred text that reveals on hover using Tailwind blur utilities

Review & Testing Checklist for Human

  • Verify solution routes exist - The links point to /solution/sales, /solution/recruiting, etc. Confirm these routes are valid and render correctly
  • Verify VS pages exist - Confirm all 6 VS pages (/vs/otter, /vs/granola, etc.) exist and render correctly
  • Test blur reveal effect - Verify the text is blurred when idle and becomes crisp on hover with a smooth transition
  • Test shuffle behavior - Hover over the links repeatedly and verify a different item appears each time
  • Test hover behavior on touch devices - On mobile the text stays blurred (no hover); verify clicking still navigates correctly

Test Plan

  1. Navigate to the website footer
  2. Observe "Versus [blurred]" and "For [blurred]" links - verify the dynamic part is blurred
  3. Hover over "Versus" link - verify the competitor name unblurs smoothly
  4. Move mouse away and hover again - verify a different competitor appears
  5. Click the link - verify it navigates to the correct VS page for the revealed competitor
  6. Repeat steps 3-5 for "For" link with use cases
  7. Test on mobile viewport to verify touch behavior (text stays blurred but navigation works)

Notes

…ources column

- Add hover-based dropdown for VS comparison pages (Otter, Granola, Fireflies, etc.)
- Add hover-based dropdown for platform-specific download pages (macOS, Windows, Linux)
- Include accessibility improvements: ARIA attributes, keyboard support, touch/click support
- Follow existing header dropdown pattern for consistency

Co-Authored-By: [email protected] <[email protected]>
@devin-ai-integration
Copy link
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI' or '@devin'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@netlify
Copy link

netlify bot commented Dec 5, 2025

Deploy Preview for hyprnote-storybook ready!

Name Link
🔨 Latest commit e6a4192
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote-storybook/deploys/693441c3e00e7500081869b0
😎 Deploy Preview https://deploy-preview-2134--hyprnote-storybook.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify
Copy link

netlify bot commented Dec 5, 2025

Deploy Preview for hyprnote ready!

Name Link
🔨 Latest commit e6a4192
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote/deploys/693441c3b14e580008eddd6f
😎 Deploy Preview https://deploy-preview-2134--hyprnote.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 5, 2025

📝 Walkthrough

Walkthrough

Adds hover-driven randomization and new dynamic links to the footer's ResourcesLinks and introduces four new solution route pages (coaching, consulting, journalism, research), each exporting a Route via createFileRoute with component and head metadata.

Changes

Cohort / File(s) Summary
Footer — ResourcesLinks interactive items
apps/web/src/components/footer.tsx
Added internal randomization utility getNextRandomIndex, vsList and useCasesList datasets, and local state (vsIndex, useCaseIndex) initialized randomly. Replaced static Brand image with internal Image component. Added hover/focus handlers to update indices and introduced dynamic ResourcesLinks entries (Pricing, Company Handbook, Prompt Gallery replacement, a Versus link navigating to /vs/{slug}, and a “👍 for {UseCase}” link). No public API changes.
New solution routes (4 files)
apps/web/src/routes/_view/solution/coaching.tsx, apps/web/src/routes/_view/solution/consulting.tsx, apps/web/src/routes/_view/solution/journalism.tsx, apps/web/src/routes/_view/solution/research.tsx
Added four new route-backed pages. Each file defines a React component composed of Hero, Features, Use Cases, and CTA sections, static content arrays, responsive markup, and exports Route = createFileRoute("/_view/solution/{name}") with a head() function providing meta and Open Graph metadata. No other public exports changed.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Review getNextRandomIndex for edge cases (length ≤ 1, stable randomness, off-by-one).
  • Verify hover/focus handlers and rapid interaction behavior in apps/web/src/components/footer.tsx.
  • Confirm constructed dynamic paths (/vs/{slug} and useCase.to) exist or are handled safely.
  • Spot-check SEO head() metadata, accessibility attributes (aria-labels), alt text, and link targets across the four new route files.

Possibly related PRs

Suggested reviewers

  • yujonglee

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding hover-reveal links for VS pages and use cases in the footer, which aligns with the primary modifications to the footer component.
Description check ✅ Passed The description comprehensively covers the changes to the footer component, detailing the hover-reveal functionality, randomization behavior, blur effects, and includes a testing checklist.
✨ 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 devin/1764919725-footer-dropdowns

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.

- Replace dropdown menus with simpler hover-reveal links
- 'Versus ???' reveals random competitor name on hover, links to VS page
- 'Hyprnote for ???' reveals random use case on hover, links to solution page
- Cleaner, less cluttered footer design

Co-Authored-By: [email protected] <[email protected]>
@devin-ai-integration devin-ai-integration bot changed the title feat(web): add dropdown menus for Compare and Platforms in footer Resources column feat(web): add hover-reveal links for VS pages and use cases in footer Dec 5, 2025
Copy link
Contributor

@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

🧹 Nitpick comments (1)
apps/web/src/components/footer.tsx (1)

168-179: Avoid useMemo + Math.random for behavior; prefer lazy useState (and reduce SSR mismatch risk)

Using useMemo with Math.random() and an empty dependency array makes the random pick part of component behavior, but useMemo isn’t guaranteed for that and will recompute on the client during hydration, which can desync from any server-rendered output.

To make the random choice truly “once per mount” and SSR-safe, consider lazy-initializing state instead:

-  const randomVs = useMemo(
-    () => vsList[Math.floor(Math.random() * vsList.length)],
-    [],
-  );
-  const randomUseCase = useMemo(
-    () => useCasesList[Math.floor(Math.random() * useCasesList.length)],
-    [],
-  );
+  const [randomVs] = useState(
+    () => vsList[Math.floor(Math.random() * vsList.length)],
+  );
+  const [randomUseCase] = useState(
+    () => useCasesList[Math.floor(Math.random() * useCasesList.length)],
+  );

This keeps the behavior stable across re-renders and better matches React 19 guidance about not relying on useMemo for observable behavior.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9c2dcc0 and b018663.

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

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Avoid creating a bunch of types/interfaces if they are not shared. Especially for function props, just inline them instead.
Never do manual state management for form/mutation. Use useForm (from tanstack-form) and useQuery/useMutation (from tanstack-query) instead for 99% of cases. Avoid patterns like setError.
If there are many classNames with conditional logic, use cn (import from @hypr/utils). It is similar to clsx. Always pass an array and split by logical grouping.
Use motion/react instead of framer-motion.

Files:

  • apps/web/src/components/footer.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Redirect rules - hyprnote
  • GitHub Check: Header rules - hyprnote
  • GitHub Check: ci
  • GitHub Check: fmt
  • GitHub Check: Pages changed - hyprnote
  • GitHub Check: Devin
🔇 Additional comments (1)
apps/web/src/components/footer.tsx (1)

3-21: Confirm lists align with “Compare” vs “Platforms” footer spec

The vsList and useCasesList structures look fine, but they encode competitor and “solution” use cases rather than the platform download targets described in the PR summary (macOS Apple Silicon/Intel, Windows, Linux). Please double‑check that this is the intended UX for the new Resources items; if the goal is truly “Platforms”, these should probably be a platformsList pointing at the platform-specific download URLs instead.

- Each hover picks a different random item from the list
- Uses getNextRandomIndex helper to avoid showing same item twice in a row
- Versus ??? and Hyprnote for ??? now shuffle on repeated hovers

Co-Authored-By: [email protected] <[email protected]>
Copy link
Contributor

@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

♻️ Duplicate comments (1)
apps/web/src/components/footer.tsx (1)

224-256: Hover-only reveal still breaks a11y and non-pointer UX; move handlers to Link and add focus/ARIA (plus verify randomization behavior)

The current implementation keeps the key issues previously flagged:

  • The real link purpose is hidden behind onMouseEnter/onMouseLeave attached to <li>:
    • Keyboard users never trigger these handlers, so they only ever see “Versus ???” / “Hyprnote for ???”.
    • Touch users typically don’t get hover, so they tap a link whose destination they can’t infer.
    • Screen readers get the literal text “Versus ???” / “Hyprnote for ???” as the accessible name, which does not describe the actual destination.
  • You also re-randomize on every mouse enter via setVsIndex / setUseCaseIndex, so the selection is no longer “stable per page load” as described in the PR objectives; instead, pointer users can get a new random target each time they hover, while non-pointer users are stuck with the initial (hidden) choice.

This is a user-facing and a11y concern, not just a cosmetic one.

Concrete suggestion:

  1. Move hover/focus handlers onto the Link elements and add keyboard support.
  2. Expose a stable accessible name via aria-label so screen readers know the destination even when the visual text shows ???.
  3. (Optional/spec check) If you intended the random selection to be stable per page load, drop the setVsIndex / setUseCaseIndex calls from hover and rely only on the initial random indices.

Example diff adapting your current code:

-        <li
-          onMouseEnter={() => {
-            setIsVersusHovered(true);
-            setVsIndex((prev) => getNextRandomIndex(vsList.length, prev));
-          }}
-          onMouseLeave={() => setIsVersusHovered(false)}
-        >
-          <Link
-            to="/vs/$slug"
-            params={{ slug: currentVs.slug }}
-            className="text-sm text-neutral-600 hover:text-stone-600 transition-colors no-underline hover:underline hover:decoration-dotted"
-          >
-            {isVersusHovered ? `Versus ${currentVs.name}` : "Versus ???"}
-          </Link>
-        </li>
+        <li>
+          <Link
+            to="/vs/$slug"
+            params={{ slug: currentVs.slug }}
+            className="text-sm text-neutral-600 hover:text-stone-600 transition-colors no-underline hover:underline hover:decoration-dotted"
+            onMouseEnter={() => {
+              setIsVersusHovered(true);
+              setVsIndex((prev) => getNextRandomIndex(vsList.length, prev));
+            }}
+            onMouseLeave={() => setIsVersusHovered(false)}
+            onFocus={() => setIsVersusHovered(true)}
+            onBlur={() => setIsVersusHovered(false)}
+            aria-label={`Compare Hyprnote vs ${currentVs.name}`}
+          >
+            {isVersusHovered ? `Versus ${currentVs.name}` : "Versus ???"}
+          </Link>
+        </li>
@@
-        <li
-          onMouseEnter={() => {
-            setIsUsedInHovered(true);
-            setUseCaseIndex((prev) =>
-              getNextRandomIndex(useCasesList.length, prev),
-            );
-          }}
-          onMouseLeave={() => setIsUsedInHovered(false)}
-        >
-          <Link
-            to={currentUseCase.to}
-            className="text-sm text-neutral-600 hover:text-stone-600 transition-colors no-underline hover:underline hover:decoration-dotted"
-          >
-            {isUsedInHovered
-              ? `Hyprnote for ${currentUseCase.label}`
-              : "Hyprnote for ???"}
-          </Link>
-        </li>
+        <li>
+          <Link
+            to={currentUseCase.to}
+            className="text-sm text-neutral-600 hover:text-stone-600 transition-colors no-underline hover:underline hover:decoration-dotted"
+            onMouseEnter={() => {
+              setIsUsedInHovered(true);
+              setUseCaseIndex((prev) =>
+                getNextRandomIndex(useCasesList.length, prev),
+              );
+            }}
+            onMouseLeave={() => setIsUsedInHovered(false)}
+            onFocus={() => setIsUsedInHovered(true)}
+            onBlur={() => setIsUsedInHovered(false)}
+            aria-label={`Hyprnote for ${currentUseCase.label}`}
+          >
+            {isUsedInHovered
+              ? `Hyprnote for ${currentUseCase.label}`
+              : "Hyprnote for ???"}
+          </Link>
+        </li>

This keeps the playful hover behavior but makes the links understandable and usable for keyboard, touch, and assistive tech users. Also, please double-check that @tanstack/react-router’s Link in your version accepts these standard DOM event handlers and ARIA props as expected.

🧹 Nitpick comments (1)
apps/web/src/components/footer.tsx (1)

176-189: State shape in ResourcesLinks is reasonable

The combination of hover flags plus index state (vsIndex, useCaseIndex) and simple derived values (currentVs, currentUseCase) is a clear and maintainable way to support the randomized footer links; no issues from a correctness or complexity standpoint. If you later touch this, you might consider renaming isUsedInHovered to something like isUseCaseHovered for clarity, but it’s non-blocking.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b018663 and c95858d.

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

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Avoid creating a bunch of types/interfaces if they are not shared. Especially for function props, just inline them instead.
Never do manual state management for form/mutation. Use useForm (from tanstack-form) and useQuery/useMutation (from tanstack-query) instead for 99% of cases. Avoid patterns like setError.
If there are many classNames with conditional logic, use cn (import from @hypr/utils). It is similar to clsx. Always pass an array and split by logical grouping.
Use motion/react instead of framer-motion.

Files:

  • apps/web/src/components/footer.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Redirect rules - hyprnote
  • GitHub Check: Header rules - hyprnote
  • GitHub Check: Devin
  • GitHub Check: Pages changed - hyprnote
  • GitHub Check: ci
  • GitHub Check: fmt
🔇 Additional comments (1)
apps/web/src/components/footer.tsx (1)

3-30: Random helper and option lists look correct

getNextRandomIndex correctly avoids repeating the previous index and is safe for small lengths; vsList and useCasesList are straightforward data sources with no obvious correctness issues. I don’t see any changes needed here.

devin-ai-integration bot and others added 3 commits December 6, 2025 05:01
- Remove hover boolean states (no longer needed)
- Use Tailwind blur-sm and group-hover:blur-none for reveal effect
- Only blur the dynamic part (competitor name / use case label)
- Add smooth transition with duration-150

Co-Authored-By: [email protected] <[email protected]>
Copy link
Contributor

@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

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fa2aa3d and d779bbc.

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

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Avoid creating a bunch of types/interfaces if they are not shared. Especially for function props, just inline them instead.
Never do manual state management for form/mutation. Use useForm (from tanstack-form) and useQuery/useMutation (from tanstack-query) instead for 99% of cases. Avoid patterns like setError.
If there are many classNames with conditional logic, use cn (import from @hypr/utils). It is similar to clsx. Always pass an array and split by logical grouping.
Use motion/react instead of framer-motion.

Files:

  • apps/web/src/components/footer.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Redirect rules - hyprnote-storybook
  • GitHub Check: Redirect rules - hyprnote
  • GitHub Check: Header rules - hyprnote-storybook
  • GitHub Check: Header rules - hyprnote
  • GitHub Check: Pages changed - hyprnote-storybook
  • GitHub Check: Pages changed - hyprnote
  • GitHub Check: ci
  • GitHub Check: fmt
🔇 Additional comments (4)
apps/web/src/components/footer.tsx (4)

3-3: LGTM!

The useState import is necessary for the new hover-reveal functionality.


5-12: LGTM!

The helper correctly prevents immediate repeats by looping until a different index is found. Edge cases (length ≤ 1) are handled appropriately.


177-186: LGTM!

State initialization correctly uses functional form to compute random initial indices only once, and derived values are cleanly computed from state.


14-21: All VS comparison routes are properly implemented through the dynamic route handler at apps/web/src/routes/_view/vs/$slug.tsx. The vsList slugs (otter, granola, fireflies, fathom, notion, obsidian) are correctly used with TanStack Router's params API (params={{ slug: currentVs.slug }}), and the single dynamic route handler serves all competitor pages.

Likely an incorrect or invalid review comment.

Copy link
Contributor

@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 (2)
apps/web/src/routes/_view/solution/research.tsx (1)

6-32: Research solution route is solid; consider a shared solution layout

This page is correctly wired and consistent with the other solution routes; if you expect more of these, you might eventually extract a shared “solution page” layout (Hero/Features/Use Cases/CTA) that takes copy and icon data as props to reduce duplication across coaching/consulting/research/journalism.

Also applies to: 96-245

apps/web/src/components/footer.tsx (1)

176-259: Randomized footer links behave as intended; watch out for SSR/hydration randomness

The hover/focus randomization plus blur reveal and aria-labels look good and are accessible-friendly; the non-repeating selection matches the spec. The only caveat is that using Math.random() in the useState initializer can cause SSR/hydration mismatches in React (server and client choose different initial items). If hydration warnings become noisy, consider a deterministic initial index (e.g., 0 or a hash of pathname) and move the randomization to a useEffect or just to the hover/focus handlers.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d779bbc and c45fae0.

⛔ Files ignored due to path filters (1)
  • apps/web/src/routeTree.gen.ts is excluded by !**/*.gen.ts
📒 Files selected for processing (5)
  • apps/web/src/components/footer.tsx (3 hunks)
  • apps/web/src/routes/_view/solution/coaching.tsx (1 hunks)
  • apps/web/src/routes/_view/solution/consulting.tsx (1 hunks)
  • apps/web/src/routes/_view/solution/journalism.tsx (1 hunks)
  • apps/web/src/routes/_view/solution/research.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Avoid creating a bunch of types/interfaces if they are not shared. Especially for function props, just inline them instead.
Never do manual state management for form/mutation. Use useForm (from tanstack-form) and useQuery/useMutation (from tanstack-query) instead for 99% of cases. Avoid patterns like setError.
If there are many classNames with conditional logic, use cn (import from @hypr/utils). It is similar to clsx. Always pass an array and split by logical grouping.
Use motion/react instead of framer-motion.

Files:

  • apps/web/src/routes/_view/solution/research.tsx
  • apps/web/src/routes/_view/solution/coaching.tsx
  • apps/web/src/routes/_view/solution/journalism.tsx
  • apps/web/src/components/footer.tsx
  • apps/web/src/routes/_view/solution/consulting.tsx
🧬 Code graph analysis (2)
apps/web/src/routes/_view/solution/research.tsx (4)
apps/web/src/routes/_view/solution/coaching.tsx (1)
  • Route (6-32)
apps/web/src/routes/_view/solution/consulting.tsx (1)
  • Route (6-32)
apps/web/src/routes/_view/solution/journalism.tsx (1)
  • Route (6-32)
packages/utils/src/cn.ts (1)
  • cn (20-22)
apps/web/src/routes/_view/solution/consulting.tsx (4)
apps/web/src/routes/_view/solution/coaching.tsx (1)
  • Route (6-32)
apps/web/src/routes/_view/solution/journalism.tsx (1)
  • Route (6-32)
apps/web/src/routes/_view/solution/research.tsx (1)
  • Route (6-32)
packages/utils/src/cn.ts (1)
  • cn (20-22)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Redirect rules - hyprnote-storybook
  • GitHub Check: Header rules - hyprnote-storybook
  • GitHub Check: Pages changed - hyprnote-storybook
  • GitHub Check: Redirect rules - hyprnote
  • GitHub Check: Header rules - hyprnote
  • GitHub Check: Pages changed - hyprnote
  • GitHub Check: ci
  • GitHub Check: fmt
🔇 Additional comments (4)
apps/web/src/routes/_view/solution/coaching.tsx (1)

6-32: Coaching solution route and layout look consistent and sound

Route config, SEO meta, and the four-section layout (Hero/Features/Use Cases/CTA) are all consistent with the existing solution pages and wired correctly; I don’t see any issues here.

Also applies to: 96-244

apps/web/src/routes/_view/solution/consulting.tsx (1)

6-32: Consulting solution page matches the shared solution pattern

Routing, meta tags, and the sectioned layout mirror the other solution pages cleanly; content and links look correct.

Also applies to: 96-244

apps/web/src/components/footer.tsx (1)

3-30: Random index helper and option lists look correct

getNextRandomIndex correctly prevents immediate repeats, and the vsList / useCasesList entries line up with the described /vs/$slug and /solution/* destinations.

apps/web/src/routes/_view/solution/journalism.tsx (1)

6-32: Journalism solution page is consistent and well-structured

Route setup, SEO meta, and the four-section layout align with the other solution pages; content and internal links look correct.

Also applies to: 96-244

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
apps/web/src/components/footer.tsx (1)

63-67: Good reuse of shared Image component for the logo

Swapping the raw <img> for the shared <Image> keeps logo styling consistent with the rest of the app and centralizes image behavior/optimizations. As a minor consistency idea, you could optionally do the same for the small Hyprnote icon in the “Versus” link for a single image pipeline.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c45fae0 and e6a4192.

📒 Files selected for processing (1)
  • apps/web/src/components/footer.tsx (5 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Avoid creating a bunch of types/interfaces if they are not shared. Especially for function props, just inline them instead.
Never do manual state management for form/mutation. Use useForm (from tanstack-form) and useQuery/useMutation (from tanstack-query) instead for 99% of cases. Avoid patterns like setError.
If there are many classNames with conditional logic, use cn (import from @hypr/utils). It is similar to clsx. Always pass an array and split by logical grouping.
Use motion/react instead of framer-motion.

Files:

  • apps/web/src/components/footer.tsx
🧬 Code graph analysis (1)
apps/web/src/components/footer.tsx (1)
apps/web/src/components/image.tsx (1)
  • Image (4-24)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Redirect rules - hyprnote
  • GitHub Check: Header rules - hyprnote
  • GitHub Check: Pages changed - hyprnote
  • GitHub Check: fmt
  • GitHub Check: ci
🔇 Additional comments (2)
apps/web/src/components/footer.tsx (2)

3-32: Random index helper and data lists look correct and side‑effect free

getNextRandomIndex correctly handles length <= 1 and guarantees a different index for length > 1, and vsList / useCasesList are simple static configs with clear slug/label fields. The lazy useState initializers using Math.random() are appropriate here and keep the randomization encapsulated.


179-295: Dynamic Resources links behavior matches the spec; only minor polish considerations

The vsIndex / useCaseIndex state plus getNextRandomIndex give the desired “no immediate repeat” randomization, and limiting updates to onMouseEnter / onFocus avoids the earlier UX issue of changing while blurred. The blur/focus classes (group-hover:blur-none, group-focus:blur-none) plus the aria-label values provide a good balance between playful UI and accessibility.

A couple of small, non‑blocking considerations:

  • Randomization fires on both onMouseEnter and onFocus, so moving from keyboard focus to mouse hover (or vice versa) can change the target again immediately; if you want slightly more predictable behavior you could choose one primary trigger (e.g., only onMouseEnter for pointer, only onFocus for keyboard).
  • Ensure the useCasesList.to paths and vsList.slug values line up with actual route definitions (/solution/* and /vs/$slug), so these links never 404 if route slugs change later.

Overall, the implementation is solid and aligned with the PR objectives.

@ComputelessComputer ComputelessComputer merged commit 38926d6 into main Dec 6, 2025
13 checks passed
@ComputelessComputer ComputelessComputer deleted the devin/1764919725-footer-dropdowns branch December 6, 2025 14:51
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