From 967bd58f0005e992b1759dea44a33cf144439994 Mon Sep 17 00:00:00 2001 From: Justin Oros Date: Mon, 28 Sep 2026 15:53:46 -0700 Subject: [PATCH] Show the three install options as numbered cards --- site/app.js | 53 ++++++++++++++++++++++++++++++------------------- site/index.html | 2 +- site/style.css | 31 ++++++++++++++++++++--------- 3 files changed, 56 insertions(+), 30 deletions(-) diff --git a/site/app.js b/site/app.js index bf5b61c..6b0dff6 100644 --- a/site/app.js +++ b/site/app.js @@ -32,31 +32,44 @@ function link(href, text) { return el("a", { href, target: "_blank", rel: "noopener" }, text); } +function optionCard(number, title, text, action, note, recommended) { + return el("div", { class: recommended ? "get-card recommended" : "get-card" }, + el("p", { class: "get-option" }, recommended ? `Option ${number}, recommended` : `Option ${number}`), + el("h3", {}, title), + el("p", {}, text), + action, + note ? el("p", { class: "get-note" }, note) : null, + ); +} + function renderGet() { const node = $("get"); - const { app, bundle } = state.manifest; - const cards = []; + const { app, bundle, mods } = state.manifest; + const options = []; if (app) { - cards.push( - el("div", { class: "get-card" }, - el("h2", {}, "Windows app"), - el("p", {}, "Finds your game automatically, even inside Program Files, and installs RedLoader and mods with one click."), - el("a", { class: "button primary", href: app.url }, `Download the app (${formatSize(app.size)})`), - el("p", { class: "get-note" }, `Version ${app.version}. If Windows shows a warning, click More info, then Run anyway.`), - ), - ); + options.push((n) => optionCard(n, "Windows app", + "Finds your game automatically, even inside Program Files. Installs, updates and removes RedLoader and mods with one click.", + el("a", { class: "button primary", href: app.url }, `Download app (${formatSize(app.size)})`), + `Version ${app.version}. If Windows shows a warning, click More info, then Run anyway.`, + true)); } if (bundle) { - cards.push( - el("div", { class: "get-card" }, - el("h2", {}, "Zip download"), - el("p", {}, "RedLoader and every mod in one zip. Extract it into your Sons of the Forest folder, the one that contains SonsOfTheForest.exe."), - el("a", { class: "button secondary", href: bundle.url, download: "sotf-mods.zip" }, `Download zip (${formatSize(bundle.size)})`), - ), - ); + options.push((n) => optionCard(n, "Zip download", + "RedLoader and every mod in one zip. Extract it into your game folder, the one with SonsOfTheForest.exe.", + el("a", { class: "button secondary", href: bundle.url, download: "sotf-mods.zip" }, `Download zip (${formatSize(bundle.size)})`), + "Download it again to update. Remove mods by deleting them from the Mods folder.")); } - node.hidden = !cards.length; - node.replaceChildren(...cards); + if ((mods || []).some((mod) => mod.installCommand)) { + options.push((n) => optionCard(n, "PowerShell scripts", + "Install one mod at a time. Copy a mod's command from the list below and paste it into PowerShell.", + el("a", { class: "button secondary", href: "#mods" }, "Go to the mod list"), + "Installs RedLoader too if needed. Run the command again to update.")); + } + node.hidden = !options.length; + node.replaceChildren( + el("div", { class: "block-head" }, el("h2", { id: "get-title" }, "Choose how to install")), + el("div", { class: "get-grid" }, options.map((make, i) => make(i + 1))), + ); } function renderRedloader() { @@ -70,7 +83,7 @@ function renderRedloader() { el("li", { class: "row" }, el("div", {}, el("h3", {}, link(rl.repo, "RedLoader")), - el("p", { class: "desc" }, "Every mod on this page runs on RedLoader. The app and the zip include it."), + el("p", { class: "desc" }, "Every mod on this page runs on RedLoader. All three install options include it."), el("p", { class: "meta" }, el("span", {}, `Latest ${rl.version}`), link(rl.releaseUrl, "Release notes")), ), ), diff --git a/site/index.html b/site/index.html index f61d606..51c23c9 100644 --- a/site/index.html +++ b/site/index.html @@ -17,7 +17,7 @@

Sons of the Forest mod loader

Install, update and remove Sons of the Forest mods with one click.

- +

diff --git a/site/style.css b/site/style.css index b388b69..d3cb1ec 100644 --- a/site/style.css +++ b/site/style.css @@ -52,7 +52,7 @@ a:hover { } .page { - max-width: 54rem; + max-width: 62rem; margin: 0 auto; padding: clamp(2.5rem, 7vw, 5rem) clamp(1.25rem, 4vw, 2.5rem) 2rem; } @@ -74,32 +74,44 @@ a:hover { font-size: 1.15rem; } -.get { +.get-grid { display: grid; - grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); + grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 1rem; - margin-top: 2.75rem; + margin-top: 1.25rem; } .get-card { display: flex; flex-direction: column; align-items: flex-start; - padding: 1.35rem 1.5rem 1.4rem; + padding: 1.25rem 1.35rem 1.35rem; background: var(--bark); border: 1px solid var(--bark-line); + border-top: 5px solid var(--bark-line); border-radius: 6px; } -.get-card:first-child { - border-top: 5px solid var(--flare); +.get-card.recommended { + border-top-color: var(--flare); } -.get-card h2 { +.get-card .get-option { margin: 0; + color: var(--lichen); + font-size: 0.9rem; +} + +.get-card.recommended .get-option { + color: var(--flare); + font-weight: 600; +} + +.get-card h3 { + margin: 0.15rem 0 0; font-family: var(--display); font-weight: 700; - font-size: 1.75rem; + font-size: 1.65rem; line-height: 1.1; } @@ -123,6 +135,7 @@ a.button { font-size: 0.95rem; line-height: 1.2; text-decoration: none; + white-space: nowrap; } a.button.primary {