updated sites UI, added links

This commit is contained in:
2026-08-22 11:02:53 -07:00
parent 6e4074bf95
commit efd547c578
22 changed files with 1337 additions and 508 deletions

View File

@@ -1,132 +0,0 @@
[
{
"image": "assets/static/background-with-logo.png",
"alt": "Soluna Script Loader Screenshot",
"title": "Soluna Script Loader",
"links": [
{
"href": "https://gitlab.com/soluna-development/api/-/raw/main/src/Loader.lua"
}
]
},
{
"image": "https://tr.rbxcdn.com/180DAY-15eb19b4816654a3270689171a3dbdef/768/432/Image/Webp/noFilter",
"alt": "Rivals Classic Script Screenshot",
"title": "Rivals Classic",
"links": [
{
"href": "https://gitlab.com/soluna-development/api/-/raw/main/src/scripts/Rivals/Classic.lua"
}
]
},
{
"image": "https://tr.rbxcdn.com/180DAY-27507ba164fae9b46c68047d34d0078b/768/432/Image/Webp/noFilter",
"alt": "Rivals Modern Script Screenshot",
"title": "Rivals Modern",
"links": [
{
"href": "https://gitlab.com/soluna-development/api/-/raw/main/src/scripts/Rivals/Modern.lua"
}
]
},
{
"image": "https://tr.rbxcdn.com/180DAY-4ca6e066ef51f10829f653ca849f350d/768/432/Image/Webp/noFilter",
"alt": "Rivals Rewrite Script Screenshot",
"title": "Rivals Rewrite",
"links": [
{
"href": "https://gitlab.com/soluna-development/api/-/raw/main/src/scripts/Rivals/Rewrite.lua"
}
]
},
{
"image": "https://tr.rbxcdn.com/180DAY-c66296c3f8c6e16eb6f6eecca67c4710/768/432/Image/Webp/noFilter",
"alt": "Rivals Skin Changer Script Screenshot",
"title": "Rivals Skin Changer",
"links": [
{
"href": "https://gitlab.com/soluna-development/api/-/raw/main/src/scripts/Rivals/Skin-Changer.lua"
}
]
},
{
"image": "https://tr.rbxcdn.com/180DAY-fd5d29ef7df403915891862d02ae09bb/768/432/Image/Webp/noFilter",
"alt": "Arsenal Script Screenshot",
"title": "Arsenal",
"links": [
{
"href": "https://gitlab.com/soluna-development/api/-/raw/main/src/scripts/Arsenal.lua"
}
]
},
{
"image": "https://tr.rbxcdn.com/180DAY-aa0679c96e6ce33f961087cebcc07ce6/768/432/Image/Webp/noFilter",
"alt": "Blade Ball Script Screenshot",
"title": "Blade Ball",
"links": [
{
"href": "https://gitlab.com/soluna-development/api/-/raw/main/src/scripts/Bladeball.lua"
}
]
},
{
"image": "https://tr.rbxcdn.com/180DAY-fe7335c3ad752e84323cd81ae38de69a/768/432/Image/Webp/noFilter",
"alt": "Murder Mystery 2 Script Screenshot",
"title": "Murder Mystery 2",
"links": [
{
"href": "https://gitlab.com/soluna-development/api/-/raw/main/src/scripts/Murder-Mystery-2.lua"
}
]
},
{
"image": "https://tr.rbxcdn.com/180DAY-643b9b9285f3bd9b63cf392db12a4d87/768/432/Image/Webp/noFilter",
"alt": "99 Nights in the Forest Script Screenshot",
"title": "99 Nights in the Forest",
"links": [
{
"href": "https://gitlab.com/soluna-development/api/-/raw/main/src/scripts/99-Nights-in-the-Forest.lua"
}
]
},
{
"image": "https://tr.rbxcdn.com/180DAY-9fb820a5978cb6a5125861c3f0cbe131/768/432/Image/Webp/noFilter",
"alt": "The Wild West Script Screenshot",
"title": "The Wild West",
"links": [
{
"href": "https://gitlab.com/soluna-development/api/-/raw/main/src/scripts/The-Wild-West.lua"
}
]
},
{
"image": "https://tr.rbxcdn.com/180DAY-09f0d9b97f35839568ec129016b18485/768/432/Image/Webp/noFilter",
"alt": "Doors Script Screenshot",
"title": "Doors",
"links": [
{
"href": "https://gitlab.com/soluna-development/api/-/raw/main/src/scripts/Doors.lua"
}
]
},
{
"image": "https://tr.rbxcdn.com/180DAY-20254f91c5043de87f6cc8adb218c624/768/432/Image/Webp/noFilter",
"alt": "Fling Things and People Script Screenshot",
"title": "Fling Things and People",
"links": [
{
"href": "https://gitlab.com/soluna-development/api/-/raw/main/src/scripts/Fling-Things-and-People.lua"
}
]
},
{
"image": "https://tr.rbxcdn.com/180DAY-be85b5af1040324de15123ab4208cf84/768/432/Image/Webp/noFilter",
"alt": "Murderers VS Sheriffs DUELS Script Screenshot",
"title": "Murderers VS Sheriffs DUELS",
"links": [
{
"href": "https://gitlab.com/soluna-development/api/-/raw/main/src/scripts/Murderers-VS-Sheriffs-DUELS.lua"
}
]
}
]

View File

@@ -3,14 +3,12 @@ export const DISCORD_INVITE_URL = `https://discord.gg/${DISCORD_INVITE_CODE}`;
export const DISCORD_LOADER_SCRIPT = 'loadstring(game:HttpGet("https://gitlab.com/soluna-development/api/-/raw/main/src/Loader.lua"))()';
export const DATA_PATHS = {
scripts: 'src/data/scripts.json',
partners: 'src/data/partners.json',
reviews: 'src/data/reviews.json',
showcases: 'src/data/showcases.json',
};
export const DISCORD_INVITE_API = `https://discord.com/api/v10/invites/${DISCORD_INVITE_CODE}?with_counts=true`;
export const WEAO_EXECUTORS_ENDPOINT = 'https://weao.xyz/api/status/exploits';
export const COPY_FEEDBACK_DURATION_MS = 1800;
export const REVEAL_THRESHOLD = 0.15;

View File

@@ -1,34 +1,18 @@
import { observeReveals } from './animations/reveal-observer.js';
import { initHeroSection } from './sections/hero.js';
import { initStatsSection } from './sections/stats.js';
import { initScriptsSection } from './sections/scripts.js';
import { initTestimonialsSection } from './sections/testimonials.js';
import { initExecutorsSection } from './sections/executors.js';
import { initShowcasesSection } from './sections/showcases.js';
import { initPartnersSection } from './sections/partners.js';
import { initFaqSection } from './sections/faq.js';
import { getExecutors } from './services/executors-service.js';
import { initStatsSection } from './sections/stats.js';
function initApp() {
observeReveals();
initHeroSection();
initStatsSection();
initScriptsSection();
initTestimonialsSection();
initExecutorsSection();
initShowcasesSection();
initPartnersSection();
initFaqSection();
window.debugExecutors = async () => {
try {
const executors = await getExecutors();
return executors;
} catch (error) {
throw error;
}
};
}
document.addEventListener('DOMContentLoaded', initApp);

View File

@@ -1,35 +0,0 @@
import { getExecutors } from '../services/executors-service.js';
import { createElement } from '../utils/dom.js';
import { createMarqueeLoop, populateLoopedTrack } from '../animations/marquee-loop.js';
const EXECUTOR_ITEM_WIDTH_PX = 180;
const BASE_SPEED = 0.35;
const BOOSTED_SPEED = 2.2;
function createExecutorItem(executor) {
const el = createElement('div', 'executor-item');
const avatar = executor.image
? `<img src="${executor.image}" alt="" onerror="this.parentElement.innerHTML=''" width="28" height="28" loading="lazy" decoding="async">`
: '';
el.innerHTML = `
<span class="executor-avatar">${avatar}</span>
<span class="executor-name">${executor.name}</span>
`;
return el;
}
export async function initExecutorsSection() {
const track = document.getElementById('executors-track');
if (!track) return;
try {
const executors = await getExecutors();
populateLoopedTrack(track, executors, createExecutorItem, EXECUTOR_ITEM_WIDTH_PX);
createMarqueeLoop(track, '--marquee-x', { baseSpeed: BASE_SPEED, boostedSpeed: BOOSTED_SPEED });
} catch (error) {
const wrap = document.querySelector('.executors-marquee-wrap');
if (wrap) {
wrap.innerHTML = '<p style="color: var(--color-muted); text-align:center; width:100%">executors unavailable.</p>';
}
}
}

View File

@@ -1,40 +0,0 @@
import { getScripts } from '../services/scripts-service.js';
import { createScriptCard } from '../components/script-card.js';
import { debounce, isMobileViewport } from '../utils/dom.js';
let snapObserver = null;
function setupSnapGlow(grid) {
if (snapObserver) snapObserver.disconnect();
if (!isMobileViewport()) return;
snapObserver = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
entry.target.classList.toggle('in-snap', entry.intersectionRatio >= 0.7);
});
},
{ root: grid, threshold: [0, 0.7, 1] }
);
grid.querySelectorAll('.script-card').forEach((card) => snapObserver.observe(card));
}
export async function initScriptsSection() {
const grid = document.getElementById('scripts-grid');
if (!grid) return;
try {
const scripts = await getScripts();
grid.innerHTML = '';
scripts.forEach((script) => {
const card = createScriptCard(script);
grid.appendChild(card);
});
setupSnapGlow(grid);
window.addEventListener('resize', debounce(() => setupSnapGlow(grid), 200));
} catch (error) {
grid.innerHTML = '<p style="color: var(--color-muted)">scripts unavailable.</p>';
}
}

View File

@@ -1,23 +0,0 @@
import { getShowcaseVideos } from '../services/showcases-service.js';
import { createShowcaseItem } from '../components/showcase-item.js';
import { createMarqueeLoop, populateLoopedTrack } from '../animations/marquee-loop.js';
const SHOWCASE_ITEM_WIDTH_PX = 280;
const BASE_SPEED = 0.4;
const BOOSTED_SPEED = 2.4;
export async function initShowcasesSection() {
const track = document.getElementById('showcase-track');
if (!track) return;
try {
const videos = await getShowcaseVideos();
populateLoopedTrack(track, videos, createShowcaseItem, SHOWCASE_ITEM_WIDTH_PX);
createMarqueeLoop(track, '--showcase-x', { baseSpeed: BASE_SPEED, boostedSpeed: BOOSTED_SPEED });
} catch (error) {
const viewport = document.querySelector('.showcase-viewport');
if (viewport) {
viewport.innerHTML = '<p style="color: var(--color-muted); text-align:center; width:100%">showcases unavailable.</p>';
}
}
}

View File

@@ -1,43 +0,0 @@
import { WEAO_EXECUTORS_ENDPOINT } from '../config/constants.js';
function faviconFromUrl(websiteUrl) {
try {
const host = new URL(websiteUrl).hostname;
return `https://favicone.com/${host}?s=64`;
} catch (error) {
return '';
}
}
function dedupeByName(executors) {
return executors.filter(
(executor, index, all) => all.findIndex((e) => e.name === executor.name) === index
);
}
export async function getExecutors() {
const response = await fetch(WEAO_EXECUTORS_ENDPOINT, {
headers: {
'User-Agent': 'WEAO-3PService'
}
});
if (!response.ok) {
throw new Error(`Failed to fetch executor status: ${response.status} ${response.statusText}`);
}
const data = await response.json();
if (!Array.isArray(data) || data.length === 0) {
throw new Error('Empty executor response');
}
const executors = data
.filter((entry) => !entry.hidden && entry.extype !== 'wexternal')
.map((entry) => ({
name: entry.title,
image: entry.websitelink ? faviconFromUrl(entry.websitelink) : '',
}));
return dedupeByName(executors);
}

View File

@@ -1,59 +0,0 @@
.executors-marquee-wrap {
position: relative;
width: 100%;
}
.executors-marquee-row {
overflow: hidden;
width: 100%;
}
.executors-marquee-track {
display: flex;
align-items: center;
gap: clamp(2rem, 5vw, 3.5rem);
width: max-content;
transform: translate3d(var(--marquee-x, 0px), 0, 0);
will-change: transform;
}
.executor-item {
display: flex;
align-items: center;
gap: 0.625rem;
flex-shrink: 0;
opacity: 0.45;
filter: grayscale(0.3);
transition: opacity var(--duration-base) ease, filter var(--duration-base) ease;
}
.executor-item:hover {
opacity: 1;
filter: grayscale(0);
}
.executor-avatar {
width: 28px;
height: 28px;
border-radius: 8px;
background: var(--color-border);
overflow: hidden;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
}
.executor-avatar img {
width: 100%;
height: 100%;
object-fit: cover;
}
.executor-name {
font-size: clamp(0.95rem, 2vw, 1.15rem);
font-weight: 700;
color: var(--color-fg);
white-space: nowrap;
letter-spacing: -0.01em;
}

View File

@@ -3,7 +3,7 @@
flex-direction: column;
align-items: center;
gap: 0.85rem;
padding-top: 120px;
padding-top: 3rem;
}
.partners-label {

View File

@@ -1,77 +0,0 @@
.showcase-viewport {
overflow: hidden;
-webkit-mask-image: linear-gradient(90deg, transparent 0, #000 6%, #000 94%, transparent 100%);
mask-image: linear-gradient(90deg, transparent 0, #000 6%, #000 94%, transparent 100%);
}
.showcase-track {
display: flex;
width: max-content;
gap: clamp(0.75rem, 1.5vw, 1.25rem);
transform: translate3d(var(--showcase-x, 0px), 0, 0);
will-change: transform;
}
.showcase-item {
flex: 0 0 auto;
width: clamp(220px, 22vw, 280px);
opacity: 0;
transition: opacity var(--duration-base) ease;
}
.showcase-item.loaded {
opacity: 1;
}
.showcase-card {
position: relative;
display: block;
width: 100%;
aspect-ratio: 16 / 9;
border-radius: var(--radius-md);
overflow: hidden;
background: var(--color-border);
cursor: pointer;
border: none;
padding: 0;
transition: transform var(--duration-base) var(--ease-standard);
}
.showcase-thumb {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
transition: filter var(--duration-base) ease;
}
.showcase-card:hover .showcase-thumb {
filter: brightness(0.7);
}
.showcase-play {
position: absolute;
inset: 0;
margin: auto;
width: 46px;
height: 46px;
display: flex;
align-items: center;
justify-content: center;
border-radius: var(--radius-pill);
background: rgba(0, 0, 0, 0.55);
color: #fff;
pointer-events: none;
transition: background var(--duration-fast) ease, transform var(--duration-fast) ease;
}
.showcase-card:hover .showcase-play {
background: rgba(0, 0, 0, 0.75);
transform: scale(1.08);
}
@media (max-width: 640px) {
.showcase-item {
width: clamp(200px, 62vw, 260px);
}
}

View File

@@ -14,8 +14,8 @@
font-weight: 400
}
.footer-section h4 {
font-size: 16px;
.footer-section h2 {
font-size: 1rem;
font-weight: 700;
margin-bottom: 7px
}

View File

@@ -0,0 +1,82 @@
.content-wrapper {
width: min(900px, calc(100% - 2 * var(--content-padding-inline)));
margin: 0 auto;
padding: var(--space-3xl) 0 var(--space-4xl);
color: var(--color-fg);
font-family: var(--font-body);
line-height: 1.7;
}
.content-wrapper h2 {
margin: 0 0 var(--space-xs);
color: var(--color-fg);
font-family: var(--font-display);
font-size: 2rem;
font-weight: 700;
letter-spacing: -0.03em;
line-height: 1.2;
}
.content-wrapper h3 {
margin: var(--space-2xl) 0 var(--space-sm);
color: var(--color-fg);
font-family: var(--font-display);
font-size: 1.1rem;
font-weight: 650;
letter-spacing: -0.015em;
line-height: 1.4;
}
.content-wrapper p {
margin: 0 0 var(--space-lg);
color: var(--color-fg-dim);
font-size: 0.95rem;
}
.content-wrapper>p:first-of-type {
margin-bottom: var(--space-2xl);
color: var(--color-muted);
font-size: 0.875rem;
}
.content-wrapper strong {
color: var(--color-fg);
font-weight: 600;
}
.content-wrapper ul {
margin: calc(var(--space-xs) * -1) 0 var(--space-lg);
padding-left: var(--space-xl);
color: var(--color-fg-dim);
}
.content-wrapper li {
margin-bottom: var(--space-sm);
padding-left: var(--space-3xs);
}
.content-wrapper li::marker {
color: var(--color-muted);
}
@media (max-width: 600px) {
.content-wrapper {
width: calc(100% - 2 * var(--content-padding-inline));
padding-top: var(--space-2xl);
padding-bottom: var(--space-3xl);
}
.content-wrapper h2 {
font-size: 1.65rem;
}
.content-wrapper h3 {
margin-top: var(--space-xl);
font-size: 1rem;
}
.content-wrapper p,
.content-wrapper li {
font-size: 0.9rem;
}
}

View File

@@ -77,6 +77,10 @@
border-radius: var(--radius-lg);
background: var(--color-bg-card);
overflow: hidden;
mask-composite: intersect;
mask-image: linear-gradient(to top, transparent, black 50%), linear-gradient(to top, transparent, black 20%);
mask-repeat: no-repeat;
mask-size: 100% 100%;
}
.feature-block,

View File

@@ -78,4 +78,61 @@
.hero-container {
padding-top: 0px;
}
}
.hero-preview-wrap {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
max-width: 980px;
margin-top: 2.25rem;
position: relative;
}
.platform-pill {
display: inline-flex;
align-items: center;
gap: 0.5rem;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(8px) saturate(140%);
-webkit-backdrop-filter: blur(8px) saturate(140%);
border: none;
padding: 0.35rem 0.85rem;
border-radius: var(--radius-pill);
font-size: 0.75rem;
font-weight: 500;
color: var(--color-fg-dim);
margin-bottom: 1.25rem;
}
.platform-pill svg {
color: var(--color-fg);
}
.hero-screen-mockup {
position: relative;
width: 100%;
overflow: hidden;
}
.hero-screen-mockup img {
width: 100%;
height: auto;
display: block;
aspect-ratio: 16 / 9;
object-fit: cover;
}
@media (max-width: 768px) {
.hero-preview-wrap {
margin-top: 1.75rem;
}
}
@media (orientation: landscape) and (max-width: 1024px) {
.hero-screen-mockup {
width: 60%;
margin-right: auto;
}
}

View File

@@ -1,13 +0,0 @@
.showcases-section {
padding: clamp(3rem, 7vw, 5rem) 0 clamp(2rem, 6vw, 4rem);
overflow: hidden;
}
.showcases-heading {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.5rem;
text-align: center;
margin-bottom: clamp(2rem, 5vw, 3rem);
}