feat: implement RECOMMENDED_ADDITIONS — cursor, scanlines, radar, display-field, VT323
- --font-crt: 'VT323' token added to :root; VT323 added to Google Fonts link - .lt-cursor / .lt-cursor--cyan/orange/red — blinking block cursor via CSS ::after - .lt-scanlines — opt-in CRT horizontal scanline overlay on body/container (light-mode suppressed) - .lt-radar / --sm / --lg / --green — radar sweep loading indicator as lt-spinner alternative - .lt-display-field — readable non-editable field variant (distinct from :disabled opacity:0.45) - base.html demos: radar variants in loading row, display-field in forms, cursor+VT323 in tags section Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -146,6 +146,7 @@
|
||||
/* --- Typography --- */
|
||||
--font-mono: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'Courier New', monospace;
|
||||
--font-display: 'JetBrains Mono', 'Fira Code', 'Courier New', monospace;
|
||||
--font-crt: 'VT323', 'Courier New', monospace;
|
||||
|
||||
/* --- Spacing --- */
|
||||
--space-xs: 0.25rem;
|
||||
@@ -907,6 +908,19 @@ hr {
|
||||
border-color: var(--border-dim);
|
||||
}
|
||||
|
||||
/* Display-only fields — readable, non-editable, not "broken" */
|
||||
.lt-display-field,
|
||||
.lt-input.lt-display-field,
|
||||
.lt-select.lt-display-field,
|
||||
.lt-textarea.lt-display-field {
|
||||
opacity: 1;
|
||||
color: var(--text-secondary);
|
||||
cursor: default;
|
||||
pointer-events: none;
|
||||
background: transparent;
|
||||
border-color: var(--border-dim);
|
||||
}
|
||||
|
||||
.lt-input::placeholder,
|
||||
.lt-textarea::placeholder { color: var(--text-dim); }
|
||||
|
||||
@@ -5488,3 +5502,86 @@ body.lt-is-offline .lt-main { margin-top: 2rem; transition: margin-top 0.25s eas
|
||||
@media (max-width: 479px) {
|
||||
.lt-footer { flex-direction: column; align-items: flex-start; gap: 0.25rem; }
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
BLINKING CURSOR
|
||||
<h1 class="lt-cursor">SYSTEM STATUS</h1>
|
||||
<span class="lt-cursor lt-cursor--cyan">SCANNING</span>
|
||||
================================================================ */
|
||||
.lt-cursor::after {
|
||||
content: '▊';
|
||||
animation: lt-blink 1s step-end infinite;
|
||||
color: var(--accent-green);
|
||||
margin-left: 2px;
|
||||
}
|
||||
.lt-cursor--cyan::after { color: var(--accent-cyan); }
|
||||
.lt-cursor--orange::after { color: var(--accent-orange); }
|
||||
.lt-cursor--red::after { color: var(--accent-red); }
|
||||
@keyframes lt-blink {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0; }
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
CRT SCANLINE OVERLAY
|
||||
Add lt-scanlines to <body> or any container to enable.
|
||||
Automatically suppressed in light theme.
|
||||
================================================================ */
|
||||
.lt-scanlines::after {
|
||||
content: '';
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: repeating-linear-gradient(
|
||||
0deg,
|
||||
transparent,
|
||||
transparent 2px,
|
||||
rgba(0, 0, 0, 0.04) 2px,
|
||||
rgba(0, 0, 0, 0.04) 4px
|
||||
);
|
||||
pointer-events: none;
|
||||
z-index: 9998;
|
||||
}
|
||||
html[data-theme="light"] .lt-scanlines::after { display: none; }
|
||||
|
||||
/* ================================================================
|
||||
RADAR SWEEP LOADING INDICATOR
|
||||
<div class="lt-radar"></div>
|
||||
Drop-in replacement for lt-spinner where a radar aesthetic fits.
|
||||
================================================================ */
|
||||
.lt-radar {
|
||||
display: inline-block;
|
||||
width: 48px; height: 48px;
|
||||
border-radius: 50%;
|
||||
border: 1px solid var(--accent-cyan);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.lt-radar::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: conic-gradient(
|
||||
from 0deg,
|
||||
transparent 70%,
|
||||
rgba(0, 212, 255, 0.35) 100%
|
||||
);
|
||||
animation: lt-radar-sweep 2s linear infinite;
|
||||
transform-origin: center;
|
||||
}
|
||||
.lt-radar::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 50% 0 0 50%;
|
||||
width: 1px; height: 50%;
|
||||
background: var(--accent-cyan);
|
||||
transform-origin: top left;
|
||||
animation: lt-radar-sweep 2s linear infinite;
|
||||
opacity: 0.6;
|
||||
}
|
||||
.lt-radar--sm { width: 28px; height: 28px; }
|
||||
.lt-radar--lg { width: 72px; height: 72px; }
|
||||
.lt-radar--green { border-color: var(--accent-green); }
|
||||
.lt-radar--green::before { background: conic-gradient(from 0deg, transparent 70%, rgba(0,255,136,0.35) 100%); }
|
||||
.lt-radar--green::after { background: var(--accent-green); }
|
||||
@keyframes lt-radar-sweep { to { transform: rotate(360deg); } }
|
||||
|
||||
@@ -29,10 +29,10 @@
|
||||
All <script> tags need: nonce="NONCE_PLACEHOLDER"
|
||||
========================================================= -->
|
||||
|
||||
<!-- Monospace font: JetBrains Mono -->
|
||||
<!-- Fonts: JetBrains Mono (UI) + VT323 (CRT display accent) -->
|
||||
<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">
|
||||
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,400;0,600;0,700;1,400&family=VT323&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- Hacker template design system CSS -->
|
||||
<link rel="stylesheet" href="/web_template/base.css">
|
||||
@@ -794,6 +794,7 @@
|
||||
<label class="lt-label">Loading state (skeleton)</label>
|
||||
<div class="lt-skeleton lt-p-md" style="height:40px"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="lt-form-group">
|
||||
<label class="lt-label">Empty state</label>
|
||||
<div class="lt-empty" style="padding:1rem">No results found</div>
|
||||
@@ -802,6 +803,13 @@
|
||||
<label class="lt-label">Loading indicator</label>
|
||||
<div class="lt-loading" style="padding:1rem"></div>
|
||||
</div>
|
||||
<div class="lt-form-group">
|
||||
<label class="lt-label">Display-only fields <code style="font-size:0.7rem">.lt-display-field</code></label>
|
||||
<select class="lt-select lt-display-field" style="margin-bottom:0.5rem">
|
||||
<option>P3 — Medium</option>
|
||||
</select>
|
||||
<input type="text" class="lt-input lt-display-field" value="Read-only value">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -959,6 +967,13 @@
|
||||
<span class="lt-tag lt-tag--purple">ADMIN</span>
|
||||
<span class="lt-tag">UNTAGGED</span>
|
||||
</div>
|
||||
<div style="margin-top:var(--space-md);display:flex;flex-wrap:wrap;gap:var(--space-md);align-items:center">
|
||||
<span class="lt-cursor" style="font-size:1.1rem;font-family:var(--font-mono)">SYSTEM STATUS</span>
|
||||
<span class="lt-cursor lt-cursor--cyan" style="font-size:1.1rem;font-family:var(--font-mono)">SCANNING</span>
|
||||
<span class="lt-cursor lt-cursor--orange" style="font-size:1.1rem;font-family:var(--font-mono)">AWAITING INPUT</span>
|
||||
<span style="font-family:var(--font-crt);font-size:2rem;color:var(--accent-green)">42 NODES</span>
|
||||
<span class="lt-tag lt-tag--red" style="font-family:var(--font-crt);font-size:1rem;letter-spacing:0.05em">CRITICAL</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CODE BLOCK -->
|
||||
@@ -1055,6 +1070,9 @@
|
||||
<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-radar lt-radar--sm"></div>
|
||||
<div class="lt-radar"></div>
|
||||
<div class="lt-radar lt-radar--green"></div>
|
||||
<div class="lt-pulse-dot"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user