From 893aa92b382ee74343f30124518bade41fd1379d Mon Sep 17 00:00:00 2001 From: root Date: Wed, 13 May 2026 22:44:34 -0400 Subject: [PATCH] Deepen TDS integration: full terminal CSS coverage + 3 new backgrounds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- src/app/features/lotus/chatBackground.ts | 60 ++++++++ src/app/features/settings/general/General.tsx | 30 +++- src/app/pages/ThemeManager.tsx | 13 +- src/app/state/settings.ts | 2 +- src/lotus-boot.ts | 2 +- src/lotus-terminal.css.ts | 140 ++++++++++++++++++ 6 files changed, 240 insertions(+), 7 deletions(-) diff --git a/src/app/features/lotus/chatBackground.ts b/src/app/features/lotus/chatBackground.ts index 5783ec7dd..498d8bad9 100644 --- a/src/app/features/lotus/chatBackground.ts +++ b/src/app/features/lotus/chatBackground.ts @@ -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 = { @@ -118,6 +121,36 @@ const DARK: Record = { '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 = { @@ -220,6 +253,33 @@ const LIGHT: Record = { '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 => diff --git a/src/app/features/settings/general/General.tsx b/src/app/features/settings/general/General.tsx index 8770a96cb..f32fb6456 100644 --- a/src/app/features/settings/general/General.tsx +++ b/src/app/features/settings/general/General.tsx @@ -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() { } + description="LotusGuild Terminal Design System: Anduril Orange + Ice Cyan + Matrix Green, dot-grid background, CRT scanlines, and boot sequence animation." + after={ + + {lotusTerminal && ( + + )} + + + } /> diff --git a/src/app/pages/ThemeManager.tsx b/src/app/pages/ThemeManager.tsx index 8c1e028db..df64119f2 100644 --- a/src/app/pages/ThemeManager.tsx +++ b/src/app/pages/ThemeManager.tsx @@ -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)'; diff --git a/src/app/state/settings.ts b/src/app/state/settings.ts index 709691107..f8c2bfc98 100644 --- a/src/app/state/settings.ts +++ b/src/app/state/settings.ts @@ -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, diff --git a/src/lotus-boot.ts b/src/lotus-boot.ts index 4c101a197..a5729478d 100644 --- a/src/lotus-boot.ts +++ b/src/lotus-boot.ts @@ -1,5 +1,5 @@ const BOOT_MESSAGES = [ - '╔═══════════════════════════════════════════════════╗', + '╔════════════════════════════════════════════════════╗', '║ LOTUS CHAT — LOTUSGUILD PLATFORM ║', '║ SECURE MATRIX CLIENT — TERMINAL MODE ACTIVE ║', '╚════════════════════════════════════════════════════╝', diff --git a/src/lotus-terminal.css.ts b/src/lotus-terminal.css.ts index eaafa3428..bfdb125da 100644 --- a/src/lotus-terminal.css.ts +++ b/src/lotus-terminal.css.ts @@ -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', +});