diff --git a/index.html b/index.html
index 26c632d9e..6854c5abc 100644
--- a/index.html
+++ b/index.html
@@ -25,6 +25,9 @@
/>
+
+
+
diff --git a/src/app/pages/ThemeManager.tsx b/src/app/pages/ThemeManager.tsx
index dbbff60fd..8c1e028db 100644
--- a/src/app/pages/ThemeManager.tsx
+++ b/src/app/pages/ThemeManager.tsx
@@ -12,20 +12,24 @@ import {
import { lotusTerminalBodyClass } from '../../lotus-terminal.css';
import { useSetting } from '../state/hooks/settings';
import { settingsAtom } from '../state/settings';
+import { runLotusBootSequence } from '../../lotus-boot';
export function UnAuthRouteThemeManager() {
const systemThemeKind = useSystemThemeKind();
+ const [lotusTerminal] = useSetting(settingsAtom, 'lotusTerminal');
useEffect(() => {
document.body.className = '';
document.body.classList.add(configClass, varsClass);
- if (systemThemeKind === ThemeKind.Dark) {
+ if (lotusTerminal) {
+ document.body.classList.add(...LotusTerminalTheme.classNames);
+ document.body.classList.add(lotusTerminalBodyClass);
+ } else if (systemThemeKind === ThemeKind.Dark) {
document.body.classList.add(...DarkTheme.classNames);
- }
- if (systemThemeKind === ThemeKind.Light) {
+ } else {
document.body.classList.add(...LightTheme.classNames);
}
- }, [systemThemeKind]);
+ }, [systemThemeKind, lotusTerminal]);
return null;
}
@@ -43,6 +47,7 @@ export function AuthRouteThemeManager({ children }: { children: ReactNode }) {
document.body.classList.add(...effectiveTheme.classNames);
if (lotusTerminal) {
document.body.classList.add(lotusTerminalBodyClass);
+ runLotusBootSequence();
}
if (monochromeMode && !lotusTerminal) {
document.body.style.filter = 'grayscale(1)';
diff --git a/src/colors.css.ts b/src/colors.css.ts
index 09fb20c40..10890529f 100644
--- a/src/colors.css.ts
+++ b/src/colors.css.ts
@@ -239,97 +239,97 @@ export const butterTheme = createTheme(color, {
export const lotusTerminalTheme = createTheme(color, {
Background: {
- Container: '#0a0000',
- ContainerHover: '#140500',
- ContainerActive: '#1e0800',
- ContainerLine: '#2a0b00',
- OnContainer: '#ffd0b8',
+ Container: '#030508',
+ ContainerHover: '#060c14',
+ ContainerActive: '#0d1520',
+ ContainerLine: '#07101a',
+ OnContainer: '#c4d9ee',
},
Surface: {
- Container: '#140500',
- ContainerHover: '#1e0800',
- ContainerActive: '#2a0b00',
- ContainerLine: '#360e00',
- OnContainer: '#ffd0b8',
+ Container: '#060c14',
+ ContainerHover: '#0d1520',
+ ContainerActive: '#07101a',
+ ContainerLine: '#111d2b',
+ OnContainer: '#c4d9ee',
},
SurfaceVariant: {
- Container: '#1e0800',
- ContainerHover: '#2a0b00',
- ContainerActive: '#360e00',
- ContainerLine: '#421100',
- OnContainer: '#ffd0b8',
+ Container: '#0d1520',
+ ContainerHover: '#07101a',
+ ContainerActive: '#111d2b',
+ ContainerLine: '#162436',
+ OnContainer: '#c4d9ee',
},
Primary: {
- Main: '#ff3300',
- MainHover: '#ff4d1a',
- MainActive: '#ff5c2e',
- MainLine: '#ff6640',
- OnMain: '#0a0000',
- Container: '#3d0d00',
- ContainerHover: '#4a1000',
- ContainerActive: '#571300',
- ContainerLine: '#641600',
- OnContainer: '#ffb399',
+ Main: '#FF6B00',
+ MainHover: '#FF8C2B',
+ MainActive: '#FF9940',
+ MainLine: '#FFA655',
+ OnMain: '#030508',
+ Container: '#2a1200',
+ ContainerHover: '#3a1a00',
+ ContainerActive: '#4a2200',
+ ContainerLine: '#5a2a00',
+ OnContainer: '#FFB87A',
},
Secondary: {
- Main: '#00dd66',
- MainHover: '#00c75c',
- MainActive: '#00b352',
- MainLine: '#009e49',
- OnMain: '#0a0000',
- Container: '#003318',
- ContainerHover: '#00401e',
- ContainerActive: '#004d24',
- ContainerLine: '#005a2a',
- OnContainer: '#99ffcc',
+ Main: '#00D4FF',
+ MainHover: '#33DFFF',
+ MainActive: '#4DE5FF',
+ MainLine: '#66EBFF',
+ OnMain: '#030508',
+ Container: '#001a22',
+ ContainerHover: '#002233',
+ ContainerActive: '#002a3d',
+ ContainerLine: '#003347',
+ OnContainer: '#99E8FF',
},
Success: {
- Main: '#00dd66',
- MainHover: '#00c75c',
- MainActive: '#00b352',
- MainLine: '#009e49',
- OnMain: '#0a0000',
- Container: '#003318',
- ContainerHover: '#00401e',
- ContainerActive: '#004d24',
- ContainerLine: '#005a2a',
- OnContainer: '#99ffcc',
+ Main: '#00FF88',
+ MainHover: '#33FFAA',
+ MainActive: '#4DFFB8',
+ MainLine: '#66FFC6',
+ OnMain: '#030508',
+ Container: '#002211',
+ ContainerHover: '#002a16',
+ ContainerActive: '#00331b',
+ ContainerLine: '#003b20',
+ OnContainer: '#99FFCC',
},
Warning: {
- Main: '#ffaa00',
- MainHover: '#e69900',
- MainActive: '#cc8800',
- MainLine: '#b37700',
- OnMain: '#0a0000',
- Container: '#332200',
- ContainerHover: '#402b00',
- ContainerActive: '#4d3300',
- ContainerLine: '#5a3c00',
- OnContainer: '#ffd980',
+ Main: '#FFB300',
+ MainHover: '#FFC233',
+ MainActive: '#FFCC4D',
+ MainLine: '#FFD566',
+ OnMain: '#030508',
+ Container: '#221900',
+ ContainerHover: '#2a2000',
+ ContainerActive: '#332800',
+ ContainerLine: '#3b2e00',
+ OnContainer: '#FFE08A',
},
Critical: {
- Main: '#ff6666',
- MainHover: '#ff5252',
- MainActive: '#ff3d3d',
- MainLine: '#ff2929',
- OnMain: '#0a0000',
- Container: '#3d0000',
- ContainerHover: '#4a0000',
- ContainerActive: '#570000',
- ContainerLine: '#640000',
- OnContainer: '#ffb3b3',
+ Main: '#FF2D55',
+ MainHover: '#FF4D6D',
+ MainActive: '#FF6080',
+ MainLine: '#FF7390',
+ OnMain: '#030508',
+ Container: '#22000d',
+ ContainerHover: '#2a0011',
+ ContainerActive: '#330015',
+ ContainerLine: '#3b0019',
+ OnContainer: '#FF99AA',
},
Other: {
- FocusRing: 'rgba(255, 51, 0, 0.6)',
+ FocusRing: 'rgba(0, 212, 255, 0.5)',
Shadow: 'rgba(0, 0, 0, 1)',
- Overlay: 'rgba(0, 0, 0, 0.85)',
+ Overlay: 'rgba(3, 5, 8, 0.94)',
},
});
diff --git a/src/lotus-boot.ts b/src/lotus-boot.ts
new file mode 100644
index 000000000..4c101a197
--- /dev/null
+++ b/src/lotus-boot.ts
@@ -0,0 +1,74 @@
+const BOOT_MESSAGES = [
+ '╔═══════════════════════════════════════════════════╗',
+ '║ LOTUS CHAT — LOTUSGUILD PLATFORM ║',
+ '║ SECURE MATRIX CLIENT — TERMINAL MODE ACTIVE ║',
+ '╚════════════════════════════════════════════════════╝',
+ '',
+ '[ OK ] Kernel modules loaded',
+ '[ OK ] Filesystem mounted read-write',
+ '[ OK ] Network interfaces configured',
+ '[ OK ] Matrix homeserver connection established',
+ '[ OK ] End-to-end encryption initialized',
+ '[ OK ] Authentication service started',
+ '[ OK ] Security headers applied',
+ '[ OK ] Room state synchronized',
+ '[ OK ] Terminal interface rendered',
+ '',
+ '> ALL SYSTEMS NOMINAL — LOTUS CHAT',
+ '',
+];
+
+const STORAGE_KEY = 'lt_booted_lotus-chat';
+
+export function resetBootSequence(): void {
+ sessionStorage.removeItem(STORAGE_KEY);
+}
+
+export function runLotusBootSequence(force = false): void {
+ if (!force && sessionStorage.getItem(STORAGE_KEY)) return;
+ sessionStorage.setItem(STORAGE_KEY, '1');
+
+ const overlay = document.createElement('div');
+ overlay.id = 'lt-boot';
+ overlay.style.cssText = [
+ 'position:fixed',
+ 'inset:0',
+ 'background:#000',
+ 'z-index:10100',
+ 'display:flex',
+ 'align-items:flex-start',
+ 'justify-content:flex-start',
+ 'padding:3rem',
+ "font-family:'JetBrains Mono','Fira Code','Courier New',monospace",
+ ].join(';');
+
+ const pre = document.createElement('pre');
+ pre.style.cssText = [
+ 'font-family:inherit',
+ 'font-size:0.78rem',
+ 'color:#00FF88',
+ 'text-shadow:0 0 6px #00FF88,0 0 16px rgba(0,255,136,0.45)',
+ 'line-height:1.7',
+ 'white-space:pre-wrap',
+ 'overflow:hidden',
+ ].join(';');
+ overlay.appendChild(pre);
+ document.body.appendChild(overlay);
+
+ let i = 0;
+ let text = '';
+ const interval = setInterval(() => {
+ if (i >= BOOT_MESSAGES.length) {
+ clearInterval(interval);
+ setTimeout(() => {
+ overlay.style.transition = 'opacity 0.5s ease';
+ overlay.style.opacity = '0';
+ setTimeout(() => overlay.remove(), 500);
+ }, 500);
+ return;
+ }
+ text += BOOT_MESSAGES[i] + '\n';
+ pre.textContent = text;
+ i++;
+ }, 65);
+}
diff --git a/src/lotus-terminal.css.ts b/src/lotus-terminal.css.ts
index da61590ab..eaafa3428 100644
--- a/src/lotus-terminal.css.ts
+++ b/src/lotus-terminal.css.ts
@@ -1,28 +1,159 @@
-import { globalStyle, style } from '@vanilla-extract/css';
+import { globalStyle, keyframes, 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',
+const glitch1 = keyframes({
+ '0%, 90%, 100%': { clipPath: 'inset(0)', transform: 'skewX(0)' },
+ '92%': { clipPath: 'inset(15% 0 72% 0)', transform: 'skewX(-4deg)' },
+ '94%': { clipPath: 'inset(54% 0 22% 0)', transform: 'skewX(3deg)' },
+ '96%': { clipPath: 'inset(30% 0 48% 0)', transform: 'skewX(-2deg)' },
});
+const glitch2 = keyframes({
+ '0%, 90%, 100%': { clipPath: 'inset(0)', transform: 'skewX(0)' },
+ '92%': { clipPath: 'inset(60% 0 8% 0)', transform: 'skewX(3deg)' },
+ '94%': { clipPath: 'inset(8% 0 68% 0)', transform: 'skewX(-3deg)' },
+ '96%': { clipPath: 'inset(42% 0 38% 0)', transform: 'skewX(1deg)' },
+});
+
+export const lotusTerminalBodyClass = style({
+ fontFamily: "'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'Courier New', monospace",
+ letterSpacing: '0.02em',
+ // Dot-grid background — TDS exact (on body since we're scoped to body class)
+ backgroundColor: '#030508',
+ backgroundImage: 'radial-gradient(circle, rgba(0,212,255,0.055) 1px, transparent 1px)',
+ backgroundSize: '28px 28px',
+ vars: {
+ // Backgrounds
+ '--lt-bg-primary': '#030508',
+ '--lt-bg-secondary': '#060c14',
+ '--lt-bg-tertiary': '#0d1520',
+ '--lt-bg-card': '#07101a',
+ '--lt-bg-terminal': '#010304',
+ // Accent — Orange
+ '--lt-accent-orange': '#FF6B00',
+ '--lt-accent-orange-bright': '#FF8C2B',
+ '--lt-accent-orange-dim': 'rgba(255,107,0,0.12)',
+ '--lt-accent-orange-border': 'rgba(255,107,0,0.35)',
+ // Accent — Amber
+ '--lt-accent-amber': '#FFB300',
+ '--lt-accent-amber-dim': 'rgba(255,179,0,0.10)',
+ // Accent — Cyan
+ '--lt-accent-cyan': '#00D4FF',
+ '--lt-accent-cyan-bright': '#33DFFF',
+ '--lt-accent-cyan-dim': 'rgba(0,212,255,0.10)',
+ '--lt-accent-cyan-border': 'rgba(0,212,255,0.22)',
+ // Accent — Green
+ '--lt-accent-green': '#00FF88',
+ '--lt-accent-green-bright': '#33FFAA',
+ '--lt-accent-green-dim': 'rgba(0,255,136,0.10)',
+ '--lt-accent-green-border': 'rgba(0,255,136,0.22)',
+ // Accent — Red
+ '--lt-accent-red': '#FF2D55',
+ '--lt-accent-red-dim': 'rgba(255,45,85,0.12)',
+ // Accent — Gold
+ '--lt-accent-gold': '#FFD700',
+ '--lt-accent-gold-dim': 'rgba(255,215,0,0.10)',
+ // Accent — Purple
+ '--lt-accent-purple': '#BF5FFF',
+ '--lt-accent-purple-dim': 'rgba(191,95,255,0.10)',
+ // Text
+ '--lt-text-primary': '#c4d9ee',
+ '--lt-text-secondary': '#7fa3bf',
+ '--lt-text-muted': '#3e607a',
+ '--lt-text-dim': '#1e3347',
+ // Borders
+ '--lt-border-color': 'rgba(0,212,255,0.16)',
+ '--lt-border-color-hi': '#00D4FF',
+ '--lt-border-color-dim': 'rgba(0,212,255,0.07)',
+ // Glows — text
+ '--lt-glow-orange': '0 0 6px #FF6B00, 0 0 16px rgba(255,107,0,0.55)',
+ '--lt-glow-orange-intense':'0 0 8px #FF6B00, 0 0 22px #FF6B00, 0 0 40px rgba(255,107,0,0.45)',
+ '--lt-glow-cyan': '0 0 6px #00D4FF, 0 0 16px rgba(0,212,255,0.45)',
+ '--lt-glow-cyan-intense': '0 0 8px #00D4FF, 0 0 22px #00D4FF, 0 0 38px rgba(0,212,255,0.35)',
+ '--lt-glow-green': '0 0 6px #00FF88, 0 0 16px rgba(0,255,136,0.45)',
+ '--lt-glow-green-intense': '0 0 8px #00FF88, 0 0 22px #00FF88, 0 0 36px rgba(0,255,136,0.35)',
+ '--lt-glow-amber': '0 0 6px #FFB300, 0 0 14px rgba(255,179,0,0.40)',
+ '--lt-glow-amber-intense': '0 0 8px #FFB300, 0 0 20px #FFB300, 0 0 34px rgba(255,179,0,0.45)',
+ '--lt-glow-red': '0 0 6px #FF2D55, 0 0 16px rgba(255,45,85,0.45)',
+ // Glows — box
+ '--lt-box-glow-orange': '0 0 18px rgba(255,107,0,0.22), 0 0 36px rgba(255,107,0,0.08)',
+ '--lt-box-glow-cyan': '0 0 18px rgba(0,212,255,0.18), 0 0 36px rgba(0,212,255,0.06)',
+ '--lt-box-glow-green': '0 0 18px rgba(0,255,136,0.18), 0 0 36px rgba(0,255,136,0.06)',
+ '--lt-box-glow-red': '0 0 18px rgba(255,45,85,0.22), 0 0 36px rgba(255,45,85,0.08)',
+ '--lt-box-glow-amber': '0 0 18px rgba(255,179,0,0.18), 0 0 36px rgba(255,179,0,0.06)',
+ // Fonts
+ '--lt-font-mono': "'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'Courier New', monospace",
+ '--lt-font-display': "'JetBrains Mono', 'Fira Code', 'Courier New', monospace",
+ '--lt-font-crt': "'VT323', 'Courier New', monospace",
+ } as any,
+});
+
+// Font on all descendants
globalStyle(`body.${lotusTerminalBodyClass} *`, {
- fontFamily: "'JetBrains Mono', 'Fira Code', 'Cascadia Code', Consolas, 'Courier New', monospace !important" as any,
+ fontFamily: "'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'Courier New', monospace",
});
-globalStyle(`body.${lotusTerminalBodyClass}::after`, {
- content: '""',
+// Scanlines — EXACT from TDS body::before
+globalStyle(`body.${lotusTerminalBodyClass}::before`, {
+ content: "''",
position: 'fixed',
- top: 0,
- left: 0,
- right: 0,
- bottom: 0,
+ inset: 0,
+ background: 'repeating-linear-gradient(0deg, rgba(0,0,0,0.07) 0px, rgba(0,0,0,0.07) 1px, transparent 1px, transparent 3px)',
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',
+// Vignette — EXACT from TDS body::after
+globalStyle(`body.${lotusTerminalBodyClass}::after`, {
+ content: "''",
+ position: 'fixed',
+ inset: 0,
+ background: 'radial-gradient(ellipse at center, transparent 55%, rgba(0,0,0,0.60) 100%)',
+ pointerEvents: 'none',
+ zIndex: 9998,
+});
+
+// Orange caret
+globalStyle(`body.${lotusTerminalBodyClass} input, body.${lotusTerminalBodyClass} textarea`, {
+ caretColor: '#FF6B00',
+});
+
+// Glitch class support
+globalStyle(`body.${lotusTerminalBodyClass} .lt-glitch`, { position: 'relative' });
+
+globalStyle(
+ `body.${lotusTerminalBodyClass} .lt-glitch::before, body.${lotusTerminalBodyClass} .lt-glitch::after`,
+ {
+ content: 'attr(data-text)' as any,
+ position: 'absolute',
+ top: 0,
+ left: 0,
+ width: '100%',
+ overflow: 'hidden',
+ }
+);
+
+globalStyle(`body.${lotusTerminalBodyClass} .lt-glitch::before`, {
+ color: '#00D4FF',
+ opacity: 0.65,
+ animationName: glitch1,
+ animationDuration: '4s',
+ animationIterationCount: 'infinite',
+});
+
+globalStyle(`body.${lotusTerminalBodyClass} .lt-glitch::after`, {
+ color: '#FF6B00',
+ animationName: glitch2,
+ animationDuration: '4s',
+ animationIterationCount: 'infinite',
+});
+
+// Scrollbar styling — matching TDS
+globalStyle(`body.${lotusTerminalBodyClass} ::-webkit-scrollbar`, { width: '6px', height: '6px' });
+globalStyle(`body.${lotusTerminalBodyClass} ::-webkit-scrollbar-track`, { background: '#030508' });
+globalStyle(`body.${lotusTerminalBodyClass} ::-webkit-scrollbar-thumb`, {
+ background: 'rgba(0,212,255,0.25)',
+ borderRadius: '3px',
+});
+globalStyle(`body.${lotusTerminalBodyClass} ::-webkit-scrollbar-thumb:hover`, {
+ background: 'rgba(0,212,255,0.50)',
});