Skip to content
Merged
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
11 changes: 5 additions & 6 deletions app/[locale]/about/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { PageHero } from "@/components/sections/shared/PageHero";
import { CtaBand, PeopleArt } from "@/components/sections/shared/CtaBand";
import { CtaBand } from "@/components/sections/shared/CtaBand";
import { ZoomSlideshow } from "@/components/sections/about/ZoomSlideshow";
import { PhotoGrid } from "@/components/sections/about/PhotoGrid";
import { MissionPillars } from "@/components/sections/about/MissionPillars";
import { FounderStory } from "@/components/sections/about/FounderStory";
import { FounderVideo } from "@/components/sections/about/FounderVideo";
import { AiScams } from "@/components/sections/about/AiScams";
import { QuoteBand } from "@/components/sections/about/QuoteBand";
import { WhatWeProvide } from "@/components/sections/about/WhatWeProvide";
import { getDictionary } from "@/lib/i18n/get-dictionary";
Expand Down Expand Up @@ -41,17 +41,16 @@ export default async function AboutPage({
</div>
</PageHero>
<ZoomSlideshow dict={dict.zoom} />
<PhotoGrid dict={dict.photos} />
<MissionPillars dict={dict.mission} />
<FounderStory dict={dict.story} />
<FounderVideo dict={dict.video} />
<AiScams dict={dict.ai} rightsHref={href("/fraud#law")} />
<QuoteBand text={dict.quote.text} cite={dict.quote.cite} />
<WhatWeProvide dict={dict.provide} projectsHref={href("/research")} />
<CtaBand
title={dict.cta.title}
body={dict.cta.body}
primary={{ label: dict.cta.primary, href: href("/join") }}
secondary={{ label: dict.cta.secondary, href: href("/team") }}
art={<PeopleArt />}
/>
</div>
);
Expand Down
27 changes: 17 additions & 10 deletions app/[locale]/fraud/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { YoyoScene } from "@/components/sections/fraud/YoyoScene";
import { FourSquare } from "@/components/sections/fraud/FourSquare";
import { FeeReceipt } from "@/components/sections/fraud/FeeReceipt";
import { AprCalculator } from "@/components/sections/fraud/AprCalculator";
import { FlipCards } from "@/components/sections/fraud/FlipCards";
import { getDictionary } from "@/lib/i18n/get-dictionary";
import { localizeHref, type Locale } from "@/lib/i18n/config";
import { caveat } from "@/lib/fonts";
Expand Down Expand Up @@ -48,7 +47,15 @@ export default async function FraudPage({

return (
<div className={`rd rd-page ${caveat.variable}`}>
<PageHero title={d.hero.title} body={d.hero.body}>
<PageHero
title={d.hero.title}
body={d.hero.body}
art={
<div className="phero-art">
<Image src="/images/graphics/key-handoff.webp" alt="" width={722} height={295} sizes="(max-width: 900px) 92vw, 520px" priority />
</div>
}
>
<div className="ctas">
<Link className="btn btn-solid" href="#flags">
{d.hero.ctaPrimary}
Expand Down Expand Up @@ -169,7 +176,14 @@ export default async function FraudPage({
<h2 className="h2">{d.after.title}</h2>
<p className="lede">{d.after.body}</p>
</div>
<FlipCards items={d.after.items} />
<ol className="num-list after-list">
{d.after.items.map((it) => (
<li key={it.front}>
<h3>{it.front}</h3>
<p>{it.back}</p>
</li>
))}
</ol>
</div>
</section>

Expand Down Expand Up @@ -203,13 +217,6 @@ export default async function FraudPage({
body={d.cta.body}
primary={{ label: d.cta.primary, href: href("/documents") }}
secondary={{ label: d.cta.secondary, href: href("/inspection") }}
art={
<svg viewBox="0 0 260 260" aria-hidden="true">
<circle cx="130" cy="130" r="120" fill="rgba(255,255,255,.12)" />
<path d="M130 50l70 30v50c0 45-30 75-70 90-40-15-70-45-70-90V80z" fill="#fff" />
<path d="M100 135l22 22 40-44" fill="none" stroke="#9533A5" strokeWidth="10" strokeLinecap="round" strokeLinejoin="round" />
</svg>
}
/>
</div>
);
Expand Down
9 changes: 2 additions & 7 deletions app/[locale]/inspection/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import Link from "next/link";
import { PageHero } from "@/components/sections/shared/PageHero";
import { Rich } from "@/components/sections/shared/Rich";
import { QuoteBand } from "@/components/sections/about/QuoteBand";
import { EngineInspector } from "@/components/sections/inspection/EngineInspector";
import { PpiDrive } from "@/components/sections/inspection/PpiDrive";
import { PpiSteps } from "@/components/sections/inspection/PpiSteps";
import { getDictionary } from "@/lib/i18n/get-dictionary";
import type { Locale } from "@/lib/i18n/config";

Expand Down Expand Up @@ -126,11 +125,7 @@ export default async function InspectionPage({
</div>
</section>

<div className="quote-pad">
<QuoteBand text={d.quote.text} cite={d.quote.cite} />
</div>

<PpiDrive dict={d.schedule} />
<PpiSteps dict={d.schedule} />
</div>
);
}
16 changes: 5 additions & 11 deletions app/[locale]/map/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ const MAP_SRC = "/vindimap/index.html";

// Same order as mapPage.news.items.
const NEWS = [
{ url: "https://www.thedrive.com/features/ai-car-dealer-scams-are-infesting-facebook-marketplace-and-theyre-working", img: "ai-dealer-scams" },
{ url: "https://consumer.ftc.gov/consumer-alerts/2026/09/scammers-are-spoofing-car-dealership-websites-what-you-need-know", img: "spoofed-dealer-sites" },
{ url: "https://www.hinshawlaw.com/en/insights/blogs/consumer-crossroads-where-financial-services-and-litigation-intersect/federal-and-state-regulators-continue-crackdown-on-junk-fees-with-dollar4-million-auto-dealer-settlement", img: "junk-fee-settlement" },
{ url: "https://pirg.org/articles/car-dealerships-nationwide-warned-to-stop-junk-fees-other-deceptive-tactics/", img: "dealer-warning-letters" },
{ url: "https://calmatters.org/politics/2025/12/california-new-law-buying-cars/", img: "california-sb-766" },
{ url: "https://www.thedrive.com/features/ai-car-dealer-scams-are-infesting-facebook-marketplace-and-theyre-working" },
{ url: "https://consumer.ftc.gov/consumer-alerts/2026/09/scammers-are-spoofing-car-dealership-websites-what-you-need-know" },
{ url: "https://www.hinshawlaw.com/en/insights/blogs/consumer-crossroads-where-financial-services-and-litigation-intersect/federal-and-state-regulators-continue-crackdown-on-junk-fees-with-dollar4-million-auto-dealer-settlement" },
{ url: "https://pirg.org/articles/car-dealerships-nationwide-warned-to-stop-junk-fees-other-deceptive-tactics/" },
{ url: "https://calmatters.org/politics/2025/12/california-new-law-buying-cars/" },
];

export async function generateMetadata({
Expand Down Expand Up @@ -57,12 +57,6 @@ export default async function MapPage({
<div className="nw-grid">
{d.news.items.map((n, i) => (
<a key={n.title} className="nw" href={NEWS[i].url} target="_blank" rel="noopener noreferrer">
<div className="nw-img">
{/* Decorative illustration; plain <img> keeps the SVG crisp. */}
{/* eslint-disable-next-line @next/next/no-img-element */}
<img src={`/images/news/${NEWS[i].img}.svg`} alt="" loading="lazy" />
<span className="nw-credit">{d.news.credit}</span>
</div>
<div className="nw-body">
<span className="nw-kicker">{n.kicker}</span>
<h3>{n.title}</h3>
Expand Down
30 changes: 9 additions & 21 deletions app/[locale]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
import type { Metadata } from "next";
import { HomeHero } from "@/components/sections/home/HomeHero";
import { ResearchSources } from "@/components/sections/home/ResearchSources";
import { PublicKnowledge } from "@/components/sections/home/PublicKnowledge";
import { PpiExplainer } from "@/components/sections/home/PpiExplainer";
import { EqualFooting } from "@/components/sections/home/EqualFooting";
import { PriceIsRightPreview } from "@/components/sections/home/PriceIsRightPreview";
import { CampusChapters } from "@/components/sections/home/CampusChapters";
import { FollowLinks } from "@/components/sections/home/FollowLinks";
import { AiScams } from "@/components/sections/home/AiScams";
import { Pillars } from "@/components/sections/home/Pillars";
import { FounderStrikes } from "@/components/sections/home/FounderStrikes";
import { FreeResources } from "@/components/sections/home/FreeResources";
import { HomeCta } from "@/components/sections/home/HomeCta";
import { getDictionary } from "@/lib/i18n/get-dictionary";
import { SHARE_IMAGE } from "@/lib/i18n/metadata";
import {
Expand Down Expand Up @@ -64,30 +59,23 @@ export default async function HomePage({

const ppi = href("/inspection");
const fraud = href("/fraud");
const story = href("/about#story");
const story = href("/about");

return (
<div className="rd rd-page">
<HomeHero dict={home.hero} ppiHref={ppi} storyHref={story} />
<ResearchSources dict={home.sources} />
<PublicKnowledge dict={home.publicKnowledge} ppiHref={ppi} fraudHref={fraud} />
<EqualFooting dict={home.footing} />
<PriceIsRightPreview
dict={home.preview}
locale={locale}
gameHref={href("/research#pir")}
<PpiExplainer
dict={home.ppi}
knowledge={home.publicKnowledge}
ppiHref={ppi}
whereHref={href("/inspection#where")}
fraudHref={fraud}
/>
<EqualFooting dict={home.footing} />
<CampusChapters dict={home.chapters} joinHref={href("/join")} />
<FollowLinks dict={home.follow} />
<AiScams dict={home.ai} rightsHref={href("/fraud#law")} />
<Pillars dict={home.pillars} ppiHref={ppi} fraudHref={fraud} />
<FounderStrikes dict={home.strikes} storyHref={story} />
<FreeResources dict={home.free} />
<HomeCta
dict={home.cta}
ppiHref={ppi}
documentsHref={href("/documents")}
/>
</div>
);
}
11 changes: 1 addition & 10 deletions app/[locale]/research/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import type { ReactNode } from "react";
import { PageHero } from "@/components/sections/shared/PageHero";
import { ChecklistArt, CtaBand } from "@/components/sections/shared/CtaBand";
import { CtaBand } from "@/components/sections/shared/CtaBand";
import { TrackNav } from "@/components/sections/research/TrackNav";
import { ProjectCard } from "@/components/sections/research/ProjectCard";
import { PriceIsRightGame } from "@/components/sections/research/PriceIsRightGame";
import { BuildTimeline } from "@/components/sections/research/BuildTimeline";
import { TRACKS, type TrackKey } from "@/components/sections/research/projects";
import { getDictionary } from "@/lib/i18n/get-dictionary";
import { getRouteMetadata } from "@/lib/i18n/metadata";
Expand Down Expand Up @@ -92,12 +90,6 @@ export default async function ResearchPage({
/>
))}
</div>
{track.key === "data" && (
<>
<PriceIsRightGame dict={d.game} locale={locale} />
<BuildTimeline dict={d.timeline} />
</>
)}
</div>
</section>
);
Expand All @@ -106,7 +98,6 @@ export default async function ResearchPage({
title={d.cta.title}
body={d.cta.body}
primary={{ label: d.cta.button, href: `${joinHref}#apply` }}
art={<ChecklistArt />}
/>
</div>
);
Expand Down
3 changes: 1 addition & 2 deletions app/[locale]/team/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { PageHero } from "@/components/sections/shared/PageHero";
import { CtaBand, PeopleArt } from "@/components/sections/shared/CtaBand";
import { CtaBand } from "@/components/sections/shared/CtaBand";
import {
TeamRoster,
type RosterMember,
Expand Down Expand Up @@ -72,7 +72,6 @@ export default async function TeamPage({
title={d.cta.title}
body={d.cta.body}
primary={{ label: d.cta.button, href: localizeHref(locale as Locale, "/join") }}
art={<PeopleArt />}
/>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion app/[locale]/volunteer/page.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const CHAPTERS = [
value: "ucberkeley",
label: "UC Berkeley Chapter",
school: "University of California, Berkeley",
lead: "Rana Darwich, President · Noirit Ghosh Choudhuri, Internal Vice President · Halima Cherif Hminat, External Vice President",
lead: "Noirit Ghosh Choudhuri, Internal Vice President · Halima Cherif Hminat, External Vice President",
contact: "noiritgc@gmail.com",
focus: "Data and outreach hub. Leads the interactive dealership risk map, contributes to data engineering on the audit study, and runs community-facing education and outreach initiatives.",
},
Expand Down
Loading