Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions components.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,8 @@
"ui": "~/ui",
"lib": "~/lib",
"hooks": "~/hooks"
},
"registries": {
"@react-bits": "https://reactbits.dev/r/{name}.json"
}
}
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,15 @@
"homepage": "https://github.com/bprosen/Website#readme",
"dependencies": {
"@radix-ui/react-slot": "^1.2.4",
"@tabler/icons-react": "^3.36.1",
"@tailwindcss/postcss": "^4.1.18",
"@vercel/analytics": "^1.6.1",
"@vercel/speed-insights": "^1.3.1",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"culori": "^4.0.2",
"framer-motion": "^12.29.0",
"gsap": "^3.13.0",
"lucide-react": "^0.544.0",
"next": "15.5.9",
"postcss": "^8.5.6",
Expand Down
64 changes: 64 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { FullPageBlurScroll, UnderConstruction } from '~/components';
import { Home } from '~/routes';

const Page: React.FC = () => <Home />;
const Page: React.FC = () => (
<FullPageBlurScroll blur>
<Home />
<UnderConstruction />
</FullPageBlurScroll>
);

export default Page;
72 changes: 72 additions & 0 deletions src/components/FullPageScroll/FullPageScroll.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
'use client';

import { motion, useInView } from 'framer-motion';
import { Children, type ReactNode, type RefObject, useRef } from 'react';
import { cn } from '~/lib/ui';

type BlurPageProps = {
children: ReactNode;
scrollRef: RefObject<HTMLDivElement | null>;
blur?: boolean;
};

const BlurPage = ({ children, scrollRef, blur }: BlurPageProps) => {
const pageRef = useRef<HTMLDivElement>(null);
const isInView = useInView(pageRef, {
amount: 0.5,
root: scrollRef,
});

return (
<motion.div
animate={{
filter: blur && !isInView ? 'blur(10px)' : 'blur(0px)',
}}
className='min-h-screen w-full snap-start snap-always'
initial={false}
ref={pageRef}
transition={{
duration: 0.5,
ease: [0.25, 0.46, 0.45, 0.94],
type: 'tween',
}}
>
{children}
</motion.div>
);
};

type FullPageBlurScrollProps = {
children: ReactNode;
className?: string;
blur?: boolean;
};

export const FullPageBlurScroll = ({
children,
className,
blur,
}: FullPageBlurScrollProps) => {
const scrollRef = useRef<HTMLDivElement>(null);
const pages = Children.toArray(children);

return (
<div
className={cn(
'h-screen min-h-screen overflow-y-auto overflow-x-hidden snap-y snap-mandatory',
className,
)}
ref={scrollRef}
>
{pages.map((page, index) => (
<BlurPage
blur={blur}
key={`scroll-page-${index + 1}`}
scrollRef={scrollRef}
>
{page}
</BlurPage>
))}
</div>
);
};
24 changes: 24 additions & 0 deletions src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {
IconBrandGithub,
IconBrandLinkedin,
IconMail,
} from '@tabler/icons-react';
import { EMAIL, GITHUB, LINKED_IN } from '~/constants';

export const Header = () => {
return (
<div className='flex justify-between w-full px-6 py-4'>
<div className='flex gap-4'>
<a href={GITHUB} target='_blank'>
<IconBrandGithub color='#FFFFFF' size={40} stroke={1.2} />
</a>
<a href={LINKED_IN} target='_blank'>
<IconBrandLinkedin color='#FFFFFF' size={40} stroke={1.2} />
</a>
<a href={EMAIL} target='_blank'>
<IconMail color='#FFFFFF' size={40} stroke={1.2} />
</a>
Comment on lines +12 to +20

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add accessible labels and rel="noopener noreferrer" to external links.

The icon-only links lack accessible names, making them unannounced to screen reader users. Additionally, target="_blank" links should include rel="noopener noreferrer" as a security best practice.

Proposed fix
-        <a href={GITHUB} target='_blank'>
+        <a href={GITHUB} target='_blank' rel='noopener noreferrer' aria-label='GitHub'>
           <IconBrandGithub color='#FFFFFF' size={40} stroke={1.2} />
         </a>
-        <a href={LINKED_IN} target='_blank'>
+        <a href={LINKED_IN} target='_blank' rel='noopener noreferrer' aria-label='LinkedIn'>
           <IconBrandLinkedin color='#FFFFFF' size={40} stroke={1.2} />
         </a>
-        <a href={EMAIL} target='_blank'>
+        <a href={EMAIL} rel='noopener noreferrer' aria-label='Email'>
           <IconMail color='#FFFFFF' size={40} stroke={1.2} />
         </a>

Note: The mailto: link doesn't need target="_blank" since it opens the email client rather than a new browser tab.

📝 Committable suggestion

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

Suggested change
<a href={GITHUB} target='_blank'>
<IconBrandGithub color='#FFFFFF' size={40} stroke={1.2} />
</a>
<a href={LINKED_IN} target='_blank'>
<IconBrandLinkedin color='#FFFFFF' size={40} stroke={1.2} />
</a>
<a href={EMAIL} target='_blank'>
<IconMail color='#FFFFFF' size={40} stroke={1.2} />
</a>
<a href={GITHUB} target='_blank' rel='noopener noreferrer' aria-label='GitHub'>
<IconBrandGithub color='#FFFFFF' size={40} stroke={1.2} />
</a>
<a href={LINKED_IN} target='_blank' rel='noopener noreferrer' aria-label='LinkedIn'>
<IconBrandLinkedin color='#FFFFFF' size={40} stroke={1.2} />
</a>
<a href={EMAIL} rel='noopener noreferrer' aria-label='Email'>
<IconMail color='#FFFFFF' size={40} stroke={1.2} />
</a>
🤖 Prompt for AI Agents
In `@src/components/Header/Header.tsx` around lines 14 - 22, Add accessible names
and security attributes to the external icon links: for the GITHUB and LINKED_IN
anchor elements (wrapping IconBrandGithub and IconBrandLinkedin) add descriptive
aria-label attributes (e.g., "GitHub profile", "LinkedIn profile") and include
rel="noopener noreferrer" alongside target="_blank"; for the EMAIL anchor
(wrapping IconMail with href using EMAIL/mailto:) remove target="_blank" (or
avoid adding it) and add an aria-label like "Email" so screen readers announce
it. Ensure the attributes are applied on the anchor elements that reference the
GITHUB, LINKED_IN, and EMAIL constants.

</div>
</div>
);
};
22 changes: 22 additions & 0 deletions src/components/Intro/Intro.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Card, TextType } from '~/ui';

export const Intro = () => {
return (
<Card className='min-w-xl shadow-xl md:max-w-xl my-4 mx-12 sm:mx-2 md:mx-auto'>
<div className='p-12 flex flex-col text-black text-2xl'>
<p>Hey I'm Ben! It's great to meet you!</p>
<div className='flex flex-row'>
<p>I'm a passionate&nbsp;</p>
<TextType
className='underline underline-offset-4 decoration-2 text-bold'
deletingSpeed={30}
text={['Frontend', 'Backend', 'React', 'Java']}
textColors={['#4720ff', '#4249fD', '#94249F', '#jfgwF89']}
typingSpeed={60}
Comment on lines +10 to +15

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Check if file exists and read the relevant section
if [ -f "src/components/Intro/Intro.tsx" ]; then
  echo "=== File exists, reading lines 10-15 ==="
  sed -n '10,15p' "src/components/Intro/Intro.tsx" | cat -n
else
  echo "File not found, searching for Intro.tsx"
  find . -name "Intro.tsx" -type f
fi

Repository: bprosen/Website

Length of output: 428


🏁 Script executed:

# Validate the hex color format
python3 << 'EOF'
import re

color = '#jfgwF89'
# Valid hex colors: # followed by 3, 4, 6, or 8 hex digits (0-9, a-f, A-F)
hex_pattern = r'^#([0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$'

if re.match(hex_pattern, color):
    print(f"✓ {color} is a VALID hex color")
else:
    print(f"✗ {color} is an INVALID hex color")
    print(f"  Issues: Contains non-hex characters ('j' and 'w' are not valid hex digits)")
EOF

Repository: bprosen/Website

Length of output: 170


🏁 Script executed:

# Look for Tailwind config files
find . -name "tailwind.config.*" -type f

Repository: bprosen/Website

Length of output: 41


🏁 Script executed:

# Search for any definition of text-bold in the codebase
rg "text-bold" --type ts --type tsx --type js --type jsx

Repository: bprosen/Website

Length of output: 86


🏁 Script executed:

# Check if there's a custom CSS or Tailwind setup that might define text-bold
find . -name "*.css" -o -name "globals.css" | head -10

Repository: bprosen/Website

Length of output: 80


🏁 Script executed:

# Search for text-bold across all files
rg "text-bold"

Repository: bprosen/Website

Length of output: 165


🏁 Script executed:

# Read globals.css to check for custom Tailwind config
cat -n "./src/app/globals.css"

Repository: bprosen/Website

Length of output: 5366


🏁 Script executed:

# Also check if there's a tailwind config in root
ls -la | grep -i tailwind

Repository: bprosen/Website

Length of output: 41


🌐 Web query:

Tailwind CSS text-bold font-bold utility class

💡 Result:

Tailwind CSS doesn’t have a text-bold utility. To make text bold, use font-bold, which sets font-weight: 700. (v3.tailwindcss.com)

<p class="font-bold">Bold text</p>

Related weights include font-semibold, font-extrabold, etc. (v3.tailwindcss.com)

Citations:


Replace invalid Tailwind class and remove invalid color value.
text-bold is not a Tailwind utility; use font-bold instead. The hex color #jfgwF89 is invalid (contains non-hex characters 'j' and 'w').

Suggested fix
-          <TextType
-            className='underline underline-offset-4 decoration-2 text-bold'
+          <TextType
+            className='underline underline-offset-4 decoration-2 font-bold'
             deletingSpeed={30}
             text={['Frontend', 'Backend', 'React', 'Java']}
-            textColors={['#4720ff', '#4249fD', '#94249F', '#jfgwF89']}
+            textColors={['#4720ff', '#4249fD', '#94249F']}
             typingSpeed={60}
           />
📝 Committable suggestion

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

Suggested change
<TextType
className='underline underline-offset-4 decoration-2 text-bold'
deletingSpeed={30}
text={['Frontend', 'Backend', 'React', 'Java']}
textColors={['#4720ff', '#4249fD', '#94249F', '#jfgwF89']}
typingSpeed={60}
<TextType
className='underline underline-offset-4 decoration-2 font-bold'
deletingSpeed={30}
text={['Frontend', 'Backend', 'React', 'Java']}
textColors={['#4720ff', '#4249fD', '#94249F']}
typingSpeed={60}
/>
🤖 Prompt for AI Agents
In `@src/components/Intro/Intro.tsx` around lines 10 - 15, In Intro.tsx update the
TextType usage: fix the className prop by replacing the invalid Tailwind utility
"text-bold" with "font-bold" and correct the textColors prop by removing or
replacing the invalid hex "#jfgwF89" (contains non-hex chars) with a valid color
(e.g., a proper 6- or 3-digit hex like "#ff8800" or a named color). Ensure these
changes are applied on the TextType component invocation so className and
textColors are valid.

/>
<div> Software Developer</div>
</div>
</div>
</Card>
);
};
9 changes: 9 additions & 0 deletions src/components/ScrollDownIndicator/ScrollDownIndicator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { IconChevronDown } from '@tabler/icons-react';

export const ScrollDownIndicator = () => {
return (
<div className='flex justify-center pb-4'>
<IconChevronDown color='#ffffff' size={50} />
</div>
);
};
36 changes: 19 additions & 17 deletions src/components/UnderConstruction/UnderConstruction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,24 @@ import { Card, CardContent, CardHeader, CardTitle } from '~/ui';

export const UnderConstruction: React.FC = () => {
return (
<Card className='shadow-xl md:max-w-xl my-4 mx-12 sm:mx-2 md:mx-auto'>
<CardHeader>
<CardTitle className='text-center text-2xl sm:text-3xl'>
Hold on a second!
</CardTitle>
</CardHeader>
<CardContent className='flex flex-col items-center gap-4'>
<Construction
className='w-[200px] h-[200px] sm:w-[250px] sm:h-[250px] md:w-[350px] md:h-[350px]'
color='#e4ec75'
strokeWidth={1.2}
/>
<p className='text-base text-center'>
This page is under construction, check back soon
</p>
</CardContent>
</Card>
<div className='min-h-screen flex items-center justify-center p-4'>
<Card className='shadow-xl md:max-w-xl w-full'>
<CardHeader>
<CardTitle className='text-center text-2xl sm:text-3xl'>
Hold on a second!
</CardTitle>
</CardHeader>
<CardContent className='flex flex-col items-center gap-4'>
<Construction
className='w-[200px] h-[200px] sm:w-[250px] sm:h-[250px] md:w-[350px] md:h-[350px]'
color='#e4ec75'
strokeWidth={1.2}
/>
<p className='text-base text-center'>
This page is under construction, check back soon
</p>
</CardContent>
</Card>
</div>
);
};
5 changes: 5 additions & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
export * from './FullPageScroll/FullPageScroll';
export * from './FullPageScroll/FullPageScroll';
export * from './Header/Header';
export * from './Intro/Intro';
export * from './ScrollDownIndicator/ScrollDownIndicator';
export * from './UnderConstruction/UnderConstruction';
1 change: 1 addition & 0 deletions src/constants/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './urls';
3 changes: 3 additions & 0 deletions src/constants/urls.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const GITHUB = 'https://github.com/bprosen';
export const LINKED_IN = 'https://www.linkedin.com/in/ben-edgar-prosen/';
export const EMAIL = 'mailto:benedgarprosen@gmail.com';
25 changes: 8 additions & 17 deletions src/routes/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
import { UnderConstruction } from '~/components';
import { VantaNet } from '~/ui';
import { isMobile } from '~/utils/utils';

export const Home = async () => {
const mobile = await isMobile();
import { Intro, ScrollDownIndicator } from '~/components';

export const Home = () => {
return (
<VantaNet
backgroundColor='var(--primary)'
className='flex flex-col items-center justify-center h-screen'
gyroControls={mobile}
maxDistance={mobile ? 20.0 : 18}
mouseControls={!mobile}
spacing={mobile ? 18.0 : 15.0}
touchControls={mobile}
>
<UnderConstruction />
</VantaNet>
<div className='min-h-screen flex flex-col'>
<div className='flex-1 flex items-center justify-center'>
<Intro />
</div>
<ScrollDownIndicator />
</div>
);
};
Loading
Loading