diff --git a/app/dwosi/data.ts b/app/dwosi/data.ts
index 46a9785..0110d9d 100644
--- a/app/dwosi/data.ts
+++ b/app/dwosi/data.ts
@@ -63,7 +63,7 @@ export const record: RecordEntry[] = [
},
]
-/** Published Dev Weekends numbers. Keep in sync with components/home-impact.tsx. */
+/** Published Dev Weekends numbers. Keep in sync with components/home/data.ts. */
export const communityStats = [
{ value: "1,000+", label: "Engineers trained since 2018" },
{ value: "$20K+", label: "Open source stipends" },
diff --git a/app/team/page.tsx b/app/team/page.tsx
index 1430ea5..0e1a2eb 100644
--- a/app/team/page.tsx
+++ b/app/team/page.tsx
@@ -4,7 +4,7 @@ import { useEffect, useState } from "react"
import Image from "next/image"
import { ExternalLink, Linkedin } from "lucide-react"
-import HomeImpact from "@/components/home-impact"
+import { Impact, Outcomes } from "@/components/home/sections-top"
import { Button, Card, Section, SectionHeading, PageHero } from "@/components/site/page-kit"
import { Voices } from "@/components/home/sections-bottom"
import { Slider } from "@/components/site/slider"
@@ -198,8 +198,9 @@ export default function TeamPage() {
- {/* Impact: the proof comes right after the people */}
-
+ {/* Impact and outcomes: the same sections as the homepage */}
+
+
{/* The founder story is written separately and rendered here */}
diff --git a/components/home-impact.tsx b/components/home-impact.tsx
deleted file mode 100644
index 4ae9b00..0000000
--- a/components/home-impact.tsx
+++ /dev/null
@@ -1,216 +0,0 @@
-import { ArrowUpRight, Info } from "lucide-react"
-
-import { SmartLink } from "@/components/home/smart-link"
-import { Card, Eyebrow, Panel, Section, SectionHeading } from "@/components/site/page-kit"
-
-/**
- * Impact block for /team. Two parts:
- * 1. "What our members went on to do": the outcomes that prove the value.
- * 2. "Value added to the economy": what those outcomes are worth in dollars.
- *
- * Every number lives in the arrays below, each with an `info` note that
- * shows on the (i) icon or under the number, so readers can see where it
- * comes from. Used only by app/team/page.tsx. Keep in sync with
- * app/dwosi/data.ts.
- */
-
-type Stat = {
- value: string
- label: string
- info: string
- detail?: string
- href?: string
- cta?: string
-}
-
-const outcomes: Stat[] = [
- {
- value: "9",
- label: "Google Summer of Code 2026 selections",
- detail:
- "Up from 2 in 2025. This year's class is at Apache, NumFOCUS, EMBL-EBI, FLARE, BRL-CAD, FOSSASIA, Drupal, InVesalius and C2SI, plus 5 more in ESoC, SSoC and GSSoC.",
- href: "/blog/gsoc",
- cta: "Meet the 2026 class",
- info: "9 fellows selected for GSoC 2026 and 2 in 2025, counted from their public GSoC project pages. Earlier alumni went to Chromium, FOSSology and Python.",
- },
- {
- value: "1 + 1",
- label: "LFX Mentorship at the Linux Foundation",
- detail:
- "1 mentee this year: Talha Amjad at CNCF, building topology-aware GPU scheduling in Volcano. And 1 mentor before him: Yash Israni, who went from contributor to the other side of the table.",
- href: "/blog/lfx-mentorship-2026-talha-amjad",
- cta: "Read Talha's story",
- info: "Talha Amjad, mentee in LFX Mentorship 2026 Term 3, one of 59 CNCF projects accepted. Yash Israni, selected as an LFX mentor in the previous cohort.",
- },
- {
- value: "100+",
- label: "Remote placements",
- detail:
- "Engineers now working for Silicon Valley and billion-dollar companies, and for international teams through Upwork, Toptal, Turing, Arc and direct hires.",
- info: "Fellows and community members who reported an international remote role or contract to us after mentorship, mock interviews or referrals.",
- },
- {
- value: "20+",
- label: "Engineers at Turing and Scale AI",
- detail:
- "Vetted by Turing and matched with top AI labs for full-time remote work. Others joined Scale AI as competitive programmers, writing and solving hard algorithmic challenges used to train and test the world's top LLMs.",
- info: "20+ members passed Turing's vetting and worked full-time remote engagements of 3 to 4 months. Members at Scale AI worked on coding and reasoning problems for frontier AI labs.",
- },
- {
- value: "50+",
- label: "Top-rated freelancers",
- detail: "Members who built a profile, landed their first client and earned top-rated status on global freelance platforms.",
- info: "Members holding Top Rated or equivalent status on Upwork and similar platforms. 23 fellows started freelancing in the last cohort alone.",
- },
- {
- value: "5",
- label: "Startups born on weekends",
- detail: "Founded by members and mentored by our team, from first idea at a Tech Grind to real products with real users.",
- info: "Companies founded by members through the X Team builder community and 2-Day Startup weekends, with ongoing mentorship from the core team.",
- },
-]
-
-// Money our members earned because of the skills and referrals they picked
-// up here. Every line is a conservative estimate from reported numbers.
-const economy: Stat[] = [
- {
- value: "$1M+",
- label: "Earned on Upwork",
- info: "20 freelancers averaging about $50,000 in lifetime earnings each, with several past $100,000, $200,000 and $300,000.",
- },
- {
- value: "$250K+",
- label: "Earned at Turing and Scale AI",
- info: "20+ engineers on full-time Turing engagements of 3 to 4 months each, plus members paid by Scale AI for competitive programming challenges used to train and test top LLMs.",
- },
- {
- value: "$20K+",
- label: "Open source stipends",
- info: "11 Google Summer of Code stipends (9 in 2026, 2 in 2025) at about $1,500 each, plus the LFX Mentorship stipend.",
- },
- {
- value: "$1.3M+",
- label: "Remote salaries, every year",
- info: "50+ members in remote jobs paying $20,000 to $90,000 a year. The median is about $20,000, and 10 of them earn $50,000 to $90,000. This one recurs annually.",
- },
-]
-
-function InfoTip({ text, onDark = false, align = "right" }: { text: string; onDark?: boolean; align?: "left" | "right" }) {
- const button = onDark
- ? "border-[#3D3D3D] text-[#A3A3A3] hover:border-white hover:text-white focus-visible:outline-white"
- : "border-[#D4D4D4] text-[#5C5C5C] hover:border-[#0A0A0A] hover:text-[#0A0A0A] focus-visible:outline-[#0A0A0A]"
- const tip = onDark ? "bg-white text-[#0A0A0A]" : "bg-[#0A0A0A] text-white"
- return (
-
-
-
- {text}
-
-
- )
-}
-
-const lift = "relative motion-safe:hover:-translate-y-1 hover:shadow-[0_20px_40px_-24px_rgba(0,0,0,0.35)]"
-
-export default function HomeImpact() {
- return (
- <>
- {/* Outcomes. Other pages link to /team#impact, so keep this id. */}
-
-
-
-
-
- {/* Economic value: the first of two black panels on the page */}
-
-
-
- Value added to the economy
-
$2.5M+
-
- earned by our members
-
-
- Free mentorship is not charity when it turns into income. This is what the placements, stipends and freelance
- contracts on this page add up to, using conservative numbers our members reported back to us.
-
-
- Sum of the four lines on the right, rounded down. Remote salaries are counted for one year only, so the true figure
- grows every year.
-
-
-
- {economy.map((e) => (
-
-
{e.value}
-
{e.label}
-
{e.info}
-
- ))}
-
-
-
- Value added for companies
-
300+
-
Placements in the local market
-
-
-
-
- Engineers who trained here now build for companies across Pakistan. They arrive with shipped projects, reviewed
- code and interview practice already behind them, so teams spend less time on hiring and ramp-up and more time
- building.
-
-
- Read the fellowship report
-
-
-
-
-
-
-
- >
- )
-}
diff --git a/components/home/data.ts b/components/home/data.ts
index 77f07e5..9af53a0 100644
--- a/components/home/data.ts
+++ b/components/home/data.ts
@@ -27,7 +27,7 @@ export const LINKS = {
guides: "/guides",
blog: "/blog",
ourStory: "/team",
- impactNumbers: "/team#impact",
+ impactNumbers: "/#impact",
fellowshipReport: "/blog/fellowship-2026-by-the-numbers",
gsocPost: "/blog/gsoc",
lfxPost: "/blog/lfx-mentorship-2026-talha-amjad",
@@ -106,6 +106,10 @@ export const applyPrograms: ApplyProgram[] = [
},
]
+/**
+ * Only countries named in content/blog/fellowship-2026-by-the-numbers.md. The post
+ * counts 30 countries but names 29, so the 30th is left out until we know it.
+ */
export const countries = [
"Pakistan", "India", "Nepal", "USA", "UK", "Nigeria", "Egypt", "Morocco", "Kenya", "Palestine",
"Rwanda", "Russia", "Australia", "Singapore", "Spain", "Italy", "China", "Turkey", "Cameroon",
@@ -155,11 +159,28 @@ export const placesLike: Org[] = [
{ name: "Olostep", href: "https://www.olostep.com", logo: "/logos/olostep.svg" },
]
+/** Every line is a conservative estimate from numbers members reported; `info` says how it is counted */
export const impactBreakdown = [
- { label: "Remote salaries, every year", value: "$1.3M+" },
- { label: "Earned on Upwork", value: "$1M+" },
- { label: "Earned at Turing and Scale AI", value: "$250K+" },
- { label: "Open source stipends", value: "$20K+" },
+ {
+ label: "Remote salaries, every year",
+ value: "$1.3M+",
+ info: "50+ members in remote jobs paying $20,000 to $90,000 a year. The median is about $20,000, and 10 of them earn $50,000 to $90,000. This one recurs every year.",
+ },
+ {
+ label: "Earned on Upwork",
+ value: "$1M+",
+ info: "20 freelancers averaging about $50,000 in lifetime earnings each, with several past $100,000, $200,000 and $300,000.",
+ },
+ {
+ label: "Earned at Turing and Scale AI",
+ value: "$250K+",
+ info: "20+ engineers on full-time Turing engagements of 3 to 4 months each, plus members paid by Scale AI for competitive programming challenges used to train and test top LLMs.",
+ },
+ {
+ label: "Open source stipends",
+ value: "$20K+",
+ info: "11 Google Summer of Code stipends (9 in 2026, 2 in 2025) at about $1,500 each, plus the LFX Mentorship stipend.",
+ },
]
export const outcomes = [
diff --git a/components/home/sections-top.tsx b/components/home/sections-top.tsx
index 3961bca..5e5dabe 100644
--- a/components/home/sections-top.tsx
+++ b/components/home/sections-top.tsx
@@ -201,10 +201,24 @@ export function Impact() {
{item.value}
))}
-
- How we count these numbers →
-
+
+
+ How we count these numbers
+ →
+
+
+ {impactBreakdown.map((item) => (
+
+ {item.label}, {item.value}. {item.info}
+
+ ))}
+
+ The total is the sum of these lines, rounded down. Remote salaries are counted for one year only, so the real
+ figure grows every year.
+
+
+
diff --git a/components/home/voices.tsx b/components/home/voices.tsx
index 46a73a5..2bcf190 100644
--- a/components/home/voices.tsx
+++ b/components/home/voices.tsx
@@ -5,13 +5,15 @@ import Link from "next/link"
import { ArrowLeft, ArrowRight, Play } from "lucide-react"
import { getVideoEmbed } from "@/lib/video-url"
+import { byStoryRank } from "@/lib/story-order"
import { LINKS, videoStories, voices } from "./data"
type LiveVideo = { name: string; role: string; url: string; previewUrl?: string }
/**
* Stories rail: video stories, loaded from the same approved stories as the
- * stories page (GSoC and LFX first), after the videos listed in data.ts.
+ * stories page, merged with the videos listed in data.ts and ordered by
+ * lib/story-order.ts (LFX, then GSoC, then senior engineers, then the rest).
* Written quotes only fill in when there are too few videos. It does not move
* by itself: people scroll it with the arrows, a swipe or the trackpad.
*/
@@ -29,7 +31,7 @@ export function VoicesRail() {
const seen = new Set()
const listed: { name: string; role: string; url: string | null; previewUrl?: string }[] = [...videoStories, ...live]
- const videos = listed.flatMap((story) => {
+ const videos = byStoryRank(listed).flatMap((story) => {
const embed = getVideoEmbed(story.url ?? undefined)
if (!embed || seen.has(embed.embedUrl)) return []
seen.add(embed.embedUrl)
diff --git a/components/story/founder-story.tsx b/components/story/founder-story.tsx
index 16f8f29..8ddb766 100644
--- a/components/story/founder-story.tsx
+++ b/components/story/founder-story.tsx
@@ -23,7 +23,8 @@ export function FounderStory() {
- We started in 2018, on weekends, because that is when working people could show up. We kept seeing the same gaps.
+ We started in 2018, on weekends, because that is when working people could show up. The name stayed; today
+ something runs almost every day. We kept seeing the same gaps.
Universities teach syntax, not systems. Talented people have no roadmap. Learning alone burns people out. We made it
free and nonprofit on purpose, because the people who need it most cannot pay. We began in Pakistan, and today our
members come from 30 countries.
diff --git a/lib/stories.ts b/lib/stories.ts
index 7ea338f..af65851 100644
--- a/lib/stories.ts
+++ b/lib/stories.ts
@@ -1,6 +1,7 @@
import connectDB from '@/lib/db';
import connectImpactDB from '@/lib/impact-db';
import { getVideoEmbed } from '@/lib/video-url';
+import { byStoryRank } from '@/lib/story-order';
import { Testimonial as TestimonialModel } from '@/models/Testimonial';
import { getImpactStoryModel } from '@/models/ImpactStory';
import type { Testimonial } from '@/components/testimonial-card';
@@ -86,16 +87,11 @@ export async function withPreviews(stories: Testimonial[]): Promise {
const stories = await getPublicStories();
const videos = stories.filter((story) => story.type === 'video' && getVideoEmbed(story.videoUrl));
const withImages = await withPreviews(videos);
- return withImages
- .map((story) => ({ name: story.name, role: story.role, url: story.videoUrl as string, previewUrl: story.previewUrl }))
- .sort((a, b) => openSourceRank(a.role) - openSourceRank(b.role));
+ return byStoryRank(
+ withImages.map((story) => ({ name: story.name, role: story.role, url: story.videoUrl as string, previewUrl: story.previewUrl })),
+ );
}
diff --git a/lib/story-order.ts b/lib/story-order.ts
new file mode 100644
index 0000000..4888148
--- /dev/null
+++ b/lib/story-order.ts
@@ -0,0 +1,22 @@
+/**
+ * Order for video stories wherever they are shown: LFX first, then Google
+ * Summer of Code (and the other summers of code), then senior engineers, then
+ * everyone else. Inside each group YouTube videos come first. Stable, so
+ * stories keep their incoming order within a group.
+ */
+export function storyRank(role = "", url = ""): number {
+ const r = role.toLowerCase()
+ const group = /lfx/.test(r)
+ ? 0
+ : /gsoc|summer of code|esoc/.test(r)
+ ? 1
+ : /senior|sr\.|lead|engineer|programmer/.test(r)
+ ? 2
+ : 3
+ const youtube = /youtube\.com|youtu\.be/.test(url) ? 0 : 1
+ return group * 2 + youtube
+}
+
+export function byStoryRank(stories: T[]): T[] {
+ return [...stories].sort((a, b) => storyRank(a.role, a.url ?? "") - storyRank(b.role, b.url ?? ""))
+}