v1.2 → v1.3: responsive overhaul, mobile nav, accessibility & bug fixes
- 8-breakpoint responsive system (xs→4k) replacing 3-breakpoint stub - Off-canvas mobile nav drawer with swipe gestures and focus trap - iOS-safe scroll lock for modals (position:fixed pattern + ref count) - Modal focus trap with Tab cycling and return-focus to trigger - Z-index stack overhaul: modal > nav drawer, toast above scanlines - Fixed --border-dim CSS variable undefined across all v1.2 components - Fixed badge absolute positioning clipping in Component Reference - Fixed accordion CSS class mismatch (open → is-open) - Fixed command palette selector/class mismatches - Select dark mode: color-scheme:dark + option background - 4K scaling: rem-based overrides for all hardcoded px elements - Safe area insets for iPhone notch/home bar (viewport-fit:cover) - Touch targets: 44px min on all interactive elements (pointer:coarse) - Disabled glitch/pulse animations on coarse/hover:none devices - Table responsive card mode with data-label attributes - viewport.is() validation, debounce caching, 350ms orientation debounce - initMobileNav() guard prevents duplicate listener registration - cmd palette: input.select() on open, consistent scroll lock Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<!--
|
<!--
|
||||||
LOTUSGUILD TERMINAL DESIGN SYSTEM v1.0 — base.html
|
LOTUSGUILD TERMINAL DESIGN SYSTEM v2.0 — base.html
|
||||||
Reference template showing every component and layout pattern.
|
Reference template showing every component and layout pattern.
|
||||||
|
|
||||||
This file is a STATIC DEMO. Framework-specific wiring is in:
|
This file is a STATIC DEMO. Framework-specific wiring is in:
|
||||||
@@ -14,7 +14,11 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
||||||
|
<meta name="theme-color" content="#030508">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||||
<title>MY APP — LotusGuild</title>
|
<title>MY APP — LotusGuild</title>
|
||||||
<meta name="description" content="LotusGuild infrastructure application">
|
<meta name="description" content="LotusGuild infrastructure application">
|
||||||
|
|
||||||
@@ -24,7 +28,12 @@
|
|||||||
All <script> tags need: nonce="NONCE_PLACEHOLDER"
|
All <script> tags need: nonce="NONCE_PLACEHOLDER"
|
||||||
========================================================= -->
|
========================================================= -->
|
||||||
|
|
||||||
<!-- Base design system CSS -->
|
<!-- Monospace font: JetBrains Mono -->
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,400;0,600;0,700;1,400&display=swap" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Hacker template design system CSS -->
|
||||||
<link rel="stylesheet" href="/web_template/base.css">
|
<link rel="stylesheet" href="/web_template/base.css">
|
||||||
<!--
|
<!--
|
||||||
App-specific CSS (override or extend after base.css):
|
App-specific CSS (override or extend after base.css):
|
||||||
@@ -47,16 +56,42 @@
|
|||||||
<!-- ===========================================================
|
<!-- ===========================================================
|
||||||
HEADER
|
HEADER
|
||||||
=========================================================== -->
|
=========================================================== -->
|
||||||
|
<!-- ===========================================================
|
||||||
|
MOBILE NAV DRAWER (hidden on desktop, slides in on mobile)
|
||||||
|
=========================================================== -->
|
||||||
|
<div id="lt-nav-drawer" class="lt-nav-drawer" aria-hidden="true" role="dialog" aria-label="Navigation menu">
|
||||||
|
<div class="lt-nav-drawer-header">
|
||||||
|
<span class="lt-brand-title">MY APP</span>
|
||||||
|
<button class="lt-nav-drawer-close" id="lt-nav-drawer-close" aria-label="Close menu">✕</button>
|
||||||
|
</div>
|
||||||
|
<nav class="lt-nav-drawer-links" aria-label="Mobile navigation">
|
||||||
|
<a href="/" class="lt-nav-drawer-link active" aria-current="page">Dashboard</a>
|
||||||
|
<a href="/tickets" class="lt-nav-drawer-link">Tickets</a>
|
||||||
|
<a href="/workers" class="lt-nav-drawer-link">Workers</a>
|
||||||
|
<div class="lt-nav-drawer-section">Admin</div>
|
||||||
|
<a href="/admin/templates" class="lt-nav-drawer-link lt-nav-drawer-link--indent">Templates</a>
|
||||||
|
<a href="/admin/workflow" class="lt-nav-drawer-link lt-nav-drawer-link--indent">Workflow</a>
|
||||||
|
<a href="/admin/audit-log" class="lt-nav-drawer-link lt-nav-drawer-link--indent">Audit Log</a>
|
||||||
|
<a href="/admin/api-keys" class="lt-nav-drawer-link lt-nav-drawer-link--indent">API Keys</a>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
<div id="lt-nav-overlay" class="lt-nav-drawer-overlay"></div>
|
||||||
|
|
||||||
<header class="lt-header">
|
<header class="lt-header">
|
||||||
<div class="lt-header-left">
|
<div class="lt-header-left">
|
||||||
|
|
||||||
|
<!-- Hamburger — visible only on tablet/mobile (CSS hides on desktop) -->
|
||||||
|
<button class="lt-menu-btn" id="lt-menu-btn" aria-label="Open navigation menu" aria-expanded="false" aria-controls="lt-nav-drawer">
|
||||||
|
<span></span><span></span><span></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
<!-- Brand -->
|
<!-- Brand -->
|
||||||
<div class="lt-brand">
|
<div class="lt-brand">
|
||||||
<span class="lt-brand-title">MY APP</span>
|
<span class="lt-brand-title lt-glitch" data-text="MY APP">MY APP</span>
|
||||||
<span class="lt-brand-subtitle">LotusGuild Infrastructure</span>
|
<span class="lt-brand-subtitle">LotusGuild Infrastructure</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Horizontal nav links -->
|
<!-- Horizontal nav links (desktop) -->
|
||||||
<nav class="lt-nav" aria-label="Main navigation">
|
<nav class="lt-nav" aria-label="Main navigation">
|
||||||
<a href="/" class="lt-nav-link active">Dashboard</a>
|
<a href="/" class="lt-nav-link active">Dashboard</a>
|
||||||
<a href="/tickets" class="lt-nav-link">Tickets</a>
|
<a href="/tickets" class="lt-nav-link">Tickets</a>
|
||||||
@@ -233,7 +268,7 @@
|
|||||||
<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" id="ticket-table">
|
<table class="lt-table lt-table-responsive" id="ticket-table">
|
||||||
<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>
|
||||||
@@ -250,14 +285,14 @@
|
|||||||
|
|
||||||
<!-- P1 Critical row -->
|
<!-- P1 Critical row -->
|
||||||
<tr class="lt-row-p1 lt-row-critical">
|
<tr class="lt-row-p1 lt-row-critical">
|
||||||
<td><input type="checkbox" class="lt-checkbox"></td>
|
<td data-label="Select"><input type="checkbox" class="lt-checkbox"></td>
|
||||||
<td><a href="/ticket/123456789">#123456789</a></td>
|
<td data-label="ID"><a href="/ticket/123456789">#123456789</a></td>
|
||||||
<td><span class="lt-p1">P1 Critical</span></td>
|
<td data-label="Priority"><span class="lt-p1">P1 Critical</span></td>
|
||||||
<td>Storage array link-down on compute-storage-01</td>
|
<td data-label="Title">Storage array link-down on compute-storage-01</td>
|
||||||
<td><span class="lt-status lt-status-open">Open</span></td>
|
<td data-label="Status"><span class="lt-status lt-status-open">Open</span></td>
|
||||||
<td class="lt-text-muted">Unassigned</td>
|
<td data-label="Assignee" class="lt-text-muted">Unassigned</td>
|
||||||
<td class="lt-text-xs lt-text-muted">5m ago</td>
|
<td data-label="Created" class="lt-text-xs lt-text-muted">5m ago</td>
|
||||||
<td>
|
<td data-label="Actions">
|
||||||
<div class="lt-btn-group">
|
<div class="lt-btn-group">
|
||||||
<a href="/ticket/123456789" class="lt-btn lt-btn-sm">View</a>
|
<a href="/ticket/123456789" class="lt-btn lt-btn-sm">View</a>
|
||||||
<button class="lt-btn lt-btn-sm lt-btn-danger">Close</button>
|
<button class="lt-btn lt-btn-sm lt-btn-danger">Close</button>
|
||||||
@@ -267,14 +302,14 @@
|
|||||||
|
|
||||||
<!-- P2 High row -->
|
<!-- P2 High row -->
|
||||||
<tr class="lt-row-p2 lt-row-warning">
|
<tr class="lt-row-p2 lt-row-warning">
|
||||||
<td><input type="checkbox" class="lt-checkbox"></td>
|
<td data-label="Select"><input type="checkbox" class="lt-checkbox"></td>
|
||||||
<td><a href="/ticket/987654321">#987654321</a></td>
|
<td data-label="ID"><a href="/ticket/987654321">#987654321</a></td>
|
||||||
<td><span class="lt-p2">P2 High</span></td>
|
<td data-label="Priority"><span class="lt-p2">P2 High</span></td>
|
||||||
<td>Switch port flapping on USW-Pro-24</td>
|
<td data-label="Title">Switch port flapping on USW-Pro-24</td>
|
||||||
<td><span class="lt-status lt-status-in-progress">In Progress</span></td>
|
<td data-label="Status"><span class="lt-status lt-status-in-progress">In Progress</span></td>
|
||||||
<td>operator</td>
|
<td data-label="Assignee">operator</td>
|
||||||
<td class="lt-text-xs lt-text-muted">2h ago</td>
|
<td data-label="Created" class="lt-text-xs lt-text-muted">2h ago</td>
|
||||||
<td>
|
<td data-label="Actions">
|
||||||
<div class="lt-btn-group">
|
<div class="lt-btn-group">
|
||||||
<a href="/ticket/987654321" class="lt-btn lt-btn-sm">View</a>
|
<a href="/ticket/987654321" class="lt-btn lt-btn-sm">View</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -283,14 +318,14 @@
|
|||||||
|
|
||||||
<!-- P3 Medium row -->
|
<!-- P3 Medium row -->
|
||||||
<tr class="lt-row-p3">
|
<tr class="lt-row-p3">
|
||||||
<td><input type="checkbox" class="lt-checkbox"></td>
|
<td data-label="Select"><input type="checkbox" class="lt-checkbox"></td>
|
||||||
<td><a href="/ticket/111222333">#111222333</a></td>
|
<td data-label="ID"><a href="/ticket/111222333">#111222333</a></td>
|
||||||
<td><span class="lt-p3">P3 Med</span></td>
|
<td data-label="Priority"><span class="lt-p3">P3 Med</span></td>
|
||||||
<td>Scheduled maintenance: replace SFP+ on large1</td>
|
<td data-label="Title">Scheduled maintenance: replace SFP+ on large1</td>
|
||||||
<td><span class="lt-status lt-status-pending">Pending</span></td>
|
<td data-label="Status"><span class="lt-status lt-status-pending">Pending</span></td>
|
||||||
<td>admin</td>
|
<td data-label="Assignee">admin</td>
|
||||||
<td class="lt-text-xs lt-text-muted">1d ago</td>
|
<td data-label="Created" class="lt-text-xs lt-text-muted">1d ago</td>
|
||||||
<td>
|
<td data-label="Actions">
|
||||||
<div class="lt-btn-group">
|
<div class="lt-btn-group">
|
||||||
<a href="/ticket/111222333" class="lt-btn lt-btn-sm">View</a>
|
<a href="/ticket/111222333" class="lt-btn lt-btn-sm">View</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -299,14 +334,14 @@
|
|||||||
|
|
||||||
<!-- P4 closed -->
|
<!-- P4 closed -->
|
||||||
<tr class="lt-row-p4">
|
<tr class="lt-row-p4">
|
||||||
<td><input type="checkbox" class="lt-checkbox"></td>
|
<td data-label="Select"><input type="checkbox" class="lt-checkbox"></td>
|
||||||
<td><a href="/ticket/444555666">#444555666</a></td>
|
<td data-label="ID"><a href="/ticket/444555666">#444555666</a></td>
|
||||||
<td><span class="lt-p4">P4 Low</span></td>
|
<td data-label="Priority"><span class="lt-p4">P4 Low</span></td>
|
||||||
<td>Update SSL cert on wiki.lotusguild.org</td>
|
<td data-label="Title">Update SSL cert on wiki.lotusguild.org</td>
|
||||||
<td><span class="lt-status lt-status-closed">Closed</span></td>
|
<td data-label="Status"><span class="lt-status lt-status-closed">Closed</span></td>
|
||||||
<td>operator</td>
|
<td data-label="Assignee">operator</td>
|
||||||
<td class="lt-text-xs lt-text-muted">3d ago</td>
|
<td data-label="Created" class="lt-text-xs lt-text-muted">3d ago</td>
|
||||||
<td>
|
<td data-label="Actions">
|
||||||
<div class="lt-btn-group">
|
<div class="lt-btn-group">
|
||||||
<a href="/ticket/444555666" class="lt-btn lt-btn-sm">View</a>
|
<a href="/ticket/444555666" class="lt-btn lt-btn-sm">View</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -598,6 +633,306 @@
|
|||||||
</div><!-- /.lt-frame-inner -->
|
</div><!-- /.lt-frame-inner -->
|
||||||
</div><!-- /.lt-frame (component showcase) -->
|
</div><!-- /.lt-frame (component showcase) -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ===========================================================
|
||||||
|
COMPONENT SHOWCASE — v1.2 ADDITIONS
|
||||||
|
=========================================================== -->
|
||||||
|
<div class="lt-frame lt-mt-lg">
|
||||||
|
<div class="lt-frame-inner">
|
||||||
|
|
||||||
|
<!-- PROGRESS BARS -->
|
||||||
|
<div class="lt-section-header">Progress Bars</div>
|
||||||
|
<div class="lt-section-body">
|
||||||
|
<div style="display:flex;flex-direction:column;gap:var(--space-md)">
|
||||||
|
<div>
|
||||||
|
<div class="lt-progress-label"><span>CPU LOAD</span><span>72%</span></div>
|
||||||
|
<div class="lt-progress"><div class="lt-progress-bar" style="width:72%" data-width="72%"></div></div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="lt-progress-label"><span>MEMORY</span><span>45%</span></div>
|
||||||
|
<div class="lt-progress lt-progress--cyan"><div class="lt-progress-bar" style="width:45%" data-width="45%"></div></div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="lt-progress-label"><span>DISK I/O</span><span>89%</span></div>
|
||||||
|
<div class="lt-progress lt-progress--red lt-progress--lg"><div class="lt-progress-bar" style="width:89%" data-width="89%"></div></div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="lt-progress-label"><span>UPTIME</span><span>100%</span></div>
|
||||||
|
<div class="lt-progress lt-progress--green lt-progress--striped"><div class="lt-progress-bar" style="width:100%" data-width="100%"></div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- BREADCRUMBS & PAGINATION -->
|
||||||
|
<div class="lt-section-header">Breadcrumbs / Pagination</div>
|
||||||
|
<div class="lt-section-body" style="display:flex;flex-direction:column;gap:var(--space-md)">
|
||||||
|
<nav class="lt-breadcrumb" aria-label="breadcrumb">
|
||||||
|
<div class="lt-breadcrumb-item"><a href="#">ROOT</a></div>
|
||||||
|
<div class="lt-breadcrumb-sep"></div>
|
||||||
|
<div class="lt-breadcrumb-item"><a href="#">SYSTEMS</a></div>
|
||||||
|
<div class="lt-breadcrumb-sep"></div>
|
||||||
|
<div class="lt-breadcrumb-item"><a href="#">NETWORK</a></div>
|
||||||
|
<div class="lt-breadcrumb-sep"></div>
|
||||||
|
<div class="lt-breadcrumb-item active">NODE-07</div>
|
||||||
|
</nav>
|
||||||
|
<nav class="lt-pagination" aria-label="pagination">
|
||||||
|
<button class="lt-page-btn" disabled>«</button>
|
||||||
|
<button class="lt-page-btn" disabled>1</button>
|
||||||
|
<button class="lt-page-btn active">2</button>
|
||||||
|
<button class="lt-page-btn">3</button>
|
||||||
|
<button class="lt-page-btn">4</button>
|
||||||
|
<button class="lt-page-btn">5</button>
|
||||||
|
<button class="lt-page-btn">»</button>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ACCORDION -->
|
||||||
|
<div class="lt-section-header">Accordion</div>
|
||||||
|
<div class="lt-section-body">
|
||||||
|
<div>
|
||||||
|
<div class="lt-accordion">
|
||||||
|
<button class="lt-accordion-header" aria-expanded="false" data-accordion>
|
||||||
|
SYSTEM OVERVIEW
|
||||||
|
<svg class="lt-accordion-icon" viewBox="0 0 10 6" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M1 1l4 4 4-4"/></svg>
|
||||||
|
</button>
|
||||||
|
<div class="lt-accordion-body"><div class="lt-accordion-content">Node running at 72% CPU. 12 active processes. Last restart: 3d ago.</div></div>
|
||||||
|
</div>
|
||||||
|
<div class="lt-accordion">
|
||||||
|
<button class="lt-accordion-header" aria-expanded="false" data-accordion>
|
||||||
|
NETWORK CONFIG
|
||||||
|
<svg class="lt-accordion-icon" viewBox="0 0 10 6" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M1 1l4 4 4-4"/></svg>
|
||||||
|
</button>
|
||||||
|
<div class="lt-accordion-body"><div class="lt-accordion-content">eth0: 10.0.0.7 — MTU 1500 — RX 4.2 GB — TX 1.1 GB</div></div>
|
||||||
|
</div>
|
||||||
|
<div class="lt-accordion">
|
||||||
|
<button class="lt-accordion-header" aria-expanded="false" data-accordion>
|
||||||
|
FIREWALL RULES
|
||||||
|
<svg class="lt-accordion-icon" viewBox="0 0 10 6" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M1 1l4 4 4-4"/></svg>
|
||||||
|
</button>
|
||||||
|
<div class="lt-accordion-body"><div class="lt-accordion-content">22/tcp ALLOW — 80/tcp ALLOW — 443/tcp ALLOW — */* DENY</div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ALERTS -->
|
||||||
|
<div class="lt-section-header">Alert Banners</div>
|
||||||
|
<div class="lt-section-body" style="display:flex;flex-direction:column;gap:var(--space-sm)">
|
||||||
|
<div class="lt-alert">
|
||||||
|
<span class="lt-alert-icon">ℹ</span>
|
||||||
|
<div class="lt-alert-body"><div class="lt-alert-title">Information</div><div class="lt-alert-msg">Scheduled maintenance window: Sunday 02:00–04:00 UTC.</div></div>
|
||||||
|
<button class="lt-alert-close" data-alert-close aria-label="Dismiss">✕</button>
|
||||||
|
</div>
|
||||||
|
<div class="lt-alert lt-alert--warning">
|
||||||
|
<span class="lt-alert-icon">⚠</span>
|
||||||
|
<div class="lt-alert-body"><div class="lt-alert-title">Warning</div><div class="lt-alert-msg">Disk usage on NODE-03 at 87%. Consider cleanup.</div></div>
|
||||||
|
<button class="lt-alert-close" data-alert-close aria-label="Dismiss">✕</button>
|
||||||
|
</div>
|
||||||
|
<div class="lt-alert lt-alert--error">
|
||||||
|
<span class="lt-alert-icon">✕</span>
|
||||||
|
<div class="lt-alert-body"><div class="lt-alert-title">Critical</div><div class="lt-alert-msg">NODE-11 unreachable. Last seen 14m ago.</div></div>
|
||||||
|
<button class="lt-alert-close" data-alert-close aria-label="Dismiss">✕</button>
|
||||||
|
</div>
|
||||||
|
<div class="lt-alert lt-alert--success">
|
||||||
|
<span class="lt-alert-icon">✓</span>
|
||||||
|
<div class="lt-alert-body"><div class="lt-alert-title">Success</div><div class="lt-alert-msg">Deployment v2.4.1 completed successfully.</div></div>
|
||||||
|
<button class="lt-alert-close" data-alert-close aria-label="Dismiss">✕</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- TOGGLES, RANGE, TAGS -->
|
||||||
|
<div class="lt-section-header">Toggles / Range / Tags</div>
|
||||||
|
<div class="lt-section-body" style="display:flex;flex-direction:column;gap:var(--space-lg)">
|
||||||
|
<div style="display:flex;gap:var(--space-lg);flex-wrap:wrap">
|
||||||
|
<label class="lt-toggle">
|
||||||
|
<input type="checkbox" checked>
|
||||||
|
<div class="lt-toggle-track"><div class="lt-toggle-thumb"></div></div>
|
||||||
|
<span class="lt-toggle-label">Auto-refresh</span>
|
||||||
|
</label>
|
||||||
|
<label class="lt-toggle">
|
||||||
|
<input type="checkbox">
|
||||||
|
<div class="lt-toggle-track"><div class="lt-toggle-thumb"></div></div>
|
||||||
|
<span class="lt-toggle-label">Dark alerts</span>
|
||||||
|
</label>
|
||||||
|
<label class="lt-toggle">
|
||||||
|
<input type="checkbox" checked>
|
||||||
|
<div class="lt-toggle-track"><div class="lt-toggle-thumb"></div></div>
|
||||||
|
<span class="lt-toggle-label">Notifications</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="lt-range-wrap" style="max-width:320px">
|
||||||
|
<div class="lt-range-header">
|
||||||
|
<span class="lt-range-label">Refresh Interval (s)</span>
|
||||||
|
<span class="lt-range-value">30</span>
|
||||||
|
</div>
|
||||||
|
<input type="range" class="lt-range" min="5" max="60" value="30">
|
||||||
|
</div>
|
||||||
|
<div class="lt-tags">
|
||||||
|
<span class="lt-tag lt-tag--orange">CRITICAL</span>
|
||||||
|
<span class="lt-tag lt-tag--cyan">NETWORK</span>
|
||||||
|
<span class="lt-tag lt-tag--green">ONLINE</span>
|
||||||
|
<span class="lt-tag lt-tag--red">OFFLINE</span>
|
||||||
|
<span class="lt-tag lt-tag--purple">ADMIN</span>
|
||||||
|
<span class="lt-tag">UNTAGGED</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- CODE BLOCK -->
|
||||||
|
<div class="lt-section-header">Code Block</div>
|
||||||
|
<div class="lt-section-body">
|
||||||
|
<div class="lt-code-block">
|
||||||
|
<div class="lt-code-header">
|
||||||
|
<span class="lt-code-lang">bash</span>
|
||||||
|
<button class="lt-code-copy" data-copy="systemctl restart nginx && systemctl status nginx">COPY</button>
|
||||||
|
</div>
|
||||||
|
<pre><code><span class="tok-cmt"># Restart and verify nginx</span>
|
||||||
|
<span class="tok-kw">systemctl</span> restart nginx <span class="tok-kw">&&</span> <span class="tok-kw">systemctl</span> status nginx
|
||||||
|
<span class="tok-cmt"># Check active connections</span>
|
||||||
|
<span class="tok-kw">ss</span> -tlnp | <span class="tok-kw">grep</span> <span class="tok-str">':80\|:443'</span></code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- KEY-VALUE + STEPPER -->
|
||||||
|
<div class="lt-section-header">Data Grid / Stepper</div>
|
||||||
|
<div class="lt-section-body" style="display:grid;grid-template-columns:1fr 1fr;gap:var(--space-lg)">
|
||||||
|
<div>
|
||||||
|
<div class="lt-kv-grid">
|
||||||
|
<div class="lt-kv-key">Hostname</div> <div class="lt-kv-val lt-kv-val--cyan">node-07.prod</div>
|
||||||
|
<div class="lt-kv-key">IP Address</div> <div class="lt-kv-val">10.0.0.7</div>
|
||||||
|
<div class="lt-kv-key">Status</div> <div class="lt-kv-val lt-kv-val--green">ONLINE</div>
|
||||||
|
<div class="lt-kv-key">Uptime</div> <div class="lt-kv-val">3d 14h 22m</div>
|
||||||
|
<div class="lt-kv-key">Load Avg</div> <div class="lt-kv-val lt-kv-val--orange">2.14 / 1.87 / 1.60</div>
|
||||||
|
<div class="lt-kv-key">Region</div> <div class="lt-kv-val">US-EAST-1</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="lt-stepper">
|
||||||
|
<div class="lt-step complete">
|
||||||
|
<div class="lt-step-num">✓</div>
|
||||||
|
<div class="lt-step-label">INIT</div>
|
||||||
|
</div>
|
||||||
|
<div class="lt-step complete">
|
||||||
|
<div class="lt-step-num">✓</div>
|
||||||
|
<div class="lt-step-label">BUILD</div>
|
||||||
|
</div>
|
||||||
|
<div class="lt-step active">
|
||||||
|
<div class="lt-step-num">3</div>
|
||||||
|
<div class="lt-step-label">DEPLOY</div>
|
||||||
|
</div>
|
||||||
|
<div class="lt-step">
|
||||||
|
<div class="lt-step-num">4</div>
|
||||||
|
<div class="lt-step-label">VERIFY</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- LIST GROUP + BADGES -->
|
||||||
|
<div class="lt-section-header">List Group / Badges</div>
|
||||||
|
<div class="lt-section-body" style="display:grid;grid-template-columns:1fr 1fr;gap:var(--space-lg)">
|
||||||
|
<div class="lt-list-group">
|
||||||
|
<div class="lt-list-item lt-list-item--active">
|
||||||
|
<span class="lt-dot lt-dot--green"></span>
|
||||||
|
<a href="#">node-01.prod</a>
|
||||||
|
<span class="lt-list-item-meta lt-kv-val--green">ONLINE</span>
|
||||||
|
</div>
|
||||||
|
<div class="lt-list-item">
|
||||||
|
<span class="lt-dot lt-dot--green"></span>
|
||||||
|
<a href="#">node-02.prod</a>
|
||||||
|
<span class="lt-list-item-meta lt-kv-val--green">ONLINE</span>
|
||||||
|
</div>
|
||||||
|
<div class="lt-list-item">
|
||||||
|
<span class="lt-dot lt-dot--orange"></span>
|
||||||
|
<a href="#">node-03.prod</a>
|
||||||
|
<span class="lt-list-item-meta lt-kv-val--orange">DEGRADED</span>
|
||||||
|
</div>
|
||||||
|
<div class="lt-list-item">
|
||||||
|
<span class="lt-dot lt-dot--red"></span>
|
||||||
|
<a href="#">node-11.prod</a>
|
||||||
|
<span class="lt-list-item-meta lt-kv-val--red">OFFLINE</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="display:flex;flex-direction:column;gap:var(--space-md)">
|
||||||
|
<div style="display:flex;gap:var(--space-md);align-items:center;flex-wrap:wrap">
|
||||||
|
<div class="lt-badge-wrap">
|
||||||
|
<button class="lt-btn lt-btn-sm">Alerts</button>
|
||||||
|
<span class="lt-badge">3</span>
|
||||||
|
</div>
|
||||||
|
<div class="lt-badge-wrap">
|
||||||
|
<button class="lt-btn lt-btn-sm">Messages</button>
|
||||||
|
<span class="lt-badge lt-badge--orange">12</span>
|
||||||
|
</div>
|
||||||
|
<div class="lt-badge-wrap">
|
||||||
|
<button class="lt-btn lt-btn-sm">Updates</button>
|
||||||
|
<span class="lt-badge lt-badge--cyan">5</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="display:flex;gap:var(--space-sm);align-items:center;flex-wrap:wrap">
|
||||||
|
<div class="lt-bar-loader"><span></span><span></span><span></span><span></span></div>
|
||||||
|
<div class="lt-spinner"></div>
|
||||||
|
<div class="lt-spinner lt-spinner--cyan lt-spinner--sm"></div>
|
||||||
|
<div class="lt-pulse-dot"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- TAB BAR -->
|
||||||
|
<div class="lt-section-header">Tab Bar</div>
|
||||||
|
<div class="lt-section-body">
|
||||||
|
<div class="lt-tab-bar" role="tablist">
|
||||||
|
<button class="lt-tab active" role="tab" data-tab-target="tab-overview" aria-selected="true">Overview</button>
|
||||||
|
<button class="lt-tab" role="tab" data-tab-target="tab-logs" aria-selected="false">Logs</button>
|
||||||
|
<button class="lt-tab" role="tab" data-tab-target="tab-metrics" aria-selected="false">Metrics</button>
|
||||||
|
<button class="lt-tab" role="tab" data-tab-target="tab-config" aria-selected="false">Config</button>
|
||||||
|
</div>
|
||||||
|
<div class="lt-tab-panels" style="padding:var(--space-md) 0">
|
||||||
|
<div id="tab-overview" class="lt-tab-panel active">System overview: all nodes nominal. 14 active sessions.</div>
|
||||||
|
<div id="tab-logs" class="lt-tab-panel">
|
||||||
|
<pre style="font-family:var(--font-mono);font-size:0.75rem;color:var(--text-secondary);margin:0">[03:41:22] nginx: 200 GET /api/nodes (12ms)
|
||||||
|
[03:41:23] cron: heartbeat OK
|
||||||
|
[03:41:24] alert: disk 87% on node-03</pre>
|
||||||
|
</div>
|
||||||
|
<div id="tab-metrics" class="lt-tab-panel">CPU avg: 34% — Mem avg: 61% — Net TX: 4.2 Mbps</div>
|
||||||
|
<div id="tab-config" class="lt-tab-panel">Config last updated: 2026-03-20 by admin@lotusguild.io</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- TOOLTIP & DIVIDER DEMO -->
|
||||||
|
<div class="lt-section-header">Tooltips / Divider</div>
|
||||||
|
<div class="lt-section-body" style="display:flex;flex-direction:column;gap:var(--space-md)">
|
||||||
|
<div style="display:flex;gap:var(--space-lg);flex-wrap:wrap;padding-top:var(--space-md)">
|
||||||
|
<span data-tooltip="Primary accent — use for actions" class="lt-tag lt-tag--orange">ORANGE</span>
|
||||||
|
<span data-tooltip="Info / border color" data-tooltip-pos="bottom" class="lt-tag lt-tag--cyan">CYAN (bottom)</span>
|
||||||
|
<span data-tooltip="Success states" class="lt-tag lt-tag--green">GREEN</span>
|
||||||
|
<span data-tooltip="Critical / error" class="lt-tag lt-tag--red">RED</span>
|
||||||
|
</div>
|
||||||
|
<div class="lt-divider"><span class="lt-divider-label">SECTION BREAK</span></div>
|
||||||
|
<div class="lt-divider lt-divider--orange"><span class="lt-divider-label">CRITICAL ZONE</span></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- DROPZONE -->
|
||||||
|
<div class="lt-section-header">File Dropzone</div>
|
||||||
|
<div class="lt-section-body">
|
||||||
|
<div class="lt-dropzone" data-dropzone data-accept=".json,.csv,.log" data-max-size="10485760">
|
||||||
|
<input type="file" accept=".json,.csv,.log" multiple>
|
||||||
|
<div class="lt-dropzone-icon">⤓</div>
|
||||||
|
<div class="lt-dropzone-text">Drop files here or <strong>click to browse</strong></div>
|
||||||
|
<div class="lt-dropzone-hint">Accepts .json, .csv, .log — max 10 MB each</div>
|
||||||
|
</div>
|
||||||
|
<div class="lt-file-list" id="demo-file-list"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- COMMAND PALETTE TRIGGER -->
|
||||||
|
<div class="lt-section-header">Command Palette</div>
|
||||||
|
<div class="lt-section-body">
|
||||||
|
<p style="font-family:var(--font-mono);font-size:0.8rem;color:var(--text-secondary);margin:0 0 var(--space-sm)">
|
||||||
|
Press <kbd style="background:var(--bg-tertiary);border:1px solid var(--border-dim);padding:2px 6px;font-family:var(--font-mono)">Ctrl+K</kbd> or click the button below to open the command palette.
|
||||||
|
</p>
|
||||||
|
<button class="lt-btn lt-btn-ghost" onclick="lt.cmdPalette.open()">⌘ Open Command Palette</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div><!-- /.lt-frame-inner (v1.2 additions) -->
|
||||||
|
</div><!-- /.lt-frame (v1.2 additions) -->
|
||||||
|
|
||||||
</main><!-- /.lt-main -->
|
</main><!-- /.lt-main -->
|
||||||
|
|
||||||
|
|
||||||
@@ -675,6 +1010,26 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- ===========================================================
|
||||||
|
COMMAND PALETTE OVERLAY
|
||||||
|
=========================================================== -->
|
||||||
|
<div id="lt-cmd-overlay" class="lt-cmd-overlay" role="dialog" aria-modal="true" aria-label="Command palette">
|
||||||
|
<div class="lt-cmd-palette" id="lt-cmd-palette">
|
||||||
|
<div class="lt-cmd-input-wrap">
|
||||||
|
<span class="lt-cmd-prompt">></span>
|
||||||
|
<input id="lt-cmd-input" class="lt-cmd-input" type="text" placeholder="Search commands…" autocomplete="off" spellcheck="false">
|
||||||
|
</div>
|
||||||
|
<div class="lt-cmd-results" id="lt-cmd-results">
|
||||||
|
<div class="lt-cmd-empty">Start typing to search…</div>
|
||||||
|
</div>
|
||||||
|
<div class="lt-cmd-footer">
|
||||||
|
<span><kbd>↑</kbd><kbd>↓</kbd> Navigate</span>
|
||||||
|
<span><kbd>Enter</kbd> Select</span>
|
||||||
|
<span><kbd>Esc</kbd> Close</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- ===========================================================
|
<!-- ===========================================================
|
||||||
SCRIPTS
|
SCRIPTS
|
||||||
=========================================================== -->
|
=========================================================== -->
|
||||||
@@ -697,20 +1052,85 @@
|
|||||||
</script>
|
</script>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- Base design system JS -->
|
<!-- LotusGuild Terminal Design System JS v1.2 -->
|
||||||
<script src="/web_template/base.js"></script>
|
<script src="/web_template/base.js"></script>
|
||||||
|
|
||||||
<!--
|
<!-- Init v1.2 modules -->
|
||||||
App-specific JS:
|
<script>
|
||||||
<script nonce="NONCE" src="/assets/js/app.js?v=20260314"></script>
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
// Accordion
|
||||||
|
lt.accordion.init();
|
||||||
|
|
||||||
Wire up sortable table after load:
|
// Tooltips (JS-positioned — optional, CSS tooltips work without this)
|
||||||
<script nonce="NONCE">
|
lt.tooltip.init();
|
||||||
lt.sortTable.init('ticket-table');
|
|
||||||
lt.tableNav.init('ticket-table');
|
// Clipboard copy buttons ([data-copy])
|
||||||
lt.keys.on('n', () => window.location.href = '/create');
|
lt.clipboard.init();
|
||||||
|
|
||||||
|
// Alert dismiss buttons
|
||||||
|
lt.alerts.init();
|
||||||
|
|
||||||
|
// Command palette demo commands
|
||||||
|
lt.cmdPalette.init([
|
||||||
|
{
|
||||||
|
group: 'Navigation',
|
||||||
|
items: [
|
||||||
|
{ icon: '⌂', label: 'Dashboard', kbd: 'G D', action: () => lt.toast.info('→ Dashboard') },
|
||||||
|
{ icon: '⊞', label: 'All Tickets', kbd: 'G T', action: () => lt.toast.info('→ Tickets') },
|
||||||
|
{ icon: '★', label: 'Saved Filters', action: () => lt.toast.info('→ Filters') },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: 'Actions',
|
||||||
|
items: [
|
||||||
|
{ icon: '+', label: 'New Ticket', kbd: 'N', action: () => lt.toast.success('New ticket form') },
|
||||||
|
{ icon: '⤓', label: 'Export CSV', action: () => lt.modal.open('export-modal') },
|
||||||
|
{ icon: '⟳', label: 'Refresh Data', kbd: 'R', action: () => lt.toast.info('Refreshing...') },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: 'Help',
|
||||||
|
items: [
|
||||||
|
{ icon: '?', label: 'Keyboard Shortcuts', kbd: '?', action: () => lt.modal.open('lt-keys-help') },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Range slider live value display
|
||||||
|
document.querySelectorAll('input[type="range"].lt-range').forEach(r => {
|
||||||
|
const wrap = r.closest('.lt-range-wrap');
|
||||||
|
const label = wrap && wrap.querySelector('.lt-range-value');
|
||||||
|
if (label) {
|
||||||
|
label.textContent = r.value;
|
||||||
|
r.addEventListener('input', () => { label.textContent = r.value; });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Animate the demo progress bars on load
|
||||||
|
document.querySelectorAll('.lt-progress-bar[data-width]').forEach(bar => {
|
||||||
|
requestAnimationFrame(() => { bar.style.width = bar.dataset.width; });
|
||||||
|
});
|
||||||
|
|
||||||
|
// Tab bar switching
|
||||||
|
document.querySelectorAll('.lt-tab-bar').forEach(bar => {
|
||||||
|
bar.addEventListener('click', e => {
|
||||||
|
const tab = e.target.closest('.lt-tab');
|
||||||
|
if (!tab) return;
|
||||||
|
const targetId = tab.dataset.tabTarget;
|
||||||
|
if (!targetId) return;
|
||||||
|
const panels = bar.nextElementSibling;
|
||||||
|
bar.querySelectorAll('.lt-tab').forEach(t => { t.classList.remove('active'); t.setAttribute('aria-selected', 'false'); });
|
||||||
|
tab.classList.add('active');
|
||||||
|
tab.setAttribute('aria-selected', 'true');
|
||||||
|
if (panels) {
|
||||||
|
panels.querySelectorAll('.lt-tab-panel').forEach(p => p.classList.remove('active'));
|
||||||
|
const target = panels.querySelector('#' + targetId);
|
||||||
|
if (target) target.classList.add('active');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
-->
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user