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
98 changes: 80 additions & 18 deletions src/components/HowItWorks.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,107 @@
import { useContext } from 'react';
import { ArrowDown, ArrowRight, BarChart3, Activity, Search } from 'lucide-react';
import { ThemeContext } from '../context/ThemeContext';
import type { ThemeContextType } from '../context/ThemeContext';

const HowItWorks = () => {
const themeContext = useContext(ThemeContext) as ThemeContextType | null;
const mode = themeContext?.mode ?? 'light';

const steps = [
{
number: 1,
title: 'Search Users',
description: 'Enter GitHub usernames or search for users by name. Add them to your tracking dashboard.'
description: 'Enter GitHub usernames or search for users by name. Add them to your tracking dashboard.',
icon: Search,
},
{
number: 2,
title: 'Monitor Activity',
description: 'Watch insights of commits, pull requests, issues, and other GitHub activities.'
description: 'Watch insights of commits, pull requests, issues, and other GitHub activities.',
icon: Activity,
},
{
number: 3,
title: 'Analyze Insights',
description: 'Review detailed analytics, export reports, and gain valuable insights into development patterns.'
description: 'Review detailed analytics, export reports, and gain valuable insights into development patterns.',
icon: BarChart3,
}
];

const sectionBgClass = mode === 'dark'
? 'bg-[#1e2130] text-white'
: 'bg-gradient-to-b from-gray-50 via-white to-slate-100 text-gray-900';
const cardSurfaceClass = mode === 'dark' ? 'bg-white/[0.04]' : 'bg-white';
const cardBorderClass = mode === 'dark' ? 'border-white/10' : 'border-gray-200';
const titleTextClass = mode === 'dark' ? 'text-white' : 'text-gray-900';
const bodyTextClass = mode === 'dark' ? 'text-gray-300' : 'text-gray-600';
const connectorBubbleClass = mode === 'dark'
? 'rounded-full border border-blue-400/25 bg-[#1e2130] p-2 text-blue-300 shadow-[0_0_20px_rgba(59,130,246,0.28)]'
: 'rounded-full border border-blue-200 bg-white p-2 text-blue-600 shadow-[0_0_18px_rgba(59,130,246,0.14)]';
const connectorLineClass = mode === 'dark'
? 'how-it-works-flow-line'
: 'how-it-works-flow-line light';

return (
<section id="how-it-works" className="px-6 py-10 bg-gray-50 dark:bg-gray-800 transition-colors duration-300">
<div className="mx-auto">
<section id="how-it-works" className={`relative overflow-hidden px-6 py-20 ${sectionBgClass}`}>
<div className="mx-auto max-w-7xl">
<div className="text-center mb-16">
<h2 className="text-3xl font-bold text-gray-900 dark:text-white mb-4">How It Works</h2>
<p className="text-xl text-gray-600 dark:text-gray-300 max-w-2xl mx-auto">
<h2 className={`text-3xl md:text-4xl font-bold mb-4 ${titleTextClass}`}>How It Works</h2>
<p className={`text-lg md:text-xl max-w-2xl mx-auto ${bodyTextClass}`}>
Get started in minutes with our simple three-step process
</p>
</div>

<div className="grid md:grid-cols-3 gap-8">
{steps.map((step, index) => (
<div key={index} className="text-center">
<div className="bg-blue-600 text-white w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-6 text-2xl font-bold">
{step.number}
</div>
<h3 className="text-xl font-semibold text-gray-900 dark:text-white mb-3">{step.title}</h3>
<p className="text-gray-600 dark:text-gray-300 leading-relaxed">
{step.description}
</p>
<div className="relative">
<div className="pointer-events-none absolute left-0 right-0 top-28 hidden md:block">
<div className="relative mx-auto h-10 max-w-6xl">
<span className={`${connectorLineClass} absolute left-16 right-16 top-1/2 -translate-y-1/2`} />
<span className={`absolute left-1/3 top-1/2 -translate-x-1/2 -translate-y-1/2 ${connectorBubbleClass}`}>
<ArrowRight className="h-4 w-4" />
</span>
<span className={`absolute left-2/3 top-1/2 -translate-x-1/2 -translate-y-1/2 ${connectorBubbleClass}`}>
<ArrowRight className="h-4 w-4" />
</span>
</div>
))}
</div>

<div className="pointer-events-none absolute left-1/2 top-24 bottom-24 flex -translate-x-1/2 flex-col items-center justify-between md:hidden">
<span className={connectorBubbleClass}>
<ArrowDown className="h-4 w-4" />
</span>
<span className={connectorBubbleClass}>
<ArrowDown className="h-4 w-4" />
</span>
Comment on lines +56 to +74
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Hide decorative connector arrows from assistive technologies.

These connector arrows are purely visual. Mark their wrapper blocks as presentational so screen readers don’t announce extra non-content graphics.

Proposed fix
-          <div className="pointer-events-none absolute left-0 right-0 top-28 hidden md:block">
+          <div aria-hidden="true" className="pointer-events-none absolute left-0 right-0 top-28 hidden md:block">
@@
-          <div className="pointer-events-none absolute left-1/2 top-24 bottom-24 flex -translate-x-1/2 flex-col items-center justify-between md:hidden">
+          <div aria-hidden="true" className="pointer-events-none absolute left-1/2 top-24 bottom-24 flex -translate-x-1/2 flex-col items-center justify-between md:hidden">
📝 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
<div className="pointer-events-none absolute left-0 right-0 top-28 hidden md:block">
<div className="relative mx-auto h-10 max-w-6xl">
<span className={`${connectorLineClass} absolute left-16 right-16 top-1/2 -translate-y-1/2`} />
<span className={`absolute left-1/3 top-1/2 -translate-x-1/2 -translate-y-1/2 ${connectorBubbleClass}`}>
<ArrowRight className="h-4 w-4" />
</span>
<span className={`absolute left-2/3 top-1/2 -translate-x-1/2 -translate-y-1/2 ${connectorBubbleClass}`}>
<ArrowRight className="h-4 w-4" />
</span>
</div>
))}
</div>
<div className="pointer-events-none absolute left-1/2 top-24 bottom-24 flex -translate-x-1/2 flex-col items-center justify-between md:hidden">
<span className={connectorBubbleClass}>
<ArrowDown className="h-4 w-4" />
</span>
<span className={connectorBubbleClass}>
<ArrowDown className="h-4 w-4" />
</span>
<div aria-hidden="true" className="pointer-events-none absolute left-0 right-0 top-28 hidden md:block">
<div className="relative mx-auto h-10 max-w-6xl">
<span className={`${connectorLineClass} absolute left-16 right-16 top-1/2 -translate-y-1/2`} />
<span className={`absolute left-1/3 top-1/2 -translate-x-1/2 -translate-y-1/2 ${connectorBubbleClass}`}>
<ArrowRight className="h-4 w-4" />
</span>
<span className={`absolute left-2/3 top-1/2 -translate-x-1/2 -translate-y-1/2 ${connectorBubbleClass}`}>
<ArrowRight className="h-4 w-4" />
</span>
</div>
</div>
<div aria-hidden="true" className="pointer-events-none absolute left-1/2 top-24 bottom-24 flex -translate-x-1/2 flex-col items-center justify-between md:hidden">
<span className={connectorBubbleClass}>
<ArrowDown className="h-4 w-4" />
</span>
<span className={connectorBubbleClass}>
<ArrowDown className="h-4 w-4" />
</span>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/HowItWorks.tsx` around lines 56 - 74, The decorative connector
arrow wrappers are being announced by screen readers; mark the two outer wrapper
divs that contain the ArrowRight/ArrowDown elements as presentational by adding
accessibility attributes (e.g., aria-hidden="true" and role="presentation") to
the divs that wrap the arrows (the divs with classes "pointer-events-none
absolute left-0 right-0 top-28 hidden md:block" and "pointer-events-none
absolute left-1/2 top-24 bottom-24 flex -translate-x-1/2 flex-col items-center
justify-between md:hidden") so the spans using
connectorLineClass/connectorBubbleClass and the ArrowRight/ArrowDown icons are
ignored by assistive tech.

<span className={`${connectorLineClass} vertical absolute left-1/2 top-0 h-full -translate-x-1/2`} />
</div>

<div className="grid gap-8 md:grid-cols-3 md:gap-6 lg:gap-8">
{steps.map((step, index) => {
const IconComponent = step.icon;

return (
<article
key={index}
className={`group relative rounded-3xl border p-8 text-center backdrop-blur-sm transition-all duration-300 hover:-translate-y-1 hover:border-blue-400/30 hover:shadow-[0_24px_60px_rgba(46,89,255,0.18)] ${cardBorderClass} ${cardSurfaceClass} ${mode === 'dark' ? 'hover:bg-white/[0.06]' : 'hover:bg-white'}`}
>
<div className="mx-auto mb-6 flex h-24 w-24 items-center justify-center rounded-full border border-blue-400/20 bg-blue-500/10 shadow-[0_0_38px_rgba(46,89,255,0.35)] ring-1 ring-blue-400/15 transition-transform duration-300 group-hover:scale-105">
<div className="flex h-16 w-16 items-center justify-center rounded-full border border-blue-300/25 bg-blue-500 text-white shadow-[inset_0_1px_0_rgba(255,255,255,0.2),0_0_24px_rgba(46,89,255,0.38)]">
<span className="text-2xl font-bold leading-none">{step.number}</span>
</div>
</div>

<div className={`mx-auto mb-5 flex h-11 w-11 items-center justify-center rounded-full border shadow-[0_0_18px_rgba(46,89,255,0.2)] ${mode === 'dark' ? 'border-white/10 bg-white/5 text-blue-300' : 'border-blue-100 bg-blue-50 text-blue-600'}`}>
<IconComponent className="h-5 w-5" />
</div>

<h3 className={`text-xl font-semibold mb-3 ${titleTextClass}`}>{step.title}</h3>
<p className={`text-sm md:text-base leading-relaxed ${bodyTextClass}`}>
{step.description}
</p>
</article>
);
})}
</div>
</div>
</div>
</section>
Expand Down
71 changes: 71 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,77 @@
@tailwind components;
@tailwind utilities;

@keyframes how-it-works-dash-flow {
from {
background-position: 0 0;
}

to {
background-position: 72px 0;
}
}

@keyframes how-it-works-dash-flow-vertical {
from {
background-position: 0 0;
}

to {
background-position: 0 72px;
}
}
Comment on lines +5 to +23
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix animation distance to ensure seamless looping.

The animation moves background-position by 72px, but the pattern repeats every 28px (from background-size). Since 72 ÷ 28 = 2.57, the pattern won't align when the animation loops, causing a visible jump.

For seamless animation, use a multiple of 28px:

  • 56px (2 full patterns) – recommended
  • 84px (3 full patterns) – alternative if slower flow is preferred
🔄 Proposed fix for seamless looping
 `@keyframes` how-it-works-dash-flow {
   from {
     background-position: 0 0;
   }

   to {
-    background-position: 72px 0;
+    background-position: 56px 0;
   }
 }

 `@keyframes` how-it-works-dash-flow-vertical {
   from {
     background-position: 0 0;
   }

   to {
-    background-position: 0 72px;
+    background-position: 0 56px;
   }
 }
📝 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
@keyframes how-it-works-dash-flow {
from {
background-position: 0 0;
}
to {
background-position: 72px 0;
}
}
@keyframes how-it-works-dash-flow-vertical {
from {
background-position: 0 0;
}
to {
background-position: 0 72px;
}
}
`@keyframes` how-it-works-dash-flow {
from {
background-position: 0 0;
}
to {
background-position: 56px 0;
}
}
`@keyframes` how-it-works-dash-flow-vertical {
from {
background-position: 0 0;
}
to {
background-position: 0 56px;
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/index.css` around lines 5 - 23, The keyframes how-it-works-dash-flow and
how-it-works-dash-flow-vertical currently move background-position by 72px which
doesn't align with the pattern repeat of 28px; update the "to" values to use a
multiple of 28px (recommended 56px) so the animation loops seamlessly (e.g.,
change background-position: 72px 0 to 56px 0 in how-it-works-dash-flow and 0
72px to 0 56px in how-it-works-dash-flow-vertical), keeping the rest of the
keyframe definitions unchanged.


.how-it-works-flow-line {
display: block;
height: 2px;
border-radius: 9999px;
background-image: repeating-linear-gradient(
90deg,
rgba(96, 165, 250, 0.78) 0,
rgba(96, 165, 250, 0.78) 14px,
rgba(96, 165, 250, 0.08) 14px,
rgba(96, 165, 250, 0.08) 26px
);
background-size: 28px 2px;
animation: how-it-works-dash-flow 10s linear infinite;
box-shadow: 0 0 18px rgba(59, 130, 246, 0.24);
Comment on lines +25 to +38
}

.how-it-works-flow-line.light {
background-image: repeating-linear-gradient(
90deg,
rgba(59, 130, 246, 0.6) 0,
rgba(59, 130, 246, 0.6) 12px,
rgba(59, 130, 246, 0.12) 12px,
rgba(59, 130, 246, 0.12) 24px
);
box-shadow: 0 0 14px rgba(59, 130, 246, 0.14);
}

.how-it-works-flow-line.vertical {
width: 2px;
height: 100%;
background-image: repeating-linear-gradient(
180deg,
rgba(96, 165, 250, 0.78) 0,
rgba(96, 165, 250, 0.78) 14px,
rgba(96, 165, 250, 0.08) 14px,
rgba(96, 165, 250, 0.08) 26px
);
background-size: 2px 28px;
animation: how-it-works-dash-flow-vertical 10s linear infinite;
}

.how-it-works-flow-line.vertical.light {
background-image: repeating-linear-gradient(
180deg,
rgba(59, 130, 246, 0.6) 0,
rgba(59, 130, 246, 0.6) 12px,
rgba(59, 130, 246, 0.12) 12px,
rgba(59, 130, 246, 0.12) 24px
);
}
Comment on lines +25 to +74
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add prefers-reduced-motion support for accessibility.

The infinite animations can cause discomfort for users with vestibular disorders or motion sensitivity. Respect the user's motion preference setting to comply with WCAG accessibility guidelines.

♿ Proposed fix to disable animations for users who prefer reduced motion
+@media (prefers-reduced-motion: reduce) {
+  .how-it-works-flow-line {
+    animation: none;
+  }
+}
+
 .how-it-works-flow-line {
   display: block;
   height: 2px;
📝 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
.how-it-works-flow-line {
display: block;
height: 2px;
border-radius: 9999px;
background-image: repeating-linear-gradient(
90deg,
rgba(96, 165, 250, 0.78) 0,
rgba(96, 165, 250, 0.78) 14px,
rgba(96, 165, 250, 0.08) 14px,
rgba(96, 165, 250, 0.08) 26px
);
background-size: 28px 2px;
animation: how-it-works-dash-flow 10s linear infinite;
box-shadow: 0 0 18px rgba(59, 130, 246, 0.24);
}
.how-it-works-flow-line.light {
background-image: repeating-linear-gradient(
90deg,
rgba(59, 130, 246, 0.6) 0,
rgba(59, 130, 246, 0.6) 12px,
rgba(59, 130, 246, 0.12) 12px,
rgba(59, 130, 246, 0.12) 24px
);
box-shadow: 0 0 14px rgba(59, 130, 246, 0.14);
}
.how-it-works-flow-line.vertical {
width: 2px;
height: 100%;
background-image: repeating-linear-gradient(
180deg,
rgba(96, 165, 250, 0.78) 0,
rgba(96, 165, 250, 0.78) 14px,
rgba(96, 165, 250, 0.08) 14px,
rgba(96, 165, 250, 0.08) 26px
);
background-size: 2px 28px;
animation: how-it-works-dash-flow-vertical 10s linear infinite;
}
.how-it-works-flow-line.vertical.light {
background-image: repeating-linear-gradient(
180deg,
rgba(59, 130, 246, 0.6) 0,
rgba(59, 130, 246, 0.6) 12px,
rgba(59, 130, 246, 0.12) 12px,
rgba(59, 130, 246, 0.12) 24px
);
}
`@media` (prefers-reduced-motion: reduce) {
.how-it-works-flow-line,
.how-it-works-flow-line.vertical {
animation: none;
}
}
.how-it-works-flow-line {
display: block;
height: 2px;
border-radius: 9999px;
background-image: repeating-linear-gradient(
90deg,
rgba(96, 165, 250, 0.78) 0,
rgba(96, 165, 250, 0.78) 14px,
rgba(96, 165, 250, 0.08) 14px,
rgba(96, 165, 250, 0.08) 26px
);
background-size: 28px 2px;
animation: how-it-works-dash-flow 10s linear infinite;
box-shadow: 0 0 18px rgba(59, 130, 246, 0.24);
}
.how-it-works-flow-line.light {
background-image: repeating-linear-gradient(
90deg,
rgba(59, 130, 246, 0.6) 0,
rgba(59, 130, 246, 0.6) 12px,
rgba(59, 130, 246, 0.12) 12px,
rgba(59, 130, 246, 0.12) 24px
);
box-shadow: 0 0 14px rgba(59, 130, 246, 0.14);
}
.how-it-works-flow-line.vertical {
width: 2px;
height: 100%;
background-image: repeating-linear-gradient(
180deg,
rgba(96, 165, 250, 0.78) 0,
rgba(96, 165, 250, 0.78) 14px,
rgba(96, 165, 250, 0.08) 14px,
rgba(96, 165, 250, 0.08) 26px
);
background-size: 2px 28px;
animation: how-it-works-dash-flow-vertical 10s linear infinite;
}
.how-it-works-flow-line.vertical.light {
background-image: repeating-linear-gradient(
180deg,
rgba(59, 130, 246, 0.6) 0,
rgba(59, 130, 246, 0.6) 12px,
rgba(59, 130, 246, 0.12) 12px,
rgba(59, 130, 246, 0.12) 24px
);
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/index.css` around lines 25 - 74, The animated repeating gradients
(.how-it-works-flow-line and .how-it-works-flow-line.vertical) use infinite
animations (how-it-works-dash-flow and how-it-works-dash-flow-vertical) which
should be disabled for users who set prefers-reduced-motion; add a media query
`@media` (prefers-reduced-motion: reduce) that targets .how-it-works-flow-line,
.how-it-works-flow-line.light, .how-it-works-flow-line.vertical and
.how-it-works-flow-line.vertical.light and set animation: none !important;
transition: none !important; and optionally reduce or remove strong visual
effects like box-shadow (e.g., box-shadow: none) to fully respect the user
preference while keeping the same selectors and keyframe names referenced.



.icon-merged {
color: #2ea44f; /* Or use your theme color */
Expand Down
Loading