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
+56 -30

No files matched your search

+33 -20
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("a", { class: "button secondary", href: bundle.url, download: "sotf-mods.zip" }, `Download zip (${formatSize(bundle.size)})`),
el("p", {}, "RedLoader and every mod in one zip. Extract it into your Sons of the Forest folder, the one that contains SonsOfTheForest.exe."), "Download it again to update. Remove mods by deleting them from the Mods folder."));
el("a", { class: "button secondary", href: bundle.url, download: "sotf-mods.zip" }, `Download zip (${formatSize(bundle.size)})`),
),
);
} }
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 {