Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions web/src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
@tailwind components;
@tailwind utilities;

:root {
color-scheme: light dark;
}

section {
flex-grow: 1;
}
Expand All @@ -10,13 +14,22 @@ section {
background-color: #cccccc; /* Background color of the track */
}

.dark ::-webkit-scrollbar-track {
background-color: #1f1f1f;
}

/* Scrollbar Thumb */
::-webkit-scrollbar-thumb {
background-color: #999999; /* Background color of the thumb */
border-radius: 0px; /* Round the corners of the thumb */
border: 2px solid #cccccc;
}

.dark ::-webkit-scrollbar-thumb {
background-color: #4d4d4d;
border-color: #1f1f1f;
}

/* Scrollbar Width */
::-webkit-scrollbar {
width: 7px; /* Set scrollbar width */
Expand Down Expand Up @@ -48,6 +61,10 @@ input[type="range"]::-webkit-slider-runnable-track {
background-color: #0c0c0c;
height: 9px;
}

.dark input[type="range"]::-webkit-slider-runnable-track {
background-color: #f5f5f5;
}
input[type="range"]:disabled {
opacity: 0.5;
}
Expand All @@ -72,6 +89,14 @@ input[type="range"]::-webkit-slider-thumb {
box-shadow: -2px -2px 0 rgba(68, 68, 68, 0.2) inset;
}

.dark input[type="range"]::-webkit-slider-thumb {
border: 1px solid #f5f5f5;
background:
url("/icons/horizontal-arrows.svg") no-repeat center,
#1a1a1a;
box-shadow: -2px -2px 0 rgba(0, 0, 0, 0.35) inset;
}

input[type="range"]:focus::-webkit-slider-thumb {
border: 1px solid #0c0c0c;
border-radius: 3px;
Expand All @@ -84,6 +109,10 @@ input[type="range"]::-moz-range-track {
height: 9px;
}

.dark input[type="range"]::-moz-range-track {
background-color: #f5f5f5;
}

/* slider thumb */
input[type="range"]::-moz-range-thumb {
border: none; /*Removes extra border that FF applies*/
Expand All @@ -100,6 +129,14 @@ input[type="range"]::-moz-range-thumb {
box-shadow: -2px -2px 0 rgba(68, 68, 68, 0.2) inset;
}

.dark input[type="range"]::-moz-range-thumb {
border: 1px solid #f5f5f5;
background:
url("/icons/horizontal-arrows.svg") no-repeat center,
#1a1a1a;
box-shadow: -2px -2px 0 rgba(0, 0, 0, 0.35) inset;
}

input[type="range"]:focus::-moz-range-thumb {
border: 1px solid #0c0c0c;
border-radius: 3px;
Expand Down Expand Up @@ -128,6 +165,12 @@ div[id^="radix"][role="dialog"][data-state="open"] {
@apply font-chicago;
}

.dark div[id^="radix"][role="dialog"][data-state="open"] {
background-color: #1a1a1a;
border-color: #444444;
box-shadow: 5px 5px 0 rgba(0, 0, 0, 0.6);
}

div[id^="radix"][role="dialog"][data-state="open"] button {
border-color: #0c0c0c;
border: 1px solid #0c0c0c;
Expand All @@ -138,6 +181,13 @@ div[id^="radix"][role="dialog"][data-state="open"] button {
2px 2px 0 rgba(0, 0, 0, 0.25);
}

.dark div[id^="radix"][role="dialog"][data-state="open"] button {
border-color: #f5f5f5;
box-shadow:
-2px -2px 0 rgba(255, 255, 255, 0.1) inset,
2px 2px 0 rgba(0, 0, 0, 0.4);
}

div[id^="radix"][role="dialog"][data-state="open"] input {
border-color: #0c0c0c;
border: 1px solid #0c0c0c !important;
Expand All @@ -148,10 +198,21 @@ div[id^="radix"][role="dialog"][data-state="open"] input {
margin-right: 8px;
}

.dark div[id^="radix"][role="dialog"][data-state="open"] input {
border-color: #f5f5f5 !important;
box-shadow:
-2px -2px 0 rgba(255, 255, 255, 0.08) inset,
2px 2px 0 rgba(0, 0, 0, 0.4);
}

div[style="pointer-events: auto;"][data-state="open"] {
@apply bg-9blueLight/70;
}

.dark div[style="pointer-events: auto;"][data-state="open"] {
background-color: rgba(0, 0, 0, 0.6);
}

div[id^="radix"][role="dialog"][data-state="open"] div[data-error] {
@apply border-none shadow-none focus:outline-none;
}
Expand Down
5 changes: 4 additions & 1 deletion web/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import GoogleAnalytics from "@/components/googleAnalytics";
import appConfig from "@/config";
import CustomToaster from "@/components/customToaster";
import CookieBanner from "@/components/cookieBanner";
import ThemeScript from "@/components/theme/themeScript";
import Providers from "@/providers";

const chicago = localFont({
Expand Down Expand Up @@ -71,8 +72,10 @@ export default async function RootLayout({
arial.className,
arial.variable,
])}
suppressHydrationWarning
>
<body className="flex min-h-screen flex-col bg-9layer">
<body className="flex min-h-screen flex-col bg-9layer text-9black transition-colors duration-300 dark:bg-9black dark:text-9gray">
<ThemeScript />
<Providers>{children}</Providers>
<CookieBanner />
<CustomToaster />
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/cardShadow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default function ShadowCard({
<div
className={combineClass(
className,
"rounded-[3px] border border-9black bg-9layer shadow-9card",
"rounded-[3px] border border-9black bg-9layer shadow-9card transition-colors dark:border-9gray dark:bg-9darkPanel dark:shadow-none",
)}
>
{children}
Expand Down
20 changes: 18 additions & 2 deletions web/src/components/header.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
"use client";

import ConnectButton from "@/components/connectButton";
import NavigationMenu from "@/components/navMenu";
import Link from "next/link";
import { combineClass } from "@/utils/combineClass";
import HeaderLogo from "./headerLogo";
import CreateCampaingButton from "./createCampaign/createCampaignHeaderButton";
import DisclaimerButton from "./disclaimerButton";
Expand All @@ -9,10 +12,16 @@ import ReferralButton from "./referral/referralButton";
import MobileMenu from "./mobileMenu";
import SimpleModeButton from "./simple/simpleModeButton";
import AdvancedModeButton from "./advanced/advancedModeButton";
import ThemeToggleButton from "./theme/themeToggleButton";

export default function Header({ simple = false }: { simple?: boolean }) {
return (
<header className="flex items-center justify-between self-stretch border-b-2 border-b-black bg-9blueLight text-xs">
<header
className={combineClass(
"flex items-center justify-between self-stretch border-b-2 border-b-black bg-9blueLight text-xs transition-colors duration-300",
"dark:border-b-9gray dark:bg-9black dark:text-9gray",
)}
>
<Link
data-test="header-logo"
href="/"
Expand All @@ -23,12 +32,19 @@ export default function Header({ simple = false }: { simple?: boolean }) {
<div className="hidden md:flex">
{simple ? <DisclaimerButton /> : <SimpleModeButton />}
</div>
<div className="hidden h-10 flex-1 border-x-2 border-x-black md:flex">
<div
className={combineClass(
"hidden h-10 flex-1 border-x-2 border-x-black transition-colors duration-300",
"dark:border-x-9gray",
"md:flex",
)}
>
<NavigationMenu simple={simple} />
</div>
<CreateCampaingButton />
<div className="relative flex items-center">
<MobileMenu simple={simple} />
<ThemeToggleButton className="md:border-l-0" />
<ConnectButton />
{simple ? <AdvancedModeButton /> : <DegenModeButton />}
<ReferralButton />
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/mobileMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default function MobileMenu({ simple = false }: { simple?: boolean }) {
}, [pathname]);
return (
<div
className="flex size-10 items-center justify-center border-l-2 border-l-black md:hidden"
className="flex size-10 items-center justify-center border-l-2 border-l-black transition-colors dark:border-l-9gray md:hidden"
onClick={() => setIsMobileMenuOpen(true)}
>
<Image src={MenuIcon} alt="menu" />
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/navMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default function NavigationMenu({
key={item.page}
href={item.page}
className={combineClass(
"font-chicago text-neutral-800 hover:underline",
"font-chicago text-neutral-800 transition-colors hover:underline dark:text-9gray",
item.disabled && "pointer-events-none opacity-30",
)}
>
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/pointsMenuButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default function PointMenuButton() {
return (
<Menu>
<MenuButton className="group flex items-center">
<span className="font-chicago text-neutral-800 group-hover:underline">
<span className="font-chicago text-neutral-800 transition-colors group-hover:underline dark:text-9gray">
Points
</span>
<Image
Expand Down
25 changes: 25 additions & 0 deletions web/src/components/theme/themeScript.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const script = `(() => {
try {
const storageKey = "9lives-theme";
const storedTheme = window.localStorage.getItem(storageKey);
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
const theme = storedTheme === "light" || storedTheme === "dark"
? storedTheme
: prefersDark
? "dark"
: "light";

if (theme === "dark") {
document.documentElement.classList.add("dark");
} else {
document.documentElement.classList.remove("dark");
}
document.documentElement.dataset.theme = theme;
} catch (error) {
console.warn("Unable to hydrate theme", error);
}
})();`;

export default function ThemeScript() {
return <script dangerouslySetInnerHTML={{ __html: script }} />;
}
31 changes: 31 additions & 0 deletions web/src/components/theme/themeToggleButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"use client";

import { useTheme } from "@/providers/theme";
import { combineClass } from "@/utils/combineClass";

export default function ThemeToggleButton({
className,
}: {
className?: string;
}) {
const { theme, toggleTheme } = useTheme();
const isDark = theme === "dark";

return (
<button
type="button"
aria-label={isDark ? "Switch to light mode" : "Switch to dark mode"}
aria-pressed={isDark}
onClick={toggleTheme}
className={combineClass(
"flex size-10 items-center justify-center border-l-2 border-l-black text-lg text-neutral-800 transition-colors hover:bg-9gray focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-9blueDark dark:border-l-9gray dark:text-9gray dark:hover:bg-9darkPanel",
className,
)}
data-state={isDark ? "on" : "off"}
>
<span role="img" aria-hidden="true">
{isDark ? "☀️" : "🌙"}
</span>
</button>
);
}
2 changes: 1 addition & 1 deletion web/src/components/themed/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export default function Modal({
>
<div
className={
"fixed inset-0 z-30 w-screen overflow-y-auto bg-9blueLight/70 backdrop-blur"
"fixed inset-0 z-30 w-screen overflow-y-auto bg-9blueLight/70 backdrop-blur transition-colors dark:bg-black/70"
}
>
<div className="flex min-h-full items-center justify-center">
Expand Down
31 changes: 17 additions & 14 deletions web/src/providers/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,25 @@ import { Suspense } from "react";
import LiFiProvider from "./lifi";
import FarcasterProvider from "./farcaster";
import RelayProvider from "./relay";
import ThemeProvider from "./theme";

export default function Providers({ children }: { children: React.ReactNode }) {
return (
<ThirdwebProvider>
<ReactQueryProvider>
<ContextInjector />
<WebSocketProvider />
<FarcasterProvider />
<RelayProvider />
<Suspense>
<ReferralHandler />
</Suspense>
<PostHogProvider>
<LiFiProvider>{children}</LiFiProvider>
</PostHogProvider>
</ReactQueryProvider>
</ThirdwebProvider>
<ThemeProvider>
<ThirdwebProvider>
<ReactQueryProvider>
<ContextInjector />
<WebSocketProvider />
<FarcasterProvider />
<RelayProvider />
<Suspense>
<ReferralHandler />
</Suspense>
<PostHogProvider>
<LiFiProvider>{children}</LiFiProvider>
</PostHogProvider>
</ReactQueryProvider>
</ThirdwebProvider>
</ThemeProvider>
);
}
Loading