feat: final production polish — light mode rebuild, lt.init(), cross-tab theme
Light mode — complete rebuild (section 51):
- Full token override for every surface, component, and state
- Desaturated accents: orange #c44e00, cyan #0062b8, green #006d35 etc.
- Glows replaced with subtle drop-shadow rings (no neon on white)
- Covers: toasts, modals, dropdowns, notification panel, context menu,
right drawer, combobox, typeahead, wizard, timeline, pagination, tabs,
badges, tables, code blocks, skeleton, avatar, sortable, markdown,
scrollbars, buttons, nav drawer, WS status — nothing missed
- Dot-grid: neutral gray (was incorrect blue tint)
- Toast background uses var(--bg-overlay) instead of hardcoded dark rgba
Theme system improvements:
- _applyTheme now sets document.documentElement.style.colorScheme
- theme-color meta tag syncs on toggle (browser chrome follows theme)
- Cross-tab sync via storage event (toggle in one tab updates others)
lt.init() master initializer:
- Single call wires accordion, tooltip, alerts, clipboard, sidebar,
submenus, and boot sequence
- Replaces 6+ individual .init() calls in user code
- demo HTML updated to use lt.init({ bootName: 'MY APP' })
Accessibility:
- Ticket table: add <caption class="lt-sr-only"> for WCAG compliance
- Table gets aria-label attribute
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1239,11 +1239,11 @@ select option:checked {
|
|||||||
min-width: 240px;
|
min-width: 240px;
|
||||||
max-width: 380px;
|
max-width: 380px;
|
||||||
border-left: 2px solid currentColor;
|
border-left: 2px solid currentColor;
|
||||||
background: rgba(6,12,20,0.97);
|
background: var(--bg-overlay, rgba(6,12,20,0.97));
|
||||||
backdrop-filter: blur(8px);
|
backdrop-filter: blur(8px);
|
||||||
border-top: 1px solid rgba(255,255,255,0.04);
|
border-top: 1px solid var(--border-dim);
|
||||||
border-right: 1px solid rgba(255,255,255,0.04);
|
border-right: 1px solid var(--border-dim);
|
||||||
border-bottom: 1px solid rgba(255,255,255,0.04);
|
border-bottom: 1px solid var(--border-dim);
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
animation: toast-in 0.2s ease;
|
animation: toast-in 0.2s ease;
|
||||||
clip-path: polygon(0 0, calc(100% - 8px) 0, 100% 8px, 100% 100%, 0 100%);
|
clip-path: polygon(0 0, calc(100% - 8px) 0, 100% 8px, 100% 100%, 0 100%);
|
||||||
@@ -3343,63 +3343,380 @@ input[type="range"].lt-range::-moz-range-thumb {
|
|||||||
/* ----------------------------------------------------------------
|
/* ----------------------------------------------------------------
|
||||||
51. LIGHT THEME
|
51. LIGHT THEME
|
||||||
---------------------------------------------------------------- */
|
---------------------------------------------------------------- */
|
||||||
|
/* ================================================================
|
||||||
|
LIGHT MODE — complete token overrides
|
||||||
|
Design intent: "military intelligence dashboard, daylight reading"
|
||||||
|
Clean off-white surfaces, desaturated accents, no neon.
|
||||||
|
================================================================ */
|
||||||
html[data-theme="light"] {
|
html[data-theme="light"] {
|
||||||
--bg-primary: #eef1f6;
|
/* — Surfaces — */
|
||||||
--bg-secondary: #e2e6ed;
|
--bg-primary: #edf0f5;
|
||||||
--bg-tertiary: #d5dae3;
|
--bg-secondary: #e2e7ef;
|
||||||
|
--bg-tertiary: #d4dae6;
|
||||||
--bg-card: #ffffff;
|
--bg-card: #ffffff;
|
||||||
--bg-terminal: #f7f9fc;
|
--bg-terminal: #f4f6fa;
|
||||||
--bg-overlay: rgba(238,241,246,0.96);
|
--bg-overlay: rgba(237,240,245,0.97);
|
||||||
--bg-input: #ffffff;
|
--bg-input: #ffffff;
|
||||||
|
|
||||||
--text-primary: #1a2035;
|
/* — Typography — */
|
||||||
--text-secondary: #3a4a6a;
|
--text-primary: #111827; /* near-black, high contrast */
|
||||||
--text-muted: #647898;
|
--text-secondary: #2d3d56;
|
||||||
--text-dim: #8fa0b8;
|
--text-muted: #5a6e8c;
|
||||||
|
--text-dim: #8a9ab8;
|
||||||
|
|
||||||
--border-color: rgba(0,100,180,0.20);
|
/* — Borders — */
|
||||||
--border-color-hi: var(--accent-cyan);
|
--border-color: rgba(50,80,130,0.18);
|
||||||
--border-color-dim: rgba(0,100,180,0.10);
|
--border-color-hi: #0062b8;
|
||||||
--border-dim: rgba(0,100,180,0.10);
|
--border-color-dim: rgba(50,80,130,0.09);
|
||||||
|
--border-dim: rgba(50,80,130,0.09);
|
||||||
|
|
||||||
/* Slightly muted glows for light bg */
|
/* — Accent colors: desaturated for readability on white — */
|
||||||
--glow-orange: 0 0 4px rgba(255,107,0,0.6), 0 0 10px rgba(255,107,0,0.3);
|
--accent-orange: #c44e00;
|
||||||
--glow-cyan: 0 0 4px rgba(0,150,200,0.6), 0 0 10px rgba(0,150,200,0.3);
|
--accent-cyan: #0062b8;
|
||||||
--glow-green: 0 0 4px rgba(0,180,80,0.5), 0 0 10px rgba(0,180,80,0.25);
|
--accent-green: #006d35;
|
||||||
--glow-red: 0 0 4px rgba(220,0,50,0.5), 0 0 10px rgba(220,0,50,0.25);
|
--accent-red: #b5001f;
|
||||||
--glow-amber: 0 0 4px rgba(200,130,0,0.5), 0 0 10px rgba(200,130,0,0.25);
|
--accent-amber: #8a5a00;
|
||||||
|
--accent-purple: #6b2fb8;
|
||||||
|
|
||||||
|
/* — Accent tints — */
|
||||||
|
--accent-orange-dim: rgba(196,78,0,0.10);
|
||||||
|
--accent-cyan-dim: rgba(0,98,184,0.10);
|
||||||
|
--accent-green-dim: rgba(0,109,53,0.10);
|
||||||
|
--accent-red-dim: rgba(181,0,31,0.10);
|
||||||
|
--accent-amber-dim: rgba(138,90,0,0.10);
|
||||||
|
--accent-cyan-border: rgba(0,98,184,0.28);
|
||||||
|
|
||||||
|
/* — Glows become subtle drop shadows in light mode — */
|
||||||
|
--glow-orange: 0 0 0 1px rgba(196,78,0,0.25), 0 1px 6px rgba(196,78,0,0.18);
|
||||||
|
--glow-cyan: 0 0 0 1px rgba(0,98,184,0.25), 0 1px 6px rgba(0,98,184,0.18);
|
||||||
|
--glow-green: 0 0 0 1px rgba(0,109,53,0.25), 0 1px 6px rgba(0,109,53,0.18);
|
||||||
|
--glow-red: 0 0 0 1px rgba(181,0,31,0.25), 0 1px 6px rgba(181,0,31,0.18);
|
||||||
|
--glow-amber: 0 0 0 1px rgba(138,90,0,0.25), 0 1px 6px rgba(138,90,0,0.18);
|
||||||
|
--glow-orange-intense: 0 0 0 2px rgba(196,78,0,0.35), 0 2px 10px rgba(196,78,0,0.25);
|
||||||
|
--glow-cyan-intense: 0 0 0 2px rgba(0,98,184,0.35), 0 2px 10px rgba(0,98,184,0.25);
|
||||||
|
--glow-green-intense: 0 0 0 2px rgba(0,109,53,0.35), 0 2px 10px rgba(0,109,53,0.25);
|
||||||
|
--glow-amber-intense: 0 0 0 2px rgba(138,90,0,0.35), 0 2px 10px rgba(138,90,0,0.25);
|
||||||
|
|
||||||
|
/* — Box glows (card/input focus rings) — */
|
||||||
|
--box-glow-orange: 0 0 0 2px rgba(196,78,0,0.22), 0 2px 8px rgba(196,78,0,0.12);
|
||||||
|
--box-glow-cyan: 0 0 0 2px rgba(0,98,184,0.22), 0 2px 8px rgba(0,98,184,0.12);
|
||||||
|
--box-glow-green: 0 0 0 2px rgba(0,109,53,0.22), 0 2px 8px rgba(0,109,53,0.12);
|
||||||
|
--box-glow-red: 0 0 0 2px rgba(181,0,31,0.22), 0 2px 8px rgba(181,0,31,0.12);
|
||||||
|
--box-glow-amber: 0 0 0 2px rgba(138,90,0,0.22), 0 2px 8px rgba(138,90,0,0.12);
|
||||||
|
|
||||||
color-scheme: light;
|
color-scheme: light;
|
||||||
}
|
}
|
||||||
/* Hide CRT overlays in light mode */
|
|
||||||
|
/* — CRT / vignette / scanlines — off in light mode — */
|
||||||
html[data-theme="light"] body::before,
|
html[data-theme="light"] body::before,
|
||||||
html[data-theme="light"] body::after { display: none; }
|
html[data-theme="light"] body::after { display: none; }
|
||||||
/* Override hardcoded dot-grid background on html element */
|
|
||||||
|
/* — Dot-grid: neutral gray, not blue — */
|
||||||
html[data-theme="light"] {
|
html[data-theme="light"] {
|
||||||
background-image: radial-gradient(circle, rgba(0,80,160,0.12) 1px, transparent 1px);
|
background-image: radial-gradient(circle, rgba(90,110,150,0.14) 1px, transparent 1px);
|
||||||
|
background-color: var(--bg-primary);
|
||||||
}
|
}
|
||||||
/* Header — hardcoded dark rgba needs explicit light override */
|
|
||||||
|
/* — Layout chrome — */
|
||||||
html[data-theme="light"] .lt-header {
|
html[data-theme="light"] .lt-header {
|
||||||
background: rgba(238,241,246,0.97);
|
background: rgba(237,240,245,0.97);
|
||||||
border-bottom-color: var(--border-color);
|
border-bottom-color: var(--border-color);
|
||||||
|
box-shadow: 0 1px 8px rgba(0,0,0,0.08);
|
||||||
}
|
}
|
||||||
html[data-theme="light"] .lt-main { background: transparent; }
|
html[data-theme="light"] .lt-main { background: transparent; }
|
||||||
html[data-theme="light"] .lt-section-header { background: linear-gradient(90deg, var(--bg-secondary) 0%, transparent 100%); }
|
html[data-theme="light"] .lt-sidebar {
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border-color: var(--border-color);
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
html[data-theme="light"] .lt-nav-drawer {
|
||||||
|
background: var(--bg-card);
|
||||||
|
box-shadow: 2px 0 16px rgba(0,0,0,0.12);
|
||||||
|
}
|
||||||
|
html[data-theme="light"] .lt-nav-drawer-overlay { background: rgba(0,0,0,0.25); }
|
||||||
|
|
||||||
|
/* — Nav links — */
|
||||||
html[data-theme="light"] .lt-nav-link,
|
html[data-theme="light"] .lt-nav-link,
|
||||||
html[data-theme="light"] .lt-nav-link:hover { color: var(--text-secondary); }
|
html[data-theme="light"] .lt-nav-link:hover { color: var(--text-secondary); }
|
||||||
html[data-theme="light"] .lt-nav-link.active { color: var(--accent-orange); }
|
html[data-theme="light"] .lt-nav-link.active { color: var(--accent-orange); }
|
||||||
html[data-theme="light"] .lt-sidebar { background: var(--bg-secondary); border-color: var(--border-color); }
|
html[data-theme="light"] .lt-nav-drawer-link { color: var(--text-secondary); }
|
||||||
|
html[data-theme="light"] .lt-nav-drawer-link:hover { background: var(--accent-cyan-dim); color: var(--accent-cyan); }
|
||||||
|
html[data-theme="light"] .lt-nav-drawer-link.active { color: var(--accent-orange); background: var(--accent-orange-dim); }
|
||||||
|
html[data-theme="light"] .lt-sidebar-nav-link { color: var(--text-secondary); }
|
||||||
|
html[data-theme="light"] .lt-sidebar-nav-link:hover { background: var(--accent-cyan-dim); }
|
||||||
|
html[data-theme="light"] .lt-sidebar-nav-link.active { background: var(--accent-orange-dim); color: var(--accent-orange); }
|
||||||
|
|
||||||
|
/* — Surfaces: cards, frames, sections — */
|
||||||
html[data-theme="light"] .lt-card,
|
html[data-theme="light"] .lt-card,
|
||||||
html[data-theme="light"] .lt-frame { background: var(--bg-card); border-color: var(--border-color); }
|
html[data-theme="light"] .lt-frame {
|
||||||
|
background: var(--bg-card);
|
||||||
|
border-color: var(--border-color);
|
||||||
|
box-shadow: 0 1px 4px rgba(0,0,0,0.06);
|
||||||
|
}
|
||||||
html[data-theme="light"] .lt-section { background: var(--bg-card); border-color: var(--border-color); }
|
html[data-theme="light"] .lt-section { background: var(--bg-card); border-color: var(--border-color); }
|
||||||
|
html[data-theme="light"] .lt-section-header {
|
||||||
|
background: linear-gradient(90deg, var(--bg-secondary) 0%, transparent 100%);
|
||||||
|
border-bottom-color: var(--border-color);
|
||||||
|
color: var(--text-muted);
|
||||||
|
}
|
||||||
|
html[data-theme="light"] .lt-frame::before { color: var(--accent-orange); opacity: 0.6; }
|
||||||
|
html[data-theme="light"] .lt-frame-bl,
|
||||||
|
html[data-theme="light"] .lt-frame-br { color: var(--accent-cyan); opacity: 0.5; }
|
||||||
|
|
||||||
|
/* — Form controls — */
|
||||||
html[data-theme="light"] .lt-input,
|
html[data-theme="light"] .lt-input,
|
||||||
html[data-theme="light"] .lt-select,
|
html[data-theme="light"] .lt-select,
|
||||||
html[data-theme="light"] .lt-textarea { background: var(--bg-input); border-color: var(--border-color); color: var(--text-primary); }
|
html[data-theme="light"] .lt-textarea {
|
||||||
html[data-theme="light"] .lt-table th { background: var(--bg-secondary); }
|
background: var(--bg-input);
|
||||||
html[data-theme="light"] .lt-table tr:hover td { background: rgba(0,100,200,0.04); }
|
border-color: rgba(50,80,130,0.22);
|
||||||
html[data-theme="light"] .lt-nav-drawer { background: var(--bg-card); }
|
color: var(--text-primary);
|
||||||
|
box-shadow: inset 0 1px 3px rgba(0,0,0,0.05);
|
||||||
|
}
|
||||||
|
html[data-theme="light"] .lt-input:focus,
|
||||||
|
html[data-theme="light"] .lt-select:focus,
|
||||||
|
html[data-theme="light"] .lt-textarea:focus {
|
||||||
|
border-color: var(--accent-cyan);
|
||||||
|
box-shadow: var(--box-glow-cyan);
|
||||||
|
}
|
||||||
|
html[data-theme="light"] .lt-label { color: var(--text-muted); }
|
||||||
|
|
||||||
|
/* — Buttons — */
|
||||||
|
html[data-theme="light"] .lt-btn {
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border-color: var(--border-color);
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
html[data-theme="light"] .lt-btn:hover {
|
||||||
|
background: var(--bg-tertiary);
|
||||||
|
border-color: rgba(50,80,130,0.3);
|
||||||
|
}
|
||||||
|
html[data-theme="light"] .lt-btn-primary { background: var(--accent-cyan); color: #fff; border-color: var(--accent-cyan); }
|
||||||
|
html[data-theme="light"] .lt-btn-primary:hover { background: #0070cc; border-color: #0070cc; }
|
||||||
|
html[data-theme="light"] .lt-btn-danger { background: var(--accent-red); color: #fff; border-color: var(--accent-red); }
|
||||||
|
html[data-theme="light"] .lt-btn-ghost { background: transparent; border-color: var(--border-color); color: var(--text-secondary); }
|
||||||
|
html[data-theme="light"] .lt-btn-ghost:hover { background: var(--accent-cyan-dim); color: var(--accent-cyan); }
|
||||||
|
|
||||||
|
/* — Tables — */
|
||||||
|
html[data-theme="light"] .lt-table th { background: var(--bg-secondary); color: var(--text-muted); border-color: var(--border-color); }
|
||||||
|
html[data-theme="light"] .lt-table td { border-color: var(--border-dim); color: var(--text-secondary); }
|
||||||
|
html[data-theme="light"] .lt-table tr:hover td { background: rgba(0,98,184,0.04); }
|
||||||
|
html[data-theme="light"] .lt-table-wrap { border-color: var(--border-color); }
|
||||||
|
|
||||||
|
/* — Badges & status — */
|
||||||
|
html[data-theme="light"] .lt-badge { background: var(--bg-tertiary); color: var(--text-secondary); }
|
||||||
|
html[data-theme="light"] .lt-badge-open { background: rgba(0,109,53,0.12); color: #006d35; }
|
||||||
|
html[data-theme="light"] .lt-badge-closed { background: rgba(90,110,150,0.12); color: #5a6e8c; }
|
||||||
|
html[data-theme="light"] .lt-badge-p1 { background: rgba(181,0,31,0.12); color: #b5001f; }
|
||||||
|
html[data-theme="light"] .lt-badge-p2 { background: rgba(196,78,0,0.12); color: #c44e00; }
|
||||||
|
html[data-theme="light"] .lt-badge-p3 { background: rgba(138,90,0,0.12); color: #8a5a00; }
|
||||||
|
html[data-theme="light"] .lt-badge-p4 { background: rgba(50,80,130,0.10); color: #2d3d56; }
|
||||||
|
html[data-theme="light"] .lt-badge-admin { background: rgba(107,47,184,0.12); color: #6b2fb8; }
|
||||||
|
|
||||||
|
/* — Toast — */
|
||||||
|
html[data-theme="light"] .lt-toast {
|
||||||
|
background: #ffffff;
|
||||||
|
border-color: var(--border-color);
|
||||||
|
border-top-color: var(--border-color);
|
||||||
|
border-right-color: var(--border-color);
|
||||||
|
border-bottom-color: var(--border-color);
|
||||||
|
box-shadow: 0 4px 20px rgba(0,0,0,0.12);
|
||||||
|
}
|
||||||
|
html[data-theme="light"] .lt-toast-icon { opacity: 0.9; }
|
||||||
|
html[data-theme="light"] .lt-toast-msg { color: var(--text-primary); }
|
||||||
|
|
||||||
|
/* — Modals — */
|
||||||
|
html[data-theme="light"] .lt-modal-overlay { background: rgba(30,40,70,0.45); }
|
||||||
|
html[data-theme="light"] .lt-modal {
|
||||||
|
background: var(--bg-card);
|
||||||
|
border-color: var(--border-color);
|
||||||
|
box-shadow: 0 8px 32px rgba(0,0,0,0.18);
|
||||||
|
}
|
||||||
|
html[data-theme="light"] .lt-modal-header {
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border-bottom-color: var(--border-color);
|
||||||
|
}
|
||||||
|
html[data-theme="light"] .lt-modal-footer {
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border-top-color: var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* — Command palette — */
|
||||||
|
html[data-theme="light"] .lt-cmd-overlay { background: rgba(30,40,70,0.45); }
|
||||||
|
html[data-theme="light"] .lt-cmd-palette { background: var(--bg-card); border-color: var(--border-color); box-shadow: 0 12px 40px rgba(0,0,0,0.2); }
|
||||||
|
html[data-theme="light"] .lt-cmd-input { background: var(--bg-input); color: var(--text-primary); border-color: var(--border-color); }
|
||||||
|
html[data-theme="light"] .lt-cmd-results { border-top-color: var(--border-color); }
|
||||||
|
html[data-theme="light"] .lt-cmd-item { color: var(--text-secondary); }
|
||||||
|
html[data-theme="light"] .lt-cmd-item:hover,
|
||||||
|
html[data-theme="light"] .lt-cmd-item.is-active { background: var(--accent-cyan-dim); color: var(--accent-cyan); }
|
||||||
|
html[data-theme="light"] .lt-cmd-group-label { color: var(--text-dim); background: var(--bg-secondary); }
|
||||||
|
|
||||||
|
/* — Context menu — */
|
||||||
|
html[data-theme="light"] .lt-context-menu { background: var(--bg-card); border-color: var(--border-color); box-shadow: 0 6px 20px rgba(0,0,0,0.15); }
|
||||||
|
html[data-theme="light"] .lt-context-menu-item { color: var(--text-secondary); }
|
||||||
|
html[data-theme="light"] .lt-context-menu-item:hover { background: var(--accent-cyan-dim); color: var(--accent-cyan); }
|
||||||
|
html[data-theme="light"] .lt-context-menu-divider { background: var(--border-dim); }
|
||||||
|
|
||||||
|
/* — Right drawer — */
|
||||||
|
html[data-theme="light"] .lt-drawer-right {
|
||||||
|
background: var(--bg-card);
|
||||||
|
border-left-color: var(--border-color);
|
||||||
|
box-shadow: -4px 0 24px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
html[data-theme="light"] .lt-drawer-right-header { background: var(--bg-secondary); border-bottom-color: var(--border-color); }
|
||||||
|
html[data-theme="light"] .lt-drawer-right-footer { background: var(--bg-secondary); border-top-color: var(--border-color); }
|
||||||
|
html[data-theme="light"] .lt-drawer-right-overlay { background: rgba(30,40,70,0.35); }
|
||||||
|
|
||||||
|
/* — Dropdowns & notification panel — */
|
||||||
|
html[data-theme="light"] .lt-dropdown-panel {
|
||||||
|
background: var(--bg-card);
|
||||||
|
border-color: var(--border-color);
|
||||||
|
box-shadow: 0 6px 20px rgba(0,0,0,0.12);
|
||||||
|
}
|
||||||
|
html[data-theme="light"] .lt-dropdown-item { color: var(--text-secondary); }
|
||||||
|
html[data-theme="light"] .lt-dropdown-item:hover { background: var(--accent-cyan-dim); color: var(--accent-cyan); }
|
||||||
|
html[data-theme="light"] .lt-dropdown-divider { background: var(--border-dim); }
|
||||||
|
html[data-theme="light"] .lt-notif-panel {
|
||||||
|
background: var(--bg-card);
|
||||||
|
border-color: var(--border-color);
|
||||||
|
box-shadow: 0 6px 20px rgba(0,0,0,0.12);
|
||||||
|
}
|
||||||
|
html[data-theme="light"] .lt-notif-panel-header { border-bottom-color: var(--border-dim); color: var(--text-muted); }
|
||||||
|
html[data-theme="light"] .lt-notif-item { border-bottom-color: var(--border-dim); }
|
||||||
|
html[data-theme="light"] .lt-notif-item:hover { background: var(--bg-secondary); }
|
||||||
|
html[data-theme="light"] .lt-notif-item--unread { background: rgba(0,98,184,0.05); }
|
||||||
|
html[data-theme="light"] .lt-notif-panel-footer { border-top-color: var(--border-dim); }
|
||||||
|
|
||||||
|
/* — Sidebar / accordion — */
|
||||||
|
html[data-theme="light"] .lt-accordion-header { background: var(--bg-secondary); color: var(--text-primary); border-color: var(--border-color); }
|
||||||
|
html[data-theme="light"] .lt-accordion-header:hover { background: var(--bg-tertiary); }
|
||||||
|
html[data-theme="light"] .lt-accordion-body { border-color: var(--border-color); background: var(--bg-card); }
|
||||||
|
|
||||||
|
/* — Code / terminal — */
|
||||||
html[data-theme="light"] code,
|
html[data-theme="light"] code,
|
||||||
html[data-theme="light"] .lt-code-block { background: var(--bg-secondary); color: var(--text-primary); }
|
html[data-theme="light"] .lt-code-block { background: var(--bg-terminal); color: var(--text-primary); border-color: var(--border-color); }
|
||||||
|
html[data-theme="light"] .lt-code-block .comment { color: #6c7e99; }
|
||||||
|
|
||||||
|
/* — Stat cards — */
|
||||||
|
html[data-theme="light"] .lt-stat-card { background: var(--bg-card); border-color: var(--border-color); box-shadow: 0 1px 4px rgba(0,0,0,0.06); }
|
||||||
|
html[data-theme="light"] .lt-stat-card:hover { box-shadow: var(--box-glow-cyan); border-color: var(--accent-cyan); }
|
||||||
|
|
||||||
|
/* — Timeline — */
|
||||||
|
html[data-theme="light"] .lt-timeline-item::before { background: var(--border-color); }
|
||||||
|
html[data-theme="light"] .lt-timeline-actor { color: var(--accent-cyan); }
|
||||||
|
html[data-theme="light"] .lt-timeline-body { color: var(--text-secondary); }
|
||||||
|
|
||||||
|
/* — Dividers — */
|
||||||
|
html[data-theme="light"] .lt-divider::before,
|
||||||
|
html[data-theme="light"] .lt-divider::after { background: var(--border-color); }
|
||||||
|
html[data-theme="light"] .lt-divider-label { color: var(--text-dim); }
|
||||||
|
|
||||||
|
/* — Tags / chips — */
|
||||||
|
html[data-theme="light"] .lt-tag { background: var(--bg-tertiary); border-color: var(--border-color); color: var(--text-secondary); }
|
||||||
|
|
||||||
|
/* — Tooltips — */
|
||||||
|
html[data-theme="light"] [data-tooltip]::before { background: #1a2035; color: #fff; }
|
||||||
|
html[data-theme="light"] [data-tooltip]::after { border-top-color: #1a2035; }
|
||||||
|
|
||||||
|
/* — Pagination — */
|
||||||
|
html[data-theme="light"] .lt-page-btn { background: var(--bg-card); border-color: var(--border-color); color: var(--text-secondary); }
|
||||||
|
html[data-theme="light"] .lt-page-btn:hover { background: var(--accent-cyan-dim); border-color: var(--accent-cyan); color: var(--accent-cyan); }
|
||||||
|
html[data-theme="light"] .lt-page-btn.active { background: var(--accent-cyan); color: #fff; border-color: var(--accent-cyan); }
|
||||||
|
html[data-theme="light"] .lt-page-btn[disabled] { opacity: 0.4; }
|
||||||
|
|
||||||
|
/* — Tabs — */
|
||||||
|
html[data-theme="light"] .lt-tab { color: var(--text-muted); border-bottom-color: transparent; }
|
||||||
|
html[data-theme="light"] .lt-tab:hover { color: var(--text-primary); }
|
||||||
|
html[data-theme="light"] .lt-tab.active { color: var(--accent-orange); border-bottom-color: var(--accent-orange); }
|
||||||
|
html[data-theme="light"] .lt-tabs { border-bottom-color: var(--border-color); }
|
||||||
|
|
||||||
|
/* — Offline banner — */
|
||||||
|
html[data-theme="light"] .lt-offline-banner { background: rgba(138,90,0,0.12); color: var(--accent-amber); border-color: rgba(138,90,0,0.25); }
|
||||||
|
|
||||||
|
/* — WS status indicator — */
|
||||||
|
html[data-theme="light"] .lt-ws-status { color: var(--text-muted); background: var(--bg-tertiary); border-color: var(--border-color); }
|
||||||
|
|
||||||
|
/* — Boot overlay — */
|
||||||
|
html[data-theme="light"] .lt-boot-overlay { background: var(--bg-primary); }
|
||||||
|
html[data-theme="light"] .lt-boot-text { color: var(--accent-cyan); }
|
||||||
|
|
||||||
|
/* — Section header accent arrow — */
|
||||||
|
html[data-theme="light"] .lt-section-title::before { color: var(--accent-orange); opacity: 0.8; }
|
||||||
|
|
||||||
|
/* — Breadcrumbs — */
|
||||||
|
html[data-theme="light"] .lt-breadcrumb-item a { color: var(--text-muted); }
|
||||||
|
html[data-theme="light"] .lt-breadcrumb-item.active { color: var(--text-primary); }
|
||||||
|
html[data-theme="light"] .lt-breadcrumb-sep { color: var(--text-dim); }
|
||||||
|
|
||||||
|
/* — Progress bars — */
|
||||||
|
html[data-theme="light"] .lt-progress { background: var(--bg-tertiary); }
|
||||||
|
html[data-theme="light"] .lt-progress-bar { background: var(--accent-cyan); }
|
||||||
|
|
||||||
|
/* — Skeleton loader — */
|
||||||
|
html[data-theme="light"] .lt-skeleton { background: linear-gradient(90deg, var(--bg-tertiary) 25%, var(--bg-secondary) 50%, var(--bg-tertiary) 75%); }
|
||||||
|
|
||||||
|
/* — Dropzone — */
|
||||||
|
html[data-theme="light"] .lt-dropzone { background: var(--bg-terminal); border-color: var(--border-color); }
|
||||||
|
html[data-theme="light"] .lt-dropzone.is-over { border-color: var(--accent-cyan); background: var(--accent-cyan-dim); }
|
||||||
|
|
||||||
|
/* — Wizard steps — */
|
||||||
|
html[data-theme="light"] .lt-wizard-step-num { background: var(--bg-tertiary); color: var(--text-muted); border-color: var(--border-color); }
|
||||||
|
html[data-theme="light"] .lt-wizard-step.active .lt-wizard-step-num { background: var(--accent-cyan); color: #fff; border-color: var(--accent-cyan); }
|
||||||
|
html[data-theme="light"] .lt-wizard-step.done .lt-wizard-step-num { background: var(--accent-green); color: #fff; border-color: var(--accent-green); }
|
||||||
|
html[data-theme="light"] .lt-wizard-connector { background: var(--border-color); }
|
||||||
|
|
||||||
|
/* — Avatar — */
|
||||||
|
html[data-theme="light"] .lt-avatar { background: var(--bg-tertiary); color: var(--text-primary); border-color: var(--border-color); }
|
||||||
|
|
||||||
|
/* — Lightbox — */
|
||||||
|
html[data-theme="light"] .lt-lightbox-overlay { background: rgba(15,20,40,0.92); }
|
||||||
|
|
||||||
|
/* — Split pane divider — */
|
||||||
|
html[data-theme="light"] .lt-split-divider { background: var(--border-color); }
|
||||||
|
html[data-theme="light"] .lt-split-divider:hover { background: var(--accent-cyan); }
|
||||||
|
|
||||||
|
/* — Theme button (active state in light mode) — */
|
||||||
|
html[data-theme="light"] .lt-theme-btn { color: var(--accent-orange); }
|
||||||
|
|
||||||
|
/* — Text glow utilities: replace neon with ink shadow in light mode — */
|
||||||
|
html[data-theme="light"] .lt-text-orange { text-shadow: none; color: var(--accent-orange); }
|
||||||
|
html[data-theme="light"] .lt-text-cyan { text-shadow: none; color: var(--accent-cyan); }
|
||||||
|
html[data-theme="light"] .lt-text-green { text-shadow: none; color: var(--accent-green); }
|
||||||
|
html[data-theme="light"] .lt-text-red { text-shadow: none; color: var(--accent-red); }
|
||||||
|
html[data-theme="light"] .lt-text-amber { text-shadow: none; color: var(--accent-amber); }
|
||||||
|
html[data-theme="light"] .lt-text-muted { color: var(--text-muted); }
|
||||||
|
|
||||||
|
/* — Markdown — */
|
||||||
|
html[data-theme="light"] .lt-markdown code { background: var(--bg-secondary); color: var(--accent-cyan); }
|
||||||
|
html[data-theme="light"] .lt-markdown blockquote { border-left-color: var(--accent-cyan); background: var(--accent-cyan-dim); }
|
||||||
|
|
||||||
|
/* — KV grid — */
|
||||||
|
html[data-theme="light"] .lt-kv-row { border-bottom-color: var(--border-dim); }
|
||||||
|
html[data-theme="light"] .lt-kv-label { color: var(--text-dim); }
|
||||||
|
|
||||||
|
/* — Empty state — */
|
||||||
|
html[data-theme="light"] .lt-empty-state-icon { color: var(--text-dim); }
|
||||||
|
html[data-theme="light"] .lt-empty-state-title { color: var(--text-secondary); }
|
||||||
|
|
||||||
|
/* — Combobox / typeahead — */
|
||||||
|
html[data-theme="light"] .lt-combobox-dropdown,
|
||||||
|
html[data-theme="light"] .lt-typeahead-dropdown { background: var(--bg-card); border-color: var(--border-color); box-shadow: 0 4px 16px rgba(0,0,0,0.1); }
|
||||||
|
html[data-theme="light"] .lt-combobox-option:hover,
|
||||||
|
html[data-theme="light"] .lt-typeahead-option:hover { background: var(--accent-cyan-dim); }
|
||||||
|
html[data-theme="light"] .lt-combobox-tag { background: var(--accent-cyan-dim); color: var(--accent-cyan); border-color: var(--accent-cyan-border); }
|
||||||
|
|
||||||
|
/* — Sortable ghost — */
|
||||||
|
html[data-theme="light"] .lt-sortable-placeholder { background: var(--accent-cyan-dim); border-color: var(--accent-cyan); }
|
||||||
|
|
||||||
|
/* — P-level row accents — softer in light mode — */
|
||||||
|
html[data-theme="light"] .lt-row-p1 { border-left-color: var(--accent-red); }
|
||||||
|
html[data-theme="light"] .lt-row-p2 { border-left-color: var(--accent-orange); }
|
||||||
|
html[data-theme="light"] .lt-row-p3 { border-left-color: var(--accent-amber); }
|
||||||
|
html[data-theme="light"] .lt-row-p4 { border-left-color: rgba(50,80,130,0.25); }
|
||||||
|
|
||||||
|
/* — Scrollbar light theme — */
|
||||||
|
html[data-theme="light"] ::-webkit-scrollbar-track { background: var(--bg-secondary); }
|
||||||
|
html[data-theme="light"] ::-webkit-scrollbar-thumb { background: var(--bg-tertiary); }
|
||||||
|
html[data-theme="light"] ::-webkit-scrollbar-thumb:hover { background: var(--accent-cyan); }
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------
|
/* ----------------------------------------------------------------
|
||||||
|
|||||||
@@ -455,7 +455,8 @@
|
|||||||
<div class="lt-section-header">Ticket Queue</div>
|
<div class="lt-section-header">Ticket Queue</div>
|
||||||
|
|
||||||
<div class="lt-table-wrap">
|
<div class="lt-table-wrap">
|
||||||
<table class="lt-table lt-table-responsive" id="ticket-table">
|
<table class="lt-table lt-table-responsive" id="ticket-table" aria-label="Ticket queue">
|
||||||
|
<caption class="lt-sr-only">Ticket queue — sorted by priority</caption>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th><input type="checkbox" class="lt-checkbox" aria-label="Select all"></th>
|
<th><input type="checkbox" class="lt-checkbox" aria-label="Select all"></th>
|
||||||
@@ -1696,17 +1697,9 @@ Storage array link-down on `compute-storage-01`.
|
|||||||
<!-- Init v1.2 modules -->
|
<!-- Init v1.2 modules -->
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
// Accordion
|
// One call initializes accordion, tooltip, alerts, clipboard, sidebar, submenus + boot.
|
||||||
lt.accordion.init();
|
// Pass { boot: false } to skip the terminal boot animation.
|
||||||
|
lt.init({ bootName: 'MY APP' });
|
||||||
// Tooltips (JS-positioned — optional, CSS tooltips work without this)
|
|
||||||
lt.tooltip.init();
|
|
||||||
|
|
||||||
// Clipboard copy buttons ([data-copy])
|
|
||||||
lt.clipboard.initCopyButtons();
|
|
||||||
|
|
||||||
// Alert dismiss buttons
|
|
||||||
lt.alerts.init();
|
|
||||||
|
|
||||||
// Command palette demo commands
|
// Command palette demo commands
|
||||||
lt.cmdPalette.init([
|
lt.cmdPalette.init([
|
||||||
|
|||||||
@@ -1462,7 +1462,11 @@
|
|||||||
const _themeKey = 'lt_theme';
|
const _themeKey = 'lt_theme';
|
||||||
function _applyTheme(t) {
|
function _applyTheme(t) {
|
||||||
document.documentElement.setAttribute('data-theme', t);
|
document.documentElement.setAttribute('data-theme', t);
|
||||||
|
document.documentElement.style.colorScheme = t;
|
||||||
try { localStorage.setItem(_themeKey, t); } catch(_) {}
|
try { localStorage.setItem(_themeKey, t); } catch(_) {}
|
||||||
|
// Sync theme-color meta for browser chrome
|
||||||
|
const metaTheme = document.querySelector('meta[name="theme-color"]');
|
||||||
|
if (metaTheme) metaTheme.setAttribute('content', t === 'light' ? '#edf0f5' : '#030508');
|
||||||
document.querySelectorAll('.lt-theme-btn').forEach(btn => {
|
document.querySelectorAll('.lt-theme-btn').forEach(btn => {
|
||||||
btn.textContent = t === 'light' ? '◐' : '☀';
|
btn.textContent = t === 'light' ? '◐' : '☀';
|
||||||
btn.setAttribute('aria-label', t === 'light' ? 'Switch to dark mode' : 'Switch to light mode');
|
btn.setAttribute('aria-label', t === 'light' ? 'Switch to dark mode' : 'Switch to light mode');
|
||||||
@@ -1480,6 +1484,10 @@
|
|||||||
let saved; try { saved = localStorage.getItem(_themeKey); } catch(_) {}
|
let saved; try { saved = localStorage.getItem(_themeKey); } catch(_) {}
|
||||||
if (!saved) _applyTheme(e.matches ? 'light' : 'dark');
|
if (!saved) _applyTheme(e.matches ? 'light' : 'dark');
|
||||||
});
|
});
|
||||||
|
// Sync theme across tabs via storage event
|
||||||
|
window.addEventListener('storage', e => {
|
||||||
|
if (e.key === _themeKey && e.newValue) _applyTheme(e.newValue);
|
||||||
|
});
|
||||||
const theme = {
|
const theme = {
|
||||||
toggle: () => _applyTheme(document.documentElement.getAttribute('data-theme') === 'light' ? 'dark' : 'light'),
|
toggle: () => _applyTheme(document.documentElement.getAttribute('data-theme') === 'light' ? 'dark' : 'light'),
|
||||||
set: t => _applyTheme(t),
|
set: t => _applyTheme(t),
|
||||||
@@ -2655,10 +2663,47 @@
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ================================================================
|
||||||
|
MASTER INIT
|
||||||
|
lt.init(opts?)
|
||||||
|
Call once after DOM ready. Runs all standard auto-init modules.
|
||||||
|
Opts: { boot: bool, bootName: str, tooltip: bool, accordion: bool,
|
||||||
|
alerts: bool, clipboard: bool, sidebar: bool, submenus: bool }
|
||||||
|
Individual modules can still be called manually.
|
||||||
|
================================================================ */
|
||||||
|
function ltInit(opts) {
|
||||||
|
const o = Object.assign({
|
||||||
|
boot: true,
|
||||||
|
bootName: null,
|
||||||
|
tooltip: true,
|
||||||
|
accordion: true,
|
||||||
|
alerts: true,
|
||||||
|
clipboard: true,
|
||||||
|
sidebar: true,
|
||||||
|
submenus: true,
|
||||||
|
}, opts || {});
|
||||||
|
|
||||||
|
if (o.accordion) accordion.init();
|
||||||
|
if (o.tooltip) tooltip.init();
|
||||||
|
if (o.alerts) alerts.init();
|
||||||
|
if (o.clipboard) initCopyButtons();
|
||||||
|
if (o.sidebar) initSidebar();
|
||||||
|
if (o.submenus) initSidebarSubmenus();
|
||||||
|
if (o.boot) {
|
||||||
|
const bootEl = document.getElementById('lt-boot');
|
||||||
|
if (bootEl) {
|
||||||
|
const name = o.bootName || bootEl.dataset.appName || document.title.split('—')[0].trim();
|
||||||
|
boot.run(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
PUBLIC API
|
PUBLIC API
|
||||||
---------------------------------------------------------------- */
|
---------------------------------------------------------------- */
|
||||||
global.lt = {
|
global.lt = {
|
||||||
|
/* Master initializer */
|
||||||
|
init: ltInit,
|
||||||
/* Core */
|
/* Core */
|
||||||
escHtml,
|
escHtml,
|
||||||
toast,
|
toast,
|
||||||
|
|||||||
Reference in New Issue
Block a user