Fortnite Chapter 1 Season 1 Lobby
by StormPanda351164 lines24.4 KB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fortnite Chapter 1 Season 1 Lobby</title>
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: Arial, Helvetica, sans-serif;
color: white;
background:
linear-gradient(120deg, rgba(6, 24, 62, .65), rgba(20, 85, 143, .25)),
linear-gradient(#1474b7, #174b85 60%, #091c42);
min-height: 100vh;
overflow-x: hidden;
}
button {
font-family: inherit;
cursor: pointer;
color: white;
font-weight: 900;
border: 0;
transition: .15s;
}
button:hover {
filter: brightness(1.18);
transform: translateY(-1px);
}
button:active {
transform: scale(.98);
}
.topbar {
height: 76px;
background: rgba(4, 14, 37, .92);
border-bottom: 2px solid rgba(255,255,255,.13);
display: flex;
align-items: center;
padding: 0 24px;
gap: 12px;
position: relative;
z-index: 5;
}
.logo {
font-size: 23px;
font-weight: 1000;
font-style: italic;
margin-right: 18px;
letter-spacing: -1px;
}
.logo span {
color: #ffd84a;
}
.nav {
display: flex;
gap: 5px;
height: 100%;
align-items: center;
}
.nav button {
height: 43px;
padding: 0 17px;
background: transparent;
color: #b8c9e3;
font-size: 13px;
border-bottom: 3px solid transparent;
}
.nav button.active {
color: white;
background: rgba(255,255,255,.1);
border-bottom-color: #ffd84a;
}
.profile {
margin-left: auto;
display: flex;
align-items: center;
gap: 10px;
font-weight: 900;
font-size: 13px;
}
.avatar {
width: 37px;
height: 37px;
border-radius: 50%;
display: grid;
place-items: center;
background: #f0bd45;
color: #142342;
border: 2px solid white;
}
.vbucks {
margin-left: 12px;
padding: 10px 13px;
background: #152c52;
border: 1px solid #49678f;
border-radius: 4px;
}
.screen {
display: none;
min-height: calc(100vh - 76px);
}
.screen.active {
display: block;
}
.lobby {
position: relative;
min-height: calc(100vh - 76px);
display: flex;
align-items: center;
padding: 30px 5%;
overflow: hidden;
}
.background-shape {
position: absolute;
width: 520px;
height: 520px;
border: 1px solid rgba(255,255,255,.1);
border-radius: 50%;
right: 9%;
top: 8%;
box-shadow: 0 0 0 55px rgba(255,255,255,.025),
0 0 0 110px rgba(255,255,255,.02);
}
.lobby-left {
width: 340px;
z-index: 2;
}
.season-label {
color: #ffe27b;
font-weight: 1000;
font-size: 12px;
letter-spacing: 2px;
}
h1 {
font-size: 38px;
margin: 10px 0;
font-weight: 1000;
font-style: italic;
text-shadow: 0 3px 0 rgba(0,0,0,.15);
}
.subtext {
color: #c8dbf5;
font-size: 13px;
line-height: 1.5;
}
.mode-card {
margin-top: 27px;
background: rgba(5, 19, 49, .75);
border: 1px solid rgba(255,255,255,.25);
padding: 17px;
box-shadow: 0 8px 25px rgba(0,0,0,.15);
}
.mode-card h3 {
font-size: 13px;
margin: 0 0 12px;
}
.mode-options {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8px;
}
.mode-button {
padding: 15px 5px;
background: #243e65;
border: 2px solid transparent;
font-size: 12px;
}
.mode-button.selected {
border-color: #ffe05b;
background: #345b8c;
}
.mode-description {
color: #c9d8eb;
font-size: 12px;
margin-top: 12px;
}
.play-button {
width: 100%;
margin-top: 16px;
padding: 19px 10px;
background: #f5c840;
color: #17213a;
font-size: 20px;
box-shadow: 0 5px 0 #b5851d;
}
.play-button:disabled {
opacity: .7;
cursor: default;
transform: none;
}
.unready-button {
display: none;
width: 100%;
margin-top: 12px;
padding: 14px;
background: #293d5e;
border: 1px solid #7e96b8;
}
.status {
font-size: 11px;
color: #d8e7fa;
margin-top: 15px;
font-weight: 800;
letter-spacing: .7px;
}
.character-area {
flex: 1;
min-width: 0;
min-height: 560px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
}
.character-name {
z-index: 2;
margin-bottom: 10px;
text-align: center;
font-size: 17px;
font-weight: 1000;
text-shadow: 0 3px 5px #081b3d;
}
.character-name small {
display: block;
color: #ffe16c;
font-size: 10px;
margin-top: 5px;
letter-spacing: 2px;
}
.platform {
width: 290px;
height: 55px;
background: linear-gradient(#9ac9ef, #3569a3);
border: 3px solid rgba(255,255,255,.55);
transform: perspective(300px) rotateX(50deg);
border-radius: 50%;
box-shadow: 0 0 55px rgba(125,198,255,.45);
position: absolute;
bottom: 65px;
}
.figure {
position: relative;
width: 190px;
height: 410px;
z-index: 1;
animation: float 3s ease-in-out infinite;
filter: drop-shadow(0 12px 12px rgba(0,0,0,.2));
}
@keyframes float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-9px); }
}
/* Character body */
.head {
position: absolute;
width: 94px;
height: 100px;
left: 48px;
top: 15px;
background: #e5b98e;
border: 3px solid #17213a;
border-radius: 28px 28px 23px 23px;
z-index: 4;
}
.hair {
position: absolute;
left: 46px;
top: 8px;
width: 98px;
height: 31px;
border-radius: 35px 35px 10px 10px;
background: #30291f;
border: 3px solid #17213a;
z-index: 5;
}
.eye {
position: absolute;
width: 9px;
height: 12px;
top: 45px;
left: 20px;
background: #17213a;
border-radius: 50%;
}
.eye.right {
left: 59px;
}
.mouth {
position: absolute;
width: 31px;
height: 12px;
left: 28px;
top: 70px;
border-bottom: 4px solid #803d32;
border-radius: 50%;
}
.body {
position: absolute;
top: 108px;
left: 33px;
width: 124px;
height: 148px;
background: #2779c7;
border: 4px solid #17213a;
border-radius: 22px 22px 12px 12px;
z-index: 3;
}
.belt {
position: absolute;
bottom: 15px;
left: -3px;
height: 19px;
width: 124px;
background: #23344e;
border-top: 3px solid #17213a;
border-bottom: 3px solid #17213a;
}
.buckle {
position: absolute;
width: 19px;
height: 19px;
left: 48px;
bottom: 13px;
background: #e4bc45;
border: 3px solid #17213a;
z-index: 2;
}
.arm {
position: absolute;
top: 120px;
width: 37px;
height: 124px;
background: #e5b98e;
border: 4px solid #17213a;
border-radius: 17px;
z-index: 2;
}
.arm.left {
left: 7px;
transform: rotate(8deg);
}
.arm.right {
right: 7px;
transform: rotate(-8deg);
}
.sleeve {
position: absolute;
top: 119px;
width: 42px;
height: 47px;
background: #2779c7;
border: 4px solid #17213a;
z-index: 4;
border-radius: 12px;
}
.sleeve.left { left: 3px; transform: rotate(8deg); }
.sleeve.right { right: 3px; transform: rotate(-8deg); }
.legs {
position: absolute;
top: 248px;
left: 38px;
width: 114px;
height: 122px;
display: flex;
gap: 5px;
z-index: 2;
}
.leg {
position: relative;
flex: 1;
background: #283e66;
border: 4px solid #17213a;
border-radius: 8px 8px 13px 13px;
}
.leg::after {
content: "";
position: absolute;
height: 22px;
bottom: -7px;
left: -5px;
right: -5px;
background: #161e2b;
border: 3px solid #101726;
border-radius: 8px;
}
/* Clowner cosmetic details */
.figure.clowner .hair {
background: #e83a45;
height: 35px;
border-radius: 50% 50% 10px 10px;
}
.figure.clowner .head {
background: #f5f1e8;
}
.figure.clowner .body {
background: #e63d4e;
}
.figure.clowner .sleeve {
background: #f4cf43;
}
.figure.clowner .arm {
background: #f5f1e8;
}
.figure.clowner .leg {
background: #463c88;
}
.figure.clowner .eye {
background: #17182a;
width: 12px;
height: 14px;
}
.figure.clowner .mouth {
width: 48px;
height: 19px;
left: 20px;
top: 65px;
background: #bb263e;
border: 3px solid #7f1830;
border-radius: 8px 8px 50% 50%;
}
.clown-nose {
display: none;
position: absolute;
top: 53px;
left: 34px;
width: 23px;
height: 23px;
background: #f52b39;
border: 3px solid #a71426;
border-radius: 50%;
z-index: 8;
}
.figure.clowner .clown-nose {
display: block;
}
.clown-cheek {
display: none;
position: absolute;
top: 62px;
width: 15px;
height: 10px;
background: #ed4354;
border-radius: 50%;
}
.clown-cheek.left { left: 7px; }
.clown-cheek.right { right: 7px; }
.figure.clowner .clown-cheek {
display: block;
}
.clown-hat {
display: none;
position: absolute;
left: 59px;
top: -9px;
width: 73px;
height: 26px;
background: #f4cf43;
border: 3px solid #17213a;
border-radius: 50% 50% 5px 5px;
z-index: 6;
transform: rotate(-8deg);
}
.figure.clowner .clown-hat {
display: block;
}
.lobby-footer {
position: absolute;
bottom: 15px;
left: 24px;
right: 24px;
display: flex;
justify-content: space-between;
color: #d5e4fa;
font-size: 10px;
font-weight: bold;
z-index: 3;
}
/* Locker */
.locker-page {
padding: 35px 5%;
min-height: calc(100vh - 76px);
background: linear-gradient(135deg, rgba(10,27,61,.45), rgba(14,62,107,.4));
}
.page-title {
font-size: 34px;
font-weight: 1000;
font-style: italic;
margin: 0 0 7px;
}
.page-subtitle {
color: #bfd4f0;
margin-bottom: 27px;
font-size: 13px;
}
.locker-layout {
display: grid;
grid-template-columns: minmax(0, 1.2fr) minmax(300px, .8fr);
gap: 22px;
max-width: 1100px;
}
.skin-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 14px;
align-content: start;
}
.skin-card {
min-height: 245px;
position: relative;
padding: 16px;
background: rgba(5,18,45,.72);
border: 2px solid rgba(255,255,255,.17);
text-align: left;
overflow: hidden;
}
.skin-card.selected {
border-color: #ffe15a;
background: rgba(37,72,113,.85);
}
.skin-card.equipped::after {
content: "EQUIPPED";
position: absolute;
top: 10px;
right: 8px;
background: #ffe15a;
color: #17213a;
padding: 5px 7px;
font-size: 9px;
}
.skin-card .figure {
transform: scale(.58);
transform-origin: top center;
margin: 0 auto -160px;
animation: none;
}
.skin-card .skin-name {
display: block;
margin-top: 6px;
font-size: 18px;
font-weight: 1000;
}
.skin-rarity {
display: block;
color: #a9c8f4;
font-size: 10px;
margin-top: 4px;
letter-spacing: 1px;
}
.skin-preview {
min-height: 460px;
background: rgba(4,17,44,.75);
border: 1px solid rgba(255,255,255,.2);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
}
.skin-preview::before {
content: "";
position: absolute;
width: 280px;
height: 280px;
border: 1px solid rgba(255,255,255,.12);
border-radius: 50%;
box-shadow: 0 0 0 35px rgba(255,255,255,.025),
0 0 0 70px rgba(255,255,255,.02);
}
.skin-preview .figure {
transform: scale(.83);
transform-origin: center center;
margin-top: 10px;
}
.skin-preview .platform {
position: relative;
bottom: auto;
margin-top: -12px;
flex-shrink: 0;
}
.preview-name {
position: relative;
z-index: 2;
font-size: 25px;
font-weight: 1000;
margin-top: 12px;
}
.preview-rarity {
color: #ffdf5c;
font-weight: 900;
letter-spacing: 2px;
font-size: 11px;
margin-top: 5px;
}
.equip-button {
position: relative;
z-index: 2;
width: 80%;
padding: 16px;
margin-top: 20px;
background: #f6cc42;
color: #182440;
font-size: 16px;
}
.equip-button:disabled {
background: #516985;
color: white;
cursor: default;
}
.notice {
min-height: 18px;
margin-top: 10px;
color: #bfe5ff;
font-size: 12px;
text-align: center;
}
.coming-soon {
display: none;
text-align: center;
padding: 80px 20px;
}
.coming-soon.active {
display: block;
}
.coming-soon h2 {
font-size: 32px;
}
@media (max-width: 760px) {
.topbar {
padding: 0 10px;
gap: 3px;
height: auto;
min-height: 70px;
flex-wrap: wrap;
}
.logo {
font-size: 18px;
margin-right: 3px;
}
.nav button {
padding: 0 8px;
font-size: 11px;
}
.profile {
display: none;
}
.vbucks {
margin-left: auto;
font-size: 11px;
}
.lobby {
align-items: flex-start;
flex-direction: column;
padding: 25px 5% 60px;
}
.lobby-left {
width: 100%;
max-width: 390px;
}
.character-area {
width: 100%;
min-height: 480px;
}
.background-shape {
right: -100px;
top: 45%;
}
.locker-layout {
grid-template-columns: 1fr;
}
.skin-preview {
min-height: 440px;
}
.lobby-footer {
font-size: 8px;
left: 10px;
right: 10px;
}
}
</style>
</head>
<body>
<header class="topbar">
<div class="logo">FORTNITE<span>★</span></div>
<nav class="nav">
<button class="active" data-tab="lobby">LOBBY</button>
<button data-tab="locker">LOCKER</button>
<button data-tab="shop">ITEM SHOP</button>
<button data-tab="career">CAREER</button>
</nav>
<div class="profile">
<div class="avatar">1</div>
<div>
<div>FARTBOT</div>
<small style="color:#b6cce8">LEVEL 1</small>
</div>
</div>
<div class="vbucks">Ⓥ 1,000</div>
</header>
<!-- LOBBY -->
<main id="lobby" class="screen active">
<div class="lobby">
<div class="background-shape"></div>
<section class="lobby-left">
<div class="season-label">CHAPTER 1 · SEASON 1</div>
<h1>BATTLE ROYALE</h1>
<div class="subtext">
The original island. The original vibe.<br>
Drop in and be the last player standing.
</div>
<div class="mode-card">
<h3>SELECT GAME MODE</h3>
<div class="mode-options">
<button class="mode-button selected" data-mode="SOLO">
👤 SOLO
</button>
<button class="mode-button" data-mode="DUOS">
👥 DUOS
</button>
</div>
<div id="modeDescription" class="mode-description">
Every player for themselves. Be the last one standing.
</div>
<button id="playButton" class="play-button">PLAY</button>
<button id="unreadyButton" class="unready-button">UNREADY</button>
<div id="status" class="status">● ONLINE · IN LOBBY</div>
</div>
</section>
<section class="character-area">
<div class="character-name">
<span id="lobbySkinName">Clowner</span>
<small>OUTFIT · EQUIPPED</small>
</div>
<div id="lobbyFigure" class="figure clowner">
<div class="clown-hat"></div>
<div class="hair"></div>
<div class="head">
<div class="eye"></div>
<div class="eye right"></div>
<div class="clown-cheek left"></div>
<div class="clown-cheek right"></div>
<div class="clown-nose"></div>
<div class="mouth"></div>
</div>
<div class="arm left"></div>
<div class="arm right"></div>
<div class="sleeve left"></div>
<div class="sleeve right"></div>
<div class="body">
<div class="belt"></div>
<div class="buckle"></div>
</div>
<div class="legs">
<div class="leg"></div>
<div class="leg"></div>
</div>
</div>
<div class="platform"></div>
</section>
<div class="lobby-footer">
<span>FORTNITE FAN-MADE LOBBY</span>
<span>SEASON 1 · VERSION 1.4</span>
</div>
</div>
</main>
<!-- LOCKER -->
<main id="locker" class="screen">
<section class="locker-page">
<h1 class="page-title">MY LOCKER</h1>
<div class="page-subtitle">
Choose your outfit. Everyone owns both skins!
</div>
<div class="locker-layout">
<div class="skin-grid">
<button class="skin-card" data-skin="Blue">
<div class="figure">
<div class="hair"></div>
<div class="head">
<div class="eye"></div>
<div class="eye right"></div>
<div class="mouth"></div>
</div>
<div class="arm left"></div>
<div class="arm right"></div>
<div class="sleeve left"></div>
<div class="sleeve right"></div>
<div class="body">
<div class="belt"></div>
<div class="buckle"></div>
</div>
<div class="legs">
<div class="leg"></div>
<div class="leg"></div>
</div>
</div>
<span class="skin-name">Blue</span>
<span class="skin-rarity">COMMON · OUTFIT</span>
</button>
<button class="skin-card selected equipped" data-skin="Clowner">
<div class="figure clowner">
<div class="clown-hat"></div>
<div class="hair"></div>
<div class="head">
<div class="eye"></div>
<div class="eye right"></div>
<div class="clown-cheek left"></div>
<div class="clown-cheek right"></div>
<div class="clown-nose"></div>
<div class="mouth"></div>
</div>
<div class="arm left"></div>
<div class="arm right"></div>
<div class="sleeve left"></div>
<div class="sleeve right"></div>
<div class="body">
<div class="belt"></div>
<div class="buckle"></div>
</div>
<div class="legs">
<div class="leg"></div>
<div class="leg"></div>
</div>
</div>
<span class="skin-name">Clowner 🤡</span>
<span class="skin-rarity">UNCOMMON · OUTFIT</span>
</button>
</div>
<div class="skin-preview">
<div id="previewFigure" class="figure clowner">
<div class="clown-hat"></div>
<div class="hair"></div>
<div class="head">
<div class="eye"></div>
<div class="eye right"></div>
<div class="clown-cheek left"></div>
<div class="clown-cheek right"></div>
<div class="clown-nose"></div>
<div class="mouth"></div>
</div>
<div class="arm left"></div>
<div class="arm right"></div>
<div class="sleeve left"></div>
<div class="sleeve right"></div>
<div class="body">
<div class="belt"></div>
<div class="buckle"></div>
</div>
<div class="legs">
<div class="leg"></div>
<div class="leg"></div>
</div>
</div>
<div class="platform"></div>
<div id="previewName" class="preview-name">Clowner</div>
<div id="previewRarity" class="preview-rarity">UNCOMMON OUTFIT</div>
<button id="equipButton" class="equip-button" disabled>
EQUIPPED
</button>
<div id="lockerNotice" class="notice">
Clowner is currently equipped!
</div>
</div>
</div>
</section>
</main>
<!-- ITEM SHOP -->
<main id="shop" class="screen">
<section class="coming-soon active">
<div class="season-label">CHAPTER 1 · SEASON 1</div>
<h2>ITEM SHOP</h2>
<p class="subtext">The shop isn't available yet.</p>
<button class="play-button" style="max-width:250px"
onclick="showTab('lobby')">BACK TO LOBBY</button>
</section>
</main>
<!-- CAREER -->
<main id="career" class="screen">
<section class="coming-soon active">
<div class="season-label">PLAYER PROFILE</div>
<h2>CAREER</h2>
<p class="subtext">PLAYER: FARTBOT · LEVEL 1</p>
<p class="subtext">OUTFIT: <span id="careerSkinName">Clowner</span></p>
<button class="play-button" style="max-width:250px"
onclick="showTab('lobby')">BACK TO LOBBY</button>
</section>
</main>
<script>
let selectedMode = "SOLO";
let equippedSkin = "Clowner";
let selectedSkin = "Clowner";
let isMatchmaking = false;
const skins = {
Blue: {
rarity: "COMMON OUTFIT",
description: "The original default outfit."
},
Clowner: {
rarity: "UNCOMMON OUTFIT",
description: "A clown-themed twist on the original default."
}
};
function showTab(tabName) {
document.querySelectorAll(".screen").forEach(screen => {
screen.classList.remove("active");
});
document.getElementById(tabName).classList.add("active");
document.querySelectorAll(".nav button").forEach(button => {
button.classList.toggle("active", button.dataset.tab === tabName);
});
}
document.querySelectorAll(".nav button").forEach(button => {
button.addEventListener("click", () => {
showTab(button.dataset.tab);
});
});
// Game mode selection
document.querySelectorAll(".mode-button").forEach(button => {
button.addEventListener("click", () => {
selectedMode = button.dataset.mode;
document.querySelectorAll(".mode-button").forEach(other => {
other.classList.toggle("selected", other === button);
});
document.getElementById("modeDescription").textContent =
selectedMode === "SOLO"
? "Every player for themselves. Be the last one standing."
: "Team up with one friend and fight to be the last duo.";
if (isMatchmaking) {
document.getElementById("status").textContent =
"● MATCHMAKING · " + selectedMode;
}
});
});
// Play and unready
document.getElementById("playButton").addEventListener("click", () => {
isMatchmaking = true;
document.getElementById("playButton").textContent = "MATCHMAKING...";
document.getElementById("playButton").disabled = true;
document.getElementById("unreadyButton").style.display = "block";
document.getElementById("status").textContent =
"● MATCHMAKING · " + selectedMode;
});
document.getElementById("unreadyButton").addEventListener("click", () => {
isMatchmaking = false;
document.getElementById("playButton").textContent = "PLAY";
document.getElementById("playButton").disabled = false;
document.getElementById("unreadyButton").style.display = "none";
document.getElementById("status").textContent = "● ONLINE · IN LOBBY";
});
// Skin selection
document.querySelectorAll(".skin-card").forEach(card => {
card.addEventListener("click", () => {
selectedSkin = card.dataset.skin;
updateLocker();
});
});
document.getElementById("equipButton").addEventListener("click", () => {
equippedSkin = selectedSkin;
updateLocker();
updateLobbySkin();
document.getElementById("lockerNotice").textContent =
equippedSkin + " equipped successfully!";
});
function updateLocker() {
document.querySelectorAll(".skin-card").forEach(card => {
const skin = card.dataset.skin;
card.classList.toggle("selected", skin === selectedSkin);
card.classList.toggle("equipped", skin === equippedSkin);
});
const preview = document.getElementById("previewFigure");
preview.classList.toggle("clowner", selectedSkin === "Clowner");
document.getElementById("previewName").textContent = selectedSkin;
document.getElementById("previewRarity").textContent =
skins[selectedSkin].rarity;
const equipButton = document.getElementById("equipButton");
if (selectedSkin === equippedSkin) {
equipButton.textContent = "EQUIPPED";
equipButton.disabled = true;
document.getElementById("lockerNotice").textContent =
selectedSkin + " is currently equipped!";
} else {
equipButton.textContent = "EQUIP " + selectedSkin.toUpperCase();
equipButton.disabled = false;
document.getElementById("lockerNotice").textContent =
"Select EQUIP to wear " + selectedSkin + ".";
}
}
function updateLobbySkin() {
const figure = document.getElementById("lobbyFigure");
figure.classList.toggle("clowner", equippedSkin === "Clowner");
document.getElementById("lobbySkinName").textContent = equippedSkin;
document.getElementById("careerSkinName").textContent = equippedSkin;
}
// Initialize with Clowner equipped for everyone.
updateLocker();
updateLobbySkin();
</script>
</body>
</html>
Game Source: Fortnite Chapter 1 Season 1 Lobby
Creator: StormPanda35
Libraries: none
Complexity: complex (1164 lines, 24.4 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: fortnite-chapter-1-season-1-lobby-stormpanda35" to link back to the original. Then publish at arcadelab.ai/publish.