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:
2026-03-26 00:12:04 -04:00
parent 1d8d274fdd
commit d5dc96178f
3 changed files with 406 additions and 51 deletions
+356 -39
View File
@@ -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 {
html[data-theme="light"] .lt-section { background: var(--bg-card); border-color: var(--border-color); } 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-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); }
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
+5 -12
View File
@@ -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([
+45
View File
@@ -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,