Landing: rig name decode/scramble in top HUD; CLAUDE.md docs sync
Landing's top-left identifier upgraded from "OPHI-118" to "OPHI-118 // [<RIG>]" where the rig portion (read from window.__TEL.rig in landing/telemetry.js) does a cyberpunk decoder reveal on first paint and re-glitches briefly every ~9 s. Bracket dimming + amber flash during scramble keep the layout width-stable. CLAUDE.md updated to reflect everything since the last sync: new Landing rig display, Music Box terminal pattern + dedicated chat status strip, widget at 549×880 (camera-paired), Desktop HUD fork, bridge nextTitles[] payload, bot !queue/!info/per-user cooldown + Mattermost going-live notifier (MM_HOOK / STATUS_URL). Plus an OBS-detection note: Flatpak's inner binary is `obs`, not `flatpak run …` — `flatpak ps` or `pgrep -x obs` are the only reliable checks. The naive `pgrep -fa 'flatpak run …'` returns "off" while OBS is up and led to JSON edits during a live session.
This commit is contained in:
@@ -51,6 +51,38 @@ body {
|
||||
.hud > .group:nth-child(3) { justify-self: end; }
|
||||
.hud .dim { color: var(--hud-dim); }
|
||||
.hud .group > span { display: inline-flex; align-items: center; gap: 12px; }
|
||||
|
||||
/* "OPHI-118 // <RIG>" station identifier. The rig portion gets a subtle
|
||||
monochrome glitch — character scramble that resolves back to the real
|
||||
name every ~9s. CSS-only flicker; the scramble itself is in JS. */
|
||||
.station {
|
||||
display: inline-flex;
|
||||
align-items: baseline;
|
||||
gap: 0;
|
||||
white-space: pre; /* preserve the " // " spacing as-is */
|
||||
}
|
||||
.station .sep { color: var(--hud-dim); margin: 0 0.45em; letter-spacing: 0.32em; }
|
||||
.station .rig {
|
||||
display: inline-block;
|
||||
color: var(--hud);
|
||||
text-shadow: 0 0 10px rgba(79, 210, 255, 0.55);
|
||||
font-variant-numeric: tabular-nums;
|
||||
/* Subtle width-stable bracket dimming. The brackets sit just outside the
|
||||
name so the scramble glyphs (which can be wider than 1ch in mono) don't
|
||||
visually push the layout around. */
|
||||
}
|
||||
.station .rig::before,
|
||||
.station .rig::after {
|
||||
color: var(--hud-dim);
|
||||
font-weight: 700;
|
||||
text-shadow: none;
|
||||
}
|
||||
.station .rig::before { content: '['; margin-right: 0.32em; }
|
||||
.station .rig::after { content: ']'; margin-left: 0.32em; }
|
||||
.station .rig.glitching {
|
||||
color: var(--warn);
|
||||
text-shadow: 0 0 12px rgba(255, 208, 0, 0.5);
|
||||
}
|
||||
.hud .led {
|
||||
display: inline-block;
|
||||
width: 11px; height: 11px;
|
||||
@@ -197,7 +229,11 @@ body {
|
||||
<header class="hud">
|
||||
<div class="group">
|
||||
<span><span class="led"></span>TRANSMISSION</span>
|
||||
<span>OPHI-118</span>
|
||||
<span class="station">
|
||||
<span class="station-id">OPHI-118</span>
|
||||
<span class="sep">//</span>
|
||||
<span class="rig" id="rigName">--</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="group">
|
||||
<span class="dim">SIGNAL</span>
|
||||
@@ -287,6 +323,56 @@ body {
|
||||
// 8 fps — visually almost identical to 12 fps but ~33% less paint work.
|
||||
setInterval(drawNoise, 1000 / 8);
|
||||
|
||||
// ───────── Rig name in the top HUD with periodic glitch-decode ─────────
|
||||
// Reads telemetry.js's window.__TEL.rig (set by telemetry.sh per-rig).
|
||||
// Behaviour: settles on the real name, then every ~9s briefly scrambles
|
||||
// each letter through random glyphs and resolves back left-to-right. Same
|
||||
// effect family as the cyberpunk "decoder" trope; pairs with the CRT
|
||||
// aesthetic rather than fighting it.
|
||||
const rigNameEl = document.getElementById('rigName');
|
||||
const RIG_NAME = (window.__TEL && window.__TEL.rig) || 'UNKNOWN';
|
||||
// ASCII-only glyph pool — tabular_nums keeps width stable in DejaVu Mono.
|
||||
const GLITCH_GLYPHS = '01ABCDEFGHIJKLMNOPQRSTUVWXYZ#@*?!§%';
|
||||
const glyph = () => GLITCH_GLYPHS[(Math.random() * GLITCH_GLYPHS.length) | 0];
|
||||
const upperRig = RIG_NAME.toUpperCase();
|
||||
|
||||
// Initial reveal: scramble for ~400ms, then resolve l→r.
|
||||
// Subsequent: small idle scramble ~every 9s.
|
||||
function scrambleOnce({ initial = false } = {}) {
|
||||
const len = upperRig.length;
|
||||
if (len === 0) { rigNameEl.textContent = '--'; return; }
|
||||
rigNameEl.classList.add('glitching');
|
||||
const totalScrambleMs = initial ? 600 : 360;
|
||||
const stepMs = 50;
|
||||
const scrambleSteps = Math.max(1, Math.floor(totalScrambleMs / stepMs));
|
||||
let step = 0;
|
||||
|
||||
const scrambleTimer = setInterval(() => {
|
||||
let s = '';
|
||||
for (let i = 0; i < len; i++) s += glyph();
|
||||
rigNameEl.textContent = s;
|
||||
if (++step >= scrambleSteps) {
|
||||
clearInterval(scrambleTimer);
|
||||
// Resolve left-to-right
|
||||
let resolved = 0;
|
||||
const resolveTimer = setInterval(() => {
|
||||
resolved++;
|
||||
let s = upperRig.slice(0, resolved);
|
||||
for (let i = resolved; i < len; i++) s += glyph();
|
||||
rigNameEl.textContent = s;
|
||||
if (resolved >= len) {
|
||||
clearInterval(resolveTimer);
|
||||
rigNameEl.textContent = upperRig;
|
||||
rigNameEl.classList.remove('glitching');
|
||||
}
|
||||
}, 60);
|
||||
}
|
||||
}, stepMs);
|
||||
}
|
||||
// First reveal happens shortly after page load; then idle re-glitch.
|
||||
setTimeout(() => scrambleOnce({ initial: true }), 600);
|
||||
setInterval(scrambleOnce, 9000);
|
||||
|
||||
// ───────── Telemetry: rotating real-data subtitle ─────────
|
||||
// All lines derive from telemetry.js (window.__TEL), generated by telemetry.sh.
|
||||
const rigEl = document.getElementById('rig');
|
||||
|
||||
Reference in New Issue
Block a user