-
Couldn't load subscription status.
- Fork 400
landing-4 #1602
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
landing-4 #1602
Conversation
|
Caution Review failedThe pull request is closed. 📝 WalkthroughWalkthroughAdds Mux-based video components and a GitHub open-source showcase, integrates them into the landing route, replaces the old downloads route with a new download page, updates header/branding and small UI tweaks, adds a /cal route, and introduces stylesheet utilities and a Mux player dependency. Changes
Sequence Diagram(s)sequenceDiagram
participant Browser as User (Browser)
participant Landing as LandingPage (index.tsx)
participant Thumbnail as VideoThumbnail
participant Player as VideoPlayer
participant Modal as VideoModal
participant OSS as GitHubOpenSource
Browser->>Landing: load page
Landing->>Thumbnail: render thumbnail(s)
Browser->>Thumbnail: hover / click
alt hover (desktop)
Thumbnail->>Player: attempt hover-play & show controls
end
Browser->>Player: click expand
Player->>Landing: request open modal (set expandedVideo)
Landing->>Modal: render isOpen=true with playbackId
Modal->>Player: invoke play on player ref (autoplay)
Browser->>OSS: view avatars / click CTA
OSS-->>Browser: navigate to GitHub repo
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 2 inconclusive)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
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. Comment |
There was a problem hiding this 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
🧹 Nitpick comments (8)
apps/web/src/routes/_view/downloads.tsx (1)
61-61: LGTM. Add a focus-visible ring for keyboard users.Improves a11y without changing visuals on mouse.
- className="group flex items-center justify-between p-6 rounded-xl border border-neutral-100 hover:border-blue-300 hover:bg-blue-50/30 transition-all duration-200" + className="group flex items-center justify-between p-6 rounded-xl border border-neutral-100 hover:border-blue-300 hover:bg-blue-50/30 transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-1"apps/web/src/routes/_view/route.tsx (2)
30-31: Prevent layout shift on logo.Specify intrinsic size and decoding hints.
- <img src="/hyprnote-logo.svg" alt="Hyprnote" className="h-6" /> + <img + src="/hyprnote-logo.svg" + alt="Hyprnote" + className="h-6 w-auto" + width="96" + height="24" + decoding="async" + fetchpriority="high" + />
34-47: Avoid blanket transition-all on text links.Use transition-colors and add underline offset for clearer affordance. Lighter on the browser.
- className="text-sm text-neutral-600 hover:text-neutral-800 transition-all hover:underline decoration-dotted" + className="text-sm text-neutral-600 hover:text-neutral-800 transition-colors hover:underline decoration-dotted underline-offset-4"Apply to Docs, Blog, Pricing, Account, and Get Started.
Also applies to: 75-87
apps/web/src/routes/auth.tsx (1)
103-115: Add a visible or sr-only label for the email field.Placeholders aren’t labels; improves screen-reader UX.
+ <label htmlFor="email" className="sr-only">Email</label> <input id="email" type="email" ... />apps/web/src/components/github-open-source.tsx (3)
30-37: Avatar a11y/perf and border consistency.
- Avatars are decorative—use empty alt and lazy loading.
- Align borders with the rest of the app (neutral-100).
- className="size-10 rounded-sm overflow-hidden border-2 border-neutral-200 bg-neutral-100" + className="size-10 rounded-sm overflow-hidden border border-neutral-100 bg-neutral-100" ... - <img - src={avatar} - alt="Contributor" - className="w-full h-full object-cover" - /> + <img + src={avatar} + alt="" + loading="lazy" + decoding="async" + className="w-full h-full object-cover" + />And in StatBadge:
- <div className="flex flex-col gap-2 h-24 items-center justify-center border border-neutral-200 rounded-sm px-4 bg-neutral-100"> + <div className="flex flex-col gap-2 h-24 items-center justify-center border border-neutral-100 rounded-sm px-4 bg-neutral-100">Also applies to: 53-60
64-76: Hard-coded GitHub counts will go stale.Consider a small query (like GithubStars) or pass counts as props with a fallback.
Example (sketch):
export function GitHubOpenSource({ stars, forks }: { stars?: number; forks?: number } = {}) { const STARS_COUNT = stars ?? 6419; const FORKS_COUNT = forks ?? 396; ... }Or reuse a lightweight useQuery to fetch stargazers_count and forks.
4-4: DRY for ORG_REPO constant.It appears in multiple files; extract to a shared constant (e.g., @/constants/github.ts).
apps/web/src/routes/_view/index.tsx (1)
460-462: Stray border color with no border width.
border-neutral-100alone has no effect. Either remove it or add a border side.- <div className="aspect-video md:aspect-auto bg-neutral-50 flex items-center justify-center border-neutral-100"> + <div className="aspect-video md:aspect-auto bg-neutral-50 flex items-center justify-center">
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (5)
apps/web/public/favicon.icois excluded by!**/*.icoapps/web/public/hyprnote-logo.svgis excluded by!**/*.svgapps/web/public/hyprnote_signature_light.svgis excluded by!**/*.svgapps/web/public/team/john.pngis excluded by!**/*.pngapps/web/public/team/yujong.pngis excluded by!**/*.png
📒 Files selected for processing (6)
apps/web/src/components/github-open-source.tsx(1 hunks)apps/web/src/routes/_view/app/account.tsx(2 hunks)apps/web/src/routes/_view/downloads.tsx(1 hunks)apps/web/src/routes/_view/index.tsx(6 hunks)apps/web/src/routes/_view/route.tsx(3 hunks)apps/web/src/routes/auth.tsx(2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
After a substantial amount of TypeScript changes, run
pnpm -r typecheck
Files:
apps/web/src/routes/_view/index.tsxapps/web/src/routes/_view/app/account.tsxapps/web/src/routes/_view/route.tsxapps/web/src/routes/auth.tsxapps/web/src/components/github-open-source.tsxapps/web/src/routes/_view/downloads.tsx
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
**/*.{tsx,jsx}: When many classNames have conditional logic in React components, usecnfrom@hypr/utils
When usingcn, always pass an array of class segments
When usingcn, split entries by logical grouping for readability
Usemotion/reactinstead offramer-motion
Files:
apps/web/src/routes/_view/index.tsxapps/web/src/routes/_view/app/account.tsxapps/web/src/routes/_view/route.tsxapps/web/src/routes/auth.tsxapps/web/src/components/github-open-source.tsxapps/web/src/routes/_view/downloads.tsx
🧬 Code graph analysis (2)
apps/web/src/routes/_view/index.tsx (5)
apps/web/src/components/download-button.tsx (1)
DownloadButton(4-32)apps/web/src/components/logo-cloud.tsx (1)
LogoCloud(35-123)apps/web/src/components/social-card.tsx (1)
SocialCard(18-82)apps/web/src/components/github-open-source.tsx (1)
GitHubOpenSource(64-110)apps/web/src/components/github-stars.tsx (1)
GithubStars(5-35)
apps/web/src/components/github-open-source.tsx (1)
packages/utils/src/cn.ts (1)
cn(20-22)
🪛 Biome (2.1.2)
apps/web/src/routes/_view/index.tsx
[error] 39-39: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the rel="noopener" attribute.
(lint/security/noBlankTarget)
🔇 Additional comments (3)
apps/web/src/routes/auth.tsx (1)
89-90: Border color consistency looks good.Matches the neutral-100 pass across the app. No functional impact.
Also applies to: 92-97, 155-156
apps/web/src/routes/_view/app/account.tsx (1)
171-186: LGTM on border updates.Consistent with the new neutral-100 theme.
Also applies to: 193-213
apps/web/src/routes/_view/index.tsx (1)
1-18: Run typecheck in your local development environment to verify no type drift from TSX movements.The sandbox environment lacks the
denointerpreter needed to run the full typecheck script (deno check supabase/functions/**/*.ts && tsc --noEmit). Please execute the following in your local development environment to ensure the substantial TSX changes don't introduce type errors:pnpm -r typecheck pnpm -r lint
ae25248 to
822609e
Compare
There was a problem hiding this 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
♻️ Duplicate comments (2)
apps/web/src/routes/_view/index.tsx (1)
36-43: Security: Add rel="noopener noreferrer" to external link.This link opens in a new tab without security attributes, enabling potential tab-nabbing attacks.
Apply this diff:
<a className="decoration-dotted underline hover:text-stone-600 transition-all" href="https://github.com/fastrepl/hyprnote" target="_blank" + rel="noopener noreferrer" >apps/web/src/components/github-open-source.tsx (1)
23-41: Fix dynamic Tailwind class that will be purged.Template-interpolated class names are not detectable by Tailwind's purge mechanism and will break in production.
Apply this diff to use explicit class variants:
+import { cn } from "@hypr/utils"; + function ProfileGrid({ profiles, cols }: { profiles: string[]; cols: 2 | 3 }) { const count = cols === 2 ? 4 : 6; return ( - <div className={`grid grid-cols-${cols} gap-3`}> + <div className={cn([ + "grid gap-3", + cols === 2 ? "grid-cols-2" : "grid-cols-3", + ])}> {profiles.slice(0, count).map((avatar, idx) => (
🧹 Nitpick comments (2)
apps/web/src/components/github-open-source.tsx (2)
7-21: Address TODO comment for curated profiles.The TODO comment indicates this list may need completion or curation.
Would you like me to help generate a more comprehensive contributor list or create an issue to track this task?
64-110: Consider fetching GitHub stats dynamically.The component uses hardcoded counts while the GithubStars component (lines 4-34 in github-stars.tsx) fetches live data from the GitHub API. Consider unifying the approach for consistency and accuracy.
Example refactor to fetch counts dynamically:
import { useQuery } from "@tanstack/react-query"; export function GitHubOpenSource() { const stats = useQuery({ queryKey: ["github-repo-stats"], queryFn: async () => { const response = await fetch(`https://api.github.com/repos/${ORG_REPO}`); const data = await response.json(); return { stars: data.stargazers_count ?? 6419, forks: data.forks_count ?? 396, }; }, }); const STARS_COUNT = stats.data?.stars ?? 6419; const FORKS_COUNT = stats.data?.forks ?? 396; // ... rest of component }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (7)
apps/web/public/favicon.icois excluded by!**/*.icoapps/web/public/hyprnote-logo.svgis excluded by!**/*.svgapps/web/public/hyprnote_signature_light.svgis excluded by!**/*.svgapps/web/public/patterns/paper.pngis excluded by!**/*.pngapps/web/public/patterns/white_leather.pngis excluded by!**/*.pngapps/web/public/team/john.pngis excluded by!**/*.pngapps/web/public/team/yujong.pngis excluded by!**/*.png
📒 Files selected for processing (6)
apps/web/src/components/github-open-source.tsx(1 hunks)apps/web/src/routes/_view/app/account.tsx(2 hunks)apps/web/src/routes/_view/downloads.tsx(1 hunks)apps/web/src/routes/_view/index.tsx(6 hunks)apps/web/src/routes/_view/route.tsx(3 hunks)apps/web/src/routes/auth.tsx(2 hunks)
✅ Files skipped from review due to trivial changes (1)
- apps/web/src/routes/auth.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- apps/web/src/routes/_view/route.tsx
- apps/web/src/routes/_view/downloads.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
After a substantial amount of TypeScript changes, run
pnpm -r typecheck
Files:
apps/web/src/routes/_view/app/account.tsxapps/web/src/components/github-open-source.tsxapps/web/src/routes/_view/index.tsx
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
**/*.{tsx,jsx}: When many classNames have conditional logic in React components, usecnfrom@hypr/utils
When usingcn, always pass an array of class segments
When usingcn, split entries by logical grouping for readability
Usemotion/reactinstead offramer-motion
Files:
apps/web/src/routes/_view/app/account.tsxapps/web/src/components/github-open-source.tsxapps/web/src/routes/_view/index.tsx
🧬 Code graph analysis (2)
apps/web/src/components/github-open-source.tsx (1)
packages/utils/src/cn.ts (1)
cn(20-22)
apps/web/src/routes/_view/index.tsx (5)
apps/web/src/components/download-button.tsx (1)
DownloadButton(4-32)apps/web/src/components/logo-cloud.tsx (1)
LogoCloud(35-123)apps/web/src/components/social-card.tsx (1)
SocialCard(18-82)apps/web/src/components/github-open-source.tsx (1)
GitHubOpenSource(64-110)apps/web/src/components/github-stars.tsx (1)
GithubStars(5-35)
🪛 Biome (2.1.2)
apps/web/src/routes/_view/index.tsx
[error] 39-39: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the rel="noopener" attribute.
(lint/security/noBlankTarget)
🪛 GitHub Actions: .github/workflows/fmt.yaml
apps/web/src/routes/_view/index.tsx
[error] 470-496: dprint formatting check failed. Found 1 not formatted file.
🔇 Additional comments (4)
apps/web/src/routes/_view/app/account.tsx (1)
171-171: LGTM! Consistent border color refresh.The border color updates from
border-neutral-200toborder-neutral-100are applied consistently across both theAccountSettingsCardandIntegrationsSettingsCardcomponents, creating a more subtle visual design. This aligns with the broader UI-wide border color refresh mentioned in the summary.Also applies to: 179-179, 193-193, 201-201
apps/web/src/routes/_view/index.tsx (1)
14-541: Well-structured landing page layout.The restructured layout effectively integrates the new GitHubOpenSource component alongside reorganized hero, features, social proof, and manifesto sections. Responsive design patterns are properly implemented with mobile-first and desktop variants.
Per coding guidelines, run typecheck after these substantial TypeScript changes:
#!/bin/bash pnpm -r typecheckapps/web/src/components/github-open-source.tsx (2)
43-62: LGTM!The StatBadge component correctly formats counts and handles both stars and forks display types.
85-97: Excellent security and styling practices.The CTA link properly includes
rel="noopener noreferrer"for security, and thecnhelper is used correctly with array format and logical grouping per coding guidelines.
822609e to
75b9999
Compare
There was a problem hiding this 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
♻️ Duplicate comments (1)
apps/web/src/routes/_view/index.tsx (1)
36-43: Security: target="_blank" missing rel attributesAdd rel="noopener noreferrer" to prevent tab‑nabbing. This was flagged earlier; applying here resolves the lint warning.
- <a + <a className="decoration-dotted underline hover:text-stone-600 transition-all" href="https://github.com/fastrepl/hyprnote" target="_blank" + rel="noopener noreferrer" > open source </a>
🧹 Nitpick comments (5)
apps/web/src/routes/_view/route.tsx (2)
34-35: Prefer targeted transitions over transition-all for perfAvoid transition-all on simple text color hovers; use transition-colors. Keeps paint scope tight and consistent with the rest of the app.
- className="text-sm text-neutral-600 hover:text-neutral-800 transition-all hover:underline decoration-dotted" + className="text-sm text-neutral-600 hover:text-neutral-800 transition-colors hover:underline decoration-dotted"Apply the same replacement to the Blog, Pricing, Account, and Get Started links in this file.
Also applies to: 40-41, 46-47, 75-76, 87-88
28-31: Optional: add intrinsic size to logo img to reduce CLSAdding width/height improves layout stability without affecting styling.
- <img src="/hyprnote-logo.svg" alt="Hyprnote" className="h-6" /> + <img src="/hyprnote-logo.svg" alt="Hyprnote" className="h-6" width="24" height="24" />apps/web/src/routes/auth.tsx (1)
196-232: Harden OAuth button: type, error path, and URL allow‑list
- Explicit type avoids accidental form submits if moved.
- Basic onError avoids silent failures.
- Allow‑list redirect origins to reduce open‑redirect risks.
-function OAuthButton({ flow, provider }: { flow: "desktop" | "web"; provider: "google" | "github" }) { +function OAuthButton({ flow, provider }: { flow: "desktop" | "web"; provider: "google" | "github" }) { const oauthMutation = useMutation({ mutationFn: (provider: "google" | "github") => doAuth({ data: { method: "oauth", provider, flow, }, }), - onSuccess: (result) => { - if (result?.url) { - window.location.href = result.url; - } - }, + onSuccess: (result) => { + if (result?.url) { + try { + const allowed = new Set(["https://accounts.google.com", "https://github.com"]); + const u = new URL(result.url); + if (allowed.has(u.origin)) window.location.assign(result.url); + } catch { + /* no-op */ + } + } + }, + onError: () => { + // TODO: surface a toast or inline error + }, }); return ( - <button + <button + type="button" onClick={() => oauthMutation.mutate(provider)} disabled={oauthMutation.isPending}apps/web/src/routes/_view/index.tsx (2)
287-289: Copy tweaksTwo small phrasing fixes for polish.
- <h2 className="text-3xl font-serif text-stone-600 mb-4">Hyprnote works like charm</h2> + <h2 className="text-3xl font-serif text-stone-600 mb-4">Hyprnote works like a charm</h2>- <h2 className="text-3xl font-serif text-stone-600 mb-4">We focus on every bit of details</h2> + <h2 className="text-3xl font-serif text-stone-600 mb-4">We focus on every detail</h2>Also applies to: 384-386
281-286: Defer non-critical images and set decoding for paint speedUse loading="lazy" and decoding="async" on offscreen/decorative images.
- <img + <img src="/hyprnote_with_noise.png" alt="Hyprnote" - className="size-24 rounded-3xl border border-neutral-100" + className="size-24 rounded-3xl border border-neutral-100" + loading="lazy" + decoding="async" />- <img + <img src="/team/john.png" alt="John Jeong" className="size-8 rounded-full object-cover border border-neutral-200" + loading="lazy" + decoding="async" />- <img + <img src="/hyprnote_signature_light.svg" alt="Hyprnote Signature" className="w-32 h-auto opacity-80" + loading="lazy" + decoding="async" />Also applies to: 486-496, 507-511
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (7)
apps/web/public/favicon.icois excluded by!**/*.icoapps/web/public/hyprnote-logo.svgis excluded by!**/*.svgapps/web/public/hyprnote_signature_light.svgis excluded by!**/*.svgapps/web/public/patterns/paper.pngis excluded by!**/*.pngapps/web/public/patterns/white_leather.pngis excluded by!**/*.pngapps/web/public/team/john.pngis excluded by!**/*.pngapps/web/public/team/yujong.pngis excluded by!**/*.png
📒 Files selected for processing (6)
apps/web/src/components/github-open-source.tsx(1 hunks)apps/web/src/routes/_view/app/account.tsx(2 hunks)apps/web/src/routes/_view/downloads.tsx(1 hunks)apps/web/src/routes/_view/index.tsx(6 hunks)apps/web/src/routes/_view/route.tsx(3 hunks)apps/web/src/routes/auth.tsx(2 hunks)
✅ Files skipped from review due to trivial changes (1)
- apps/web/src/routes/_view/app/account.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- apps/web/src/routes/_view/downloads.tsx
- apps/web/src/components/github-open-source.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
After a substantial amount of TypeScript changes, run
pnpm -r typecheck
Files:
apps/web/src/routes/_view/route.tsxapps/web/src/routes/auth.tsxapps/web/src/routes/_view/index.tsx
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
**/*.{tsx,jsx}: When many classNames have conditional logic in React components, usecnfrom@hypr/utils
When usingcn, always pass an array of class segments
When usingcn, split entries by logical grouping for readability
Usemotion/reactinstead offramer-motion
Files:
apps/web/src/routes/_view/route.tsxapps/web/src/routes/auth.tsxapps/web/src/routes/_view/index.tsx
🧬 Code graph analysis (1)
apps/web/src/routes/_view/index.tsx (5)
apps/web/src/components/download-button.tsx (1)
DownloadButton(4-32)apps/web/src/components/logo-cloud.tsx (1)
LogoCloud(35-123)apps/web/src/components/social-card.tsx (1)
SocialCard(18-82)apps/web/src/components/github-open-source.tsx (1)
GitHubOpenSource(64-111)apps/web/src/components/github-stars.tsx (1)
GithubStars(5-35)
🪛 Biome (2.1.2)
apps/web/src/routes/_view/index.tsx
[error] 39-39: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the rel="noopener" attribute.
(lint/security/noBlankTarget)
🪛 GitHub Actions: .github/workflows/fmt.yaml
apps/web/src/routes/auth.tsx
[error] 136-140: dprint formatting check failed. 2 files not formatted. Command: ~/.dprint/bin/dprint check --config 'dprint.json'. Please run 'dprint --config dprint.json --write' to fix code style issues in this file.
apps/web/src/routes/_view/index.tsx
[error] 470-497: dprint formatting check failed. 2 files not formatted. Command: ~/.dprint/bin/dprint check --config 'dprint.json'. Please run 'dprint --config dprint.json --write' to fix code style issues in this file.
🔇 Additional comments (2)
apps/web/src/routes/auth.tsx (1)
138-193: Remove this review comment—the suggested fix command does not exist in the repositoryThe suggested command
pnpm -r fmtfails because there are nofmtorformatnpm scripts in the codebase. The repo uses dprint directly via CI workflows (.github/workflows/fmt.yaml), not npm scripts. Additionally, the code in the snippet is properly formatted according to TypeScript standards and usescn()correctly with array formatting and logical grouping.Likely an incorrect or invalid review comment.
apps/web/src/routes/_view/index.tsx (1)
470-497: Addrel="noopener noreferrer"to the unsafetarget="_blank"link at line 39 and review pre-existing unsafe anchors across the repoThe code at lines 470-497 is properly formatted and introduces no new rel issues. However, the existing
target="_blank"link at line 39 (GitHub link in the CTA section) lacks the requiredrelattribute for security. While this is a pre-existing issue (unchanged by this PR), it should be fixed. Additionally, 7 other pre-existing unsafetarget="_blank"anchors were found in the repository:
apps/desktop/src/components/main/body/sessions/outer-header/metadata/participants.tsx:95apps/desktop/src/components/main/body/sessions/outer-header/metadata/others.tsx:91apps/web/src/components/social-card.tsx:58apps/web/src/components/github-open-source.tsx:87apps/web/src/components/github-stars.tsx:21README.md:7,8
There was a problem hiding this 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 (2)
apps/web/src/routes/_view/index.tsx (2)
36-43: Security: target="_blank" missing rel attributes.This security issue was previously flagged and remains unaddressed. Add
rel="noopener noreferrer"to prevent tab-nabbing.Apply this diff:
<a className="decoration-dotted underline hover:text-stone-600 transition-all" href="https://github.com/fastrepl/hyprnote" target="_blank" + rel="noopener noreferrer" >
459-462: Visual bug: border color without border width.Similar to the previous comment on this section,
border-neutral-100has no effect without specifying a border width.Apply this diff:
- <div className="aspect-video md:aspect-auto bg-neutral-50 flex items-center justify-center border-neutral-100"> + <div className="aspect-video md:aspect-auto bg-neutral-50 flex items-center justify-center border border-neutral-100">
🧹 Nitpick comments (1)
apps/web/src/routes/_view/index.tsx (1)
1-557: Consider running typecheck after substantial changes.Per the coding guidelines, after substantial TypeScript changes, consider running the typecheck command to ensure type safety across the codebase.
Based on coding guidelines.
#!/bin/bash # Run typecheck across all packages pnpm -r typecheck
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
apps/web/src/routes/_view/index.tsx(6 hunks)apps/web/src/routes/auth.tsx(0 hunks)
💤 Files with no reviewable changes (1)
- apps/web/src/routes/auth.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
After a substantial amount of TypeScript changes, run
pnpm -r typecheck
Files:
apps/web/src/routes/_view/index.tsx
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
**/*.{tsx,jsx}: When many classNames have conditional logic in React components, usecnfrom@hypr/utils
When usingcn, always pass an array of class segments
When usingcn, split entries by logical grouping for readability
Usemotion/reactinstead offramer-motion
Files:
apps/web/src/routes/_view/index.tsx
🧬 Code graph analysis (1)
apps/web/src/routes/_view/index.tsx (5)
apps/web/src/components/download-button.tsx (1)
DownloadButton(4-32)apps/web/src/components/logo-cloud.tsx (1)
LogoCloud(35-123)apps/web/src/components/social-card.tsx (1)
SocialCard(18-82)apps/web/src/components/github-open-source.tsx (1)
GitHubOpenSource(64-111)apps/web/src/components/github-stars.tsx (1)
GithubStars(5-35)
🪛 Biome (2.1.2)
apps/web/src/routes/_view/index.tsx
[error] 39-39: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the rel="noopener" attribute.
(lint/security/noBlankTarget)
🔇 Additional comments (7)
apps/web/src/routes/_view/index.tsx (7)
5-5: LGTM: Import added correctly.The GitHubOpenSource component import is properly structured and matches the usage at line 468.
47-89: LGTM: Responsive video and feature cards layout.The mobile-first approach with proper responsive breakpoints is well-implemented. The placeholder content is appropriate for pre-launch state.
93-275: LGTM: Social proof section well-structured.The responsive testimonials layout with horizontal scroll on mobile and grid on desktop is well-implemented. The SocialCard component properly handles external links with security attributes.
277-379: LGTM: Features section grid layout.The feature cards grid with responsive column spans is well-organized. The "Coming Soon" badge appropriately indicates the Daily Note feature status.
467-468: LGTM: GitHubOpenSource component integrated.The component is properly imported and integrated into the page structure with appropriate section boundaries.
470-531: LGTM: Manifesto section with decorative design.The postcard-style manifesto section with background patterns and team signatures is well-crafted. The content effectively communicates the product philosophy.
533-553: LGTM: Final CTA section.The closing section with dual CTAs (DownloadButton and GithubStars) provides clear next steps for users. The styling is consistent with the page's design system.
e100929 to
5659139
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/web/src/routes/_view/route.tsx (1)
56-59: Fix Tailwind gradient class name: changebg-linear-to-ttobg-gradient-to-t.The review comment is accurate.
bg-linear-to-tis not a standard Tailwind class; the correct syntax isbg-gradient-to-t. No custom Tailwind configuration or CSS definitions forbg-linear-to-*were found in the codebase, confirming this is a typo that needs correction.- className="px-4 h-8 flex items-center text-sm bg-linear-to-t from-stone-600 to-stone-500 text-white rounded-full shadow-md hover:shadow-lg hover:scale-[102%] active:scale-[98%] transition-all" + className="px-4 h-8 flex items-center text-sm bg-gradient-to-t from-stone-600 to-stone-500 text-white rounded-full shadow-md hover:shadow-lg hover:scale-[102%] active:scale-[98%] transition-all"
♻️ Duplicate comments (3)
apps/web/src/routes/_view/index.tsx (3)
70-76: Security: add rel to external link opening in a new tab.target="_blank" without rel enables tab‑nabbing. Add rel="noopener noreferrer".
- <a + <a className="decoration-dotted underline hover:text-stone-600 transition-all" href="https://github.com/fastrepl/hyprnote" target="_blank" + rel="noopener noreferrer" >
511-517: Border color without border width.border-neutral-100 won’t render without a border width.
- <div className="aspect-video md:aspect-auto border-neutral-100 overflow-hidden"> + <div className="aspect-video md:aspect-auto border border-neutral-100 overflow-hidden">
1-14: Add missingrelattribute to external link.In the GitHub link (line 73), add
rel="noopener noreferrer"when usingtarget="_blank"for security:<a className="decoration-dotted underline hover:text-stone-600 transition-all" href="https://github.com/fastrepl/hyprnote" target="_blank" rel="noopener noreferrer" > open source </a>TypeCheck verification note: The sandbox environment lacks
deno, preventingpnpm -r typecheckexecution. This should be verified locally before merging, per coding guidelines. Thecn()utility usage in the file correctly follows array-based class grouping conventions.
🧹 Nitpick comments (14)
apps/web/src/routes/_view/route.tsx (2)
28-31: Brand link wraps an image; remove text/font classes and add intrinsic size.Font-related classes on the Link are redundant when the child is an
. Also add width/height to reduce CLS.
- className="font-semibold text-2xl font-serif hover:scale-105 transition-transform mr-4" + className="hover:scale-105 transition-transform mr-4" ... - <img src="/hyprnote/logo.svg" alt="Hyprnote" className="h-6" /> + <img src="/hyprnote/logo.svg" alt="Hyprnote" width="96" height="24" className="h-6 w-auto" />
22-64: Consider reducing transition-all usage.transition-colors/transition-transform are cheaper and avoid layout/repaint side effects.
apps/web/src/components/video-modal.tsx (3)
50-58: Add dialog semantics and basic focus management.Add role="dialog", aria-modal, and focus the close button on open; this improves accessibility. A full focus trap (e.g., with @radix-ui/react-dialog) would be ideal.
- <div - className="fixed inset-0 z-50 flex items-center justify-center bg-black/90 p-4" - onClick={onClose} - > + <div + className="fixed inset-0 z-50 flex items-center justify-center bg-black/90 p-4" + role="dialog" + aria-modal="true" + aria-labelledby="video-modal-title" + onClick={onClose} + > ... - <div + <div ref={modalRef} className="relative w-full max-w-6xl aspect-video" onClick={(e) => e.stopPropagation()} > + <h2 id="video-modal-title" className="sr-only">Hyprnote Feature Demo</h2>And focus the close button:
- const modalRef = useRef<HTMLDivElement>(null); + const modalRef = useRef<HTMLDivElement>(null); + const closeBtnRef = useRef<HTMLButtonElement>(null); ... - <button + <button + ref={closeBtnRef}Add effect:
+ useEffect(() => { + if (isOpen) closeBtnRef.current?.focus(); + }, [isOpen]);
62-67: Follow cn usage guideline: pass an array of grouped segments.Per guidelines, use cn with an array and group logically.
- className={cn( - "absolute -top-12 right-0 p-2", - "text-white hover:text-neutral-300", - "transition-colors duration-200", - )} + className={cn([ + "absolute -top-12 right-0 p-2", + "text-white hover:text-neutral-300", + "transition-colors duration-200", + ])}
61-71: Close button positioning risk on small viewports.-top-12 may render the button off-canvas for small videos. Consider placing it inside the frame (top-2 right-2) with a subtle background.
- className={cn(["absolute -top-12 right-0 p-2", ...])} + className={cn(["absolute top-2 right-2 p-2 rounded bg-black/30 hover:bg-black/40", "text-white", "transition-colors"])}apps/web/src/components/video-thumbnail.tsx (3)
17-28: Use a static thumbnail image instead of mounting a MuxPlayer for an image.MuxPlayer is heavy for a poster-only thumbnail. Use Mux’s image endpoint for better perf and LCP.
- <MuxPlayer - playbackId={playbackId} - muted - playsInline - className="w-full h-full object-cover pointer-events-none" - style={{ - "--controls": "none", - aspectRatio: "16/9", - } as React.CSSProperties} - /> + <img + src={`https://image.mux.com/${playbackId}/thumbnail.jpg?time=0`} + alt="" + loading="lazy" + width="1280" + height="720" + className="w-full h-full object-cover pointer-events-none" + style={{ aspectRatio: "16/9" } as React.CSSProperties} + />
17-17: Make the container keyboard-accessible.Clickable divs should be focusable and respond to Enter/Space.
- <div className={cn("relative w-full h-full overflow-hidden group cursor-pointer", className)} onClick={onPlay}> + <div + role="button" + tabIndex={0} + onKeyDown={(e) => (e.key === "Enter" || e.key === " ") && onPlay?.()} + className={cn(["relative w-full h-full overflow-hidden group cursor-pointer", className])} + onClick={onPlay} + >
37-43: Follow cn array style guideline and add focus-visible state.Use cn([...]) and provide a visible keyboard focus on the play button.
- className={cn( - "size-16 rounded-full bg-white/90 backdrop-blur-sm", - "flex items-center justify-center", - "hover:bg-white hover:scale-110 transition-all duration-200", - "shadow-xl", - )} + className={cn([ + "size-16 rounded-full bg-white/90 backdrop-blur-sm", + "flex items-center justify-center shadow-xl", + "hover:bg-white hover:scale-110 transition-all duration-200", + "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/80 focus-visible:ring-offset-2 focus-visible:ring-offset-black/20", + ])}apps/web/src/components/video-player.tsx (3)
24-37: Guard against unnecessary play/pause churn and respect reduced motion.Avoid toggling on every minor hover flicker; also skip autoplay for users preferring reduced motion.
- useEffect(() => { - if (playerRef.current) { - if (isHovered) { - playerRef.current.play().catch(() => { - // Ignore autoplay errors - }); - setShowControls(true); - } else { - playerRef.current.pause(); - playerRef.current.currentTime = 0; - setShowControls(false); - } - } - }, [isHovered]); + useEffect(() => { + const el = playerRef.current; + if (!el) return; + const prefersReduced = typeof window !== "undefined" && window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches; + if (isHovered && !prefersReduced) { + el.play().catch(() => {}); + setShowControls(true); + } else { + el.pause(); + try { el.currentTime = 0; } catch {} + setShowControls(false); + } + }, [isHovered]);
41-57: Follow cn array style; consider preload="metadata".Align with cn guideline and reduce network cost when idle.
- className={cn("relative w-full h-full overflow-hidden group", className)} + className={cn(["relative w-full h-full overflow-hidden group", className])} ... - <MuxPlayer + <MuxPlayer ref={playerRef} playbackId={playbackId} loop muted playsInline + preload="metadata" accentColor="#78716c" className="w-full h-full object-cover" style={{ "--controls": "none", aspectRatio: "16/9", } as React.CSSProperties} />
60-100: Keyboard parity for overlay and cn array usage.Show overlay when focused, not just hovered; convert cn calls to array form.
- <div + <div ... - onMouseEnter={() => setIsHovered(true)} - onMouseLeave={() => setIsHovered(false)} + onMouseEnter={() => setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} + onFocus={() => setIsHovered(true)} + onBlur={() => setIsHovered(false)} > ... - <div - className={cn( + <div + className={cn([ "absolute bottom-0 left-0 right-0", "transition-all duration-300 ease-out", "flex gap-0", - isHovered ? "translate-y-0 opacity-100" : "translate-y-full opacity-0", - )} + isHovered ? "translate-y-0 opacity-100" : "translate-y-full opacity-0", + ])} > ... - className={cn( + className={cn([ "flex-1 py-4 text-xs font-mono", "bg-stone-100/95 text-stone-800", "border-r border-stone-400/50", "hover:bg-stone-200/95 active:bg-stone-400/95", "transition-all duration-150", "backdrop-blur-sm", - )} + ])} > ... - className={cn( + className={cn([ "flex-1 py-4 text-xs font-mono", "bg-stone-100/95 text-stone-800", "hover:bg-stone-200/95 active:bg-stone-400/95", "transition-all duration-150", "backdrop-blur-sm", - )} + ])}apps/web/src/routes/_view/index.tsx (3)
34-41: Use cn with an array of class segments.Align with project guideline to pass arrays to cn for readability.
As per coding guidelines.
- <div - className={cn( - "flex items-center justify-center gap-2 text-center", - "bg-stone-50/70 border-b border-stone-100", - "py-3 px-4", - "font-serif text-sm text-stone-700", - "hover:bg-stone-50 transition-all", - )} - > + <div + className={cn([ + "flex items-center justify-center gap-2 text-center", + "bg-stone-50/70 border-b border-stone-100", + "py-3 px-4", + "font-serif text-sm text-stone-700", + "hover:bg-stone-50 transition-all", + ])} + >- className={cn("h-4 w-4 inline-block group-hover:scale-105")} + className={cn(["h-4 w-4 inline-block group-hover:scale-105"])}Also applies to: 46-46
331-333: Prefer router navigation over window.location.Avoid full reloads; use Link or useNavigate from @tanstack/react-router for client routing.
As per coding guidelines.
Also applies to: 349-353, 371-374, 391-394, 513-516
410-410: Lazy‑load non‑critical images.Improve performance by adding loading="lazy" to below‑the‑fold images.
- <img src="/static.gif" alt="Daily Note feature" className="w-full h-full object-cover" /> + <img src="/static.gif" alt="Daily Note feature" className="w-full h-full object-cover" loading="lazy" />- <img + <img src="/team/john.png" alt="John Jeong" - className="size-8 rounded-full object-cover border border-neutral-200" + className="size-8 rounded-full object-cover border border-neutral-200" + loading="lazy" />- <img + <img src="/team/yujong.png" alt="Yujong Lee" - className="size-8 rounded-full object-cover border border-neutral-200" + className="size-8 rounded-full object-cover border border-neutral-200" + loading="lazy" />- <img + <img src="/hyprnote/signature.svg" alt="Hyprnote Signature" className="w-32 h-auto opacity-80" + loading="lazy" />Also applies to: 556-559, 561-564, 577-580
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (6)
apps/web/public/hyprnote/icon.pngis excluded by!**/*.pngapps/web/public/hyprnote/logo.svgis excluded by!**/*.svgapps/web/public/hyprnote/signature.svgis excluded by!**/*.svgapps/web/public/icons/yc_stone.svgis excluded by!**/*.svgapps/web/public/static.gifis excluded by!**/*.gifpnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (7)
apps/web/package.json(1 hunks)apps/web/src/components/video-modal.tsx(1 hunks)apps/web/src/components/video-player.tsx(1 hunks)apps/web/src/components/video-thumbnail.tsx(1 hunks)apps/web/src/routes/_view/index.tsx(5 hunks)apps/web/src/routes/_view/route.tsx(3 hunks)apps/web/src/routes/auth.tsx(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- apps/web/src/routes/auth.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
After a substantial amount of TypeScript changes, run
pnpm -r typecheck
Files:
apps/web/src/routes/_view/route.tsxapps/web/src/components/video-modal.tsxapps/web/src/components/video-thumbnail.tsxapps/web/src/components/video-player.tsxapps/web/src/routes/_view/index.tsx
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
**/*.{tsx,jsx}: When many classNames have conditional logic in React components, usecnfrom@hypr/utils
When usingcn, always pass an array of class segments
When usingcn, split entries by logical grouping for readability
Usemotion/reactinstead offramer-motion
Files:
apps/web/src/routes/_view/route.tsxapps/web/src/components/video-modal.tsxapps/web/src/components/video-thumbnail.tsxapps/web/src/components/video-player.tsxapps/web/src/routes/_view/index.tsx
🧬 Code graph analysis (4)
apps/web/src/components/video-modal.tsx (1)
packages/utils/src/cn.ts (1)
cn(20-22)
apps/web/src/components/video-thumbnail.tsx (1)
packages/utils/src/cn.ts (1)
cn(20-22)
apps/web/src/components/video-player.tsx (1)
packages/utils/src/cn.ts (1)
cn(20-22)
apps/web/src/routes/_view/index.tsx (9)
packages/utils/src/cn.ts (1)
cn(20-22)apps/web/src/components/download-button.tsx (1)
DownloadButton(4-32)apps/web/src/components/video-thumbnail.tsx (1)
VideoThumbnail(11-50)apps/web/src/components/logo-cloud.tsx (1)
LogoCloud(35-123)apps/web/src/components/social-card.tsx (1)
SocialCard(18-82)apps/web/src/components/video-player.tsx (1)
VideoPlayer(13-104)apps/web/src/components/github-open-source.tsx (1)
GitHubOpenSource(64-111)apps/web/src/components/github-stars.tsx (1)
GithubStars(5-35)apps/web/src/components/video-modal.tsx (1)
VideoModal(12-88)
🪛 Biome (2.1.2)
apps/web/src/routes/_view/index.tsx
[error] 73-73: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the rel="noopener" attribute.
(lint/security/noBlankTarget)
| const playerRef = useRef<MuxPlayerRefAttributes>(null); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Type of playerRef — confirm compatibility with current @mux/mux-player-react types.
Ensure MuxPlayerRefAttributes matches the ref element’s shape under React 19; update if package types changed.
🏁 Script executed:
#!/bin/bash
pnpm -r typecheck
rg -n "MuxPlayerRefAttributes|HTMLMuxPlayerElement" -SLength of output: 841
---
🏁 Script executed:
```shell
#!/bin/bash
# Find package.json files and check @mux/mux-player-react version
fd -t f "package.json" -x grep -l "@mux/mux-player-react" {} \;
Length of output: 23
🏁 Script executed:
#!/bin/bash
# Show the full entry for @mux/mux-player-react in package.json
fd -t f "package.json" -x grep -A1 -B1 "@mux/mux-player-react" {} \;Length of output: 111
🌐 Web query:
MuxPlayerRefAttributes React 19 compatibility @mux/mux-player-react
💡 Result:
Short answer: Yes — @mux/mux-player-react is implemented as a thin React wrapper around the mux-player web component (so runtime works with React 19), and the package ships TypeScript types for the player API. If you hit TypeScript/peer-dependency warnings with React 19, they’ll be from dev/peer deps (React/@types/react) rather than the web component itself; upgrading @mux/mux-player-react to the latest version or installing matching @types/react usually resolves them. Test by installing the latest @mux/mux-player-react and checking for peerDependency warnings; file an issue on Mux’s repo if type/peer-dep errors remain. [1][2][3]
Sources:
- Mux docs — integrating & React component (shows @mux/mux-player-react is a React wrapper). [1]
- Mux Player React API reference (types/props & guidance using the element). [2]
- @mux/mux-player-react npm entry (package/releases info; useful for checking latest version/peer deps). [3]
---
🏁 Script executed:
```shell
#!/bin/bash
# Check if there are any type errors or comments around the ref usage
rg -n -B3 -A3 "playerRef.*useRef.*MuxPlayerRefAttributes" apps/web/src/components/
Length of output: 1064
🏁 Script executed:
#!/bin/bash
# Check @types/react version in apps/web
grep -E '"@types/react"' apps/web/package.jsonLength of output: 30
🌐 Web query:
MuxPlayerRefAttributes useRef type definition mux-player-react
💡 Result:
Do you want the exact TypeScript type definition (copied from the package source) or an example of how to type a useRef for the MuxPlayer React component?
---
🏁 Script executed:
```shell
#!/bin/bash
# Check for any TypeScript diagnostic files or errors related to video-player.tsx
fd -t f "*.d.ts" -path "*mux-player-react*" 2>/dev/null | head -20
Length of output: 0
🏁 Script executed:
#!/bin/bash
# Look for actual type definition or export of MuxPlayerRefAttributes
rg "export.*MuxPlayerRefAttributes|type MuxPlayerRefAttributes|interface MuxPlayerRefAttributes" --type ts --type tsxLength of output: 27
🏁 Script executed:
#!/bin/bash
# Check actual ref usage - does it call methods that would indicate the correct type
rg -n "playerRef\.current\." apps/web/src/components/video-player.tsx apps/web/src/components/video-modal.tsxLength of output: 344
🌐 Web query:
@mux/mux-player-react MuxPlayerRefAttributes API documentation
💡 Result:
I couldn't find a public TypeScript symbol named "MuxPlayerRefAttributes". The React package documents that the ref for is a React ref to the underlying MuxPlayerElement (the web-component instance) and the full React API reference is in the Mux docs. See:
- Mux Player React API reference (shows ref is a React ref to the underlying MuxPlayerElement). [1]
- Mux Player API / repo (web components + React wrapper live in the muxinc/elements codebase). [2]
If you want the exact TypeScript interface exported by the package, I can:
- fetch the package's type definitions from the @mux/mux-player-react npm package, or
- open the muxinc/elements GitHub repo and look for the exported types (MuxPlayerRef*), and paste the interface here — which would show the available methods/properties on the ref. Which option do you prefer?
Sources:
[1] Mux Player React API Reference — Mux Docs.
[2] muxinc/elements GitHub (Mux Player + mux-player-react).
---
🌐 Web query:
```web
MuxPlayerElement ref type @mux/mux-player-react React useRef
💡 Result:
Use the web component instance type from @mux/mux-player and give that to useRef. Example:
import type MuxPlayerElement from '@mux/mux-player';
import MuxPlayer from '@mux/mux-player-react';
import { useRef } from 'react';
const playerRef = useRef<MuxPlayerElement | null>(null);
This matches the docs: the React component's ref is the underlying MuxPlayerElement. [1][2]
Sources:
[1] Mux Player React API reference (ref is a React ref to MuxPlayerElement).
[2] Mux blog/docs example importing type MuxPlayerElement from '@mux/mux-player'.
🏁 Script executed:
#!/bin/bash
# Check if MuxPlayerElement is imported anywhere
rg -n "MuxPlayerElement" apps/web/src/components/Length of output: 0
🏁 Script executed:
#!/bin/bash
# Show complete imports for both files
rg -n "^import" apps/web/src/components/video-player.tsx apps/web/src/components/video-modal.tsxLength of output: 664
Replace MuxPlayerRefAttributes with MuxPlayerElement from the correct package.
The current type is undocumented and not part of the official Mux API. Per Mux documentation, the ref should be typed as MuxPlayerElement imported from '@mux/mux-player'.
Update both files:
apps/web/src/components/video-player.tsx(line 2 and 22)apps/web/src/components/video-modal.tsx(line 3 and 13)
Change from:
import MuxPlayer, { type MuxPlayerRefAttributes } from "@mux/mux-player-react";
const playerRef = useRef<MuxPlayerRefAttributes>(null);
To:
import type MuxPlayerElement from "@mux/mux-player";
import MuxPlayer from "@mux/mux-player-react";
const playerRef = useRef<MuxPlayerElement | null>(null);
🤖 Prompt for AI Agents
In apps/web/src/components/video-player.tsx (line 2 and 22) and
apps/web/src/components/video-modal.tsx (line 3 and 13), replace the
undocumented MuxPlayerRefAttributes usage with the official MuxPlayerElement
type: import the type MuxPlayerElement from '@mux/mux-player' while keeping the
default MuxPlayer import from '@mux/mux-player-react', and change playerRef to
use useRef<MuxPlayerElement | null>(null) so the ref is correctly typed per Mux
documentation.
5659139 to
f99ecf3
Compare
There was a problem hiding this 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)
apps/web/src/routes/_view/index.tsx (2)
317-317: Fix grammar in heading text.The phrase "works like charm" is missing the article "a". It should read "works like a charm".
Apply this diff:
- <h2 className="text-3xl font-serif text-stone-600 mb-4">Hyprnote works like charm</h2> + <h2 className="text-3xl font-serif text-stone-600 mb-4">Hyprnote works like a charm</h2>
70-77: Security: Add missing rel attribute to external link.The anchor tag uses
target="_blank"but is missing therel="noopener noreferrer"attribute, which is a security risk (tab-nabbing vulnerability).Apply this diff:
<a className="decoration-dotted underline hover:text-stone-600 transition-all" href="https://github.com/fastrepl/hyprnote" target="_blank" + rel="noopener noreferrer" >
🧹 Nitpick comments (2)
apps/web/src/components/video-thumbnail.tsx (1)
17-17: Follow coding guidelines: use cn with an array.The coding guidelines specify that when using
cn, always pass an array of class segments.As per coding guidelines
Apply this diff:
- <div className={cn("relative w-full h-full overflow-hidden group cursor-pointer", className)} onClick={onPlay}> + <div className={cn(["relative w-full h-full overflow-hidden group cursor-pointer", className])} onClick={onPlay}>apps/web/src/components/github-open-source.tsx (1)
8-8: Remove obsolete TODO comment.The TODO indicates the curated list needs to be added, but the list is already populated with 12 avatar URLs (lines 9-21).
Apply this diff:
- // TODO: Add your curated list of avatar URLs here "https://avatars.githubusercontent.com/u/61503739?v=4",
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (11)
apps/web/public/favicon.icois excluded by!**/*.icoapps/web/public/hyprnote/icon.pngis excluded by!**/*.pngapps/web/public/hyprnote/logo.svgis excluded by!**/*.svgapps/web/public/hyprnote/signature.svgis excluded by!**/*.svgapps/web/public/icons/yc_stone.svgis excluded by!**/*.svgapps/web/public/patterns/paper.pngis excluded by!**/*.pngapps/web/public/patterns/white_leather.pngis excluded by!**/*.pngapps/web/public/static.gifis excluded by!**/*.gifapps/web/public/team/john.pngis excluded by!**/*.pngapps/web/public/team/yujong.pngis excluded by!**/*.pngpnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (10)
apps/web/package.json(1 hunks)apps/web/src/components/github-open-source.tsx(1 hunks)apps/web/src/components/video-modal.tsx(1 hunks)apps/web/src/components/video-player.tsx(1 hunks)apps/web/src/components/video-thumbnail.tsx(1 hunks)apps/web/src/routes/_view/app/account.tsx(2 hunks)apps/web/src/routes/_view/downloads.tsx(1 hunks)apps/web/src/routes/_view/index.tsx(5 hunks)apps/web/src/routes/_view/route.tsx(3 hunks)apps/web/src/routes/auth.tsx(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
- apps/web/src/routes/_view/route.tsx
- apps/web/src/components/video-player.tsx
- apps/web/src/routes/_view/app/account.tsx
- apps/web/src/routes/_view/downloads.tsx
- apps/web/src/routes/auth.tsx
- apps/web/src/components/video-modal.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
After a substantial amount of TypeScript changes, run
pnpm -r typecheck
Files:
apps/web/src/components/github-open-source.tsxapps/web/src/routes/_view/index.tsxapps/web/src/components/video-thumbnail.tsx
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
**/*.{tsx,jsx}: When many classNames have conditional logic in React components, usecnfrom@hypr/utils
When usingcn, always pass an array of class segments
When usingcn, split entries by logical grouping for readability
Usemotion/reactinstead offramer-motion
Files:
apps/web/src/components/github-open-source.tsxapps/web/src/routes/_view/index.tsxapps/web/src/components/video-thumbnail.tsx
🧬 Code graph analysis (3)
apps/web/src/components/github-open-source.tsx (1)
packages/utils/src/cn.ts (1)
cn(20-22)
apps/web/src/routes/_view/index.tsx (9)
packages/utils/src/cn.ts (1)
cn(20-22)apps/web/src/components/download-button.tsx (1)
DownloadButton(4-32)apps/web/src/components/video-thumbnail.tsx (1)
VideoThumbnail(11-50)apps/web/src/components/logo-cloud.tsx (1)
LogoCloud(35-123)apps/web/src/components/social-card.tsx (1)
SocialCard(18-82)apps/web/src/components/video-player.tsx (1)
VideoPlayer(13-104)apps/web/src/components/github-open-source.tsx (1)
GitHubOpenSource(64-111)apps/web/src/components/github-stars.tsx (1)
GithubStars(5-35)apps/web/src/components/video-modal.tsx (1)
VideoModal(12-88)
apps/web/src/components/video-thumbnail.tsx (1)
packages/utils/src/cn.ts (1)
cn(20-22)
🪛 Biome (2.1.2)
apps/web/src/routes/_view/index.tsx
[error] 73-73: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the rel="noopener" attribute.
(lint/security/noBlankTarget)
🔇 Additional comments (1)
apps/web/src/routes/_view/index.tsx (1)
21-22: LGTM: Clean state management for video modal.The video expansion state is well-structured using
useStateto track which video is expanded, with a proper null check for the modal'sisOpenprop.
| rel="noopener noreferrer" | ||
| className={cn([ | ||
| "group px-6 h-12 inline-flex items-center justify-center gap-2 text-base sm:text-lg", | ||
| "bg-linear-to-t from-neutral-800 to-neutral-700 text-white rounded-full", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix invalid Tailwind utility class.
bg-linear-to-t is not a valid Tailwind class. The correct class for a top-to-bottom gradient is bg-gradient-to-t.
Apply this diff:
- "bg-linear-to-t from-neutral-800 to-neutral-700 text-white rounded-full",
+ "bg-gradient-to-t from-neutral-800 to-neutral-700 text-white rounded-full",📝 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.
| "bg-linear-to-t from-neutral-800 to-neutral-700 text-white rounded-full", | |
| "bg-gradient-to-t from-neutral-800 to-neutral-700 text-white rounded-full", |
🤖 Prompt for AI Agents
In apps/web/src/components/github-open-source.tsx around line 91, the Tailwind
utility "bg-linear-to-t" is invalid; replace it with the correct gradient class
"bg-gradient-to-t" while keeping the rest of the class list intact so the line
becomes "bg-gradient-to-t from-neutral-800 to-neutral-700 text-white
rounded-full".
There was a problem hiding this 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
♻️ Duplicate comments (2)
apps/web/src/routes/_view/index.tsx (2)
396-396: Copy fix (regression).“works like charm” → “works like a charm”.
- <h2 className="text-3xl font-serif text-stone-600 mb-4">Hyprnote works like charm</h2> + <h2 className="text-3xl font-serif text-stone-600 mb-4">Hyprnote works like a charm</h2>
160-166: Security: target="_blank" missing rel.Add rel="noopener noreferrer" to prevent tab-nabbing.
- <a + <a className="decoration-dotted underline hover:text-stone-600 transition-all" href="https://github.com/fastrepl/hyprnote" target="_blank" + rel="noopener noreferrer" >
🧹 Nitpick comments (7)
apps/web/src/routes/_view/route.tsx (1)
28-31: Avoid CLS: add intrinsic size on logo img.Provide width/height (or sizes via CSS) and decoding for better LCP.
- <img src="/hyprnote/logo.svg" alt="Hyprnote" className="h-6" /> + <img + src="/hyprnote/logo.svg" + alt="Hyprnote" + className="h-6" + width="96" + height="24" + decoding="async" + />apps/web/src/components/logo-cloud.tsx (2)
17-21: Follow cn guideline: always pass an array.Update for consistency/readability.
- className={cn( - "flex items-center justify-center bg-transparent px-4 py-8 md:p-8 hover:bg-neutral-50 transition-colors", - className, - )} + className={cn([ + "flex items-center justify-center bg-transparent px-4 py-8 md:p-8", + "hover:bg-neutral-50 transition-colors", + className, + ])}
24-29: Fix img dimensions and lazy-load static logos.Avoid invalid "auto" width/height; either omit or use CSS, and add loading/decoding.
- <img + <img alt={logo.alt} className="pointer-events-none h-5 select-none md:h-6" - height={logo.height || "auto"} + height={logo.height ?? undefined} src={logo.src} - width={logo.width || "auto"} + width={logo.width ?? undefined} + loading="lazy" + decoding="async" />apps/web/src/routes/_view/index.tsx (4)
406-415: Remove unknown/duplicate scrollbar class.Use the new .scrollbar-none utility; drop scrollbar-hide to avoid dead CSS.
- className="overflow-x-auto snap-x snap-mandatory scrollbar-hide scrollbar-none -mx-4" + className="overflow-x-auto snap-x snap-mandatory scrollbar-none -mx-4"- className="overflow-x-auto scrollbar-none snap-x snap-mandatory scrollbar-hide -mx-4" + className="overflow-x-auto scrollbar-none snap-x snap-mandatory -mx-4"Also applies to: 584-593
123-129: cn usage: prefer array form per guidelines.Switch to cn([...]) and group logically.
- <div - className={cn( - "flex items-center justify-center gap-2 text-center", - "bg-stone-50/70 border-b border-stone-100", - "py-3 px-4", - "font-serif text-sm text-stone-700", - "hover:bg-stone-50 transition-all", - )} - > + <div + className={cn([ + "flex items-center justify-center gap-2 text-center", + "bg-stone-50/70 border-b border-stone-100", + "py-3 px-4", + "font-serif text-sm text-stone-700", + "hover:bg-stone-50 transition-all", + ])} + >
460-466: Standardize cn([...]) across conditionals.Adopt array form for consistency/readability.
- className={cn( - "h-1 rounded-full transition-all cursor-pointer", - selectedFeature === index - ? "w-8 bg-stone-600" - : "w-8 bg-neutral-300 hover:bg-neutral-400", - )} + className={cn([ + "h-1 rounded-full transition-all cursor-pointer", + selectedFeature === index ? "w-8 bg-stone-600" : "w-8 bg-neutral-300 hover:bg-neutral-400", + ])}- className={cn( - "h-1 rounded-full transition-all cursor-pointer", - selectedDetail === index - ? "w-8 bg-stone-600" - : "w-8 bg-neutral-300 hover:bg-neutral-400", - )} + className={cn([ + "h-1 rounded-full transition-all cursor-pointer", + selectedDetail === index ? "w-8 bg-stone-600" : "w-8 bg-neutral-300 hover:bg-neutral-400", + ])}- className={cn( - "p-6 cursor-pointer transition-colors", - index < detailsFeatures.length - 1 && "border-b border-neutral-100", - "hover:bg-neutral-50", - )} + className={cn([ + "p-6 cursor-pointer transition-colors", + index < detailsFeatures.length - 1 && "border-b border-neutral-100", + "hover:bg-neutral-50", + ])}Also applies to: 631-635, 695-700
764-773: Lazy-load below-the-fold images.Save bandwidth and improve LCP by marking non-critical images as lazy with async decoding.
- <img + <img src="/team/john.png" alt="John Jeong" className="size-8 rounded-full object-cover border border-neutral-200" + loading="lazy" + decoding="async" />- <img + <img src="/hyprnote/signature.svg" alt="Hyprnote Signature" className="w-32 h-auto opacity-80" + loading="lazy" + decoding="async" />- <img + <img src="/hyprnote/icon.png" alt="Hyprnote" className="size-36 mx-auto rounded-[40px] border border-neutral-100" + loading="lazy" + decoding="async" />Also applies to: 786-789, 801-804
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
apps/web/public/icons/adobe.svgis excluded by!**/*.svg
📒 Files selected for processing (7)
apps/web/src/components/github-open-source.tsx(1 hunks)apps/web/src/components/logo-cloud.tsx(1 hunks)apps/web/src/components/social-card.tsx(1 hunks)apps/web/src/components/video-player.tsx(1 hunks)apps/web/src/routes/_view/index.tsx(5 hunks)apps/web/src/routes/_view/route.tsx(4 hunks)apps/web/src/styles.css(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- apps/web/src/components/social-card.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- apps/web/src/components/video-player.tsx
- apps/web/src/components/github-open-source.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
After a substantial amount of TypeScript changes, run
pnpm -r typecheck
Files:
apps/web/src/routes/_view/index.tsxapps/web/src/routes/_view/route.tsxapps/web/src/components/logo-cloud.tsx
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
**/*.{tsx,jsx}: When many classNames have conditional logic in React components, usecnfrom@hypr/utils
When usingcn, always pass an array of class segments
When usingcn, split entries by logical grouping for readability
Usemotion/reactinstead offramer-motion
Files:
apps/web/src/routes/_view/index.tsxapps/web/src/routes/_view/route.tsxapps/web/src/components/logo-cloud.tsx
🧬 Code graph analysis (1)
apps/web/src/routes/_view/index.tsx (9)
packages/utils/src/cn.ts (1)
cn(20-22)apps/web/src/components/download-button.tsx (1)
DownloadButton(4-32)apps/web/src/components/video-thumbnail.tsx (1)
VideoThumbnail(11-50)apps/web/src/components/logo-cloud.tsx (1)
LogoCloud(35-123)apps/web/src/components/social-card.tsx (1)
SocialCard(18-82)apps/web/src/components/video-player.tsx (1)
VideoPlayer(13-104)apps/web/src/components/github-open-source.tsx (1)
GitHubOpenSource(64-111)apps/web/src/components/github-stars.tsx (1)
GithubStars(5-35)apps/web/src/components/video-modal.tsx (1)
VideoModal(12-88)
🪛 Biome (2.1.2)
apps/web/src/routes/_view/index.tsx
[error] 162-162: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the rel="noopener" attribute.
(lint/security/noBlankTarget)
🔇 Additional comments (4)
apps/web/src/styles.css (1)
4-8: Breakpoint var looks good.--breakpoint-laptop matches usage of laptop: classes in the app.
apps/web/src/routes/_view/route.tsx (2)
23-24: Container padding breakpoint change LGTM.
98-111: Footer container breakpoint change LGTM.apps/web/src/routes/_view/index.tsx (1)
1-15: Thepnpm -r typecheckcommand failed in the sandbox because the build environment lacks dependencies (node_modules, vite). This is expected in the sandbox and does not reflect the actual code quality.The review comment is requesting a manual verification step that must be performed in your local development environment.
Run
pnpm -r typechecklocally to verify no type regressions before merging.Ensure the command completes successfully without errors in your development environment.
| @layer utilities { | ||
| .scrollbar-none { | ||
| -ms-overflow-style: none; | ||
| scrollbar-width: none; | ||
| } | ||
|
|
||
| .scrollbar-none::-webkit-scrollbar { | ||
| display: none; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
Scrollbar utility: consistent usage across the app.
You introduced .scrollbar-none here; elsewhere the code still uses scrollbar-hide. Standardize on one (prefer .scrollbar-none) to avoid dead classes.
Search and replace leftovers:
🏁 Script executed:
#!/bin/bash
rg -n "scrollbar-hide|scrollbar-none" apps/web/src | sed -n '1,200p'Length of output: 527
I'll verify whether .scrollbar-hide is defined in the codebase to determine if it's dead code or a necessary class.
🏁 Script executed:
#!/bin/bash
# Search for scrollbar-hide class definition in CSS files
rg -n "\.scrollbar-hide\s*[:{]" apps/web/src --type=cssLength of output: 0
🏁 Script executed:
#!/bin/bash
# Check if scrollbar-hide appears in any CSS or style files
fd -e css -e scss -e sass | xargs grep -l "scrollbar-hide" 2>/dev/null | head -20Length of output: 0
🏁 Script executed:
#!/bin/bash
# Get full context for the lines using both scrollbar classes
rg -n -B2 -A2 "scrollbar-hide scrollbar-none|scrollbar-none.*scrollbar-hide" apps/web/srcLength of output: 889
Let me search for all occurrences of scrollbar-hide to get a complete picture:
🏁 Script executed:
#!/bin/bash
# Find all scrollbar-hide usages in the entire codebase
rg -n "scrollbar-hide" apps/web/srcLength of output: 281
Remove dead .scrollbar-hide class references in routes/_view/index.tsx.
.scrollbar-hide is never defined in the CSS but is used at lines 407 and 585 alongside .scrollbar-none. Since .scrollbar-hide has no CSS definition and line 646 demonstrates .scrollbar-none works alone, remove all scrollbar-hide references from the className strings.
🤖 Prompt for AI Agents
In apps/web/src/routes/_view/index.tsx at lines 407 and 585, remove the unused
"scrollbar-hide" token from the className strings (leave ".scrollbar-none"
intact) because ".scrollbar-hide" is not defined in apps/web/src/styles.css;
search the file for any other "scrollbar-hide" occurrences and delete them so
only the working ".scrollbar-none" remains in className lists, then run a quick
dev build to ensure no className typos remain.
c2de687 to
abb7a14
Compare
There was a problem hiding this 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
♻️ Duplicate comments (1)
apps/web/src/routes/_view/index.tsx (1)
160-167: Add missing rel attribute for security.The external link uses
target="_blank"without rel attributes, which can expose the page to tab-nabbing attacks.Apply this diff:
<a className="decoration-dotted underline hover:text-stone-600 transition-all" href="https://github.com/fastrepl/hyprnote" target="_blank" + rel="noopener noreferrer" >
🧹 Nitpick comments (2)
apps/web/src/styles.css (1)
7-8: Remove the unused--breakpoint-laptopbreakpoint variable.The variable is defined at line 7 but has no references anywhere in the codebase. Either use this breakpoint in media queries or remove it.
apps/web/src/routes/_view/index.tsx (1)
426-426: Consider implementing "Learn more" functionality.Multiple instances throughout the file use
window.location.href = "#"as a placeholder. Consider implementing the actual navigation or removing the button if not needed.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (12)
apps/web/public/favicon.icois excluded by!**/*.icoapps/web/public/hyprnote/icon.pngis excluded by!**/*.pngapps/web/public/hyprnote/logo.svgis excluded by!**/*.svgapps/web/public/hyprnote/signature.svgis excluded by!**/*.svgapps/web/public/icons/adobe.svgis excluded by!**/*.svgapps/web/public/icons/yc_stone.svgis excluded by!**/*.svgapps/web/public/patterns/paper.pngis excluded by!**/*.pngapps/web/public/patterns/white_leather.pngis excluded by!**/*.pngapps/web/public/static.gifis excluded by!**/*.gifapps/web/public/team/john.pngis excluded by!**/*.pngapps/web/public/team/yujong.pngis excluded by!**/*.pngpnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (14)
apps/web/package.json(1 hunks)apps/web/src/components/github-open-source.tsx(1 hunks)apps/web/src/components/join-waitlist-button.tsx(1 hunks)apps/web/src/components/logo-cloud.tsx(1 hunks)apps/web/src/components/social-card.tsx(1 hunks)apps/web/src/components/video-modal.tsx(1 hunks)apps/web/src/components/video-player.tsx(1 hunks)apps/web/src/components/video-thumbnail.tsx(1 hunks)apps/web/src/routes/_view/app/account.tsx(2 hunks)apps/web/src/routes/_view/downloads.tsx(1 hunks)apps/web/src/routes/_view/index.tsx(5 hunks)apps/web/src/routes/_view/route.tsx(2 hunks)apps/web/src/routes/auth.tsx(3 hunks)apps/web/src/styles.css(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
- apps/web/src/components/social-card.tsx
- apps/web/src/routes/_view/app/account.tsx
- apps/web/package.json
- apps/web/src/components/video-player.tsx
- apps/web/src/components/video-modal.tsx
- apps/web/src/components/github-open-source.tsx
- apps/web/src/routes/auth.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
After a substantial amount of TypeScript changes, run
pnpm -r typecheck
Files:
apps/web/src/components/logo-cloud.tsxapps/web/src/components/join-waitlist-button.tsxapps/web/src/components/video-thumbnail.tsxapps/web/src/routes/_view/index.tsxapps/web/src/routes/_view/route.tsxapps/web/src/routes/_view/downloads.tsx
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
**/*.{tsx,jsx}: When many classNames have conditional logic in React components, usecnfrom@hypr/utils
When usingcn, always pass an array of class segments
When usingcn, split entries by logical grouping for readability
Usemotion/reactinstead offramer-motion
Files:
apps/web/src/components/logo-cloud.tsxapps/web/src/components/join-waitlist-button.tsxapps/web/src/components/video-thumbnail.tsxapps/web/src/routes/_view/index.tsxapps/web/src/routes/_view/route.tsxapps/web/src/routes/_view/downloads.tsx
🧬 Code graph analysis (3)
apps/web/src/components/join-waitlist-button.tsx (1)
packages/utils/src/cn.ts (1)
cn(20-22)
apps/web/src/components/video-thumbnail.tsx (1)
packages/utils/src/cn.ts (1)
cn(20-22)
apps/web/src/routes/_view/index.tsx (10)
packages/utils/src/cn.ts (1)
cn(20-22)apps/web/src/components/join-waitlist-button.tsx (1)
JoinWaitlistButton(3-33)apps/web/src/components/video-thumbnail.tsx (1)
VideoThumbnail(11-50)apps/web/src/components/logo-cloud.tsx (1)
LogoCloud(35-123)apps/web/src/components/social-card.tsx (1)
SocialCard(18-82)apps/web/src/components/video-player.tsx (1)
VideoPlayer(13-104)apps/web/src/components/github-open-source.tsx (1)
GitHubOpenSource(64-111)apps/web/src/components/download-button.tsx (1)
DownloadButton(4-32)apps/web/src/components/github-stars.tsx (1)
GithubStars(5-35)apps/web/src/components/video-modal.tsx (1)
VideoModal(12-88)
🪛 Biome (2.1.2)
apps/web/src/routes/_view/index.tsx
[error] 163-163: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the rel="noopener" attribute.
(lint/security/noBlankTarget)
🔇 Additional comments (5)
apps/web/src/styles.css (1)
10-19: Cross-browser scrollbar hiding implementation looks solid.This utility properly addresses the earlier issue regarding the undefined
.scrollbar-hideclass. The implementation covers IE/Edge (-ms-overflow-style), Firefox (scrollbar-width), and WebKit browsers (::-webkit-scrollbarpseudo-element), which are the standard requirements for cross-browser scrollbar hiding.apps/web/src/routes/_view/downloads.tsx (1)
61-61: LGTM!The border color adjustment to a lighter shade aligns with the overall UI refresh in this PR.
apps/web/src/components/join-waitlist-button.tsx (1)
1-33: LGTM!The component follows coding guidelines correctly, using
cnwith array syntax and proper class grouping. The external link includes appropriate security attributes.apps/web/src/routes/_view/route.tsx (1)
23-74: LGTM!The header and footer updates are well-implemented:
- Breakpoint adjustments to
laptop:px-0provide better control for wider layouts- Logo image includes proper alt text
- Navigation links have enhanced transitions with underline effects
- External waitlist link includes proper security attributes
apps/web/src/components/logo-cloud.tsx (1)
18-25: LGTM!The styling updates improve the visual presentation:
- Removing
cursor-pointeris appropriate for non-interactive elements- Logo size increase enhances visibility
3a5150b to
3183eb8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
♻️ Duplicate comments (4)
apps/web/src/components/video-modal.tsx (2)
16-22: Addmutedattribute for reliable autoplay.Autoplay will be blocked by browsers unless the video is muted. Add
mutedto the MuxPlayer props to ensure consistent autoplay behavior across browsers.Apply this diff:
<MuxPlayer ref={playerRef} playbackId={playbackId} autoPlay + muted loopAlso applies to: 77-77
35-44: Preserve previous body overflow value.The current implementation always resets
document.body.style.overflowto an empty string, which may clobber the page's previous overflow setting.Apply this diff:
useEffect(() => { + const prev = document.body.style.overflow; if (isOpen) { document.body.style.overflow = "hidden"; } else { - document.body.style.overflow = ""; + document.body.style.overflow = prev; } return () => { - document.body.style.overflow = ""; + document.body.style.overflow = prev; }; }, [isOpen]);apps/web/src/components/github-open-source.tsx (1)
96-96: Fix invalid Tailwind gradient class.
bg-linear-to-tis not a valid Tailwind class. Usebg-gradient-to-tinstead.Apply this diff:
- "bg-linear-to-t from-neutral-800 to-neutral-700 text-white rounded-full", + "bg-gradient-to-t from-neutral-800 to-neutral-700 text-white rounded-full",apps/web/src/routes/_view/index.tsx (1)
160-167: Add missingrelattribute for security.The external link uses
target="_blank"withoutrelattributes, which is a security risk (tab-nabbing).Apply this diff:
<a className="decoration-dotted underline hover:text-stone-600 transition-all" href="https://github.com/fastrepl/hyprnote" target="_blank" + rel="noopener noreferrer" >
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (13)
apps/web/public/favicon.icois excluded by!**/*.icoapps/web/public/hyprnote/icon.pngis excluded by!**/*.pngapps/web/public/hyprnote/logo.svgis excluded by!**/*.svgapps/web/public/hyprnote/signature.svgis excluded by!**/*.svgapps/web/public/icons/adobe.svgis excluded by!**/*.svgapps/web/public/icons/yc_stone.svgis excluded by!**/*.svgapps/web/public/patterns/paper.pngis excluded by!**/*.pngapps/web/public/patterns/white_leather.pngis excluded by!**/*.pngapps/web/public/static.gifis excluded by!**/*.gifapps/web/public/team/john.pngis excluded by!**/*.pngapps/web/public/team/yujong.pngis excluded by!**/*.pngapps/web/src/routeTree.gen.tsis excluded by!**/*.gen.tspnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (15)
apps/web/package.json(1 hunks)apps/web/src/components/github-open-source.tsx(1 hunks)apps/web/src/components/join-waitlist-button.tsx(1 hunks)apps/web/src/components/logo-cloud.tsx(1 hunks)apps/web/src/components/social-card.tsx(1 hunks)apps/web/src/components/video-modal.tsx(1 hunks)apps/web/src/components/video-player.tsx(1 hunks)apps/web/src/components/video-thumbnail.tsx(1 hunks)apps/web/src/routes/_view/app/account.tsx(2 hunks)apps/web/src/routes/_view/downloads.tsx(1 hunks)apps/web/src/routes/_view/index.tsx(5 hunks)apps/web/src/routes/_view/route.tsx(3 hunks)apps/web/src/routes/auth.tsx(3 hunks)apps/web/src/routes/cal.tsx(1 hunks)apps/web/src/styles.css(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
- apps/web/package.json
- apps/web/src/components/video-player.tsx
- apps/web/src/components/logo-cloud.tsx
- apps/web/src/components/video-thumbnail.tsx
- apps/web/src/routes/auth.tsx
- apps/web/src/routes/_view/app/account.tsx
- apps/web/src/routes/_view/downloads.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
After a substantial amount of TypeScript changes, run
pnpm -r typecheck
Files:
apps/web/src/routes/cal.tsxapps/web/src/components/social-card.tsxapps/web/src/routes/_view/route.tsxapps/web/src/components/github-open-source.tsxapps/web/src/components/join-waitlist-button.tsxapps/web/src/routes/_view/index.tsxapps/web/src/components/video-modal.tsx
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
**/*.{tsx,jsx}: When many classNames have conditional logic in React components, usecnfrom@hypr/utils
When usingcn, always pass an array of class segments
When usingcn, split entries by logical grouping for readability
Usemotion/reactinstead offramer-motion
Files:
apps/web/src/routes/cal.tsxapps/web/src/components/social-card.tsxapps/web/src/routes/_view/route.tsxapps/web/src/components/github-open-source.tsxapps/web/src/components/join-waitlist-button.tsxapps/web/src/routes/_view/index.tsxapps/web/src/components/video-modal.tsx
🧠 Learnings (3)
📚 Learning: 2025-10-26T00:28:22.016Z
Learnt from: CR
PR: fastrepl/hyprnote#0
File: .cursor/rules/simple.mdc:0-0
Timestamp: 2025-10-26T00:28:22.016Z
Learning: Applies to **/*.{tsx,jsx} : When using `cn`, always pass an array of class segments
Applied to files:
apps/web/src/routes/_view/index.tsx
📚 Learning: 2025-10-26T00:28:22.016Z
Learnt from: CR
PR: fastrepl/hyprnote#0
File: .cursor/rules/simple.mdc:0-0
Timestamp: 2025-10-26T00:28:22.016Z
Learning: Applies to **/*.{tsx,jsx} : When many classNames have conditional logic in React components, use `cn` from `hypr/utils`
Applied to files:
apps/web/src/routes/_view/index.tsx
📚 Learning: 2025-10-26T00:28:22.016Z
Learnt from: CR
PR: fastrepl/hyprnote#0
File: .cursor/rules/simple.mdc:0-0
Timestamp: 2025-10-26T00:28:22.016Z
Learning: Applies to **/*.{tsx,jsx} : When using `cn`, split entries by logical grouping for readability
Applied to files:
apps/web/src/routes/_view/index.tsx
🧬 Code graph analysis (5)
apps/web/src/routes/cal.tsx (2)
apps/web/src/routes/_view/route.tsx (1)
Route(3-6)packages/utils/src/cn.ts (1)
cn(20-22)
apps/web/src/components/github-open-source.tsx (1)
packages/utils/src/cn.ts (1)
cn(20-22)
apps/web/src/components/join-waitlist-button.tsx (1)
packages/utils/src/cn.ts (1)
cn(20-22)
apps/web/src/routes/_view/index.tsx (10)
packages/utils/src/cn.ts (1)
cn(20-22)apps/web/src/components/join-waitlist-button.tsx (1)
JoinWaitlistButton(3-33)apps/web/src/components/video-thumbnail.tsx (1)
VideoThumbnail(11-50)apps/web/src/components/logo-cloud.tsx (1)
LogoCloud(35-123)apps/web/src/components/social-card.tsx (1)
SocialCard(18-82)apps/web/src/components/video-player.tsx (1)
VideoPlayer(13-104)apps/web/src/components/github-open-source.tsx (1)
GitHubOpenSource(138-314)apps/web/src/components/download-button.tsx (1)
DownloadButton(4-32)apps/web/src/components/github-stars.tsx (1)
GithubStars(5-35)apps/web/src/components/video-modal.tsx (1)
VideoModal(12-88)
apps/web/src/components/video-modal.tsx (1)
packages/utils/src/cn.ts (1)
cn(20-22)
🪛 Biome (2.1.2)
apps/web/src/routes/_view/index.tsx
[error] 163-163: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the rel="noopener" attribute.
(lint/security/noBlankTarget)
🔇 Additional comments (7)
apps/web/src/styles.css (2)
7-7: LGTM!The custom breakpoint follows Tailwind's @theme convention and provides a reasonable laptop breakpoint at 1152px.
10-19: LGTM!The
.scrollbar-noneutility is correctly implemented with cross-browser support for hiding scrollbars (IE/Edge, Firefox, and WebKit browsers).apps/web/src/components/social-card.tsx (1)
78-78: LGTM!The responsive text truncation (4 lines mobile, 15 lines desktop) improves the mobile UX while preserving full content on larger screens.
apps/web/src/routes/_view/route.tsx (2)
10-10: LGTM!The layout updates consistently use the new
laptop:breakpoint and add proper flex layout for a sticky footer pattern.Also applies to: 23-23, 74-74
28-30: LGTM!Replacing text branding with an SVG logo improves visual consistency and brand identity.
apps/web/src/routes/_view/index.tsx (2)
29-94: LGTM!The feature data structures are well-organized with clear separation between main features and details. The
comingSoonflags and consistent icon naming make the data easy to maintain.
96-112: LGTM!The scroll helper functions correctly calculate scroll positions and sync with the indicators. The smooth scrolling behavior enhances UX.
6df8aac to
def95fe
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
♻️ Duplicate comments (14)
apps/web/src/components/video-modal.tsx (4)
35-44: Preserve previous body overflow value.The current implementation unconditionally resets
overflowto"", which may clobber the page's previous state if it had a custom overflow setting.Apply this diff:
useEffect(() => { + const prev = document.body.style.overflow; if (isOpen) { document.body.style.overflow = "hidden"; } else { - document.body.style.overflow = ""; + document.body.style.overflow = prev; } return () => { - document.body.style.overflow = ""; + document.body.style.overflow = prev; }; }, [isOpen]);
3-3: Replace undocumented type with official MuxPlayerElement.The
MuxPlayerRefAttributestype is not part of the official Mux API. Per Mux documentation, useMuxPlayerElementfrom'@mux/mux-player'.Apply this diff:
-import MuxPlayer, { type MuxPlayerRefAttributes } from "@mux/mux-player-react"; +import type MuxPlayerElement from "@mux/mux-player"; +import MuxPlayer from "@mux/mux-player-react";And update line 13:
- const playerRef = useRef<MuxPlayerRefAttributes>(null); + const playerRef = useRef<MuxPlayerElement | null>(null);
1-4: Add "use client" directive for SSR compatibility.This component uses MuxPlayer (a web component) and DOM manipulation, requiring client-side rendering to avoid hydration mismatches.
Add this directive at the top of the file:
+"use client"; + import { cn } from "@hypr/utils";
74-84: Add muted attribute for reliable autoplay.Autoplay without
mutedwill be blocked by most browsers, especially Safari/iOS. Add themutedattribute to ensure consistent behavior.Apply this diff:
<MuxPlayer ref={playerRef} playbackId={playbackId} autoPlay + muted + playsInline loop accentColor="#78716c"apps/web/src/components/join-waitlist-button.tsx (1)
11-11: Fix invalid Tailwind gradient class.
bg-linear-to-tis not a valid Tailwind class. Usebg-gradient-to-tinstead.Apply this diff:
- "bg-linear-to-t from-stone-600 to-stone-500 text-white rounded-full", + "bg-gradient-to-t from-stone-600 to-stone-500 text-white rounded-full",apps/web/src/components/video-player.tsx (2)
2-2: Replace undocumented type with official MuxPlayerElement.The
MuxPlayerRefAttributestype is not part of the official Mux API. Per Mux documentation, useMuxPlayerElementfrom'@mux/mux-player'.Apply this diff:
-import MuxPlayer, { type MuxPlayerRefAttributes } from "@mux/mux-player-react"; +import type MuxPlayerElement from "@mux/mux-player"; +import MuxPlayer from "@mux/mux-player-react";And update line 22:
- const playerRef = useRef<MuxPlayerRefAttributes>(null); + const playerRef = useRef<MuxPlayerElement | null>(null);
1-4: Add "use client" directive for SSR compatibility.Since this component uses MuxPlayer (a web component), it needs client-side rendering to avoid hydration mismatches in the SSR environment.
Add this directive at the top of the file:
+"use client"; + import { cn } from "@hypr/utils";apps/web/src/routes/_view/index.tsx (7)
114-114: Fix invalid Tailwind gradient class.
bg-linear-to-bis not a valid Tailwind class. Usebg-gradient-to-binstead.Apply this diff:
- <main className="flex-1 bg-linear-to-b from-white via-stone-50/20 to-white min-h-screen"> + <main className="flex-1 bg-gradient-to-b from-white via-stone-50/20 to-white min-h-screen">
142-142: Fix invalid Tailwind gradient class.
bg-linear-to-bis not a valid Tailwind class. Usebg-gradient-to-binstead.Apply this diff:
- <div className="bg-linear-to-b from-stone-50/30 to-stone-100/30"> + <div className="bg-gradient-to-b from-stone-50/30 to-stone-100/30">
160-167: Add missing rel attribute for security.External links with
target="_blank"requirerel="noopener noreferrer"to prevent tab-nabbing security issues.Apply this diff:
<a className="decoration-dotted underline hover:text-stone-600 transition-all" href="https://github.com/fastrepl/hyprnote" target="_blank" + rel="noopener noreferrer" >
408-408: Remove dead scrollbar-hide class.The
scrollbar-hideclass is not defined in the CSS. Onlyscrollbar-noneis needed.Apply this diff:
- className="overflow-x-auto snap-x snap-mandatory scrollbar-hide scrollbar-none -mx-4" + className="overflow-x-auto snap-x snap-mandatory scrollbar-none -mx-4"
586-586: Remove dead scrollbar-hide class.The
scrollbar-hideclass is not defined in the CSS. Onlyscrollbar-noneis needed.Apply this diff:
- className="overflow-x-auto scrollbar-none snap-x snap-mandatory scrollbar-hide -mx-4" + className="overflow-x-auto scrollbar-none snap-x snap-mandatory -mx-4"
798-798: Fix invalid Tailwind gradient class.
bg-linear-to-tis not a valid Tailwind class. Usebg-gradient-to-tinstead.Apply this diff:
- <section className="py-16 border-t border-neutral-100 bg-linear-to-t from-stone-50/30 to-stone-100/30 px-4 laptop:px-0"> + <section className="py-16 border-t border-neutral-100 bg-gradient-to-t from-stone-50/30 to-stone-100/30 px-4 laptop:px-0">
124-131: Refactor cn usage to array syntax.Per coding guidelines,
cnshould always receive an array of class segments.Based on learnings
Apply this diff:
<div - className={cn( + className={cn([ "flex items-center justify-center gap-2 text-center", "bg-stone-50/70 border-b border-stone-100", "py-3 px-4", "font-serif text-sm text-stone-700", "hover:bg-stone-50 transition-all", - )} + ])} >
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (13)
apps/web/public/favicon.icois excluded by!**/*.icoapps/web/public/hyprnote/icon.pngis excluded by!**/*.pngapps/web/public/hyprnote/logo.svgis excluded by!**/*.svgapps/web/public/hyprnote/signature.svgis excluded by!**/*.svgapps/web/public/icons/adobe.svgis excluded by!**/*.svgapps/web/public/icons/yc_stone.svgis excluded by!**/*.svgapps/web/public/patterns/paper.pngis excluded by!**/*.pngapps/web/public/patterns/white_leather.pngis excluded by!**/*.pngapps/web/public/static.gifis excluded by!**/*.gifapps/web/public/team/john.pngis excluded by!**/*.pngapps/web/public/team/yujong.pngis excluded by!**/*.pngapps/web/src/routeTree.gen.tsis excluded by!**/*.gen.tspnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (15)
apps/web/package.json(1 hunks)apps/web/src/components/github-open-source.tsx(1 hunks)apps/web/src/components/join-waitlist-button.tsx(1 hunks)apps/web/src/components/logo-cloud.tsx(1 hunks)apps/web/src/components/social-card.tsx(1 hunks)apps/web/src/components/video-modal.tsx(1 hunks)apps/web/src/components/video-player.tsx(1 hunks)apps/web/src/components/video-thumbnail.tsx(1 hunks)apps/web/src/routes/_view/app/account.tsx(2 hunks)apps/web/src/routes/_view/downloads.tsx(1 hunks)apps/web/src/routes/_view/index.tsx(5 hunks)apps/web/src/routes/_view/route.tsx(3 hunks)apps/web/src/routes/auth.tsx(3 hunks)apps/web/src/routes/cal.tsx(1 hunks)apps/web/src/styles.css(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
- apps/web/src/routes/_view/app/account.tsx
- apps/web/src/routes/cal.tsx
- apps/web/src/routes/_view/downloads.tsx
- apps/web/src/components/social-card.tsx
- apps/web/src/components/video-thumbnail.tsx
- apps/web/src/components/github-open-source.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
After a substantial amount of TypeScript changes, run
pnpm -r typecheck
Files:
apps/web/src/routes/auth.tsxapps/web/src/components/video-player.tsxapps/web/src/components/logo-cloud.tsxapps/web/src/components/join-waitlist-button.tsxapps/web/src/routes/_view/route.tsxapps/web/src/components/video-modal.tsxapps/web/src/routes/_view/index.tsx
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
**/*.{tsx,jsx}: When many classNames have conditional logic in React components, usecnfrom@hypr/utils
When usingcn, always pass an array of class segments
When usingcn, split entries by logical grouping for readability
Usemotion/reactinstead offramer-motion
Files:
apps/web/src/routes/auth.tsxapps/web/src/components/video-player.tsxapps/web/src/components/logo-cloud.tsxapps/web/src/components/join-waitlist-button.tsxapps/web/src/routes/_view/route.tsxapps/web/src/components/video-modal.tsxapps/web/src/routes/_view/index.tsx
🧠 Learnings (3)
📚 Learning: 2025-10-26T00:28:22.016Z
Learnt from: CR
PR: fastrepl/hyprnote#0
File: .cursor/rules/simple.mdc:0-0
Timestamp: 2025-10-26T00:28:22.016Z
Learning: Applies to **/*.{tsx,jsx} : When many classNames have conditional logic in React components, use `cn` from `hypr/utils`
Applied to files:
apps/web/src/routes/auth.tsxapps/web/src/routes/_view/index.tsx
📚 Learning: 2025-10-26T00:28:22.016Z
Learnt from: CR
PR: fastrepl/hyprnote#0
File: .cursor/rules/simple.mdc:0-0
Timestamp: 2025-10-26T00:28:22.016Z
Learning: Applies to **/*.{tsx,jsx} : When using `cn`, always pass an array of class segments
Applied to files:
apps/web/src/routes/_view/index.tsx
📚 Learning: 2025-10-26T00:28:22.016Z
Learnt from: CR
PR: fastrepl/hyprnote#0
File: .cursor/rules/simple.mdc:0-0
Timestamp: 2025-10-26T00:28:22.016Z
Learning: Applies to **/*.{tsx,jsx} : When using `cn`, split entries by logical grouping for readability
Applied to files:
apps/web/src/routes/_view/index.tsx
🧬 Code graph analysis (4)
apps/web/src/components/video-player.tsx (1)
packages/utils/src/cn.ts (1)
cn(20-22)
apps/web/src/components/join-waitlist-button.tsx (1)
packages/utils/src/cn.ts (1)
cn(20-22)
apps/web/src/components/video-modal.tsx (1)
packages/utils/src/cn.ts (1)
cn(20-22)
apps/web/src/routes/_view/index.tsx (10)
packages/utils/src/cn.ts (1)
cn(20-22)apps/web/src/components/join-waitlist-button.tsx (1)
JoinWaitlistButton(3-33)apps/web/src/components/video-thumbnail.tsx (1)
VideoThumbnail(11-50)apps/web/src/components/logo-cloud.tsx (1)
LogoCloud(35-123)apps/web/src/components/social-card.tsx (1)
SocialCard(18-82)apps/web/src/components/video-player.tsx (1)
VideoPlayer(13-104)apps/web/src/components/github-open-source.tsx (1)
GitHubOpenSource(138-314)apps/web/src/components/download-button.tsx (1)
DownloadButton(4-32)apps/web/src/components/github-stars.tsx (1)
GithubStars(5-35)apps/web/src/components/video-modal.tsx (1)
VideoModal(12-88)
🪛 Biome (2.1.2)
apps/web/src/routes/_view/index.tsx
[error] 163-163: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the rel="noopener" attribute.
(lint/security/noBlankTarget)
🔇 Additional comments (3)
apps/web/src/components/logo-cloud.tsx (1)
25-25: LGTM: Logo size increase improves visibility.The increased logo dimensions (h-5 and md:h-6) enhance visual presence without causing layout issues.
apps/web/src/styles.css (1)
7-18: LGTM! Well-structured CSS utilities.The custom breakpoint and scrollbar utility are properly defined with comprehensive browser support.
apps/web/src/routes/auth.tsx (1)
1-229: LGTM! Clean layout refactor with proper cn usage.The simplified container structure and updated branding assets improve the auth flow. The cn usage correctly follows the coding guidelines with array syntax.
def95fe to
80dbe58
Compare
Improve page layout with full-height container and expand GitHub contributors list with usernames and avatar URLs for better representation and attribution of open-source contributors.
There was a problem hiding this 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 (4)
apps/web/src/routes/_view/index.tsx (4)
804-804: Fix invalid Tailwind gradient class.The class
bg-linear-to-tis not valid Tailwind CSS. Usebg-gradient-to-tinstead.Apply this diff:
- <section className="py-16 border-t border-neutral-100 bg-linear-to-t from-stone-50/30 to-stone-100/30 px-4 laptop:px-0"> + <section className="py-16 border-t border-neutral-100 bg-gradient-to-t from-stone-50/30 to-stone-100/30 px-4 laptop:px-0">
114-114: Fix invalid Tailwind gradient class.The class
bg-linear-to-bis not valid Tailwind CSS. Usebg-gradient-to-binstead.Apply this diff:
- <main className="flex-1 bg-linear-to-b from-white via-stone-50/20 to-white min-h-screen"> + <main className="flex-1 bg-gradient-to-b from-white via-stone-50/20 to-white min-h-screen">
162-169: Security: Add missing rel attribute to prevent tab-nabbing.The external link uses
target="_blank"withoutrel="noopener noreferrer", which creates a security vulnerability.Apply this diff:
<a className="decoration-dotted underline hover:text-stone-600 transition-all" href="https://github.com/fastrepl/hyprnote" target="_blank" + rel="noopener noreferrer" >
144-144: Fix invalid Tailwind gradient class.The class
bg-linear-to-bis not valid Tailwind CSS. Usebg-gradient-to-binstead.Apply this diff:
- <div className="bg-linear-to-b from-stone-50/30 to-stone-100/30"> + <div className="bg-gradient-to-b from-stone-50/30 to-stone-100/30">
🧹 Nitpick comments (1)
apps/web/src/routes/_view/index.tsx (1)
428-428: Address placeholder navigation callbacks.Multiple instances of
onLearnMore={() => window.location.href = "#"}appear throughout the file (lines 428, 484, 503, 522, 541, 606, 687, 730). These are no-ops that don't provide any functionality. Consider either removing the onLearnMore prop or implementing proper navigation.Either remove the prop if not needed:
<VideoPlayer playbackId={MUX_PLAYBACK_ID} - onLearnMore={() => window.location.href = "#"} onExpandVideo={() => setExpandedVideo(MUX_PLAYBACK_ID)} />Or implement proper navigation to a relevant section/page.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
apps/web/src/components/video-player.tsx(1 hunks)apps/web/src/components/video-thumbnail.tsx(1 hunks)apps/web/src/routes/_view/index.tsx(5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- apps/web/src/components/video-player.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
After a substantial amount of TypeScript changes, run
pnpm -r typecheck
Files:
apps/web/src/routes/_view/index.tsxapps/web/src/components/video-thumbnail.tsx
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
**/*.{tsx,jsx}: When many classNames have conditional logic in React components, usecnfrom@hypr/utils
When usingcn, always pass an array of class segments
When usingcn, split entries by logical grouping for readability
Usemotion/reactinstead offramer-motion
Files:
apps/web/src/routes/_view/index.tsxapps/web/src/components/video-thumbnail.tsx
🧠 Learnings (3)
📚 Learning: 2025-10-26T00:28:22.016Z
Learnt from: CR
PR: fastrepl/hyprnote#0
File: .cursor/rules/simple.mdc:0-0
Timestamp: 2025-10-26T00:28:22.016Z
Learning: Applies to **/*.{tsx,jsx} : When using `cn`, always pass an array of class segments
Applied to files:
apps/web/src/routes/_view/index.tsxapps/web/src/components/video-thumbnail.tsx
📚 Learning: 2025-10-26T00:28:22.016Z
Learnt from: CR
PR: fastrepl/hyprnote#0
File: .cursor/rules/simple.mdc:0-0
Timestamp: 2025-10-26T00:28:22.016Z
Learning: Applies to **/*.{tsx,jsx} : When many classNames have conditional logic in React components, use `cn` from `hypr/utils`
Applied to files:
apps/web/src/routes/_view/index.tsxapps/web/src/components/video-thumbnail.tsx
📚 Learning: 2025-10-26T00:28:22.016Z
Learnt from: CR
PR: fastrepl/hyprnote#0
File: .cursor/rules/simple.mdc:0-0
Timestamp: 2025-10-26T00:28:22.016Z
Learning: Applies to **/*.{tsx,jsx} : When using `cn`, split entries by logical grouping for readability
Applied to files:
apps/web/src/routes/_view/index.tsxapps/web/src/components/video-thumbnail.tsx
🧬 Code graph analysis (2)
apps/web/src/routes/_view/index.tsx (9)
packages/utils/src/cn.ts (1)
cn(20-22)apps/web/src/components/join-waitlist-button.tsx (1)
JoinWaitlistButton(3-33)apps/web/src/components/video-thumbnail.tsx (1)
VideoThumbnail(11-50)apps/web/src/components/logo-cloud.tsx (1)
LogoCloud(35-123)apps/web/src/components/social-card.tsx (1)
SocialCard(18-82)apps/web/src/components/video-player.tsx (1)
VideoPlayer(13-106)apps/web/src/components/download-button.tsx (1)
DownloadButton(4-32)apps/web/src/components/github-stars.tsx (1)
GithubStars(5-35)apps/web/src/components/video-modal.tsx (1)
VideoModal(12-88)
apps/web/src/components/video-thumbnail.tsx (1)
packages/utils/src/cn.ts (1)
cn(20-22)
🪛 Biome (2.1.2)
apps/web/src/routes/_view/index.tsx
[error] 165-165: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the rel="noopener" attribute.
(lint/security/noBlankTarget)
🔇 Additional comments (5)
apps/web/src/components/video-thumbnail.tsx (1)
1-50: LGTM! Component follows coding guidelines.The VideoThumbnail component is well-implemented with proper use of
cnarray syntax, good accessibility (aria-label), and correct event handling (stopPropagation). The structure is clean and the MuxPlayer integration looks solid.apps/web/src/routes/_view/index.tsx (4)
659-664: Refactor cn to use array syntax.Per coding guidelines,
cnmust always receive an array of class segments.As per coding guidelines
Apply this diff:
className={cn( + [ "p-6 border-r border-neutral-100 last:border-r-0 min-w-[280px] text-left transition-colors", selectedDetail === index ? "bg-stone-50" : "hover:bg-neutral-50", + ] )}
702-706: Refactor cn to use array syntax.Per coding guidelines,
cnmust always receive an array of class segments.As per coding guidelines
Apply this diff:
className={cn( + [ "p-6 cursor-pointer transition-colors", index < detailsFeatures.length - 1 && "border-b border-neutral-100", "hover:bg-neutral-50", + ] )}
22-112: Well-structured component state and helpers.The state management, data structures (mainFeatures, detailsFeatures), and scroll helper functions are well-organized and clean. The use of refs for scroll containers is appropriate.
828-832: VideoModal integration looks good.The expandedVideo state is properly wired to the VideoModal component with correct props and state management.
80dbe58 to
3556cd7
Compare
There was a problem hiding this 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 (11)
apps/web/src/components/logo-cloud.tsx (1)
17-20: Follow coding guidelines: wrapcnarguments in an array.The
cnutility should be called with an array of class segments per the project's coding guidelines and retrieved learnings. This issue was already flagged in a previous review but remains unresolved.As per coding guidelines.
Apply this diff:
- className={cn( - "flex items-center justify-center bg-transparent px-4 py-8 md:p-8 hover:bg-neutral-50 transition-colors", - className, - )} + className={cn([ + "flex items-center justify-center bg-transparent px-4 py-8 md:p-8 hover:bg-neutral-50 transition-colors", + className, + ])}apps/web/src/styles.css (1)
10-18: Scrollbar utility: add WebKit width/height for robustness + a11y fallback.Pattern is solid. To cover WebKit cases that ignore
display: none, also set zero width/height on the pseudo-element. Consider an a11y fallback for high-contrast users.Apply within this block:
.scrollbar-none::-webkit-scrollbar { - display: none; + display: none; + width: 0; + height: 0; }Optionally add outside this block (same file):
/* Revert utility when needed (nested components) */ @layer utilities { .scrollbar-auto { -ms-overflow-style: auto; scrollbar-width: auto; } } /* Respect system high-contrast settings */ @media (forced-colors: active) { .scrollbar-none { -ms-overflow-style: auto; scrollbar-width: auto; } }Also, continue removing any
.scrollbar-hideremnants across the app to standardize on.scrollbar-none.apps/web/src/components/video-modal.tsx (3)
35-44: Preserve previous body overflow value.Already flagged in past review; capture and restore original overflow state.
3-3: Use MuxPlayerElement type.Already flagged in past review; import from
@mux/mux-player.Also applies to: 13-13
16-23: Add muted attribute for reliable autoplay.Already flagged in past review; autoplay requires muted for Safari/iOS.
apps/web/src/routes/_view/route.tsx (1)
57-57: Fix invalid Tailwind gradient class.
bg-linear-to-tis not valid; usebg-gradient-to-t.apps/web/src/components/video-player.tsx (1)
2-2: Use MuxPlayerElement instead of MuxPlayerRefAttributes.Per past review and Mux documentation, import
MuxPlayerElementfrom@mux/mux-player.Also applies to: 22-22
apps/web/src/routes/_view/index.tsx (4)
114-114: Fix invalid gradient class.Use
bg-gradient-to-binstead ofbg-linear-to-b.
165-166: Add rel="noopener noreferrer" to external link.Security: prevent tab-nabbing on target="_blank" links.
659-664: Refactor cn to use array syntax.Per coding guidelines, wrap class strings in an array.
Based on learnings
702-706: Refactor cn to use array syntax.Per coding guidelines, wrap arguments in an array.
Based on learnings
🧹 Nitpick comments (1)
apps/web/src/components/social-card.tsx (1)
78-78: Good responsive improvement; consider removing redundant class.The responsive text clamping (4 lines on mobile, 15 on larger screens) improves readability on smaller viewports. However,
overflow-hiddenis redundant since Tailwind'sline-clamp-*utilities already include it.Apply this diff to remove the redundant class:
- <p className="text-neutral-700 leading-relaxed line-clamp-4 md:line-clamp-15 overflow-hidden">{body}</p> + <p className="text-neutral-700 leading-relaxed line-clamp-4 md:line-clamp-15">{body}</p>
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (13)
apps/web/public/favicon.icois excluded by!**/*.icoapps/web/public/hyprnote/icon.pngis excluded by!**/*.pngapps/web/public/hyprnote/logo.svgis excluded by!**/*.svgapps/web/public/hyprnote/signature.svgis excluded by!**/*.svgapps/web/public/icons/adobe.svgis excluded by!**/*.svgapps/web/public/icons/yc_stone.svgis excluded by!**/*.svgapps/web/public/patterns/paper.pngis excluded by!**/*.pngapps/web/public/patterns/white_leather.pngis excluded by!**/*.pngapps/web/public/static.gifis excluded by!**/*.gifapps/web/public/team/john.pngis excluded by!**/*.pngapps/web/public/team/yujong.pngis excluded by!**/*.pngapps/web/src/routeTree.gen.tsis excluded by!**/*.gen.tspnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (15)
apps/web/package.json(1 hunks)apps/web/src/components/github-open-source.tsx(1 hunks)apps/web/src/components/join-waitlist-button.tsx(1 hunks)apps/web/src/components/logo-cloud.tsx(1 hunks)apps/web/src/components/social-card.tsx(1 hunks)apps/web/src/components/video-modal.tsx(1 hunks)apps/web/src/components/video-player.tsx(1 hunks)apps/web/src/components/video-thumbnail.tsx(1 hunks)apps/web/src/routes/_view/app/account.tsx(2 hunks)apps/web/src/routes/_view/downloads.tsx(1 hunks)apps/web/src/routes/_view/index.tsx(5 hunks)apps/web/src/routes/_view/route.tsx(3 hunks)apps/web/src/routes/auth.tsx(3 hunks)apps/web/src/routes/cal.tsx(1 hunks)apps/web/src/styles.css(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
- apps/web/src/components/join-waitlist-button.tsx
- apps/web/src/routes/auth.tsx
- apps/web/src/routes/cal.tsx
- apps/web/src/components/video-thumbnail.tsx
- apps/web/package.json
- apps/web/src/components/github-open-source.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
After a substantial amount of TypeScript changes, run
pnpm -r typecheck
Files:
apps/web/src/routes/_view/app/account.tsxapps/web/src/routes/_view/downloads.tsxapps/web/src/routes/_view/route.tsxapps/web/src/components/logo-cloud.tsxapps/web/src/components/social-card.tsxapps/web/src/routes/_view/index.tsxapps/web/src/components/video-player.tsxapps/web/src/components/video-modal.tsx
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
**/*.{tsx,jsx}: When many classNames have conditional logic in React components, usecnfrom@hypr/utils
When usingcn, always pass an array of class segments
When usingcn, split entries by logical grouping for readability
Usemotion/reactinstead offramer-motion
Files:
apps/web/src/routes/_view/app/account.tsxapps/web/src/routes/_view/downloads.tsxapps/web/src/routes/_view/route.tsxapps/web/src/components/logo-cloud.tsxapps/web/src/components/social-card.tsxapps/web/src/routes/_view/index.tsxapps/web/src/components/video-player.tsxapps/web/src/components/video-modal.tsx
🧠 Learnings (3)
📚 Learning: 2025-10-26T00:28:22.016Z
Learnt from: CR
PR: fastrepl/hyprnote#0
File: .cursor/rules/simple.mdc:0-0
Timestamp: 2025-10-26T00:28:22.016Z
Learning: Applies to **/*.{tsx,jsx} : When using `cn`, always pass an array of class segments
Applied to files:
apps/web/src/components/logo-cloud.tsxapps/web/src/routes/_view/index.tsx
📚 Learning: 2025-10-26T00:28:22.016Z
Learnt from: CR
PR: fastrepl/hyprnote#0
File: .cursor/rules/simple.mdc:0-0
Timestamp: 2025-10-26T00:28:22.016Z
Learning: Applies to **/*.{tsx,jsx} : When many classNames have conditional logic in React components, use `cn` from `hypr/utils`
Applied to files:
apps/web/src/components/logo-cloud.tsxapps/web/src/routes/_view/index.tsx
📚 Learning: 2025-10-26T00:28:22.016Z
Learnt from: CR
PR: fastrepl/hyprnote#0
File: .cursor/rules/simple.mdc:0-0
Timestamp: 2025-10-26T00:28:22.016Z
Learning: Applies to **/*.{tsx,jsx} : When using `cn`, split entries by logical grouping for readability
Applied to files:
apps/web/src/routes/_view/index.tsx
🧬 Code graph analysis (3)
apps/web/src/routes/_view/index.tsx (6)
packages/utils/src/cn.ts (1)
cn(20-22)apps/web/src/components/join-waitlist-button.tsx (1)
JoinWaitlistButton(3-33)apps/web/src/components/video-thumbnail.tsx (1)
VideoThumbnail(11-50)apps/web/src/components/video-player.tsx (1)
VideoPlayer(13-106)apps/web/src/components/github-open-source.tsx (1)
GitHubOpenSource(138-314)apps/web/src/components/video-modal.tsx (1)
VideoModal(12-88)
apps/web/src/components/video-player.tsx (1)
packages/utils/src/cn.ts (1)
cn(20-22)
apps/web/src/components/video-modal.tsx (1)
packages/utils/src/cn.ts (1)
cn(20-22)
🪛 Biome (2.1.2)
apps/web/src/routes/_view/index.tsx
[error] 165-165: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the rel="noopener" attribute.
(lint/security/noBlankTarget)
🔇 Additional comments (9)
apps/web/src/components/logo-cloud.tsx (1)
18-18: LGTM: appropriate visual adjustments.The removal of
cursor-pointeris correct since the logos are non-interactive, and the logo size increase (h-4→h-5, md:h-5→md:h-6) provides better visual balance. These changes align well with the broader UI polish in this PR.Also applies to: 25-25
apps/web/src/styles.css (1)
7-8: Breakpoint token looks good; verify consumer classes exist.Defining
--breakpoint-laptop: 72remwill generate alaptop:screen in Tailwind v4. Please confirm there are real usages and no overlap/conflicts with nearby screens (e.g.,lg,xl). If unused, consider deferring to avoid token drift.apps/web/src/routes/_view/downloads.tsx (1)
61-61: LGTM - Consistent styling refinement.The border color change aligns with the broader styling harmonization across the PR.
apps/web/src/routes/_view/app/account.tsx (1)
159-159: LGTM - Consistent border styling updates.The border color updates across both settings cards align with the broader UI styling harmonization in this PR.
Also applies to: 167-167, 181-181, 189-189
apps/web/src/components/video-player.tsx (1)
39-105: LGTM - Well-structured video player component.The hover-driven autoplay, overlay controls, and
cnarray syntax usage all follow best practices.apps/web/src/routes/_view/index.tsx (4)
22-27: LGTM - Well-structured state management and feature definitions.The video state, scroll refs, feature arrays, and scroll helpers are cleanly organized and support the interactive UI patterns well.
Also applies to: 29-112
124-132: LGTM - Correct cn array syntax.Properly uses array syntax with logical groupings.
Based on learnings
463-471: LGTM - Correct cn array syntax with conditional.Properly structured with array syntax.
Based on learnings
635-643: LGTM - Correct cn array syntax.Follows guidelines with array syntax.
Based on learnings
3556cd7 to
bb91c7a
Compare
Decompose the booking page into smaller, reusable components for improved code organization and readability. Split the existing monolithic component into separate Header, BookingButton, and FAQ sections, making the code more maintainable and easier to understand.
bb91c7a to
cb767a6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
♻️ Duplicate comments (6)
apps/web/src/components/video-modal.tsx (2)
36-45: Preserve previous body overflow value.The current implementation always resets
document.body.style.overflowto an empty string, which may clobber the page's previous overflow setting.Apply this diff:
useEffect(() => { + const prev = document.body.style.overflow; if (isOpen) { document.body.style.overflow = "hidden"; } else { - document.body.style.overflow = ""; + document.body.style.overflow = prev; } return () => { - document.body.style.overflow = ""; + document.body.style.overflow = prev; }; }, [isOpen]);
17-23: Autoplay may fail without muted attribute.Browsers often block autoplay unless the video is muted. Add
mutedandplaysInlineto ensure reliable autoplay across all browsers, especially Safari/iOS.Apply this diff to the useEffect:
useEffect(() => { if (isOpen && playerRef.current) { + playerRef.current.muted = true; playerRef.current.play().catch(() => { // Ignore autoplay errors }); } }, [isOpen]);And update the MuxPlayer props:
<MuxPlayer ref={playerRef} playbackId={playbackId} autoPlay + muted + playsInline loopapps/web/src/components/github-open-source.tsx (1)
96-96: Fix invalid Tailwind gradient class.
bg-linear-to-tis not a valid Tailwind class. Usebg-gradient-to-tinstead.Apply this diff:
- "bg-linear-to-t from-neutral-800 to-neutral-700 text-white rounded-full", + "bg-gradient-to-t from-neutral-800 to-neutral-700 text-white rounded-full",apps/web/src/routes/_view/index.tsx (3)
116-116: Fix invalid Tailwind gradient class.
bg-linear-to-bis not a valid Tailwind class. Usebg-gradient-to-binstead.Apply this diff:
- <main className="flex-1 bg-linear-to-b from-white via-stone-50/20 to-white min-h-screen"> + <main className="flex-1 bg-gradient-to-b from-white via-stone-50/20 to-white min-h-screen">
180-180: Fix invalid Tailwind gradient class.
bg-linear-to-bis not a valid Tailwind class. Usebg-gradient-to-binstead.Apply this diff:
- <div className="bg-linear-to-b from-stone-50/30 to-stone-100/30"> + <div className="bg-gradient-to-b from-stone-50/30 to-stone-100/30">
943-943: Fix invalid Tailwind gradient class.
bg-linear-to-tis not a valid Tailwind class. Usebg-gradient-to-tinstead.Apply this diff:
- <section className="py-16 border-t border-neutral-100 bg-linear-to-t from-stone-50/30 to-stone-100/30 px-4 laptop:px-0"> + <section className="py-16 border-t border-neutral-100 bg-gradient-to-t from-stone-50/30 to-stone-100/30 px-4 laptop:px-0">
🧹 Nitpick comments (1)
apps/web/src/components/social-card.tsx (1)
77-77: Nice responsive design improvement!The mobile-first line-clamping (4 lines on small screens, 15 on medium+) improves readability on smaller devices.
Optional: The
overflow-hiddenclass is redundant since Tailwind'sline-clamp-*utilities already applyoverflow: hidden. You can safely remove it:- <p className="text-neutral-700 leading-relaxed line-clamp-4 md:line-clamp-15 overflow-hidden">{body}</p> + <p className="text-neutral-700 leading-relaxed line-clamp-4 md:line-clamp-15">{body}</p>
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
apps/web/src/routeTree.gen.tsis excluded by!**/*.gen.ts
📒 Files selected for processing (15)
apps/web/src/components/download-button.tsx(1 hunks)apps/web/src/components/github-open-source.tsx(1 hunks)apps/web/src/components/github-stars.tsx(1 hunks)apps/web/src/components/not-found.tsx(1 hunks)apps/web/src/components/social-card.tsx(1 hunks)apps/web/src/components/testimonial-card.tsx(0 hunks)apps/web/src/components/video-modal.tsx(1 hunks)apps/web/src/components/video-player.tsx(1 hunks)apps/web/src/components/video-thumbnail.tsx(1 hunks)apps/web/src/routes/_view/app/account.tsx(2 hunks)apps/web/src/routes/_view/download.tsx(1 hunks)apps/web/src/routes/_view/downloads.tsx(0 hunks)apps/web/src/routes/_view/index.tsx(5 hunks)apps/web/src/routes/_view/pricing.tsx(1 hunks)apps/web/src/routes/cal.tsx(1 hunks)
💤 Files with no reviewable changes (2)
- apps/web/src/components/testimonial-card.tsx
- apps/web/src/routes/_view/downloads.tsx
✅ Files skipped from review due to trivial changes (1)
- apps/web/src/components/github-stars.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
- apps/web/src/routes/cal.tsx
- apps/web/src/routes/_view/app/account.tsx
- apps/web/src/components/video-player.tsx
- apps/web/src/components/video-thumbnail.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
After a substantial amount of TypeScript changes, run
pnpm -r typecheck
Files:
apps/web/src/routes/_view/download.tsxapps/web/src/routes/_view/pricing.tsxapps/web/src/components/github-open-source.tsxapps/web/src/components/not-found.tsxapps/web/src/components/download-button.tsxapps/web/src/routes/_view/index.tsxapps/web/src/components/social-card.tsxapps/web/src/components/video-modal.tsx
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/simple.mdc)
**/*.{tsx,jsx}: When many classNames have conditional logic in React components, usecnfrom@hypr/utils
When usingcn, always pass an array of class segments
When usingcn, split entries by logical grouping for readability
Usemotion/reactinstead offramer-motion
Files:
apps/web/src/routes/_view/download.tsxapps/web/src/routes/_view/pricing.tsxapps/web/src/components/github-open-source.tsxapps/web/src/components/not-found.tsxapps/web/src/components/download-button.tsxapps/web/src/routes/_view/index.tsxapps/web/src/components/social-card.tsxapps/web/src/components/video-modal.tsx
🧠 Learnings (3)
📚 Learning: 2025-10-26T00:28:22.016Z
Learnt from: CR
PR: fastrepl/hyprnote#0
File: .cursor/rules/simple.mdc:0-0
Timestamp: 2025-10-26T00:28:22.016Z
Learning: Applies to **/*.{tsx,jsx} : When using `cn`, always pass an array of class segments
Applied to files:
apps/web/src/routes/_view/index.tsx
📚 Learning: 2025-10-26T00:28:22.016Z
Learnt from: CR
PR: fastrepl/hyprnote#0
File: .cursor/rules/simple.mdc:0-0
Timestamp: 2025-10-26T00:28:22.016Z
Learning: Applies to **/*.{tsx,jsx} : When many classNames have conditional logic in React components, use `cn` from `hypr/utils`
Applied to files:
apps/web/src/routes/_view/index.tsx
📚 Learning: 2025-10-26T00:28:22.016Z
Learnt from: CR
PR: fastrepl/hyprnote#0
File: .cursor/rules/simple.mdc:0-0
Timestamp: 2025-10-26T00:28:22.016Z
Learning: Applies to **/*.{tsx,jsx} : When using `cn`, split entries by logical grouping for readability
Applied to files:
apps/web/src/routes/_view/index.tsx
🧬 Code graph analysis (5)
apps/web/src/routes/_view/download.tsx (2)
apps/web/src/routes/_view/index.tsx (1)
Route(86-88)packages/utils/src/cn.ts (1)
cn(20-22)
apps/web/src/routes/_view/pricing.tsx (3)
apps/web/src/routes/_view/index.tsx (1)
Route(86-88)apps/web/src/routes/_view/route.tsx (1)
Route(3-6)packages/utils/src/cn.ts (1)
cn(20-22)
apps/web/src/components/github-open-source.tsx (1)
packages/utils/src/cn.ts (1)
cn(20-22)
apps/web/src/routes/_view/index.tsx (10)
apps/web/src/components/github-open-source.tsx (1)
GitHubOpenSource(138-281)apps/web/src/components/video-modal.tsx (1)
VideoModal(13-89)packages/utils/src/cn.ts (1)
cn(20-22)apps/web/src/components/join-waitlist-button.tsx (1)
JoinWaitlistButton(3-33)apps/web/src/components/video-thumbnail.tsx (1)
VideoThumbnail(12-49)apps/web/src/components/logo-cloud.tsx (1)
LogoCloud(35-123)apps/web/src/components/social-card.tsx (1)
SocialCard(17-81)apps/web/src/components/video-player.tsx (1)
VideoPlayer(14-104)apps/web/src/components/download-button.tsx (1)
DownloadButton(5-33)apps/web/src/components/github-stars.tsx (1)
GithubStars(6-36)
apps/web/src/components/video-modal.tsx (1)
packages/utils/src/cn.ts (1)
cn(20-22)
🪛 Biome (2.1.2)
apps/web/src/routes/_view/index.tsx
[error] 200-200: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the rel="noopener" attribute.
(lint/security/noBlankTarget)
🪛 GitHub Actions: .github/workflows/fmt.yaml
apps/web/src/routes/_view/pricing.tsx
[error] 165-191: dprint formatting check failed. Found 1 not formatted file. Command: '/.dprint/bin/dprint check --config dprint.json'. To fix, run '/.dprint/bin/dprint fmt --config dprint.json' to format.
🔇 Additional comments (13)
apps/web/src/components/not-found.tsx (1)
75-75: LGTM! Route update is consistent with the refactoring.The change from
/downloadsto/downloadaligns with the removal of the old downloads route and the introduction of the new download page.apps/web/src/components/download-button.tsx (1)
2-8: LGTM! Route update is consistent.The change to
/downloadaligns with the broader route reorganization in this PR.apps/web/src/routes/_view/download.tsx (1)
13-26: LGTM! Informative banner for users.The information banner clearly communicates platform-specific features and limitations.
apps/web/src/components/github-open-source.tsx (2)
7-60: LGTM! Well-structured contributor data.The curated profiles list is comprehensive and properly formatted for the open-source showcase.
138-281: LGTM! Well-structured responsive layout.The component properly handles mobile and desktop layouts with appropriate breakpoints and maintains visual consistency across viewports.
apps/web/src/routes/_view/pricing.tsx (1)
10-82: LGTM! Well-structured pricing data.The pricing plans and features are clearly defined with appropriate metadata (coming soon flags, tooltips, etc.).
apps/web/src/components/video-modal.tsx (1)
51-88: LGTM! Well-structured modal with accessibility.The modal includes proper accessibility attributes, event handling, and responsive layout.
apps/web/src/routes/_view/index.tsx (6)
1-84: LGTM! Well-organized imports and feature data.The new imports and data structures for features are comprehensive and properly typed.
97-113: LGTM! Well-implemented scroll helpers.The scroll functions properly handle smooth scrolling to feature and detail sections.
482-563: LGTM! Well-implemented mobile carousel.The features carousel includes proper scroll tracking, snap points, and navigation indicators.
709-780: LGTM! Well-implemented details carousel.The details carousel mirrors the features carousel with consistent behavior and UI patterns.
565-663: LGTM! Well-structured desktop feature grid.The desktop grid layout properly showcases features with appropriate spacing and video integration.
879-939: LGTM! Well-crafted manifesto section.The manifesto presentation effectively communicates the company's values with appropriate styling and layout.
|
|
||
| function Component() { | ||
| return ( | ||
| <div className="bg-linear-to-b from-white via-blue-50/20 to-white min-h-screen"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix invalid Tailwind gradient class.
bg-linear-to-b is not a valid Tailwind class. Use bg-gradient-to-b instead.
Apply this diff:
- <div className="bg-linear-to-b from-white via-blue-50/20 to-white min-h-screen">
+ <div className="bg-gradient-to-b from-white via-blue-50/20 to-white min-h-screen">📝 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.
| <div className="bg-linear-to-b from-white via-blue-50/20 to-white min-h-screen"> | |
| <div className="bg-gradient-to-b from-white via-blue-50/20 to-white min-h-screen"> |
🤖 Prompt for AI Agents
In apps/web/src/routes/_view/download.tsx around line 12, the Tailwind class
"bg-linear-to-b" is invalid; replace it with the correct "bg-gradient-to-b" in
the div's className so the gradient renders properly (update the className
string to swap "bg-linear-to-b" -> "bg-gradient-to-b").
| <DownloadCard | ||
| iconName="simple-icons:apple" | ||
| spec="macOS 14.2+ (Apple Silicon)" | ||
| downloadUrl="#" | ||
| available={true} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Replace placeholder download URL with actual link.
The macOS (Apple Silicon) card is marked as available but uses a placeholder URL (#). Ensure this is updated with the actual download link before release.
🏁 Script executed:
#!/bin/bash
# Examine the download.tsx file to verify downloadUrl placeholder usage
cat apps/web/src/routes/_view/download.tsxLength of output: 4331
🏁 Script executed:
#!/bin/bash
# Search for downloadUrl patterns and any constants/environment vars that might populate URLs
rg -nP 'downloadUrl|DOWNLOAD|download.*url' apps/web/src/routes/_view/download.tsx -A 2 -B 2Length of output: 1630
🏁 Script executed:
#!/bin/bash
# Check for any constants files or config that might contain download URLs
fd -e ts -e tsx -e js -e json 'download|url|config' apps/web/src/ --type f | head -20Length of output: 82
🏁 Script executed:
#!/bin/bash
# Check download-button.tsx for any URL patterns or constants
cat apps/web/src/components/download-button.tsxLength of output: 926
Replace placeholder download URL with actual macOS download link.
The macOS Apple Silicon card (line 47) is the only available platform but has a non-functional placeholder URL (downloadUrl="#"). This must be updated with the actual download link before release.
🤖 Prompt for AI Agents
In apps/web/src/routes/_view/download.tsx around lines 44 to 48, the macOS Apple
Silicon DownloadCard uses a placeholder URL (downloadUrl="#"); replace that
placeholder with the actual macOS Apple Silicon download link (the signed
.dmg/.pkg or the public CDN/path) so the card is clickable and functional —
update the prop to the real URL, keep available={true}, and ensure the URL is an
absolute HTTPS link (or internal route) before merging.
| ? ( | ||
| <a | ||
| href={downloadUrl} | ||
| className="group w-full px-4 h-11 flex items-center justify-center bg-linear-to-t from-stone-600 to-stone-500 text-white rounded-full shadow-md hover:shadow-lg hover:scale-[102%] active:scale-[98%] transition-all text-base font-medium" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix invalid Tailwind gradient class.
bg-linear-to-t is not a valid Tailwind class. Use bg-gradient-to-t instead.
Apply this diff:
- className="group w-full px-4 h-11 flex items-center justify-center bg-linear-to-t from-stone-600 to-stone-500 text-white rounded-full shadow-md hover:shadow-lg hover:scale-[102%] active:scale-[98%] transition-all text-base font-medium"
+ className="group w-full px-4 h-11 flex items-center justify-center bg-gradient-to-t from-stone-600 to-stone-500 text-white rounded-full shadow-md hover:shadow-lg hover:scale-[102%] active:scale-[98%] transition-all text-base font-medium"📝 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.
| className="group w-full px-4 h-11 flex items-center justify-center bg-linear-to-t from-stone-600 to-stone-500 text-white rounded-full shadow-md hover:shadow-lg hover:scale-[102%] active:scale-[98%] transition-all text-base font-medium" | |
| className="group w-full px-4 h-11 flex items-center justify-center bg-gradient-to-t from-stone-600 to-stone-500 text-white rounded-full shadow-md hover:shadow-lg hover:scale-[102%] active:scale-[98%] transition-all text-base font-medium" |
🤖 Prompt for AI Agents
In apps/web/src/routes/_view/download.tsx around line 116, the Tailwind class
`bg-linear-to-t` is invalid; replace it with the correct `bg-gradient-to-t` in
the className string so the gradient utility is applied correctly (update the
className value to use `bg-gradient-to-t` while leaving the rest of the classes
unchanged).
| <a | ||
| className="decoration-dotted underline hover:text-stone-600 transition-all" | ||
| href="https://github.com/fastrepl/hyprnote" | ||
| target="_blank" | ||
| > | ||
| open source | ||
| </a> | ||
| </p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add missing rel attribute for security.
The external link uses target="_blank" without rel="noopener noreferrer", which is a security risk (tab-nabbing).
Apply this diff:
<a
className="decoration-dotted underline hover:text-stone-600 transition-all"
href="https://github.com/fastrepl/hyprnote"
target="_blank"
+ rel="noopener noreferrer"
>📝 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.
| <a | |
| className="decoration-dotted underline hover:text-stone-600 transition-all" | |
| href="https://github.com/fastrepl/hyprnote" | |
| target="_blank" | |
| > | |
| open source | |
| </a> | |
| </p> | |
| <a | |
| className="decoration-dotted underline hover:text-stone-600 transition-all" | |
| href="https://github.com/fastrepl/hyprnote" | |
| target="_blank" | |
| rel="noopener noreferrer" | |
| > | |
| open source | |
| </a> | |
| </p> |
🧰 Tools
🪛 Biome (2.1.2)
[error] 200-200: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the rel="noopener" attribute.
(lint/security/noBlankTarget)
🤖 Prompt for AI Agents
In apps/web/src/routes/_view/index.tsx around lines 197 to 204, the anchor tag
opens an external link with target="_blank" but lacks rel="noopener noreferrer";
add rel="noopener noreferrer" to the <a> element to prevent tab-nabbing and
ensure the link is opened securely in a new tab.
| function Component() { | ||
| return <div>Hello "/_view/_layout/pricing"!</div>; | ||
| return ( | ||
| <main className="flex-1 bg-linear-to-b from-white via-stone-50/20 to-white min-h-screen"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix invalid Tailwind gradient class.
bg-linear-to-b is not a valid Tailwind class. Use bg-gradient-to-b instead.
Apply this diff:
- <main className="flex-1 bg-linear-to-b from-white via-stone-50/20 to-white min-h-screen">
+ <main className="flex-1 bg-gradient-to-b from-white via-stone-50/20 to-white min-h-screen">📝 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.
| <main className="flex-1 bg-linear-to-b from-white via-stone-50/20 to-white min-h-screen"> | |
| <main className="flex-1 bg-gradient-to-b from-white via-stone-50/20 to-white min-h-screen"> |
🤖 Prompt for AI Agents
In apps/web/src/routes/_view/pricing.tsx around line 86, the Tailwind class
"bg-linear-to-b" is invalid; replace it with the correct "bg-gradient-to-b" to
enable the intended top-to-bottom gradient; update the className value to use
"bg-gradient-to-b" (keeping the other utility classes unchanged).
| ? "bg-linear-to-t from-stone-600 to-stone-500 text-white rounded-full shadow-md hover:shadow-lg hover:scale-[102%] active:scale-[98%]" | ||
| : "bg-linear-to-t from-neutral-200 to-neutral-100 text-neutral-900 rounded-full shadow-sm hover:shadow-md hover:scale-[102%] active:scale-[98%]", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix invalid Tailwind gradient classes.
bg-linear-to-t is not a valid Tailwind class. Use bg-gradient-to-t instead.
Apply this diff:
plan.popular
- ? "bg-linear-to-t from-stone-600 to-stone-500 text-white rounded-full shadow-md hover:shadow-lg hover:scale-[102%] active:scale-[98%]"
- : "bg-linear-to-t from-neutral-200 to-neutral-100 text-neutral-900 rounded-full shadow-sm hover:shadow-md hover:scale-[102%] active:scale-[98%]",
+ ? "bg-gradient-to-t from-stone-600 to-stone-500 text-white rounded-full shadow-md hover:shadow-lg hover:scale-[102%] active:scale-[98%]"
+ : "bg-gradient-to-t from-neutral-200 to-neutral-100 text-neutral-900 rounded-full shadow-sm hover:shadow-md hover:scale-[102%] active:scale-[98%]",📝 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.
| ? "bg-linear-to-t from-stone-600 to-stone-500 text-white rounded-full shadow-md hover:shadow-lg hover:scale-[102%] active:scale-[98%]" | |
| : "bg-linear-to-t from-neutral-200 to-neutral-100 text-neutral-900 rounded-full shadow-sm hover:shadow-md hover:scale-[102%] active:scale-[98%]", | |
| ? "bg-gradient-to-t from-stone-600 to-stone-500 text-white rounded-full shadow-md hover:shadow-lg hover:scale-[102%] active:scale-[98%]" | |
| : "bg-gradient-to-t from-neutral-200 to-neutral-100 text-neutral-900 rounded-full shadow-sm hover:shadow-md hover:scale-[102%] active:scale-[98%]", |
🤖 Prompt for AI Agents
In apps/web/src/routes/_view/pricing.tsx around lines 213 to 214, the Tailwind
class name "bg-linear-to-t" is invalid; replace both occurrences with the
correct "bg-gradient-to-t" so the gradient utilities apply properly while
keeping the rest of the class strings unchanged.
|
|
||
| function CTASection() { | ||
| return ( | ||
| <section className="py-16 border-t border-neutral-100 bg-linear-to-t from-stone-50/30 to-stone-100/30 px-4 laptop:px-0"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix invalid Tailwind gradient class.
bg-linear-to-t is not a valid Tailwind class. Use bg-gradient-to-t instead.
Apply this diff:
- <section className="py-16 border-t border-neutral-100 bg-linear-to-t from-stone-50/30 to-stone-100/30 px-4 laptop:px-0">
+ <section className="py-16 border-t border-neutral-100 bg-gradient-to-t from-stone-50/30 to-stone-100/30 px-4 laptop:px-0">📝 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.
| <section className="py-16 border-t border-neutral-100 bg-linear-to-t from-stone-50/30 to-stone-100/30 px-4 laptop:px-0"> | |
| <section className="py-16 border-t border-neutral-100 bg-gradient-to-t from-stone-50/30 to-stone-100/30 px-4 laptop:px-0"> |
🤖 Prompt for AI Agents
In apps/web/src/routes/_view/pricing.tsx around line 296, the section element
uses an invalid Tailwind class `bg-linear-to-t`; replace it with the correct
`bg-gradient-to-t` class so the background gradient renders properly (i.e.,
update the className value to use `bg-gradient-to-t` instead of
`bg-linear-to-t`).
| className="px-8 h-10 flex items-center justify-center text-sm bg-linear-to-t from-stone-600 to-stone-500 text-white rounded-full shadow-md hover:shadow-lg hover:scale-[102%] active:scale-[98%] transition-all" | ||
| > | ||
| Download for Free | ||
| </a> | ||
| <a | ||
| href="https://github.com/fastrepl/hyprnote" | ||
| target="_blank" | ||
| rel="noopener noreferrer" | ||
| className="px-8 h-10 flex items-center justify-center text-sm bg-linear-to-t from-neutral-200 to-neutral-100 text-neutral-900 rounded-full shadow-sm hover:shadow-md hover:scale-[102%] active:scale-[98%] transition-all" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix invalid Tailwind gradient classes in CTA buttons.
bg-linear-to-t is not a valid Tailwind class. Use bg-gradient-to-t instead.
Apply this diff:
target="_blank"
rel="noopener noreferrer"
- className="px-8 h-10 flex items-center justify-center text-sm bg-linear-to-t from-stone-600 to-stone-500 text-white rounded-full shadow-md hover:shadow-lg hover:scale-[102%] active:scale-[98%] transition-all"
+ className="px-8 h-10 flex items-center justify-center text-sm bg-gradient-to-t from-stone-600 to-stone-500 text-white rounded-full shadow-md hover:shadow-lg hover:scale-[102%] active:scale-[98%] transition-all"
>
Download for Free
</a>
<a
href="https://github.com/fastrepl/hyprnote"
target="_blank"
rel="noopener noreferrer"
- className="px-8 h-10 flex items-center justify-center text-sm bg-linear-to-t from-neutral-200 to-neutral-100 text-neutral-900 rounded-full shadow-sm hover:shadow-md hover:scale-[102%] active:scale-[98%] transition-all"
+ className="px-8 h-10 flex items-center justify-center text-sm bg-gradient-to-t from-neutral-200 to-neutral-100 text-neutral-900 rounded-full shadow-sm hover:shadow-md hover:scale-[102%] active:scale-[98%] transition-all"
>📝 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.
| className="px-8 h-10 flex items-center justify-center text-sm bg-linear-to-t from-stone-600 to-stone-500 text-white rounded-full shadow-md hover:shadow-lg hover:scale-[102%] active:scale-[98%] transition-all" | |
| > | |
| Download for Free | |
| </a> | |
| <a | |
| href="https://github.com/fastrepl/hyprnote" | |
| target="_blank" | |
| rel="noopener noreferrer" | |
| className="px-8 h-10 flex items-center justify-center text-sm bg-linear-to-t from-neutral-200 to-neutral-100 text-neutral-900 rounded-full shadow-sm hover:shadow-md hover:scale-[102%] active:scale-[98%] transition-all" | |
| className="px-8 h-10 flex items-center justify-center text-sm bg-gradient-to-t from-stone-600 to-stone-500 text-white rounded-full shadow-md hover:shadow-lg hover:scale-[102%] active:scale-[98%] transition-all" | |
| > | |
| Download for Free | |
| </a> | |
| <a | |
| href="https://github.com/fastrepl/hyprnote" | |
| target="_blank" | |
| rel="noopener noreferrer" | |
| className="px-8 h-10 flex items-center justify-center text-sm bg-gradient-to-t from-neutral-200 to-neutral-100 text-neutral-900 rounded-full shadow-sm hover:shadow-md hover:scale-[102%] active:scale-[98%] transition-all" |
🤖 Prompt for AI Agents
In apps/web/src/routes/_view/pricing.tsx around lines 316 to 324, the CTA
anchors use an invalid Tailwind class "bg-linear-to-t"; replace that with the
correct Tailwind gradient class "bg-gradient-to-t" for both buttons so the
gradient utilities apply properly, keeping the rest of the className strings
unchanged.
No description provided.