FEATURE SHOWCASE

reusable effects and components already scattered across the site (plus a couple of new ones), demoed live with copy-pasteable code. grab whatever's useful for the next thing being built instead of re-deriving it from scratch.

typewriter text

used in hold6.html's typeAgent() and Agent Ø's replies. types out one character at a time.
function typeText(el, text, speed, onDone) {
  let i = 0;
  el.textContent = '';
  (function step() {
    if (i < text.length) {
      el.textContent += text.charAt(i++);
      setTimeout(step, speed);
    } else if (onDone) onDone();
  })();
}

text scramble

new — not used anywhere yet. characters randomize then settle into place left-to-right, classic "decrypting" reveal. could fit dont_trust.html or a future puzzle page.
function scrambleText(el, finalText, duration) {
  const chars = '!<>-_/[]{}=+*^?#';
  let frame = 0;
  const totalFrames = Math.round(duration / 30);
  const settleAt = finalText.split('').map((_, i) =>
    Math.floor((i / finalText.length) * totalFrames));
  const iv = setInterval(() => {
    let out = '';
    for (let i = 0; i < finalText.length; i++) {
      out += frame >= settleAt[i] ? finalText[i]
        : chars[Math.floor(Math.random() * chars.length)];
    }
    el.textContent = out;
    if (frame++ > totalFrames) clearInterval(iv);
  }, 30);
}

screen glitch

used in hold6.html (body.glitch) and this lab's hold6-stages tool. a quick shake, paired with a flash-overlay in the real version.
SYSTEM NOMINAL
.glitch { animation: shake 0.2s cubic-bezier(.36,.07,.19,.97) both; }
@keyframes shake {
  10%, 90% { transform: translate3d(-1px, 0, 0); }
  20%, 80% { transform: translate3d(2px, 0, 0); }
  30%, 50%, 70% { transform: translate3d(-4px, 0, 0); }
  40%, 60% { transform: translate3d(4px, 0, 0); }
}
// el.classList.add('glitch'); setTimeout(() => el.classList.remove('glitch'), 200);

scanline overlay

used in hold6.html stages 3-4 and the CRT-flavored pages. a repeating gradient laid over the content, opacity-toggled.
CRT MODE
#scan {
  position: absolute; inset: 0; pointer-events: none;
  background: repeating-linear-gradient(0deg,
    rgba(34,255,102,0.08) 0px, rgba(34,255,102,0.08) 1px,
    transparent 1px, transparent 2px);
}

blinking cursor

used on still.b0r3d.org's own homepage (uptime line) and the offline joke page.
still online
.cursor {
  display: inline-block; width: 10px; height: 1.1em;
  background-color: #00ff00; vertical-align: text-bottom;
  animation: blink 1s step-end infinite; margin-left: 4px;
}
@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }

LED digit counter

used for still.b0r3d.org's visitor counter. pads any number into fixed-width glowing digits.
function renderLed(el, n, width) {
  const digits = String(n).padStart(width, '0').split('');
  el.innerHTML = digits.map(d =>
    `<span class="led-digit">${d}</span>`).join('');
}

terminal boot sequence

used on the still-offline joke page — lines fade in one at a time on a stagger, reads like a system booting or failing.
lines.forEach((text, i) => {
  setTimeout(() => {
    const el = document.createElement('div');
    el.textContent = text;
    el.style.animation = 'fadein 0.4s ease forwards';
    container.appendChild(el);
  }, i * 500);
});
// @keyframes fadein { from{opacity:0;transform:translateY(3px)} to{opacity:1;transform:translateY(0)} }

chromatic glitch text

pulled from an early draft of this exact showcase page. a continuous RGB-shadow jitter — different technique from the shake effect above, reads more like a broken CRT than a shudder.
SIGNAL LOST
.chroma-glitch {
  color: red;
  text-shadow: 1px 1px lime, -1px -1px blue;
  animation: chromaGlitch 0.3s infinite;
}
@keyframes chromaGlitch {
  0% { transform: translate(0, 0); }
  20% { transform: translate(-1px, 1px); }
  40% { transform: translate(1px, -1px); }
  60% { transform: translate(-1px, 1px); }
  80% { transform: translate(1px, 1px); }
  100% { transform: translate(0, 0); }
}

hover to reveal

same source draft as the glitch text above. dim text that only reads clearly on hover — a cheap way to hide a line in plain sight.
hover over this to reveal its true nature
.hover-reveal { color: #555; transition: color 0.5s ease; }
.hover-reveal:hover { color: #0f0; }

mouse trail

found in an old scratch file. dots follow the cursor and fade+scale out — mix-blend-mode: difference makes each one invert whatever's underneath it. scoped to the box below only; move your mouse across it.
move here
el.addEventListener('mousemove', e => {
  const r = el.getBoundingClientRect();
  const dot = document.createElement('div');
  dot.className = 'trail-dot';
  dot.style.left = (e.clientX - r.left) + 'px';
  dot.style.top = (e.clientY - r.top) + 'px';
  el.appendChild(dot);
  setTimeout(() => dot.remove(), 1000);
});
/* .trail-dot { position:absolute; width:10px; height:10px; background:cyan;
   border-radius:50%; pointer-events:none; mix-blend-mode:difference;
   animation: fadeOutTrail 1s forwards; }
   @keyframes fadeOutTrail { to { opacity:0; transform:scale(3); } } */

tab title randomizer

same scratch file as the mouse trail. cycles the browser tab's own title while active — easy to miss until you glance at your open tabs. runs for 5 seconds then restores the real title.
check this tab's title in your browser
const words = ['LOADING', 'BOOTING', 'ERROR', 'SUCCESS', '??!?!'];
const original = document.title;
const iv = setInterval(() => {
  document.title = words[Math.floor(Math.random() * words.length)]
    + Math.floor(Math.random() * 99);
}, 300);
setTimeout(() => { clearInterval(iv); document.title = original; }, 5000);

hidden message

from an old scratch page about a room with breathing walls. text the same color as its background, tiny font — invisible at a glance, only found via select-all (try Ctrl+A / Cmd+A on the demo box) or view-source. classic ARG trick.
nothing to see here. don't trust the walls.
<p style="font-size:4px; color:#111;">
  the hidden text, colored to match its background
</p>
/* only found via Ctrl+A or view-source — never rely on it being unbreakable,
   it's a "reward the curious" trick, not real security */

ambient breathing

same scratch page as the hidden message. a slow scale loop on a background — reads as something quietly alive rather than a static image.
the walls seem to shift and breathe
@keyframes breathe {
  0% { transform: scale(1); }
  50% { transform: scale(1.02); }
  100% { transform: scale(1); }
}
/* apply to a background container: animation: breathe 10s ease-in-out infinite; */

anomaly trigger

from an old "intercept log" bookmark page — a link list where a few entries were traps. clicking one shook the screen and flashed a full-screen warning with a rapid flicker before fading out. strong effect, worth using sparingly.
function triggerAnomaly(message) {
  document.body.classList.add('shake');
  readout.innerText = message;
  readout.style.display = 'block';
  let n = 0;
  const iv = setInterval(() => {
    readout.style.opacity = Math.random() > 0.5 ? '1' : '0';
    if (++n > 10) {
      clearInterval(iv);
      readout.style.opacity = '1';
      setTimeout(() => {
        readout.style.display = 'none';
        document.body.classList.remove('shake');
      }, 2000);
    }
  }, 50);
}
/* .shake reuses the same shake keyframes as the screen glitch card above.
   readout is a fixed, centered, high-z-index overlay div. */

BSOD easter egg

js/bsod.js, loaded site-wide. press Shift+F4 anywhere on the real site for a fake Windows STOP screen (RUKUS_MODE_EXCEPTION_NOT_HANDLED). never showcased before — demo below is scoped to this box instead of covering your whole screen like the real one does.
// real version: full-viewport, position:fixed, triggered by Shift+F4
bsod.style.animation = 'bsod-flicker 0.15s infinite alternate';
bsod.innerHTML = `<pre>
*** STOP: 0x000000D3 (...)
A problem has been detected and Windows has been shut down...
*** STOP: RUKUS_MODE_EXCEPTION_NOT_HANDLED
</pre>`;
document.addEventListener('keydown', e => {
  if (e.shiftKey && e.key === 'F4') bsod.style.display = 'block';
});
/* @keyframes bsod-flicker { from{opacity:.98} to{opacity:1} } */

real glitch + static

js/glitch.js, loaded site-wide — a 1% chance per page load. the site's actual canonical glitch: page shake+rotate+hue-shift *plus* genuine canvas-rendered noise redrawn every 100ms. more sophisticated than the shake-only "screen glitch" card near the top. scoped to this box for the demo; the real one hits the whole page.
SIGNAL
.glitch-mode { animation: glitchAnim 0.5s infinite, hueShift 1s infinite; filter: contrast(200%); }
@keyframes glitchAnim {
  0% { transform: translate(0); }
  20% { transform: translate(-2px,2px) rotate(1deg); }
  40% { transform: translate(2px,-2px) rotate(-1deg); }
  /* ...settles back to 0 by 100% */
}
@keyframes hueShift {
  0% { filter: hue-rotate(0deg) contrast(200%); }
  50% { filter: hue-rotate(180deg) contrast(200%); }
  100% { filter: hue-rotate(360deg) contrast(200%); }
}
// + a <canvas> overlay redrawing random per-pixel noise every 100ms,
// removed after 3s along with the glitch-mode class.

split-layer RGB glitch

from 404.html. two colored ::before/::after copies of the text, clipped and offset only during rare glitch frames (steps(1), mostly settled) rather than continuous jitter — reads as intermittent signal corruption. also a good example of the site respecting prefers-reduced-motion.
404
.glitch { position: relative; display: inline-block; }
.glitch::before, .glitch::after {
  content: attr(data-text); position: absolute; left: 0; top: 0;
  width: 100%; overflow: hidden;
}
.glitch::before { color: cyan; clip-path: inset(0 0 82% 0); animation: glitchTop 3.4s infinite steps(1); }
.glitch::after  { color: magenta; clip-path: inset(78% 0 0 0); animation: glitchBottom 3.4s infinite steps(1); }
@keyframes glitchTop {
  0%, 92%, 100% { transform: translate(0,0); clip-path: inset(0 0 82% 0); }
  93% { transform: translate(-3px,1px); clip-path: inset(0 0 60% 0); }
  95% { transform: translate(3px,-1px); clip-path: inset(0 0 88% 0); }
}
/* glitchBottom mirrors this, offset differently — see 404.html */
@media (prefers-reduced-motion: reduce) {
  .glitch::before, .glitch::after { animation: none; }
}

3D rotating cube

from dont_trust.html. pure CSS 3D transforms, no canvas/WebGL — six faces, each independently colored and labeled. a completely different kind of effect from everything else here.
DUST
RUST
TAPE
ECHO
PAST
TRUTH
.cube { width: 100px; height: 100px; position: relative;
  transform-style: preserve-3d; animation: rotate 8s linear infinite; }
.cube-face { position: absolute; width: 100px; height: 100px; border: 2px solid #fff; }
.front  { transform: translateZ(50px); }
.back   { transform: rotateY(180deg) translateZ(50px); }
.right  { transform: rotateY(90deg) translateZ(50px); }
.left   { transform: rotateY(-90deg) translateZ(50px); }
.top    { transform: rotateX(90deg) translateZ(50px); }
.bottom { transform: rotateX(-90deg) translateZ(50px); }
@keyframes rotate {
  from { transform: rotateX(0deg) rotateY(0deg); }
  to   { transform: rotateX(360deg) rotateY(360deg); }
}

CRT flicker

from login.html. a brief brightness dip rather than a position shake — reads as an old CRT losing signal for a frame, distinct from the shake/scanline effects above.
ACCESS TERMINAL
@keyframes crtFlicker {
  0%, 100% { opacity: 1; }
  42% { opacity: 0.96; }
  43% { opacity: 0.4; }
  44% { opacity: 0.96; }
}
/* apply: animation: crtFlicker 1.2s infinite; */

theme palette reference

every color theme currently live on the site, for quick reference when starting something new. click a swatch to copy its hex.
back to lab