Show the three install options as numbered cards

This commit is contained in:
justin committed 2026-09-28 15:53:46 -07:00
1 parent 9bac1f221e
commit 967bd58f00
3 files changed
+55 -29

No files matched your search

+32 -19
View File
@@ -32,31 +32,44 @@ function link(href, text) {
return el("a", { href, target: "_blank", rel: "noopener" }, 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() { function renderGet() {
const node = $("get"); const node = $("get");
const { app, bundle } = state.manifest; const { app, bundle, mods } = state.manifest;
const cards = []; const options = [];
if (app) { if (app) {
cards.push( options.push((n) => optionCard(n, "Windows app",
el("div", { class: "get-card" }, "Finds your game automatically, even inside Program Files. Installs, updates and removes RedLoader and mods with one click.",
el("h2", {}, "Windows app"), el("a", { class: "button primary", href: app.url }, `Download app (${formatSize(app.size)})`),
el("p", {}, "Finds your game automatically, even inside Program Files, and installs RedLoader and mods with one click."), `Version ${app.version}. If Windows shows a warning, click More info, then Run anyway.`,
el("a", { class: "button primary", href: app.url }, `Download the app (${formatSize(app.size)})`), true));
el("p", { class: "get-note" }, `Version ${app.version}. If Windows shows a warning, click More info, then Run anyway.`),
),
);
} }
if (bundle) { if (bundle) {
cards.push( options.push((n) => optionCard(n, "Zip download",
el("div", { class: "get-card" }, "RedLoader and every mod in one zip. Extract it into your game folder, the one with SonsOfTheForest.exe.",
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)})`), 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; if ((mods || []).some((mod) => mod.installCommand)) {
node.replaceChildren(...cards); 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() { function renderRedloader() {
@@ -70,7 +83,7 @@ function renderRedloader() {
el("li", { class: "row" }, el("li", { class: "row" },
el("div", {}, el("div", {},
el("h3", {}, link(rl.repo, "RedLoader")), 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")), el("p", { class: "meta" }, el("span", {}, `Latest ${rl.version}`), link(rl.releaseUrl, "Release notes")),
), ),
), ),
+1 -1
View File
@@ -17,7 +17,7 @@
<h1>Sons of the Forest mod loader</h1> <h1>Sons of the Forest mod loader</h1>
<p class="lede">Install, update and remove Sons of the Forest mods with one click.</p> <p class="lede">Install, update and remove Sons of the Forest mods with one click.</p>
</header> </header>
<section id="get" class="get" aria-label="Ways to install" hidden></section> <section id="get" class="block get" aria-labelledby="get-title" hidden></section>
<section id="redloader" class="block" aria-labelledby="redloader-title" hidden></section> <section id="redloader" class="block" aria-labelledby="redloader-title" hidden></section>
<section id="mods" class="block" aria-labelledby="mods-title"></section> <section id="mods" class="block" aria-labelledby="mods-title"></section>
<p id="status" class="status" role="status" aria-live="polite"></p> <p id="status" class="status" role="status" aria-live="polite"></p>
+22 -9
View File
@@ -52,7 +52,7 @@ a:hover {
} }
.page { .page {
max-width: 54rem; max-width: 62rem;
margin: 0 auto; margin: 0 auto;
padding: clamp(2.5rem, 7vw, 5rem) clamp(1.25rem, 4vw, 2.5rem) 2rem; padding: clamp(2.5rem, 7vw, 5rem) clamp(1.25rem, 4vw, 2.5rem) 2rem;
} }
@@ -74,32 +74,44 @@ a:hover {
font-size: 1.15rem; font-size: 1.15rem;
} }
.get { .get-grid {
display: grid; display: grid;
grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
gap: 1rem; gap: 1rem;
margin-top: 2.75rem; margin-top: 1.25rem;
} }
.get-card { .get-card {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: flex-start; align-items: flex-start;
padding: 1.35rem 1.5rem 1.4rem; padding: 1.25rem 1.35rem 1.35rem;
background: var(--bark); background: var(--bark);
border: 1px solid var(--bark-line); border: 1px solid var(--bark-line);
border-top: 5px solid var(--bark-line);
border-radius: 6px; border-radius: 6px;
} }
.get-card:first-child { .get-card.recommended {
border-top: 5px solid var(--flare); border-top-color: var(--flare);
} }
.get-card h2 { .get-card .get-option {
margin: 0; 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-family: var(--display);
font-weight: 700; font-weight: 700;
font-size: 1.75rem; font-size: 1.65rem;
line-height: 1.1; line-height: 1.1;
} }
@@ -123,6 +135,7 @@ a.button {
font-size: 0.95rem; font-size: 0.95rem;
line-height: 1.2; line-height: 1.2;
text-decoration: none; text-decoration: none;
white-space: nowrap;
} }
a.button.primary { a.button.primary {