feat: add dark mode #422 (#466)

* feat: add dark mode #422
This commit is contained in:
Kalidou Diagne
2025-06-16 10:34:24 +04:00
committed by GitHub
parent 1866c24304
commit a972305d4b
67 changed files with 465 additions and 310 deletions

View File

@@ -16,10 +16,10 @@ export default async function AboutPage() {
return (
<div className="flex flex-col">
<div className="w-full bg-page-header-gradient">
<div className="w-full bg-page-header-gradient dark:bg-transparent-gradient">
<AppContent className="flex flex-col gap-4 py-10 w-full max-w-[978px] mx-auto">
<Label.PageTitle label={LABELS.ABOUT_PAGE.TITLE} />
<h6 className="font-sans text-base font-normal text-tuatara-950 md:text-[18px] md:leading-[27px] md:max-w-[700px]">
<h6 className="font-sans text-base font-normal text-primary md:text-[18px] md:leading-[27px] md:max-w-[700px]">
{LABELS.ABOUT_PAGE.DESCRIPTION}
</h6>
<Link
@@ -42,7 +42,7 @@ export default async function AboutPage() {
</Link>
</AppContent>
</div>
<Divider.Section className="bg-white">
<Divider.Section className="bg-background">
<div className="flex justify-center">
<AppContent className="container flex w-full max-w-[978px] flex-col gap-8 py-10 md:py-16">
<Label.Section

View File

@@ -83,7 +83,7 @@ export default function BlogArticle({ params }: any) {
: undefined,
}}
/>
<div className="flex items-start justify-center z-0 bg-cover border-tuatara-300 border-b w-full">
<div className="flex items-start justify-center z-0 bg-cover border-tuatara-300 border-b w-full dark:border-anakiwa-800">
<AppContent className="flex flex-col gap-8 py-10 max-w-[978px]">
<Label.PageTitle
label={post?.title}
@@ -135,7 +135,7 @@ export default function BlogArticle({ params }: any) {
<span
className={cn(
"text-sm italic",
imageAsCover ? "text-white" : "text-tuatara-950"
imageAsCover ? "text-white" : "text-primary"
)}
>
Tags:

View File

@@ -83,7 +83,7 @@ const BlogTagPage = async ({ params }: BlogTagPageProps) => {
<AppContent className="flex flex-col gap-10 pb-10 lg:py-10 lg:max-w-[978px]">
<div className="flex flex-col gap-4 py-10 w-full">
<Link
className="flex items-center gap-2 text-tuatara-950/80 hover:text-tuatara-950 mr-auto"
className="flex items-center gap-2 text-primary/80 hover:text-primary mr-auto"
href="/blog"
>
<Icons.arrowLeft />

View File

@@ -36,7 +36,7 @@ const BlogTagsPage = async () => {
<AppContent className="flex flex-col gap-6 py-10 lg:max-w-[978px]">
<div className="flex flex-col gap-4 py-10 w-full">
<Link
className="flex items-center gap-2 text-tuatara-950/80 hover:text-tuatara-950 mr-auto"
className="flex items-center gap-2 text-primary/80 hover:text-primary mr-auto"
href="/blog"
>
<Icons.arrowLeft />
@@ -53,7 +53,7 @@ const BlogTagsPage = async () => {
<Link
href={`/blog/tags/${tag.id}`}
key={tag.id}
className="text-neutral-950 border-b-[2px] border-b-anakiwa-500 text-sm font-medium w-fit hover:text-anakiwa-500 duration-200"
className="text-primary border-b-[2px] border-b-anakiwa-500 text-sm font-medium w-fit hover:text-anakiwa-500 duration-200"
>
{tag.name}
</Link>

View File

@@ -33,10 +33,10 @@ export const Devcon7Booths = () => {
<span className="text-anakiwa-500 text-xs font-sans leading-5 tracking-[2.5px] uppercase font-bold">
BOOTH
</span>
<span className="text-[22px] leading-[24px] text-tuatara-950 font-display font-bold">
<span className="text-[22px] leading-[24px] text-primary font-display font-bold">
{booth?.title}
</span>
<span className="text-xs text-tuatara-950 font-sans font-normal">
<span className="text-xs text-primary font-sans font-normal">
{booth?.description}
{booth?.learMore && (
<Link

View File

@@ -32,7 +32,7 @@ const EventCard = ({ event = {}, speakers = [], location = "" }: any) => {
)}
>
<div className="flex flex-col gap-1 order-3 lg:order-1">
<span className="text-sm text-tuatara-950 font-bold font-sans leading-5">
<span className="text-sm text-primary font-bold font-sans leading-5">
{event?.date}
</span>
<div className="grid grid-cols-[1fr_16px] lg:grid-cols-1">
@@ -70,7 +70,7 @@ const EventCard = ({ event = {}, speakers = [], location = "" }: any) => {
<Link
href={event?.url ?? "#"}
target="_blank"
className="text-[22px] inline-flex leading-[24px] text-tuatara-950 underline font-display hover:text-anakiwa-500 font-bold duration-200"
className="text-[22px] inline-flex leading-[24px] text-primary underline font-display hover:text-anakiwa-500 font-bold duration-200"
>
{event?.title}
</Link>
@@ -105,7 +105,7 @@ const EventCard = ({ event = {}, speakers = [], location = "" }: any) => {
"lg:transition-none lg:overflow-visible"
)}
>
<span className="text-base leading-6 text-tuatara-950 font-sans font-normal">
<span className="text-base leading-6 text-primary font-sans font-normal">
{event?.description}
</span>
<div className="pt-2 flex lg:!hidden">

View File

@@ -28,7 +28,7 @@ type ProgramDetailProps = {
const SectionTitle = ({ label }: { label: string }) => {
return (
<span className="text-center font-display text-[32px] font-bold text-tuatara-950">
<span className="text-center font-display text-[32px] font-bold text-primary">
{label}
</span>
)
@@ -44,7 +44,7 @@ const AccordionLabel = ({
return (
<span
className={twMerge(
"mx-auto text-center text-base font-bold uppercase tracking-[3.36px] text-tuatara-950",
"mx-auto text-center text-base font-bold uppercase tracking-[3.36px] text-primary",
className
)}
>
@@ -62,13 +62,13 @@ const ProgramDetail = ({
}: ProgramDetailProps) => {
return (
<div className="flex flex-col gap-4 text-center">
<span className="font-display text-lg font-bold leading-none text-black">
<span className="font-display text-lg font-bold leading-none text-primary">
{region} <br />
{title}
</span>
{deadline && (
<span className="font-sans text-xs font-normal italic text-tuatara-500">
<span className="font-sans text-xs font-normal italic text-tuatara-500 dark:text-whit">
Application Deadline: {deadline}
</span>
)}
@@ -76,14 +76,16 @@ const ProgramDetail = ({
{location && (
<div className="mx-auto flex items-center gap-2">
<Icons.location />
<span className="font-sans text-xs font-normal text-black">
<span className="font-sans text-xs font-normal text-primary">
{location}
</span>
</div>
)}
<div className="mx-auto flex items-center gap-2">
<Icons.calendar />
<span className="font-sans text-xs font-normal text-black">{date}</span>
<span className="font-sans text-xs font-normal text-primary">
{date}
</span>
</div>
</div>
)
@@ -154,7 +156,7 @@ export const ProgramPageContent = () => {
return (
<Divider.Section className="flex flex-col">
<div className="bg-second-gradient">
<div className="bg-second-gradient dark:bg-transparent-gradient">
<PageHeader
title={LABELS.PROGRAMS_PAGE.TITLE}
subtitle={LABELS.PROGRAMS_PAGE.DESCRIPTION}
@@ -173,13 +175,13 @@ export const ProgramPageContent = () => {
<div className="sticky right-0 top-0 z-10 mx-auto flex w-full max-w-screen-3xl">
<div
id="sidebar"
className="relative ml-auto hidden bg-white p-2 lg:block"
className="relative ml-auto hidden bg-background p-2 lg:block"
>
<div className="absolute right-0 mt-[80px] flex flex-col gap-4 lg:w-[220px] xl:w-[320px] xl:px-8">
<h6 className="font-display text-lg font-bold text-tuatara-700">
<h6 className="font-display text-lg font-bold text-secondary">
{LABELS.COMMON.ON_THIS_PAGE}
</h6>
<ul className="text-normal font-sans text-black">
<ul className="text-normal font-sans text-primary">
{ProgramSections.map((id: string) => {
const label = getSectionTitle(id)
@@ -262,7 +264,7 @@ export const ProgramPageContent = () => {
return (
<span
key={index}
className="font-sans text-base text-tuatara-950"
className="font-sans text-base text-primary"
>
{description}
</span>
@@ -304,7 +306,7 @@ export const ProgramPageContent = () => {
value: index.toString(),
children: (
<span
className="font-sans text-sm font-normal text-black"
className="font-sans text-sm font-normal text-primary"
dangerouslySetInnerHTML={{
__html: answer?.toString() ?? "",
}}
@@ -362,7 +364,7 @@ export const ProgramPageContent = () => {
return (
<span
key={index}
className="font-sans text-base text-tuatara-950"
className="font-sans text-base text-primary"
>
{description}
</span>
@@ -376,7 +378,7 @@ export const ProgramPageContent = () => {
<div className="flex flex-col gap-8 pb-10 md:pb-16">
<div id="howToApply" className="flex flex-col gap-8">
<div>
<span className="text-base font-medium text-tuatara-950">
<span className="text-base font-medium text-primary">
{LABELS.PROGRAMS_PAGE.HOW_TO_APPLY.OPEN_TASKS.TITLE}
</span>
<ul className="list-decimal">
@@ -388,7 +390,7 @@ export const ProgramPageContent = () => {
className="ml-8 list-item items-center"
>
<div
className="text-tuatara-950"
className="text-primary"
dangerouslySetInnerHTML={{
__html: task,
}}
@@ -400,7 +402,7 @@ export const ProgramPageContent = () => {
</ul>
</div>
<div>
<span className="text-base font-medium text-tuatara-950">
<span className="text-base font-medium text-primary">
{
LABELS.PROGRAMS_PAGE.HOW_TO_APPLY.SUBMIT_IDEA
.TITLE
@@ -426,7 +428,7 @@ export const ProgramPageContent = () => {
)}
</ul>
</div>
<span className="text-base text-tuatara-950">
<span className="text-base text-primary">
{LABELS.PROGRAMS_PAGE.HOW_TO_APPLY.DESCRIPTION}
</span>
</div>
@@ -445,7 +447,7 @@ export const ProgramPageContent = () => {
label,
value: index.toString(),
children: (
<span className="flex flex-col gap-3 text-base text-tuatara-950">
<span className="flex flex-col gap-3 text-base text-primary">
{typeof answer === "string"
? answer
: answer.map((item, index) => {

View File

@@ -17,10 +17,10 @@ export const metadata: Metadata = {
export default async function ProjectsPage() {
return (
<div className="flex flex-col">
<div className="w-full bg-page-header-gradient">
<div className="w-full bg-page-header-gradient dark:bg-transparent-gradient">
<AppContent className="flex flex-col gap-4 py-10 w-full">
<Label.PageTitle label={LABELS.PROJECTS_PAGE.TITLE} />
<h6 className="font-sans text-base font-normal text-tuatara-950 md:text-[18px] md:leading-[27px] md:max-w-[700px]">
<h6 className="font-sans text-base font-normal text-primary md:text-[18px] md:leading-[27px] md:max-w-[700px]">
{LABELS.PROJECTS_PAGE.SUBTITLE}
</h6>
</AppContent>

View File

@@ -20,41 +20,46 @@ import { ProjectTeamMembers } from "@/components/project/project-team"
import { ProjectBlogArticles } from "@/components/blog/project-blog-articles"
import { ProjectYouTubeVideos } from "@/components/sections/ProjectYouTubeVideos"
import { useProjects } from "@/app/providers/ProjectsProvider"
import { Button } from "@/components/ui/button"
const markdownContentClassName =
"text-neutral-700 text-[22px] leading-6 font-bold pt-10 pb-4 dark:text-tuatara-100"
const markdownComponents = {
h1: ({ ...props }) =>
createMarkdownElement("h1", {
className: "text-neutral-700 text-[22px] leading-6 font-bold pt-10 pb-4",
className: markdownContentClassName,
...props,
}),
h2: ({ ...props }) =>
createMarkdownElement("h2", {
className: "text-neutral-700 text-[22px] leading-6 font-bold pt-10 pb-4",
className: markdownContentClassName,
...props,
}),
h3: ({ ...props }) =>
createMarkdownElement("h3", {
className: "text-neutral-700 text-[22px] leading-6 font-bold pt-10 pb-4",
className: markdownContentClassName,
...props,
}),
h4: ({ ...props }) =>
createMarkdownElement("h4", {
className: "text-neutral-700 text-[22px] leading-6 font-bold pt-10 pb-4",
className: markdownContentClassName,
...props,
}),
h5: ({ ...props }) =>
createMarkdownElement("h5", {
className: "text-neutral-700 text-[22px] leading-6 font-bold pt-10 pb-4",
className: markdownContentClassName,
...props,
}),
h6: ({ ...props }) =>
createMarkdownElement("h6", {
className: "text-neutral-700 text-[22px] leading-6 font-bold pt-10 pb-4",
className: markdownContentClassName,
...props,
}),
p: ({ ...props }) =>
createMarkdownElement("p", {
className: "py-2 leading-[150%] text-base text-slate-600",
className:
"py-2 leading-[150%] text-base text-slate-600 dark:text-tuatara-100",
...props,
}),
}
@@ -81,10 +86,8 @@ export const ProjectContent = ({ id }: { id: string }) => {
return null
}
console.log(" rest", project)
return (
<section className="bg-project-page-gradient">
<section className="bg-project-page-gradient dark:bg-transparent-gradient">
<div className="flex flex-col">
<Divider.Section className="flex flex-col items-center">
<AppContent className="flex flex-col gap-12 py-16">
@@ -109,7 +112,7 @@ export const ProjectContent = ({ id }: { id: string }) => {
<div className="flex flex-col">
<div className="flex flex-col gap-6 text-left">
<Link
className="flex items-center gap-2 text-tuatara-950/80 hover:text-tuatara-950 mr-auto"
className="flex items-center gap-2 text-primary/80 hover:text-primary mr-auto"
href="/projects"
>
<Icons.arrowLeft />
@@ -142,7 +145,7 @@ export const ProjectContent = ({ id }: { id: string }) => {
>
<div className="flex items-center gap-2">
{ProjectLinkIconMap?.[key]}
<p className="capitalize duration-200 text-slate-600 group-hover:text-orange">
<p className="capitalize duration-200 text-slate-600 group-hover:text-orange dark:text-white dark:group-hover:text-orange">
{key}
</p>
</div>
@@ -203,10 +206,10 @@ export const ProjectContent = ({ id }: { id: string }) => {
target="_blank"
rel="noreferrer"
passHref
className="inline-flex items-center self-start gap-2 px-4 py-2 duration-200 bg-white border-2 rounded-md group border-tuatara-950 hover:bg-tuatara-950 hover:text-white"
className="inline-flex items-center self-start gap-2 px-4 py-2 duration-200 bg-white border-2 rounded-md group border-tuatara-950 hover:bg-tuatara-950 hover:text-white dark:bg-black dark:border-anakiwa-800 dark:border dark:hover:bg-anakiwa-400"
>
<Icons.edit />
<span className="text-sm duration-200 text-tuatara-950 group-hover:text-white">
<span className="text-sm duration-200 text-primary group-hover:text-white">
{LABELS.COMMON.EDIT_THIS_PAGE}
</span>
</Link>

View File

@@ -13,10 +13,10 @@ export const metadata: Metadata = {
const ResearchPage = async () => {
return (
<div className="flex flex-col gap-10 lg:gap-32 pb-[128px] ">
<div className="w-full bg-page-header-gradient">
<div className="w-full bg-page-header-gradient dark:bg-transparent-gradient">
<AppContent className="flex flex-col gap-4 py-10 w-full">
<Label.PageTitle label={LABELS.RESEARCH_PAGE.TITLE} />
<h6 className="font-sans text-base font-normal text-tuatara-950 md:text-[18px] md:leading-[27px] md:max-w-[700px]">
<h6 className="font-sans text-base font-normal text-primary md:text-[18px] md:leading-[27px] md:max-w-[700px]">
{LABELS.RESEARCH_PAGE.SUBTITLE}
</h6>
</AppContent>

View File

@@ -52,18 +52,20 @@ const ResourceItem = ({
className="group pb-3 duration-500 group-hover:transition self-start"
>
<div className="flex items-center gap-1">
<div className="flex space-x-3">
<div className="h-6 w-6 text-anakiwa-500 opacity-50 transition group-hover:text-tuatara-950 group-hover:opacity-100">
<div className="flex space-x-3 items-center">
<div className="h-6 w-6 text-anakiwa-500 opacity-50 transition group-hover:text-primary group-hover:opacity-100">
<Icon />
</div>
<span className="text-lg font-medium duration-200 group-hover:text-orange">
<span className="text-lg font-medium duration-200 group-hover:text-orange leading-none">
{label}
</span>
</div>
<Icons.externalUrl className="text-tuatara-950 transition duration-200 group-hover:text-orange" />
<Icons.externalUrl className="text-primary transition duration-200 group-hover:text-orange" />
</div>
<div className="p-[2px]"></div>
<p className="text-sm text-tuatara-500 ">{description}</p>
<p className="text-sm text-tuatara-500 dark:text-anakiwa-50">
{description}
</p>
</Link>
)
}
@@ -76,7 +78,7 @@ const ResourceCard = ({ id, title, children }: ResourceCardProps) => {
className="mx-auto flex max-w-[644px] flex-col rounded-lg"
>
<Label.Section label={title} className="pb-8 text-center" />
<div className="mb-4 grid gap-6 rounded-lg border border-tuatara-300 bg-anakiwa-100 px-10 py-8">
<div className="mb-4 grid gap-6 rounded-lg border border-tuatara-300 bg-anakiwa-100 px-10 py-8 dark:border-anakiwa-800 dark:bg-black dark:text-white">
{children}
</div>
</div>
@@ -134,10 +136,10 @@ const ResourceNav = () => {
return (
<div className="flex flex-col gap-6 p-8">
<div className="flex flex-col gap-4">
<h6 className="font-display text-lg font-bold text-tuatara-700">
<h6 className="font-display text-lg font-bold text-secondary dark:text-white">
{LABELS.RESOURCES_PAGE.ON_THIS_PAGE}
</h6>
<ul className="text-normal font-sans text-black">
<ul className="text-normal font-sans text-primary">
{Object.entries(ID_LABELS_MAPPING).map(([id, label]) => {
const active = id === activeId
return (
@@ -167,10 +169,10 @@ const ResourceNav = () => {
export default function ResourcePage() {
return (
<div className="flex flex-col">
<div className="w-full bg-page-header-gradient">
<div className="w-full bg-page-header-gradient dark:bg-transparent-gradient">
<AppContent className="flex flex-col gap-4 py-10 w-full">
<Label.PageTitle label={LABELS.RESOURCES_PAGE.TITLE} />
<h6 className="font-sans text-base font-normal text-tuatara-950 md:text-[18px] md:leading-[27px] md:max-w-[700px]">
<h6 className="font-sans text-base font-normal text-primary md:text-[18px] md:leading-[27px] md:max-w-[700px]">
{LABELS.RESOURCES_PAGE.SUBTITLE}
</h6>
<Link
@@ -191,7 +193,7 @@ export default function ResourcePage() {
</Link>
</AppContent>
</div>
<Divider.Section className="bg-white">
<Divider.Section className="bg-background">
<div className="flex justify-center">
<AppContent className="grid grid-cols-1 gap-6 py-10 md:grid-cols-[3fr_1fr] md:pb-20 lg:grid-cols-[4fr_1fr]">
<div className="flex flex-col gap-6">
@@ -217,7 +219,7 @@ export default function ResourcePage() {
</div>
<Banner
title={
<h3 className="py-2 font-display text-[18px] font-bold text-tuatara-950 md:text-3xl">
<h3 className="py-2 font-display text-[18px] font-bold text-primary md:text-3xl">
{LABELS.RESOURCES_PAGE.ADD_RESOURCE_QUESTION}
</h3>
}

View File

@@ -0,0 +1,28 @@
"use client"
import { useGlobalProvider } from "@/app/providers/GlobalProvider"
import { cn } from "@/lib/utils"
import { ReactNode, useEffect } from "react"
interface ThemeProviderProps {
children: ReactNode
}
export function ThemeProvider({ children }: ThemeProviderProps) {
const { isDarkMode } = useGlobalProvider()
useEffect(() => {
document.documentElement.classList.toggle("dark", isDarkMode)
document.body.classList.toggle("dark", isDarkMode)
}, [isDarkMode])
return (
<div
className={cn("min-h-screen bg-background antialiased", {
dark: isDarkMode,
})}
>
{children}
</div>
)
}

View File

@@ -6,6 +6,7 @@ import { GlobalProviderLayout } from "@/components/layouts/GlobalProviderLayout"
import { SiteFooter } from "@/components/site-footer"
import { SiteHeader } from "@/components/site-header"
import { TailwindIndicator } from "@/components/tailwind-indicator"
import { ThemeProvider } from "./components/layouts/ThemeProvider"
import { siteConfig } from "@/config/site"
import { cn } from "@/lib/utils"
@@ -138,17 +139,16 @@ export default function RootLayout({ children }: RootLayoutProps) {
`}
</Script>
<head />
<body
suppressHydrationWarning
className="min-h-screen bg-background antialiased"
>
<body suppressHydrationWarning>
<GlobalProviderLayout>
<div className="relative flex min-h-screen flex-col">
<SiteHeader />
<div className="flex-1">{children}</div>
<SiteFooter />
</div>
<TailwindIndicator />
<ThemeProvider>
<div className="relative flex min-h-screen flex-col">
<SiteHeader />
<div className="flex-1">{children}</div>
<SiteFooter />
</div>
<TailwindIndicator />
</ThemeProvider>
</GlobalProviderLayout>
</body>
</html>

View File

@@ -41,7 +41,7 @@ export default function NotFound() {
/>
</div>
<div className="flex flex-col gap-5">
<span className="font-display text-2xl font-bold text-tuatara-950 md:text-6xl">
<span className="font-display text-2xl font-bold text-primary md:text-6xl">
{LABELS.COMMON.ERROR["404"].TITLE}
</span>
<span className="font-sans text-base font-normal md:text-lg">

View File

@@ -27,25 +27,47 @@ const queryClient = new QueryClient({
},
})
const PSE_DARK_MODE_KEY = "pse-dark-mode"
export function GlobalProvider({ children }: { children: ReactNode }) {
const [isDarkMode, setIsDarkMode] = useState(false)
const [isInitialized, setIsInitialized] = useState(false)
// Initialize dark mode from system preference
// Initialize dark mode from localStorage or system preference
useEffect(() => {
const storedPreference = localStorage.getItem(PSE_DARK_MODE_KEY)
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)")
setIsDarkMode(mediaQuery.matches)
if (storedPreference !== null) {
setIsDarkMode(storedPreference === "true")
} else {
setIsDarkMode(mediaQuery.matches)
}
setIsInitialized(true)
const handleChange = (e: MediaQueryListEvent) => {
setIsDarkMode(e.matches)
if (localStorage.getItem(PSE_DARK_MODE_KEY) === null) {
setIsDarkMode(e.matches)
}
}
mediaQuery.addEventListener("change", handleChange)
return () => mediaQuery.removeEventListener("change", handleChange)
}, [])
const handleSetIsDarkMode = (value: boolean) => {
setIsDarkMode(value)
localStorage.setItem(PSE_DARK_MODE_KEY, String(value))
}
const value = {
isDarkMode,
setIsDarkMode,
setIsDarkMode: handleSetIsDarkMode,
}
if (!isInitialized) {
return null
}
return (

View File

@@ -10,18 +10,22 @@ type BannerProps = {
const Banner = ({ title, subtitle, children }: BannerProps) => {
return (
<section className="relative bg-white text-center">
<section className="relative bg-background text-center">
<div className="py-16">
<AppContent className="flex flex-col gap-6">
<div className="flex flex-col items-center text-center">
{typeof title === "string" ? (
<h6 className="py-4 font-sans text-base font-bold uppercase tracking-[4px] text-tuatara-950">
<h6 className="py-4 font-sans text-base font-bold uppercase tracking-[4px] text-primary dark:text-white">
{title}
</h6>
) : (
title
)}
{subtitle && <p className="md:max-w-[600px]">{subtitle}</p>}
{subtitle && (
<span className="md:max-w-[600px] font-normal font-sans text-xl text-primary dark:text-white">
{subtitle}
</span>
)}
</div>
{children}
</AppContent>

View File

@@ -3,6 +3,7 @@ import Link from "next/link"
import { Markdown } from "../ui/markdown"
import { Article } from "@/lib/content"
import { getBackgroundImage } from "@/lib/utils"
import { Button } from "../ui/button"
export const ArticleListCard = ({
article,
@@ -24,7 +25,10 @@ export const ArticleListCard = ({
(article.tldr && article.tldr.length > 120 ? "..." : "")
: article.tldr || ""
const tags = article?.tags ?? []
const backgroundImage = getBackgroundImage(article?.image)
const contentClassName =
"font-sans text-sm text-tuatara-600 group-hover:text-primary duration-200 dark:text-tuatara-200"
return (
<div className="flex h-full">
@@ -44,56 +48,43 @@ export const ArticleListCard = ({
backgroundPosition: "center",
}}
></div>
<div className="flex flex-col gap-2 lg:gap-5">
<div className="flex flex-col gap-2 order-2 lg:order-1">
<span className="text-xs font-display lg:text-[22px] font-bold text-tuatara-950 group-hover:text-anakiwa-500 group-hover:underline duration-200 leading-none">
<div className="flex flex-col gap-4 lg:gap-5">
<span className="text-[10px] font-bold tracking-[2.1px] text-tuatara-400 font-sans uppercase dark:text-tuatara-100">
{formattedDate}
</span>
<div className="flex flex-col gap-2">
<span className="text-xs font-display lg:text-[22px] font-bold text-primary group-hover:text-anakiwa-500 group-hover:underline duration-200 lg:leading-6">
{article.title}
</span>
<span className="lg:uppercase text-tuatara-400 lg:text-sm text-[10px] leading-none font-inter">
<span className="lg:uppercase text-tuatara-400 lg:text-xs text-[10px] leading-none font-sans dark:text-tuatara-300">
{article.authors?.map((author) => author).join(", ")}
</span>
<div className="hidden lg:block">
<Markdown
components={{
a: ({ children }) => (
<span className="font-sans text-sm text-tuatara-600 group-hover:text-tuatara-950 duration-200">
{children}
</span>
<span className={contentClassName}>{children}</span>
),
h1: ({ children }) => (
<h1 className="font-sans text-sm text-tuatara-600 group-hover:text-tuatara-950 duration-200">
{children}
</h1>
<h1 className={contentClassName}>{children}</h1>
),
h2: ({ children }) => (
<h2 className="font-sans text-sm text-tuatara-600 group-hover:text-tuatara-950 duration-200">
{children}
</h2>
<h2 className={contentClassName}>{children}</h2>
),
h3: ({ children }) => (
<h3 className="font-sans text-sm text-tuatara-600 group-hover:text-tuatara-950 duration-200">
{children}
</h3>
<h3 className={contentClassName}>{children}</h3>
),
h4: ({ children }) => (
<h4 className="font-sans text-sm text-tuatara-600 group-hover:text-tuatara-950 duration-200">
{children}
</h4>
<h4 className={contentClassName}>{children}</h4>
),
h5: ({ children }) => (
<h5 className="font-sans text-sm text-tuatara-600 group-hover:text-tuatara-950 duration-200">
{children}
</h5>
<h5 className={contentClassName}>{children}</h5>
),
h6: ({ children }) => (
<h6 className="font-sans text-sm text-tuatara-600 group-hover:text-tuatara-950 duration-200">
{children}
</h6>
<h6 className={contentClassName}>{children}</h6>
),
p: ({ children }) => (
<p className="font-sans text-sm text-tuatara-600 group-hover:text-tuatara-950 duration-200">
{children}
</p>
<p className={contentClassName}>{children}</p>
),
img: ({ src, alt }) => null,
}}
@@ -102,12 +93,17 @@ export const ArticleListCard = ({
</Markdown>
</div>
</div>
<span
className="order-1 lg:order-2 text-[10px] font-bold tracking-[2.1px] text-tuatara-400 font-sans
uppercase"
>
{formattedDate}
</span>
{tags?.length > 0 && (
<div className="flex flex-wrap gap-2">
{tags.slice(0, 5).map((tag) => (
<Link key={tag.id} href={`/blog/tags/${tag.id}`}>
<Button size="xs" variant="secondary">
{tag.name}
</Button>
</Link>
))}
</div>
)}
</div>
</div>
</Link>

View File

@@ -4,7 +4,7 @@ import { cva } from "class-variance-authority"
import Image from "next/image"
export const blogArticleCardTagCardVariants = cva(
"text-xs font-sans text-tuatara-950 rounded-[3px] py-[2px] px-[6px] w-fit shrink-[0]",
"text-xs font-sans text-primary rounded-[3px] py-[2px] px-[6px] w-fit shrink-[0] dark:text-black",
{
variants: {
variant: {

View File

@@ -23,7 +23,7 @@ export const BlogArticleRelatedProjects = ({
return (
<div className="flex flex-col gap-8">
<h3 className="text-tuatara-950 text-lg font-semibold leading-6">
<h3 className="text-primary text-lg font-semibold leading-6">
Related projects
</h3>
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 md:gap-x-6 md:gap-y-10 lg:grid-cols-3">

View File

@@ -70,7 +70,7 @@ export function BlogContent({ post, isNewsletter = false }: BlogContentProps) {
{moreArticles?.length > 0 && (
<div className="flex flex-col gap-8">
<div className="flex items-center justify-between">
<span className="text-tuatara-950 text-lg font-semibold leading-6">
<span className="text-primary text-lg font-semibold leading-6">
More articles
</span>
<Link

View File

@@ -143,7 +143,7 @@ export async function BlogRecentArticles() {
<div className="py-10 lg:py-16">
<AppContent>
<div className="flex flex-col gap-10">
<h3 className="text-base font-bold font-sans text-center uppercase tracking-[3.36px]">
<h3 className="font-sans text-base font-bold uppercase tracking-[4px] text-primary text-center">
{LABELS.BLOG_PAGE.RECENT_ARTICLES}
</h3>
<div className="grid grid-cols-1 lg:grid-cols-5 gap-10 lg:gap-x-14 lg:max-w-[1200px] mx-auto relative">
@@ -164,7 +164,7 @@ export async function BlogRecentArticles() {
href={`/blog/${article.id}`}
className={cn("group border-b pb-4")}
>
<h4 className="text-xl font-medium text-tuatara-950 duration-200 group-hover:text-anakiwa-500 transition-colors">
<h4 className="text-xl font-medium text-primary duration-200 group-hover:text-anakiwa-500 transition-colors">
{article.title}
</h4>
{article.authors && (

View File

@@ -33,12 +33,12 @@ export const ProjectBlogArticles = ({
key={i}
className="grid grid-cols-[80px_1fr] lg:grid-cols-[120px_1fr] items-center gap-4 lg:gap-10"
>
<div className="size-[80px] lg:size-[120px] rounded-full bg-slate-200 animate-pulse"></div>
<div className="size-[80px] lg:size-[120px] rounded-full bg-skeleton animate-pulse"></div>
<div className="flex flex-col gap-2">
<div className="h-5 w-full bg-slate-200 animate-pulse"></div>
<div className="h-4 w-full bg-slate-200 animate-pulse"></div>
<div className="h-4 w-2/3 bg-slate-200 animate-pulse "></div>
<div className="h-2 w-14 bg-slate-200 animate-pulse "></div>
<div className="h-5 w-full bg-skeleton animate-pulse"></div>
<div className="h-4 w-full bg-skeleton animate-pulse"></div>
<div className="h-4 w-2/3 bg-skeleton animate-pulse "></div>
<div className="h-2 w-14 bg-skeleton animate-pulse "></div>
</div>
</div>
))}
@@ -60,7 +60,7 @@ export const ProjectBlogArticles = ({
className="py-10 lg:py-16 w-full"
>
<div className="flex flex-col gap-10">
<h3 className="text-[22px] font-bold text-tuatara-700">
<h3 className="text-[22px] font-bold text-secondary">
Related articles
</h3>
<div className="grid grid-cols-1 gap-4 lg:gap-8">

View File

@@ -5,7 +5,7 @@ import { cn } from "@/lib/utils"
const cardVariants = cva("flex flex-col rounded-[8px] overflow-hidden", {
variants: {
variant: {
blue: "bg-anakiwa-100 border border-tuatara-300",
blue: "bg-anakiwa-100 border border-tuatara-300 dark:bg-black dark:border-anakiwa-800",
transparent: "bg-transparent border border-tuatara-300",
},
padding: {

View File

@@ -21,8 +21,8 @@ export const TableRowCard = ({ items, className }: TableRowCardProps) => {
key={index}
className="grid grid-cols-1 divide-tuatara-300 md:grid-cols-[1fr_2.5fr] md:divide-x"
>
<div className="flex h-[96px] items-center justify-center border-b border-tuatara-300 bg-anakiwa-100 p-2 text-center md:border-none">
<span className="max-w-[136px] text-xs font-bold uppercase tracking-[2.5px] text-tuatara-950">
<div className="flex h-[96px] items-center justify-center border-b border-tuatara-300 bg-anakiwa-100 p-2 text-center md:border-none dark:bg-anakiwa-800">
<span className="max-w-[136px] text-xs font-bold uppercase tracking-[2.5px] text-primary">
{item.title}
</span>
</div>

View File

@@ -32,11 +32,11 @@ const WikiDetail = ({ label, value }: WikiDetailProps) => {
return (
<div className="grid grid-cols-1 gap-2 md:grid-cols-[90px_1fr] md:items-start md:gap-5">
<div className="break-all font-sans text-xs font-bold leading-[14px] text-black">
<div className="break-all font-sans text-xs font-bold leading-[14px] text-primary">
{label}
</div>
{typeof value === "string" ? (
<span className="font-sans text-xs font-normal leading-[18px] text-black">
<span className="font-sans text-xs font-normal leading-[18px] text-primary">
{value}
</span>
) : (
@@ -71,7 +71,7 @@ export const WikiCard = ({ project, className = "" }: WikiCardProps) => {
return (
<div className={cn("flex flex-col gap-6", className)}>
<div className="mx-auto flex max-w-[290px] flex-col gap-6">
<Card className="bg-white" padding="none">
<Card className="bg-background" padding="none">
<div className="relative flex h-[140px] items-center justify-center overflow-hidden rounded-t-lg">
<Image
src={`/project-banners/${
@@ -147,7 +147,7 @@ export const WikiCard = ({ project, className = "" }: WikiCardProps) => {
</span>
)}
</div>
<div className="flex items-center justify-center py-4 bg-white">
<div className="flex items-center justify-center py-4 bg-background">
<span className="text-xs font-normal text-black">
{LABELS.COMMON.PREV_BRAND_IMAGE}
</span>

View File

@@ -4,7 +4,12 @@ import { cn } from "@/lib/utils"
const Section = ({ children, className }: HTMLAttributes<HTMLDivElement>) => {
return (
<div className={cn("divide-y divide-tuatara-300 w-full", className)}>
<div
className={cn(
"divide-y divide-tuatara-300 w-full dark:divide-anakiwa-800",
className
)}
>
{children}
</div>
)

View File

@@ -56,6 +56,22 @@ export const Icons = {
/>
</svg>
),
Burgher: (props: LucideProps) => (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
id="Vector"
d="M18 18V20H6V18H18ZM21 11V13H3V11H21ZM18 4V6H6V4H18Z"
fill="currentColor"
/>
</svg>
),
eventLocation: (props: LucideProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
@@ -117,11 +133,33 @@ export const Icons = {
),
close: X,
check: Check,
logo: (props: LucideProps) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" {...props}>
Logo: (props: LucideProps) => (
<svg
fill="none"
height={props.size || 48}
viewBox="0 0 49 48"
width={props.size || 49}
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
d="m48.3357 27.0002c0 .8711-.6236 1.5945-1.4472 1.7617-.1176.0233-.2392.035-.3647.035h-6.0513c-1.0039 0-1.8157.805-1.8157 1.8005v6.0005c0 .6222-.3177 1.1667-.8001 1.4933-.1921.1284-.4118.2217-.6471.2722-.1176.0234-.2392.035-.3647.035h-6.0513c-1.0039 0-1.8157.805-1.8157 1.8006v6.0005c0 .9955-.8118 1.8005-1.8158 1.8005h-6.0513c-1.0039 0-1.8157-.805-1.8157-1.8005v-6.0005c0-.9956.8118-1.8006 1.8157-1.8006h6.0513c1.004 0 1.8158-.8049 1.8158-1.8005v-6.0005c0-.9955.8118-1.8005 1.8157-1.8005h6.0513c1.004 0 1.8158-.805 1.8158-1.8005v-7.8011c0-5.2888-4.3139-9.58208-9.6475-9.59763-5.3297.01944-9.6476 4.30883-9.6476 9.59763v7.8011c0 .9955-.8118 1.8005-1.8157 1.8005h-6.0513c-1.004 0-1.81578.805-1.81578 1.8005v15.6021c0 .9955-.8118 1.8005-1.81577 1.8005h-6.05128c-1.003966 0-1.81577-.805-1.81577-1.8005v-15.6021c0-.9955.811804-1.8005 1.81577-1.8005h6.05128c1.00397 0 1.81577-.805 1.81577-1.8005v-7.8361c0-10.58151 8.65138-19.1603 19.32638-19.1603 10.6751 0 19.3265 8.57879 19.3265 19.1642z"
fill="currentColor"
/>
</svg>
),
Filter: (props: LucideProps) => (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
d="M15 12.75C13.6065 12.75 12.4418 13.71 12.1065 15H3V16.5H12.1065C12.4418 17.79 13.6065 18.75 15 18.75C16.3935 18.75 17.5583 17.79 17.8935 16.5H21V15H17.8935C17.5583 13.71 16.3935 12.75 15 12.75ZM9 6C7.6065 6 6.44175 6.96 6.1065 8.25H3V9.75H6.1065C6.44175 11.04 7.6065 12 9 12C10.3935 12 11.5583 11.04 11.8935 9.75H21V8.25H11.8935C11.5583 6.96 10.3935 6 9 6Z"
fill="currentColor"
d="M11.572 0c-.176 0-.31.001-.358.007a19.76 19.76 0 0 1-.364.033C7.443.346 4.25 2.185 2.228 5.012a11.875 11.875 0 0 0-2.119 5.243c-.096.659-.108.854-.108 1.747s.012 1.089.108 1.748c.652 4.506 3.86 8.292 8.209 9.695.779.25 1.6.422 2.534.525.363.04 1.935.04 2.299 0 1.611-.178 2.977-.577 4.323-1.264.207-.106.247-.134.219-.158-.02-.013-.9-1.193-1.955-2.62l-1.919-2.592-2.404-3.558a338.739 338.739 0 0 0-2.422-3.556c-.009-.002-.018 1.579-.023 3.51-.007 3.38-.01 3.515-.052 3.595a.426.426 0 0 1-.206.214c-.075.037-.14.044-.495.044H7.81l-.108-.068a.438.438 0 0 1-.157-.171l-.05-.106.006-4.703.007-4.705.072-.092a.645.645 0 0 1 .174-.143c.096-.047.134-.051.54-.051.478 0 .558.018.682.154.035.038 1.337 1.999 2.895 4.361a10760.433 10760.433 0 0 0 4.735 7.17l1.9 2.879.096-.063a12.317 12.317 0 0 0 2.466-2.163 11.944 11.944 0 0 0 2.824-6.134c.096-.66.108-.854.108-1.748 0-.893-.012-1.088-.108-1.747-.652-4.506-3.859-8.292-8.208-9.695a12.597 12.597 0 0 0-2.499-.523A33.119 33.119 0 0 0 11.573 0zm4.069 7.217c.347 0 .408.005.486.047a.473.473 0 0 1 .237.277c.018.06.023 1.365.018 4.304l-.006 4.218-.744-1.14-.746-1.14v-3.066c0-1.982.01-3.097.023-3.15a.478.478 0 0 1 .233-.296c.096-.05.13-.054.5-.054z"
/>
</svg>
),

View File

@@ -1,15 +1,16 @@
"use client"
import Image from "next/image"
import Link from "next/link"
import { usePathname } from "next/navigation"
import { useState } from "react"
import PSELogo from "@/public/logos/header-logo.svg"
import { NavItem } from "@/types/nav"
import { cn } from "@/lib/utils"
import { SearchButton } from "@/components/search/search-button"
import { SearchModal } from "@/components/search/search-modal"
import { Icons } from "./icons"
import { SunMedium as SunIcon, Moon as MoonIcon } from "lucide-react"
import { useGlobalProvider } from "@/app/providers/GlobalProvider"
export interface MainNavProps {
items: NavItem[]
@@ -18,12 +19,13 @@ export interface MainNavProps {
export function MainNav({ items }: MainNavProps) {
const router = usePathname()
const [isSearchModalOpen, setIsSearchModalOpen] = useState(false)
const { isDarkMode, setIsDarkMode } = useGlobalProvider()
return (
<div className="flex flex-1 items-center justify-between gap-6 md:gap-10">
<div className="flex items-center gap-6 md:gap-10">
<Link href="/" className="flex items-center space-x-2">
<Image src={PSELogo} alt="PSE Logo" width={32} height={32} />
<Icons.Logo className="text-black dark:text-anakiwa-400" size={32} />
</Link>
<nav className="hidden items-center gap-6 md:flex">
{items.map((item, index) => {
@@ -64,10 +66,16 @@ export function MainNav({ items }: MainNavProps) {
</nav>
</div>
<div className="flex items-center mr-5">
<div className="w-60">
<div className="flex items-center mr-5 gap-4 lg:gap-10">
<div className="w-60 mx-auto lg:mx-0 lg:ml-auto">
<SearchButton onClick={() => setIsSearchModalOpen(true)} />
</div>
<button
onClick={() => setIsDarkMode(!isDarkMode)}
className="text-black dark:text-anakiwa-400 ml-auto hidden lg:inline-block"
>
{isDarkMode ? <SunIcon size={20} /> : <MoonIcon size={20} />}
</button>
</div>
<SearchModal open={isSearchModalOpen} setOpen={setIsSearchModalOpen} />

View File

@@ -24,14 +24,14 @@ const PageHeader = ({
size = "small",
}: PageHeaderProps) => {
return (
<div className="flex h-full w-full items-center bg-cover-gradient md:h-[600px]">
<div className="flex h-full w-full items-center bg-cover-gradient md:h-[600px] dark:bg-transparent-gradient">
<AppContent className="relative flex flex-col w-full gap-10 py-10 md:gap-14 md:py-20">
<div className="flex flex-col items-start justify-between gap-10 md:flex-row md:gap-28">
<div className="flex w-full flex-col justify-center gap-6 md:max-w-[700px] md:gap-8 lg:gap-14">
<div className="flex flex-col gap-4 md:gap-8">
<Label.PageTitle label={title} size={size} />
{subtitle && (
<h6 className="font-sans text-base font-normal text-tuatara-950 md:text-[18px] md:leading-[27px]">
<h6 className="font-sans text-base font-normal text-primary md:text-[18px] md:leading-[27px] dark:text-tuatara-100">
{subtitle}
</h6>
)}

View File

@@ -37,7 +37,7 @@ export default function DiscoverMoreProjects({ project }: ProjectProps) {
}, [allProjects, project.id, project.tags?.themes, onFilterProject])
return (
<div className="w-full bg-cover-gradient">
<div className="w-full bg-cover-gradient dark:bg-transparent-gradient">
<div className="mx-auto flex w-full max-w-[644px] flex-col items-center justify-center gap-14 px-6 py-12 md:px-0 md:py-16">
<h2 className="text-3xl font-bold text-center">
{LABELS.COMMON.DISCOVER_MORE}
@@ -48,7 +48,7 @@ export default function DiscoverMoreProjects({ project }: ProjectProps) {
))}
</div>
<Link
className="flex items-center gap-2 text-tuatara-950/80 hover:text-tuatara-950"
className="flex items-center gap-2 text-primary/80 hover:text-primary"
href="/projects"
>
<Icons.arrowLeft />

View File

@@ -23,7 +23,7 @@ interface ProjectCardProps
}
const tagCardVariants = cva(
"text-xs font-sans text-tuatara-950 rounded-[3px] py-[2px] px-[6px]",
"text-xs font-sans text-white rounded-[3px] py-[2px] px-[6px] dark:text-black",
{
variants: {
variant: {
@@ -42,7 +42,7 @@ const projectCardVariants = cva(
false: "min-h-[200px]",
},
border: {
true: "border border-slate-900/20",
true: "border border-slate-900/20 dark:border-anakiwa-800",
},
},
}
@@ -94,16 +94,18 @@ export default function ProjectCard({
)}
</div>
)}
<div className="flex flex-col justify-between h-full gap-8 p-4 bg-white rounded-b-lg">
<div className="flex flex-col justify-between h-full gap-8 p-4 bg-white rounded-b-lg dark:bg-black">
<div className="flex flex-col justify-start gap-2">
<Link href={`/projects/${id}`}>
<h1 className="text-2xl font-bold leading-7 text-black duration-200 cursor-pointer hover:text-anakiwa-500">
<h1 className="text-2xl font-bold leading-7 text-primary duration-200 cursor-pointer hover:text-anakiwa-500">
{name}
</h1>
</Link>
{(tldr ?? "")?.length > 0 && (
<div className="flex flex-col h-24 gap-4">
<p className="text-slate-900/80 line-clamp-4">{tldr}</p>
<p className="text-slate-900/80 line-clamp-4 dark:text-tuatara-200">
{tldr}
</p>
</div>
)}
</div>
@@ -124,7 +126,7 @@ export default function ProjectCard({
)}
<div
className="px-[6px] py-[2px] text-xs font-normal leading-none flex items-center justify-center rounded-[3px]"
className="px-[6px] py-[2px] text-xs font-normal leading-none flex items-center justify-center rounded-[3px] text-white dark:text-black"
style={{
backgroundColor: ProjectStatusColorMapping[projectStatus],
}}

View File

@@ -25,7 +25,7 @@ interface TagGroup {
const TagsWrapper = ({ label, children }: TagsProps) => {
return (
<div className="flex flex-col items-start gap-2">
<h3 className="text-[22px] font-bold text-tuatara-700">{label}</h3>
<h3 className="text-[22px] font-bold text-secondary">{label}</h3>
{children}
</div>
)

View File

@@ -59,7 +59,7 @@ export default function ProjectExtraLinks({ project }: ProjectExtraLinksProps) {
return (
<div className="flex flex-col gap-2" data-section-id={id}>
<div className="flex items-center gap-2">
<p className="text-[22px] font-bold text-tuatara-700">{label}</p>
<p className="text-[22px] font-bold text-secondary">{label}</p>
</div>
<div className="flex flex-col items-start gap-2">
{links.map((link: ActionLinkTypeLink, index) => {
@@ -70,7 +70,7 @@ export default function ProjectExtraLinks({ project }: ProjectExtraLinksProps) {
key={index}
href={url}
target="_blank"
className="flex items-center gap-1 overflow-hidden font-sans font-normal duration-200 ease-in-out border-b cursor-pointer border-anakiwa-400 text-tuatara-950 hover:border-orange"
className="flex items-center gap-1 overflow-hidden font-sans font-normal duration-200 ease-in-out border-b cursor-pointer border-anakiwa-400 text-primary hover:border-orange"
>
{label}
<Icons.externalUrl />

View File

@@ -1,14 +1,10 @@
"use client"
import React, { ChangeEvent, ReactNode, useEffect, useState } from "react"
import Image from "next/image"
import { useRouter, useSearchParams } from "next/navigation"
import FiltersIcon from "@/public/icons/filters.svg"
import { useDebounce } from "react-use"
import { IThemeStatus, IThemesButton } from "@/types/common"
import {
ProjectCategories,
ProjectCategory,
ProjectSectionLabelMapping,
ProjectSections,
ProjectStatus,
@@ -46,7 +42,7 @@ interface FilterWrapperProps {
const FilterWrapper = ({ label, children, className }: FilterWrapperProps) => {
return (
<div className={cn("flex flex-col gap-4 py-6", className)}>
<span className="text-sm font-medium text-tuatara-950 md:text-base">
<span className="text-sm font-medium text-primary md:text-base">
{label}
</span>
{children}
@@ -276,7 +272,7 @@ export default function ProjectFiltersBar() {
})}
>
<div className="flex items-center gap-2">
<Image src={FiltersIcon} alt="filter icon" />
<Icons.Filter className="text-anakiwa-950 dark:text-anakiwa-400" />
<span className="hidden md:block">
{LABELS.COMMON.FILTERS}
</span>
@@ -286,9 +282,9 @@ export default function ProjectFiltersBar() {
<button
disabled={!hasActiveFilters}
onClick={clearAllFilters}
className="hidden bg-transparent cursor-pointer opacity-85 text-primary hover:opacity-100 disabled:pointer-events-none disabled:opacity-50 md:block"
className="hidden bg-transparent cursor-pointer opacity-85 text-primary hover:opacity-100 disabled:pointer-events-none disabled:opacity-50 md:block dark:text-anakiwa-400 dark:hover:text-anakiwa-400"
>
<div className="flex items-center gap-2 border-b-2 border-black">
<div className="flex items-center gap-2 border-b-2 border-black dark:border-anakiwa-800">
<span className="text-sm font-medium">
{LABELS.COMMON.CLEAR_ALL}
</span>

View File

@@ -20,7 +20,18 @@ import ProjectCard from "./project-card"
import { useProjects } from "@/app/providers/ProjectsProvider"
const sectionTitleClass = cva(
"relative font-sans text-base font-bold uppercase tracking-[3.36px] text-anakiwa-950 after:ml-8 after:absolute after:top-1/2 after:h-[1px] after:w-full after:translate-y-1/2 after:bg-anakiwa-300 after:content-['']"
"relative font-sans text-base font-bold uppercase tracking-[3.36px] text-anakiwa-950 dark:text-anakiwa-400 dark:text-white",
{
variants: {
variant: {
default:
"after:ml-8 after:absolute after:top-1/2 after:h-[1px] after:w-full after:translate-y-1/2 after:bg-anakiwa-300 after:content-['']",
},
},
defaultVariants: {
variant: "default",
},
}
)
const NoResults = () => {
@@ -29,10 +40,10 @@ const NoResults = () => {
<div className="mx-auto">
<Image className="h-9 w-9" src={NoResultIcon} alt="no result icon" />
</div>
<span className="text-2xl font-bold font-display text-tuatara-950">
<span className="text-2xl font-bold font-display text-primary">
{LABELS.COMMON.NO_RESULTS}
</span>
<span className="text-lg font-normal text-tuatara-950">
<span className="text-lg font-normal text-primary">
{LABELS.COMMON.NO_RESULTS_DESCRIPTION}
</span>
</div>
@@ -170,7 +181,7 @@ export const ProjectList = () => {
{!hasSearchParams && (
<div className="flex flex-col gap-6 overflow-hidden">
<h3 className={cn(sectionTitleClass())}>{status}</h3>
<span className="font-sans text-base italic text-tuatara-950">
<span className="font-sans text-base italic text-primary">
{description}
</span>
</div>
@@ -194,7 +205,7 @@ export const ProjectList = () => {
<div id="sidebar" className="sticky hidden p-8 top-20 bg-white/30">
<div className="flex flex-col gap-4">
<h6 className="text-lg font-bold font-display text-tuatara-700">
<h6 className="text-lg font-bold font-display text-secondary">
{LABELS.RESOURCES_PAGE.ON_THIS_PAGE}
</h6>
<ul className="font-sans text-black text-normal">

View File

@@ -12,7 +12,8 @@ import { interpolate } from "@/lib/utils"
import { CategoryTag } from "../ui/categoryTag"
import { Dropdown } from "../ui/dropdown"
const labelClass = "h-5 text-xs text-base md:h-6 text-slate-900/70 md:text-sm"
const labelClass =
"h-5 text-xs text-base md:h-6 text-slate-900/70 md:text-sm dark:text-white"
export const ProjectResultBar = () => {
const { activeFilters, toggleFilter, projects, sortProjectBy, sortBy } =

View File

@@ -16,7 +16,7 @@ export const ProjectTeamMembers = ({ team }: ProjectTeamMembersProps) => {
return (
<div className="w-full" id="team" data-section-id="team">
<h2 className="text-[22px] font-bold text-tuatara-700 mb-6">
<h2 className="text-[22px] font-bold text-secondary mb-6">
{LABELS.COMMON.PROJECT_TEAM}
</h2>
@@ -24,7 +24,7 @@ export const ProjectTeamMembers = ({ team }: ProjectTeamMembersProps) => {
{team.map((member, index) => (
<div
key={`${member.name}-${index}`}
className="flex flex-col gap-2 p-4 border border-black/10 rounded-md bg-white"
className="flex flex-col gap-2 p-4 border border-black/10 rounded-md bg-transparent dark:border-anakiwa-800"
>
<div className="flex items-center gap-4">
{member.image ? (
@@ -54,7 +54,7 @@ export const ProjectTeamMembers = ({ team }: ProjectTeamMembersProps) => {
{member.email && (
<a
href={`mailto:${member.email}`}
className="font-sans text-sm text-tuatara-600 hover:text-orange transition-colors mt-1 flex items-center gap-1.5"
className="font-sans text-sm text-tuatara-600 hover:text-orange transition-colors mt-1 flex items-center gap-1.5 dark:text-white"
>
<Icons.email className="h-4 w-4" />
<span>{member.email}</span>

View File

@@ -27,7 +27,7 @@ interface ProjectCardProps
}
const tagCardVariants = cva(
"text-xs font-sans text-tuatara-950 rounded-[3px] py-[2px] px-[6px]",
"text-xs font-sans text-primary rounded-[3px] py-[2px] px-[6px]",
{
variants: {
variant: {
@@ -90,12 +90,7 @@ export default function ProjectCard({
)}
>
{showBanner && (
<div
className="relative flex flex-col border-b border-black/10 cursor-pointer"
onClick={() => {
router.push(`/projects/${id?.toLowerCase()}`)
}}
>
<div className="relative flex flex-col border-b border-black/10 cursor-pointer">
<Image
src={`/project-banners/${image ? image : "fallback.webp"}`}
alt={`${name} banner`}
@@ -112,21 +107,23 @@ export default function ProjectCard({
)}
<div
className={cn(
"flex flex-col justify-between h-full gap-8 p-[30px] bg-white rounded-b-lg hover:bg-research-card-gradient duration-300",
"flex flex-col justify-between h-full rounded-lg overflow-hidden gap-8 p-[30px] hover:bg-research-card-gradient duration-300 dark:border dark:border-anakiwa-800",
contentClassName,
{
"bg-white": !showBanner,
"bg-white dark:bg-black": !showBanner,
"bg-transparent": showBanner,
}
)}
>
<div className="flex flex-col justify-start gap-2">
<h1 className="text-2xl font-bold leading-7 duration-200 cursor-pointer text-anakiwa-700 line-clamp-2">
<h1 className="text-2xl font-bold leading-7 duration-200 cursor-pointer text-anakiwa-700 line-clamp-2 dark:text-white">
{name}
</h1>
{(tldr ?? "")?.length > 0 && (
<div className="flex flex-col h-24 gap-4">
<p className="text-slate-900/80 line-clamp-3">{tldr}</p>
<p className="text-slate-900/80 line-clamp-3 dark:text-anakiwa-100">
{tldr}
</p>
</div>
)}
</div>

View File

@@ -14,7 +14,7 @@ import ResearchCard from "./research-card"
import Link from "next/link"
const sectionTitleClass = cva(
"relative font-sans text-base font-bold uppercase tracking-[3.36px] text-anakiwa-950 after:ml-8 after:absolute after:top-1/2 after:h-[1px] after:w-full after:translate-y-1/2 after:bg-anakiwa-300 after:content-['']"
"relative font-sans text-base font-bold uppercase tracking-[3.36px] text-anakiwa-950 after:ml-8 after:absolute after:top-1/2 after:h-[1px] after:w-full after:translate-y-1/2 after:bg-anakiwa-300 after:content-[''] dark:text-white"
)
const NoResults = () => {
@@ -23,10 +23,10 @@ const NoResults = () => {
<div className="mx-auto">
<Image className="h-9 w-9" src={NoResultIcon} alt="no result icon" />
</div>
<span className="text-2xl font-bold font-display text-tuatara-950">
<span className="text-2xl font-bold font-display text-primary">
{LABELS.COMMON.NO_RESULTS}
</span>
<span className="text-lg font-normal text-tuatara-950">
<span className="text-lg font-normal text-primary">
{LABELS.COMMON.NO_RESULTS_DESCRIPTION}
</span>
</div>
@@ -126,7 +126,7 @@ export const ResearchList = () => {
<Link
href={`/projects/${project?.id}`}
key={project?.id}
className="text-neutral-950 border-b-[2px] border-b-anakiwa-500 text-sm font-medium w-fit hover:text-anakiwa-500 duration-200"
className="text-neutral-950 border-b-[2px] border-b-anakiwa-500 text-sm font-medium w-fit hover:text-anakiwa-500 duration-200 dark:text-white"
>
{project.name}
</Link>

View File

@@ -77,11 +77,11 @@ function Hit({
return (
<Link
href={url}
className="block p-4 mb-2 bg-white hover:bg-gray-100 rounded-md shadow-sm border border-gray-200 text-black"
className="block p-4 mb-2 bg-background hover:bg-gray-100 rounded-md shadow-sm border border-gray-200 text-black dark:border-anakiwa-800 dark:hover:bg-anakiwa-400/10"
onClick={() => setOpen(false)}
>
<div className="flex items-center justify-between mb-1">
<h3 className="text-lg font-semibold text-gray-900">{title}</h3>
<h3 className="text-lg font-semibold text-primary">{title}</h3>
<CategoryTag variant="blue">{section}</CategoryTag>
</div>
{snippet && (
@@ -109,7 +109,7 @@ function Hit({
})
return (
<span className="text-tuatara-700 font-sans text-base font-normal">
<span className="text-secondary font-sans text-base font-normal">
{textContent}
</span>
)
@@ -125,7 +125,7 @@ function Hit({
function NoResults() {
return (
<div className="text-center p-8 text-gray-500">
<div className="text-center p-8 text-gray-500 dark:text-white">
No results found. Try a different search term.
</div>
)
@@ -133,7 +133,7 @@ function NoResults() {
const LoadingIndicator = () => {
return (
<div className="h-12 w-full rounded-md bg-gray-100 animate-pulse border border-gray-300"></div>
<div className="h-12 w-full rounded-md bg-skeleton animate-pulse border border-gray-300 dark:bg-anakiwa-800 dark:border-anakiwa-700"></div>
)
}
@@ -174,7 +174,7 @@ function DirectSearchResults({
<div key={indexResult.indexName}>
{indexResult.hits.length > 0 && (
<div className="mb-4">
<div className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-2">
<div className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-2 dark:text-white">
{indexResult.indexName}
</div>
{indexResult.hits.map((hit: SearchHit) => (
@@ -283,7 +283,7 @@ const CustomSearchResult = ({
<div>
{results.map((indexResult: IndexResult) => (
<div key={indexResult.indexName} className="mb-6">
<div className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-2">
<div className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-2 dark:text-white">
{indexResult.indexName.replace(/-/g, " ")}
</div>
<div>
@@ -312,7 +312,7 @@ const MultiIndexSearchView = ({
if (searchQuery.trim() === "") {
return (
<div className="text-center p-8 text-gray-500">
<div className="text-center p-8 text-gray-500 dark:text-white">
Enter a search term to begin
</div>
)
@@ -342,7 +342,7 @@ const MultiIndexSearchView = ({
<div>
{sortedIndexes.map((indexName: string) => (
<div key={indexName} className="mb-6">
<div className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-2">
<div className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-2 dark:text-white">
{indexName.replace(/-/g, " ")}
</div>
<IndexSearchResults
@@ -393,7 +393,11 @@ export const SearchModal = ({ open, setOpen }: SearchModalProps) => {
}
return (
<Modal open={open} setOpen={setOpen} className="bg-page-header-gradient">
<Modal
open={open}
setOpen={setOpen}
className="bg-page-header-gradient dark:bg-transparent-gradient"
>
<div className="pt-8">
<Input
type="text"

View File

@@ -11,7 +11,7 @@ import { Button } from "../ui/button"
const ConnectWithUs = () => {
return (
<div className="bg-white py-14 md:pb-32 md:pt-16">
<div className="py-14 md:pb-32 md:pt-16">
<div className="flex flex-col gap-10">
<h3 className="text-center font-sans text-base font-bold uppercase tracking-[3.36px]">
{interpolate(LABELS.COMMON.OUR_YEAR_PROGRAM, {

View File

@@ -23,7 +23,7 @@ export const HomepageBanner = () => {
<Button>
<div className="flex items-center gap-2">
<Icons.discord fill="white" className="h-4" />
<span className="text-[14px] uppercase">
<span className="uppercase">
{LABELS.HOMEPAGE.JOIN_OUR_DISCORD}
</span>
<Icons.externalUrl fill="white" className="h-5" />

View File

@@ -37,7 +37,7 @@ export const HomepageHeader = () => {
}
actions={
<div className="flex flex-col gap-4 lg:flex-row lg:gap-10">
<Link href={"/research"} className="flex items-center gap-2 group">
<Link href="/research" className="flex items-center gap-2 group">
<Button className="w-full sm:w-auto">
<div className="flex items-center gap-1">
<span className="text-base font-medium uppercase">
@@ -50,7 +50,7 @@ export const HomepageHeader = () => {
</div>
</Button>
</Link>
<Link href={"/projects"} className="flex items-center gap-2 group">
<Link href="/projects" className="flex items-center gap-2 group">
<Button className="w-full sm:w-auto">
<div className="flex items-center gap-1">
<span className="text-base font-medium uppercase">

View File

@@ -51,16 +51,16 @@ const VideoCardSkeleton = () => {
return (
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6 lg:gap-8">
<div className="flex flex-col gap-1">
<div className="bg-slate-200 aspect-video w-full animate-pulse"></div>
<div className="bg-slate-200 h-3 w-full animate-pulse"></div>
<div className="bg-skeleton aspect-video w-full animate-pulse"></div>
<div className="bg-skeleton h-3 w-full animate-pulse"></div>
</div>
<div className="flex flex-col gap-1">
<div className="bg-slate-200 aspect-video w-full animate-pulse"></div>
<div className="bg-slate-200 h-3 w-full animate-pulse"></div>
<div className="bg-skeleton aspect-video w-full animate-pulse"></div>
<div className="bg-skeleton h-3 w-full animate-pulse"></div>
</div>
<div className="flex flex-col gap-1">
<div className="bg-slate-200 aspect-video w-full animate-pulse"></div>
<div className="bg-slate-200 h-3 w-full animate-pulse"></div>
<div className="bg-skeleton aspect-video w-full animate-pulse"></div>
<div className="bg-skeleton h-3 w-full animate-pulse"></div>
</div>
</div>
)
@@ -70,14 +70,14 @@ export const HomepageVideoFeed = () => {
const { data: videos = [], isLoading, isError } = useYoutube()
return (
<section className="mx-auto px-6 lg:px-8 py-10 lg:py-16 bg-tuatara-950">
<section className="mx-auto px-6 lg:px-8 py-10 lg:py-16 bg-tuatara-950 dark:bg-black">
<AppContent className="flex flex-col gap-8 lg:max-w-[1200px] w-full">
<div className="col-span-1 lg:col-span-4">
<h2 className="text-base text-center font-sans font-bold text-white">
<h2 className="font-sans text-base font-bold uppercase tracking-[4px] text-primary text-center">
{LABELS.HOMEPAGE.VIDEOS}
</h2>
</div>
<div className="grid grid-cols-1 lg:grid-cols-4 gap-10 lg:gap-8 lg:divide-x divide-[#626262]">
<div className="grid grid-cols-1 lg:grid-cols-[1fr_1fr_1fr_280px] gap-10 lg:gap-8 lg:divide-x divide-[#626262]">
<div className="lg:col-span-3">
{isLoading ? (
<VideoCardSkeleton />
@@ -109,7 +109,7 @@ export const HomepageVideoFeed = () => {
>
<Button className="w-full" variant="orange">
<div className="flex items-center gap-1">
<span className="text-base font-medium uppercase">
<span className="font-medium uppercase">
{LABELS.HOMEPAGE.VISIT_OUR_CHANNEL}
</span>
<ArrowRight className="h-5 w-5 duration-200 ease-in-out group-hover:translate-x-2" />

View File

@@ -13,12 +13,12 @@ import { Parser as HtmlToReactParser } from "html-to-react"
const ContentPlaceholder = () => (
<div className="flex flex-col gap-2">
<div className="bg-slate-200 h-5 w-full"></div>
<div className="bg-slate-200 h-5 w-1/3"></div>
<div className="bg-slate-200 h-5 w-2/3"></div>
<div className="bg-slate-200 h-5 w-2/3"></div>
<div className="bg-slate-200 h-5 w-full"></div>
<div className="bg-slate-200 h-5 w-1/3"></div>
<div className="bg-skeleton h-5 w-full"></div>
<div className="bg-skeleton h-5 w-1/3"></div>
<div className="bg-skeleton h-5 w-2/3"></div>
<div className="bg-skeleton h-5 w-2/3"></div>
<div className="bg-skeleton h-5 w-full"></div>
<div className="bg-skeleton h-5 w-1/3"></div>
</div>
)
@@ -74,7 +74,7 @@ export const NewsSection = () => {
</span>
)
) : (
<div className="bg-slate-200 h-5 w-1/3"></div>
<div className="bg-skeleton h-5 w-1/3"></div>
)}
<Link
type="button"
@@ -93,7 +93,7 @@ export const NewsSection = () => {
</span>
</Link>
</div>
<span className="break-words text-base md:text-xl text-tuatara-950 font-sans font-normal leading-[30px] [&>a]:text-anakiwa-600 [&>a]:font-medium">
<span className="break-words text-base md:text-xl text-primary font-sans font-normal leading-[30px] [&>a]:text-anakiwa-600 [&>a]:font-medium">
{!loading ? announcementContent : <ContentPlaceholder />}
</span>
</div>
@@ -106,7 +106,7 @@ export const NewsSection = () => {
>
<Icons.discord className="text-anakiwa-400" />
<span>{LABELS.NEWS_SECTION.SEE_ALL_UPDATES}</span>
<Icons.externalUrl className="text-tuatara-950" />
<Icons.externalUrl className="text-primary" />
</Link>
</AppContent>
</div>

View File

@@ -38,7 +38,7 @@ const VideoCard = ({ videoId }: VideoCardProps) => {
rel="noopener noreferrer"
className="group flex flex-col gap-4"
>
<div className="relative overflow-hidden aspect-video rounded-sm">
<div className="relative overflow-hidden aspect-video rounded-sm dark:border-anakiwa-800">
<div className="absolute inset-0 bg-black opacity-20 group-hover:opacity-60 transition-opacity duration-300 z-10"></div>
<Image
src={thumbnailUrl}
@@ -59,7 +59,7 @@ const VideoCard = ({ videoId }: VideoCardProps) => {
</div>
<h3 className="font-sans text-sm font-normal line-clamp-3 text-tuatara-800 group-hover:text-tuatara-600 transition-colors">
{isLoading ? (
<div className="h-5 w-full bg-slate-200 animate-pulse rounded-sm"></div>
<div className="h-5 w-full bg-skeleton animate-pulse rounded-sm"></div>
) : (
title || "YouTube Video"
)}
@@ -109,7 +109,7 @@ export const ProjectYouTubeVideos = ({
data-section-id="youtube-videos"
>
<div className="flex flex-col gap-6">
<h2 className="text-[22px] font-bold text-tuatara-700">
<h2 className="text-[22px] font-bold text-secondary">
{LABELS.COMMON.YOUTUBE_VIDEOS}
</h2>

View File

@@ -27,32 +27,32 @@ export const WhatWeDo = () => {
]
return (
<div className="bg-cover-gradient">
<div className="bg-cover-gradient dark:bg-transparent-gradient">
<AppContent className="mx-auto lg:max-w-[1200px] w-full">
<section className="flex flex-col gap-16 py-16 md:pb-24">
<div className="flex flex-col text-center">
<h6 className="py-6 font-sans text-base font-bold uppercase tracking-[4px] text-tuatara-950">
<h6 className="py-6 font-sans text-base font-bold uppercase tracking-[4px] text-primary">
{LABELS.WHAT_WE_DO_SECTION.WHAT_WE_DO}
</h6>
<h3 className="font-display text-[18px] font-bold text-tuatara-950 md:text-3xl">
<h3 className="font-display text-[18px] font-bold text-primary md:text-3xl">
{LABELS.WHAT_WE_DO_SECTION.WHAT_WE_DO_DESCRIPTION}
</h3>
</div>
<div className="grid grid-cols-1 gap-8 lg:grid-cols-3">
{content.map((item, index) => (
<article
className="border-tuatara-300 flex flex-col gap-2 rounded-[6px] border bg-white px-8 py-4"
className="border-tuatara-300 flex flex-col gap-2 rounded-[6px] border bg-white px-8 py-4 dark:bg-black dark:border-anakiwa-800 dark:text-anakiwa-100"
key={index}
>
<div className="flex items-center gap-2">
<div className="w-4">
<item.icon />
</div>
<h6 className="font-sans text-base font-bold uppercase tracking-[4px] text-anakiwa-700">
<h6 className="font-sans text-lg font-bold uppercase tracking-[4px] text-anakiwa-700 dark:text-anakiwa-400">
{item.title}
</h6>
</div>
<p className="font-sans text-base text-tuatara-950">
<p className="font-sans text-base text-primary">
{item.description}
</p>
</article>

View File

@@ -49,8 +49,8 @@ export function SiteFooter() {
return (
<footer className="flex flex-col">
<div className="bg-tuatara-950 py-8 text-left text-[14px] text-white">
<AppContent className="grid grid-cols-1 justify-between gap-10 bg-tuatara-950 py-2 text-white lg:grid-cols-[400px_1fr] lg:gap-24">
<div className="bg-tuatara-950 text-white py-8 text-left text-[14px] dark:bg-black dark:border-t dark:border-anakiwa-800">
<AppContent className="grid grid-cols-1 justify-between gap-10 py-2 lg:grid-cols-[400px_1fr] lg:gap-24">
<div className="order-1 flex flex-col items-center gap-4 md:flex-row md:gap-8">
<Image
width={140}

View File

@@ -4,7 +4,6 @@ import { useState } from "react"
import NextImage from "next/image"
import NextLink from "next/link"
import CloseVector from "@/public/icons/close-fill.svg"
import HeaderVector from "@/public/icons/menu-burger.svg"
import { NavItem } from "@/types/nav"
import { siteConfig } from "@/config/site"
@@ -17,22 +16,25 @@ import {
Twitter,
} from "@/components/svgs/social-medias"
import { LABELS } from "@/app/labels"
import { Icons } from "./icons"
import { SunMedium as SunIcon, Moon as MoonIcon } from "lucide-react"
import { useGlobalProvider } from "@/app/providers/GlobalProvider"
export const SiteHeaderMobile = () => {
const [header, setHeader] = useState(false)
const { isDarkMode, setIsDarkMode } = useGlobalProvider()
const { MAIN_NAV } = useAppSettings()
return (
<div className="flex items-center md:hidden">
<NextImage
src={HeaderVector}
alt="logo"
className="cursor-pointer"
onClick={() => setHeader(true)}
width={24}
height={24}
/>
<button type="button" onClick={() => setHeader(true)}>
<Icons.Burgher
size={24}
className="text-[#171C1B] dark:text-anakiwa-400"
/>
</button>
{header && (
<div
className="z-5 fixed inset-0 flex justify-end bg-black opacity-50"
@@ -67,7 +69,14 @@ export const SiteHeaderMobile = () => {
</NextLink>
)
})}
<button
onClick={() => setIsDarkMode(!isDarkMode)}
className="text-black dark:text-anakiwa-400 ml-auto mt-10"
>
{isDarkMode ? <SunIcon size={20} /> : <MoonIcon size={20} />}
</button>
</div>
<div className="flex h-full w-full flex-col items-center justify-end gap-5 py-[40px] text-sm">
<div className="flex gap-5">
<NextLink
@@ -100,6 +109,7 @@ export const SiteHeaderMobile = () => {
<Mirror color="white" />{" "}
</NextLink>
</div>
<div className="flex gap-5 text-white">
<h1>{LABELS.COMMON.FOOTER.PRIVACY_POLICY}</h1>
<h1>{LABELS.COMMON.FOOTER.TERMS_OF_USE}</h1>

View File

@@ -10,7 +10,7 @@ export function SiteHeader() {
const { MAIN_NAV } = useAppSettings()
return (
<header className="sticky top-0 z-40 w-full border-b border-tuatara-300 bg-white shadow-sm">
<header className="sticky top-0 z-40 w-full border-b border-tuatara-300 bg-white shadow-sm dark:bg-black dark:border-anakiwa-950">
<AppContent>
<div className="flex h-16 items-center justify-between space-x-4 sm:space-x-0">
<MainNav items={MAIN_NAV} />

View File

@@ -16,7 +16,7 @@ interface LineSkeletonProps {
className?: string
}
const CardSkeleton = cva("bg-slate-200 animate-pulse", {
const CardSkeleton = cva("bg-skeleton animate-pulse", {
variants: {
size: {
sm: "w-full h-40",
@@ -31,7 +31,7 @@ const CardSkeleton = cva("bg-slate-200 animate-pulse", {
},
})
const CircleSkeleton = cva("bg-slate-200 animate-pulse rounded-full", {
const CircleSkeleton = cva("bg-skeleton animate-pulse rounded-full", {
variants: {
size: {
sm: "w-10 h-10",
@@ -40,7 +40,7 @@ const CircleSkeleton = cva("bg-slate-200 animate-pulse rounded-full", {
},
})
const LineSkeleton = cva("bg-slate-200 animate-pulse", {
const LineSkeleton = cva("bg-skeleton animate-pulse", {
variants: {
size: {
sm: "w-full h-4",

View File

@@ -61,7 +61,7 @@ const Accordion = ({
<RadixAccordion.Trigger className="w-full">
<div
className={cn(
"relative grid w-full grid-cols-[1fr_20px] items-center justify-between border-t border-t-black ring-0 focus:outline-none md:grid-cols-[1fr_30px]",
"relative grid w-full grid-cols-[1fr_20px] items-center justify-between border-t border-t-primary ring-0 focus:outline-none md:grid-cols-[1fr_30px]",
className,
{
[AccordionSizeMapping.xs]: size === "xs",
@@ -70,11 +70,11 @@ const Accordion = ({
)}
>
{size === "sm" ? (
<span className="block text-left font-sans text-base font-bold uppercase tracking-[3.36px] text-black md:text-xl md:tracking-[4.2px]">
<span className="block text-left font-sans text-base font-bold uppercase tracking-[3.36px] text-primary md:text-xl md:tracking-[4.2px]">
{label}
</span>
) : (
<span className="text-left font-sans text-base font-medium text-black">
<span className="text-left font-sans text-base font-medium text-primary">
{label}
</span>
)}

View File

@@ -9,8 +9,8 @@ export default function Badge({ value, children }: BadgeProps) {
return (
<div className="relative">
<div className="min-w-4 absolute right-[-5px] top-[-5px] m-auto flex h-4 items-center justify-center rounded-full bg-anakiwa-950 px-[6px]">
<span className="text-xs text-white">{value}</span>
<div className="min-w-4 absolute right-[-5px] top-[-5px] m-auto flex h-4 items-center justify-center rounded-full bg-anakiwa-950 px-[6px] dark:bg-anakiwa-400">
<span className="text-xs text-white dark:text-black">{value}</span>
</div>
{children}
</div>

View File

@@ -6,18 +6,18 @@ import { LucideIcon } from "lucide-react"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
"font-sans inline-flex items-center justify-center duration-200 rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background w-fit",
"font-sans inline-flex items-center justify-center duration-200 rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background w-fit",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
default: "bg-tuatara-950 text-white hover:bg-tuatara-950/90",
orange: "bg-orangeDark text-white hover:bg-orangeDark/80",
destructive:
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline:
"border border-input hover:bg-accent hover:text-accent-foreground",
secondary:
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
"bg-anakiwa-400 text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "underline-offset-4 hover:underline text-primary",
black: "bg-tuatara-950 text-white hover:bg-black",
@@ -27,12 +27,23 @@ const buttonVariants = cva(
"bg-[#F6F7F7] hover:bg-[#E9ECEF] text-gray-500 border border-gray-200 rounded-md",
},
size: {
default: "h-10 py-2 px-4",
xs: "h-8 px-2 rounded-md",
sm: "h-9 px-3 rounded-md",
lg: "h-11 px-8 rounded-md",
default: "h-10 py-2 px-4 text-lg",
xs: "h-[18px] px-2 rounded-md text-xs py-[2px]",
sm: "h-9 px-3 rounded-md text-sm",
lg: "h-11 px-8 rounded-md text-lg",
},
},
compoundVariants: [
{
variant: ["default", "orange", "black", "white", "blue", "search"],
className:
"dark:bg-transparent dark:border dark:border-anakiwa-400 dark:text-anakiwa-400 dark:hover:bg-anakiwa-400/20 dark:hover:text-anakiwa-400",
},
{
variant: ["secondary"],
className: "dark:bg-anakiwa-400 dark:text-black",
},
],
defaultVariants: {
variant: "default",
size: "default",

View File

@@ -12,7 +12,7 @@ const categoryTagVariants = cva(
variant: {
default: "bg-white text-black",
ghost: "hover:bg-accent hover:text-accent-foreground",
gray: "bg-tuatara-100 text-tuatara-950",
gray: "bg-tuatara-100 text-primary",
blue: "bg-anakiwa-300 text-black",
selected: "bg-transparent border text-black border",
},
@@ -22,6 +22,12 @@ const categoryTagVariants = cva(
lg: "h-11 px-8 rounded-md",
},
},
compoundVariants: [
{
variant: ["default", "ghost", "blue", "selected", "gray"],
className: "dark:bg-anakiwa-300 dark:text-tuatara-950",
},
],
defaultVariants: {
variant: "default",
size: "default",

View File

@@ -18,7 +18,7 @@ const Checkbox = ({ label, name, checked, ...props }: CheckboxProps) => {
<CheckboxComponent.Root
{...props}
checked={checked}
className="flex h-[14px] w-[14px] cursor-pointer items-center justify-center rounded-[1.5px] border-2 border-solid border-tuatara-200 bg-white duration-100 ease-in aria-checked:border-black aria-checked:bg-black"
className="flex h-[14px] w-[14px] cursor-pointer items-center justify-center rounded-[1.5px] border-2 border-solid border-tuatara-200 bg-primary duration-100 ease-in aria-checked:border-black aria-checked:bg-black dark:border-anakiwa-800"
id={name}
>
<CheckboxComponent.Indicator className="text-white">

View File

@@ -49,7 +49,7 @@ const Dropdown = ({
aria-label="dropdown menu"
>
<div className="flex items-center gap-1">
<span className="break-words text-sm font-medium text-tuatara-950">
<span className="break-words text-sm font-medium text-primary">
{selectedLabel ?? label}
</span>
<div className="ml-auto">
@@ -63,7 +63,7 @@ const Dropdown = ({
<DropdownMenu.Content
style={{ width: `${width}px` }}
className={cn(
"z-[50] max-h-[250px] overflow-scroll rounded-md border border-tuatara-200 bg-white py-2",
"z-[50] max-h-[250px] overflow-scroll rounded-md border border-tuatara-200 bg-white py-2 dark:bg-black dark:border-anakiwa-800",
{
"max-w-[136px]": width === undefined,
}
@@ -78,7 +78,7 @@ const Dropdown = ({
className={cn(
"text-duration-200 relative w-full cursor-pointer px-5 py-3 font-sans text-sm ring-0 hover:font-medium hover:text-anakiwa-500 focus:outline-none",
{
"text-tuatara-950 font-normal": !active,
"text-primary font-normal": !active,
"text-anakiwa-500 font-medium": active,
}
)}

View File

@@ -4,7 +4,16 @@ import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const inputVariants = cva(
"text-anakiwa-950 transition-colors duration-100 animate border-[1.5px] rounded-md focus:ring-0 border-tuatara-200 focus-visible:border-2 focus-visible:border-tuatara-950 bg-zinc-50 focus-visible:ring-0 focus-visible:none focus-visible:outline-none placeholder-anakiwa-950",
[
"rounded-md bg-zinc-50",
"text-anakiwa-950 placeholder-anakiwa-950",
"border-[1.5px] border-tuatara-200",
"transition-colors duration-100 animate",
"focus:ring-0",
"focus-visible:border-2 focus-visible:border-tuatara-950",
"focus-visible:ring-0 focus-visible:none focus-visible:outline-none",
"dark:bg-transparent dark:border dark:border-anakiwa-800 dark:text-anakiwa-300 dark:placeholder-anakiwa-300",
].join(" "),
{
variants: {
size: {

View File

@@ -10,7 +10,7 @@ const SectionTitle = ({ label, className = "" }: LabelProps) => {
return (
<span
className={cn(
"font-sans text-base font-bold uppercase leading-[24px] tracking-[3.36px] text-tuatara-950",
"font-sans text-base font-bold uppercase leading-[24px] tracking-[3.36px] text-primary",
className
)}
>
@@ -27,7 +27,7 @@ const MainPageTitle = ({
return (
<span
className={cn(
"text-4xl font-bold break-words font-display text-tuatara-950 ",
"text-4xl font-bold break-words font-display text-primary dark:text-anakiwa-400",
size === "small" ? "lg:text-5xl" : "lg:text-6xl xl:text-7xl",
className
)}

View File

@@ -90,7 +90,7 @@ export const createMarkdownElement = (
const Table = (props: any) => {
return (
<div className="w-full overflow-x-auto border rounded-lg border-tuatara-300">
<table className="min-w-full" data-component="table">
<table className="min-w-full !bg-background" data-component="table">
{props.children}
</table>
</div>
@@ -481,32 +481,32 @@ const REACT_MARKDOWN_CONFIG = (darkMode: boolean): CustomComponents => ({
},
h1: ({ ...props }) =>
createMarkdownElement("h1", {
className: "text-neutral-800 text-4xl md:text-5xl font-bold",
className: "text-primary text-4xl md:text-5xl font-bold",
...props,
}),
h2: ({ ...props }) =>
createMarkdownElement("h2", {
className: "text-neutral-800 text-4xl",
className: "text-primary text-4xl",
...props,
}),
h3: ({ ...props }) =>
createMarkdownElement("h3", {
className: "text-neutral-800 text-3xl",
className: "text-primary text-3xl",
...props,
}),
h4: ({ ...props }) =>
createMarkdownElement("h4", {
className: "text-neutral-800 text-xl",
className: "text-primary text-xl",
...props,
}),
h5: ({ ...props }) =>
createMarkdownElement("h5", {
className: "text-neutral-800 text-lg font-bold",
className: "text-primary text-lg font-bold",
...props,
}),
h6: ({ ...props }) =>
createMarkdownElement("h6", {
className: "text-neutral-800 text-md font-bold",
className: "text-primary text-md font-bold",
...props,
}),
code: ({ node, inline, className, children, ...props }) => {
@@ -557,7 +557,7 @@ const REACT_MARKDOWN_CONFIG = (darkMode: boolean): CustomComponents => ({
if (containsMath(text)) {
return (
<p
className={`${darkMode ? "text-white" : "text-tuatara-700"} font-sans text-base font-normal ${isMathOnly ? "math-only" : ""}`}
className={`${darkMode ? "text-white" : "text-secondary"} font-sans text-base font-normal ${isMathOnly ? "math-only" : ""}`}
>
<MathText text={text} />
</p>
@@ -566,7 +566,7 @@ const REACT_MARKDOWN_CONFIG = (darkMode: boolean): CustomComponents => ({
return (
<p
className={`${darkMode ? "text-white" : "text-tuatara-700"} font-sans text-base font-normal`}
className={`${darkMode ? "text-white" : "text-secondary"} font-sans text-base font-normal`}
>
{children}
</p>
@@ -586,7 +586,7 @@ const REACT_MARKDOWN_CONFIG = (darkMode: boolean): CustomComponents => ({
if (containsMath(text)) {
return (
<li
className="text-tuatara-700 font-sans text-base font-normal"
className="text-secondary font-sans text-base font-normal"
{...props}
>
<MathText text={text} />
@@ -595,10 +595,7 @@ const REACT_MARKDOWN_CONFIG = (darkMode: boolean): CustomComponents => ({
}
return (
<li
className="text-tuatara-700 font-sans text-base font-normal"
{...props}
>
<li className="text-secondary font-sans text-base font-normal" {...props}>
{children}
</li>
)
@@ -606,13 +603,13 @@ const REACT_MARKDOWN_CONFIG = (darkMode: boolean): CustomComponents => ({
ul: ({ ordered, ...props }) =>
createMarkdownElement(ordered ? "ol" : "ul", {
className:
"ml-6 list-disc text-tuatara-700 font-sans text-base font-normal",
"ml-6 list-disc text-secondary font-sans text-base font-normal",
...props,
}),
ol: ({ ordered, ...props }) =>
createMarkdownElement(ordered ? "ol" : "ul", {
className:
"list-decimal text-tuatara-700 font-sans text-base font-normal mt-3",
"list-decimal text-secondary font-sans text-base font-normal mt-3",
...props,
}),
table: Table,
@@ -797,7 +794,7 @@ const REACT_MARKDOWN_CONFIG = (darkMode: boolean): CustomComponents => ({
return (
<div
id={`fn-${identifier}`}
className="flex gap-2 text-sm text-tuatara-700 mb-2"
className="flex gap-2 text-sm text-secondary mb-2"
>
<div className="flex-none">[{label}]</div>
<div className="flex-1">

View File

@@ -28,7 +28,7 @@ const ModalContent = ({ children, className = "" }: ModalWrapperProps) => {
}
const modalContentVariants = cva(
"data-[state=open]:animate-content-show flex flex-col bg-white rounded-b-none rounded-t-lg md:rounded-lg shadow-sm top-3 bottom-0 fixed md:-translate-y-1/2 md:-translate-x-1/2 md:top-1/2 md:left-1/2 md:h-full md:max-h-[80vh] focus:outline-none z-50",
"data-[state=open]:animate-content-show flex flex-col bg-white dark:bg-black rounded-b-none rounded-t-lg md:rounded-lg shadow-sm top-3 bottom-0 fixed md:-translate-y-1/2 md:-translate-x-1/2 md:top-1/2 md:left-1/2 md:h-full md:max-h-[80vh] focus:outline-none z-50 dark:border dark:border-anakiwa-800",
{
variants: {
size: {
@@ -54,11 +54,11 @@ const Modal = ({
}: ModalProps) => (
<Dialog.Root open={open} onOpenChange={setOpen}>
<Dialog.Portal>
<Dialog.Overlay className="fixed inset-0 z-50 bg-black opacity-80 data-[state=open]:animate-overlay-show" />
<Dialog.Overlay className="fixed inset-0 z-50 bg-black opacity-80 data-[state=open]:animate-overlay-show dark:bg-anakiwa-950 dark:opacity-90" />
<Dialog.Content className={cn(modalContentVariants({ size }), className)}>
{title && (
<Dialog.Title>
<ModalContent className="border-b border-b-tuatara-200 text-center">
<ModalContent className="border-b border-b-tuatara-200 text-center dark:border-anakiwa-800">
{title}
</ModalContent>
</Dialog.Title>
@@ -69,7 +69,7 @@ const Modal = ({
</ModalContent>
{footer && (
<ModalContent className="mt-auto border-t border-t-tuatara-200">
<ModalContent className="mt-auto border-t border-t-tuatara-200 dark:border-anakiwa-800">
{footer}
</ModalContent>
)}

View File

@@ -167,10 +167,10 @@ export const WikiSideNavigation = ({
return (
<div className="sticky overflow-hidden top-20">
<aside className={cn("flex flex-col", className)}>
<h6 className="text-lg font-bold font-display text-tuatara-700">
<h6 className="text-lg font-bold font-display text-secondary">
{LABELS.COMMON.CONTENTS}
</h6>
<ul className="pt-4 font-sans text-black text-normal">
<ul className="pt-4 font-sans text-primary text-normal">
{sections.map((section, index) => (
<SideNavigationItem
key={index}

View File

@@ -1,3 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15 12.75C13.6065 12.75 12.4418 13.71 12.1065 15H3V16.5H12.1065C12.4418 17.79 13.6065 18.75 15 18.75C16.3935 18.75 17.5583 17.79 17.8935 16.5H21V15H17.8935C17.5583 13.71 16.3935 12.75 15 12.75ZM9 6C7.6065 6 6.44175 6.96 6.1065 8.25H3V9.75H6.1065C6.44175 11.04 7.6065 12 9 12C10.3935 12 11.5583 11.04 11.8935 9.75H21V8.25H11.8935C11.5583 6.96 10.3935 6 9 6Z" fill="#103241"/>
</svg>

Before

Width:  |  Height:  |  Size: 487 B

View File

@@ -1,10 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="menu-5-line" clip-path="url(#clip0_3593_17537)">
<path id="Vector" d="M18 18V20H6V18H18ZM21 11V13H3V11H21ZM18 4V6H6V4H18Z" fill="#171C1B"/>
</g>
<defs>
<clipPath id="clip0_3593_17537">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 359 B

View File

@@ -1 +0,0 @@
<svg fill="none" height="48" viewBox="0 0 49 48" width="49" xmlns="http://www.w3.org/2000/svg"><path d="m48.3357 27.0002c0 .8711-.6236 1.5945-1.4472 1.7617-.1176.0233-.2392.035-.3647.035h-6.0513c-1.0039 0-1.8157.805-1.8157 1.8005v6.0005c0 .6222-.3177 1.1667-.8001 1.4933-.1921.1284-.4118.2217-.6471.2722-.1176.0234-.2392.035-.3647.035h-6.0513c-1.0039 0-1.8157.805-1.8157 1.8006v6.0005c0 .9955-.8118 1.8005-1.8158 1.8005h-6.0513c-1.0039 0-1.8157-.805-1.8157-1.8005v-6.0005c0-.9956.8118-1.8006 1.8157-1.8006h6.0513c1.004 0 1.8158-.8049 1.8158-1.8005v-6.0005c0-.9955.8118-1.8005 1.8157-1.8005h6.0513c1.004 0 1.8158-.805 1.8158-1.8005v-7.8011c0-5.2888-4.3139-9.58208-9.6475-9.59763-5.3297.01944-9.6476 4.30883-9.6476 9.59763v7.8011c0 .9955-.8118 1.8005-1.8157 1.8005h-6.0513c-1.004 0-1.81578.805-1.81578 1.8005v15.6021c0 .9955-.8118 1.8005-1.81577 1.8005h-6.05128c-1.003966 0-1.81577-.805-1.81577-1.8005v-15.6021c0-.9955.811804-1.8005 1.81577-1.8005h6.05128c1.00397 0 1.81577-.805 1.81577-1.8005v-7.8361c0-10.58151 8.65138-19.1603 19.32638-19.1603 10.6751 0 19.3265 8.57879 19.3265 19.1642z" fill="#171c1b"/></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -7,6 +7,17 @@
--background: #FFFFFF;
--foreground: #0F172A;
--text-primary: #242528;
--text-secondary: #166F8E;
--gradient-research-card: linear-gradient(84deg, #FFF -1.95%, #EAFAFF 59.98%, #FFF 100.64%);
--skeleton-background: #f3f4f6;
/* TODO: */
--active-selection: #50C3E0;
--primary: 222.2 47.4% 11.2%;
@@ -16,8 +27,6 @@
--text-primary: #242528;
--text-secondary: #808590;
/* TODO: */
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;
@@ -51,15 +60,19 @@
--background: #000000;
--foreground: #FFFFFF;
--active-selection: #E1523A;
--text-primary: #FFFFFF;
--text-secondary: #FFFFFF;
--text-primary: #242528;
--text-secondary: #808590;
--gradient-research-card: linear-gradient(179deg, #29ACCE -202.54%, rgba(0, 0, 0, 0.00) 192.47%);
--skeleton-background: #175e75;
/* TODO: */
--active-selection: #E1523A;
--primary: #E1523A;
--primary-foreground: #FFF;
@@ -155,7 +168,7 @@
}
table[data-component='table'] tbody > tr > td {
@apply px-4 py-1 text-sm font-medium text-left text-tuatara-700;
@apply px-4 py-1 text-sm font-medium text-left text-secondary;
}
/* Ensure line breaks in table cells work properly */

View File

@@ -26,10 +26,11 @@ module.exports = {
"radial-gradient(325.52% 79.63% at 100% -0.02%, #FFF 0%, rgba(255, 255, 255, 0.00) 100%), radial-gradient(205.45% 61.89% at 2.34% 99.98%, #FFF 0%, rgba(255, 255, 255, 0.00) 100%)",
"project-page-gradient":
"linear-gradient(180deg, #C2E8F5 -17.44%, #FFF 17.72%)",
"research-card-gradient":
"linear-gradient(84deg, #FFF -1.95%, #EAFAFF 59.98%, #FFF 100.64%)",
"research-card-gradient": "var(--gradient-research-card)",
"page-header-gradient":
"linear-gradient(180deg, #C2E8F5 -17.44%, #FFF 62.5%)",
"transparent-gradient":
"linear-gradient(180deg, #000000 0%, #000000 100%)",
},
colors: {
corduroy: "#4A5754",
@@ -50,6 +51,7 @@ module.exports = {
600: "#1A8BAF",
700: "#166F8E",
900: "#184F62",
800: "#175E75",
950: "#103241",
},
tuatara: {
@@ -62,19 +64,21 @@ module.exports = {
700: "#4A4C54",
950: "#242528",
},
skeleton: {
DEFAULT: "var(--skeleton-background)",
},
background: "var(--background)",
foreground: "var(--foreground)",
active: {
selection: "var(--active-selection)",
},
primary: {
DEFAULT: "var(--primary)",
DEFAULT: "var(--text-primary)",
foreground: "hsl(var(--primary-foreground))",
},
secondary: {
DEFAULT: "hsl(var(--secondary))",
DEFAULT: "var(--text-secondary)",
foreground: "hsl(var(--secondary-foreground))",
},
destructive: {