Deepen TDS integration: full terminal CSS coverage + 3 new backgrounds
Terminal Mode: - Text selection: orange highlight rgba(255,107,0,0.28) - Links: cyan (#00D4FF) with orange hover glow (#FF6B00) - Code/pre: TDS green (#00FF88) on terminal bg, left green border - Strong/b → orange, em/i → cyan, mark → amber, del → red - Blockquote: orange left border (matches chat reply quotes) - HR: cyan border with dim glow - Input/textarea/[contenteditable] focus: orange glow ring - Tables: TDS headers (orange+uppercase), cyan borders, hover rows - List markers: cyan ▸ for ul, orange for ol - Boot box-drawing alignment fixed (51→52 ═) - data-theme=\"dark\" set on html element when terminal active - Updated description: correct TDS palette names - ▶ Boot replay button in settings (visible when terminal on) Chat backgrounds (+3): - Tactical: LotusGuild TDS exact cyan dot-grid (28px) - Circuit: green grid + node dots on dark terminal bg - Hex Grid: isometric cyan hexagonal outlines Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,9 @@ export const BG_OPTIONS: { value: ChatBackground; label: string }[] = [
|
||||
{ value: 'polka', label: 'Polka' },
|
||||
{ value: 'triangles', label: 'Triangles' },
|
||||
{ value: 'plaid', label: 'Plaid' },
|
||||
{ value: 'tactical', label: 'Tactical' },
|
||||
{ value: 'circuit', label: 'Circuit' },
|
||||
{ value: 'hexgrid', label: 'Hex Grid' },
|
||||
];
|
||||
|
||||
const DARK: Record<ChatBackground, CSSProperties> = {
|
||||
@@ -118,6 +121,36 @@ const DARK: Record<ChatBackground, CSSProperties> = {
|
||||
'repeating-linear-gradient(90deg, transparent, transparent 7px, rgba(152,0,0,0.08) 7px, rgba(152,0,0,0.08) 8px)',
|
||||
].join(','),
|
||||
},
|
||||
|
||||
// LotusGuild TDS exact dot-grid
|
||||
tactical: {
|
||||
backgroundColor: '#030508',
|
||||
backgroundImage: 'radial-gradient(circle, rgba(0,212,255,0.055) 1px, transparent 1px)',
|
||||
backgroundSize: '28px 28px',
|
||||
},
|
||||
|
||||
// Circuit board — green grid with node dots
|
||||
circuit: {
|
||||
backgroundColor: '#040a04',
|
||||
backgroundImage: [
|
||||
'linear-gradient(rgba(0,255,136,0.045) 1px, transparent 1px)',
|
||||
'linear-gradient(90deg, rgba(0,255,136,0.045) 1px, transparent 1px)',
|
||||
'radial-gradient(circle, rgba(0,255,136,0.20) 1.5px, transparent 1.5px)',
|
||||
].join(','),
|
||||
backgroundSize: '40px 40px, 40px 40px, 40px 40px',
|
||||
backgroundPosition: '0 0, 0 0, 20px 20px',
|
||||
},
|
||||
|
||||
// Isometric hex grid — cyan outlines
|
||||
hexgrid: {
|
||||
backgroundColor: '#060c14',
|
||||
backgroundImage: [
|
||||
'linear-gradient(60deg, rgba(0,212,255,0.07) 25%, transparent 25%, transparent 75%, rgba(0,212,255,0.07) 75%)',
|
||||
'linear-gradient(120deg, rgba(0,212,255,0.07) 25%, transparent 25%, transparent 75%, rgba(0,212,255,0.07) 75%)',
|
||||
].join(','),
|
||||
backgroundSize: '30px 52px',
|
||||
backgroundPosition: '0 0, 15px 26px',
|
||||
},
|
||||
};
|
||||
|
||||
const LIGHT: Record<ChatBackground, CSSProperties> = {
|
||||
@@ -220,6 +253,33 @@ const LIGHT: Record<ChatBackground, CSSProperties> = {
|
||||
'repeating-linear-gradient(90deg, transparent, transparent 7px, rgba(200,0,0,0.09) 7px, rgba(200,0,0,0.09) 8px)',
|
||||
].join(','),
|
||||
},
|
||||
|
||||
tactical: {
|
||||
backgroundColor: '#f0f4fa',
|
||||
backgroundImage: 'radial-gradient(circle, rgba(0,100,200,0.08) 1px, transparent 1px)',
|
||||
backgroundSize: '28px 28px',
|
||||
},
|
||||
|
||||
circuit: {
|
||||
backgroundColor: '#f0f8f0',
|
||||
backgroundImage: [
|
||||
'linear-gradient(rgba(0,160,80,0.06) 1px, transparent 1px)',
|
||||
'linear-gradient(90deg, rgba(0,160,80,0.06) 1px, transparent 1px)',
|
||||
'radial-gradient(circle, rgba(0,160,80,0.22) 1.5px, transparent 1.5px)',
|
||||
].join(','),
|
||||
backgroundSize: '40px 40px, 40px 40px, 40px 40px',
|
||||
backgroundPosition: '0 0, 0 0, 20px 20px',
|
||||
},
|
||||
|
||||
hexgrid: {
|
||||
backgroundColor: '#f4f8ff',
|
||||
backgroundImage: [
|
||||
'linear-gradient(60deg, rgba(50,100,220,0.08) 25%, transparent 25%, transparent 75%, rgba(50,100,220,0.08) 75%)',
|
||||
'linear-gradient(120deg, rgba(50,100,220,0.08) 25%, transparent 25%, transparent 75%, rgba(50,100,220,0.08) 75%)',
|
||||
].join(','),
|
||||
backgroundSize: '30px 52px',
|
||||
backgroundPosition: '0 0, 15px 26px',
|
||||
},
|
||||
};
|
||||
|
||||
export const getChatBg = (bg: ChatBackground, isDark: boolean): CSSProperties =>
|
||||
|
||||
@@ -48,6 +48,7 @@ import {
|
||||
} from '../../../hooks/useTheme';
|
||||
import { stopPropagation } from '../../../utils/keyboard';
|
||||
import { BG_OPTIONS, getChatBg } from '../../lotus/chatBackground';
|
||||
import { resetBootSequence, runLotusBootSequence } from '../../../../lotus-boot';
|
||||
import { useMessageLayoutItems } from '../../../hooks/useMessageLayout';
|
||||
import { useMessageSpacingItems } from '../../../hooks/useMessageSpacing';
|
||||
import { useDateFormatItems } from '../../../hooks/useDateFormat';
|
||||
@@ -375,8 +376,33 @@ function Appearance() {
|
||||
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
|
||||
<SettingTile
|
||||
title="Lotus Terminal Mode"
|
||||
description="Red phosphor color scheme, monospace font, and retro CRT scanlines. A full visual overhaul."
|
||||
after={<Switch variant="Primary" value={lotusTerminal} onChange={setLotusTerminal} />}
|
||||
description="LotusGuild Terminal Design System: Anduril Orange + Ice Cyan + Matrix Green, dot-grid background, CRT scanlines, and boot sequence animation."
|
||||
after={
|
||||
<Box direction="Row" gap="200" align="Center">
|
||||
{lotusTerminal && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => { resetBootSequence(); runLotusBootSequence(true); }}
|
||||
title="Replay boot sequence"
|
||||
style={{
|
||||
background: 'transparent',
|
||||
border: '1px solid rgba(255,107,0,0.35)',
|
||||
color: '#FF6B00',
|
||||
fontSize: '0.65rem',
|
||||
padding: '0.2rem 0.6rem',
|
||||
cursor: 'pointer',
|
||||
fontFamily: 'inherit',
|
||||
letterSpacing: '0.1em',
|
||||
textTransform: 'uppercase',
|
||||
whiteSpace: 'nowrap',
|
||||
}}
|
||||
>
|
||||
▶ Boot
|
||||
</button>
|
||||
)}
|
||||
<Switch variant="Primary" value={lotusTerminal} onChange={setLotusTerminal} />
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
</SequenceCard>
|
||||
</Box>
|
||||
|
||||
@@ -22,12 +22,16 @@ export function UnAuthRouteThemeManager() {
|
||||
document.body.className = '';
|
||||
document.body.classList.add(configClass, varsClass);
|
||||
if (lotusTerminal) {
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
document.body.classList.add(...LotusTerminalTheme.classNames);
|
||||
document.body.classList.add(lotusTerminalBodyClass);
|
||||
} else if (systemThemeKind === ThemeKind.Dark) {
|
||||
document.body.classList.add(...DarkTheme.classNames);
|
||||
} else {
|
||||
document.body.classList.add(...LightTheme.classNames);
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
if (systemThemeKind === ThemeKind.Dark) {
|
||||
document.body.classList.add(...DarkTheme.classNames);
|
||||
} else {
|
||||
document.body.classList.add(...LightTheme.classNames);
|
||||
}
|
||||
}
|
||||
}, [systemThemeKind, lotusTerminal]);
|
||||
|
||||
@@ -46,8 +50,11 @@ export function AuthRouteThemeManager({ children }: { children: ReactNode }) {
|
||||
document.body.classList.add(configClass, varsClass);
|
||||
document.body.classList.add(...effectiveTheme.classNames);
|
||||
if (lotusTerminal) {
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
document.body.classList.add(lotusTerminalBodyClass);
|
||||
runLotusBootSequence();
|
||||
} else {
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
}
|
||||
if (monochromeMode && !lotusTerminal) {
|
||||
document.body.style.filter = 'grayscale(1)';
|
||||
|
||||
@@ -3,7 +3,7 @@ import { atom } from 'jotai';
|
||||
const STORAGE_KEY = 'settings';
|
||||
export type DateFormat = 'D MMM YYYY' | 'DD/MM/YYYY' | 'MM/DD/YYYY' | 'YYYY/MM/DD' | '';
|
||||
export type MessageSpacing = '0' | '100' | '200' | '300' | '400' | '500';
|
||||
export type ChatBackground = 'none' | 'blueprint' | 'carbon' | 'stars' | 'topographic' | 'herringbone' | 'crosshatch' | 'chevron' | 'polka' | 'triangles' | 'plaid';
|
||||
export type ChatBackground = 'none' | 'blueprint' | 'carbon' | 'stars' | 'topographic' | 'herringbone' | 'crosshatch' | 'chevron' | 'polka' | 'triangles' | 'plaid' | 'tactical' | 'circuit' | 'hexgrid';
|
||||
export enum MessageLayout {
|
||||
Modern = 0,
|
||||
Compact = 1,
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
const BOOT_MESSAGES = [
|
||||
'╔═══════════════════════════════════════════════════╗',
|
||||
'╔════════════════════════════════════════════════════╗',
|
||||
'║ LOTUS CHAT — LOTUSGUILD PLATFORM ║',
|
||||
'║ SECURE MATRIX CLIENT — TERMINAL MODE ACTIVE ║',
|
||||
'╚════════════════════════════════════════════════════╝',
|
||||
|
||||
@@ -157,3 +157,143 @@ globalStyle(`body.${lotusTerminalBodyClass} ::-webkit-scrollbar-thumb`, {
|
||||
globalStyle(`body.${lotusTerminalBodyClass} ::-webkit-scrollbar-thumb:hover`, {
|
||||
background: 'rgba(0,212,255,0.50)',
|
||||
});
|
||||
|
||||
// ── Text selection — orange highlight (TDS aesthetic) ─────────────────────
|
||||
globalStyle(`body.${lotusTerminalBodyClass} ::selection`, {
|
||||
background: 'rgba(255,107,0,0.28)',
|
||||
color: '#ffffff',
|
||||
});
|
||||
|
||||
// ── Links — cyan primary, orange on hover with glow ────────────────────────
|
||||
globalStyle(`body.${lotusTerminalBodyClass} a`, {
|
||||
color: '#00D4FF',
|
||||
textDecoration: 'none',
|
||||
transition: 'color 0.12s ease, text-shadow 0.12s ease',
|
||||
});
|
||||
globalStyle(`body.${lotusTerminalBodyClass} a:hover`, {
|
||||
color: '#FF6B00',
|
||||
textShadow: '0 0 6px #FF6B00, 0 0 16px rgba(255,107,0,0.55)',
|
||||
});
|
||||
globalStyle(`body.${lotusTerminalBodyClass} a:focus-visible`, {
|
||||
outline: '2px solid #00D4FF',
|
||||
outlineOffset: '2px',
|
||||
});
|
||||
|
||||
// ── Code blocks — TDS exact: green text, dark bg, left border ──────────────
|
||||
globalStyle(`body.${lotusTerminalBodyClass} code`, {
|
||||
fontFamily: "'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'Courier New', monospace",
|
||||
fontSize: '0.8em',
|
||||
background: '#010304',
|
||||
border: '1px solid rgba(0,212,255,0.16)',
|
||||
color: '#00FF88',
|
||||
padding: '0.1em 0.4em',
|
||||
borderRadius: '2px',
|
||||
});
|
||||
globalStyle(`body.${lotusTerminalBodyClass} pre`, {
|
||||
fontFamily: "'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'Courier New', monospace",
|
||||
fontSize: '0.8rem',
|
||||
background: '#010304',
|
||||
border: '1px solid rgba(0,212,255,0.16)',
|
||||
borderLeft: '2px solid #00FF88',
|
||||
color: '#00FF88',
|
||||
textShadow: '0 0 6px rgba(0,255,136,0.35)',
|
||||
padding: '1rem',
|
||||
overflowX: 'auto',
|
||||
whiteSpace: 'pre-wrap',
|
||||
lineHeight: 1.6,
|
||||
});
|
||||
globalStyle(`body.${lotusTerminalBodyClass} pre code`, {
|
||||
background: 'transparent',
|
||||
border: 'none',
|
||||
padding: 0,
|
||||
fontSize: 'inherit',
|
||||
color: 'inherit',
|
||||
textShadow: 'inherit',
|
||||
});
|
||||
|
||||
// ── Inline text semantics ──────────────────────────────────────────────────
|
||||
globalStyle(`body.${lotusTerminalBodyClass} strong, body.${lotusTerminalBodyClass} b`, {
|
||||
color: '#FF6B00',
|
||||
fontWeight: '700',
|
||||
});
|
||||
globalStyle(`body.${lotusTerminalBodyClass} em, body.${lotusTerminalBodyClass} i`, {
|
||||
color: '#00D4FF',
|
||||
fontStyle: 'italic',
|
||||
});
|
||||
globalStyle(`body.${lotusTerminalBodyClass} mark`, {
|
||||
background: 'rgba(255,179,0,0.25)',
|
||||
color: '#FFB300',
|
||||
padding: '0 0.25em',
|
||||
});
|
||||
globalStyle(`body.${lotusTerminalBodyClass} del, body.${lotusTerminalBodyClass} s`, {
|
||||
color: '#FF2D55',
|
||||
opacity: 0.7,
|
||||
});
|
||||
|
||||
// ── Blockquote — TDS orange left border (matches reply quotes in chat) ──────
|
||||
globalStyle(`body.${lotusTerminalBodyClass} blockquote`, {
|
||||
borderLeft: '2px solid #FF6B00',
|
||||
background: 'rgba(255,107,0,0.05)',
|
||||
color: '#7fa3bf',
|
||||
padding: '0.4rem 0.75rem',
|
||||
margin: '0.25rem 0',
|
||||
fontStyle: 'italic',
|
||||
});
|
||||
|
||||
// ── Horizontal rule — cyan dim glow ────────────────────────────────────────
|
||||
globalStyle(`body.${lotusTerminalBodyClass} hr`, {
|
||||
border: 'none',
|
||||
borderTop: '1px solid rgba(0,212,255,0.22)',
|
||||
boxShadow: '0 0 6px rgba(0,212,255,0.15)',
|
||||
margin: '1rem 0',
|
||||
});
|
||||
|
||||
// ── Input / textarea / contenteditable focus — orange glow ─────────────────
|
||||
globalStyle(
|
||||
`body.${lotusTerminalBodyClass} input:focus,` +
|
||||
`body.${lotusTerminalBodyClass} textarea:focus`,
|
||||
{
|
||||
outline: 'none',
|
||||
borderColor: '#FF6B00',
|
||||
boxShadow: '0 0 0 2px rgba(255,107,0,0.25), 0 0 12px rgba(255,107,0,0.12)',
|
||||
}
|
||||
);
|
||||
globalStyle(`body.${lotusTerminalBodyClass} [contenteditable="true"]:focus`, {
|
||||
outline: 'none',
|
||||
boxShadow: '0 0 0 1px rgba(255,107,0,0.45), 0 0 12px rgba(255,107,0,0.12)',
|
||||
});
|
||||
|
||||
// ── Tables — TDS style ──────────────────────────────────────────────────────
|
||||
globalStyle(`body.${lotusTerminalBodyClass} table`, {
|
||||
width: '100%',
|
||||
borderCollapse: 'collapse',
|
||||
fontSize: '0.8rem',
|
||||
border: '1px solid rgba(0,212,255,0.16)',
|
||||
});
|
||||
globalStyle(`body.${lotusTerminalBodyClass} th`, {
|
||||
color: '#FF6B00',
|
||||
fontWeight: '700',
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: '0.10em',
|
||||
padding: '0.5rem 0.75rem',
|
||||
borderBottom: '1px solid rgba(0,212,255,0.22)',
|
||||
background: 'rgba(255,107,0,0.06)',
|
||||
textAlign: 'left',
|
||||
});
|
||||
globalStyle(`body.${lotusTerminalBodyClass} td`, {
|
||||
padding: '0.5rem 0.75rem',
|
||||
borderBottom: '1px solid rgba(0,212,255,0.07)',
|
||||
color: '#c4d9ee',
|
||||
});
|
||||
globalStyle(`body.${lotusTerminalBodyClass} tr:hover td`, {
|
||||
background: 'rgba(255,107,0,0.035)',
|
||||
});
|
||||
|
||||
// ── Lists — add TDS prefix character ───────────────────────────────────────
|
||||
globalStyle(`body.${lotusTerminalBodyClass} ul li::marker`, {
|
||||
color: '#00D4FF',
|
||||
content: '"▸ "',
|
||||
});
|
||||
globalStyle(`body.${lotusTerminalBodyClass} ol li::marker`, {
|
||||
color: '#FF6B00',
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user