From 185eb160e7f029db28967363e3133ed3c48cbebb Mon Sep 17 00:00:00 2001 From: root Date: Wed, 13 May 2026 22:22:06 -0400 Subject: [PATCH] Add Lotus Terminal Mode + fix all remaining Cinny branding - New: Lotus Terminal Mode toggle in Appearance settings - Red phosphor color scheme (bg #0a0000, primary #ff3300, accent #00dd66) - Monospace font override (JetBrains Mono / Fira Code / Cascadia Code) - Retro CRT scanline overlay via CSS pseudo-element - Wired into ThemeManager with dedicated lotusTerminalBodyClass - Branding: replace all user-visible Cinny references with Lotus Chat - WelcomePage, AuthLayout, SplashScreen, index.html meta tags - Device display names in login/register/token flows - System notification brand field - (Preserved internal Matrix protocol CinnySpaces event type) Co-Authored-By: Claude Sonnet 4.6 --- index.html | 4 +- .../components/splash-screen/SplashScreen.tsx | 2 +- src/app/features/settings/general/General.tsx | 8 ++ .../notifications/SystemNotification.tsx | 2 +- src/app/hooks/useTheme.ts | 7 +- src/app/pages/ThemeManager.tsx | 18 ++-- src/app/pages/auth/AuthLayout.tsx | 2 +- .../pages/auth/login/PasswordLoginForm.tsx | 6 +- src/app/pages/auth/login/TokenLogin.tsx | 2 +- .../auth/register/PasswordRegisterForm.tsx | 4 +- src/app/pages/client/WelcomePage.tsx | 2 +- src/app/state/settings.ts | 2 + src/colors.css.ts | 97 +++++++++++++++++++ src/lotus-terminal.css.ts | 28 ++++++ 14 files changed, 165 insertions(+), 19 deletions(-) create mode 100644 src/lotus-terminal.css.ts diff --git a/index.html b/index.html index fbd8de773..26c632d9e 100644 --- a/index.html +++ b/index.html @@ -29,8 +29,8 @@ - - + + diff --git a/src/app/components/splash-screen/SplashScreen.tsx b/src/app/components/splash-screen/SplashScreen.tsx index 27adadbad..24de6719b 100644 --- a/src/app/components/splash-screen/SplashScreen.tsx +++ b/src/app/components/splash-screen/SplashScreen.tsx @@ -21,7 +21,7 @@ export function SplashScreen({ children }: SplashScreenProps) { justifyContent="Center" > - Cinny + Lotus Chat diff --git a/src/app/features/settings/general/General.tsx b/src/app/features/settings/general/General.tsx index 0104834ad..8770a96cb 100644 --- a/src/app/features/settings/general/General.tsx +++ b/src/app/features/settings/general/General.tsx @@ -310,6 +310,7 @@ function Appearance() { const [monochromeMode, setMonochromeMode] = useSetting(settingsAtom, 'monochromeMode'); const [twitterEmoji, setTwitterEmoji] = useSetting(settingsAtom, 'twitterEmoji'); const [perMessageProfiles, setPerMessageProfiles] = useSetting(settingsAtom, 'perMessageProfiles'); + const [lotusTerminal, setLotusTerminal] = useSetting(settingsAtom, 'lotusTerminal'); return ( @@ -371,6 +372,13 @@ function Appearance() { after={} /> + + } + /> + ); } diff --git a/src/app/features/settings/notifications/SystemNotification.tsx b/src/app/features/settings/notifications/SystemNotification.tsx index e0df06df9..460002360 100644 --- a/src/app/features/settings/notifications/SystemNotification.tsx +++ b/src/app/features/settings/notifications/SystemNotification.tsx @@ -27,7 +27,7 @@ function EmailNotification() { device_display_name: email, lang: 'en', data: { - brand: 'Cinny', + brand: 'Lotus Chat', }, append: true, }); diff --git a/src/app/hooks/useTheme.ts b/src/app/hooks/useTheme.ts index cdbb9dba3..5a82b57cb 100644 --- a/src/app/hooks/useTheme.ts +++ b/src/app/hooks/useTheme.ts @@ -1,7 +1,7 @@ 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 { butterTheme, darkTheme, lotusTerminalTheme, silverTheme } from '../../colors.css'; import { settingsAtom } from '../state/settings'; import { useSetting } from '../state/hooks/settings'; @@ -37,6 +37,11 @@ export const ButterTheme: Theme = { kind: ThemeKind.Dark, classNames: ['butter-theme', butterTheme, onDarkFontWeight, 'prism-dark'], }; +export const LotusTerminalTheme: Theme = { + id: 'lotus-terminal-theme', + kind: ThemeKind.Dark, + classNames: ['lotus-terminal-theme', lotusTerminalTheme, onDarkFontWeight, 'prism-dark'], +}; export const useThemes = (): Theme[] => { const themes: Theme[] = useMemo(() => [LightTheme, SilverTheme, DarkTheme, ButterTheme], []); diff --git a/src/app/pages/ThemeManager.tsx b/src/app/pages/ThemeManager.tsx index 69d50cdb9..dbbff60fd 100644 --- a/src/app/pages/ThemeManager.tsx +++ b/src/app/pages/ThemeManager.tsx @@ -3,11 +3,13 @@ import { configClass, varsClass } from 'folds'; import { DarkTheme, LightTheme, + LotusTerminalTheme, ThemeContextProvider, ThemeKind, useActiveTheme, useSystemThemeKind, } from '../hooks/useTheme'; +import { lotusTerminalBodyClass } from '../../lotus-terminal.css'; import { useSetting } from '../state/hooks/settings'; import { settingsAtom } from '../state/settings'; @@ -31,19 +33,23 @@ export function UnAuthRouteThemeManager() { export function AuthRouteThemeManager({ children }: { children: ReactNode }) { const activeTheme = useActiveTheme(); const [monochromeMode] = useSetting(settingsAtom, 'monochromeMode'); + const [lotusTerminal] = useSetting(settingsAtom, 'lotusTerminal'); + + const effectiveTheme = lotusTerminal ? LotusTerminalTheme : activeTheme; useEffect(() => { document.body.className = ''; document.body.classList.add(configClass, varsClass); - - document.body.classList.add(...activeTheme.classNames); - - if (monochromeMode) { + document.body.classList.add(...effectiveTheme.classNames); + if (lotusTerminal) { + document.body.classList.add(lotusTerminalBodyClass); + } + if (monochromeMode && !lotusTerminal) { document.body.style.filter = 'grayscale(1)'; } else { document.body.style.filter = ''; } - }, [activeTheme, monochromeMode]); + }, [effectiveTheme, monochromeMode, lotusTerminal]); - return {children}; + return {children}; } diff --git a/src/app/pages/auth/AuthLayout.tsx b/src/app/pages/auth/AuthLayout.tsx index 74395f35c..0d71eca5a 100644 --- a/src/app/pages/auth/AuthLayout.tsx +++ b/src/app/pages/auth/AuthLayout.tsx @@ -135,7 +135,7 @@ export function AuthLayout() {
Lotus Chat Logo - Cinny + Lotus Chat
diff --git a/src/app/pages/auth/login/PasswordLoginForm.tsx b/src/app/pages/auth/login/PasswordLoginForm.tsx index 62f46dd2c..24faf680c 100644 --- a/src/app/pages/auth/login/PasswordLoginForm.tsx +++ b/src/app/pages/auth/login/PasswordLoginForm.tsx @@ -133,7 +133,7 @@ export function PasswordLoginForm({ defaultUsername, defaultEmail }: PasswordLog user: username, }, password, - initial_device_display_name: 'Cinny Web', + initial_device_display_name: 'Lotus Chat Web', }); }; @@ -151,7 +151,7 @@ export function PasswordLoginForm({ defaultUsername, defaultEmail }: PasswordLog user: mxIdUsername, }, password, - initial_device_display_name: 'Cinny Web', + initial_device_display_name: 'Lotus Chat Web', }); }; const handleEmailLogin = (email: string, password: string) => { @@ -163,7 +163,7 @@ export function PasswordLoginForm({ defaultUsername, defaultEmail }: PasswordLog address: email, }, password, - initial_device_display_name: 'Cinny Web', + initial_device_display_name: 'Lotus Chat Web', }); }; diff --git a/src/app/pages/auth/login/TokenLogin.tsx b/src/app/pages/auth/login/TokenLogin.tsx index 761d5dc53..c21fb2328 100644 --- a/src/app/pages/auth/login/TokenLogin.tsx +++ b/src/app/pages/auth/login/TokenLogin.tsx @@ -57,7 +57,7 @@ export function TokenLogin({ token }: TokenLoginProps) { startLogin(baseUrl, { type: 'm.login.token', token, - initial_device_display_name: 'Cinny Web', + initial_device_display_name: 'Lotus Chat Web', }); }, [baseUrl, token, startLogin]); diff --git a/src/app/pages/auth/register/PasswordRegisterForm.tsx b/src/app/pages/auth/register/PasswordRegisterForm.tsx index 9f1734229..9f947680b 100644 --- a/src/app/pages/auth/register/PasswordRegisterForm.tsx +++ b/src/app/pages/auth/register/PasswordRegisterForm.tsx @@ -109,7 +109,7 @@ function RegisterUIAFlow({ auth: authDict, password, username, - initial_device_display_name: 'Cinny Web', + initial_device_display_name: 'Lotus Chat Web', }); }, [onRegister, formData] @@ -250,7 +250,7 @@ export function PasswordRegisterForm({ auth: { session: authData.session, }, - initial_device_display_name: 'Cinny Web', + initial_device_display_name: 'Lotus Chat Web', }); }; diff --git a/src/app/pages/client/WelcomePage.tsx b/src/app/pages/client/WelcomePage.tsx index 4b9dd3dc9..9ab0c5e10 100644 --- a/src/app/pages/client/WelcomePage.tsx +++ b/src/app/pages/client/WelcomePage.tsx @@ -15,7 +15,7 @@ export function WelcomePage() { } - title="Welcome to Cinny" + title="Welcome to Lotus Chat" subTitle={ Yet another matrix client.{' '} diff --git a/src/app/state/settings.ts b/src/app/state/settings.ts index 723747576..709691107 100644 --- a/src/app/state/settings.ts +++ b/src/app/state/settings.ts @@ -42,6 +42,7 @@ export interface Settings { dateFormatString: string; developerTools: boolean; + lotusTerminal: boolean; chatBackground: ChatBackground; perMessageProfiles: boolean; @@ -79,6 +80,7 @@ const defaultSettings: Settings = { dateFormatString: 'D MMM YYYY', developerTools: false, + lotusTerminal: false, chatBackground: 'none', perMessageProfiles: false, diff --git a/src/colors.css.ts b/src/colors.css.ts index 268cbf788..09fb20c40 100644 --- a/src/colors.css.ts +++ b/src/colors.css.ts @@ -236,3 +236,100 @@ export const butterTheme = createTheme(color, { OnContainer: '#F2EED3', }, }); + +export const lotusTerminalTheme = createTheme(color, { + Background: { + Container: '#0a0000', + ContainerHover: '#140500', + ContainerActive: '#1e0800', + ContainerLine: '#2a0b00', + OnContainer: '#ffd0b8', + }, + + Surface: { + Container: '#140500', + ContainerHover: '#1e0800', + ContainerActive: '#2a0b00', + ContainerLine: '#360e00', + OnContainer: '#ffd0b8', + }, + + SurfaceVariant: { + Container: '#1e0800', + ContainerHover: '#2a0b00', + ContainerActive: '#360e00', + ContainerLine: '#421100', + OnContainer: '#ffd0b8', + }, + + Primary: { + Main: '#ff3300', + MainHover: '#ff4d1a', + MainActive: '#ff5c2e', + MainLine: '#ff6640', + OnMain: '#0a0000', + Container: '#3d0d00', + ContainerHover: '#4a1000', + ContainerActive: '#571300', + ContainerLine: '#641600', + OnContainer: '#ffb399', + }, + + Secondary: { + Main: '#00dd66', + MainHover: '#00c75c', + MainActive: '#00b352', + MainLine: '#009e49', + OnMain: '#0a0000', + Container: '#003318', + ContainerHover: '#00401e', + ContainerActive: '#004d24', + ContainerLine: '#005a2a', + OnContainer: '#99ffcc', + }, + + Success: { + Main: '#00dd66', + MainHover: '#00c75c', + MainActive: '#00b352', + MainLine: '#009e49', + OnMain: '#0a0000', + Container: '#003318', + ContainerHover: '#00401e', + ContainerActive: '#004d24', + ContainerLine: '#005a2a', + OnContainer: '#99ffcc', + }, + + Warning: { + Main: '#ffaa00', + MainHover: '#e69900', + MainActive: '#cc8800', + MainLine: '#b37700', + OnMain: '#0a0000', + Container: '#332200', + ContainerHover: '#402b00', + ContainerActive: '#4d3300', + ContainerLine: '#5a3c00', + OnContainer: '#ffd980', + }, + + Critical: { + Main: '#ff6666', + MainHover: '#ff5252', + MainActive: '#ff3d3d', + MainLine: '#ff2929', + OnMain: '#0a0000', + Container: '#3d0000', + ContainerHover: '#4a0000', + ContainerActive: '#570000', + ContainerLine: '#640000', + OnContainer: '#ffb3b3', + }, + + Other: { + FocusRing: 'rgba(255, 51, 0, 0.6)', + Shadow: 'rgba(0, 0, 0, 1)', + Overlay: 'rgba(0, 0, 0, 0.85)', + }, +}); diff --git a/src/lotus-terminal.css.ts b/src/lotus-terminal.css.ts new file mode 100644 index 000000000..da61590ab --- /dev/null +++ b/src/lotus-terminal.css.ts @@ -0,0 +1,28 @@ +import { globalStyle, style } from '@vanilla-extract/css'; + +export const lotusTerminalBodyClass = style({}); + +globalStyle(`body.${lotusTerminalBodyClass}`, { + fontFamily: "'JetBrains Mono', 'Fira Code', 'Cascadia Code', Consolas, 'Courier New', monospace", + letterSpacing: '0.01em', +}); + +globalStyle(`body.${lotusTerminalBodyClass} *`, { + fontFamily: "'JetBrains Mono', 'Fira Code', 'Cascadia Code', Consolas, 'Courier New', monospace !important" as any, +}); + +globalStyle(`body.${lotusTerminalBodyClass}::after`, { + content: '""', + position: 'fixed', + top: 0, + left: 0, + right: 0, + bottom: 0, + pointerEvents: 'none', + zIndex: 9999, + backgroundImage: 'repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(0,0,0,0.12) 2px, rgba(0,0,0,0.12) 4px)', +}); + +globalStyle(`body.${lotusTerminalBodyClass} input, body.${lotusTerminalBodyClass} textarea`, { + caretColor: '#ff3300', +});