mirror of
https://github.com/privacy-scaling-explorations/pse.dev.git
synced 2026-01-10 14:48:13 -05:00
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
}
|
||||
|
||||
28
app/components/layouts/ThemeProvider.tsx
Normal file
28
app/components/layouts/ThemeProvider.tsx
Normal 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>
|
||||
)
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 && (
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
|
||||
@@ -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>
|
||||
),
|
||||
|
||||
@@ -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} />
|
||||
|
||||
@@ -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>
|
||||
)}
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -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],
|
||||
}}
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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 } =
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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, {
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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} />
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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>
|
||||
)}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
)}
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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
|
||||
)}
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
)}
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 */
|
||||
|
||||
@@ -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: {
|
||||
|
||||
Reference in New Issue
Block a user