fix(ui): dark mode support on Team and Privacy pages
Deploy to VPS / deploy (push) Has been cancelled

The new public pages were built light-mode only, so toggling dark mode
(which adds .dark to <html>) left them unchanged. Add dark: variants
matching the rest of the site:

- team/page.tsx: page bg, eyebrow, title, description, empty state
- team/TeamGrid.tsx: card bg/border/shadow, portrait gradient, name,
  role, bio, social-link buttons (cyan accent on hover in dark)
- privacy/page.tsx: page bg, title, dates, the template-notice callout,
  section headings, body text, mailto links

Palette consistent with ApplicationClient/CaseStudyModal:
light #F5F5F7/#1D1D1F/#0066CC -> dark #050505/#fff/#00F0FF, secondary
#A1A1A6, cards #111.

Verified: build compiles, TypeScript clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-06 17:33:53 -05:00
parent 7c689e034e
commit 8a98f88047
3 changed files with 20 additions and 20 deletions
+9 -9
View File
@@ -40,26 +40,26 @@ export default async function PrivacyPage({
]; ];
return ( return (
<main className="relative w-full min-h-screen bg-[#F5F5F7]"> <main className="relative w-full min-h-screen bg-[#F5F5F7] dark:bg-[#050505]">
<div className="max-w-3xl mx-auto px-6 pt-28 md:pt-36 pb-24"> <div className="max-w-3xl mx-auto px-6 pt-28 md:pt-36 pb-24">
<Breadcrumbs items={crumbs} /> <Breadcrumbs items={crumbs} />
<header className="mt-6 mb-10"> <header className="mt-6 mb-10">
<h1 className="text-3xl md:text-5xl font-light text-[#1D1D1F] tracking-tight"> <h1 className="text-3xl md:text-5xl font-light text-[#1D1D1F] dark:text-white tracking-tight">
Privacy &amp; Cookie <span className="font-medium">Policy</span> Privacy &amp; Cookie <span className="font-medium">Policy</span>
</h1> </h1>
<p className="mt-3 text-sm text-[#86868B]">Last updated: {LAST_UPDATED}</p> <p className="mt-3 text-sm text-[#86868B] dark:text-[#A1A1A6]">Last updated: {LAST_UPDATED}</p>
</header> </header>
{/* Template disclaimer — remove once reviewed by legal counsel */} {/* Template disclaimer — remove once reviewed by legal counsel */}
<div className="mb-10 rounded-2xl border border-amber-300/50 bg-amber-50 p-4 text-sm text-amber-900"> <div className="mb-10 rounded-2xl border border-amber-300/50 dark:border-amber-400/30 bg-amber-50 dark:bg-amber-400/10 p-4 text-sm text-amber-900 dark:text-amber-200">
<strong>Template notice:</strong> this is a standard GDPR-compliant <strong>Template notice:</strong> this is a standard GDPR-compliant
template provided as a starting point. Please have it reviewed and template provided as a starting point. Please have it reviewed and
adapted by your legal counsel before relying on it, and confirm the adapted by your legal counsel before relying on it, and confirm the
contact details below. contact details below.
</div> </div>
<div className="space-y-8 text-[#1D1D1F]"> <div className="space-y-8 text-[#1D1D1F] dark:text-[#F5F5F7]">
<Section title="1. Who we are"> <Section title="1. Who we are">
<P> <P>
{COMPANY} (&ldquo;we&rdquo;, &ldquo;us&rdquo;, &ldquo;our&rdquo;) {COMPANY} (&ldquo;we&rdquo;, &ldquo;us&rdquo;, &ldquo;our&rdquo;)
@@ -69,7 +69,7 @@ export default async function PrivacyPage({
</P> </P>
<P> <P>
For any privacy-related request you can contact us at{" "} For any privacy-related request you can contact us at{" "}
<a href={`mailto:${CONTACT_EMAIL}`} className="text-[#0066CC] underline underline-offset-2"> <a href={`mailto:${CONTACT_EMAIL}`} className="text-[#0066CC] dark:text-[#00F0FF] underline underline-offset-2">
{CONTACT_EMAIL} {CONTACT_EMAIL}
</a> </a>
. .
@@ -155,7 +155,7 @@ export default async function PrivacyPage({
</ul> </ul>
<P> <P>
To exercise any of these rights, contact us at{" "} To exercise any of these rights, contact us at{" "}
<a href={`mailto:${CONTACT_EMAIL}`} className="text-[#0066CC] underline underline-offset-2"> <a href={`mailto:${CONTACT_EMAIL}`} className="text-[#0066CC] dark:text-[#00F0FF] underline underline-offset-2">
{CONTACT_EMAIL} {CONTACT_EMAIL}
</a> </a>
. .
@@ -187,12 +187,12 @@ const SITE = "rf-flux.com";
function Section({ title, children }: { title: string; children: React.ReactNode }) { function Section({ title, children }: { title: string; children: React.ReactNode }) {
return ( return (
<section> <section>
<h2 className="text-lg md:text-xl font-semibold text-[#1D1D1F] mb-3">{title}</h2> <h2 className="text-lg md:text-xl font-semibold text-[#1D1D1F] dark:text-white mb-3">{title}</h2>
<div className="space-y-3 text-[15px] leading-relaxed">{children}</div> <div className="space-y-3 text-[15px] leading-relaxed">{children}</div>
</section> </section>
); );
} }
function P({ children }: { children: React.ReactNode }) { function P({ children }: { children: React.ReactNode }) {
return <p className="text-[#3A3A3C]">{children}</p>; return <p className="text-[#3A3A3C] dark:text-[#A1A1A6]">{children}</p>;
} }
+6 -6
View File
@@ -27,10 +27,10 @@ export default function TeamGrid({ members }: { members: TeamCard[] }) {
whileInView={{ opacity: 1, y: 0 }} whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, margin: "-60px" }} viewport={{ once: true, margin: "-60px" }}
transition={{ duration: 0.5, delay: Math.min(i * 0.06, 0.4), ease: [0.16, 1, 0.3, 1] }} transition={{ duration: 0.5, delay: Math.min(i * 0.06, 0.4), ease: [0.16, 1, 0.3, 1] }}
className="group relative flex flex-col rounded-3xl bg-white border border-black/[0.06] shadow-[0_2px_20px_rgba(0,0,0,0.04)] hover:shadow-[0_12px_40px_rgba(0,0,0,0.10)] transition-all duration-500 overflow-hidden" className="group relative flex flex-col rounded-3xl bg-white dark:bg-[#111] border border-black/[0.06] dark:border-white/10 shadow-[0_2px_20px_rgba(0,0,0,0.04)] hover:shadow-[0_12px_40px_rgba(0,0,0,0.10)] dark:shadow-[0_2px_20px_rgba(0,0,0,0.4)] transition-all duration-500 overflow-hidden"
> >
{/* Portrait */} {/* Portrait */}
<div className="relative aspect-[4/5] w-full overflow-hidden bg-gradient-to-br from-[#EEF2F5] to-[#E3E9ED]"> <div className="relative aspect-[4/5] w-full overflow-hidden bg-gradient-to-br from-[#EEF2F5] to-[#E3E9ED] dark:from-[#1A1A1C] dark:to-[#0E0E10]">
{m.photoUrl ? ( {m.photoUrl ? (
<Image <Image
src={m.photoUrl} src={m.photoUrl}
@@ -50,13 +50,13 @@ export default function TeamGrid({ members }: { members: TeamCard[] }) {
{/* Body */} {/* Body */}
<div className="flex flex-col flex-1 p-6"> <div className="flex flex-col flex-1 p-6">
<h3 className="text-lg font-semibold text-[#1D1D1F] tracking-tight">{m.name}</h3> <h3 className="text-lg font-semibold text-[#1D1D1F] dark:text-white tracking-tight">{m.name}</h3>
<p className="text-[#0066CC] text-xs font-medium uppercase tracking-[0.12em] mt-1"> <p className="text-[#0066CC] dark:text-[#00F0FF] text-xs font-medium uppercase tracking-[0.12em] mt-1">
{m.role} {m.role}
</p> </p>
{m.bio && ( {m.bio && (
<p className="mt-4 text-sm leading-relaxed text-[#6E6E73] line-clamp-5">{m.bio}</p> <p className="mt-4 text-sm leading-relaxed text-[#6E6E73] dark:text-[#A1A1A6] line-clamp-5">{m.bio}</p>
)} )}
{/* Social links — only the ones that exist */} {/* Social links — only the ones that exist */}
@@ -106,7 +106,7 @@ function SocialLink({
title={label} title={label}
{...(external ? { target: "_blank", rel: "noopener noreferrer" } : {})} {...(external ? { target: "_blank", rel: "noopener noreferrer" } : {})}
onClick={() => trackEvent({ name: "contact_cta_clicked", params: { location: `team:${network}` } })} onClick={() => trackEvent({ name: "contact_cta_clicked", params: { location: `team:${network}` } })}
className="inline-flex items-center justify-center w-9 h-9 rounded-full border border-black/[0.08] text-[#6E6E73] hover:text-white hover:bg-[#1D1D1F] hover:border-[#1D1D1F] transition-colors" className="inline-flex items-center justify-center w-9 h-9 rounded-full border border-black/[0.08] dark:border-white/15 text-[#6E6E73] dark:text-[#A1A1A6] hover:text-white hover:bg-[#1D1D1F] hover:border-[#1D1D1F] dark:hover:bg-[#00F0FF] dark:hover:text-black dark:hover:border-[#00F0FF] transition-colors"
> >
{children} {children}
</a> </a>
+5 -5
View File
@@ -76,7 +76,7 @@ export default async function TeamPage({ params }: { params: Promise<{ locale: s
<> <>
{personSchemas.length > 0 && <JsonLd data={personSchemas} />} {personSchemas.length > 0 && <JsonLd data={personSchemas} />}
<main className="relative w-full min-h-screen bg-[#F5F5F7] overflow-hidden"> <main className="relative w-full min-h-screen bg-[#F5F5F7] dark:bg-[#050505] overflow-hidden">
{/* Ambient visual, consistent with the News / Heritage hubs */} {/* Ambient visual, consistent with the News / Heritage hubs */}
<div className="absolute inset-0 opacity-60 pointer-events-none"> <div className="absolute inset-0 opacity-60 pointer-events-none">
<BreathingField /> <BreathingField />
@@ -86,20 +86,20 @@ export default async function TeamPage({ params }: { params: Promise<{ locale: s
<Breadcrumbs items={crumbs} /> <Breadcrumbs items={crumbs} />
<header className="max-w-3xl mt-6 mb-16 md:mb-24"> <header className="max-w-3xl mt-6 mb-16 md:mb-24">
<p className="text-[#0066CC] text-xs md:text-sm font-semibold uppercase tracking-[0.2em] mb-4"> <p className="text-[#0066CC] dark:text-[#00F0FF] text-xs md:text-sm font-semibold uppercase tracking-[0.2em] mb-4">
{t("eyebrow")} {t("eyebrow")}
</p> </p>
<h1 className="text-4xl md:text-6xl font-light text-[#1D1D1F] tracking-tight leading-[1.05]"> <h1 className="text-4xl md:text-6xl font-light text-[#1D1D1F] dark:text-white tracking-tight leading-[1.05]">
{t("title1")}{" "} {t("title1")}{" "}
<span className="font-medium">{t("title2")}</span> <span className="font-medium">{t("title2")}</span>
</h1> </h1>
<p className="mt-6 text-base md:text-lg text-[#6E6E73] leading-relaxed max-w-2xl"> <p className="mt-6 text-base md:text-lg text-[#6E6E73] dark:text-[#A1A1A6] leading-relaxed max-w-2xl">
{t("description")} {t("description")}
</p> </p>
</header> </header>
{members.length === 0 ? ( {members.length === 0 ? (
<div className="text-center py-24 text-[#86868B]"> <div className="text-center py-24 text-[#86868B] dark:text-[#A1A1A6]">
<p>{t("empty")}</p> <p>{t("empty")}</p>
</div> </div>
) : ( ) : (