diff --git a/equipment/equipment.js b/equipment/equipment.js
new file mode 100644
index 0000000..86d5a27
--- /dev/null
+++ b/equipment/equipment.js
@@ -0,0 +1,133 @@
+function loadHeader() {
+ fetch("../../../header.html")
+ .then(res => res.text())
+ .then(html => {
+ const headerContainer = document.getElementById("header-container");
+ if (headerContainer) {
+ headerContainer.innerHTML = html;
+
+ const stageButton = headerContainer.querySelector('.menu-item.stage');
+ if (stageButton) {
+ stageButton.classList.add('active');
+ }
+ }
+ })
+ .catch(err => console.error("Failed to load header:", err));
+}
+
+function animateLoadingCanvas() {
+ const canvas = document.getElementById("loading-canvas");
+ const loadingOverlay = document.getElementById("loading-overlay");
+ if (!canvas || !loadingOverlay) return;
+ const ctx = canvas.getContext("2d");
+ const image = new Image();
+ image.src = "/assets/en/loading/@2x-se6335ab797-cb27d69f23a4d1112bc2a0d272538f39dd3017be20e5f2e3f4a460bd0071b68d.png";
+ const frameWidth = 100;
+ const frameHeight = 100;
+ const totalFrames = 17;
+ let currentFrame = 0;
+ let lastUpdateTime = 0;
+ let animationId;
+ image.onload = () => {
+ function animate(timestamp = 0) {
+ if (loadingOverlay.style.display === "none") {
+ cancelAnimationFrame(animationId);
+ return;
+ }
+ if (!lastUpdateTime) lastUpdateTime = timestamp;
+ const elapsed = timestamp - lastUpdateTime;
+ if (elapsed > 50) {
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ ctx.drawImage(
+ image,
+ 0,
+ currentFrame * frameHeight,
+ frameWidth,
+ frameHeight,
+ 0,
+ 0,
+ frameWidth,
+ frameHeight
+ );
+ currentFrame = (currentFrame + 1) % totalFrames;
+ lastUpdateTime = timestamp;
+ }
+ animationId = requestAnimationFrame(animate);
+ }
+ animationId = requestAnimationFrame(animate);
+ };
+}
+
+//pain in the ass to implement. im proud of ts
+const canvas = document.getElementById("squid-canvas");
+const ctx = canvas.getContext("2d");
+const frameWidth = 64;
+const frameHeight = 64;
+const totalFrames = 8;
+const squidCount = 5;
+const squids = [];
+const canvasWidth = canvas.width;
+const canvasHeight = canvas.height;
+const titleYThreshold = 0;
+
+function createSquid() {
+ return {
+ x: Math.random() * canvasWidth,
+ y: canvasHeight + Math.random() * 300,
+ currentFrame: Math.floor(Math.random() * totalFrames),
+ speed: 0.05 + Math.random() * 0.15,
+ lastFrameUpdate: 0
+ };
+}
+
+for (let i = 0; i < squidCount; i++) {
+ squids.push(createSquid());
+}
+
+let lastTimestamp = 0;
+
+const image = new Image();
+image.src = "/assets/ika-8e075a29ff487983044303f98958fb8c852bc3e9ab07ee7597724b6c0aa4a5d7.png";
+
+image.onload = () => {
+ function animate(timestamp = 0) {
+ if (!lastTimestamp) lastTimestamp = timestamp;
+ const delta = timestamp - lastTimestamp;
+
+ ctx.clearRect(0, 0, canvasWidth, canvasHeight);
+
+ for (const squid of squids) {
+ squid.y -= squid.speed * delta;
+
+ if (squid.y + frameHeight < titleYThreshold) {
+ squid.x = Math.random() * canvasWidth;
+ squid.y = canvasHeight + Math.random() * 300;
+ squid.currentFrame = Math.floor(Math.random() * totalFrames);
+ squid.speed = 0.05 + Math.random() * 0.15;
+ }
+
+ if (timestamp - squid.lastFrameUpdate > 100) {
+ squid.currentFrame = (squid.currentFrame + 1) % totalFrames;
+ squid.lastFrameUpdate = timestamp;
+ }
+
+ ctx.drawImage(
+ image,
+ squid.currentFrame * frameWidth,
+ 0,
+ frameWidth,
+ frameHeight,
+ squid.x,
+ squid.y,
+ frameWidth,
+ frameHeight
+ );
+ }
+
+ lastTimestamp = timestamp;
+ requestAnimationFrame(animate);
+ }
+ requestAnimationFrame(animate);
+};
+
+animateLoadingCanvas();
\ No newline at end of file
diff --git a/equipment/index.html b/equipment/index.html
new file mode 100644
index 0000000..8a5b713
--- /dev/null
+++ b/equipment/index.html
@@ -0,0 +1,44 @@
+
+
+
+
+ SplatNet - Splatoon's multiplayer service hub
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/equipment/styles.css b/equipment/styles.css
new file mode 100644
index 0000000..61aba75
--- /dev/null
+++ b/equipment/styles.css
@@ -0,0 +1,106 @@
+@font-face {
+ font-family: "Splatoon1";
+ src: url("../splatoon1.otf") format("opentype");
+ font-weight: normal;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: "Regular";
+ src: url("../regular.otf") format("opentype");
+ font-weight: normal;
+ font-style: normal;
+}
+
+html {
+ height: 100%;
+}
+
+body {
+ margin: 0;
+ padding: 0;
+ display: flex;
+ align-items: flex-start;
+ min-height: 100vh;
+ background-image: url("/assets/en/bg/@2x/bg_equipment-bedf92d6f41ee59b7f391f7e01d7ec00cb932e5152a2196ac939df0ad6c674b3.png");
+ background-repeat: repeat;
+ background-size: 800px 800px;
+ background-attachment: fixed;
+}
+
+.menu-item .hover-state {
+ display: none;
+}
+
+.menu-item:hover .hover-state,
+.menu-item.active .hover-state {
+ display: block;
+}
+
+.menu-item:hover .default,
+.menu-item.active .default {
+ display: none;
+}
+
+.loading-overlay {
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 200px;
+ height: 250px;
+ background-color: rgba(0,0,0,0.8);
+ border: 3px solid white;
+ border-radius: 12px;
+ padding: 20px 24px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ z-index: 9999;
+ user-select: none;
+ pointer-events: none;
+ box-sizing: border-box;
+}
+
+#loading-canvas {
+ image-rendering: pixelated;
+ width: 100px;
+ height: 100px;
+ display: block;
+ margin: 0 auto;
+}
+
+#loading-text {
+ margin-top: 12px;
+ color: white;
+ font-family: "Splatoon1", sans-serif;
+ font-size: 20px;
+ letter-spacing: 1.2px;
+ text-align: center;
+}
+
+#squid-container {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100vh;
+ overflow: visible;
+ pointer-events: none;
+ z-index: 0;
+}
+
+#squid-canvas {
+ position: absolute;
+ left: 50%;
+ top: 0;
+ transform: translateX(-50%);
+ width: 1920px;
+ height: 1080px;
+ will-change: transform;
+ pointer-events: none;
+ user-select: none;
+ z-index: 0;
+ display: block;
+}
\ No newline at end of file
diff --git a/friend_list/friendlist.js b/friend_list/friendlist.js
new file mode 100644
index 0000000..86d5a27
--- /dev/null
+++ b/friend_list/friendlist.js
@@ -0,0 +1,133 @@
+function loadHeader() {
+ fetch("../../../header.html")
+ .then(res => res.text())
+ .then(html => {
+ const headerContainer = document.getElementById("header-container");
+ if (headerContainer) {
+ headerContainer.innerHTML = html;
+
+ const stageButton = headerContainer.querySelector('.menu-item.stage');
+ if (stageButton) {
+ stageButton.classList.add('active');
+ }
+ }
+ })
+ .catch(err => console.error("Failed to load header:", err));
+}
+
+function animateLoadingCanvas() {
+ const canvas = document.getElementById("loading-canvas");
+ const loadingOverlay = document.getElementById("loading-overlay");
+ if (!canvas || !loadingOverlay) return;
+ const ctx = canvas.getContext("2d");
+ const image = new Image();
+ image.src = "/assets/en/loading/@2x-se6335ab797-cb27d69f23a4d1112bc2a0d272538f39dd3017be20e5f2e3f4a460bd0071b68d.png";
+ const frameWidth = 100;
+ const frameHeight = 100;
+ const totalFrames = 17;
+ let currentFrame = 0;
+ let lastUpdateTime = 0;
+ let animationId;
+ image.onload = () => {
+ function animate(timestamp = 0) {
+ if (loadingOverlay.style.display === "none") {
+ cancelAnimationFrame(animationId);
+ return;
+ }
+ if (!lastUpdateTime) lastUpdateTime = timestamp;
+ const elapsed = timestamp - lastUpdateTime;
+ if (elapsed > 50) {
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ ctx.drawImage(
+ image,
+ 0,
+ currentFrame * frameHeight,
+ frameWidth,
+ frameHeight,
+ 0,
+ 0,
+ frameWidth,
+ frameHeight
+ );
+ currentFrame = (currentFrame + 1) % totalFrames;
+ lastUpdateTime = timestamp;
+ }
+ animationId = requestAnimationFrame(animate);
+ }
+ animationId = requestAnimationFrame(animate);
+ };
+}
+
+//pain in the ass to implement. im proud of ts
+const canvas = document.getElementById("squid-canvas");
+const ctx = canvas.getContext("2d");
+const frameWidth = 64;
+const frameHeight = 64;
+const totalFrames = 8;
+const squidCount = 5;
+const squids = [];
+const canvasWidth = canvas.width;
+const canvasHeight = canvas.height;
+const titleYThreshold = 0;
+
+function createSquid() {
+ return {
+ x: Math.random() * canvasWidth,
+ y: canvasHeight + Math.random() * 300,
+ currentFrame: Math.floor(Math.random() * totalFrames),
+ speed: 0.05 + Math.random() * 0.15,
+ lastFrameUpdate: 0
+ };
+}
+
+for (let i = 0; i < squidCount; i++) {
+ squids.push(createSquid());
+}
+
+let lastTimestamp = 0;
+
+const image = new Image();
+image.src = "/assets/ika-8e075a29ff487983044303f98958fb8c852bc3e9ab07ee7597724b6c0aa4a5d7.png";
+
+image.onload = () => {
+ function animate(timestamp = 0) {
+ if (!lastTimestamp) lastTimestamp = timestamp;
+ const delta = timestamp - lastTimestamp;
+
+ ctx.clearRect(0, 0, canvasWidth, canvasHeight);
+
+ for (const squid of squids) {
+ squid.y -= squid.speed * delta;
+
+ if (squid.y + frameHeight < titleYThreshold) {
+ squid.x = Math.random() * canvasWidth;
+ squid.y = canvasHeight + Math.random() * 300;
+ squid.currentFrame = Math.floor(Math.random() * totalFrames);
+ squid.speed = 0.05 + Math.random() * 0.15;
+ }
+
+ if (timestamp - squid.lastFrameUpdate > 100) {
+ squid.currentFrame = (squid.currentFrame + 1) % totalFrames;
+ squid.lastFrameUpdate = timestamp;
+ }
+
+ ctx.drawImage(
+ image,
+ squid.currentFrame * frameWidth,
+ 0,
+ frameWidth,
+ frameHeight,
+ squid.x,
+ squid.y,
+ frameWidth,
+ frameHeight
+ );
+ }
+
+ lastTimestamp = timestamp;
+ requestAnimationFrame(animate);
+ }
+ requestAnimationFrame(animate);
+};
+
+animateLoadingCanvas();
\ No newline at end of file
diff --git a/friend_list/index.html b/friend_list/index.html
new file mode 100644
index 0000000..b1a4ca3
--- /dev/null
+++ b/friend_list/index.html
@@ -0,0 +1,44 @@
+
+
+
+
+ SplatNet - Splatoon's multiplayer service hub
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/friend_list/styles.css b/friend_list/styles.css
new file mode 100644
index 0000000..56fea98
--- /dev/null
+++ b/friend_list/styles.css
@@ -0,0 +1,106 @@
+@font-face {
+ font-family: "Splatoon1";
+ src: url("../splatoon1.otf") format("opentype");
+ font-weight: normal;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: "Regular";
+ src: url("../regular.otf") format("opentype");
+ font-weight: normal;
+ font-style: normal;
+}
+
+html {
+ height: 100%;
+}
+
+body {
+ margin: 0;
+ padding: 0;
+ display: flex;
+ align-items: flex-start;
+ min-height: 100vh;
+ background-image: url("/assets/en/bg/@2x/bg_friendlist-d20dccde83e0d769455ff580421b84805be7ff1c6494e812200a51d067b10be0.png");
+ background-repeat: repeat;
+ background-size: 800px 800px;
+ background-attachment: fixed;
+}
+
+.menu-item .hover-state {
+ display: none;
+}
+
+.menu-item:hover .hover-state,
+.menu-item.active .hover-state {
+ display: block;
+}
+
+.menu-item:hover .default,
+.menu-item.active .default {
+ display: none;
+}
+
+.loading-overlay {
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 200px;
+ height: 250px;
+ background-color: rgba(0,0,0,0.8);
+ border: 3px solid white;
+ border-radius: 12px;
+ padding: 20px 24px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ z-index: 9999;
+ user-select: none;
+ pointer-events: none;
+ box-sizing: border-box;
+}
+
+#loading-canvas {
+ image-rendering: pixelated;
+ width: 100px;
+ height: 100px;
+ display: block;
+ margin: 0 auto;
+}
+
+#loading-text {
+ margin-top: 12px;
+ color: white;
+ font-family: "Splatoon1", sans-serif;
+ font-size: 20px;
+ letter-spacing: 1.2px;
+ text-align: center;
+}
+
+#squid-container {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100vh;
+ overflow: visible;
+ pointer-events: none;
+ z-index: 0;
+}
+
+#squid-canvas {
+ position: absolute;
+ left: 50%;
+ top: 0;
+ transform: translateX(-50%);
+ width: 1920px;
+ height: 1080px;
+ will-change: transform;
+ pointer-events: none;
+ user-select: none;
+ z-index: 0;
+ display: block;
+}
\ No newline at end of file
diff --git a/header.html b/header.html
index b6aecb4..6806643 100644
--- a/header.html
+++ b/header.html
@@ -11,49 +11,49 @@
-
+
-
+
-
+
-
+