🎮ArcadeLab

NIGHT SHIFT — Five Nights

by LunarPanda23
3035 lines49.7 KB
▶ Play
<!DOCTYPE html>
<html lang="he" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
<title>NIGHT SHIFT — Five Nights</title>

<style>
*{
    box-sizing:border-box;
    -webkit-tap-highlight-color:transparent;
    user-select:none;
}

html,body{
    margin:0;
    width:100%;
    height:100%;
    background:#050708;
    color:#d9e3e3;
    font-family:Arial,Helvetica,sans-serif;
    overflow:hidden;
}

button{
    font-family:inherit;
    cursor:pointer;
}

#game{
    position:relative;
    width:100vw;
    height:100vh;
    min-height:520px;
    overflow:hidden;
    background:#080d0e;
}

/* =========================
   INTRO
========================= */

.screen{
    position:absolute;
    inset:0;
    display:flex;
    align-items:center;
    justify-content:center;
    background:
        radial-gradient(circle at 50% 45%,#182426 0%,#080c0d 45%,#020303 100%);
}

.panel{
    width:min(560px,90vw);
    border:2px solid #536365;
    background:rgba(8,13,14,.96);
    padding:34px;
    box-shadow:0 0 60px rgba(0,0,0,.8);
}

.logo{
    font-size:clamp(30px,7vw,64px);
    letter-spacing:7px;
    font-weight:900;
    text-align:center;
    color:#e5eeee;
}

.subtitle{
    text-align:center;
    color:#829294;
    letter-spacing:4px;
    margin:10px 0 35px;
}

.menuBtn{
    width:100%;
    padding:17px;
    margin:8px 0;
    background:#111a1b;
    border:1px solid #657577;
    color:#dbe5e5;
    font-size:17px;
    letter-spacing:2px;
}

.menuBtn:hover{
    background:#1c292b;
}

.small{
    text-align:center;
    font-size:11px;
    color:#647375;
    margin-top:25px;
    line-height:1.7;
}

/* =========================
   HUD
========================= */

#hud{
    position:absolute;
    top:0;
    left:0;
    right:0;
    height:92px;
    z-index:50;
    border-bottom:3px solid #3e4d4f;
    background:
        linear-gradient(90deg,#090f10,#101718,#090f10);
    display:flex;
    align-items:center;
    justify-content:space-between;
    padding:12px 24px;
}

#clock{
    font-size:clamp(30px,5vw,54px);
    font-weight:bold;
}

.hudSmall{
    color:#91a4a4;
    font-size:12px;
    letter-spacing:3px;
}

#powerBox{
    width:180px;
    text-align:left;
}

#power{
    font-size:27px;
    font-weight:bold;
    text-align:right;
}

.powerBar{
    height:7px;
    border:1px solid #78898a;
    margin-top:5px;
}

#powerFill{
    height:100%;
    width:100%;
    background:#b9c9bd;
    transition:.3s;
}

/* =========================
   OFFICE
========================= */

#office{
    position:absolute;
    top:92px;
    bottom:0;
    left:0;
    right:0;
    overflow:hidden;
    background:
        radial-gradient(ellipse at 50% 45%,#202b2d 0%,#121a1b 42%,#050809 100%);
}

#ceiling{
    position:absolute;
    top:0;
    left:5%;
    right:5%;
    height:33%;
    background:
        linear-gradient(150deg,#0a1011,#172022 45%,#080c0d);
    clip-path:polygon(10% 0,90% 0,72% 100%,28% 100%);
    opacity:.85;
}

#backWall{
    position:absolute;
    top:30%;
    left:17%;
    right:17%;
    bottom:22%;
    background:
        repeating-linear-gradient(
            90deg,
            rgba(255,255,255,.025) 0,
            rgba(255,255,255,.025) 2px,
            transparent 2px,
            transparent 70px
        ),
        linear-gradient(#182123,#11191a);
    border-left:2px solid #273436;
    border-right:2px solid #273436;
}

.floor{
    position:absolute;
    left:0;
    right:0;
    bottom:0;
    height:28%;
    background:
        repeating-linear-gradient(
            90deg,
            transparent 0,
            transparent 80px,
            rgba(150,160,160,.09) 81px,
            transparent 83px
        ),
        repeating-linear-gradient(
            0deg,
            transparent 0,
            transparent 65px,
            rgba(150,160,160,.08) 66px,
            transparent 68px
        ),
        linear-gradient(#0d1516,#050708);
    transform:perspective(450px) rotateX(5deg);
    transform-origin:bottom;
}

/* =========================
   DOORS
========================= */

.doorArea{
    position:absolute;
    top:35%;
    width:19%;
    height:51%;
    min-width:130px;
}

#leftArea{
    left:1.5%;
}

#rightArea{
    right:1.5%;
}

.doorFrame{
    position:absolute;
    inset:0;
    border:7px solid #59686a;
    background:#070b0c;
    box-shadow:
        inset 0 0 30px #000,
        0 0 20px rgba(0,0,0,.7);
}

.door{
    position:absolute;
    inset:8px;
    background:
        repeating-linear-gradient(
            90deg,
            #12191a 0,
            #12191a 13px,
            #1d2728 14px,
            #0d1314 18px
        );
    transition:.18s;
}

.door.closed{
    box-shadow:
        inset 0 0 35px #000,
        0 0 15px rgba(180,40,40,.15);
}

.door.closed:after{
    content:"";
    position:absolute;
    inset:0;
    background:
        repeating-linear-gradient(
            90deg,
            rgba(255,255,255,.025) 0,
            rgba(255,255,255,.025) 2px,
            transparent 2px,
            transparent 18px
        );
}

.door.open{
    transform:translateY(-82%);
    opacity:.25;
}

.doorLabel{
    position:absolute;
    top:-30px;
    width:100%;
    text-align:center;
    letter-spacing:3px;
    color:#8b9b9c;
    font-size:12px;
}

/* WINDOWS */

.window{
    position:absolute;
    top:12%;
    width:45%;
    height:28%;
    border:5px solid #647476;
    background:#020405;
    overflow:hidden;
    z-index:8;
}

#leftWindow{
    right:-54%;
}

#rightWindow{
    left:-54%;
}

.windowGlass{
    position:absolute;
    inset:5px;
    background:
        radial-gradient(ellipse at 50% 50%,rgba(70,85,87,.35),transparent 65%),
        #060b0c;
    overflow:hidden;
}

.windowLight{
    position:absolute;
    inset:0;
    background:
        radial-gradient(circle at center,#d8e1ce 0%,rgba(180,200,180,.35) 35%,rgba(100,130,110,.12) 65%,transparent 100%);
    opacity:0;
    transition:.1s;
}

.window.on .windowLight{
    opacity:1;
}

.windowText{
    position:absolute;
    bottom:3px;
    left:0;
    right:0;
    text-align:center;
    font-size:9px;
    color:#718080;
    letter-spacing:2px;
}

/* monster silhouettes in windows */

.windowMonster{
    position:absolute;
    left:50%;
    bottom:-8px;
    transform:translateX(-50%) scale(.9);
    width:60%;
    height:85%;
    opacity:0;
    transition:.15s;
}

.window.on .windowMonster.visible{
    opacity:1;
}

.monsterBody{
    position:absolute;
    left:20%;
    right:20%;
    bottom:0;
    height:65%;
    border-radius:40% 40% 8% 8%;
    background:#263234;
}

.monsterHead{
    position:absolute;
    width:68%;
    height:45%;
    left:16%;
    top:2%;
    border-radius:48% 48% 42% 42%;
    background:#354345;
    box-shadow:inset 0 -8px 0 rgba(0,0,0,.3);
}

.eye{
    position:absolute;
    top:38%;
    width:12px;
    height:12px;
    border-radius:50%;
    background:#d8e4cf;
    box-shadow:0 0 14px #dcead5;
}

.eye.left{left:24%}
.eye.right{right:24%}

.mouth{
    position:absolute;
    left:20%;
    right:20%;
    bottom:13%;
    height:14%;
    background:#060809;
    border-radius:50%;
}

.monsterA .monsterHead{
    border-radius:55% 45% 35% 50%;
    background:#34474a;
}
.monsterA .monsterBody{
    background:#22383a;
}

.monsterB .monsterHead{
    border-radius:35% 55% 48% 45%;
    background:#443a35;
}
.monsterB .monsterBody{
    background:#332923;
}

.monsterC .monsterHead{
    border-radius:48% 48% 55% 35%;
    background:#3a3848;
}
.monsterC .monsterBody{
    background:#292839;
}

.monsterD .monsterHead{
    border-radius:42% 58% 40% 42%;
    background:#3e343b;
}
.monsterD .monsterBody{
    background:#30252c;
}

.ear{
    position:absolute;
    top:-18%;
    width:28%;
    height:35%;
    background:inherit;
    clip-path:polygon(50% 0,100% 100%,0 100%);
}

.ear.left{left:0}
.ear.right{right:0}

/* =========================
   PHYSICAL CONTROLS
========================= */

.control{
    position:absolute;
    z-index:20;
    width:125px;
    background:#0a1112;
    border:2px solid #526264;
    padding:8px;
    box-shadow:0 8px 20px #000;
}

#leftControl{
    left:calc(1.5% + 24px);
    top:calc(35% + 55%);
}

#rightControl{
    right:calc(1.5% + 24px);
    top:calc(35% + 55%);
}

.controlTitle{
    text-align:center;
    font-size:10px;
    color:#8b999a;
    letter-spacing:2px;
    margin-bottom:6px;
}

.ctrlBtn{
    width:100%;
    padding:12px 4px;
    margin:4px 0;
    border:2px solid #59696a;
    background:#111a1b;
    color:#dbe5e5;
    font-weight:bold;
    font-size:12px;
}

.ctrlBtn.active{
    background:#702c31;
    border-color:#d05a5f;
}

.ctrlBtn.lightActive{
    background:#6e7049;
    border-color:#d7d89b;
    color:#fff;
}

/* =========================
   DESK
========================= */

#desk{
    position:absolute;
    bottom:8%;
    left:50%;
    transform:translateX(-50%);
    width:240px;
    height:100px;
    background:#101819;
    border:3px solid #38484a;
    z-index:10;
    box-shadow:0 10px 30px #000;
}

#terminal{
    position:absolute;
    width:90px;
    height:65px;
    left:50%;
    top:-62px;
    transform:translateX(-50%);
    background:#0b1112;
    border:3px solid #445355;
    display:flex;
    align-items:center;
    justify-content:center;
    font-size:10px;
    color:#93a1a2;
    letter-spacing:2px;
}

#monitorButton{
    position:absolute;
    bottom:-68px;
    left:50%;
    transform:translateX(-50%);
    width:220px;
    height:55px;
    border:3px solid #667778;
    background:#10191a;
    color:#dce7e5;
    font-size:16px;
    font-weight:bold;
    letter-spacing:2px;
}

/* =========================
   CAMERA
========================= */

#camera{
    position:absolute;
    inset:0;
    z-index:40;
    display:none;
    background:#070b0c;
}

#camera.active{
    display:block;
}

.camView{
    position:absolute;
    top:0;
    left:0;
    right:0;
    bottom:130px;
    overflow:hidden;
    background:
        radial-gradient(ellipse at center,#1b2526,#0b1011 60%,#030405);
}

.camRoom{
    position:absolute;
    top:0;
    bottom:0;
    width:150%;
    left:-25%;
    transition:left .25s ease;
}

.camRoom.wall{
    background:
        repeating-linear-gradient(
            90deg,
            rgba(255,255,255,.045) 0,
            rgba(255,255,255,.045) 2px,
            transparent 2px,
            transparent 80px
        ),
        linear-gradient(90deg,#11191a,#252f30 50%,#0e1516);
}

.camRoom.storage{
    background:
        linear-gradient(90deg,#101616,#252d2d 45%,#111718);
}

.camRoom.dining{
    background:
        radial-gradient(ellipse at 50% 35%,#39423c,#151c1a 65%,#080b0b);
}

.camRoom.stage{
    background:
        linear-gradient(90deg,#090a0d,#2b1e24 48%,#090a0d);
}

.camRoom.back{
    background:
        linear-gradient(90deg,#111,#202426,#090b0c);
}

.roomCeiling{
    position:absolute;
    top:0;
    left:0;
    right:0;
    height:25%;
    background:linear-gradient(#06090a,#202728);
}

.roomFloor{
    position:absolute;
    bottom:0;
    left:0;
    right:0;
    height:35%;
    background:
        repeating-linear-gradient(
            90deg,
            transparent 0,
            transparent 90px,
            rgba(255,255,255,.07) 91px,
            transparent 93px
        ),
        linear-gradient(#151d1e,#080b0c);
    transform:perspective(500px) rotateX(5deg);
}

.camObject{
    position:absolute;
    border:3px solid #4c5c5e;
    background:#11191a;
    box-shadow:0 8px 20px #000;
}

.camLabel{
    position:absolute;
    top:18px;
    left:25px;
    padding:8px 14px;
    border:2px solid #667779;
    background:rgba(0,0,0,.65);
    color:#b6c3c3;
    letter-spacing:3px;
    font-size:12px;
    z-index:5;
}

.static{
    position:absolute;
    inset:0;
    pointer-events:none;
    opacity:.10;
    background-image:
        repeating-linear-gradient(
            0deg,
            rgba(255,255,255,.3) 0,
            rgba(255,255,255,.3) 1px,
            transparent 1px,
            transparent 4px
        );
    animation:static .08s infinite;
}

@keyframes static{
    0%{transform:translateY(0)}
    50%{transform:translateY(3px)}
    100%{transform:translateY(-2px)}
}

/* camera monster */

.camMonster{
    position:absolute;
    width:140px;
    height:260px;
    bottom:23%;
    left:50%;
    transform:translateX(-50%);
    filter:drop-shadow(0 12px 18px #000);
    transition:.4s;
}

.camMonster.hidden{
    display:none;
}

.camMonster .body{
    position:absolute;
    bottom:0;
    left:20%;
    width:60%;
    height:65%;
    border-radius:45% 45% 10% 10%;
    background:#293638;
}

.camMonster .head{
    position:absolute;
    top:0;
    left:15%;
    width:70%;
    height:42%;
    border-radius:48%;
    background:#39484a;
}

.camMonster .eye{
    position:absolute;
    width:13px;
    height:13px;
    background:#e4f0d9;
    border-radius:50%;
    top:42%;
    box-shadow:0 0 18px #fff;
}

.camMonster .eye.left{left:23%}
.camMonster .eye.right{right:23%}

.camMonster .mouth{
    position:absolute;
    bottom:12%;
    left:20%;
    right:20%;
    height:17%;
    background:#040606;
    border-radius:50%;
}

/* different camera appearances */

.camA .head{
    border-radius:55% 45% 35% 55%;
    background:#394a4b;
}
.camA .body{background:#263b3d}

.camB .head{
    border-radius:35% 55% 50% 40%;
    background:#514239;
}
.camB .body{background:#392d26}

.camC .head{
    border-radius:48% 48% 55% 35%;
    background:#423e52;
}
.camC .body{background:#2c2939}

.camD .head{
    border-radius:42% 58% 40% 42%;
    background:#493943;
}
.camD .body{background:#30252e}

/* =========================
   CAMERA BOTTOM BAR
========================= */

#camBottom{
    position:absolute;
    left:0;
    right:0;
    bottom:0;
    height:130px;
    border-top:3px solid #546567;
    background:#090f10;
    display:flex;
    align-items:center;
    justify-content:center;
    gap:15px;
    padding:12px;
}

.camArrow{
    width:65px;
    height:70px;
    background:#111b1c;
    border:2px solid #607173;
    color:#dce6e5;
    font-size:32px;
}

.camArrow:active{
    background:#283637;
}

#camName{
    width:210px;
    text-align:center;
    font-size:15px;
    font-weight:bold;
    letter-spacing:3px;
}

#closeCam{
    position:absolute;
    right:15px;
    top:-55px;
    width:120px;
    height:43px;
    background:#1a2021;
    border:2px solid #657577;
    color:#e3eaea;
}

/* =========================
   MAP
========================= */

#map{
    position:absolute;
    right:25px;
    top:80px;
    width:240px;
    min-height:230px;
    z-index:8;
    border:2px solid #5a6b6d;
    background:rgba(5,9,10,.9);
    padding:12px;
}

.mapTitle{
    text-align:center;
    font-size:12px;
    letter-spacing:3px;
    margin-bottom:10px;
}

.mapGrid{
    display:grid;
    grid-template-columns:1fr 1fr;
    gap:7px;
}

.mapBtn{
    min-height:52px;
    background:#11191a;
    border:2px solid #536466;
    color:#ccd8d7;
    font-size:10px;
    line-height:1.2;
}

.mapBtn.current{
    border-color:#d8dfdf;
    box-shadow:0 0 8px rgba(210,220,220,.35);
}

.mapBtn.danger{
    border-color:#9e4248;
    color:#f0a1a3;
}

#playerMarker{
    margin-top:10px;
    text-align:center;
    font-size:10px;
    color:#879697;
}

/* =========================
   JUMPSCARE
========================= */

#jumpscare{
    position:absolute;
    inset:0;
    z-index:200;
    display:none;
    background:#020202;
    align-items:center;
    justify-content:center;
    overflow:hidden;
}

#jumpscare.show{
    display:flex;
    animation:shake .07s infinite;
}

@keyframes shake{
    0%{transform:translate(0)}
    25%{transform:translate(8px,-5px)}
    50%{transform:translate(-7px,6px)}
    75%{transform:translate(5px,4px)}
    100%{transform:translate(-4px,-6px)}
}

.scareFace{
    position:relative;
    width:min(500px,90vw);
    height:min(500px,75vh);
    border-radius:45%;
    background:
        radial-gradient(circle at 35% 40%,#eee 0 3%,transparent 4%),
        radial-gradient(circle at 65% 40%,#eee 0 3%,transparent 4%),
        radial-gradient(ellipse at center,#465456,#171c1d 65%,#050606);
    box-shadow:0 0 100px #000;
    transform:scale(1.15);
}

.scareFace:before,
.scareFace:after{
    content:"";
    position:absolute;
    top:28%;
    width:18%;
    height:18%;
    border-radius:50%;
    background:#e9f4df;
    box-shadow:0 0 35px #fff;
}

.scareFace:before{left:25%}
.scareFace:after{right:25%}

.scareMouth{
    position:absolute;
    left:20%;
    right:20%;
    bottom:18%;
    height:27%;
    background:#020202;
    border-radius:50%;
    border:5px solid #252b2c;
}

.scareText{
    position:absolute;
    bottom:25px;
    left:0;
    right:0;
    text-align:center;
    font-size:16px;
    letter-spacing:5px;
    color:#fff;
}

/* =========================
   END SCREEN
========================= */

#endScreen{
    display:none;
    z-index:300;
}

#endScreen.show{
    display:flex;
}

.endTitle{
    font-size:42px;
    text-align:center;
    letter-spacing:5px;
    margin-bottom:15px;
}

.endText{
    text-align:center;
    color:#9eacad;
    line-height:1.7;
}

.hidden{
    display:none!important;
}

/* =========================
   RESPONSIVE
========================= */

@media(max-width:700px){

    #hud{
        height:75px;
        padding:8px 12px;
    }

    #office{
        top:75px;
    }

    .hudSmall{
        font-size:8px;
        letter-spacing:2px;
    }

    #powerBox{
        width:110px;
    }

    #power{
        font-size:20px;
    }

    .doorArea{
        top:35%;
        width:24%;
        min-width:92px;
        height:43%;
    }

    #leftArea{left:1%}
    #rightArea{right:1%}

    .control{
        width:105px;
        padding:5px;
    }

    #leftControl{
        left:calc(1% + 5px);
        top:calc(35% + 44%);
    }

    #rightControl{
        right:calc(1% + 5px);
        top:calc(35% + 44%);
    }

    .ctrlBtn{
        padding:9px 2px;
        font-size:10px;
    }

    #desk{
        width:170px;
        height:75px;
        bottom:11%;
    }

    #terminal{
        width:65px;
        height:48px;
        top:-48px;
    }

    #monitorButton{
        width:175px;
        height:47px;
        bottom:-55px;
        font-size:12px;
    }

    #map{
        width:180px;
        right:8px;
        top:60px;
        padding:8px;
    }

    .mapBtn{
        min-height:45px;
        font-size:8px;
    }

    #camBottom{
        height:105px;
    }

    .camArrow{
        width:55px;
        height:55px;
        font-size:25px;
    }

    #camName{
        width:125px;
        font-size:11px;
    }

    #closeCam{
        top:-43px;
        width:100px;
        height:36px;
        font-size:10px;
    }
}
</style>
</head>

<body>

<div id="game">

<!-- =========================
     MENU
========================= -->

<div id="menu" class="screen">
    <div class="panel">

        <div class="logo">NIGHT SHIFT</div>
        <div class="subtitle">SECURITY TERMINAL</div>

        <button class="menuBtn" onclick="startNight(1)">
            START NIGHT 01
        </button>

        <button class="menuBtn" onclick="showNights()">
            SELECT NIGHT
        </button>

        <div id="nightSelect" class="hidden">

            <button class="menuBtn" onclick="startNight(1)">NIGHT 01</button>
            <button class="menuBtn" onclick="startNight(2)">NIGHT 02</button>
            <button class="menuBtn" onclick="startNight(3)">NIGHT 03</button>
            <button class="menuBtn" onclick="startNight(4)">NIGHT 04</button>
            <button class="menuBtn" onclick="startNight(5)">NIGHT 05</button>

        </div>

        <div class="small">
            ORIGINAL SURVIVAL HORROR EXPERIENCE<br>
            WATCH THE CAMERAS • MANAGE POWER • SURVIVE UNTIL 6 AM
        </div>

    </div>
</div>


<!-- =========================
     HUD
========================= -->

<div id="hud" class="hidden">

    <div>
        <div class="hudSmall">NIGHT SHIFT / SECURITY NETWORK</div>
        <div id="clock">12 AM</div>
        <div class="hudSmall">SYSTEM ONLINE</div>
    </div>

    <div id="powerBox">

        <div class="hudSmall">
            NIGHT <span id="nightNumber">01</span>
        </div>

        <div id="power">100%</div>

        <div class="powerBar">
            <div id="powerFill"></div>
        </div>

    </div>

</div>


<!-- =========================
     OFFICE
========================= -->

<div id="office" class="hidden">

    <div id="ceiling"></div>
    <div id="backWall"></div>
    <div class="floor"></div>


    <!-- LEFT DOOR -->

    <div id="leftArea" class="doorArea">

        <div class="doorLabel">WEST / LEFT</div>

        <div class="doorFrame">

            <div id="leftDoor" class="door open"></div>

            <div id="leftWindow" class="window">

                <div class="windowGlass">

                    <div class="windowLight"></div>

                    <div id="leftMonster" class="windowMonster monsterA">

                        <div class="monsterBody"></div>

                        <div class="monsterHead">

                            <div class="ear left"></div>
                            <div class="ear right"></div>

                            <div class="eye left"></div>
                            <div class="eye right"></div>

                            <div class="mouth"></div>

                        </div>

                    </div>

                    <div class="windowText">VISUAL CHECK</div>

                </div>

            </div>

        </div>

    </div>


    <!-- RIGHT DOOR -->

    <div id="rightArea" class="doorArea">

        <div class="doorLabel">EAST / RIGHT</div>

        <div class="doorFrame">

            <div id="rightDoor" class="door open"></div>

            <div id="rightWindow" class="window">

                <div class="windowGlass">

                    <div class="windowLight"></div>

                    <div id="rightMonster" class="windowMonster monsterB">

                        <div class="monsterBody"></div>

                        <div class="monsterHead">

                            <div class="ear left"></div>
                            <div class="ear right"></div>

                            <div class="eye left"></div>
                            <div class="eye right"></div>

                            <div class="mouth"></div>

                        </div>

                    </div>

                    <div class="windowText">VISUAL CHECK</div>

                </div>

            </div>

        </div>

    </div>


    <!-- LEFT PHYSICAL CONTROL -->

    <div id="leftControl" class="control">

        <div class="controlTitle">WEST CONTROL</div>

        <button id="leftDoorBtn"
                class="ctrlBtn"
                onclick="toggleDoor('left')">
            CLOSE DOOR
        </button>

        <button id="leftLightBtn"
                class="ctrlBtn"
                onclick="toggleLight('left')">
            LIGHT OFF
        </button>

    </div>


    <!-- RIGHT PHYSICAL CONTROL -->

    <div id="rightControl" class="control">

        <div class="controlTitle">EAST CONTROL</div>

        <button id="rightDoorBtn"
                class="ctrlBtn"
                onclick="toggleDoor('right')">
            CLOSE DOOR
        </button>

        <button id="rightLightBtn"
                class="ctrlBtn"
                onclick="toggleLight('right')">
            LIGHT OFF
        </button>

    </div>


    <!-- DESK -->

    <div id="desk">

        <div id="terminal">
            SECURITY<br>
            TERMINAL
        </div>

        <button id="monitorButton" onclick="openCamera()">
            OPEN CAMERA SYSTEM
        </button>

    </div>

</div>


<!-- =========================
     CAMERA SYSTEM
========================= -->

<div id="camera">

    <div class="camView">

        <div id="camRoom" class="camRoom wall">

            <div class="roomCeiling"></div>
            <div class="roomFloor"></div>

            <div id="roomObjects"></div>

            <div id="camMonster"
                 class="camMonster hidden">

                <div class="body"></div>

                <div class="head">

                    <div class="eye left"></div>
                    <div class="eye right"></div>

                    <div class="mouth"></div>

                </div>

            </div>

            <div id="camLabel" class="camLabel">
                CAM 01 / SHOWROOM
            </div>

            <div class="static"></div>

        </div>

        <!-- MAP -->

        <div id="map">

            <div class="mapTitle">
                FACILITY MAP
            </div>

            <div class="mapGrid">

                <button class="mapBtn current"
                        onclick="selectCam(1)">
                    CAM 01<br>SHOWROOM
                </button>

                <button class="mapBtn"
                        onclick="selectCam(2)">
                    CAM 02<br>STORAGE
                </button>

                <button class="mapBtn"
                        onclick="selectCam(3)">
                    CAM 03<br>WORKSHOP
                </button>

                <button class="mapBtn"
                        onclick="selectCam(4)">
                    CAM 04<br>DINING
                </button>

                <button class="mapBtn"
                        onclick="selectCam(5)">
                    CAM 05<br>WEST HALL
                </button>

                <button class="mapBtn"
                        onclick="selectCam(6)">
                    CAM 06<br>EAST HALL
                </button>

                <button class="mapBtn"
                        onclick="selectCam(7)">
                    CAM 07<br>BACK ROOM
                </button>

                <button class="mapBtn"
                        onclick="selectCam(8)">
                    CAM 08<br>STAGE
                </button>

                <button class="mapBtn"
                        onclick="selectCam(9)">
                    CAM 09<br>LOADING
                </button>

            </div>

            <div id="playerMarker">
                ● YOU — SECURITY OFFICE
            </div>

        </div>

    </div>


    <!-- CAMERA BAR -->

    <div id="camBottom">

        <button class="camArrow"
                onclick="moveCamera(-1)">
            ◀
        </button>

        <div id="camName">
            CAM 01 / SHOWROOM
        </div>

        <button class="camArrow"
                onclick="moveCamera(1)">
            ▶
        </button>

        <button id="closeCam"
                onclick="closeCamera()">
            CLOSE CAMERAS
        </button>

    </div>

</div>


<!-- =========================
     JUMPSCARE
========================= -->

<div id="jumpscare">

    <div class="scareFace">

        <div class="scareMouth"></div>

    </div>

    <div class="scareText">
        SIGNAL LOST
    </div>

</div>


<!-- =========================
     END
========================= -->

<div id="endScreen" class="screen">

    <div class="panel">

        <div id="endTitle" class="endTitle">
            6 AM
        </div>

        <div id="endText" class="endText">
            SHIFT COMPLETE
        </div>

        <button class="menuBtn"
                onclick="location.reload()">
            RETURN TO MENU
        </button>

    </div>

</div>

</div>


<script>

/* =========================================================
   NIGHT SHIFT
   ORIGINAL SINGLE-FILE HORROR GAME
   ========================================================= */


/* =========================
   GAME STATE
========================= */

const state = {

    running:false,

    night:1,

    hour:0,

    minute:0,

    power:100,

    cameraOpen:false,

    camera:1,

    cameraSide:0,

    leftDoor:false,

    rightDoor:false,

    leftLight:false,

    rightLight:false,

    gameOver:false,

    elapsed:0,

    lastTime:0

};


/* =========================
   CAMERA DATA
========================= */

const cameras = {

    1:{
        name:"CAM 01 / SHOWROOM",
        type:"showroom",
        monsterPositions:{
            1:{x:50,y:58},
            2:{x:67,y:57},
            3:{x:35,y:58},
            4:{x:80,y:57}
        }
    },

    2:{
        name:"CAM 02 / STORAGE",
        type:"storage",
        monsterPositions:{
            1:{x:34,y:57},
            2:{x:70,y:58},
            3:{x:48,y:60},
            4:{x:82,y:57}
        }
    },

    3:{
        name:"CAM 03 / WORKSHOP",
        type:"workshop",
        monsterPositions:{
            1:{x:58,y:59},
            2:{x:31,y:60},
            3:{x:76,y:59},
            4:{x:48,y:58}
        }
    },

    4:{
        name:"CAM 04 / DINING",
        type:"dining",
        monsterPositions:{
            1:{x:45,y:58},
            2:{x:75,y:59},
            3:{x:30,y:60},
            4:{x:61,y:58}
        }
    },

    5:{
        name:"CAM 05 / WEST HALL",
        type:"hall",
        monsterPositions:{
            1:{x:62,y:60},
            2:{x:40,y:58},
            3:{x:75,y:59},
            4:{x:50,y:60}
        }
    },

    6:{
        name:"CAM 06 / EAST HALL",
        type:"hall",
        monsterPositions:{
            1:{x:40,y:60},
            2:{x:64,y:58},
            3:{x:75,y:59},
            4:{x:50,y:59}
        }
    },

    7:{
        name:"CAM 07 / BACK ROOM",
        type:"back",
        monsterPositions:{
            1:{x:54,y:59},
            2:{x:72,y:59},
            3:{x:33,y:58},
            4:{x:62,y:60}
        }
    },

    8:{
        name:"CAM 08 / STAGE",
        type:"stage",
        monsterPositions:{
            1:{x:48,y:57},
            2:{x:64,y:58},
            3:{x:35,y:58},
            4:{x:78,y:58}
        }
    },

    9:{
        name:"CAM 09 / LOADING",
        type:"loading",
        monsterPositions:{
            1:{x:35,y:60},
            2:{x:67,y:60},
            3:{x:52,y:58},
            4:{x:80,y:59}
        }
    }

};


/* =========================
   MONSTERS
========================= */

const monsters = [

    {
        id:1,
        name:"MARA",
        style:"camA",

        path:[1,2,3,5,"LEFT"],

        position:0,

        aggression:[1,2,3,4,5],

        moveBase:21000,

        lastMove:0
    },

    {
        id:2,
        name:"BRICK",
        style:"camB",

        path:[8,4,6,7,"RIGHT"],

        position:0,

        aggression:[1,2,3,4,5],

        moveBase:26000,

        lastMove:0
    },

    {
        id:3,
        name:"VEX",
        style:"camC",

        path:[2,3,4,6,7,"RIGHT"],

        position:0,

        aggression:[2,3,4,5],

        moveBase:30000,

        lastMove:0
    },

    {
        id:4,
        name:"NULL",
        style:"camD",

        path:[7,9,5,"LEFT"],

        position:0,

        aggression:[3,4,5],

        moveBase:34000,

        lastMove:0
    }

];


/* =========================
   AUDIO ENGINE
========================= */

let audioCtx=null;

function initAudio(){

    if(!audioCtx){

        audioCtx =
            new (window.AudioContext ||
                 window.webkitAudioContext)();

    }

    if(audioCtx.state==="suspended"){
        audioCtx.resume();
    }

}


function tone(freq,duration,type="sine",volume=.04){

    try{

        initAudio();

        const osc=audioCtx.createOscillator();

        const gain=audioCtx.createGain();

        osc.type=type;

        osc.frequency.value=freq;

        gain.gain.setValueAtTime(volume,audioCtx.currentTime);

        gain.gain.exponentialRampToValueAtTime(
            .001,
            audioCtx.currentTime+duration
        );

        osc.connect(gain);

        gain.connect(audioCtx.destination);

        osc.start();

        osc.stop(audioCtx.currentTime+duration);

    }catch(e){}

}


function noise(duration=.15,volume=.04){

    try{

        initAudio();

        const buffer=audioCtx.createBuffer(
            1,
            audioCtx.sampleRate*duration,
            audioCtx.sampleRate
        );

        const data=buffer.getChannelData(0);

        for(let i=0;i<data.length;i++){
            data[i]=(Math.random()*2-1);
        }

        const source=audioCtx.createBufferSource();

        const gain=audioCtx.createGain();

        source.buffer=buffer;

        gain.gain.value=volume;

        source.connect(gain);

        gain.connect(audioCtx.destination);

        source.start();

    }catch(e){}

}


function soundDoor(){

    tone(80,.15,"square",.07);

    setTimeout(()=>{
        tone(45,.2,"sawtooth",.04);
    },70);

}


function soundLight(){

    tone(420,.06,"square",.025);

}


function soundCamera(){

    noise(.18,.05);

    tone(120,.12,"square",.025);

}


function soundStep(){

    tone(55,.12,"triangle",.04);

}


function soundWarning(){

    tone(70,.3,"sawtooth",.04);

    setTimeout(()=>{
        tone(55,.3,"sawtooth",.04);
    },320);

}


function soundJumpscare(){

    noise(.8,.22);

    tone(45,.8,"sawtooth",.18);

    setTimeout(()=>{
        tone(850,.15,"square",.12);
    },100);

}


/* =========================
   NIGHT START
========================= */

function startNight(n){

    initAudio();

    state.night=n;

    state.hour=0;

    state.minute=0;

    state.power=100;

    state.cameraOpen=false;

    state.camera=1;

    state.cameraSide=0;

    state.leftDoor=false;

    state.rightDoor=false;

    state.leftLight=false;

    state.rightLight=false;

    state.gameOver=false;

    state.running=true;

    monsters.forEach((m,i)=>{

        m.position=0;

        m.lastMove=performance.now()+i*3000;

    });

    document.getElementById("menu")
        .classList.add("hidden");

    document.getElementById("endScreen")
        .classList.remove("show");

    document.getElementById("hud")
        .classList.remove("hidden");

    document.getElementById("office")
        .classList.remove("hidden");

    document.getElementById("camera")
        .classList.remove("active");

    document.getElementById("nightNumber")
        .textContent=
            String(n).padStart(2,"0");

    updateOffice();

    state.lastTime=performance.now();

    requestAnimationFrame(gameLoop);

}


/* =========================
   NIGHT DIFFICULTY
========================= */

function difficulty(){

    return {

        timeScale:
            [1.0,.95,.9,.84,.78][state.night-1],

        aggression:
            [0.45,.65,.82,1.0,1.18][state.night-1],

        powerDrain:
            [0.75,.9,1.05,1.2,1.4][state.night-1]

    };

}


/* =========================
   GAME LOOP
========================= */

function gameLoop(now){

    if(!state.running || state.gameOver)return;

    const dt=now-state.lastTime;

    state.lastTime=now;

    state.elapsed+=dt;

    updateClock();

    updatePower(dt);

    updateMonsters(now);

    updateOffice();

    if(state.power<=0){

        state.power=0;

        state.leftDoor=false;

        state.rightDoor=false;

        state.leftLight=false;

        state.rightLight=false;

        closeCamera();

        setTimeout(()=>{
            loseGame("POWER FAILURE");
        },3500);

        return;

    }

    requestAnimationFrame(gameLoop);

}


/* =========================
   CLOCK
========================= */

function updateClock(){

    /*
       A full night lasts about 9 minutes.
       Each hour = 90 seconds.
       Night 1 is deliberately slower.
    */

    const d=difficulty();

    const hourLength=
        90000*d.timeScale;

    state.hour=
        Math.floor(state.elapsed/hourLength);

    if(state.hour>=6){

        winNight();

        return;

    }

    const partial=
        state.elapsed%hourLength;

    state.minute=
        Math.floor(
            partial/hourLength*60
        );

    let text;

    if(state.hour===0){
        text="12 AM";
    }else{
        text=state.hour+" AM";
    }

    document.getElementById("clock")
        .textContent=text;

}


/* =========================
   POWER
========================= */

function updatePower(dt){

    const d=difficulty();

    let drain=.0022*d.powerDrain;

    if(state.cameraOpen)
        drain+=.0013*d.powerDrain;

    if(state.leftDoor)
        drain+=.0028*d.powerDrain;

    if(state.rightDoor)
        drain+=.0028*d.powerDrain;

    if(state.leftLight)
        drain+=.0018*d.powerDrain;

    if(state.rightLight)
        drain+=.0018*d.powerDrain;

    state.power-=drain*(dt/16.67);

    if(state.power<0)
        state.power=0;

    document.getElementById("power")
        .textContent=
            Math.ceil(state.power)+"%";

    document.getElementById("powerFill")
        .style.width=
            Math.max(0,state.power)+"%";

}


/* =========================
   MONSTER AI
========================= */

function updateMonsters(now){

    const d=difficulty();

    monsters.forEach(m=>{

        const aggression=
            d.aggression *
            (m.aggression.includes(state.night)?1:.45);

        const interval=
            m.moveBase/
            Math.max(.25,aggression);

        if(now-m.lastMove<interval)
            return;

        m.lastMove=now;

        /*
           Random chance to move.
           Higher nights = more likely.
        */

        const chance=
            .30+
            aggression*.10;

        if(Math.random()>chance)
            return;

        if(m.position<m.path.length-1){

            /*
              Different monsters don't move together:
              each has its own timer + random chance.
            */

            m.position++;

            soundStep();

            if(
                m.path[m.position]==="LEFT" ||
                m.path[m.position]==="RIGHT"
            ){

                setTimeout(()=>{
                    checkAttack(m);
                },800+Math.random()*1400);

            }

        }

    });

}


/* =========================
   ATTACK CHECK
========================= */

function checkAttack(m){

    if(state.gameOver)return;

    const destination=
        m.path[m.position];

    if(destination==="LEFT"){

        if(state.leftDoor){

            /*
              Closed door blocks attack.
              Monster retreats after a short time.
            */

            soundDoor();

            if(Math.random()<.7){
                m.position=Math.max(0,m.position-1);
            }

        }else{

            loseGame(m.name);

        }

    }


    if(destination==="RIGHT"){

        if(state.rightDoor){

            soundDoor();

            if(Math.random()<.7){
                m.position=Math.max(0,m.position-1);
            }

        }else{

            loseGame(m.name);

        }

    }

}


/* =========================
   DOORS
========================= */

function toggleDoor(side){

    if(state.gameOver)return;

    initAudio();

    if(side==="left"){

        state.leftDoor=
            !state.leftDoor;

    }else{

        state.rightDoor=
            !state.rightDoor;

    }

    soundDoor();

    updateOffice();

}


/* =========================
   LIGHTS
========================= */

function toggleLight(side){

    if(state.gameOver)return;

    initAudio();

    if(side==="left"){

        state.leftLight=
            !state.leftLight;

    }else{

        state.rightLight=
            !state.rightLight;

    }

    soundLight();

    updateOffice();

}


/* =========================
   OFFICE UPDATE
========================= */

function updateOffice(){

    const ld=
        document.getElementById("leftDoor");

    const rd=
        document.getElementById("rightDoor");

    const lw=
        document.getElementById("leftWindow");

    const rw=
        document.getElementById("rightWindow");


    ld.classList.toggle(
        "closed",
        state.leftDoor
    );

    ld.classList.toggle(
        "open",
        !state.leftDoor
    );

    rd.classList.toggle(
        "closed",
        state.rightDoor
    );

    rd.classList.toggle(
        "open",
        !state.rightDoor
    );


    const leftMonster=
        monsters.find(m=>
            m.path[m.position]==="LEFT"
        );

    const rightMonster=
        monsters.find(m=>
            m.path[m.position]==="RIGHT"
        );


    document.getElementById("leftMonster")
        .classList.toggle(
            "visible",
            !!leftMonster
        );

    document.getElementById("rightMonster")
        .classList.toggle(
            "visible",
            !!rightMonster
        );


    lw.classList.toggle(
        "on",
        state.leftLight
    );

    rw.classList.toggle(
        "on",
        state.rightLight
    );


    const lBtn=
        document.getElementById("leftDoorBtn");

    const rBtn=
        document.getElementById("rightDoorBtn");

    const llBtn=
        document.getElementById("leftLightBtn");

    const rlBtn=
        document.getElementById("rightLightBtn");


    lBtn.textContent=
        state.leftDoor?
        "OPEN DOOR":
        "CLOSE DOOR";

    rBtn.textContent=
        state.rightDoor?
        "OPEN DOOR":
        "CLOSE DOOR";


    llBtn.textContent=
        state.leftLight?
        "LIGHT ON":
        "LIGHT OFF";

    rlBtn.textContent=
        state.rightLight?
        "LIGHT ON":
        "LIGHT OFF";


    lBtn.classList.toggle(
        "active",
        state.leftDoor
    );

    rBtn.classList.toggle(
        "active",
        state.rightDoor
    );

    llBtn.classList.toggle(
        "lightActive",
        state.leftLight
    );

    rlBtn.classList.toggle(
        "lightActive",
        state.rightLight
    );

}


/* =========================
   CAMERA
========================= */

function openCamera(){

    if(state.gameOver)return;

    initAudio();

    if(state.power<=0)return;

    state.cameraOpen=true;

    document.getElementById("camera")
        .classList.add("active");

    soundCamera();

    renderCamera();

}


function closeCamera(){

    state.cameraOpen=false;

    document.getElementById("camera")
        .classList.remove("active");

}


/* =========================
   CAMERA SELECTION
========================= */

function selectCam(n){

    if(state.gameOver)return;

    initAudio();

    state.camera=n;

    state.cameraSide=0;

    soundCamera();

    renderCamera();

}


function moveCamera(direction){

    state.cameraSide+=direction;

    if(state.cameraSide<-1)
        state.cameraSide=-1;

    if(state.cameraSide>1)
        state.cameraSide=1;

    const room=
        document.getElementById("camRoom");

    room.style.left=
        (-25 + state.cameraSide*18)+"%";

    soundCamera();

}


/* =========================
   CAMERA RENDER
========================= */

function renderCamera(){

    const data=
        cameras[state.camera];

    const room=
        document.getElementById("camRoom");

    const label=
        document.getElementById("camLabel");

    const name=
        document.getElementById("camName");

    room.className=
        "camRoom "+data.type;

    room.style.left="-25%";

    state.cameraSide=0;

    label.textContent=
        data.name;

    name.textContent=
        data.name;


    /*
       Make every room visually different.
    */

    const objects=
        document.getElementById("roomObjects");

    objects.innerHTML="";


    if(data.type==="showroom"){

        createObject(
            objects,
            "display shelf",
            15,40,25,28
        );

        createObject(
            objects,
            "display shelf",
            60,43,25,25
        );

        createObject(
            objects,
            "poster",
            42,30,16,15
        );

    }


    if(data.type==="storage"){

        createObject(
            objects,
            "crate",
            12,45,20,22
        );

        createObject(
            objects,
            "crate",
            38,52,18,18
        );

        createObject(
            objects,
            "crate",
            68,42,22,25
        );

    }


    if(data.type==="workshop"){

        createObject(
            objects,
            "table",
            30,50,40,12
        );

        createObject(
            objects,
            "machine",
            70,35,14,30
        );

        createObject(
            objects,
            "cabinet",
            8,36,18,35
        );

    }


    if(data.type==="dining"){

        createObject(
            objects,
            "table",
            35,50,30,9
        );

        createObject(
            objects,
            "chair",
            30,57,8,20
        );

        createObject(
            objects,
            "chair",
            63,57,8,20
        );

    }


    if(data.type==="hall"){

        createObject(
            objects,
            "door",
            43,25,14,47
        );

        createObject(
            objects,
            "pipe",
            20,20,5,55
        );

        createObject(
            objects,
            "pipe",
            75,20,5,55
        );

    }


    if(data.type==="back"){

        createObject(
            objects,
            "cabinet",
            12,32,20,40
        );

        createObject(
            objects,
            "cabinet",
            70,30,20,42
        );

        createObject(
            objects,
            "box",
            42,55,15,15
        );

    }


    if(data.type==="stage"){

        createObject(
            objects,
            "curtain",
            5,15,25,65
        );

        createObject(
            objects,
            "curtain",
            70,15,25,65
        );

        createObject(
            objects,
            "platform",
            30,56,40,10
        );

    }


    if(data.type==="loading"){

        createObject(
            objects,
            "container",
            10,35,28,30
        );

        createObject(
            objects,
            "container",
            58,40,30,27
        );

    }


    /*
       Determine whether a monster is actually here.
    */

    const active=
        monsters.find(m=>
            m.path[m.position]===state.camera
        );


    const visual=
        document.getElementById("camMonster");

    if(active){

        visual.className=
            "camMonster "+active.style;

        visual.classList.remove("hidden");

        const pos=
            data.monsterPositions[active.id];

        visual.style.left=
            pos.x+"%";

        visual.style.bottom=
            (100-pos.y)+"%";

    }else{

        visual.classList.add("hidden");

    }


    updateMap();

}


/* =========================
   CAMERA OBJECT
========================= */

function createObject(parent,name,x,y,w,h){

    const obj=
        document.createElement("div");

    obj.className=
        "camObject";

    obj.style.left=x+"%";
    obj.style.top=y+"%";
    obj.style.width=w+"%";
    obj.style.height=h+"%";

    parent.appendChild(obj);

}


/* =========================
   MAP UPDATE
========================= */

function updateMap(){

    document.querySelectorAll(".mapBtn")
        .forEach((btn,i)=>{

            const cam=i+1;

            btn.classList.toggle(
                "current",
                cam===state.camera
            );

            const danger=
                monsters.some(m=>
                    m.path[m.position]===cam
                );

            btn.classList.toggle(
                "danger",
                danger
            );

        });

}


/* =========================
   LOSE
========================= */

function loseGame(reason){

    if(state.gameOver)return;

    state.gameOver=true;

    state.running=false;

    closeCamera();

    soundJumpscare();

    const scare=
        document.getElementById("jumpscare");

    scare.classList.add("show");

    setTimeout(()=>{

        scare.classList.remove("show");

        document.getElementById("office")
            .classList.add("hidden");

        document.getElementById("hud")
            .classList.add("hidden");

        const end=
            document.getElementById("endScreen");

        document.getElementById("endTitle")
            .textContent=
                "SHIFT FAILED";

        document.getElementById("endText")
            .innerHTML=
                "THE SECURITY SYSTEM LOST CONTACT.<br><br>"+
                "CAUSE: "+reason+
                "<br><br>NIGHT "+
                String(state.night).padStart(2,"0");

        end.classList.add("show");

    },1600);

}


/* =========================
   WIN
========================= */

function winNight(){

    if(state.gameOver)return;

    state.gameOver=true;

    state.running=false;

    closeCamera();

    document.getElementById("office")
        .classList.add("hidden");

    document.getElementById("hud")
        .classList.add("hidden");

    const end=
        document.getElementById("endScreen");

    document.getElementById("endTitle")
        .textContent=
            "6 AM";

    let message=
        "NIGHT "+
        String(state.night).padStart(2,"0")+
        " COMPLETE";

    if(state.night<5){

        message+=
            "<br><br>"+
            "THE NEXT SHIFT WILL BE MORE ACTIVE.";

    }else{

        message+=
            "<br><br>"+
            "ALL FIVE NIGHTS SURVIVED.<br>"+
            "YOU MADE IT.";

    }

    document.getElementById("endText")
        .innerHTML=message;

    end.classList.add("show");

}


/* =========================
   NIGHT MENU
========================= */

function showNights(){

    document.getElementById("nightSelect")
        .classList.toggle("hidden");

}


/* =========================
   KEYBOARD
========================= */

document.addEventListener("keydown",e=>{

    if(!state.running)return;

    if(e.key==="a")
        toggleDoor("left");

    if(e.key==="d")
        toggleDoor("right");

    if(e.key==="q")
        toggleLight("left");

    if(e.key==="e")
        toggleLight("right");

    if(e.key===" ")
        openCamera();

    if(e.key==="Escape")
        closeCamera();

    if(state.cameraOpen){

        if(e.key==="ArrowLeft")
            moveCamera(-1);

        if(e.key==="ArrowRight")
            moveCamera(1);

        if(e.key>="1" && e.key<="9")
            selectCam(Number(e.key));

    }

});


/* =========================
   PREVENT DOUBLE TAP ZOOM
========================= */

let lastTouch=0;

document.addEventListener(
    "touchend",
    e=>{

        const now=Date.now();

        if(now-lastTouch<=300){
            e.preventDefault();
        }

        lastTouch=now;

    },
    {passive:false}
);


/* =========================
   STARTUP
========================= */

updateMap();

</script>

</body>
</html>

Game Source: NIGHT SHIFT — Five Nights

Creator: LunarPanda23

Libraries: none

Complexity: complex (3035 lines, 49.7 KB)

The full source code is displayed above on this page.

Remix Instructions

To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: night-shift-five-nights-lunarpanda23" to link back to the original. Then publish at arcadelab.ai/publish.