From e039299e830f385d90d7c704b852b08db9ba9566 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Thu, 12 Mar 2026 12:16:03 +0530 Subject: [PATCH] Gradient Theme - Moonlight --- src/app/components/nav/styles.css.ts | 1 - src/app/components/page/Page.tsx | 6 +- src/app/components/page/style.css.ts | 14 ++ src/app/components/sidebar/Sidebar.css.ts | 3 - .../splash-screen/SplashScreen.css.ts | 1 - src/app/features/call-status/CallStatus.tsx | 4 +- src/app/features/call/CallView.tsx | 7 +- src/app/features/create-room/CreateRoom.tsx | 1 + src/app/features/create-space/CreateSpace.tsx | 1 + .../JoinBeforeNavigate.tsx | 4 +- src/app/features/lobby/Lobby.tsx | 4 +- src/app/features/lobby/SpaceItem.tsx | 4 + .../room-nav/RoomNavCategoryButton.tsx | 1 + src/app/features/room/CallChatView.tsx | 5 +- src/app/features/room/MembersDrawer.tsx | 11 +- src/app/features/room/Room.tsx | 11 +- src/app/features/room/RoomView.tsx | 5 +- .../features/room/RoomViewFollowing.css.ts | 2 - src/app/features/room/RoomViewHeader.tsx | 6 +- src/app/hooks/useTheme.ts | 24 +- src/app/pages/ThemeManager.tsx | 4 +- src/app/pages/client/WelcomePage.tsx | 4 +- src/app/pages/client/create/Create.tsx | 4 +- src/app/pages/client/direct/Direct.tsx | 7 +- src/app/pages/client/direct/DirectCreate.tsx | 4 +- src/app/pages/client/explore/Featured.tsx | 4 +- src/app/pages/client/explore/Server.tsx | 4 +- src/app/pages/client/home/CreateRoom.tsx | 4 +- src/app/pages/client/home/Home.tsx | 7 +- src/app/pages/client/home/Search.tsx | 4 +- src/app/pages/client/inbox/Invites.tsx | 4 +- src/app/pages/client/inbox/Notifications.tsx | 3 +- src/app/pages/client/space/Search.tsx | 4 +- src/app/pages/client/space/Space.tsx | 7 +- src/app/styles/Patterns.css.ts | 6 +- src/colors.css.ts | 221 +++++++++++++++++- src/index.css | 3 +- src/index.css.ts | 10 + src/index.tsx | 1 + 39 files changed, 350 insertions(+), 70 deletions(-) create mode 100644 src/index.css.ts diff --git a/src/app/components/nav/styles.css.ts b/src/app/components/nav/styles.css.ts index 48b2a4d34..75dc0f38b 100644 --- a/src/app/components/nav/styles.css.ts +++ b/src/app/components/nav/styles.css.ts @@ -49,7 +49,6 @@ const NavItemBase = style({ display: 'flex', justifyContent: 'start', cursor: 'pointer', - backgroundColor: Container, color: OnContainer, outline: 'none', minHeight: toRem(36), diff --git a/src/app/components/page/Page.tsx b/src/app/components/page/Page.tsx index a54563855..c79997208 100644 --- a/src/app/components/page/Page.tsx +++ b/src/app/components/page/Page.tsx @@ -14,7 +14,7 @@ export function PageRoot({ nav, children }: PageRootProps) { const screenSize = useScreenSizeContext(); return ( - + {nav} {screenSize !== ScreenSize.Mobile && ( @@ -79,11 +79,11 @@ export function PageNavContent({ ); } -export const Page = as<'div'>(({ className, ...props }, ref) => ( +export const Page = as<'div', css.PageVariants>(({ className, transparent, ...props }, ref) => ( diff --git a/src/app/components/page/style.css.ts b/src/app/components/page/style.css.ts index bd14cd583..2a779465e 100644 --- a/src/app/components/page/style.css.ts +++ b/src/app/components/page/style.css.ts @@ -1,6 +1,7 @@ import { style } from '@vanilla-extract/css'; import { recipe, RecipeVariants } from '@vanilla-extract/recipes'; import { DefaultReset, color, config, toRem } from 'folds'; +import { ContainerColor } from '../../styles/ContainerColor.css'; export const PageNav = recipe({ variants: { @@ -59,6 +60,19 @@ export const PageNavContent = style({ paddingBottom: config.space.S700, }); +export const Page = recipe({ + base: [ContainerColor({ variant: 'Surface' })], + variants: { + transparent: { + true: { + background: 'transparent', + }, + }, + }, +}); + +export type PageVariants = RecipeVariants; + export const PageHeader = recipe({ base: { paddingLeft: config.space.S400, diff --git a/src/app/components/sidebar/Sidebar.css.ts b/src/app/components/sidebar/Sidebar.css.ts index c36862232..88a7abf76 100644 --- a/src/app/components/sidebar/Sidebar.css.ts +++ b/src/app/components/sidebar/Sidebar.css.ts @@ -1,13 +1,11 @@ import { createVar, style } from '@vanilla-extract/css'; import { recipe, RecipeVariants } from '@vanilla-extract/recipes'; import { color, config, DefaultReset, Disabled, FocusOutline, toRem } from 'folds'; -import { ContainerColor } from '../../styles/ContainerColor.css'; export const Sidebar = style([ DefaultReset, { width: toRem(66), - backgroundColor: color.Background.Container, borderRight: `${config.borderWidth.B300} solid ${color.Background.ContainerLine}`, display: 'flex', @@ -187,7 +185,6 @@ export type SidebarAvatarVariants = RecipeVariants; export const SidebarFolder = recipe({ base: [ - ContainerColor({ variant: 'Background' }), { padding: config.space.S100, width: toRem(42), diff --git a/src/app/components/splash-screen/SplashScreen.css.ts b/src/app/components/splash-screen/SplashScreen.css.ts index bd3c300a7..c7fa5cea5 100644 --- a/src/app/components/splash-screen/SplashScreen.css.ts +++ b/src/app/components/splash-screen/SplashScreen.css.ts @@ -3,7 +3,6 @@ import { color, config } from 'folds'; export const SplashScreen = style({ minHeight: '100%', - backgroundColor: color.Background.Container, color: color.Background.OnContainer, }); diff --git a/src/app/features/call-status/CallStatus.tsx b/src/app/features/call-status/CallStatus.tsx index 1d30d1b40..941462225 100644 --- a/src/app/features/call-status/CallStatus.tsx +++ b/src/app/features/call-status/CallStatus.tsx @@ -1,11 +1,9 @@ import React from 'react'; import { Box, Spinner } from 'folds'; -import classNames from 'classnames'; import { LiveChip } from './LiveChip'; import * as css from './styles.css'; import { CallRoomName } from './CallRoomName'; import { CallControl } from './CallControl'; -import { ContainerColor } from '../../styles/ContainerColor.css'; import { useCallMembers, useCallSession } from '../../hooks/useCall'; import { ScreenSize, useScreenSize } from '../../hooks/useScreenSize'; import { MemberGlance } from './MemberGlance'; @@ -33,7 +31,7 @@ export function CallStatus({ callEmbed }: CallStatusProps) { return ( + {!currentJoined && } diff --git a/src/app/features/create-room/CreateRoom.tsx b/src/app/features/create-room/CreateRoom.tsx index 94799f6ea..cada36599 100644 --- a/src/app/features/create-room/CreateRoom.tsx +++ b/src/app/features/create-room/CreateRoom.tsx @@ -213,6 +213,7 @@ export function CreateRoomForm({ Options } onClick={() => setAdvance(!advance)} diff --git a/src/app/features/create-space/CreateSpace.tsx b/src/app/features/create-space/CreateSpace.tsx index b0c12f565..c6132ed68 100644 --- a/src/app/features/create-space/CreateSpace.tsx +++ b/src/app/features/create-space/CreateSpace.tsx @@ -180,6 +180,7 @@ export function CreateSpaceForm({ defaultAccess, space, onCreate }: CreateSpaceF } onClick={() => setAdvance(!advance)} type="button" diff --git a/src/app/features/join-before-navigate/JoinBeforeNavigate.tsx b/src/app/features/join-before-navigate/JoinBeforeNavigate.tsx index 028cd560e..8df431dc0 100644 --- a/src/app/features/join-before-navigate/JoinBeforeNavigate.tsx +++ b/src/app/features/join-before-navigate/JoinBeforeNavigate.tsx @@ -10,6 +10,7 @@ import { useMatrixClient } from '../../hooks/useMatrixClient'; import { allRoomsAtom } from '../../state/room-list/roomList'; import { ScreenSize, useScreenSizeContext } from '../../hooks/useScreenSize'; import { BackRouteHandler } from '../../components/BackRouteHandler'; +import { useTheme } from '../../hooks/useTheme'; type JoinBeforeNavigateProps = { roomIdOrAlias: string; eventId?: string; viaServers?: string[] }; export function JoinBeforeNavigate({ @@ -21,6 +22,7 @@ export function JoinBeforeNavigate({ const allRooms = useAtomValue(allRoomsAtom); const { navigateRoom, navigateSpace } = useRoomNavigate(); const screenSize = useScreenSizeContext(); + const theme = useTheme(); const handleView = (roomId: string) => { if (mx.getRoom(roomId)?.isSpaceRoom()) { @@ -31,7 +33,7 @@ export function JoinBeforeNavigate({ }; return ( - + diff --git a/src/app/features/lobby/Lobby.tsx b/src/app/features/lobby/Lobby.tsx index 4b19e5163..16261cada 100644 --- a/src/app/features/lobby/Lobby.tsx +++ b/src/app/features/lobby/Lobby.tsx @@ -56,6 +56,7 @@ import { useGetRoom } from '../../hooks/useGetRoom'; import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback'; import { getRoomPermissionsAPI } from '../../hooks/useRoomPermissions'; import { getRoomCreatorsForRoomId } from '../../hooks/useRoomCreators'; +import { useTheme } from '../../hooks/useTheme'; const useCanDropLobbyItem = ( space: Room, @@ -151,6 +152,7 @@ const useCanDropLobbyItem = ( export function Lobby() { const navigate = useNavigate(); const mx = useMatrixClient(); + const theme = useTheme(); const mDirects = useAtomValue(mDirectAtom); const allRooms = useAtomValue(allRoomsAtom); const allJoinedRooms = useMemo(() => new Set(allRooms), [allRooms]); @@ -430,7 +432,7 @@ export function Lobby() { return ( - + @@ -121,6 +122,7 @@ function UnjoinedSpaceProfile({ @@ -230,6 +233,7 @@ function RootSpaceProfile({ closed, categoryId, handleClose }: RootSpaceProfileP onClick={handleClose} className={css.HeaderChip} variant="Surface" + fill="None" size="500" after={} > diff --git a/src/app/features/room-nav/RoomNavCategoryButton.tsx b/src/app/features/room-nav/RoomNavCategoryButton.tsx index 3af8aeac8..f426eb09b 100644 --- a/src/app/features/room-nav/RoomNavCategoryButton.tsx +++ b/src/app/features/room-nav/RoomNavCategoryButton.tsx @@ -9,6 +9,7 @@ export const RoomNavCategoryButton = as<'button', { closed?: boolean }>( className={classNames(css.CategoryButton, className)} variant="Background" radii="Pill" + fill="None" before={ {(triggerRef) => ( - + )} diff --git a/src/app/features/room/MembersDrawer.tsx b/src/app/features/room/MembersDrawer.tsx index d9205076b..b2aa4f26f 100644 --- a/src/app/features/room/MembersDrawer.tsx +++ b/src/app/features/room/MembersDrawer.tsx @@ -56,7 +56,6 @@ import { MembershipFilterMenu } from '../../components/MembershipFilterMenu'; import { MemberSortMenu } from '../../components/MemberSortMenu'; import { useOpenUserRoomProfile, useUserRoomProfileState } from '../../state/hooks/userRoomProfile'; import { useSpaceOptionally } from '../../hooks/useSpace'; -import { ContainerColor } from '../../styles/ContainerColor.css'; import { useFlattenPowerTagMembers, useGetMemberPowerTag } from '../../hooks/useMemberPowerTag'; import { useRoomCreators } from '../../hooks/useRoomCreators'; @@ -89,6 +88,7 @@ function MemberDrawerHeader({ room }: MemberDrawerHeaderProps) { setPeopleDrawer(false)} > @@ -132,6 +132,7 @@ function MemberItem({ aria-pressed={pressed} data-user-id={member.userId} variant="Background" + fill="None" radii="400" onClick={onClick} before={ @@ -245,11 +246,7 @@ export function MembersDrawer({ room, members }: MembersDrawerProps) { }; return ( - + @@ -279,6 +276,7 @@ export function MembersDrawer({ room, members }: MembersDrawerProps) { )) as MouseEventHandler } variant="Background" + fill="None" size="400" radii="300" before={} @@ -311,6 +309,7 @@ export function MembersDrawer({ room, members }: MembersDrawerProps) { )) as MouseEventHandler } variant="Background" + fill="None" size="400" radii="300" after={} diff --git a/src/app/features/room/Room.tsx b/src/app/features/room/Room.tsx index 5e5d7d784..8f08e57ee 100644 --- a/src/app/features/room/Room.tsx +++ b/src/app/features/room/Room.tsx @@ -18,11 +18,14 @@ import { CallView } from '../call/CallView'; import { RoomViewHeader } from './RoomViewHeader'; import { callChatAtom } from '../../state/callEmbed'; import { CallChatView } from './CallChatView'; +import { Page } from '../../components/page'; +import { useTheme } from '../../hooks/useTheme'; export function Room() { const { eventId } = useParams(); const room = useRoom(); const mx = useMatrixClient(); + const theme = useTheme(); const [isDrawer] = useSetting(settingsAtom, 'isPeopleDrawer'); const [hideActivity] = useSetting(settingsAtom, 'hideActivity'); @@ -49,20 +52,20 @@ export function Room() { {callView && (screenSize === ScreenSize.Desktop || !chat) && ( - + - + )} {!callView && ( - + - + )} {callView && chat && ( diff --git a/src/app/features/room/RoomView.tsx b/src/app/features/room/RoomView.tsx index a4f0d7af6..3de4bb84e 100644 --- a/src/app/features/room/RoomView.tsx +++ b/src/app/features/room/RoomView.tsx @@ -14,7 +14,6 @@ import { RoomViewTyping } from './RoomViewTyping'; import { RoomTombstone } from './RoomTombstone'; import { RoomInput } from './RoomInput'; import { RoomViewFollowing, RoomViewFollowingPlaceholder } from './RoomViewFollowing'; -import { Page } from '../../components/page'; import { useKeyDown } from '../../hooks/useKeyDown'; import { editableActiveElement } from '../../utils/dom'; import { settingsAtom } from '../../state/settings'; @@ -91,7 +90,7 @@ export function RoomView({ eventId }: { eventId?: string }) { ); return ( - + {hideActivity ? : } - + ); } diff --git a/src/app/features/room/RoomViewFollowing.css.ts b/src/app/features/room/RoomViewFollowing.css.ts index 18b53ac92..0d88e5282 100644 --- a/src/app/features/room/RoomViewFollowing.css.ts +++ b/src/app/features/room/RoomViewFollowing.css.ts @@ -16,8 +16,6 @@ export const RoomViewFollowing = recipe({ minHeight: toRem(28), padding: `0 ${config.space.S400}`, width: '100%', - backgroundColor: color.Surface.Container, - color: color.Surface.OnContainer, outline: 'none', }, ], diff --git a/src/app/features/room/RoomViewHeader.tsx b/src/app/features/room/RoomViewHeader.tsx index a19058d26..49fc3951e 100644 --- a/src/app/features/room/RoomViewHeader.tsx +++ b/src/app/features/room/RoomViewHeader.tsx @@ -66,7 +66,6 @@ import { useRoomNavigate } from '../../hooks/useRoomNavigate'; import { useRoomCreators } from '../../hooks/useRoomCreators'; import { useRoomPermissions } from '../../hooks/useRoomPermissions'; import { InviteUserPrompt } from '../../components/invite-user-prompt'; -import { ContainerColor } from '../../styles/ContainerColor.css'; import { RoomSettingsPage } from '../../state/roomSettings'; type RoomMenuProps = { @@ -305,10 +304,7 @@ export function RoomViewHeader({ callView }: { callView?: boolean }) { }; return ( - + {screenSize === ScreenSize.Mobile && ( diff --git a/src/app/hooks/useTheme.ts b/src/app/hooks/useTheme.ts index cdbb9dba3..d60c45328 100644 --- a/src/app/hooks/useTheme.ts +++ b/src/app/hooks/useTheme.ts @@ -1,7 +1,6 @@ -import { lightTheme } from 'folds'; import { createContext, useContext, useEffect, useMemo, useState } from 'react'; import { onDarkFontWeight, onLightFontWeight } from '../../config.css'; -import { butterTheme, darkTheme, silverTheme } from '../../colors.css'; +import { lightTheme, butterTheme, darkTheme, silverTheme, moonlightTheme } from '../../colors.css'; import { settingsAtom } from '../state/settings'; import { useSetting } from '../state/hooks/settings'; @@ -14,6 +13,8 @@ export type Theme = { id: string; kind: ThemeKind; classNames: string[]; + flat?: boolean; + gradient?: string; }; export const LightTheme: Theme = { @@ -25,21 +26,31 @@ export const LightTheme: Theme = { export const SilverTheme: Theme = { id: 'silver-theme', kind: ThemeKind.Light, - classNames: ['silver-theme', silverTheme, onLightFontWeight, 'prism-light'], + classNames: [silverTheme, onLightFontWeight, 'prism-light'], }; + export const DarkTheme: Theme = { id: 'dark-theme', kind: ThemeKind.Dark, - classNames: ['dark-theme', darkTheme, onDarkFontWeight, 'prism-dark'], + classNames: ['global-dark', darkTheme, onDarkFontWeight, 'prism-dark'], }; export const ButterTheme: Theme = { id: 'butter-theme', kind: ThemeKind.Dark, - classNames: ['butter-theme', butterTheme, onDarkFontWeight, 'prism-dark'], + classNames: ['global-dark', butterTheme, onDarkFontWeight, 'prism-dark'], +}; +export const MoonlightTheme: Theme = { + id: 'moonlight-theme', + kind: ThemeKind.Dark, + classNames: ['global-dark', moonlightTheme, onDarkFontWeight, 'prism-dark'], + flat: true, }; export const useThemes = (): Theme[] => { - const themes: Theme[] = useMemo(() => [LightTheme, SilverTheme, DarkTheme, ButterTheme], []); + const themes: Theme[] = useMemo( + () => [LightTheme, SilverTheme, DarkTheme, ButterTheme, MoonlightTheme], + [] + ); return themes; }; @@ -51,6 +62,7 @@ export const useThemeNames = (): Record => [SilverTheme.id]: 'Silver', [DarkTheme.id]: 'Dark', [ButterTheme.id]: 'Butter', + [MoonlightTheme.id]: 'Moonlight', }), [] ); diff --git a/src/app/pages/ThemeManager.tsx b/src/app/pages/ThemeManager.tsx index 69d50cdb9..898fb3a18 100644 --- a/src/app/pages/ThemeManager.tsx +++ b/src/app/pages/ThemeManager.tsx @@ -39,9 +39,9 @@ export function AuthRouteThemeManager({ children }: { children: ReactNode }) { document.body.classList.add(...activeTheme.classNames); if (monochromeMode) { - document.body.style.filter = 'grayscale(1)'; + document.body.style.setProperty('filter', 'grayscale(1)'); } else { - document.body.style.filter = ''; + document.body.style.removeProperty('filter'); } }, [activeTheme, monochromeMode]); diff --git a/src/app/pages/client/WelcomePage.tsx b/src/app/pages/client/WelcomePage.tsx index 8b0bc3c6f..f10faf625 100644 --- a/src/app/pages/client/WelcomePage.tsx +++ b/src/app/pages/client/WelcomePage.tsx @@ -2,10 +2,12 @@ import React from 'react'; import { Box, Button, Icon, Icons, Text, config, toRem } from 'folds'; import { Page, PageHero, PageHeroSection } from '../../components/page'; import CinnySVG from '../../../../public/res/svg/cinny.svg'; +import { useTheme } from '../../hooks/useTheme'; export function WelcomePage() { + const theme = useTheme(); return ( - + + diff --git a/src/app/pages/client/direct/Direct.tsx b/src/app/pages/client/direct/Direct.tsx index 04edf1090..f614cef53 100644 --- a/src/app/pages/client/direct/Direct.tsx +++ b/src/app/pages/client/direct/Direct.tsx @@ -107,7 +107,12 @@ function DirectHeader() { - + diff --git a/src/app/pages/client/direct/DirectCreate.tsx b/src/app/pages/client/direct/DirectCreate.tsx index 3deb0b6dd..ac2618ecb 100644 --- a/src/app/pages/client/direct/DirectCreate.tsx +++ b/src/app/pages/client/direct/DirectCreate.tsx @@ -17,10 +17,12 @@ import { } from '../../../components/page'; import { BackRouteHandler } from '../../../components/BackRouteHandler'; import { CreateChat } from '../../../features/create-chat'; +import { useTheme } from '../../../hooks/useTheme'; export function DirectCreate() { const mx = useMatrixClient(); const screenSize = useScreenSizeContext(); + const theme = useTheme(); const navigate = useNavigate(); const [searchParams] = useSearchParams(); @@ -38,7 +40,7 @@ export function DirectCreate() { }, [mx, navigate, directs, userId]); return ( - + {screenSize === ScreenSize.Mobile && ( diff --git a/src/app/pages/client/explore/Featured.tsx b/src/app/pages/client/explore/Featured.tsx index f056cbb5c..2f8a8c25a 100644 --- a/src/app/pages/client/explore/Featured.tsx +++ b/src/app/pages/client/explore/Featured.tsx @@ -18,8 +18,10 @@ import * as css from './style.css'; import { useRoomNavigate } from '../../../hooks/useRoomNavigate'; import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize'; import { BackRouteHandler } from '../../../components/BackRouteHandler'; +import { useTheme } from '../../../hooks/useTheme'; export function FeaturedRooms() { + const theme = useTheme(); const { featuredCommunities } = useClientConfig(); const { rooms, spaces } = featuredCommunities ?? {}; const allRooms = useAtomValue(allRoomsAtom); @@ -27,7 +29,7 @@ export function FeaturedRooms() { const { navigateSpace, navigateRoom } = useRoomNavigate(); return ( - + {screenSize === ScreenSize.Mobile && ( diff --git a/src/app/pages/client/explore/Server.tsx b/src/app/pages/client/explore/Server.tsx index 48f267ccd..0ec2ee29c 100644 --- a/src/app/pages/client/explore/Server.tsx +++ b/src/app/pages/client/explore/Server.tsx @@ -45,6 +45,7 @@ import { getMxIdServer } from '../../../utils/matrix'; import { stopPropagation } from '../../../utils/keyboard'; import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize'; import { BackRouteHandler } from '../../../components/BackRouteHandler'; +import { useTheme } from '../../../hooks/useTheme'; const useServerSearchParams = (searchParams: URLSearchParams): ExploreServerPathSearchParams => useMemo( @@ -343,6 +344,7 @@ function LimitButton({ limit, onLimitChange }: LimitButtonProps) { export function PublicRooms() { const { server } = useParams(); const mx = useMatrixClient(); + const theme = useTheme(); const userId = mx.getUserId(); const userServer = userId && getMxIdServer(userId); const allRooms = useAtomValue(allRoomsAtom); @@ -469,7 +471,7 @@ export function PublicRooms() { }; return ( - + {isSearch ? ( <> diff --git a/src/app/pages/client/home/CreateRoom.tsx b/src/app/pages/client/home/CreateRoom.tsx index fddd75aac..4e83d7c22 100644 --- a/src/app/pages/client/home/CreateRoom.tsx +++ b/src/app/pages/client/home/CreateRoom.tsx @@ -12,14 +12,16 @@ import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize'; import { BackRouteHandler } from '../../../components/BackRouteHandler'; import { CreateRoomForm } from '../../../features/create-room'; import { useRoomNavigate } from '../../../hooks/useRoomNavigate'; +import { useTheme } from '../../../hooks/useTheme'; export function HomeCreateRoom() { const screenSize = useScreenSizeContext(); + const theme = useTheme(); const { navigateRoom } = useRoomNavigate(); return ( - + {screenSize === ScreenSize.Mobile && ( diff --git a/src/app/pages/client/home/Home.tsx b/src/app/pages/client/home/Home.tsx index d87db963d..bae42f967 100644 --- a/src/app/pages/client/home/Home.tsx +++ b/src/app/pages/client/home/Home.tsx @@ -121,7 +121,12 @@ function HomeHeader() { - + diff --git a/src/app/pages/client/home/Search.tsx b/src/app/pages/client/home/Search.tsx index d5ddfb778..a55864693 100644 --- a/src/app/pages/client/home/Search.tsx +++ b/src/app/pages/client/home/Search.tsx @@ -5,14 +5,16 @@ import { MessageSearch } from '../../../features/message-search'; import { useHomeRooms } from './useHomeRooms'; import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize'; import { BackRouteHandler } from '../../../components/BackRouteHandler'; +import { useTheme } from '../../../hooks/useTheme'; export function HomeSearch() { const scrollRef = useRef(null); const rooms = useHomeRooms(); const screenSize = useScreenSizeContext(); + const theme = useTheme(); return ( - + diff --git a/src/app/pages/client/inbox/Invites.tsx b/src/app/pages/client/inbox/Invites.tsx index 20518e568..b4956dab8 100644 --- a/src/app/pages/client/inbox/Invites.tsx +++ b/src/app/pages/client/inbox/Invites.tsx @@ -67,6 +67,7 @@ import { useIgnoredUsers } from '../../../hooks/useIgnoredUsers'; import { useReportRoomSupported } from '../../../hooks/useReportRoomSupported'; import { useSetting } from '../../../state/hooks/settings'; import { settingsAtom } from '../../../state/settings'; +import { useTheme } from '../../../hooks/useTheme'; const COMPACT_CARD_WIDTH = 548; @@ -693,6 +694,7 @@ function SpamInvites({ export function Invites() { const mx = useMatrixClient(); + const theme = useTheme(); const useAuthentication = useMediaAuthentication(); const { navigateRoom, navigateSpace } = useRoomNavigate(); const allRooms = useAtomValue(allRoomsAtom); @@ -746,7 +748,7 @@ export function Invites() { }; return ( - + diff --git a/src/app/pages/client/inbox/Notifications.tsx b/src/app/pages/client/inbox/Notifications.tsx index 9592224f8..0ab080c1d 100644 --- a/src/app/pages/client/inbox/Notifications.tsx +++ b/src/app/pages/client/inbox/Notifications.tsx @@ -563,6 +563,7 @@ const DEFAULT_REFRESH_MS = 7000; export function Notifications() { const mx = useMatrixClient(); + const theme = useTheme(); const [hideActivity] = useSetting(settingsAtom, 'hideActivity'); const [mediaAutoLoad] = useSetting(settingsAtom, 'mediaAutoLoad'); const [urlPreview] = useSetting(settingsAtom, 'urlPreview'); @@ -635,7 +636,7 @@ export function Notifications() { }, [timelineState, notificationTimeline, lastVItemIndex, loadTimeline]); return ( - + diff --git a/src/app/pages/client/space/Search.tsx b/src/app/pages/client/space/Search.tsx index 017262b5b..1773480f2 100644 --- a/src/app/pages/client/space/Search.tsx +++ b/src/app/pages/client/space/Search.tsx @@ -11,9 +11,11 @@ import { roomToParentsAtom } from '../../../state/room/roomToParents'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize'; import { BackRouteHandler } from '../../../components/BackRouteHandler'; +import { useTheme } from '../../../hooks/useTheme'; export function SpaceSearch() { const mx = useMatrixClient(); + const theme = useTheme(); const scrollRef = useRef(null); const space = useSpace(); const screenSize = useScreenSizeContext(); @@ -27,7 +29,7 @@ export function SpaceSearch() { ); return ( - + diff --git a/src/app/pages/client/space/Space.tsx b/src/app/pages/client/space/Space.tsx index 2a7c61993..4f5011f78 100644 --- a/src/app/pages/client/space/Space.tsx +++ b/src/app/pages/client/space/Space.tsx @@ -273,7 +273,12 @@ function SpaceHeader() { {joinRules?.join_rule !== JoinRule.Public && } - + diff --git a/src/app/styles/Patterns.css.ts b/src/app/styles/Patterns.css.ts index e45594167..41d72ba25 100644 --- a/src/app/styles/Patterns.css.ts +++ b/src/app/styles/Patterns.css.ts @@ -2,8 +2,8 @@ import { style } from '@vanilla-extract/css'; import { color, toRem } from 'folds'; export const BackgroundDotPattern = style({ - backgroundImage: `radial-gradient(${color.Background.ContainerActive} ${toRem(2)}, ${ - color.Background.Container - } ${toRem(2)})`, + backgroundImage: `radial-gradient(${color.Background.ContainerActive} ${toRem( + 2 + )}, transparent ${toRem(2)})`, backgroundSize: `${toRem(40)} ${toRem(40)}`, }); diff --git a/src/colors.css.ts b/src/colors.css.ts index 268cbf788..b83b7baac 100644 --- a/src/colors.css.ts +++ b/src/colors.css.ts @@ -1,7 +1,115 @@ -import { createTheme } from '@vanilla-extract/css'; +import { createTheme, createThemeContract } from '@vanilla-extract/css'; import { color } from 'folds'; -export const silverTheme = createTheme(color, { +export const extendedColor = createThemeContract({ + background: '', +}); + +const ThemeContract = { + ...extendedColor, + ...color, +}; + +export const lightTheme = createTheme(ThemeContract, { + background: '#F2F2F2', + Background: { + Container: '#F2F2F2', + ContainerHover: '#E5E5E5', + ContainerActive: '#D9D9D9', + ContainerLine: '#CCCCCC', + OnContainer: '#000000', + }, + + Surface: { + Container: '#FFFFFF', + ContainerHover: '#F2F2F2', + ContainerActive: '#E5E5E5', + ContainerLine: '#D9D9D9', + OnContainer: '#000000', + }, + + SurfaceVariant: { + Container: '#F2F2F2', + ContainerHover: '#E5E5E5', + ContainerActive: '#D9D9D9', + ContainerLine: '#CCCCCC', + OnContainer: '#000000', + }, + + Primary: { + Main: '#1858D5', + MainHover: '#164FC0', + MainActive: '#144BB5', + MainLine: '#1346AA', + OnMain: '#FFFFFF', + Container: '#E8EEFB', + ContainerHover: '#DCE6F9', + ContainerActive: '#D1DEF7', + ContainerLine: '#C5D5F5', + OnContainer: '#113E95', + }, + + Secondary: { + Main: '#000000', + MainHover: '#1A1A1A', + MainActive: '#262626', + MainLine: '#333333', + OnMain: '#FFFFFF', + Container: '#D9D9D9', + ContainerHover: '#CCCCCC', + ContainerActive: '#BFBFBF', + ContainerLine: '#B2B2B2', + OnContainer: '#0D0D0D', + }, + + Success: { + Main: '#00844C', + MainHover: '#007744', + MainActive: '#007041', + MainLine: '#006A3D', + OnMain: '#FFFFFF', + Container: '#E5F3ED', + ContainerHover: '#D9EDE4', + ContainerActive: '#CCE6DB', + ContainerLine: '#BFE0D2', + OnContainer: '#005C35', + }, + + Warning: { + Main: '#A85400', + MainHover: '#974C00', + MainActive: '#8F4700', + MainLine: '#864300', + OnMain: '#FFFFFF', + Container: '#F6EEE5', + ContainerHover: '#F2E5D9', + ContainerActive: '#EEDDCC', + ContainerLine: '#E9D4BF', + OnContainer: '#763B00', + }, + + Critical: { + Main: '#C40E0E', + MainHover: '#AC0909', + MainActive: '#A60C0C', + MainLine: '#9C0B0B', + OnMain: '#FFFFFF', + Container: '#F9E7E7', + ContainerHover: '#F6DBDB', + ContainerActive: '#F3CFCF', + ContainerLine: '#F0C3C3', + OnContainer: '#890A0A', + }, + + Other: { + FocusRing: 'rgba(0 0 0 / 50%)', + Shadow: 'rgba(0 0 0 / 20%)', + Overlay: 'rgba(0 0 0 / 50%)', + }, +}); + +export const silverTheme = createTheme(ThemeContract, { + background: '#DEDEDE', Background: { Container: '#DEDEDE', ContainerHover: '#D3D3D3', @@ -99,6 +207,7 @@ export const silverTheme = createTheme(color, { }); const darkThemeData = { + background: color.Background.Container, Background: { Container: '#1A1A1A', ContainerHover: '#262626', @@ -195,9 +304,9 @@ const darkThemeData = { }, }; -export const darkTheme = createTheme(color, darkThemeData); +export const darkTheme = createTheme(ThemeContract, darkThemeData); -export const butterTheme = createTheme(color, { +export const butterTheme = createTheme(ThemeContract, { ...darkThemeData, Background: { Container: '#1A1916', @@ -236,3 +345,107 @@ export const butterTheme = createTheme(color, { OnContainer: '#F2EED3', }, }); + +export const moonlightTheme = createTheme(ThemeContract, { + background: 'linear-gradient(to bottom right, #000546, #000)', + + Background: { + Container: '#000000', + ContainerHover: '#01032B', + ContainerActive: '#020546', + ContainerLine: '#030977', + OnContainer: '#FFFFFF', + }, + + Surface: { + Container: '#01032B', + ContainerHover: '#020546', + ContainerActive: '#03075E', + ContainerLine: '#030977', + OnContainer: '#FFFFFF', + }, + + SurfaceVariant: { + Container: '#020546', + ContainerHover: '#03075E', + ContainerActive: '#030977', + ContainerLine: '#030977', + OnContainer: '#F2F2F2', + }, + + Primary: { + Main: '#0043FF', + MainHover: '#1A56FF', + MainActive: '#3369FF', + MainLine: '#4D7BFF', + OnMain: '#FFFFFF', + + Container: '#00144D', + ContainerHover: '#001B66', + ContainerActive: '#002180', + ContainerLine: '#002899', + OnContainer: '#FFFFFF', + }, + + Secondary: { + Main: '#E5E7FF', + MainHover: '#CCCFFF', + MainActive: '#B2B6FF', + MainLine: '#999EFF', + OnMain: '#000000', + + Container: '#030763', + ContainerHover: '#04097C', + ContainerActive: '#050B94', + ContainerLine: '#050CAD', + OnContainer: '#FFFFFF', + }, + + Success: { + Main: '#00FF95', + MainHover: '#1AFFA0', + MainActive: '#33FFAA', + MainLine: '#4DFFB5', + OnMain: '#0B2E22', + + Container: '#004D3B', + ContainerHover: '#00664F', + ContainerActive: '#008062', + ContainerLine: '#008062', + OnContainer: '#CCF2E2', + }, + + Warning: { + Main: '#FF9933', + MainHover: '#FFA64D', + MainActive: '#FFB266', + MainLine: '#FFBF80', + OnMain: '#000000', + + Container: '#4D2600', + ContainerHover: '#663200', + ContainerActive: '#803F00', + ContainerLine: '#994C00', + OnContainer: '#F3E2D1', + }, + + Critical: { + Main: '#CB0000', + MainHover: '#E50000', + MainActive: '#FF0000', + MainLine: '#FF1A1A', + OnMain: '#ffffff', + + Container: '#4D0000', + ContainerHover: '#660000', + ContainerActive: '#800000', + ContainerLine: '#990000', + OnContainer: '#F5D6D6', + }, + + Other: { + FocusRing: 'hsla(237, 100%, 70%, 0.6)', + Shadow: 'rgba(0, 0, 0, 0.9)', + Overlay: 'rgba(0, 0, 0, 0.8)', + }, +}); diff --git a/src/index.css b/src/index.css index ca28536d2..dd4dd2cd1 100644 --- a/src/index.css +++ b/src/index.css @@ -22,8 +22,7 @@ --font-secondary: 'InterVariable', var(--font-emoji), sans-serif; } -.dark-theme, -.butter-theme { +.global-dark { --tc-link: hsl(213deg 100% 80%); --mx-uc-1: hsl(208, 100%, 75%); diff --git a/src/index.css.ts b/src/index.css.ts new file mode 100644 index 000000000..626c881f3 --- /dev/null +++ b/src/index.css.ts @@ -0,0 +1,10 @@ +import { globalStyle } from '@vanilla-extract/css'; +import { color } from 'folds'; +import { extendedColor } from './colors.css'; + +globalStyle('body', { + background: extendedColor.background, + borderColor: color.Background.ContainerLine, + outlineColor: color.Background.ContainerLine, + color: color.Background.OnContainer, +}); diff --git a/src/index.tsx b/src/index.tsx index 6cc0ca38f..86e059391 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -5,6 +5,7 @@ import { enableMapSet } from 'immer'; import '@fontsource/inter/variable.css'; import 'folds/dist/style.css'; import { configClass, varsClass } from 'folds'; +import './index.css.ts'; enableMapSet();