diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bc1742d..a1b6623 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,7 +6,7 @@ name: Release # Optional repository variables (Settings → Secrets and variables → Actions → Variables): # PANEL_URL https://panel.example.com — baked into the launcher as the default server # LOCK_PANEL "1" to stop players from changing the server -# LAUNCHER_NAME Installer / window name (default "ScopeNet Launcher") +# LAUNCHER_NAME Installer / window name (default "SCOPENET Launcher") on: push: diff --git a/Dockerfile b/Dockerfile index c0564c9..f3a1f2a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # syntax=docker/dockerfile:1.7 # -# ScopeNet admin panel — a single static binary + the web UI on `scratch`. +# SCOPENET admin panel — a single static binary + the web UI on `scratch`. # Multi-arch (amd64/arm64) is cross-compiled with cargo-zigbuild on the # build machine's native arch, so no slow QEMU emulation is needed. @@ -29,7 +29,7 @@ WORKDIR /src COPY . . # No --locked: release builds stamp the version into Cargo.toml. Dependencies # stay pinned by Cargo.lock either way (CI enforces --locked). -RUN --mount=type=cache,target=/usr/local/cargo/registry,id=cargo-registry \ +RUN --mount=type=cache,target=/usr/local/cargo/registry,id=cargo-registry,sharing=locked \ --mount=type=cache,target=/src/target,id=scopenet-target-$TARGETARCH \ cargo zigbuild --release -p scopenet-panel --target "$(cat /rust-target)" \ && cp "target/$(cat /rust-target)/release/scopenet-panel" /scopenet-panel @@ -38,8 +38,8 @@ RUN mkdir -p /out/data && chown 65532:65532 /out/data # ---- 3. Runtime -------------------------------------------------------------- FROM scratch -LABEL org.opencontainers.image.title="ScopeNet Panel" \ - org.opencontainers.image.description="Admin panel for the ScopeNet Minecraft launcher" \ +LABEL org.opencontainers.image.title="SCOPENET Panel" \ + org.opencontainers.image.description="Admin panel for the SCOPENET Minecraft launcher" \ org.opencontainers.image.source="https://github.com/scopeddlol/SCOPENET-MC" COPY --from=build /scopenet-panel /scopenet-panel COPY --from=web /src/panel/web/dist /web diff --git a/README.md b/README.md index cdf4580..3d81459 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ -# ScopeNet +# SCOPENET **A fast, fully customisable Minecraft launcher — and the self-hosted admin panel that controls it.** @@ -117,5 +117,5 @@ docker-compose.yml Panel deployment ## Notes -- Minecraft is a trademark of Mojang Studios. ScopeNet is not affiliated with Mojang or Microsoft. Offline mode is intended for your own community servers. +- Minecraft is a trademark of Mojang Studios. SCOPENET is not affiliated with Mojang or Microsoft. Offline mode is intended for your own community servers. - No license has been chosen yet — add a `LICENSE` file before distributing. diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index c240206..b6ebcf9 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "scopenet-core" -description = "Minecraft install / launch engine used by the ScopeNet launcher (and meta lookups in the panel)" +description = "Minecraft install / launch engine used by the SCOPENET launcher (and meta lookups in the panel)" version.workspace = true edition.workspace = true diff --git a/crates/core/src/http.rs b/crates/core/src/http.rs index a9967f7..0916859 100644 --- a/crates/core/src/http.rs +++ b/crates/core/src/http.rs @@ -13,7 +13,7 @@ use std::sync::Arc; use std::time::{Duration, Instant}; use tokio::io::AsyncWriteExt; -pub const USER_AGENT: &str = concat!("ScopeNet-Launcher/", env!("CARGO_PKG_VERSION"), " (+https://github.com/scopeddlol/SCOPENET-MC)"); +pub const USER_AGENT: &str = concat!("SCOPENET-Launcher/", env!("CARGO_PKG_VERSION"), " (+https://github.com/scopeddlol/SCOPENET-MC)"); pub fn client() -> reqwest::Client { reqwest::Client::builder() diff --git a/crates/core/src/launch.rs b/crates/core/src/launch.rs index ee82876..bac1fc2 100644 --- a/crates/core/src/launch.rs +++ b/crates/core/src/launch.rs @@ -346,7 +346,7 @@ mod tests { resolution: Some((1280, 720)), fullscreen: false, join_server: join.then(|| ("play.example.net".to_string(), 25565)), - version_label: "ScopeNet".into(), + version_label: "SCOPENET".into(), launcher_name: "scopenet".into(), launcher_version: "0.1.0".into(), } @@ -368,7 +368,7 @@ mod tests { assert!(a.contains("--width 1280 --height 720")); assert!(a.contains("--quickPlayMultiplayer play.example.net:25565")); assert!(!a.contains("--server")); - assert!(a.contains("--versionType ScopeNet")); + assert!(a.contains("--versionType SCOPENET")); assert!(a.contains("-Djava.library.path=/n")); } diff --git a/crates/core/src/lib.rs b/crates/core/src/lib.rs index dd2b42a..517d024 100644 --- a/crates/core/src/lib.rs +++ b/crates/core/src/lib.rs @@ -1,4 +1,4 @@ -//! ScopeNet launcher engine. +//! SCOPENET launcher engine. //! //! The Tauri app is a thin UI shell around this crate: everything that //! downloads, installs or launches Minecraft lives here so it can be unit diff --git a/crates/core/src/servers_dat.rs b/crates/core/src/servers_dat.rs index 70918e7..06a8bbc 100644 --- a/crates/core/src/servers_dat.rs +++ b/crates/core/src/servers_dat.rs @@ -76,9 +76,9 @@ mod tests { fn upserts_without_losing_player_servers() { let dir = tempfile::tempdir().unwrap(); upsert(dir.path(), "Friend", "friend.net").unwrap(); - upsert(dir.path(), "ScopeNet", "play.scopenet.gg").unwrap(); - upsert(dir.path(), "ScopeNet SMP", "play.scopenet.gg").unwrap(); - assert_eq!(names(dir.path()), vec![("ScopeNet SMP".into(), "play.scopenet.gg".into()), ("Friend".into(), "friend.net".into())]); + upsert(dir.path(), "SCOPENET", "play.scopenet.gg").unwrap(); + upsert(dir.path(), "SCOPENET SMP", "play.scopenet.gg").unwrap(); + assert_eq!(names(dir.path()), vec![("SCOPENET SMP".into(), "play.scopenet.gg".into()), ("Friend".into(), "friend.net".into())]); assert_eq!(format_address("a.b", 25565), "a.b"); assert_eq!(format_address("a.b", 25570), "a.b:25570"); } diff --git a/crates/core/src/sys.rs b/crates/core/src/sys.rs index b2f56b1..088a258 100644 --- a/crates/core/src/sys.rs +++ b/crates/core/src/sys.rs @@ -11,7 +11,7 @@ fn imp() -> Option { let mut status: MEMORYSTATUSEX = unsafe { std::mem::zeroed() }; status.dwLength = std::mem::size_of::() as u32; let ok = unsafe { GlobalMemoryStatusEx(&mut status) }; - (ok != 0).then(|| status.ullTotalPhys / 1024 / 1024) + (ok != 0).then_some(status.ullTotalPhys / 1024 / 1024) } #[cfg(target_os = "linux")] diff --git a/crates/shared/Cargo.toml b/crates/shared/Cargo.toml index ff08c23..015a2aa 100644 --- a/crates/shared/Cargo.toml +++ b/crates/shared/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "scopenet-shared" -description = "Types shared between the ScopeNet launcher and admin panel" +description = "Types shared between the SCOPENET launcher and admin panel" version.workspace = true edition.workspace = true diff --git a/crates/shared/src/lib.rs b/crates/shared/src/lib.rs index 6d7b001..aea8358 100644 --- a/crates/shared/src/lib.rs +++ b/crates/shared/src/lib.rs @@ -1,4 +1,4 @@ -//! Wire types shared by the ScopeNet launcher and the admin panel. +//! Wire types shared by the SCOPENET launcher and the admin panel. //! //! Everything the panel sends to the launcher is described here, so both //! sides always agree on the JSON shape. @@ -39,19 +39,19 @@ pub struct Branding { impl Default for Branding { fn default() -> Self { Self { - name: "ScopeNet".into(), + name: "SCOPENET".into(), tagline: "Your worlds, one click away.".into(), logo_url: None, icon_url: None, background: Background::default(), colors: Palette::default(), - font: "Outfit".into(), - radius: 14, - glass: true, - version_label: "ScopeNet".into(), + font: "Inter".into(), + radius: 10, + glass: false, + version_label: "SCOPENET".into(), news: vec![NewsItem { id: "welcome".into(), - title: "Welcome to ScopeNet".into(), + title: "Welcome to SCOPENET".into(), body: "Your admin can customise this launcher from the panel: colours, news, instances and more.".into(), image_url: None, link: None, @@ -80,7 +80,7 @@ pub struct Background { impl Default for Background { fn default() -> Self { - Self { kind: "gradient".into(), url: None, blur: 0, dim: 45 } + Self { kind: "gradient".into(), url: None, blur: 0, dim: 55 } } } @@ -100,14 +100,14 @@ pub struct Palette { impl Default for Palette { fn default() -> Self { Self { - accent: "#7c5cff".into(), - accent_2: "#22d3ee".into(), - background: "#0b0d17".into(), - surface: "#141828".into(), - text: "#eef0ff".into(), - muted: "#8b90b3".into(), - success: "#34d399".into(), - danger: "#f43f5e".into(), + accent: "#6d6af5".into(), + accent_2: "#8b88f8".into(), + background: "#0d0e12".into(), + surface: "#16181e".into(), + text: "#ecedf1".into(), + muted: "#8b8f9a".into(), + success: "#3fb97c".into(), + danger: "#e5484d".into(), } } } @@ -396,7 +396,7 @@ mod tests { #[test] fn manifest_roundtrip_with_defaults() { let m: LauncherManifest = serde_json::from_str("{}").unwrap(); - assert_eq!(m.branding.name, "ScopeNet"); + assert_eq!(m.branding.name, "SCOPENET"); let loader: Loader = serde_json::from_str("\"neoforge\"").unwrap(); assert_eq!(loader, Loader::NeoForge); } diff --git a/docker-compose.yml b/docker-compose.yml index c149d7f..94dcb54 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,4 @@ -# ScopeNet admin panel +# SCOPENET admin panel # # cp .env.example .env # set ADMIN_PASSWORD at least # docker compose up -d diff --git a/docs/screenshots/launcher-appearance.webp b/docs/screenshots/launcher-appearance.webp index 08ba17a..c69bccf 100644 Binary files a/docs/screenshots/launcher-appearance.webp and b/docs/screenshots/launcher-appearance.webp differ diff --git a/docs/screenshots/launcher-controls.webp b/docs/screenshots/launcher-controls.webp index 1ee7a3b..e785876 100644 Binary files a/docs/screenshots/launcher-controls.webp and b/docs/screenshots/launcher-controls.webp differ diff --git a/docs/screenshots/launcher-home.webp b/docs/screenshots/launcher-home.webp index 4459cd3..0d57b47 100644 Binary files a/docs/screenshots/launcher-home.webp and b/docs/screenshots/launcher-home.webp differ diff --git a/docs/screenshots/launcher-install.webp b/docs/screenshots/launcher-install.webp index a47ff4e..f44ecd8 100644 Binary files a/docs/screenshots/launcher-install.webp and b/docs/screenshots/launcher-install.webp differ diff --git a/docs/screenshots/launcher-login.webp b/docs/screenshots/launcher-login.webp index 11eddbe..26ae01a 100644 Binary files a/docs/screenshots/launcher-login.webp and b/docs/screenshots/launcher-login.webp differ diff --git a/docs/screenshots/panel-dashboard.webp b/docs/screenshots/panel-dashboard.webp index ff57cf8..c4b1920 100644 Binary files a/docs/screenshots/panel-dashboard.webp and b/docs/screenshots/panel-dashboard.webp differ diff --git a/docs/screenshots/panel-design.webp b/docs/screenshots/panel-design.webp index e678f07..d2ec4e4 100644 Binary files a/docs/screenshots/panel-design.webp and b/docs/screenshots/panel-design.webp differ diff --git a/docs/screenshots/panel-instance.webp b/docs/screenshots/panel-instance.webp index 4b7aea0..76c9555 100644 Binary files a/docs/screenshots/panel-instance.webp and b/docs/screenshots/panel-instance.webp differ diff --git a/docs/screenshots/panel-players.webp b/docs/screenshots/panel-players.webp index 97fa7e6..26f9dba 100644 Binary files a/docs/screenshots/panel-players.webp and b/docs/screenshots/panel-players.webp differ diff --git a/launcher/index.html b/launcher/index.html index cbc4f0e..0eead3a 100644 --- a/launcher/index.html +++ b/launcher/index.html @@ -4,7 +4,7 @@ - ScopeNet Launcher + SCOPENET Launcher
diff --git a/launcher/src-tauri/Cargo.toml b/launcher/src-tauri/Cargo.toml index 38b726d..f1537ad 100644 --- a/launcher/src-tauri/Cargo.toml +++ b/launcher/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "scopenet-launcher" -description = "ScopeNet Minecraft launcher" +description = "SCOPENET Minecraft launcher" version.workspace = true edition.workspace = true diff --git a/launcher/src-tauri/icons/128x128.png b/launcher/src-tauri/icons/128x128.png index ead83d9..b36ad73 100644 Binary files a/launcher/src-tauri/icons/128x128.png and b/launcher/src-tauri/icons/128x128.png differ diff --git a/launcher/src-tauri/icons/128x128@2x.png b/launcher/src-tauri/icons/128x128@2x.png index b4a477f..98b87d1 100644 Binary files a/launcher/src-tauri/icons/128x128@2x.png and b/launcher/src-tauri/icons/128x128@2x.png differ diff --git a/launcher/src-tauri/icons/32x32.png b/launcher/src-tauri/icons/32x32.png index b97c12a..bf8f227 100644 Binary files a/launcher/src-tauri/icons/32x32.png and b/launcher/src-tauri/icons/32x32.png differ diff --git a/launcher/src-tauri/icons/64x64.png b/launcher/src-tauri/icons/64x64.png index 6b35dac..55cb35e 100644 Binary files a/launcher/src-tauri/icons/64x64.png and b/launcher/src-tauri/icons/64x64.png differ diff --git a/launcher/src-tauri/icons/icon.icns b/launcher/src-tauri/icons/icon.icns index 1472e68..a9b869d 100644 Binary files a/launcher/src-tauri/icons/icon.icns and b/launcher/src-tauri/icons/icon.icns differ diff --git a/launcher/src-tauri/icons/icon.ico b/launcher/src-tauri/icons/icon.ico index b1ebe49..36294a3 100644 Binary files a/launcher/src-tauri/icons/icon.ico and b/launcher/src-tauri/icons/icon.ico differ diff --git a/launcher/src-tauri/icons/icon.png b/launcher/src-tauri/icons/icon.png index 877cff5..0fba465 100644 Binary files a/launcher/src-tauri/icons/icon.png and b/launcher/src-tauri/icons/icon.png differ diff --git a/launcher/src-tauri/icons/logo.svg b/launcher/src-tauri/icons/logo.svg index 0635e30..93f43d0 100644 --- a/launcher/src-tauri/icons/logo.svg +++ b/launcher/src-tauri/icons/logo.svg @@ -1 +1 @@ - + diff --git a/launcher/src-tauri/src/commands.rs b/launcher/src-tauri/src/commands.rs index 43a6e85..5d57c16 100644 --- a/launcher/src-tauri/src/commands.rs +++ b/launcher/src-tauri/src/commands.rs @@ -79,7 +79,7 @@ async fn fetch_manifest(state: &AppState, panel: &str) -> anyhow::Result diff --git a/launcher/src/app.css b/launcher/src/app.css index c700fc1..dd103d0 100644 --- a/launcher/src/app.css +++ b/launcher/src/app.css @@ -1,23 +1,23 @@ /* Sizes are in rem so the "UI scale" setting scales everything (1rem = 15px at 100%). */ :root { - --accent: #7c5cff; - --accent-2: #22d3ee; - --bg: #0b0d17; - --surface: #141828; - --text: #eef0ff; - --muted: #8b90b3; - --success: #34d399; - --danger: #f43f5e; - --warn: #fbbf24; - --radius: 14px; - --radius-sm: 9px; - --font: 'Outfit Variable', system-ui, sans-serif; + --accent: #6d6af5; + --accent-2: #8b88f8; + --bg: #0d0e12; + --surface: #16181e; + --text: #ecedf1; + --muted: #8b8f9a; + --success: #3fb97c; + --danger: #e5484d; + --warn: #e2a336; + --radius: 10px; + --radius-sm: 7px; + --font: 'Inter Variable', system-ui, sans-serif; --mono: 'JetBrains Mono Variable', ui-monospace, monospace; - --line: color-mix(in srgb, var(--text) 8%, transparent); - --line-strong: color-mix(in srgb, var(--text) 14%, transparent); - --panel: color-mix(in srgb, var(--surface) 62%, transparent); + --line: color-mix(in srgb, var(--text) 7%, transparent); + --line-strong: color-mix(in srgb, var(--text) 12%, transparent); + --panel: color-mix(in srgb, var(--surface) 78%, transparent); --panel-solid: var(--surface); - --blur: blur(18px) saturate(1.3); + --blur: blur(14px); --ease: cubic-bezier(0.2, 0.8, 0.2, 1); font-size: 15px; color-scheme: dark; @@ -82,23 +82,22 @@ button { align-items: center; justify-content: center; gap: 0.5rem; - font-weight: 560; - font-size: 0.93rem; - transition: background 0.15s, border-color 0.15s, transform 0.1s var(--ease), opacity 0.15s, box-shadow 0.2s; + font-weight: 520; + font-size: 0.9rem; + transition: background 0.15s, border-color 0.15s, opacity 0.15s; white-space: nowrap; } button:hover { background: color-mix(in srgb, var(--text) 11%, transparent); } -button:active { transform: scale(0.98); } +button:active { background: color-mix(in srgb, var(--text) 14%, transparent); } button:disabled { opacity: 0.45; cursor: not-allowed; transform: none; } button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } button.primary { - background: linear-gradient(135deg, var(--accent), color-mix(in srgb, var(--accent) 60%, var(--accent-2))); + background: var(--accent); border-color: transparent; color: white; - box-shadow: 0 0.5rem 1.6rem -0.6rem var(--accent); } -button.primary:hover { filter: brightness(1.1); } +button.primary:hover { background: color-mix(in srgb, var(--accent) 88%, white); } button.ghost { background: transparent; border-color: transparent; color: color-mix(in srgb, var(--text) 75%, transparent); } button.ghost:hover { background: color-mix(in srgb, var(--text) 7%, transparent); color: var(--text); } button.danger { color: color-mix(in srgb, var(--danger) 70%, white); background: color-mix(in srgb, var(--danger) 12%, transparent); border-color: color-mix(in srgb, var(--danger) 30%, transparent); } @@ -122,7 +121,10 @@ input:focus, select:focus, textarea:focus { outline: none; border-color: var(--a input::placeholder, textarea::placeholder { color: color-mix(in srgb, var(--muted) 80%, transparent); } select { appearance: none; padding-right: 2.2rem; background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%); background-position: calc(100% - 1.15rem) 55%, calc(100% - 0.8rem) 55%; background-size: 0.33rem 0.33rem; background-repeat: no-repeat; } select option { background: var(--surface); } -input[type='range'] { padding: 0; border: none; background: transparent; accent-color: var(--accent); } +input[type='range'] { -webkit-appearance: none; appearance: none; padding: 0; height: 1.2rem; border: none; background: transparent; cursor: pointer; } +input[type='range']::-webkit-slider-runnable-track { height: 0.25rem; border-radius: 99rem; background: color-mix(in srgb, var(--text) 12%, transparent); } +input[type='range']::-webkit-slider-thumb { -webkit-appearance: none; width: 0.95rem; height: 0.95rem; margin-top: -0.35rem; border-radius: 50%; background: var(--text); border: 3px solid var(--accent); } +input[type='range']:hover, input[type='range']:focus { background: transparent; } input[type='checkbox'] { width: auto; accent-color: var(--accent); } textarea { resize: vertical; min-height: 5rem; line-height: 1.5; } @@ -130,15 +132,15 @@ label.field { display: flex; flex-direction: column; gap: 0.45rem; font-size: 0. .help { font-size: 0.8rem; color: var(--muted); font-weight: 400; line-height: 1.45; } .chip { - display: inline-flex; align-items: center; gap: 0.35rem; font-size: 0.78rem; font-weight: 620; - padding: 0.28rem 0.7rem; border-radius: 99rem; background: color-mix(in srgb, var(--text) 10%, transparent); - border: 1px solid color-mix(in srgb, var(--text) 12%, transparent); backdrop-filter: var(--blur); white-space: nowrap; + display: inline-flex; align-items: center; gap: 0.35rem; font-size: 0.76rem; font-weight: 520; + padding: 0.22rem 0.6rem; border-radius: 0.35rem; background: color-mix(in srgb, var(--text) 7%, transparent); + color: color-mix(in srgb, var(--text) 80%, transparent); white-space: nowrap; } -.chip.accent { background: color-mix(in srgb, var(--accent) 22%, transparent); border-color: color-mix(in srgb, var(--accent) 40%, transparent); } +.chip.accent { background: color-mix(in srgb, var(--accent) 16%, transparent); } .segmented { display: inline-flex; padding: 0.2rem; gap: 0.15rem; border-radius: var(--radius-sm); background: color-mix(in srgb, var(--bg) 70%, transparent); border: 1px solid var(--line-strong); } .segmented button { border: none; background: transparent; padding: 0.45rem 0.9rem; font-size: 0.87rem; color: var(--muted); border-radius: calc(var(--radius-sm) - 2px); } -.segmented button.active { background: color-mix(in srgb, var(--text) 12%, transparent); color: var(--text); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25); } +.segmented button.active { background: color-mix(in srgb, var(--text) 10%, transparent); color: var(--text); } .col > .segmented { align-self: flex-start; } .row { display: flex; align-items: center; gap: 0.75rem; } diff --git a/launcher/src/components/Background.svelte b/launcher/src/components/Background.svelte index c01b42d..57427fa 100644 --- a/launcher/src/components/Background.svelte +++ b/launcher/src/components/Background.svelte @@ -1,5 +1,5 @@ (hidden = document.hidden)} /> diff --git a/launcher/src/components/Console.svelte b/launcher/src/components/Console.svelte index 1a3dc1b..388fa90 100644 --- a/launcher/src/components/Console.svelte +++ b/launcher/src/components/Console.svelte @@ -38,7 +38,7 @@ diff --git a/launcher/src/components/NewsFeed.svelte b/launcher/src/components/NewsFeed.svelte index 525cf2d..d6b571a 100644 --- a/launcher/src/components/NewsFeed.svelte +++ b/launcher/src/components/NewsFeed.svelte @@ -1,5 +1,5 @@
-

Latest news

+

News

- {#each sorted as n, i (n.id)} -
+ {#each sorted as n (n.id)} +
{#if n.image_url}{/if}
@@ -35,16 +35,16 @@ diff --git a/launcher/src/components/PlayButton.svelte b/launcher/src/components/PlayButton.svelte index d0045e5..2e1c0b4 100644 --- a/launcher/src/components/PlayButton.svelte +++ b/launcher/src/components/PlayButton.svelte @@ -40,13 +40,13 @@ {:else if running} {:else} {/if} {#if mine && l.state === 'error'} @@ -59,33 +59,28 @@
diff --git a/launcher/src/components/Rail.svelte b/launcher/src/components/Rail.svelte index 9a73614..d93c25e 100644 --- a/launcher/src/components/Rail.svelte +++ b/launcher/src/components/Rail.svelte @@ -59,30 +59,31 @@ diff --git a/launcher/src/pages/Login.svelte b/launcher/src/pages/Login.svelte index fd6360c..03a4488 100644 --- a/launcher/src/pages/Login.svelte +++ b/launcher/src/pages/Login.svelte @@ -7,7 +7,7 @@ diff --git a/launcher/src/pages/Settings.svelte b/launcher/src/pages/Settings.svelte index d337e47..ecb9b05 100644 --- a/launcher/src/pages/Settings.svelte +++ b/launcher/src/pages/Settings.svelte @@ -343,7 +343,7 @@
-
{b?.name ?? 'ScopeNet'} Launcher

Version {app.boot?.app.version} · {app.boot?.app.os} {app.boot?.app.arch}

+
{b?.name ?? 'SCOPENET'} Launcher

Version {app.boot?.app.version} · {app.boot?.app.os} {app.boot?.app.arch}

{#if app.update}
@@ -365,27 +365,27 @@
diff --git a/panel/web/src/app.css b/panel/web/src/app.css index ab3620f..59bc7dc 100644 --- a/panel/web/src/app.css +++ b/panel/web/src/app.css @@ -1,24 +1,24 @@ :root { - --bg: #090a12; - --bg-2: #0e1019; - --surface: #12141f; - --surface-2: #181b29; - --surface-3: #20243a; + --bg: #0d0e12; + --bg-2: #111217; + --surface: #16181e; + --surface-2: #1c1e25; + --surface-3: #25272f; --line: rgba(255, 255, 255, 0.07); - --line-strong: rgba(255, 255, 255, 0.13); - --text: #eef0ff; - --text-2: #b7bbdb; - --muted: #7d82a8; - --accent: #8b6cff; - --accent-2: #22d3ee; - --accent-soft: rgba(139, 108, 255, 0.14); - --good: #34d399; - --warn: #fbbf24; - --bad: #f43f5e; - --radius: 14px; - --radius-sm: 9px; - --shadow: 0 20px 60px -20px rgba(0, 0, 0, 0.6); - --font: 'Outfit Variable', system-ui, sans-serif; + --line-strong: rgba(255, 255, 255, 0.12); + --text: #ecedf1; + --text-2: #b4b7c0; + --muted: #8b8f9a; + --accent: #6d6af5; + --accent-2: #8b88f8; + --accent-soft: rgba(109, 106, 245, 0.14); + --good: #3fb97c; + --warn: #e2a336; + --bad: #e5484d; + --radius: 10px; + --radius-sm: 7px; + --shadow: 0 10px 30px -12px rgba(0, 0, 0, 0.5); + --font: 'Inter Variable', system-ui, sans-serif; --mono: 'JetBrains Mono Variable', ui-monospace, monospace; color-scheme: dark; } @@ -34,17 +34,11 @@ body { background: var(--bg); color: var(--text); font-family: var(--font); - font-size: 15px; + font-size: 14.5px; -webkit-font-smoothing: antialiased; } -body { - background: - radial-gradient(1200px 600px at 110% -10%, rgba(139, 108, 255, 0.12), transparent 60%), - radial-gradient(900px 500px at -10% 110%, rgba(34, 211, 238, 0.07), transparent 60%), - var(--bg); - background-attachment: fixed; -} +body { background: var(--bg); } a { color: var(--accent-2); @@ -53,11 +47,11 @@ a { h1, h2, h3, h4 { margin: 0; - font-weight: 650; + font-weight: 600; letter-spacing: -0.01em; } -h1 { font-size: 1.75rem; } +h1 { font-size: 1.5rem; } h2 { font-size: 1.2rem; } h3 { font-size: 1rem; } @@ -69,7 +63,7 @@ code, .mono { } ::selection { - background: rgba(139, 108, 255, 0.4); + background: rgba(109, 106, 245, 0.4); } ::-webkit-scrollbar { width: 10px; height: 10px; } @@ -109,20 +103,16 @@ code, .mono { .tiny { font-size: 0.75rem; } .card { - background: linear-gradient(180deg, rgba(255, 255, 255, 0.025), rgba(255, 255, 255, 0.01)), var(--surface); + background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 20px; } .card.hover { - transition: border-color 0.15s, transform 0.15s, box-shadow 0.15s; -} -.card.hover:hover { - border-color: var(--line-strong); - transform: translateY(-2px); - box-shadow: var(--shadow); + transition: border-color 0.15s; } +.card.hover:hover { border-color: var(--line-strong); } .section-title { display: flex; @@ -151,29 +141,28 @@ button, .btn { align-items: center; justify-content: center; gap: 8px; - font-weight: 550; - transition: background 0.15s, border-color 0.15s, transform 0.08s, box-shadow 0.15s, opacity 0.15s; + font-weight: 520; + transition: background 0.15s, border-color 0.15s, opacity 0.15s; white-space: nowrap; } button:hover { background: var(--surface-3); } -button:active { transform: translateY(1px); } button:disabled { opacity: 0.5; cursor: not-allowed; } button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } -button.primary { - background: linear-gradient(135deg, var(--accent), #6a4cf0); +button.primary, a.btn.primary { + background: var(--accent); border-color: transparent; - box-shadow: 0 8px 24px -10px rgba(139, 108, 255, 0.8); + color: white; } -button.primary:hover { filter: brightness(1.1); } +button.primary:hover, a.btn.primary:hover { background: color-mix(in srgb, var(--accent) 88%, white); } button.ghost { background: transparent; border-color: transparent; color: var(--text-2); } button.ghost:hover { background: rgba(255, 255, 255, 0.05); color: var(--text); } -button.danger { color: #ff8a9e; border-color: rgba(244, 63, 94, 0.3); background: rgba(244, 63, 94, 0.08); } -button.danger:hover { background: rgba(244, 63, 94, 0.16); } +button.danger { color: #f2999c; border-color: rgba(229, 72, 77, 0.3); background: rgba(229, 72, 77, 0.08); } +button.danger:hover { background: rgba(229, 72, 77, 0.15); } button.icon { padding: 8px; } button.sm { padding: 6px 11px; font-size: 0.85rem; } @@ -194,7 +183,10 @@ select { appearance: none; background-image: linear-gradient(45deg, transparent input[type='color'] { padding: 0; width: 42px; height: 42px; border-radius: 10px; cursor: pointer; overflow: hidden; } input[type='color']::-webkit-color-swatch-wrapper { padding: 0; } input[type='color']::-webkit-color-swatch { border: none; } -input[type='range'] { padding: 0; accent-color: var(--accent); border: none; background: transparent; } +input[type='range'] { -webkit-appearance: none; appearance: none; padding: 0; height: 18px; border: none; background: transparent; cursor: pointer; } +input[type='range']::-webkit-slider-runnable-track { height: 4px; border-radius: 99px; background: var(--surface-3); } +input[type='range']::-webkit-slider-thumb { -webkit-appearance: none; width: 14px; height: 14px; margin-top: -5px; border-radius: 50%; background: var(--text); border: 3px solid var(--accent); } +input[type='range']:hover, input[type='range']:focus { background: transparent; } input[type='checkbox'] { width: auto; accent-color: var(--accent); } label.field { @@ -212,15 +204,15 @@ label.field .help { color: var(--muted); font-weight: 400; font-size: 0.78rem; } align-items: center; gap: 5px; padding: 3px 9px; - border-radius: 999px; + border-radius: 5px; font-size: 0.75rem; - font-weight: 600; + font-weight: 520; background: rgba(255, 255, 255, 0.06); color: var(--text-2); border: 1px solid var(--line); white-space: nowrap; } -.badge.accent { background: var(--accent-soft); color: #c4b5ff; border-color: rgba(139, 108, 255, 0.3); } +.badge.accent { background: var(--accent-soft); color: #b9b7fb; border-color: rgba(109, 106, 245, 0.28); } .badge.good { background: rgba(52, 211, 153, 0.12); color: #6ee7b7; border-color: rgba(52, 211, 153, 0.25); } .badge.warn { background: rgba(251, 191, 36, 0.12); color: #fcd34d; border-color: rgba(251, 191, 36, 0.25); } .badge.bad { background: rgba(244, 63, 94, 0.12); color: #fda4af; border-color: rgba(244, 63, 94, 0.25); } @@ -241,7 +233,7 @@ label.field .help { color: var(--muted); font-weight: 400; font-size: 0.78rem; } color: var(--muted); font-size: 0.88rem; } -.segmented button.active { background: var(--surface-3); color: var(--text); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); } +.segmented button.active { background: var(--surface-3); color: var(--text); } .tabs { display: flex; @@ -271,8 +263,6 @@ table.table { color: var(--muted); font-weight: 500; font-size: 0.78rem; - text-transform: uppercase; - letter-spacing: 0.05em; padding: 10px 14px; border-bottom: 1px solid var(--line); } @@ -304,7 +294,7 @@ table.table { .spin { animation: spin 0.9s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } -@keyframes fade-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } } +@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } } @media (max-width: 900px) { .page { padding: 20px 16px 48px; } diff --git a/panel/web/src/components/BarChart.svelte b/panel/web/src/components/BarChart.svelte index c3abb3b..038541f 100644 --- a/panel/web/src/components/BarChart.svelte +++ b/panel/web/src/components/BarChart.svelte @@ -66,7 +66,7 @@ svg { width: 100%; height: auto; display: block; overflow: visible; } .grid { stroke: rgba(255, 255, 255, 0.06); stroke-width: 1; } .tick { fill: var(--muted); font-size: 11px; font-family: var(--font); } - .bar { fill: #8b6cff; transition: opacity 0.15s; } + .bar { fill: #6d6af5; transition: opacity 0.15s; } .bar.dim { opacity: 0.4; } .tip { position: absolute; transform: translate(-50%, calc(-100% - 10px)); pointer-events: none; background: var(--surface-3); diff --git a/panel/web/src/components/LauncherPreview.svelte b/panel/web/src/components/LauncherPreview.svelte index bfa00dc..8613e46 100644 --- a/panel/web/src/components/LauncherPreview.svelte +++ b/panel/web/src/components/LauncherPreview.svelte @@ -1,26 +1,22 @@
-
- {#if b.background.kind === 'video' && b.background.url} - - + {#if media} +
+ {#if b.background.kind === 'video'} + + + {:else} +
+ {/if} +
+
{/if} -
-
-
- {#if b.logo_url}{:else}{/if} - {b.name} - - -
- -
- {instanceName.slice(0, 1)} - C - V - - - -
- -
-
-
1.21.1Fabric
-

{instanceName}

-

{b.tagline}

+
+ {#if b.logo_url}{:else}{/if} + {b.name}
-
- - {#if b.features.server_status} - 42/100 online + +
+ {instanceName.slice(0, 2).toUpperCase()} + CB + CA + + + +
+ +
+
+
1.21.1Fabric
+

{instanceName}

+

{b.tagline}

+
+ Play + {#if b.features.server_status} 42/100 online{/if} +
+
+ {#if b.features.news && news.length} +
+ News + {#each news as n} +
+ {#if n.image_url}{/if} +
+ {#if n.tag}{n.tag}{/if} + {n.title || 'Untitled'} + {n.body} +
+
+ {/each} +
{/if}
- {#if b.features.news && news.length} -
- News - {#each news as n} -
- {#if n.image_url}{/if} -
- {#if n.tag}{n.tag}{/if} - {n.title || 'Untitled'} - {n.body} -
-
- {/each} -
- {/if} -
diff --git a/panel/web/src/components/Modal.svelte b/panel/web/src/components/Modal.svelte index 1952d2f..8882f45 100644 --- a/panel/web/src/components/Modal.svelte +++ b/panel/web/src/components/Modal.svelte @@ -28,17 +28,17 @@ diff --git a/panel/web/src/components/Sidebar.svelte b/panel/web/src/components/Sidebar.svelte index c6a4613..3b3a7ad 100644 --- a/panel/web/src/components/Sidebar.svelte +++ b/panel/web/src/components/Sidebar.svelte @@ -4,7 +4,7 @@ import { logout, session } from '../lib/session.svelte'; import Avatar from './Avatar.svelte'; - let { brandName = 'ScopeNet', logo = null }: { brandName?: string; logo?: string | null } = $props(); + let { brandName = 'SCOPENET', logo = null }: { brandName?: string; logo?: string | null } = $props(); const items = [ { id: 'dashboard', label: 'Dashboard', icon: LayoutDashboard }, @@ -54,12 +54,12 @@ diff --git a/panel/web/src/pages/Instances.svelte b/panel/web/src/pages/Instances.svelte index c46db82..4e347a7 100644 --- a/panel/web/src/pages/Instances.svelte +++ b/panel/web/src/pages/Instances.svelte @@ -126,7 +126,7 @@ .inst { padding: 0; overflow: hidden; color: var(--text); display: flex; flex-direction: column; } .inst.disabled { opacity: 0.6; } .banner { - height: 110px; background: radial-gradient(120% 120% at 100% 0%, rgba(139, 108, 255, 0.45), transparent 60%), radial-gradient(100% 100% at 0% 100%, rgba(34, 211, 238, 0.25), transparent 60%), var(--surface-2); + height: 96px; background: var(--surface-2); border-bottom: 1px solid var(--line); background-size: cover; background-position: center; position: relative; } .badges { position: absolute; top: 10px; right: 10px; display: flex; gap: 6px; } diff --git a/panel/web/src/pages/Login.svelte b/panel/web/src/pages/Login.svelte index 5aebce4..9c64428 100644 --- a/panel/web/src/pages/Login.svelte +++ b/panel/web/src/pages/Login.svelte @@ -26,8 +26,6 @@
-
-