Futuristic Code Previewer
HTML
CSS
JavaScript
Incorrect Password. Try Again.
Incorrect Password. Try Again.
See the Pen Terminal Hacker by Thomas John (@NoRabbit) on CodePen.
I am tab #3 content. Click edit button to change this text. Drops of rain could be heard hitting the pane, which made him feel quite sad. How about if I sleep a little bit longer and forget all this nonsense.
See the Pen Untitled by Max Scopp (@max-scopp) on CodePen.
See the Pen Making a CSS animation using a sprite sheet by Hannah Gooding (@hannahgooding) on CodePen.
See the Pen The typewriter effect by gbohlin (@gbohlin) on CodePen.
See the Pen Terminal Loading Bar by Anil Person (@anilperson) on CodePen.
See the Pen The typewriter effect by gbohlin (@gbohlin) on CodePen.
<div class="wrapper">
<pre><output id="output"></output><div class="user-input"><span class="incentive">$></span><input type="text"/></div></pre>
</div>
<!--
Package: GlitchedWriter
Version: 2.0.7
Time: 1208ms
Asset Size Chunks Chunk Names
index.js 12.3 MB 0 [emitted] [big] index
dashboard.js 6.36 MB 1 [emitted] [big] dashboard
0.81c79b4db476a98d272f.hot-update.js 87.4 kB 0 [emitted] project
81c79b4db476a98d272f.hot-update.json 52 bytes [emitted]
manifest.json 272 bytes [emitted]
./app/javascript/common/components/Termianl.js 2.42 kB {0} {1} [built]
Welcome To Glitched Terminal! (v 2.0.7)
23/3/2021, 18:39
Documentation: type "help"
-->
$black: #000000;
$dark: #33202a;
$lighter: #5f5566;
$white: #f5f4f6;
$red: #f05d5e;
$yellow: #fcab10;
body {
background-color: $black;
background: radial-gradient(
ellipse at right 34% bottom 5%,
$dark,
$black 80%,
$black
);
background-position: left;
height: 100vh;
margin: 0;
overflow: hidden;
color: $white;
font: 1.3rem Inconsolata, monospace;
text-shadow: 0 0 5px $white;
&::after {
content: "";
position: absolute;
opacity: 0.3;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: repeating-linear-gradient(
0deg,
rgba($black, 1),
rgba($black, 1) 2px,
transparent,
transparent 4px
);
pointer-events: none;
}
&::before {
content: "";
position: absolute;
z-index: 1000;
opacity: 0.4;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: radial-gradient(
ellipse at right 34% bottom 5%,
transparent 60%,
$black
);
pointer-events: none;
}
}
::selection {
background: $dark;
text-shadow: none;
}
pre {
margin: 0;
white-space: pre-wrap;
margin-bottom: 80vh;
animation: text-blink 0.01s steps(2) infinite;
}
@keyframes text-blink {
from,
to {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
@keyframes blink {
from,
to {
opacity: 1;
}
50% {
opacity: 0;
}
}
#output {
&:after {
content: "▮";
opacity: 1;
animation: blink 1s steps(1) infinite;
}
&.gw-writing {
&:after {
animation: none;
}
}
a {
color: $yellow;
text-decoration: none;
text-shadow: 0 0 5px $yellow;
&:hover {
font-weight: bold;
}
}
b {
font-weight: normal;
&:hover {
color: $lighter;
text-shadow: 0 0 5px $lighter;
}
}
strong {
font-weight: normal;
color: $red;
text-shadow: 0 0 5px $red;
}
i {
color: $lighter;
text-shadow: 0 0 5px $lighter;
font-style: normal;
}
}
.wrapper {
padding: 2rem;
overflow-y: scroll;
height: 100%;
-ms-overflow-style: none;
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
}
.user-input {
display: flex;
display: none;
}
.incentive {
color: $yellow;
}
input {
width: 100%;
margin-left: 10px;
background: transparent;
outline: none !important;
border: none !important;
color: $white;
font: 1.3rem Inconsolata, monospace;
text-shadow: 0 0 5px $white;
}
import GlitchedWriter, {
wait,
presets
} from "https://cdn.skypack.dev/glitched-writer@2.0.29";
// Glitched Writer npm module:
// https://www.npmjs.com/package/glitched-writer
const random = (min, max, mathFunc = null) => {
let w = Math.random() * (max - min) + min;
return mathFunc == null ? w : Math[mathFunc](w);
};
const Writer = new GlitchedWriter("#output", {
...presets.terminal,
mode: "erase_smart",
html: true
});
const date = new Date();
(async function () {
await Writer.write("script: Compiling.");
await wait(200);
await Writer.add(".");
await wait(200);
await Writer.add(".");
await wait(200);
await Writer.remove(1);
await wait(200);
await Writer.remove(1);
await wait(200);
await Writer.add(".");
await wait(200);
await Writer.add(".");
await wait(300);
await Writer.write(`script: Compiled successfully.
hash: ${Date.now()}
package: <a href="https://glitched-writer.site" target="_blank">glitched-writer</a>
version: 2.0.29
time: ${random(0, 1500, "round")}ms
Asset Size Chunks Chunk Names
<i>index.js</i> ${random(
10,
50,
"round"
)}.3 MB 3 <strong>[emitted]</strong> <strong>[big]</strong> index
<i>dashboard.js</i> 6.${random(
10,
80,
"round"
)} MB 1 <strong>[emitted]</strong> <strong>[big]</strong> dashboard
<i>0.81c79b4db476a98d272f.hot-update.js</i> ${random(
40,
100,
"round"
)}.4 kB 0 <strong>[emitted]</strong> project
<i>81c79b4db476a98d272f.hot-update.json</i> 52 bytes <strong>[emitted]</strong>
<i>manifest.json</i> ${random(
100,
300,
"round"
)} bytes <strong>[emitted]</strong>
<i>./app/javascript/common/components/Terminal.js</i> 2.42 kB {0} {1} <strong>[built]</strong>
<b>Welcome To Glitched Terminal!</b> (v 2.0.29)
<i>${date.getDate()}/${
date.getMonth() + 1
}/${date.getFullYear()} ${date.getHours()}:${date.getMinutes()}</i>
Documentation: type "help"
`);
})();
See the Pen Fallout 4 Terminal by Willmer Barahona (@wbarahona) on CodePen.
See the Pen Terminal with Scan Lines by Patrick Himes (@patrickhimes) on CodePen.
See the Pen Time Machine by Kris Watts (@UncleDozer) on CodePen.
See the Pen #Codevember10 - CRT TV Effect by Karl Saunders (@Mobius1) on CodePen.
See the Pen Command Line by Solaiman Kmail (@solaimankmail) on CodePen.
// Chrome for best experience, if you're on FF... sorry - correct sequence is at the bottom of the JS file.
// Inspired by a scene from Call of Duty: Advanced warefare this is my attemp to recreate a login panel the player uses towards the middle of the game. The entire design concept as well as behaviors come from the game, I just tried to implement them via the web. Give it a couple of tries and when you've had enough.
block body
main.page
section.login
div.welcome
h2= 'hope you enjoyed that'
p= 'I took some shortcuts with error cases, transition events, and backbone in general but overall it should work well enough as a password form. Hope you liked it and a thanks to the baller designers at Sledgehammer for coming up with this terminal concept. Hit that button if you wanna play with the terminal some more. Cheers =)'
button(class="btn--rst" terminal-reset)= 'reset'
@import "compass/css3";
* { box-sizing: border-box; }
html, body {
margin: 0; padding: 0; position: relative;
width: 100%; height: 100%;
background-color: #3d4340;
font-family: "Dosis";
font-weight: 400;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: grayscale;
-moz-osx-font-smoothing: grayscale;
text-shadow: 0 1px rgba(255, 255, 255, 0.1);
background: #212121;
}
/* VARS */
/* $teal: #79BB9F; */
$teal: lighten(#2E8B5D, 20%);
$light-orange: #c2b769;
$orange: #c2a069;
$light-red: #cc6570;
$dark-red: #8F1934;
$red: #bd5d68;
$green: #3d6645;
$light-green: #76c160;
$pad: 24px;
$pad-double: $pad * 2;
$pad-half: $pad / 2;
$space: 26px;
$space-and-half: $space * 1.5;
$space-double: $space * 2;
$space-half: $space / 2;
/* STYLES */
// defaults
button {
-webkit-appearance: none;
outline: none;
background: tranparent;
border: none;
display: block;
cursor: pointer;
}
// page
.login {
position: absolute; top: 0; right: 0; bottom: 0; left: 0;
margin: auto;
display: -webkit-flex;
display: flex;
-webkit-align-items: center;
align-items: center;
-moz-box-align: center;
-webkit-box-pack: center;
-webkit-justify-content: center;
justify-content: center;
-moz-box-pack: center;
-ms-flex-pack: center;
}
// terminal wrapper and header
.terminal {
&.state--frozen .pwd__btn {
cursor: default;
pointer-events: none;
}
&.state--warp {
@include animation(warpOut .35s ease);
@include animation-fill-mode(forwards);
}
}
.terminal-title {
text-transform: uppercase;
color: rgba($teal, .8);
padding-bottom: $pad-double;
span, h3 {
opacity: 0;
@include transform-style(preserve-3d);
}
span {
display: block;
font-size: 14px;
@include animation(shiftInUp .35s ease .20s);
@include animation-fill-mode(forwards);
}
h3 {
font-size: 42px;
font-weight: 600;
@include animation(shiftInUp .35s ease .30s);
@include animation-fill-mode(forwards);
}
}
// sequence pad
$seq-pad-corner-offset: 2px;
.seq-pad {
padding: $pad $pad 0 $pad;
border: 1px solid rgba($teal, .15);
position: relative;
opacity: 0;
@include transform-style(preserve-3d);
@include animation(warpIn .45s ease);
@include animation-fill-mode(forwards);
}
.seq-pad__cnr { // corner dots
position: absolute;
display: block;
width: 6px; height: 6px;
background-color: $teal;
&.cnr--tp-lt {
top: $seq-pad-corner-offset;
left: $seq-pad-corner-offset;
}
&.cnr--tp-rt {
top: $seq-pad-corner-offset;
right: $seq-pad-corner-offset;
}&.cnr--bt-lt {
bottom: $seq-pad-corner-offset;
left: $seq-pad-corner-offset;
}
&.cnr--bt-rt {
bottom: $seq-pad-corner-offset;
right: $seq-pad-corner-offset;
}
}
// buttons wrapper and buttons
$btns-per-row: 8;
$btn-bdr-size: 1px;
.seq-pad__inr {
overflow: hidden;
}
%terminal-btn {
display: block; position: relative;
width: 80px; height: 80px;
float: left;
margin-right: 6px;
margin-bottom: $space;
&:nth-child(#{$btns-per-row}n + 1) {
clear: left;
}
}
.pad-btn {
@extend %terminal-btn;
background-color: rgba(#fff, .05);
color: rgba($teal, .8);
font-family: "Dosis";
font-size: 38px;
font-weight: 400;
@include transition(all .25s);
// states
&:hover {
color: rgba($teal, 1);
background-color: rgba(#fff, .15);
}
&.state--active {
color: $light-orange;
background-color: rgba($orange, .15);
.pad-btn__bdr {
background-color: rgba($orange, .65);
}
}
&.state--error {
color: $light-red;
background-color: rgba($red, .15);
.pad-btn__bdr {
background-color: rgba($red, .65);
}
}
&.state--success {
color: $light-green;
background-color: rgba($green, .15);
.pad-btn__bdr {
background-color: rgba($green, .85);
}
}
}
.pad-btn--blnk {
@extend %terminal-btn;
}
// button squares
.pad-btn__sqrs {
position: absolute;
left: 8px;
bottom: 8px;
overflow: hidden;
.pad-btn__sqr {
width: 4px;
height: 4px;
display: block;
float: left;
margin-right: 2px;
background-color: $teal;
}
}
// button border and corners
.pad-btn__bdr {
display: block; position: absolute;
width: 6px; height: 6px;
background-color: rgba($teal, .4);
&:before, &:after {
content: "";
position: absolute; display: block;
background-color: inherit;
}
&.bdr--tp, &.bdr--bt {
height: $btn-bdr-size;
width: calc(100% - 12px);
left: 0; right: 0; top: 0;
margin: auto;
&:before, &:after {
width: $btn-bdr-size * 2;
height: $btn-bdr-size;
top: 0; left: -6px;
}
&:after {
left: auto; right: -6px;
}
}
&.bdr--bt {
top: auto; bottom: 0;
}
&.bdr--rt, &.bdr--lt {
width: $btn-bdr-size;
height: calc(100% - 12px);
top: 0; bottom: 0; right: 0;
margin: auto;
}
&.bdr--lt {
left: 0; right: auto;
}
}
// footer
.terminal-footer {
position: relative;
width: 100%;
margin-top: $space;
clear: both;
text-align: center;
min-height: 40px;
}
.btn--clr {
display: block; position: absolute;
top: 0;
left: 0;
height: $space;
text-transform: uppercase;
font-size: 14px;
line-height: $space;
padding: 0 $pad-half;
font-weight: 500;
border: none;
background-color: $dark-red;
color: #1a1a1a;
visibility: hidden;
opacity: 0;
@include transition(all, .25s);
@include transform(translate3d(0, -6px, 0));
&.state--visible {
visibility: visible;
opacity: 1;
@include transform(translate3d(0, 0, 0));
}
}
.verify-msg {
display: inline-block;
vertical-align: top;
line-height: $space;
font-size: 16px;
text-transform: uppercase;
white-space: nowrap;
@include transform(translate3d(0, 6px, 0));
@include transition(width .25s, transform .25s);
@include animation(blink .35s ease infinite alternate);
@include animation-play-state(paused);
&.state--play {
@include transform(translate3d(0, 0, 0));
@include animation-play-state(running);
width: 150px;
}
&.state--error {
color: $light-red;
}
&.state--success {
color: $light-green;
}
}
.terminal-load-bar {
height: 2px;
width: 50%;
display: block;
position: relative;
margin-top: 10px;
&:before {
content: ''; display: block; position: absolute;
top: 0; left: 50%; bottom: 0; margin: auto;
width: 0;
background: rgba($light-green, .35);
@include transition(width 1.8s);
}
&.state--loading:before {
width: 100%;
}
}
// welcome message and reset
.welcome {
display: none;
width: 340px;
h2 {
font-size: 22px;
text-transform: uppercase;
color: $teal;
line-height: 1;
}
p {
font-size: 14px;
line-height: 20px;
color: rgba($teal, .7);
padding: $space 0;
text-transform: uppercase;
letter-spacing: 1px;
}
.btn--rst {
text-transform: uppercase;
font-size: 14px;
line-height: $space;
padding: 0 $pad-half;
font-weight: 500;
border: none;
background-color: $dark-red;
color: #1a1a1a;
}
}
@include keyframes(shiftInUp) {
0% {
opacity: 0;
@include transform(translate3d(0,20px,0));
}
100% {
opacity: 1;
@include transform(translate3d(0,0,0));
}
}
@include keyframes(blink) {
0% { opacity: 0; }
100% { opacity: 1; }
}
@-webkit-keyframes warpIn {
0% {
opacity: 0;
@include transform(scale(.8, .8));
@include transform-origin(center, center);
}
100% {
opacity: 1;
@include transform(scale(1, 1));
@include transform-origin(center, center);
}
}
@include keyframes(warpOut) {
0% {
opacity: 1;
@include transform(scale(1, 1));
@include transform-origin(center, center);
}
100% {
opacity: 0;
visibility: hidden;
@include transform(scale(1.2, 1.2));
@include transform-origin(center, center);
}
}
/*
* !! Passcode at the bottom
*/
/*
* Predeined arrays for various stuff
*/
var terminalKeys = [
{ val: 'D8', dots: 3 },
{ val: 'J5', dots: 2 },
{ val: 'K2', dots: 1 },
{ val: 'C1', dots: 2 },
{ val: 'S9', dots: 3 },
{ val: 'A2', dots: 3 },
{ val: 'MN', dots: 1 },
{ val: '2Z', dots: 1 },
{ val: '43', dots: 1 },
{ val: 'X0', dots: 0 },
{ val: 'Q0', dots: 2 },
{ val: 'L7', dots: 0 },
{ val: 'R5', dots: 1 },
{ val: 'V6', dots: 2 },
{ val: 'H4', dots: 0 },
{ val: '99', dots: 2 },
{ val: false, dots: 0},
{ val: 'S6', dots: 1},
{ val: 'U4', dots: 3},
{ val: 'Y1', dots: 3},
{ val: '4B', dots: 0},
{ val: 'I3', dots: 0},
{ val: '91', dots: 1},
{ val: false, dots: 0}];
var terminalTpl = "<header class='terminal-title'>" +
"<span>admin terminal r75_zone 24</span>" +
"<h3>access code required</h3>" +
"</header>" +
"<div class='seq-pad'>" +
"<span class='seq-pad__cnr cnr--tp-lt'></span>" +
"<span class='seq-pad__cnr cnr--tp-rt'></span>" +
"<span class='seq-pad__cnr cnr--bt-lt'></span>" +
"<span class='seq-pad__cnr cnr--bt-rt'></span>" +
"<div class='seq-pad__inr'>" +
"<% _.each(data, function(item,key){ %>" +
"<% if(!item.val) { %>" +
"<div class='pad-btn--blnk'></div>" +
"<% } else { %>" +
"<button class='pad-btn' key='<%= item.val %>'>" +
"<%= item.val %>" +
"<span class='pad-btn__bdr bdr--tp'></span>" +
"<span class='pad-btn__bdr bdr--rt'></span>" +
"<span class='pad-btn__bdr bdr--bt'></span>" +
"<span class='pad-btn__bdr bdr--lt'></span>" +
"<div class='pad-btn__sqrs'>" +
"<% for(var i=0; i<item.dots; i++) { %>" +
"<span class='pad-btn__sqr'></span>" +
"<% } %>" +
"</div>" +
"</button>" +
"<% } %>" +
"<% }); %>" +
"</div>" +
"</div>" +
"<div class='terminal-footer'>" +
"<button class='btn--clr' pad-actn-clr>reset</button>" +
"<span class='verify-msg' pad-actn-msg></span>" +
"<span class='terminal-load-bar'></span>" +
"</div>";
/*
* Set up backbone
*/
var Panel = Backbone.Model.extend({
defaults: {
passcode: ['C1', 'I3', '91', 'X0'],
sequence: [],
},
initialize: function(opts) {
this.opts = opts;
this.set('sequence', []);
this.listenTo(this, 'change', this.verify);
},
addKey: function(key) {
var temp = this.get('sequence');
temp.push(key);
this.set('sequence', temp);
this.trigger('change');
},
clearPass: function() {
this.set('sequence', []);
},
testSequence: function() {
var i = 0,
match = true;
for(var i=0; i< this.get('passcode').length; i++) {
if(this.get('sequence')[i] !== this.get('passcode')[i]) {
match = false;
break;
}
}
return match;
},
isIncomplete: function() {
return (this.isEmpty() || this.isFull()) ? false : true;
},
isEmpty: function() {
return (this.get('sequence').length == 0) ? true : false;
},
isFull: function() {
return (this.get('sequence').length == this.get('passcode').length) ? true : false;
},
verify: function() {
if (!this.isFull()) {
return;
} else {
(!this.testSequence())
? this.trigger('mismatch')
: this.trigger('match');
}
}
});
var PanelView = Backbone.View.extend({
tagName: 'div',
className: 'terminal',
model: null,
template: null,
events: {
'click .pad-btn': 'addKey',
'click [pad-actn-clr]': 'resetForm'
},
initialize: function(opts){
this.sequence = []; // used to store the current sequence
this.opts = opts;
this.template = _.template(this.opts.template);
this.listenTo(this.model, 'change:sequence', this.toggleControls);
this.listenTo(this.model, 'mismatch', this.setFailState);
this.listenTo(this.model, 'match', this.setPassState);
this.listenTo(this.model, 'destroy', this.trash);
},
render: function(){
var _self = this;
this.$el.append(this.template({'data': this.opts.data }));
this.$btnPads = this.$el.find('.pad-btn');
this.$btnReset = this.$el.find('[pad-actn-clr]');
this.$msg = this.$el.find('[pad-actn-msg]');
this.$loadbar = this.$el.find('.terminal-load-bar');
this.$el.on('animationend webkitAnimationEnd', function(){
if (_self.$el.hasClass('state--warp')) {
_self.model.destroy();
}
});
$('.login').append(this.$el);
},
addKey: function(e){
var $temp = $(e.target);
if ($temp.hasClass('state--active')) {
return;
}
$temp.addClass('state--active');
this.model.addKey($temp.attr('key'));
},
toggleControls: function(force) {
var show = (force == true || force == false) ? force : this.model.isIncomplete();
this.$btnReset[(show) ? 'addClass' : 'removeClass']('state--visible');
},
setFailState: function() {
this.showMessage({
success: false,
btnClass: 'state--error',
formMsg: 'wrong sequence',
formMsgClass: 'state--error'
});
},
setPassState: function() {
this.showMessage({
success: true,
btnClass: 'state--success',
formMsg: 'logging in',
formMsgClass: 'state--success'
});
},
showMessage: function(obj) {
var _self = this;
this.$btnPads.filter('.state--active')
.removeClass('state--active')
.addClass(obj.btnClass);
this.$el.addClass('state--frozen');
this.$msg.text(obj.formMsg).addClass('state--play ' + obj.formMsgClass);
if (!obj.success) {
setTimeout(function(){
_self.resetForm();
}, 2100);
} else {
setTimeout(function(){
_self.loginForm();
});
}
},
resetForm: function() {
this.model.clearPass();
this.$el.removeClass('state--frozen');
this.$btnPads.removeClass('state--active state--error state--success');
this.$msg.text('').removeClass('state--play');
this.toggleControls(false);
},
loginForm: function() {
var _self = this;
this.$loadbar.addClass('state--loading')
.on('transitionend webkitTransitionEnd', function(e){
_self.$el.addClass('state--warp');
});
},
trash: function() {
toggleWelcome(true); // cheating
this.undelegateEvents();
this.remove();
Backbone.View.prototype.remove.call(this);
}
});
// terminal set up, so it can be called more than once
var initTerminal = function() {
var login = null,
pad = null;
login = new Panel();
pad = new PanelView({
model: login,
template: terminalTpl,
data: terminalKeys
});
// render the view
pad.render();
}
// switch welcome on or off
var toggleWelcome = function(on) {
var $welcome = $('.welcome');
(on) ? $welcome.show() : $welcome.hide();
}
// reset button binding
$('[terminal-reset]').on('click', function(){
toggleWelcome(false);
initTerminal();
});
// finally launch the terminal
initTerminal();
// password solution
// 'C1', 'I3', '91', 'X0'[/]
< SYSTEM REBOOTING >
HYDRA VER 2.1 SYS RECOVERY
PROCESS: 0%
REBOOTING SUCCESSFUL
<output></output>
@display-height: 70vh;
@blink-time: 500ms;
@keyframes blink {
0%,49% { border-right-color: transparent }
50%,100% { border-right-color: currentColor }
}
@keyframes scan {
0% { background-position: 0 -100vh; }
35%,100% { background-position: 0 100vh; }
}
html {
background-color: black;
padding: 1em;
}
output {
border-radius: 1em;
background-color: #131;
background-image:
radial-gradient(ellipse 500% 100% at 50% 90%, transparent, #121);
//background-size: 500% 100%;
background-position: center;
display: block;
height: @display-height;
padding: 2em;
box-shadow: inset 0 0 10em 1em rgba(0,0,0,0.5);
overflow: auto;
font-family: monospace;
color: rgba(128,255,128,0.8);
position: relative;
.layer() {
position: absolute;
content: "";
display: block;
top:0; left: 0; right: 0; bottom: 0;
pointer-events:none;
}
// Scan
&::before {
.layer();
background-image: linear-gradient(0deg,
transparent 0%,
rgba(32,128,32,0.2) 2%,
rgba(32,128,32,0.8) 3%,
rgba(32,128,32,0.2) 3%,
transparent 100%);
background-repeat: no-repeat;
animation: scan 7.5s linear 0s infinite;
}
&::after {
.layer();
background-image:
// Glare
radial-gradient(ellipse 50% 15% at 50% 15%, rgba(255,255,255,0.05), transparent),
radial-gradient(ellipse 50% 10% at 50% 12%, rgba(255,255,255,0.1), transparent),
radial-gradient(ellipse 50% 5% at 50% 10%, rgba(255,255,255,0.1), transparent),
radial-gradient(ellipse 50% 3% at 50% 9%, rgba(255,255,255,0.1), transparent),
// Shadow
radial-gradient(ellipse 200% 20% at 50% 0%, rgba(0,0,0,0.5), transparent),
// Scanlines
linear-gradient(0deg, rgba(0,0,0,0.2) 50%, transparent 50%);
background-size: 100%, 100%, 100%, 100%, 100%, 100% 0.25ch;
}
q {
border-right: 0 solid currentColor;
animation: blink @blink-time linear 0s infinite;
text-shadow: 0 0 1ex #3f3, 0 0 2px rgba(255,255,255,0.8);
margin-bottom: 1em;
line-height: 150%;
&::before {
content: "> ";
}
&:last-child {
border-right-width: 1ch;
}
}
}
var bind = Function.prototype.bind,
$append = bind.call(Element.prototype.appendChild, document.querySelector("output")),
$new = bind.call(Document.prototype.createElement, document),
$text = bind.call(Document.prototype.createTextNode, document),
$rnd = function() { return (Math.random() * 125 + 0)|0; },
$promise = function(thenFn) {
var args, promise, wait, slice=Array.prototype.slice, isResolved = false;
var promise = {
wait: function(ms) {
wait = ms;
return promise;
},
then: function() {
args = slice.call(arguments);
return promise = $promise(thenFn);
},
resolve: function() {
isResolved = true;
if(args) {
var next = Function.prototype.bind.apply(thenFn, [undefined].concat(args).concat([promise]));
wait ? setTimeout(next, wait) : next();
}
}
};
return promise;
};
var process = function(target, chars, promise) {
var first = chars[0], rest = chars.slice(1);
if(!first) {
promise.resolve();
return;
}
target.appendChild(first);
setTimeout(process.bind(undefined, target, rest, promise), $rnd());
}
var type = function(text, promise) {
var chars = text.split("").map($text);
promise = promise || $promise(type);
$append($new("br"));
process($append($new("q")), chars, promise);
return promise;
};
type("Testing....")
.wait(500)
.then("This is just a test...")
.then("This is *only* a test...")
.wait(1500)
.then("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin vitae tellus aliquet, eleifend mi id, malesuada massa. Nam sit amet nunc ut nulla elementum tempor eu ut ipsum. Suspendisse eget augue sollicitudin, adipiscing dui sed, blandit nulla. Donec tempor vehicula nisi at molestie. Vestibulum interdum sem arcu, vitae sodales libero gravida et. Suspendisse pretium consectetur augue at lacinia. Ut urna lectus, tincidunt ut elit vitae, egestas egestas ipsum. Maecenas gravida tortor eget metus pulvinar sodales. Cras vitae nisi nec felis varius auctor. Donec semper aliquam mollis.");
<!-- you can try to combine it with: https://github.com/nolanlawson/emoji-picker-element -->
body {
margin: 0;
height: 100vh;
--size: 1.5;
}
/* hack for version 2.29.1 */
.terminal {
--glow: x;
}
/*
use css below if you use
--animation: terminal-underline
span:not(.cursor) > .emoji {
top: 1px;
}
.cursor .emoji {
top: -1px;
}
*/
.cmd .emoji, .terminal-output>:not(.raw) .emoji {
background-size: contain;
background-repeat: no-repeat;
}
var term = $('body').terminal(function(command) {
const cmd = $.terminal.parse_command(command);
if (cmd.name == 'apropos') {
names.filter(name => name.match(cmd.args[0])).forEach(name => {
term.echo(`${name}: :${name}:`);
});
} else {
this.echo('you typed [[bi;#fff;]' + JSON.stringify(command) + ']', {
formatters: false
});
}
}, {
name: 'emoji',
// detect iframe codepen preview
enabled: $('body').attr('onload') === undefined,
onInit: function() {
// in Window 10 it will render 8️⃣ as icon
// in other browsers you may render it as
// text
this.echo('type :smiley: or :) to render emoji :smiley:')
.echo('<span><div data-text>You can also paste Unicode codepoints that create emoji ' +
'like 8️⃣ to render </span><span style="width: 2ch" class="emoji eight" '+
'data-text="8️⃣">8️⃣</span></span>', {raw: true})
.echo('you need to wait a moment while we fetch emoji data')
.echo('to see available emoji use apropos command (e.g. apropos /smil/)');
},
completion: function(string, callback) {
if (string.match(/^:/)) {
return names.map(function(name) {
return ':' + name + ':';
});
} else {
return commands;
}
}
});
// for codepen preview
if (!term.enabled()) {
term.find('.cursor').addClass('blink');
}
var commands = ['apropos'];
var names = [];
var list;
$.get('https://cdn.jsdelivr.net/npm/emoji-datasource').then(function(list) {
$.terminal.emoji(list);
names = list.map(function(emoji) { return emoji.short_name; });
term.clear_cache().refresh();
if (term.get_command()) {
term.cmd().resize();
}
});
// regexes copy from jQuery Terminal source code
var re_re = /(\/((?:\\\/|[^/]|\[[^\]]*\/[^\]]*\])+)\/([gimsuy]*))/g;
var string_re = /("(?:[^"\\]|\\(?:\\\\)*"|\\\\)*"|'(?:[^'\\]|\\(?:\\\\)*'|\\\\)*'|`(?:[^`\\]|\\(?:\\\\)*`|\\\\)*`)/g;
$.terminal.new_formatter([new RegExp(commands.join('|'), 'g'), '[[;white;]apropos]']);
$.terminal.new_formatter(function(input) {
return input
.replace(re_re, '[[;rebeccapurple;]$1]')
.replace(string_re, '[[;green;]$1]');
});
github('jcubic/jquery.terminal');
/*
$.terminal.defaults.allowedAttributes.push('style');
term.echo('[[;;;emoji smiley;;{"style": "width:2ch;display:inline-block;"}]☺️]y')
term.echo('😂')
*/
<header>
<nav>
<ul role="list">
<li>File</li>
<li>Edit</li>
<li>Search</li>
<li>Options</li>
<li>Help</li>
</ul>
</nav>
</header>
<main contenteditable><span class="cursor active"></span></main>
<footer>
MS-DOS Editor <span>
Click anywhere in the editor to begin
</span>
</footer>
$grey: #a8a8a8;
$blue: #0b00a8;
$teal: #00a7a8;
* {
box-sizing: border-box;
}
body {
min-height: 100vh;
display: grid;
grid-template-rows: min-content 1fr min-content;
font-family: "Inconsolata", monospace;
font-weight: bold;
letter-spacing: 0.03em;
font-size: 1.25rem;
line-height: 1;
}
nav {
background-color: $grey;
ul {
list-style: none;
margin: 0;
padding: 0.15rem 2rem;
display: flex;
li + li {
margin-left: 1rem;
}
li:last-child {
margin-left: auto;
}
}
}
main {
background-color: $blue;
color: $grey;
padding: 1.25rem 1rem;
box-shadow: inset 0 0 0 7px $blue, inset 0 0 0 9px currentcolor;
position: relative;
&:focus {
outline: none;
}
&:before {
content: "HELLOWORLD.BAT";
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
background-color: $grey;
color: $blue;
padding: 0 0.75rem;
}
span {
display: inline-flex;
}
}
footer {
background-color: $teal;
color: #fff;
padding: 0.05rem 1rem;
display: flex;
span {
margin-left: 2rem;
}
}
.cursor:after {
content: "";
display: inline-block;
width: 1ch;
height: 1.1em;
background-color: $blue;
margin: -0.03em 0 -0.03em -0.03em;
}
.cursor.active:after {
animation: cursor 400ms ease-in-out infinite;
}
@keyframes cursor {
0%,
100% {
background-color: $blue;
}
50% {
background-color: $grey;
}
}
// Described here:
// @link https://dev.to/5t3ph/helloworld-bat-vanillajs-plain-text-editor-25c7
const main = document.querySelector("main");
const hwArray = `HELLO WORLD`.split("");
const msgArray = `You may type your own content here.`.split("");
const typeSpeed = 130;
const hwDuration = typeSpeed * hwArray.length;
const msgDuration = typeSpeed * msgArray.length;
const msgDelay = hwDuration + 300;
const newLineDelay = hwDuration + msgDuration + 300;
// Type scripted messages
const type = (msgArray, target) => {
msgArray.map((l, i) => {
const letter = document.createTextNode(l);
const delay = typeSpeed * i;
setTimeout(() => {
main.querySelector(target).appendChild(letter);
}, delay);
});
};
// Clear cursor animation from previous line
// Only works for new lines, doesn't work if you backspace to previous line
const clearCursor = () => {
document.querySelector(".cursor.active").classList.remove("active");
};
// Create new line
const newLine = () => {
const line = document.createElement("DIV");
line.innerHTML = '<span class="cursor active"></span>';
main.appendChild(line);
clearCursor();
};
// Type initial greeting
setTimeout(() => {
type(hwArray, "span");
}, 1000);
// Type instructions
setTimeout(() => {
newLine();
type(msgArray, "div span");
}, msgDelay + 1000);
// Type new line for user content
setTimeout(() => {
newLine();
}, newLineDelay + 1000);
// If new line, drop "active" class
// from first active cursor to remove animation
main.addEventListener("keydown", (e) => {
const key = e.keyCode;
if (key === 13) {
setTimeout(() => {
clearCursor();
}, 10);
}
});
<header>
<nav>
<ul role="list">
<li>File</li>
<li>Edit</li>
<li>Search</li>
<li>Options</li>
<li>Help</li>
</ul>
</nav>
</header>
<main contenteditable><span class="cursor active"></span></main>
<footer>
MS-DOS Editor <span>
Click anywhere in the editor to begin
</span>
</footer>
$grey: #a8a8a8;
$blue: #0b00a8;
$teal: #00a7a8;
* {
box-sizing: border-box;
}
body {
min-height: 100vh;
display: grid;
grid-template-rows: min-content 1fr min-content;
font-family: "Inconsolata", monospace;
font-weight: bold;
letter-spacing: 0.03em;
font-size: 1.25rem;
line-height: 1;
}
nav {
background-color: $grey;
ul {
list-style: none;
margin: 0;
padding: 0.15rem 2rem;
display: flex;
li + li {
margin-left: 1rem;
}
li:last-child {
margin-left: auto;
}
}
}
main {
background-color: $blue;
color: $grey;
padding: 1.25rem 1rem;
box-shadow: inset 0 0 0 7px $blue, inset 0 0 0 9px currentcolor;
position: relative;
&:focus {
outline: none;
}
&:before {
content: "HELLOWORLD.BAT";
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
background-color: $grey;
color: $blue;
padding: 0 0.75rem;
}
span {
display: inline-flex;
}
}
footer {
background-color: $teal;
color: #fff;
padding: 0.05rem 1rem;
display: flex;
span {
margin-left: 2rem;
}
}
.cursor:after {
content: "";
display: inline-block;
width: 1ch;
height: 1.1em;
background-color: $blue;
margin: -0.03em 0 -0.03em -0.03em;
}
.cursor.active:after {
animation: cursor 400ms ease-in-out infinite;
}
@keyframes cursor {
0%,
100% {
background-color: $blue;
}
50% {
background-color: $grey;
}
}
// Described here:
// @link https://dev.to/5t3ph/helloworld-bat-vanillajs-plain-text-editor-25c7
const main = document.querySelector("main");
const hwArray = `HELLO WORLD`.split("");
const msgArray = `You may type your own content here.`.split("");
const typeSpeed = 130;
const hwDuration = typeSpeed * hwArray.length;
const msgDuration = typeSpeed * msgArray.length;
const msgDelay = hwDuration + 300;
const newLineDelay = hwDuration + msgDuration + 300;
// Type scripted messages
const type = (msgArray, target) => {
msgArray.map((l, i) => {
const letter = document.createTextNode(l);
const delay = typeSpeed * i;
setTimeout(() => {
main.querySelector(target).appendChild(letter);
}, delay);
});
};
// Clear cursor animation from previous line
// Only works for new lines, doesn't work if you backspace to previous line
const clearCursor = () => {
document.querySelector(".cursor.active").classList.remove("active");
};
// Create new line
const newLine = () => {
const line = document.createElement("DIV");
line.innerHTML = '<span class="cursor active"></span>';
main.appendChild(line);
clearCursor();
};
// Type initial greeting
setTimeout(() => {
type(hwArray, "span");
}, 1000);
// Type instructions
setTimeout(() => {
newLine();
type(msgArray, "div span");
}, msgDelay + 1000);
// Type new line for user content
setTimeout(() => {
newLine();
}, newLineDelay + 1000);
// If new line, drop "active" class
// from first active cursor to remove animation
main.addEventListener("keydown", (e) => {
const key = e.keyCode;
if (key === 13) {
setTimeout(() => {
clearCursor();
}, 10);
}
});
<div id="termynal" data-termynal data-termynal data-ty-typeDelay="40" data-ty-lineDelay="700">
<span data-ty="input">pip install spacy</span>
<span data-ty="progress"></span>
<span data-ty>Successfully installed spacy</span>
<span data-ty></span>
<span data-ty="input">python -m spacy download en</span>
<span data-ty="progress"></span>
<span data-ty>Installed model 'en'</span>
<span data-ty></span>
<span data-ty="input">python</span>
<span data-ty="input" data-ty-prompt=">>>">import spacy</span>
<span data-ty="input" data-ty-prompt=">>>">nlp = spacy.load('en')</span>
<span data-ty="input" data-ty-prompt=">>>">doc = nlp(u'Hello world')</span>
<span data-ty="input" data-ty-prompt=">>>">print([(w.text, w.pos_) for w in doc])</span>
<span data-ty>[('Hello', 'INTJ'), ('world', 'NOUN')]</span>
</div>
body {
--color-bg: #ddd;
--color-text: #1a1e24;
--color-text-subtle: #D76D77;
padding: 0; margin: 0;
background: linear-gradient(to right, #3a1c71, #d76d77, #ffaf7b);
width: 100%;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/**
* termynal.js
*
* @author Ines Montani <ines@ines.io>
* @version 0.0.1
* @license MIT
*/
:root {
--color-bg: #252a33;
--color-text: #eee;
--color-text-subtle: #a2a2a2;
}
[data-termynal] {
width: 750px;
max-width: 100%;
background: var(--color-bg);
color: var(--color-text);
font-size: 18px;
font-family: 'Fira Mono', Consolas, Menlo, Monaco, 'Courier New', Courier, monospace;
border-radius: 4px;
padding: 75px 45px 35px;
position: relative;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
[data-termynal]:before {
content: '';
position: absolute;
top: 15px;
left: 15px;
display: inline-block;
width: 15px;
height: 15px;
border-radius: 50%;
/* A little hack to display the window buttons in one pseudo element. */
background: #d9515d;
-webkit-box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930;
box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930;
}
[data-ty] {
display: block;
line-height: 2;
}
[data-ty]:before {
/* Set up defaults and ensure empty lines are displayed. */
content: '';
display: inline-block;
vertical-align: middle;
}
[data-ty="input"]:before,
[data-ty-prompt]:before {
margin-right: 0.75em;
color: var(--color-text-subtle);
}
[data-ty="input"]:before {
content: '$';
}
[data-ty][data-ty-prompt]:before {
content: attr(data-ty-prompt);
}
[data-ty-cursor]:after {
content: attr(data-ty-cursor);
font-family: monospace;
margin-left: 0.5em;
-webkit-animation: blink 1s infinite;
animation: blink 1s infinite;
}
/* Cursor animation */
@-webkit-keyframes blink {
50% {
opacity: 0;
}
}
@keyframes blink {
50% {
opacity: 0;
}
}
// https://github.com/ines/termynal
var termynal = new Termynal('#termynal');<div class="noise"></div>
<div class="overlay"></div>
<div class="terminal">
<h1>Error <span class="errorcode">404</span></h1>
<p class="output">The page you are looking for might have been removed, had its name changed or is temporarily unavailable.</p>
<p class="output">Please try to <a href="#1">go back</a> or <a href="#2">return to the homepage</a>.</p>
<p class="output"> Here’s a conceptual-mathematical framework and code sketch to model telomere dynamics using analogies from non-computability, self-reference (Gödelian loops), and undecidable processes. This is speculative but aligns with theoretical biology and formal systems.
________________________________________
1. Telomeres as Non-Computable Functions
Mathematical Framework:
Telomere shortening can be modeled as a recursive function that approaches a "halting state" (senescence or apoptosis). However, if telomerase (the enzyme that extends telomeres) acts as an oracle for an otherwise non-computable process, the system evades the "halting problem" of biological decay.
Define telomere length L(t)L(t) at time tt as:
L(t+1)=f(L(t))−Δ+ϵ(t),L(t+1)=f(L(t))−Δ+ϵ(t),
where:
• f(L(t))f(L(t)): Repair function (e.g., telomerase activity).
• ΔΔ: Fixed shortening per division (non-computable if ff depends on an undecidable halting condition).
• ϵ(t)ϵ(t): Stochastic noise (environmental factors).
If f(L(t))f(L(t)) is a non-computable function (e.g., requires solving the Halting Problem for cellular replication), telomere dynamics become formally undecidable:
If ∃ t where L(t)≤Lcrit, then HALT(L(t)) is undecidable.If ∃twhere L(t)≤Lcrit, then HALT(L(t)) is undecidable.
Code Sketch (Python):
import numpy as np
def telomere_dynamics(L, t_max, delta, epsilon):
# Non-computable repair function (oracle-like)
def f(L_current):
# Assume f(L) requires solving an undecidable problem
# For analogy, simulate as random repair
return L_current + np.random.choice([0, 1]) # Stochastic repair
history = []
for t in range(t_max):
L = f(L) - delta + np.random.normal(0, epsilon)
history.append(L)
if L <= 0:
break # Senescence (halting state)
return history
# Simulate non-computable telomere attrition
L_initial = 100
history = telomere_dynamics(L_initial, t_max=50, delta=2, epsilon=0.5)
________________________________________
2. Gödelian Loops in Telomere Maintenance
Mathematical Framework:
Borrowing from Gödel’s incompleteness, define a self-referential maintenance system where telomerase activation is contingent on a proposition that cannot be proven within the system itself.
Let TT be a formal system encoding telomere biology. A Gödelian proposition GG states:
G(T):"This system T cannot prove that telomerase will halt aging."G(T):"This system T cannot prove that telomerase will halt aging."
If TT is consistent, G(T)G(T) is true but unprovable in TT, creating a "loop" where telomerase activity is neither fully determined nor ruled out.
Dynamical System Model:
Model telomere length L(t)L(t) with a feedback term that depends on its own consistency:
dLdt=−αL+β⋅H(G(T)),dtdL=−αL+β⋅H(G(T)),
where H(G(T))H(G(T)) is 1 if G(T)G(T) is true (telomerase active) and 0 otherwise. Since G(T)G(T) is unprovable, H(G(T))H(G(T)) becomes a paradoxical term, leading to unpredictable dynamics.
Code Sketch (Symbolic Logic):
class GödelianTelomereSystem:
def __init__(self, L_initial):
self.L = L_initial
self.consistent = True # System assumes consistency
def gödel_proposition(self):
# This proposition cannot be proven within the system
return "This system cannot prove telomerase halts aging."
def update(self, alpha, beta):
try:
H = 1 if self.gödel_proposition() else 0 # Paradoxical term
except ParadoxError: # Catch self-reference
H = np.random.choice([0, 1]) # Randomize repair
self.L = -alpha * self.L + beta * H
return self.L
# Simulate the loop
system = GödelianTelomereSystem(L_initial=100)
for _ in range(50):
L = system.update(alpha=0.1, beta=10)
if L <= 0:
print("System halted (senescence).")
break
________________________________________
3. Hybrid Model: Undecidable Attrition
Combine both frameworks:
L(t+1)=L(t)−Δ+ϵ(t)⏟Stochastic+γ⋅Chaitin(Ω)⏟Non-computable,L(t+1)=L(t)−Δ+Stochasticϵ(t)+Non-computableγ⋅Chaitin(Ω),
where Chaitin(Ω)Chaitin(Ω) is a constant from algorithmic information theory (the halting probability), representing irreducible randomness.
________________________________________
Summary & Implications
• Non-computability: Telomere attrition/repair may depend on undecidable halting conditions, evading classical predictive models.
• Gödelian Loops: Self-referential logic in telomerase regulation creates a paradox, akin to biological "incompleteness."
• Code: Stochasticity and self-reference in simulations mirror the unpredictability of aging.
This framework is metaphorical but provides a bridge between theoretical biology, computability theory, and self-referential systems. For practical use, empirical calibration would replace the speculative terms (e.g., Chaitin(Ω)Chaitin(Ω)) with measurable biological parameters.
</div></p>
@import 'https://fonts.googleapis.com/css?family=Inconsolata';
html {
min-height: 100%;
}
body {
box-sizing: border-box;
height: 100%;
background-color: #000000;
background-image: radial-gradient(#11581E, #041607), url("https://media.giphy.com/media/oEI9uBYSzLpBK/giphy.gif");
background-repeat: no-repeat;
background-size: cover;
font-family: 'Inconsolata', Helvetica, sans-serif;
font-size: 1.5rem;
color: rgba(128, 255, 128, 0.8);
text-shadow:
0 0 1ex rgba(51, 255, 51, 1),
0 0 2px rgba(255, 255, 255, 0.8);
}
.noise {
pointer-events: none;
position: absolute;
width: 100%;
height: 100%;
background-image: url("https://media.giphy.com/media/oEI9uBYSzLpBK/giphy.gif");
background-repeat: no-repeat;
background-size: cover;
z-index: -1;
opacity: .02;
}
.overlay {
pointer-events: none;
position: absolute;
width: 100%;
height: 100%;
background:
repeating-linear-gradient(
180deg,
rgba(0, 0, 0, 0) 0,
rgba(0, 0, 0, 0.3) 50%,
rgba(0, 0, 0, 0) 100%);
background-size: auto 4px;
z-index: 1;
}
.overlay::before {
content: "";
pointer-events: none;
position: absolute;
display: block;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
background-image: linear-gradient(
0deg,
transparent 0%,
rgba(32, 128, 32, 0.2) 2%,
rgba(32, 128, 32, 0.8) 3%,
rgba(32, 128, 32, 0.2) 3%,
transparent 100%);
background-repeat: no-repeat;
animation: scan 7.5s linear 0s infinite;
}
@keyframes scan {
0% { background-position: 0 -100vh; }
35%, 100% { background-position: 0 100vh; }
}
.terminal {
box-sizing: inherit;
position: absolute;
height: 100%;
width: 1000px;
max-width: 100%;
padding: 4rem;
text-transform: uppercase;
}
.output {
color: rgba(128, 255, 128, 0.8);
text-shadow:
0 0 1px rgba(51, 255, 51, 0.4),
0 0 2px rgba(255, 255, 255, 0.8);
}
.output::before {
content: "> ";
}
/*
.input {
color: rgba(192, 255, 192, 0.8);
text-shadow:
0 0 1px rgba(51, 255, 51, 0.4),
0 0 2px rgba(255, 255, 255, 0.8);
}
.input::before {
content: "$ ";
}
*/
a {
color: #fff;
text-decoration: none;
}
a::before {
content: "[";
}
a::after {
content: "]";
}
.errorcode {
color: white;
}