Fortnite - Chapter 1 Season 1
by StormPanda35561 lines16.6 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</title>
<style>
* { box-sizing: border-box; }
body {
margin: 0;
color: white;
font-family: Arial, sans-serif;
background: #07182b;
}
button, input { font: inherit; }
button { cursor: pointer; font-weight: bold; }
button:hover { filter: brightness(1.15); }
.hidden { display: none !important; }
#authScreen {
min-height: 100vh;
display: grid;
place-items: center;
padding: 20px;
background:
radial-gradient(ellipse at 50% 20%, #246a9b, transparent 60%),
linear-gradient(145deg, #081326, #164a70);
}
.authbox {
width: min(430px, 100%);
padding: 35px;
background: #101d31ed;
border: 2px solid #4aa8e9;
box-shadow: 0 0 35px #0008;
text-align: center;
}
.logo { font-size: 36px; font-weight: 1000; font-style: italic; }
.logo span { color: #f8d94e; }
.auth-sub { color: #82d1ff; margin: 8px 0 28px; }
label { display: block; text-align: left; margin-bottom: 8px; font-size: 12px; }
input {
width: 100%;
padding: 13px;
border: 1px solid #66819d;
background: #071426;
color: white;
margin-bottom: 14px;
}
.primary {
background: #f3c62f;
border: 0;
padding: 14px;
color: #14233b;
width: 100%;
}
#authMessage { color: #ffaaaa; min-height: 25px; margin-top: 12px; }
.fineprint { color: #9daec2; font-size: 11px; line-height: 1.5; }
#game {
min-height: 100vh;
background:
linear-gradient(90deg, #071629e8, #0b2946aa),
radial-gradient(ellipse at 75% 45%, #2784a3, #123f61 45%, #08162a);
}
header {
height: 75px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 4%;
background: #081321e8;
border-bottom: 2px solid #e3bb37;
gap: 15px;
}
.brand { font-size: 25px; font-weight: 1000; font-style: italic; }
.brand span { color: #f4cb37; }
.header-right { display: flex; align-items: center; gap: 15px; }
.small-button { background: #233c57; color: white; border: 1px solid #617b95; padding: 9px 12px; }
nav {
display: flex;
gap: 8px;
padding: 14px 4%;
background: #101f33;
flex-wrap: wrap;
}
nav button {
border: 0;
padding: 12px 20px;
color: white;
background: transparent;
}
nav button.active { background: #e9c13c; color: #10233b; }
.page { display: none; padding: 25px 4%; }
.page.active { display: block; }
.lobby-layout {
min-height: 490px;
display: grid;
grid-template-columns: minmax(250px, 1fr) minmax(260px, 1.2fr);
gap: 25px;
}
.panel {
background: #09172ad9;
border: 1px solid #42617c;
padding: 22px;
}
h1 { margin-top: 0; font-size: 30px; }
h2 { font-size: 20px; }
.muted { color: #a9bed1; }
.mode-row { display: flex; gap: 10px; margin: 20px 0; }
.mode {
flex: 1;
padding: 16px 8px;
background: #172c43;
border: 2px solid #3d5c77;
color: white;
}
.mode.selected { border-color: #f1ce40; background: #294563; }
#play {
width: 100%;
padding: 17px;
border: 0;
color: #142238;
background: #f4cc38;
font-size: 19px;
}
#unready {
width: 100%;
padding: 14px;
margin-top: 10px;
border: 1px solid #8095a8;
background: #273d55;
color: white;
}
#status { margin-top: 15px; color: #9fddff; min-height: 22px; }
.player-stage {
display: grid;
place-items: center;
position: relative;
overflow: hidden;
min-height: 400px;
background: radial-gradient(ellipse at 50% 65%, #3e9dc0, #154768 45%, #0b1a2e);
}
.player-stage:after {
content: "";
position: absolute;
bottom: 35px;
width: 220px;
height: 25px;
background: #020a15;
border-radius: 50%;
filter: blur(9px);
}
.figure {
position: relative;
z-index: 1;
width: 125px;
height: 260px;
margin-top: 30px;
}
.head {
position: absolute;
top: 0;
left: 40px;
width: 48px;
height: 52px;
border: 3px solid #1b2636;
border-radius: 10px;
background: #d7a77c;
}
.hair {
position: absolute;
top: -5px;
left: 37px;
width: 54px;
height: 20px;
border-radius: 12px 12px 3px 3px;
background: #3a2a22;
}
.torso {
position: absolute;
top: 52px;
left: 24px;
width: 80px;
height: 105px;
border: 3px solid #1b2636;
border-radius: 12px 12px 5px 5px;
background: #2478c6;
}
.arm {
position: absolute;
top: 59px;
width: 23px;
height: 90px;
border: 3px solid #1b2636;
border-radius: 9px;
background: #d7a77c;
}
.arm.left { left: 3px; transform: rotate(8deg); }
.arm.right { right: 3px; transform: rotate(-8deg); }
.leg {
position: absolute;
top: 151px;
width: 36px;
height: 94px;
border: 3px solid #1b2636;
border-radius: 4px 4px 10px 10px;
background: #253e62;
}
.leg.left { left: 27px; }
.leg.right { right: 27px; }
.figure.clowner .head { background: white; }
.figure.clowner .hair { background: #e73d45; height: 28px; }
.figure.clowner .torso {
background: repeating-linear-gradient(45deg, #e13c4b 0 12px, #f6f0d9 12px 24px);
}
.figure.clowner .arm { background: #f5f0db; }
.figure.clowner .leg { background: #b52b43; }
.skin-label {
position: absolute;
z-index: 2;
bottom: 12px;
font-weight: bold;
letter-spacing: 2px;
}
.skin-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
gap: 15px;
}
.skin-card {
background: #10243a;
border: 2px solid #45617b;
padding: 15px;
text-align: center;
}
.skin-card.selected { border-color: #f4d33e; }
.skin-card.locked { opacity: .65; }
.skin-card .figure { transform: scale(.7); transform-origin: top center; margin-bottom: -60px; }
.skin-card button { margin-top: 12px; padding: 10px; width: 100%; border: 0; background: #eac63a; color: #13243a; }
.badge { font-size: 11px; color: #9ec8ed; letter-spacing: 1px; }
#lockerNotice { color: #ffcc65; min-height: 25px; }
.stat { background: #142b43; padding: 20px; margin: 12px 0; }
#logout { color: white; background: #7a2932; border: 0; padding: 9px 12px; }
@media (max-width: 700px) {
header { height: auto; padding: 15px 4%; flex-wrap: wrap; }
.lobby-layout { grid-template-columns: 1fr; }
.player-stage { min-height: 340px; }
.authbox { padding: 25px; }
}
</style>
</head>
<body>
<section id="authScreen">
<div class="authbox">
<div class="logo">FORTNITE<span>โ
</span></div>
<div class="auth-sub">CHAPTER 1 ยท SEASON 1</div>
<form id="usernameForm">
<label for="username">CHOOSE YOUR USERNAME</label>
<input id="username" maxlength="20" minlength="3"
placeholder="Enter a username" autocomplete="off" required>
<button class="primary" type="submit">LAUNCH GAME</button>
</form>
<div id="authMessage" role="status"></div>
<div class="fineprint">
Usernames can be reused. Volxer requires a special code.
</div>
</div>
</section>
<div id="game" class="hidden">
<header>
<div class="brand">FORTNITE<span>โ
</span></div>
<div class="header-right">
<span>LEVEL <strong>1</strong></span>
<strong id="headerUser">Player</strong>
<button id="logout" type="button">LOG OUT</button>
</div>
</header>
<nav>
<button class="active" data-tab="lobby">PLAY</button>
<button data-tab="locker">LOCKER</button>
<button data-tab="shop">ITEM SHOP</button>
<button data-tab="career">CAREER</button>
</nav>
<main>
<section id="lobby" class="page active">
<div class="lobby-layout">
<div class="panel">
<div class="badge">CHAPTER 1 ยท SEASON 1</div>
<h1>BATTLE ROYALE</h1>
<p class="muted">Drop in. Loot up. Be the last one standing.</p>
<h2>SELECT GAME MODE</h2>
<div class="mode-row">
<button class="mode selected" data-mode="Solo">SOLO</button>
<button class="mode" data-mode="Duos">DUOS</button>
</div>
<p id="modeDescription" class="muted">Every player for themselves.</p>
<button id="play" type="button">PLAY</button>
<button id="unready" type="button" class="hidden">UNREADY</button>
<div id="status" role="status">Ready to play.</div>
</div>
<div class="player-stage">
<div id="lobbyFigure" class="figure">
<div class="hair"></div><div class="head"></div>
<div class="arm left"></div><div class="arm right"></div>
<div class="torso"></div>
<div class="leg left"></div><div class="leg right"></div>
</div>
<div id="lobbySkinName" class="skin-label">BLUE</div>
</div>
</div>
</section>
<section id="locker" class="page">
<div class="panel">
<h1>LOCKER</h1>
<p class="muted">Choose your outfit.</p>
<p id="lockerNotice" role="status"></p>
<div class="skin-grid">
<div class="skin-card selected" data-skin="Blue">
<div class="badge">COMMON OUTFIT</div>
<div class="figure">
<div class="hair"></div><div class="head"></div>
<div class="arm left"></div><div class="arm right"></div>
<div class="torso"></div>
<div class="leg left"></div><div class="leg right"></div>
</div>
<h2>Blue</h2>
<p class="muted">Classic default outfit</p>
<button type="button" class="select-skin">EQUIP</button>
</div>
<div class="skin-card" data-skin="Clowner">
<div class="badge">SPECIAL OUTFIT</div>
<div class="figure clowner">
<div class="hair"></div><div class="head"></div>
<div class="arm left"></div><div class="arm right"></div>
<div class="torso"></div>
<div class="leg left"></div><div class="leg right"></div>
</div>
<h2>Clowner</h2>
<p class="muted">Reserved for Volxer</p>
<button type="button" class="select-skin">EQUIP</button>
</div>
</div>
</div>
</section>
<section id="shop" class="page">
<div class="panel">
<h1>ITEM SHOP</h1>
<p>Welcome to the Item Shop!</p>
<div class="stat">
<h2>Daily Shop</h2>
<p class="muted">No items available in this prototype.</p>
</div>
<div class="stat">
<h2>Featured Items</h2>
<p class="muted">More outfits coming soon.</p>
</div>
</div>
</section>
<section id="career" class="page">
<div class="panel">
<h1>CAREER</h1>
<div class="stat">USERNAME: <strong id="careerUser">Player</strong></div>
<div class="stat">LEVEL: <strong>1</strong></div>
<div class="stat">EQUIPPED OUTFIT: <strong id="careerSkin">Blue</strong></div>
<div class="stat">SEASON: <strong>CHAPTER 1 ยท SEASON 1</strong></div>
</div>
</section>
</main>
</div>
<script>
const SECRET_CODE = "notcha";
let currentUser = "";
let equippedSkin = "Blue";
let selectedMode = "Solo";
let matchmaking = false;
const authScreen = document.getElementById("authScreen");
const game = document.getElementById("game");
const usernameInput = document.getElementById("username");
const authMessage = document.getElementById("authMessage");
function isVolxer() {
return currentUser === "Volxer";
}
function makeFigureClowner(figure, skin) {
figure.classList.toggle("clowner", skin === "Clowner");
}
function updateSkinUI() {
if (isVolxer()) equippedSkin = "Clowner";
else if (equippedSkin === "Clowner") equippedSkin = "Blue";
makeFigureClowner(document.getElementById("lobbyFigure"), equippedSkin);
document.getElementById("lobbySkinName").textContent = equippedSkin.toUpperCase();
document.getElementById("careerSkin").textContent = equippedSkin;
document.querySelectorAll(".skin-card").forEach(card => {
const skin = card.dataset.skin;
card.classList.toggle("selected", skin === equippedSkin);
const button = card.querySelector(".select-skin");
if (skin === "Clowner" && !isVolxer()) {
card.classList.add("locked");
button.textContent = "LOCKED";
button.disabled = true;
} else {
card.classList.remove("locked");
button.disabled = false;
button.textContent = skin === equippedSkin ? "EQUIPPED" : "EQUIP";
}
});
}
document.getElementById("usernameForm").addEventListener("submit", function(e) {
e.preventDefault();
const username = usernameInput.value.trim();
if (!/^[A-Za-z0-9_]{3,20}$/.test(username)) {
authMessage.textContent =
"Use 3โ20 letters, numbers, or underscores.";
return;
}
// Only the exact spelling "Volxer" receives the special account.
if (username === "Volxer") {
const code = prompt("Volxer is reserved! Enter the secret code:");
if (code !== SECRET_CODE) {
authMessage.textContent = "Incorrect code. Volxer is reserved!";
return;
}
} else if (username.toLowerCase() === "volxer") {
authMessage.textContent =
"Please type Volxer with an uppercase V to use that username.";
return;
}
currentUser = username;
equippedSkin = isVolxer() ? "Clowner" : "Blue";
document.getElementById("headerUser").textContent = currentUser;
document.getElementById("careerUser").textContent = currentUser;
authScreen.classList.add("hidden");
game.classList.remove("hidden");
document.querySelectorAll(".page").forEach(page => page.classList.remove("active"));
document.getElementById("lobby").classList.add("active");
document.querySelectorAll("nav button").forEach(btn => btn.classList.remove("active"));
document.querySelector('nav button[data-tab="lobby"]').classList.add("active");
matchmaking = false;
document.getElementById("play").classList.remove("hidden");
document.getElementById("unready").classList.add("hidden");
document.getElementById("status").textContent = "Ready to play.";
updateSkinUI();
});
document.querySelectorAll("nav button[data-tab]").forEach(button => {
button.addEventListener("click", () => {
const tab = button.dataset.tab;
document.querySelectorAll("nav button").forEach(btn => btn.classList.remove("active"));
button.classList.add("active");
document.querySelectorAll(".page").forEach(page => page.classList.remove("active"));
document.getElementById(tab).classList.add("active");
});
});
document.querySelectorAll(".mode").forEach(button => {
button.addEventListener("click", () => {
selectedMode = button.dataset.mode;
document.querySelectorAll(".mode").forEach(btn => {
btn.classList.toggle("selected", btn === button);
});
document.getElementById("modeDescription").textContent =
selectedMode === "Solo"
? "Every player for themselves."
: "Team up with one other player.";
if (matchmaking) {
document.getElementById("status").textContent =
"Mode changed to " + selectedMode + ". Press PLAY to ready up again.";
matchmaking = false;
document.getElementById("play").classList.remove("hidden");
document.getElementById("unready").classList.add("hidden");
}
});
});
document.getElementById("play").addEventListener("click", () => {
matchmaking = true;
document.getElementById("play").classList.add("hidden");
document.getElementById("unready").classList.remove("hidden");
document.getElementById("status").textContent =
"MATCHMAKING... Mode: " + selectedMode;
});
document.getElementById("unready").addEventListener("click", () => {
matchmaking = false;
document.getElementById("play").classList.remove("hidden");
document.getElementById("unready").classList.add("hidden");
document.getElementById("status").textContent = "You are no longer queued.";
});
document.querySelectorAll(".select-skin").forEach(button => {
button.addEventListener("click", () => {
const card = button.closest(".skin-card");
const skin = card.dataset.skin;
if (skin === "Clowner" && !isVolxer()) {
document.getElementById("lockerNotice").textContent =
"Clowner is reserved for Volxer!";
return;
}
equippedSkin = skin;
document.getElementById("lockerNotice").textContent =
skin + " equipped!";
updateSkinUI();
});
});
document.getElementById("logout").addEventListener("click", () => {
currentUser = "";
equippedSkin = "Blue";
matchmaking = false;
usernameInput.value = "";
authMessage.textContent = "";
game.classList.add("hidden");
authScreen.classList.remove("hidden");
usernameInput.focus();
});
</script>
</body>
</html>
Game Source: Fortnite - Chapter 1 Season 1
Creator: StormPanda35
Libraries: none
Complexity: complex (561 lines, 16.6 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-stormpanda35" to link back to the original. Then publish at arcadelab.ai/publish.