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
32 changes: 16 additions & 16 deletions app/about/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ export const metadata: Metadata = {
const strengths = [
{
title: "Full-stack engineering",
description: "I can set up the backend, design the database, build the API, and ship the frontend. I've also handled infra, deployments, and compliance logic — whatever the project needs.",
description: "I can set up the backend, design the database, build the API, and ship the frontend myself. I've also handled infra, deployments, and compliance logic when a project needed it.",
icon: "⚙️",
},
{
title: "Frontend that feels right",
description: "Most of my frontend work is in React and Next.js. I care about performance, accessibility, and getting the details right, not just making it work.",
description: "Most of my frontend work is in React and Next.js. Getting a feature working is the easy part. Once it works, most of my time goes into performance and accessibility.",
icon: "🎨",
},
{
Expand All @@ -30,7 +30,7 @@ const strengths = [
},
{
title: "Getting it in front of people",
description: "I've worked on onboarding flows, technical SEO, analytics, and acquisition tooling. Shipping something that nobody uses isn't really shipping.",
description: "I've worked on onboarding flows and technical SEO at Fubo and Winuall, plus analytics and acquisition tooling at FactoStack. Shipping something nobody uses isn't really shipping.",
icon: "📈",
},
];
Expand Down Expand Up @@ -74,33 +74,33 @@ const techCategories = [

const experienceSummaries: Record<string, { summary: string; highlights: string[] }> = {
fubo: {
summary: "Working on frontend features, playback, and technical SEO for Fubo and Molotov. One navigation refactor cleared over 50,000 broken URLs from Google Search Console.",
summary: "I work on frontend features, video playback, and technical SEO for Fubo and Molotov. One navigation refactor I shipped cleared over 50,000 broken URLs from Google Search Console.",
highlights: [
"Rebuilt Molotov navigation — cleared 50,000+ broken URLs",
"Rebuilt Molotov navigation, clearing 50,000+ broken URLs",
"AI-powered live sports highlights for NBA games",
"Frame-accurate seeking in VideoJS for HLS/DASH",
"Structured data & SEO for program listing pages",
],
},
winuall: {
summary: "Built storefronts, learning products, onboarding flows, and shared frontend components across a platform used by over 2,000 tutors.",
summary: "I built storefronts, learning products, onboarding flows, and shared frontend components for a platform used by more than 2,000 tutors.",
highlights: [
"Online Store enabling 2,000+ tutors to sell products",
"Onboarding system for 3,000+ paying users",
"30% performance boost via code splitting",
"Migrated legacy app to SSR — 60% SEO improvement",
"Migrated legacy app to SSR, improving SEO score by 60%",
],
},
teal: {
summary: "Worked on a consumer product, built a Gatsby and Ghost publishing site, and wrote end-to-end tests.",
summary: "I worked on a consumer product, built a Gatsby and Ghost publishing site, and wrote end-to-end tests.",
highlights: [
"Built Tealcheck B2C product from scratch",
"Deployed Regcheck with Ghost CMS and Gatsby",
"90% E2E test coverage with Cypress",
],
},
printrove: {
summary: "Built internal order management tools and merchant-facing features for a print-on-demand platform.",
summary: "I built internal order management tools and merchant-facing features for a print-on-demand platform.",
highlights: [
"100% automation of order processing system",
"Design simulation suite used by 15,000+ designers",
Expand All @@ -114,7 +114,7 @@ export default function AboutPage() {
<main id="main-content" className="page-shell">
<header className="page-intro">
<p className="eyebrow">About</p>
<h1 className="max-w-5xl">I build things end-to-end — and I&apos;ve been doing it for five years.</h1>
<h1 className="max-w-5xl">I build things end to end, and I&apos;ve been doing it for five years.</h1>
<p className="max-w-2xl">Right now I&apos;m a Software Engineer 2 at Fubo, and I&apos;m also building FactoStack on the side. The two are pretty different, and I think that&apos;s made me a better engineer.</p>
</header>

Expand All @@ -137,10 +137,10 @@ export default function AboutPage() {
Engineering at scale, and from scratch.
</h2>
<p className="mt-5 leading-7 text-muted-foreground">
At Fubo I work on a large team with real engineering constraintsperformance budgets, accessibility standards, SEO at scale. One navigation refactor I shipped cleared over 50,000 broken URLs from Google Search Console. This is what disciplined, production-grade engineering looks like.
At Fubo I work on a large team with real constraints: performance budgets, accessibility bars to clear, SEO that has to hold up at scale. One navigation refactor I shipped cleared over 50,000 broken URLs from Google Search Console. That&apos;s most of what the job actually looks like.
</p>
<p className="mt-4 leading-7 text-muted-foreground">
FactoStack is where I own everything — product decisions, architecture, compliance logic, deployments, and customer conversations. No handoffs, no product manager. Building both has sharpened my instincts in ways that neither alone could.
FactoStack is the opposite. There&apos;s no product manager and nobody to hand things off to, so product decisions, architecture, and customer conversations are all mine. Doing both jobs at once has sharpened my instincts more than either one alone would have.
</p>
<div className="mt-7 flex flex-col gap-3 sm:flex-row lg:flex-col xl:flex-row">
<Button asChild><a href="mailto:sudharsangs.99@gmail.com"><Mail aria-hidden="true" />Email me</a></Button>
Expand All @@ -163,7 +163,7 @@ export default function AboutPage() {
<div className="max-w-2xl">
<p className="eyebrow">Tech stack</p>
<h2 id="tech-heading" className="mt-2 font-serif text-3xl font-semibold sm:text-4xl">What I build with.</h2>
<p className="mt-4 leading-7 text-muted-foreground">These are the tools I reach for day-to-daynot a résumé keyword list, but the actual stack I&apos;ve shipped production software with.</p>
<p className="mt-4 leading-7 text-muted-foreground">These are the tools I actually reach for day to day, not a résumé keyword list.</p>
</div>
<div className="mt-9 grid gap-6 sm:grid-cols-3">
{techCategories.map(({ category, items }) => (
Expand All @@ -189,7 +189,7 @@ export default function AboutPage() {
<div className="max-w-2xl">
<p className="eyebrow">Experience</p>
<h2 id="experience-heading" className="mt-2 font-serif text-3xl font-semibold sm:text-4xl">Where I&apos;ve worked.</h2>
<p className="mt-4 leading-7 text-muted-foreground">Five years across streaming, education, consumer products, and internal operations.</p>
<p className="mt-4 leading-7 text-muted-foreground">Five years split mostly between streaming and education, plus a consumer product and internal tooling early on.</p>
</div>
<div className="mt-9 space-y-5">
{experiences.map((experience) => {
Expand All @@ -209,7 +209,7 @@ export default function AboutPage() {
)}
</div>
<span className="shrink-0 rounded-full bg-secondary/60 px-3 py-1 text-xs font-medium text-muted-foreground">
{experience.period.start} {experience.period.end}
{experience.period.start} {experience.period.end}
</span>
</div>
{experience.roles && (
Expand All @@ -232,7 +232,7 @@ export default function AboutPage() {
)}
</p>
<p className="text-xs text-muted-foreground">
{role.start} {role.end}
{role.start} {role.end}
</p>
</div>
</li>
Expand Down
12 changes: 6 additions & 6 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,22 @@ const playfairDisplay = Playfair_Display({

export const metadata: Metadata = {
metadataBase: new URL("https://sudharsangs.in"),
title: "Sudharsan GS — Full-Stack Engineer | Fubo · FactoStack · Winuall",
description: "Full-stack product engineer with 5 years across Fubo, FactoStack, and Winuall. I take operations-heavy problems to production end to endERP, SaaS, streaming, and technical SEO.",
title: "Sudharsan GS, Product Engineer | Fubo · FactoStack · Winuall",
description: "Product engineer with five years across Fubo, FactoStack, and Winuall. I build operations-heavy software end to end, from a manufacturing ERP to streaming interfaces, and handle the technical SEO that gets it found.",
authors: [{ name: "Sudharsan GS" }],
creator: "Sudharsan GS",
openGraph: {
type: "website",
locale: "en_IN",
url: "/",
title: "Sudharsan GS — Full-Stack Engineer | Fubo · FactoStack · Winuall",
description: "Full-stack product engineer with 5 years across Fubo, FactoStack, and Winuall. I take operations-heavy problems to production end to endERP, SaaS, streaming, and technical SEO.",
title: "Sudharsan GS, Product Engineer | Fubo · FactoStack · Winuall",
description: "Product engineer with five years across Fubo, FactoStack, and Winuall. I build operations-heavy software end to end, from a manufacturing ERP to streaming interfaces, and handle the technical SEO that gets it found.",
siteName: "Sudharsan GS",
},
twitter: {
card: "summary_large_image",
title: "Sudharsan GS — Full-Stack Engineer | Fubo · FactoStack · Winuall",
description: "Full-stack product engineer with 5 years across Fubo, FactoStack, and Winuall. I take operations-heavy problems to production end to endERP, SaaS, streaming, and technical SEO.",
title: "Sudharsan GS, Product Engineer | Fubo · FactoStack · Winuall",
description: "Product engineer with five years across Fubo, FactoStack, and Winuall. I build operations-heavy software end to end, from a manufacturing ERP to streaming interfaces, and handle the technical SEO that gets it found.",
creator: "@sudharsangs",
},
};
Expand Down
4 changes: 2 additions & 2 deletions app/opengraph-image.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ImageResponse } from "next/og";

export const runtime = "edge";
export const alt = "Sudharsan GS — Full-Stack Engineer";
export const alt = "Sudharsan GS, Product Engineer";
export const size = { width: 1200, height: 630 };
export const contentType = "image/png";

Expand Down Expand Up @@ -58,7 +58,7 @@ export default function OGImage() {
maxWidth: "860px",
}}
>
Full-stack product engineer — Fubo · FactoStack · Winuall
Five years shipping production software at Fubo, FactoStack, and Winuall
</div>
</div>
<div
Expand Down
4 changes: 2 additions & 2 deletions app/projects/independent/quickpicks/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const screenshots = [
url: "/projects/independent/unlocker/unlocker-quickpicks.png",
alt: "QuickPicks pick creation flow",
caption:
"Create a pick in 30 seconds structured form with event, pricing, and instant publish.",
"Create a pick in 30 seconds: a structured form for event details, pricing, and instant publish.",
},
{
url: "/projects/independent/quickpicks/pick-flow.png",
Expand All @@ -95,7 +95,7 @@ export default function QuickPicksPage() {
<div className="relative w-full h-[280px] md:h-[380px] mb-12 rounded-2xl overflow-hidden border border-primary/20">
<Image
src="/projects/independent/unlocker/unlocker-quickpicks.png"
alt="QuickPicks create a pick in 30 seconds"
alt="QuickPicks, create a pick in 30 seconds"
fill
className="object-cover object-top"
/>
Expand Down
6 changes: 3 additions & 3 deletions app/projects/independent/unlocker/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ export default function UnlockerPage() {
"Stripe Connect integration for marketplace payments with direct payouts to experts",
"JWT authentication with role-based access control for users, experts, and admins"
],
problemStatement: "The sports betting advisory industry suffers from fake claims, cherry-picked results, and zero accountability. Bettors lack verification methods for expert claims, while legitimate experts struggle to build sustainable businesses with difficulty proving legitimacy and no professional monetization platform.",
solution: "A transparent marketplace where every pick, result, and performance metric is publicly tracked and verified. Experts build reputations through provable consistent results, enabling trust-driven conversions and sustainable recurring revenue.",
problemStatement: "The sports betting advisory industry runs on fake claims, cherry-picked results, and zero accountability. Bettors have no way to verify an expert's track record, and the legitimate experts have no real platform to build a business on.",
solution: "A marketplace where every pick, result, and performance metric is public and verified. Experts build a track record they can actually point to, which is what gets someone to subscribe and keep subscribing.",
challenges: [
{
title: "Stripe Connect Integration",
Expand Down Expand Up @@ -77,7 +77,7 @@ export default function UnlockerPage() {
<div className="relative w-full h-[280px] md:h-[380px] mb-12 rounded-2xl overflow-hidden border border-primary/20">
<Image
src="/projects/independent/unlocker/unlocker-marketplace.png"
alt="Unlocker marketplace all experts listing"
alt="Unlocker marketplace, all experts listing"
fill
className="object-cover object-top"
/>
Expand Down
4 changes: 2 additions & 2 deletions app/projects/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const groups = [
eyebrow: "Full-time work",
navLabel: "Fubo and Winuall",
title: "Work at Fubo, Molotov, and Winuall",
description: "Frontend and product work across streaming, video, education, e-commerce, onboarding, and technical SEO.",
description: "Frontend and product work at Fubo, Molotov, and Winuall, spanning streaming video, e-commerce, and onboarding.",
projects: pick(["molotov-program-list-pages", "molotov-navbar-redesign", "molotov-evergreen-program-pages", "winuall-apps"]),
},
{
Expand Down Expand Up @@ -50,7 +50,7 @@ export default function ProjectsPage() {
<main id="main-content" className="page-shell">
<header className="page-intro">
<p className="eyebrow">Projects</p>
<h1>Frontend, full-stack, and product work.</h1>
<h1>Full-stack and product work.</h1>
<p>A selection of things I’ve built at work, for clients, and on my own.</p>
</header>

Expand Down
15 changes: 7 additions & 8 deletions app/projects/personal/factostack-platform/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const highlights = [
{
title: "Built around real MSME constraints",
description:
"The product engineering work goes beyond generic ERP screens. The implemented routes cover Indian factory issues such as MSME payment deadlines, ITC risk, GST exports, receivables aging, and lender-style credit scoring.",
"I didn't want generic ERP screens, so the routes are built around actual Indian factory problems: MSME payment deadlines, ITC risk, GST exports, receivables aging, and lender-style credit scoring.",
},
{
title: "Operator and owner workflows in one app",
Expand All @@ -69,7 +69,7 @@ const highlights = [
];

const results = [
"The product is still early-stage, so I describe it as a platform in validation rather than claiming scaled business impact that does not exist yet.",
"The product is still early. I'd rather call it a platform in validation than inflate numbers that aren't there yet.",
"Mapped six factory workflow domains into one product without copying generic ERP patterns. The scope came from real constraints: GST exports, MSME payment deadlines, ITC tracking, receivables aging.",
"Built a tenant-aware architecture so different factory configurations can onboard without rebuilding core flows.",
"Validated that Indian MSME compliance requirements need product-level design decisions, not just UI implementation.",
Expand Down Expand Up @@ -106,7 +106,7 @@ export default function FactoStackPlatformPage() {
return (
<ProjectPageLayout
title="FactoStack Manufacturing Platform"
description="The core product behind FactoStack: a product engineering effort focused on Indian MSME manufacturers who need production, inventory, procurement, GST, and owner visibility in one operating system."
description="FactoStack's core product. It gives Indian MSME manufacturers production, inventory, procurement, GST, and owner-level visibility in one system, so they're not stitching it together from Excel and WhatsApp."
type="personal"
date="2025-2026"
liveUrl="https://app.factostack.com"
Expand Down Expand Up @@ -154,11 +154,10 @@ export default function FactoStackPlatformPage() {
>
<p className="text-muted-foreground leading-relaxed">
Indian MSMEs often run core factory work across Excel sheets,
WhatsApp messages, paper slips, and separate accounting tools. In
the platform repo, that pain shows up in the workflows I chose to
build: WIP tracking, QR job cards, material variance, MSME payment
compliance, ITC verification, receivables aging, GST exports, and
owner dashboards.
WhatsApp messages, paper slips, and separate accounting tools.
FactoStack covers WIP tracking, QR job cards, material variance,
MSME payment compliance, ITC verification, receivables aging, and
GST exports, with a dashboard the owner can actually check.
</p>
</ProjectSection>

Expand Down
2 changes: 1 addition & 1 deletion app/projects/personal/factostack-website/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export default function FactoStackWebsitePage() {
return (
<ProjectPageLayout
title="FactoStack Marketing Website"
description="The acquisition site for FactoStack, built as the marketing and SEO engine for a complex manufacturing product with search, tools, content, and conversion paths working together."
description="This is the acquisition site for FactoStack, a marketing and SEO engine built for a complex manufacturing product. It covers search-driven content, free tools, and the paths that turn a visitor into a trial signup."
type="personal"
date="2025-2026"
liveUrl="https://factostack.com"
Expand Down
10 changes: 4 additions & 6 deletions app/projects/personal/form-to-sheets/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,10 @@ export default function FormToSheetsPage() {
{ name: 'TailwindCSS', icon: '/skills/tailwind.svg' }
],
features: [
"Seamless integration of Google Forms into any website",
"Support for multiple frameworks, including React, Vue, HTML, and Svelte",
"Effortless code generation for easy embedding",
"Developer-friendly and user-centric design",
"Real-time data integration for efficient data management",
"Secure and robust infrastructure for data protection"
"Embed a Google Form on any website without an iframe",
"Generates ready-to-use code for React, Vue, Svelte, and plain HTML",
"Copy-paste embedding, no backend setup required",
"Form responses still flow straight into your Google Sheet"
],
images: [
{
Expand Down
2 changes: 1 addition & 1 deletion app/projects/work/molotov-evergreen-program-pages/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const metadata: Metadata = {
export default function MolotovEvergreenProgramPagesPage() {
const projectData = {
title: "Program Pages",
description: "Designed and built canonical program pages for Molotov TV, consolidating dozens of fragmented legacy URLs per title into a single authoritative page, wired up with schema.org microdata, deeplinks into the streaming app, and LCP optimizations targeting French streaming audiences.",
description: "Designed and built canonical program pages for Molotov TV, consolidating dozens of fragmented legacy URLs per title into one authoritative page. Each page carries schema.org microdata, deep links into the streaming app, and LCP tuning aimed at French streaming audiences.",
company: {
name: "Molotov by Fubo",
url: "https://www.molotov.tv",
Expand Down
Loading